{
if (CONST_INT_P (operands[2]))
{
+ int reg0 = REGNO (operands[0]);
+ int reg1 = REGNO (operands[1]);
bool ldreg_p = test_hard_reg_class (LD_REGS, operands[0]);
int offs = INTVAL (operands[2]);
*plen = 0;
if (offs <= 3
- || (offs <= 6 && ! ldreg_p))
+ || (offs <= 5 && ! ldreg_p))
{
for (int i = 0; i < offs; ++i)
avr_asm_len ("lsl %0", operands, plen, 1);
"lsl %0" CR_TAB
"andi %0,0xe0", operands, plen, 3);
case 6:
- return avr_asm_len ("swap %0" CR_TAB
- "lsl %0" CR_TAB
- "lsl %0" CR_TAB
- "andi %0,0xc0", operands, plen, 4);
+ if (ldreg_p && reg0 == reg1)
+ return avr_asm_len ("swap %0" CR_TAB
+ "lsl %0" CR_TAB
+ "lsl %0" CR_TAB
+ "andi %0,0xc0", operands, plen, 4);
+ if (ldreg_p && reg0 != reg1 && AVR_HAVE_MUL)
+ return avr_asm_len ("ldi %0,1<<6" CR_TAB
+ "mul %0,%1" CR_TAB
+ "mov %0,r0" CR_TAB
+ "clr __zero_reg__", operands, plen, 4);
+ return reg0 != reg1
+ ? avr_asm_len ("clr %0" CR_TAB
+ "bst %1,0" CR_TAB
+ "bld %0,6" CR_TAB
+ "bst %1,1" CR_TAB
+ "bld %0,7", operands, plen, 5)
+ : avr_asm_len ("lsl %0" CR_TAB
+ "lsl %0" CR_TAB
+ "lsl %0" CR_TAB
+ "lsl %0" CR_TAB
+ "lsl %0" CR_TAB
+ "lsl %0", operands, plen, 6);
case 7:
return avr_asm_len ("bst %1,0" CR_TAB
"clr %0" CR_TAB
{
if (CONST_INT_P (operands[2]))
{
+ int reg0 = REGNO (operands[0]);
+ int reg1 = REGNO (operands[1]);
bool ldreg_p = test_hard_reg_class (LD_REGS, operands[0]);
int offs = INTVAL (operands[2]);
*plen = 0;
if (offs <= 3
- || (offs <= 6 && ! ldreg_p))
+ || (offs <= 5 && ! ldreg_p))
{
for (int i = 0; i < offs; ++i)
avr_asm_len ("lsr %0", operands, plen, 1);
"lsr %0" CR_TAB
"andi %0,0x7", operands, plen, 3);
case 6:
- return avr_asm_len ("swap %0" CR_TAB
- "lsr %0" CR_TAB
- "lsr %0" CR_TAB
- "andi %0,0x3", operands, plen, 4);
+ if (ldreg_p && reg0 == reg1)
+ return avr_asm_len ("swap %0" CR_TAB
+ "lsr %0" CR_TAB
+ "lsr %0" CR_TAB
+ "andi %0,0x3", operands, plen, 4);
+ if (ldreg_p && reg0 != reg1 && AVR_HAVE_MUL)
+ return avr_asm_len ("ldi %0,1<<2" CR_TAB
+ "mul %0,%1" CR_TAB
+ "mov %0,r1" CR_TAB
+ "clr __zero_reg__", operands, plen, 4);
+ return reg0 != reg1
+ ? avr_asm_len ("clr %0" CR_TAB
+ "bst %1,6" CR_TAB
+ "bld %0,0" CR_TAB
+ "bst %1,7" CR_TAB
+ "bld %0,1", operands, plen, 5)
+ : avr_asm_len ("lsr %0" CR_TAB
+ "lsr %0" CR_TAB
+ "lsr %0" CR_TAB
+ "lsr %0" CR_TAB
+ "lsr %0" CR_TAB
+ "lsr %0", operands, plen, 6);
case 7:
return avr_asm_len ("bst %1,7" CR_TAB
"clr %0" CR_TAB
{
if (val1 == 7)
*total = COSTS_N_INSNS (3);
- else if (val1 >= 0 && val1 <= 7)
+ else if (val1 == 6)
+ *total = COSTS_N_INSNS (5 - AVR_HAVE_MUL);
+ else if (val1 >= 0 && val1 <= 5)
*total = COSTS_N_INSNS (val1);
else
*total = COSTS_N_INSNS (1);
*total = COSTS_N_INSNS (4);
else if (val1 == 7)
*total = COSTS_N_INSNS (2);
- else if (val1 >= 0 && val1 <= 7)
+ else if (val1 >= 0 && val1 <= 5)
*total = COSTS_N_INSNS (val1);
else
*total = COSTS_N_INSNS (1);
{
if (val1 == 7)
*total = COSTS_N_INSNS (3);
- else if (val1 >= 0 && val1 <= 7)
+ else if (val1 == 6)
+ *total = COSTS_N_INSNS (5 - AVR_HAVE_MUL);
+ else if (val1 >= 0 && val1 <= 5)
*total = COSTS_N_INSNS (val1);
else
*total = COSTS_N_INSNS (1);
;; "*ashlqi3"
;; "*ashlqq3" "*ashluqq3"
(define_insn_and_split "*ashl<mode>3_split"
- [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,r ,!d,r,r")
- (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,r ,0 ,0,0")
- (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C07,n ,n,Qm")))]
+ [(set (match_operand:ALL1 0 "register_operand" "=r,r ,r ,r,r")
+ (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "0,0 ,r ,0,0")
+ (match_operand:QI 2 "nop_general_operand" "r,LPK,C07 C06,n,Qm")))]
""
"#"
"&& reload_completed"
(clobber (reg:CC REG_CC))])])
(define_insn "*ashl<mode>3"
- [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,r ,!d,r,r")
- (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,r ,0 ,0,0")
- (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C07,n ,n,Qm")))
+ [(set (match_operand:ALL1 0 "register_operand" "=r,r ,r ,r,r")
+ (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "0,0 ,r ,0,0")
+ (match_operand:QI 2 "nop_general_operand" "r,LPK,C07 C06,n,Qm")))
(clobber (reg:CC REG_CC))]
"reload_completed"
{
return ashlqi3_out (insn, operands, NULL);
}
- [(set_attr "length" "5,0,1,2,3,4,6,9")
+ [(set_attr "length" "9")
(set_attr "adjust_len" "ashlqi")])
;; "ashlhi3"
;; "*lshrqq3"
;; "*lshruqq3"
(define_insn_and_split "*lshr<mode>3_split"
- [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,r ,!d,r,r")
- (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,r ,0 ,0,0")
- (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C07,n ,n,Qm")))]
+ [(set (match_operand:ALL1 0 "register_operand" "=r,r ,r ,r,r")
+ (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0 ,r ,0,0")
+ (match_operand:QI 2 "nop_general_operand" "r,LPK,C07 C06,n,Qm")))]
""
"#"
"&& reload_completed"
(clobber (reg:CC REG_CC))])])
(define_insn "*lshr<mode>3"
- [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,r ,!d,r,r")
- (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,r ,0 ,0,0")
- (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C07,n ,n,Qm")))
+ [(set (match_operand:ALL1 0 "register_operand" "=r,r ,r ,r,r")
+ (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0 ,r ,0,0")
+ (match_operand:QI 2 "nop_general_operand" "r,LPK,C07 C06,n,Qm")))
(clobber (reg:CC REG_CC))]
"reload_completed"
{