diff options
author | denisc <denisc@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-05-09 17:53:54 +0000 |
---|---|---|
committer | denisc <denisc@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-05-09 17:53:54 +0000 |
commit | 1cb396585d6f4e497ca6c84f92526172802fbbd0 (patch) | |
tree | 39d0cbe8ae83caf442106c714b33af99b4c31047 /gcc/config | |
parent | 85eaefbcbfd861ec7f71ac005f7092820b736b33 (diff) | |
download | gcc-1cb396585d6f4e497ca6c84f92526172802fbbd0.tar.gz |
* 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
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@33802 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/avr/avr-protos.h | 4 | ||||
-rw-r--r-- | gcc/config/avr/avr.c | 370 | ||||
-rw-r--r-- | gcc/config/avr/avr.h | 3 | ||||
-rw-r--r-- | gcc/config/avr/avr.md | 32 | ||||
-rw-r--r-- | gcc/config/avr/t-avr | 1 |
5 files changed, 261 insertions, 149 deletions
diff --git a/gcc/config/avr/avr-protos.h b/gcc/config/avr/avr-protos.h index 605c2a33e6d..90dc5aac649 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 171dba5a206..73758cabf12 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 c180e6cfb86..f459bc038da 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 019c36bc0d4..064e9ab9289 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 9f549f459cd..1bc971eac04 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 |