Commit 23fed240 by DJ Delorie Committed by DJ Delorie

shift.md: Rewrite...

* config/m32c/shift.md: Rewrite: Allow arbitrary operands for
shift counts, separate SI shifts for m32c vs m16c, pass shift type
so that constant shifts can be split.
* config/m32c/m32c.c (m32c_const_ok_for_constraint_p): Add In6.
(m32c_valid_pointer_mode): Make static.
(shift_gen_func_for): New.
(m32c_prepare_shift): Use it.  Split large const shifts into
multiple shifts.
* config/m32c/predicates.md (shiftcount_operand): Allow more
general operands.
(longshiftcount_operand): New.
* doc/md.texi (Machine Constraints): Document In6.

From-SVN: r109661
parent dadb213f
2006-01-12 DJ Delorie <dj@redhat.com>
* config/m32c/shift.md: Rewrite: Allow arbitrary operands for
shift counts, separate SI shifts for m32c vs m16c, pass shift type
so that constant shifts can be split.
* config/m32c/m32c.c (m32c_const_ok_for_constraint_p): Add In6.
(m32c_valid_pointer_mode): Make static.
(shift_gen_func_for): New.
(m32c_prepare_shift): Use it. Split large const shifts into
multiple shifts.
* config/m32c/predicates.md (shiftcount_operand): Allow more
general operands.
(longshiftcount_operand): New.
* doc/md.texi (Machine Constraints): Document In6.
2006-01-13 Ben Elliston <bje@au.ibm.com>
* doc/tm.texi (Data Output): Add REAL_VALUE_TO_TARGET_DECIMAL32,
......
......@@ -901,6 +901,10 @@ m32c_const_ok_for_constraint_p (HOST_WIDE_INT value,
{
return (-16 <= value && value && value <= 16);
}
if (memcmp (str, "In6", 3) == 0)
{
return (-32 <= value && value && value <= 32);
}
if (memcmp (str, "IM2", 3) == 0)
{
return (-65536 <= value && value && value <= -1);
......@@ -1505,7 +1509,7 @@ m32c_function_arg_regno_p (int r)
for some opcodes in R8C/M16C and for reset vectors and such. */
#undef TARGET_VALID_POINTER_MODE
#define TARGET_VALID_POINTER_MODE m32c_valid_pointer_mode
bool
static bool
m32c_valid_pointer_mode (enum machine_mode mode)
{
if (mode == HImode
......@@ -2834,27 +2838,63 @@ m32c_split_move (rtx * operands, enum machine_mode mode, int split_all)
return rv;
}
typedef rtx (*shift_gen_func)(rtx, rtx, rtx);
static shift_gen_func
shift_gen_func_for (int mode, int code)
{
#define GFF(m,c,f) if (mode == m && code == c) return f
GFF(QImode, ASHIFT, gen_ashlqi3_i);
GFF(QImode, ASHIFTRT, gen_ashrqi3_i);
GFF(QImode, LSHIFTRT, gen_lshrqi3_i);
GFF(HImode, ASHIFT, gen_ashlhi3_i);
GFF(HImode, ASHIFTRT, gen_ashrhi3_i);
GFF(HImode, LSHIFTRT, gen_lshrhi3_i);
GFF(PSImode, ASHIFT, gen_ashlpsi3_i);
GFF(PSImode, ASHIFTRT, gen_ashrpsi3_i);
GFF(PSImode, LSHIFTRT, gen_lshrpsi3_i);
GFF(SImode, ASHIFT, TARGET_A16 ? gen_ashlsi3_16 : gen_ashlsi3_24);
GFF(SImode, ASHIFTRT, TARGET_A16 ? gen_ashrsi3_16 : gen_ashrsi3_24);
GFF(SImode, LSHIFTRT, TARGET_A16 ? gen_lshrsi3_16 : gen_lshrsi3_24);
#undef GFF
}
/* The m32c only has one shift, but it takes a signed count. GCC
doesn't want this, so we fake it by negating any shift count when
we're pretending to shift the other way. */
int
m32c_prepare_shift (rtx * operands, int scale, int bits)
m32c_prepare_shift (rtx * operands, int scale, int shift_code)
{
enum machine_mode mode = GET_MODE (operands[0]);
shift_gen_func func = shift_gen_func_for (mode, shift_code);
rtx temp;
if (GET_CODE (operands[2]) == CONST_INT
&& INTVAL (operands[2]) <= (1 << (bits - 1))
&& INTVAL (operands[2]) >= -(1 << (bits - 1)))
if (GET_CODE (operands[2]) == CONST_INT)
{
operands[2] = GEN_INT (scale * INTVAL (operands[2]));
return 0;
int maxc = TARGET_A24 && (mode == PSImode || mode == SImode) ? 32 : 8;
int count = INTVAL (operands[2]) * scale;
while (count > maxc)
{
temp = gen_reg_rtx (mode);
emit_insn (func (temp, operands[1], GEN_INT (maxc)));
operands[1] = temp;
count -= maxc;
}
while (count < -maxc)
{
temp = gen_reg_rtx (mode);
emit_insn (func (temp, operands[1], GEN_INT (-maxc)));
operands[1] = temp;
count += maxc;
}
emit_insn (func (operands[0], operands[1], GEN_INT (count)));
return 1;
}
if (scale < 0)
{
temp = gen_reg_rtx (QImode);
if (GET_CODE (operands[2]) == CONST_INT)
temp = GEN_INT (-INTVAL (operands[2]));
else
emit_move_insn (temp, gen_rtx_NEG (QImode, operands[2]));
emit_move_insn (temp, gen_rtx_NEG (QImode, operands[2]));
}
else
temp = operands[2];
......
......@@ -145,9 +145,13 @@
; TRUE if we can shift by this amount. Constant shift counts have a
; limited range.
(define_predicate "shiftcount_operand"
(ior (match_operand 0 "m32c_pseudo" "")
(ior (match_operand 0 "mra_operand" "")
(and (match_operand 2 "const_int_operand" "")
(match_test "-8 <= INTVAL (op) && INTVAL (op) && INTVAL (op) <= 8"))))
(define_predicate "longshiftcount_operand"
(ior (match_operand 0 "mra_operand" "")
(and (match_operand 2 "const_int_operand" "")
(match_test "-32 <= INTVAL (op) && INTVAL (op) && INTVAL (op) <= 32"))))
; TRUE for r0..r3, a0..a1, or sp.
(define_predicate "mra_or_sp_operand"
......
......@@ -33,34 +33,34 @@
(define_insn "ashlqi3_i"
[(set (match_operand:QI 0 "mra_operand" "=RqiSd*Rmm,RqiSd*Rmm")
(ashift:QI (match_operand:QI 1 "mra_operand" "0,0")
(match_operand:QI 2 "mrai_operand" "In4,R1w")))
(match_operand:QI 2 "mrai_operand" "In4,RqiSd")))
(clobber (match_scratch:HI 3 "=X,R1w"))]
""
"@
sha.b\t%2,%0
mov.b\tr1l,r1h\n\tsha.b\tr1h,%0"
mov.b\t%2,r1h\n\tsha.b\tr1h,%0"
)
(define_insn "ashrqi3_i"
[(set (match_operand:QI 0 "mra_operand" "=RqiSd*Rmm,RqiSd*Rmm")
(ashiftrt:QI (match_operand:QI 1 "mra_operand" "0,0")
(neg:QI (match_operand:QI 2 "mrai_operand" "In4,R1w"))))
(neg:QI (match_operand:QI 2 "mrai_operand" "In4,RqiSd"))))
(clobber (match_scratch:HI 3 "=X,R1w"))]
""
"@
sha.b\t%2,%0
mov.b\tr1l,r1h\n\tsha.b\tr1h,%0"
mov.b\t%2,r1h\n\tsha.b\tr1h,%0"
)
(define_insn "lshlqi3_i"
(define_insn "lshrqi3_i"
[(set (match_operand:QI 0 "mra_operand" "=RqiSd*Rmm,RqiSd*Rmm")
(lshiftrt:QI (match_operand:QI 1 "mra_operand" "0,0")
(neg:QI (match_operand:QI 2 "mrai_operand" "In4,R1w"))))
(neg:QI (match_operand:QI 2 "mrai_operand" "In4,RqiSd"))))
(clobber (match_scratch:HI 3 "=X,R1w"))]
""
"@
shl.b\t%2,%0
mov.b\tr1l,r1h\n\tshl.b\tr1h,%0"
mov.b\t%2,r1h\n\tshl.b\tr1h,%0"
)
......@@ -70,7 +70,7 @@
(match_operand:QI 2 "general_operand" "")))
(clobber (match_scratch:HI 3 ""))])]
""
"if (m32c_prepare_shift (operands, 1, 4))
"if (m32c_prepare_shift (operands, 1, ASHIFT))
DONE;"
)
......@@ -80,7 +80,7 @@
(neg:QI (match_operand:QI 2 "general_operand" ""))))
(clobber (match_scratch:HI 3 ""))])]
""
"if (m32c_prepare_shift (operands, -1, 4))
"if (m32c_prepare_shift (operands, -1, ASHIFTRT))
DONE;"
)
......@@ -90,7 +90,7 @@
(neg:QI (match_operand:QI 2 "general_operand" ""))))
(clobber (match_scratch:HI 3 ""))])]
""
"if (m32c_prepare_shift (operands, -1, 4))
"if (m32c_prepare_shift (operands, -1, LSHIFTRT))
DONE;"
)
......@@ -99,34 +99,34 @@
(define_insn "ashlhi3_i"
[(set (match_operand:HI 0 "mra_operand" "=SdRhi*Rmm,SdRhi*Rmm")
(ashift:HI (match_operand:HI 1 "mra_operand" "0,0")
(match_operand:QI 2 "mrai_operand" "In4,R1w")))
(match_operand:QI 2 "mrai_operand" "In4,RqiSd")))
(clobber (match_scratch:HI 3 "=X,R1w"))]
""
"@
sha.w\t%2,%0
mov.b\tr1l,r1h\n\tsha.w\tr1h,%0"
mov.b\t%2,r1h\n\tsha.w\tr1h,%0"
)
(define_insn "ashrhi3_i"
[(set (match_operand:HI 0 "mra_operand" "=SdRhi*Rmm,SdRhi*Rmm")
(ashiftrt:HI (match_operand:HI 1 "mra_operand" "0,0")
(neg:QI (match_operand:QI 2 "mrai_operand" "In4,R1w"))))
(neg:QI (match_operand:QI 2 "mrai_operand" "In4,RqiSd"))))
(clobber (match_scratch:HI 3 "=X,R1w"))]
""
"@
sha.w\t%2,%0
mov.b\tr1l,r1h\n\tsha.w\tr1h,%0"
mov.b\t%2,r1h\n\tsha.w\tr1h,%0"
)
(define_insn "lshlhi3_i"
(define_insn "lshrhi3_i"
[(set (match_operand:HI 0 "mra_operand" "=RhiSd*Rmm,RhiSd*Rmm")
(lshiftrt:HI (match_operand:HI 1 "mra_operand" "0,0")
(neg:QI (match_operand:QI 2 "mrai_operand" "In4,R1w"))))
(neg:QI (match_operand:QI 2 "mrai_operand" "In4,RqiSd"))))
(clobber (match_scratch:HI 3 "=X,R1w"))]
""
"@
shl.w\t%2,%0
mov.b\tr1l,r1h\n\tshl.w\tr1h,%0"
mov.b\t%2,r1h\n\tshl.w\tr1h,%0"
)
......@@ -136,7 +136,7 @@
(match_operand:QI 2 "general_operand" "")))
(clobber (match_scratch:HI 3 ""))])]
""
"if (m32c_prepare_shift (operands, 1, 4))
"if (m32c_prepare_shift (operands, 1, ASHIFT))
DONE;"
)
......@@ -146,7 +146,7 @@
(neg:QI (match_operand:QI 2 "general_operand" ""))))
(clobber (match_scratch:HI 3 ""))])]
""
"if (m32c_prepare_shift (operands, -1, 4))
"if (m32c_prepare_shift (operands, -1, ASHIFTRT))
DONE;"
)
......@@ -156,7 +156,7 @@
(neg:QI (match_operand:QI 2 "general_operand" ""))))
(clobber (match_scratch:HI 3 ""))])]
""
"if (m32c_prepare_shift (operands, -1, 4))
"if (m32c_prepare_shift (operands, -1, LSHIFTRT))
DONE;"
)
......@@ -169,34 +169,34 @@
(define_insn "ashlpsi3_i"
[(set (match_operand:PSI 0 "mra_operand" "=R02RaaSd*Rmm,R02RaaSd*Rmm")
(ashift:PSI (match_operand:PSI 1 "mra_operand" "0,0")
(match_operand:QI 2 "mrai_operand" "In4,R1w")))
(match_operand:QI 2 "mrai_operand" "In4,RqiSd")))
(clobber (match_scratch:HI 3 "=X,R1w"))]
"TARGET_A24"
"@
sha.l\t%2,%0
mov.b\tr1l,r1h\n\tsha.l\tr1h,%0"
mov.b\t%2,r1h\n\tsha.l\tr1h,%0"
)
(define_insn "ashrpsi3_i"
[(set (match_operand:PSI 0 "mra_operand" "=R02RaaSd*Rmm,R02RaaSd*Rmm")
(ashiftrt:PSI (match_operand:PSI 1 "mra_operand" "0,0")
(neg:QI (match_operand:QI 2 "mrai_operand" "In4,R1w"))))
(neg:QI (match_operand:QI 2 "mrai_operand" "In4,RqiSd"))))
(clobber (match_scratch:HI 3 "=X,R1w"))]
"TARGET_A24"
"@
sha.l\t%2,%0
mov.b\tr1l,r1h\n\tsha.l\tr1h,%0"
mov.b\t%2,r1h\n\tsha.l\tr1h,%0"
)
(define_insn "lshlpsi3_i"
(define_insn "lshrpsi3_i"
[(set (match_operand:PSI 0 "mra_operand" "=R02RaaSd,??Rmm")
(lshiftrt:PSI (match_operand:PSI 1 "mra_operand" "0,0")
(neg:QI (match_operand:QI 2 "shiftcount_operand" "In4,R1w"))))
(neg:QI (match_operand:QI 2 "shiftcount_operand" "In4,RqiSd"))))
(clobber (match_scratch:HI 3 "=X,R1w"))]
"TARGET_A24"
"@
shl.l\t%2,%0
mov.b\tr1l,r1h\n\tshl.l\tr1h,%0"
mov.b\t%2,r1h\n\tshl.l\tr1h,%0"
)
......@@ -206,7 +206,7 @@
(match_operand:QI 2 "mrai_operand" "")))
(clobber (match_scratch:HI 3 ""))])]
"TARGET_A24"
"if (m32c_prepare_shift (operands, 1, 4))
"if (m32c_prepare_shift (operands, 1, ASHIFT))
DONE;"
)
......@@ -216,7 +216,7 @@
(neg:QI (match_operand:QI 2 "mrai_operand" ""))))
(clobber (match_scratch:HI 3 ""))])]
"TARGET_A24"
"if (m32c_prepare_shift (operands, -1, 4))
"if (m32c_prepare_shift (operands, -1, ASHIFTRT))
DONE;"
)
......@@ -226,55 +226,98 @@
(neg:QI (match_operand:QI 2 "mrai_operand" ""))))
(clobber (match_scratch:HI 3 ""))])]
"TARGET_A24"
"if (m32c_prepare_shift (operands, -1, 4))
"if (m32c_prepare_shift (operands, -1, LSHIFTRT))
DONE;"
)
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; The m16c has a maximum shift count of -16..16, even when in a
; register. It's optimal to use multiple shifts of -8..8 rather than
; loading larger constants into R1H multiple time. The m32c can shift
; -32..32 either via immediates or in registers. Hence, separate
; patterns.
(define_insn "ashlsi3_i"
(define_insn "ashlsi3_16"
[(set (match_operand:SI 0 "r0123_operand" "=R03,R03")
(ashift:SI (match_operand:SI 1 "r0123_operand" "0,0")
(match_operand:QI 2 "mrai_operand" "In4,R1w")))
(match_operand:QI 2 "shiftcount_operand" "In4,RqiSd")))
(clobber (match_scratch:HI 3 "=X,R1w"))]
""
"TARGET_A16"
"@
sha.l\t%2,%0
mov.b\tr1l,r1h\n\tsha.l\tr1h,%0"
mov.b\t%2,r1h\n\tsha.l\tr1h,%0"
[(set_attr "flags" "sz,sz")]
)
(define_insn "ashrsi3_i"
(define_insn "ashrsi3_16"
[(set (match_operand:SI 0 "r0123_operand" "=R03,R03")
(ashiftrt:SI (match_operand:SI 1 "r0123_operand" "0,0")
(neg:QI (match_operand:QI 2 "mrai_operand" "In4,R1w"))))
(neg:QI (match_operand:QI 2 "shiftcount_operand" "In4,RqiSd"))))
(clobber (match_scratch:HI 3 "=X,R1w"))]
""
"TARGET_A16"
"@
sha.l\t%2,%0
mov.b\tr1l,r1h\n\tsha.l\tr1h,%0"
mov.b\t%2,r1h\n\tsha.l\tr1h,%0"
)
(define_insn "lshlsi3_i"
(define_insn "lshrsi3_16"
[(set (match_operand:SI 0 "r0123_operand" "=R03,R03")
(lshiftrt:SI (match_operand:SI 1 "r0123_operand" "0,0")
(neg:QI (match_operand:QI 2 "mrai_operand" "In4,R1w"))))
(neg:QI (match_operand:QI 2 "shiftcount_operand" "In4,RqiSd"))))
(clobber (match_scratch:HI 3 "=X,R1w"))]
""
"TARGET_A16"
"@
shl.l\t%2,%0
mov.b\tr1l,r1h\n\tshl.l\tr1h,%0"
mov.b\t%2,r1h\n\tshl.l\tr1h,%0"
)
(define_insn "ashlsi3_24"
[(set (match_operand:SI 0 "r0123_operand" "=R03,R03")
(ashift:SI (match_operand:SI 1 "r0123_operand" "0,0")
(match_operand:QI 2 "longshiftcount_operand" "In6,RqiSd")))
(clobber (match_scratch:HI 3 "=X,R1w"))]
"TARGET_A24"
"@
sha.l\t%2,%0
mov.b\t%2,r1h\n\tsha.l\tr1h,%0"
)
(define_insn "ashrsi3_24"
[(set (match_operand:SI 0 "r0123_operand" "=R03,R03")
(ashiftrt:SI (match_operand:SI 1 "r0123_operand" "0,0")
(neg:QI (match_operand:QI 2 "longshiftcount_operand" "In6,RqiSd"))))
(clobber (match_scratch:HI 3 "=X,R1w"))]
"TARGET_A24"
"@
sha.l\t%2,%0
mov.b\t%2,r1h\n\tsha.l\tr1h,%0"
)
(define_insn "lshrsi3_24"
[(set (match_operand:SI 0 "r0123_operand" "=R03,R03")
(lshiftrt:SI (match_operand:SI 1 "r0123_operand" "0,0")
(neg:QI (match_operand:QI 2 "longshiftcount_operand" "In6,RqiSd"))))
(clobber (match_scratch:HI 3 "=X,R1w"))]
"TARGET_A24"
"@
shl.l\t%2,%0
mov.b\t%2,r1h\n\tshl.l\tr1h,%0"
)
(define_expand "ashlsi3"
[(parallel [(set (match_operand:SI 0 "r0123_operand" "")
(ashift:SI (match_operand:SI 1 "r0123_operand" "")
(match_operand:QI 2 "mrai_operand" "")))
(ashift:SI (match_operand:SI 1 "r0123_operand" "")
(match_operand:QI 2 "mrai_operand" "")))
(clobber (match_scratch:HI 3 ""))])]
""
"if (m32c_prepare_shift (operands, 1, 4))
"if (m32c_prepare_shift (operands, 1, ASHIFT))
DONE;"
)
......@@ -284,7 +327,7 @@
(neg:QI (match_operand:QI 2 "mrai_operand" ""))))
(clobber (match_scratch:HI 3 ""))])]
""
"if (m32c_prepare_shift (operands, -1, 4))
"if (m32c_prepare_shift (operands, -1, ASHIFTRT))
DONE;"
)
......@@ -294,6 +337,6 @@
(neg:QI (match_operand:QI 2 "mrai_operand" ""))))
(clobber (match_scratch:HI 3 ""))])]
""
"if (m32c_prepare_shift (operands, -1, 5))
"if (m32c_prepare_shift (operands, -1, LSHIFTRT))
DONE;"
)
......@@ -2323,8 +2323,8 @@ Used to match function return values.
@item In5
-16 @dots{} -1 or 1 @dots{} 16
@item In4
-8 @dots{} -1 or 1 @dots{} 8
@item In6
-32 @dots{} -1 or 1 @dots{} 32
@item IM2
-65536 @dots{} -1
......
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