avr.md - Tweak xor insn constraints.
xor insn can handle some more values without the requirement of a scratch register. This patch adds a new constraint alternative for such values. The output function avr_out_bitop already handles these cases, so no change is needed there. gcc/ * config/avr/constraints.md (CX2, CX3, CX4): New constraints. * config/avr/avr-protos.h (avr_xor_noclobber_dconst): New proto. * config/avr/avr.cc (avr_xor_noclobber_dconst): New function. * config/avr/avr.md (xorhi3, *xorhi3): Add "d,0,CX2,X" alternative. (xorpsi3, *xorpsi3): Add "d,0,CX3,X" alternative. (xorsi3, *xorsi3): Add "d,0,CX4,X" alternative.
This commit is contained in:
parent
58753dba80
commit
9361f19e08
4 changed files with 72 additions and 31 deletions
|
@ -101,6 +101,7 @@ extern const char* avr_out_xload (rtx_insn *, rtx*, int*);
|
|||
extern const char* avr_out_cpymem (rtx_insn *, rtx*, int*);
|
||||
extern const char* avr_out_insert_bits (rtx*, int*);
|
||||
extern bool avr_popcount_each_byte (rtx, int, int);
|
||||
extern bool avr_xor_noclobber_dconst (rtx, int);
|
||||
extern bool avr_has_nibble_0xf (rtx);
|
||||
|
||||
extern int extra_constraint_Q (rtx x);
|
||||
|
|
|
@ -281,6 +281,31 @@ avr_popcount_each_byte (rtx xval, int n_bytes, int pop_mask)
|
|||
}
|
||||
|
||||
|
||||
/* Constraint helper function. XVAL is a CONST_INT. Return true if we
|
||||
can perform XOR without a clobber reg, provided the operation is on
|
||||
a d-register. This means each byte is in { 0, 0xff, 0x80 }. */
|
||||
|
||||
bool
|
||||
avr_xor_noclobber_dconst (rtx xval, int n_bytes)
|
||||
{
|
||||
machine_mode mode = GET_MODE (xval);
|
||||
|
||||
if (VOIDmode == mode)
|
||||
mode = SImode;
|
||||
|
||||
for (int i = 0; i < n_bytes; ++i)
|
||||
{
|
||||
rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
|
||||
unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
|
||||
|
||||
if (val8 != 0 && val8 != 0xff && val8 != 0x80)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Access some RTX as INT_MODE. If X is a CONST_FIXED we can get
|
||||
the bit representation of X by "casting" it to CONST_INT. */
|
||||
|
||||
|
|
|
@ -4741,10 +4741,10 @@
|
|||
[(set_attr "length" "1")])
|
||||
|
||||
(define_insn_and_split "xorhi3"
|
||||
[(set (match_operand:HI 0 "register_operand" "=??r,r ,r")
|
||||
(xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0")
|
||||
(match_operand:HI 2 "nonmemory_operand" "r,Cx2,n")))
|
||||
(clobber (match_scratch:QI 3 "=X,X ,&d"))]
|
||||
[(set (match_operand:HI 0 "register_operand" "=??r,r ,d ,r")
|
||||
(xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0 ,0")
|
||||
(match_operand:HI 2 "nonmemory_operand" "r,Cx2,CX2,n")))
|
||||
(clobber (match_scratch:QI 3 "=X,X ,X ,&d"))]
|
||||
""
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
|
@ -4755,10 +4755,10 @@
|
|||
(clobber (reg:CC REG_CC))])])
|
||||
|
||||
(define_insn "*xorhi3"
|
||||
[(set (match_operand:HI 0 "register_operand" "=??r,r ,r")
|
||||
(xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0")
|
||||
(match_operand:HI 2 "nonmemory_operand" "r,Cx2,n")))
|
||||
(clobber (match_scratch:QI 3 "=X,X ,&d"))
|
||||
[(set (match_operand:HI 0 "register_operand" "=??r,r ,d ,r")
|
||||
(xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0 ,0")
|
||||
(match_operand:HI 2 "nonmemory_operand" "r,Cx2,CX2,n")))
|
||||
(clobber (match_scratch:QI 3 "=X,X ,X ,&d"))
|
||||
(clobber (reg:CC REG_CC))]
|
||||
"reload_completed"
|
||||
{
|
||||
|
@ -4767,14 +4767,14 @@
|
|||
|
||||
return avr_out_bitop (insn, operands, NULL);
|
||||
}
|
||||
[(set_attr "length" "2,2,4")
|
||||
(set_attr "adjust_len" "*,out_bitop,out_bitop")])
|
||||
[(set_attr "length" "2,2,4,4")
|
||||
(set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")])
|
||||
|
||||
(define_insn_and_split "xorpsi3"
|
||||
[(set (match_operand:PSI 0 "register_operand" "=??r,r ,r")
|
||||
(xor:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0")
|
||||
(match_operand:PSI 2 "nonmemory_operand" "r,Cx3,n")))
|
||||
(clobber (match_scratch:QI 3 "=X,X ,&d"))]
|
||||
[(set (match_operand:PSI 0 "register_operand" "=??r,r ,d ,r")
|
||||
(xor:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0 ,0")
|
||||
(match_operand:PSI 2 "nonmemory_operand" "r,Cx3,CX3,n")))
|
||||
(clobber (match_scratch:QI 3 "=X,X ,X ,&d"))]
|
||||
""
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
|
@ -4785,10 +4785,10 @@
|
|||
(clobber (reg:CC REG_CC))])])
|
||||
|
||||
(define_insn "*xorpsi3"
|
||||
[(set (match_operand:PSI 0 "register_operand" "=??r,r ,r")
|
||||
(xor:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0")
|
||||
(match_operand:PSI 2 "nonmemory_operand" "r,Cx3,n")))
|
||||
(clobber (match_scratch:QI 3 "=X,X ,&d"))
|
||||
[(set (match_operand:PSI 0 "register_operand" "=??r,r ,d ,r")
|
||||
(xor:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0 ,0")
|
||||
(match_operand:PSI 2 "nonmemory_operand" "r,Cx3,CX3,n")))
|
||||
(clobber (match_scratch:QI 3 "=X,X ,X ,&d"))
|
||||
(clobber (reg:CC REG_CC))]
|
||||
"reload_completed"
|
||||
{
|
||||
|
@ -4799,14 +4799,14 @@
|
|||
|
||||
return avr_out_bitop (insn, operands, NULL);
|
||||
}
|
||||
[(set_attr "length" "3,6,6")
|
||||
(set_attr "adjust_len" "*,out_bitop,out_bitop")])
|
||||
[(set_attr "length" "3,6,6,6")
|
||||
(set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")])
|
||||
|
||||
(define_insn_and_split "xorsi3"
|
||||
[(set (match_operand:SI 0 "register_operand" "=??r,r ,r")
|
||||
(xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0")
|
||||
(match_operand:SI 2 "nonmemory_operand" "r,Cx4,n")))
|
||||
(clobber (match_scratch:QI 3 "=X,X ,&d"))]
|
||||
[(set (match_operand:SI 0 "register_operand" "=??r,r ,d ,r")
|
||||
(xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0 ,0")
|
||||
(match_operand:SI 2 "nonmemory_operand" "r,Cx4,CX4,n")))
|
||||
(clobber (match_scratch:QI 3 "=X,X ,X ,&d"))]
|
||||
""
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
|
@ -4817,10 +4817,10 @@
|
|||
(clobber (reg:CC REG_CC))])])
|
||||
|
||||
(define_insn "*xorsi3"
|
||||
[(set (match_operand:SI 0 "register_operand" "=??r,r ,r")
|
||||
(xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0")
|
||||
(match_operand:SI 2 "nonmemory_operand" "r,Cx4,n")))
|
||||
(clobber (match_scratch:QI 3 "=X,X ,&d"))
|
||||
[(set (match_operand:SI 0 "register_operand" "=??r,r ,d ,r")
|
||||
(xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0 ,0")
|
||||
(match_operand:SI 2 "nonmemory_operand" "r,Cx4,CX4,n")))
|
||||
(clobber (match_scratch:QI 3 "=X,X ,X ,&d"))
|
||||
(clobber (reg:CC REG_CC))]
|
||||
"reload_completed"
|
||||
{
|
||||
|
@ -4832,8 +4832,8 @@
|
|||
|
||||
return avr_out_bitop (insn, operands, NULL);
|
||||
}
|
||||
[(set_attr "length" "4,8,8")
|
||||
(set_attr "adjust_len" "*,out_bitop,out_bitop")])
|
||||
[(set_attr "length" "4,8,8,8")
|
||||
(set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")])
|
||||
|
||||
|
||||
(define_split
|
||||
|
|
|
@ -169,7 +169,7 @@
|
|||
(match_test "avr_popcount_each_byte (op, 4, (1<<0) | (1<<7) | (1<<8))")))
|
||||
|
||||
(define_constraint "Co1"
|
||||
"Constant 1-byte integer that allows AND by means of SET + BLD."
|
||||
"Constant 1-byte integer that allows OR by means of SET + BLD."
|
||||
(and (match_code "const_int")
|
||||
(match_test "avr_popcount_each_byte (op, 1, 1<<1)")))
|
||||
|
||||
|
@ -218,6 +218,21 @@
|
|||
(and (match_code "const_int")
|
||||
(match_test "avr_popcount_each_byte (op, 4, (1<<0) | (1<<8))")))
|
||||
|
||||
(define_constraint "CX2"
|
||||
"Constant 2-byte integer that allows XOR without clobber register but requires a d-register."
|
||||
(and (match_code "const_int")
|
||||
(match_test "avr_xor_noclobber_dconst (op, 2)")))
|
||||
|
||||
(define_constraint "CX3"
|
||||
"Constant 3-byte integer that allows XOR without clobber register but requires a d-register."
|
||||
(and (match_code "const_int")
|
||||
(match_test "avr_xor_noclobber_dconst (op, 3)")))
|
||||
|
||||
(define_constraint "CX4"
|
||||
"Constant 4-byte integer that allows XOR without clobber register but requires a d-register."
|
||||
(and (match_code "const_int")
|
||||
(match_test "avr_xor_noclobber_dconst (op, 4)")))
|
||||
|
||||
(define_constraint "Csp"
|
||||
"Integer constant in the range -11 @dots{} 6."
|
||||
(and (match_code "const_int")
|
||||
|
|
Loading…
Add table
Reference in a new issue