Commit dc3c6806 by Stephane Carrez Committed by Stephane Carrez

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
parent 5a62a693
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
......
......@@ -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)
......
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