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:
parent
5a62a69372
commit
dc3c68066b
@ -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
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user