===================================================================
@@ -726,7 +726,7 @@ (define_insn "*addhi3_zero_extend1"
(define_insn "*addhi3_sp_R_pc2"
[(set (match_operand:HI 1 "stack_register_operand" "=q")
(plus:HI (match_operand:HI 2 "stack_register_operand" "q")
- (match_operand:HI 0 "avr_sp_immediate_operand" "R")))]
+ (match_operand:HI 0 "avr_sp_immediate_operand" "C65")))]
"AVR_2_BYTE_PC"
"*{
if (CONST_INT_P (operands[0]))
@@ -795,7 +795,7 @@ (define_insn "*addhi3_sp_R_pc2"
(define_insn "*addhi3_sp_R_pc3"
[(set (match_operand:HI 1 "stack_register_operand" "=q")
(plus:HI (match_operand:HI 2 "stack_register_operand" "q")
- (match_operand:QI 0 "avr_sp_immediate_operand" "R")))]
+ (match_operand:QI 0 "avr_sp_immediate_operand" "C65")))]
"AVR_3_BYTE_PC"
"*{
if (CONST_INT_P (operands[0]))
@@ -1372,7 +1372,7 @@ (define_expand "mulsi3"
[(parallel [(set (match_operand:SI 0 "register_operand" "")
(mult:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "nonmemory_operand" "")))
- (clobber (reg:DI 18))])]
+ (clobber (reg:HI 26))])]
"AVR_HAVE_MUL"
{
if (u16_operand (operands[2], SImode))
@@ -1391,23 +1391,14 @@ (define_expand "mulsi3"
})
(define_insn_and_split "*mulsi3"
- [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
- (mult:SI (match_operand:SI 1 "pseudo_register_operand" "r")
- (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
- (clobber (reg:DI 18))]
- "AVR_HAVE_MUL && !reload_completed"
- { gcc_unreachable(); }
- "&& 1"
- [(set (reg:SI 18)
- (match_dup 1))
- (set (reg:SI 22)
- (match_dup 2))
- (parallel [(set (reg:SI 22)
- (mult:SI (reg:SI 22)
- (reg:SI 18)))
- (clobber (reg:HI 26))])
- (set (match_dup 0)
- (reg:SI 22))]
+ [(set (match_operand:SI 0 "register_operand" "=RS22")
+ (mult:SI (match_operand:SI 1 "register_operand" "%0")
+ (match_operand:SI 2 "nonmemory_operand" "RS18")))
+ (clobber (reg:HI 26))]
+ "AVR_HAVE_MUL"
+ "%~call __mulsi3"
+ "&& !reload_completed"
+ [(clobber (const_int 0))]
{
if (u16_operand (operands[2], SImode))
{
@@ -1422,37 +1413,43 @@ (define_insn_and_split "*mulsi3"
emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
DONE;
}
- })
-;; "muluqisi3"
-;; "muluhisi3"
-(define_insn_and_split "mulu<mode>si3"
- [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
- (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
- (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
- (clobber (reg:DI 18))]
- "AVR_HAVE_MUL && !reload_completed"
+ FAIL;
+ }
+ [(set_attr "type" "xcall")
+ (set_attr "cc" "clobber")])
+
+(define_insn "muluhisi3"
+ [(set (match_operand:SI 0 "register_operand" "=RS22")
+ (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "x"))
+ (match_operand:SI 2 "register_operand" "RS18")))]
+ "AVR_HAVE_MUL"
+ "%~call __muluhisi3"
+ [(set_attr "type" "xcall")
+ (set_attr "cc" "clobber")])
+
+;; "*muluqisi3.split"
+;; "*muluhisi3.split"
+(define_insn_and_split "*mulu<mode>si3.split"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (mult:SI (zero_extend:SI (match_operand:QIHI 1 "register_operand" "r"))
+ (match_operand:SI 2 "nonmemory_operand" "rn")))
+ (clobber (reg:HI 26))]
+ "AVR_HAVE_MUL"
{ gcc_unreachable(); }
- "&& 1"
- [(set (reg:HI 26)
- (match_dup 1))
- (set (reg:SI 18)
- (match_dup 2))
- (set (reg:SI 22)
- (mult:SI (zero_extend:SI (reg:HI 26))
- (reg:SI 18)))
- (set (match_dup 0)
- (reg:SI 22))]
+ "&& !reload_completed"
+ [(set (match_dup 0)
+ (mult:SI (zero_extend:SI (match_dup 1))
+ (match_dup 2)))]
{
/* Do the QI -> HI extension explicitely before the multiplication. */
/* Do the HI -> SI extension implicitely and after the multiplication. */
if (QImode == <MODE>mode)
- operands[1] = gen_rtx_ZERO_EXTEND (HImode, operands[1]);
+ operands[1] = force_reg (HImode, gen_rtx_ZERO_EXTEND (HImode, operands[1]));
if (u16_operand (operands[2], SImode))
{
- operands[1] = force_reg (HImode, operands[1]);
operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
emit_insn (gen_umulhisi3 (operands[0], operands[1], operands[2]));
DONE;
@@ -1602,16 +1599,6 @@ (define_insn_and_split
}
})
-(define_insn "*mulsi3_call"
- [(set (reg:SI 22)
- (mult:SI (reg:SI 22)
- (reg:SI 18)))
- (clobber (reg:HI 26))]
- "AVR_HAVE_MUL"
- "%~call __mulsi3"
- [(set_attr "type" "xcall")
- (set_attr "cc" "clobber")])
-
(define_insn "*mulhisi3_call"
[(set (reg:SI 22)
(mult:SI (sign_extend:SI (reg:HI 18))
@@ -1639,15 +1626,6 @@ (define_insn "*usmulhisi3_call"
[(set_attr "type" "xcall")
(set_attr "cc" "clobber")])
-(define_insn "*muluhisi3_call"
- [(set (reg:SI 22)
- (mult:SI (zero_extend:SI (reg:HI 26))
- (reg:SI 18)))]
- "AVR_HAVE_MUL"
- "%~call __muluhisi3"
- [(set_attr "type" "xcall")
- (set_attr "cc" "clobber")])
-
(define_insn "*mulshisi3_call"
[(set (reg:SI 22)
(mult:SI (sign_extend:SI (reg:HI 26))
===================================================================
@@ -17,14 +17,74 @@
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.
-;; Register constraints
+;; 1-Register Register Constraints
(define_register_constraint "t" "R0_REG"
"Temporary register r0")
+(define_register_constraint "RQ18" "R18_REG"
+ "Register r18")
+
+(define_register_constraint "RQ19" "R19_REG"
+ "Register r19")
+
+(define_register_constraint "RQ20" "R20_REG"
+ "Register r20")
+
+(define_register_constraint "RQ21" "R21_REG"
+ "Register r21")
+
+(define_register_constraint "RQ22" "R22_REG"
+ "Register r22")
+
+(define_register_constraint "RQ23" "R23_REG"
+ "Register r23")
+
+(define_register_constraint "RQ24" "R24_REG"
+ "Register r24")
+
+(define_register_constraint "RQ25" "R25_REG"
+ "Register r25")
+
+;; 2-Register Register Constraints
+
+(define_register_constraint "RH18" "R18_R19_REGS"
+ "Register pair r18--r19")
+
+(define_register_constraint "RH20" "R20_R21_REGS"
+ "Register pair r20--r21")
+
+(define_register_constraint "RH22" "R22_R23_REGS"
+ "Register pair r22--r23")
+
+(define_register_constraint "RH24" "R24_R25_REGS"
+ "Register pair r24--r25")
+
+(define_register_constraint "x" "POINTER_X_REGS"
+ "Register pair X (r27:r26).")
+
+(define_register_constraint "y" "POINTER_Y_REGS"
+ "Register pair Y (r29:r28).")
+
+(define_register_constraint "z" "POINTER_Z_REGS"
+ "Register pair Z (r31:r30).")
+
+(define_register_constraint "q" "STACK_REG"
+ "Stack pointer register (SPH:SPL).")
+
+;; 4-Register Register Constraints
+
+(define_register_constraint "RS18" "R18_R21_REGS"
+ "Register r18--r21")
+
+(define_register_constraint "RS22" "R22_R25_REGS"
+ "Register r22--r25")
+
(define_register_constraint "b" "BASE_POINTER_REGS"
"Base pointer registers (r28--r31)")
+;; Even more Register Constraints
+
(define_register_constraint "e" "POINTER_REGS"
"Pointer registers (r26--r31)")
@@ -41,18 +101,6 @@ (define_register_constraint "l" "NO_LD_R
(define_register_constraint "a" "SIMPLE_LD_REGS"
"Registers from r16 to r23.")
-(define_register_constraint "x" "POINTER_X_REGS"
- "Register pair X (r27:r26).")
-
-(define_register_constraint "y" "POINTER_Y_REGS"
- "Register pair Y (r29:r28).")
-
-(define_register_constraint "z" "POINTER_Z_REGS"
- "Register pair Z (r31:r30).")
-
-(define_register_constraint "q" "STACK_REG"
- "Stack pointer register (SPH:SPL).")
-
(define_constraint "I"
"Integer constant in the range 0 @dots{} 63."
(and (match_code "const_int")
@@ -98,7 +146,7 @@ (define_constraint "G"
(and (match_code "const_double")
(match_test "op == CONST0_RTX (SFmode)")))
-(define_constraint "R"
+(define_constraint "C65"
"Integer constant in the range -6 @dots{} 5."
(and (match_code "const_int")
(match_test "ival >= -6 && ival <= 5")))
===================================================================
@@ -277,22 +277,6 @@ avr_option_override (void)
init_machine_status = avr_init_machine_status;
}
-/* return register class from register number. */
-
-static const enum reg_class reg_class_tab[]={
- GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
- GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
- GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
- GENERAL_REGS, /* r0 - r15 */
- LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,
- LD_REGS, /* r16 - 23 */
- ADDW_REGS,ADDW_REGS, /* r24,r25 */
- POINTER_X_REGS,POINTER_X_REGS, /* r26,27 */
- POINTER_Y_REGS,POINTER_Y_REGS, /* r28,r29 */
- POINTER_Z_REGS,POINTER_Z_REGS, /* r30,r31 */
- STACK_REG,STACK_REG /* SPL,SPH */
-};
-
/* Function to set up the backend function structure. */
static struct machine_function *
@@ -306,7 +290,30 @@ avr_init_machine_status (void)
enum reg_class
avr_regno_reg_class (int r)
{
- if (r <= 33)
+ static const enum reg_class
+ reg_class_tab[] =
+ {
+ /* r0 - r15 */
+ R0_REG, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
+ NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
+ NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
+ NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
+ /* r16 - r17 */
+ SIMPLE_LD_REGS, SIMPLE_LD_REGS,
+ /* r18 - r25 */
+ R18_REG, R19_REG, R20_REG, R21_REG,
+ R22_REG, R23_REG, R24_REG, R25_REG,
+ /* r26 - r27 */
+ POINTER_X_REGS, POINTER_X_REGS,
+ /* r28 - r29 */
+ POINTER_Y_REGS, POINTER_Y_REGS,
+ /* r30 - r31 */
+ POINTER_Z_REGS, POINTER_Z_REGS,
+ /* SPL, SPH */
+ STACK_REG, STACK_REG
+ };
+
+ if (r <= 33)
return reg_class_tab[r];
return ALL_REGS;
}
===================================================================
@@ -235,59 +235,102 @@ extern GTY(()) section *progmem_section;
enum reg_class {
NO_REGS,
- R0_REG, /* r0 */
- POINTER_X_REGS, /* r26 - r27 */
- POINTER_Y_REGS, /* r28 - r29 */
- POINTER_Z_REGS, /* r30 - r31 */
- STACK_REG, /* STACK */
- BASE_POINTER_REGS, /* r28 - r31 */
- POINTER_REGS, /* r26 - r31 */
- ADDW_REGS, /* r24 - r31 */
- SIMPLE_LD_REGS, /* r16 - r23 */
- LD_REGS, /* r16 - r31 */
- NO_LD_REGS, /* r0 - r15 */
- GENERAL_REGS, /* r0 - r31 */
- ALL_REGS, LIM_REG_CLASSES
+ R0_REG, /* r0 */
+ R18_REG, /* r18 */
+ R19_REG, /* r19 */
+ R20_REG, /* r20 */
+ R21_REG, /* r21 */
+ R22_REG, /* r22 */
+ R23_REG, /* r23 */
+ R24_REG, /* r24 */
+ R25_REG, /* r25 */
+ R18_R19_REGS, /* r18-r19 */
+ R20_R21_REGS, /* r20-r21 */
+ R22_R23_REGS, /* r22-r23 */
+ R24_R25_REGS, /* r24-r25 */
+ R18_R21_REGS, /* r18-r21 */
+ R22_R25_REGS, /* r22-r25 */
+ POINTER_X_REGS, /* r26 - r27 */
+ POINTER_Y_REGS, /* r28 - r29 */
+ POINTER_Z_REGS, /* r30 - r31 */
+ STACK_REG, /* STACK */
+ BASE_POINTER_REGS, /* r28 - r31 */
+ POINTER_REGS, /* r26 - r31 */
+ ADDW_REGS, /* r24 - r31 */
+ SIMPLE_LD_REGS, /* r16 - r23 */
+ LD_REGS, /* r16 - r31 */
+ NO_LD_REGS, /* r0 - r15 */
+ GENERAL_REGS, /* r0 - r31 */
+ ALL_REGS,
+ LIM_REG_CLASSES
};
#define N_REG_CLASSES (int)LIM_REG_CLASSES
-#define REG_CLASS_NAMES { \
- "NO_REGS", \
- "R0_REG", /* r0 */ \
- "POINTER_X_REGS", /* r26 - r27 */ \
- "POINTER_Y_REGS", /* r28 - r29 */ \
- "POINTER_Z_REGS", /* r30 - r31 */ \
- "STACK_REG", /* STACK */ \
- "BASE_POINTER_REGS", /* r28 - r31 */ \
- "POINTER_REGS", /* r26 - r31 */ \
- "ADDW_REGS", /* r24 - r31 */ \
- "SIMPLE_LD_REGS", /* r16 - r23 */ \
- "LD_REGS", /* r16 - r31 */ \
- "NO_LD_REGS", /* r0 - r15 */ \
- "GENERAL_REGS", /* r0 - r31 */ \
- "ALL_REGS" }
-
-#define REG_CLASS_CONTENTS { \
- {0x00000000,0x00000000}, /* NO_REGS */ \
- {0x00000001,0x00000000}, /* R0_REG */ \
- {3 << REG_X,0x00000000}, /* POINTER_X_REGS, r26 - r27 */ \
- {3 << REG_Y,0x00000000}, /* POINTER_Y_REGS, r28 - r29 */ \
- {3 << REG_Z,0x00000000}, /* POINTER_Z_REGS, r30 - r31 */ \
- {0x00000000,0x00000003}, /* STACK_REG, STACK */ \
- {(3 << REG_Y) | (3 << REG_Z), \
- 0x00000000}, /* BASE_POINTER_REGS, r28 - r31 */ \
- {(3 << REG_X) | (3 << REG_Y) | (3 << REG_Z), \
- 0x00000000}, /* POINTER_REGS, r26 - r31 */ \
- {(3 << REG_X) | (3 << REG_Y) | (3 << REG_Z) | (3 << REG_W), \
- 0x00000000}, /* ADDW_REGS, r24 - r31 */ \
- {0x00ff0000,0x00000000}, /* SIMPLE_LD_REGS r16 - r23 */ \
- {(3 << REG_X)|(3 << REG_Y)|(3 << REG_Z)|(3 << REG_W)|(0xff << 16), \
- 0x00000000}, /* LD_REGS, r16 - r31 */ \
- {0x0000ffff,0x00000000}, /* NO_LD_REGS r0 - r15 */ \
- {0xffffffff,0x00000000}, /* GENERAL_REGS, r0 - r31 */ \
- {0xffffffff,0x00000003} /* ALL_REGS */ \
+#define REG_CLASS_NAMES { \
+ "NO_REGS", \
+ "R0_REG", /* r0 */ \
+ "R18_REG", /* r18 */ \
+ "R19_REG", /* r19 */ \
+ "R20_REG", /* r20 */ \
+ "R21_REG", /* r21 */ \
+ "R22_REG", /* r22 */ \
+ "R23_REG", /* r23 */ \
+ "R24_REG", /* r24 */ \
+ "R25_REG", /* r25 */ \
+ "R18_R19_REGS", /* r18 - r19 */ \
+ "R20_R21_REGS", /* r20 - r21 */ \
+ "R22_R23_REGS", /* r22 - r23 */ \
+ "R24_R25_REGS", /* r24 - r25 */ \
+ "R18_R21_REGS", /* r18 - r21 */ \
+ "R22_R25_REGS", /* r22 - r25 */ \
+ "POINTER_X_REGS", /* r26 - r27 */ \
+ "POINTER_Y_REGS", /* r28 - r29 */ \
+ "POINTER_Z_REGS", /* r30 - r31 */ \
+ "STACK_REG", /* STACK */ \
+ "BASE_POINTER_REGS",/* r28 - r31 */ \
+ "POINTER_REGS", /* r26 - r31 */ \
+ "ADDW_REGS", /* r24 - r31 */ \
+ "SIMPLE_LD_REGS", /* r16 - r23 */ \
+ "LD_REGS", /* r16 - r31 */ \
+ "NO_LD_REGS", /* r0 - r15 */ \
+ "GENERAL_REGS", /* r0 - r31 */ \
+ "ALL_REGS" \
+}
+
+#define REG_CLASS_CONTENTS { \
+ { 0, 0 }, /* NO_REGS */ \
+ { 1 << 0, 0 }, /* R0_REG */ \
+ { 1 << 18, 0 }, /* r18 */ \
+ { 1 << 19, 0 }, /* r19 */ \
+ { 1 << 20, 0 }, /* r20 */ \
+ { 1 << 21, 0 }, /* r21 */ \
+ { 1 << 22, 0 }, /* r22 */ \
+ { 1 << 23, 0 }, /* r23 */ \
+ { 1 << 24, 0 }, /* r24 */ \
+ { 1 << 25, 0 }, /* r25 */ \
+ { 3 << 18, 0 }, /* r18 - r19 */ \
+ { 3 << 20, 0 }, /* r20 - r21 */ \
+ { 3 << 22, 0 }, /* r22 - r23 */ \
+ { 3 << 24, 0 }, /* r24 - r25 */ \
+ { 15 << 18, 0 }, /* r28 - r21 */ \
+ { 15 << 22, 0 }, /* r22 - r25 */ \
+ { 3 << REG_X, 0 }, /* POINTER_X_REGS, r26 - r27 */ \
+ { 3 << REG_Y, 0 }, /* POINTER_Y_REGS, r28 - r29 */ \
+ { 3 << REG_Z, 0 }, /* POINTER_Z_REGS, r30 - r31 */ \
+ { 0, 0x3 }, /* STACK_REG, Stack Pointer */ \
+ /* BASE_POINTER_REGS, r28-r31 */ \
+ { (3 << REG_Y) | (3 << REG_Z), 0 }, \
+ /* POINTER_REGS, r26 - r31 */ \
+ { (3 << REG_X) | (3 << REG_Y) | (3 << REG_Z), 0 }, \
+ /* ADDW_REGS, r24 - r31 */ \
+ { (3 << REG_X) | (3 << REG_Y) | (3 << REG_Z) | (3 << REG_W), 0 }, \
+ { 0x00ff0000, 0 }, /* SIMPLE_LD_REGS, r16 - r23 */ \
+ { 0xffff0000, 0 }, /* LD_REGS, r16 - r31 */ \
+ { 0x0000ffff, 0 }, /* NO_LD_REGS, r0 - r15 */ \
+ { 0xffffffff, 0 }, /* GENERAL_REGS, r0 - r31 */ \
+ { 0xffffffff, 0x3 } /* ALL_REGS */ \
}
#define REGNO_REG_CLASS(R) avr_regno_reg_class(R)