@@ -6715,7 +6715,7 @@ ashlqi3_out (rtx_insn *insn, rtx operands[], int *len)
fatal_insn ("internal compiler error. Incorrect shift:", insn);
out_shift_with_cnt ("lsl %0",
- insn, operands, len, 1);
+ insn, operands, len, 1);
return "";
}
@@ -6728,8 +6728,8 @@ ashlhi3_out (rtx_insn *insn, rtx operands[], int *len)
if (CONST_INT_P (operands[2]))
{
int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL
- && XVECLEN (PATTERN (insn), 0) == 3
- && REG_P (operands[3]));
+ && XVECLEN (PATTERN (insn), 0) == 3
+ && REG_P (operands[3]));
int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
int k;
int *t = len;
@@ -6826,8 +6826,9 @@ ashlhi3_out (rtx_insn *insn, rtx operands[], int *len)
"ror %A0");
case 8:
- return *len = 2, ("mov %B0,%A1" CR_TAB
- "clr %A0");
+ *len = 2;
+ return ("mov %B0,%A1" CR_TAB
+ "clr %A0");
case 9:
*len = 3;
@@ -6974,7 +6975,7 @@ ashlhi3_out (rtx_insn *insn, rtx operands[], int *len)
len = t;
}
out_shift_with_cnt ("lsl %A0" CR_TAB
- "rol %B0", insn, operands, len, 2);
+ "rol %B0", insn, operands, len, 2);
return "";
}
@@ -6990,54 +6991,126 @@ avr_out_ashlpsi3 (rtx_insn *insn, rtx *op, int *plen)
if (CONST_INT_P (op[2]))
{
switch (INTVAL (op[2]))
- {
- default:
- if (INTVAL (op[2]) < 24)
- break;
+ {
+ default:
+ if (INTVAL (op[2]) < 24)
+ break;
- return avr_asm_len ("clr %A0" CR_TAB
- "clr %B0" CR_TAB
- "clr %C0", op, plen, 3);
+ return avr_asm_len ("clr %A0" CR_TAB
+ "clr %B0" CR_TAB
+ "clr %C0", op, plen, 3);
- case 8:
- {
- int reg0 = REGNO (op[0]);
- int reg1 = REGNO (op[1]);
-
- if (reg0 >= reg1)
- return avr_asm_len ("mov %C0,%B1" CR_TAB
- "mov %B0,%A1" CR_TAB
- "clr %A0", op, plen, 3);
- else
- return avr_asm_len ("clr %A0" CR_TAB
- "mov %B0,%A1" CR_TAB
- "mov %C0,%B1", op, plen, 3);
- }
+ case 8:
+ if (REGNO (op[0]) >= REGNO (op[1]))
+ return avr_asm_len ("mov %C0,%B1" CR_TAB
+ "mov %B0,%A1" CR_TAB
+ "clr %A0", op, plen, 3);
+ else
+ return avr_asm_len ("clr %A0" CR_TAB
+ "mov %B0,%A1" CR_TAB
+ "mov %C0,%B1", op, plen, 3);
- case 16:
- {
- int reg0 = REGNO (op[0]);
- int reg1 = REGNO (op[1]);
+ case 9:
+ if (REGNO (op[0]) >= REGNO (op[1]))
+ return avr_asm_len ("mov %C0,%B1" CR_TAB
+ "mov %B0,%A1" CR_TAB
+ "lsl %B0" CR_TAB
+ "rol %C0" CR_TAB
+ "clr %A0", op, plen, 5);
+ else
+ return avr_asm_len ("clr %A0" CR_TAB
+ "mov %B0,%A1" CR_TAB
+ "mov %C0,%B1" CR_TAB
+ "lsl %B0" CR_TAB
+ "rol %C0", op, plen, 5);
- if (reg0 + 2 != reg1)
- avr_asm_len ("mov %C0,%A0", op, plen, 1);
+ case 16:
+ if (REGNO (op[0]) + 2 != REGNO (op[1]))
+ avr_asm_len ("mov %C0,%A0", op, plen, 1);
+ return avr_asm_len ("clr %B0" CR_TAB
+ "clr %A0", op, plen, 2);
+
+ case 17:
+ if (REGNO (op[0]) + 2 != REGNO (op[1]))
+ avr_asm_len ("mov %C0,%A0", op, plen, 1);
+ return avr_asm_len ("lsl %C0" CR_TAB
+ "clr %B0" CR_TAB
+ "clr %A0", op, plen, 3);
+
+ case 18:
+ if (REGNO (op[0]) + 2 != REGNO (op[1]))
+ avr_asm_len ("mov %C0,%A0", op, plen, 1);
+ return avr_asm_len ("lsl %C0" CR_TAB
+ "lsl %C0" CR_TAB
+ "clr %B0" CR_TAB
+ "clr %A0", op, plen, 4);
+
+ case 19:
+ if (REGNO (op[0]) + 2 != REGNO (op[1]))
+ avr_asm_len ("mov %C0,%A0", op, plen, 1);
+ return avr_asm_len ("lsl %C0" CR_TAB
+ "lsl %C0" CR_TAB
+ "lsl %C0" CR_TAB
+ "clr %B0" CR_TAB
+ "clr %A0", op, plen, 5);
+
+ case 20:
+ if (!optimize_size)
+ {
+ if (REGNO (op[0]) + 2 != REGNO (op[1]))
+ avr_asm_len ("mov %C0,%A0", op, plen, 1);
+ return avr_asm_len ("lsl %C0" CR_TAB
+ "lsl %C0" CR_TAB
+ "lsl %C0" CR_TAB
+ "lsl %C0" CR_TAB
+ "clr %B0" CR_TAB
+ "clr %A0", op, plen, 6);
+ }
+ break;
- return avr_asm_len ("clr %B0" CR_TAB
- "clr %A0", op, plen, 2);
- }
+ case 21:
+ if (!optimize_size)
+ {
+ if (REGNO (op[0]) + 2 != REGNO (op[1]))
+ avr_asm_len ("mov %C0,%A0", op, plen, 1);
+ return avr_asm_len ("lsl %C0" CR_TAB
+ "lsl %C0" CR_TAB
+ "lsl %C0" CR_TAB
+ "lsl %C0" CR_TAB
+ "lsl %C0" CR_TAB
+ "clr %B0" CR_TAB
+ "clr %A0", op, plen, 7);
+ }
+ break;
- case 23:
- return avr_asm_len ("clr %C0" CR_TAB
- "lsr %A0" CR_TAB
- "ror %C0" CR_TAB
- "clr %B0" CR_TAB
- "clr %A0", op, plen, 5);
- }
+ case 22:
+ if (!optimize_size)
+ {
+ if (REGNO (op[0]) + 2 != REGNO (op[1]))
+ avr_asm_len ("mov %C0,%A0", op, plen, 1);
+ return avr_asm_len ("lsl %C0" CR_TAB
+ "lsl %C0" CR_TAB
+ "lsl %C0" CR_TAB
+ "lsl %C0" CR_TAB
+ "lsl %C0" CR_TAB
+ "lsl %C0" CR_TAB
+ "clr %B0" CR_TAB
+ "clr %A0", op, plen, 8);
+ }
+ break;
+
+ case 23:
+ return avr_asm_len ("clr %C0" CR_TAB
+ "lsr %A0" CR_TAB
+ "ror %C0" CR_TAB
+ "clr %B0" CR_TAB
+ "clr %A0", op, plen, 5);
+ }
}
out_shift_with_cnt ("lsl %A0" CR_TAB
- "rol %B0" CR_TAB
- "rol %C0", insn, op, plen, 3);
+ "rol %B0" CR_TAB
+ "rol %C0", insn, op, plen, 3);
return "";
}
@@ -7072,39 +7145,56 @@ ashlsi3_out (rtx_insn *insn, rtx operands[], int *len)
"clr %A0");
case 8:
- {
- int reg0 = true_regnum (operands[0]);
- int reg1 = true_regnum (operands[1]);
- *len = 4;
- if (reg0 >= reg1)
- return ("mov %D0,%C1" CR_TAB
- "mov %C0,%B1" CR_TAB
- "mov %B0,%A1" CR_TAB
- "clr %A0");
- else
- return ("clr %A0" CR_TAB
- "mov %B0,%A1" CR_TAB
- "mov %C0,%B1" CR_TAB
- "mov %D0,%C1");
- }
+ *len = 4;
+ if (true_regnum (operands[0]) >= true_regnum (operands[1]))
+ return ("mov %D0,%C1" CR_TAB
+ "mov %C0,%B1" CR_TAB
+ "mov %B0,%A1" CR_TAB
+ "clr %A0");
+ else
+ return ("clr %A0" CR_TAB
+ "mov %B0,%A1" CR_TAB
+ "mov %C0,%B1" CR_TAB
+ "mov %D0,%C1");
+
+ case 9:
+ *len = 7;
+ if (true_regnum (operands[0]) >= true_regnum (operands[1]))
+ return ("mov %D0,%C1" CR_TAB
+ "mov %C0,%B1" CR_TAB
+ "mov %B0,%A1" CR_TAB
+ "clr %A0" CR_TAB
+ "lsl %B0" CR_TAB
+ "rol %C0" CR_TAB
+ "rol %D0");
+ else
+ return ("clr %A0" CR_TAB
+ "mov %B0,%A1" CR_TAB
+ "mov %C0,%B1" CR_TAB
+ "mov %D0,%C1" CR_TAB
+ "lsl %B0" CR_TAB
+ "rol %C0" CR_TAB
+ "rol %D0");
case 16:
- {
- int reg0 = true_regnum (operands[0]);
- int reg1 = true_regnum (operands[1]);
- if (reg0 + 2 == reg1)
- return *len = 2, ("clr %B0" CR_TAB
- "clr %A0");
- if (AVR_HAVE_MOVW)
- return *len = 3, ("movw %C0,%A1" CR_TAB
- "clr %B0" CR_TAB
- "clr %A0");
- else
- return *len = 4, ("mov %C0,%A1" CR_TAB
- "mov %D0,%B1" CR_TAB
- "clr %B0" CR_TAB
- "clr %A0");
- }
+ if (true_regnum (operands[0]) + 2 == true_regnum (operands[1]))
+ {
+ *len = 2;
+ return ("clr %B0" CR_TAB
+ "clr %A0");
+ }
+ if (AVR_HAVE_MOVW)
+ {
+ *len = 3;
+ return ("movw %C0,%A1" CR_TAB
+ "clr %B0" CR_TAB
+ "clr %A0");
+ }
+ *len = 4;
+ return ("mov %C0,%A1" CR_TAB
+ "mov %D0,%B1" CR_TAB
+ "clr %B0" CR_TAB
+ "clr %A0");
case 24:
*len = 4;
@@ -7113,6 +7203,74 @@ ashlsi3_out (rtx_insn *insn, rtx operands[], int *len)
"clr %B0" CR_TAB
"clr %A0");
+ case 25:
+ *len = 5;
+ return ("mov %D0,%A1" CR_TAB
+ "lsl %D0" CR_TAB
+ "clr %C0" CR_TAB
+ "clr %B0" CR_TAB
+ "clr %A0");
+
+ case 26:
+ *len = 6;
+ return ("mov %D0,%A1" CR_TAB
+ "lsl %D0" CR_TAB
+ "lsl %D0" CR_TAB
+ "clr %C0" CR_TAB
+ "clr %B0" CR_TAB
+ "clr %A0");
+
+ case 27:
+ *len = 7;
+ return ("mov %D0,%A1" CR_TAB
+ "lsl %D0" CR_TAB
+ "lsl %D0" CR_TAB
+ "lsl %D0" CR_TAB
+ "clr %C0" CR_TAB
+ "clr %B0" CR_TAB
+ "clr %A0");
+
+ case 28:
+ if (optimize_size)
+ break;
+ *len = 8;
+ return ("mov %D0,%A1" CR_TAB
+ "lsl %D0" CR_TAB
+ "lsl %D0" CR_TAB
+ "lsl %D0" CR_TAB
+ "lsl %D0" CR_TAB
+ "clr %C0" CR_TAB
+ "clr %B0" CR_TAB
+ "clr %A0");
+
+ case 29:
+ if (optimize_size)
+ break;
+ *len = 9;
+ return ("mov %D0,%A1" CR_TAB
+ "lsl %D0" CR_TAB
+ "lsl %D0" CR_TAB
+ "lsl %D0" CR_TAB
+ "lsl %D0" CR_TAB
+ "lsl %D0" CR_TAB
+ "clr %C0" CR_TAB
+ "clr %B0" CR_TAB
+ "clr %A0");
+
+ case 30:
+ if (optimize_size)
+ break;
+ *len = 10;
+ return ("mov %D0,%A1" CR_TAB
+ "lsl %D0" CR_TAB
+ "lsl %D0" CR_TAB
+ "lsl %D0" CR_TAB
+ "lsl %D0" CR_TAB
+ "lsl %D0" CR_TAB
+ "clr %C0" CR_TAB
+ "clr %B0" CR_TAB
+ "clr %A0");
+
case 31:
*len = 6;
return ("clr %D0" CR_TAB
@@ -7125,9 +7283,9 @@ ashlsi3_out (rtx_insn *insn, rtx operands[], int *len)
len = t;
}
out_shift_with_cnt ("lsl %A0" CR_TAB
- "rol %B0" CR_TAB
- "rol %C0" CR_TAB
- "rol %D0", insn, operands, len, 4);
+ "rol %B0" CR_TAB
+ "rol %C0" CR_TAB
+ "rol %D0", insn, operands, len, 4);
return "";
}
@@ -7168,6 +7326,8 @@ ashrqi3_out (rtx_insn *insn, rtx operands[], int *len)
"asr %0");
case 5:
+ if (optimize_size)
+ break;
*len = 5;
return ("asr %0" CR_TAB
"asr %0" CR_TAB
@@ -7198,7 +7358,7 @@ ashrqi3_out (rtx_insn *insn, rtx operands[], int *len)
fatal_insn ("internal compiler error. Incorrect shift:", insn);
out_shift_with_cnt ("asr %0",
- insn, operands, len, 1);
+ insn, operands, len, 1);
return "";
}
@@ -7211,8 +7371,8 @@ ashrhi3_out (rtx_insn *insn, rtx operands[], int *len)
if (CONST_INT_P (operands[2]))
{
int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL
- && XVECLEN (PATTERN (insn), 0) == 3
- && REG_P (operands[3]));
+ && XVECLEN (PATTERN (insn), 0) == 3
+ && REG_P (operands[3]));
int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
int k;
int *t = len;
@@ -7248,25 +7408,23 @@ ashrhi3_out (rtx_insn *insn, rtx operands[], int *len)
"sbc %B0,%B0");
case 8:
- {
- int reg0 = true_regnum (operands[0]);
- int reg1 = true_regnum (operands[1]);
-
- if (reg0 == reg1)
- return *len = 3, ("mov %A0,%B0" CR_TAB
- "lsl %B0" CR_TAB
- "sbc %B0,%B0");
- else
- return *len = 4, ("mov %A0,%B1" CR_TAB
- "clr %B0" CR_TAB
- "sbrc %A0,7" CR_TAB
- "dec %B0");
- }
+ if (true_regnum (operands[0]) == true_regnum (operands[1]))
+ {
+ *len = 3;
+ return ("mov %A0,%B0" CR_TAB
+ "lsl %B0" CR_TAB
+ "sbc %B0,%B0");
+ }
+ *len = 4;
+ return ("mov %A0,%B1" CR_TAB
+ "clr %B0" CR_TAB
+ "sbrc %A0,7" CR_TAB
+ "dec %B0");
case 9:
*len = 4;
return ("mov %A0,%B0" CR_TAB
- "lsl %B0" CR_TAB
+ "lsl %B0" CR_TAB
"sbc %B0,%B0" CR_TAB
"asr %A0");
@@ -7356,14 +7514,15 @@ ashrhi3_out (rtx_insn *insn, rtx operands[], int *len)
/* fall through */
case 15:
- return *len = 3, ("lsl %B0" CR_TAB
- "sbc %A0,%A0" CR_TAB
- "mov %B0,%A0");
+ *len = 3;
+ return ("lsl %B0" CR_TAB
+ "sbc %A0,%A0" CR_TAB
+ "mov %B0,%A0");
}
len = t;
}
out_shift_with_cnt ("asr %B0" CR_TAB
- "ror %A0", insn, operands, len, 2);
+ "ror %A0", insn, operands, len, 2);
return "";
}
@@ -7379,50 +7538,58 @@ avr_out_ashrpsi3 (rtx_insn *insn, rtx *op, int *plen)
if (CONST_INT_P (op[2]))
{
if (plen)
- *plen = 0;
+ *plen = 0;
switch (INTVAL (op[2]))
- {
- case 8:
- if (dest <= src)
- return avr_asm_len ("mov %A0,%B1" CR_TAB
- "mov %B0,%C1" CR_TAB
- "clr %C0" CR_TAB
- "sbrc %B0,7" CR_TAB
- "dec %C0", op, plen, 5);
- else
- return avr_asm_len ("clr %C0" CR_TAB
- "sbrc %C1,7" CR_TAB
- "dec %C0" CR_TAB
- "mov %B0,%C1" CR_TAB
- "mov %A0,%B1", op, plen, 5);
-
- case 16:
- if (dest != src + 2)
- avr_asm_len ("mov %A0,%C1", op, plen, 1);
+ {
+ case 8:
+ if (dest <= src)
+ return avr_asm_len ("mov %A0,%B1" CR_TAB
+ "mov %B0,%C1" CR_TAB
+ "clr %C0" CR_TAB
+ "sbrc %B0,7" CR_TAB
+ "dec %C0", op, plen, 5);
+ else
+ return avr_asm_len ("clr %C0" CR_TAB
+ "sbrc %C1,7" CR_TAB
+ "dec %C0" CR_TAB
+ "mov %B0,%C1" CR_TAB
+ "mov %A0,%B1", op, plen, 5);
- return avr_asm_len ("clr %B0" CR_TAB
- "sbrc %A0,7" CR_TAB
- "com %B0" CR_TAB
- "mov %C0,%B0", op, plen, 4);
+ case 16:
+ if (dest != src + 2)
+ avr_asm_len ("mov %A0,%C1", op, plen, 1);
+ return avr_asm_len ("clr %B0" CR_TAB
+ "sbrc %A0,7" CR_TAB
+ "com %B0" CR_TAB
+ "mov %C0,%B0", op, plen, 4);
+
+ case 17:
+ if (dest != src + 2)
+ avr_asm_len ("mov %A0,%C1", op, plen, 1);
+ return avr_asm_len ("clr %B0" CR_TAB
+ "sbrc %A0,7" CR_TAB
+ "com %B0" CR_TAB
+ "mov %C0,%B0" CR_TAB
+ "asr %A0", op, plen, 5);
- default:
- if (INTVAL (op[2]) < 24)
- break;
+ default:
+ if (INTVAL (op[2]) < 24)
+ break;
- /* fall through */
+ /* fall through */
- case 23:
- return avr_asm_len ("lsl %C0" CR_TAB
- "sbc %A0,%A0" CR_TAB
- "mov %B0,%A0" CR_TAB
- "mov %C0,%A0", op, plen, 4);
- } /* switch */
+ case 23:
+ return avr_asm_len ("lsl %C0" CR_TAB
+ "sbc %A0,%A0" CR_TAB
+ "mov %B0,%A0" CR_TAB
+ "mov %C0,%A0", op, plen, 4);
+ } /* switch */
}
out_shift_with_cnt ("asr %C0" CR_TAB
- "ror %B0" CR_TAB
- "ror %A0", insn, op, plen, 3);
+ "ror %B0" CR_TAB
+ "ror %A0", insn, op, plen, 3);
return "";
}
@@ -7443,58 +7610,99 @@ ashrsi3_out (rtx_insn *insn, rtx operands[], int *len)
switch (INTVAL (operands[2]))
{
case 8:
- {
- int reg0 = true_regnum (operands[0]);
- int reg1 = true_regnum (operands[1]);
- *len=6;
- if (reg0 <= reg1)
- return ("mov %A0,%B1" CR_TAB
- "mov %B0,%C1" CR_TAB
- "mov %C0,%D1" CR_TAB
- "clr %D0" CR_TAB
- "sbrc %C0,7" CR_TAB
- "dec %D0");
- else
- return ("clr %D0" CR_TAB
- "sbrc %D1,7" CR_TAB
- "dec %D0" CR_TAB
- "mov %C0,%D1" CR_TAB
- "mov %B0,%C1" CR_TAB
- "mov %A0,%B1");
- }
+ *len = 6;
+ if (true_regnum (operands[0]) <= true_regnum (operands[1]))
+ return ("mov %A0,%B1" CR_TAB
+ "mov %B0,%C1" CR_TAB
+ "mov %C0,%D1" CR_TAB
+ "clr %D0" CR_TAB
+ "sbrc %C0,7" CR_TAB
+ "dec %D0");
+ return ("clr %D0" CR_TAB
+ "sbrc %D1,7" CR_TAB
+ "dec %D0" CR_TAB
+ "mov %C0,%D1" CR_TAB
+ "mov %B0,%C1" CR_TAB
+ "mov %A0,%B1");
case 16:
- {
- int reg0 = true_regnum (operands[0]);
- int reg1 = true_regnum (operands[1]);
-
- if (reg0 == reg1 + 2)
- return *len = 4, ("clr %D0" CR_TAB
- "sbrc %B0,7" CR_TAB
- "com %D0" CR_TAB
- "mov %C0,%D0");
- if (AVR_HAVE_MOVW)
- return *len = 5, ("movw %A0,%C1" CR_TAB
- "clr %D0" CR_TAB
- "sbrc %B0,7" CR_TAB
- "com %D0" CR_TAB
- "mov %C0,%D0");
- else
- return *len = 6, ("mov %B0,%D1" CR_TAB
- "mov %A0,%C1" CR_TAB
- "clr %D0" CR_TAB
- "sbrc %B0,7" CR_TAB
- "com %D0" CR_TAB
- "mov %C0,%D0");
- }
+ if (true_regnum (operands[0]) == true_regnum (operands[1]) + 2)
+ {
+ *len = 4;
+ return ("clr %D0" CR_TAB
+ "sbrc %B0,7" CR_TAB
+ "com %D0" CR_TAB
+ "mov %C0,%D0");
+ }
+ if (AVR_HAVE_MOVW)
+ {
+ *len = 5;
+ return ("movw %A0,%C1" CR_TAB
+ "clr %D0" CR_TAB
+ "sbrc %B0,7" CR_TAB
+ "com %D0" CR_TAB
+ "mov %C0,%D0");
+ }
+ *len = 6;
+ return ("mov %B0,%D1" CR_TAB
+ "mov %A0,%C1" CR_TAB
+ "clr %D0" CR_TAB
+ "sbrc %B0,7" CR_TAB
+ "com %D0" CR_TAB
+ "mov %C0,%D0");
+
+ case 17:
+ if (true_regnum (operands[0]) == true_regnum (operands[1]) + 2)
+ {
+ *len = 6;
+ return ("clr %D0" CR_TAB
+ "sbrc %B0,7" CR_TAB
+ "com %D0" CR_TAB
+ "mov %C0,%D0" CR_TAB
+ "asr %B0" CR_TAB
+ "ror %A0");
+ }
+ if (AVR_HAVE_MOVW)
+ {
+ *len = 7;
+ return ("movw %A0,%C1" CR_TAB
+ "clr %D0" CR_TAB
+ "sbrc %B0,7" CR_TAB
+ "com %D0" CR_TAB
+ "mov %C0,%D0" CR_TAB
+ "asr %B0" CR_TAB
+ "ror %A0");
+ }
+ if (optimize_size)
+ break;
+ *len = 8;
+ return ("mov %B0,%D1" CR_TAB
+ "mov %A0,%C1" CR_TAB
+ "clr %D0" CR_TAB
+ "sbrc %B0,7" CR_TAB
+ "com %D0" CR_TAB
+ "mov %C0,%D0" CR_TAB
+ "asr %B0" CR_TAB
+ "ror %A0");
case 24:
- return *len = 6, ("mov %A0,%D1" CR_TAB
- "clr %D0" CR_TAB
- "sbrc %A0,7" CR_TAB
- "com %D0" CR_TAB
- "mov %B0,%D0" CR_TAB
- "mov %C0,%D0");
+ *len = 6;
+ return ("mov %A0,%D1" CR_TAB
+ "clr %D0" CR_TAB
+ "sbrc %A0,7" CR_TAB
+ "com %D0" CR_TAB
+ "mov %B0,%D0" CR_TAB
+ "mov %C0,%D0");
+
+ case 25:
+ *len = 7;
+ return ("mov %A0,%D1" CR_TAB
+ "clr %D0" CR_TAB
+ "sbrc %A0,7" CR_TAB
+ "com %D0" CR_TAB
+ "mov %B0,%D0" CR_TAB
+ "mov %C0,%D0" CR_TAB
+ "asr %A0");
default:
if (INTVAL (operands[2]) < 32)
@@ -7504,23 +7712,26 @@ ashrsi3_out (rtx_insn *insn, rtx operands[], int *len)
case 31:
if (AVR_HAVE_MOVW)
- return *len = 4, ("lsl %D0" CR_TAB
- "sbc %A0,%A0" CR_TAB
- "mov %B0,%A0" CR_TAB
- "movw %C0,%A0");
- else
- return *len = 5, ("lsl %D0" CR_TAB
- "sbc %A0,%A0" CR_TAB
- "mov %B0,%A0" CR_TAB
- "mov %C0,%A0" CR_TAB
- "mov %D0,%A0");
+ {
+ *len = 4;
+ return ("lsl %D0" CR_TAB
+ "sbc %A0,%A0" CR_TAB
+ "mov %B0,%A0" CR_TAB
+ "movw %C0,%A0");
+ }
+ *len = 5;
+ return ("lsl %D0" CR_TAB
+ "sbc %A0,%A0" CR_TAB
+ "mov %B0,%A0" CR_TAB
+ "mov %C0,%A0" CR_TAB
+ "mov %D0,%A0");
}
len = t;
}
out_shift_with_cnt ("asr %D0" CR_TAB
- "ror %C0" CR_TAB
- "ror %B0" CR_TAB
- "ror %A0", insn, operands, len, 4);
+ "ror %C0" CR_TAB
+ "ror %B0" CR_TAB
+ "ror %A0", insn, operands, len, 4);
return "";
}
@@ -7562,7 +7773,7 @@ lshrqi3_out (rtx_insn *insn, rtx operands[], int *len)
case 4:
if (test_hard_reg_class (LD_REGS, operands[0]))
{
- *len=2;
+ *len = 2;
return ("swap %0" CR_TAB
"andi %0,0x0f");
}
@@ -7615,7 +7826,7 @@ lshrqi3_out (rtx_insn *insn, rtx operands[], int *len)
fatal_insn ("internal compiler error. Incorrect shift:", insn);
out_shift_with_cnt ("lsr %0",
- insn, operands, len, 1);
+ insn, operands, len, 1);
return "";
}
@@ -7627,8 +7838,8 @@ lshrhi3_out (rtx_insn *insn, rtx operands[], int *len)
if (CONST_INT_P (operands[2]))
{
int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL
- && XVECLEN (PATTERN (insn), 0) == 3
- && REG_P (operands[3]));
+ && XVECLEN (PATTERN (insn), 0) == 3
+ && REG_P (operands[3]));
int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
int k;
int *t = len;
@@ -7725,8 +7936,9 @@ lshrhi3_out (rtx_insn *insn, rtx operands[], int *len)
"neg %B0");
case 8:
- return *len = 2, ("mov %A0,%B1" CR_TAB
- "clr %B0");
+ *len = 2;
+ return ("mov %A0,%B1" CR_TAB
+ "clr %B0");
case 9:
*len = 3;
@@ -7873,7 +8085,7 @@ lshrhi3_out (rtx_insn *insn, rtx operands[], int *len)
len = t;
}
out_shift_with_cnt ("lsr %B0" CR_TAB
- "ror %A0", insn, operands, len, 2);
+ "ror %A0", insn, operands, len, 2);
return "";
}
@@ -7889,45 +8101,121 @@ avr_out_lshrpsi3 (rtx_insn *insn, rtx *op, int *plen)
if (CONST_INT_P (op[2]))
{
if (plen)
- *plen = 0;
+ *plen = 0;
switch (INTVAL (op[2]))
- {
- case 8:
- if (dest <= src)
- return avr_asm_len ("mov %A0,%B1" CR_TAB
- "mov %B0,%C1" CR_TAB
- "clr %C0", op, plen, 3);
- else
- return avr_asm_len ("clr %C0" CR_TAB
- "mov %B0,%C1" CR_TAB
- "mov %A0,%B1", op, plen, 3);
+ {
+ case 8:
+ if (dest <= src)
+ return avr_asm_len ("mov %A0,%B1" CR_TAB
+ "mov %B0,%C1" CR_TAB
+ "clr %C0", op, plen, 3);
+ else
+ return avr_asm_len ("clr %C0" CR_TAB
+ "mov %B0,%C1" CR_TAB
+ "mov %A0,%B1", op, plen, 3);
- case 16:
- if (dest != src + 2)
- avr_asm_len ("mov %A0,%C1", op, plen, 1);
+ case 9:
+ if (dest <= src)
+ return avr_asm_len ("mov %A0,%B1" CR_TAB
+ "mov %B0,%C1" CR_TAB
+ "clr %C0" CR_TAB
+ "lsr %B0" CR_TAB
+ "ror %A0", op, plen, 5);
+ else
+ return avr_asm_len ("clr %C0" CR_TAB
+ "mov %B0,%C1" CR_TAB
+ "mov %A0,%B1" CR_TAB
+ "lsr %B0" CR_TAB
+ "ror %A0", op, plen, 5);
- return avr_asm_len ("clr %B0" CR_TAB
- "clr %C0", op, plen, 2);
+ case 16:
+ if (dest != src + 2)
+ avr_asm_len ("mov %A0,%C1", op, plen, 1);
+ return avr_asm_len ("clr %B0" CR_TAB
+ "clr %C0", op, plen, 2);
+
+ case 17:
+ if (dest != src + 2)
+ avr_asm_len ("mov %A0,%C1", op, plen, 1);
+ return avr_asm_len ("clr %B0" CR_TAB
+ "clr %C0" CR_TAB
+ "lsr %A0", op, plen, 3);
+
+ case 18:
+ if (dest != src + 2)
+ avr_asm_len ("mov %A0,%C1", op, plen, 1);
+ return avr_asm_len ("clr %B0" CR_TAB
+ "clr %C0" CR_TAB
+ "lsr %A0" CR_TAB
+ "lsr %A0", op, plen, 4);
+
+ case 19:
+ if (dest != src + 2)
+ avr_asm_len ("mov %A0,%C1", op, plen, 1);
+ return avr_asm_len ("clr %B0" CR_TAB
+ "clr %C0" CR_TAB
+ "lsr %A0" CR_TAB
+ "lsr %A0" CR_TAB
+ "lsr %A0", op, plen, 5);
+
+ case 20:
+ if (optimize_size)
+ break;
+ if (dest != src + 2)
+ avr_asm_len ("mov %A0,%C1", op, plen, 1);
+ return avr_asm_len ("clr %B0" CR_TAB
+ "clr %C0" CR_TAB
+ "lsr %A0" CR_TAB
+ "lsr %A0" CR_TAB
+ "lsr %A0" CR_TAB
+ "lsr %A0", op, plen, 6);
+
+ case 21:
+ if (optimize_size)
+ break;
+ if (dest != src + 2)
+ avr_asm_len ("mov %A0,%C1", op, plen, 1);
+ return avr_asm_len ("clr %B0" CR_TAB
+ "clr %C0" CR_TAB
+ "lsr %A0" CR_TAB
+ "lsr %A0" CR_TAB
+ "lsr %A0" CR_TAB
+ "lsr %A0" CR_TAB
+ "lsr %A0", op, plen, 7);
+
+ case 22:
+ if (optimize_size)
+ break;
+ if (dest != src + 2)
+ avr_asm_len ("mov %A0,%C1", op, plen, 1);
+ return avr_asm_len ("clr %B0" CR_TAB
+ "clr %C0" CR_TAB
+ "lsr %A0" CR_TAB
+ "lsr %A0" CR_TAB
+ "lsr %A0" CR_TAB
+ "lsr %A0" CR_TAB
+ "lsr %A0" CR_TAB
+ "lsr %A0", op, plen, 8);
- default:
- if (INTVAL (op[2]) < 24)
- break;
+ default:
+ if (INTVAL (op[2]) < 24)
+ break;
- /* fall through */
+ /* fall through */
- case 23:
- return avr_asm_len ("bst %C1,7" CR_TAB
- "clr %A0" CR_TAB
- "clr %B0" CR_TAB
- "clr %C0" CR_TAB
- "bld %A0,0", op, plen, 5);
- } /* switch */
+ case 23:
+ return avr_asm_len ("bst %C1,7" CR_TAB
+ "clr %A0" CR_TAB
+ "clr %B0" CR_TAB
+ "clr %C0" CR_TAB
+ "bld %A0,0", op, plen, 5);
+ } /* switch */
}
out_shift_with_cnt ("lsr %C0" CR_TAB
- "ror %B0" CR_TAB
- "ror %A0", insn, op, plen, 3);
+ "ror %B0" CR_TAB
+ "ror %A0", insn, op, plen, 3);
return "";
}
@@ -7952,9 +8240,12 @@ lshrsi3_out (rtx_insn *insn, rtx operands[], int *len)
break;
if (AVR_HAVE_MOVW)
- return *len = 3, ("clr %D0" CR_TAB
- "clr %C0" CR_TAB
- "movw %A0,%C0");
+ {
+ *len = 3;
+ return ("clr %D0" CR_TAB
+ "clr %C0" CR_TAB
+ "movw %A0,%C0");
+ }
*len = 4;
return ("clr %D0" CR_TAB
"clr %C0" CR_TAB
@@ -7962,54 +8253,203 @@ lshrsi3_out (rtx_insn *insn, rtx operands[], int *len)
"clr %A0");
case 8:
- {
- int reg0 = true_regnum (operands[0]);
- int reg1 = true_regnum (operands[1]);
- *len = 4;
- if (reg0 <= reg1)
- return ("mov %A0,%B1" CR_TAB
- "mov %B0,%C1" CR_TAB
- "mov %C0,%D1" CR_TAB
- "clr %D0");
- else
- return ("clr %D0" CR_TAB
- "mov %C0,%D1" CR_TAB
- "mov %B0,%C1" CR_TAB
- "mov %A0,%B1");
- }
+ *len = 4;
+ if (true_regnum (operands[0]) <= true_regnum (operands[1]))
+ return ("mov %A0,%B1" CR_TAB
+ "mov %B0,%C1" CR_TAB
+ "mov %C0,%D1" CR_TAB
+ "clr %D0");
+ else
+ return ("clr %D0" CR_TAB
+ "mov %C0,%D1" CR_TAB
+ "mov %B0,%C1" CR_TAB
+ "mov %A0,%B1");
+
+ case 9:
+ *len = 7;
+ if (true_regnum (operands[0]) <= true_regnum (operands[1]))
+ return ("mov %A0,%B1" CR_TAB
+ "mov %B0,%C1" CR_TAB
+ "mov %C0,%D1" CR_TAB
+ "clr %D0" CR_TAB
+ "lsr %C0" CR_TAB
+ "ror %B0" CR_TAB
+ "ror %A0");
+ else
+ return ("clr %D0" CR_TAB
+ "mov %C0,%D1" CR_TAB
+ "mov %B0,%C1" CR_TAB
+ "mov %A0,%B1" CR_TAB
+ "lsr %C0" CR_TAB
+ "ror %B0" CR_TAB
+ "ror %A0");
case 16:
- {
- int reg0 = true_regnum (operands[0]);
- int reg1 = true_regnum (operands[1]);
-
- if (reg0 == reg1 + 2)
- return *len = 2, ("clr %C0" CR_TAB
- "clr %D0");
- if (AVR_HAVE_MOVW)
- return *len = 3, ("movw %A0,%C1" CR_TAB
- "clr %C0" CR_TAB
- "clr %D0");
- else
- return *len = 4, ("mov %B0,%D1" CR_TAB
- "mov %A0,%C1" CR_TAB
- "clr %C0" CR_TAB
- "clr %D0");
- }
+ if (true_regnum (operands[0]) == true_regnum (operands[1]) + 2)
+ {
+ *len = 2;
+ return ("clr %C0" CR_TAB
+ "clr %D0");
+ }
+ if (AVR_HAVE_MOVW)
+ {
+ *len = 3;
+ return ("movw %A0,%C1" CR_TAB
+ "clr %C0" CR_TAB
+ "clr %D0");
+ }
+ *len = 4;
+ return ("mov %B0,%D1" CR_TAB
+ "mov %A0,%C1" CR_TAB
+ "clr %C0" CR_TAB
+ "clr %D0");
+
+ case 17:
+ if (true_regnum (operands[0]) == true_regnum (operands[1]) + 2)
+ {
+ *len = 4;
+ return ("clr %C0" CR_TAB
+ "clr %D0" CR_TAB
+ "lsr %B0" CR_TAB
+ "ror %A0");
+ }
+ if (AVR_HAVE_MOVW)
+ {
+ *len = 5;
+ return ("movw %A0,%C1" CR_TAB
+ "clr %C0" CR_TAB
+ "clr %D0" CR_TAB
+ "lsr %B0" CR_TAB
+ "ror %A0");
+ }
+ *len = 6;
+ return ("mov %B0,%D1" CR_TAB
+ "mov %A0,%C1" CR_TAB
+ "clr %C0" CR_TAB
+ "clr %D0" CR_TAB
+ "lsr %B0" CR_TAB
+ "ror %A0");
+
+ case 18:
+ if (true_regnum (operands[0]) == true_regnum (operands[1]) + 2)
+ {
+ *len = 6;
+ return ("clr %C0" CR_TAB
+ "clr %D0" CR_TAB
+ "lsr %B0" CR_TAB
+ "ror %A0" CR_TAB
+ "lsr %B0" CR_TAB
+ "ror %A0");
+ }
+ if (AVR_HAVE_MOVW)
+ {
+ *len = 7;
+ return ("movw %A0,%C1" CR_TAB
+ "clr %C0" CR_TAB
+ "clr %D0" CR_TAB
+ "lsr %B0" CR_TAB
+ "ror %A0" CR_TAB
+ "lsr %B0" CR_TAB
+ "ror %A0");
+ }
+ if (optimize_size)
+ break;
+ *len = 8;
+ return ("mov %B0,%D1" CR_TAB
+ "mov %A0,%C1" CR_TAB
+ "clr %C0" CR_TAB
+ "clr %D0" CR_TAB
+ "lsr %B0" CR_TAB
+ "ror %A0" CR_TAB
+ "lsr %B0" CR_TAB
+ "ror %A0");
case 24:
- return *len = 4, ("mov %A0,%D1" CR_TAB
- "clr %B0" CR_TAB
- "clr %C0" CR_TAB
- "clr %D0");
+ *len = 4;
+ return ("mov %A0,%D1" CR_TAB
+ "clr %B0" CR_TAB
+ "clr %C0" CR_TAB
+ "clr %D0");
+
+ case 25:
+ *len = 5;
+ return ("mov %A0,%D1" CR_TAB
+ "clr %B0" CR_TAB
+ "clr %C0" CR_TAB
+ "clr %D0" CR_TAB
+ "lsr %A0");
+
+ case 26:
+ *len = 6;
+ return ("mov %A0,%D1" CR_TAB
+ "clr %B0" CR_TAB
+ "clr %C0" CR_TAB
+ "clr %D0" CR_TAB
+ "lsr %A0" CR_TAB
+ "lsr %A0");
+
+ case 27:
+ *len = 7;
+ return ("mov %A0,%D1" CR_TAB
+ "clr %B0" CR_TAB
+ "clr %C0" CR_TAB
+ "clr %D0" CR_TAB
+ "lsr %A0" CR_TAB
+ "lsr %A0" CR_TAB
+ "lsr %A0");
+
+ case 28:
+ if (optimize_size)
+ break;
+ *len = 8;
+ return ("mov %A0,%D1" CR_TAB
+ "clr %B0" CR_TAB
+ "clr %C0" CR_TAB
+ "clr %D0" CR_TAB
+ "lsr %A0" CR_TAB
+ "lsr %A0" CR_TAB
+ "lsr %A0" CR_TAB
+ "lsr %A0");
+
+ case 29:
+ if (optimize_size)
+ break;
+ *len = 9;
+ return ("mov %A0,%D1" CR_TAB
+ "clr %B0" CR_TAB
+ "clr %C0" CR_TAB
+ "clr %D0" CR_TAB
+ "lsr %A0" CR_TAB
+ "lsr %A0" CR_TAB
+ "lsr %A0" CR_TAB
+ "lsr %A0" CR_TAB
+ "lsr %A0");
+
+ case 30:
+ if (optimize_size)
+ break;
+ *len = 10;
+ return ("mov %A0,%D1" CR_TAB
+ "clr %B0" CR_TAB
+ "clr %C0" CR_TAB
+ "clr %D0" CR_TAB
+ "lsr %A0" CR_TAB
+ "lsr %A0" CR_TAB
+ "lsr %A0" CR_TAB
+ "lsr %A0" CR_TAB
+ "lsr %A0" CR_TAB
+ "lsr %A0");
case 31:
if (AVR_HAVE_MOVW)
- return *len = 5, ("bst %D1,7" CR_TAB
- "clr %A0" CR_TAB
- "clr %B0" CR_TAB
- "movw %C0,%A0" CR_TAB
- "bld %A0,0");
+ {
+ *len = 5;
+ return ("bst %D1,7" CR_TAB
+ "clr %A0" CR_TAB
+ "clr %B0" CR_TAB
+ "movw %C0,%A0" CR_TAB
+ "bld %A0,0");
+ }
*len = 6;
return ("bst %D1,7" CR_TAB
"clr %A0" CR_TAB
@@ -8021,9 +8461,9 @@ lshrsi3_out (rtx_insn *insn, rtx operands[], int *len)
len = t;
}
out_shift_with_cnt ("lsr %D0" CR_TAB
- "ror %C0" CR_TAB
- "ror %B0" CR_TAB
- "ror %A0", insn, operands, len, 4);
+ "ror %C0" CR_TAB
+ "ror %B0" CR_TAB
+ "ror %A0", insn, operands, len, 4);
return "";
}
new file mode 100644
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+unsigned long foo(unsigned long x)
+{
+ return x << 1;
+}
+
+/* { dg-final { scan-assembler "lsl r22" } } */
+/* { dg-final { scan-assembler-times "rol r2\\d" 3 } } */
new file mode 100644
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+unsigned long foo(unsigned long x)
+{
+ return x << 26;
+}
+
+/* { dg-final { scan-assembler-times "lsl r25" 2 } } */
+/* { dg-final { scan-assembler-times "clr r2\\d" 3 } } */
new file mode 100644
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+long foo(long x)
+{
+ return x >> 1;
+}
+
+/* { dg-final { scan-assembler "asr r25" } } */
+/* { dg-final { scan-assembler-times "ror r2\\d" 3 } } */
new file mode 100644
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+long foo(long x)
+{
+ return x >> 25;
+}
+
+/* { dg-final { scan-assembler "sbrc r22,7" } } */
+/* { dg-final { scan-assembler-times "mov r2\\d,r25" 3 } } */
+/* { dg-final { scan-assembler-times "asr r22" 1 } } */
new file mode 100644
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+unsigned long foo(unsigned long x)
+{
+ return x >> 1;
+}
+
+/* { dg-final { scan-assembler "lsr r25" } } */
+/* { dg-final { scan-assembler-times "ror r2\\d" 3 } } */
new file mode 100644
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+unsigned long foo(unsigned long x)
+{
+ return x >> 26;
+}
+
+/* { dg-final { scan-assembler-times "clr r2\\d" 3 } } */
+/* { dg-final { scan-assembler-times "lsr r22" 2 } } */