aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephane Carrez <Stephane.Carrez@worldnet.fr>2001-05-04 20:22:00 +0200
committerStephane Carrez <ciceron@gcc.gnu.org>2001-05-04 20:22:00 +0200
commitdc3c68066b153303c4760be6e077b9a2c5d50067 (patch)
treeb6ed617e23cfec5dcb5f810bfb76e02329f4affc
parent5a62a69372b8e6f55dcc3d5cb86b661efc3ea999 (diff)
downloadgcc-dc3c68066b153303c4760be6e077b9a2c5d50067.zip
gcc-dc3c68066b153303c4760be6e077b9a2c5d50067.tar.gz
gcc-dc3c68066b153303c4760be6e077b9a2c5d50067.tar.bz2
m68hc11.md (*tbne, *tbeq): New patterns for 68HC12.
* config/m68hc11/m68hc11.md (*tbne, *tbeq): New patterns for 68HC12. (extendqisi2, extendqihi2, extendhisi2): Use sex for 68HC12. (uminqi3, umaxqi3, uminhi3, umaxhi3): New pattern for 68HC12. From-SVN: r41836
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/m68hc11/m68hc11.md215
2 files changed, 215 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 47cdf86..5d4139a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
2001-05-04 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+ * config/m68hc11/m68hc11.md (*tbne, *tbeq): New patterns for 68HC12.
+ (extendqisi2, extendqihi2, extendhisi2): Use sex for 68HC12.
+ (uminqi3, umaxqi3, uminhi3, umaxhi3): New pattern for 68HC12.
+
+2001-05-04 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
* config/m68hc11/m68hc11.h (CONST_COSTS): Make the cost of
constants cheap after reload.
* config/m68hc11/m68hc11.c (m68hc11_shift_cost): Shift by 16 and 32
diff --git a/gcc/config/m68hc11/m68hc11.md b/gcc/config/m68hc11/m68hc11.md
index a4380c3..46bfad8 100644
--- a/gcc/config/m68hc11/m68hc11.md
+++ b/gcc/config/m68hc11/m68hc11.md
@@ -1273,6 +1273,20 @@
rtx ops[3];
int need_tst = 0;
+ /* The 68HC12 has a sign-extension instruction. Use it when the
+ destination is the register (X,D). First sign-extend the low
+ part and fill X with the sign-extension of the high part. */
+ if (TARGET_M6812 && X_REG_P (operands[0]))
+ {
+ if (!D_REG_P (operands[1]))
+ {
+ ops[0] = gen_rtx (REG, QImode, HARD_D_REGNUM);
+ ops[1] = operands[1];
+ m68hc11_gen_movqi (insn, ops);
+ }
+ return \"sex\\tb,d\\n\\tsex\\ta,x\";
+ }
+
ops[2] = gen_label_rtx ();
if (X_REG_P (operands[1]))
@@ -1368,6 +1382,16 @@
ops[0] = gen_label_rtx ();
if (D_REG_P (operands[0]))
{
+ if (TARGET_M6812)
+ {
+ if (!D_REG_P (operands[1]))
+ {
+ ops[0] = gen_rtx (REG, QImode, HARD_D_REGNUM);
+ ops[1] = operands[1];
+ m68hc11_gen_movqi (insn, ops);
+ }
+ return \"sex\\tb,d\";
+ }
output_asm_insn (\"clra\", operands);
if (H_REG_P (operands[1]))
{
@@ -1426,14 +1450,12 @@
"*
{
extern rtx ix_reg;
- rtx ops[1];
+ rtx ops[2];
int x_reg_used;
if (Y_REG_P (operands[1]))
return \"#\";
- ops[0] = gen_label_rtx ();
-
if (X_REG_P (operands[1]))
{
output_asm_insn (\"xgdx\", operands);
@@ -1446,9 +1468,29 @@
x_reg_used = reg_mentioned_p (ix_reg, operands[1]);
if (x_reg_used)
{
- output_asm_insn (\"ldd\\t%1\", operands);
+ ops[0] = gen_rtx (REG, HImode, HARD_D_REGNUM);
+ ops[1] = operands[1];
+ m68hc11_gen_movhi (insn, ops);
}
}
+
+ CC_STATUS_INIT;
+ if (TARGET_M6812 && 0)
+ {
+ /* This sequence of code is larger than the one for 68HC11.
+ Don't use it; keep it for documentation. */
+ if (!D_REG_P (operands[1]) && !x_reg_used)
+ {
+ ops[0] = gen_rtx (REG, HImode, HARD_D_REGNUM);
+ ops[1] = operands[1];
+ m68hc11_gen_movhi (insn, ops);
+ }
+ output_asm_insn (\"sex\\ta,x\", operands);
+ output_asm_insn (\"xgdx\", operands);
+ output_asm_insn (\"sex\\ta,d\", operands);
+ return \"xgdx\";
+ }
+
output_asm_insn (\"ldx\\t#0\", operands);
if (D_REG_P (operands[1]) || x_reg_used)
{
@@ -1456,18 +1498,107 @@
}
else
{
- output_asm_insn (\"ldd\\t%1\", operands);
+ ops[0] = gen_rtx (REG, HImode, HARD_D_REGNUM);
+ ops[1] = operands[1];
+ m68hc11_gen_movhi (insn, ops);
}
+
+ ops[0] = gen_label_rtx ();
output_asm_insn (\"bpl\\t%l0\", ops);
output_asm_insn (\"dex\", operands);
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[0]));
- CC_STATUS_INIT;
return \"\";
}")
;;--------------------------------------------------------------------
+;;- Min and Max instructions (68HC12).
+;;--------------------------------------------------------------------
+(define_insn "uminqi3"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
+ (umin:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:QI 2 "general_operand" "m,d")))]
+ "TARGET_M6812"
+ "*
+{
+ /* Flags are set according to (sub:QI (operand 1) (operand2)).
+ The mina/minm use A as the source or destination. This is the
+ high part of D. There is no way to express that in the pattern
+ so we must use 'exg a,b' to put the operand in the good register. */
+ CC_STATUS_INIT;
+ if (D_REG_P (operands[0]))
+ {
+ return \"exg\\ta,b\\n\\tmina\\t%2\\n\\texg\\ta,b\";
+ }
+ else
+ {
+ return \"exg\\ta,b\\n\\tminm\\t%0\\n\\texg\\ta,b\";
+ }
+}")
+
+(define_insn "umaxqi3"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
+ (umax:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:QI 2 "general_operand" "m,d")))]
+ "TARGET_M6812"
+ "*
+{
+ /* Flags are set according to (sub:QI (operand 1) (operand2)).
+ The maxa/maxm use A as the source or destination. This is the
+ high part of D. There is no way to express that in the pattern
+ so we must use 'exg a,b' to put the operand in the good register. */
+ CC_STATUS_INIT;
+ if (D_REG_P (operands[0]))
+ {
+ return \"exg\\ta,b\\n\\tmaxa\\t%2\\n\\texg\\ta,b\";
+ }
+ else
+ {
+ return \"exg\\ta,b\\n\\tmaxm\\t%0\\n\\texg\\ta,b\";
+ }
+}")
+
+(define_insn "uminhi3"
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
+ (umin:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:HI 2 "general_operand" "m,d")))]
+ "TARGET_M6812"
+ "*
+{
+ /* Flags are set according to (sub:HI (operand 1) (operand2)). */
+ CC_STATUS_INIT;
+ if (D_REG_P (operands[0]))
+ {
+ return \"emind\\t%2\";
+ }
+ else
+ {
+ return \"eminm\\t%0\";
+ }
+}")
+
+(define_insn "umaxhi3"
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
+ (umax:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:HI 2 "general_operand" "m,d")))]
+ "TARGET_M6812"
+ "*
+{
+ /* Flags are set according to (sub:HI (operand 1) (operand2)). */
+ CC_STATUS_INIT;
+ if (D_REG_P (operands[0]))
+ {
+ return \"emaxd\\t%2\";
+ }
+ else
+ {
+ return \"emaxm\\t%0\";
+ }
+}")
+
+
+;;--------------------------------------------------------------------
;;- Add instructions.
;;--------------------------------------------------------------------
;; 64-bit: Use a library call because what GCC generates is huge.
@@ -5218,6 +5349,78 @@
DONE;
}")
+;;
+;; Test and branch instructions for 68HC12 for EQ and NE.
+;; 'z' must not appear in the constraints because the z replacement
+;; pass does not know how to restore the replacement register.
+;;
+(define_insn "*tbeq"
+ [(set (pc)
+ (if_then_else (eq (match_operand:HI 0 "register_operand" "dxy")
+ (const_int 0))
+ (label_ref (match_operand 1 "" ""))
+ (pc)))]
+ "TARGET_M6812"
+ "*
+{
+ /* If the flags are already set correctly, use 'bne/beq' which are
+ smaller and a little bit faster. This happens quite often due
+ to reloading of operands[0]. In that case, flags are set correctly
+ due to the load instruction. */
+ if (cc_status.value1 && rtx_equal_p (cc_status.value1, operands[0]))
+ return \"beq\\t%l1\";
+ else
+ return \"tbeq\\t%0,%l1\";
+}")
+
+(define_insn "*tbne"
+ [(set (pc)
+ (if_then_else (ne (match_operand:HI 0 "register_operand" "dxy")
+ (const_int 0))
+ (label_ref (match_operand 1 "" ""))
+ (pc)))]
+ "TARGET_M6812"
+ "*
+{
+ if (cc_status.value1 && rtx_equal_p (cc_status.value1, operands[0]))
+ return \"bne\\t%l1\";
+ else
+ return \"tbne\\t%0,%l1\";
+}")
+
+;;
+;; Test and branch with 8-bit register. Register must be B (or A).
+;;
+(define_insn "*tbeq8"
+ [(set (pc)
+ (if_then_else (eq (match_operand:QI 0 "register_operand" "d")
+ (const_int 0))
+ (label_ref (match_operand 1 "" ""))
+ (pc)))]
+ "TARGET_M6812"
+ "*
+{
+ if (cc_status.value1 && rtx_equal_p (cc_status.value1, operands[0]))
+ return \"beq\\t%l1\";
+ else
+ return \"tbeq\\tb,%l1\";
+}")
+
+(define_insn "*tbne8"
+ [(set (pc)
+ (if_then_else (ne (match_operand:QI 0 "register_operand" "d")
+ (const_int 0))
+ (label_ref (match_operand 1 "" ""))
+ (pc)))]
+ "TARGET_M6812"
+ "*
+{
+ if (cc_status.value1 && rtx_equal_p (cc_status.value1, operands[0]))
+ return \"bne\\t%l1\";
+ else
+ return \"tbne\\tb,%l1\";
+}")
+
(define_insn "*beq"
[(set (pc)
(if_then_else (eq (cc0)