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
This commit is contained in:
Stephane Carrez 2001-05-04 20:22:00 +02:00 committed by Stephane Carrez
parent 5a62a69372
commit dc3c68066b
2 changed files with 215 additions and 6 deletions

View File

@ -1,3 +1,9 @@
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

View File

@ -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,17 +1498,106 @@
}
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.
;;--------------------------------------------------------------------
@ -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)