avr-protos.h (avr_out_sign_extend): New.
* avr-protos.h (avr_out_sign_extend): New. * avr.c (avr_adjust_insn_length) [ADJUST_LEN_SEXT]: Handle. (avr_out_sign_extend): New function. * avr.md (extendqihi2, extendqipsi2, extendqisi2, extendhipsi2) (extendhisi2, extendpsisi2): Use it. (adjust_len) [sext]: New. From-SVN: r216668
This commit is contained in:
parent
709def90a4
commit
8e3d9e673a
4 changed files with 95 additions and 30 deletions
|
@ -1,3 +1,12 @@
|
|||
2014-10-24 Georg-Johann Lay <avr@gjlay.de>
|
||||
|
||||
* avr-protos.h (avr_out_sign_extend): New.
|
||||
* avr.c (avr_adjust_insn_length) [ADJUST_LEN_SEXT]: Handle.
|
||||
(avr_out_sign_extend): New function.
|
||||
* avr.md (extendqihi2, extendqipsi2, extendqisi2, extendhipsi2)
|
||||
(extendhisi2, extendpsisi2): Use it.
|
||||
(adjust_len) [sext]: New.
|
||||
|
||||
2014-10-24 Martin Liska <mliska@suse.cz>
|
||||
|
||||
* ipa-icf.c (sem_function::compare_phi_node): PHI result comparison
|
||||
|
|
|
@ -57,6 +57,7 @@ extern const char *avr_out_compare (rtx_insn *, rtx*, int*);
|
|||
extern const char *avr_out_compare64 (rtx_insn *, rtx*, int*);
|
||||
extern const char *ret_cond_branch (rtx x, int len, int reverse);
|
||||
extern const char *avr_out_movpsi (rtx_insn *, rtx*, int*);
|
||||
extern const char *avr_out_sign_extend (rtx_insn *, rtx*, int*);
|
||||
|
||||
extern const char *ashlqi3_out (rtx_insn *insn, rtx operands[], int *len);
|
||||
extern const char *ashlhi3_out (rtx_insn *insn, rtx operands[], int *len);
|
||||
|
|
|
@ -7734,6 +7734,56 @@ avr_out_bitop (rtx insn, rtx *xop, int *plen)
|
|||
}
|
||||
|
||||
|
||||
/* Output sign extension from XOP[1] to XOP[0] and return "".
|
||||
If PLEN == NULL, print assembler instructions to perform the operation;
|
||||
otherwise, set *PLEN to the length of the instruction sequence (in words)
|
||||
as printed with PLEN == NULL. */
|
||||
|
||||
const char*
|
||||
avr_out_sign_extend (rtx_insn *insn, rtx *xop, int *plen)
|
||||
{
|
||||
// Size in bytes of source resp. destination operand.
|
||||
unsigned n_src = GET_MODE_SIZE (GET_MODE (xop[1]));
|
||||
unsigned n_dest = GET_MODE_SIZE (GET_MODE (xop[0]));
|
||||
rtx r_msb = all_regs_rtx[REGNO (xop[1]) + n_src - 1];
|
||||
|
||||
if (plen)
|
||||
*plen = 0;
|
||||
|
||||
// Copy destination to source
|
||||
|
||||
if (REGNO (xop[0]) != REGNO (xop[1]))
|
||||
{
|
||||
gcc_assert (n_src <= 2);
|
||||
|
||||
if (n_src == 2)
|
||||
avr_asm_len (AVR_HAVE_MOVW
|
||||
? "movw %0,%1"
|
||||
: "mov %B0,%B1", xop, plen, 1);
|
||||
if (n_src == 1 || !AVR_HAVE_MOVW)
|
||||
avr_asm_len ("mov %A0,%A1", xop, plen, 1);
|
||||
}
|
||||
|
||||
// Set Carry to the sign bit MSB.7...
|
||||
|
||||
if (REGNO (xop[0]) == REGNO (xop[1])
|
||||
|| !reg_unused_after (insn, r_msb))
|
||||
{
|
||||
avr_asm_len ("mov __tmp_reg__,%0", &r_msb, plen, 1);
|
||||
r_msb = tmp_reg_rtx;
|
||||
}
|
||||
|
||||
avr_asm_len ("lsl %0", &r_msb, plen, 1);
|
||||
|
||||
// ...and propagate it to all the new sign bits
|
||||
|
||||
for (unsigned n = n_src; n < n_dest; n++)
|
||||
avr_asm_len ("sbc %0,%0", &all_regs_rtx[REGNO (xop[0]) + n], plen, 1);
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/* PLEN == NULL: Output code to add CONST_INT OP[0] to SP.
|
||||
PLEN != NULL: Set *PLEN to the length of that sequence.
|
||||
Return "". */
|
||||
|
@ -8578,6 +8628,7 @@ avr_adjust_insn_length (rtx_insn *insn, int len)
|
|||
case ADJUST_LEN_MOVMEM: avr_out_movmem (insn, op, &len); break;
|
||||
case ADJUST_LEN_XLOAD: avr_out_xload (insn, op, &len); break;
|
||||
case ADJUST_LEN_LPM: avr_out_lpm (insn, op, &len); break;
|
||||
case ADJUST_LEN_SEXT: avr_out_sign_extend (insn, op, &len); break;
|
||||
|
||||
case ADJUST_LEN_SFRACT: avr_out_fract (insn, op, true, &len); break;
|
||||
case ADJUST_LEN_UFRACT: avr_out_fract (insn, op, false, &len); break;
|
||||
|
|
|
@ -147,7 +147,7 @@
|
|||
;; Otherwise do special processing depending on the attribute.
|
||||
|
||||
(define_attr "adjust_len"
|
||||
"out_bitop, plus, addto_sp,
|
||||
"out_bitop, plus, addto_sp, sext,
|
||||
tsthi, tstpsi, tstsi, compare, compare64, call,
|
||||
mov8, mov16, mov24, mov32, reload_in16, reload_in24, reload_in32,
|
||||
ufract, sfract, round,
|
||||
|
@ -4174,62 +4174,66 @@
|
|||
[(set (match_operand:HI 0 "register_operand" "=r,r")
|
||||
(sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
|
||||
""
|
||||
"@
|
||||
clr %B0\;sbrc %0,7\;com %B0
|
||||
mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
|
||||
{
|
||||
return avr_out_sign_extend (insn, operands, NULL);
|
||||
}
|
||||
[(set_attr "length" "3,4")
|
||||
(set_attr "cc" "set_n,set_n")])
|
||||
(set_attr "adjust_len" "sext")
|
||||
(set_attr "cc" "set_n")])
|
||||
|
||||
(define_insn "extendqipsi2"
|
||||
[(set (match_operand:PSI 0 "register_operand" "=r,r")
|
||||
(sign_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
|
||||
""
|
||||
"@
|
||||
clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0
|
||||
mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0"
|
||||
{
|
||||
return avr_out_sign_extend (insn, operands, NULL);
|
||||
}
|
||||
[(set_attr "length" "4,5")
|
||||
(set_attr "cc" "set_n,set_n")])
|
||||
(set_attr "adjust_len" "sext")
|
||||
(set_attr "cc" "set_n")])
|
||||
|
||||
(define_insn "extendqisi2"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
||||
(sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
|
||||
""
|
||||
"@
|
||||
clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
|
||||
mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
|
||||
{
|
||||
return avr_out_sign_extend (insn, operands, NULL);
|
||||
}
|
||||
[(set_attr "length" "5,6")
|
||||
(set_attr "cc" "set_n,set_n")])
|
||||
(set_attr "adjust_len" "sext")
|
||||
(set_attr "cc" "set_n")])
|
||||
|
||||
(define_insn "extendhipsi2"
|
||||
[(set (match_operand:PSI 0 "register_operand" "=r,r ,r")
|
||||
(sign_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
|
||||
[(set (match_operand:PSI 0 "register_operand" "=r,r")
|
||||
(sign_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))]
|
||||
""
|
||||
"@
|
||||
clr %C0\;sbrc %B0,7\;com %C0
|
||||
mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0
|
||||
movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0"
|
||||
[(set_attr "length" "3,5,4")
|
||||
(set_attr "isa" "*,mov,movw")
|
||||
{
|
||||
return avr_out_sign_extend (insn, operands, NULL);
|
||||
}
|
||||
[(set_attr "length" "3,5")
|
||||
(set_attr "adjust_len" "sext")
|
||||
(set_attr "cc" "set_n")])
|
||||
|
||||
(define_insn "extendhisi2"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r,r ,r")
|
||||
(sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
|
||||
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
||||
(sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))]
|
||||
""
|
||||
"@
|
||||
clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
|
||||
mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
|
||||
movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
|
||||
[(set_attr "length" "4,6,5")
|
||||
(set_attr "isa" "*,mov,movw")
|
||||
{
|
||||
return avr_out_sign_extend (insn, operands, NULL);
|
||||
}
|
||||
[(set_attr "length" "4,6")
|
||||
(set_attr "adjust_len" "sext")
|
||||
(set_attr "cc" "set_n")])
|
||||
|
||||
(define_insn "extendpsisi2"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(sign_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "0")))]
|
||||
""
|
||||
"clr %D0\;sbrc %C0,7\;com %D0"
|
||||
{
|
||||
return avr_out_sign_extend (insn, operands, NULL);
|
||||
}
|
||||
[(set_attr "length" "3")
|
||||
(set_attr "adjust_len" "sext")
|
||||
(set_attr "cc" "set_n")])
|
||||
|
||||
;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
|
||||
|
|
Loading…
Add table
Reference in a new issue