aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/arm/arm.c6
-rw-r--r--gcc/config/dfp-bit.c2
-rw-r--r--gcc/config/fr30/fr30.h15
-rw-r--r--gcc/config/fr30/fr30.md16
-rw-r--r--gcc/config/i386/i386.c173
-rw-r--r--gcc/config/m32c/m32c.h3
-rw-r--r--gcc/config/mips/mips.c14
-rw-r--r--gcc/config/mmix/mmix.h1
-rw-r--r--gcc/config/pa/pa.c56
-rw-r--r--gcc/config/pa/pa.md276
-rw-r--r--gcc/config/pa/t-pa648
-rw-r--r--gcc/config/rs6000/e500-double.h4
-rw-r--r--gcc/config/rs6000/rs6000.c62
-rw-r--r--gcc/config/rs6000/rs6000.h5
-rw-r--r--gcc/config/rs6000/sfp-machine.h63
-rw-r--r--gcc/config/rs6000/t-fprules12
-rw-r--r--gcc/config/rs6000/t-fprules-fpbit11
-rw-r--r--gcc/config/rs6000/t-fprules-softfp6
-rw-r--r--gcc/config/rs6000/t-linux6421
-rw-r--r--gcc/config/rs6000/t-ppccomm2
-rw-r--r--gcc/config/s390/s390.md108
-rw-r--r--gcc/config/sh/embed-elf.h9
-rw-r--r--gcc/config/sh/lib1funcs-Os-4-200.asm325
-rw-r--r--gcc/config/sh/lib1funcs.asm44
-rw-r--r--gcc/config/sh/lib1funcs.h69
-rw-r--r--gcc/config/sh/sh.h4
-rw-r--r--gcc/config/sh/sh.md2
-rw-r--r--gcc/config/sh/symbian.c6
-rw-r--r--gcc/config/sh/t-elf2
-rw-r--r--gcc/config/sh/t-sh10
-rw-r--r--gcc/config/sh/t-superh2
-rw-r--r--gcc/config/sh/t-symbian4
-rw-r--r--gcc/config/soft-fp/README4
-rw-r--r--gcc/config/soft-fp/adddf3.c49
-rw-r--r--gcc/config/soft-fp/addsf3.c50
-rw-r--r--gcc/config/soft-fp/addtf3.c49
-rw-r--r--gcc/config/soft-fp/divdf3.c49
-rw-r--r--gcc/config/soft-fp/divsf3.c49
-rw-r--r--gcc/config/soft-fp/divtf3.c49
-rw-r--r--gcc/config/soft-fp/double.h264
-rw-r--r--gcc/config/soft-fp/eqdf2.c51
-rw-r--r--gcc/config/soft-fp/eqsf2.c51
-rw-r--r--gcc/config/soft-fp/eqtf2.c51
-rw-r--r--gcc/config/soft-fp/extenddftf2.c54
-rw-r--r--gcc/config/soft-fp/extended.h453
-rw-r--r--gcc/config/soft-fp/extendsfdf2.c54
-rw-r--r--gcc/config/soft-fp/extendsftf2.c54
-rw-r--r--gcc/config/soft-fp/fixdfdi.c46
-rw-r--r--gcc/config/soft-fp/fixdfsi.c46
-rw-r--r--gcc/config/soft-fp/fixsfdi.c46
-rw-r--r--gcc/config/soft-fp/fixsfsi.c46
-rw-r--r--gcc/config/soft-fp/fixtfdi.c46
-rw-r--r--gcc/config/soft-fp/fixtfsi.c46
-rw-r--r--gcc/config/soft-fp/fixunsdfdi.c46
-rw-r--r--gcc/config/soft-fp/fixunsdfsi.c46
-rw-r--r--gcc/config/soft-fp/fixunssfdi.c46
-rw-r--r--gcc/config/soft-fp/fixunssfsi.c46
-rw-r--r--gcc/config/soft-fp/fixunstfdi.c46
-rw-r--r--gcc/config/soft-fp/fixunstfsi.c46
-rw-r--r--gcc/config/soft-fp/floatdidf.c46
-rw-r--r--gcc/config/soft-fp/floatdisf.c46
-rw-r--r--gcc/config/soft-fp/floatditf.c46
-rw-r--r--gcc/config/soft-fp/floatsidf.c46
-rw-r--r--gcc/config/soft-fp/floatsisf.c46
-rw-r--r--gcc/config/soft-fp/floatsitf.c46
-rw-r--r--gcc/config/soft-fp/floatundidf.c47
-rw-r--r--gcc/config/soft-fp/floatundisf.c47
-rw-r--r--gcc/config/soft-fp/floatunditf.c47
-rw-r--r--gcc/config/soft-fp/floatunsidf.c47
-rw-r--r--gcc/config/soft-fp/floatunsisf.c47
-rw-r--r--gcc/config/soft-fp/floatunsitf.c47
-rw-r--r--gcc/config/soft-fp/gedf2.c51
-rw-r--r--gcc/config/soft-fp/gesf2.c51
-rw-r--r--gcc/config/soft-fp/getf2.c51
-rw-r--r--gcc/config/soft-fp/ledf2.c51
-rw-r--r--gcc/config/soft-fp/lesf2.c51
-rw-r--r--gcc/config/soft-fp/letf2.c51
-rw-r--r--gcc/config/soft-fp/muldf3.c49
-rw-r--r--gcc/config/soft-fp/mulsf3.c49
-rw-r--r--gcc/config/soft-fp/multf3.c49
-rw-r--r--gcc/config/soft-fp/negdf2.c48
-rw-r--r--gcc/config/soft-fp/negsf2.c48
-rw-r--r--gcc/config/soft-fp/negtf2.c48
-rw-r--r--gcc/config/soft-fp/op-1.h302
-rw-r--r--gcc/config/soft-fp/op-2.h615
-rw-r--r--gcc/config/soft-fp/op-4.h686
-rw-r--r--gcc/config/soft-fp/op-8.h111
-rw-r--r--gcc/config/soft-fp/op-common.h1330
-rw-r--r--gcc/config/soft-fp/quad.h271
-rw-r--r--gcc/config/soft-fp/single.h151
-rw-r--r--gcc/config/soft-fp/soft-fp.h209
-rw-r--r--gcc/config/soft-fp/subdf3.c49
-rw-r--r--gcc/config/soft-fp/subsf3.c49
-rw-r--r--gcc/config/soft-fp/subtf3.c49
-rw-r--r--gcc/config/soft-fp/t-softfp108
-rw-r--r--gcc/config/soft-fp/truncdfsf2.c54
-rw-r--r--gcc/config/soft-fp/trunctfdf2.c54
-rw-r--r--gcc/config/soft-fp/trunctfsf2.c54
-rw-r--r--gcc/config/soft-fp/unorddf2.c45
-rw-r--r--gcc/config/soft-fp/unordsf2.c46
-rw-r--r--gcc/config/soft-fp/unordtf2.c46
-rw-r--r--gcc/config/sparc/sparc.c168
102 files changed, 8366 insertions, 410 deletions
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 0f46b3e8dd9..3b221e2977e 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -1230,6 +1230,12 @@ arm_override_options (void)
if (arm_float_abi == ARM_FLOAT_ABI_HARD && TARGET_VFP)
sorry ("-mfloat-abi=hard and VFP");
+ /* FPA and iWMMXt are incompatible because the insn encodings overlap.
+ VFP and iWMMXt can theoretically coexist, but it's unlikely such silicon
+ will ever exist. GCC makes no attempt to support this combination. */
+ if (TARGET_IWMMXT && !TARGET_SOFT_FLOAT)
+ sorry ("iWMMXt and hardware floating point");
+
/* If soft-float is specified then don't use FPU. */
if (TARGET_SOFT_FLOAT)
arm_fpu_arch = FPUTYPE_NONE;
diff --git a/gcc/config/dfp-bit.c b/gcc/config/dfp-bit.c
index 271bfb5627a..c9374c51f06 100644
--- a/gcc/config/dfp-bit.c
+++ b/gcc/config/dfp-bit.c
@@ -411,7 +411,7 @@ DFP_TO_INT (DFP_C_TYPE x)
TO_INTERNAL (&s, &n1);
/* Rescale if the exponent is less than zero. */
decNumberToIntegralValue (&n2, &n1, &context);
- /* Get a value to use for the quanitize call. */
+ /* Get a value to use for the quantize call. */
decNumberFromString (&qval, (char *) "1.0", &context);
/* Force the exponent to zero. */
decNumberQuantize (&n1, &n2, &qval, &context);
diff --git a/gcc/config/fr30/fr30.h b/gcc/config/fr30/fr30.h
index b423b0a66ce..0901649c312 100644
--- a/gcc/config/fr30/fr30.h
+++ b/gcc/config/fr30/fr30.h
@@ -842,13 +842,15 @@ do \
goto LABEL; \
if (GET_CODE (X) == PLUS \
&& ((MODE) == SImode || (MODE) == SFmode) \
- && XEXP (X, 0) == stack_pointer_rtx \
+ && GET_CODE (XEXP (X, 0)) == REG \
+ && REGNO (XEXP (X, 0)) == STACK_POINTER_REGNUM \
&& GET_CODE (XEXP (X, 1)) == CONST_INT \
&& IN_RANGE (INTVAL (XEXP (X, 1)), 0, (1 << 6) - 4)) \
goto LABEL; \
if (GET_CODE (X) == PLUS \
&& ((MODE) == SImode || (MODE) == SFmode) \
- && XEXP (X, 0) == frame_pointer_rtx \
+ && GET_CODE (XEXP (X, 0)) == REG \
+ && REGNO (XEXP (X, 0)) == FRAME_POINTER_REGNUM \
&& GET_CODE (XEXP (X, 1)) == CONST_INT \
&& IN_RANGE (INTVAL (XEXP (X, 1)), -(1 << 9), (1 << 9) - 4)) \
goto LABEL; \
@@ -862,15 +864,16 @@ do \
goto LABEL; \
if (GET_CODE (X) == PLUS \
&& ((MODE) == SImode || (MODE) == SFmode) \
- && XEXP (X, 0) == stack_pointer_rtx \
+ && GET_CODE (XEXP (X, 0)) == REG \
+ && REGNO (XEXP (X, 0)) == STACK_POINTER_REGNUM \
&& GET_CODE (XEXP (X, 1)) == CONST_INT \
&& IN_RANGE (INTVAL (XEXP (X, 1)), 0, (1 << 6) - 4)) \
goto LABEL; \
if (GET_CODE (X) == PLUS \
&& ((MODE) == SImode || (MODE) == SFmode) \
- && GET_CODE (XEXP (X, 0)) == REG \
- && (REGNO (XEXP (X, 0)) == FRAME_POINTER_REGNUM \
- || REGNO (XEXP (X, 0)) == ARG_POINTER_REGNUM) \
+ && GET_CODE (XEXP (X, 0)) == REG \
+ && (REGNO (XEXP (X, 0)) == FRAME_POINTER_REGNUM \
+ || REGNO (XEXP (X, 0)) == ARG_POINTER_REGNUM) \
&& GET_CODE (XEXP (X, 1)) == CONST_INT \
&& IN_RANGE (INTVAL (XEXP (X, 1)), -(1 << 9), (1 << 9) - 4)) \
goto LABEL; \
diff --git a/gcc/config/fr30/fr30.md b/gcc/config/fr30/fr30.md
index 734b3749ada..0deda961e85 100644
--- a/gcc/config/fr30/fr30.md
+++ b/gcc/config/fr30/fr30.md
@@ -290,7 +290,9 @@
(define_split
[(set (match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "const_int_operand" ""))]
- "INTVAL (operands[1]) <= -1 && INTVAL (operands[1]) >= -128"
+ "INTVAL (operands[1]) <= -1 && INTVAL (operands[1]) >= -128
+ && (GET_CODE (operands[0]) != SUBREG
+ || SCALAR_INT_MODE_P (GET_MODE (XEXP (operands[0], 0))))"
[(set:SI (match_dup 0) (match_dup 1))
(set:SI (match_dup 0) (sign_extend:SI (match_dup 2)))]
"{
@@ -654,10 +656,10 @@
emit_insn (gen_addsi_regs (operands[0], operands[1], operands[2]));
else if (GET_CODE (operands[2]) != CONST_INT)
emit_insn (gen_addsi_big_int (operands[0], operands[1], operands[2]));
- else if ( (REGNO (operands[1]) != FRAME_POINTER_REGNUM)
- && (REGNO (operands[1]) != ARG_POINTER_REGNUM)
- && (INTVAL (operands[2]) >= -16)
- && (INTVAL (operands[2]) <= 15))
+ else if (INTVAL (operands[2]) >= -16
+ && INTVAL (operands[2]) <= 15
+ && (!REGNO_PTR_FRAME_P (REGNO (operands[1]))
+ || REGNO (operands[1]) == STACK_POINTER_REGNUM))
emit_insn (gen_addsi_small_int (operands[0], operands[1], operands[2]));
else
emit_insn (gen_addsi_big_int (operands[0], operands[1], operands[2]));
@@ -680,8 +682,8 @@
[(set (match_operand:SI 0 "register_operand" "=r,r")
(plus:SI (match_operand:SI 1 "register_operand" "0,0")
(match_operand:SI 2 "add_immediate_operand" "I,J")))]
- " (REGNO (operands[1]) != FRAME_POINTER_REGNUM)
- && (REGNO (operands[1]) != ARG_POINTER_REGNUM)"
+ "! REGNO_PTR_FRAME_P (REGNO (operands[1]))
+ || REGNO (operands[1]) == STACK_POINTER_REGNUM"
"@
addn %2, %0
addn2 %2, %0"
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 9c24004411b..3e65b4e58a1 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -1084,8 +1084,8 @@ static rtx get_thread_pointer (int);
static rtx legitimize_tls_address (rtx, enum tls_model, int);
static void get_pc_thunk_name (char [32], unsigned int);
static rtx gen_push (rtx);
-static int ix86_flags_dependant (rtx, rtx, enum attr_type);
-static int ix86_agi_dependant (rtx, rtx, enum attr_type);
+static int ix86_flags_dependent (rtx, rtx, enum attr_type);
+static int ix86_agi_dependent (rtx, rtx, enum attr_type);
static struct machine_function * ix86_init_machine_status (void);
static int ix86_split_to_parts (rtx, rtx *, enum machine_mode);
static int ix86_nsaved_regs (void);
@@ -4123,6 +4123,7 @@ ix86_va_start (tree valist, rtx nextarg)
HOST_WIDE_INT words, n_gpr, n_fpr;
tree f_gpr, f_fpr, f_ovf, f_sav;
tree gpr, fpr, ovf, sav, t;
+ tree type;
/* Only 64bit target needs something special. */
if (!TARGET_64BIT)
@@ -4153,26 +4154,29 @@ ix86_va_start (tree valist, rtx nextarg)
if (cfun->va_list_gpr_size)
{
- t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
- build_int_cst (NULL_TREE, n_gpr * 8));
+ type = TREE_TYPE (gpr);
+ t = build2 (MODIFY_EXPR, type, gpr,
+ build_int_cst (type, n_gpr * 8));
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
if (cfun->va_list_fpr_size)
{
- t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
- build_int_cst (NULL_TREE, n_fpr * 16 + 8*REGPARM_MAX));
+ type = TREE_TYPE (fpr);
+ t = build2 (MODIFY_EXPR, type, fpr,
+ build_int_cst (type, n_fpr * 16 + 8*REGPARM_MAX));
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
/* Find the overflow area. */
- t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
+ type = TREE_TYPE (ovf);
+ t = make_tree (type, virtual_incoming_args_rtx);
if (words != 0)
- t = build2 (PLUS_EXPR, TREE_TYPE (ovf), t,
- build_int_cst (NULL_TREE, words * UNITS_PER_WORD));
- t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
+ t = build2 (PLUS_EXPR, type, t,
+ build_int_cst (type, words * UNITS_PER_WORD));
+ t = build2 (MODIFY_EXPR, type, ovf, t);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
@@ -4180,8 +4184,9 @@ ix86_va_start (tree valist, rtx nextarg)
{
/* Find the register save area.
Prologue of the function save it right above stack frame. */
- t = make_tree (TREE_TYPE (sav), frame_pointer_rtx);
- t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
+ type = TREE_TYPE (sav);
+ t = make_tree (type, frame_pointer_rtx);
+ t = build2 (MODIFY_EXPR, type, sav, t);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
@@ -13428,7 +13433,7 @@ ix86_issue_rate (void)
by DEP_INSN and nothing set by DEP_INSN. */
static int
-ix86_flags_dependant (rtx insn, rtx dep_insn, enum attr_type insn_type)
+ix86_flags_dependent (rtx insn, rtx dep_insn, enum attr_type insn_type)
{
rtx set, set2;
@@ -13473,7 +13478,7 @@ ix86_flags_dependant (rtx insn, rtx dep_insn, enum attr_type insn_type)
address with operands set by DEP_INSN. */
static int
-ix86_agi_dependant (rtx insn, rtx dep_insn, enum attr_type insn_type)
+ix86_agi_dependent (rtx insn, rtx dep_insn, enum attr_type insn_type)
{
rtx addr;
@@ -13531,17 +13536,17 @@ ix86_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
{
case PROCESSOR_PENTIUM:
/* Address Generation Interlock adds a cycle of latency. */
- if (ix86_agi_dependant (insn, dep_insn, insn_type))
+ if (ix86_agi_dependent (insn, dep_insn, insn_type))
cost += 1;
/* ??? Compares pair with jump/setcc. */
- if (ix86_flags_dependant (insn, dep_insn, insn_type))
+ if (ix86_flags_dependent (insn, dep_insn, insn_type))
cost = 0;
/* Floating point stores require value to be ready one cycle earlier. */
if (insn_type == TYPE_FMOV
&& get_attr_memory (insn) == MEMORY_STORE
- && !ix86_agi_dependant (insn, dep_insn, insn_type))
+ && !ix86_agi_dependent (insn, dep_insn, insn_type))
cost += 1;
break;
@@ -13564,7 +13569,7 @@ ix86_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
in parallel with previous instruction in case
previous instruction is not needed to compute the address. */
if ((memory == MEMORY_LOAD || memory == MEMORY_BOTH)
- && !ix86_agi_dependant (insn, dep_insn, insn_type))
+ && !ix86_agi_dependent (insn, dep_insn, insn_type))
{
/* Claim moves to take one cycle, as core can issue one load
at time and the next load can start cycle later. */
@@ -13593,7 +13598,7 @@ ix86_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
in parallel with previous instruction in case
previous instruction is not needed to compute the address. */
if ((memory == MEMORY_LOAD || memory == MEMORY_BOTH)
- && !ix86_agi_dependant (insn, dep_insn, insn_type))
+ && !ix86_agi_dependent (insn, dep_insn, insn_type))
{
/* Claim moves to take one cycle, as core can issue one load
at time and the next load can start cycle later. */
@@ -13617,7 +13622,7 @@ ix86_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
in parallel with previous instruction in case
previous instruction is not needed to compute the address. */
if ((memory == MEMORY_LOAD || memory == MEMORY_BOTH)
- && !ix86_agi_dependant (insn, dep_insn, insn_type))
+ && !ix86_agi_dependent (insn, dep_insn, insn_type))
{
enum attr_unit unit = get_attr_unit (insn);
int loadcost = 3;
@@ -17852,11 +17857,66 @@ ix86_expand_vector_init_duplicate (bool mmx_ok, enum machine_mode mode,
wvmode = V4HImode;
goto widen;
case V8HImode:
+ if (TARGET_SSE2)
+ {
+ rtx tmp1, tmp2;
+ /* Extend HImode to SImode using a paradoxical SUBREG. */
+ tmp1 = gen_reg_rtx (SImode);
+ emit_move_insn (tmp1, gen_lowpart (SImode, val));
+ /* Insert the SImode value as low element of V4SImode vector. */
+ tmp2 = gen_reg_rtx (V4SImode);
+ tmp1 = gen_rtx_VEC_MERGE (V4SImode,
+ gen_rtx_VEC_DUPLICATE (V4SImode, tmp1),
+ CONST0_RTX (V4SImode),
+ const1_rtx);
+ emit_insn (gen_rtx_SET (VOIDmode, tmp2, tmp1));
+ /* Cast the V4SImode vector back to a V8HImode vector. */
+ tmp1 = gen_reg_rtx (V8HImode);
+ emit_move_insn (tmp1, gen_lowpart (V8HImode, tmp2));
+ /* Duplicate the low short through the whole low SImode word. */
+ emit_insn (gen_sse2_punpcklwd (tmp1, tmp1, tmp1));
+ /* Cast the V8HImode vector back to a V4SImode vector. */
+ tmp2 = gen_reg_rtx (V4SImode);
+ emit_move_insn (tmp2, gen_lowpart (V4SImode, tmp1));
+ /* Replicate the low element of the V4SImode vector. */
+ emit_insn (gen_sse2_pshufd (tmp2, tmp2, const0_rtx));
+ /* Cast the V2SImode back to V8HImode, and store in target. */
+ emit_move_insn (target, gen_lowpart (V8HImode, tmp2));
+ return true;
+ }
smode = HImode;
wsmode = SImode;
wvmode = V4SImode;
goto widen;
case V16QImode:
+ if (TARGET_SSE2)
+ {
+ rtx tmp1, tmp2;
+ /* Extend QImode to SImode using a paradoxical SUBREG. */
+ tmp1 = gen_reg_rtx (SImode);
+ emit_move_insn (tmp1, gen_lowpart (SImode, val));
+ /* Insert the SImode value as low element of V4SImode vector. */
+ tmp2 = gen_reg_rtx (V4SImode);
+ tmp1 = gen_rtx_VEC_MERGE (V4SImode,
+ gen_rtx_VEC_DUPLICATE (V4SImode, tmp1),
+ CONST0_RTX (V4SImode),
+ const1_rtx);
+ emit_insn (gen_rtx_SET (VOIDmode, tmp2, tmp1));
+ /* Cast the V4SImode vector back to a V16QImode vector. */
+ tmp1 = gen_reg_rtx (V16QImode);
+ emit_move_insn (tmp1, gen_lowpart (V16QImode, tmp2));
+ /* Duplicate the low byte through the whole low SImode word. */
+ emit_insn (gen_sse2_punpcklbw (tmp1, tmp1, tmp1));
+ emit_insn (gen_sse2_punpcklbw (tmp1, tmp1, tmp1));
+ /* Cast the V16QImode vector back to a V4SImode vector. */
+ tmp2 = gen_reg_rtx (V4SImode);
+ emit_move_insn (tmp2, gen_lowpart (V4SImode, tmp1));
+ /* Replicate the low element of the V4SImode vector. */
+ emit_insn (gen_sse2_pshufd (tmp2, tmp2, const0_rtx));
+ /* Cast the V2SImode back to V16QImode, and store in target. */
+ emit_move_insn (target, gen_lowpart (V16QImode, tmp2));
+ return true;
+ }
smode = QImode;
wsmode = HImode;
wvmode = V8HImode;
@@ -17881,15 +17941,16 @@ ix86_expand_vector_init_duplicate (bool mmx_ok, enum machine_mode mode,
}
/* A subroutine of ix86_expand_vector_init. Store into TARGET a vector
- whose low element is VAR, and other elements are zero. Return true
+ whose ONE_VAR element is VAR, and other elements are zero. Return true
if successful. */
static bool
-ix86_expand_vector_init_low_nonzero (bool mmx_ok, enum machine_mode mode,
- rtx target, rtx var)
+ix86_expand_vector_init_one_nonzero (bool mmx_ok, enum machine_mode mode,
+ rtx target, rtx var, int one_var)
{
enum machine_mode vsimode;
- rtx x;
+ rtx new_target;
+ rtx x, tmp;
switch (mode)
{
@@ -17901,6 +17962,8 @@ ix86_expand_vector_init_low_nonzero (bool mmx_ok, enum machine_mode mode,
case V2DFmode:
case V2DImode:
+ if (one_var != 0)
+ return false;
var = force_reg (GET_MODE_INNER (mode), var);
x = gen_rtx_VEC_CONCAT (mode, var, CONST0_RTX (GET_MODE_INNER (mode)));
emit_insn (gen_rtx_SET (VOIDmode, target, x));
@@ -17908,10 +17971,55 @@ ix86_expand_vector_init_low_nonzero (bool mmx_ok, enum machine_mode mode,
case V4SFmode:
case V4SImode:
+ if (!REG_P (target) || REGNO (target) < FIRST_PSEUDO_REGISTER)
+ new_target = gen_reg_rtx (mode);
+ else
+ new_target = target;
var = force_reg (GET_MODE_INNER (mode), var);
x = gen_rtx_VEC_DUPLICATE (mode, var);
x = gen_rtx_VEC_MERGE (mode, x, CONST0_RTX (mode), const1_rtx);
- emit_insn (gen_rtx_SET (VOIDmode, target, x));
+ emit_insn (gen_rtx_SET (VOIDmode, new_target, x));
+ if (one_var != 0)
+ {
+ /* We need to shuffle the value to the correct position, so
+ create a new pseudo to store the intermediate result. */
+
+ /* With SSE2, we can use the integer shuffle insns. */
+ if (mode != V4SFmode && TARGET_SSE2)
+ {
+ emit_insn (gen_sse2_pshufd_1 (new_target, new_target,
+ GEN_INT (1),
+ GEN_INT (one_var == 1 ? 0 : 1),
+ GEN_INT (one_var == 2 ? 0 : 1),
+ GEN_INT (one_var == 3 ? 0 : 1)));
+ if (target != new_target)
+ emit_move_insn (target, new_target);
+ return true;
+ }
+
+ /* Otherwise convert the intermediate result to V4SFmode and
+ use the SSE1 shuffle instructions. */
+ if (mode != V4SFmode)
+ {
+ tmp = gen_reg_rtx (V4SFmode);
+ emit_move_insn (tmp, gen_lowpart (V4SFmode, new_target));
+ }
+ else
+ tmp = new_target;
+
+ emit_insn (gen_sse_shufps_1 (tmp, tmp, tmp,
+ GEN_INT (1),
+ GEN_INT (one_var == 1 ? 0 : 1),
+ GEN_INT (one_var == 2 ? 0+4 : 1+4),
+ GEN_INT (one_var == 3 ? 0+4 : 1+4)));
+
+ if (mode != V4SFmode)
+ emit_move_insn (target, gen_lowpart (V4SImode, tmp));
+ else if (tmp != target)
+ emit_move_insn (target, tmp);
+ }
+ else if (target != new_target)
+ emit_move_insn (target, new_target);
return true;
case V8HImode:
@@ -17925,11 +18033,15 @@ ix86_expand_vector_init_low_nonzero (bool mmx_ok, enum machine_mode mode,
vsimode = V2SImode;
goto widen;
widen:
+ if (one_var != 0)
+ return false;
+
/* Zero extend the variable element to SImode and recurse. */
var = convert_modes (SImode, GET_MODE_INNER (mode), var, true);
x = gen_reg_rtx (vsimode);
- if (!ix86_expand_vector_init_low_nonzero (mmx_ok, vsimode, x, var))
+ if (!ix86_expand_vector_init_one_nonzero (mmx_ok, vsimode, x,
+ var, one_var))
gcc_unreachable ();
emit_move_insn (target, gen_lowpart (mode, x));
@@ -18186,9 +18298,10 @@ ix86_expand_vector_init (bool mmx_ok, rtx target, rtx vals)
the pool and overwritten via move later. */
if (n_var == 1)
{
- if (all_const_zero && one_var == 0
- && ix86_expand_vector_init_low_nonzero (mmx_ok, mode, target,
- XVECEXP (vals, 0, 0)))
+ if (all_const_zero
+ && ix86_expand_vector_init_one_nonzero (mmx_ok, mode, target,
+ XVECEXP (vals, 0, one_var),
+ one_var))
return;
if (ix86_expand_vector_init_one_var (mmx_ok, mode, target, vals, one_var))
@@ -18749,7 +18862,7 @@ asm_preferred_eh_data_format (int code, int global)
{
if (flag_pic)
{
-int type = DW_EH_PE_sdata8;
+ int type = DW_EH_PE_sdata8;
if (!TARGET_64BIT
|| ix86_cmodel == CM_SMALL_PIC
|| (ix86_cmodel == CM_MEDIUM_PIC && (global || code)))
diff --git a/gcc/config/m32c/m32c.h b/gcc/config/m32c/m32c.h
index 5eb2aaecf2c..1b1d357c2b7 100644
--- a/gcc/config/m32c/m32c.h
+++ b/gcc/config/m32c/m32c.h
@@ -171,6 +171,9 @@ machine_function;
#define DEFAULT_SIGNED_CHAR 1
+#undef PTRDIFF_TYPE
+#define PTRDIFF_TYPE (TARGET_A16 ? "int" : "long int")
+
/* REGISTER USAGE */
/* Register Basics */
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index ffe047ea068..f66cdc255af 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -409,6 +409,7 @@ static rtx mips_expand_builtin_compare (enum mips_builtin_type,
static rtx mips_expand_builtin_bposge (enum mips_builtin_type, rtx);
static void mips_encode_section_info (tree, rtx, int);
static void mips_extra_live_on_entry (bitmap);
+static int mips_mode_rep_extended (enum machine_mode, enum machine_mode);
/* Structure to be filled in by compute_frame_size with register
save masks, and offsets for the current function. */
@@ -1139,6 +1140,9 @@ static struct mips_rtx_cost_data const mips_rtx_cost_data[PROCESSOR_MAX] =
#undef TARGET_ARG_PARTIAL_BYTES
#define TARGET_ARG_PARTIAL_BYTES mips_arg_partial_bytes
+#undef TARGET_MODE_REP_EXTENDED
+#define TARGET_MODE_REP_EXTENDED mips_mode_rep_extended
+
#undef TARGET_VECTOR_MODE_SUPPORTED_P
#define TARGET_VECTOR_MODE_SUPPORTED_P mips_vector_mode_supported_p
@@ -10725,5 +10729,15 @@ mips_extra_live_on_entry (bitmap regs)
bitmap_set_bit (regs, PIC_FUNCTION_ADDR_REGNUM);
}
+/* SImode values are represented as sign-extended to DImode. */
+
+int
+mips_mode_rep_extended (enum machine_mode mode, enum machine_mode mode_rep)
+{
+ if (TARGET_64BIT && mode == SImode && mode_rep == DImode)
+ return SIGN_EXTEND;
+
+ return UNKNOWN;
+}
#include "gt-mips.h"
diff --git a/gcc/config/mmix/mmix.h b/gcc/config/mmix/mmix.h
index 9ae7bc7f36d..f41b8d38cb2 100644
--- a/gcc/config/mmix/mmix.h
+++ b/gcc/config/mmix/mmix.h
@@ -165,7 +165,6 @@ extern int target_flags;
if (SIZE || LEVEL > 1) \
{ \
flag_omit_frame_pointer = TRUE; \
- flag_strength_reduce = FALSE; \
} \
} \
while (0)
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 509e016cd13..48b8ca4f560 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -1,6 +1,6 @@
/* Subroutines for insn-output.c for HPPA.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
Contributed by Tim Moore (moore@cs.utah.edu), based on sparc.c
This file is part of GCC.
@@ -6436,27 +6436,27 @@ output_bb (rtx *operands ATTRIBUTE_UNUSED, int negated, rtx insn, int which)
{
nullify = 1;
xdelay = 0;
- operands[4] = GEN_INT (length - 8);
+ operands[4] = GEN_INT (length);
}
else
{
xdelay = 1;
- operands[4] = GEN_INT (length - 4);
+ operands[4] = GEN_INT (length + 4);
}
if (GET_MODE (operands[0]) == DImode)
- strcpy (buf, "extrd,s,*");
+ strcpy (buf, "bb,*");
else
- strcpy (buf, "{extrs,|extrw,s,}");
+ strcpy (buf, "bb,");
if ((which == 0 && negated)
|| (which == 1 && !negated))
- strcat (buf, ">= %0,%1,1,%%r0\n\t");
+ strcat (buf, "<");
else
- strcat (buf, "< %0,%1,1,%%r0\n\t");
+ strcat (buf, ">=");
if (nullify)
- strcat (buf, "b,n .+%4");
+ strcat (buf, ",n %0,%1,.+%4");
else
- strcat (buf, "b .+%4");
+ strcat (buf, " %0,%1,.+%4");
output_asm_insn (buf, operands);
return output_lbranch (negated ? operands[3] : operands[2],
insn, xdelay);
@@ -6616,27 +6616,27 @@ output_bvb (rtx *operands ATTRIBUTE_UNUSED, int negated, rtx insn, int which)
{
nullify = 1;
xdelay = 0;
- operands[4] = GEN_INT (length - 8);
+ operands[4] = GEN_INT (length);
}
else
{
xdelay = 1;
- operands[4] = GEN_INT (length - 4);
+ operands[4] = GEN_INT (length + 4);
}
if (GET_MODE (operands[0]) == DImode)
- strcpy (buf, "extrd,s,*");
+ strcpy (buf, "bb,*");
else
- strcpy (buf, "{extrs,|extrw,s,}");
+ strcpy (buf, "{bvb,|bb,}");
if ((which == 0 && negated)
|| (which == 1 && !negated))
- strcat (buf, ">= {%0,%1,1,%%r0|%0,%%sar,1,%%r0}\n\t");
+ strcat (buf, "<");
else
- strcat (buf, "< {%0,%1,1,%%r0|%0,%%sar,1,%%r0}\n\t");
+ strcat (buf, ">=");
if (nullify)
- strcat (buf, "b,n .+%4");
+ strcat (buf, ",n {%0,.+%4|%0,%%sar,.+%4}");
else
- strcat (buf, "b .+%4");
+ strcat (buf, " {%0,.+%4|%0,%%sar,.+%4}");
output_asm_insn (buf, operands);
return output_lbranch (negated ? operands[3] : operands[2],
insn, xdelay);
@@ -6763,8 +6763,8 @@ output_dbra (rtx *operands, rtx insn, int which_alternative)
return "{comclr|cmpclr},%B2 %%r0,%4,%%r0\n\tb %3\n\t{fldws|fldw} -16(%%r30),%0";
else
{
- operands[4] = GEN_INT (length - 24);
- output_asm_insn ("addib,%N2 %1,%0,.+%4", operands);
+ operands[5] = GEN_INT (length - 16);
+ output_asm_insn ("{comb|cmpb},%B2 %%r0,%4,.+%5", operands);
output_asm_insn ("{fldws|fldw} -16(%%r30),%0", operands);
return output_lbranch (operands[3], insn, 0);
}
@@ -6781,8 +6781,8 @@ output_dbra (rtx *operands, rtx insn, int which_alternative)
return "addi,%N2 %1,%4,%4\n\tb %3\n\tstw %4,%0";
else
{
- operands[5] = GEN_INT (length - 12);
- output_asm_insn ("addib,%N2 %1,%0,.+%5\n\tstw %4,%0", operands);
+ operands[5] = GEN_INT (length - 4);
+ output_asm_insn ("addib,%N2 %1,%4,.+%5\n\tstw %4,%0", operands);
return output_lbranch (operands[3], insn, 0);
}
}
@@ -6906,8 +6906,8 @@ output_movb (rtx *operands, rtx insn, int which_alternative,
return "{comclr|cmpclr},%B2 %%r0,%1,%%r0\n\tb %3\n\t{fldws|fldw} -16(%%r30),%0";
else
{
- operands[4] = GEN_INT (length - 12);
- output_asm_insn ("movb,%N2 %1,%0,.+%4", operands);
+ operands[4] = GEN_INT (length - 4);
+ output_asm_insn ("{comb|cmpb},%B2 %%r0,%1,.+%4", operands);
output_asm_insn ("{fldws|fldw} -16(%%r30),%0", operands);
return output_lbranch (operands[3], insn, 0);
}
@@ -6923,8 +6923,9 @@ output_movb (rtx *operands, rtx insn, int which_alternative,
return "{comclr|cmpclr},%B2 %%r0,%1,%%r0\n\tb %3\n\tstw %1,%0";
else
{
- operands[4] = GEN_INT (length - 8);
- output_asm_insn ("movb,%N2 %1,%0,.+%4\n\tstw %1,%0", operands);
+ operands[4] = GEN_INT (length);
+ output_asm_insn ("{comb|cmpb},%B2 %%r0,%1,.+%4\n\tstw %1,%0",
+ operands);
return output_lbranch (operands[3], insn, 0);
}
}
@@ -6937,8 +6938,9 @@ output_movb (rtx *operands, rtx insn, int which_alternative,
return "{comclr|cmpclr},%B2 %%r0,%1,%%r0\n\tb %3\n\tmtsar %r1";
else
{
- operands[4] = GEN_INT (length - 8);
- output_asm_insn ("movb,%N2 %1,%0,.+%4\n\tmtsar %r1", operands);
+ operands[4] = GEN_INT (length);
+ output_asm_insn ("{comb|cmpb},%B2 %%r0,%1,.+%4\n\tmtsar %r1",
+ operands);
return output_lbranch (operands[3], insn, 0);
}
}
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index e8acd9a465a..ada336823df 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -1,6 +1,6 @@
;;- Machine description for HP PA-RISC architecture for GCC compiler
;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-;; 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+;; 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
;; Contributed by the Center for Software Science at the University
;; of Utah.
@@ -52,6 +52,16 @@
(UNSPECV_LONGJMP 5) ; builtin_longjmp
])
+;; Maximum pc-relative branch offsets.
+
+;; These numbers are a bit smaller than the maximum allowable offsets
+;; so that a few instructions may be inserted before the actual branch.
+
+(define_constants
+ [(MAX_12BIT_OFFSET 8184) ; 12-bit branch
+ (MAX_17BIT_OFFSET 262100) ; 17-bit branch
+ ])
+
;; Insn type. Used to default other attribute values.
;; type "unary" insns have one input operand (1) and one output operand (0)
@@ -1713,10 +1723,10 @@
[(set_attr "type" "cbranch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
(const_int 24)
@@ -1742,10 +1752,10 @@
[(set_attr "type" "cbranch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
(const_int 24)
@@ -1769,10 +1779,10 @@
[(set_attr "type" "cbranch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
(const_int 24)
@@ -1798,10 +1808,10 @@
[(set_attr "type" "cbranch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
(const_int 24)
@@ -1824,10 +1834,10 @@
[(set_attr "type" "cbranch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
(const_int 24)
@@ -1853,10 +1863,10 @@
[(set_attr "type" "cbranch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
(const_int 24)
@@ -1882,16 +1892,16 @@
[(set_attr "type" "cbranch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
- (const_int 28)
+ (const_int 24)
(eq (symbol_ref "flag_pic") (const_int 0))
- (const_int 24)]
- (const_int 32)))])
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc)
@@ -1910,16 +1920,16 @@
[(set_attr "type" "cbranch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
- (const_int 28)
+ (const_int 24)
(eq (symbol_ref "flag_pic") (const_int 0))
- (const_int 24)]
- (const_int 32)))])
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc)
@@ -1938,16 +1948,16 @@
[(set_attr "type" "cbranch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
- (const_int 28)
+ (const_int 24)
(eq (symbol_ref "flag_pic") (const_int 0))
- (const_int 24)]
- (const_int 32)))])
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc)
@@ -1966,16 +1976,16 @@
[(set_attr "type" "cbranch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
- (const_int 28)
+ (const_int 24)
(eq (symbol_ref "flag_pic") (const_int 0))
- (const_int 24)]
- (const_int 32)))])
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc)
@@ -1994,16 +2004,16 @@
[(set_attr "type" "cbranch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
- (const_int 28)
+ (const_int 24)
(eq (symbol_ref "flag_pic") (const_int 0))
- (const_int 24)]
- (const_int 32)))])
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc)
@@ -2022,16 +2032,16 @@
[(set_attr "type" "cbranch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
- (const_int 28)
+ (const_int 24)
(eq (symbol_ref "flag_pic") (const_int 0))
- (const_int 24)]
- (const_int 32)))])
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc)
@@ -2050,16 +2060,16 @@
[(set_attr "type" "cbranch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
- (const_int 28)
+ (const_int 24)
(eq (symbol_ref "flag_pic") (const_int 0))
- (const_int 24)]
- (const_int 32)))])
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc)
@@ -2078,16 +2088,16 @@
[(set_attr "type" "cbranch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
- (const_int 28)
+ (const_int 24)
(eq (symbol_ref "flag_pic") (const_int 0))
- (const_int 24)]
- (const_int 32)))])
+ (const_int 20)]
+ (const_int 28)))])
;; Branch on Variable Bit patterns.
(define_insn ""
@@ -2107,16 +2117,16 @@
[(set_attr "type" "cbranch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
- (const_int 28)
+ (const_int 24)
(eq (symbol_ref "flag_pic") (const_int 0))
- (const_int 24)]
- (const_int 32)))])
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc)
@@ -2135,16 +2145,16 @@
[(set_attr "type" "cbranch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
- (const_int 28)
+ (const_int 24)
(eq (symbol_ref "flag_pic") (const_int 0))
- (const_int 24)]
- (const_int 32)))])
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc)
@@ -2163,16 +2173,16 @@
[(set_attr "type" "cbranch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
- (const_int 28)
+ (const_int 24)
(eq (symbol_ref "flag_pic") (const_int 0))
- (const_int 24)]
- (const_int 32)))])
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc)
@@ -2191,16 +2201,16 @@
[(set_attr "type" "cbranch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
- (const_int 28)
+ (const_int 24)
(eq (symbol_ref "flag_pic") (const_int 0))
- (const_int 24)]
- (const_int 32)))])
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc)
@@ -2219,16 +2229,16 @@
[(set_attr "type" "cbranch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
- (const_int 28)
+ (const_int 24)
(eq (symbol_ref "flag_pic") (const_int 0))
- (const_int 24)]
- (const_int 32)))])
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc)
@@ -2247,16 +2257,16 @@
[(set_attr "type" "cbranch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
- (const_int 28)
+ (const_int 24)
(eq (symbol_ref "flag_pic") (const_int 0))
- (const_int 24)]
- (const_int 32)))])
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc)
@@ -2275,16 +2285,16 @@
[(set_attr "type" "cbranch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
- (const_int 28)
+ (const_int 24)
(eq (symbol_ref "flag_pic") (const_int 0))
- (const_int 24)]
- (const_int 32)))])
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc)
@@ -2303,16 +2313,16 @@
[(set_attr "type" "cbranch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
- (const_int 28)
+ (const_int 24)
(eq (symbol_ref "flag_pic") (const_int 0))
- (const_int 24)]
- (const_int 32)))])
+ (const_int 20)]
+ (const_int 28)))])
;; Floating point branches
@@ -2355,7 +2365,7 @@
[(set_attr "type" "fbranch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
(const_int 32)
@@ -2399,7 +2409,7 @@
[(set_attr "type" "fbranch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 12)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
(const_int 28)
@@ -7181,11 +7191,11 @@
(cond [(eq (symbol_ref "jump_in_call_delay (insn)") (const_int 1))
(if_then_else (lt (abs (minus (match_dup 0)
(plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(const_int 8))
(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 4)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
(const_int 20)
@@ -9007,10 +9017,10 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
;; Short branch has length of 4
;; Long branch has length of 8, 20, 24 or 28
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
(const_int 24)
@@ -9023,10 +9033,10 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
(if_then_else (eq_attr "alternative" "1")
(if_then_else (lt (match_dup 3) (pc))
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 24)
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 28)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
(const_int 44)
@@ -9034,10 +9044,10 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
(const_int 40)]
(const_int 48))
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 24)
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 28)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
(const_int 44)
@@ -9049,10 +9059,10 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
;; Extra goo to deal with additional reload insns.
(if_then_else (lt (match_dup 3) (pc))
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 12)
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 16)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
(const_int 32)
@@ -9060,10 +9070,10 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
(const_int 28)]
(const_int 36))
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 12)
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 16)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
(const_int 32)
@@ -9090,10 +9100,10 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
;; Short branch has length of 4
;; Long branch has length of 8, 20, 24 or 28
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
(const_int 24)
@@ -9106,10 +9116,10 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
(if_then_else (eq_attr "alternative" "1")
(if_then_else (lt (match_dup 3) (pc))
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 12)
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 16)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
(const_int 32)
@@ -9117,10 +9127,10 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
(const_int 28)]
(const_int 36))
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 12)
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 16)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
(const_int 32)
@@ -9131,10 +9141,10 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
;; Loop counter in memory or sar case.
;; Extra goo to deal with additional reload insns.
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 8)
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 12)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
(const_int 28)
@@ -9162,10 +9172,10 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
;; Short branch has length of 4
;; Long branch has length of 8
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
(const_int 24)
@@ -9178,10 +9188,10 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
(if_then_else (eq_attr "alternative" "1")
(if_then_else (lt (match_dup 3) (pc))
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 12)
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 16)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
(const_int 32)
@@ -9189,10 +9199,10 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
(const_int 28)]
(const_int 36))
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 12)
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 16)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
(const_int 32)
@@ -9203,10 +9213,10 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
;; Loop counter in memory or SAR case.
;; Extra goo to deal with additional reload insns.
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 8)
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 12)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
(const_int 28)
@@ -9227,10 +9237,10 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
[(set_attr "type" "parallel_branch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
(const_int 24)
@@ -9250,10 +9260,10 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
[(set_attr "type" "parallel_branch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
(const_int 24)
@@ -9273,10 +9283,10 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
[(set_attr "type" "parallel_branch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
(const_int 24)
@@ -9296,10 +9306,10 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
[(set_attr "type" "parallel_branch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
(const_int 24)
@@ -9319,10 +9329,10 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
[(set_attr "type" "parallel_branch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
(const_int 24)
diff --git a/gcc/config/pa/t-pa64 b/gcc/config/pa/t-pa64
index 9d4a545f16c..66cc4b5b04b 100644
--- a/gcc/config/pa/t-pa64
+++ b/gcc/config/pa/t-pa64
@@ -6,19 +6,19 @@ stublib.c: $(srcdir)/config/pa/stublib.c
rm -f stublib.c
cp $(srcdir)/config/pa/stublib.c .
-rfi-stub.o: stublib.c
+rfi-stub.o: stublib.c $(GCC_PASSES)
$(GCC_FOR_TARGET) -c -O2 -DL_register_frame_info stublib.c \
-o rfi-stub.o
-dfi-stub.o: stublib.c
+dfi-stub.o: stublib.c $(GCC_PASSES)
$(GCC_FOR_TARGET) -c -O2 -DL_deregister_frame_info stublib.c \
-o dfi-stub.o
-cxaf-stub.o: stublib.c
+cxaf-stub.o: stublib.c $(GCC_PASSES)
$(GCC_FOR_TARGET) -c -O2 -DL_cxa_finalize stublib.c \
-o cxaf-stub.o
-jvrc-stub.o: stublib.c
+jvrc-stub.o: stublib.c $(GCC_PASSES)
$(GCC_FOR_TARGET) -c -O2 -DL_Jv_RegisterClasses stublib.c \
-o jvrc-stub.o
diff --git a/gcc/config/rs6000/e500-double.h b/gcc/config/rs6000/e500-double.h
index 3c0d906a4bd..55587e469b8 100644
--- a/gcc/config/rs6000/e500-double.h
+++ b/gcc/config/rs6000/e500-double.h
@@ -1,5 +1,5 @@
/* Target definitions for E500 with double precision FP.
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
Contributed by Aldy Hernandez (aldyh@redhat.com).
This file is part of GCC.
@@ -21,5 +21,5 @@
#undef SUB3TARGET_OVERRIDE_OPTIONS
#define SUB3TARGET_OVERRIDE_OPTIONS \
- if (rs6000_float_gprs_string == NULL) \
+ if (!rs6000_explicit_options.float_gprs) \
rs6000_float_gprs = 2;
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index ec2cfdef933..e373e687f59 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -3402,9 +3402,12 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
&& !flag_pic
#endif
/* Don't do this for TFmode, since the result isn't offsettable.
- The same goes for DImode without 64-bit gprs. */
+ The same goes for DImode without 64-bit gprs and DFmode
+ without fprs. */
&& mode != TFmode
- && (mode != DImode || TARGET_POWERPC64))
+ && (mode != DImode || TARGET_POWERPC64)
+ && (mode != DFmode || TARGET_POWERPC64
+ || (TARGET_FPRS && TARGET_HARD_FLOAT)))
{
#if TARGET_MACHO
if (flag_pic)
@@ -5058,17 +5061,13 @@ rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
if (align_words + n_units > GP_ARG_NUM_REG)
/* Not all of the arg fits in gprs. Say that it goes in memory too,
using a magic NULL_RTX component.
- FIXME: This is not strictly correct. Only some of the arg
- belongs in memory, not all of it. However, there isn't any way
- to do this currently, apart from building rtx descriptions for
- the pieces of memory we want stored. Due to bugs in the generic
- code we can't use the normal function_arg_partial_nregs scheme
- with the PARALLEL arg description we emit here.
- In any case, the code to store the whole arg to memory is often
- more efficient than code to store pieces, and we know that space
- is available in the right place for the whole arg. */
- /* FIXME: This should be fixed since the conversion to
- TARGET_ARG_PARTIAL_BYTES. */
+ This is not strictly correct. Only some of the arg belongs in
+ memory, not all of it. However, the normal scheme using
+ function_arg_partial_nregs can result in unusual subregs, eg.
+ (subreg:SI (reg:DF) 4), which are not handled well. The code to
+ store the whole arg to memory is often more efficient than code
+ to store pieces, and we know that space is available in the right
+ place for the whole arg. */
rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
i = 0;
@@ -5310,9 +5309,8 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
include the portion actually in registers here. */
enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
rtx off;
- int i=0;
- if (align_words + n_words > GP_ARG_NUM_REG
- && (TARGET_32BIT && TARGET_POWERPC64))
+ int i = 0;
+ if (align_words + n_words > GP_ARG_NUM_REG)
/* Not all of the arg fits in gprs. Say that it
goes in memory too, using a magic NULL_RTX
component. Also see comment in
@@ -5391,18 +5389,20 @@ rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
align_words = rs6000_parm_start (mode, type, cum->words);
- if (USE_FP_FOR_ARG_P (cum, mode, type)
+ if (USE_FP_FOR_ARG_P (cum, mode, type))
+ {
/* If we are passing this arg in the fixed parameter save area
(gprs or memory) as well as fprs, then this function should
- return the number of bytes passed in the parameter save area
- rather than bytes passed in fprs. */
- && !(type
- && (cum->nargs_prototype <= 0
- || (DEFAULT_ABI == ABI_AIX
- && TARGET_XL_COMPAT
- && align_words >= GP_ARG_NUM_REG))))
- {
- if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3) > FP_ARG_MAX_REG + 1)
+ return the number of partial bytes passed in the parameter
+ save area rather than partial bytes passed in fprs. */
+ if (type
+ && (cum->nargs_prototype <= 0
+ || (DEFAULT_ABI == ABI_AIX
+ && TARGET_XL_COMPAT
+ && align_words >= GP_ARG_NUM_REG)))
+ return 0;
+ else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
+ > FP_ARG_MAX_REG + 1)
ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
else if (cum->nargs_prototype >= 0)
return 0;
@@ -5960,10 +5960,10 @@ rs6000_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
t = build1 (LABEL_EXPR, void_type_node, lab_false);
append_to_statement_list (t, pre_p);
- if (n_reg > 2)
+ if ((n_reg == 2 && reg != gpr) || n_reg > 2)
{
/* Ensure that we don't find any more args in regs.
- Alignment has taken care of the n_reg == 2 case. */
+ Alignment has taken care of the n_reg == 2 gpr case. */
t = build2 (MODIFY_EXPR, TREE_TYPE (reg), reg, size_int (8));
gimplify_and_add (t, pre_p);
}
@@ -15326,7 +15326,8 @@ rs6000_output_function_epilogue (FILE *file,
official way to discover the language being compiled, so we
use language_string.
C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
- Java is 13. Objective-C is 14. */
+ Java is 13. Objective-C is 14. Objective-C++ isn't assigned
+ a number, so for now use 9. */
if (! strcmp (language_string, "GNU C"))
i = 0;
else if (! strcmp (language_string, "GNU F77")
@@ -15336,7 +15337,8 @@ rs6000_output_function_epilogue (FILE *file,
i = 2;
else if (! strcmp (language_string, "GNU Ada"))
i = 3;
- else if (! strcmp (language_string, "GNU C++"))
+ else if (! strcmp (language_string, "GNU C++")
+ || ! strcmp (language_string, "GNU Objective-C++"))
i = 9;
else if (! strcmp (language_string, "GNU Java"))
i = 13;
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 75ff4a66cd6..f47324e3e12 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1024,7 +1024,7 @@ enum reg_class
{ 0xffffffff, 0x00000000, 0x0000000f, 0x00022000 }, /* SPEC_OR_GEN_REGS */ \
{ 0x00000000, 0x00000000, 0x00000010, 0x00000000 }, /* CR0_REGS */ \
{ 0x00000000, 0x00000000, 0x00000ff0, 0x00000000 }, /* CR_REGS */ \
- { 0xffffffff, 0x00000000, 0x0000efff, 0x00000000 }, /* NON_FLOAT_REGS */ \
+ { 0xffffffff, 0x00000000, 0x0000efff, 0x00020000 }, /* NON_FLOAT_REGS */ \
{ 0x00000000, 0x00000000, 0x00001000, 0x00000000 }, /* XER_REGS */ \
{ 0xffffffff, 0xffffffff, 0xffffffff, 0x0003ffff } /* ALL_REGS */ \
}
@@ -1598,7 +1598,8 @@ typedef struct rs6000_args
#define EASY_VECTOR_15(n) ((n) >= -16 && (n) <= 15)
#define EASY_VECTOR_15_ADD_SELF(n) (!EASY_VECTOR_15((n)) \
- && EASY_VECTOR_15((n) >> 1))
+ && EASY_VECTOR_15((n) >> 1) \
+ && ((n) & 1) == 0)
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.
diff --git a/gcc/config/rs6000/sfp-machine.h b/gcc/config/rs6000/sfp-machine.h
new file mode 100644
index 00000000000..29173e235dc
--- /dev/null
+++ b/gcc/config/rs6000/sfp-machine.h
@@ -0,0 +1,63 @@
+#define _FP_W_TYPE_SIZE 32
+#define _FP_W_TYPE unsigned long
+#define _FP_WS_TYPE signed long
+#define _FP_I_TYPE long
+
+#define _FP_MUL_MEAT_S(R,X,Y) \
+ _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_D(R,X,Y) \
+ _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y) \
+ _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_loop(S,R,X,Y)
+#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1)
+#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1), -1
+#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
+#define _FP_NANSIGN_S 0
+#define _FP_NANSIGN_D 0
+#define _FP_NANSIGN_Q 0
+
+#define _FP_KEEPNANFRACP 1
+
+/* Someone please check this. */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
+ do { \
+ if ((_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs) \
+ && !(_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)) \
+ { \
+ R##_s = Y##_s; \
+ _FP_FRAC_COPY_##wc(R,Y); \
+ } \
+ else \
+ { \
+ R##_s = X##_s; \
+ _FP_FRAC_COPY_##wc(R,X); \
+ } \
+ R##_c = FP_CLS_NAN; \
+ } while (0)
+
+#define __LITTLE_ENDIAN 1234
+#define __BIG_ENDIAN 4321
+
+#if defined __BIG_ENDIAN__ || defined _BIG_ENDIAN
+# if defined __LITTLE_ENDIAN__ || defined _LITTLE_ENDIAN
+# error "Both BIG_ENDIAN and LITTLE_ENDIAN defined!"
+# endif
+# define __BYTE_ORDER __BIG_ENDIAN
+#else
+# if defined __LITTLE_ENDIAN__ || defined _LITTLE_ENDIAN
+# define __BYTE_ORDER __LITTLE_ENDIAN
+# else
+# error "Cannot determine current byte order"
+# endif
+#endif
+
+
+/* Define ALIASNAME as a strong alias for NAME. */
+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+# define _strong_alias(name, aliasname) \
+ extern __typeof (name) aliasname __attribute__ ((alias (#name)));
diff --git a/gcc/config/rs6000/t-fprules b/gcc/config/rs6000/t-fprules
index d311d8c3187..aa686c15b00 100644
--- a/gcc/config/rs6000/t-fprules
+++ b/gcc/config/rs6000/t-fprules
@@ -1,15 +1,3 @@
-# We want fine grained libraries, so use the new code to build the
-# floating point emulation libraries.
-FPBIT = fp-bit.c
-DPBIT = dp-bit.c
-
-dp-bit.c: $(srcdir)/config/fp-bit.c
- cat $(srcdir)/config/fp-bit.c > dp-bit.c
-
-fp-bit.c: $(srcdir)/config/fp-bit.c
- echo '#define FLOAT' > fp-bit.c
- cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-
MULTILIB_MATCHES_FLOAT = msoft-float=mcpu?401 \
msoft-float=mcpu?403 \
msoft-float=mcpu?405 \
diff --git a/gcc/config/rs6000/t-fprules-fpbit b/gcc/config/rs6000/t-fprules-fpbit
new file mode 100644
index 00000000000..a80c1cf4eec
--- /dev/null
+++ b/gcc/config/rs6000/t-fprules-fpbit
@@ -0,0 +1,11 @@
+# We want fine grained libraries, so use the new code to build the
+# floating point emulation libraries.
+FPBIT = fp-bit.c
+DPBIT = dp-bit.c
+
+dp-bit.c: $(srcdir)/config/fp-bit.c
+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
+
+fp-bit.c: $(srcdir)/config/fp-bit.c
+ echo '#define FLOAT' > fp-bit.c
+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
diff --git a/gcc/config/rs6000/t-fprules-softfp b/gcc/config/rs6000/t-fprules-softfp
new file mode 100644
index 00000000000..10b271f036d
--- /dev/null
+++ b/gcc/config/rs6000/t-fprules-softfp
@@ -0,0 +1,6 @@
+softfp_float_modes := sf df
+softfp_int_modes := si di
+softfp_extensions := sfdf
+softfp_truncations := dfsf
+softfp_machine_header := rs6000/sfp-machine.h
+softfp_exclude_libgcc2 := y
diff --git a/gcc/config/rs6000/t-linux64 b/gcc/config/rs6000/t-linux64
index 2c30a89892f..a2c04f928e6 100644
--- a/gcc/config/rs6000/t-linux64
+++ b/gcc/config/rs6000/t-linux64
@@ -1,8 +1,9 @@
#rs6000/t-linux64
-LIB2FUNCS_EXTRA = tramp.S $(srcdir)/config/rs6000/ppc64-fp.c \
+LIB2FUNCS_EXTRA += tramp.S $(srcdir)/config/rs6000/ppc64-fp.c \
$(srcdir)/config/rs6000/darwin-ldouble.c
+LIB2FUNCS_EXTRA := $(sort $(LIB2FUNCS_EXTRA))
TARGET_LIBGCC2_CFLAGS += -mno-minimal-toc
@@ -14,19 +15,5 @@ MULTILIB_EXCLUSIONS = m64/!m32/msoft-float
MULTILIB_OSDIRNAMES = ../lib64 ../lib nof
MULTILIB_MATCHES = $(MULTILIB_MATCHES_FLOAT)
-# We want fine grained libraries, so use the new code to build the
-# floating point emulation libraries.
-# fp-bit is only to be used by 32-bit multilibs
-FPBIT = fp-bit32.c
-DPBIT = dp-bit32.c
-
-dp-bit32.c: $(srcdir)/config/fp-bit.c
- ( echo '#ifndef __powerpc64__'; \
- cat $(srcdir)/config/fp-bit.c; \
- echo '#endif' ) > dp-bit32.c
-
-fp-bit32.c: $(srcdir)/config/fp-bit.c
- ( echo '#ifndef __powerpc64__'; \
- echo '#define FLOAT'; \
- cat $(srcdir)/config/fp-bit.c; \
- echo '#endif' ) > fp-bit32.c
+softfp_wrap_start := '\#ifndef __powerpc64__'
+softfp_wrap_end := '\#endif'
diff --git a/gcc/config/rs6000/t-ppccomm b/gcc/config/rs6000/t-ppccomm
index e58dfe5f687..1ca509cd59a 100644
--- a/gcc/config/rs6000/t-ppccomm
+++ b/gcc/config/rs6000/t-ppccomm
@@ -1,6 +1,6 @@
# Common support for PowerPC ELF targets (both EABI and SVR4).
-LIB2FUNCS_EXTRA = tramp.S $(srcdir)/config/rs6000/darwin-ldouble.c
+LIB2FUNCS_EXTRA += tramp.S $(srcdir)/config/rs6000/darwin-ldouble.c
# This one can't end up in shared libgcc
LIB2FUNCS_STATIC_EXTRA = eabi.S
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index c03f8808b55..54822da8081 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -467,6 +467,7 @@
"ltgfr\t%2,%0"
[(set_attr "op_type" "RRE")])
+; ltr, lt, ltgr, ltg
(define_insn "*tst<mode>_extimm"
[(set (reg CC_REGNUM)
(compare (match_operand:GPR 0 "nonimmediate_operand" "d,m")
@@ -479,6 +480,7 @@
lt<g>\t%2,%0"
[(set_attr "op_type" "RR<E>,RXY")])
+; ltr, lt, ltgr, ltg
(define_insn "*tst<mode>_cconly_extimm"
[(set (reg CC_REGNUM)
(compare (match_operand:GPR 0 "nonimmediate_operand" "d,m")
@@ -534,6 +536,7 @@
[(set_attr "op_type" "RS")
(set_attr "atype" "reg")])
+; ltr, ltgr
(define_insn "*tst<mode>_cconly2"
[(set (reg CC_REGNUM)
(compare (match_operand:GPR 0 "register_operand" "d")
@@ -656,6 +659,7 @@
chy\t%0,%1"
[(set_attr "op_type" "RX,RXY")])
+; cr, chi, cfi, c, cy, cgr, cghi, cgfi, cg
(define_insn "*cmp<mode>_ccs"
[(set (reg CC_REGNUM)
(compare (match_operand:GPR 0 "register_operand" "d,d,d,d,d")
@@ -774,6 +778,7 @@
; (DF|SF) instructions
+; ltxbr, ltdbr, ltebr
(define_insn "*cmp<mode>_ccs_0"
[(set (reg CC_REGNUM)
(compare (match_operand:FPR 0 "register_operand" "f")
@@ -783,6 +788,7 @@
[(set_attr "op_type" "RRE")
(set_attr "type" "fsimp<mode>")])
+; ltxr, ltdr, lter
(define_insn "*cmp<mode>_ccs_0_ibm"
[(set (reg CC_REGNUM)
(compare (match_operand:FPR 0 "register_operand" "f")
@@ -792,6 +798,7 @@
[(set_attr "op_type" "<RRe>")
(set_attr "type" "fsimp<mode>")])
+; cxbr, cdbr, cebr, cxb, cdb, ceb
(define_insn "*cmp<mode>_ccs"
[(set (reg CC_REGNUM)
(compare (match_operand:FPR 0 "register_operand" "f,f")
@@ -803,6 +810,7 @@
[(set_attr "op_type" "RRE,RXE")
(set_attr "type" "fsimp<mode>")])
+; cxr, cdr, cer, cx, cd, ce
(define_insn "*cmp<mode>_ccs_ibm"
[(set (reg CC_REGNUM)
(compare (match_operand:FPR 0 "register_operand" "f,f")
@@ -2860,6 +2868,7 @@
; extendqi(si|di)2 instruction pattern(s).
;
+; lbr, lgbr, lb, lgb
(define_insn "*extendqi<mode>2_extimm"
[(set (match_operand:GPR 0 "register_operand" "=d,d")
(sign_extend:GPR (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
@@ -2869,6 +2878,7 @@
l<g>b\t%0,%1"
[(set_attr "op_type" "RRE,RXY")])
+; lb, lgb
(define_insn "*extendqi<mode>2"
[(set (match_operand:GPR 0 "register_operand" "=d")
(sign_extend:GPR (match_operand:QI 1 "memory_operand" "m")))]
@@ -3020,6 +3030,7 @@
}
})
+; llhr, llcr, llghr, llgcr, llh, llc, llgh, llgc
(define_insn "*zero_extend<HQI:mode><GPR:mode>2_extimm"
[(set (match_operand:GPR 0 "register_operand" "=d,d")
(zero_extend:GPR (match_operand:HQI 1 "nonimmediate_operand" "d,m")))]
@@ -3029,6 +3040,7 @@
ll<g><hc>\t%0,%1"
[(set_attr "op_type" "RRE,RXY")])
+; llgh, llgc
(define_insn "*zero_extend<HQI:mode><GPR:mode>2"
[(set (match_operand:GPR 0 "register_operand" "=d")
(zero_extend:GPR (match_operand:HQI 1 "memory_operand" "m")))]
@@ -3136,6 +3148,7 @@
DONE;
})
+; cgxbr, cgdbr, cgebr, cfxbr, cfdbr, cfebr
(define_insn "fix_trunc<FPR:mode><GPR:mode>2_ieee"
[(set (match_operand:GPR 0 "register_operand" "=d")
(fix:GPR (match_operand:FPR 1 "register_operand" "f")))
@@ -3234,6 +3247,7 @@
; float(si|di)(tf|df|sf)2 instruction pattern(s).
;
+; cxgbr, cdgbr, cegbr
(define_insn "floatdi<mode>2"
[(set (match_operand:FPR 0 "register_operand" "=f")
(float:FPR (match_operand:DI 1 "register_operand" "d")))]
@@ -3242,6 +3256,7 @@
[(set_attr "op_type" "RRE")
(set_attr "type" "itof" )])
+; cxfbr, cdfbr, cefbr
(define_insn "floatsi<mode>2_ieee"
[(set (match_operand:FPR 0 "register_operand" "=f")
(float:FPR (match_operand:SI 1 "register_operand" "d")))]
@@ -3682,6 +3697,7 @@
; add(di|si)3 instruction pattern(s).
;
+; ar, ahi, alfi, slfi, a, ay, agr, aghi, algfi, slgfi, ag
(define_insn "*add<mode>3"
[(set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d,d")
(plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0,0")
@@ -3697,6 +3713,7 @@
a<y>\t%0,%2"
[(set_attr "op_type" "RR<E>,RI,RIL,RIL,RX<Y>,RXY")])
+; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg
(define_insn "*add<mode>3_carry1_cc"
[(set (reg CC_REGNUM)
(compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0")
@@ -3713,6 +3730,7 @@
al<y>\t%0,%2"
[(set_attr "op_type" "RR<E>,RIL,RIL,RX<Y>,RXY")])
+; alr, al, aly, algr, alg
(define_insn "*add<mode>3_carry1_cconly"
[(set (reg CC_REGNUM)
(compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0")
@@ -3726,6 +3744,7 @@
al<y>\t%0,%2"
[(set_attr "op_type" "RR<E>,RX<Y>,RXY")])
+; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg
(define_insn "*add<mode>3_carry2_cc"
[(set (reg CC_REGNUM)
(compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0")
@@ -3742,6 +3761,7 @@
al<y>\t%0,%2"
[(set_attr "op_type" "RR<E>,RIL,RIL,RX<Y>,RXY")])
+; alr, al, aly, algr, alg
(define_insn "*add<mode>3_carry2_cconly"
[(set (reg CC_REGNUM)
(compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0")
@@ -3755,6 +3775,7 @@
al<y>\t%0,%2"
[(set_attr "op_type" "RR<E>,RX<Y>,RXY")])
+; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg
(define_insn "*add<mode>3_cc"
[(set (reg CC_REGNUM)
(compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0")
@@ -3771,6 +3792,7 @@
al<y>\t%0,%2"
[(set_attr "op_type" "RR<E>,RIL,RIL,RX<Y>,RXY")])
+; alr, al, aly, algr, alg
(define_insn "*add<mode>3_cconly"
[(set (reg CC_REGNUM)
(compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0")
@@ -3784,6 +3806,7 @@
al<y>\t%0,%2"
[(set_attr "op_type" "RR<E>,RX<Y>,RXY")])
+; alr, al, aly, algr, alg
(define_insn "*add<mode>3_cconly2"
[(set (reg CC_REGNUM)
(compare (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0")
@@ -3796,6 +3819,7 @@
al<y>\t%0,%2"
[(set_attr "op_type" "RR<E>,RX<Y>,RXY")])
+; ahi, afi, aghi, agfi
(define_insn "*add<mode>3_imm_cc"
[(set (reg CC_REGNUM)
(compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
@@ -3825,6 +3849,7 @@
"TARGET_HARD_FLOAT"
"")
+; axbr, adbr, aebr, axb, adb, aeb
(define_insn "*add<mode>3"
[(set (match_operand:FPR 0 "register_operand" "=f,f")
(plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0")
@@ -3837,6 +3862,7 @@
[(set_attr "op_type" "RRE,RXE")
(set_attr "type" "fsimp<mode>")])
+; axbr, adbr, aebr, axb, adb, aeb
(define_insn "*add<mode>3_cc"
[(set (reg CC_REGNUM)
(compare (plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0")
@@ -3851,6 +3877,7 @@
[(set_attr "op_type" "RRE,RXE")
(set_attr "type" "fsimp<mode>")])
+; axbr, adbr, aebr, axb, adb, aeb
(define_insn "*add<mode>3_cconly"
[(set (reg CC_REGNUM)
(compare (plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0")
@@ -3864,6 +3891,7 @@
[(set_attr "op_type" "RRE,RXE")
(set_attr "type" "fsimp<mode>")])
+; axr, adr, aer, ax, ad, ae
(define_insn "*add<mode>3_ibm"
[(set (match_operand:FPR 0 "register_operand" "=f,f")
(plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0")
@@ -4053,6 +4081,7 @@
; sub(di|si)3 instruction pattern(s).
;
+; sr, s, sy, sgr, sg
(define_insn "*sub<mode>3"
[(set (match_operand:GPR 0 "register_operand" "=d,d,d")
(minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0")
@@ -4065,6 +4094,7 @@
s<y>\t%0,%2"
[(set_attr "op_type" "RR<E>,RX<Y>,RXY")])
+; slr, sl, sly, slgr, slg
(define_insn "*sub<mode>3_borrow_cc"
[(set (reg CC_REGNUM)
(compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0")
@@ -4079,6 +4109,7 @@
sl<y>\t%0,%2"
[(set_attr "op_type" "RR<E>,RX<Y>,RXY")])
+; slr, sl, sly, slgr, slg
(define_insn "*sub<mode>3_borrow_cconly"
[(set (reg CC_REGNUM)
(compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0")
@@ -4092,6 +4123,7 @@
sl<y>\t%0,%2"
[(set_attr "op_type" "RR<E>,RX<Y>,RXY")])
+; slr, sl, sly, slgr, slg
(define_insn "*sub<mode>3_cc"
[(set (reg CC_REGNUM)
(compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0")
@@ -4106,6 +4138,7 @@
sl<y>\t%0,%2"
[(set_attr "op_type" "RR<E>,RX<Y>,RXY")])
+; slr, sl, sly, slgr, slg
(define_insn "*sub<mode>3_cc2"
[(set (reg CC_REGNUM)
(compare (match_operand:GPR 1 "register_operand" "0,0,0")
@@ -4119,6 +4152,7 @@
sl<y>\t%0,%2"
[(set_attr "op_type" "RR<E>,RX<Y>,RXY")])
+; slr, sl, sly, slgr, slg
(define_insn "*sub<mode>3_cconly"
[(set (reg CC_REGNUM)
(compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0")
@@ -4132,6 +4166,7 @@
sl<y>\t%0,%2"
[(set_attr "op_type" "RR<E>,RX<Y>,RXY")])
+; slr, sl, sly, slgr, slg
(define_insn "*sub<mode>3_cconly2"
[(set (reg CC_REGNUM)
(compare (match_operand:GPR 1 "register_operand" "0,0,0")
@@ -4157,6 +4192,7 @@
"TARGET_HARD_FLOAT"
"")
+; sxbr, sdbr, sebr, sxb, sdb, seb
(define_insn "*sub<mode>3"
[(set (match_operand:FPR 0 "register_operand" "=f,f")
(minus:FPR (match_operand:FPR 1 "register_operand" "0,0")
@@ -4169,6 +4205,7 @@
[(set_attr "op_type" "RRE,RXE")
(set_attr "type" "fsimp<mode>")])
+; sxbr, sdbr, sebr, sxb, sdb, seb
(define_insn "*sub<mode>3_cc"
[(set (reg CC_REGNUM)
(compare (minus:FPR (match_operand:FPR 1 "nonimmediate_operand" "0,0")
@@ -4183,6 +4220,7 @@
[(set_attr "op_type" "RRE,RXE")
(set_attr "type" "fsimp<mode>")])
+; sxbr, sdbr, sebr, sxb, sdb, seb
(define_insn "*sub<mode>3_cconly"
[(set (reg CC_REGNUM)
(compare (minus:FPR (match_operand:FPR 1 "nonimmediate_operand" "0,0")
@@ -4196,6 +4234,7 @@
[(set_attr "op_type" "RRE,RXE")
(set_attr "type" "fsimp<mode>")])
+; sxr, sdr, ser, sx, sd, se
(define_insn "*sub<mode>3_ibm"
[(set (match_operand:FPR 0 "register_operand" "=f,f")
(minus:FPR (match_operand:FPR 1 "register_operand" "0,0")
@@ -4217,6 +4256,7 @@
; add(di|si)cc instruction pattern(s).
;
+; alcr, alc, alcgr, alcg
(define_insn "*add<mode>3_alc_cc"
[(set (reg CC_REGNUM)
(compare
@@ -4232,6 +4272,7 @@
alc<g>\t%0,%2"
[(set_attr "op_type" "RRE,RXY")])
+; alcr, alc, alcgr, alcg
(define_insn "*add<mode>3_alc"
[(set (match_operand:GPR 0 "register_operand" "=d,d")
(plus:GPR (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0")
@@ -4244,6 +4285,7 @@
alc<g>\t%0,%2"
[(set_attr "op_type" "RRE,RXY")])
+; slbr, slb, slbgr, slbg
(define_insn "*sub<mode>3_slb_cc"
[(set (reg CC_REGNUM)
(compare
@@ -4259,6 +4301,7 @@
slb<g>\t%0,%2"
[(set_attr "op_type" "RRE,RXY")])
+; slbr, slb, slbgr, slbg
(define_insn "*sub<mode>3_slb"
[(set (match_operand:GPR 0 "register_operand" "=d,d")
(minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
@@ -4457,6 +4500,7 @@
"TARGET_HARD_FLOAT"
"")
+; mxbr mdbr, meebr, mxb, mxb, meeb
(define_insn "*mul<mode>3"
[(set (match_operand:FPR 0 "register_operand" "=f,f")
(mult:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0")
@@ -4468,6 +4512,7 @@
[(set_attr "op_type" "RRE,RXE")
(set_attr "type" "fmul<mode>")])
+; mxr, mdr, mer, mx, md, me
(define_insn "*mul<mode>3_ibm"
[(set (match_operand:FPR 0 "register_operand" "=f,f")
(mult:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0")
@@ -4479,6 +4524,7 @@
[(set_attr "op_type" "<RRe>,<RXe>")
(set_attr "type" "fmul<mode>")])
+; maxbr, madbr, maebr, maxb, madb, maeb
(define_insn "*fmadd<mode>"
[(set (match_operand:DSF 0 "register_operand" "=f,f")
(plus:DSF (mult:DSF (match_operand:DSF 1 "register_operand" "%f,f")
@@ -4491,6 +4537,7 @@
[(set_attr "op_type" "RRE,RXE")
(set_attr "type" "fmul<mode>")])
+; msxbr, msdbr, msebr, msxb, msdb, mseb
(define_insn "*fmsub<mode>"
[(set (match_operand:DSF 0 "register_operand" "=f,f")
(minus:DSF (mult:DSF (match_operand:DSF 1 "register_operand" "f,f")
@@ -4950,6 +4997,7 @@
"TARGET_HARD_FLOAT"
"")
+; dxbr, ddbr, debr, dxb, ddb, deb
(define_insn "*div<mode>3"
[(set (match_operand:FPR 0 "register_operand" "=f,f")
(div:FPR (match_operand:FPR 1 "register_operand" "0,0")
@@ -4961,6 +5009,7 @@
[(set_attr "op_type" "RRE,RXE")
(set_attr "type" "fdiv<mode>")])
+; dxr, ddr, der, dx, dd, de
(define_insn "*div<mode>3_ibm"
[(set (match_operand:FPR 0 "register_operand" "=f,f")
(div:FPR (match_operand:FPR 1 "register_operand" "0,0")
@@ -5878,6 +5927,7 @@
"lcgfr\t%0,%1"
[(set_attr "op_type" "RRE")])
+; lcr, lcgr
(define_insn "*neg<mode>2_cc"
[(set (reg CC_REGNUM)
(compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
@@ -5887,7 +5937,8 @@
"s390_match_ccmode (insn, CCAmode)"
"lc<g>r\t%0,%1"
[(set_attr "op_type" "RR<E>")])
-
+
+; lcr, lcgr
(define_insn "*neg<mode>2_cconly"
[(set (reg CC_REGNUM)
(compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
@@ -5896,7 +5947,8 @@
"s390_match_ccmode (insn, CCAmode)"
"lc<g>r\t%0,%1"
[(set_attr "op_type" "RR<E>")])
-
+
+; lcr, lcgr
(define_insn "*neg<mode>2"
[(set (match_operand:GPR 0 "register_operand" "=d")
(neg:GPR (match_operand:GPR 1 "register_operand" "d")))
@@ -5945,6 +5997,7 @@
"TARGET_HARD_FLOAT"
"")
+; lcxbr, lcdbr, lcebr
(define_insn "*neg<mode>2_cc"
[(set (reg CC_REGNUM)
(compare (neg:FPR (match_operand:FPR 1 "register_operand" "f"))
@@ -5955,7 +6008,8 @@
"lc<xde>br\t%0,%1"
[(set_attr "op_type" "RRE")
(set_attr "type" "fsimp<mode>")])
-
+
+; lcxbr, lcdbr, lcebr
(define_insn "*neg<mode>2_cconly"
[(set (reg CC_REGNUM)
(compare (neg:FPR (match_operand:FPR 1 "register_operand" "f"))
@@ -5965,7 +6019,8 @@
"lc<xde>br\t%0,%1"
[(set_attr "op_type" "RRE")
(set_attr "type" "fsimp<mode>")])
-
+
+; lcxbr, lcdbr, lcebr
(define_insn "*neg<mode>2"
[(set (match_operand:FPR 0 "register_operand" "=f")
(neg:FPR (match_operand:FPR 1 "register_operand" "f")))
@@ -5975,6 +6030,7 @@
[(set_attr "op_type" "RRE")
(set_attr "type" "fsimp<mode>")])
+; lcxr, lcdr, lcer
(define_insn "*neg<mode>2_ibm"
[(set (match_operand:FPR 0 "register_operand" "=f")
(neg:FPR (match_operand:FPR 1 "register_operand" "f")))
@@ -6013,6 +6069,7 @@
"lpgfr\t%0,%1"
[(set_attr "op_type" "RRE")])
+; lpr, lpgr
(define_insn "*abs<mode>2_cc"
[(set (reg CC_REGNUM)
(compare (abs:GPR (match_operand:DI 1 "register_operand" "d"))
@@ -6022,7 +6079,8 @@
"s390_match_ccmode (insn, CCAmode)"
"lp<g>r\t%0,%1"
[(set_attr "op_type" "RR<E>")])
-
+
+; lpr, lpgr
(define_insn "*abs<mode>2_cconly"
[(set (reg CC_REGNUM)
(compare (abs:GPR (match_operand:GPR 1 "register_operand" "d"))
@@ -6031,7 +6089,8 @@
"s390_match_ccmode (insn, CCAmode)"
"lp<g>r\t%0,%1"
[(set_attr "op_type" "RR<E>")])
-
+
+; lpr, lpgr
(define_insn "abs<mode>2"
[(set (match_operand:GPR 0 "register_operand" "=d")
(abs:GPR (match_operand:GPR 1 "register_operand" "d")))
@@ -6052,6 +6111,7 @@
"TARGET_HARD_FLOAT"
"")
+; lpxbr, lpdbr, lpebr
(define_insn "*abs<mode>2_cc"
[(set (reg CC_REGNUM)
(compare (abs:FPR (match_operand:FPR 1 "register_operand" "f"))
@@ -6062,7 +6122,8 @@
"lp<xde>br\t%0,%1"
[(set_attr "op_type" "RRE")
(set_attr "type" "fsimp<mode>")])
-
+
+; lpxbr, lpdbr, lpebr
(define_insn "*abs<mode>2_cconly"
[(set (reg CC_REGNUM)
(compare (abs:FPR (match_operand:FPR 1 "register_operand" "f"))
@@ -6072,7 +6133,8 @@
"lp<xde>br\t%0,%1"
[(set_attr "op_type" "RRE")
(set_attr "type" "fsimp<mode>")])
-
+
+; lpxbr, lpdbr, lpebr
(define_insn "*abs<mode>2"
[(set (match_operand:FPR 0 "register_operand" "=f")
(abs:FPR (match_operand:FPR 1 "register_operand" "f")))
@@ -6082,6 +6144,7 @@
[(set_attr "op_type" "RRE")
(set_attr "type" "fsimp<mode>")])
+; lpxr, lpdr, lper
(define_insn "*abs<mode>2_ibm"
[(set (match_operand:FPR 0 "register_operand" "=f")
(abs:FPR (match_operand:FPR 1 "register_operand" "f")))
@@ -6120,6 +6183,7 @@
"lngfr\t%0,%1"
[(set_attr "op_type" "RRE")])
+; lnr, lngr
(define_insn "*negabs<mode>2_cc"
[(set (reg CC_REGNUM)
(compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
@@ -6129,7 +6193,8 @@
"s390_match_ccmode (insn, CCAmode)"
"ln<g>r\t%0,%1"
[(set_attr "op_type" "RR<E>")])
-
+
+; lnr, lngr
(define_insn "*negabs<mode>2_cconly"
[(set (reg CC_REGNUM)
(compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
@@ -6138,7 +6203,8 @@
"s390_match_ccmode (insn, CCAmode)"
"ln<g>r\t%0,%1"
[(set_attr "op_type" "RR<E>")])
-
+
+; lnr, lngr
(define_insn "*negabs<mode>2"
[(set (match_operand:GPR 0 "register_operand" "=d")
(neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d"))))
@@ -6151,6 +6217,7 @@
; Floating point
;
+; lnxbr, lndbr, lnebr
(define_insn "*negabs<mode>2_cc"
[(set (reg CC_REGNUM)
(compare (neg:FPR (abs:FPR (match_operand:FPR 1 "register_operand" "f")))
@@ -6161,7 +6228,8 @@
"ln<xde>br\t%0,%1"
[(set_attr "op_type" "RRE")
(set_attr "type" "fsimp<mode>")])
-
+
+; lnxbr, lndbr, lnebr
(define_insn "*negabs<mode>2_cconly"
[(set (reg CC_REGNUM)
(compare (neg:FPR (abs:FPR (match_operand:FPR 1 "register_operand" "f")))
@@ -6171,7 +6239,8 @@
"ln<xde>br\t%0,%1"
[(set_attr "op_type" "RRE")
(set_attr "type" "fsimp<mode>")])
-
+
+; lnxbr, lndbr, lnebr
(define_insn "*negabs<mode>2"
[(set (match_operand:FPR 0 "register_operand" "=f")
(neg:FPR (abs:FPR (match_operand:FPR 1 "register_operand" "f"))))
@@ -6189,6 +6258,7 @@
; sqrt(df|sf)2 instruction pattern(s).
;
+; sqxbr, sqdbr, sqebr, sqxb, sqdb, sqeb
(define_insn "sqrt<mode>2"
[(set (match_operand:FPR 0 "register_operand" "=f,f")
(sqrt:FPR (match_operand:FPR 1 "general_operand" "f,<Rf>")))]
@@ -6269,6 +6339,7 @@
; rotl(di|si)3 instruction pattern(s).
;
+; rll, rllg
(define_insn "rotl<mode>3"
[(set (match_operand:GPR 0 "register_operand" "=d")
(rotate:GPR (match_operand:GPR 1 "register_operand" "d")
@@ -6278,6 +6349,7 @@
[(set_attr "op_type" "RSE")
(set_attr "atype" "reg")])
+; rll, rllg
(define_insn "*rotl<mode>3_and"
[(set (match_operand:GPR 0 "register_operand" "=d")
(rotate:GPR (match_operand:GPR 1 "register_operand" "d")
@@ -6304,6 +6376,7 @@
""
"")
+; sldl, srdl
(define_insn "*<shift>di3_31"
[(set (match_operand:DI 0 "register_operand" "=d")
(SHIFT:DI (match_operand:DI 1 "register_operand" "0")
@@ -6313,6 +6386,7 @@
[(set_attr "op_type" "RS")
(set_attr "atype" "reg")])
+; sll, srl, sllg, srlg
(define_insn "*<shift><mode>3"
[(set (match_operand:GPR 0 "register_operand" "=d")
(SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>")
@@ -6322,6 +6396,7 @@
[(set_attr "op_type" "RS<E>")
(set_attr "atype" "reg")])
+; sldl, srdl
(define_insn "*<shift>di3_31_and"
[(set (match_operand:DI 0 "register_operand" "=d")
(SHIFT:DI (match_operand:DI 1 "register_operand" "0")
@@ -6332,6 +6407,7 @@
[(set_attr "op_type" "RS")
(set_attr "atype" "reg")])
+; sll, srl, sllg, srlg
(define_insn "*<shift><mode>3_and"
[(set (match_operand:GPR 0 "register_operand" "=d")
(SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>")
@@ -6388,6 +6464,7 @@
[(set_attr "op_type" "RS")
(set_attr "atype" "reg")])
+; sra, srag
(define_insn "*ashr<mode>3_cc"
[(set (reg CC_REGNUM)
(compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>")
@@ -6400,6 +6477,7 @@
[(set_attr "op_type" "RS<E>")
(set_attr "atype" "reg")])
+; sra, srag
(define_insn "*ashr<mode>3_cconly"
[(set (reg CC_REGNUM)
(compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>")
@@ -6411,6 +6489,7 @@
[(set_attr "op_type" "RS<E>")
(set_attr "atype" "reg")])
+; sra, srag
(define_insn "*ashr<mode>3"
[(set (match_operand:GPR 0 "register_operand" "=d")
(ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>")
@@ -6462,6 +6541,7 @@
[(set_attr "op_type" "RS")
(set_attr "atype" "reg")])
+; sra, srag
(define_insn "*ashr<mode>3_cc_and"
[(set (reg CC_REGNUM)
(compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>")
@@ -6475,6 +6555,7 @@
[(set_attr "op_type" "RS<E>")
(set_attr "atype" "reg")])
+; sra, srag
(define_insn "*ashr<mode>3_cconly_and"
[(set (reg CC_REGNUM)
(compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>")
@@ -6487,6 +6568,7 @@
[(set_attr "op_type" "RS<E>")
(set_attr "atype" "reg")])
+; sra, srag
(define_insn "*ashr<mode>3_and"
[(set (match_operand:GPR 0 "register_operand" "=d")
(ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>")
@@ -7376,6 +7458,7 @@
s390_compare_emitted = operands[4];
})
+; cds, cdsg
(define_insn "*sync_compare_and_swap<mode>"
[(set (match_operand:DP 0 "register_operand" "=r")
(match_operand:DP 1 "memory_operand" "+Q"))
@@ -7392,6 +7475,7 @@
[(set_attr "op_type" "RS<TE>")
(set_attr "type" "sem")])
+; cs, csg
(define_insn "*sync_compare_and_swap<mode>"
[(set (match_operand:GPR 0 "register_operand" "=r")
(match_operand:GPR 1 "memory_operand" "+Q"))
diff --git a/gcc/config/sh/embed-elf.h b/gcc/config/sh/embed-elf.h
index f8c0713ee65..4497cf34636 100644
--- a/gcc/config/sh/embed-elf.h
+++ b/gcc/config/sh/embed-elf.h
@@ -25,7 +25,14 @@ Boston, MA 02110-1301, USA. */
#undef TARGET_POSIX_IO
+/* While the speed-optimized implementations of udivsi3_i4i / sdivsi3_i4i
+ in libgcc are not available for SH2, the space-optimized ones in
+ libgcc-Os-4-200 are. Thus, when not optimizing for space, link
+ libgcc-Os-4-200 after libgcc, so that -mdiv=call-table works for -m2. */
#define LIBGCC_SPEC "%{!shared: \
%{m4-100*:-lic_invalidate_array_4-100} \
%{m4-200*:-lic_invalidate_array_4-200} \
- %{m4a*:-lic_invalidate_array_4a}} -lgcc"
+ %{m4a*:-lic_invalidate_array_4a}} \
+ %{Os: -lgcc-Os-4-200} \
+ -lgcc \
+ %{!Os: -lgcc-Os-4-200}"
diff --git a/gcc/config/sh/lib1funcs-Os-4-200.asm b/gcc/config/sh/lib1funcs-Os-4-200.asm
new file mode 100644
index 00000000000..e71ccd1de6e
--- /dev/null
+++ b/gcc/config/sh/lib1funcs-Os-4-200.asm
@@ -0,0 +1,325 @@
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING. If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
+
+/* Moderately Space-optimized libgcc routines for the Renesas SH /
+ STMicroelectronics ST40 CPUs.
+ Contributed by J"orn Rennecke joern.rennecke@st.com. */
+
+#include "lib1funcs.h"
+
+#ifdef L_udivsi3_i4i
+
+/* 88 bytes; sh4-200 cycle counts:
+ divisor >= 2G: 11 cycles
+ dividend < 2G: 48 cycles
+ dividend >= 2G: divisor != 1: 54 cycles
+ dividend >= 2G, divisor == 1: 22 cycles */
+#if defined (__SH_FPU_DOUBLE__) || defined (__SH4_SINGLE_ONLY__)
+!! args in r4 and r5, result in r0, clobber r1
+
+ .global GLOBAL(udivsi3_i4i)
+ FUNC(GLOBAL(udivsi3_i4i))
+GLOBAL(udivsi3_i4i):
+ mova L1,r0
+ cmp/pz r5
+ sts fpscr,r1
+ lds.l @r0+,fpscr
+ sts.l fpul,@-r15
+ bf LOCAL(huge_divisor)
+ mov.l r1,@-r15
+ lds r4,fpul
+ cmp/pz r4
+#ifdef FMOVD_WORKS
+ fmov.d dr0,@-r15
+ float fpul,dr0
+ fmov.d dr2,@-r15
+ bt LOCAL(dividend_adjusted)
+ mov #1,r1
+ fmov.d @r0,dr2
+ cmp/eq r1,r5
+ bt LOCAL(div_by_1)
+ fadd dr2,dr0
+LOCAL(dividend_adjusted):
+ lds r5,fpul
+ float fpul,dr2
+ fdiv dr2,dr0
+LOCAL(div_by_1):
+ fmov.d @r15+,dr2
+ ftrc dr0,fpul
+ fmov.d @r15+,dr0
+#else /* !FMOVD_WORKS */
+ fmov.s DR01,@-r15
+ mov #1,r1
+ fmov.s DR00,@-r15
+ float fpul,dr0
+ fmov.s DR21,@-r15
+ bt/s LOCAL(dividend_adjusted)
+ fmov.s DR20,@-r15
+ cmp/eq r1,r5
+ bt LOCAL(div_by_1)
+ fmov.s @r0+,DR20
+ fmov.s @r0,DR21
+ fadd dr2,dr0
+LOCAL(dividend_adjusted):
+ lds r5,fpul
+ float fpul,dr2
+ fdiv dr2,dr0
+LOCAL(div_by_1):
+ fmov.s @r15+,DR20
+ fmov.s @r15+,DR21
+ ftrc dr0,fpul
+ fmov.s @r15+,DR00
+ fmov.s @r15+,DR01
+#endif /* !FMOVD_WORKS */
+ lds.l @r15+,fpscr
+ sts fpul,r0
+ rts
+ lds.l @r15+,fpul
+
+#ifdef FMOVD_WORKS
+ .p2align 3 ! make double below 8 byte aligned.
+#endif
+LOCAL(huge_divisor):
+ lds r1,fpscr
+ add #4,r15
+ cmp/hs r5,r4
+ rts
+ movt r0
+
+ .p2align 2
+L1:
+#ifndef FMOVD_WORKS
+ .long 0x80000
+#else
+ .long 0x180000
+#endif
+ .double 4294967296
+
+ ENDFUNC(GLOBAL(udivsi3_i4i))
+#elif !defined (__sh1__) /* !__SH_FPU_DOUBLE__ */
+
+#if 0
+/* With 36 bytes, the following would probably be the most compact
+ implementation, but with 139 cycles on an sh4-200, it is extremely slow. */
+GLOBAL(udivsi3_i4i):
+ mov.l r2,@-r15
+ mov #0,r1
+ div0u
+ mov r1,r2
+ mov.l r3,@-r15
+ mov r1,r3
+ sett
+ mov r4,r0
+LOCAL(loop):
+ rotcr r2
+ ;
+ bt/s LOCAL(end)
+ cmp/gt r2,r3
+ rotcl r0
+ bra LOCAL(loop)
+ div1 r5,r1
+LOCAL(end):
+ rotcl r0
+ mov.l @r15+,r3
+ rts
+ mov.l @r15+,r2
+#endif /* 0 */
+
+/* Size: 186 bytes jointly for udivsi3_i4i and sdivsi3_i4i
+ sh4-200 run times:
+ udiv small divisor: 55 cycles
+ udiv large divisor: 52 cycles
+ sdiv small divisor, positive result: 59 cycles
+ sdiv large divisor, positive result: 56 cycles
+ sdiv small divisor, negative result: 65 cycles (*)
+ sdiv large divisor, negative result: 62 cycles (*)
+ (*): r2 is restored in the rts delay slot and has a lingering latency
+ of two more cycles. */
+ .balign 4
+ .global GLOBAL(udivsi3_i4i)
+ FUNC(GLOBAL(udivsi3_i4i))
+ FUNC(GLOBAL(sdivsi3_i4i))
+GLOBAL(udivsi3_i4i):
+ sts pr,r1
+ mov.l r4,@-r15
+ extu.w r5,r0
+ cmp/eq r5,r0
+ swap.w r4,r0
+ shlr16 r4
+ bf/s LOCAL(large_divisor)
+ div0u
+ mov.l r5,@-r15
+ shll16 r5
+LOCAL(sdiv_small_divisor):
+ div1 r5,r4
+ bsr LOCAL(div6)
+ div1 r5,r4
+ div1 r5,r4
+ bsr LOCAL(div6)
+ div1 r5,r4
+ xtrct r4,r0
+ xtrct r0,r4
+ bsr LOCAL(div7)
+ swap.w r4,r4
+ div1 r5,r4
+ bsr LOCAL(div7)
+ div1 r5,r4
+ xtrct r4,r0
+ mov.l @r15+,r5
+ swap.w r0,r0
+ mov.l @r15+,r4
+ jmp @r1
+ rotcl r0
+LOCAL(div7):
+ div1 r5,r4
+LOCAL(div6):
+ div1 r5,r4; div1 r5,r4; div1 r5,r4
+ div1 r5,r4; div1 r5,r4; rts; div1 r5,r4
+
+LOCAL(divx3):
+ rotcl r0
+ div1 r5,r4
+ rotcl r0
+ div1 r5,r4
+ rotcl r0
+ rts
+ div1 r5,r4
+
+LOCAL(large_divisor):
+ mov.l r5,@-r15
+LOCAL(sdiv_large_divisor):
+ xor r4,r0
+ .rept 4
+ rotcl r0
+ bsr LOCAL(divx3)
+ div1 r5,r4
+ .endr
+ mov.l @r15+,r5
+ mov.l @r15+,r4
+ jmp @r1
+ rotcl r0
+ ENDFUNC(GLOBAL(udivsi3_i4i))
+
+ .global GLOBAL(sdivsi3_i4i)
+GLOBAL(sdivsi3_i4i):
+ mov.l r4,@-r15
+ cmp/pz r5
+ mov.l r5,@-r15
+ bt/s LOCAL(pos_divisor)
+ cmp/pz r4
+ neg r5,r5
+ extu.w r5,r0
+ bt/s LOCAL(neg_result)
+ cmp/eq r5,r0
+ neg r4,r4
+LOCAL(pos_result):
+ swap.w r4,r0
+ bra LOCAL(sdiv_check_divisor)
+ sts pr,r1
+LOCAL(pos_divisor):
+ extu.w r5,r0
+ bt/s LOCAL(pos_result)
+ cmp/eq r5,r0
+ neg r4,r4
+LOCAL(neg_result):
+ mova LOCAL(negate_result),r0
+ ;
+ mov r0,r1
+ swap.w r4,r0
+ lds r2,macl
+ sts pr,r2
+LOCAL(sdiv_check_divisor):
+ shlr16 r4
+ bf/s LOCAL(sdiv_large_divisor)
+ div0u
+ bra LOCAL(sdiv_small_divisor)
+ shll16 r5
+ .balign 4
+LOCAL(negate_result):
+ neg r0,r0
+ jmp @r2
+ sts macl,r2
+ ENDFUNC(GLOBAL(sdivsi3_i4i))
+#endif /* !__SH_FPU_DOUBLE__ */
+#endif /* L_udivsi3_i4i */
+
+#ifdef L_sdivsi3_i4i
+#if defined (__SH_FPU_DOUBLE__) || defined (__SH4_SINGLE_ONLY__)
+/* 48 bytes, 45 cycles on sh4-200 */
+!! args in r4 and r5, result in r0, clobber r1
+
+ .global GLOBAL(sdivsi3_i4i)
+ FUNC(GLOBAL(sdivsi3_i4i))
+GLOBAL(sdivsi3_i4i):
+ sts.l fpscr,@-r15
+ sts fpul,r1
+ mova L1,r0
+ lds.l @r0+,fpscr
+ lds r4,fpul
+#ifdef FMOVD_WORKS
+ fmov.d dr0,@-r15
+ float fpul,dr0
+ lds r5,fpul
+ fmov.d dr2,@-r15
+#else
+ fmov.s DR01,@-r15
+ fmov.s DR00,@-r15
+ float fpul,dr0
+ lds r5,fpul
+ fmov.s DR21,@-r15
+ fmov.s DR20,@-r15
+#endif
+ float fpul,dr2
+ fdiv dr2,dr0
+#ifdef FMOVD_WORKS
+ fmov.d @r15+,dr2
+#else
+ fmov.s @r15+,DR20
+ fmov.s @r15+,DR21
+#endif
+ ftrc dr0,fpul
+#ifdef FMOVD_WORKS
+ fmov.d @r15+,dr0
+#else
+ fmov.s @r15+,DR00
+ fmov.s @r15+,DR01
+#endif
+ lds.l @r15+,fpscr
+ sts fpul,r0
+ rts
+ lds r1,fpul
+
+ .p2align 2
+L1:
+#ifndef FMOVD_WORKS
+ .long 0x80000
+#else
+ .long 0x180000
+#endif
+
+ ENDFUNC(GLOBAL(sdivsi3_i4i))
+#endif /* __SH_FPU_DOUBLE__ */
+#endif /* L_sdivsi3_i4i */
diff --git a/gcc/config/sh/lib1funcs.asm b/gcc/config/sh/lib1funcs.asm
index 07292812abc..a815c3619e9 100644
--- a/gcc/config/sh/lib1funcs.asm
+++ b/gcc/config/sh/lib1funcs.asm
@@ -38,31 +38,7 @@ Boston, MA 02110-1301, USA. */
ELF local label prefixes by J"orn Rennecke
amylaar@cygnus.com */
-#ifdef __ELF__
-#define LOCAL(X) .L_##X
-#define FUNC(X) .type X,@function
-#define HIDDEN_FUNC(X) FUNC(X); .hidden X
-#define HIDDEN_ALIAS(X,Y) ALIAS (X,Y); .hidden GLOBAL(X)
-#define ENDFUNC0(X) .Lfe_##X: .size X,.Lfe_##X-X
-#define ENDFUNC(X) ENDFUNC0(X)
-#else
-#define LOCAL(X) L_##X
-#define FUNC(X)
-#define HIDDEN_FUNC(X)
-#define HIDDEN_ALIAS(X,Y) ALIAS (X,Y)
-#define ENDFUNC(X)
-#endif
-
-#define CONCAT(A,B) A##B
-#define GLOBAL0(U,X) CONCAT(U,__##X)
-#define GLOBAL(X) GLOBAL0(__USER_LABEL_PREFIX__,X)
-
-#define ALIAS(X,Y) .global GLOBAL(X); .set GLOBAL(X),GLOBAL(Y)
-
-#ifdef __SH2A__
-#undef FMOVD_WORKS
-#define FMOVD_WORKS
-#endif
+#include "lib1funcs.h"
#if ! __SH5__
#ifdef L_ashiftrt
@@ -1375,13 +1351,8 @@ GLOBAL(udivsi3_i4):
#ifdef FMOVD_WORKS
fmov.d @r0+,dr4
#else
-#ifdef __LITTLE_ENDIAN__
- fmov.s @r0+,fr5
- fmov.s @r0,fr4
-#else
- fmov.s @r0+,fr4
- fmov.s @r0,fr5
-#endif
+ fmov.s @r0+,DR40
+ fmov.s @r0,DR41
#endif
float fpul,dr0
xor r1,r5
@@ -1444,13 +1415,8 @@ GLOBAL(udivsi3_i4):
#ifdef FMOVD_WORKS
fmov.d @r0+,dr4
#else
-#ifdef __LITTLE_ENDIAN__
- fmov.s @r0+,fr5
- fmov.s @r0,fr4
-#else
- fmov.s @r0+,fr4
- fmov.s @r0,fr5
-#endif
+ fmov.s @r0+,DR40
+ fmov.s @r0,DR41
#endif
float fpul,dr0
xor r1,r5
diff --git a/gcc/config/sh/lib1funcs.h b/gcc/config/sh/lib1funcs.h
new file mode 100644
index 00000000000..566f3a5fc96
--- /dev/null
+++ b/gcc/config/sh/lib1funcs.h
@@ -0,0 +1,69 @@
+/* Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+ 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING. If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
+
+#ifdef __ELF__
+#define LOCAL(X) .L_##X
+#define FUNC(X) .type X,@function
+#define HIDDEN_FUNC(X) FUNC(X); .hidden X
+#define HIDDEN_ALIAS(X,Y) ALIAS (X,Y); .hidden GLOBAL(X)
+#define ENDFUNC0(X) .Lfe_##X: .size X,.Lfe_##X-X
+#define ENDFUNC(X) ENDFUNC0(X)
+#else
+#define LOCAL(X) L_##X
+#define FUNC(X)
+#define HIDDEN_FUNC(X)
+#define HIDDEN_ALIAS(X,Y) ALIAS (X,Y)
+#define ENDFUNC(X)
+#endif
+
+#define CONCAT(A,B) A##B
+#define GLOBAL0(U,X) CONCAT(U,__##X)
+#define GLOBAL(X) GLOBAL0(__USER_LABEL_PREFIX__,X)
+
+#define ALIAS(X,Y) .global GLOBAL(X); .set GLOBAL(X),GLOBAL(Y)
+
+#ifdef __SH2A__
+#undef FMOVD_WORKS
+#define FMOVD_WORKS
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define DR00 fr1
+#define DR01 fr0
+#define DR20 fr3
+#define DR21 fr2
+#define DR40 fr5
+#define DR41 fr4
+#else /* !__LITTLE_ENDIAN__ */
+#define DR00 fr0
+#define DR01 fr1
+#define DR20 fr2
+#define DR21 fr3
+#define DR40 fr4
+#define DR41 fr5
+#endif /* !__LITTLE_ENDIAN__ */
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index c61c357ec36..272d9e57eb6 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -631,7 +631,7 @@ do { \
|| (TARGET_HARD_SH4 && TARGET_SH2E) \
|| (TARGET_SHCOMPACT && TARGET_FPU_ANY))) \
sh_div_strategy = SH_DIV_CALL_FP; \
- else if (! strcmp (sh_div_str, "call-table") && TARGET_SH3) \
+ else if (! strcmp (sh_div_str, "call-table") && TARGET_SH2) \
sh_div_strategy = SH_DIV_CALL_TABLE; \
else \
/* Pick one that makes most sense for the target in general. \
@@ -651,6 +651,8 @@ do { \
sh_div_strategy = SH_DIV_CALL_FP; \
/* SH1 .. SH3 cores often go into small-footprint systems, so \
default to the smallest implementation available. */ \
+ else if (TARGET_SH2) /* ??? EXPERIMENTAL */ \
+ sh_div_strategy = SH_DIV_CALL_TABLE; \
else \
sh_div_strategy = SH_DIV_CALL_DIV1; \
} \
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index 0c9ab44d385..73f64ce704e 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -1094,6 +1094,8 @@
"(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
<= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
&& peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
+ && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
+ && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
&& ! reg_overlap_mentioned_p (operands[0], operands[3])
&& ! reg_overlap_mentioned_p (operands[2], operands[0])
&& ! reg_overlap_mentioned_p (operands[0], operands[1])
diff --git a/gcc/config/sh/symbian.c b/gcc/config/sh/symbian.c
index 8568f32f72d..4836d9b4e64 100644
--- a/gcc/config/sh/symbian.c
+++ b/gcc/config/sh/symbian.c
@@ -233,7 +233,7 @@ sh_symbian_mark_dllexport (tree decl)
unit which has included the header in order to ensure argument
correctness. */
oldname += strlen (DLL_IMPORT_PREFIX);
- DECL_NON_ADDR_CONST_P (decl) = 0;
+ DECL_DLLIMPORT_P (decl) = 0;
}
else if (sh_symbian_dllexport_name_p (oldname))
return; /* Already done. */
@@ -309,7 +309,7 @@ sh_symbian_encode_section_info (tree decl, rtx rtl, int first)
/* It might be that DECL has already been marked as dllimport, but a
subsequent definition nullified that. The attribute is gone but
DECL_RTL still has (DLL_IMPORT_PREFIX) prefixed. We need to remove
- that. Ditto for the DECL_NON_ADDR_CONST_P flag. */
+ that. Ditto for the DECL_DLLIMPORT_P flag. */
else if ( (TREE_CODE (decl) == FUNCTION_DECL
|| TREE_CODE (decl) == VAR_DECL)
&& DECL_RTL (decl) != NULL_RTX
@@ -330,7 +330,7 @@ sh_symbian_encode_section_info (tree decl, rtx rtl, int first)
XEXP (DECL_RTL (decl), 0) = newrtl;
- DECL_NON_ADDR_CONST_P (decl) = 0;
+ DECL_DLLIMPORT_P (decl) = 0;
}
}
diff --git a/gcc/config/sh/t-elf b/gcc/config/sh/t-elf
index 9d9454a7221..333efb54e09 100644
--- a/gcc/config/sh/t-elf
+++ b/gcc/config/sh/t-elf
@@ -1,5 +1,5 @@
EXTRA_MULTILIB_PARTS= crt1.o crti.o crtn.o \
- crtbegin.o crtend.o crtbeginS.o crtendS.o $(IC_EXTRA_PARTS)
+ crtbegin.o crtend.o crtbeginS.o crtendS.o $(IC_EXTRA_PARTS) $(OPT_EXTRA_PARTS)
# Compile crtbeginS.o and crtendS.o with pic.
CRTSTUFF_T_CFLAGS_S = -fPIC
diff --git a/gcc/config/sh/t-sh b/gcc/config/sh/t-sh
index 1efe67009e2..c81cc3fd020 100644
--- a/gcc/config/sh/t-sh
+++ b/gcc/config/sh/t-sh
@@ -76,7 +76,8 @@ gt-sh.h : s-gtype ; @true
IC_EXTRA_PARTS= libic_invalidate_array_4-100.a libic_invalidate_array_4-200.a \
libic_invalidate_array_4a.a
-EXTRA_MULTILIB_PARTS= $(IC_EXTRA_PARTS)
+OPT_EXTRA_PARTS= libgcc-Os-4-200.a
+EXTRA_MULTILIB_PARTS= $(IC_EXTRA_PARTS) $(OPT_EXTRA_PARTS)
$(T)ic_invalidate_array_4-100.o: $(srcdir)/config/sh/lib1funcs.asm $(GCC_PASSES)
$(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) -c -o $(T)ic_invalidate_array_4-100.o -DL_ic_invalidate_array -DWAYS=1 -DWAY_SIZE=0x2000 -x assembler-with-cpp $(srcdir)/config/sh/lib1funcs.asm
@@ -93,6 +94,13 @@ $(T)ic_invalidate_array_4a.o: $(srcdir)/config/sh/lib1funcs.asm $(GCC_PASSES)
$(T)libic_invalidate_array_4a.a: $(T)ic_invalidate_array_4a.o $(GCC_PASSES)
$(AR_CREATE_FOR_TARGET) $(T)libic_invalidate_array_4a.a $(T)ic_invalidate_array_4a.o
+$(T)sdivsi3_i4i-Os-4-200.o: $(srcdir)/config/sh/lib1funcs-Os-4-200.asm $(GCC_PASSES)
+ $(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) -c -o $@ -DL_sdivsi3_i4i -x assembler-with-cpp $<
+$(T)udivsi3_i4i-Os-4-200.o: $(srcdir)/config/sh/lib1funcs-Os-4-200.asm $(GCC_PASSES)
+ $(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) -c -o $@ -DL_udivsi3_i4i -x assembler-with-cpp $<
+$(T)libgcc-Os-4-200.a: $(T)sdivsi3_i4i-Os-4-200.o $(T)udivsi3_i4i-Os-4-200.o $(GCC_PASSES)
+ $(AR_CREATE_FOR_TARGET) $@ $(T)sdivsi3_i4i-Os-4-200.o $(T)udivsi3_i4i-Os-4-200.o
+
# Local Variables:
# mode: Makefile
# End:
diff --git a/gcc/config/sh/t-superh b/gcc/config/sh/t-superh
index 875f7529f24..429cec999e8 100644
--- a/gcc/config/sh/t-superh
+++ b/gcc/config/sh/t-superh
@@ -1,6 +1,6 @@
EXTRA_MULTILIB_PARTS= crt1.o crti.o crtn.o \
crtbegin.o crtend.o crtbeginS.o crtendS.o \
- crt1-mmu.o gcrt1-mmu.o gcrt1.o $(IC_EXTRA_PARTS)
+ crt1-mmu.o gcrt1-mmu.o gcrt1.o $(IC_EXTRA_PARTS) $(OPT_EXTRA_PARTS)
# Compile crt1-mmu.o as crt1.o with -DMMU_SUPPORT
$(T)crt1-mmu.o: $(srcdir)/config/sh/crt1.asm $(GCC_PASSES)
diff --git a/gcc/config/sh/t-symbian b/gcc/config/sh/t-symbian
index 494029fabfa..1d15d59c059 100644
--- a/gcc/config/sh/t-symbian
+++ b/gcc/config/sh/t-symbian
@@ -1,3 +1,7 @@
+sh-c.o: $(srcdir)/config/sh/sh-c.c \
+ $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TM_H) $(TM_P_H) coretypes.h
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/sh/sh-c.c
+
LIB1ASMSRC = sh/lib1funcs.asm
LIB1ASMFUNCS = _ashiftrt _ashiftrt_n _ashiftlt _lshiftrt _movstr \
_movstr_i4 _mulsi3 _sdivsi3 _sdivsi3_i4 _udivsi3 _udivsi3_i4 _set_fpscr \
diff --git a/gcc/config/soft-fp/README b/gcc/config/soft-fp/README
new file mode 100644
index 00000000000..870025cc53a
--- /dev/null
+++ b/gcc/config/soft-fp/README
@@ -0,0 +1,4 @@
+Except for t-softfp, the files in this directory are part of the GNU C
+Library, not part of GCC. As described at
+<http://gcc.gnu.org/codingconventions.html>, changes should be made to
+the GNU C Library and the changed files then imported into GCC.
diff --git a/gcc/config/soft-fp/adddf3.c b/gcc/config/soft-fp/adddf3.c
new file mode 100644
index 00000000000..24c03db0a64
--- /dev/null
+++ b/gcc/config/soft-fp/adddf3.c
@@ -0,0 +1,49 @@
+/* Software floating-point emulation.
+ Return a + b
+ Copyright (C) 1997,1999, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "double.h"
+
+DFtype __adddf3(DFtype a, DFtype b)
+{
+ FP_DECL_EX;
+ FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R);
+ DFtype r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_SEMIRAW_D(A, a);
+ FP_UNPACK_SEMIRAW_D(B, b);
+ FP_ADD_D(R, A, B);
+ FP_PACK_SEMIRAW_D(r, R);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/addsf3.c b/gcc/config/soft-fp/addsf3.c
new file mode 100644
index 00000000000..b86991ee562
--- /dev/null
+++ b/gcc/config/soft-fp/addsf3.c
@@ -0,0 +1,50 @@
+/* Software floating-point emulation.
+ Return a + b
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "single.h"
+
+SFtype __addsf3(SFtype a, SFtype b)
+{
+ FP_DECL_EX;
+ FP_DECL_S(A); FP_DECL_S(B); FP_DECL_S(R);
+ SFtype r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_SEMIRAW_S(A, a);
+ FP_UNPACK_SEMIRAW_S(B, b);
+ FP_ADD_S(R, A, B);
+ FP_PACK_SEMIRAW_S(r, R);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
+
diff --git a/gcc/config/soft-fp/addtf3.c b/gcc/config/soft-fp/addtf3.c
new file mode 100644
index 00000000000..49b67f0ba96
--- /dev/null
+++ b/gcc/config/soft-fp/addtf3.c
@@ -0,0 +1,49 @@
+/* Software floating-point emulation.
+ Return a + b
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+TFtype __addtf3(TFtype a, TFtype b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(R);
+ TFtype r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_SEMIRAW_Q(A, a);
+ FP_UNPACK_SEMIRAW_Q(B, b);
+ FP_ADD_Q(R, A, B);
+ FP_PACK_SEMIRAW_Q(r, R);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/divdf3.c b/gcc/config/soft-fp/divdf3.c
new file mode 100644
index 00000000000..c3bb0d247cb
--- /dev/null
+++ b/gcc/config/soft-fp/divdf3.c
@@ -0,0 +1,49 @@
+/* Software floating-point emulation.
+ Return a / b
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "double.h"
+
+DFtype __divdf3(DFtype a, DFtype b)
+{
+ FP_DECL_EX;
+ FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R);
+ DFtype r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_D(A, a);
+ FP_UNPACK_D(B, b);
+ FP_DIV_D(R, A, B);
+ FP_PACK_D(r, R);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/divsf3.c b/gcc/config/soft-fp/divsf3.c
new file mode 100644
index 00000000000..176bb3c2cb3
--- /dev/null
+++ b/gcc/config/soft-fp/divsf3.c
@@ -0,0 +1,49 @@
+/* Software floating-point emulation.
+ Return a / b
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "single.h"
+
+SFtype __divsf3(SFtype a, SFtype b)
+{
+ FP_DECL_EX;
+ FP_DECL_S(A); FP_DECL_S(B); FP_DECL_S(R);
+ SFtype r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_S(A, a);
+ FP_UNPACK_S(B, b);
+ FP_DIV_S(R, A, B);
+ FP_PACK_S(r, R);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/divtf3.c b/gcc/config/soft-fp/divtf3.c
new file mode 100644
index 00000000000..916fbfe9748
--- /dev/null
+++ b/gcc/config/soft-fp/divtf3.c
@@ -0,0 +1,49 @@
+/* Software floating-point emulation.
+ Return a / b
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+TFtype __divtf3(TFtype a, TFtype b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(R);
+ TFtype r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_Q(A, a);
+ FP_UNPACK_Q(B, b);
+ FP_DIV_Q(R, A, B);
+ FP_PACK_Q(r, R);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/double.h b/gcc/config/soft-fp/double.h
new file mode 100644
index 00000000000..c8f4420af85
--- /dev/null
+++ b/gcc/config/soft-fp/double.h
@@ -0,0 +1,264 @@
+/* Software floating-point emulation.
+ Definitions for IEEE Double Precision
+ Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com),
+ Jakub Jelinek (jj@ultra.linux.cz),
+ David S. Miller (davem@redhat.com) and
+ Peter Maydell (pmaydell@chiark.greenend.org.uk).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#if _FP_W_TYPE_SIZE < 32
+#error "Here's a nickel kid. Go buy yourself a real computer."
+#endif
+
+#if _FP_W_TYPE_SIZE < 64
+#define _FP_FRACTBITS_D (2 * _FP_W_TYPE_SIZE)
+#else
+#define _FP_FRACTBITS_D _FP_W_TYPE_SIZE
+#endif
+
+#define _FP_FRACBITS_D 53
+#define _FP_FRACXBITS_D (_FP_FRACTBITS_D - _FP_FRACBITS_D)
+#define _FP_WFRACBITS_D (_FP_WORKBITS + _FP_FRACBITS_D)
+#define _FP_WFRACXBITS_D (_FP_FRACTBITS_D - _FP_WFRACBITS_D)
+#define _FP_EXPBITS_D 11
+#define _FP_EXPBIAS_D 1023
+#define _FP_EXPMAX_D 2047
+
+#define _FP_QNANBIT_D \
+ ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-2) % _FP_W_TYPE_SIZE)
+#define _FP_QNANBIT_SH_D \
+ ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE)
+#define _FP_IMPLBIT_D \
+ ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-1) % _FP_W_TYPE_SIZE)
+#define _FP_IMPLBIT_SH_D \
+ ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE)
+#define _FP_OVERFLOW_D \
+ ((_FP_W_TYPE)1 << _FP_WFRACBITS_D % _FP_W_TYPE_SIZE)
+
+typedef float DFtype __attribute__((mode(DF)));
+
+#if _FP_W_TYPE_SIZE < 64
+
+union _FP_UNION_D
+{
+ DFtype flt;
+ struct {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned sign : 1;
+ unsigned exp : _FP_EXPBITS_D;
+ unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE;
+ unsigned frac0 : _FP_W_TYPE_SIZE;
+#else
+ unsigned frac0 : _FP_W_TYPE_SIZE;
+ unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE;
+ unsigned exp : _FP_EXPBITS_D;
+ unsigned sign : 1;
+#endif
+ } bits __attribute__((packed));
+};
+
+#define FP_DECL_D(X) _FP_DECL(2,X)
+#define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_2(D,X,val)
+#define FP_UNPACK_RAW_DP(X,val) _FP_UNPACK_RAW_2_P(D,X,val)
+#define FP_PACK_RAW_D(val,X) _FP_PACK_RAW_2(D,val,X)
+#define FP_PACK_RAW_DP(val,X) \
+ do { \
+ if (!FP_INHIBIT_RESULTS) \
+ _FP_PACK_RAW_2_P(D,val,X); \
+ } while (0)
+
+#define FP_UNPACK_D(X,val) \
+ do { \
+ _FP_UNPACK_RAW_2(D,X,val); \
+ _FP_UNPACK_CANONICAL(D,2,X); \
+ } while (0)
+
+#define FP_UNPACK_DP(X,val) \
+ do { \
+ _FP_UNPACK_RAW_2_P(D,X,val); \
+ _FP_UNPACK_CANONICAL(D,2,X); \
+ } while (0)
+
+#define FP_UNPACK_SEMIRAW_D(X,val) \
+ do { \
+ _FP_UNPACK_RAW_2(D,X,val); \
+ _FP_UNPACK_SEMIRAW(D,2,X); \
+ } while (0)
+
+#define FP_UNPACK_SEMIRAW_DP(X,val) \
+ do { \
+ _FP_UNPACK_RAW_2_P(D,X,val); \
+ _FP_UNPACK_SEMIRAW(D,2,X); \
+ } while (0)
+
+#define FP_PACK_D(val,X) \
+ do { \
+ _FP_PACK_CANONICAL(D,2,X); \
+ _FP_PACK_RAW_2(D,val,X); \
+ } while (0)
+
+#define FP_PACK_DP(val,X) \
+ do { \
+ _FP_PACK_CANONICAL(D,2,X); \
+ if (!FP_INHIBIT_RESULTS) \
+ _FP_PACK_RAW_2_P(D,val,X); \
+ } while (0)
+
+#define FP_PACK_SEMIRAW_D(val,X) \
+ do { \
+ _FP_PACK_SEMIRAW(D,2,X); \
+ _FP_PACK_RAW_2(D,val,X); \
+ } while (0)
+
+#define FP_PACK_SEMIRAW_DP(val,X) \
+ do { \
+ _FP_PACK_SEMIRAW(D,2,X); \
+ if (!FP_INHIBIT_RESULTS) \
+ _FP_PACK_RAW_2_P(D,val,X); \
+ } while (0)
+
+#define FP_ISSIGNAN_D(X) _FP_ISSIGNAN(D,2,X)
+#define FP_NEG_D(R,X) _FP_NEG(D,2,R,X)
+#define FP_ADD_D(R,X,Y) _FP_ADD(D,2,R,X,Y)
+#define FP_SUB_D(R,X,Y) _FP_SUB(D,2,R,X,Y)
+#define FP_MUL_D(R,X,Y) _FP_MUL(D,2,R,X,Y)
+#define FP_DIV_D(R,X,Y) _FP_DIV(D,2,R,X,Y)
+#define FP_SQRT_D(R,X) _FP_SQRT(D,2,R,X)
+#define _FP_SQRT_MEAT_D(R,S,T,X,Q) _FP_SQRT_MEAT_2(R,S,T,X,Q)
+
+#define FP_CMP_D(r,X,Y,un) _FP_CMP(D,2,r,X,Y,un)
+#define FP_CMP_EQ_D(r,X,Y) _FP_CMP_EQ(D,2,r,X,Y)
+#define FP_CMP_UNORD_D(r,X,Y) _FP_CMP_UNORD(D,2,r,X,Y)
+
+#define FP_TO_INT_D(r,X,rsz,rsg) _FP_TO_INT(D,2,r,X,rsz,rsg)
+#define FP_FROM_INT_D(X,r,rs,rt) _FP_FROM_INT(D,2,X,r,rs,rt)
+
+#define _FP_FRAC_HIGH_D(X) _FP_FRAC_HIGH_2(X)
+#define _FP_FRAC_HIGH_RAW_D(X) _FP_FRAC_HIGH_2(X)
+
+#else
+
+union _FP_UNION_D
+{
+ DFtype flt;
+ struct {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned sign : 1;
+ unsigned exp : _FP_EXPBITS_D;
+ unsigned long frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0);
+#else
+ unsigned long frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0);
+ unsigned exp : _FP_EXPBITS_D;
+ unsigned sign : 1;
+#endif
+ } bits __attribute__((packed));
+};
+
+#define FP_DECL_D(X) _FP_DECL(1,X)
+#define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_1(D,X,val)
+#define FP_UNPACK_RAW_DP(X,val) _FP_UNPACK_RAW_1_P(D,X,val)
+#define FP_PACK_RAW_D(val,X) _FP_PACK_RAW_1(D,val,X)
+#define FP_PACK_RAW_DP(val,X) \
+ do { \
+ if (!FP_INHIBIT_RESULTS) \
+ _FP_PACK_RAW_1_P(D,val,X); \
+ } while (0)
+
+#define FP_UNPACK_D(X,val) \
+ do { \
+ _FP_UNPACK_RAW_1(D,X,val); \
+ _FP_UNPACK_CANONICAL(D,1,X); \
+ } while (0)
+
+#define FP_UNPACK_DP(X,val) \
+ do { \
+ _FP_UNPACK_RAW_1_P(D,X,val); \
+ _FP_UNPACK_CANONICAL(D,1,X); \
+ } while (0)
+
+#define FP_UNPACK_SEMIRAW_D(X,val) \
+ do { \
+ _FP_UNPACK_RAW_2(1,X,val); \
+ _FP_UNPACK_SEMIRAW(D,1,X); \
+ } while (0)
+
+#define FP_UNPACK_SEMIRAW_DP(X,val) \
+ do { \
+ _FP_UNPACK_RAW_2_P(1,X,val); \
+ _FP_UNPACK_SEMIRAW(D,1,X); \
+ } while (0)
+
+#define FP_PACK_D(val,X) \
+ do { \
+ _FP_PACK_CANONICAL(D,1,X); \
+ _FP_PACK_RAW_1(D,val,X); \
+ } while (0)
+
+#define FP_PACK_DP(val,X) \
+ do { \
+ _FP_PACK_CANONICAL(D,1,X); \
+ if (!FP_INHIBIT_RESULTS) \
+ _FP_PACK_RAW_1_P(D,val,X); \
+ } while (0)
+
+#define FP_PACK_SEMIRAW_D(val,X) \
+ do { \
+ _FP_PACK_SEMIRAW(D,1,X); \
+ _FP_PACK_RAW_1(D,val,X); \
+ } while (0)
+
+#define FP_PACK_SEMIRAW_DP(val,X) \
+ do { \
+ _FP_PACK_SEMIRAW(D,1,X); \
+ if (!FP_INHIBIT_RESULTS) \
+ _FP_PACK_RAW_1_P(D,val,X); \
+ } while (0)
+
+#define FP_ISSIGNAN_D(X) _FP_ISSIGNAN(D,1,X)
+#define FP_NEG_D(R,X) _FP_NEG(D,1,R,X)
+#define FP_ADD_D(R,X,Y) _FP_ADD(D,1,R,X,Y)
+#define FP_SUB_D(R,X,Y) _FP_SUB(D,1,R,X,Y)
+#define FP_MUL_D(R,X,Y) _FP_MUL(D,1,R,X,Y)
+#define FP_DIV_D(R,X,Y) _FP_DIV(D,1,R,X,Y)
+#define FP_SQRT_D(R,X) _FP_SQRT(D,1,R,X)
+#define _FP_SQRT_MEAT_D(R,S,T,X,Q) _FP_SQRT_MEAT_1(R,S,T,X,Q)
+
+/* The implementation of _FP_MUL_D and _FP_DIV_D should be chosen by
+ the target machine. */
+
+#define FP_CMP_D(r,X,Y,un) _FP_CMP(D,1,r,X,Y,un)
+#define FP_CMP_EQ_D(r,X,Y) _FP_CMP_EQ(D,1,r,X,Y)
+#define FP_CMP_UNORD_D(r,X,Y) _FP_CMP_UNORD(D,1,r,X,Y)
+
+#define FP_TO_INT_D(r,X,rsz,rsg) _FP_TO_INT(D,1,r,X,rsz,rsg)
+#define FP_FROM_INT_D(X,r,rs,rt) _FP_FROM_INT(D,1,X,r,rs,rt)
+
+#define _FP_FRAC_HIGH_D(X) _FP_FRAC_HIGH_1(X)
+#define _FP_FRAC_HIGH_RAW_D(X) _FP_FRAC_HIGH_1(X)
+
+#endif /* W_TYPE_SIZE < 64 */
diff --git a/gcc/config/soft-fp/eqdf2.c b/gcc/config/soft-fp/eqdf2.c
new file mode 100644
index 00000000000..efa769e986d
--- /dev/null
+++ b/gcc/config/soft-fp/eqdf2.c
@@ -0,0 +1,51 @@
+/* Software floating-point emulation.
+ Return 0 iff a == b, 1 otherwise
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "double.h"
+
+int __eqdf2(DFtype a, DFtype b)
+{
+ FP_DECL_EX;
+ FP_DECL_D(A); FP_DECL_D(B);
+ int r;
+
+ FP_UNPACK_RAW_D(A, a);
+ FP_UNPACK_RAW_D(B, b);
+ FP_CMP_EQ_D(r, A, B);
+ if (r && (FP_ISSIGNAN_D(A) || FP_ISSIGNAN_D(B)))
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
+
+strong_alias(__eqdf2, __nedf2);
diff --git a/gcc/config/soft-fp/eqsf2.c b/gcc/config/soft-fp/eqsf2.c
new file mode 100644
index 00000000000..7e01c01d2f4
--- /dev/null
+++ b/gcc/config/soft-fp/eqsf2.c
@@ -0,0 +1,51 @@
+/* Software floating-point emulation.
+ Return 0 iff a == b, 1 otherwise
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "single.h"
+
+int __eqsf2(SFtype a, SFtype b)
+{
+ FP_DECL_EX;
+ FP_DECL_S(A); FP_DECL_S(B);
+ int r;
+
+ FP_UNPACK_RAW_S(A, a);
+ FP_UNPACK_RAW_S(B, b);
+ FP_CMP_EQ_S(r, A, B);
+ if (r && (FP_ISSIGNAN_S(A) || FP_ISSIGNAN_S(B)))
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
+
+strong_alias(__eqsf2, __nesf2);
diff --git a/gcc/config/soft-fp/eqtf2.c b/gcc/config/soft-fp/eqtf2.c
new file mode 100644
index 00000000000..fd6ffd1ebef
--- /dev/null
+++ b/gcc/config/soft-fp/eqtf2.c
@@ -0,0 +1,51 @@
+/* Software floating-point emulation.
+ Return 0 iff a == b, 1 otherwise
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int __eqtf2(TFtype a, TFtype b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B);
+ int r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_UNPACK_RAW_Q(B, b);
+ FP_CMP_EQ_Q(r, A, B);
+ if (r && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B)))
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
+
+strong_alias(__eqtf2, __netf2);
diff --git a/gcc/config/soft-fp/extenddftf2.c b/gcc/config/soft-fp/extenddftf2.c
new file mode 100644
index 00000000000..4101639a947
--- /dev/null
+++ b/gcc/config/soft-fp/extenddftf2.c
@@ -0,0 +1,54 @@
+/* Software floating-point emulation.
+ Return a converted to IEEE quad
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "double.h"
+#include "quad.h"
+
+TFtype __extenddftf2(DFtype a)
+{
+ FP_DECL_EX;
+ FP_DECL_D(A);
+ FP_DECL_Q(R);
+ TFtype r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_RAW_D(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+ FP_EXTEND(Q,D,4,2,R,A);
+#else
+ FP_EXTEND(Q,D,2,1,R,A);
+#endif
+ FP_PACK_RAW_Q(r, R);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/extended.h b/gcc/config/soft-fp/extended.h
new file mode 100644
index 00000000000..bbf39429e7f
--- /dev/null
+++ b/gcc/config/soft-fp/extended.h
@@ -0,0 +1,453 @@
+/* Software floating-point emulation.
+ Definitions for IEEE Extended Precision.
+ Copyright (C) 1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#if _FP_W_TYPE_SIZE < 32
+#error "Here's a nickel, kid. Go buy yourself a real computer."
+#endif
+
+#if _FP_W_TYPE_SIZE < 64
+#define _FP_FRACTBITS_E (4*_FP_W_TYPE_SIZE)
+#else
+#define _FP_FRACTBITS_E (2*_FP_W_TYPE_SIZE)
+#endif
+
+#define _FP_FRACBITS_E 64
+#define _FP_FRACXBITS_E (_FP_FRACTBITS_E - _FP_FRACBITS_E)
+#define _FP_WFRACBITS_E (_FP_WORKBITS + _FP_FRACBITS_E)
+#define _FP_WFRACXBITS_E (_FP_FRACTBITS_E - _FP_WFRACBITS_E)
+#define _FP_EXPBITS_E 15
+#define _FP_EXPBIAS_E 16383
+#define _FP_EXPMAX_E 32767
+
+#define _FP_QNANBIT_E \
+ ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-2) % _FP_W_TYPE_SIZE)
+#define _FP_QNANBIT_SH_E \
+ ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE)
+#define _FP_IMPLBIT_E \
+ ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-1) % _FP_W_TYPE_SIZE)
+#define _FP_IMPLBIT_SH_E \
+ ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE)
+#define _FP_OVERFLOW_E \
+ ((_FP_W_TYPE)1 << (_FP_WFRACBITS_E % _FP_W_TYPE_SIZE))
+
+typedef float XFtype __attribute__((mode(XF)));
+
+#if _FP_W_TYPE_SIZE < 64
+
+union _FP_UNION_E
+{
+ XFtype flt;
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned long pad1 : _FP_W_TYPE_SIZE;
+ unsigned long pad2 : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E);
+ unsigned long sign : 1;
+ unsigned long exp : _FP_EXPBITS_E;
+ unsigned long frac1 : _FP_W_TYPE_SIZE;
+ unsigned long frac0 : _FP_W_TYPE_SIZE;
+#else
+ unsigned long frac0 : _FP_W_TYPE_SIZE;
+ unsigned long frac1 : _FP_W_TYPE_SIZE;
+ unsigned exp : _FP_EXPBITS_E;
+ unsigned sign : 1;
+#endif /* not bigendian */
+ } bits __attribute__((packed));
+};
+
+
+#define FP_DECL_E(X) _FP_DECL(4,X)
+
+#define FP_UNPACK_RAW_E(X, val) \
+ do { \
+ union _FP_UNION_E _flo; _flo.flt = (val); \
+ \
+ X##_f[2] = 0; X##_f[3] = 0; \
+ X##_f[0] = _flo.bits.frac0; \
+ X##_f[1] = _flo.bits.frac1; \
+ X##_e = _flo.bits.exp; \
+ X##_s = _flo.bits.sign; \
+ if (!X##_e && (X##_f[1] || X##_f[0]) \
+ && !(X##_f[1] & _FP_IMPLBIT_E)) \
+ { \
+ X##_e++; \
+ FP_SET_EXCEPTION(FP_EX_DENORM); \
+ } \
+ } while (0)
+
+#define FP_UNPACK_RAW_EP(X, val) \
+ do { \
+ union _FP_UNION_E *_flo = \
+ (union _FP_UNION_E *)(val); \
+ \
+ X##_f[2] = 0; X##_f[3] = 0; \
+ X##_f[0] = _flo->bits.frac0; \
+ X##_f[1] = _flo->bits.frac1; \
+ X##_e = _flo->bits.exp; \
+ X##_s = _flo->bits.sign; \
+ if (!X##_e && (X##_f[1] || X##_f[0]) \
+ && !(X##_f[1] & _FP_IMPLBIT_E)) \
+ { \
+ X##_e++; \
+ FP_SET_EXCEPTION(FP_EX_DENORM); \
+ } \
+ } while (0)
+
+#define FP_PACK_RAW_E(val, X) \
+ do { \
+ union _FP_UNION_E _flo; \
+ \
+ if (X##_e) X##_f[1] |= _FP_IMPLBIT_E; \
+ else X##_f[1] &= ~(_FP_IMPLBIT_E); \
+ _flo.bits.frac0 = X##_f[0]; \
+ _flo.bits.frac1 = X##_f[1]; \
+ _flo.bits.exp = X##_e; \
+ _flo.bits.sign = X##_s; \
+ \
+ (val) = _flo.flt; \
+ } while (0)
+
+#define FP_PACK_RAW_EP(val, X) \
+ do { \
+ if (!FP_INHIBIT_RESULTS) \
+ { \
+ union _FP_UNION_E *_flo = \
+ (union _FP_UNION_E *)(val); \
+ \
+ if (X##_e) X##_f[1] |= _FP_IMPLBIT_E; \
+ else X##_f[1] &= ~(_FP_IMPLBIT_E); \
+ _flo->bits.frac0 = X##_f[0]; \
+ _flo->bits.frac1 = X##_f[1]; \
+ _flo->bits.exp = X##_e; \
+ _flo->bits.sign = X##_s; \
+ } \
+ } while (0)
+
+#define FP_UNPACK_E(X,val) \
+ do { \
+ FP_UNPACK_RAW_E(X,val); \
+ _FP_UNPACK_CANONICAL(E,4,X); \
+ } while (0)
+
+#define FP_UNPACK_EP(X,val) \
+ do { \
+ FP_UNPACK_RAW_EP(X,val); \
+ _FP_UNPACK_CANONICAL(E,4,X); \
+ } while (0)
+
+#define FP_UNPACK_SEMIRAW_E(X,val) \
+ do { \
+ _FP_UNPACK_RAW_E(X,val); \
+ _FP_UNPACK_SEMIRAW(E,4,X); \
+ } while (0)
+
+#define FP_UNPACK_SEMIRAW_EP(X,val) \
+ do { \
+ _FP_UNPACK_RAW_EP(X,val); \
+ _FP_UNPACK_SEMIRAW(E,4,X); \
+ } while (0)
+
+#define FP_PACK_E(val,X) \
+ do { \
+ _FP_PACK_CANONICAL(E,4,X); \
+ FP_PACK_RAW_E(val,X); \
+ } while (0)
+
+#define FP_PACK_EP(val,X) \
+ do { \
+ _FP_PACK_CANONICAL(E,4,X); \
+ FP_PACK_RAW_EP(val,X); \
+ } while (0)
+
+#define FP_PACK_SEMIRAW_E(val,X) \
+ do { \
+ _FP_PACK_SEMIRAW(E,4,X); \
+ _FP_PACK_RAW_E(val,X); \
+ } while (0)
+
+#define FP_PACK_SEMIRAW_EP(val,X) \
+ do { \
+ _FP_PACK_SEMIRAW(E,4,X); \
+ _FP_PACK_RAW_EP(val,X); \
+ } while (0)
+
+#define FP_ISSIGNAN_E(X) _FP_ISSIGNAN(E,4,X)
+#define FP_NEG_E(R,X) _FP_NEG(E,4,R,X)
+#define FP_ADD_E(R,X,Y) _FP_ADD(E,4,R,X,Y)
+#define FP_SUB_E(R,X,Y) _FP_SUB(E,4,R,X,Y)
+#define FP_MUL_E(R,X,Y) _FP_MUL(E,4,R,X,Y)
+#define FP_DIV_E(R,X,Y) _FP_DIV(E,4,R,X,Y)
+#define FP_SQRT_E(R,X) _FP_SQRT(E,4,R,X)
+
+/*
+ * Square root algorithms:
+ * We have just one right now, maybe Newton approximation
+ * should be added for those machines where division is fast.
+ * This has special _E version because standard _4 square
+ * root would not work (it has to start normally with the
+ * second word and not the first), but as we have to do it
+ * anyway, we optimize it by doing most of the calculations
+ * in two UWtype registers instead of four.
+ */
+
+#define _FP_SQRT_MEAT_E(R, S, T, X, q) \
+ do { \
+ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \
+ _FP_FRAC_SRL_4(X, (_FP_WORKBITS)); \
+ while (q) \
+ { \
+ T##_f[1] = S##_f[1] + q; \
+ if (T##_f[1] <= X##_f[1]) \
+ { \
+ S##_f[1] = T##_f[1] + q; \
+ X##_f[1] -= T##_f[1]; \
+ R##_f[1] += q; \
+ } \
+ _FP_FRAC_SLL_2(X, 1); \
+ q >>= 1; \
+ } \
+ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \
+ while (q) \
+ { \
+ T##_f[0] = S##_f[0] + q; \
+ T##_f[1] = S##_f[1]; \
+ if (T##_f[1] < X##_f[1] || \
+ (T##_f[1] == X##_f[1] && \
+ T##_f[0] <= X##_f[0])) \
+ { \
+ S##_f[0] = T##_f[0] + q; \
+ S##_f[1] += (T##_f[0] > S##_f[0]); \
+ _FP_FRAC_DEC_2(X, T); \
+ R##_f[0] += q; \
+ } \
+ _FP_FRAC_SLL_2(X, 1); \
+ q >>= 1; \
+ } \
+ _FP_FRAC_SLL_4(R, (_FP_WORKBITS)); \
+ if (X##_f[0] | X##_f[1]) \
+ { \
+ if (S##_f[1] < X##_f[1] || \
+ (S##_f[1] == X##_f[1] && \
+ S##_f[0] < X##_f[0])) \
+ R##_f[0] |= _FP_WORK_ROUND; \
+ R##_f[0] |= _FP_WORK_STICKY; \
+ } \
+ } while (0)
+
+#define FP_CMP_E(r,X,Y,un) _FP_CMP(E,4,r,X,Y,un)
+#define FP_CMP_EQ_E(r,X,Y) _FP_CMP_EQ(E,4,r,X,Y)
+#define FP_CMP_UNORD_E(r,X,Y) _FP_CMP_UNORD(E,4,r,X,Y)
+
+#define FP_TO_INT_E(r,X,rsz,rsg) _FP_TO_INT(E,4,r,X,rsz,rsg)
+#define FP_FROM_INT_E(X,r,rs,rt) _FP_FROM_INT(E,4,X,r,rs,rt)
+
+#define _FP_FRAC_HIGH_E(X) (X##_f[2])
+#define _FP_FRAC_HIGH_RAW_E(X) (X##_f[1])
+
+#else /* not _FP_W_TYPE_SIZE < 64 */
+union _FP_UNION_E
+{
+ XFtype flt;
+ struct {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned long pad : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E);
+ unsigned sign : 1;
+ unsigned exp : _FP_EXPBITS_E;
+ unsigned long frac : _FP_W_TYPE_SIZE;
+#else
+ unsigned long frac : _FP_W_TYPE_SIZE;
+ unsigned exp : _FP_EXPBITS_E;
+ unsigned sign : 1;
+#endif
+ } bits;
+};
+
+#define FP_DECL_E(X) _FP_DECL(2,X)
+
+#define FP_UNPACK_RAW_E(X, val) \
+ do { \
+ union _FP_UNION_E _flo; _flo.flt = (val); \
+ \
+ X##_f0 = _flo.bits.frac; \
+ X##_f1 = 0; \
+ X##_e = _flo.bits.exp; \
+ X##_s = _flo.bits.sign; \
+ if (!X##_e && X##_f0 && !(X##_f0 & _FP_IMPLBIT_E)) \
+ { \
+ X##_e++; \
+ FP_SET_EXCEPTION(FP_EX_DENORM); \
+ } \
+ } while (0)
+
+#define FP_UNPACK_RAW_EP(X, val) \
+ do { \
+ union _FP_UNION_E *_flo = \
+ (union _FP_UNION_E *)(val); \
+ \
+ X##_f0 = _flo->bits.frac; \
+ X##_f1 = 0; \
+ X##_e = _flo->bits.exp; \
+ X##_s = _flo->bits.sign; \
+ if (!X##_e && X##_f0 && !(X##_f0 & _FP_IMPLBIT_E)) \
+ { \
+ X##_e++; \
+ FP_SET_EXCEPTION(FP_EX_DENORM); \
+ } \
+ } while (0)
+
+#define FP_PACK_RAW_E(val, X) \
+ do { \
+ union _FP_UNION_E _flo; \
+ \
+ if (X##_e) X##_f0 |= _FP_IMPLBIT_E; \
+ else X##_f0 &= ~(_FP_IMPLBIT_E); \
+ _flo.bits.frac = X##_f0; \
+ _flo.bits.exp = X##_e; \
+ _flo.bits.sign = X##_s; \
+ \
+ (val) = _flo.flt; \
+ } while (0)
+
+#define FP_PACK_RAW_EP(fs, val, X) \
+ do { \
+ if (!FP_INHIBIT_RESULTS) \
+ { \
+ union _FP_UNION_E *_flo = \
+ (union _FP_UNION_E *)(val); \
+ \
+ if (X##_e) X##_f0 |= _FP_IMPLBIT_E; \
+ else X##_f0 &= ~(_FP_IMPLBIT_E); \
+ _flo->bits.frac = X##_f0; \
+ _flo->bits.exp = X##_e; \
+ _flo->bits.sign = X##_s; \
+ } \
+ } while (0)
+
+
+#define FP_UNPACK_E(X,val) \
+ do { \
+ FP_UNPACK_RAW_E(X,val); \
+ _FP_UNPACK_CANONICAL(E,2,X); \
+ } while (0)
+
+#define FP_UNPACK_EP(X,val) \
+ do { \
+ FP_UNPACK_RAW_EP(X,val); \
+ _FP_UNPACK_CANONICAL(E,2,X); \
+ } while (0)
+
+#define FP_UNPACK_SEMIRAW_E(X,val) \
+ do { \
+ _FP_UNPACK_RAW_E(X,val); \
+ _FP_UNPACK_SEMIRAW(E,2,X); \
+ } while (0)
+
+#define FP_UNPACK_SEMIRAW_EP(X,val) \
+ do { \
+ _FP_UNPACK_RAW_EP(X,val); \
+ _FP_UNPACK_SEMIRAW(E,2,X); \
+ } while (0)
+
+#define FP_PACK_E(val,X) \
+ do { \
+ _FP_PACK_CANONICAL(E,2,X); \
+ FP_PACK_RAW_E(val,X); \
+ } while (0)
+
+#define FP_PACK_EP(val,X) \
+ do { \
+ _FP_PACK_CANONICAL(E,2,X); \
+ FP_PACK_RAW_EP(val,X); \
+ } while (0)
+
+#define FP_PACK_SEMIRAW_E(val,X) \
+ do { \
+ _FP_PACK_SEMIRAW(E,2,X); \
+ _FP_PACK_RAW_E(val,X); \
+ } while (0)
+
+#define FP_PACK_SEMIRAW_EP(val,X) \
+ do { \
+ _FP_PACK_SEMIRAW(E,2,X); \
+ _FP_PACK_RAW_EP(val,X); \
+ } while (0)
+
+#define FP_ISSIGNAN_E(X) _FP_ISSIGNAN(E,2,X)
+#define FP_NEG_E(R,X) _FP_NEG(E,2,R,X)
+#define FP_ADD_E(R,X,Y) _FP_ADD(E,2,R,X,Y)
+#define FP_SUB_E(R,X,Y) _FP_SUB(E,2,R,X,Y)
+#define FP_MUL_E(R,X,Y) _FP_MUL(E,2,R,X,Y)
+#define FP_DIV_E(R,X,Y) _FP_DIV(E,2,R,X,Y)
+#define FP_SQRT_E(R,X) _FP_SQRT(E,2,R,X)
+
+/*
+ * Square root algorithms:
+ * We have just one right now, maybe Newton approximation
+ * should be added for those machines where division is fast.
+ * We optimize it by doing most of the calculations
+ * in one UWtype registers instead of two, although we don't
+ * have to.
+ */
+#define _FP_SQRT_MEAT_E(R, S, T, X, q) \
+ do { \
+ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \
+ _FP_FRAC_SRL_2(X, (_FP_WORKBITS)); \
+ while (q) \
+ { \
+ T##_f0 = S##_f0 + q; \
+ if (T##_f0 <= X##_f0) \
+ { \
+ S##_f0 = T##_f0 + q; \
+ X##_f0 -= T##_f0; \
+ R##_f0 += q; \
+ } \
+ _FP_FRAC_SLL_1(X, 1); \
+ q >>= 1; \
+ } \
+ _FP_FRAC_SLL_2(R, (_FP_WORKBITS)); \
+ if (X##_f0) \
+ { \
+ if (S##_f0 < X##_f0) \
+ R##_f0 |= _FP_WORK_ROUND; \
+ R##_f0 |= _FP_WORK_STICKY; \
+ } \
+ } while (0)
+
+#define FP_CMP_E(r,X,Y,un) _FP_CMP(E,2,r,X,Y,un)
+#define FP_CMP_EQ_E(r,X,Y) _FP_CMP_EQ(E,2,r,X,Y)
+#define FP_CMP_UNORD_E(r,X,Y) _FP_CMP_UNORD(E,2,r,X,Y)
+
+#define FP_TO_INT_E(r,X,rsz,rsg) _FP_TO_INT(E,2,r,X,rsz,rsg)
+#define FP_FROM_INT_E(X,r,rs,rt) _FP_FROM_INT(E,2,X,r,rs,rt)
+
+#define _FP_FRAC_HIGH_E(X) (X##_f1)
+#define _FP_FRAC_HIGH_RAW_E(X) (X##_f0)
+
+#endif /* not _FP_W_TYPE_SIZE < 64 */
diff --git a/gcc/config/soft-fp/extendsfdf2.c b/gcc/config/soft-fp/extendsfdf2.c
new file mode 100644
index 00000000000..fba22d5a197
--- /dev/null
+++ b/gcc/config/soft-fp/extendsfdf2.c
@@ -0,0 +1,54 @@
+/* Software floating-point emulation.
+ Return a converted to IEEE double
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "single.h"
+#include "double.h"
+
+DFtype __extendsfdf2(SFtype a)
+{
+ FP_DECL_EX;
+ FP_DECL_S(A);
+ FP_DECL_D(R);
+ DFtype r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_RAW_S(A, a);
+#if _FP_W_TYPE_SIZE < _FP_FRACBITS_D
+ FP_EXTEND(D,S,2,1,R,A);
+#else
+ FP_EXTEND(D,S,1,1,R,A);
+#endif
+ FP_PACK_RAW_D(r, R);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/extendsftf2.c b/gcc/config/soft-fp/extendsftf2.c
new file mode 100644
index 00000000000..c43cf1edee5
--- /dev/null
+++ b/gcc/config/soft-fp/extendsftf2.c
@@ -0,0 +1,54 @@
+/* Software floating-point emulation.
+ Return a converted to IEEE quad
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "single.h"
+#include "quad.h"
+
+TFtype __extendsftf2(SFtype a)
+{
+ FP_DECL_EX;
+ FP_DECL_S(A);
+ FP_DECL_Q(R);
+ TFtype r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_RAW_S(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+ FP_EXTEND(Q,S,4,1,R,A);
+#else
+ FP_EXTEND(Q,S,2,1,R,A);
+#endif
+ FP_PACK_RAW_Q(r, R);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/fixdfdi.c b/gcc/config/soft-fp/fixdfdi.c
new file mode 100644
index 00000000000..fdfe35af519
--- /dev/null
+++ b/gcc/config/soft-fp/fixdfdi.c
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+ Convert a to 64bit signed integer
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "double.h"
+
+DItype __fixdfdi(DFtype a)
+{
+ FP_DECL_EX;
+ FP_DECL_D(A);
+ UDItype r;
+
+ FP_UNPACK_RAW_D(A, a);
+ FP_TO_INT_D(r, A, DI_BITS, 1);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/fixdfsi.c b/gcc/config/soft-fp/fixdfsi.c
new file mode 100644
index 00000000000..a05f3e39a5f
--- /dev/null
+++ b/gcc/config/soft-fp/fixdfsi.c
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+ Convert a to 32bit signed integer
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "double.h"
+
+SItype __fixdfsi(DFtype a)
+{
+ FP_DECL_EX;
+ FP_DECL_D(A);
+ USItype r;
+
+ FP_UNPACK_RAW_D(A, a);
+ FP_TO_INT_D(r, A, SI_BITS, 1);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/fixsfdi.c b/gcc/config/soft-fp/fixsfdi.c
new file mode 100644
index 00000000000..384d9bdd536
--- /dev/null
+++ b/gcc/config/soft-fp/fixsfdi.c
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+ Convert a to 64bit signed integer
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "single.h"
+
+DItype __fixsfdi(SFtype a)
+{
+ FP_DECL_EX;
+ FP_DECL_S(A);
+ UDItype r;
+
+ FP_UNPACK_RAW_S(A, a);
+ FP_TO_INT_S(r, A, DI_BITS, 1);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/fixsfsi.c b/gcc/config/soft-fp/fixsfsi.c
new file mode 100644
index 00000000000..1d40ed05df7
--- /dev/null
+++ b/gcc/config/soft-fp/fixsfsi.c
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+ Convert a to 32bit signed integer
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "single.h"
+
+SItype __fixsfsi(SFtype a)
+{
+ FP_DECL_EX;
+ FP_DECL_S(A);
+ USItype r;
+
+ FP_UNPACK_RAW_S(A, a);
+ FP_TO_INT_S(r, A, SI_BITS, 1);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/fixtfdi.c b/gcc/config/soft-fp/fixtfdi.c
new file mode 100644
index 00000000000..ea10ce2dd3b
--- /dev/null
+++ b/gcc/config/soft-fp/fixtfdi.c
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+ Convert a to 64bit signed integer
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+DItype __fixtfdi(TFtype a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ UDItype r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_TO_INT_Q(r, A, DI_BITS, 1);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/fixtfsi.c b/gcc/config/soft-fp/fixtfsi.c
new file mode 100644
index 00000000000..eb71038bc35
--- /dev/null
+++ b/gcc/config/soft-fp/fixtfsi.c
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+ Convert a to 32bit signed integer
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+SItype __fixtfsi(TFtype a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ USItype r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_TO_INT_Q(r, A, SI_BITS, 1);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/fixunsdfdi.c b/gcc/config/soft-fp/fixunsdfdi.c
new file mode 100644
index 00000000000..d85198f1853
--- /dev/null
+++ b/gcc/config/soft-fp/fixunsdfdi.c
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+ Convert a to 64bit unsigned integer
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "double.h"
+
+UDItype __fixunsdfdi(DFtype a)
+{
+ FP_DECL_EX;
+ FP_DECL_D(A);
+ UDItype r;
+
+ FP_UNPACK_RAW_D(A, a);
+ FP_TO_INT_D(r, A, DI_BITS, 0);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/fixunsdfsi.c b/gcc/config/soft-fp/fixunsdfsi.c
new file mode 100644
index 00000000000..492ffdea680
--- /dev/null
+++ b/gcc/config/soft-fp/fixunsdfsi.c
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+ Convert a to 32bit unsigned integer
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "double.h"
+
+USItype __fixunsdfsi(DFtype a)
+{
+ FP_DECL_EX;
+ FP_DECL_D(A);
+ USItype r;
+
+ FP_UNPACK_RAW_D(A, a);
+ FP_TO_INT_D(r, A, SI_BITS, 0);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/fixunssfdi.c b/gcc/config/soft-fp/fixunssfdi.c
new file mode 100644
index 00000000000..54841538372
--- /dev/null
+++ b/gcc/config/soft-fp/fixunssfdi.c
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+ Convert a to 64bit unsigned integer
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "single.h"
+
+UDItype __fixunssfdi(SFtype a)
+{
+ FP_DECL_EX;
+ FP_DECL_S(A);
+ UDItype r;
+
+ FP_UNPACK_RAW_S(A, a);
+ FP_TO_INT_S(r, A, DI_BITS, 0);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/fixunssfsi.c b/gcc/config/soft-fp/fixunssfsi.c
new file mode 100644
index 00000000000..ac9d4b9654f
--- /dev/null
+++ b/gcc/config/soft-fp/fixunssfsi.c
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+ Convert a to 32bit unsigned integer
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "single.h"
+
+USItype __fixunssfsi(SFtype a)
+{
+ FP_DECL_EX;
+ FP_DECL_S(A);
+ USItype r;
+
+ FP_UNPACK_RAW_S(A, a);
+ FP_TO_INT_S(r, A, SI_BITS, 0);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/fixunstfdi.c b/gcc/config/soft-fp/fixunstfdi.c
new file mode 100644
index 00000000000..86f1fc85629
--- /dev/null
+++ b/gcc/config/soft-fp/fixunstfdi.c
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+ Convert a to 64bit unsigned integer
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+UDItype __fixunstfdi(TFtype a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ UDItype r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_TO_INT_Q(r, A, DI_BITS, 0);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/fixunstfsi.c b/gcc/config/soft-fp/fixunstfsi.c
new file mode 100644
index 00000000000..e0335da4790
--- /dev/null
+++ b/gcc/config/soft-fp/fixunstfsi.c
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+ Convert a to 32bit unsigned integer
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+USItype __fixunstfsi(TFtype a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ USItype r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_TO_INT_Q(r, A, SI_BITS, 0);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/floatdidf.c b/gcc/config/soft-fp/floatdidf.c
new file mode 100644
index 00000000000..21e9fb1899c
--- /dev/null
+++ b/gcc/config/soft-fp/floatdidf.c
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+ Convert a 64bit signed integer to IEEE double
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "double.h"
+
+DFtype __floatdidf(DItype i)
+{
+ FP_DECL_EX;
+ FP_DECL_D(A);
+ DFtype a;
+
+ FP_FROM_INT_D(A, i, DI_BITS, UDItype);
+ FP_PACK_RAW_D(a, A);
+ FP_HANDLE_EXCEPTIONS;
+
+ return a;
+}
diff --git a/gcc/config/soft-fp/floatdisf.c b/gcc/config/soft-fp/floatdisf.c
new file mode 100644
index 00000000000..ee57915c3b8
--- /dev/null
+++ b/gcc/config/soft-fp/floatdisf.c
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+ Convert a 64bit signed integer to IEEE single
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "single.h"
+
+SFtype __floatdisf(DItype i)
+{
+ FP_DECL_EX;
+ FP_DECL_S(A);
+ SFtype a;
+
+ FP_FROM_INT_S(A, i, DI_BITS, UDItype);
+ FP_PACK_RAW_S(a, A);
+ FP_HANDLE_EXCEPTIONS;
+
+ return a;
+}
diff --git a/gcc/config/soft-fp/floatditf.c b/gcc/config/soft-fp/floatditf.c
new file mode 100644
index 00000000000..564800bc05a
--- /dev/null
+++ b/gcc/config/soft-fp/floatditf.c
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+ Convert a 64bit signed integer to IEEE quad
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+TFtype __floatditf(DItype i)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ TFtype a;
+
+ FP_FROM_INT_Q(A, i, DI_BITS, UDItype);
+ FP_PACK_RAW_Q(a, A);
+ FP_HANDLE_EXCEPTIONS;
+
+ return a;
+}
diff --git a/gcc/config/soft-fp/floatsidf.c b/gcc/config/soft-fp/floatsidf.c
new file mode 100644
index 00000000000..b6d5f8d1d2a
--- /dev/null
+++ b/gcc/config/soft-fp/floatsidf.c
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+ Convert a 32bit signed integer to IEEE double
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "double.h"
+
+DFtype __floatsidf(SItype i)
+{
+ FP_DECL_EX;
+ FP_DECL_D(A);
+ DFtype a;
+
+ FP_FROM_INT_D(A, i, SI_BITS, USItype);
+ FP_PACK_RAW_D(a, A);
+ FP_HANDLE_EXCEPTIONS;
+
+ return a;
+}
diff --git a/gcc/config/soft-fp/floatsisf.c b/gcc/config/soft-fp/floatsisf.c
new file mode 100644
index 00000000000..76217fe3478
--- /dev/null
+++ b/gcc/config/soft-fp/floatsisf.c
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+ Convert a 32bit signed integer to IEEE single
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "single.h"
+
+SFtype __floatsisf(SItype i)
+{
+ FP_DECL_EX;
+ FP_DECL_S(A);
+ SFtype a;
+
+ FP_FROM_INT_S(A, i, SI_BITS, USItype);
+ FP_PACK_RAW_S(a, A);
+ FP_HANDLE_EXCEPTIONS;
+
+ return a;
+}
diff --git a/gcc/config/soft-fp/floatsitf.c b/gcc/config/soft-fp/floatsitf.c
new file mode 100644
index 00000000000..8c3d9cc6193
--- /dev/null
+++ b/gcc/config/soft-fp/floatsitf.c
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+ Convert a 32bit signed integer to IEEE quad
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+TFtype __floatsitf(SItype i)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ TFtype a;
+
+ FP_FROM_INT_Q(A, i, SI_BITS, USItype);
+ FP_PACK_RAW_Q(a, A);
+ FP_HANDLE_EXCEPTIONS;
+
+ return a;
+}
diff --git a/gcc/config/soft-fp/floatundidf.c b/gcc/config/soft-fp/floatundidf.c
new file mode 100644
index 00000000000..2169a3f1988
--- /dev/null
+++ b/gcc/config/soft-fp/floatundidf.c
@@ -0,0 +1,47 @@
+/* Software floating-point emulation.
+ Convert a 64bit unsigned integer to IEEE double
+ Copyright (C) 1997,1999, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "double.h"
+
+double
+__floatundidf(UDItype i)
+{
+ FP_DECL_EX;
+ FP_DECL_D(A);
+ DFtype a;
+
+ FP_FROM_INT_D(A, i, DI_BITS, UDItype);
+ FP_PACK_RAW_D(a, A);
+ FP_HANDLE_EXCEPTIONS;
+
+ return a;
+}
diff --git a/gcc/config/soft-fp/floatundisf.c b/gcc/config/soft-fp/floatundisf.c
new file mode 100644
index 00000000000..5f08764dc50
--- /dev/null
+++ b/gcc/config/soft-fp/floatundisf.c
@@ -0,0 +1,47 @@
+/* Software floating-point emulation.
+ Convert a 64bit unsigned integer to IEEE single
+ Copyright (C) 1997,1999, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "single.h"
+
+float
+__floatundisf(UDItype i)
+{
+ FP_DECL_EX;
+ FP_DECL_S(A);
+ SFtype a;
+
+ FP_FROM_INT_S(A, i, DI_BITS, UDItype);
+ FP_PACK_RAW_S(a, A);
+ FP_HANDLE_EXCEPTIONS;
+
+ return a;
+}
diff --git a/gcc/config/soft-fp/floatunditf.c b/gcc/config/soft-fp/floatunditf.c
new file mode 100644
index 00000000000..ab357f051c3
--- /dev/null
+++ b/gcc/config/soft-fp/floatunditf.c
@@ -0,0 +1,47 @@
+/* Software floating-point emulation.
+ Convert a 64bit unsigned integer to IEEE quad
+ Copyright (C) 1997,1999, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+TFtype
+__floatunditf(UDItype i)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ TFtype a;
+
+ FP_FROM_INT_Q(A, i, DI_BITS, UDItype);
+ FP_PACK_RAW_Q(a, A);
+ FP_HANDLE_EXCEPTIONS;
+
+ return a;
+}
diff --git a/gcc/config/soft-fp/floatunsidf.c b/gcc/config/soft-fp/floatunsidf.c
new file mode 100644
index 00000000000..97b488ab68a
--- /dev/null
+++ b/gcc/config/soft-fp/floatunsidf.c
@@ -0,0 +1,47 @@
+/* Software floating-point emulation.
+ Convert a 32bit unsigned integer to IEEE double
+ Copyright (C) 1997,1999, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "double.h"
+
+double
+__floatunsidf(USItype i)
+{
+ FP_DECL_EX;
+ FP_DECL_D(A);
+ DFtype a;
+
+ FP_FROM_INT_D(A, i, SI_BITS, USItype);
+ FP_PACK_RAW_D(a, A);
+ FP_HANDLE_EXCEPTIONS;
+
+ return a;
+}
diff --git a/gcc/config/soft-fp/floatunsisf.c b/gcc/config/soft-fp/floatunsisf.c
new file mode 100644
index 00000000000..2ec16ba7b7f
--- /dev/null
+++ b/gcc/config/soft-fp/floatunsisf.c
@@ -0,0 +1,47 @@
+/* Software floating-point emulation.
+ Convert a 32bit unsigned integer to IEEE single
+ Copyright (C) 1997,1999, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "single.h"
+
+float
+__floatunsisf(USItype i)
+{
+ FP_DECL_EX;
+ FP_DECL_S(A);
+ SFtype a;
+
+ FP_FROM_INT_S(A, i, SI_BITS, USItype);
+ FP_PACK_RAW_S(a, A);
+ FP_HANDLE_EXCEPTIONS;
+
+ return a;
+}
diff --git a/gcc/config/soft-fp/floatunsitf.c b/gcc/config/soft-fp/floatunsitf.c
new file mode 100644
index 00000000000..c993716e54a
--- /dev/null
+++ b/gcc/config/soft-fp/floatunsitf.c
@@ -0,0 +1,47 @@
+/* Software floating-point emulation.
+ Convert a 32bit unsigned integer to IEEE quad
+ Copyright (C) 1997,1999, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+TFtype
+__floatunsitf(USItype i)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ TFtype a;
+
+ FP_FROM_INT_Q(A, i, SI_BITS, USItype);
+ FP_PACK_RAW_Q(a, A);
+ FP_HANDLE_EXCEPTIONS;
+
+ return a;
+}
diff --git a/gcc/config/soft-fp/gedf2.c b/gcc/config/soft-fp/gedf2.c
new file mode 100644
index 00000000000..e0dc8620eee
--- /dev/null
+++ b/gcc/config/soft-fp/gedf2.c
@@ -0,0 +1,51 @@
+/* Software floating-point emulation.
+ Return 0 iff a == b, 1 iff a > b, -2 iff a ? b, -1 iff a < b
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "double.h"
+
+int __gedf2(DFtype a, DFtype b)
+{
+ FP_DECL_EX;
+ FP_DECL_D(A); FP_DECL_D(B);
+ int r;
+
+ FP_UNPACK_RAW_D(A, a);
+ FP_UNPACK_RAW_D(B, b);
+ FP_CMP_D(r, A, B, -2);
+ if (r == -2 && (FP_ISSIGNAN_D(A) || FP_ISSIGNAN_D(B)))
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
+
+strong_alias(__gedf2, __gtdf2);
diff --git a/gcc/config/soft-fp/gesf2.c b/gcc/config/soft-fp/gesf2.c
new file mode 100644
index 00000000000..d1f3ba2f9f5
--- /dev/null
+++ b/gcc/config/soft-fp/gesf2.c
@@ -0,0 +1,51 @@
+/* Software floating-point emulation.
+ Return 0 iff a == b, 1 iff a > b, -2 iff a ? b, -1 iff a < b
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "single.h"
+
+int __gesf2(SFtype a, SFtype b)
+{
+ FP_DECL_EX;
+ FP_DECL_S(A); FP_DECL_S(B);
+ int r;
+
+ FP_UNPACK_RAW_S(A, a);
+ FP_UNPACK_RAW_S(B, b);
+ FP_CMP_S(r, A, B, -2);
+ if (r == -2 && (FP_ISSIGNAN_S(A) || FP_ISSIGNAN_S(B)))
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
+
+strong_alias(__gesf2, __gtsf2);
diff --git a/gcc/config/soft-fp/getf2.c b/gcc/config/soft-fp/getf2.c
new file mode 100644
index 00000000000..82ff283d0d9
--- /dev/null
+++ b/gcc/config/soft-fp/getf2.c
@@ -0,0 +1,51 @@
+/* Software floating-point emulation.
+ Return 0 iff a == b, 1 iff a > b, -2 iff a ? b, -1 iff a < b
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int __getf2(TFtype a, TFtype b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B);
+ int r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_UNPACK_RAW_Q(B, b);
+ FP_CMP_Q(r, A, B, -2);
+ if (r == -2 && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B)))
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
+
+strong_alias(__getf2, __gttf2);
diff --git a/gcc/config/soft-fp/ledf2.c b/gcc/config/soft-fp/ledf2.c
new file mode 100644
index 00000000000..528a9819cef
--- /dev/null
+++ b/gcc/config/soft-fp/ledf2.c
@@ -0,0 +1,51 @@
+/* Software floating-point emulation.
+ Return 0 iff a == b, 1 iff a > b, 2 iff a ? b, -1 iff a < b
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "double.h"
+
+int __ledf2(DFtype a, DFtype b)
+{
+ FP_DECL_EX;
+ FP_DECL_D(A); FP_DECL_D(B);
+ int r;
+
+ FP_UNPACK_RAW_D(A, a);
+ FP_UNPACK_RAW_D(B, b);
+ FP_CMP_D(r, A, B, 2);
+ if (r == 2 && (FP_ISSIGNAN_D(A) || FP_ISSIGNAN_D(B)))
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
+
+strong_alias(__ledf2, __ltdf2);
diff --git a/gcc/config/soft-fp/lesf2.c b/gcc/config/soft-fp/lesf2.c
new file mode 100644
index 00000000000..c564bd9539e
--- /dev/null
+++ b/gcc/config/soft-fp/lesf2.c
@@ -0,0 +1,51 @@
+/* Software floating-point emulation.
+ Return 0 iff a == b, 1 iff a > b, 2 iff a ? b, -1 iff a < b
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "single.h"
+
+int __lesf2(SFtype a, SFtype b)
+{
+ FP_DECL_EX;
+ FP_DECL_S(A); FP_DECL_S(B);
+ int r;
+
+ FP_UNPACK_RAW_S(A, a);
+ FP_UNPACK_RAW_S(B, b);
+ FP_CMP_S(r, A, B, 2);
+ if (r == 2 && (FP_ISSIGNAN_S(A) || FP_ISSIGNAN_S(B)))
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
+
+strong_alias(__lesf2, __ltsf2);
diff --git a/gcc/config/soft-fp/letf2.c b/gcc/config/soft-fp/letf2.c
new file mode 100644
index 00000000000..35e03aaacfe
--- /dev/null
+++ b/gcc/config/soft-fp/letf2.c
@@ -0,0 +1,51 @@
+/* Software floating-point emulation.
+ Return 0 iff a == b, 1 iff a > b, 2 iff a ? b, -1 iff a < b
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int __letf2(TFtype a, TFtype b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B);
+ int r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_UNPACK_RAW_Q(B, b);
+ FP_CMP_Q(r, A, B, 2);
+ if (r == 2 && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B)))
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
+
+strong_alias(__letf2, __lttf2);
diff --git a/gcc/config/soft-fp/muldf3.c b/gcc/config/soft-fp/muldf3.c
new file mode 100644
index 00000000000..7eb2015ae56
--- /dev/null
+++ b/gcc/config/soft-fp/muldf3.c
@@ -0,0 +1,49 @@
+/* Software floating-point emulation.
+ Return a * b
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "double.h"
+
+DFtype __muldf3(DFtype a, DFtype b)
+{
+ FP_DECL_EX;
+ FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R);
+ DFtype r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_D(A, a);
+ FP_UNPACK_D(B, b);
+ FP_MUL_D(R, A, B);
+ FP_PACK_D(r, R);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/mulsf3.c b/gcc/config/soft-fp/mulsf3.c
new file mode 100644
index 00000000000..5df44068720
--- /dev/null
+++ b/gcc/config/soft-fp/mulsf3.c
@@ -0,0 +1,49 @@
+/* Software floating-point emulation.
+ Return a * b
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "single.h"
+
+SFtype __mulsf3(SFtype a, SFtype b)
+{
+ FP_DECL_EX;
+ FP_DECL_S(A); FP_DECL_S(B); FP_DECL_S(R);
+ SFtype r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_S(A, a);
+ FP_UNPACK_S(B, b);
+ FP_MUL_S(R, A, B);
+ FP_PACK_S(r, R);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/multf3.c b/gcc/config/soft-fp/multf3.c
new file mode 100644
index 00000000000..0abab6ddc3b
--- /dev/null
+++ b/gcc/config/soft-fp/multf3.c
@@ -0,0 +1,49 @@
+/* Software floating-point emulation.
+ Return a * b
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+TFtype __multf3(TFtype a, TFtype b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(R);
+ TFtype r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_Q(A, a);
+ FP_UNPACK_Q(B, b);
+ FP_MUL_Q(R, A, B);
+ FP_PACK_Q(r, R);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/negdf2.c b/gcc/config/soft-fp/negdf2.c
new file mode 100644
index 00000000000..54869e9a68d
--- /dev/null
+++ b/gcc/config/soft-fp/negdf2.c
@@ -0,0 +1,48 @@
+/* Software floating-point emulation.
+ Return -a
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "double.h"
+
+DFtype __negdf2(DFtype a)
+{
+ FP_DECL_EX;
+ FP_DECL_D(A); FP_DECL_D(R);
+ DFtype r;
+
+ FP_UNPACK_D(A, a);
+ FP_NEG_D(R, A);
+ FP_PACK_D(r, R);
+ FP_CLEAR_EXCEPTIONS;
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/negsf2.c b/gcc/config/soft-fp/negsf2.c
new file mode 100644
index 00000000000..bf5db7a452c
--- /dev/null
+++ b/gcc/config/soft-fp/negsf2.c
@@ -0,0 +1,48 @@
+/* Software floating-point emulation.
+ Return -a
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "single.h"
+
+SFtype __negsf2(SFtype a)
+{
+ FP_DECL_EX;
+ FP_DECL_S(A); FP_DECL_S(R);
+ SFtype r;
+
+ FP_UNPACK_S(A, a);
+ FP_NEG_S(R, A);
+ FP_PACK_S(r, R);
+ FP_CLEAR_EXCEPTIONS;
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/negtf2.c b/gcc/config/soft-fp/negtf2.c
new file mode 100644
index 00000000000..5524c82df1c
--- /dev/null
+++ b/gcc/config/soft-fp/negtf2.c
@@ -0,0 +1,48 @@
+/* Software floating-point emulation.
+ Return -a
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+TFtype __negtf2(TFtype a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(R);
+ TFtype r;
+
+ FP_UNPACK_Q(A, a);
+ FP_NEG_Q(R, A);
+ FP_PACK_Q(r, R);
+ FP_CLEAR_EXCEPTIONS;
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/op-1.h b/gcc/config/soft-fp/op-1.h
new file mode 100644
index 00000000000..35cd0ba7bb1
--- /dev/null
+++ b/gcc/config/soft-fp/op-1.h
@@ -0,0 +1,302 @@
+/* Software floating-point emulation.
+ Basic one-word fraction declaration and manipulation.
+ Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com),
+ Jakub Jelinek (jj@ultra.linux.cz),
+ David S. Miller (davem@redhat.com) and
+ Peter Maydell (pmaydell@chiark.greenend.org.uk).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define _FP_FRAC_DECL_1(X) _FP_W_TYPE X##_f
+#define _FP_FRAC_COPY_1(D,S) (D##_f = S##_f)
+#define _FP_FRAC_SET_1(X,I) (X##_f = I)
+#define _FP_FRAC_HIGH_1(X) (X##_f)
+#define _FP_FRAC_LOW_1(X) (X##_f)
+#define _FP_FRAC_WORD_1(X,w) (X##_f)
+
+#define _FP_FRAC_ADDI_1(X,I) (X##_f += I)
+#define _FP_FRAC_SLL_1(X,N) \
+ do { \
+ if (__builtin_constant_p(N) && (N) == 1) \
+ X##_f += X##_f; \
+ else \
+ X##_f <<= (N); \
+ } while (0)
+#define _FP_FRAC_SRL_1(X,N) (X##_f >>= N)
+
+/* Right shift with sticky-lsb. */
+#define _FP_FRAC_SRST_1(X,S,N,sz) __FP_FRAC_SRST_1(X##_f, S, N, sz)
+#define _FP_FRAC_SRS_1(X,N,sz) __FP_FRAC_SRS_1(X##_f, N, sz)
+
+#define __FP_FRAC_SRST_1(X,S,N,sz) \
+do { \
+ S = (__builtin_constant_p(N) && (N) == 1 \
+ ? X & 1 : (X << (_FP_W_TYPE_SIZE - (N))) != 0); \
+ X = X >> (N); \
+} while (0)
+
+#define __FP_FRAC_SRS_1(X,N,sz) \
+ (X = (X >> (N) | (__builtin_constant_p(N) && (N) == 1 \
+ ? X & 1 : (X << (_FP_W_TYPE_SIZE - (N))) != 0)))
+
+#define _FP_FRAC_ADD_1(R,X,Y) (R##_f = X##_f + Y##_f)
+#define _FP_FRAC_SUB_1(R,X,Y) (R##_f = X##_f - Y##_f)
+#define _FP_FRAC_DEC_1(X,Y) (X##_f -= Y##_f)
+#define _FP_FRAC_CLZ_1(z, X) __FP_CLZ(z, X##_f)
+
+/* Predicates */
+#define _FP_FRAC_NEGP_1(X) ((_FP_WS_TYPE)X##_f < 0)
+#define _FP_FRAC_ZEROP_1(X) (X##_f == 0)
+#define _FP_FRAC_OVERP_1(fs,X) (X##_f & _FP_OVERFLOW_##fs)
+#define _FP_FRAC_CLEAR_OVERP_1(fs,X) (X##_f &= ~_FP_OVERFLOW_##fs)
+#define _FP_FRAC_EQ_1(X, Y) (X##_f == Y##_f)
+#define _FP_FRAC_GE_1(X, Y) (X##_f >= Y##_f)
+#define _FP_FRAC_GT_1(X, Y) (X##_f > Y##_f)
+
+#define _FP_ZEROFRAC_1 0
+#define _FP_MINFRAC_1 1
+#define _FP_MAXFRAC_1 (~(_FP_WS_TYPE)0)
+
+/*
+ * Unpack the raw bits of a native fp value. Do not classify or
+ * normalize the data.
+ */
+
+#define _FP_UNPACK_RAW_1(fs, X, val) \
+ do { \
+ union _FP_UNION_##fs _flo; _flo.flt = (val); \
+ \
+ X##_f = _flo.bits.frac; \
+ X##_e = _flo.bits.exp; \
+ X##_s = _flo.bits.sign; \
+ } while (0)
+
+#define _FP_UNPACK_RAW_1_P(fs, X, val) \
+ do { \
+ union _FP_UNION_##fs *_flo = \
+ (union _FP_UNION_##fs *)(val); \
+ \
+ X##_f = _flo->bits.frac; \
+ X##_e = _flo->bits.exp; \
+ X##_s = _flo->bits.sign; \
+ } while (0)
+
+/*
+ * Repack the raw bits of a native fp value.
+ */
+
+#define _FP_PACK_RAW_1(fs, val, X) \
+ do { \
+ union _FP_UNION_##fs _flo; \
+ \
+ _flo.bits.frac = X##_f; \
+ _flo.bits.exp = X##_e; \
+ _flo.bits.sign = X##_s; \
+ \
+ (val) = _flo.flt; \
+ } while (0)
+
+#define _FP_PACK_RAW_1_P(fs, val, X) \
+ do { \
+ union _FP_UNION_##fs *_flo = \
+ (union _FP_UNION_##fs *)(val); \
+ \
+ _flo->bits.frac = X##_f; \
+ _flo->bits.exp = X##_e; \
+ _flo->bits.sign = X##_s; \
+ } while (0)
+
+
+/*
+ * Multiplication algorithms:
+ */
+
+/* Basic. Assuming the host word size is >= 2*FRACBITS, we can do the
+ multiplication immediately. */
+
+#define _FP_MUL_MEAT_1_imm(wfracbits, R, X, Y) \
+ do { \
+ R##_f = X##_f * Y##_f; \
+ /* Normalize since we know where the msb of the multiplicands \
+ were (bit B), we know that the msb of the of the product is \
+ at either 2B or 2B-1. */ \
+ _FP_FRAC_SRS_1(R, wfracbits-1, 2*wfracbits); \
+ } while (0)
+
+/* Given a 1W * 1W => 2W primitive, do the extended multiplication. */
+
+#define _FP_MUL_MEAT_1_wide(wfracbits, R, X, Y, doit) \
+ do { \
+ _FP_W_TYPE _Z_f0, _Z_f1; \
+ doit(_Z_f1, _Z_f0, X##_f, Y##_f); \
+ /* Normalize since we know where the msb of the multiplicands \
+ were (bit B), we know that the msb of the of the product is \
+ at either 2B or 2B-1. */ \
+ _FP_FRAC_SRS_2(_Z, wfracbits-1, 2*wfracbits); \
+ R##_f = _Z_f0; \
+ } while (0)
+
+/* Finally, a simple widening multiply algorithm. What fun! */
+
+#define _FP_MUL_MEAT_1_hard(wfracbits, R, X, Y) \
+ do { \
+ _FP_W_TYPE _xh, _xl, _yh, _yl, _z_f0, _z_f1, _a_f0, _a_f1; \
+ \
+ /* split the words in half */ \
+ _xh = X##_f >> (_FP_W_TYPE_SIZE/2); \
+ _xl = X##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1); \
+ _yh = Y##_f >> (_FP_W_TYPE_SIZE/2); \
+ _yl = Y##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1); \
+ \
+ /* multiply the pieces */ \
+ _z_f0 = _xl * _yl; \
+ _a_f0 = _xh * _yl; \
+ _a_f1 = _xl * _yh; \
+ _z_f1 = _xh * _yh; \
+ \
+ /* reassemble into two full words */ \
+ if ((_a_f0 += _a_f1) < _a_f1) \
+ _z_f1 += (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2); \
+ _a_f1 = _a_f0 >> (_FP_W_TYPE_SIZE/2); \
+ _a_f0 = _a_f0 << (_FP_W_TYPE_SIZE/2); \
+ _FP_FRAC_ADD_2(_z, _z, _a); \
+ \
+ /* normalize */ \
+ _FP_FRAC_SRS_2(_z, wfracbits - 1, 2*wfracbits); \
+ R##_f = _z_f0; \
+ } while (0)
+
+
+/*
+ * Division algorithms:
+ */
+
+/* Basic. Assuming the host word size is >= 2*FRACBITS, we can do the
+ division immediately. Give this macro either _FP_DIV_HELP_imm for
+ C primitives or _FP_DIV_HELP_ldiv for the ISO function. Which you
+ choose will depend on what the compiler does with divrem4. */
+
+#define _FP_DIV_MEAT_1_imm(fs, R, X, Y, doit) \
+ do { \
+ _FP_W_TYPE _q, _r; \
+ X##_f <<= (X##_f < Y##_f \
+ ? R##_e--, _FP_WFRACBITS_##fs \
+ : _FP_WFRACBITS_##fs - 1); \
+ doit(_q, _r, X##_f, Y##_f); \
+ R##_f = _q | (_r != 0); \
+ } while (0)
+
+/* GCC's longlong.h defines a 2W / 1W => (1W,1W) primitive udiv_qrnnd
+ that may be useful in this situation. This first is for a primitive
+ that requires normalization, the second for one that does not. Look
+ for UDIV_NEEDS_NORMALIZATION to tell which your machine needs. */
+
+#define _FP_DIV_MEAT_1_udiv_norm(fs, R, X, Y) \
+ do { \
+ _FP_W_TYPE _nh, _nl, _q, _r, _y; \
+ \
+ /* Normalize Y -- i.e. make the most significant bit set. */ \
+ _y = Y##_f << _FP_WFRACXBITS_##fs; \
+ \
+ /* Shift X op correspondingly high, that is, up one full word. */ \
+ if (X##_f < Y##_f) \
+ { \
+ R##_e--; \
+ _nl = 0; \
+ _nh = X##_f; \
+ } \
+ else \
+ { \
+ _nl = X##_f << (_FP_W_TYPE_SIZE - 1); \
+ _nh = X##_f >> 1; \
+ } \
+ \
+ udiv_qrnnd(_q, _r, _nh, _nl, _y); \
+ R##_f = _q | (_r != 0); \
+ } while (0)
+
+#define _FP_DIV_MEAT_1_udiv(fs, R, X, Y) \
+ do { \
+ _FP_W_TYPE _nh, _nl, _q, _r; \
+ if (X##_f < Y##_f) \
+ { \
+ R##_e--; \
+ _nl = X##_f << _FP_WFRACBITS_##fs; \
+ _nh = X##_f >> _FP_WFRACXBITS_##fs; \
+ } \
+ else \
+ { \
+ _nl = X##_f << (_FP_WFRACBITS_##fs - 1); \
+ _nh = X##_f >> (_FP_WFRACXBITS_##fs + 1); \
+ } \
+ udiv_qrnnd(_q, _r, _nh, _nl, Y##_f); \
+ R##_f = _q | (_r != 0); \
+ } while (0)
+
+
+/*
+ * Square root algorithms:
+ * We have just one right now, maybe Newton approximation
+ * should be added for those machines where division is fast.
+ */
+
+#define _FP_SQRT_MEAT_1(R, S, T, X, q) \
+ do { \
+ while (q != _FP_WORK_ROUND) \
+ { \
+ T##_f = S##_f + q; \
+ if (T##_f <= X##_f) \
+ { \
+ S##_f = T##_f + q; \
+ X##_f -= T##_f; \
+ R##_f += q; \
+ } \
+ _FP_FRAC_SLL_1(X, 1); \
+ q >>= 1; \
+ } \
+ if (X##_f) \
+ { \
+ if (S##_f < X##_f) \
+ R##_f |= _FP_WORK_ROUND; \
+ R##_f |= _FP_WORK_STICKY; \
+ } \
+ } while (0)
+
+/*
+ * Assembly/disassembly for converting to/from integral types.
+ * No shifting or overflow handled here.
+ */
+
+#define _FP_FRAC_ASSEMBLE_1(r, X, rsize) (r = X##_f)
+#define _FP_FRAC_DISASSEMBLE_1(X, r, rsize) (X##_f = r)
+
+
+/*
+ * Convert FP values between word sizes
+ */
+
+#define _FP_FRAC_COPY_1_1(D, S) (D##_f = S##_f)
diff --git a/gcc/config/soft-fp/op-2.h b/gcc/config/soft-fp/op-2.h
new file mode 100644
index 00000000000..5c9bce4c179
--- /dev/null
+++ b/gcc/config/soft-fp/op-2.h
@@ -0,0 +1,615 @@
+/* Software floating-point emulation.
+ Basic two-word fraction declaration and manipulation.
+ Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com),
+ Jakub Jelinek (jj@ultra.linux.cz),
+ David S. Miller (davem@redhat.com) and
+ Peter Maydell (pmaydell@chiark.greenend.org.uk).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define _FP_FRAC_DECL_2(X) _FP_W_TYPE X##_f0, X##_f1
+#define _FP_FRAC_COPY_2(D,S) (D##_f0 = S##_f0, D##_f1 = S##_f1)
+#define _FP_FRAC_SET_2(X,I) __FP_FRAC_SET_2(X, I)
+#define _FP_FRAC_HIGH_2(X) (X##_f1)
+#define _FP_FRAC_LOW_2(X) (X##_f0)
+#define _FP_FRAC_WORD_2(X,w) (X##_f##w)
+
+#define _FP_FRAC_SLL_2(X,N) \
+(void)(((N) < _FP_W_TYPE_SIZE) \
+ ? ({ \
+ if (__builtin_constant_p(N) && (N) == 1) \
+ { \
+ X##_f1 = X##_f1 + X##_f1 + (((_FP_WS_TYPE)(X##_f0)) < 0); \
+ X##_f0 += X##_f0; \
+ } \
+ else \
+ { \
+ X##_f1 = X##_f1 << (N) | X##_f0 >> (_FP_W_TYPE_SIZE - (N)); \
+ X##_f0 <<= (N); \
+ } \
+ 0; \
+ }) \
+ : ({ \
+ X##_f1 = X##_f0 << ((N) - _FP_W_TYPE_SIZE); \
+ X##_f0 = 0; \
+ }))
+
+
+#define _FP_FRAC_SRL_2(X,N) \
+(void)(((N) < _FP_W_TYPE_SIZE) \
+ ? ({ \
+ X##_f0 = X##_f0 >> (N) | X##_f1 << (_FP_W_TYPE_SIZE - (N)); \
+ X##_f1 >>= (N); \
+ }) \
+ : ({ \
+ X##_f0 = X##_f1 >> ((N) - _FP_W_TYPE_SIZE); \
+ X##_f1 = 0; \
+ }))
+
+/* Right shift with sticky-lsb. */
+#define _FP_FRAC_SRST_2(X,S, N,sz) \
+(void)(((N) < _FP_W_TYPE_SIZE) \
+ ? ({ \
+ S = (__builtin_constant_p(N) && (N) == 1 \
+ ? X##_f0 & 1 \
+ : (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0); \
+ X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N)); \
+ X##_f1 >>= (N); \
+ }) \
+ : ({ \
+ S = ((((N) == _FP_W_TYPE_SIZE \
+ ? 0 \
+ : (X##_f1 << (2*_FP_W_TYPE_SIZE - (N)))) \
+ | X##_f0) != 0); \
+ X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE)); \
+ X##_f1 = 0; \
+ }))
+
+#define _FP_FRAC_SRS_2(X,N,sz) \
+(void)(((N) < _FP_W_TYPE_SIZE) \
+ ? ({ \
+ X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N) | \
+ (__builtin_constant_p(N) && (N) == 1 \
+ ? X##_f0 & 1 \
+ : (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0)); \
+ X##_f1 >>= (N); \
+ }) \
+ : ({ \
+ X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE) | \
+ ((((N) == _FP_W_TYPE_SIZE \
+ ? 0 \
+ : (X##_f1 << (2*_FP_W_TYPE_SIZE - (N)))) \
+ | X##_f0) != 0)); \
+ X##_f1 = 0; \
+ }))
+
+#define _FP_FRAC_ADDI_2(X,I) \
+ __FP_FRAC_ADDI_2(X##_f1, X##_f0, I)
+
+#define _FP_FRAC_ADD_2(R,X,Y) \
+ __FP_FRAC_ADD_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0)
+
+#define _FP_FRAC_SUB_2(R,X,Y) \
+ __FP_FRAC_SUB_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0)
+
+#define _FP_FRAC_DEC_2(X,Y) \
+ __FP_FRAC_DEC_2(X##_f1, X##_f0, Y##_f1, Y##_f0)
+
+#define _FP_FRAC_CLZ_2(R,X) \
+ do { \
+ if (X##_f1) \
+ __FP_CLZ(R,X##_f1); \
+ else \
+ { \
+ __FP_CLZ(R,X##_f0); \
+ R += _FP_W_TYPE_SIZE; \
+ } \
+ } while(0)
+
+/* Predicates */
+#define _FP_FRAC_NEGP_2(X) ((_FP_WS_TYPE)X##_f1 < 0)
+#define _FP_FRAC_ZEROP_2(X) ((X##_f1 | X##_f0) == 0)
+#define _FP_FRAC_OVERP_2(fs,X) (_FP_FRAC_HIGH_##fs(X) & _FP_OVERFLOW_##fs)
+#define _FP_FRAC_CLEAR_OVERP_2(fs,X) (_FP_FRAC_HIGH_##fs(X) &= ~_FP_OVERFLOW_##fs)
+#define _FP_FRAC_EQ_2(X, Y) (X##_f1 == Y##_f1 && X##_f0 == Y##_f0)
+#define _FP_FRAC_GT_2(X, Y) \
+ (X##_f1 > Y##_f1 || (X##_f1 == Y##_f1 && X##_f0 > Y##_f0))
+#define _FP_FRAC_GE_2(X, Y) \
+ (X##_f1 > Y##_f1 || (X##_f1 == Y##_f1 && X##_f0 >= Y##_f0))
+
+#define _FP_ZEROFRAC_2 0, 0
+#define _FP_MINFRAC_2 0, 1
+#define _FP_MAXFRAC_2 (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0)
+
+/*
+ * Internals
+ */
+
+#define __FP_FRAC_SET_2(X,I1,I0) (X##_f0 = I0, X##_f1 = I1)
+
+#define __FP_CLZ_2(R, xh, xl) \
+ do { \
+ if (xh) \
+ __FP_CLZ(R,xh); \
+ else \
+ { \
+ __FP_CLZ(R,xl); \
+ R += _FP_W_TYPE_SIZE; \
+ } \
+ } while(0)
+
+#if 0
+
+#ifndef __FP_FRAC_ADDI_2
+#define __FP_FRAC_ADDI_2(xh, xl, i) \
+ (xh += ((xl += i) < i))
+#endif
+#ifndef __FP_FRAC_ADD_2
+#define __FP_FRAC_ADD_2(rh, rl, xh, xl, yh, yl) \
+ (rh = xh + yh + ((rl = xl + yl) < xl))
+#endif
+#ifndef __FP_FRAC_SUB_2
+#define __FP_FRAC_SUB_2(rh, rl, xh, xl, yh, yl) \
+ (rh = xh - yh - ((rl = xl - yl) > xl))
+#endif
+#ifndef __FP_FRAC_DEC_2
+#define __FP_FRAC_DEC_2(xh, xl, yh, yl) \
+ do { \
+ UWtype _t = xl; \
+ xh -= yh + ((xl -= yl) > _t); \
+ } while (0)
+#endif
+
+#else
+
+#undef __FP_FRAC_ADDI_2
+#define __FP_FRAC_ADDI_2(xh, xl, i) add_ssaaaa(xh, xl, xh, xl, 0, i)
+#undef __FP_FRAC_ADD_2
+#define __FP_FRAC_ADD_2 add_ssaaaa
+#undef __FP_FRAC_SUB_2
+#define __FP_FRAC_SUB_2 sub_ddmmss
+#undef __FP_FRAC_DEC_2
+#define __FP_FRAC_DEC_2(xh, xl, yh, yl) sub_ddmmss(xh, xl, xh, xl, yh, yl)
+
+#endif
+
+/*
+ * Unpack the raw bits of a native fp value. Do not classify or
+ * normalize the data.
+ */
+
+#define _FP_UNPACK_RAW_2(fs, X, val) \
+ do { \
+ union _FP_UNION_##fs _flo; _flo.flt = (val); \
+ \
+ X##_f0 = _flo.bits.frac0; \
+ X##_f1 = _flo.bits.frac1; \
+ X##_e = _flo.bits.exp; \
+ X##_s = _flo.bits.sign; \
+ } while (0)
+
+#define _FP_UNPACK_RAW_2_P(fs, X, val) \
+ do { \
+ union _FP_UNION_##fs *_flo = \
+ (union _FP_UNION_##fs *)(val); \
+ \
+ X##_f0 = _flo->bits.frac0; \
+ X##_f1 = _flo->bits.frac1; \
+ X##_e = _flo->bits.exp; \
+ X##_s = _flo->bits.sign; \
+ } while (0)
+
+
+/*
+ * Repack the raw bits of a native fp value.
+ */
+
+#define _FP_PACK_RAW_2(fs, val, X) \
+ do { \
+ union _FP_UNION_##fs _flo; \
+ \
+ _flo.bits.frac0 = X##_f0; \
+ _flo.bits.frac1 = X##_f1; \
+ _flo.bits.exp = X##_e; \
+ _flo.bits.sign = X##_s; \
+ \
+ (val) = _flo.flt; \
+ } while (0)
+
+#define _FP_PACK_RAW_2_P(fs, val, X) \
+ do { \
+ union _FP_UNION_##fs *_flo = \
+ (union _FP_UNION_##fs *)(val); \
+ \
+ _flo->bits.frac0 = X##_f0; \
+ _flo->bits.frac1 = X##_f1; \
+ _flo->bits.exp = X##_e; \
+ _flo->bits.sign = X##_s; \
+ } while (0)
+
+
+/*
+ * Multiplication algorithms:
+ */
+
+/* Given a 1W * 1W => 2W primitive, do the extended multiplication. */
+
+#define _FP_MUL_MEAT_2_wide(wfracbits, R, X, Y, doit) \
+ do { \
+ _FP_FRAC_DECL_4(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \
+ \
+ doit(_FP_FRAC_WORD_4(_z,1), _FP_FRAC_WORD_4(_z,0), X##_f0, Y##_f0); \
+ doit(_b_f1, _b_f0, X##_f0, Y##_f1); \
+ doit(_c_f1, _c_f0, X##_f1, Y##_f0); \
+ doit(_FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2), X##_f1, Y##_f1); \
+ \
+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
+ _FP_FRAC_WORD_4(_z,1), 0, _b_f1, _b_f0, \
+ _FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
+ _FP_FRAC_WORD_4(_z,1)); \
+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
+ _FP_FRAC_WORD_4(_z,1), 0, _c_f1, _c_f0, \
+ _FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
+ _FP_FRAC_WORD_4(_z,1)); \
+ \
+ /* Normalize since we know where the msb of the multiplicands \
+ were (bit B), we know that the msb of the of the product is \
+ at either 2B or 2B-1. */ \
+ _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \
+ R##_f0 = _FP_FRAC_WORD_4(_z,0); \
+ R##_f1 = _FP_FRAC_WORD_4(_z,1); \
+ } while (0)
+
+/* Given a 1W * 1W => 2W primitive, do the extended multiplication.
+ Do only 3 multiplications instead of four. This one is for machines
+ where multiplication is much more expensive than subtraction. */
+
+#define _FP_MUL_MEAT_2_wide_3mul(wfracbits, R, X, Y, doit) \
+ do { \
+ _FP_FRAC_DECL_4(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \
+ _FP_W_TYPE _d; \
+ int _c1, _c2; \
+ \
+ _b_f0 = X##_f0 + X##_f1; \
+ _c1 = _b_f0 < X##_f0; \
+ _b_f1 = Y##_f0 + Y##_f1; \
+ _c2 = _b_f1 < Y##_f0; \
+ doit(_d, _FP_FRAC_WORD_4(_z,0), X##_f0, Y##_f0); \
+ doit(_FP_FRAC_WORD_4(_z,2), _FP_FRAC_WORD_4(_z,1), _b_f0, _b_f1); \
+ doit(_c_f1, _c_f0, X##_f1, Y##_f1); \
+ \
+ _b_f0 &= -_c2; \
+ _b_f1 &= -_c1; \
+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
+ _FP_FRAC_WORD_4(_z,1), (_c1 & _c2), 0, _d, \
+ 0, _FP_FRAC_WORD_4(_z,2), _FP_FRAC_WORD_4(_z,1)); \
+ __FP_FRAC_ADDI_2(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
+ _b_f0); \
+ __FP_FRAC_ADDI_2(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
+ _b_f1); \
+ __FP_FRAC_DEC_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
+ _FP_FRAC_WORD_4(_z,1), \
+ 0, _d, _FP_FRAC_WORD_4(_z,0)); \
+ __FP_FRAC_DEC_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
+ _FP_FRAC_WORD_4(_z,1), 0, _c_f1, _c_f0); \
+ __FP_FRAC_ADD_2(_FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2), \
+ _c_f1, _c_f0, \
+ _FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2)); \
+ \
+ /* Normalize since we know where the msb of the multiplicands \
+ were (bit B), we know that the msb of the of the product is \
+ at either 2B or 2B-1. */ \
+ _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \
+ R##_f0 = _FP_FRAC_WORD_4(_z,0); \
+ R##_f1 = _FP_FRAC_WORD_4(_z,1); \
+ } while (0)
+
+#define _FP_MUL_MEAT_2_gmp(wfracbits, R, X, Y) \
+ do { \
+ _FP_FRAC_DECL_4(_z); \
+ _FP_W_TYPE _x[2], _y[2]; \
+ _x[0] = X##_f0; _x[1] = X##_f1; \
+ _y[0] = Y##_f0; _y[1] = Y##_f1; \
+ \
+ mpn_mul_n(_z_f, _x, _y, 2); \
+ \
+ /* Normalize since we know where the msb of the multiplicands \
+ were (bit B), we know that the msb of the of the product is \
+ at either 2B or 2B-1. */ \
+ _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \
+ R##_f0 = _z_f[0]; \
+ R##_f1 = _z_f[1]; \
+ } while (0)
+
+/* Do at most 120x120=240 bits multiplication using double floating
+ point multiplication. This is useful if floating point
+ multiplication has much bigger throughput than integer multiply.
+ It is supposed to work for _FP_W_TYPE_SIZE 64 and wfracbits
+ between 106 and 120 only.
+ Caller guarantees that X and Y has (1LLL << (wfracbits - 1)) set.
+ SETFETZ is a macro which will disable all FPU exceptions and set rounding
+ towards zero, RESETFE should optionally reset it back. */
+
+#define _FP_MUL_MEAT_2_120_240_double(wfracbits, R, X, Y, setfetz, resetfe) \
+ do { \
+ static const double _const[] = { \
+ /* 2^-24 */ 5.9604644775390625e-08, \
+ /* 2^-48 */ 3.5527136788005009e-15, \
+ /* 2^-72 */ 2.1175823681357508e-22, \
+ /* 2^-96 */ 1.2621774483536189e-29, \
+ /* 2^28 */ 2.68435456e+08, \
+ /* 2^4 */ 1.600000e+01, \
+ /* 2^-20 */ 9.5367431640625e-07, \
+ /* 2^-44 */ 5.6843418860808015e-14, \
+ /* 2^-68 */ 3.3881317890172014e-21, \
+ /* 2^-92 */ 2.0194839173657902e-28, \
+ /* 2^-116 */ 1.2037062152420224e-35}; \
+ double _a240, _b240, _c240, _d240, _e240, _f240, \
+ _g240, _h240, _i240, _j240, _k240; \
+ union { double d; UDItype i; } _l240, _m240, _n240, _o240, \
+ _p240, _q240, _r240, _s240; \
+ UDItype _t240, _u240, _v240, _w240, _x240, _y240 = 0; \
+ \
+ if (wfracbits < 106 || wfracbits > 120) \
+ abort(); \
+ \
+ setfetz; \
+ \
+ _e240 = (double)(long)(X##_f0 & 0xffffff); \
+ _j240 = (double)(long)(Y##_f0 & 0xffffff); \
+ _d240 = (double)(long)((X##_f0 >> 24) & 0xffffff); \
+ _i240 = (double)(long)((Y##_f0 >> 24) & 0xffffff); \
+ _c240 = (double)(long)(((X##_f1 << 16) & 0xffffff) | (X##_f0 >> 48)); \
+ _h240 = (double)(long)(((Y##_f1 << 16) & 0xffffff) | (Y##_f0 >> 48)); \
+ _b240 = (double)(long)((X##_f1 >> 8) & 0xffffff); \
+ _g240 = (double)(long)((Y##_f1 >> 8) & 0xffffff); \
+ _a240 = (double)(long)(X##_f1 >> 32); \
+ _f240 = (double)(long)(Y##_f1 >> 32); \
+ _e240 *= _const[3]; \
+ _j240 *= _const[3]; \
+ _d240 *= _const[2]; \
+ _i240 *= _const[2]; \
+ _c240 *= _const[1]; \
+ _h240 *= _const[1]; \
+ _b240 *= _const[0]; \
+ _g240 *= _const[0]; \
+ _s240.d = _e240*_j240;\
+ _r240.d = _d240*_j240 + _e240*_i240;\
+ _q240.d = _c240*_j240 + _d240*_i240 + _e240*_h240;\
+ _p240.d = _b240*_j240 + _c240*_i240 + _d240*_h240 + _e240*_g240;\
+ _o240.d = _a240*_j240 + _b240*_i240 + _c240*_h240 + _d240*_g240 + _e240*_f240;\
+ _n240.d = _a240*_i240 + _b240*_h240 + _c240*_g240 + _d240*_f240; \
+ _m240.d = _a240*_h240 + _b240*_g240 + _c240*_f240; \
+ _l240.d = _a240*_g240 + _b240*_f240; \
+ _k240 = _a240*_f240; \
+ _r240.d += _s240.d; \
+ _q240.d += _r240.d; \
+ _p240.d += _q240.d; \
+ _o240.d += _p240.d; \
+ _n240.d += _o240.d; \
+ _m240.d += _n240.d; \
+ _l240.d += _m240.d; \
+ _k240 += _l240.d; \
+ _s240.d -= ((_const[10]+_s240.d)-_const[10]); \
+ _r240.d -= ((_const[9]+_r240.d)-_const[9]); \
+ _q240.d -= ((_const[8]+_q240.d)-_const[8]); \
+ _p240.d -= ((_const[7]+_p240.d)-_const[7]); \
+ _o240.d += _const[7]; \
+ _n240.d += _const[6]; \
+ _m240.d += _const[5]; \
+ _l240.d += _const[4]; \
+ if (_s240.d != 0.0) _y240 = 1; \
+ if (_r240.d != 0.0) _y240 = 1; \
+ if (_q240.d != 0.0) _y240 = 1; \
+ if (_p240.d != 0.0) _y240 = 1; \
+ _t240 = (DItype)_k240; \
+ _u240 = _l240.i; \
+ _v240 = _m240.i; \
+ _w240 = _n240.i; \
+ _x240 = _o240.i; \
+ R##_f1 = (_t240 << (128 - (wfracbits - 1))) \
+ | ((_u240 & 0xffffff) >> ((wfracbits - 1) - 104)); \
+ R##_f0 = ((_u240 & 0xffffff) << (168 - (wfracbits - 1))) \
+ | ((_v240 & 0xffffff) << (144 - (wfracbits - 1))) \
+ | ((_w240 & 0xffffff) << (120 - (wfracbits - 1))) \
+ | ((_x240 & 0xffffff) >> ((wfracbits - 1) - 96)) \
+ | _y240; \
+ resetfe; \
+ } while (0)
+
+/*
+ * Division algorithms:
+ */
+
+#define _FP_DIV_MEAT_2_udiv(fs, R, X, Y) \
+ do { \
+ _FP_W_TYPE _n_f2, _n_f1, _n_f0, _r_f1, _r_f0, _m_f1, _m_f0; \
+ if (_FP_FRAC_GT_2(X, Y)) \
+ { \
+ _n_f2 = X##_f1 >> 1; \
+ _n_f1 = X##_f1 << (_FP_W_TYPE_SIZE - 1) | X##_f0 >> 1; \
+ _n_f0 = X##_f0 << (_FP_W_TYPE_SIZE - 1); \
+ } \
+ else \
+ { \
+ R##_e--; \
+ _n_f2 = X##_f1; \
+ _n_f1 = X##_f0; \
+ _n_f0 = 0; \
+ } \
+ \
+ /* Normalize, i.e. make the most significant bit of the \
+ denominator set. */ \
+ _FP_FRAC_SLL_2(Y, _FP_WFRACXBITS_##fs); \
+ \
+ udiv_qrnnd(R##_f1, _r_f1, _n_f2, _n_f1, Y##_f1); \
+ umul_ppmm(_m_f1, _m_f0, R##_f1, Y##_f0); \
+ _r_f0 = _n_f0; \
+ if (_FP_FRAC_GT_2(_m, _r)) \
+ { \
+ R##_f1--; \
+ _FP_FRAC_ADD_2(_r, Y, _r); \
+ if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r)) \
+ { \
+ R##_f1--; \
+ _FP_FRAC_ADD_2(_r, Y, _r); \
+ } \
+ } \
+ _FP_FRAC_DEC_2(_r, _m); \
+ \
+ if (_r_f1 == Y##_f1) \
+ { \
+ /* This is a special case, not an optimization \
+ (_r/Y##_f1 would not fit into UWtype). \
+ As _r is guaranteed to be < Y, R##_f0 can be either \
+ (UWtype)-1 or (UWtype)-2. But as we know what kind \
+ of bits it is (sticky, guard, round), we don't care. \
+ We also don't care what the reminder is, because the \
+ guard bit will be set anyway. -jj */ \
+ R##_f0 = -1; \
+ } \
+ else \
+ { \
+ udiv_qrnnd(R##_f0, _r_f1, _r_f1, _r_f0, Y##_f1); \
+ umul_ppmm(_m_f1, _m_f0, R##_f0, Y##_f0); \
+ _r_f0 = 0; \
+ if (_FP_FRAC_GT_2(_m, _r)) \
+ { \
+ R##_f0--; \
+ _FP_FRAC_ADD_2(_r, Y, _r); \
+ if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r)) \
+ { \
+ R##_f0--; \
+ _FP_FRAC_ADD_2(_r, Y, _r); \
+ } \
+ } \
+ if (!_FP_FRAC_EQ_2(_r, _m)) \
+ R##_f0 |= _FP_WORK_STICKY; \
+ } \
+ } while (0)
+
+
+#define _FP_DIV_MEAT_2_gmp(fs, R, X, Y) \
+ do { \
+ _FP_W_TYPE _x[4], _y[2], _z[4]; \
+ _y[0] = Y##_f0; _y[1] = Y##_f1; \
+ _x[0] = _x[3] = 0; \
+ if (_FP_FRAC_GT_2(X, Y)) \
+ { \
+ R##_e++; \
+ _x[1] = (X##_f0 << (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE) | \
+ X##_f1 >> (_FP_W_TYPE_SIZE - \
+ (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE))); \
+ _x[2] = X##_f1 << (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE); \
+ } \
+ else \
+ { \
+ _x[1] = (X##_f0 << (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE) | \
+ X##_f1 >> (_FP_W_TYPE_SIZE - \
+ (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE))); \
+ _x[2] = X##_f1 << (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE); \
+ } \
+ \
+ (void) mpn_divrem (_z, 0, _x, 4, _y, 2); \
+ R##_f1 = _z[1]; \
+ R##_f0 = _z[0] | ((_x[0] | _x[1]) != 0); \
+ } while (0)
+
+
+/*
+ * Square root algorithms:
+ * We have just one right now, maybe Newton approximation
+ * should be added for those machines where division is fast.
+ */
+
+#define _FP_SQRT_MEAT_2(R, S, T, X, q) \
+ do { \
+ while (q) \
+ { \
+ T##_f1 = S##_f1 + q; \
+ if (T##_f1 <= X##_f1) \
+ { \
+ S##_f1 = T##_f1 + q; \
+ X##_f1 -= T##_f1; \
+ R##_f1 += q; \
+ } \
+ _FP_FRAC_SLL_2(X, 1); \
+ q >>= 1; \
+ } \
+ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \
+ while (q != _FP_WORK_ROUND) \
+ { \
+ T##_f0 = S##_f0 + q; \
+ T##_f1 = S##_f1; \
+ if (T##_f1 < X##_f1 || \
+ (T##_f1 == X##_f1 && T##_f0 <= X##_f0)) \
+ { \
+ S##_f0 = T##_f0 + q; \
+ S##_f1 += (T##_f0 > S##_f0); \
+ _FP_FRAC_DEC_2(X, T); \
+ R##_f0 += q; \
+ } \
+ _FP_FRAC_SLL_2(X, 1); \
+ q >>= 1; \
+ } \
+ if (X##_f0 | X##_f1) \
+ { \
+ if (S##_f1 < X##_f1 || \
+ (S##_f1 == X##_f1 && S##_f0 < X##_f0)) \
+ R##_f0 |= _FP_WORK_ROUND; \
+ R##_f0 |= _FP_WORK_STICKY; \
+ } \
+ } while (0)
+
+
+/*
+ * Assembly/disassembly for converting to/from integral types.
+ * No shifting or overflow handled here.
+ */
+
+#define _FP_FRAC_ASSEMBLE_2(r, X, rsize) \
+(void)((rsize <= _FP_W_TYPE_SIZE) \
+ ? ({ r = X##_f0; }) \
+ : ({ \
+ r = X##_f1; \
+ r <<= _FP_W_TYPE_SIZE; \
+ r += X##_f0; \
+ }))
+
+#define _FP_FRAC_DISASSEMBLE_2(X, r, rsize) \
+ do { \
+ X##_f0 = r; \
+ X##_f1 = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE); \
+ } while (0)
+
+/*
+ * Convert FP values between word sizes
+ */
+
+#define _FP_FRAC_COPY_1_2(D, S) (D##_f = S##_f0)
+
+#define _FP_FRAC_COPY_2_1(D, S) ((D##_f0 = S##_f), (D##_f1 = 0))
diff --git a/gcc/config/soft-fp/op-4.h b/gcc/config/soft-fp/op-4.h
new file mode 100644
index 00000000000..34f5098e8c2
--- /dev/null
+++ b/gcc/config/soft-fp/op-4.h
@@ -0,0 +1,686 @@
+/* Software floating-point emulation.
+ Basic four-word fraction declaration and manipulation.
+ Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com),
+ Jakub Jelinek (jj@ultra.linux.cz),
+ David S. Miller (davem@redhat.com) and
+ Peter Maydell (pmaydell@chiark.greenend.org.uk).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define _FP_FRAC_DECL_4(X) _FP_W_TYPE X##_f[4]
+#define _FP_FRAC_COPY_4(D,S) \
+ (D##_f[0] = S##_f[0], D##_f[1] = S##_f[1], \
+ D##_f[2] = S##_f[2], D##_f[3] = S##_f[3])
+#define _FP_FRAC_SET_4(X,I) __FP_FRAC_SET_4(X, I)
+#define _FP_FRAC_HIGH_4(X) (X##_f[3])
+#define _FP_FRAC_LOW_4(X) (X##_f[0])
+#define _FP_FRAC_WORD_4(X,w) (X##_f[w])
+
+#define _FP_FRAC_SLL_4(X,N) \
+ do { \
+ _FP_I_TYPE _up, _down, _skip, _i; \
+ _skip = (N) / _FP_W_TYPE_SIZE; \
+ _up = (N) % _FP_W_TYPE_SIZE; \
+ _down = _FP_W_TYPE_SIZE - _up; \
+ if (!_up) \
+ for (_i = 3; _i >= _skip; --_i) \
+ X##_f[_i] = X##_f[_i-_skip]; \
+ else \
+ { \
+ for (_i = 3; _i > _skip; --_i) \
+ X##_f[_i] = X##_f[_i-_skip] << _up \
+ | X##_f[_i-_skip-1] >> _down; \
+ X##_f[_i--] = X##_f[0] << _up; \
+ } \
+ for (; _i >= 0; --_i) \
+ X##_f[_i] = 0; \
+ } while (0)
+
+/* This one was broken too */
+#define _FP_FRAC_SRL_4(X,N) \
+ do { \
+ _FP_I_TYPE _up, _down, _skip, _i; \
+ _skip = (N) / _FP_W_TYPE_SIZE; \
+ _down = (N) % _FP_W_TYPE_SIZE; \
+ _up = _FP_W_TYPE_SIZE - _down; \
+ if (!_down) \
+ for (_i = 0; _i <= 3-_skip; ++_i) \
+ X##_f[_i] = X##_f[_i+_skip]; \
+ else \
+ { \
+ for (_i = 0; _i < 3-_skip; ++_i) \
+ X##_f[_i] = X##_f[_i+_skip] >> _down \
+ | X##_f[_i+_skip+1] << _up; \
+ X##_f[_i++] = X##_f[3] >> _down; \
+ } \
+ for (; _i < 4; ++_i) \
+ X##_f[_i] = 0; \
+ } while (0)
+
+
+/* Right shift with sticky-lsb.
+ * What this actually means is that we do a standard right-shift,
+ * but that if any of the bits that fall off the right hand side
+ * were one then we always set the LSbit.
+ */
+#define _FP_FRAC_SRST_4(X,S,N,size) \
+ do { \
+ _FP_I_TYPE _up, _down, _skip, _i; \
+ _FP_W_TYPE _s; \
+ _skip = (N) / _FP_W_TYPE_SIZE; \
+ _down = (N) % _FP_W_TYPE_SIZE; \
+ _up = _FP_W_TYPE_SIZE - _down; \
+ for (_s = _i = 0; _i < _skip; ++_i) \
+ _s |= X##_f[_i]; \
+ if (!_down) \
+ for (_i = 0; _i <= 3-_skip; ++_i) \
+ X##_f[_i] = X##_f[_i+_skip]; \
+ else \
+ { \
+ _s |= X##_f[_i] << _up; \
+ for (_i = 0; _i < 3-_skip; ++_i) \
+ X##_f[_i] = X##_f[_i+_skip] >> _down \
+ | X##_f[_i+_skip+1] << _up; \
+ X##_f[_i++] = X##_f[3] >> _down; \
+ } \
+ for (; _i < 4; ++_i) \
+ X##_f[_i] = 0; \
+ S = (_s != 0); \
+ } while (0)
+
+#define _FP_FRAC_SRS_4(X,N,size) \
+ do { \
+ int _sticky; \
+ _FP_FRAC_SRST_4(X, _sticky, N, size); \
+ X##_f[0] |= _sticky; \
+ } while (0)
+
+#define _FP_FRAC_ADD_4(R,X,Y) \
+ __FP_FRAC_ADD_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0], \
+ X##_f[3], X##_f[2], X##_f[1], X##_f[0], \
+ Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0])
+
+#define _FP_FRAC_SUB_4(R,X,Y) \
+ __FP_FRAC_SUB_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0], \
+ X##_f[3], X##_f[2], X##_f[1], X##_f[0], \
+ Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0])
+
+#define _FP_FRAC_DEC_4(X,Y) \
+ __FP_FRAC_DEC_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], \
+ Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0])
+
+#define _FP_FRAC_ADDI_4(X,I) \
+ __FP_FRAC_ADDI_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], I)
+
+#define _FP_ZEROFRAC_4 0,0,0,0
+#define _FP_MINFRAC_4 0,0,0,1
+#define _FP_MAXFRAC_4 (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0)
+
+#define _FP_FRAC_ZEROP_4(X) ((X##_f[0] | X##_f[1] | X##_f[2] | X##_f[3]) == 0)
+#define _FP_FRAC_NEGP_4(X) ((_FP_WS_TYPE)X##_f[3] < 0)
+#define _FP_FRAC_OVERP_4(fs,X) (_FP_FRAC_HIGH_##fs(X) & _FP_OVERFLOW_##fs)
+#define _FP_FRAC_CLEAR_OVERP_4(fs,X) (_FP_FRAC_HIGH_##fs(X) &= ~_FP_OVERFLOW_##fs)
+
+#define _FP_FRAC_EQ_4(X,Y) \
+ (X##_f[0] == Y##_f[0] && X##_f[1] == Y##_f[1] \
+ && X##_f[2] == Y##_f[2] && X##_f[3] == Y##_f[3])
+
+#define _FP_FRAC_GT_4(X,Y) \
+ (X##_f[3] > Y##_f[3] || \
+ (X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] || \
+ (X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] || \
+ (X##_f[1] == Y##_f[1] && X##_f[0] > Y##_f[0]) \
+ )) \
+ )) \
+ )
+
+#define _FP_FRAC_GE_4(X,Y) \
+ (X##_f[3] > Y##_f[3] || \
+ (X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] || \
+ (X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] || \
+ (X##_f[1] == Y##_f[1] && X##_f[0] >= Y##_f[0]) \
+ )) \
+ )) \
+ )
+
+
+#define _FP_FRAC_CLZ_4(R,X) \
+ do { \
+ if (X##_f[3]) \
+ { \
+ __FP_CLZ(R,X##_f[3]); \
+ } \
+ else if (X##_f[2]) \
+ { \
+ __FP_CLZ(R,X##_f[2]); \
+ R += _FP_W_TYPE_SIZE; \
+ } \
+ else if (X##_f[1]) \
+ { \
+ __FP_CLZ(R,X##_f[1]); \
+ R += _FP_W_TYPE_SIZE*2; \
+ } \
+ else \
+ { \
+ __FP_CLZ(R,X##_f[0]); \
+ R += _FP_W_TYPE_SIZE*3; \
+ } \
+ } while(0)
+
+
+#define _FP_UNPACK_RAW_4(fs, X, val) \
+ do { \
+ union _FP_UNION_##fs _flo; _flo.flt = (val); \
+ X##_f[0] = _flo.bits.frac0; \
+ X##_f[1] = _flo.bits.frac1; \
+ X##_f[2] = _flo.bits.frac2; \
+ X##_f[3] = _flo.bits.frac3; \
+ X##_e = _flo.bits.exp; \
+ X##_s = _flo.bits.sign; \
+ } while (0)
+
+#define _FP_UNPACK_RAW_4_P(fs, X, val) \
+ do { \
+ union _FP_UNION_##fs *_flo = \
+ (union _FP_UNION_##fs *)(val); \
+ \
+ X##_f[0] = _flo->bits.frac0; \
+ X##_f[1] = _flo->bits.frac1; \
+ X##_f[2] = _flo->bits.frac2; \
+ X##_f[3] = _flo->bits.frac3; \
+ X##_e = _flo->bits.exp; \
+ X##_s = _flo->bits.sign; \
+ } while (0)
+
+#define _FP_PACK_RAW_4(fs, val, X) \
+ do { \
+ union _FP_UNION_##fs _flo; \
+ _flo.bits.frac0 = X##_f[0]; \
+ _flo.bits.frac1 = X##_f[1]; \
+ _flo.bits.frac2 = X##_f[2]; \
+ _flo.bits.frac3 = X##_f[3]; \
+ _flo.bits.exp = X##_e; \
+ _flo.bits.sign = X##_s; \
+ (val) = _flo.flt; \
+ } while (0)
+
+#define _FP_PACK_RAW_4_P(fs, val, X) \
+ do { \
+ union _FP_UNION_##fs *_flo = \
+ (union _FP_UNION_##fs *)(val); \
+ \
+ _flo->bits.frac0 = X##_f[0]; \
+ _flo->bits.frac1 = X##_f[1]; \
+ _flo->bits.frac2 = X##_f[2]; \
+ _flo->bits.frac3 = X##_f[3]; \
+ _flo->bits.exp = X##_e; \
+ _flo->bits.sign = X##_s; \
+ } while (0)
+
+/*
+ * Multiplication algorithms:
+ */
+
+/* Given a 1W * 1W => 2W primitive, do the extended multiplication. */
+
+#define _FP_MUL_MEAT_4_wide(wfracbits, R, X, Y, doit) \
+ do { \
+ _FP_FRAC_DECL_8(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \
+ _FP_FRAC_DECL_2(_d); _FP_FRAC_DECL_2(_e); _FP_FRAC_DECL_2(_f); \
+ \
+ doit(_FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0), X##_f[0], Y##_f[0]); \
+ doit(_b_f1, _b_f0, X##_f[0], Y##_f[1]); \
+ doit(_c_f1, _c_f0, X##_f[1], Y##_f[0]); \
+ doit(_d_f1, _d_f0, X##_f[1], Y##_f[1]); \
+ doit(_e_f1, _e_f0, X##_f[0], Y##_f[2]); \
+ doit(_f_f1, _f_f0, X##_f[2], Y##_f[0]); \
+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2), \
+ _FP_FRAC_WORD_8(_z,1), 0,_b_f1,_b_f0, \
+ 0,0,_FP_FRAC_WORD_8(_z,1)); \
+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2), \
+ _FP_FRAC_WORD_8(_z,1), 0,_c_f1,_c_f0, \
+ _FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2), \
+ _FP_FRAC_WORD_8(_z,1)); \
+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \
+ _FP_FRAC_WORD_8(_z,2), 0,_d_f1,_d_f0, \
+ 0,_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2)); \
+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \
+ _FP_FRAC_WORD_8(_z,2), 0,_e_f1,_e_f0, \
+ _FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \
+ _FP_FRAC_WORD_8(_z,2)); \
+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \
+ _FP_FRAC_WORD_8(_z,2), 0,_f_f1,_f_f0, \
+ _FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \
+ _FP_FRAC_WORD_8(_z,2)); \
+ doit(_b_f1, _b_f0, X##_f[0], Y##_f[3]); \
+ doit(_c_f1, _c_f0, X##_f[3], Y##_f[0]); \
+ doit(_d_f1, _d_f0, X##_f[1], Y##_f[2]); \
+ doit(_e_f1, _e_f0, X##_f[2], Y##_f[1]); \
+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \
+ _FP_FRAC_WORD_8(_z,3), 0,_b_f1,_b_f0, \
+ 0,_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3)); \
+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \
+ _FP_FRAC_WORD_8(_z,3), 0,_c_f1,_c_f0, \
+ _FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \
+ _FP_FRAC_WORD_8(_z,3)); \
+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \
+ _FP_FRAC_WORD_8(_z,3), 0,_d_f1,_d_f0, \
+ _FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \
+ _FP_FRAC_WORD_8(_z,3)); \
+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \
+ _FP_FRAC_WORD_8(_z,3), 0,_e_f1,_e_f0, \
+ _FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \
+ _FP_FRAC_WORD_8(_z,3)); \
+ doit(_b_f1, _b_f0, X##_f[2], Y##_f[2]); \
+ doit(_c_f1, _c_f0, X##_f[1], Y##_f[3]); \
+ doit(_d_f1, _d_f0, X##_f[3], Y##_f[1]); \
+ doit(_e_f1, _e_f0, X##_f[2], Y##_f[3]); \
+ doit(_f_f1, _f_f0, X##_f[3], Y##_f[2]); \
+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \
+ _FP_FRAC_WORD_8(_z,4), 0,_b_f1,_b_f0, \
+ 0,_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4)); \
+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \
+ _FP_FRAC_WORD_8(_z,4), 0,_c_f1,_c_f0, \
+ _FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \
+ _FP_FRAC_WORD_8(_z,4)); \
+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \
+ _FP_FRAC_WORD_8(_z,4), 0,_d_f1,_d_f0, \
+ _FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \
+ _FP_FRAC_WORD_8(_z,4)); \
+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \
+ _FP_FRAC_WORD_8(_z,5), 0,_e_f1,_e_f0, \
+ 0,_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5)); \
+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \
+ _FP_FRAC_WORD_8(_z,5), 0,_f_f1,_f_f0, \
+ _FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \
+ _FP_FRAC_WORD_8(_z,5)); \
+ doit(_b_f1, _b_f0, X##_f[3], Y##_f[3]); \
+ __FP_FRAC_ADD_2(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \
+ _b_f1,_b_f0, \
+ _FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6)); \
+ \
+ /* Normalize since we know where the msb of the multiplicands \
+ were (bit B), we know that the msb of the of the product is \
+ at either 2B or 2B-1. */ \
+ _FP_FRAC_SRS_8(_z, wfracbits-1, 2*wfracbits); \
+ __FP_FRAC_SET_4(R, _FP_FRAC_WORD_8(_z,3), _FP_FRAC_WORD_8(_z,2), \
+ _FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0)); \
+ } while (0)
+
+#define _FP_MUL_MEAT_4_gmp(wfracbits, R, X, Y) \
+ do { \
+ _FP_FRAC_DECL_8(_z); \
+ \
+ mpn_mul_n(_z_f, _x_f, _y_f, 4); \
+ \
+ /* Normalize since we know where the msb of the multiplicands \
+ were (bit B), we know that the msb of the of the product is \
+ at either 2B or 2B-1. */ \
+ _FP_FRAC_SRS_8(_z, wfracbits-1, 2*wfracbits); \
+ __FP_FRAC_SET_4(R, _FP_FRAC_WORD_8(_z,3), _FP_FRAC_WORD_8(_z,2), \
+ _FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0)); \
+ } while (0)
+
+/*
+ * Helper utility for _FP_DIV_MEAT_4_udiv:
+ * pppp = m * nnn
+ */
+#define umul_ppppmnnn(p3,p2,p1,p0,m,n2,n1,n0) \
+ do { \
+ UWtype _t; \
+ umul_ppmm(p1,p0,m,n0); \
+ umul_ppmm(p2,_t,m,n1); \
+ __FP_FRAC_ADDI_2(p2,p1,_t); \
+ umul_ppmm(p3,_t,m,n2); \
+ __FP_FRAC_ADDI_2(p3,p2,_t); \
+ } while (0)
+
+/*
+ * Division algorithms:
+ */
+
+#define _FP_DIV_MEAT_4_udiv(fs, R, X, Y) \
+ do { \
+ int _i; \
+ _FP_FRAC_DECL_4(_n); _FP_FRAC_DECL_4(_m); \
+ _FP_FRAC_SET_4(_n, _FP_ZEROFRAC_4); \
+ if (_FP_FRAC_GT_4(X, Y)) \
+ { \
+ _n_f[3] = X##_f[0] << (_FP_W_TYPE_SIZE - 1); \
+ _FP_FRAC_SRL_4(X, 1); \
+ } \
+ else \
+ R##_e--; \
+ \
+ /* Normalize, i.e. make the most significant bit of the \
+ denominator set. */ \
+ _FP_FRAC_SLL_4(Y, _FP_WFRACXBITS_##fs); \
+ \
+ for (_i = 3; ; _i--) \
+ { \
+ if (X##_f[3] == Y##_f[3]) \
+ { \
+ /* This is a special case, not an optimization \
+ (X##_f[3]/Y##_f[3] would not fit into UWtype). \
+ As X## is guaranteed to be < Y, R##_f[_i] can be either \
+ (UWtype)-1 or (UWtype)-2. */ \
+ R##_f[_i] = -1; \
+ if (!_i) \
+ break; \
+ __FP_FRAC_SUB_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], \
+ Y##_f[2], Y##_f[1], Y##_f[0], 0, \
+ X##_f[2], X##_f[1], X##_f[0], _n_f[_i]); \
+ _FP_FRAC_SUB_4(X, Y, X); \
+ if (X##_f[3] > Y##_f[3]) \
+ { \
+ R##_f[_i] = -2; \
+ _FP_FRAC_ADD_4(X, Y, X); \
+ } \
+ } \
+ else \
+ { \
+ udiv_qrnnd(R##_f[_i], X##_f[3], X##_f[3], X##_f[2], Y##_f[3]); \
+ umul_ppppmnnn(_m_f[3], _m_f[2], _m_f[1], _m_f[0], \
+ R##_f[_i], Y##_f[2], Y##_f[1], Y##_f[0]); \
+ X##_f[2] = X##_f[1]; \
+ X##_f[1] = X##_f[0]; \
+ X##_f[0] = _n_f[_i]; \
+ if (_FP_FRAC_GT_4(_m, X)) \
+ { \
+ R##_f[_i]--; \
+ _FP_FRAC_ADD_4(X, Y, X); \
+ if (_FP_FRAC_GE_4(X, Y) && _FP_FRAC_GT_4(_m, X)) \
+ { \
+ R##_f[_i]--; \
+ _FP_FRAC_ADD_4(X, Y, X); \
+ } \
+ } \
+ _FP_FRAC_DEC_4(X, _m); \
+ if (!_i) \
+ { \
+ if (!_FP_FRAC_EQ_4(X, _m)) \
+ R##_f[0] |= _FP_WORK_STICKY; \
+ break; \
+ } \
+ } \
+ } \
+ } while (0)
+
+
+/*
+ * Square root algorithms:
+ * We have just one right now, maybe Newton approximation
+ * should be added for those machines where division is fast.
+ */
+
+#define _FP_SQRT_MEAT_4(R, S, T, X, q) \
+ do { \
+ while (q) \
+ { \
+ T##_f[3] = S##_f[3] + q; \
+ if (T##_f[3] <= X##_f[3]) \
+ { \
+ S##_f[3] = T##_f[3] + q; \
+ X##_f[3] -= T##_f[3]; \
+ R##_f[3] += q; \
+ } \
+ _FP_FRAC_SLL_4(X, 1); \
+ q >>= 1; \
+ } \
+ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \
+ while (q) \
+ { \
+ T##_f[2] = S##_f[2] + q; \
+ T##_f[3] = S##_f[3]; \
+ if (T##_f[3] < X##_f[3] || \
+ (T##_f[3] == X##_f[3] && T##_f[2] <= X##_f[2])) \
+ { \
+ S##_f[2] = T##_f[2] + q; \
+ S##_f[3] += (T##_f[2] > S##_f[2]); \
+ __FP_FRAC_DEC_2(X##_f[3], X##_f[2], \
+ T##_f[3], T##_f[2]); \
+ R##_f[2] += q; \
+ } \
+ _FP_FRAC_SLL_4(X, 1); \
+ q >>= 1; \
+ } \
+ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \
+ while (q) \
+ { \
+ T##_f[1] = S##_f[1] + q; \
+ T##_f[2] = S##_f[2]; \
+ T##_f[3] = S##_f[3]; \
+ if (T##_f[3] < X##_f[3] || \
+ (T##_f[3] == X##_f[3] && (T##_f[2] < X##_f[2] || \
+ (T##_f[2] == X##_f[2] && T##_f[1] <= X##_f[1])))) \
+ { \
+ S##_f[1] = T##_f[1] + q; \
+ S##_f[2] += (T##_f[1] > S##_f[1]); \
+ S##_f[3] += (T##_f[2] > S##_f[2]); \
+ __FP_FRAC_DEC_3(X##_f[3], X##_f[2], X##_f[1], \
+ T##_f[3], T##_f[2], T##_f[1]); \
+ R##_f[1] += q; \
+ } \
+ _FP_FRAC_SLL_4(X, 1); \
+ q >>= 1; \
+ } \
+ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \
+ while (q != _FP_WORK_ROUND) \
+ { \
+ T##_f[0] = S##_f[0] + q; \
+ T##_f[1] = S##_f[1]; \
+ T##_f[2] = S##_f[2]; \
+ T##_f[3] = S##_f[3]; \
+ if (_FP_FRAC_GE_4(X,T)) \
+ { \
+ S##_f[0] = T##_f[0] + q; \
+ S##_f[1] += (T##_f[0] > S##_f[0]); \
+ S##_f[2] += (T##_f[1] > S##_f[1]); \
+ S##_f[3] += (T##_f[2] > S##_f[2]); \
+ _FP_FRAC_DEC_4(X, T); \
+ R##_f[0] += q; \
+ } \
+ _FP_FRAC_SLL_4(X, 1); \
+ q >>= 1; \
+ } \
+ if (!_FP_FRAC_ZEROP_4(X)) \
+ { \
+ if (_FP_FRAC_GT_4(X,S)) \
+ R##_f[0] |= _FP_WORK_ROUND; \
+ R##_f[0] |= _FP_WORK_STICKY; \
+ } \
+ } while (0)
+
+
+/*
+ * Internals
+ */
+
+#define __FP_FRAC_SET_4(X,I3,I2,I1,I0) \
+ (X##_f[3] = I3, X##_f[2] = I2, X##_f[1] = I1, X##_f[0] = I0)
+
+#ifndef __FP_FRAC_ADD_3
+#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \
+ do { \
+ _FP_W_TYPE _c1, _c2; \
+ r0 = x0 + y0; \
+ _c1 = r0 < x0; \
+ r1 = x1 + y1; \
+ _c2 = r1 < x1; \
+ r1 += _c1; \
+ _c2 |= r1 < _c1; \
+ r2 = x2 + y2 + _c2; \
+ } while (0)
+#endif
+
+#ifndef __FP_FRAC_ADD_4
+#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \
+ do { \
+ _FP_W_TYPE _c1, _c2, _c3; \
+ r0 = x0 + y0; \
+ _c1 = r0 < x0; \
+ r1 = x1 + y1; \
+ _c2 = r1 < x1; \
+ r1 += _c1; \
+ _c2 |= r1 < _c1; \
+ r2 = x2 + y2; \
+ _c3 = r2 < x2; \
+ r2 += _c2; \
+ _c3 |= r2 < _c2; \
+ r3 = x3 + y3 + _c3; \
+ } while (0)
+#endif
+
+#ifndef __FP_FRAC_SUB_3
+#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \
+ do { \
+ _FP_W_TYPE _c1, _c2; \
+ r0 = x0 - y0; \
+ _c1 = r0 > x0; \
+ r1 = x1 - y1; \
+ _c2 = r1 > x1; \
+ r1 -= _c1; \
+ _c2 |= r1 > _c1; \
+ r2 = x2 - y2 - _c2; \
+ } while (0)
+#endif
+
+#ifndef __FP_FRAC_SUB_4
+#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \
+ do { \
+ _FP_W_TYPE _c1, _c2, _c3; \
+ r0 = x0 - y0; \
+ _c1 = r0 > x0; \
+ r1 = x1 - y1; \
+ _c2 = r1 > x1; \
+ r1 -= _c1; \
+ _c2 |= r1 > _c1; \
+ r2 = x2 - y2; \
+ _c3 = r2 > x2; \
+ r2 -= _c2; \
+ _c3 |= r2 > _c2; \
+ r3 = x3 - y3 - _c3; \
+ } while (0)
+#endif
+
+#ifndef __FP_FRAC_DEC_3
+#define __FP_FRAC_DEC_3(x2,x1,x0,y2,y1,y0) \
+ do { \
+ UWtype _t0, _t1, _t2; \
+ _t0 = x0, _t1 = x1, _t2 = x2; \
+ __FP_FRAC_SUB_3 (x2, x1, x0, _t2, _t1, _t0, y2, y1, y0); \
+ } while (0)
+#endif
+
+#ifndef __FP_FRAC_DEC_4
+#define __FP_FRAC_DEC_4(x3,x2,x1,x0,y3,y2,y1,y0) \
+ do { \
+ UWtype _t0, _t1, _t2, _t3; \
+ _t0 = x0, _t1 = x1, _t2 = x2, _t3 = x3; \
+ __FP_FRAC_SUB_4 (x3,x2,x1,x0,_t3,_t2,_t1,_t0, y3,y2,y1,y0); \
+ } while (0)
+#endif
+
+#ifndef __FP_FRAC_ADDI_4
+#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i) \
+ do { \
+ UWtype _t; \
+ _t = ((x0 += i) < i); \
+ x1 += _t; _t = (x1 < _t); \
+ x2 += _t; _t = (x2 < _t); \
+ x3 += _t; \
+ } while (0)
+#endif
+
+/* Convert FP values between word sizes. This appears to be more
+ * complicated than I'd have expected it to be, so these might be
+ * wrong... These macros are in any case somewhat bogus because they
+ * use information about what various FRAC_n variables look like
+ * internally [eg, that 2 word vars are X_f0 and x_f1]. But so do
+ * the ones in op-2.h and op-1.h.
+ */
+#define _FP_FRAC_COPY_1_4(D, S) (D##_f = S##_f[0])
+
+#define _FP_FRAC_COPY_2_4(D, S) \
+do { \
+ D##_f0 = S##_f[0]; \
+ D##_f1 = S##_f[1]; \
+} while (0)
+
+/* Assembly/disassembly for converting to/from integral types.
+ * No shifting or overflow handled here.
+ */
+/* Put the FP value X into r, which is an integer of size rsize. */
+#define _FP_FRAC_ASSEMBLE_4(r, X, rsize) \
+ do { \
+ if (rsize <= _FP_W_TYPE_SIZE) \
+ r = X##_f[0]; \
+ else if (rsize <= 2*_FP_W_TYPE_SIZE) \
+ { \
+ r = X##_f[1]; \
+ r <<= _FP_W_TYPE_SIZE; \
+ r += X##_f[0]; \
+ } \
+ else \
+ { \
+ /* I'm feeling lazy so we deal with int == 3words (implausible)*/ \
+ /* and int == 4words as a single case. */ \
+ r = X##_f[3]; \
+ r <<= _FP_W_TYPE_SIZE; \
+ r += X##_f[2]; \
+ r <<= _FP_W_TYPE_SIZE; \
+ r += X##_f[1]; \
+ r <<= _FP_W_TYPE_SIZE; \
+ r += X##_f[0]; \
+ } \
+ } while (0)
+
+/* "No disassemble Number Five!" */
+/* move an integer of size rsize into X's fractional part. We rely on
+ * the _f[] array consisting of words of size _FP_W_TYPE_SIZE to avoid
+ * having to mask the values we store into it.
+ */
+#define _FP_FRAC_DISASSEMBLE_4(X, r, rsize) \
+ do { \
+ X##_f[0] = r; \
+ X##_f[1] = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE); \
+ X##_f[2] = (rsize <= 2*_FP_W_TYPE_SIZE ? 0 : r >> 2*_FP_W_TYPE_SIZE); \
+ X##_f[3] = (rsize <= 3*_FP_W_TYPE_SIZE ? 0 : r >> 3*_FP_W_TYPE_SIZE); \
+ } while (0);
+
+#define _FP_FRAC_COPY_4_1(D, S) \
+do { \
+ D##_f[0] = S##_f; \
+ D##_f[1] = D##_f[2] = D##_f[3] = 0; \
+} while (0)
+
+#define _FP_FRAC_COPY_4_2(D, S) \
+do { \
+ D##_f[0] = S##_f0; \
+ D##_f[1] = S##_f1; \
+ D##_f[2] = D##_f[3] = 0; \
+} while (0)
diff --git a/gcc/config/soft-fp/op-8.h b/gcc/config/soft-fp/op-8.h
new file mode 100644
index 00000000000..e0612a5e62f
--- /dev/null
+++ b/gcc/config/soft-fp/op-8.h
@@ -0,0 +1,111 @@
+/* Software floating-point emulation.
+ Basic eight-word fraction declaration and manipulation.
+ Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com),
+ Jakub Jelinek (jj@ultra.linux.cz) and
+ Peter Maydell (pmaydell@chiark.greenend.org.uk).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* We need just a few things from here for op-4, if we ever need some
+ other macros, they can be added. */
+#define _FP_FRAC_DECL_8(X) _FP_W_TYPE X##_f[8]
+#define _FP_FRAC_HIGH_8(X) (X##_f[7])
+#define _FP_FRAC_LOW_8(X) (X##_f[0])
+#define _FP_FRAC_WORD_8(X,w) (X##_f[w])
+
+#define _FP_FRAC_SLL_8(X,N) \
+ do { \
+ _FP_I_TYPE _up, _down, _skip, _i; \
+ _skip = (N) / _FP_W_TYPE_SIZE; \
+ _up = (N) % _FP_W_TYPE_SIZE; \
+ _down = _FP_W_TYPE_SIZE - _up; \
+ if (!_up) \
+ for (_i = 7; _i >= _skip; --_i) \
+ X##_f[_i] = X##_f[_i-_skip]; \
+ else \
+ { \
+ for (_i = 7; _i > _skip; --_i) \
+ X##_f[_i] = X##_f[_i-_skip] << _up \
+ | X##_f[_i-_skip-1] >> _down; \
+ X##_f[_i--] = X##_f[0] << _up; \
+ } \
+ for (; _i >= 0; --_i) \
+ X##_f[_i] = 0; \
+ } while (0)
+
+#define _FP_FRAC_SRL_8(X,N) \
+ do { \
+ _FP_I_TYPE _up, _down, _skip, _i; \
+ _skip = (N) / _FP_W_TYPE_SIZE; \
+ _down = (N) % _FP_W_TYPE_SIZE; \
+ _up = _FP_W_TYPE_SIZE - _down; \
+ if (!_down) \
+ for (_i = 0; _i <= 7-_skip; ++_i) \
+ X##_f[_i] = X##_f[_i+_skip]; \
+ else \
+ { \
+ for (_i = 0; _i < 7-_skip; ++_i) \
+ X##_f[_i] = X##_f[_i+_skip] >> _down \
+ | X##_f[_i+_skip+1] << _up; \
+ X##_f[_i++] = X##_f[7] >> _down; \
+ } \
+ for (; _i < 8; ++_i) \
+ X##_f[_i] = 0; \
+ } while (0)
+
+
+/* Right shift with sticky-lsb.
+ * What this actually means is that we do a standard right-shift,
+ * but that if any of the bits that fall off the right hand side
+ * were one then we always set the LSbit.
+ */
+#define _FP_FRAC_SRS_8(X,N,size) \
+ do { \
+ _FP_I_TYPE _up, _down, _skip, _i; \
+ _FP_W_TYPE _s; \
+ _skip = (N) / _FP_W_TYPE_SIZE; \
+ _down = (N) % _FP_W_TYPE_SIZE; \
+ _up = _FP_W_TYPE_SIZE - _down; \
+ for (_s = _i = 0; _i < _skip; ++_i) \
+ _s |= X##_f[_i]; \
+ if (!_down) \
+ for (_i = 0; _i <= 7-_skip; ++_i) \
+ X##_f[_i] = X##_f[_i+_skip]; \
+ else \
+ { \
+ _s |= X##_f[_i] << _up; \
+ for (_i = 0; _i < 7-_skip; ++_i) \
+ X##_f[_i] = X##_f[_i+_skip] >> _down \
+ | X##_f[_i+_skip+1] << _up; \
+ X##_f[_i++] = X##_f[7] >> _down; \
+ } \
+ for (; _i < 8; ++_i) \
+ X##_f[_i] = 0; \
+ /* don't fix the LSB until the very end when we're sure f[0] is stable */ \
+ X##_f[0] |= (_s != 0); \
+ } while (0)
+
diff --git a/gcc/config/soft-fp/op-common.h b/gcc/config/soft-fp/op-common.h
new file mode 100644
index 00000000000..4ec7fade485
--- /dev/null
+++ b/gcc/config/soft-fp/op-common.h
@@ -0,0 +1,1330 @@
+/* Software floating-point emulation. Common operations.
+ Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com),
+ Jakub Jelinek (jj@ultra.linux.cz),
+ David S. Miller (davem@redhat.com) and
+ Peter Maydell (pmaydell@chiark.greenend.org.uk).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define _FP_DECL(wc, X) \
+ _FP_I_TYPE X##_c __attribute__((unused)), X##_s, X##_e; \
+ _FP_FRAC_DECL_##wc(X)
+
+/*
+ * Finish truely unpacking a native fp value by classifying the kind
+ * of fp value and normalizing both the exponent and the fraction.
+ */
+
+#define _FP_UNPACK_CANONICAL(fs, wc, X) \
+do { \
+ switch (X##_e) \
+ { \
+ default: \
+ _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \
+ _FP_FRAC_SLL_##wc(X, _FP_WORKBITS); \
+ X##_e -= _FP_EXPBIAS_##fs; \
+ X##_c = FP_CLS_NORMAL; \
+ break; \
+ \
+ case 0: \
+ if (_FP_FRAC_ZEROP_##wc(X)) \
+ X##_c = FP_CLS_ZERO; \
+ else \
+ { \
+ /* a denormalized number */ \
+ _FP_I_TYPE _shift; \
+ _FP_FRAC_CLZ_##wc(_shift, X); \
+ _shift -= _FP_FRACXBITS_##fs; \
+ _FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS)); \
+ X##_e -= _FP_EXPBIAS_##fs - 1 + _shift; \
+ X##_c = FP_CLS_NORMAL; \
+ FP_SET_EXCEPTION(FP_EX_DENORM); \
+ } \
+ break; \
+ \
+ case _FP_EXPMAX_##fs: \
+ if (_FP_FRAC_ZEROP_##wc(X)) \
+ X##_c = FP_CLS_INF; \
+ else \
+ { \
+ X##_c = FP_CLS_NAN; \
+ /* Check for signaling NaN */ \
+ if (!(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \
+ FP_SET_EXCEPTION(FP_EX_INVALID); \
+ } \
+ break; \
+ } \
+} while (0)
+
+/* Finish unpacking an fp value in semi-raw mode: the mantissa is
+ shifted by _FP_WORKBITS but the implicit MSB is not inserted and
+ other classification is not done. */
+#define _FP_UNPACK_SEMIRAW(fs, wc, X) _FP_FRAC_SLL_##wc(X, _FP_WORKBITS)
+
+/* A semi-raw value has overflowed to infinity. Adjust the mantissa
+ and exponent appropriately. */
+#define _FP_OVERFLOW_SEMIRAW(fs, wc, X) \
+do { \
+ if (FP_ROUNDMODE == FP_RND_NEAREST \
+ || (FP_ROUNDMODE == FP_RND_PINF && !X##_s) \
+ || (FP_ROUNDMODE == FP_RND_MINF && X##_s)) \
+ { \
+ X##_e = _FP_EXPMAX_##fs; \
+ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
+ } \
+ else \
+ { \
+ X##_e = _FP_EXPMAX_##fs - 1; \
+ FP_SET_EXCEPTION(FP_EX_OVERFLOW); \
+ FP_SET_EXCEPTION(FP_EX_INEXACT); \
+ _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \
+ } \
+} while (0)
+
+/* Check for a semi-raw value being a signaling NaN and raise the
+ invalid exception if so. */
+#define _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X) \
+do { \
+ if (X##_e == _FP_EXPMAX_##fs \
+ && !_FP_FRAC_ZEROP_##wc(X) \
+ && !(_FP_FRAC_HIGH_##fs(X) & _FP_QNANBIT_SH_##fs)) \
+ FP_SET_EXCEPTION(FP_EX_INVALID); \
+} while (0)
+
+/* Choose a NaN result from an operation on two semi-raw NaN
+ values. */
+#define _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP) \
+do { \
+ /* _FP_CHOOSENAN expects raw values, so shift as required. */ \
+ _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
+ _FP_FRAC_SRL_##wc(Y, _FP_WORKBITS); \
+ _FP_CHOOSENAN(fs, wc, R, X, Y, OP); \
+ _FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \
+} while (0)
+
+/* Test whether a biased exponent is normal (not zero or maximum). */
+#define _FP_EXP_NORMAL(fs, wc, X) (((X##_e + 1) & _FP_EXPMAX_##fs) > 1)
+
+/* Prepare to pack an fp value in semi-raw mode: the mantissa is
+ rounded and shifted right, with the rounding possibly increasing
+ the exponent (including changing a finite value to infinity). */
+#define _FP_PACK_SEMIRAW(fs, wc, X) \
+do { \
+ _FP_ROUND(wc, X); \
+ if (_FP_FRAC_HIGH_##fs(X) \
+ & (_FP_OVERFLOW_##fs >> 1)) \
+ { \
+ _FP_FRAC_HIGH_##fs(X) &= ~(_FP_OVERFLOW_##fs >> 1); \
+ X##_e++; \
+ if (X##_e == _FP_EXPMAX_##fs) \
+ _FP_OVERFLOW_SEMIRAW(fs, wc, X); \
+ } \
+ _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
+ if (!_FP_EXP_NORMAL(fs, wc, X) && !_FP_FRAC_ZEROP_##wc(X)) \
+ { \
+ if (X##_e == 0) \
+ FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \
+ else \
+ { \
+ if (!_FP_KEEPNANFRACP) \
+ { \
+ _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \
+ X##_s = _FP_NANSIGN_##fs; \
+ } \
+ else \
+ _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs; \
+ } \
+ } \
+} while (0)
+
+/*
+ * Before packing the bits back into the native fp result, take care
+ * of such mundane things as rounding and overflow. Also, for some
+ * kinds of fp values, the original parts may not have been fully
+ * extracted -- but that is ok, we can regenerate them now.
+ */
+
+#define _FP_PACK_CANONICAL(fs, wc, X) \
+do { \
+ switch (X##_c) \
+ { \
+ case FP_CLS_NORMAL: \
+ X##_e += _FP_EXPBIAS_##fs; \
+ if (X##_e > 0) \
+ { \
+ _FP_ROUND(wc, X); \
+ if (_FP_FRAC_OVERP_##wc(fs, X)) \
+ { \
+ _FP_FRAC_CLEAR_OVERP_##wc(fs, X); \
+ X##_e++; \
+ } \
+ _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
+ if (X##_e >= _FP_EXPMAX_##fs) \
+ { \
+ /* overflow */ \
+ switch (FP_ROUNDMODE) \
+ { \
+ case FP_RND_NEAREST: \
+ X##_c = FP_CLS_INF; \
+ break; \
+ case FP_RND_PINF: \
+ if (!X##_s) X##_c = FP_CLS_INF; \
+ break; \
+ case FP_RND_MINF: \
+ if (X##_s) X##_c = FP_CLS_INF; \
+ break; \
+ } \
+ if (X##_c == FP_CLS_INF) \
+ { \
+ /* Overflow to infinity */ \
+ X##_e = _FP_EXPMAX_##fs; \
+ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
+ } \
+ else \
+ { \
+ /* Overflow to maximum normal */ \
+ X##_e = _FP_EXPMAX_##fs - 1; \
+ _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \
+ } \
+ FP_SET_EXCEPTION(FP_EX_OVERFLOW); \
+ FP_SET_EXCEPTION(FP_EX_INEXACT); \
+ } \
+ } \
+ else \
+ { \
+ /* we've got a denormalized number */ \
+ X##_e = -X##_e + 1; \
+ if (X##_e <= _FP_WFRACBITS_##fs) \
+ { \
+ _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs); \
+ _FP_ROUND(wc, X); \
+ if (_FP_FRAC_HIGH_##fs(X) \
+ & (_FP_OVERFLOW_##fs >> 1)) \
+ { \
+ X##_e = 1; \
+ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
+ } \
+ else \
+ { \
+ X##_e = 0; \
+ _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
+ FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \
+ } \
+ } \
+ else \
+ { \
+ /* underflow to zero */ \
+ X##_e = 0; \
+ if (!_FP_FRAC_ZEROP_##wc(X)) \
+ { \
+ _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \
+ _FP_ROUND(wc, X); \
+ _FP_FRAC_LOW_##wc(X) >>= (_FP_WORKBITS); \
+ } \
+ FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \
+ } \
+ } \
+ break; \
+ \
+ case FP_CLS_ZERO: \
+ X##_e = 0; \
+ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
+ break; \
+ \
+ case FP_CLS_INF: \
+ X##_e = _FP_EXPMAX_##fs; \
+ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
+ break; \
+ \
+ case FP_CLS_NAN: \
+ X##_e = _FP_EXPMAX_##fs; \
+ if (!_FP_KEEPNANFRACP) \
+ { \
+ _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \
+ X##_s = _FP_NANSIGN_##fs; \
+ } \
+ else \
+ _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs; \
+ break; \
+ } \
+} while (0)
+
+/* This one accepts raw argument and not cooked, returns
+ * 1 if X is a signaling NaN.
+ */
+#define _FP_ISSIGNAN(fs, wc, X) \
+({ \
+ int __ret = 0; \
+ if (X##_e == _FP_EXPMAX_##fs) \
+ { \
+ if (!_FP_FRAC_ZEROP_##wc(X) \
+ && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \
+ __ret = 1; \
+ } \
+ __ret; \
+})
+
+
+
+
+
+/* Addition on semi-raw values. */
+#define _FP_ADD_INTERNAL(fs, wc, R, X, Y, OP) \
+do { \
+ if (X##_s == Y##_s) \
+ { \
+ /* Addition. */ \
+ R##_s = X##_s; \
+ int ediff = X##_e - Y##_e; \
+ if (ediff > 0) \
+ { \
+ R##_e = X##_e; \
+ if (Y##_e == 0) \
+ { \
+ /* Y is zero or denormalized. */ \
+ if (_FP_FRAC_ZEROP_##wc(Y)) \
+ { \
+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
+ _FP_FRAC_COPY_##wc(R, X); \
+ goto add_done; \
+ } \
+ else \
+ { \
+ FP_SET_EXCEPTION(FP_EX_DENORM); \
+ ediff--; \
+ if (ediff == 0) \
+ { \
+ _FP_FRAC_ADD_##wc(R, X, Y); \
+ goto add3; \
+ } \
+ if (X##_e == _FP_EXPMAX_##fs) \
+ { \
+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
+ _FP_FRAC_COPY_##wc(R, X); \
+ goto add_done; \
+ } \
+ goto add1; \
+ } \
+ } \
+ else if (X##_e == _FP_EXPMAX_##fs) \
+ { \
+ /* X is NaN or Inf, Y is normal. */ \
+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
+ _FP_FRAC_COPY_##wc(R, X); \
+ goto add_done; \
+ } \
+ \
+ /* Insert implicit MSB of Y. */ \
+ _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \
+ \
+ add1: \
+ /* Shift the mantissa of Y to the right EDIFF steps; \
+ remember to account later for the implicit MSB of X. */ \
+ if (ediff <= _FP_WFRACBITS_##fs) \
+ _FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs); \
+ else if (!_FP_FRAC_ZEROP_##wc(Y)) \
+ _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \
+ _FP_FRAC_ADD_##wc(R, X, Y); \
+ } \
+ else if (ediff < 0) \
+ { \
+ ediff = -ediff; \
+ R##_e = Y##_e; \
+ if (X##_e == 0) \
+ { \
+ /* X is zero or denormalized. */ \
+ if (_FP_FRAC_ZEROP_##wc(X)) \
+ { \
+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
+ _FP_FRAC_COPY_##wc(R, Y); \
+ goto add_done; \
+ } \
+ else \
+ { \
+ FP_SET_EXCEPTION(FP_EX_DENORM); \
+ ediff--; \
+ if (ediff == 0) \
+ { \
+ _FP_FRAC_ADD_##wc(R, Y, X); \
+ goto add3; \
+ } \
+ if (Y##_e == _FP_EXPMAX_##fs) \
+ { \
+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
+ _FP_FRAC_COPY_##wc(R, Y); \
+ goto add_done; \
+ } \
+ goto add2; \
+ } \
+ } \
+ else if (Y##_e == _FP_EXPMAX_##fs) \
+ { \
+ /* Y is NaN or Inf, X is normal. */ \
+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
+ _FP_FRAC_COPY_##wc(R, Y); \
+ goto add_done; \
+ } \
+ \
+ /* Insert implicit MSB of X. */ \
+ _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \
+ \
+ add2: \
+ /* Shift the mantissa of X to the right EDIFF steps; \
+ remember to account later for the implicit MSB of Y. */ \
+ if (ediff <= _FP_WFRACBITS_##fs) \
+ _FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs); \
+ else if (!_FP_FRAC_ZEROP_##wc(X)) \
+ _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \
+ _FP_FRAC_ADD_##wc(R, Y, X); \
+ } \
+ else \
+ { \
+ /* ediff == 0. */ \
+ if (!_FP_EXP_NORMAL(fs, wc, X)) \
+ { \
+ if (X##_e == 0) \
+ { \
+ /* X and Y are zero or denormalized. */ \
+ R##_e = 0; \
+ if (_FP_FRAC_ZEROP_##wc(X)) \
+ { \
+ if (!_FP_FRAC_ZEROP_##wc(Y)) \
+ FP_SET_EXCEPTION(FP_EX_DENORM); \
+ _FP_FRAC_COPY_##wc(R, Y); \
+ goto add_done; \
+ } \
+ else if (_FP_FRAC_ZEROP_##wc(Y)) \
+ { \
+ FP_SET_EXCEPTION(FP_EX_DENORM); \
+ _FP_FRAC_COPY_##wc(R, X); \
+ goto add_done; \
+ } \
+ else \
+ { \
+ FP_SET_EXCEPTION(FP_EX_DENORM); \
+ _FP_FRAC_ADD_##wc(R, X, Y); \
+ if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
+ { \
+ /* Normalized result. */ \
+ _FP_FRAC_HIGH_##fs(R) \
+ &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \
+ R##_e = 1; \
+ } \
+ goto add_done; \
+ } \
+ } \
+ else \
+ { \
+ /* X and Y are NaN or Inf. */ \
+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
+ R##_e = _FP_EXPMAX_##fs; \
+ if (_FP_FRAC_ZEROP_##wc(X)) \
+ _FP_FRAC_COPY_##wc(R, Y); \
+ else if (_FP_FRAC_ZEROP_##wc(Y)) \
+ _FP_FRAC_COPY_##wc(R, X); \
+ else \
+ _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \
+ goto add_done; \
+ } \
+ } \
+ /* The exponents of X and Y, both normal, are equal. The \
+ implicit MSBs will always add to increase the \
+ exponent. */ \
+ _FP_FRAC_ADD_##wc(R, X, Y); \
+ R##_e = X##_e + 1; \
+ _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \
+ if (R##_e == _FP_EXPMAX_##fs) \
+ /* Overflow to infinity (depending on rounding mode). */ \
+ _FP_OVERFLOW_SEMIRAW(fs, wc, R); \
+ goto add_done; \
+ } \
+ add3: \
+ if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
+ { \
+ /* Overflow. */ \
+ _FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \
+ R##_e++; \
+ _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \
+ if (R##_e == _FP_EXPMAX_##fs) \
+ /* Overflow to infinity (depending on rounding mode). */ \
+ _FP_OVERFLOW_SEMIRAW(fs, wc, R); \
+ } \
+ add_done: ; \
+ } \
+ else \
+ { \
+ /* Subtraction. */ \
+ int ediff = X##_e - Y##_e; \
+ if (ediff > 0) \
+ { \
+ R##_e = X##_e; \
+ R##_s = X##_s; \
+ if (Y##_e == 0) \
+ { \
+ /* Y is zero or denormalized. */ \
+ if (_FP_FRAC_ZEROP_##wc(Y)) \
+ { \
+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
+ _FP_FRAC_COPY_##wc(R, X); \
+ goto sub_done; \
+ } \
+ else \
+ { \
+ FP_SET_EXCEPTION(FP_EX_DENORM); \
+ ediff--; \
+ if (ediff == 0) \
+ { \
+ _FP_FRAC_SUB_##wc(R, X, Y); \
+ goto sub3; \
+ } \
+ if (X##_e == _FP_EXPMAX_##fs) \
+ { \
+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
+ _FP_FRAC_COPY_##wc(R, X); \
+ goto sub_done; \
+ } \
+ goto sub1; \
+ } \
+ } \
+ else if (X##_e == _FP_EXPMAX_##fs) \
+ { \
+ /* X is NaN or Inf, Y is normal. */ \
+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
+ _FP_FRAC_COPY_##wc(R, X); \
+ goto sub_done; \
+ } \
+ \
+ /* Insert implicit MSB of Y. */ \
+ _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \
+ \
+ sub1: \
+ /* Shift the mantissa of Y to the right EDIFF steps; \
+ remember to account later for the implicit MSB of X. */ \
+ if (ediff <= _FP_WFRACBITS_##fs) \
+ _FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs); \
+ else if (!_FP_FRAC_ZEROP_##wc(Y)) \
+ _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \
+ _FP_FRAC_SUB_##wc(R, X, Y); \
+ } \
+ else if (ediff < 0) \
+ { \
+ ediff = -ediff; \
+ R##_e = Y##_e; \
+ R##_s = Y##_s; \
+ if (X##_e == 0) \
+ { \
+ /* X is zero or denormalized. */ \
+ if (_FP_FRAC_ZEROP_##wc(X)) \
+ { \
+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
+ _FP_FRAC_COPY_##wc(R, Y); \
+ goto sub_done; \
+ } \
+ else \
+ { \
+ FP_SET_EXCEPTION(FP_EX_DENORM); \
+ ediff--; \
+ if (ediff == 0) \
+ { \
+ _FP_FRAC_SUB_##wc(R, Y, X); \
+ goto sub3; \
+ } \
+ if (Y##_e == _FP_EXPMAX_##fs) \
+ { \
+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
+ _FP_FRAC_COPY_##wc(R, Y); \
+ goto sub_done; \
+ } \
+ goto sub2; \
+ } \
+ } \
+ else if (Y##_e == _FP_EXPMAX_##fs) \
+ { \
+ /* Y is NaN or Inf, X is normal. */ \
+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
+ _FP_FRAC_COPY_##wc(R, Y); \
+ goto sub_done; \
+ } \
+ \
+ /* Insert implicit MSB of X. */ \
+ _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \
+ \
+ sub2: \
+ /* Shift the mantissa of X to the right EDIFF steps; \
+ remember to account later for the implicit MSB of Y. */ \
+ if (ediff <= _FP_WFRACBITS_##fs) \
+ _FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs); \
+ else if (!_FP_FRAC_ZEROP_##wc(X)) \
+ _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \
+ _FP_FRAC_SUB_##wc(R, Y, X); \
+ } \
+ else \
+ { \
+ /* ediff == 0. */ \
+ if (!_FP_EXP_NORMAL(fs, wc, X)) \
+ { \
+ if (X##_e == 0) \
+ { \
+ /* X and Y are zero or denormalized. */ \
+ R##_e = 0; \
+ if (_FP_FRAC_ZEROP_##wc(X)) \
+ { \
+ _FP_FRAC_COPY_##wc(R, Y); \
+ if (_FP_FRAC_ZEROP_##wc(Y)) \
+ R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
+ else \
+ { \
+ FP_SET_EXCEPTION(FP_EX_DENORM); \
+ R##_s = Y##_s; \
+ } \
+ goto sub_done; \
+ } \
+ else if (_FP_FRAC_ZEROP_##wc(Y)) \
+ { \
+ FP_SET_EXCEPTION(FP_EX_DENORM); \
+ _FP_FRAC_COPY_##wc(R, X); \
+ R##_s = X##_s; \
+ goto sub_done; \
+ } \
+ else \
+ { \
+ FP_SET_EXCEPTION(FP_EX_DENORM); \
+ _FP_FRAC_SUB_##wc(R, X, Y); \
+ R##_s = X##_s; \
+ if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
+ { \
+ /* |X| < |Y|, negate result. */ \
+ _FP_FRAC_SUB_##wc(R, Y, X); \
+ R##_s = Y##_s; \
+ } \
+ else if (_FP_FRAC_ZEROP_##wc(R)) \
+ R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
+ goto sub_done; \
+ } \
+ } \
+ else \
+ { \
+ /* X and Y are NaN or Inf, of opposite signs. */ \
+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
+ R##_e = _FP_EXPMAX_##fs; \
+ if (_FP_FRAC_ZEROP_##wc(X)) \
+ { \
+ if (_FP_FRAC_ZEROP_##wc(Y)) \
+ { \
+ /* Inf - Inf. */ \
+ R##_s = _FP_NANSIGN_##fs; \
+ _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
+ _FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \
+ FP_SET_EXCEPTION(FP_EX_INVALID); \
+ } \
+ else \
+ { \
+ /* Inf - NaN. */ \
+ R##_s = Y##_s; \
+ _FP_FRAC_COPY_##wc(R, Y); \
+ } \
+ } \
+ else \
+ { \
+ if (_FP_FRAC_ZEROP_##wc(Y)) \
+ { \
+ /* NaN - Inf. */ \
+ R##_s = X##_s; \
+ _FP_FRAC_COPY_##wc(R, X); \
+ } \
+ else \
+ { \
+ /* NaN - NaN. */ \
+ _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \
+ } \
+ } \
+ goto sub_done; \
+ } \
+ } \
+ /* The exponents of X and Y, both normal, are equal. The \
+ implicit MSBs cancel. */ \
+ R##_e = X##_e; \
+ _FP_FRAC_SUB_##wc(R, X, Y); \
+ R##_s = X##_s; \
+ if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
+ { \
+ /* |X| < |Y|, negate result. */ \
+ _FP_FRAC_SUB_##wc(R, Y, X); \
+ R##_s = Y##_s; \
+ } \
+ else if (_FP_FRAC_ZEROP_##wc(R)) \
+ { \
+ R##_e = 0; \
+ R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
+ goto sub_done; \
+ } \
+ goto norm; \
+ } \
+ sub3: \
+ if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
+ { \
+ int diff; \
+ /* Carry into most significant bit of larger one of X and Y, \
+ canceling it; renormalize. */ \
+ _FP_FRAC_HIGH_##fs(R) &= _FP_IMPLBIT_SH_##fs - 1; \
+ norm: \
+ _FP_FRAC_CLZ_##wc(diff, R); \
+ diff -= _FP_WFRACXBITS_##fs; \
+ _FP_FRAC_SLL_##wc(R, diff); \
+ if (R##_e <= diff) \
+ { \
+ /* R is denormalized. */ \
+ diff = diff - R##_e + 1; \
+ _FP_FRAC_SRS_##wc(R, diff, _FP_WFRACBITS_##fs); \
+ R##_e = 0; \
+ } \
+ else \
+ { \
+ R##_e -= diff; \
+ _FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \
+ } \
+ } \
+ sub_done: ; \
+ } \
+} while (0)
+
+#define _FP_ADD(fs, wc, R, X, Y) _FP_ADD_INTERNAL(fs, wc, R, X, Y, '+')
+#define _FP_SUB(fs, wc, R, X, Y) \
+ do { \
+ if (!(Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) Y##_s ^= 1; \
+ _FP_ADD_INTERNAL(fs, wc, R, X, Y, '-'); \
+ } while (0)
+
+
+/*
+ * Main negation routine. FIXME -- when we care about setting exception
+ * bits reliably, this will not do. We should examine all of the fp classes.
+ */
+
+#define _FP_NEG(fs, wc, R, X) \
+ do { \
+ _FP_FRAC_COPY_##wc(R, X); \
+ R##_c = X##_c; \
+ R##_e = X##_e; \
+ R##_s = 1 ^ X##_s; \
+ } while (0)
+
+
+/*
+ * Main multiplication routine. The input values should be cooked.
+ */
+
+#define _FP_MUL(fs, wc, R, X, Y) \
+do { \
+ R##_s = X##_s ^ Y##_s; \
+ switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
+ { \
+ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
+ R##_c = FP_CLS_NORMAL; \
+ R##_e = X##_e + Y##_e + 1; \
+ \
+ _FP_MUL_MEAT_##fs(R,X,Y); \
+ \
+ if (_FP_FRAC_OVERP_##wc(fs, R)) \
+ _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \
+ else \
+ R##_e--; \
+ break; \
+ \
+ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
+ _FP_CHOOSENAN(fs, wc, R, X, Y, '*'); \
+ break; \
+ \
+ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \
+ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \
+ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \
+ R##_s = X##_s; \
+ \
+ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \
+ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \
+ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \
+ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \
+ _FP_FRAC_COPY_##wc(R, X); \
+ R##_c = X##_c; \
+ break; \
+ \
+ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \
+ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \
+ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \
+ R##_s = Y##_s; \
+ \
+ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \
+ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \
+ _FP_FRAC_COPY_##wc(R, Y); \
+ R##_c = Y##_c; \
+ break; \
+ \
+ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \
+ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \
+ R##_s = _FP_NANSIGN_##fs; \
+ R##_c = FP_CLS_NAN; \
+ _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
+ FP_SET_EXCEPTION(FP_EX_INVALID); \
+ break; \
+ \
+ default: \
+ abort(); \
+ } \
+} while (0)
+
+
+/*
+ * Main division routine. The input values should be cooked.
+ */
+
+#define _FP_DIV(fs, wc, R, X, Y) \
+do { \
+ R##_s = X##_s ^ Y##_s; \
+ switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
+ { \
+ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
+ R##_c = FP_CLS_NORMAL; \
+ R##_e = X##_e - Y##_e; \
+ \
+ _FP_DIV_MEAT_##fs(R,X,Y); \
+ break; \
+ \
+ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
+ _FP_CHOOSENAN(fs, wc, R, X, Y, '/'); \
+ break; \
+ \
+ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \
+ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \
+ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \
+ R##_s = X##_s; \
+ _FP_FRAC_COPY_##wc(R, X); \
+ R##_c = X##_c; \
+ break; \
+ \
+ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \
+ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \
+ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \
+ R##_s = Y##_s; \
+ _FP_FRAC_COPY_##wc(R, Y); \
+ R##_c = Y##_c; \
+ break; \
+ \
+ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \
+ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \
+ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \
+ R##_c = FP_CLS_ZERO; \
+ break; \
+ \
+ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \
+ FP_SET_EXCEPTION(FP_EX_DIVZERO); \
+ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \
+ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \
+ R##_c = FP_CLS_INF; \
+ break; \
+ \
+ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \
+ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \
+ R##_s = _FP_NANSIGN_##fs; \
+ R##_c = FP_CLS_NAN; \
+ _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
+ FP_SET_EXCEPTION(FP_EX_INVALID); \
+ break; \
+ \
+ default: \
+ abort(); \
+ } \
+} while (0)
+
+
+/*
+ * Main differential comparison routine. The inputs should be raw not
+ * cooked. The return is -1,0,1 for normal values, 2 otherwise.
+ */
+
+#define _FP_CMP(fs, wc, ret, X, Y, un) \
+ do { \
+ /* NANs are unordered */ \
+ if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
+ || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \
+ { \
+ ret = un; \
+ } \
+ else \
+ { \
+ int __is_zero_x; \
+ int __is_zero_y; \
+ \
+ __is_zero_x = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0; \
+ __is_zero_y = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0; \
+ \
+ if (__is_zero_x && __is_zero_y) \
+ ret = 0; \
+ else if (__is_zero_x) \
+ ret = Y##_s ? 1 : -1; \
+ else if (__is_zero_y) \
+ ret = X##_s ? -1 : 1; \
+ else if (X##_s != Y##_s) \
+ ret = X##_s ? -1 : 1; \
+ else if (X##_e > Y##_e) \
+ ret = X##_s ? -1 : 1; \
+ else if (X##_e < Y##_e) \
+ ret = X##_s ? 1 : -1; \
+ else if (_FP_FRAC_GT_##wc(X, Y)) \
+ ret = X##_s ? -1 : 1; \
+ else if (_FP_FRAC_GT_##wc(Y, X)) \
+ ret = X##_s ? 1 : -1; \
+ else \
+ ret = 0; \
+ } \
+ } while (0)
+
+
+/* Simplification for strict equality. */
+
+#define _FP_CMP_EQ(fs, wc, ret, X, Y) \
+ do { \
+ /* NANs are unordered */ \
+ if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
+ || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \
+ { \
+ ret = 1; \
+ } \
+ else \
+ { \
+ ret = !(X##_e == Y##_e \
+ && _FP_FRAC_EQ_##wc(X, Y) \
+ && (X##_s == Y##_s || (!X##_e && _FP_FRAC_ZEROP_##wc(X)))); \
+ } \
+ } while (0)
+
+/* Version to test unordered. */
+
+#define _FP_CMP_UNORD(fs, wc, ret, X, Y) \
+ do { \
+ ret = ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
+ || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))); \
+ } while (0)
+
+/*
+ * Main square root routine. The input value should be cooked.
+ */
+
+#define _FP_SQRT(fs, wc, R, X) \
+do { \
+ _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S); \
+ _FP_W_TYPE q; \
+ switch (X##_c) \
+ { \
+ case FP_CLS_NAN: \
+ _FP_FRAC_COPY_##wc(R, X); \
+ R##_s = X##_s; \
+ R##_c = FP_CLS_NAN; \
+ break; \
+ case FP_CLS_INF: \
+ if (X##_s) \
+ { \
+ R##_s = _FP_NANSIGN_##fs; \
+ R##_c = FP_CLS_NAN; /* NAN */ \
+ _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
+ FP_SET_EXCEPTION(FP_EX_INVALID); \
+ } \
+ else \
+ { \
+ R##_s = 0; \
+ R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */ \
+ } \
+ break; \
+ case FP_CLS_ZERO: \
+ R##_s = X##_s; \
+ R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */ \
+ break; \
+ case FP_CLS_NORMAL: \
+ R##_s = 0; \
+ if (X##_s) \
+ { \
+ R##_c = FP_CLS_NAN; /* sNAN */ \
+ R##_s = _FP_NANSIGN_##fs; \
+ _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
+ FP_SET_EXCEPTION(FP_EX_INVALID); \
+ break; \
+ } \
+ R##_c = FP_CLS_NORMAL; \
+ if (X##_e & 1) \
+ _FP_FRAC_SLL_##wc(X, 1); \
+ R##_e = X##_e >> 1; \
+ _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc); \
+ _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc); \
+ q = _FP_OVERFLOW_##fs >> 1; \
+ _FP_SQRT_MEAT_##wc(R, S, T, X, q); \
+ } \
+ } while (0)
+
+/*
+ * Convert from FP to integer. Input is raw.
+ */
+
+/* RSIGNED can have following values:
+ * 0: the number is required to be 0..(2^rsize)-1, if not, NV is set plus
+ * the result is either 0 or (2^rsize)-1 depending on the sign in such
+ * case.
+ * 1: the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not,
+ * NV is set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1
+ * depending on the sign in such case.
+ * -1: the number is required to be -(2^(rsize-1))..(2^rsize)-1, if not, NV is
+ * set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1
+ * depending on the sign in such case.
+ */
+#define _FP_TO_INT(fs, wc, r, X, rsize, rsigned) \
+do { \
+ if (X##_e < _FP_EXPBIAS_##fs) \
+ { \
+ r = 0; \
+ if (X##_e == 0) \
+ { \
+ if (!_FP_FRAC_ZEROP_##wc(X)) \
+ { \
+ FP_SET_EXCEPTION(FP_EX_INEXACT); \
+ FP_SET_EXCEPTION(FP_EX_DENORM); \
+ } \
+ } \
+ else \
+ FP_SET_EXCEPTION(FP_EX_INEXACT); \
+ } \
+ else if (X##_e >= _FP_EXPBIAS_##fs + rsize - (rsigned > 0 || X##_s) \
+ || (!rsigned && X##_s)) \
+ { \
+ /* Overflow or converting to the most negative integer. */ \
+ if (rsigned) \
+ { \
+ r = 1; \
+ r <<= rsize - 1; \
+ r -= 1 - X##_s; \
+ } else { \
+ r = 0; \
+ if (X##_s) \
+ r = ~r; \
+ } \
+ \
+ if (rsigned && X##_s && X##_e == _FP_EXPBIAS_##fs + rsize - 1) \
+ { \
+ /* Possibly converting to most negative integer; check the \
+ mantissa. */ \
+ int inexact = 0; \
+ (void)((_FP_FRACBITS_##fs > rsize) \
+ ? ({ _FP_FRAC_SRST_##wc(X, inexact, \
+ _FP_FRACBITS_##fs - rsize, \
+ _FP_FRACBITS_##fs); 0; }) \
+ : 0); \
+ if (!_FP_FRAC_ZEROP_##wc(X)) \
+ FP_SET_EXCEPTION(FP_EX_INVALID); \
+ else if (inexact) \
+ FP_SET_EXCEPTION(FP_EX_INEXACT); \
+ } \
+ else \
+ FP_SET_EXCEPTION(FP_EX_INVALID); \
+ } \
+ else \
+ { \
+ _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \
+ if (X##_e >= _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1) \
+ { \
+ _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
+ r <<= X##_e - _FP_EXPBIAS_##fs - _FP_FRACBITS_##fs + 1; \
+ } \
+ else \
+ { \
+ int inexact; \
+ _FP_FRAC_SRST_##wc(X, inexact, \
+ (_FP_FRACBITS_##fs + _FP_EXPBIAS_##fs - 1 \
+ - X##_e), \
+ _FP_FRACBITS_##fs); \
+ if (inexact) \
+ FP_SET_EXCEPTION(FP_EX_INEXACT); \
+ _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
+ } \
+ if (rsigned && X##_s) \
+ r = -r; \
+ } \
+} while (0)
+
+/* Convert integer to fp. Output is raw. RTYPE is unsigned even if
+ input is signed. */
+#define _FP_FROM_INT(fs, wc, X, r, rsize, rtype) \
+ do { \
+ if (r) \
+ { \
+ rtype ur_; \
+ \
+ if ((X##_s = (r < 0))) \
+ r = -(rtype)r; \
+ \
+ ur_ = (rtype) r; \
+ (void)((rsize <= _FP_W_TYPE_SIZE) \
+ ? ({ \
+ int lz_; \
+ __FP_CLZ(lz_, (_FP_W_TYPE)ur_); \
+ X##_e = _FP_EXPBIAS_##fs + _FP_W_TYPE_SIZE - 1 - lz_; \
+ }) \
+ : ((rsize <= 2 * _FP_W_TYPE_SIZE) \
+ ? ({ \
+ int lz_; \
+ __FP_CLZ_2(lz_, (_FP_W_TYPE)(ur_ >> _FP_W_TYPE_SIZE), \
+ (_FP_W_TYPE)ur_); \
+ X##_e = (_FP_EXPBIAS_##fs + 2 * _FP_W_TYPE_SIZE - 1 \
+ - lz_); \
+ }) \
+ : (abort(), 0))); \
+ \
+ if (rsize - 1 + _FP_EXPBIAS_##fs >= _FP_EXPMAX_##fs \
+ && X##_e >= _FP_EXPMAX_##fs) \
+ { \
+ /* Exponent too big; overflow to infinity. (May also \
+ happen after rounding below.) */ \
+ _FP_OVERFLOW_SEMIRAW(fs, wc, X); \
+ goto pack_semiraw; \
+ } \
+ \
+ if (rsize <= _FP_FRACBITS_##fs \
+ || X##_e < _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs) \
+ { \
+ /* Exactly representable; shift left. */ \
+ _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \
+ _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs \
+ + _FP_FRACBITS_##fs - 1 - X##_e)); \
+ } \
+ else \
+ { \
+ /* More bits in integer than in floating type; need to \
+ round. */ \
+ if (_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 < X##_e) \
+ ur_ = ((ur_ >> (X##_e - _FP_EXPBIAS_##fs \
+ - _FP_WFRACBITS_##fs + 1)) \
+ | ((ur_ << (rsize - (X##_e - _FP_EXPBIAS_##fs \
+ - _FP_WFRACBITS_##fs + 1))) \
+ != 0)); \
+ _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \
+ if ((_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 - X##_e) > 0) \
+ _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs \
+ + _FP_WFRACBITS_##fs - 1 - X##_e)); \
+ _FP_FRAC_HIGH_##fs(X) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \
+ pack_semiraw: \
+ _FP_PACK_SEMIRAW(fs, wc, X); \
+ } \
+ } \
+ else \
+ { \
+ X##_s = 0; \
+ X##_e = 0; \
+ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
+ } \
+ } while (0)
+
+
+/* Extend from a narrower floating-point format to a wider one. Input
+ and output are raw. */
+#define FP_EXTEND(dfs,sfs,dwc,swc,D,S) \
+do { \
+ if (_FP_FRACBITS_##dfs < _FP_FRACBITS_##sfs \
+ || (_FP_EXPMAX_##dfs - _FP_EXPBIAS_##dfs \
+ < _FP_EXPMAX_##sfs - _FP_EXPBIAS_##sfs) \
+ || _FP_EXPBIAS_##dfs < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1) \
+ abort(); \
+ D##_s = S##_s; \
+ _FP_FRAC_COPY_##dwc##_##swc(D, S); \
+ if (_FP_EXP_NORMAL(sfs, swc, S)) \
+ { \
+ D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \
+ _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs - _FP_FRACBITS_##sfs)); \
+ } \
+ else \
+ { \
+ if (S##_e == 0) \
+ { \
+ if (_FP_FRAC_ZEROP_##swc(S)) \
+ D##_e = 0; \
+ else \
+ { \
+ int _lz; \
+ FP_SET_EXCEPTION(FP_EX_DENORM); \
+ _FP_FRAC_CLZ_##swc(_lz, S); \
+ _FP_FRAC_SLL_##dwc(D, \
+ _lz + _FP_FRACBITS_##dfs \
+ - _FP_FRACTBITS_##sfs); \
+ D##_e = (_FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs + 1 \
+ + _FP_FRACXBITS_##sfs - _lz); \
+ } \
+ } \
+ else \
+ { \
+ D##_e = _FP_EXPMAX_##dfs; \
+ if (!_FP_FRAC_ZEROP_##swc(S)) \
+ { \
+ if (!(_FP_FRAC_HIGH_RAW_##sfs(S) & _FP_QNANBIT_##sfs)) \
+ FP_SET_EXCEPTION(FP_EX_INVALID); \
+ _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \
+ - _FP_FRACBITS_##sfs)); \
+ } \
+ } \
+ } \
+} while (0)
+
+/* Truncate from a wider floating-point format to a narrower one.
+ Input and output are semi-raw. */
+#define FP_TRUNC(dfs,sfs,dwc,swc,D,S) \
+do { \
+ if (_FP_FRACBITS_##sfs < _FP_FRACBITS_##dfs \
+ || _FP_EXPBIAS_##sfs < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1) \
+ abort(); \
+ D##_s = S##_s; \
+ if (_FP_EXP_NORMAL(sfs, swc, S)) \
+ { \
+ D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \
+ if (D##_e >= _FP_EXPMAX_##dfs) \
+ _FP_OVERFLOW_SEMIRAW(dfs, dwc, D); \
+ else \
+ { \
+ if (D##_e <= 0) \
+ { \
+ if (D##_e <= 1 - _FP_FRACBITS_##dfs) \
+ _FP_FRAC_SET_##swc(S, _FP_ZEROFRAC_##swc); \
+ else \
+ { \
+ _FP_FRAC_HIGH_##sfs(S) |= _FP_IMPLBIT_SH_##sfs; \
+ _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \
+ - _FP_WFRACBITS_##dfs + 1 - D##_e), \
+ _FP_WFRACBITS_##sfs); \
+ } \
+ D##_e = 0; \
+ } \
+ else \
+ _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \
+ - _FP_WFRACBITS_##dfs), \
+ _FP_WFRACBITS_##sfs); \
+ _FP_FRAC_COPY_##dwc##_##swc(D, S); \
+ } \
+ } \
+ else \
+ { \
+ if (S##_e == 0) \
+ { \
+ D##_e = 0; \
+ _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \
+ if (!_FP_FRAC_ZEROP_##swc(S)) \
+ { \
+ FP_SET_EXCEPTION(FP_EX_DENORM); \
+ FP_SET_EXCEPTION(FP_EX_INEXACT); \
+ } \
+ } \
+ else \
+ { \
+ D##_e = _FP_EXPMAX_##dfs; \
+ if (_FP_FRAC_ZEROP_##swc(S)) \
+ _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \
+ else \
+ { \
+ _FP_CHECK_SIGNAN_SEMIRAW(sfs, swc, S); \
+ _FP_FRAC_SRL_##swc(S, (_FP_WFRACBITS_##sfs \
+ - _FP_WFRACBITS_##dfs)); \
+ _FP_FRAC_COPY_##dwc##_##swc(D, S); \
+ _FP_FRAC_HIGH_##dfs(D) |= _FP_QNANBIT_SH_##dfs; \
+ } \
+ } \
+ } \
+} while (0)
+
+/*
+ * Helper primitives.
+ */
+
+/* Count leading zeros in a word. */
+
+#ifndef __FP_CLZ
+/* GCC 3.4 and later provide the builtins for us. */
+#define __FP_CLZ(r, x) \
+ do { \
+ if (sizeof (_FP_W_TYPE) == sizeof (unsigned int)) \
+ r = __builtin_clz (x); \
+ else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long)) \
+ r = __builtin_clzl (x); \
+ else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long long)) \
+ r = __builtin_clzll (x); \
+ else \
+ abort (); \
+ } while (0)
+#endif /* ndef __FP_CLZ */
+
+#define _FP_DIV_HELP_imm(q, r, n, d) \
+ do { \
+ q = n / d, r = n % d; \
+ } while (0)
+
+
+/* A restoring bit-by-bit division primitive. */
+
+#define _FP_DIV_MEAT_N_loop(fs, wc, R, X, Y) \
+ do { \
+ int count = _FP_WFRACBITS_##fs; \
+ _FP_FRAC_DECL_##wc (u); \
+ _FP_FRAC_DECL_##wc (v); \
+ _FP_FRAC_COPY_##wc (u, X); \
+ _FP_FRAC_COPY_##wc (v, Y); \
+ _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc); \
+ /* Normalize U and V. */ \
+ _FP_FRAC_SLL_##wc (u, _FP_WFRACXBITS_##fs); \
+ _FP_FRAC_SLL_##wc (v, _FP_WFRACXBITS_##fs); \
+ /* First round. Since the operands are normalized, either the \
+ first or second bit will be set in the fraction. Produce a \
+ normalized result by checking which and adjusting the loop \
+ count and exponent accordingly. */ \
+ if (_FP_FRAC_GE_1 (u, v)) \
+ { \
+ _FP_FRAC_SUB_##wc (u, u, v); \
+ _FP_FRAC_LOW_##wc (R) |= 1; \
+ count--; \
+ } \
+ else \
+ R##_e--; \
+ /* Subsequent rounds. */ \
+ do { \
+ int msb = (_FP_WS_TYPE) _FP_FRAC_HIGH_##wc (u) < 0; \
+ _FP_FRAC_SLL_##wc (u, 1); \
+ _FP_FRAC_SLL_##wc (R, 1); \
+ if (msb || _FP_FRAC_GE_1 (u, v)) \
+ { \
+ _FP_FRAC_SUB_##wc (u, u, v); \
+ _FP_FRAC_LOW_##wc (R) |= 1; \
+ } \
+ } while (--count > 0); \
+ /* If there's anything left in U, the result is inexact. */ \
+ _FP_FRAC_LOW_##wc (R) |= !_FP_FRAC_ZEROP_##wc (u); \
+ } while (0)
+
+#define _FP_DIV_MEAT_1_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 1, R, X, Y)
+#define _FP_DIV_MEAT_2_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 2, R, X, Y)
+#define _FP_DIV_MEAT_4_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 4, R, X, Y)
diff --git a/gcc/config/soft-fp/quad.h b/gcc/config/soft-fp/quad.h
new file mode 100644
index 00000000000..d7840ff0662
--- /dev/null
+++ b/gcc/config/soft-fp/quad.h
@@ -0,0 +1,271 @@
+/* Software floating-point emulation.
+ Definitions for IEEE Quad Precision.
+ Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com),
+ Jakub Jelinek (jj@ultra.linux.cz),
+ David S. Miller (davem@redhat.com) and
+ Peter Maydell (pmaydell@chiark.greenend.org.uk).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#if _FP_W_TYPE_SIZE < 32
+#error "Here's a nickel, kid. Go buy yourself a real computer."
+#endif
+
+#if _FP_W_TYPE_SIZE < 64
+#define _FP_FRACTBITS_Q (4*_FP_W_TYPE_SIZE)
+#else
+#define _FP_FRACTBITS_Q (2*_FP_W_TYPE_SIZE)
+#endif
+
+#define _FP_FRACBITS_Q 113
+#define _FP_FRACXBITS_Q (_FP_FRACTBITS_Q - _FP_FRACBITS_Q)
+#define _FP_WFRACBITS_Q (_FP_WORKBITS + _FP_FRACBITS_Q)
+#define _FP_WFRACXBITS_Q (_FP_FRACTBITS_Q - _FP_WFRACBITS_Q)
+#define _FP_EXPBITS_Q 15
+#define _FP_EXPBIAS_Q 16383
+#define _FP_EXPMAX_Q 32767
+
+#define _FP_QNANBIT_Q \
+ ((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-2) % _FP_W_TYPE_SIZE)
+#define _FP_QNANBIT_SH_Q \
+ ((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE)
+#define _FP_IMPLBIT_Q \
+ ((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-1) % _FP_W_TYPE_SIZE)
+#define _FP_IMPLBIT_SH_Q \
+ ((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE)
+#define _FP_OVERFLOW_Q \
+ ((_FP_W_TYPE)1 << (_FP_WFRACBITS_Q % _FP_W_TYPE_SIZE))
+
+typedef float TFtype __attribute__((mode(TF)));
+
+#if _FP_W_TYPE_SIZE < 64
+
+union _FP_UNION_Q
+{
+ TFtype flt;
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned sign : 1;
+ unsigned exp : _FP_EXPBITS_Q;
+ unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3);
+ unsigned long frac2 : _FP_W_TYPE_SIZE;
+ unsigned long frac1 : _FP_W_TYPE_SIZE;
+ unsigned long frac0 : _FP_W_TYPE_SIZE;
+#else
+ unsigned long frac0 : _FP_W_TYPE_SIZE;
+ unsigned long frac1 : _FP_W_TYPE_SIZE;
+ unsigned long frac2 : _FP_W_TYPE_SIZE;
+ unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3);
+ unsigned exp : _FP_EXPBITS_Q;
+ unsigned sign : 1;
+#endif /* not bigendian */
+ } bits __attribute__((packed));
+};
+
+
+#define FP_DECL_Q(X) _FP_DECL(4,X)
+#define FP_UNPACK_RAW_Q(X,val) _FP_UNPACK_RAW_4(Q,X,val)
+#define FP_UNPACK_RAW_QP(X,val) _FP_UNPACK_RAW_4_P(Q,X,val)
+#define FP_PACK_RAW_Q(val,X) _FP_PACK_RAW_4(Q,val,X)
+#define FP_PACK_RAW_QP(val,X) \
+ do { \
+ if (!FP_INHIBIT_RESULTS) \
+ _FP_PACK_RAW_4_P(Q,val,X); \
+ } while (0)
+
+#define FP_UNPACK_Q(X,val) \
+ do { \
+ _FP_UNPACK_RAW_4(Q,X,val); \
+ _FP_UNPACK_CANONICAL(Q,4,X); \
+ } while (0)
+
+#define FP_UNPACK_QP(X,val) \
+ do { \
+ _FP_UNPACK_RAW_4_P(Q,X,val); \
+ _FP_UNPACK_CANONICAL(Q,4,X); \
+ } while (0)
+
+#define FP_UNPACK_SEMIRAW_Q(X,val) \
+ do { \
+ _FP_UNPACK_RAW_4(Q,X,val); \
+ _FP_UNPACK_SEMIRAW(Q,4,X); \
+ } while (0)
+
+#define FP_UNPACK_SEMIRAW_QP(X,val) \
+ do { \
+ _FP_UNPACK_RAW_4_P(Q,X,val); \
+ _FP_UNPACK_SEMIRAW(Q,4,X); \
+ } while (0)
+
+#define FP_PACK_Q(val,X) \
+ do { \
+ _FP_PACK_CANONICAL(Q,4,X); \
+ _FP_PACK_RAW_4(Q,val,X); \
+ } while (0)
+
+#define FP_PACK_QP(val,X) \
+ do { \
+ _FP_PACK_CANONICAL(Q,4,X); \
+ if (!FP_INHIBIT_RESULTS) \
+ _FP_PACK_RAW_4_P(Q,val,X); \
+ } while (0)
+
+#define FP_PACK_SEMIRAW_Q(val,X) \
+ do { \
+ _FP_PACK_SEMIRAW(Q,4,X); \
+ _FP_PACK_RAW_4(Q,val,X); \
+ } while (0)
+
+#define FP_PACK_SEMIRAW_QP(val,X) \
+ do { \
+ _FP_PACK_SEMIRAW(Q,4,X); \
+ if (!FP_INHIBIT_RESULTS) \
+ _FP_PACK_RAW_4_P(Q,val,X); \
+ } while (0)
+
+#define FP_ISSIGNAN_Q(X) _FP_ISSIGNAN(Q,4,X)
+#define FP_NEG_Q(R,X) _FP_NEG(Q,4,R,X)
+#define FP_ADD_Q(R,X,Y) _FP_ADD(Q,4,R,X,Y)
+#define FP_SUB_Q(R,X,Y) _FP_SUB(Q,4,R,X,Y)
+#define FP_MUL_Q(R,X,Y) _FP_MUL(Q,4,R,X,Y)
+#define FP_DIV_Q(R,X,Y) _FP_DIV(Q,4,R,X,Y)
+#define FP_SQRT_Q(R,X) _FP_SQRT(Q,4,R,X)
+#define _FP_SQRT_MEAT_Q(R,S,T,X,Q) _FP_SQRT_MEAT_4(R,S,T,X,Q)
+
+#define FP_CMP_Q(r,X,Y,un) _FP_CMP(Q,4,r,X,Y,un)
+#define FP_CMP_EQ_Q(r,X,Y) _FP_CMP_EQ(Q,4,r,X,Y)
+#define FP_CMP_UNORD_Q(r,X,Y) _FP_CMP_UNORD(Q,4,r,X,Y)
+
+#define FP_TO_INT_Q(r,X,rsz,rsg) _FP_TO_INT(Q,4,r,X,rsz,rsg)
+#define FP_FROM_INT_Q(X,r,rs,rt) _FP_FROM_INT(Q,4,X,r,rs,rt)
+
+#define _FP_FRAC_HIGH_Q(X) _FP_FRAC_HIGH_4(X)
+#define _FP_FRAC_HIGH_RAW_Q(X) _FP_FRAC_HIGH_4(X)
+
+#else /* not _FP_W_TYPE_SIZE < 64 */
+union _FP_UNION_Q
+{
+ TFtype flt /* __attribute__((mode(TF))) */ ;
+ struct {
+ _FP_W_TYPE a, b;
+ } longs;
+ struct {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned sign : 1;
+ unsigned exp : _FP_EXPBITS_Q;
+ unsigned long frac1 : _FP_FRACBITS_Q-(_FP_IMPLBIT_Q != 0)-_FP_W_TYPE_SIZE;
+ unsigned long frac0 : _FP_W_TYPE_SIZE;
+#else
+ unsigned long frac0 : _FP_W_TYPE_SIZE;
+ unsigned long frac1 : _FP_FRACBITS_Q-(_FP_IMPLBIT_Q != 0)-_FP_W_TYPE_SIZE;
+ unsigned exp : _FP_EXPBITS_Q;
+ unsigned sign : 1;
+#endif
+ } bits;
+};
+
+#define FP_DECL_Q(X) _FP_DECL(2,X)
+#define FP_UNPACK_RAW_Q(X,val) _FP_UNPACK_RAW_2(Q,X,val)
+#define FP_UNPACK_RAW_QP(X,val) _FP_UNPACK_RAW_2_P(Q,X,val)
+#define FP_PACK_RAW_Q(val,X) _FP_PACK_RAW_2(Q,val,X)
+#define FP_PACK_RAW_QP(val,X) \
+ do { \
+ if (!FP_INHIBIT_RESULTS) \
+ _FP_PACK_RAW_2_P(Q,val,X); \
+ } while (0)
+
+#define FP_UNPACK_Q(X,val) \
+ do { \
+ _FP_UNPACK_RAW_2(Q,X,val); \
+ _FP_UNPACK_CANONICAL(Q,2,X); \
+ } while (0)
+
+#define FP_UNPACK_QP(X,val) \
+ do { \
+ _FP_UNPACK_RAW_2_P(Q,X,val); \
+ _FP_UNPACK_CANONICAL(Q,2,X); \
+ } while (0)
+
+#define FP_UNPACK_SEMIRAW_Q(X,val) \
+ do { \
+ _FP_UNPACK_RAW_2(Q,X,val); \
+ _FP_UNPACK_SEMIRAW(Q,2,X); \
+ } while (0)
+
+#define FP_UNPACK_SEMIRAW_QP(X,val) \
+ do { \
+ _FP_UNPACK_RAW_2_P(Q,X,val); \
+ _FP_UNPACK_SEMIRAW(Q,2,X); \
+ } while (0)
+
+#define FP_PACK_Q(val,X) \
+ do { \
+ _FP_PACK_CANONICAL(Q,2,X); \
+ _FP_PACK_RAW_2(Q,val,X); \
+ } while (0)
+
+#define FP_PACK_QP(val,X) \
+ do { \
+ _FP_PACK_CANONICAL(Q,2,X); \
+ if (!FP_INHIBIT_RESULTS) \
+ _FP_PACK_RAW_2_P(Q,val,X); \
+ } while (0)
+
+#define FP_PACK_SEMIRAW_Q(val,X) \
+ do { \
+ _FP_PACK_SEMIRAW(Q,2,X); \
+ _FP_PACK_RAW_2(Q,val,X); \
+ } while (0)
+
+#define FP_PACK_SEMIRAW_QP(val,X) \
+ do { \
+ _FP_PACK_SEMIRAW(Q,2,X); \
+ if (!FP_INHIBIT_RESULTS) \
+ _FP_PACK_RAW_2_P(Q,val,X); \
+ } while (0)
+
+#define FP_ISSIGNAN_Q(X) _FP_ISSIGNAN(Q,2,X)
+#define FP_NEG_Q(R,X) _FP_NEG(Q,2,R,X)
+#define FP_ADD_Q(R,X,Y) _FP_ADD(Q,2,R,X,Y)
+#define FP_SUB_Q(R,X,Y) _FP_SUB(Q,2,R,X,Y)
+#define FP_MUL_Q(R,X,Y) _FP_MUL(Q,2,R,X,Y)
+#define FP_DIV_Q(R,X,Y) _FP_DIV(Q,2,R,X,Y)
+#define FP_SQRT_Q(R,X) _FP_SQRT(Q,2,R,X)
+#define _FP_SQRT_MEAT_Q(R,S,T,X,Q) _FP_SQRT_MEAT_2(R,S,T,X,Q)
+
+#define FP_CMP_Q(r,X,Y,un) _FP_CMP(Q,2,r,X,Y,un)
+#define FP_CMP_EQ_Q(r,X,Y) _FP_CMP_EQ(Q,2,r,X,Y)
+#define FP_CMP_UNORD_Q(r,X,Y) _FP_CMP_UNORD(Q,2,r,X,Y)
+
+#define FP_TO_INT_Q(r,X,rsz,rsg) _FP_TO_INT(Q,2,r,X,rsz,rsg)
+#define FP_FROM_INT_Q(X,r,rs,rt) _FP_FROM_INT(Q,2,X,r,rs,rt)
+
+#define _FP_FRAC_HIGH_Q(X) _FP_FRAC_HIGH_2(X)
+#define _FP_FRAC_HIGH_RAW_Q(X) _FP_FRAC_HIGH_2(X)
+
+#endif /* not _FP_W_TYPE_SIZE < 64 */
diff --git a/gcc/config/soft-fp/single.h b/gcc/config/soft-fp/single.h
new file mode 100644
index 00000000000..9c3734adf48
--- /dev/null
+++ b/gcc/config/soft-fp/single.h
@@ -0,0 +1,151 @@
+/* Software floating-point emulation.
+ Definitions for IEEE Single Precision.
+ Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com),
+ Jakub Jelinek (jj@ultra.linux.cz),
+ David S. Miller (davem@redhat.com) and
+ Peter Maydell (pmaydell@chiark.greenend.org.uk).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#if _FP_W_TYPE_SIZE < 32
+#error "Here's a nickel kid. Go buy yourself a real computer."
+#endif
+
+#define _FP_FRACTBITS_S _FP_W_TYPE_SIZE
+
+#define _FP_FRACBITS_S 24
+#define _FP_FRACXBITS_S (_FP_FRACTBITS_S - _FP_FRACBITS_S)
+#define _FP_WFRACBITS_S (_FP_WORKBITS + _FP_FRACBITS_S)
+#define _FP_WFRACXBITS_S (_FP_FRACTBITS_S - _FP_WFRACBITS_S)
+#define _FP_EXPBITS_S 8
+#define _FP_EXPBIAS_S 127
+#define _FP_EXPMAX_S 255
+#define _FP_QNANBIT_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-2))
+#define _FP_QNANBIT_SH_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-2+_FP_WORKBITS))
+#define _FP_IMPLBIT_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-1))
+#define _FP_IMPLBIT_SH_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-1+_FP_WORKBITS))
+#define _FP_OVERFLOW_S ((_FP_W_TYPE)1 << (_FP_WFRACBITS_S))
+
+/* The implementation of _FP_MUL_MEAT_S and _FP_DIV_MEAT_S should be
+ chosen by the target machine. */
+
+typedef float SFtype __attribute__((mode(SF)));
+
+union _FP_UNION_S
+{
+ SFtype flt;
+ struct {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned sign : 1;
+ unsigned exp : _FP_EXPBITS_S;
+ unsigned frac : _FP_FRACBITS_S - (_FP_IMPLBIT_S != 0);
+#else
+ unsigned frac : _FP_FRACBITS_S - (_FP_IMPLBIT_S != 0);
+ unsigned exp : _FP_EXPBITS_S;
+ unsigned sign : 1;
+#endif
+ } bits __attribute__((packed));
+};
+
+#define FP_DECL_S(X) _FP_DECL(1,X)
+#define FP_UNPACK_RAW_S(X,val) _FP_UNPACK_RAW_1(S,X,val)
+#define FP_UNPACK_RAW_SP(X,val) _FP_UNPACK_RAW_1_P(S,X,val)
+#define FP_PACK_RAW_S(val,X) _FP_PACK_RAW_1(S,val,X)
+#define FP_PACK_RAW_SP(val,X) \
+ do { \
+ if (!FP_INHIBIT_RESULTS) \
+ _FP_PACK_RAW_1_P(S,val,X); \
+ } while (0)
+
+#define FP_UNPACK_S(X,val) \
+ do { \
+ _FP_UNPACK_RAW_1(S,X,val); \
+ _FP_UNPACK_CANONICAL(S,1,X); \
+ } while (0)
+
+#define FP_UNPACK_SP(X,val) \
+ do { \
+ _FP_UNPACK_RAW_1_P(S,X,val); \
+ _FP_UNPACK_CANONICAL(S,1,X); \
+ } while (0)
+
+#define FP_UNPACK_SEMIRAW_S(X,val) \
+ do { \
+ _FP_UNPACK_RAW_1(S,X,val); \
+ _FP_UNPACK_SEMIRAW(S,1,X); \
+ } while (0)
+
+#define FP_UNPACK_SEMIRAW_SP(X,val) \
+ do { \
+ _FP_UNPACK_RAW_1_P(S,X,val); \
+ _FP_UNPACK_SEMIRAW(S,1,X); \
+ } while (0)
+
+#define FP_PACK_S(val,X) \
+ do { \
+ _FP_PACK_CANONICAL(S,1,X); \
+ _FP_PACK_RAW_1(S,val,X); \
+ } while (0)
+
+#define FP_PACK_SP(val,X) \
+ do { \
+ _FP_PACK_CANONICAL(S,1,X); \
+ if (!FP_INHIBIT_RESULTS) \
+ _FP_PACK_RAW_1_P(S,val,X); \
+ } while (0)
+
+#define FP_PACK_SEMIRAW_S(val,X) \
+ do { \
+ _FP_PACK_SEMIRAW(S,1,X); \
+ _FP_PACK_RAW_1(S,val,X); \
+ } while (0)
+
+#define FP_PACK_SEMIRAW_SP(val,X) \
+ do { \
+ _FP_PACK_SEMIRAW(S,1,X); \
+ if (!FP_INHIBIT_RESULTS) \
+ _FP_PACK_RAW_1_P(S,val,X); \
+ } while (0)
+
+#define FP_ISSIGNAN_S(X) _FP_ISSIGNAN(S,1,X)
+#define FP_NEG_S(R,X) _FP_NEG(S,1,R,X)
+#define FP_ADD_S(R,X,Y) _FP_ADD(S,1,R,X,Y)
+#define FP_SUB_S(R,X,Y) _FP_SUB(S,1,R,X,Y)
+#define FP_MUL_S(R,X,Y) _FP_MUL(S,1,R,X,Y)
+#define FP_DIV_S(R,X,Y) _FP_DIV(S,1,R,X,Y)
+#define FP_SQRT_S(R,X) _FP_SQRT(S,1,R,X)
+#define _FP_SQRT_MEAT_S(R,S,T,X,Q) _FP_SQRT_MEAT_1(R,S,T,X,Q)
+
+#define FP_CMP_S(r,X,Y,un) _FP_CMP(S,1,r,X,Y,un)
+#define FP_CMP_EQ_S(r,X,Y) _FP_CMP_EQ(S,1,r,X,Y)
+#define FP_CMP_UNORD_S(r,X,Y) _FP_CMP_UNORD(S,1,r,X,Y)
+
+#define FP_TO_INT_S(r,X,rsz,rsg) _FP_TO_INT(S,1,r,X,rsz,rsg)
+#define FP_FROM_INT_S(X,r,rs,rt) _FP_FROM_INT(S,1,X,r,rs,rt)
+
+#define _FP_FRAC_HIGH_S(X) _FP_FRAC_HIGH_1(X)
+#define _FP_FRAC_HIGH_RAW_S(X) _FP_FRAC_HIGH_1(X)
diff --git a/gcc/config/soft-fp/soft-fp.h b/gcc/config/soft-fp/soft-fp.h
new file mode 100644
index 00000000000..dbf080e7f48
--- /dev/null
+++ b/gcc/config/soft-fp/soft-fp.h
@@ -0,0 +1,209 @@
+/* Software floating-point emulation.
+ Copyright (C) 1997,1998,1999,2000,2002,2003,2005,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com),
+ Jakub Jelinek (jj@ultra.linux.cz),
+ David S. Miller (davem@redhat.com) and
+ Peter Maydell (pmaydell@chiark.greenend.org.uk).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#ifndef SOFT_FP_H
+#define SOFT_FP_H
+
+#ifdef _LIBC
+#include <sfp-machine.h>
+#else
+#include "sfp-machine.h"
+#endif
+
+/* Allow sfp-machine to have its own byte order definitions. */
+#ifndef __BYTE_ORDER
+#ifdef _LIBC
+#include <endian.h>
+#else
+#error "endianness not defined by sfp-machine.h"
+#endif
+#endif
+
+#define _FP_WORKBITS 3
+#define _FP_WORK_LSB ((_FP_W_TYPE)1 << 3)
+#define _FP_WORK_ROUND ((_FP_W_TYPE)1 << 2)
+#define _FP_WORK_GUARD ((_FP_W_TYPE)1 << 1)
+#define _FP_WORK_STICKY ((_FP_W_TYPE)1 << 0)
+
+#ifndef FP_RND_NEAREST
+# define FP_RND_NEAREST 0
+# define FP_RND_ZERO 1
+# define FP_RND_PINF 2
+# define FP_RND_MINF 3
+#endif
+#ifndef FP_ROUNDMODE
+# define FP_ROUNDMODE FP_RND_NEAREST
+#endif
+
+/* By default don't care about exceptions. */
+#ifndef FP_EX_INVALID
+#define FP_EX_INVALID 0
+#endif
+#ifndef FP_EX_OVERFLOW
+#define FP_EX_OVERFLOW 0
+#endif
+#ifndef FP_EX_UNDERFLOW
+#define FP_EX_UNDERFLOW 0
+#endif
+#ifndef FP_EX_DIVZERO
+#define FP_EX_DIVZERO 0
+#endif
+#ifndef FP_EX_INEXACT
+#define FP_EX_INEXACT 0
+#endif
+#ifndef FP_EX_DENORM
+#define FP_EX_DENORM 0
+#endif
+
+#ifdef _FP_DECL_EX
+#define FP_DECL_EX \
+ int _fex = 0; \
+ _FP_DECL_EX
+#else
+#define FP_DECL_EX int _fex = 0
+#endif
+
+#ifndef FP_INIT_ROUNDMODE
+#define FP_INIT_ROUNDMODE do {} while (0)
+#endif
+
+#ifndef FP_HANDLE_EXCEPTIONS
+#define FP_HANDLE_EXCEPTIONS do {} while (0)
+#endif
+
+#ifndef FP_INHIBIT_RESULTS
+/* By default we write the results always.
+ * sfp-machine may override this and e.g.
+ * check if some exceptions are unmasked
+ * and inhibit it in such a case.
+ */
+#define FP_INHIBIT_RESULTS 0
+#endif
+
+#define FP_SET_EXCEPTION(ex) \
+ _fex |= (ex)
+
+#define FP_UNSET_EXCEPTION(ex) \
+ _fex &= ~(ex)
+
+#define FP_CLEAR_EXCEPTIONS \
+ _fex = 0
+
+#define _FP_ROUND_NEAREST(wc, X) \
+do { \
+ if ((_FP_FRAC_LOW_##wc(X) & 15) != _FP_WORK_ROUND) \
+ _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND); \
+} while (0)
+
+#define _FP_ROUND_ZERO(wc, X) (void)0
+
+#define _FP_ROUND_PINF(wc, X) \
+do { \
+ if (!X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \
+ _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \
+} while (0)
+
+#define _FP_ROUND_MINF(wc, X) \
+do { \
+ if (X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \
+ _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \
+} while (0)
+
+#define _FP_ROUND(wc, X) \
+do { \
+ if (_FP_FRAC_LOW_##wc(X) & 7) \
+ FP_SET_EXCEPTION(FP_EX_INEXACT); \
+ switch (FP_ROUNDMODE) \
+ { \
+ case FP_RND_NEAREST: \
+ _FP_ROUND_NEAREST(wc,X); \
+ break; \
+ case FP_RND_ZERO: \
+ _FP_ROUND_ZERO(wc,X); \
+ break; \
+ case FP_RND_PINF: \
+ _FP_ROUND_PINF(wc,X); \
+ break; \
+ case FP_RND_MINF: \
+ _FP_ROUND_MINF(wc,X); \
+ break; \
+ } \
+} while (0)
+
+#define FP_CLS_NORMAL 0
+#define FP_CLS_ZERO 1
+#define FP_CLS_INF 2
+#define FP_CLS_NAN 3
+
+#define _FP_CLS_COMBINE(x,y) (((x) << 2) | (y))
+
+#include "op-1.h"
+#include "op-2.h"
+#include "op-4.h"
+#include "op-8.h"
+#include "op-common.h"
+
+/* Sigh. Silly things longlong.h needs. */
+#define UWtype _FP_W_TYPE
+#define W_TYPE_SIZE _FP_W_TYPE_SIZE
+
+typedef int QItype __attribute__((mode(QI)));
+typedef int SItype __attribute__((mode(SI)));
+typedef int DItype __attribute__((mode(DI)));
+typedef unsigned int UQItype __attribute__((mode(QI)));
+typedef unsigned int USItype __attribute__((mode(SI)));
+typedef unsigned int UDItype __attribute__((mode(DI)));
+#if _FP_W_TYPE_SIZE == 32
+typedef unsigned int UHWtype __attribute__((mode(HI)));
+#elif _FP_W_TYPE_SIZE == 64
+typedef USItype UHWtype;
+#endif
+
+#define SI_BITS (__CHAR_BIT__ * (int)sizeof(SItype))
+#define DI_BITS (__CHAR_BIT__ * (int)sizeof(DItype))
+
+#ifndef umul_ppmm
+#ifdef _LIBC
+#include <stdlib/longlong.h>
+#else
+#include "longlong.h"
+#endif
+#endif
+
+#ifdef _LIBC
+#include <stdlib.h>
+#else
+extern void abort (void);
+#endif
+
+#endif
diff --git a/gcc/config/soft-fp/subdf3.c b/gcc/config/soft-fp/subdf3.c
new file mode 100644
index 00000000000..3978b52998d
--- /dev/null
+++ b/gcc/config/soft-fp/subdf3.c
@@ -0,0 +1,49 @@
+/* Software floating-point emulation.
+ Return a - b
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "double.h"
+
+DFtype __subdf3(DFtype a, DFtype b)
+{
+ FP_DECL_EX;
+ FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R);
+ DFtype r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_SEMIRAW_D(A, a);
+ FP_UNPACK_SEMIRAW_D(B, b);
+ FP_SUB_D(R, A, B);
+ FP_PACK_SEMIRAW_D(r, R);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/subsf3.c b/gcc/config/soft-fp/subsf3.c
new file mode 100644
index 00000000000..f1cbdd1ff1f
--- /dev/null
+++ b/gcc/config/soft-fp/subsf3.c
@@ -0,0 +1,49 @@
+/* Software floating-point emulation.
+ Return a - b
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "single.h"
+
+SFtype __subsf3(SFtype a, SFtype b)
+{
+ FP_DECL_EX;
+ FP_DECL_S(A); FP_DECL_S(B); FP_DECL_S(R);
+ SFtype r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_SEMIRAW_S(A, a);
+ FP_UNPACK_SEMIRAW_S(B, b);
+ FP_SUB_S(R, A, B);
+ FP_PACK_SEMIRAW_S(r, R);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/subtf3.c b/gcc/config/soft-fp/subtf3.c
new file mode 100644
index 00000000000..7ba4c8c5ea0
--- /dev/null
+++ b/gcc/config/soft-fp/subtf3.c
@@ -0,0 +1,49 @@
+/* Software floating-point emulation.
+ Return a - b
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+TFtype __subtf3(TFtype a, TFtype b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(R);
+ TFtype r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_SEMIRAW_Q(A, a);
+ FP_UNPACK_SEMIRAW_Q(B, b);
+ FP_SUB_Q(R, A, B);
+ FP_PACK_SEMIRAW_Q(r, R);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/t-softfp b/gcc/config/soft-fp/t-softfp
new file mode 100644
index 00000000000..4a3f91e15ee
--- /dev/null
+++ b/gcc/config/soft-fp/t-softfp
@@ -0,0 +1,108 @@
+# Copyright (C) 2006 Free Software Foundation, Inc.
+
+# This file is part of GCC.
+
+# GCC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# GCC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING. If not, write to
+# the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+# Boston MA 02110-1301, USA.
+
+# Targets using soft-fp should define the following variables:
+#
+# softfp_float_modes: a list of soft-float floating-point modes,
+# e.g. sf df
+# softfp_int_modes: a list of integer modes for which to define conversions,
+# e.g. si di
+# softfp_extensions: a list of extensions between floating-point modes,
+# e.g. sfdf
+# softfp_truncations: a list of truncations between floating-point modes,
+# e.g. dfsf
+# softfp_machine_header: the target sfp-machine.h file (relative to config/),
+# e.g. rs6000/sfp-machine.h
+#
+# Extensions and truncations should include those where only one mode
+# is a soft-float mode; for example, sftf where sf is hard-float and
+# tf is soft-float.
+#
+# If the libgcc2.c functions should not be replaced, also define:
+#
+# softfp_exclude_libgcc2 := y
+#
+# Avoiding replacing the libgcc2.c functions is a temporary measure
+# for targets with both hard-float and soft-float multilibs, since
+# these variables apply for all multilibs. With toplevel libgcc,
+# soft-fp can be used conditionally on the multilib instead.
+#
+# If the code should not be compiled at all for some multilibs, define:
+#
+# softfp_wrap_start: text to put at the start of wrapper source files,
+# output with echo
+# e.g. '#ifndef __powerpc64__'
+# softfp_wrap_end: text to put at the end of wrapper source files,
+# e.g. '#endif'
+#
+# This is another temporary measure.
+
+softfp_float_funcs = add$(m)3 div$(m)3 eq$(m)2 ge$(m)2 le$(m)2 mul$(m)3 \
+ neg$(m)2 sub$(m)3 unord$(m)2
+softfp_floatint_funcs = fix$(m)$(i) fixuns$(m)$(i) \
+ float$(i)$(m) floatun$(i)$(m)
+
+softfp_func_list := \
+ $(foreach m,$(softfp_float_modes), \
+ $(softfp_float_funcs) \
+ $(foreach i,$(softfp_int_modes), \
+ $(softfp_floatint_funcs))) \
+ $(foreach e,$(softfp_extensions),extend$(e)2) \
+ $(foreach t,$(softfp_truncations),trunc$(t)2)
+
+ifeq ($(softfp_exclude_libgcc2),y)
+# This list is taken from mklibgcc.in and doesn't presently allow for
+# 64-bit targets where si should become di and di should become ti.
+softfp_func_list := $(filter-out floatdidf floatdisf fixunsdfsi fixunssfsi \
+ fixunsdfdi fixdfdi fixunssfdi fixsfdi fixxfdi fixunsxfdi \
+ floatdixf fixunsxfsi fixtfdi fixunstfdi floatditf \
+ floatundidf floatundisf floatundixf floatunditf,$(softfp_func_list))
+endif
+
+ifeq ($(softfp_wrap_start),)
+softfp_file_list := \
+ $(addsuffix .c,$(addprefix $(srcdir)/config/soft-fp/,$(softfp_func_list)))
+else
+softfp_file_list := $(addsuffix .c,$(softfp_func_list))
+
+$(softfp_file_list):
+ echo $(softfp_wrap_start) > $@
+ echo '#include "config/soft-fp/$@"' >> $@
+ echo $(softfp_wrap_end) >> $@
+endif
+
+LIB2FUNCS_EXTRA += $(softfp_file_list)
+
+ifneq ($(softfp_exclude_libgcc2),y)
+# Functions in libgcc2.c are excluded for each soft-float mode (a
+# target may have both soft-float and hard-float modes), for the fixed
+# list of integer modes (si and di) for which libgcc2.c defines any
+# such functions. Depending on the target, the si and di symbols may
+# in fact define di and ti functions.
+
+LIB2FUNCS_EXCLUDE += \
+ $(addprefix _,$(foreach m,$(softfp_float_modes), \
+ $(foreach i,si di, \
+ $(softfp_floatint_funcs))))
+endif
+
+SFP_MACHINE := sfp-machine.h
+
+$(SFP_MACHINE): $(srcdir)/config/$(softfp_machine_header)
+ cp $(srcdir)/config/$(softfp_machine_header) $(SFP_MACHINE)
diff --git a/gcc/config/soft-fp/truncdfsf2.c b/gcc/config/soft-fp/truncdfsf2.c
new file mode 100644
index 00000000000..bd953912e98
--- /dev/null
+++ b/gcc/config/soft-fp/truncdfsf2.c
@@ -0,0 +1,54 @@
+/* Software floating-point emulation.
+ Truncate IEEE double into IEEE single
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "single.h"
+#include "double.h"
+
+SFtype __truncdfsf2(DFtype a)
+{
+ FP_DECL_EX;
+ FP_DECL_D(A);
+ FP_DECL_S(R);
+ SFtype r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_SEMIRAW_D(A, a);
+#if _FP_W_TYPE_SIZE < _FP_FRACBITS_D
+ FP_TRUNC(S,D,1,2,R,A);
+#else
+ FP_TRUNC(S,D,1,1,R,A);
+#endif
+ FP_PACK_SEMIRAW_S(r, R);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/trunctfdf2.c b/gcc/config/soft-fp/trunctfdf2.c
new file mode 100644
index 00000000000..c3827b08abe
--- /dev/null
+++ b/gcc/config/soft-fp/trunctfdf2.c
@@ -0,0 +1,54 @@
+/* Software floating-point emulation.
+ Truncate IEEE quad into IEEE double
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "double.h"
+#include "quad.h"
+
+DFtype __trunctfdf2(TFtype a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ FP_DECL_D(R);
+ DFtype r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_SEMIRAW_Q(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+ FP_TRUNC(D,Q,2,4,R,A);
+#else
+ FP_TRUNC(D,Q,1,2,R,A);
+#endif
+ FP_PACK_SEMIRAW_D(r, R);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/trunctfsf2.c b/gcc/config/soft-fp/trunctfsf2.c
new file mode 100644
index 00000000000..676c937e20a
--- /dev/null
+++ b/gcc/config/soft-fp/trunctfsf2.c
@@ -0,0 +1,54 @@
+/* Software floating-point emulation.
+ Truncate IEEE quad into IEEE single
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "single.h"
+#include "quad.h"
+
+SFtype __trunctfsf2(TFtype a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ FP_DECL_S(R);
+ SFtype r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_SEMIRAW_Q(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+ FP_TRUNC(S,Q,1,4,R,A);
+#else
+ FP_TRUNC(S,Q,1,2,R,A);
+#endif
+ FP_PACK_SEMIRAW_S(r, R);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/unorddf2.c b/gcc/config/soft-fp/unorddf2.c
new file mode 100644
index 00000000000..c83a5632759
--- /dev/null
+++ b/gcc/config/soft-fp/unorddf2.c
@@ -0,0 +1,45 @@
+/* Software floating-point emulation.
+ Return 1 iff a or b is a NaN, 0 otherwise.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Joseph Myers (joseph@codesourcery.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "double.h"
+
+int
+__unorddf2(DFtype a, DFtype b)
+{
+ FP_DECL_D(A); FP_DECL_D(B);
+ int r;
+
+ FP_UNPACK_RAW_D(A, a);
+ FP_UNPACK_RAW_D(B, b);
+ FP_CMP_UNORD_D(r, A, B);
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/unordsf2.c b/gcc/config/soft-fp/unordsf2.c
new file mode 100644
index 00000000000..8de75635660
--- /dev/null
+++ b/gcc/config/soft-fp/unordsf2.c
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+ Return 1 iff a or b is a NaN, 0 otherwise.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Joseph Myers (joseph@codesourcery.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "single.h"
+
+int
+__unordsf2(SFtype a, SFtype b)
+{
+ FP_DECL_S(A);
+ FP_DECL_S(B);
+ int r;
+
+ FP_UNPACK_RAW_S(A, a);
+ FP_UNPACK_RAW_S(B, b);
+ FP_CMP_UNORD_S(r, A, B);
+
+ return r;
+}
diff --git a/gcc/config/soft-fp/unordtf2.c b/gcc/config/soft-fp/unordtf2.c
new file mode 100644
index 00000000000..134b1d09b8a
--- /dev/null
+++ b/gcc/config/soft-fp/unordtf2.c
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+ Return 1 iff a or b is a NaN, 0 otherwise.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Joseph Myers (joseph@codesourcery.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int
+__unordtf2(TFtype a, TFtype b)
+{
+ FP_DECL_Q(A);
+ FP_DECL_Q(B);
+ int r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_UNPACK_RAW_Q(B, b);
+ FP_CMP_UNORD_Q(r, A, B);
+
+ return r;
+}
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index e880226412e..692e46e5584 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -4559,7 +4559,10 @@ function_arg_slotno (const struct sparc_args *cum, enum machine_mode mode,
gcc_assert (mode == BLKmode);
- if (TARGET_ARCH32 || !type || (TREE_CODE (type) == UNION_TYPE))
+ if (TARGET_ARCH32
+ || !type
+ || (TREE_CODE (type) != VECTOR_TYPE
+ && TREE_CODE (type) != RECORD_TYPE))
{
if (slotno >= SPARC_INT_ARG_MAX)
return -1;
@@ -5073,62 +5076,58 @@ function_arg (const struct sparc_args *cum, enum machine_mode mode,
: SPARC_OUTGOING_INT_ARG_FIRST);
int slotno, regno, padding;
enum mode_class mclass = GET_MODE_CLASS (mode);
- rtx reg;
slotno = function_arg_slotno (cum, mode, type, named, incoming_p,
&regno, &padding);
-
if (slotno == -1)
return 0;
- if (TARGET_ARCH32)
+ /* Vector types deserve special treatment because they are polymorphic wrt
+ their mode, depending upon whether VIS instructions are enabled. */
+ if (type && TREE_CODE (type) == VECTOR_TYPE)
{
- reg = gen_rtx_REG (mode, regno);
- return reg;
+ HOST_WIDE_INT size = int_size_in_bytes (type);
+ gcc_assert ((TARGET_ARCH32 && size <= 8)
+ || (TARGET_ARCH64 && size <= 16));
+
+ if (mode == BLKmode)
+ return function_arg_vector_value (size,
+ TYPE_MODE (TREE_TYPE (type)),
+ SPARC_FP_ARG_FIRST + 2*slotno);
+ else
+ mclass = MODE_FLOAT;
}
-
- if (type && TREE_CODE (type) == RECORD_TYPE)
- {
- /* Structures up to 16 bytes in size are passed in arg slots on the
- stack and are promoted to registers where possible. */
- gcc_assert (int_size_in_bytes (type) <= 16);
+ if (TARGET_ARCH32)
+ return gen_rtx_REG (mode, regno);
- return function_arg_record_value (type, mode, slotno, named, regbase);
- }
- else if (type && TREE_CODE (type) == UNION_TYPE)
+ /* Structures up to 16 bytes in size are passed in arg slots on the stack
+ and are promoted to registers if possible. */
+ if (type && TREE_CODE (type) == RECORD_TYPE)
{
HOST_WIDE_INT size = int_size_in_bytes (type);
-
gcc_assert (size <= 16);
- return function_arg_union_value (size, mode, slotno, regno);
+ return function_arg_record_value (type, mode, slotno, named, regbase);
}
- else if (type && TREE_CODE (type) == VECTOR_TYPE)
+
+ /* Unions up to 16 bytes in size are passed in integer registers. */
+ else if (type && TREE_CODE (type) == UNION_TYPE)
{
- /* Vector types deserve special treatment because they are
- polymorphic wrt their mode, depending upon whether VIS
- instructions are enabled. */
HOST_WIDE_INT size = int_size_in_bytes (type);
-
gcc_assert (size <= 16);
- if (mode == BLKmode)
- return function_arg_vector_value (size,
- TYPE_MODE (TREE_TYPE (type)),
- SPARC_FP_ARG_FIRST + 2*slotno);
- else
- mclass = MODE_FLOAT;
+ return function_arg_union_value (size, mode, slotno, regno);
}
/* v9 fp args in reg slots beyond the int reg slots get passed in regs
but also have the slot allocated for them.
If no prototype is in scope fp values in register slots get passed
in two places, either fp regs and int regs or fp regs and memory. */
- if ((mclass == MODE_FLOAT || mclass == MODE_COMPLEX_FLOAT)
- && SPARC_FP_REG_P (regno))
+ else if ((mclass == MODE_FLOAT || mclass == MODE_COMPLEX_FLOAT)
+ && SPARC_FP_REG_P (regno))
{
- reg = gen_rtx_REG (mode, regno);
+ rtx reg = gen_rtx_REG (mode, regno);
if (cum->prototype_p || cum->libcall_p)
{
/* "* 2" because fp reg numbers are recorded in 4 byte
@@ -5189,13 +5188,18 @@ function_arg (const struct sparc_args *cum, enum machine_mode mode,
}
}
}
- else
+
+ /* All other aggregate types are passed in an integer register in a mode
+ corresponding to the size of the type. */
+ else if (type && AGGREGATE_TYPE_P (type))
{
- /* Scalar or complex int. */
- reg = gen_rtx_REG (mode, regno);
+ HOST_WIDE_INT size = int_size_in_bytes (type);
+ gcc_assert (size <= 16);
+
+ mode = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0);
}
- return reg;
+ return gen_rtx_REG (mode, regno);
}
/* For an arg passed partly in registers and partly in memory,
@@ -5271,7 +5275,6 @@ sparc_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
bool named ATTRIBUTE_UNUSED)
{
if (TARGET_ARCH32)
- {
/* Original SPARC 32-bit ABI says that structures and unions,
and quad-precision floats are passed by reference. For Pascal,
also pass arrays by reference. All other base types are passed
@@ -5286,19 +5289,17 @@ sparc_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
integers are passed like floats of the same size, that is in
registers up to 8 bytes. Pass all vector floats by reference
like structure and unions. */
- return ((type && (AGGREGATE_TYPE_P (type) || VECTOR_FLOAT_TYPE_P (type)))
- || mode == SCmode
- /* Catch CDImode, TFmode, DCmode and TCmode. */
- || GET_MODE_SIZE (mode) > 8
- || (type
- && TREE_CODE (type) == VECTOR_TYPE
- && (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8));
- }
+ return ((type && (AGGREGATE_TYPE_P (type) || VECTOR_FLOAT_TYPE_P (type)))
+ || mode == SCmode
+ /* Catch CDImode, TFmode, DCmode and TCmode. */
+ || GET_MODE_SIZE (mode) > 8
+ || (type
+ && TREE_CODE (type) == VECTOR_TYPE
+ && (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8));
else
- {
/* Original SPARC 64-bit ABI says that structures and unions
smaller than 16 bytes are passed in registers, as well as
- all other base types. For Pascal, pass arrays by reference.
+ all other base types.
Extended ABI (as implemented by the Sun compiler) says that
complex floats are passed in registers up to 16 bytes. Pass
@@ -5309,13 +5310,11 @@ sparc_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
integers are passed like floats of the same size, that is in
registers (up to 16 bytes). Pass all vector floats like structure
and unions. */
- return ((type && TREE_CODE (type) == ARRAY_TYPE)
- || (type
- && (AGGREGATE_TYPE_P (type) || TREE_CODE (type) == VECTOR_TYPE)
- && (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 16)
- /* Catch CTImode and TCmode. */
- || GET_MODE_SIZE (mode) > 16);
- }
+ return ((type
+ && (AGGREGATE_TYPE_P (type) || TREE_CODE (type) == VECTOR_TYPE)
+ && (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 16)
+ /* Catch CTImode and TCmode. */
+ || GET_MODE_SIZE (mode) > 16);
}
/* Handle the FUNCTION_ARG_ADVANCE macro.
@@ -5499,13 +5498,11 @@ function_value (tree type, enum machine_mode mode, int incoming_p)
enum mode_class mclass = GET_MODE_CLASS (mode);
int regno;
+ /* Vector types deserve special treatment because they are polymorphic wrt
+ their mode, depending upon whether VIS instructions are enabled. */
if (type && TREE_CODE (type) == VECTOR_TYPE)
{
- /* Vector types deserve special treatment because they are
- polymorphic wrt their mode, depending upon whether VIS
- instructions are enabled. */
HOST_WIDE_INT size = int_size_in_bytes (type);
-
gcc_assert ((TARGET_ARCH32 && size <= 8)
|| (TARGET_ARCH64 && size <= 32));
@@ -5516,34 +5513,41 @@ function_value (tree type, enum machine_mode mode, int incoming_p)
else
mclass = MODE_FLOAT;
}
- else if (type && TARGET_ARCH64)
+
+ if (TARGET_ARCH64 && type)
{
+ /* Structures up to 32 bytes in size are returned in registers. */
if (TREE_CODE (type) == RECORD_TYPE)
{
- /* Structures up to 32 bytes in size are passed in registers,
- promoted to fp registers where possible. */
-
- gcc_assert (int_size_in_bytes (type) <= 32);
+ HOST_WIDE_INT size = int_size_in_bytes (type);
+ gcc_assert (size <= 32);
return function_arg_record_value (type, mode, 0, 1, regbase);
}
+
+ /* Unions up to 32 bytes in size are returned in integer registers. */
else if (TREE_CODE (type) == UNION_TYPE)
{
HOST_WIDE_INT size = int_size_in_bytes (type);
-
gcc_assert (size <= 32);
return function_arg_union_value (size, mode, 0, regbase);
}
+
+ /* Objects that require it are returned in FP registers. */
+ else if (mclass == MODE_FLOAT || mclass == MODE_COMPLEX_FLOAT)
+ ;
+
+ /* All other aggregate types are returned in an integer register in a
+ mode corresponding to the size of the type. */
else if (AGGREGATE_TYPE_P (type))
{
/* All other aggregate types are passed in an integer register
in a mode corresponding to the size of the type. */
- HOST_WIDE_INT bytes = int_size_in_bytes (type);
-
- gcc_assert (bytes <= 32);
+ HOST_WIDE_INT size = int_size_in_bytes (type);
+ gcc_assert (size <= 32);
- mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 0);
+ mode = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0);
/* ??? We probably should have made the same ABI change in
3.4.0 as the one we made for unions. The latter was
@@ -5555,17 +5559,17 @@ function_value (tree type, enum machine_mode mode, int incoming_p)
try to be unduly clever, and simply follow the ABI
for unions in that case. */
if (mode == BLKmode)
- return function_arg_union_value (bytes, mode, 0, regbase);
+ return function_arg_union_value (size, mode, 0, regbase);
else
mclass = MODE_INT;
}
- else if (mclass == MODE_INT
- && GET_MODE_SIZE (mode) < UNITS_PER_WORD)
+
+ /* This must match PROMOTE_FUNCTION_MODE. */
+ else if (mclass == MODE_INT && GET_MODE_SIZE (mode) < UNITS_PER_WORD)
mode = word_mode;
}
- if ((mclass == MODE_FLOAT || mclass == MODE_COMPLEX_FLOAT)
- && TARGET_FPU)
+ if ((mclass == MODE_FLOAT || mclass == MODE_COMPLEX_FLOAT) && TARGET_FPU)
regno = SPARC_FP_ARG_FIRST;
else
regno = regbase;
@@ -8483,16 +8487,24 @@ sparc_rtx_costs (rtx x, int code, int outer_code, int *total)
}
}
-/* Emit the sequence of insns SEQ while preserving the registers. */
+/* Emit the sequence of insns SEQ while preserving the registers REG and REG2.
+ This is achieved by means of a manual dynamic stack space allocation in
+ the current frame. We make the assumption that SEQ doesn't contain any
+ function calls, with the possible exception of calls to the PIC helper. */
static void
emit_and_preserve (rtx seq, rtx reg, rtx reg2)
{
- /* STACK_BOUNDARY guarantees that this is a 2-word slot. */
- rtx slot = gen_rtx_MEM (word_mode,
- plus_constant (stack_pointer_rtx, SPARC_STACK_BIAS));
+ /* We must preserve the lowest 16 words for the register save area. */
+ HOST_WIDE_INT offset = 16*UNITS_PER_WORD;
+ /* We really need only 2 words of fresh stack space. */
+ HOST_WIDE_INT size = SPARC_STACK_ALIGN (offset + 2*UNITS_PER_WORD);
+
+ rtx slot
+ = gen_rtx_MEM (word_mode, plus_constant (stack_pointer_rtx,
+ SPARC_STACK_BIAS + offset));
- emit_insn (gen_stack_pointer_dec (GEN_INT (STACK_BOUNDARY/BITS_PER_UNIT)));
+ emit_insn (gen_stack_pointer_dec (GEN_INT (size)));
emit_insn (gen_rtx_SET (VOIDmode, slot, reg));
if (reg2)
emit_insn (gen_rtx_SET (VOIDmode,
@@ -8504,7 +8516,7 @@ emit_and_preserve (rtx seq, rtx reg, rtx reg2)
reg2,
adjust_address (slot, word_mode, UNITS_PER_WORD)));
emit_insn (gen_rtx_SET (VOIDmode, reg, slot));
- emit_insn (gen_stack_pointer_inc (GEN_INT (STACK_BOUNDARY/BITS_PER_UNIT)));
+ emit_insn (gen_stack_pointer_inc (GEN_INT (size)));
}
/* Output the assembler code for a thunk function. THUNK_DECL is the