summaryrefslogtreecommitdiff
path: root/lang/gcc/patches/patch-aw
diff options
context:
space:
mode:
Diffstat (limited to 'lang/gcc/patches/patch-aw')
-rw-r--r--lang/gcc/patches/patch-aw161
1 files changed, 157 insertions, 4 deletions
diff --git a/lang/gcc/patches/patch-aw b/lang/gcc/patches/patch-aw
index 57c62477123..0fb74fdae6c 100644
--- a/lang/gcc/patches/patch-aw
+++ b/lang/gcc/patches/patch-aw
@@ -1,7 +1,7 @@
-$NetBSD: patch-aw,v 1.2 2002/01/03 20:40:43 tron Exp $
+$NetBSD: patch-aw,v 1.3 2002/03/28 10:11:53 jmc Exp $
---- ../gcc-2.95.3/gcc/config/sparc/sparc.c.orig Thu Jan 25 15:03:37 2001
-+++ ../gcc-2.95.3/gcc/config/sparc/sparc.c Thu Jan 3 20:37:53 2002
+--- ../gcc-2.95.3/gcc/config/sparc/sparc.c.orig 2001/04/23 12:00:42 1.1.1.2
++++ ../gcc-2.95.3/gcc/config/sparc/sparc.c 2002/03/28 08:14:56 1.5
@@ -142,6 +142,8 @@
int sparc_align_jumps;
int sparc_align_funcs;
@@ -116,7 +116,160 @@ $NetBSD: patch-aw,v 1.2 2002/01/03 20:40:43 tron Exp $
this_slotno = slotno + parms.intoffset / BITS_PER_WORD;
intslots = MIN (intslots, SPARC_INT_ARG_MAX - this_slotno);
-@@ -5850,6 +5896,8 @@
+@@ -4532,6 +4578,152 @@
+ return string;
+ }
+
++/* Emit a library call comparison between floating point X and Y.
++ COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
++ TARGET_ARCH64 uses _Qp_* functions, which use pointers to TFmode
++ values as arguments instead of the TFmode registers themselves,
++ that's why we cannot call emit_float_lib_cmp. */
++void
++sparc_emit_float_lib_cmp (x, y, comparison)
++ rtx x, y;
++ enum rtx_code comparison;
++{
++ char *qpfunc;
++ rtx slot0, slot1, result, tem, tem2;
++ enum machine_mode mode;
++
++ switch (comparison)
++ {
++ case EQ:
++ qpfunc = (TARGET_ARCH64) ? "_Qp_feq" : "_Q_feq";
++ break;
++
++ case NE:
++ qpfunc = (TARGET_ARCH64) ? "_Qp_fne" : "_Q_fne";
++ break;
++
++ case GT:
++ qpfunc = (TARGET_ARCH64) ? "_Qp_fgt" : "_Q_fgt";
++ break;
++
++ case GE:
++ qpfunc = (TARGET_ARCH64) ? "_Qp_fge" : "_Q_fge";
++ break;
++
++ case LT:
++ qpfunc = (TARGET_ARCH64) ? "_Qp_flt" : "_Q_flt";
++ break;
++
++ case LE:
++ qpfunc = (TARGET_ARCH64) ? "_Qp_fle" : "_Q_fle";
++ break;
++
++ /* case UNORDERED:
++ case UNGT:
++ case UNLT:
++ case UNEQ:
++ case UNGE:
++ case UNLE:
++ case LTGT:
++ qpfunc = (TARGET_ARCH64) ? "_Qp_cmp" : "_Q_cmp";
++ break;
++ */
++ default:
++ abort();
++ break;
++ }
++
++ if (TARGET_ARCH64)
++ {
++ if (GET_CODE (x) != MEM)
++ {
++ slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
++ emit_insn (gen_rtx_SET (VOIDmode, slot0, x));
++ }
++ else
++ slot0 = x;
++
++ if (GET_CODE (y) != MEM)
++ {
++ slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
++ emit_insn (gen_rtx_SET (VOIDmode, slot1, y));
++ }
++ else
++ slot1 = y;
++
++ emit_library_call (gen_rtx_SYMBOL_REF (Pmode, qpfunc), 1,
++ DImode, 2,
++ XEXP (slot0, 0), Pmode,
++ XEXP (slot1, 0), Pmode);
++
++ mode = DImode;
++ }
++ else
++ {
++ emit_library_call (gen_rtx_SYMBOL_REF (Pmode, qpfunc), 1,
++ SImode, 2,
++ x, TFmode, y, TFmode);
++
++ mode = SImode;
++ }
++
++
++ /* Immediately move the result of the libcall into a pseudo
++ register so reload doesn't clobber the value if it needs
++ the return register for a spill reg. */
++ result = gen_reg_rtx (mode);
++ emit_move_insn (result, hard_libcall_value (mode));
++
++ switch (comparison)
++ {
++ default:
++ emit_cmp_insn (result, const0_rtx, NE,
++ NULL_RTX, mode, 0, 0);
++ break;
++ /* case ORDERED:
++ case UNORDERED:
++ emit_cmp_insn (result, GEN_INT(3),
++ (comparison == UNORDERED) ? EQ : NE,
++ NULL_RTX, mode, 0, 0);
++ break;
++ case UNGT:
++ case UNGE:
++ emit_cmp_insn (result, const1_rtx,
++ (comparison == UNGT) ? GT : NE,
++ NULL_RTX, mode, 0, 0);
++ break;
++ case UNLE:
++ emit_cmp_insn (result, const2_rtx, NE,
++ NULL_RTX, mode, 0, 0);
++ break;
++ case UNLT:
++ tem = gen_reg_rtx (mode);
++ if (TARGET_ARCH32)
++ emit_insn (gen_andsi3 (tem, result, const1_rtx));
++ else
++ emit_insn (gen_anddi3 (tem, result, const1_rtx));
++ emit_cmp_insn (tem, const0_rtx, NE,
++ NULL_RTX, mode, 0, 0);
++ break;
++ case UNEQ:
++ case LTGT:
++ tem = gen_reg_rtx (mode);
++ if (TARGET_ARCH32)
++ emit_insn (gen_addsi3 (tem, result, const1_rtx));
++ else
++ emit_insn (gen_adddi3 (tem, result, const1_rtx));
++ tem2 = gen_reg_rtx (mode);
++ if (TARGET_ARCH32)
++ emit_insn (gen_andsi3 (tem2, tem, const2_rtx));
++ else
++ emit_insn (gen_anddi3 (tem2, tem, const2_rtx));
++ emit_cmp_insn (tem2, const0_rtx,
++ (comparison == UNEQ) ? EQ : NE,
++ NULL_RTX, mode, 0, 0);
++ break;*/
++ }
++}
++
+ /* Return the string to output a conditional branch to LABEL, testing
+ register REG. LABEL is the operand number of the label; REG is the
+ operand number of the reg. OP is the conditional expression. The mode
+@@ -5850,6 +6042,8 @@
{
char *sp_str = reg_names[STACK_POINTER_REGNUM];
unsigned long gmask = current_frame_info.gmask;