@@ -32,6 +32,7 @@
;; m: Memory operand.
;;
;; The following constraints are intended for internal use only:
+;; Rmd0, Rms0, Rms1: Registers for MUL instruction operands.
;; Rsib: Jump address register suitable for sibling calls.
;; Rrio: The R30 and R31 I/O registers.
;; M: -255 to 0 (for converting ADD to SUB with suitable UBYTE OP2).
@@ -50,6 +51,19 @@ (define_register_constraint "Rsib" "SIB_REGS"
"@internal
A register suitable for an indirect sibcall.")
+(define_register_constraint "Rmd0" "MULDST_REGS"
+ "@internal
+ The multiply destination register."
+ "regno == MULDST_REGNUM")
+
+(define_register_constraint "Rms0" "MULSRC0_REGS"
+ "@internal
+ The multiply source 0 register.")
+
+(define_register_constraint "Rms1" "MULSRC1_REGS"
+ "@internal
+ The multiply source 1 register.")
+
(define_register_constraint "Rrio" "REGIO_REGS"
"@internal
The R30 and R31 I/O registers.")
@@ -83,7 +83,8 @@ (define_predicate "pru_muldst_operand"
else
return 0;
- return regno == MULDST_REGNUM || regno >= FIRST_PSEUDO_REGISTER;
+ return REGNO_REG_CLASS (regno) == MULDST_REGS
+ || regno >= FIRST_PSEUDO_REGISTER;
}
return 0;
})
@@ -102,7 +103,8 @@ (define_predicate "pru_mulsrc0_operand"
else
return 0;
- return regno == MULSRC0_REGNUM || regno >= FIRST_PSEUDO_REGISTER;
+ return REGNO_REG_CLASS (regno) == MULSRC0_REGS
+ || regno >= FIRST_PSEUDO_REGISTER;
}
return 0;
})
@@ -121,7 +123,8 @@ (define_predicate "pru_mulsrc1_operand"
else
return 0;
- return regno == MULSRC1_REGNUM || regno >= FIRST_PSEUDO_REGISTER;
+ return REGNO_REG_CLASS (regno) == MULSRC1_REGS
+ || regno >= FIRST_PSEUDO_REGISTER;
}
return 0;
})
@@ -216,6 +216,10 @@ enum reg_class
{
NO_REGS,
SIB_REGS,
+ LOOPCNTR_REGS,
+ MULDST_REGS,
+ MULSRC0_REGS,
+ MULSRC1_REGS,
REGIO_REGS,
GP_REGS,
ALL_REGS,
@@ -227,6 +231,10 @@ enum reg_class
#define REG_CLASS_NAMES \
{ "NO_REGS", \
"SIB_REGS", \
+ "LOOPCNTR_REGS", \
+ "MULDST_REGS", \
+ "MULSRC0_REGS", \
+ "MULSRC1_REGS", \
"REGIO_REGS", \
"GP_REGS", \
"ALL_REGS" }
@@ -237,6 +245,10 @@ enum reg_class
{ \
/* NO_REGS */ { 0, 0, 0, 0, 0}, \
/* SIB_REGS */ { 0xf, 0xff000000u, ~0u, 0xffffffu, 0},\
+ /* LOOPCNTR_REGS */ { 0, 0, 0, 0, 0xf}, \
+ /* MULDST_REGS */ { 0, 0, 0, 0x0000ff00u, 0}, \
+ /* MULSRC0_REGS */ { 0, 0, 0, 0x000f0000u, 0}, \
+ /* MULSRC1_REGS */ { 0, 0, 0, 0x00f00000u, 0}, \
/* REGIO_REGS */ { 0, 0, 0, 0xff000000u, 0}, \
/* GP_REGS */ { ~0u, ~0u, ~0u, ~0u, 0}, \
/* ALL_REGS */ { ~0u, ~0u, ~0u, ~0u, ~0u} \
@@ -245,11 +257,15 @@ enum reg_class
#define GP_REG_P(REGNO) ((unsigned)(REGNO) <= LAST_GP_REGNUM)
#define REGNO_REG_CLASS(REGNO) \
- ((REGNO) == R30_REGNUM ? REGIO_REGS \
+ ((REGNO) == MULDST_REGNUM ? MULDST_REGS \
+ : (REGNO) == MULSRC0_REGNUM ? MULSRC0_REGS \
+ : (REGNO) == MULSRC1_REGNUM ? MULSRC1_REGS \
+ : (REGNO) == R30_REGNUM ? REGIO_REGS \
: (REGNO) == R31_REGNUM ? REGIO_REGS \
: (REGNO) >= FIRST_ARG_REGNUM \
&& (REGNO) <= LAST_ARG_REGNUM ? SIB_REGS \
: (REGNO) == STATIC_CHAIN_REGNUM ? SIB_REGS \
+ : (REGNO) == LOOPCNTR_REGNUM ? LOOPCNTR_REGS \
: (REGNO) <= LAST_NONIO_GP_REGNUM ? GP_REGS \
: ALL_REGS)
@@ -1208,26 +1208,26 @@ (define_insn "one_cmpldi2"
[(set_attr "type" "alu")
(set_attr "length" "8")])
-;; Multiply instruction. The nop is required to ensure that source
+;; Multiply instruction. The nop is required to ensure that Rmd0 and Rms0
;; registers are sampled and multiplication is executed on those values.
;; Only after that one cycle can xin obtain the result.
(define_insn "mulsi3"
- [(set (match_operand:SI 0 "pru_muldst_operand" "={r26}")
- (mult:SI (match_operand:SI 1 "pru_mulsrc0_operand" "%{r28}")
- (match_operand:SI 2 "pru_mulsrc1_operand" "{r29}")))]
+ [(set (match_operand:SI 0 "pru_muldst_operand" "=Rmd0")
+ (mult:SI (match_operand:SI 1 "pru_mulsrc0_operand" "%Rms0")
+ (match_operand:SI 2 "pru_mulsrc1_operand" "Rms1")))]
"TARGET_OPT_MUL"
"nop\;xin\\t0, %0, 4"
[(set_attr "type" "alu")
(set_attr "length" "8")])
(define_insn "umulsidi3"
- [(set (match_operand:DI 0 "pru_muldst_operand" "={r26}")
+ [(set (match_operand:DI 0 "pru_muldst_operand" "=Rmd0")
(mult:DI
(zero_extend:DI
- (match_operand:SI 1 "pru_mulsrc0_operand" "%{r28}"))
+ (match_operand:SI 1 "pru_mulsrc0_operand" "%Rms0"))
(zero_extend:DI
- (match_operand:SI 2 "pru_mulsrc1_operand" "{r29}"))))]
+ (match_operand:SI 2 "pru_mulsrc1_operand" "Rms1"))))]
"TARGET_OPT_MUL"
"nop\;xin\\t0, %0, 8"
[(set_attr "type" "alu")