Commit be88b0c7 by Georg-Johann Lay Committed by Georg-Johann Lay

predicates.md (const_m255_to_m1_operand): New.

	* config/avr/predicates.md (const_m255_to_m1_operand): New.
	* config/avr/constraints.md (Cn8, Ca1, Co1, Yx2): New constraints.
	* config/avr/avr.md (add<mode>3) <ALL1>: Make "r,0,r" more
	expensive.
	(*cmphi.zero-extend.0, *cmphi.zero-extend.1)
	(*usum_widenqihi3, *udiff_widenqihi3)
	(*addhi3_zero_extend.const): New combiner insns.
	(andqi3, iorqi3): Provide "l" (NO_LD_REGS) alternative if
	just 1 bit is affected.
	* config/avr/avr.c (avr_out_bitop) <QImode>: Don't access xop[3].
	(avr_out_compare) [EQ,NE]: Tweak comparing d-regs against -1.

From-SVN: r238381
parent 5eed9a88
2016-07-15 Georg-Johann Lay <avr@gjlay.de>
* config/avr/predicates.md (const_m255_to_m1_operand): New.
* config/avr/constraints.md (Cn8, Ca1, Co1, Yx2): New constraints.
* config/avr/avr.md (add<mode>3) <ALL1>: Make "r,0,r" more
expensive.
(*cmphi.zero-extend.0, *cmphi.zero-extend.1)
(*usum_widenqihi3, *udiff_widenqihi3)
(*addhi3_zero_extend.const): New combiner insns.
(andqi3, iorqi3): Provide "l" (NO_LD_REGS) alternative if
just 1 bit is affected.
* config/avr/avr.c (avr_out_bitop) <QImode>: Don't access xop[3].
(avr_out_compare) [EQ,NE]: Tweak comparing d-regs against -1.
2016-07-15 Cesar Philippidis <cesar@codesourcery.com> 2016-07-15 Cesar Philippidis <cesar@codesourcery.com>
* omp-low.c (lower_omp_target): Mark data clauses with * omp-low.c (lower_omp_target): Mark data clauses with
......
...@@ -5346,6 +5346,34 @@ avr_out_compare (rtx_insn *insn, rtx *xop, int *plen) ...@@ -5346,6 +5346,34 @@ avr_out_compare (rtx_insn *insn, rtx *xop, int *plen)
} }
} }
/* Comparisons == -1 and != -1 of a d-register that's used after the
comparison. (If it's unused after we use CPI / SBCI or ADIW sequence
from below.) Instead of CPI Rlo,-1 / LDI Rx,-1 / CPC Rhi,Rx we can
use CPI Rlo,-1 / CPC Rhi,Rlo which is 1 instruction shorter:
If CPI is true then Rlo contains -1 and we can use Rlo instead of Rx
when CPC'ing the high part. If CPI is false then CPC cannot render
the result to true. This also works for the more generic case where
the constant is of the form 0xabab. */
if (n_bytes == 2
&& xval != 0
&& test_hard_reg_class (LD_REGS, xreg)
&& compare_eq_p (insn)
&& !reg_unused_after (insn, xreg))
{
rtx xlo8 = simplify_gen_subreg (QImode, xval, mode, 0);
rtx xhi8 = simplify_gen_subreg (QImode, xval, mode, 1);
if (INTVAL (xlo8) == INTVAL (xhi8))
{
xop[0] = xreg;
xop[1] = xlo8;
return avr_asm_len ("cpi %A0,%1" CR_TAB
"cpc %B0,%A0", xop, plen, 2);
}
}
for (i = 0; i < n_bytes; i++) for (i = 0; i < n_bytes; i++)
{ {
/* We compare byte-wise. */ /* We compare byte-wise. */
...@@ -7687,11 +7715,11 @@ avr_out_bitop (rtx insn, rtx *xop, int *plen) ...@@ -7687,11 +7715,11 @@ avr_out_bitop (rtx insn, rtx *xop, int *plen)
/* op[0]: 8-bit destination register /* op[0]: 8-bit destination register
op[1]: 8-bit const int op[1]: 8-bit const int
op[2]: 8-bit clobber register or SCRATCH op[2]: 8-bit clobber register, SCRATCH or NULL_RTX.
op[3]: 8-bit register containing 0xff or NULL_RTX */ op[3]: 8-bit register containing 0xff or NULL_RTX */
rtx op[4]; rtx op[4];
op[2] = xop[3]; op[2] = QImode == mode ? NULL_RTX : xop[3];
op[3] = NULL_RTX; op[3] = NULL_RTX;
if (plen) if (plen)
......
...@@ -1175,7 +1175,7 @@ ...@@ -1175,7 +1175,7 @@
inc %0\;inc %0 inc %0\;inc %0
dec %0\;dec %0" dec %0\;dec %0"
[(set_attr "length" "1,1,1,1,2,2") [(set_attr "length" "1,1,1,1,2,2")
(set_attr "cc" "set_czn,set_czn,set_vzn,set_vzn,set_vzn,set_vzn")]) (set_attr "cc" "set_czn,set_czn,set_vzn,set_vzn,set_zn,set_zn")])
;; "addhi3" ;; "addhi3"
;; "addhq3" "adduhq3" ;; "addhq3" "adduhq3"
...@@ -1240,6 +1240,33 @@ ...@@ -1240,6 +1240,33 @@
[(set_attr "length" "5") [(set_attr "length" "5")
(set_attr "cc" "clobber")]) (set_attr "cc" "clobber")])
(define_insn "*addhi3_zero_extend.const"
[(set (match_operand:HI 0 "register_operand" "=d")
(plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
(match_operand:HI 2 "const_m255_to_m1_operand" "Cn8")))]
""
"subi %A0,%n2\;sbc %B0,%B0"
[(set_attr "length" "2")
(set_attr "cc" "set_czn")])
(define_insn "*usum_widenqihi3"
[(set (match_operand:HI 0 "register_operand" "=r")
(plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
(zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
""
"add %A0,%2\;clr %B0\;rol %B0"
[(set_attr "length" "3")
(set_attr "cc" "clobber")])
(define_insn "*udiff_widenqihi3"
[(set (match_operand:HI 0 "register_operand" "=r")
(minus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
(zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
""
"sub %A0,%2\;sbc %B0,%B0"
[(set_attr "length" "2")
(set_attr "cc" "set_czn")])
(define_insn "*addhi3_sp" (define_insn "*addhi3_sp"
[(set (match_operand:HI 1 "stack_register_operand" "=q") [(set (match_operand:HI 1 "stack_register_operand" "=q")
(plus:HI (match_operand:HI 2 "stack_register_operand" "q") (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
...@@ -3102,15 +3129,16 @@ ...@@ -3102,15 +3129,16 @@
; and ; and
(define_insn "andqi3" (define_insn "andqi3"
[(set (match_operand:QI 0 "register_operand" "=??r,d") [(set (match_operand:QI 0 "register_operand" "=??r,d,*l")
(and:QI (match_operand:QI 1 "register_operand" "%0,0") (and:QI (match_operand:QI 1 "register_operand" "%0,0,0")
(match_operand:QI 2 "nonmemory_operand" "r,i")))] (match_operand:QI 2 "nonmemory_operand" "r,i,Ca1")))]
"" ""
"@ "@
and %0,%2 and %0,%2
andi %0,lo8(%2)" andi %0,lo8(%2)
[(set_attr "length" "1,1") * return avr_out_bitop (insn, operands, NULL);"
(set_attr "cc" "set_zn,set_zn")]) [(set_attr "length" "1,1,2")
(set_attr "cc" "set_zn,set_zn,none")])
(define_insn "andhi3" (define_insn "andhi3"
[(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r") [(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r")
...@@ -3184,15 +3212,16 @@ ...@@ -3184,15 +3212,16 @@
;; ior ;; ior
(define_insn "iorqi3" (define_insn "iorqi3"
[(set (match_operand:QI 0 "register_operand" "=??r,d") [(set (match_operand:QI 0 "register_operand" "=??r,d,*l")
(ior:QI (match_operand:QI 1 "register_operand" "%0,0") (ior:QI (match_operand:QI 1 "register_operand" "%0,0,0")
(match_operand:QI 2 "nonmemory_operand" "r,i")))] (match_operand:QI 2 "nonmemory_operand" "r,i,Co1")))]
"" ""
"@ "@
or %0,%2 or %0,%2
ori %0,lo8(%2)" ori %0,lo8(%2)
[(set_attr "length" "1,1") * return avr_out_bitop (insn, operands, NULL);"
(set_attr "cc" "set_zn,set_zn")]) [(set_attr "length" "1,1,2")
(set_attr "cc" "set_zn,set_zn,none")])
(define_insn "iorhi3" (define_insn "iorhi3"
[(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r") [(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r")
...@@ -4607,6 +4636,25 @@ ...@@ -4607,6 +4636,25 @@
[(set_attr "cc" "compare") [(set_attr "cc" "compare")
(set_attr "length" "1")]) (set_attr "length" "1")])
(define_insn "*cmphi.zero-extend.0"
[(set (cc0)
(compare (zero_extend:HI (match_operand:QI 0 "register_operand" "r"))
(match_operand:HI 1 "register_operand" "r")))]
""
"cp %0,%A1\;cpc __zero_reg__,%B1"
[(set_attr "cc" "compare")
(set_attr "length" "2")])
(define_insn "*cmphi.zero-extend.1"
[(set (cc0)
(compare (match_operand:HI 0 "register_operand" "r")
(zero_extend:HI (match_operand:QI 1 "register_operand" "r"))))]
""
"cp %A0,%1\;cpc %B0,__zero_reg__"
[(set_attr "cc" "compare")
(set_attr "length" "2")])
;; "*cmphi" ;; "*cmphi"
;; "*cmphq" "*cmpuhq" ;; "*cmphq" "*cmpuhq"
;; "*cmpha" "*cmpuha" ;; "*cmpha" "*cmpuha"
......
...@@ -133,6 +133,11 @@ ...@@ -133,6 +133,11 @@
(and (match_code "const_int") (and (match_code "const_int")
(match_test "ival == 7"))) (match_test "ival == 7")))
(define_constraint "Ca1"
"Constant 1-byte integer that allows AND by means of CLT + BLD."
(and (match_code "const_int")
(match_test "avr_popcount_each_byte (op, 1, 1<<7)")))
(define_constraint "Ca2" (define_constraint "Ca2"
"Constant 2-byte integer that allows AND without clobber register." "Constant 2-byte integer that allows AND without clobber register."
(and (match_code "const_int") (and (match_code "const_int")
...@@ -148,6 +153,11 @@ ...@@ -148,6 +153,11 @@
(and (match_code "const_int") (and (match_code "const_int")
(match_test "avr_popcount_each_byte (op, 4, (1<<0) | (1<<7) | (1<<8))"))) (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."
(and (match_code "const_int")
(match_test "avr_popcount_each_byte (op, 1, 1<<1)")))
(define_constraint "Co2" (define_constraint "Co2"
"Constant 2-byte integer that allows OR without clobber register." "Constant 2-byte integer that allows OR without clobber register."
(and (match_code "const_int") (and (match_code "const_int")
...@@ -193,6 +203,11 @@ ...@@ -193,6 +203,11 @@
(and (match_code "const_int") (and (match_code "const_int")
(match_test "!avr_has_nibble_0xf (op)"))) (match_test "!avr_has_nibble_0xf (op)")))
(define_constraint "Cn8"
"A negative constant integer in the range @minus{}255 @dots{} @minus{}1."
(and (match_code "const_int")
(match_test "IN_RANGE (ival, -255, -1)")))
;; CONST_FIXED is no element of 'n' so cook our own. ;; CONST_FIXED is no element of 'n' so cook our own.
;; "i" or "s" would match but because the insn uses iterators that cover ;; "i" or "s" would match but because the insn uses iterators that cover
;; INT_MODE, "i" or "s" is not always possible. ;; INT_MODE, "i" or "s" is not always possible.
...@@ -230,6 +245,12 @@ ...@@ -230,6 +245,12 @@
(match_test "-2 == INTVAL (avr_to_int_mode (op))")) (match_test "-2 == INTVAL (avr_to_int_mode (op))"))
(match_test "satisfies_constraint_Cm2 (op)"))) (match_test "satisfies_constraint_Cm2 (op)")))
(define_constraint "Yx2"
"Fixed-point or integer constant not in the range @minus{}2 @dots{} 2"
(and (ior (match_code "const_int")
(match_code "const_fixed"))
(match_test "!IN_RANGE (INTVAL (avr_to_int_mode (op)), -2, 2)")))
;; Similar to "IJ" used with ADIW/SBIW, but for CONST_FIXED. ;; Similar to "IJ" used with ADIW/SBIW, but for CONST_FIXED.
(define_constraint "YIJ" (define_constraint "YIJ"
......
...@@ -114,6 +114,11 @@ ...@@ -114,6 +114,11 @@
(and (match_code "const_int") (and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), 2, 6)"))) (match_test "IN_RANGE (INTVAL (op), 2, 6)")))
;; Return 1 if OP is constant integer -255..-1.
(define_predicate "const_m255_to_m1_operand"
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), -255, -1)")))
;; Returns true if OP is either the constant zero or a register. ;; Returns true if OP is either the constant zero or a register.
(define_predicate "reg_or_0_operand" (define_predicate "reg_or_0_operand"
(ior (match_operand 0 "register_operand") (ior (match_operand 0 "register_operand")
......
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