Commit 19047e4a by Eric Botcazou Committed by Eric Botcazou

sparc-protos.h (gen_compare_operator): Declare.

	* config/sparc/sparc-protos.h (gen_compare_operator): Declare.
	(sparc_emit_float_lib_cmp): Change return type.
	* config/sparc/sparc.c (gen_compare_reg): Add comment about TFmode.
	(gen_compare_operator): New function.
	(sparc_emit_float_lib_cmp): Return the new operator to be used in
	the comparison sequence.  Minor tweaks.
	* config/sparc/sparc.md (seq, sne, sgt, slt, sge, sle): Assert
	that the final operator and the result of sparc_emit_float_lib_cmp
	match for software TFmode; use emit_insn in lieu of emit_jump_insn.
	(beq, bne, bgt, blt, bge, ble, bunordered, bordered, bungt, bunlt,
	buneq, bunge, bunle, bltgt): Assert that the final operator and the
	result of sparc_emit_float_lib_cmp match for software TFmode.
	(movqicc, movhicc, movsicc, movdicc): Merge into...
	(mov<I:mode>cc): ...this.
	(movsfcc, movdfcc, movtfcc): Merge into...
	(mov<F:mode>cc): ...this.
	(movqi_cc_sp64, movhi_cc_sp64, movsi_cc_sp64, movdi_cc_sp64): Merge
	into...
	(mov<I:mode>_cc_v9): ...this.
	(movdi_cc_sp64_trunc): Delete.
	(movqi_cc_reg_sp64, movhi_cc_reg_sp64, movsi_cc_reg_sp64,
	movdi_cc_reg_sp64): Merge into...
	(mov<I:mode>_cc_reg_sp64): ...this.
	(movsf_cc_sp64): Rename into...
	(movsf_cc_v9): ...this.
	(movdf_cc_sp64): Rename into...
	(movdf_cc_v9): ...this.
	(movtf_cc_hq_sp64): Rename into...
	(movtf_cc_hq_v9): ...this.
	(movtf_cc_sp64): Rename into...
	(movtf_cc_v9): ...this.  Adjust for renaming of movdf_cc_sp64.

From-SVN: r140530
parent 4b7f8314
2008-09-21 Eric Botcazou <ebotcazou@adacore.com>
* config/sparc/sparc-protos.h (gen_compare_operator): Declare.
(sparc_emit_float_lib_cmp): Change return type.
* config/sparc/sparc.c (gen_compare_reg): Add comment about TFmode.
(gen_compare_operator): New function.
(sparc_emit_float_lib_cmp): Return the new operator to be used in
the comparison sequence. Minor tweaks.
* config/sparc/sparc.md (seq, sne, sgt, slt, sge, sle): Assert
that the final operator and the result of sparc_emit_float_lib_cmp
match for software TFmode; use emit_insn in lieu of emit_jump_insn.
(beq, bne, bgt, blt, bge, ble, bunordered, bordered, bungt, bunlt,
buneq, bunge, bunle, bltgt): Assert that the final operator and the
result of sparc_emit_float_lib_cmp match for software TFmode.
(movqicc, movhicc, movsicc, movdicc): Merge into...
(mov<I:mode>cc): ...this.
(movsfcc, movdfcc, movtfcc): Merge into...
(mov<F:mode>cc): ...this.
(movqi_cc_sp64, movhi_cc_sp64, movsi_cc_sp64, movdi_cc_sp64): Merge
into...
(mov<I:mode>_cc_v9): ...this.
(movdi_cc_sp64_trunc): Delete.
(movqi_cc_reg_sp64, movhi_cc_reg_sp64, movsi_cc_reg_sp64,
movdi_cc_reg_sp64): Merge into...
(mov<I:mode>_cc_reg_sp64): ...this.
(movsf_cc_sp64): Rename into...
(movsf_cc_v9): ...this.
(movdf_cc_sp64): Rename into...
(movdf_cc_v9): ...this.
(movtf_cc_hq_sp64): Rename into...
(movtf_cc_hq_v9): ...this.
(movtf_cc_sp64): Rename into...
(movtf_cc_v9): ...this. Adjust for renaming of movdf_cc_sp64.
2008-09-21 Diego Novillo <dnovillo@google.com> 2008-09-21 Diego Novillo <dnovillo@google.com>
* doc/gccint.texi: Include generic.texi and gimple.texi. * doc/gccint.texi: Include generic.texi and gimple.texi.
......
...@@ -54,7 +54,8 @@ extern void sparc_output_scratch_registers (FILE *); ...@@ -54,7 +54,8 @@ extern void sparc_output_scratch_registers (FILE *);
extern enum machine_mode select_cc_mode (enum rtx_code, rtx, rtx); extern enum machine_mode select_cc_mode (enum rtx_code, rtx, rtx);
/* Define the function that build the compare insn for scc and bcc. */ /* Define the function that build the compare insn for scc and bcc. */
extern rtx gen_compare_reg (enum rtx_code code); extern rtx gen_compare_reg (enum rtx_code code);
extern void sparc_emit_float_lib_cmp (rtx, rtx, enum rtx_code); extern rtx gen_compare_operator (enum rtx_code code);
extern enum rtx_code sparc_emit_float_lib_cmp (rtx, rtx, enum rtx_code);
extern void sparc_emit_floatunsdi (rtx [2], enum machine_mode); extern void sparc_emit_floatunsdi (rtx [2], enum machine_mode);
extern void sparc_emit_fixunsdi (rtx [2], enum machine_mode); extern void sparc_emit_fixunsdi (rtx [2], enum machine_mode);
extern void emit_tfmode_binop (enum rtx_code, rtx *); extern void emit_tfmode_binop (enum rtx_code, rtx *);
......
...@@ -2001,8 +2001,7 @@ select_cc_mode (enum rtx_code op, rtx x, rtx y ATTRIBUTE_UNUSED) ...@@ -2001,8 +2001,7 @@ select_cc_mode (enum rtx_code op, rtx x, rtx y ATTRIBUTE_UNUSED)
} }
} }
/* X and Y are two things to compare using CODE. Emit the compare insn and /* Emit the compare insn and return the CC reg for a CODE comparison. */
return the rtx for the cc reg in the proper mode. */
rtx rtx
gen_compare_reg (enum rtx_code code) gen_compare_reg (enum rtx_code code)
...@@ -2065,12 +2064,28 @@ gen_compare_reg (enum rtx_code code) ...@@ -2065,12 +2064,28 @@ gen_compare_reg (enum rtx_code code)
else else
cc_reg = gen_rtx_REG (mode, SPARC_ICC_REG); cc_reg = gen_rtx_REG (mode, SPARC_ICC_REG);
emit_insn (gen_rtx_SET (VOIDmode, cc_reg, /* We shouldn't get there for TFmode if !TARGET_HARD_QUAD. If we do, this
gen_rtx_COMPARE (mode, x, y))); will only result in an unrecognizable insn so no point in asserting. */
emit_insn (gen_rtx_SET (VOIDmode, cc_reg, gen_rtx_COMPARE (mode, x, y)));
return cc_reg; return cc_reg;
} }
/* Same as above but return the whole compare operator. */
rtx
gen_compare_operator (enum rtx_code code)
{
rtx cc_reg;
if (GET_MODE (sparc_compare_op0) == TFmode && !TARGET_HARD_QUAD)
code
= sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, code);
cc_reg = gen_compare_reg (code);
return gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
}
/* This function is used for v9 only. /* This function is used for v9 only.
CODE is the code for an Scc's comparison. CODE is the code for an Scc's comparison.
OPERANDS[0] is the target of the Scc insn. OPERANDS[0] is the target of the Scc insn.
...@@ -6099,41 +6114,45 @@ output_cbranch (rtx op, rtx dest, int label, int reversed, int annul, ...@@ -6099,41 +6114,45 @@ output_cbranch (rtx op, rtx dest, int label, int reversed, int annul,
} }
/* Emit a library call comparison between floating point X and Y. /* Emit a library call comparison between floating point X and Y.
COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). COMPARISON is the operator to compare with (EQ, NE, GT, etc).
Return the new operator to be used in the comparison sequence.
TARGET_ARCH64 uses _Qp_* functions, which use pointers to TFmode TARGET_ARCH64 uses _Qp_* functions, which use pointers to TFmode
values as arguments instead of the TFmode registers themselves, values as arguments instead of the TFmode registers themselves,
that's why we cannot call emit_float_lib_cmp. */ that's why we cannot call emit_float_lib_cmp. */
void
enum rtx_code
sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison) sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
{ {
const char *qpfunc; const char *qpfunc;
rtx slot0, slot1, result, tem, tem2; rtx slot0, slot1, result, tem, tem2;
enum machine_mode mode; enum machine_mode mode;
enum rtx_code new_comparison;
switch (comparison) switch (comparison)
{ {
case EQ: case EQ:
qpfunc = (TARGET_ARCH64) ? "_Qp_feq" : "_Q_feq"; qpfunc = (TARGET_ARCH64 ? "_Qp_feq" : "_Q_feq");
break; break;
case NE: case NE:
qpfunc = (TARGET_ARCH64) ? "_Qp_fne" : "_Q_fne"; qpfunc = (TARGET_ARCH64 ? "_Qp_fne" : "_Q_fne");
break; break;
case GT: case GT:
qpfunc = (TARGET_ARCH64) ? "_Qp_fgt" : "_Q_fgt"; qpfunc = (TARGET_ARCH64 ? "_Qp_fgt" : "_Q_fgt");
break; break;
case GE: case GE:
qpfunc = (TARGET_ARCH64) ? "_Qp_fge" : "_Q_fge"; qpfunc = (TARGET_ARCH64 ? "_Qp_fge" : "_Q_fge");
break; break;
case LT: case LT:
qpfunc = (TARGET_ARCH64) ? "_Qp_flt" : "_Q_flt"; qpfunc = (TARGET_ARCH64 ? "_Qp_flt" : "_Q_flt");
break; break;
case LE: case LE:
qpfunc = (TARGET_ARCH64) ? "_Qp_fle" : "_Q_fle"; qpfunc = (TARGET_ARCH64 ? "_Qp_fle" : "_Q_fle");
break; break;
case ORDERED: case ORDERED:
...@@ -6144,7 +6163,7 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison) ...@@ -6144,7 +6163,7 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
case UNGE: case UNGE:
case UNLE: case UNLE:
case LTGT: case LTGT:
qpfunc = (TARGET_ARCH64) ? "_Qp_cmp" : "_Q_cmp"; qpfunc = (TARGET_ARCH64 ? "_Qp_cmp" : "_Q_cmp");
break; break;
default: default:
...@@ -6153,27 +6172,26 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison) ...@@ -6153,27 +6172,26 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
if (TARGET_ARCH64) if (TARGET_ARCH64)
{ {
if (GET_CODE (x) != MEM) if (MEM_P (x))
slot0 = x;
else
{ {
slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
emit_move_insn (slot0, x); emit_move_insn (slot0, x);
} }
else
slot0 = x;
if (GET_CODE (y) != MEM) if (MEM_P (y))
slot1 = y;
else
{ {
slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
emit_move_insn (slot1, y); emit_move_insn (slot1, y);
} }
else
slot1 = y;
emit_library_call (gen_rtx_SYMBOL_REF (Pmode, qpfunc), LCT_NORMAL, emit_library_call (gen_rtx_SYMBOL_REF (Pmode, qpfunc), LCT_NORMAL,
DImode, 2, DImode, 2,
XEXP (slot0, 0), Pmode, XEXP (slot0, 0), Pmode,
XEXP (slot1, 0), Pmode); XEXP (slot1, 0), Pmode);
mode = DImode; mode = DImode;
} }
else else
...@@ -6181,7 +6199,6 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison) ...@@ -6181,7 +6199,6 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
emit_library_call (gen_rtx_SYMBOL_REF (Pmode, qpfunc), LCT_NORMAL, emit_library_call (gen_rtx_SYMBOL_REF (Pmode, qpfunc), LCT_NORMAL,
SImode, 2, SImode, 2,
x, TFmode, y, TFmode); x, TFmode, y, TFmode);
mode = SImode; mode = SImode;
} }
...@@ -6195,20 +6212,22 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison) ...@@ -6195,20 +6212,22 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
switch (comparison) switch (comparison)
{ {
default: default:
emit_cmp_insn (result, const0_rtx, NE, NULL_RTX, mode, 0); new_comparison = NE;
emit_cmp_insn (result, const0_rtx, new_comparison, NULL_RTX, mode, 0);
break; break;
case ORDERED: case ORDERED:
case UNORDERED: case UNORDERED:
emit_cmp_insn (result, GEN_INT(3), comparison == UNORDERED ? EQ : NE, new_comparison = (comparison == UNORDERED ? EQ : NE);
NULL_RTX, mode, 0); emit_cmp_insn (result, GEN_INT(3), new_comparison, NULL_RTX, mode, 0);
break; break;
case UNGT: case UNGT:
case UNGE: case UNGE:
emit_cmp_insn (result, const1_rtx, new_comparison = (comparison == UNGT ? GT : NE);
comparison == UNGT ? GT : NE, NULL_RTX, mode, 0); emit_cmp_insn (result, const1_rtx, new_comparison, NULL_RTX, mode, 0);
break; break;
case UNLE: case UNLE:
emit_cmp_insn (result, const2_rtx, NE, NULL_RTX, mode, 0); new_comparison = NE;
emit_cmp_insn (result, const2_rtx, new_comparison, NULL_RTX, mode, 0);
break; break;
case UNLT: case UNLT:
tem = gen_reg_rtx (mode); tem = gen_reg_rtx (mode);
...@@ -6216,7 +6235,8 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison) ...@@ -6216,7 +6235,8 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
emit_insn (gen_andsi3 (tem, result, const1_rtx)); emit_insn (gen_andsi3 (tem, result, const1_rtx));
else else
emit_insn (gen_anddi3 (tem, result, const1_rtx)); emit_insn (gen_anddi3 (tem, result, const1_rtx));
emit_cmp_insn (tem, const0_rtx, NE, NULL_RTX, mode, 0); new_comparison = NE;
emit_cmp_insn (tem, const0_rtx, new_comparison, NULL_RTX, mode, 0);
break; break;
case UNEQ: case UNEQ:
case LTGT: case LTGT:
...@@ -6230,10 +6250,12 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison) ...@@ -6230,10 +6250,12 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
emit_insn (gen_andsi3 (tem2, tem, const2_rtx)); emit_insn (gen_andsi3 (tem2, tem, const2_rtx));
else else
emit_insn (gen_anddi3 (tem2, tem, const2_rtx)); emit_insn (gen_anddi3 (tem2, tem, const2_rtx));
emit_cmp_insn (tem2, const0_rtx, comparison == UNEQ ? EQ : NE, new_comparison = (comparison == UNEQ ? EQ : NE);
NULL_RTX, mode, 0); emit_cmp_insn (tem2, const0_rtx, new_comparison, NULL_RTX, mode, 0);
break; break;
} }
return new_comparison;
} }
/* Generate an unsigned DImode to FP conversion. This is the same code /* Generate an unsigned DImode to FP conversion. This is the same code
......
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