aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Chertykov <denisc@overta.ru>2000-05-09 17:53:54 +0000
committerDenis Chertykov <denisc@gcc.gnu.org>2000-05-09 21:53:54 +0400
commit3454eb731b213cda64cbd7ac18a9d0093c33cbc7 (patch)
tree39d0cbe8ae83caf442106c714b33af99b4c31047
parent7a544ce153d84b697ec10a5acfd9b2e35a94fd87 (diff)
downloadgcc-3454eb731b213cda64cbd7ac18a9d0093c33cbc7.zip
gcc-3454eb731b213cda64cbd7ac18a9d0093c33cbc7.tar.gz
gcc-3454eb731b213cda64cbd7ac18a9d0093c33cbc7.tar.bz2
avr-protos.h (extra_constraint): change a type of second argument from char to int to avoid warnings.
* config/avr/avr-protos.h (extra_constraint): change a type of second argument from char to int to avoid warnings. (asm_output_byte): Likewise. * config/avr/avr.c (MAX_LD_OFFSET) New macro. (initial_elimination_offset): Handle elimination from FRAME_POINTER_REGNUM to STACK_POINTER_REGNUM. (legitimate_address_p): Use MAX_LD_OFFSET. (legitimize_address): Likewise. (out_movqi_r_mr): Likewise. (out_movhi_r_mr): Likewise, use `fatal_insn' instead of `fatal'. (out_movsi_r_mr): Use MAX_LD_OFFSET. (out_movsi_mr_r): Likewise. (out_movqi_mr_r): Likewise. (out_movhi_mr_r): Likewise. (notice_update_cc): Correct CC for the ashrqi3 with the shift count as CONST_INT != 6. (ashlqi3_out): Coding style modifications. Run `fatal_insn' if shift count is a CONSTANT_P, but not a CONST_INT. (ashlhi3_out): Coding style modifications. (ashlsi3_out): Likewise. (ashrhi3_out): Likewise. (ashrsi3_out): Likewise. (lshrhi3_out): Likewise. (lshrsi3_out): Likewise. (ashrqi3_out): Generate shift for any known constant count without scratch register. Run `fatal_insn' if shift count is a CONSTANT_P, but not a CONST_INT. (lshrqi3_out): Coding style modifications. Run `fatal_insn' if shift count is a CONSTANT_P, but not a CONST_INT. (extra_constraint): change a type of second argument from char to int to avoid warnings. (asm_output_byte): Likewise. (asm_file_end): Output size generated commands count as a hex number too. * config/avr/avr.h (RETURN_ADDR_RTX): New macro. * config/avr/avr.md (addhi3): Fragment commented by &&0 is removed. (ashlqi3): Values of "length" attribute changed. Shift count uses constraints 'n' instead of 'i'. (ashrqi3): Likewise. Values of "cc" attribute changed. Generate shifts without clobber register. (lshrqi3): Shift count uses constraints 'n' instead of 'i'. (call_insn): Correct test for which_alternative == 1 (was 0). (call_value_insn): Likewise. * config/avr/t-avr: Remove definition of FLOAT while generates fp-bit.c From-SVN: r33802
-rw-r--r--gcc/ChangeLog53
-rw-r--r--gcc/config/avr/avr-protos.h4
-rw-r--r--gcc/config/avr/avr.c370
-rw-r--r--gcc/config/avr/avr.h3
-rw-r--r--gcc/config/avr/avr.md32
-rw-r--r--gcc/config/avr/t-avr1
6 files changed, 314 insertions, 149 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3f33f4f..fb1de4d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,56 @@
+Tue May 9 20:52:43 2000 Denis Chertykov <denisc@overta.ru>
+
+ * config/avr/avr-protos.h (extra_constraint): change a type of
+ second argument from char to int to avoid warnings.
+ (asm_output_byte): Likewise.
+
+ * config/avr/avr.c (MAX_LD_OFFSET) New macro.
+ (initial_elimination_offset): Handle elimination from
+ FRAME_POINTER_REGNUM to STACK_POINTER_REGNUM.
+ (legitimate_address_p): Use MAX_LD_OFFSET.
+ (legitimize_address): Likewise.
+ (out_movqi_r_mr): Likewise.
+ (out_movhi_r_mr): Likewise, use `fatal_insn' instead of `fatal'.
+ (out_movsi_r_mr): Use MAX_LD_OFFSET.
+ (out_movsi_mr_r): Likewise.
+ (out_movqi_mr_r): Likewise.
+ (out_movhi_mr_r): Likewise.
+ (notice_update_cc): Correct CC for the ashrqi3 with the shift
+ count as CONST_INT != 6.
+ (ashlqi3_out): Coding style modifications. Run `fatal_insn' if
+ shift count is a CONSTANT_P, but not a CONST_INT.
+ (ashlhi3_out): Coding style modifications.
+ (ashlsi3_out): Likewise.
+ (ashrhi3_out): Likewise.
+ (ashrsi3_out): Likewise.
+ (lshrhi3_out): Likewise.
+ (lshrsi3_out): Likewise.
+ (ashrqi3_out): Generate shift for any known constant count without
+ scratch register. Run `fatal_insn' if shift count is a CONSTANT_P,
+ but not a CONST_INT.
+ (lshrqi3_out): Coding style modifications. Run `fatal_insn' if
+ shift count is a CONSTANT_P, but not a CONST_INT.
+ (extra_constraint): change a type of
+ second argument from char to int to avoid warnings.
+ (asm_output_byte): Likewise.
+ (asm_file_end): Output size generated commands count as a hex
+ number too.
+
+ * config/avr/avr.h (RETURN_ADDR_RTX): New macro.
+
+ * config/avr/avr.md (addhi3): Fragment commented by &&0 is
+ removed.
+ (ashlqi3): Values of "length" attribute changed. Shift count
+ uses constraints 'n' instead of 'i'.
+ (ashrqi3): Likewise. Values of "cc" attribute changed. Generate
+ shifts without clobber register.
+ (lshrqi3): Shift count uses constraints 'n' instead of 'i'.
+ (call_insn): Correct test for which_alternative == 1 (was 0).
+ (call_value_insn): Likewise.
+
+ * config/avr/t-avr: Remove definition of FLOAT while generates
+ fp-bit.c
+
2000-05-09 Bruce Korb <bkorb@gnu.org>
* fixinc/check.tpl: Template for checking fixes
diff --git a/gcc/config/avr/avr-protos.h b/gcc/config/avr/avr-protos.h
index 605c2a33..90dc5aa 100644
--- a/gcc/config/avr/avr-protos.h
+++ b/gcc/config/avr/avr-protos.h
@@ -110,7 +110,7 @@ extern char * lshrsi3_out PARAMS ((rtx insn, rtx operands[], int *len));
extern enum reg_class preferred_reload_class PARAMS ((rtx x,
enum reg_class class));
extern int avr_address_cost PARAMS ((rtx x));
-extern int extra_constraint PARAMS ((rtx x, char c));
+extern int extra_constraint PARAMS ((rtx x, int c));
extern rtx legitimize_address PARAMS ((rtx x, rtx oldx,
enum machine_mode mode));
extern int adjust_insn_length PARAMS ((rtx insn, int len));
@@ -123,7 +123,7 @@ extern int default_rtx_costs PARAMS ((rtx X, RTX_CODE code,
RTX_CODE outer_code));
extern void asm_output_char PARAMS ((FILE *file, rtx value));
extern void asm_output_short PARAMS ((FILE *file, rtx value));
-extern void asm_output_byte PARAMS ((FILE *file, char value));
+extern void asm_output_byte PARAMS ((FILE *file, int value));
extern enum reg_class secondary_input_reload_class PARAMS ((enum reg_class,
enum machine_mode,
rtx));
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 171dba5..73758ca 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -40,6 +40,8 @@
#include "recog.h"
#include "tm_p.h"
+/* Maximal allowed offset for an address in the LD command */
+#define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
static int avr_naked_function_p PARAMS ((tree));
static int interrupt_function_p PARAMS ((tree));
@@ -230,7 +232,7 @@ interrupt_function_p (func)
return a != NULL_TREE;
}
-/* Return nonzero if FUNC is an signal function as specified
+/* Return nonzero if FUNC is a signal function as specified
by the "signal" attribute. */
static int
@@ -254,24 +256,30 @@ initial_elimination_offset (from,to)
int to ATTRIBUTE_UNUSED;
{
int reg;
- int interrupt_func_p = interrupt_function_p (current_function_decl);
- int signal_func_p = signal_function_p (current_function_decl);
- int leaf_func_p = leaf_function_p ();
- int offset= frame_pointer_needed ? 2 : 0;
-
- for (reg = 0; reg < 32; ++reg)
- {
- if ((!leaf_func_p && (call_used_regs[reg]
- && (interrupt_func_p || signal_func_p)))
- || (regs_ever_live[reg]
- && (!call_used_regs[reg] || interrupt_func_p || signal_func_p)
- && ! (frame_pointer_needed
- && (reg == REG_Y || reg == (REG_Y+1)))))
+ if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
+ return 0;
+ else
+ {
+ int interrupt_func_p = interrupt_function_p (current_function_decl);
+ int signal_func_p = signal_function_p (current_function_decl);
+ int leaf_func_p = leaf_function_p ();
+ int offset= frame_pointer_needed ? 2 : 0;
+
+ for (reg = 0; reg < 32; ++reg)
{
- ++offset;
+ if ((!leaf_func_p && (call_used_regs[reg]
+ && (interrupt_func_p || signal_func_p)))
+ || (regs_ever_live[reg]
+ && (!call_used_regs[reg] || interrupt_func_p || signal_func_p)
+ && ! (frame_pointer_needed
+ && (reg == REG_Y || reg == (REG_Y+1)))))
+ {
+ ++offset;
+ }
}
+ return get_frame_size () + 2 + 1 + offset;
}
- return get_frame_size () + 2 + 1 + offset;
+ return 0;
}
/* This function checks sequence of live registers */
@@ -672,7 +680,7 @@ legitimate_address_p (mode, x, strict)
&& REG_P (XEXP (x, 0))
&& GET_CODE (XEXP (x, 1)) == CONST_INT
&& INTVAL (XEXP (x, 1)) >= 0
- && INTVAL (XEXP (x, 1)) <= (64 - GET_MODE_SIZE (mode))
+ && INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode)
&& reg_renumber
)
fprintf (stderr, "(r%d ---> r%d)", REGNO (XEXP (x, 0)),
@@ -689,7 +697,7 @@ legitimate_address_p (mode, x, strict)
&& GET_CODE (XEXP (x, 1)) == CONST_INT
&& INTVAL (XEXP (x, 1)) >= 0)
{
- int fit = INTVAL (XEXP (x, 1)) <= (64 - GET_MODE_SIZE (mode));
+ int fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
if (fit)
{
if (! strict
@@ -741,7 +749,7 @@ legitimize_address (x, oldx, mode)
{
int offs = INTVAL (XEXP (oldx,1));
if (frame_pointer_rtx != XEXP (oldx,0))
- if (offs > 64 - GET_MODE_SIZE (mode))
+ if (offs > MAX_LD_OFFSET (mode))
{
if (TARGET_ALL_DEBUG)
fprintf (stderr, "force_reg (big offset)\n");
@@ -938,6 +946,8 @@ notice_update_cc (body, insn)
rtx body ATTRIBUTE_UNUSED;
rtx insn;
{
+ rtx set;
+
switch (get_attr_cc (insn))
{
case CC_NONE:
@@ -949,44 +959,58 @@ notice_update_cc (body, insn)
break;
case CC_SET_ZN:
- {
- rtx set = single_set (insn);
- CC_STATUS_INIT;
- if (set)
- {
- cc_status.flags |= CC_NO_OVERFLOW;
- cc_status.value1 = SET_DEST (set);
- }
- }
+ set = single_set (insn);
+ CC_STATUS_INIT;
+ if (set)
+ {
+ cc_status.flags |= CC_NO_OVERFLOW;
+ cc_status.value1 = SET_DEST (set);
+ }
break;
case CC_SET_CZN:
/* Insn sets the Z,N,C flags of CC to recog_operand[0].
The V flag may or may not be known but that's ok because
alter_cond will change tests to use EQ/NE. */
- {
- rtx set = single_set (insn);
- CC_STATUS_INIT;
- if (set)
- {
- cc_status.value1 = SET_DEST (set);
- cc_status.flags |= CC_OVERFLOW_UNUSABLE;
- }
- }
+ set = single_set (insn);
+ CC_STATUS_INIT;
+ if (set)
+ {
+ cc_status.value1 = SET_DEST (set);
+ cc_status.flags |= CC_OVERFLOW_UNUSABLE;
+ }
break;
case CC_COMPARE:
- {
- rtx set = single_set (insn);
- CC_STATUS_INIT;
- if (set)
- cc_status.value1 = SET_SRC (set);
- }
+ set = single_set (insn);
+ CC_STATUS_INIT;
+ if (set)
+ cc_status.value1 = SET_SRC (set);
break;
-
+
case CC_CLOBBER:
/* Insn doesn't leave CC in a usable state. */
CC_STATUS_INIT;
+
+ /* Correct CC for the ashrqi3 with the shift count as CONST_INT != 6 */
+ set = single_set (insn);
+ if (set)
+ {
+ rtx src = SET_SRC (set);
+
+ if (GET_CODE (src) == ASHIFTRT
+ && GET_MODE (src) == QImode)
+ {
+ rtx x = XEXP (src, 1);
+
+ if (GET_CODE (x) == CONST_INT
+ && INTVAL (x) != 6)
+ {
+ cc_status.value1 = SET_DEST (set);
+ cc_status.flags |= CC_OVERFLOW_UNUSABLE;
+ }
+ }
+ }
break;
}
}
@@ -1273,7 +1297,7 @@ out_movqi_r_mr (insn, op, l)
int disp = INTVAL (XEXP (x,1));
if (REGNO (XEXP (x,0)) != REG_Y)
fatal_insn ("Incorrect insn:",insn);
- if (disp <= 63 + 64 - GET_MODE_SIZE (GET_MODE (op[1])))
+ if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (op[1])))
{
if (l)
*l = 3;
@@ -1358,12 +1382,12 @@ out_movhi_r_mr (insn, op, l)
int disp = INTVAL(XEXP (XEXP (op[1],0), 1));
int reg_base = true_regnum (XEXP (XEXP (op[1],0), 0));
- if (disp > 64 - GET_MODE_SIZE (GET_MODE (op[1])))
+ if (disp > MAX_LD_OFFSET (GET_MODE (op[1])))
{
rtx x = XEXP (op[1],0);
if (REGNO (XEXP (x,0)) != REG_Y)
fatal_insn ("Incorrect insn:",insn);
- if (disp <= 63 + 64 - GET_MODE_SIZE (GET_MODE (op[1])))
+ if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (op[1])))
{
op[4] = GEN_INT (disp - 62);
return *l=4, (AS2 (adiw, r28, %4) CR_TAB
@@ -1425,20 +1449,16 @@ out_movhi_r_mr (insn, op, l)
else if (GET_CODE (XEXP (op[1],0)) == PRE_DEC) /* (--R) */
{
if (reg_overlap_mentioned_p (op[0], XEXP (XEXP (op[1],0),0)))
- {
- debug_rtx (insn);
- fatal ("Internal error. Incorrect insn.");
- }
+ fatal_insn ("Incorrect insn:", insn);
+
return *l=2, (AS2 (ld,%B0,%1) CR_TAB
AS2 (ld,%A0,%1));
}
else if (GET_CODE (XEXP (op[1],0)) == POST_INC) /* (R++) */
{
if (reg_overlap_mentioned_p (op[0], XEXP (XEXP (op[1],0),0)))
- {
- debug_rtx (insn);
- fatal ("Internal error. Incorrect insn.");
- }
+ fatal_insn ("Incorrect insn:", insn);
+
return *l=2, (AS2 (ld,%A0,%1) CR_TAB
AS2 (ld,%B0,%1));
}
@@ -1514,12 +1534,12 @@ out_movsi_r_mr (insn,op,l)
{
int disp = INTVAL(XEXP (XEXP (op[1],0), 1));
- if (disp > 64 - GET_MODE_SIZE (GET_MODE (op[1])))
+ if (disp > MAX_LD_OFFSET (GET_MODE (op[1])))
{
rtx x = XEXP (op[1],0);
if (REGNO (XEXP (x,0)) != REG_Y)
fatal_insn ("Incorrect insn:",insn);
- if (disp <= 63 + 64 - GET_MODE_SIZE (GET_MODE (op[1])))
+ if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (op[1])))
{
op[4] = GEN_INT (disp - 60);
return *l=6,(AS2 (adiw, r28, %4) CR_TAB
@@ -1652,12 +1672,12 @@ out_movsi_mr_r (insn,op,l)
else if (GET_CODE (XEXP (op[0],0)) == PLUS) /* (R + i) */
{
int disp = INTVAL(XEXP (XEXP (op[0],0), 1));
- if (disp > 64 - GET_MODE_SIZE (GET_MODE (op[0])))
+ if (disp > MAX_LD_OFFSET (GET_MODE (op[0])))
{
rtx x = XEXP (op[0],0);
if (REGNO (XEXP (x,0)) != REG_Y)
fatal_insn ("Incorrect insn:",insn);
- if (disp <= 63 + 64 - GET_MODE_SIZE (GET_MODE (op[0])))
+ if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (op[0])))
{
op[4] = GEN_INT (disp - 60);
return *l=6,(AS2 (adiw, r28, %4) CR_TAB
@@ -1781,7 +1801,7 @@ out_movqi_mr_r (insn, op, l)
int disp = INTVAL (XEXP (x,1));
if (REGNO (XEXP (x,0)) != REG_Y)
fatal_insn ("Incorrect insn:",insn);
- if (disp <= 63 + 64 - GET_MODE_SIZE (GET_MODE (op[0])))
+ if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (op[0])))
{
if (l)
*l = 3;
@@ -1877,12 +1897,12 @@ out_movhi_mr_r (insn,op,l)
else if (GET_CODE (XEXP (op[0],0)) == PLUS)
{
int disp = INTVAL(XEXP (XEXP (op[0],0), 1));
- if (disp > 64 - GET_MODE_SIZE (GET_MODE (op[0])))
+ if (disp > MAX_LD_OFFSET (GET_MODE (op[0])))
{
rtx x = XEXP (op[0],0);
if (REGNO (XEXP (x,0)) != REG_Y)
fatal_insn ("Incorrect insn:",insn);
- if (disp <= 63 + 64 - GET_MODE_SIZE (GET_MODE (op[0])))
+ if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (op[0])))
{
op[4] = GEN_INT (disp - 62);
return *l=4,(AS2 (adiw, r28, %4) CR_TAB
@@ -2107,73 +2127,86 @@ ashlqi3_out (insn,operands,len)
if (GET_CODE (operands[2]) == CONST_INT)
{
int k;
- int *t=len;
+
if (!len)
len = &k;
+
switch (INTVAL (operands[2]))
{
- default: len = t; break;
+ default:
+ *len = 1;
+ return AS1 (clr,%0);
+
case 1:
- *len=1;
+ *len = 1;
return AS1 (lsl,%0);
+
case 2:
- *len=2;
+ *len = 2;
return (AS1 (lsl,%0) CR_TAB
AS1 (lsl,%0));
+
case 3:
- *len=3;
+ *len = 3;
return (AS1 (lsl,%0) CR_TAB
AS1 (lsl,%0) CR_TAB
AS1 (lsl,%0));
+
case 4:
if (TEST_HARD_REG_CLASS (LD_REGS, true_regnum (operands[0])))
{
- *len=2;
+ *len = 2;
return (AS1 (swap,%0) CR_TAB
AS2 (andi,%0,0xf0));
}
- *len=4;
+ *len = 4;
return (AS1 (lsl,%0) CR_TAB
AS1 (lsl,%0) CR_TAB
AS1 (lsl,%0) CR_TAB
AS1 (lsl,%0));
+
case 5:
if (TEST_HARD_REG_CLASS (LD_REGS, true_regnum (operands[0])))
{
- *len=3;
+ *len = 3;
return (AS1 (swap,%0) CR_TAB
AS1 (lsl,%0) CR_TAB
AS2 (andi,%0,0xe0));
}
- *len=5;
+ *len = 5;
return (AS1 (lsl,%0) CR_TAB
AS1 (lsl,%0) CR_TAB
AS1 (lsl,%0) CR_TAB
AS1 (lsl,%0) CR_TAB
AS1 (lsl,%0));
+
case 6:
if (TEST_HARD_REG_CLASS (LD_REGS, true_regnum (operands[0])))
{
- *len=4;
+ *len = 4;
return (AS1 (swap,%0) CR_TAB
AS1 (lsl,%0) CR_TAB
AS1 (lsl,%0) CR_TAB
AS2 (andi,%0,0xc0));
}
- *len=6;
+ *len = 6;
return (AS1 (lsl,%0) CR_TAB
AS1 (lsl,%0) CR_TAB
AS1 (lsl,%0) CR_TAB
AS1 (lsl,%0) CR_TAB
AS1 (lsl,%0) CR_TAB
AS1 (lsl,%0));
+
case 7:
- *len=3;
+ *len = 3;
return (AS1 (ror,%0) CR_TAB
AS1 (clr,%0) CR_TAB
AS1 (ror,%0));
}
}
+ else if (CONSTANT_P (operands[2]))
+ fatal_insn ("Internal compiler bug.\nIncorrect shift:", insn);
+
if (len)
*len = 3;
out_shift_with_cnt (AS1 (lsl,%0),
@@ -2194,21 +2227,26 @@ ashlhi3_out (insn,operands,len)
{
int k;
int *t=len;
+
if (!len)
len = &k;
+
switch (INTVAL (operands[2]))
{
default: len = t; break;
+
case 1:
- *len=2;
+ *len = 2;
return (AS1 (lsl,%A0) CR_TAB
AS1 (rol,%B0));
+
case 2:
- *len=4;
+ *len = 4;
return (AS1 (lsl,%A0) CR_TAB
AS1 (rol,%B0) CR_TAB
AS1 (lsl,%0) CR_TAB
AS1 (rol,%B0));
+
case 8:
if (true_regnum (operands[0]) + 1 == true_regnum (operands[1]))
return *len = 1, AS1 (clr,%A0);
@@ -2238,65 +2276,80 @@ ashlsi3_out (insn,operands,len)
{
int k;
int *t=len;
+
if (!len)
len = &k;
+
switch (INTVAL (operands[2]))
{
default: len = t; break;
+
case 1:
- *len=4;
+ *len = 4;
return (AS1 (lsl,%A0) CR_TAB
AS1 (rol,%B0) CR_TAB
AS1 (rol,%C0) CR_TAB
AS1 (rol,%D0));
+
case 8:
{
int reg0 = true_regnum (operands[0]);
int reg1 = true_regnum (operands[1]);
- *len=4;
+ *len = 4;
if (reg0 >= reg1)
return (AS2 (mov,%D0,%C1) CR_TAB
AS2 (mov,%C0,%B1) CR_TAB
AS2 (mov,%B0,%A1) CR_TAB
AS1 (clr,%A0));
else if (reg0 + 1 == reg1)
- return *len = 1, AS1 (clr,%A0);
+ {
+ *len = 1;
+ return AS1 (clr,%A0);
+ }
else
return (AS1 (clr,%A0) CR_TAB
AS2 (mov,%B0,%A1) CR_TAB
AS2 (mov,%C0,%B1) CR_TAB
AS2 (mov,%D0,%C1));
}
+
case 16:
{
int reg0 = true_regnum (operands[0]);
int reg1 = true_regnum (operands[1]);
- *len=4;
+ *len = 4;
if (reg0 + 1 >= reg1)
return (AS2 (mov,%D0,%B1) CR_TAB
AS2 (mov,%C0,%A1) CR_TAB
AS1 (clr,%B0) CR_TAB
AS1 (clr,%A0));
if (reg0 + 2 == reg1)
- return *len = 2, (AS1 (clr,%B0) CR_TAB
- AS1 (clr,%A0));
+ {
+ *len = 2;
+ return (AS1 (clr,%B0) CR_TAB
+ AS1 (clr,%A0));
+ }
else
return (AS2 (mov,%C0,%A1) CR_TAB
AS2 (mov,%D0,%B1) CR_TAB
AS1 (clr,%B0) CR_TAB
AS1 (clr,%A0));
}
+
case 24:
- *len=4;
+ *len = 4;
if (true_regnum (operands[0]) + 3 != true_regnum (operands[1]))
return (AS2 (mov,%D0,%A1) CR_TAB
AS1 (clr,%C0) CR_TAB
AS1 (clr,%B0) CR_TAB
AS1 (clr,%A0));
else
- return *len = 3, (AS1 (clr,%C0) CR_TAB
- AS1 (clr,%B0) CR_TAB
- AS1 (clr,%A0));
+ {
+ *len = 3;
+ return (AS1 (clr,%C0) CR_TAB
+ AS1 (clr,%B0) CR_TAB
+ AS1 (clr,%A0));
+ }
}
}
if (len)
@@ -2319,33 +2372,60 @@ ashrqi3_out (insn,operands,len)
{
if (GET_CODE (operands[2]) == CONST_INT)
{
- int *t=len;
int k;
+
if (!len)
len = &k;
+
switch (INTVAL (operands[2]))
{
- default: len = t; break;
case 1:
- *len=1;
+ *len = 1;
return AS1 (asr,%0);
+
case 2:
- *len=2;
+ *len = 2;
return (AS1 (asr,%0) CR_TAB
AS1 (asr,%0));
+
case 3:
- *len=3;
+ *len = 3;
return (AS1 (asr,%0) CR_TAB
AS1 (asr,%0) CR_TAB
AS1 (asr,%0));
+
case 4:
- *len=4;
+ *len = 4;
+ return (AS1 (asr,%0) CR_TAB
+ AS1 (asr,%0) CR_TAB
+ AS1 (asr,%0) CR_TAB
+ AS1 (asr,%0));
+
+ case 5:
+ *len = 5;
return (AS1 (asr,%0) CR_TAB
AS1 (asr,%0) CR_TAB
AS1 (asr,%0) CR_TAB
+ AS1 (asr,%0) CR_TAB
AS1 (asr,%0));
+
+ case 6:
+ *len = 4;
+ return (AS2 (bst,%0,6) CR_TAB
+ AS1 (lsl,%0) CR_TAB
+ AS2 (sbc,%0,%0) CR_TAB
+ AS2 (bld,%0,0));
+
+ default:
+ case 7:
+ *len = 2;
+ return (AS1 (lsl,%0) CR_TAB
+ AS2 (sbc,%0,%0));
}
}
+ else if (CONSTANT_P (operands[2]))
+ fatal_insn ("Internal compiler bug.\nIncorrect shift:", insn);
+
if (len)
*len = 3;
out_shift_with_cnt (AS1 (asr,%0),
@@ -2365,22 +2445,27 @@ ashrhi3_out (insn,operands,len)
if (GET_CODE (operands[2]) == CONST_INT)
{
int k;
- int *t=len;
+ int *t = len;
+
if (!len)
len = &k;
+
switch (INTVAL (operands[2]))
{
default: len = t; break;
+
case 1:
*len=2;
return (AS1 (asr,%B0) CR_TAB
AS1 (ror,%A0));
+
case 2:
*len=4;
return (AS1 (asr,%B0) CR_TAB
AS1 (ror,%A0) CR_TAB
AS1 (asr,%B0) CR_TAB
AS1 (ror,%A0));
+
case 8:
if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
@@ -2391,6 +2476,7 @@ ashrhi3_out (insn,operands,len)
return *len = 3, (AS1 (clr,%B0) CR_TAB
AS2 (sbrc,%A0,7) CR_TAB
AS1 (dec,%B0));
+
case 15:
return *len = 3, (AS1 (lsl,%B0) CR_TAB
AS2 (sbc,%A0,%A0) CR_TAB
@@ -2418,17 +2504,21 @@ ashrsi3_out (insn,operands,len)
{
int k;
int *t = len;
+
if (!len)
len = &k;
+
switch (INTVAL (operands[2]))
{
default: len = t; break;
+
case 1:
*len=4;
return (AS1 (asr,%D0) CR_TAB
- AS1 (ror,%C0) CR_TAB
- AS1 (ror,%B0) CR_TAB
+ AS1 (ror,%C0) CR_TAB
+ AS1 (ror,%B0) CR_TAB
AS1 (ror,%A0));
+
case 8:
{
int reg0 = true_regnum (operands[0]);
@@ -2442,9 +2532,12 @@ ashrsi3_out (insn,operands,len)
AS2 (sbrc,%C0,7) CR_TAB
AS1 (dec,%D0));
else if (reg0 == reg1 + 1)
- return *len = 3, (AS1 (clr,%D0) CR_TAB
- AS2 (sbrc,%C0,7) CR_TAB
- AS1 (dec,%D0));
+ {
+ *len = 3;
+ return (AS1 (clr,%D0) CR_TAB
+ AS2 (sbrc,%C0,7) CR_TAB
+ AS1 (dec,%D0));
+ }
else
return (AS1 (clr,%D0) CR_TAB
AS2 (sbrc,%D1,7) CR_TAB
@@ -2453,6 +2546,7 @@ ashrsi3_out (insn,operands,len)
AS2 (mov,%B0,%C1) CR_TAB
AS2 (mov,%A0,%B1));
}
+
case 16:
{
int reg0 = true_regnum (operands[0]);
@@ -2478,6 +2572,7 @@ ashrsi3_out (insn,operands,len)
AS1 (com,%D0) CR_TAB
AS2 (mov,%C0,%D0));
}
+
case 24:
if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
return *len = 6, (AS2 (mov,%A0,%D1) CR_TAB
@@ -2515,24 +2610,30 @@ lshrqi3_out (insn,operands,len)
if (GET_CODE (operands[2]) == CONST_INT)
{
int k;
- int *t=len;
+
if (!len)
len = &k;
+
switch (INTVAL (operands[2]))
{
- default: len = t; break;
+ default:
+ *len = 1;
+ return AS1 (clr,%0);
+
case 1:
- *len=1;
+ *len = 1;
return AS1 (lsr,%0);
+
case 2:
- *len=2;
+ *len = 2;
return (AS1 (lsr,%0) CR_TAB
AS1 (lsr,%0));
case 3:
- *len=3;
+ *len = 3;
return (AS1 (lsr,%0) CR_TAB
AS1 (lsr,%0) CR_TAB
AS1 (lsr,%0));
+
case 4:
if (TEST_HARD_REG_CLASS (LD_REGS, true_regnum (operands[0])))
{
@@ -2540,48 +2641,54 @@ lshrqi3_out (insn,operands,len)
return (AS1 (swap,%0) CR_TAB
AS2 (andi,%0,0x0f));
}
- *len=4;
+ *len = 4;
return (AS1 (lsr,%0) CR_TAB
AS1 (lsr,%0) CR_TAB
AS1 (lsr,%0) CR_TAB
AS1 (lsr,%0));
+
case 5:
if (TEST_HARD_REG_CLASS (LD_REGS, true_regnum (operands[0])))
{
- *len=3;
+ *len = 3;
return (AS1 (swap,%0) CR_TAB
AS1 (lsr,%0) CR_TAB
AS2 (andi,%0,0x7));
}
- *len=5;
+ *len = 5;
return (AS1 (lsr,%0) CR_TAB
AS1 (lsr,%0) CR_TAB
AS1 (lsr,%0) CR_TAB
AS1 (lsr,%0) CR_TAB
AS1 (lsr,%0));
+
case 6:
if (TEST_HARD_REG_CLASS (LD_REGS, true_regnum (operands[0])))
{
- *len=4;
+ *len = 4;
return (AS1 (swap,%0) CR_TAB
AS1 (lsr,%0) CR_TAB
AS1 (lsr,%0) CR_TAB
AS2 (andi,%0,0x3));
}
- *len=6;
+ *len = 6;
return (AS1 (lsr,%0) CR_TAB
AS1 (lsr,%0) CR_TAB
AS1 (lsr,%0) CR_TAB
AS1 (lsr,%0) CR_TAB
AS1 (lsr,%0) CR_TAB
AS1 (lsr,%0));
+
case 7:
- *len=3;
+ *len = 3;
return (AS1 (rol,%0) CR_TAB
AS1 (clr,%0) CR_TAB
AS1 (rol,%0));
}
}
+ else if (CONSTANT_P (operands[2]))
+ fatal_insn ("Internal compiler bug.\nIncorrect shift:", insn);
+
if (len)
*len = 3;
out_shift_with_cnt (AS1 (lsr,%0),
@@ -2600,22 +2707,27 @@ lshrhi3_out (insn,operands,len)
if (GET_CODE (operands[2]) == CONST_INT)
{
int k;
- int *t=len;
+ int *t = len;
+
if (!len)
len = &k;
+
switch (INTVAL (operands[2]))
{
default: len = t; break;
+
case 1:
- *len=2;
+ *len = 2;
return (AS1 (lsr,%B0) CR_TAB
AS1 (ror,%A0));
+
case 2:
- *len=4;
+ *len = 4;
return (AS1 (lsr,%B0) CR_TAB
AS1 (ror,%A0) CR_TAB
AS1 (lsr,%B0) CR_TAB
AS1 (ror,%A0));
+
case 8:
if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
@@ -2624,10 +2736,11 @@ lshrhi3_out (insn,operands,len)
return *len = 1, AS1 (clr,%B0);
case 15:
- return *len = 4, (AS1 (lsl,%B0) CR_TAB
- AS2 (sbc,%A0,%A0) CR_TAB
- AS1 (neg,%A0) CR_TAB
- AS1 (clr,%B0));
+ *len = 4;
+ return (AS1 (lsl,%B0) CR_TAB
+ AS2 (sbc,%A0,%A0) CR_TAB
+ AS1 (neg,%A0) CR_TAB
+ AS1 (clr,%B0));
}
}
if (len)
@@ -2649,23 +2762,27 @@ lshrsi3_out (insn,operands,len)
if (GET_CODE (operands[2]) == CONST_INT)
{
int k;
- int *t=len;
+ int *t = len;
+
if (!len)
len = &k;
+
switch (INTVAL (operands[2]))
{
default: len = t; break;
+
case 1:
- *len=4;
+ *len = 4;
return (AS1 (lsr,%D0) CR_TAB
AS1 (ror,%C0) CR_TAB
AS1 (ror,%B0) CR_TAB
AS1 (ror,%A0));
+
case 8:
{
int reg0 = true_regnum (operands[0]);
int reg1 = true_regnum (operands[1]);
- *len=4;
+ *len = 4;
if (reg0 <= reg1)
return (AS2 (mov,%A0,%B1) CR_TAB
AS2 (mov,%B0,%C1) CR_TAB
@@ -2679,11 +2796,12 @@ lshrsi3_out (insn,operands,len)
AS2 (mov,%B0,%C1) CR_TAB
AS2 (mov,%A0,%B1));
}
+
case 16:
{
int reg0 = true_regnum (operands[0]);
int reg1 = true_regnum (operands[1]);
- *len=4;
+ *len = 4;
if (reg0 <= reg1 + 1)
return (AS2 (mov,%A0,%C1) CR_TAB
AS2 (mov,%B0,%D1) CR_TAB
@@ -2698,6 +2816,7 @@ lshrsi3_out (insn,operands,len)
AS1 (clr,%C0) CR_TAB
AS1 (clr,%D0));
}
+
case 24:
if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
return *len = 4, (AS2 (mov,%A0,%D1) CR_TAB
@@ -3010,7 +3129,7 @@ asm_output_char(file,value)
void
asm_output_byte (file,value)
FILE *file;
- char value;
+ int value;
{
fprintf (file, "\t.byte 0x%x\n",value & 0xff);
}
@@ -3342,9 +3461,10 @@ asm_file_end (file)
FILE *file;
{
fprintf (file,
- "/* File %s: code %4d (%4d), prologues %3d, epilogues %3d */\n",
+ "/* File %s: code %4d = 0x%04x (%4d), prologues %3d, epilogues %3d */\n",
main_input_filename,
commands_in_file,
+ commands_in_file,
commands_in_file - commands_in_prologues - commands_in_epilogues,
commands_in_prologues, commands_in_epilogues);
}
@@ -3487,7 +3607,7 @@ avr_address_cost (rtx x)
int
extra_constraint (x,c)
rtx x;
- char c;
+ int c;
{
if (c == 'Q'
&& GET_CODE (x) == MEM
@@ -3506,7 +3626,7 @@ extra_constraint (x,c)
&& REG_P (XEXP (XEXP (x,0), 0))
&& GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
&& (INTVAL (XEXP (XEXP (x,0), 1))
- <= (64 - GET_MODE_SIZE (GET_MODE (x)))))
+ <= MAX_LD_OFFSET (GET_MODE (x))))
{
rtx xx = XEXP (XEXP (x,0), 0);
int regno = REGNO (xx);
@@ -3667,7 +3787,7 @@ avr_function_value (type,func)
tree type;
tree func ATTRIBUTE_UNUSED;
{
- int offs;
+ unsigned int offs;
if (TYPE_MODE (type) != BLKmode)
return avr_libcall_value (TYPE_MODE (type));
diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h
index c180e6c..f459bc0 100644
--- a/gcc/config/avr/avr.h
+++ b/gcc/config/avr/avr.h
@@ -1079,6 +1079,9 @@ enum reg_class {
registers. This macro must be defined if `ELIMINABLE_REGS' is
defined. */
+#define RETURN_ADDR_RTX(count, x) \
+ gen_rtx_MEM (Pmode, memory_address (Pmode, plus_constant (tem, 1)))
+
#define PUSH_ROUNDING(NPUSHED) (NPUSHED)
/* A C expression that is the number of bytes actually pushed onto the
stack when an instruction attempts to push NPUSHED bytes.
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index 019c36b..064e9ab 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -254,7 +254,7 @@
case 1: /* mov r,L */
return (AS1 (clr,%A0) CR_TAB
AS1 (clr,%B0));
- case 2: /* mov r,d */
+ case 2: /* ld d,i */
if (operands[1] == const1_rtx
&& (link = find_reg_note (insn, REG_WAS_0, 0))
/* Make sure the insn that stored the 0 is still present. */
@@ -272,7 +272,7 @@
return out_movhi_r_mr (insn, operands, NULL);
case 4: /* mov m,r*/
{
- rtx save1=NULL;
+ rtx save1 = NULL;
if (operands[1] == const0_rtx)
{
save1 = operands[1];
@@ -543,15 +543,6 @@
short tmp = INTVAL (operands[2]);
operands[2] = GEN_INT(tmp);
}
- if (! (reload_completed | reload_in_progress))
- {
- if (REGNO (operands[0]) != REGNO (operands[1])
- && REGNO (operands[0]) != REGNO (operands[2])&&0)
- {
- emit_move_insn (operands[0], operands[1]);
- operands[1] = operands[0];
- }
- }
}")
@@ -871,10 +862,10 @@
(define_insn "ashlqi3"
[(set (match_operand:QI 0 "register_operand" "=r,!d,r,r")
(ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0")
- (match_operand:QI 2 "general_operand" "r,i,i,Qm")))]
+ (match_operand:QI 2 "general_operand" "r,n,n,Qm")))]
""
"* return ashlqi3_out (insn, operands, NULL);"
- [(set_attr "length" "6,4,6,7")
+ [(set_attr "length" "5,4,6,7")
(set_attr "cc" "clobber,set_czn,set_czn,clobber")])
(define_insn "ashlhi3"
@@ -903,12 +894,11 @@
(define_insn "ashrqi3"
[(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r")
(ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0")
- (match_operand:QI 2 "general_operand" "r,P,K,i,Qm")))
- (clobber (match_scratch:QI 3 "=X,X,X,&d,X"))]
+ (match_operand:QI 2 "general_operand" "r,P,K,n,Qm")))]
""
- "* return ashrqi3_out (insn,operands, NULL);"
- [(set_attr "length" "6,1,2,4,7")
- (set_attr "cc" "clobber,clobber,clobber,clobber,clobber")])
+ "* return ashrqi3_out (insn, operands, NULL);"
+ [(set_attr "length" "5,1,2,5,7")
+ (set_attr "cc" "clobber,set_zn,set_zn,clobber,clobber")])
(define_insn "ashrhi3"
[(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r")
@@ -936,7 +926,7 @@
(define_insn "lshrqi3"
[(set (match_operand:QI 0 "register_operand" "=r,d,r,r")
(lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0")
- (match_operand:QI 2 "general_operand" "r,i,i,Qm")))]
+ (match_operand:QI 2 "general_operand" "r,n,n,Qm")))]
""
"* return lshrqi3_out (insn,operands, NULL);"
[(set_attr "length" "6,4,6,7")
@@ -1621,7 +1611,7 @@
(set (attr "length")
(cond [(eq (symbol_ref "which_alternative") (const_int 0))
(const_int 1)
- (eq (symbol_ref "which_alternative") (const_int 0))
+ (eq (symbol_ref "which_alternative") (const_int 1))
(const_int 3)
(eq (symbol_ref "!AVR_MEGA")
(const_int 0))
@@ -1651,7 +1641,7 @@
(set (attr "length")
(cond [(eq (symbol_ref "which_alternative") (const_int 0))
(const_int 1)
- (eq (symbol_ref "which_alternative") (const_int 0))
+ (eq (symbol_ref "which_alternative") (const_int 1))
(const_int 3)
(eq (symbol_ref "!AVR_MEGA")
(const_int 0))
diff --git a/gcc/config/avr/t-avr b/gcc/config/avr/t-avr
index 9f549f4..1bc971e 100644
--- a/gcc/config/avr/t-avr
+++ b/gcc/config/avr/t-avr
@@ -32,7 +32,6 @@ TARGET_LIBGCC2_CFLAGS = -DDF=SF -Dinhibit_libc
#LIBGCC2 = $(LIBGCC1)
fp-bit.c: $(srcdir)/config/fp-bit.c $(srcdir)/config/avr/t-avr
- echo '#define FLOAT' > fp-bit.c
echo '#define FLOAT_ONLY' >> fp-bit.c
echo '#define CMPtype QItype' >> fp-bit.c
echo '#define DF SF' >> fp-bit.c