Commit afee2a52 by Marek Michalkiewicz Committed by Denis Chertykov

avr-protos.h (avr_output_bld): New.

	* config/avr/avr-protos.h (avr_output_bld): New.
	(out_shift_with_cnt): Add t_len argument.
	* config/avr/avr.c (avr_num_arg_regs): Remove -mpack-args.
	(output_movqi, output_movhi, output_movsisf): Optimize loading
	any constant with exactly one bit set to NO_LD_REGS.
	(out_shift_with_cnt): Optimize output code for size or speed,
	depending on optimize_size.  Handle small shift counts as well
	(if not hand-optimized in ?sh??i3_out).  Shifts can be done
	with or without a scratch register, with help of __tmp_reg__
	or __zero_reg__ if necessary.  Add T_LEN argument to pass the
	length of TEMPLATE in words, return total insn length in *LEN.
	(ashlqi3_out, ashrqi3_out, lshrqi3_out): Change all calls to
	out_shift_with_cnt to work with the above change.
	(ashlhi3_out, ashlsi3_out, ashrhi3_out, ashrsi3_out, lshrhi3_out,
	lshrsi3_out): Likewise.  Optimize more known shift count cases.
	Remove cases already well optimized in out_shift_with_cnt.
	(avr_output_bld): New function.
	* config/avr/avr.h (MASK_PACK_ARGS, TARGET_PACK_ARGS): Remove.
	(TARGET_SWITCHES): Remove -mpack-args backward compatibility.
	* config/avr/avr.md (*reload_inqi, *reload_inhi, *reload_insi):
	Add reload_completed to insn condition - only for peepholes.
	(ashlqi3, ashrqi3, lshrqi3): Correct insn length for shift counts
	in a register or memory.
	(ashlhi3, ashlsi3, ashrhi3, ashrsi3, lshrhi3, lshrsi3): Likewise.
	Do not require a scratch register.
	(*ashlhi3_const, *ashlsi3_const, *ashrhi3_const, *ashrsi3_const,
	*lshrhi3_const, *lshrsi3_const): New insns and matching peepholes.
	Optimize shifts by known count using a scratch register, but only
	if one is still available after register allocation.

From-SVN: r36963
parent 406b0a7c
2000-10-14 Marek Michalkiewicz <marekm@linux.org.pl>
* config/avr/avr-protos.h (avr_output_bld): New.
(out_shift_with_cnt): Add t_len argument.
* config/avr/avr.c (avr_num_arg_regs): Remove -mpack-args.
(output_movqi, output_movhi, output_movsisf): Optimize loading
any constant with exactly one bit set to NO_LD_REGS.
(out_shift_with_cnt): Optimize output code for size or speed,
depending on optimize_size. Handle small shift counts as well
(if not hand-optimized in ?sh??i3_out). Shifts can be done
with or without a scratch register, with help of __tmp_reg__
or __zero_reg__ if necessary. Add T_LEN argument to pass the
length of TEMPLATE in words, return total insn length in *LEN.
(ashlqi3_out, ashrqi3_out, lshrqi3_out): Change all calls to
out_shift_with_cnt to work with the above change.
(ashlhi3_out, ashlsi3_out, ashrhi3_out, ashrsi3_out, lshrhi3_out,
lshrsi3_out): Likewise. Optimize more known shift count cases.
Remove cases already well optimized in out_shift_with_cnt.
(avr_output_bld): New function.
* config/avr/avr.h (MASK_PACK_ARGS, TARGET_PACK_ARGS): Remove.
(TARGET_SWITCHES): Remove -mpack-args backward compatibility.
* config/avr/avr.md (*reload_inqi, *reload_inhi, *reload_insi):
Add reload_completed to insn condition - only for peepholes.
(ashlqi3, ashrqi3, lshrqi3): Correct insn length for shift counts
in a register or memory.
(ashlhi3, ashlsi3, ashrhi3, ashrsi3, lshrhi3, lshrsi3): Likewise.
Do not require a scratch register.
(*ashlhi3_const, *ashlsi3_const, *ashrhi3_const, *ashrsi3_const,
*lshrhi3_const, *lshrsi3_const): New insns and matching peepholes.
Optimize shifts by known count using a scratch register, but only
if one is still available after register allocation.
2000-10-20 J. David Anglin <dave@hiauly1.hia.nrc.ca> 2000-10-20 J. David Anglin <dave@hiauly1.hia.nrc.ca>
* t-vax: New file. Don't build modules from libgcc1.c. * t-vax: New file. Don't build modules from libgcc1.c.
......
...@@ -109,6 +109,8 @@ extern const char * lshrqi3_out PARAMS ((rtx insn, rtx operands[], int *len)); ...@@ -109,6 +109,8 @@ extern const char * lshrqi3_out PARAMS ((rtx insn, rtx operands[], int *len));
extern const char * lshrhi3_out PARAMS ((rtx insn, rtx operands[], int *len)); extern const char * lshrhi3_out PARAMS ((rtx insn, rtx operands[], int *len));
extern const char * lshrsi3_out PARAMS ((rtx insn, rtx operands[], int *len)); extern const char * lshrsi3_out PARAMS ((rtx insn, rtx operands[], int *len));
extern void avr_output_bld PARAMS ((rtx operands[], int bit_nr));
extern enum reg_class preferred_reload_class PARAMS ((rtx x, extern enum reg_class preferred_reload_class PARAMS ((rtx x,
enum reg_class class)); enum reg_class class));
extern int avr_address_cost PARAMS ((rtx x)); extern int avr_address_cost PARAMS ((rtx x));
...@@ -150,7 +152,8 @@ extern int avr_simplify_comparision_p PARAMS ((enum machine_mode mode, ...@@ -150,7 +152,8 @@ extern int avr_simplify_comparision_p PARAMS ((enum machine_mode mode,
extern RTX_CODE avr_normalize_condition PARAMS ((RTX_CODE condition)); extern RTX_CODE avr_normalize_condition PARAMS ((RTX_CODE condition));
extern int compare_eq_p PARAMS ((rtx insn)); extern int compare_eq_p PARAMS ((rtx insn));
extern void out_shift_with_cnt PARAMS ((const char *template, rtx insn, extern void out_shift_with_cnt PARAMS ((const char *template, rtx insn,
rtx operands[], int *len)); rtx operands[], int *len,
int t_len));
extern int const_int_pow2_p PARAMS ((rtx x)); extern int const_int_pow2_p PARAMS ((rtx x));
#endif /* RTX_CODE */ #endif /* RTX_CODE */
......
...@@ -1363,17 +1363,10 @@ avr_num_arg_regs (mode, type) ...@@ -1363,17 +1363,10 @@ avr_num_arg_regs (mode, type)
else else
size = GET_MODE_SIZE (mode); size = GET_MODE_SIZE (mode);
/* Align all function arguments to start in even-numbered registers, /* Align all function arguments to start in even-numbered registers.
for "movw" on the enhanced core (to keep call conventions the same Odd-sized arguments leave holes above them. */
on all devices, do it even if "movw" is not available). Odd-sized
arguments leave holes above them - registers still available for
other uses. Use -mpack-args for compatibility with old asm code
(the new convention will still be used for libgcc calls). */
if (!(type && TARGET_PACK_ARGS)) return (size + 1) & ~1;
size += size & 1;
return size;
} }
/* Controls whether a function argument is passed /* Controls whether a function argument is passed
...@@ -1464,20 +1457,6 @@ output_movqi (insn, operands, l) ...@@ -1464,20 +1457,6 @@ output_movqi (insn, operands, l)
return (AS1 (clr,%0) CR_TAB return (AS1 (clr,%0) CR_TAB
AS1 (inc,%0)); AS1 (inc,%0));
} }
else if (src == const2_rtx)
{
if (reg_was_0 (insn, dest))
{
*l = 2;
return (AS1 (inc,%0 ; reg_was_0) CR_TAB
AS1 (inc,%0));
}
*l = 3;
return (AS1 (clr,%0) CR_TAB
AS1 (inc,%0) CR_TAB
AS1 (inc,%0));
}
else if (src == constm1_rtx) else if (src == constm1_rtx)
{ {
/* Immediate constants -1 to any register */ /* Immediate constants -1 to any register */
...@@ -1488,7 +1467,31 @@ output_movqi (insn, operands, l) ...@@ -1488,7 +1467,31 @@ output_movqi (insn, operands, l)
return (AS1 (clr,%0) CR_TAB return (AS1 (clr,%0) CR_TAB
AS1 (dec,%0)); AS1 (dec,%0));
} }
else
{
int bit_nr = exact_log2 (INTVAL (src));
if (bit_nr >= 0)
{
if (reg_was_0 (insn, dest))
{
*l = 2;
if (!real_l)
output_asm_insn ("set ; reg_was_0", operands);
}
else
{
*l = 3;
if (!real_l)
output_asm_insn ((AS1 (clr,%0) CR_TAB
"set"), operands);
}
if (!real_l)
avr_output_bld (operands, bit_nr);
return "";
}
}
} }
/* Last resort, larger than loading from memory. */ /* Last resort, larger than loading from memory. */
...@@ -1621,21 +1624,6 @@ output_movhi (insn, operands, l) ...@@ -1621,21 +1624,6 @@ output_movhi (insn, operands, l)
AS1 (clr,%B0) CR_TAB AS1 (clr,%B0) CR_TAB
AS1 (inc,%A0)); AS1 (inc,%A0));
} }
else if (src == const2_rtx)
{
if (reg_was_0 (insn, dest))
{
*l = 2;
return (AS1 (inc,%0 ; reg_was_0) CR_TAB
AS1 (inc,%0));
}
*l = 4;
return (AS1 (clr,%A0) CR_TAB
AS1 (clr,%B0) CR_TAB
AS1 (inc,%A0) CR_TAB
AS1 (inc,%A0));
}
else if (src == constm1_rtx) else if (src == constm1_rtx)
{ {
/* Immediate constants -1 to any register */ /* Immediate constants -1 to any register */
...@@ -1651,6 +1639,33 @@ output_movhi (insn, operands, l) ...@@ -1651,6 +1639,33 @@ output_movhi (insn, operands, l)
AS1 (dec,%A0) CR_TAB AS1 (dec,%A0) CR_TAB
AS2 (mov,%B0,%A0)); AS2 (mov,%B0,%A0));
} }
else
{
int bit_nr = exact_log2 (INTVAL (src));
if (bit_nr >= 0)
{
if (reg_was_0 (insn, dest))
{
*l = 2;
if (!real_l)
output_asm_insn ("set ; reg_was_0", operands);
}
else
{
*l = 4;
if (!real_l)
output_asm_insn ((AS1 (clr,%A0) CR_TAB
AS1 (clr,%B0) CR_TAB
"set"), operands);
}
if (!real_l)
avr_output_bld (operands, bit_nr);
return "";
}
}
if ((INTVAL (src) & 0xff) == 0) if ((INTVAL (src) & 0xff) == 0)
{ {
*l = 5; *l = 5;
...@@ -2260,20 +2275,19 @@ output_movsisf(insn, operands, l) ...@@ -2260,20 +2275,19 @@ output_movsisf(insn, operands, l)
if (GET_CODE (src) == CONST_INT) if (GET_CODE (src) == CONST_INT)
{ {
const char *clr_op0 =
AVR_ENHANCED ? (AS1 (clr,%A0) CR_TAB
AS1 (clr,%B0) CR_TAB
AS2 (movw,%C0,%A0))
: (AS1 (clr,%A0) CR_TAB
AS1 (clr,%B0) CR_TAB
AS1 (clr,%C0) CR_TAB
AS1 (clr,%D0));
if (src == const0_rtx) /* mov r,L */ if (src == const0_rtx) /* mov r,L */
{ {
if (AVR_ENHANCED) *l = AVR_ENHANCED ? 3 : 4;
{ return clr_op0;
*l = 3;
return (AS1 (clr,%A0) CR_TAB
AS1 (clr,%B0) CR_TAB
AS2 (movw,%C0,%A0));
}
*l = 4;
return (AS1 (clr,%A0) CR_TAB
AS1 (clr,%B0) CR_TAB
AS1 (clr,%C0) CR_TAB
AS1 (clr,%D0));
} }
else if (src == const1_rtx) else if (src == const1_rtx)
{ {
...@@ -2282,46 +2296,10 @@ output_movsisf(insn, operands, l) ...@@ -2282,46 +2296,10 @@ output_movsisf(insn, operands, l)
*l = 1; *l = 1;
return AS1 (inc,%A0 ; reg_was_0); return AS1 (inc,%A0 ; reg_was_0);
} }
if (AVR_ENHANCED) if (!real_l)
{ output_asm_insn (clr_op0, operands);
*l = 4; *l = AVR_ENHANCED ? 4 : 5;
return (AS1 (clr,%A0) CR_TAB return AS1 (inc,%A0);
AS1 (clr,%B0) CR_TAB
AS2 (movw,%C0,%A0) CR_TAB
AS1 (inc,%A0));
}
*l = 5;
return (AS1 (clr,%A0) CR_TAB
AS1 (clr,%B0) CR_TAB
AS1 (clr,%C0) CR_TAB
AS1 (clr,%D0) CR_TAB
AS1 (inc,%A0));
}
else if (src == const2_rtx)
{
if (reg_was_0 (insn, dest))
{
*l = 2;
return (AS1 (inc,%A0 ; reg_was_0) CR_TAB
AS1 (inc,%A0));
}
if (AVR_ENHANCED)
{
*l = 5;
return (AS1 (clr,%D0) CR_TAB
AS1 (clr,%C0) CR_TAB
AS2 (movw,%A0,%C0) CR_TAB
AS1 (inc,%A0) CR_TAB
AS1 (inc,%A0));
}
*l = 6;
return (AS1 (clr,%D0) CR_TAB
AS1 (clr,%B0) CR_TAB
AS1 (clr,%C0) CR_TAB
AS1 (clr,%A0) CR_TAB
AS1 (inc,%A0) CR_TAB
AS1 (inc,%A0));
} }
else if (src == constm1_rtx) else if (src == constm1_rtx)
{ {
...@@ -2356,6 +2334,33 @@ output_movsisf(insn, operands, l) ...@@ -2356,6 +2334,33 @@ output_movsisf(insn, operands, l)
AS2 (mov,%C0,%A0) CR_TAB AS2 (mov,%C0,%A0) CR_TAB
AS2 (mov,%D0,%A0)); AS2 (mov,%D0,%A0));
} }
else
{
int bit_nr = exact_log2 (INTVAL (src));
if (bit_nr >= 0)
{
if (reg_was_0 (insn, dest))
{
*l = 2;
if (!real_l)
output_asm_insn ("set ; reg_was_0", operands);
}
else
{
*l = AVR_ENHANCED ? 5 : 6;
if (!real_l)
{
output_asm_insn (clr_op0, operands);
output_asm_insn ("set", operands);
}
}
if (!real_l)
avr_output_bld (operands, bit_nr);
return "";
}
}
} }
/* Last resort, better than loading from memory. */ /* Last resort, better than loading from memory. */
...@@ -2684,52 +2689,107 @@ out_tstsi (insn, l) ...@@ -2684,52 +2689,107 @@ out_tstsi (insn, l)
} }
/* Generate asm equivalent for various shift's. /* Generate asm equivalent for various shifts.
Shift count are CONST_INT or REG. */ Shift count is a CONST_INT, MEM or REG.
This only handles cases that are not already
carefully hand-optimized in ?sh??i3_out. */
void void
out_shift_with_cnt (template, insn, operands, len) out_shift_with_cnt (template, insn, operands, len, t_len)
const char *template; const char *template;
rtx insn; rtx insn;
rtx operands[]; rtx operands[];
int *len; int *len;
int t_len; /* Length of template. */
{ {
rtx op[10]; rtx op[10];
char str[300]; char str[500];
int second_label = 1; int second_label = 1;
int saved_in_tmp = 0;
int use_zero_reg = 0;
op[0] = operands[0]; op[0] = operands[0];
op[1] = operands[1]; op[1] = operands[1];
op[2] = operands[2]; op[2] = operands[2];
op[3] = operands[3]; op[3] = operands[3];
str[0] = 0; str[0] = 0;
if (CONSTANT_P (operands[2])) if (len)
*len = 1;
if (GET_CODE (operands[2]) == CONST_INT)
{ {
if (len) int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
++*len; int count = INTVAL (operands[2]);
int max_len = 10; /* If larger than this, always use a loop. */
if (count < 8 && !scratch)
use_zero_reg = 1;
if (optimize_size)
max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
if (t_len * count <= max_len)
{
/* Output shifts inline with no loop - faster. */
if (len)
*len = t_len * count;
else
{
while (count-- > 0)
output_asm_insn (template, op);
}
return;
}
if (scratch)
{
if (!len)
strcat (str, AS2 (ldi,%3,%2));
}
else if (use_zero_reg)
{
/* Hack to save one word: use __zero_reg__ as loop counter.
Set one bit, then shift in a loop until it is 0 again. */
op[3] = zero_reg_rtx;
if (len)
*len = 2;
else
strcat (str, ("set" CR_TAB
AS2 (bld,%3,%2-1)));
}
else else
strcat (str, AS2 (ldi,%3,lo8((%2)-1))); {
/* No scratch register available, use one from LD_REGS (saved in
__tmp_reg__) that doesn't overlap with registers to shift. */
op[3] = gen_rtx (REG, QImode,
((true_regnum (operands[0]) - 1) & 15) + 16);
op[4] = tmp_reg_rtx;
saved_in_tmp = 1;
if (len)
*len = 3; /* Includes "mov %3,%4" after the loop. */
else
strcat (str, (AS2 (mov,%4,%3) CR_TAB
AS2 (ldi,%3,%2)));
}
second_label = 0; second_label = 0;
} }
else if (GET_CODE (operands[2]) == MEM) else if (GET_CODE (operands[2]) == MEM)
{ {
int mov_len;
rtx op_mov[10]; rtx op_mov[10];
op[3] = op_mov[0] = tmp_reg_rtx; op[3] = op_mov[0] = tmp_reg_rtx;
op_mov[1] = op[2]; op_mov[1] = op[2];
if (!len) if (len)
{ out_movqi_r_mr (insn, op_mov, len);
output_asm_insn (out_movqi_r_mr (insn, op_mov, NULL), op_mov);
strcat (str, AS1 (rjmp,2f));
}
else else
{ output_asm_insn (out_movqi_r_mr (insn, op_mov, NULL), op_mov);
out_movqi_r_mr (insn, op_mov, &mov_len);
*len += mov_len + 1;
}
} }
else if (register_operand (operands[2], QImode)) else if (register_operand (operands[2], QImode))
{ {
...@@ -2738,26 +2798,33 @@ out_shift_with_cnt (template, insn, operands, len) ...@@ -2738,26 +2798,33 @@ out_shift_with_cnt (template, insn, operands, len)
else else
{ {
op[3] = tmp_reg_rtx; op[3] = tmp_reg_rtx;
if (len) if (!len)
++*len; strcat (str, (AS2 (mov,%3,%2) CR_TAB));
else
strcat (str, AS2 (mov,%3,%2) CR_TAB);
} }
}
else
fatal_insn ("Bad shift insn:", insn);
if (second_label)
{
if (len) if (len)
++*len; ++*len;
else else
strcat (str, AS1 (rjmp,2f)); strcat (str, AS1 (rjmp,2f));
} }
if (!len)
if (len)
*len += t_len + 2; /* template + dec + brXX */
else
{ {
strcat (str, "\n1:\t"); strcat (str, "\n1:\t");
strcat (str, template); strcat (str, template);
strcat (str, second_label ? "\n2:\t" : "\n\t"); strcat (str, second_label ? "\n2:\t" : "\n\t");
strcat (str, strcat (str, use_zero_reg ? AS1 (lsr,%3) : AS1 (dec,%3));
AS1 (dec,%3) CR_TAB strcat (str, CR_TAB);
AS1 (brpl,1b)); strcat (str, second_label ? AS1 (brpl,1b) : AS1 (brne,1b));
if (saved_in_tmp)
strcat (str, (CR_TAB AS2 (mov,%3,%4)));
output_asm_insn (str, op); output_asm_insn (str, op);
} }
} }
...@@ -2854,10 +2921,8 @@ ashlqi3_out (insn, operands, len) ...@@ -2854,10 +2921,8 @@ ashlqi3_out (insn, operands, len)
else if (CONSTANT_P (operands[2])) else if (CONSTANT_P (operands[2]))
fatal_insn ("Internal compiler bug.\nIncorrect shift:", insn); fatal_insn ("Internal compiler bug.\nIncorrect shift:", insn);
if (len)
*len = 3;
out_shift_with_cnt (AS1 (lsl,%0), out_shift_with_cnt (AS1 (lsl,%0),
insn, operands, len); insn, operands, len, 1);
return ""; return "";
} }
...@@ -2872,25 +2937,85 @@ ashlhi3_out (insn, operands, len) ...@@ -2872,25 +2937,85 @@ ashlhi3_out (insn, operands, len)
{ {
if (GET_CODE (operands[2]) == CONST_INT) if (GET_CODE (operands[2]) == CONST_INT)
{ {
int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
int k; int k;
int *t=len; int *t = len;
if (!len) if (!len)
len = &k; len = &k;
switch (INTVAL (operands[2])) switch (INTVAL (operands[2]))
{ {
case 1: case 4:
*len = 2; if (optimize_size && scratch)
return (AS1 (lsl,%A0) CR_TAB break; /* 5 */
AS1 (rol,%B0)); if (ldi_ok)
{
*len = 6;
return (AS1 (swap,%A0) CR_TAB
AS1 (swap,%B0) CR_TAB
AS2 (andi,%B0,0xf0) CR_TAB
AS2 (eor,%B0,%A0) CR_TAB
AS2 (andi,%A0,0xf0) CR_TAB
AS2 (eor,%B0,%A0));
}
if (scratch)
{
*len = 7;
return (AS1 (swap,%A0) CR_TAB
AS1 (swap,%B0) CR_TAB
AS2 (ldi,%3,0xf0) CR_TAB
AS2 (and,%B0,%3) CR_TAB
AS2 (eor,%B0,%A0) CR_TAB
AS2 (and,%A0,%3) CR_TAB
AS2 (eor,%B0,%A0));
}
break; /* optimize_size ? 6 : 8 */
case 2: case 5:
*len = 4; if (optimize_size)
return (AS1 (lsl,%A0) CR_TAB break; /* scratch ? 5 : 6 */
AS1 (rol,%B0) CR_TAB if (ldi_ok)
AS1 (lsl,%A0) CR_TAB {
AS1 (rol,%B0)); *len = 8;
return (AS1 (lsl,%A0) CR_TAB
AS1 (rol,%B0) CR_TAB
AS1 (swap,%A0) CR_TAB
AS1 (swap,%B0) CR_TAB
AS2 (andi,%B0,0xf0) CR_TAB
AS2 (eor,%B0,%A0) CR_TAB
AS2 (andi,%A0,0xf0) CR_TAB
AS2 (eor,%B0,%A0));
}
if (scratch)
{
*len = 9;
return (AS1 (lsl,%A0) CR_TAB
AS1 (rol,%B0) CR_TAB
AS1 (swap,%A0) CR_TAB
AS1 (swap,%B0) CR_TAB
AS2 (ldi,%3,0xf0) CR_TAB
AS2 (and,%B0,%3) CR_TAB
AS2 (eor,%B0,%A0) CR_TAB
AS2 (and,%A0,%3) CR_TAB
AS2 (eor,%B0,%A0));
}
break; /* 10 */
case 6:
if (optimize_size)
break; /* scratch ? 5 : 6 */
*len = 9;
return (AS1 (clr,__tmp_reg__) CR_TAB
AS1 (lsr,%B0) CR_TAB
AS1 (ror,%A0) CR_TAB
AS1 (ror,__tmp_reg__) CR_TAB
AS1 (lsr,%B0) CR_TAB
AS1 (ror,%A0) CR_TAB
AS1 (ror,__tmp_reg__) CR_TAB
AS2 (mov,%B0,%A0) CR_TAB
AS2 (mov,%A0,__tmp_reg__));
case 7: case 7:
*len = 5; *len = 5;
...@@ -2929,7 +3054,7 @@ ashlhi3_out (insn, operands, len) ...@@ -2929,7 +3054,7 @@ ashlhi3_out (insn, operands, len)
AS1 (lsl,%B0)); AS1 (lsl,%B0));
case 12: case 12:
if (test_hard_reg_class (LD_REGS, operands[0])) if (ldi_ok)
{ {
*len = 4; *len = 4;
return (AS2 (mov,%B0,%A0) CR_TAB return (AS2 (mov,%B0,%A0) CR_TAB
...@@ -2937,16 +3062,25 @@ ashlhi3_out (insn, operands, len) ...@@ -2937,16 +3062,25 @@ ashlhi3_out (insn, operands, len)
AS1 (swap,%B0) CR_TAB AS1 (swap,%B0) CR_TAB
AS2 (andi,%B0,0xf0)); AS2 (andi,%B0,0xf0));
} }
/* %3 is a scratch register from class LD_REGS */ if (scratch)
*len = 5; {
*len = 5;
return (AS2 (mov,%B0,%A0) CR_TAB
AS1 (clr,%A0) CR_TAB
AS1 (swap,%B0) CR_TAB
AS2 (ldi,%3,0xf0) CR_TAB
AS2 (and,%B0,%3));
}
*len = 6;
return (AS2 (mov,%B0,%A0) CR_TAB return (AS2 (mov,%B0,%A0) CR_TAB
AS1 (clr,%A0) CR_TAB AS1 (clr,%A0) CR_TAB
AS1 (swap,%B0) CR_TAB AS1 (lsl,%B0) CR_TAB
AS2 (ldi,%3,0xf0) CR_TAB AS1 (lsl,%B0) CR_TAB
AS2 (and,%B0,%3)); AS1 (lsl,%B0) CR_TAB
AS1 (lsl,%B0));
case 13: case 13:
if (test_hard_reg_class (LD_REGS, operands[0])) if (ldi_ok)
{ {
*len = 5; *len = 5;
return (AS2 (mov,%B0,%A0) CR_TAB return (AS2 (mov,%B0,%A0) CR_TAB
...@@ -2955,7 +3089,7 @@ ashlhi3_out (insn, operands, len) ...@@ -2955,7 +3089,7 @@ ashlhi3_out (insn, operands, len)
AS1 (lsl,%B0) CR_TAB AS1 (lsl,%B0) CR_TAB
AS2 (andi,%B0,0xe0)); AS2 (andi,%B0,0xe0));
} }
if (AVR_ENHANCED) if (AVR_ENHANCED && scratch)
{ {
*len = 5; *len = 5;
return (AS2 (ldi,%3,0x20) CR_TAB return (AS2 (ldi,%3,0x20) CR_TAB
...@@ -2964,10 +3098,48 @@ ashlhi3_out (insn, operands, len) ...@@ -2964,10 +3098,48 @@ ashlhi3_out (insn, operands, len)
AS1 (clr,%A0) CR_TAB AS1 (clr,%A0) CR_TAB
AS1 (clr,__zero_reg__)); AS1 (clr,__zero_reg__));
} }
break; if (optimize_size && scratch)
break; /* 5 */
if (scratch)
{
*len = 6;
return (AS2 (mov,%B0,%A0) CR_TAB
AS1 (clr,%A0) CR_TAB
AS1 (swap,%B0) CR_TAB
AS1 (lsl,%B0) CR_TAB
AS2 (ldi,%3,0xe0) CR_TAB
AS2 (and,%B0,%3));
}
if (AVR_ENHANCED)
{
*len = 6;
return ("set" CR_TAB
AS2 (bld,r1,5) CR_TAB
AS2 (mul,%A0,r1) CR_TAB
AS2 (mov,%B0,r0) CR_TAB
AS1 (clr,%A0) CR_TAB
AS1 (clr,__zero_reg__));
}
*len = 7;
return (AS2 (mov,%B0,%A0) CR_TAB
AS1 (clr,%A0) CR_TAB
AS1 (lsl,%B0) CR_TAB
AS1 (lsl,%B0) CR_TAB
AS1 (lsl,%B0) CR_TAB
AS1 (lsl,%B0) CR_TAB
AS1 (lsl,%B0));
case 14: case 14:
if (AVR_ENHANCED) if (AVR_ENHANCED && ldi_ok)
{
*len = 5;
return (AS2 (ldi,%B0,0x40) CR_TAB
AS2 (mul,%A0,%B0) CR_TAB
AS2 (mov,%B0,r0) CR_TAB
AS1 (clr,%A0) CR_TAB
AS1 (clr,__zero_reg__));
}
if (AVR_ENHANCED && scratch)
{ {
*len = 5; *len = 5;
return (AS2 (ldi,%3,0x40) CR_TAB return (AS2 (ldi,%3,0x40) CR_TAB
...@@ -2976,7 +3148,24 @@ ashlhi3_out (insn, operands, len) ...@@ -2976,7 +3148,24 @@ ashlhi3_out (insn, operands, len)
AS1 (clr,%A0) CR_TAB AS1 (clr,%A0) CR_TAB
AS1 (clr,__zero_reg__)); AS1 (clr,__zero_reg__));
} }
break; if (optimize_size && ldi_ok)
{
*len = 5;
return (AS2 (mov,%B0,%A0) CR_TAB
AS2 (ldi,%A0,6) "\n1:\t"
AS1 (lsl,%B0) CR_TAB
AS1 (dec,%A0) CR_TAB
AS1 (brne,1b));
}
if (optimize_size && scratch)
break; /* 5 */
*len = 6;
return (AS1 (clr,%B0) CR_TAB
AS1 (lsr,%A0) CR_TAB
AS1 (ror,%B0) CR_TAB
AS1 (lsr,%A0) CR_TAB
AS1 (ror,%B0) CR_TAB
AS1 (clr,%A0));
case 15: case 15:
*len = 4; *len = 4;
...@@ -2987,11 +3176,9 @@ ashlhi3_out (insn, operands, len) ...@@ -2987,11 +3176,9 @@ ashlhi3_out (insn, operands, len)
} }
len = t; len = t;
} }
if (len) out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
*len = 4; AS1 (rol,%B0)),
out_shift_with_cnt (AS1 (lsl,%0) CR_TAB insn, operands, len, 2);
AS1 (rol,%B0),
insn, operands, len);
return ""; return "";
} }
...@@ -3007,32 +3194,13 @@ ashlsi3_out (insn, operands, len) ...@@ -3007,32 +3194,13 @@ ashlsi3_out (insn, operands, len)
if (GET_CODE (operands[2]) == CONST_INT) if (GET_CODE (operands[2]) == CONST_INT)
{ {
int k; int k;
int *t=len; int *t = len;
if (!len) if (!len)
len = &k; len = &k;
switch (INTVAL (operands[2])) switch (INTVAL (operands[2]))
{ {
case 1:
*len = 4;
return (AS1 (lsl,%A0) CR_TAB
AS1 (rol,%B0) CR_TAB
AS1 (rol,%C0) CR_TAB
AS1 (rol,%D0));
case 2:
/* Loop is one word smaller, but slower and needs a register. */
*len = 8;
return (AS1 (lsl,%A0) CR_TAB
AS1 (rol,%B0) CR_TAB
AS1 (rol,%C0) CR_TAB
AS1 (rol,%D0) CR_TAB
AS1 (lsl,%A0) CR_TAB
AS1 (rol,%B0) CR_TAB
AS1 (rol,%C0) CR_TAB
AS1 (rol,%D0));
case 8: case 8:
{ {
int reg0 = true_regnum (operands[0]); int reg0 = true_regnum (operands[0]);
...@@ -3111,13 +3279,11 @@ ashlsi3_out (insn, operands, len) ...@@ -3111,13 +3279,11 @@ ashlsi3_out (insn, operands, len)
} }
len = t; len = t;
} }
if (len) out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
*len = 6; AS1 (rol,%B0) CR_TAB
out_shift_with_cnt (AS1 (lsl,%0) CR_TAB AS1 (rol,%C0) CR_TAB
AS1 (rol,%B0) CR_TAB AS1 (rol,%D0)),
AS1 (rol,%C0) CR_TAB insn, operands, len, 4);
AS1 (rol,%D0),
insn, operands, len);
return ""; return "";
} }
...@@ -3185,10 +3351,8 @@ ashrqi3_out (insn, operands, len) ...@@ -3185,10 +3351,8 @@ ashrqi3_out (insn, operands, len)
else if (CONSTANT_P (operands[2])) else if (CONSTANT_P (operands[2]))
fatal_insn ("Internal compiler bug.\nIncorrect shift:", insn); fatal_insn ("Internal compiler bug.\nIncorrect shift:", insn);
if (len)
*len = 3;
out_shift_with_cnt (AS1 (asr,%0), out_shift_with_cnt (AS1 (asr,%0),
insn, operands, len); insn, operands, len, 1);
return ""; return "";
} }
...@@ -3203,6 +3367,8 @@ ashrhi3_out (insn, operands, len) ...@@ -3203,6 +3367,8 @@ ashrhi3_out (insn, operands, len)
{ {
if (GET_CODE (operands[2]) == CONST_INT) if (GET_CODE (operands[2]) == CONST_INT)
{ {
int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
int k; int k;
int *t = len; int *t = len;
...@@ -3211,17 +3377,23 @@ ashrhi3_out (insn, operands, len) ...@@ -3211,17 +3377,23 @@ ashrhi3_out (insn, operands, len)
switch (INTVAL (operands[2])) switch (INTVAL (operands[2]))
{ {
case 1: case 4:
*len=2; case 5:
return (AS1 (asr,%B0) CR_TAB /* XXX try to optimize this too? */
AS1 (ror,%A0)); break;
case 2: case 6:
*len=4; if (optimize_size)
return (AS1 (asr,%B0) CR_TAB break; /* scratch ? 5 : 6 */
AS1 (ror,%A0) CR_TAB *len = 8;
AS1 (asr,%B0) CR_TAB return (AS2 (mov,__tmp_reg__,%A0) CR_TAB
AS1 (ror,%A0)); AS2 (mov,%A0,%B0) CR_TAB
AS1 (lsl,__tmp_reg__) CR_TAB
AS1 (rol,%A0) CR_TAB
AS2 (sbc,%B0,%B0) CR_TAB
AS1 (lsl,__tmp_reg__) CR_TAB
AS1 (rol,%A0) CR_TAB
AS1 (rol,%B0));
case 7: case 7:
*len = 4; *len = 4;
...@@ -3231,15 +3403,24 @@ ashrhi3_out (insn, operands, len) ...@@ -3231,15 +3403,24 @@ ashrhi3_out (insn, operands, len)
AS2 (sbc,%B0,%B0)); AS2 (sbc,%B0,%B0));
case 8: case 8:
if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1) {
int reg0 = true_regnum (operands[0]);
int reg1 = true_regnum (operands[1]);
if (reg0 == reg1)
return *len = 3, (AS2 (mov,%A0,%B0) CR_TAB
AS1 (lsl,%B0) CR_TAB
AS2 (sbc,%B0,%B0));
else if (reg0 == reg1 + 1)
return *len = 3, (AS1 (clr,%B0) CR_TAB
AS2 (sbrc,%A0,7) CR_TAB
AS1 (dec,%B0));
return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
AS1 (clr,%B0) CR_TAB AS1 (clr,%B0) CR_TAB
AS2 (sbrc,%A0,7) CR_TAB AS2 (sbrc,%A0,7) CR_TAB
AS1 (dec,%B0)); AS1 (dec,%B0));
else }
return *len = 3, (AS1 (clr,%B0) CR_TAB
AS2 (sbrc,%A0,7) CR_TAB
AS1 (dec,%B0));
case 9: case 9:
*len = 4; *len = 4;
...@@ -3257,40 +3438,67 @@ ashrhi3_out (insn, operands, len) ...@@ -3257,40 +3438,67 @@ ashrhi3_out (insn, operands, len)
AS1 (asr,%A0)); AS1 (asr,%A0));
case 11: case 11:
if (AVR_ENHANCED && test_hard_reg_class (LD_REGS, operands[0])) if (AVR_ENHANCED && ldi_ok)
{ {
*len = 5; *len = 5;
return (AS2 (ldi,%3,0x20) CR_TAB return (AS2 (ldi,%A0,0x20) CR_TAB
AS2 (muls,%B0,%3) CR_TAB AS2 (muls,%B0,%A0) CR_TAB
AS2 (mov,%A0,r1) CR_TAB AS2 (mov,%A0,r1) CR_TAB
AS2 (sbc,%B0,%B0) CR_TAB AS2 (sbc,%B0,%B0) CR_TAB
AS1 (clr,__zero_reg__)); AS1 (clr,__zero_reg__));
} }
break; if (optimize_size && scratch)
break; /* 5 */
*len = 6;
return (AS2 (mov,%A0,%B0) CR_TAB
AS1 (lsl,%B0) CR_TAB
AS2 (sbc,%B0,%B0) CR_TAB
AS1 (asr,%A0) CR_TAB
AS1 (asr,%A0) CR_TAB
AS1 (asr,%A0));
case 12: case 12:
if (AVR_ENHANCED && test_hard_reg_class (LD_REGS, operands[0])) if (AVR_ENHANCED && ldi_ok)
{ {
*len = 5; *len = 5;
return (AS2 (ldi,%3,0x10) CR_TAB return (AS2 (ldi,%A0,0x10) CR_TAB
AS2 (muls,%B0,%3) CR_TAB AS2 (muls,%B0,%A0) CR_TAB
AS2 (mov,%A0,r1) CR_TAB AS2 (mov,%A0,r1) CR_TAB
AS2 (sbc,%B0,%B0) CR_TAB AS2 (sbc,%B0,%B0) CR_TAB
AS1 (clr,__zero_reg__)); AS1 (clr,__zero_reg__));
} }
break; if (optimize_size && scratch)
break; /* 5 */
*len = 7;
return (AS2 (mov,%A0,%B0) CR_TAB
AS1 (lsl,%B0) CR_TAB
AS2 (sbc,%B0,%B0) CR_TAB
AS1 (asr,%A0) CR_TAB
AS1 (asr,%A0) CR_TAB
AS1 (asr,%A0) CR_TAB
AS1 (asr,%A0));
case 13: case 13:
if (AVR_ENHANCED && test_hard_reg_class (LD_REGS, operands[0])) if (AVR_ENHANCED && ldi_ok)
{ {
*len = 5; *len = 5;
return (AS2 (ldi,%3,0x08) CR_TAB return (AS2 (ldi,%A0,0x08) CR_TAB
AS2 (muls,%B0,%3) CR_TAB AS2 (muls,%B0,%A0) CR_TAB
AS2 (mov,%A0,r1) CR_TAB AS2 (mov,%A0,r1) CR_TAB
AS2 (sbc,%B0,%B0) CR_TAB AS2 (sbc,%B0,%B0) CR_TAB
AS1 (clr,__zero_reg__)); AS1 (clr,__zero_reg__));
} }
break; if (optimize_size)
break; /* scratch ? 5 : 7 */
*len = 8;
return (AS2 (mov,%A0,%B0) CR_TAB
AS1 (lsl,%B0) CR_TAB
AS2 (sbc,%B0,%B0) CR_TAB
AS1 (asr,%A0) CR_TAB
AS1 (asr,%A0) CR_TAB
AS1 (asr,%A0) CR_TAB
AS1 (asr,%A0) CR_TAB
AS1 (asr,%A0));
case 14: case 14:
*len = 5; *len = 5;
...@@ -3307,11 +3515,9 @@ ashrhi3_out (insn, operands, len) ...@@ -3307,11 +3515,9 @@ ashrhi3_out (insn, operands, len)
} }
len = t; len = t;
} }
if (len) out_shift_with_cnt ((AS1 (asr,%B0) CR_TAB
*len = 4; AS1 (ror,%A0)),
out_shift_with_cnt (AS1 (asr,%B0) CR_TAB insn, operands, len, 2);
AS1 (ror,%A0),
insn, operands, len);
return ""; return "";
} }
...@@ -3334,25 +3540,6 @@ ashrsi3_out (insn, operands, len) ...@@ -3334,25 +3540,6 @@ ashrsi3_out (insn, operands, len)
switch (INTVAL (operands[2])) switch (INTVAL (operands[2]))
{ {
case 1:
*len=4;
return (AS1 (asr,%D0) CR_TAB
AS1 (ror,%C0) CR_TAB
AS1 (ror,%B0) CR_TAB
AS1 (ror,%A0));
case 2:
/* Loop is one word smaller, but slower and needs a register. */
*len = 8;
return (AS1 (asr,%D0) CR_TAB
AS1 (ror,%C0) CR_TAB
AS1 (ror,%B0) CR_TAB
AS1 (ror,%A0) CR_TAB
AS1 (asr,%D0) CR_TAB
AS1 (ror,%C0) CR_TAB
AS1 (ror,%B0) CR_TAB
AS1 (ror,%A0));
case 8: case 8:
{ {
int reg0 = true_regnum (operands[0]); int reg0 = true_regnum (operands[0]);
...@@ -3446,13 +3633,11 @@ ashrsi3_out (insn, operands, len) ...@@ -3446,13 +3633,11 @@ ashrsi3_out (insn, operands, len)
} }
len = t; len = t;
} }
if (len) out_shift_with_cnt ((AS1 (asr,%D0) CR_TAB
*len = 6; AS1 (ror,%C0) CR_TAB
out_shift_with_cnt (AS1 (asr,%D0) CR_TAB AS1 (ror,%B0) CR_TAB
AS1 (ror,%C0) CR_TAB AS1 (ror,%A0)),
AS1 (ror,%B0) CR_TAB insn, operands, len, 4);
AS1 (ror,%A0),
insn, operands, len);
return ""; return "";
} }
...@@ -3546,10 +3731,8 @@ lshrqi3_out (insn, operands, len) ...@@ -3546,10 +3731,8 @@ lshrqi3_out (insn, operands, len)
else if (CONSTANT_P (operands[2])) else if (CONSTANT_P (operands[2]))
fatal_insn ("Internal compiler bug.\nIncorrect shift:", insn); fatal_insn ("Internal compiler bug.\nIncorrect shift:", insn);
if (len)
*len = 3;
out_shift_with_cnt (AS1 (lsr,%0), out_shift_with_cnt (AS1 (lsr,%0),
insn, operands, len); insn, operands, len, 1);
return ""; return "";
} }
...@@ -3563,25 +3746,85 @@ lshrhi3_out (insn, operands, len) ...@@ -3563,25 +3746,85 @@ lshrhi3_out (insn, operands, len)
{ {
if (GET_CODE (operands[2]) == CONST_INT) if (GET_CODE (operands[2]) == CONST_INT)
{ {
int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
int k; int k;
int *t = len; int *t = len;
if (!len) if (!len)
len = &k; len = &k;
switch (INTVAL (operands[2])) switch (INTVAL (operands[2]))
{ {
case 1: case 4:
*len = 2; if (optimize_size && scratch)
return (AS1 (lsr,%B0) CR_TAB break; /* 5 */
AS1 (ror,%A0)); if (ldi_ok)
{
case 2: *len = 6;
*len = 4; return (AS1 (swap,%B0) CR_TAB
return (AS1 (lsr,%B0) CR_TAB AS1 (swap,%A0) CR_TAB
AS1 (ror,%A0) CR_TAB AS2 (andi,%A0,0x0f) CR_TAB
AS1 (lsr,%B0) CR_TAB AS2 (eor,%A0,%B0) CR_TAB
AS1 (ror,%A0)); AS2 (andi,%B0,0x0f) CR_TAB
AS2 (eor,%A0,%B0));
}
if (scratch)
{
*len = 7;
return (AS1 (swap,%B0) CR_TAB
AS1 (swap,%A0) CR_TAB
AS2 (ldi,%3,0x0f) CR_TAB
AS2 (and,%A0,%3) CR_TAB
AS2 (eor,%A0,%B0) CR_TAB
AS2 (and,%B0,%3) CR_TAB
AS2 (eor,%A0,%B0));
}
break; /* optimize_size ? 6 : 8 */
case 5:
if (optimize_size)
break; /* scratch ? 5 : 6 */
if (ldi_ok)
{
*len = 8;
return (AS1 (lsr,%B0) CR_TAB
AS1 (ror,%A0) CR_TAB
AS1 (swap,%B0) CR_TAB
AS1 (swap,%A0) CR_TAB
AS2 (andi,%A0,0x0f) CR_TAB
AS2 (eor,%A0,%B0) CR_TAB
AS2 (andi,%B0,0x0f) CR_TAB
AS2 (eor,%A0,%B0));
}
if (scratch)
{
*len = 9;
return (AS1 (lsr,%B0) CR_TAB
AS1 (ror,%A0) CR_TAB
AS1 (swap,%B0) CR_TAB
AS1 (swap,%A0) CR_TAB
AS2 (ldi,%3,0x0f) CR_TAB
AS2 (and,%A0,%3) CR_TAB
AS2 (eor,%A0,%B0) CR_TAB
AS2 (and,%B0,%3) CR_TAB
AS2 (eor,%A0,%B0));
}
break; /* 10 */
case 6:
if (optimize_size)
break; /* scratch ? 5 : 6 */
*len = 9;
return (AS1 (clr,__tmp_reg__) CR_TAB
AS1 (lsl,%A0) CR_TAB
AS1 (rol,%B0) CR_TAB
AS1 (rol,__tmp_reg__) CR_TAB
AS1 (lsl,%A0) CR_TAB
AS1 (rol,%B0) CR_TAB
AS1 (rol,__tmp_reg__) CR_TAB
AS2 (mov,%A0,%B0) CR_TAB
AS2 (mov,%B0,__tmp_reg__));
case 7: case 7:
*len = 5; *len = 5;
...@@ -3620,7 +3863,7 @@ lshrhi3_out (insn, operands, len) ...@@ -3620,7 +3863,7 @@ lshrhi3_out (insn, operands, len)
AS1 (lsr,%A0)); AS1 (lsr,%A0));
case 12: case 12:
if (test_hard_reg_class (LD_REGS, operands[0])) if (ldi_ok)
{ {
*len = 4; *len = 4;
return (AS2 (mov,%A0,%B0) CR_TAB return (AS2 (mov,%A0,%B0) CR_TAB
...@@ -3628,16 +3871,25 @@ lshrhi3_out (insn, operands, len) ...@@ -3628,16 +3871,25 @@ lshrhi3_out (insn, operands, len)
AS1 (swap,%A0) CR_TAB AS1 (swap,%A0) CR_TAB
AS2 (andi,%A0,0x0f)); AS2 (andi,%A0,0x0f));
} }
/* %3 is a scratch register from class LD_REGS */ if (scratch)
*len = 5; {
*len = 5;
return (AS2 (mov,%A0,%B0) CR_TAB
AS1 (clr,%B0) CR_TAB
AS1 (swap,%A0) CR_TAB
AS2 (ldi,%3,0x0f) CR_TAB
AS2 (and,%A0,%3));
}
*len = 6;
return (AS2 (mov,%A0,%B0) CR_TAB return (AS2 (mov,%A0,%B0) CR_TAB
AS1 (clr,%B0) CR_TAB AS1 (clr,%B0) CR_TAB
AS1 (swap,%A0) CR_TAB AS1 (lsr,%A0) CR_TAB
AS2 (ldi,%3,0x0f) CR_TAB AS1 (lsr,%A0) CR_TAB
AS2 (and,%A0,%3)); AS1 (lsr,%A0) CR_TAB
AS1 (lsr,%A0));
case 13: case 13:
if (test_hard_reg_class (LD_REGS, operands[0])) if (ldi_ok)
{ {
*len = 5; *len = 5;
return (AS2 (mov,%A0,%B0) CR_TAB return (AS2 (mov,%A0,%B0) CR_TAB
...@@ -3646,7 +3898,7 @@ lshrhi3_out (insn, operands, len) ...@@ -3646,7 +3898,7 @@ lshrhi3_out (insn, operands, len)
AS1 (lsr,%A0) CR_TAB AS1 (lsr,%A0) CR_TAB
AS2 (andi,%A0,0x07)); AS2 (andi,%A0,0x07));
} }
if (AVR_ENHANCED) if (AVR_ENHANCED && scratch)
{ {
*len = 5; *len = 5;
return (AS2 (ldi,%3,0x08) CR_TAB return (AS2 (ldi,%3,0x08) CR_TAB
...@@ -3655,10 +3907,48 @@ lshrhi3_out (insn, operands, len) ...@@ -3655,10 +3907,48 @@ lshrhi3_out (insn, operands, len)
AS1 (clr,%B0) CR_TAB AS1 (clr,%B0) CR_TAB
AS1 (clr,__zero_reg__)); AS1 (clr,__zero_reg__));
} }
break; if (optimize_size && scratch)
break; /* 5 */
if (scratch)
{
*len = 6;
return (AS2 (mov,%A0,%B0) CR_TAB
AS1 (clr,%B0) CR_TAB
AS1 (swap,%A0) CR_TAB
AS1 (lsr,%A0) CR_TAB
AS2 (ldi,%3,0x07) CR_TAB
AS2 (and,%A0,%3));
}
if (AVR_ENHANCED)
{
*len = 6;
return ("set" CR_TAB
AS2 (bld,r1,3) CR_TAB
AS2 (mul,%B0,r1) CR_TAB
AS2 (mov,%A0,r1) CR_TAB
AS1 (clr,%B0) CR_TAB
AS1 (clr,__zero_reg__));
}
*len = 7;
return (AS2 (mov,%A0,%B0) CR_TAB
AS1 (clr,%B0) CR_TAB
AS1 (lsr,%A0) CR_TAB
AS1 (lsr,%A0) CR_TAB
AS1 (lsr,%A0) CR_TAB
AS1 (lsr,%A0) CR_TAB
AS1 (lsr,%A0));
case 14: case 14:
if (AVR_ENHANCED) if (AVR_ENHANCED && ldi_ok)
{
*len = 5;
return (AS2 (ldi,%A0,0x04) CR_TAB
AS2 (mul,%B0,%A0) CR_TAB
AS2 (mov,%A0,r1) CR_TAB
AS1 (clr,%B0) CR_TAB
AS1 (clr,__zero_reg__));
}
if (AVR_ENHANCED && scratch)
{ {
*len = 5; *len = 5;
return (AS2 (ldi,%3,0x04) CR_TAB return (AS2 (ldi,%3,0x04) CR_TAB
...@@ -3667,22 +3957,37 @@ lshrhi3_out (insn, operands, len) ...@@ -3667,22 +3957,37 @@ lshrhi3_out (insn, operands, len)
AS1 (clr,%B0) CR_TAB AS1 (clr,%B0) CR_TAB
AS1 (clr,__zero_reg__)); AS1 (clr,__zero_reg__));
} }
break; if (optimize_size && ldi_ok)
{
*len = 5;
return (AS2 (mov,%A0,%B0) CR_TAB
AS2 (ldi,%B0,6) "\n1:\t"
AS1 (lsr,%A0) CR_TAB
AS1 (dec,%B0) CR_TAB
AS1 (brne,1b));
}
if (optimize_size && scratch)
break; /* 5 */
*len = 6;
return (AS1 (clr,%A0) CR_TAB
AS1 (lsl,%B0) CR_TAB
AS1 (rol,%A0) CR_TAB
AS1 (lsl,%B0) CR_TAB
AS1 (rol,%A0) CR_TAB
AS1 (clr,%B0));
case 15: case 15:
*len = 4; *len = 4;
return (AS1 (lsl,%B0) CR_TAB return (AS1 (clr,%A0) CR_TAB
AS2 (sbc,%A0,%A0) CR_TAB AS1 (lsl,%B0) CR_TAB
AS1 (neg,%A0) CR_TAB AS1 (rol,%A0) CR_TAB
AS1 (clr,%B0)); AS1 (clr,%B0));
} }
len = t; len = t;
} }
if (len) out_shift_with_cnt ((AS1 (lsr,%B0) CR_TAB
*len = 4; AS1 (ror,%A0)),
out_shift_with_cnt (AS1 (lsr,%B0) CR_TAB insn, operands, len, 2);
AS1 (ror,%A0),
insn, operands, len);
return ""; return "";
} }
...@@ -3704,25 +4009,6 @@ lshrsi3_out (insn, operands, len) ...@@ -3704,25 +4009,6 @@ lshrsi3_out (insn, operands, len)
switch (INTVAL (operands[2])) switch (INTVAL (operands[2]))
{ {
case 1:
*len = 4;
return (AS1 (lsr,%D0) CR_TAB
AS1 (ror,%C0) CR_TAB
AS1 (ror,%B0) CR_TAB
AS1 (ror,%A0));
case 2:
/* Loop is one word smaller, but slower and needs a register. */
*len = 8;
return (AS1 (lsr,%D0) CR_TAB
AS1 (ror,%C0) CR_TAB
AS1 (ror,%B0) CR_TAB
AS1 (ror,%A0) CR_TAB
AS1 (lsr,%D0) CR_TAB
AS1 (ror,%C0) CR_TAB
AS1 (ror,%B0) CR_TAB
AS1 (ror,%A0));
case 8: case 8:
{ {
int reg0 = true_regnum (operands[0]); int reg0 = true_regnum (operands[0]);
...@@ -3791,13 +4077,11 @@ lshrsi3_out (insn, operands, len) ...@@ -3791,13 +4077,11 @@ lshrsi3_out (insn, operands, len)
} }
len = t; len = t;
} }
if (len) out_shift_with_cnt ((AS1 (lsr,%D0) CR_TAB
*len = 6; AS1 (ror,%C0) CR_TAB
out_shift_with_cnt (AS1 (lsr,%D0) CR_TAB AS1 (ror,%B0) CR_TAB
AS1 (ror,%C0) CR_TAB AS1 (ror,%A0)),
AS1 (ror,%B0) CR_TAB insn, operands, len, 4);
AS1 (ror,%A0),
insn, operands, len);
return ""; return "";
} }
...@@ -4994,3 +5278,16 @@ output_reload_insisf (insn, operands, len) ...@@ -4994,3 +5278,16 @@ output_reload_insisf (insn, operands, len)
} }
return ""; return "";
} }
void
avr_output_bld (operands, bit_nr)
rtx operands[];
int bit_nr;
{
static char s[] = "bld %A0,0";
s[5] = 'A' + (bit_nr >> 3);
s[8] = '0' + (bit_nr & 7);
output_asm_insn (s, operands);
}
...@@ -55,7 +55,6 @@ extern int target_flags; ...@@ -55,7 +55,6 @@ extern int target_flags;
#define MASK_NO_INTERRUPTS 0x00020000 #define MASK_NO_INTERRUPTS 0x00020000
#define MASK_CALL_PROLOGUES 0x00040000 #define MASK_CALL_PROLOGUES 0x00040000
#define MASK_TINY_STACK 0x00080000 #define MASK_TINY_STACK 0x00080000
#define MASK_PACK_ARGS 0x00100000
#define TARGET_ORDER_1 (target_flags & MASK_ORDER_1) #define TARGET_ORDER_1 (target_flags & MASK_ORDER_1)
#define TARGET_ORDER_2 (target_flags & MASK_ORDER_2) #define TARGET_ORDER_2 (target_flags & MASK_ORDER_2)
...@@ -64,7 +63,6 @@ extern int target_flags; ...@@ -64,7 +63,6 @@ extern int target_flags;
#define TARGET_INSN_SIZE_DUMP (target_flags & MASK_INSN_SIZE_DUMP) #define TARGET_INSN_SIZE_DUMP (target_flags & MASK_INSN_SIZE_DUMP)
#define TARGET_CALL_PROLOGUES (target_flags & MASK_CALL_PROLOGUES) #define TARGET_CALL_PROLOGUES (target_flags & MASK_CALL_PROLOGUES)
#define TARGET_TINY_STACK (target_flags & MASK_TINY_STACK) #define TARGET_TINY_STACK (target_flags & MASK_TINY_STACK)
#define TARGET_PACK_ARGS (target_flags & MASK_PACK_ARGS)
/* Dump each assembler insn's rtl into the output file. /* Dump each assembler insn's rtl into the output file.
This is for debugging the compiler itself. */ This is for debugging the compiler itself. */
...@@ -104,8 +102,6 @@ extern int target_flags; ...@@ -104,8 +102,6 @@ extern int target_flags;
N_("Use subroutines for function prologue/epilogue") }, \ N_("Use subroutines for function prologue/epilogue") }, \
{ "tiny-stack", MASK_TINY_STACK, \ { "tiny-stack", MASK_TINY_STACK, \
N_("Change only the low 8 bits of the stack pointer") }, \ N_("Change only the low 8 bits of the stack pointer") }, \
{ "pack-args", MASK_PACK_ARGS, \
N_("Do not align function arguments on even numbered registers") }, \
{ "rtl", MASK_RTL_DUMP, NULL }, \ { "rtl", MASK_RTL_DUMP, NULL }, \
{ "size", MASK_INSN_SIZE_DUMP, \ { "size", MASK_INSN_SIZE_DUMP, \
N_("Output instruction sizes to the asm file") }, \ N_("Output instruction sizes to the asm file") }, \
......
...@@ -182,7 +182,7 @@ ...@@ -182,7 +182,7 @@
[(set (match_operand:QI 0 "register_operand" "=l") [(set (match_operand:QI 0 "register_operand" "=l")
(match_operand:QI 1 "immediate_operand" "i")) (match_operand:QI 1 "immediate_operand" "i"))
(clobber (match_operand:QI 2 "register_operand" "=&d"))] (clobber (match_operand:QI 2 "register_operand" "=&d"))]
"" "reload_completed"
"ldi %2,lo8(%1) "ldi %2,lo8(%1)
mov %0,%2" mov %0,%2"
[(set_attr "length" "2") [(set_attr "length" "2")
...@@ -231,7 +231,7 @@ ...@@ -231,7 +231,7 @@
[(set (match_operand:HI 0 "register_operand" "=r") [(set (match_operand:HI 0 "register_operand" "=r")
(match_operand:HI 1 "immediate_operand" "i")) (match_operand:HI 1 "immediate_operand" "i"))
(clobber (match_operand:QI 2 "register_operand" "=&d"))] (clobber (match_operand:QI 2 "register_operand" "=&d"))]
"" "reload_completed"
"* return output_reload_inhi (insn, operands, NULL);" "* return output_reload_inhi (insn, operands, NULL);"
[(set_attr "length" "4") [(set_attr "length" "4")
(set_attr "cc" "none")]) (set_attr "cc" "none")])
...@@ -279,7 +279,7 @@ ...@@ -279,7 +279,7 @@
[(set (match_operand:SI 0 "register_operand" "=r") [(set (match_operand:SI 0 "register_operand" "=r")
(match_operand:SI 1 "immediate_operand" "i")) (match_operand:SI 1 "immediate_operand" "i"))
(clobber (match_operand:QI 2 "register_operand" "=&d"))] (clobber (match_operand:QI 2 "register_operand" "=&d"))]
"" "reload_completed"
"* return output_reload_insisf (insn, operands, NULL);" "* return output_reload_insisf (insn, operands, NULL);"
[(set_attr "length" "8") [(set_attr "length" "8")
(set_attr "cc" "none")]) (set_attr "cc" "none")])
...@@ -889,34 +889,74 @@ ...@@ -889,34 +889,74 @@
;; arithmetic shift left ;; arithmetic shift left
(define_insn "ashlqi3" (define_insn "ashlqi3"
[(set (match_operand:QI 0 "register_operand" "=r,!d,r,r") [(set (match_operand:QI 0 "register_operand" "=r,r,r,!d,r,r")
(ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0") (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0")
(match_operand:QI 2 "general_operand" "r,n,n,Qm")))] (match_operand:QI 2 "general_operand" "r,P,K,n,n,Qm")))]
"" ""
"* return ashlqi3_out (insn, operands, NULL);" "* return ashlqi3_out (insn, operands, NULL);"
[(set_attr "length" "5,4,6,7") [(set_attr "length" "5,1,2,4,6,9")
(set_attr "cc" "clobber,set_czn,set_czn,clobber")]) (set_attr "cc" "clobber,set_czn,set_czn,set_czn,set_czn,clobber")])
(define_insn "ashlhi3" (define_insn "ashlhi3"
[(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r") [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r")
(ashift:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0,0") (ashift:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0,0")
(match_operand:QI 2 "general_operand" "r,P,O,K,i,Qm"))) (match_operand:QI 2 "general_operand" "r,P,O,K,n,Qm")))]
(clobber (match_scratch:QI 3 "=X,X,X,X,&d,X"))]
"" ""
"* return ashlhi3_out (insn, operands, NULL);" "* return ashlhi3_out (insn, operands, NULL);"
[(set_attr "length" "7,2,2,4,5,8") [(set_attr "length" "6,2,2,4,10,10")
(set_attr "cc" "clobber,set_n,clobber,set_n,clobber,clobber")]) (set_attr "cc" "clobber,set_n,clobber,set_n,clobber,clobber")])
(define_insn "ashlsi3" (define_insn "ashlsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r") [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
(ashift:SI (match_operand:SI 1 "register_operand" "0,0,r,0,0,0") (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r,0,0,0")
(match_operand:QI 2 "general_operand" "r,P,O,K,i,Qm"))) (match_operand:QI 2 "general_operand" "r,P,O,K,n,Qm")))]
(clobber (match_scratch:QI 3 "=X,X,X,X,&d,X"))]
"" ""
"* return ashlsi3_out (insn, operands, NULL);" "* return ashlsi3_out (insn, operands, NULL);"
[(set_attr "length" "9,4,4,8,7,10") [(set_attr "length" "8,4,4,8,10,12")
(set_attr "cc" "clobber,set_n,clobber,set_n,clobber,clobber")]) (set_attr "cc" "clobber,set_n,clobber,set_n,clobber,clobber")])
;; Optimize if a scratch register from LD_REGS happens to be available.
(define_peephole2
[(match_scratch:QI 3 "d")
(set (match_operand:HI 0 "register_operand" "")
(ashift:HI (match_operand:HI 1 "register_operand" "")
(match_operand:QI 2 "const_int_operand" "")))]
""
[(parallel [(set (match_dup 0) (ashift:HI (match_dup 1) (match_dup 2)))
(clobber (match_dup 3))])]
"")
(define_insn "*ashlhi3_const"
[(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
(ashift:HI (match_operand:HI 1 "register_operand" "0,r,0,0")
(match_operand:QI 2 "const_int_operand" "P,O,K,n")))
(clobber (match_scratch:QI 3 "=X,X,X,&d"))]
"reload_completed"
"* return ashlhi3_out (insn, operands, NULL);"
[(set_attr "length" "2,2,4,10")
(set_attr "cc" "set_n,clobber,set_n,clobber")])
(define_peephole2
[(match_scratch:QI 3 "d")
(set (match_operand:SI 0 "register_operand" "")
(ashift:SI (match_operand:SI 1 "register_operand" "")
(match_operand:QI 2 "const_int_operand" "")))]
""
[(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
(clobber (match_dup 3))])]
"")
(define_insn "*ashlsi3_const"
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
(ashift:SI (match_operand:SI 1 "register_operand" "0,r,0")
(match_operand:QI 2 "const_int_operand" "P,O,n")))
(clobber (match_scratch:QI 3 "=X,X,&d"))]
"reload_completed"
"* return ashlsi3_out (insn, operands, NULL);"
[(set_attr "length" "4,4,10")
(set_attr "cc" "set_n,clobber,clobber")])
;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
;; arithmetic shift right ;; arithmetic shift right
...@@ -926,61 +966,141 @@ ...@@ -926,61 +966,141 @@
(match_operand:QI 2 "general_operand" "r,P,K,n,Qm")))] (match_operand:QI 2 "general_operand" "r,P,K,n,Qm")))]
"" ""
"* return ashrqi3_out (insn, operands, NULL);" "* return ashrqi3_out (insn, operands, NULL);"
[(set_attr "length" "5,1,2,5,7") [(set_attr "length" "5,1,2,5,9")
(set_attr "cc" "clobber,set_zn,set_zn,clobber,clobber")]) (set_attr "cc" "clobber,clobber,clobber,clobber,clobber")])
(define_insn "ashrhi3" (define_insn "ashrhi3"
[(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r") [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r")
(ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0") (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0,0")
(match_operand:QI 2 "general_operand" "r,P,K,O,i,Qm"))) (match_operand:QI 2 "general_operand" "r,P,O,K,n,Qm")))]
(clobber (match_scratch:QI 3 "=X,X,X,X,&d,X"))]
"" ""
"* return ashrhi3_out (insn, operands, NULL);" "* return ashrhi3_out (insn, operands, NULL);"
[(set_attr "length" "7,2,4,4,5,8") [(set_attr "length" "6,2,4,4,10,10")
(set_attr "cc" "clobber,clobber,clobber,clobber,clobber,clobber")]) (set_attr "cc" "clobber,clobber,set_n,clobber,clobber,clobber")])
(define_insn "ashrsi3" (define_insn "ashrsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r") [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
(ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0,0,0") (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0,0,0")
(match_operand:QI 2 "general_operand" "r,P,O,K,i,Qm"))) (match_operand:QI 2 "general_operand" "r,P,O,K,n,Qm")))]
(clobber (match_scratch:QI 3 "=X,X,X,X,&d,X"))]
"" ""
"* return ashrsi3_out (insn, operands, NULL);" "* return ashrsi3_out (insn, operands, NULL);"
[(set_attr "length" "9,4,6,8,7,10") [(set_attr "length" "8,4,6,8,10,12")
(set_attr "cc" "clobber,clobber,clobber,clobber,clobber,clobber")]) (set_attr "cc" "clobber,clobber,set_n,clobber,clobber,clobber")])
;; Optimize if a scratch register from LD_REGS happens to be available.
(define_peephole2
[(match_scratch:QI 3 "d")
(set (match_operand:HI 0 "register_operand" "")
(ashiftrt:HI (match_operand:HI 1 "register_operand" "")
(match_operand:QI 2 "const_int_operand" "")))]
""
[(parallel [(set (match_dup 0) (ashiftrt:HI (match_dup 1) (match_dup 2)))
(clobber (match_dup 3))])]
"")
(define_insn "*ashrhi3_const"
[(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
(ashiftrt:HI (match_operand:HI 1 "register_operand" "0,r,0,0")
(match_operand:QI 2 "const_int_operand" "P,O,K,n")))
(clobber (match_scratch:QI 3 "=X,X,X,&d"))]
"reload_completed"
"* return ashrhi3_out (insn, operands, NULL);"
[(set_attr "length" "2,4,4,10")
(set_attr "cc" "clobber,set_n,clobber,clobber")])
(define_peephole2
[(match_scratch:QI 3 "d")
(set (match_operand:SI 0 "register_operand" "")
(ashiftrt:SI (match_operand:SI 1 "register_operand" "")
(match_operand:QI 2 "const_int_operand" "")))]
""
[(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (match_dup 2)))
(clobber (match_dup 3))])]
"")
(define_insn "*ashrsi3_const"
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
(ashiftrt:SI (match_operand:SI 1 "register_operand" "0,r,0")
(match_operand:QI 2 "const_int_operand" "P,O,n")))
(clobber (match_scratch:QI 3 "=X,X,&d"))]
"reload_completed"
"* return ashrsi3_out (insn, operands, NULL);"
[(set_attr "length" "4,4,10")
(set_attr "cc" "clobber,set_n,clobber")])
;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
;; logical shift right ;; logical shift right
(define_insn "lshrqi3" (define_insn "lshrqi3"
[(set (match_operand:QI 0 "register_operand" "=r,d,r,r") [(set (match_operand:QI 0 "register_operand" "=r,r,r,!d,r,r")
(lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0") (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0")
(match_operand:QI 2 "general_operand" "r,n,n,Qm")))] (match_operand:QI 2 "general_operand" "r,P,K,n,n,Qm")))]
"" ""
"* return lshrqi3_out (insn, operands, NULL);" "* return lshrqi3_out (insn, operands, NULL);"
[(set_attr "length" "6,4,6,7") [(set_attr "length" "5,1,2,4,6,9")
(set_attr "cc" "clobber,set_czn,set_czn,clobber")]) (set_attr "cc" "clobber,set_czn,set_czn,set_czn,set_czn,clobber")])
(define_insn "lshrhi3" (define_insn "lshrhi3"
[(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r") [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r")
(lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0") (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0,0")
(match_operand:QI 2 "general_operand" "r,P,K,O,i,Qm"))) (match_operand:QI 2 "general_operand" "r,P,O,K,n,Qm")))]
(clobber (match_scratch:QI 3 "=X,X,X,X,&d,X"))]
"" ""
"* return lshrhi3_out (insn, operands, NULL);" "* return lshrhi3_out (insn, operands, NULL);"
[(set_attr "length" "7,2,4,2,5,8") [(set_attr "length" "6,2,2,4,10,10")
(set_attr "cc" "clobber,clobber,clobber,clobber,clobber,clobber")]) (set_attr "cc" "clobber,clobber,clobber,clobber,clobber,clobber")])
(define_insn "lshrsi3" (define_insn "lshrsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r") [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
(lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0,0,0") (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0,0,0")
(match_operand:QI 2 "general_operand" "r,P,O,K,i,Qm"))) (match_operand:QI 2 "general_operand" "r,P,O,K,n,Qm")))]
(clobber (match_scratch:QI 3 "=X,X,X,X,&d,X"))]
"" ""
"* return lshrsi3_out (insn, operands, NULL);" "* return lshrsi3_out (insn, operands, NULL);"
[(set_attr "length" "9,4,4,8,7,10") [(set_attr "length" "8,4,4,8,10,12")
(set_attr "cc" "clobber,clobber,clobber,clobber,clobber,clobber")]) (set_attr "cc" "clobber,clobber,clobber,clobber,clobber,clobber")])
;; Optimize if a scratch register from LD_REGS happens to be available.
(define_peephole2
[(match_scratch:QI 3 "d")
(set (match_operand:HI 0 "register_operand" "")
(lshiftrt:HI (match_operand:HI 1 "register_operand" "")
(match_operand:QI 2 "const_int_operand" "")))]
""
[(parallel [(set (match_dup 0) (lshiftrt:HI (match_dup 1) (match_dup 2)))
(clobber (match_dup 3))])]
"")
(define_insn "*lshrhi3_const"
[(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
(lshiftrt:HI (match_operand:HI 1 "register_operand" "0,r,0,0")
(match_operand:QI 2 "const_int_operand" "P,O,K,n")))
(clobber (match_scratch:QI 3 "=X,X,X,&d"))]
"reload_completed"
"* return lshrhi3_out (insn, operands, NULL);"
[(set_attr "length" "2,2,4,10")
(set_attr "cc" "clobber,clobber,clobber,clobber")])
(define_peephole2
[(match_scratch:QI 3 "d")
(set (match_operand:SI 0 "register_operand" "")
(lshiftrt:SI (match_operand:SI 1 "register_operand" "")
(match_operand:QI 2 "const_int_operand" "")))]
""
[(parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (match_dup 2)))
(clobber (match_dup 3))])]
"")
(define_insn "*lshrsi3_const"
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
(lshiftrt:SI (match_operand:SI 1 "register_operand" "0,r,0")
(match_operand:QI 2 "const_int_operand" "P,O,n")))
(clobber (match_scratch:QI 3 "=X,X,&d"))]
"reload_completed"
"* return lshrsi3_out (insn, operands, NULL);"
[(set_attr "length" "4,4,10")
(set_attr "cc" "clobber,clobber,clobber")])
;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
;; abs ;; abs
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment