Index: avr.c =================================================================== --- avr.c (revision 132380) +++ avr.c (working copy) @@ -976,6 +976,8 @@ true_regnum (XEXP (x, 0))); debug_rtx (x); } + if (!strict && GET_CODE (x) == SUBREG) + x = SUBREG_REG (x); if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x) : REG_OK_FOR_BASE_NOSTRICT_P (x))) r = POINTER_REGS; @@ -990,6 +992,7 @@ if (fit) { if (! strict + || REGNO (XEXP (x,0)) == REG_X || REGNO (XEXP (x,0)) == REG_Y || REGNO (XEXP (x,0)) == REG_Z) r = BASE_POINTER_REGS; @@ -1957,7 +1960,7 @@ /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude it but I have this situation with extremal optimization options. */ - + *l = 4; if (reg_base == reg_dest) return (AS2 (adiw,r26,%o1) CR_TAB @@ -4840,43 +4843,9 @@ order_regs_for_local_alloc (void) { unsigned int i; - static const int order_0[] = { - 24,25, - 18,19, - 20,21, - 22,23, - 30,31, - 26,27, - 28,29, - 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2, - 0,1, - 32,33,34,35 - }; - static const int order_1[] = { - 18,19, - 20,21, - 22,23, - 24,25, - 30,31, - 26,27, - 28,29, - 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2, - 0,1, - 32,33,34,35 - }; - static const int order_2[] = { - 25,24, - 23,22, - 21,20, - 19,18, - 30,31, - 26,27, - 28,29, - 17,16, - 15,14,13,12,11,10,9,8,7,6,5,4,3,2, - 1,0, - 32,33,34,35 - }; + static const int order_0[] = REG_ALLOC_ORDER_0; + static const int order_1[] = REG_ALLOC_ORDER_1; + static const int order_2[] = REG_ALLOC_ORDER_2; const int *order = (TARGET_ORDER_1 ? order_1 : TARGET_ORDER_2 ? order_2 : @@ -5490,6 +5459,14 @@ || xx == arg_pointer_rtx) return 1; /* XXX frame & arg pointer checks */ } + else if (GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC) + { + int regno = REGNO (XEXP (x, 0)); + if (regno == REG_Z || regno == REG_Y || regno == REG_X) + return 1; + } + + return 0; } @@ -5692,7 +5669,7 @@ return 1; /* Modes larger than QImode occupy consecutive registers. */ - if (regno + GET_MODE_SIZE (mode) > FIRST_PSEUDO_REGISTER) + if (regno <= (REG_Z + 1) && (regno + GET_MODE_SIZE (mode)) > (REG_Z + 2)) return 0; /* All modes larger than QImode should start in an even register. */ Index: avr.h =================================================================== --- avr.h (revision 132380) +++ avr.h (working copy) @@ -199,19 +199,29 @@ 1,1,/* STACK */ \ 1,1 /* arg pointer */ } -#define REG_ALLOC_ORDER { \ - 24,25, \ - 18,19, \ - 20,21, \ - 22,23, \ - 30,31, \ - 26,27, \ - 28,29, \ - 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2, \ - 0,1, \ - 32,33,34,35 \ - } +#define REG_ALLOC_ORDER_0 {\ + 24,25,18,19,20,21,22,23,30,31,26,27,28,29, \ + 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,\ + 0,1,\ + 32,33,34,35 } + +#define REG_ALLOC_ORDER_1 {\ + 18,19,20,21,22,23,24,25,30,31,26,27,28,29,\ + 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,\ + 0,1,\ + 32,33,34,35 } + +#define REG_ALLOC_ORDER_2 {\ + 18,22,20,24,19,23,21,25,30,31,26,27,28,29, \ + 17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,\ + 0,1,\ + 32,33,34,35 } + + +#define REG_ALLOC_ORDER REG_ALLOC_ORDER_0 + + #define ORDER_REGS_FOR_LOCAL_ALLOC order_regs_for_local_alloc () @@ -453,11 +463,14 @@ OPNUM, TYPE); \ goto WIN; \ } \ + if(0) \ + { \ push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL, \ BASE_POINTER_REGS, GET_MODE (X), VOIDmode, 0, 0, \ OPNUM, TYPE); \ goto WIN; \ } \ + } \ else if (! (frame_pointer_needed && XEXP (X,0) == frame_pointer_rtx)) \ { \ push_reload (X, NULL_RTX, &X, NULL, \ Index: avr.md =================================================================== --- avr.md (revision 132380) +++ avr.md (working copy) @@ -251,8 +251,8 @@ (set_attr "cc" "none")]) (define_insn "*movhi" - [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,d,*r,q,r") - (match_operand:HI 1 "general_operand" "r,m,rL,i,i,r,q"))] + [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,Qm,d,*r,q,r") + (match_operand:HI 1 "general_operand" "r,Qm,rL,i,i,r,q"))] "(register_operand (operands[0],HImode) || register_operand (operands[1],HImode) || const0_rtx == operands[1])" "* return output_movhi (insn, operands, NULL);"