* Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) @ 2002-12-14 14:09 Kaveh R. Ghazi 2002-12-16 9:24 ` Rainer Orth 2002-12-16 9:51 ` Alexandre Oliva 0 siblings, 2 replies; 72+ messages in thread From: Kaveh R. Ghazi @ 2002-12-14 14:09 UTC (permalink / raw) To: gcc-bugs, gcc; +Cc: libstdc++, oldham, ro I'm getting wierd (i.e. I think wrong) results for long doubles on mips-irix6. Consider the following C testcase: #include <stdio.h> int main() { char buf[1024]; long double ldin[] = { 1.0L, 1.0L, 1.0L }; long double ldout[3]; fprintf (stdout, "sizeof(long double) == %d\n", (int) sizeof ldin[0]); sprintf (buf, "%Lf %Lf %Lf", ldin[0], ldin[1], ldin[2]); sscanf (buf, "%Lf %Lf %Lf", &ldout[0], &ldout[1], &ldout[2]); fprintf (stdout, "<%Lf><%Lf><%Lf>\n", ldout[0], ldout[1], ldout[2]); return 0; } Compiling and then running this program with "cc -n32" or "cc -64" on irix6.2 or irix6.5 (correctly I believe for these ABIs) yields: > sizeof(long double) == 16 > <1.000000><1.000000><1.000000> Compiling and then running this program with "gcc -mabi=n32" or "gcc -mabi=64" on irix6.2 or irix6.5 (erroneously) yields: > sizeof(long double) == 8 > <1.000000><0.000000><-nan0xffffffff> > Bus error (core dumped) This appears to occur for all gcc versions from 2.8.1 through the current CVS trunk. As you can see, gcc's sizeof (long double) doesn't agree with that from the system compiler and I would assume therefore that gcc also disagrees with libc's notion of long double. This means that the %Lf specifier is hosed and cannot be used from gcc on irix6. I believe this is the cause of the 27_io/ostream_inserter_arith.cc failures we've been getting on irix6. See also http://gcc.gnu.org/ml/gcc-bugs/2001-08/msg00088.html which apears to be the same issue. Does anyone have any thoughts on this? (Or better yet a fix?) Thanks, --Kaveh -- Kaveh R. Ghazi ghazi@caip.rutgers.edu ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2002-12-14 14:09 Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) Kaveh R. Ghazi @ 2002-12-16 9:24 ` Rainer Orth 2002-12-16 9:51 ` Alexandre Oliva 1 sibling, 0 replies; 72+ messages in thread From: Rainer Orth @ 2002-12-16 9:24 UTC (permalink / raw) To: Kaveh R. Ghazi; +Cc: gcc-bugs, gcc, libstdc++, oldham Kaveh R. Ghazi writes: > As you can see, gcc's sizeof (long double) doesn't agree with that > from the system compiler and I would assume therefore that gcc also > disagrees with libc's notion of long double. This means that the %Lf > specifier is hosed and cannot be used from gcc on irix6. > > I believe this is the cause of the 27_io/ostream_inserter_arith.cc > failures we've been getting on irix6. > > See also http://gcc.gnu.org/ml/gcc-bugs/2001-08/msg00088.html which > apears to be the same issue. It is. The following comment from config/mips/abi64.h (lost when the definitions from that file were merged into mips.h) still applies: /* ??? Unimplemented stuff follows. */ /* ??? Add support for 16 byte/128 bit long doubles here when mips_abi != ABI32. */ > Does anyone have any thoughts on this? (Or better yet a fix?) I didn't have much time to work on gcc lately, but David Edelsohn's support or 128-bit long doubles in AIX (implemented as a pair of 64-bit doubles) applies to IRIX 6 long doubles as well, since both platforms use the same format as documented in math(3M). Rainer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2002-12-14 14:09 Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) Kaveh R. Ghazi 2002-12-16 9:24 ` Rainer Orth @ 2002-12-16 9:51 ` Alexandre Oliva 2002-12-16 9:52 ` Rainer Orth 2002-12-16 21:58 ` Kaveh R. Ghazi 1 sibling, 2 replies; 72+ messages in thread From: Alexandre Oliva @ 2002-12-16 9:51 UTC (permalink / raw) To: Kaveh R. Ghazi; +Cc: gcc-bugs, gcc, libstdc++, oldham, ro On Dec 14, 2002, "Kaveh R. Ghazi" <ghazi@caip.rutgers.edu> wrote: > Does anyone have any thoughts on this? (Or better yet a fix?) I've been working on a patch that will enable us to switch to 128-bit long doubles on mips n32 and n64, but I still need a little bit of polishing and checking (I know that my current patch still doesn't pass long double arguments in the right registers). I expect to have it finished in the next few days. That said, I'm not sure it would be wise to break the gcc ABI on IRIX 6 by introducing this change. It's not like long double is the most widely used type, but still, I'm a bit concerned about changing it. Opinions? -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2002-12-16 9:51 ` Alexandre Oliva @ 2002-12-16 9:52 ` Rainer Orth 2002-12-16 12:23 ` Eric Christopher 2002-12-16 21:58 ` Kaveh R. Ghazi 1 sibling, 1 reply; 72+ messages in thread From: Rainer Orth @ 2002-12-16 9:52 UTC (permalink / raw) To: Alexandre Oliva; +Cc: Kaveh R. Ghazi, gcc-bugs, gcc, libstdc++, oldham Alexandre Oliva writes: > I've been working on a patch that will enable us to switch to 128-bit > long doubles on mips n32 and n64, but I still need a little bit of > polishing and checking (I know that my current patch still doesn't > pass long double arguments in the right registers). I expect to have > it finished in the next few days. Great. > That said, I'm not sure it would be wise to break the gcc ABI on IRIX > 6 by introducing this change. It's not like long double is the most > widely used type, but still, I'm a bit concerned about changing it. > Opinions? On the contrary: we shouldn't introduce a GCC ABI (which is especially useless since it doesn't interoperate with libc as is the case with 64-bit long double), but try to implement the vendor ABI correctly. I think the same is true for the major other ABI non-conformance on IRIX, namely passing of small structures (where Jim Wilson is working on a fix, as I understand). This has caused so many people trouble and required platform-specific work-arounds in so many packages that we should get this right once and for all, even if this means non-interoperability with the older (broken) GCC implementation. Rainer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2002-12-16 9:52 ` Rainer Orth @ 2002-12-16 12:23 ` Eric Christopher 0 siblings, 0 replies; 72+ messages in thread From: Eric Christopher @ 2002-12-16 12:23 UTC (permalink / raw) To: Rainer Orth Cc: Alexandre Oliva, Kaveh R. Ghazi, gcc-bugs, gcc, libstdc++, oldham > understand). This has caused so many people trouble and required > platform-specific work-arounds in so many packages that we should get this > right once and for all, even if this means non-interoperability with the > older (broken) GCC implementation. > I'm inclined to agree with Rainer here. If we're going to say that we want to support the ABI that we do, we need to support as much as we possibly can. If we can support 128-bit long doubles we should. -eric -- Yeah, I used to play basketball... ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2002-12-16 9:51 ` Alexandre Oliva 2002-12-16 9:52 ` Rainer Orth @ 2002-12-16 21:58 ` Kaveh R. Ghazi 2002-12-21 10:45 ` Alexandre Oliva 1 sibling, 1 reply; 72+ messages in thread From: Kaveh R. Ghazi @ 2002-12-16 21:58 UTC (permalink / raw) To: aoliva; +Cc: gcc-bugs, gcc, libstdc++, oldham, ro > From: Alexandre Oliva <aoliva@redhat.com> > > On Dec 14, 2002, "Kaveh R. Ghazi" <ghazi@caip.rutgers.edu> wrote: > > > Does anyone have any thoughts on this? (Or better yet a fix?) > > I've been working on a patch that will enable us to switch to 128-bit > long doubles on mips n32 and n64, but I still need a little bit of > polishing and checking (I know that my current patch still doesn't > pass long double arguments in the right registers). I expect to have > it finished in the next few days. Excellent! Let me know if I can be of service testing your patch. > That said, I'm not sure it would be wise to break the gcc ABI on IRIX > 6 by introducing this change. It's not like long double is the most > widely used type, but still, I'm a bit concerned about changing it. > Opinions? Considering the current irix libc incompatibility, one cannot currently input or output long doubles using stdio. What good is that? :-) I definitely support fixing the ABI, perhaps even on the 3.3 branch if the patch is not too invasive. Thanks, --Kaveh -- Kaveh R. Ghazi ghazi@caip.rutgers.edu ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2002-12-16 21:58 ` Kaveh R. Ghazi @ 2002-12-21 10:45 ` Alexandre Oliva 2002-12-22 6:02 ` Kaveh R. Ghazi 2002-12-22 10:24 ` Alexandre Oliva 0 siblings, 2 replies; 72+ messages in thread From: Alexandre Oliva @ 2002-12-21 10:45 UTC (permalink / raw) To: Kaveh R. Ghazi; +Cc: gcc-bugs, gcc, libstdc++, oldham, ro On Dec 17, 2002, "Kaveh R. Ghazi" <ghazi@caip.rutgers.edu> wrote: >> From: Alexandre Oliva <aoliva@redhat.com> >> >> On Dec 14, 2002, "Kaveh R. Ghazi" <ghazi@caip.rutgers.edu> wrote: >> >> > Does anyone have any thoughts on this? (Or better yet a fix?) >> >> I've been working on a patch that will enable us to switch to 128-bit >> long doubles on mips n32 and n64, but I still need a little bit of >> polishing and checking (I know that my current patch still doesn't >> pass long double arguments in the right registers). I expect to have >> it finished in the next few days. > Excellent! Let me know if I can be of service testing your patch. Thanks. It's taking longer than I expected, because I hadn't realized IRIX actually used a different 128-bit long double format than IEEE 854 long double, which I had blindly assumed. I've now introduced support for both in my copy of gcc/config/fp-bit.c, and adjusted the function-calling conventions, but this happened to uncover a number of problems in GCC. Some had to do with the inability to get PARALLELs in return values of libcalls, which I've already fixed. The other has to do with some gcse problems that, because of some gratuitous copying introduced inside such libcalls when PARALLELs are used, it ends up replacing uses of the REG_RETVAL of the libcall with uses of a pseudo internal to the libcall. Then, the RETVAL ends up dead, and we delete the entire libcall sequence. Oops :-) I've worked around that too, but I'm still observing mis-compilation of the multiply code, in what appears to be another gcse/libcall problem, or perhaps just another occurrence of the same problem, that happens not to be worked around with the fixes I've put in. > I definitely support fixing the ABI, perhaps even on the 3.3 branch if > the patch is not too invasive. None of the patches seem risky, and they actually do fix real bugs, but, the more code I have to tweak, the less likely I fell this will find its way into the 3.3 branch :-( -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2002-12-21 10:45 ` Alexandre Oliva @ 2002-12-22 6:02 ` Kaveh R. Ghazi 2002-12-22 10:24 ` Alexandre Oliva 1 sibling, 0 replies; 72+ messages in thread From: Kaveh R. Ghazi @ 2002-12-22 6:02 UTC (permalink / raw) To: aoliva; +Cc: gcc-bugs, gcc, libstdc++, oldham, ro > From: Alexandre Oliva <aoliva@redhat.com> > > On Dec 17, 2002, "Kaveh R. Ghazi" <ghazi@caip.rutgers.edu> wrote: > > > I definitely support fixing the ABI, perhaps even on the 3.3 branch if > > the patch is not too invasive. > > None of the patches seem risky, and they actually do fix real bugs, > but, the more code I have to tweak, the less likely I fell this will > find its way into the 3.3 branch :-( Well, that can be evaluated once you post the patch. Perhaps if you split it into pieces, each addressing separate problems it might help the reviewer "see" that each piece is safe. Obviously, if you can create testcases separate from your mips work that triggers some problem or crash that would help smooth the way for each of these extra fixes. In any case, even just having your work on the trunk is mega-better than the current situation. So thanks a lot for working on this. --Kaveh -- Kaveh R. Ghazi ghazi@caip.rutgers.edu ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2002-12-21 10:45 ` Alexandre Oliva 2002-12-22 6:02 ` Kaveh R. Ghazi @ 2002-12-22 10:24 ` Alexandre Oliva 2002-12-22 10:35 ` Alexandre Oliva 2002-12-23 9:46 ` Alexandre Oliva 1 sibling, 2 replies; 72+ messages in thread From: Alexandre Oliva @ 2002-12-22 10:24 UTC (permalink / raw) To: Kaveh R. Ghazi, gcc-patches; +Cc: gcc-bugs, gcc, libstdc++, oldham, ro [-- Attachment #1: Type: text/plain, Size: 2190 bytes --] On Dec 21, 2002, Alexandre Oliva <aoliva@redhat.com> wrote: > The other has to do with some gcse problems that, because of some > gratuitous copying introduced inside such libcalls when PARALLELs > are used, it ends up replacing uses of the REG_RETVAL of the libcall > with uses of a pseudo internal to the libcall. Then, the RETVAL > ends up dead, and we delete the entire libcall sequence. Oops :-) It turned out that it wasn't gcse's fault, but rather a problem in open-coded add/sub operations for wide types that failed to store the result of a wide add/sub computation in the target without returning the location of the result to the caller. Oops. >> I definitely support fixing the ABI, perhaps even on the 3.3 branch if >> the patch is not too invasive. > None of the patches seem risky, and they actually do fix real bugs, > but, the more code I have to tweak, the less likely I fell this will > find its way into the 3.3 branch :-( s/fell/feel/ Anyway, I'm more confident about being able to get this patch in than what I had last night, since I could revert the most intrusive parts after fixing the aforementioned bug. The result is almost pretty. Tested in the 3.3 branch with a mips-sgi-irix6.5 bootstrap, as well as by visual inspection of the assembly code emitted for some of the attached source programs, as well as by execution of the programs that contained main(). I feel I may be missing some additional rounding in the code that packs back to the native long double format of irix, but I've now idea of how to tell whether it's actually necessary. Do any FP experts care to comment? Oh, it would probably be appropriate for us to use the native long double function calls on IRIX, but since I was implementing this for a different operating system, and I wanted to make sure the implementation was compatible with that of IRIX, I didn't make the effort to use the native IRIX library. I'll leave that as an exercise for those who actually care about long double performance on IRIX. The performance of the current implementation is probably awful, especially on multiplies and divides. Get it right first, optimize later, if ever :-D Ok to install? [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: gcc-mips-tfmode-emul.patch --] [-- Type: text/x-patch, Size: 40952 bytes --] ? gcc/config/mips/_tilib.c Index: gcc/ChangeLog from Alexandre Oliva <aoliva@redhat.com> * config/mips/mips.h (LONG_DUBLE_TYPE_SIZE): Set to 128 on N32 and N64. (MAX_FIXED_MODE_SIZE): Define to LONG_DOUBLE_TYPE_SIZE. (LIBGCC2_LONG_DOUBLE_TYPE_SIZE): Define. (BIGGEST_ALIGNMENT): Same as LONG_DOUBLE_TYPE_SIZE. (FUNCTION_VALUE_REGNO_P): Set for FP_RETURN+2 on N32 and N64. * config/mips/mips.c (mips_arg_info): Pass TFmode values in even FP registers on N32 and N64. (override_options): Set TFmode format. Set it as allowable in FP registers. (mips_function_value): Return TFmode in $f0 and $f2 on N32 or N64. * config/mips/_tilib.c (__negti2, __ashlti3, __lshrti3): New. * config/mips/t-iris6 (LIB2FUNCS_EXTRA): Add _tilib.c. (TPBIT): Set to tp-bit.c. (tp-bit.c): Create out of fp-bit.c. * Makefile.in (FPBIT_FUNCS): Added _sf_to_tf. (DBBIT_FUNCS): Added _df_to_tf. (TPBIT_FUNCS): New. (libgcc.mk): Pass TPBIT and TPBIT_FUNCS down. (LIBGCC_DEPS): Added TPBIT. * mklibgcc.in: Support TPBIT and TPBIT_FUNCS. * fp-bit.h: Define macros for TFmode floating-point constants in IEEE and IBM-extended TFmode types. Declare functions according to L_ macros. (TMODES): Define if __LDBL_MANT_DIG__ has one of the newly-supported widths. (TFtype, TItype, UTItype): Define if TMODES is defined. (MAX_UDI_INT, MAX_DI_INT, BITS_PER_DI): Likewise. (F_T_BITOFF, D_T_BITOFF): Define. (IMPLICIT_1, IMPLICIT_2): Cast constants to types that are guaranteed to be wide enough. * config/fp-bit.c: Check for L_ macros for tf functions. (__thenan_tf): New. (nan): Adjust. (pack_d, unpack_d): Support IEEE and IBM-extended TFmode types. (_fpmul_parts): Support TFmode. (usi_to_float): Cast constants to be shifted to fractype instead of assuming long long is wide enough. (sf_to_tf, df_to_tf, __make_tp, tf_to_df, tf_to_sf): New. * print-rtl.c (print_rtx): Don't print MEM details in GENERATOR_FILEs. * rtl.c (get_mode_alignment): Moved to... * stor-layout.c: ... here. * calls.c (emit_library_call_value_1): Handle return values in a PARALLEL. * expr.c (emit_group_store): Initialize dst with CONST0_RTX for the appropriate mode. * optabs.c (expand_binop) <add, sub>: Return xtarget if we haven't been able to move the result to target. Index: gcc/Makefile.in =================================================================== RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v retrieving revision 1.958 diff -u -p -r1.958 Makefile.in --- gcc/Makefile.in 24 Nov 2002 20:43:01 -0000 1.958 +++ gcc/Makefile.in 22 Dec 2002 03:38:03 -0000 @@ -796,12 +796,17 @@ LIB2FUNCS_ST = _eprintf _bb __gcc_bcmp FPBIT_FUNCS = _pack_sf _unpack_sf _addsub_sf _mul_sf _div_sf \ _fpcmp_parts_sf _compare_sf _eq_sf _ne_sf _gt_sf _ge_sf \ _lt_sf _le_sf _unord_sf _si_to_sf _sf_to_si _negate_sf _make_sf \ - _sf_to_df _thenan_sf _sf_to_usi _usi_to_sf + _sf_to_df _sf_to_tf _thenan_sf _sf_to_usi _usi_to_sf DPBIT_FUNCS = _pack_df _unpack_df _addsub_df _mul_df _div_df \ _fpcmp_parts_df _compare_df _eq_df _ne_df _gt_df _ge_df \ _lt_df _le_df _unord_df _si_to_df _df_to_si _negate_df _make_df \ - _df_to_sf _thenan_df _df_to_usi _usi_to_df + _df_to_sf _df_to_tf _thenan_df _df_to_usi _usi_to_df + +TPBIT_FUNCS = _pack_tf _unpack_tf _addsub_tf _mul_tf _div_tf \ + _fpcmp_parts_tf _compare_tf _eq_tf _ne_tf _gt_tf _ge_tf \ + _lt_tf _le_tf _unord_tf _si_to_tf _tf_to_si _negate_tf _make_tf \ + _tf_to_df _tf_to_sf _thenan_tf _tf_to_usi _usi_to_tf # These might cause a divide overflow trap and so are compiled with # unwinder info. @@ -1021,6 +1026,8 @@ libgcc.mk: config.status Makefile mklibg LIB2_DIVMOD_FUNCS='$(LIB2_DIVMOD_FUNCS)' \ DPBIT='$(DPBIT)' \ DPBIT_FUNCS='$(DPBIT_FUNCS)' \ + TPBIT='$(TPBIT)' \ + TPBIT_FUNCS='$(TPBIT_FUNCS)' \ MULTILIBS=`$(GCC_FOR_TARGET) --print-multi-lib` \ EXTRA_MULTILIB_PARTS='$(EXTRA_MULTILIB_PARTS)' \ SHLIB_LINK='$(SHLIB_LINK)' \ @@ -1040,8 +1047,9 @@ libgcc.mk: config.status Makefile mklibg LIBGCC_DEPS = $(GCC_PASSES) $(LANGUAGES) stmp-int-hdrs $(STMP_FIXPROTO) \ libgcc.mk $(srcdir)/libgcc2.c $(TCONFIG_H) \ $(MACHMODE_H) longlong.h gbl-ctors.h config.status stmp-int-hdrs \ - tsystem.h $(FPBIT) $(DPBIT) $(LIB2ADD) $(LIB2ADD_ST) $(LIB2ADDEH) \ - $(LIB2ADDEHDEP) $(EXTRA_PARTS) $(srcdir)/config/$(LIB1ASMSRC) + tsystem.h $(FPBIT) $(DPBIT) $(TPBIT) $(LIB2ADD) \ + $(LIB2ADD_ST) $(LIB2ADDEH) $(LIB2ADDEHDEP) $(EXTRA_PARTS) \ + $(srcdir)/config/$(LIB1ASMSRC) libgcc.a: $(LIBGCC_DEPS) $(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \ Index: gcc/calls.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/calls.c,v retrieving revision 1.244 diff -u -p -r1.244 calls.c --- gcc/calls.c 9 Dec 2002 17:54:03 -0000 1.244 +++ gcc/calls.c 22 Dec 2002 03:38:08 -0000 @@ -4131,7 +4131,7 @@ emit_library_call_value_1 (retval, orgfu { rtx insns; - if (valreg == 0 || GET_CODE (valreg) == PARALLEL) + if (valreg == 0) { insns = get_insns (); end_sequence (); @@ -4140,9 +4140,18 @@ emit_library_call_value_1 (retval, orgfu else { rtx note = 0; - rtx temp = gen_reg_rtx (GET_MODE (valreg)); + rtx temp; int i; + if (GET_CODE (valreg) == PARALLEL) + { + temp = gen_reg_rtx (outmode); + emit_group_store (temp, valreg, outmode); + valreg = temp; + } + + temp = gen_reg_rtx (GET_MODE (valreg)); + /* Construct an "equal form" for the value which mentions all the arguments in order as well as the function name. */ for (i = 0; i < nargs; i++) @@ -4175,6 +4184,12 @@ emit_library_call_value_1 (retval, orgfu value = mem_value; if (value != mem_value) emit_move_insn (value, mem_value); + } + else if (GET_CODE (valreg) == PARALLEL) + { + if (value == 0) + value = gen_reg_rtx (outmode); + emit_group_store (value, valreg, outmode); } else if (value != 0) emit_move_insn (value, valreg); Index: gcc/expr.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/expr.c,v retrieving revision 1.498 diff -u -p -r1.498 expr.c --- gcc/expr.c 13 Dec 2002 00:17:18 -0000 1.498 +++ gcc/expr.c 22 Dec 2002 03:38:19 -0000 @@ -2436,7 +2436,7 @@ emit_group_store (orig_dst, src, ssize) { dst = gen_reg_rtx (GET_MODE (orig_dst)); /* Make life a bit easier for combine. */ - emit_move_insn (dst, const0_rtx); + emit_move_insn (dst, CONST0_RTX (GET_MODE (orig_dst))); } /* Process the pieces. */ Index: gcc/mklibgcc.in =================================================================== RCS file: /cvs/gcc/gcc/gcc/mklibgcc.in,v retrieving revision 1.48 diff -u -p -r1.48 mklibgcc.in --- gcc/mklibgcc.in 3 Oct 2002 20:35:13 -0000 1.48 +++ gcc/mklibgcc.in 22 Dec 2002 03:38:19 -0000 @@ -21,6 +21,8 @@ # LIB2_DIVMOD_FUNCS # DPBIT # DPBIT_FUNCS +# TPBIT +# TPBIT_FUNCS # LIBGCC # MULTILIBS # EXTRA_MULTILIB_PARTS @@ -169,6 +171,21 @@ if [ "$DPBIT" ]; then echo $out: $DPBIT $fpbit_c_dep echo " $gcc_compile" -DFINE_GRAINED_LIBRARIES $flags -DL$name \ -c $DPBIT -o $out + done + libgcc2_objs="$libgcc2_objs ${name}${objext}" + done +fi + +if [ "$TPBIT" ]; then + for name in $TPBIT_FUNCS; do + for ml in $MULTILIBS; do + dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'` + flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`; + out="libgcc/${dir}/${name}${objext}" + + echo $out: $TPBIT $fpbit_c_dep + echo " $gcc_compile" -DFINE_GRAINED_LIBRARIES $flags -DL$name \ + -c $TPBIT -o $out done libgcc2_objs="$libgcc2_objs ${name}${objext}" done Index: gcc/optabs.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/optabs.c,v retrieving revision 1.153 diff -u -p -r1.153 optabs.c --- gcc/optabs.c 20 Nov 2002 21:52:59 -0000 1.153 +++ gcc/optabs.c 22 Dec 2002 03:38:22 -0000 @@ -1306,6 +1306,8 @@ expand_binop (mode, binoptab, op0, op1, copy_rtx (xop0), copy_rtx (xop1))); } + else + target = xtarget; return target; } Index: gcc/print-rtl.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/print-rtl.c,v retrieving revision 1.91 diff -u -p -r1.91 print-rtl.c --- gcc/print-rtl.c 16 Oct 2002 00:40:27 -0000 1.91 +++ gcc/print-rtl.c 22 Dec 2002 03:38:22 -0000 @@ -1,5 +1,5 @@ /* Print RTL for GNU C Compiler. - Copyright (C) 1987, 1988, 1992, 1997, 1998, 1999, 2000 + Copyright (C) 1987, 1988, 1992, 1997, 1998, 1999, 2000, 2002 Free Software Foundation, Inc. This file is part of GCC. @@ -491,6 +491,7 @@ print_rtx (in_rtx) switch (GET_CODE (in_rtx)) { +#ifndef GENERATOR_FILE case MEM: fputs (" [", outfile); fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, MEM_ALIAS_SET (in_rtx)); @@ -518,7 +519,6 @@ print_rtx (in_rtx) fputc (']', outfile); break; -#ifndef GENERATOR_FILE case CONST_DOUBLE: if (FLOAT_MODE_P (GET_MODE (in_rtx))) { Index: gcc/rtl.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/rtl.c,v retrieving revision 1.120 diff -u -p -r1.120 rtl.c --- gcc/rtl.c 14 Oct 2002 02:36:25 -0000 1.120 +++ gcc/rtl.c 22 Dec 2002 03:38:23 -0000 @@ -396,29 +396,6 @@ shallow_copy_rtx (orig) return copy; } - -/* Return the alignment of MODE. This will be bounded by 1 and - BIGGEST_ALIGNMENT. */ - -unsigned int -get_mode_alignment (mode) - enum machine_mode mode; -{ - unsigned int alignment; - - if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT - || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT) - alignment = GET_MODE_UNIT_SIZE (mode); - else - alignment = GET_MODE_SIZE (mode); - - /* Extract the LSB of the size. */ - alignment = alignment & -alignment; - alignment *= BITS_PER_UNIT; - - alignment = MIN (BIGGEST_ALIGNMENT, MAX (1, alignment)); - return alignment; -} \f /* This is 1 until after the rtl generation pass. */ int rtx_equal_function_value_matters; Index: gcc/stor-layout.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/stor-layout.c,v retrieving revision 1.134 diff -u -p -r1.134 stor-layout.c --- gcc/stor-layout.c 20 Nov 2002 10:09:00 -0000 1.134 +++ gcc/stor-layout.c 22 Dec 2002 03:38:24 -0000 @@ -298,6 +298,29 @@ int_mode_for_mode (mode) return mode; } +/* Return the alignment of MODE. This will be bounded by 1 and + BIGGEST_ALIGNMENT. */ + +unsigned int +get_mode_alignment (mode) + enum machine_mode mode; +{ + unsigned int alignment; + + if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT + || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT) + alignment = GET_MODE_UNIT_SIZE (mode); + else + alignment = GET_MODE_SIZE (mode); + + /* Extract the LSB of the size. */ + alignment = alignment & -alignment; + alignment *= BITS_PER_UNIT; + + alignment = MIN (BIGGEST_ALIGNMENT, MAX (1, alignment)); + return alignment; +} + /* Return the value of VALUE, rounded up to a multiple of DIVISOR. This can only be applied to objects of a sizetype. */ Index: gcc/config/fp-bit.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/fp-bit.c,v retrieving revision 1.36 diff -u -p -r1.36 fp-bit.c --- gcc/config/fp-bit.c 7 Oct 2002 08:47:09 -0000 1.36 +++ gcc/config/fp-bit.c 22 Dec 2002 03:38:26 -0000 @@ -130,6 +130,10 @@ void __lttf2 (void) { abort(); } const fp_number_type __thenan_sf = { CLASS_SNAN, 0, 0, {(fractype) 0} }; #elif defined L_thenan_df const fp_number_type __thenan_df = { CLASS_SNAN, 0, 0, {(fractype) 0} }; +#elif defined L_thenan_tf +const fp_number_type __thenan_tf = { CLASS_SNAN, 0, 0, {(fractype) 0} }; +#elif defined TFLOAT +extern const fp_number_type __thenan_tf; #elif defined FLOAT extern const fp_number_type __thenan_sf; #else @@ -141,7 +145,9 @@ static fp_number_type * nan (void) { /* Discard the const qualifier... */ -#ifdef FLOAT +#ifdef TFLOAT + return (fp_number_type *) (& __thenan_tf); +#elif defined FLOAT return (fp_number_type *) (& __thenan_sf); #else return (fp_number_type *) (& __thenan_df); @@ -180,7 +186,7 @@ flip_sign ( fp_number_type * x) extern FLO_type pack_d ( fp_number_type * ); -#if defined(L_pack_df) || defined(L_pack_sf) +#if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf) FLO_type pack_d ( fp_number_type * src) { @@ -316,24 +322,80 @@ pack_d ( fp_number_type * src) dst.bits.exp = exp; dst.bits.sign = sign; #else +# if defined TFLOAT && defined HALFFRACBITS + { + halffractype high, low; + + high = (fraction >> (FRACBITS - HALFFRACBITS)); + high &= (((fractype)1) << HALFFRACBITS) - 1; + high |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << HALFFRACBITS; + high |= ((fractype) (sign & 1)) << (HALFFRACBITS | EXPBITS); + + low = (halffractype)fraction & + ((((halffractype)1) << (FRACBITS - HALFFRACBITS)) - 1); + + if (exp == EXPMAX || exp == 0 || low == 0) + low = 0; + else + { + const int ngards = FRACBITS - 2 * HALFFRACBITS - 1; + + exp -= HALFFRACBITS + 1; + + while (low < ((halffractype)1 << (HALFFRACBITS + ngards))) + { + low <<= 1; + exp--; + } + + if (exp < -HALFFRACBITS) + low = exp = sign = 0; + else if (exp < 0) + { + low >>= -exp; + exp = 0; + } + + low >>= ngards; + + low &= ((halffractype)1 << HALFFRACBITS) - 1; + low |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << HALFFRACBITS; + low |= ((fractype) (sign & 1)) << (HALFFRACBITS | EXPBITS); + } + + dst.value_raw = (((fractype) high) << HALFSHIFT) | low; + } +# else dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1); dst.value_raw |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << FRACBITS; dst.value_raw |= ((fractype) (sign & 1)) << (FRACBITS | EXPBITS); +# endif #endif #if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT) +#ifdef TFLOAT + { + qrtrfractype tmp1 = dst.words[0]; + qrtrfractype tmp2 = dst.words[1]; + dst.words[0] = dst.words[3]; + dst.words[1] = dst.words[2]; + dst.words[2] = tmp2; + dst.words[3] = tmp1; + } +#else { halffractype tmp = dst.words[0]; dst.words[0] = dst.words[1]; dst.words[1] = tmp; } #endif +#endif return dst.value; } #endif -#if defined(L_unpack_df) || defined(L_unpack_sf) +#if defined(L_unpack_df) || defined(L_unpack_sf) || defined(L_unpack_tf) void unpack_d (FLO_union_type * src, fp_number_type * dst) { @@ -347,8 +409,15 @@ unpack_d (FLO_union_type * src, fp_numbe #if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT) FLO_union_type swapped; +#ifdef TFLOAT + swapped.words[0] = src->words[3]; + swapped.words[1] = src->words[2]; + swapped.words[2] = src->words[1]; + swapped.words[3] = src->words[0]; +#else swapped.words[0] = src->words[1]; swapped.words[1] = src->words[0]; +#endif src = &swapped; #endif @@ -357,9 +426,34 @@ unpack_d (FLO_union_type * src, fp_numbe exp = src->bits.exp; sign = src->bits.sign; #else - fraction = src->value_raw & ((((fractype)1) << FRACBITS) - (fractype)1); +# if defined TFLOAT && defined HALFFRACBITS + { + halffractype high, low; + + high = src->value_raw >> HALFSHIFT; + low = src->value_raw & (((fractype)1 << HALFSHIFT) - 1); + + fraction = high & ((((fractype)1) << HALFFRACBITS) - 1); + fraction <<= FRACBITS - HALFFRACBITS; + exp = ((int)(high >> HALFFRACBITS)) & ((1 << EXPBITS) - 1); + sign = ((int)(high >> (((HALFFRACBITS + EXPBITS))))) & 1; + + if (exp != EXPMAX && exp != 0 && low != 0) + { + int lowexp = ((int)(low >> HALFFRACBITS)) & ((1 << EXPBITS) - 1); + + low &= (((fractype)1) << HALFFRACBITS) - 1; + if (lowexp) + low |= ((halffractype)1) << HALFFRACBITS; + fraction |= ((fractype)low << (FRACBITS - HALFFRACBITS)) + >> (exp - lowexp); + } + } +# else + fraction = src->value_raw & ((((fractype)1) << FRACBITS) - 1); exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1); sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1; +# endif #endif dst->sign = sign; @@ -427,7 +521,7 @@ unpack_d (FLO_union_type * src, fp_numbe } #endif /* L_unpack_df || L_unpack_sf */ -#if defined(L_addsub_sf) || defined(L_addsub_df) +#if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf) static fp_number_type * _fpadd_parts (fp_number_type * a, fp_number_type * b, @@ -611,7 +705,7 @@ sub (FLO_type arg_a, FLO_type arg_b) } #endif /* L_addsub_sf || L_addsub_df */ -#if defined(L_mul_sf) || defined(L_mul_df) +#if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf) static inline __attribute__ ((__always_inline__)) fp_number_type * _fpmul_parts ( fp_number_type * a, fp_number_type * b, @@ -660,7 +754,7 @@ _fpmul_parts ( fp_number_type * a, /* Calculate the mantissa by multiplying both numbers to get a twice-as-wide number. */ { -#if defined(NO_DI_MODE) +#if defined(NO_DI_MODE) || defined(TFLOAT) { fractype x = a->fraction.ll; fractype ylow = b->fraction.ll; @@ -725,7 +819,9 @@ _fpmul_parts ( fp_number_type * a, tmp->normal_exp = a->normal_exp + b->normal_exp; tmp->sign = a->sign != b->sign; -#ifdef FLOAT +#ifdef TFLOAT + tmp->normal_exp += 6; /* ??????????????? */ +#elif defined FLOAT tmp->normal_exp += 2; /* ??????????????? */ #else tmp->normal_exp += 4; /* ??????????????? */ @@ -803,7 +899,7 @@ multiply (FLO_type arg_a, FLO_type arg_b } #endif /* L_mul_sf || L_mul_df */ -#if defined(L_div_sf) || defined(L_div_df) +#if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf) static inline __attribute__ ((__always_inline__)) fp_number_type * _fpdiv_parts (fp_number_type * a, fp_number_type * b) @@ -913,7 +1009,8 @@ divide (FLO_type arg_a, FLO_type arg_b) } #endif /* L_div_sf || L_div_df */ -#if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) +#if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) \ + || defined(L_fpcmp_parts_tf) /* according to the demo, fpcmp returns a comparison with 0... thus a<b -> -1 a==b -> 0 @@ -998,7 +1095,7 @@ __fpcmp_parts (fp_number_type * a, fp_nu } #endif -#if defined(L_compare_sf) || defined(L_compare_df) +#if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compoare_tf) CMPtype compare (FLO_type arg_a, FLO_type arg_b) { @@ -1020,7 +1117,7 @@ compare (FLO_type arg_a, FLO_type arg_b) /* These should be optimized for their specific tasks someday. */ -#if defined(L_eq_sf) || defined(L_eq_df) +#if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf) CMPtype _eq_f2 (FLO_type arg_a, FLO_type arg_b) { @@ -1041,7 +1138,7 @@ _eq_f2 (FLO_type arg_a, FLO_type arg_b) } #endif /* L_eq_sf || L_eq_df */ -#if defined(L_ne_sf) || defined(L_ne_df) +#if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf) CMPtype _ne_f2 (FLO_type arg_a, FLO_type arg_b) { @@ -1062,7 +1159,7 @@ _ne_f2 (FLO_type arg_a, FLO_type arg_b) } #endif /* L_ne_sf || L_ne_df */ -#if defined(L_gt_sf) || defined(L_gt_df) +#if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf) CMPtype _gt_f2 (FLO_type arg_a, FLO_type arg_b) { @@ -1083,7 +1180,7 @@ _gt_f2 (FLO_type arg_a, FLO_type arg_b) } #endif /* L_gt_sf || L_gt_df */ -#if defined(L_ge_sf) || defined(L_ge_df) +#if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf) CMPtype _ge_f2 (FLO_type arg_a, FLO_type arg_b) { @@ -1103,7 +1200,7 @@ _ge_f2 (FLO_type arg_a, FLO_type arg_b) } #endif /* L_ge_sf || L_ge_df */ -#if defined(L_lt_sf) || defined(L_lt_df) +#if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf) CMPtype _lt_f2 (FLO_type arg_a, FLO_type arg_b) { @@ -1124,7 +1221,7 @@ _lt_f2 (FLO_type arg_a, FLO_type arg_b) } #endif /* L_lt_sf || L_lt_df */ -#if defined(L_le_sf) || defined(L_le_df) +#if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf) CMPtype _le_f2 (FLO_type arg_a, FLO_type arg_b) { @@ -1147,7 +1244,7 @@ _le_f2 (FLO_type arg_a, FLO_type arg_b) #endif /* ! US_SOFTWARE_GOFAST */ -#if defined(L_unord_sf) || defined(L_unord_df) +#if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf) CMPtype _unord_f2 (FLO_type arg_a, FLO_type arg_b) { @@ -1165,7 +1262,7 @@ _unord_f2 (FLO_type arg_a, FLO_type arg_ } #endif /* L_unord_sf || L_unord_df */ -#if defined(L_si_to_sf) || defined(L_si_to_df) +#if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf) FLO_type si_to_float (SItype arg_a) { @@ -1193,7 +1290,7 @@ si_to_float (SItype arg_a) else in.fraction.ll = arg_a; - while (in.fraction.ll < (1LL << (FRACBITS + NGARDS))) + while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS))) { in.fraction.ll <<= 1; in.normal_exp -= 1; @@ -1203,7 +1300,7 @@ si_to_float (SItype arg_a) } #endif /* L_si_to_sf || L_si_to_df */ -#if defined(L_usi_to_sf) || defined(L_usi_to_df) +#if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf) FLO_type usi_to_float (USItype arg_a) { @@ -1220,12 +1317,12 @@ usi_to_float (USItype arg_a) in.normal_exp = FRACBITS + NGARDS; in.fraction.ll = arg_a; - while (in.fraction.ll > (1LL << (FRACBITS + NGARDS))) + while (in.fraction.ll > ((fractype)1 << (FRACBITS + NGARDS))) { in.fraction.ll >>= 1; in.normal_exp += 1; } - while (in.fraction.ll < (1LL << (FRACBITS + NGARDS))) + while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS))) { in.fraction.ll <<= 1; in.normal_exp -= 1; @@ -1235,7 +1332,7 @@ usi_to_float (USItype arg_a) } #endif -#if defined(L_sf_to_si) || defined(L_df_to_si) +#if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si) SItype float_to_si (FLO_type arg_a) { @@ -1263,8 +1360,8 @@ float_to_si (FLO_type arg_a) } #endif /* L_sf_to_si || L_df_to_si */ -#if defined(L_sf_to_usi) || defined(L_df_to_usi) -#ifdef US_SOFTWARE_GOFAST +#if defined(L_sf_to_usi) || defined(L_df_to_usi) || defined(L_tf_to_usi) +#if defined US_SOFTWARE_GOFAST || defined(L_tf_to_usi) /* While libgcc2.c defines its own __fixunssfsi and __fixunsdfsi routines, we also define them for GOFAST because the ones in libgcc2.c have the wrong names and I'd rather define these here and keep GOFAST CYG-LOC's @@ -1303,7 +1400,7 @@ float_to_usi (FLO_type arg_a) #endif /* US_SOFTWARE_GOFAST */ #endif /* L_sf_to_usi || L_df_to_usi */ -#if defined(L_negate_sf) || defined(L_negate_df) +#if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf) FLO_type negate (FLO_type arg_a) { @@ -1359,6 +1456,21 @@ sf_to_df (SFtype arg_a) } #endif /* L_sf_to_df */ +#if defined(L_sf_to_tf) && defined(TMODES) +TFtype +sf_to_tf (SFtype arg_a) +{ + fp_number_type in; + FLO_union_type au; + + au.value = arg_a; + unpack_d (&au, &in); + + return __make_tp (in.class, in.sign, in.normal_exp, + ((UTItype) in.fraction.ll) << F_T_BITOFF); +} +#endif /* L_sf_to_df */ + #endif /* ! FLOAT_ONLY */ #endif /* FLOAT */ @@ -1401,6 +1513,85 @@ df_to_sf (DFtype arg_a) return __make_fp (in.class, in.sign, in.normal_exp, sffrac); } #endif /* L_df_to_sf */ + +#if defined(L_df_to_tf) && defined(TMODES) \ + && !defined(FLOAT) && !defined(TFLOAT) +TFtype +df_to_tf (DFtype arg_a) +{ + fp_number_type in; + FLO_union_type au; + + au.value = arg_a; + unpack_d (&au, &in); + + return __make_tp (in.class, in.sign, in.normal_exp, + ((UTItype) in.fraction.ll) << D_T_BITOFF); +} +#endif /* L_sf_to_df */ + +#ifdef TFLOAT +#if defined(L_make_tf) +TFtype +__make_tp(fp_class_type class, + unsigned int sign, + int exp, + UTItype frac) +{ + fp_number_type in; + + in.class = class; + in.sign = sign; + in.normal_exp = exp; + in.fraction.ll = frac; + return pack_d (&in); +} +#endif /* L_make_tf */ + +#if defined(L_tf_to_df) +DFtype +tf_to_df (TFtype arg_a) +{ + fp_number_type in; + UDItype sffrac; + FLO_union_type au; + + au.value = arg_a; + unpack_d (&au, &in); + + sffrac = in.fraction.ll >> D_T_BITOFF; + + /* We set the lowest guard bit in SFFRAC if we discarded any non + zero bits. */ + if ((in.fraction.ll & (((UTItype) 1 << D_T_BITOFF) - 1)) != 0) + sffrac |= 1; + + return __make_dp (in.class, in.sign, in.normal_exp, sffrac); +} +#endif /* L_tf_to_df */ + +#if defined(L_tf_to_sf) +SFtype +tf_to_sf (TFtype arg_a) +{ + fp_number_type in; + USItype sffrac; + FLO_union_type au; + + au.value = arg_a; + unpack_d (&au, &in); + + sffrac = in.fraction.ll >> F_T_BITOFF; + + /* We set the lowest guard bit in SFFRAC if we discarded any non + zero bits. */ + if ((in.fraction.ll & (((UTItype) 1 << F_T_BITOFF) - 1)) != 0) + sffrac |= 1; + + return __make_fp (in.class, in.sign, in.normal_exp, sffrac); +} +#endif /* L_tf_to_sf */ +#endif /* TFLOAT */ #endif /* ! FLOAT */ #endif /* !EXTENDED_FLOAT_STUBS */ Index: gcc/config/fp-bit.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/fp-bit.h,v retrieving revision 1.7 diff -u -p -r1.7 fp-bit.h --- gcc/config/fp-bit.h 19 Jun 2002 23:01:59 -0000 1.7 +++ gcc/config/fp-bit.h 22 Dec 2002 03:38:26 -0000 @@ -1,5 +1,5 @@ /* Header file for fp-bit.c. */ -/* Copyright (C) 2000 +/* Copyright (C) 2000, 2002 Free Software Foundation, Inc. This file is part of GNU CC. @@ -87,12 +87,22 @@ Boston, MA 02111-1307, USA. */ #endif #endif /* ! FINE_GRAINED_LIBRARIES */ +#if __LDBL_MANT_DIG__ == 113 || __LDBL_MANT_DIG__ == 106 +# define TMODES +#endif + typedef float SFtype __attribute__ ((mode (SF))); typedef float DFtype __attribute__ ((mode (DF))); +#ifdef TMODES +typedef float TFtype __attribute__ ((mode (TF))); +#endif typedef int HItype __attribute__ ((mode (HI))); typedef int SItype __attribute__ ((mode (SI))); typedef int DItype __attribute__ ((mode (DI))); +#ifdef TMODES +typedef int TItype __attribute__ ((mode (TI))); +#endif /* The type of the result of a fp compare */ #ifndef CMPtype @@ -102,16 +112,68 @@ typedef int DItype __attribute__ ((mode typedef unsigned int UHItype __attribute__ ((mode (HI))); typedef unsigned int USItype __attribute__ ((mode (SI))); typedef unsigned int UDItype __attribute__ ((mode (DI))); +#ifdef TMODES +typedef unsigned int UTItype __attribute__ ((mode (TI))); +#endif #define MAX_USI_INT (~(USItype)0) #define MAX_SI_INT ((SItype) (MAX_USI_INT >> 1)) #define BITS_PER_SI (4 * BITS_PER_UNIT) +#ifdef TMODES +#define MAX_UDI_INT (~(UDItype)0) +#define MAX_DI_INT ((DItype) (MAX_UDI_INT >> 1)) +#define BITS_PER_DI (8 * BITS_PER_UNIT) +#endif #ifdef FLOAT_ONLY #define NO_DI_MODE #endif -#ifdef FLOAT +#ifdef TFLOAT +# ifndef TMODES +# error "TFLOAT requires long double to have 113 bits of mantissa" +# endif + +# define PREFIXFPDP tp +# define PREFIXSFDF tf +# define NGARDS 10L /* Is this right? */ +# define GARDROUND 0x1ff +# define GARDMASK 0x3ff +# define GARDMSB 0x200 +# define FRAC_NBITS 128 + +# if __LDBL_MANT_DIG__ == 113 /* IEEE quad */ +# define EXPBITS 15 +# define EXPBIAS 16383 +# define EXPMAX (0x7fff) +# define QUIET_NAN ((TItype)0x8 << 108) +# define FRACHIGH ((TItype)0x8 << 124) +# define FRACHIGH2 ((TItype)0xc << 124) +# define FRACBITS 112 +# endif + +# if __LDBL_MANT_DIG__ == 106 /* IBM extended (double+double) */ +# define EXPBITS 11 +# define EXPBIAS 1023 +# define EXPMAX (0x7ff) +# define QUIET_NAN ((TItype)0x8 << (48 + 64)) +# define FRACHIGH ((TItype)0x8 << 124) +# define FRACHIGH2 ((TItype)0xc << 124) +# define FRACBITS 112 +# define HALFFRACBITS 52 +# define HALFSHIFT 64 +# endif + +# define pack_d __pack_t +# define unpack_d __unpack_t +# define __fpcmp_parts __fpcmp_parts_t + typedef UTItype fractype; + typedef UDItype halffractype; + typedef USItype qrtrfractype; +#define qrtrfractype qrtrfractype + typedef TFtype FLO_type; + typedef TItype intfrac; +#elif defined FLOAT # define NGARDS 7L # define GARDROUND 0x3f # define GARDMASK 0x7f @@ -157,7 +219,9 @@ typedef unsigned int UDItype __attribute #endif /* FLOAT */ #ifdef US_SOFTWARE_GOFAST -# ifdef FLOAT +# ifdef TFLOAT +# error "GOFAST TFmode not supported" +# elif defined FLOAT # define add fpadd # define sub fpsub # define multiply fpmul @@ -170,8 +234,8 @@ typedef unsigned int UDItype __attribute # define float_to_usi fptoui # define negate __negsf2 # define sf_to_df fptodp -# define dptofp dptofp -#else +# define sf_to_tf __extendsftf2 +# else # define add dpadd # define sub dpsub # define multiply dpmul @@ -184,9 +248,30 @@ typedef unsigned int UDItype __attribute # define float_to_usi dptoul # define negate __negdf2 # define df_to_sf dptofp +# define df_to_tf __extenddftf2 # endif /* FLOAT */ #else -# ifdef FLOAT +# ifdef TFLOAT +# define add __addtf3 +# define sub __subtf3 +# define multiply __multf3 +# define divide __divtf3 +# define compare __cmptf2 +# define _eq_f2 __eqtf2 +# define _ne_f2 __netf2 +# define _gt_f2 __gttf2 +# define _ge_f2 __getf2 +# define _lt_f2 __lttf2 +# define _le_f2 __letf2 +# define _unord_f2 __unordtf2 +# define usi_to_float __floatunsitf +# define si_to_float __floatsitf +# define float_to_si __fixtfsi +# define float_to_usi __fixunstfsi +# define negate __negtf2 +# define tf_to_sf __trunctfsf2 +# define tf_to_df __trunctfdf2 +# elif defined FLOAT # define add __addsf3 # define sub __subsf3 # define multiply __mulsf3 @@ -205,7 +290,8 @@ typedef unsigned int UDItype __attribute # define float_to_usi __fixunssfsi # define negate __negsf2 # define sf_to_df __extendsfdf2 -#else +# define sf_to_tf __extendsftf2 +# else # define add __adddf3 # define sub __subdf3 # define multiply __muldf3 @@ -224,6 +310,7 @@ typedef unsigned int UDItype __attribute # define float_to_usi __fixunsdfsi # define negate __negdf2 # define df_to_sf __truncdfsf2 +# define df_to_tf __extenddftf2 # endif /* FLOAT */ #endif /* US_SOFTWARE_GOFAST */ @@ -240,11 +327,13 @@ typedef unsigned int UDItype __attribute (double::FRAC_BITS+double::NGARDS-(float::FRAC_BITS-float::NGARDS)) */ #define F_D_BITOFF (52+8-(23+7)) +#define F_T_BITOFF (113+10-(23+7)) +#define D_T_BITOFF (113+10-(52+8)) #define NORMAL_EXPMIN (-(EXPBIAS)+1) -#define IMPLICIT_1 (1LL<<(FRACBITS+NGARDS)) -#define IMPLICIT_2 (1LL<<(FRACBITS+1+NGARDS)) +#define IMPLICIT_1 ((fractype)1<<(FRACBITS+NGARDS)) +#define IMPLICIT_2 ((fractype)1<<(FRACBITS+1+NGARDS)) /* common types */ @@ -282,7 +371,11 @@ typedef union fractype value_raw; #ifndef FLOAT +# ifdef qrtrfractype + qrtrfractype qwords[4]; +# else halffractype words[2]; +# endif #endif #ifdef FLOAT_BIT_ORDER_MISMATCH @@ -317,82 +410,82 @@ FLO_union_type; /* Prototypes */ -#if defined(L_pack_df) || defined(L_pack_sf) +#if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf) extern FLO_type pack_d (fp_number_type *); #endif extern void unpack_d (FLO_union_type *, fp_number_type *); -#if defined(L_addsub_sf) || defined(L_addsub_df) +#if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf) extern FLO_type add (FLO_type, FLO_type); extern FLO_type sub (FLO_type, FLO_type); #endif -#if defined(L_mul_sf) || defined(L_mul_df) +#if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf) extern FLO_type multiply (FLO_type, FLO_type); #endif -#if defined(L_div_sf) || defined(L_div_df) +#if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf) extern FLO_type divide (FLO_type, FLO_type); #endif extern int __fpcmp_parts (fp_number_type *, fp_number_type *); -#if defined(L_compare_sf) || defined(L_compare_df) +#if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compare_tf) extern CMPtype compare (FLO_type, FLO_type); #endif #ifndef US_SOFTWARE_GOFAST -#if defined(L_eq_sf) || defined(L_eq_df) +#if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf) extern CMPtype _eq_f2 (FLO_type, FLO_type); #endif -#if defined(L_ne_sf) || defined(L_ne_df) +#if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf) extern CMPtype _ne_f2 (FLO_type, FLO_type); #endif -#if defined(L_gt_sf) || defined(L_gt_df) +#if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf) extern CMPtype _gt_f2 (FLO_type, FLO_type); #endif -#if defined(L_ge_sf) || defined(L_ge_df) +#if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf) extern CMPtype _ge_f2 (FLO_type, FLO_type); #endif -#if defined(L_lt_sf) || defined(L_lt_df) +#if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf) extern CMPtype _lt_f2 (FLO_type, FLO_type); #endif -#if defined(L_le_sf) || defined(L_le_df) +#if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf) extern CMPtype _le_f2 (FLO_type, FLO_type); #endif -#if defined(L_unord_sf) || defined(L_unord_df) +#if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf) extern CMPtype _unord_f2 (FLO_type, FLO_type); #endif #endif /* ! US_SOFTWARE_GOFAST */ -#if defined(L_si_to_sf) || defined(L_si_to_df) +#if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf) extern FLO_type si_to_float (SItype); #endif -#if defined(L_sf_to_si) || defined(L_df_to_si) +#if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si) extern SItype float_to_si (FLO_type); #endif -#if defined(L_sf_to_usi) || defined(L_df_to_usi) +#if defined(L_sf_to_usi) || defined(L_df_to_usi) || defined(L_tf_to_usi) #ifdef US_SOFTWARE_GOFAST extern USItype float_to_usi (FLO_type); #endif #endif -#if defined(L_usi_to_sf) || defined(L_usi_to_df) +#if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf) extern FLO_type usi_to_float (USItype); #endif -#if defined(L_negate_sf) || defined(L_negate_df) +#if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf) extern FLO_type negate (FLO_type); #endif @@ -405,6 +498,9 @@ extern DFtype __make_dp (fp_class_type, #if defined(L_sf_to_df) extern DFtype sf_to_df (SFtype); #endif +#if defined(L_sf_to_tf) && defined(TMODES) +extern TFtype sf_to_tf (SFtype); +#endif #endif /* ! FLOAT_ONLY */ #endif /* FLOAT */ @@ -416,6 +512,24 @@ extern DFtype __make_dp (fp_class_type, #if defined(L_df_to_sf) extern SFtype df_to_sf (DFtype); #endif +#if defined(L_df_to_tf) && defined(TMODES) +extern TFtype df_to_tf (DFtype); +#endif #endif /* ! FLOAT */ + +#if defined TFLOAT && defined(TMODES) +#if defined(L_make_tf) +extern TFtype __make_tp (fp_class_type, unsigned int, int, UTItype); +#endif +#if defined(L_tf_to_sf) +extern SFtype tf_to_sf (TFtype); +#endif +#if defined(L_tf_to_df) +extern DFtype tf_to_df (TFtype); +#endif +#if defined(L_di_to_tf) +extern TFtype di_to_df (DItype); +#endif +#endif #endif /* ! GCC_FP_BIT_H */ Index: gcc/config/mips/mips.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.c,v retrieving revision 1.241 diff -u -p -r1.241 mips.c --- gcc/config/mips/mips.c 12 Dec 2002 05:13:03 -0000 1.241 +++ gcc/config/mips/mips.c 22 Dec 2002 03:38:33 -0000 @@ -4286,7 +4286,9 @@ mips_arg_info (cum, mode, type, named, i info->fpr_p = false; if (GET_MODE_CLASS (mode) == MODE_FLOAT - && GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE) + && GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE * ((mips_abi == ABI_N32 + || mips_abi == ABI_64) + ? 2 : 1)) { switch (mips_abi) { @@ -4321,9 +4323,11 @@ mips_arg_info (cum, mode, type, named, i is a double, but $f14 if it is a single. Otherwise, on a 32-bit double-float machine, each FP argument must start in a new register pair. */ - even_reg_p = ((mips_abi == ABI_O64 && mode == SFmode) || FP_INC > 1); + even_reg_p = (GET_MODE_SIZE (mode) > UNITS_PER_FPVALUE /* TFmode */ + || (mips_abi == ABI_O64 && mode == SFmode) + || FP_INC > 1); } - else if (!TARGET_64BIT) + else if (!TARGET_64BIT || mips_abi == ABI_N32 || mips_abi == ABI_64) { if (GET_MODE_CLASS (mode) == MODE_INT || GET_MODE_CLASS (mode) == MODE_FLOAT) @@ -5365,6 +5369,8 @@ override_options () else mips16 = 0; + real_format_for_mode[TFmode - QFmode] = &ibm_extended_format; + mips_print_operand_punct['?'] = 1; mips_print_operand_punct['#'] = 1; mips_print_operand_punct['&'] = 1; @@ -5454,7 +5460,10 @@ override_options () register. */ || (mips_abi == ABI_MEABI && size <= 4)) && (((class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT) - && size <= UNITS_PER_FPVALUE) + && size <= (UNITS_PER_FPVALUE + * ((mips_abi == ABI_N32 + || mips_abi == ABI_64) + ? 2 : 1))) /* Allow integer modes that fit into a single register. We need to put integers into FPRs when using instructions like cvt and trunc. */ @@ -8271,8 +8280,24 @@ mips_function_value (valtype, func, mode } mclass = GET_MODE_CLASS (mode); - if (mclass == MODE_FLOAT && GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE) + if (mclass == MODE_FLOAT + && GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE) reg = FP_RETURN; + + else if (mclass == MODE_FLOAT + && mode == TFmode + && (mips_abi == ABI_N32 || mips_abi == ABI_64)) + /* long doubles are really split between f0 and f2, not f1. Eek. */ + return gen_rtx_PARALLEL + (VOIDmode, + gen_rtvec (2, + gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_REG (DImode, FP_RETURN), + GEN_INT (0)), + gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_REG (DImode, FP_RETURN + 2), + GEN_INT (GET_MODE_SIZE (mode) / 2)))); + else if (mclass == MODE_COMPLEX_FLOAT && GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE * 2) Index: gcc/config/mips/mips.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.h,v retrieving revision 1.227 diff -u -p -r1.227 mips.h --- gcc/config/mips/mips.h 5 Nov 2002 12:41:52 -0000 1.227 +++ gcc/config/mips/mips.h 22 Dec 2002 03:38:37 -0000 @@ -1535,7 +1535,21 @@ do { \ /* A C expression for the size in bits of the type `long double' on the target machine. If you don't define this, the default is two words. */ -#define LONG_DOUBLE_TYPE_SIZE 64 +#define LONG_DOUBLE_TYPE_SIZE \ + (mips_abi == ABI_N32 || mips_abi == ABI_64 ? 128 : 64) + +/* long double is not a fixed mode, but the idea is that, if we + support long double, we also want a 128-bit integer type. */ +#define MAX_FIXED_MODE_SIZE LONG_DOUBLE_TYPE_SIZE + +#ifdef IN_LIBGCC2 +#if (defined _ABIN32 && _MIPS_SIM == _ABIN32) \ + || (defined _ABI64 && _MIPS_SIM == _ABI64) +# define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 128 +# else +# define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64 +# endif +#endif /* Width in bits of a pointer. See also the macro `Pmode' defined below. */ @@ -1562,7 +1576,8 @@ do { \ #define STRUCTURE_SIZE_BOUNDARY 8 /* There is no point aligning anything to a rounder boundary than this. */ -#define BIGGEST_ALIGNMENT 64 +#define BIGGEST_ALIGNMENT ((mips_abi == ABI_N32 || mips_abi == ABI_64) \ + ? 128 : 64) /* Set this nonzero if move instructions will actually fail to work when given unaligned data. */ @@ -2624,7 +2639,9 @@ extern enum reg_class mips_char_to_class On the MIPS, R2 R3 and F0 F2 are the only register thus used. Currently, R2 and F0 are only implemented here (C has no complex type) */ -#define FUNCTION_VALUE_REGNO_P(N) ((N) == GP_RETURN || (N) == FP_RETURN) +#define FUNCTION_VALUE_REGNO_P(N) ((N) == GP_RETURN || (N) == FP_RETURN \ + || ((mips_abi == ABI_N32 || mips_abi == ABI_64) && FP_RETURN != GP_RETURN \ + && (N) == FP_RETURN + 2)) /* 1 if N is a possible register number for function argument passing. We have no FP argument registers when soft-float. When FP registers Index: gcc/config/mips/t-iris6 =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/mips/t-iris6,v retrieving revision 1.16 diff -u -p -r1.16 t-iris6 --- gcc/config/mips/t-iris6 12 Nov 2002 11:15:48 -0000 1.16 +++ gcc/config/mips/t-iris6 22 Dec 2002 03:38:37 -0000 @@ -18,3 +18,16 @@ CRTSTUFF_T_CFLAGS=-g1 # This is only needed in the static libgcc as a band-aid until gcc correctly # implements the N32/N64 ABI structure passing conventions LIB2FUNCS_STATIC_EXTRA = $(srcdir)/config/mips/irix6-libc-compat.c + +LIB2FUNCS_EXTRA = $(srcdir)/config/mips/_tilib.c + +TPBIT = tp-bit.c + +tp-bit.c: $(srcdir)/config/fp-bit.c + echo '#ifdef __MIPSEL__' > tp-bit.c + echo '# define FLOAT_BIT_ORDER_MISMATCH' >> tp-bit.c + echo '#endif' >> tp-bit.c + echo '#if __LDBL_MANT_DIG__ == 106' >> tp-bit.c + echo '# define TFLOAT' >> tp-bit.c + cat $(srcdir)/config/fp-bit.c >> tp-bit.c + echo '#endif' >> tp-bit.c [-- Attachment #3: Type: text/plain, Size: 289 bytes --] -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2002-12-22 10:24 ` Alexandre Oliva @ 2002-12-22 10:35 ` Alexandre Oliva 2002-12-23 9:46 ` Alexandre Oliva 1 sibling, 0 replies; 72+ messages in thread From: Alexandre Oliva @ 2002-12-22 10:35 UTC (permalink / raw) To: Kaveh R. Ghazi; +Cc: gcc-patches, gcc-bugs, gcc, libstdc++, oldham, ro [-- Attachment #1: Type: text/plain, Size: 405 bytes --] On Dec 22, 2002, Alexandre Oliva <aoliva@redhat.com> wrote: > Tested in the 3.3 branch with a mips-sgi-irix6.5 bootstrap, as well as > by visual inspection of the assembly code emitted for some of the > attached source programs, as well as by execution of the programs that > contained main(). Err... These programs. I tested variations of the last one to get more coverage of arithmetic operations. [-- Attachment #2: fpcst.c --] [-- Type: application/octet-stream, Size: 169 bytes --] long double one = 1; long double two = 2; long double minus_one = -1; long double onek = 1024; long double onemeg = 1048576; long double small = 0.1234567890123456789l; [-- Attachment #3: fpabi.c --] [-- Type: application/octet-stream, Size: 97 bytes --] #include <stdio.h> main() { long double i = 1.0l, j = 1.12345l; printf("%Lf %Lf\n", i, j); } [-- Attachment #4: fpprint.c --] [-- Type: application/octet-stream, Size: 97 bytes --] #include <stdio.h> main() { long double i = 1.0l, j = 1.12345l; printf("%Lf %Lf\n", i, j); } [-- Attachment #5: fpcheck.c --] [-- Type: application/octet-stream, Size: 325 bytes --] #include <stdio.h> long double y = 0; main() { union { long double ld; long long ll[2]; } x = { 15.0l }; while (x.ld > 0) { printf ("0x%016llx.%016llx = %L35.30g\n", x.ll[0], x.ll[1], x.ld); x.ld += y; printf ("0x%016llx.%016llx = %L35.30g\n", x.ll[0], x.ll[1], x.ld); x.ld /= 10.0l; } } [-- Attachment #6: Type: text/plain, Size: 289 bytes --] -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2002-12-22 10:24 ` Alexandre Oliva 2002-12-22 10:35 ` Alexandre Oliva @ 2002-12-23 9:46 ` Alexandre Oliva 2002-12-24 11:07 ` Kaveh R. Ghazi ` (2 more replies) 1 sibling, 3 replies; 72+ messages in thread From: Alexandre Oliva @ 2002-12-23 9:46 UTC (permalink / raw) To: Kaveh R. Ghazi; +Cc: gcc-patches, gcc-bugs, gcc, libstdc++, oldham, ro [-- Attachment #1: Type: text/plain, Size: 161 bytes --] On Dec 22, 2002, Alexandre Oliva <aoliva@redhat.com> wrote: > ? gcc/config/mips/_tilib.c Here's the file that I had failed to cvs add before taking the diff: [-- Attachment #2: _tilib.c --] [-- Type: application/octet-stream, Size: 3002 bytes --] /* A few TImode functions needed for TFmode emulated arithmetic. Copyright 2002 Free Software Foundation, Inc. Contributed by Alexandre Oliva <aoliva@redhat.com> This file is part of GNU CC. GNU CC 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. GNU CC 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 GNU CC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "tconfig.h" #include "tsystem.h" #ifndef LIBGCC2_WORDS_BIG_ENDIAN #define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN #endif #if _MIPS_SIM == 2 /* N32 */ || _MIPS_SIM == 3 /* 64 */ typedef int TItype __attribute__ ((mode (TI))); typedef int DItype __attribute__ ((mode (DI))); typedef int SItype __attribute__ ((mode (SI))); typedef unsigned int UDItype __attribute__ ((mode (DI))); typedef union { struct TIstruct { #if LIBGCC2_WORDS_BIG_ENDIAN DItype high, low; #else DItype low, high; #endif } s; TItype ll; } TIunion; TItype __negti2 (TItype u) { TIunion w; TIunion uu; uu.ll = u; w.s.low = -uu.s.low; w.s.high = -uu.s.high - ((UDItype) w.s.low > 0); return w.ll; } TItype __ashlti3 (TItype u, int b) { TIunion w; int bm; TIunion uu; if (b == 0) return u; uu.ll = u; bm = (sizeof (DItype) * BITS_PER_UNIT) - b; if (bm <= 0) { w.s.low = 0; w.s.high = (UDItype) uu.s.low << -bm; } else { UDItype carries = (UDItype) uu.s.low >> bm; w.s.low = (UDItype) uu.s.low << b; w.s.high = ((UDItype) uu.s.high << b) | carries; } return w.ll; } #if 0 TItype __ashrti3 (TItype u, int b) { TIunion w; int bm; TIunion uu; if (b == 0) return u; uu.ll = u; bm = (sizeof (DItype) * BITS_PER_UNIT) - b; if (bm <= 0) { /* w.s.high = 1..1 or 0..0 */ w.s.high = uu.s.high >> (sizeof (DItype) * BITS_PER_UNIT - 1); w.s.low = uu.s.high >> -bm; } else { UDItype carries = (UDItype) uu.s.high << bm; w.s.high = uu.s.high >> b; w.s.low = ((UDItype) uu.s.low >> b) | carries; } return w.ll; } #endif TItype __lshrti3 (TItype u, int b) { TIunion w; int bm; TIunion uu; if (b == 0) return u; uu.ll = u; bm = (sizeof (DItype) * BITS_PER_UNIT) - b; if (bm <= 0) { w.s.high = 0; w.s.low = (UDItype) uu.s.high >> -bm; } else { UDItype carries = (UDItype) uu.s.high << bm; w.s.high = (UDItype) uu.s.high >> b; w.s.low = ((UDItype) uu.s.low >> b) | carries; } return w.ll; } #endif /* N32 or N64 */ [-- Attachment #3: Type: text/plain, Size: 289 bytes --] -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2002-12-23 9:46 ` Alexandre Oliva @ 2002-12-24 11:07 ` Kaveh R. Ghazi 2002-12-25 8:04 ` Alexandre Oliva 2002-12-24 18:15 ` Kaveh R. Ghazi 2003-01-07 22:40 ` Richard Henderson 2 siblings, 1 reply; 72+ messages in thread From: Kaveh R. Ghazi @ 2002-12-24 11:07 UTC (permalink / raw) To: aoliva; +Cc: gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro > From: Alexandre Oliva <aoliva@redhat.com> > > On Dec 22, 2002, Alexandre Oliva <aoliva@redhat.com> wrote: > > > ? gcc/config/mips/_tilib.c > > Here's the file that I had failed to cvs add before taking the diff: I tried out this stuff on irix6.5 against the trunk. I had to add this minor patch for it to work there as opposed to 3.3-pre: --- gcc-CVS20021223/gcc/config/mips/_tilib.c~ 2002-12-23 17:11:54.306377600 -0500 +++ gcc-CVS20021223/gcc/config/mips/_tilib.c 2002-12-23 17:08:53.719848000 -0500 @@ -22,6 +22,8 @@ Boston, MA 02111-1307, USA. */ #include "tconfig.h" #include "tsystem.h" +#include "coretypes.h" +#include "tm.h" #ifndef LIBGCC2_WORDS_BIG_ENDIAN #define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN Bootstrap went ok, however there were a couple of regressions in the c-torture testsuite: > FAIL: gcc.c-torture/execute/va-arg-5.c execution, -O0 > FAIL: gcc.c-torture/execute/va-arg-5.c execution, -O1 > FAIL: gcc.c-torture/execute/va-arg-5.c execution, -O2 > FAIL: gcc.c-torture/execute/va-arg-5.c execution, -O3 -fomit-frame-pointer > FAIL: gcc.c-torture/execute/va-arg-5.c execution, -O3 -g > FAIL: gcc.c-torture/execute/va-arg-5.c execution, -Os > FAIL: gcc.c-torture/execute/ieee/20011123-1.c execution, -O0 > FAIL: gcc.c-torture/execute/ieee/20011123-1.c execution, -O1 > FAIL: gcc.c-torture/execute/ieee/20011123-1.c execution, -O2 > FAIL: gcc.c-torture/execute/ieee/20011123-1.c execution, -O3 -fomit-frame-pointer > FAIL: gcc.c-torture/execute/ieee/20011123-1.c execution, -O3 -g > FAIL: gcc.c-torture/execute/ieee/20011123-1.c execution, -Os These tests both manipulate long doubles. Also the original test 27_io/ostream_inserter_arith still fails. However it looks as if it's in a different place, I'll check further and provide details. --Kaveh -- Kaveh R. Ghazi ghazi@caip.rutgers.edu ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2002-12-24 11:07 ` Kaveh R. Ghazi @ 2002-12-25 8:04 ` Alexandre Oliva 2002-12-26 13:48 ` Alexandre Oliva 0 siblings, 1 reply; 72+ messages in thread From: Alexandre Oliva @ 2002-12-25 8:04 UTC (permalink / raw) To: Kaveh R. Ghazi; +Cc: gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro On Dec 24, 2002, "Kaveh R. Ghazi" <ghazi@caip.rutgers.edu> wrote: > Bootstrap went ok, however there were a couple of regressions in the > c-torture testsuite: Thanks for catching these. The fix for va-arg-5.c didn't make it to the patch I posted, and the bootstrap obviously didn't catch the lack of support for getting long double arguments in varargs lists. Oops :-) ieee/20011123-1.c may be a victim of the rounding issue I mentioned in my earlier e-mail. I'll investigate it and post a revised patch. It looks like it's time for me to get expect and dejagnu to build and work on IRIX again... :-( -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2002-12-25 8:04 ` Alexandre Oliva @ 2002-12-26 13:48 ` Alexandre Oliva 2002-12-27 7:06 ` Alexandre Oliva 0 siblings, 1 reply; 72+ messages in thread From: Alexandre Oliva @ 2002-12-26 13:48 UTC (permalink / raw) To: Kaveh R. Ghazi; +Cc: gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro [-- Attachment #1: Type: text/plain, Size: 4020 bytes --] On Dec 24, 2002, Alexandre Oliva <aoliva@redhat.com> wrote: > On Dec 24, 2002, "Kaveh R. Ghazi" <ghazi@caip.rutgers.edu> wrote: >> Bootstrap went ok, however there were a couple of regressions in the >> c-torture testsuite: > Thanks for catching these. The fix for va-arg-5.c didn't make it to > the patch I posted, and the bootstrap obviously didn't catch the lack > of support for getting long double arguments in varargs lists. Oops > :-) > ieee/20011123-1.c may be a victim of the rounding issue I mentioned > in my earlier e-mail. I'll investigate it and post a revised patch. It was actually a victim of __make_tp not having been declared in the translation units that called it. Eek. So much for testing by hand... The libstdc++-v3 failures had to do with __LDBL_DENORM_MIN__ being set incorrectly. I ended up changing the real_format structure such that, instead of assuming the same number of bits is available for the mantissa of normalized and denormalized numbers and using a bool to tell whether denorms are available, the number of denorm mantissa bits is specified by itself, and we test whether it's zero to check whether denorms are supported. Then we can tell real.c that only 53 bits are available in the denorm mantissa of a long double format that has 106 bits of mantissa for normals. Hmm... It's actually 52. /me ponders whether to adjust the new comment in real.h or all entries, and figures he can't make his mind up :-) Suggestions? > It looks like it's time for me to get expect and dejagnu to build and > work on IRIX again... :-( Done. Wasn't that hard, I just had to find the patches for expect to build and work on IRIX that I had come up with a while ago. Anyway, here's the patch for the 3.3 branch. No failures in libstdc++-v3 with it (and a number of XPASSes). Full bootstrap and test cycle still going, but I've verified by hand that gcc.c-torture/execute/{va-arg-5.c,ieee/20011123-1.c} now pass, and I doubt these further tweaks might have actually introduced any regressions, so... Ok to install in the 3.3 branch (plus Kaveh's patch for gcc/config/mips/_tilib.c in mainline), if bootstrap and regression testing completes? Oh, I made another change that should speed things up a little bit too: instead of keeping even more excess precision for the emulation of IRIX' long double to internally use the same number of bits as IEEE 854 128-bit long doubles, which would probably cause rounding problems unless I explicitly handled it, I arranged for the emulation library to already keep 106 bits of mantissa. This means we never get excess precision in the final result, even if the would-be-implicit-1 bit of the least-significant double turns out to be zero and we have to look for some other less-significant bit for it. It sounded like a good idea at first, but I've now realized it may mess up numeric models that actually depend on exact knowledge of the number of mantissa bits. Not that this knowledge can actually be relied upon in case of denorms... Or even when the exponent is so small that the most-significant double is normal but the least-significant one isn't. In this case, I believe we should do some rounding, but I was not sure it actually mattered, so I just left it out. Another case that I haven't handled is that of numbers that are too large to represent in a single double, but that could be represented with the addition of the two doubles, using the maximum exponent on both. I figured this is probably not something that is meant to be done, since the documentation of this format explicitly states that it doesn't extend the range of exponents, when compared with double. Also, there's no check that the sign of the least-significant double is the same as that of the most-significant one, nor is there a check that the LSD is NaN or +/-Inf. I'm treating all these cases as constraint violations in the long double format, that invoke undefined behavior. Hope that's ok. Anyway, enough rambling. Here's the patch. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: gcc-mips-tfmode-emul-take3.patch --] [-- Type: text/x-patch, Size: 51093 bytes --] Index: gcc/ChangeLog from Alexandre Oliva <aoliva@redhat.com> * config/mips/mips.h (LONG_DUBLE_TYPE_SIZE): Set to 128 on N32 and N64. (MAX_FIXED_MODE_SIZE): Define to LONG_DOUBLE_TYPE_SIZE. (LIBGCC2_LONG_DOUBLE_TYPE_SIZE): Define. (BIGGEST_ALIGNMENT): Same as LONG_DOUBLE_TYPE_SIZE. (FUNCTION_VALUE_REGNO_P): Set for FP_RETURN+2 on N32 and N64. * config/mips/mips.c (mips_arg_info): Pass TFmode values in even FP registers on N32 and N64. (mips_va_arg): Impose additional even-register-like alignment to 128-bit arguments. (override_options): Set TFmode format. Set it as allowable in FP registers. (mips_function_value): Return TFmode in $f0 and $f2 on N32 or N64. * config/mips/_tilib.c (__negti2, __ashlti3, __lshrti3): New. * config/mips/t-iris6 (LIB2FUNCS_EXTRA): Add _tilib.c. (TPBIT): Set to tp-bit.c. (tp-bit.c): Create out of fp-bit.c. * Makefile.in (FPBIT_FUNCS): Added _sf_to_tf. (DBBIT_FUNCS): Added _df_to_tf. (TPBIT_FUNCS): New. (libgcc.mk): Pass TPBIT and TPBIT_FUNCS down. (LIBGCC_DEPS): Added TPBIT. * mklibgcc.in: Support TPBIT and TPBIT_FUNCS. * fp-bit.h: Define macros for TFmode floating-point constants in IEEE and IBM-extended TFmode types. Declare functions according to L_ macros. (TMODES): Define if __LDBL_MANT_DIG__ has one of the newly-supported widths. (TFtype, TItype, UTItype): Define if TMODES is defined. (MAX_UDI_INT, MAX_DI_INT, BITS_PER_DI): Likewise. (F_T_BITOFF, D_T_BITOFF): Define. (IMPLICIT_1, IMPLICIT_2): Cast constants to types that are guaranteed to be wide enough. * config/fp-bit.c: Check for L_ macros for tf functions. (__thenan_tf): New. (nan): Adjust. (pack_d, unpack_d): Support IEEE 854 and IBM-extended TFmode types. (_fpmul_parts): Support TFmode. (usi_to_float): Cast constants to be shifted to fractype instead of assuming long long is wide enough. (sf_to_tf, df_to_tf, __make_tp, tf_to_df, tf_to_sf): New. * print-rtl.c (print_rtx): Don't print MEM details in GENERATOR_FILEs. * rtl.c (get_mode_alignment): Moved to... * stor-layout.c: ... here. * calls.c (emit_library_call_value_1): Handle return values in a PARALLEL. * expr.c (emit_group_store): Initialize dst with CONST0_RTX for the appropriate mode. * optabs.c (expand_binop) <add, sub>: Return xtarget if we haven't been able to move the result to target. * real.h (struct real_format): Add denorm_p, remove has_denorm. * real.c: Adjust all formats and references to has_denorm. * c-common.c (builtin_define_float_constants): Use denorm_p to define DENORM_MIN. Index: gcc/Makefile.in =================================================================== RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v retrieving revision 1.958 diff -u -p -r1.958 Makefile.in --- gcc/Makefile.in 24 Nov 2002 20:43:01 -0000 1.958 +++ gcc/Makefile.in 26 Dec 2002 00:06:33 -0000 @@ -796,12 +796,17 @@ LIB2FUNCS_ST = _eprintf _bb __gcc_bcmp FPBIT_FUNCS = _pack_sf _unpack_sf _addsub_sf _mul_sf _div_sf \ _fpcmp_parts_sf _compare_sf _eq_sf _ne_sf _gt_sf _ge_sf \ _lt_sf _le_sf _unord_sf _si_to_sf _sf_to_si _negate_sf _make_sf \ - _sf_to_df _thenan_sf _sf_to_usi _usi_to_sf + _sf_to_df _sf_to_tf _thenan_sf _sf_to_usi _usi_to_sf DPBIT_FUNCS = _pack_df _unpack_df _addsub_df _mul_df _div_df \ _fpcmp_parts_df _compare_df _eq_df _ne_df _gt_df _ge_df \ _lt_df _le_df _unord_df _si_to_df _df_to_si _negate_df _make_df \ - _df_to_sf _thenan_df _df_to_usi _usi_to_df + _df_to_sf _df_to_tf _thenan_df _df_to_usi _usi_to_df + +TPBIT_FUNCS = _pack_tf _unpack_tf _addsub_tf _mul_tf _div_tf \ + _fpcmp_parts_tf _compare_tf _eq_tf _ne_tf _gt_tf _ge_tf \ + _lt_tf _le_tf _unord_tf _si_to_tf _tf_to_si _negate_tf _make_tf \ + _tf_to_df _tf_to_sf _thenan_tf _tf_to_usi _usi_to_tf # These might cause a divide overflow trap and so are compiled with # unwinder info. @@ -1021,6 +1026,8 @@ libgcc.mk: config.status Makefile mklibg LIB2_DIVMOD_FUNCS='$(LIB2_DIVMOD_FUNCS)' \ DPBIT='$(DPBIT)' \ DPBIT_FUNCS='$(DPBIT_FUNCS)' \ + TPBIT='$(TPBIT)' \ + TPBIT_FUNCS='$(TPBIT_FUNCS)' \ MULTILIBS=`$(GCC_FOR_TARGET) --print-multi-lib` \ EXTRA_MULTILIB_PARTS='$(EXTRA_MULTILIB_PARTS)' \ SHLIB_LINK='$(SHLIB_LINK)' \ @@ -1040,8 +1047,9 @@ libgcc.mk: config.status Makefile mklibg LIBGCC_DEPS = $(GCC_PASSES) $(LANGUAGES) stmp-int-hdrs $(STMP_FIXPROTO) \ libgcc.mk $(srcdir)/libgcc2.c $(TCONFIG_H) \ $(MACHMODE_H) longlong.h gbl-ctors.h config.status stmp-int-hdrs \ - tsystem.h $(FPBIT) $(DPBIT) $(LIB2ADD) $(LIB2ADD_ST) $(LIB2ADDEH) \ - $(LIB2ADDEHDEP) $(EXTRA_PARTS) $(srcdir)/config/$(LIB1ASMSRC) + tsystem.h $(FPBIT) $(DPBIT) $(TPBIT) $(LIB2ADD) \ + $(LIB2ADD_ST) $(LIB2ADDEH) $(LIB2ADDEHDEP) $(EXTRA_PARTS) \ + $(srcdir)/config/$(LIB1ASMSRC) libgcc.a: $(LIBGCC_DEPS) $(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \ Index: gcc/c-common.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/c-common.c,v retrieving revision 1.393 diff -u -p -r1.393 c-common.c --- gcc/c-common.c 11 Dec 2002 06:36:04 -0000 1.393 +++ gcc/c-common.c 26 Dec 2002 00:06:37 -0000 @@ -4866,9 +4866,9 @@ builtin_define_float_constants (name_pre positive floating-point number, b**(emin-p). Zero for formats that don't support denormals. */ sprintf (name, "__%s_DENORM_MIN__", name_prefix); - if (fmt->has_denorm) + if (fmt->denorm_p) { - sprintf (buf, "0x1p%d", (fmt->emin - fmt->p) * fmt->log2_b); + sprintf (buf, "0x1p%d", (fmt->emin - fmt->denorm_p) * fmt->log2_b); builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix); } Index: gcc/calls.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/calls.c,v retrieving revision 1.244 diff -u -p -r1.244 calls.c --- gcc/calls.c 9 Dec 2002 17:54:03 -0000 1.244 +++ gcc/calls.c 26 Dec 2002 00:06:40 -0000 @@ -4131,7 +4131,7 @@ emit_library_call_value_1 (retval, orgfu { rtx insns; - if (valreg == 0 || GET_CODE (valreg) == PARALLEL) + if (valreg == 0) { insns = get_insns (); end_sequence (); @@ -4140,9 +4140,18 @@ emit_library_call_value_1 (retval, orgfu else { rtx note = 0; - rtx temp = gen_reg_rtx (GET_MODE (valreg)); + rtx temp; int i; + if (GET_CODE (valreg) == PARALLEL) + { + temp = gen_reg_rtx (outmode); + emit_group_store (temp, valreg, outmode); + valreg = temp; + } + + temp = gen_reg_rtx (GET_MODE (valreg)); + /* Construct an "equal form" for the value which mentions all the arguments in order as well as the function name. */ for (i = 0; i < nargs; i++) @@ -4175,6 +4184,12 @@ emit_library_call_value_1 (retval, orgfu value = mem_value; if (value != mem_value) emit_move_insn (value, mem_value); + } + else if (GET_CODE (valreg) == PARALLEL) + { + if (value == 0) + value = gen_reg_rtx (outmode); + emit_group_store (value, valreg, outmode); } else if (value != 0) emit_move_insn (value, valreg); Index: gcc/expr.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/expr.c,v retrieving revision 1.498.2.1 diff -u -p -r1.498.2.1 expr.c --- gcc/expr.c 23 Dec 2002 16:47:20 -0000 1.498.2.1 +++ gcc/expr.c 26 Dec 2002 00:06:46 -0000 @@ -2436,7 +2436,7 @@ emit_group_store (orig_dst, src, ssize) { dst = gen_reg_rtx (GET_MODE (orig_dst)); /* Make life a bit easier for combine. */ - emit_move_insn (dst, const0_rtx); + emit_move_insn (dst, CONST0_RTX (GET_MODE (orig_dst))); } /* Process the pieces. */ Index: gcc/mklibgcc.in =================================================================== RCS file: /cvs/gcc/gcc/gcc/mklibgcc.in,v retrieving revision 1.48 diff -u -p -r1.48 mklibgcc.in --- gcc/mklibgcc.in 3 Oct 2002 20:35:13 -0000 1.48 +++ gcc/mklibgcc.in 26 Dec 2002 00:06:47 -0000 @@ -21,6 +21,8 @@ # LIB2_DIVMOD_FUNCS # DPBIT # DPBIT_FUNCS +# TPBIT +# TPBIT_FUNCS # LIBGCC # MULTILIBS # EXTRA_MULTILIB_PARTS @@ -169,6 +171,21 @@ if [ "$DPBIT" ]; then echo $out: $DPBIT $fpbit_c_dep echo " $gcc_compile" -DFINE_GRAINED_LIBRARIES $flags -DL$name \ -c $DPBIT -o $out + done + libgcc2_objs="$libgcc2_objs ${name}${objext}" + done +fi + +if [ "$TPBIT" ]; then + for name in $TPBIT_FUNCS; do + for ml in $MULTILIBS; do + dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'` + flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`; + out="libgcc/${dir}/${name}${objext}" + + echo $out: $TPBIT $fpbit_c_dep + echo " $gcc_compile" -DFINE_GRAINED_LIBRARIES $flags -DL$name \ + -c $TPBIT -o $out done libgcc2_objs="$libgcc2_objs ${name}${objext}" done Index: gcc/optabs.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/optabs.c,v retrieving revision 1.153 diff -u -p -r1.153 optabs.c --- gcc/optabs.c 20 Nov 2002 21:52:59 -0000 1.153 +++ gcc/optabs.c 26 Dec 2002 00:06:50 -0000 @@ -1306,6 +1306,8 @@ expand_binop (mode, binoptab, op0, op1, copy_rtx (xop0), copy_rtx (xop1))); } + else + target = xtarget; return target; } Index: gcc/print-rtl.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/print-rtl.c,v retrieving revision 1.91 diff -u -p -r1.91 print-rtl.c --- gcc/print-rtl.c 16 Oct 2002 00:40:27 -0000 1.91 +++ gcc/print-rtl.c 26 Dec 2002 00:06:50 -0000 @@ -1,5 +1,5 @@ /* Print RTL for GNU C Compiler. - Copyright (C) 1987, 1988, 1992, 1997, 1998, 1999, 2000 + Copyright (C) 1987, 1988, 1992, 1997, 1998, 1999, 2000, 2002 Free Software Foundation, Inc. This file is part of GCC. @@ -491,6 +491,7 @@ print_rtx (in_rtx) switch (GET_CODE (in_rtx)) { +#ifndef GENERATOR_FILE case MEM: fputs (" [", outfile); fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, MEM_ALIAS_SET (in_rtx)); @@ -518,7 +519,6 @@ print_rtx (in_rtx) fputc (']', outfile); break; -#ifndef GENERATOR_FILE case CONST_DOUBLE: if (FLOAT_MODE_P (GET_MODE (in_rtx))) { Index: gcc/real.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/real.c,v retrieving revision 1.105 diff -u -p -r1.105 real.c --- gcc/real.c 17 Nov 2002 20:20:39 -0000 1.105 +++ gcc/real.c 26 Dec 2002 00:06:51 -0000 @@ -2353,7 +2353,7 @@ round_for_format (fmt, r) { int diff; - if (!fmt->has_denorm) + if (!fmt->denorm_p) { /* Don't underflow completely until we've had a chance to round. */ if (r->exp < emin2m1) @@ -2676,7 +2676,7 @@ decode_ieee_single (fmt, r, buf) if (exp == 0) { - if (image && fmt->has_denorm) + if (image && fmt->denorm_p) { r->class = rvc_normal; r->sign = sign; @@ -2719,12 +2719,12 @@ const struct real_format ieee_single_for 2, 1, 24, + 24, -125, 128, true, true, true, - true, true }; @@ -2845,7 +2845,7 @@ decode_ieee_double (fmt, r, buf) if (exp == 0) { - if ((image_hi || image_lo) && fmt->has_denorm) + if ((image_hi || image_lo) && fmt->denorm_p) { r->class = rvc_normal; r->sign = sign; @@ -2912,12 +2912,12 @@ const struct real_format ieee_double_for 2, 1, 53, + 53, -1021, 1024, true, true, true, - true, true }; @@ -3084,7 +3084,7 @@ decode_ieee_extended (fmt, r, buf) if (exp == 0) { - if ((sig_hi || sig_lo) && fmt->has_denorm) + if ((sig_hi || sig_lo) && fmt->denorm_p) { r->class = rvc_normal; r->sign = sign; @@ -3167,12 +3167,12 @@ const struct real_format ieee_extended_m 2, 1, 64, + 64, -16382, 16384, true, true, true, - true, true }; @@ -3183,12 +3183,12 @@ const struct real_format ieee_extended_i 2, 1, 64, + 64, -16381, 16384, true, true, true, - true, true }; @@ -3199,12 +3199,12 @@ const struct real_format ieee_extended_i 2, 1, 64, + 64, -16381, 16384, true, true, true, - true, true }; @@ -3292,12 +3292,12 @@ const struct real_format ibm_extended_fo 2, 1, 53 + 53, + 53, -1021, 1024, true, true, true, - true, true }; @@ -3461,7 +3461,7 @@ decode_ieee_quad (fmt, r, buf) if (exp == 0) { - if ((image3 | image2 | image1 | image0) && fmt->has_denorm) + if ((image3 | image2 | image1 | image0) && fmt->denorm_p) { r->class = rvc_normal; r->sign = sign; @@ -3545,12 +3545,12 @@ const struct real_format ieee_quad_forma 2, 1, 113, + 113, -16381, 16384, true, true, true, - true, true }; \f @@ -3852,12 +3852,12 @@ const struct real_format vax_f_format = 2, 1, 24, + 0, -127, 127, false, false, false, - false, false }; @@ -3868,12 +3868,12 @@ const struct real_format vax_d_format = 2, 1, 56, + 0, -127, 127, false, false, false, - false, false }; @@ -3884,12 +3884,12 @@ const struct real_format vax_g_format = 2, 1, 53, + 0, -1023, 1023, false, false, false, - false, false }; \f @@ -4065,12 +4065,12 @@ const struct real_format i370_single_for 16, 4, 6, + 0, /* ??? The encoding does allow for "unnormals". */ -64, 63, false, false, false, /* ??? The encoding does allow for "unnormals". */ - false, /* ??? The encoding does allow for "unnormals". */ false }; @@ -4081,12 +4081,12 @@ const struct real_format i370_double_for 16, 4, 14, + 0, /* ??? The encoding does allow for "unnormals". */ -64, 63, false, false, false, /* ??? The encoding does allow for "unnormals". */ - false, /* ??? The encoding does allow for "unnormals". */ false }; \f @@ -4295,12 +4295,12 @@ const struct real_format c4x_single_form 2, 1, 24, + 0, -126, 128, false, false, false, - false, false }; @@ -4311,12 +4311,12 @@ const struct real_format c4x_extended_fo 2, 1, 32, + 0, -126, 128, false, false, false, - false, false }; @@ -4356,11 +4356,11 @@ const struct real_format real_internal_f 2, 1, SIGNIFICAND_BITS - 2, + 0, -MAX_EXP, MAX_EXP, true, true, - false, true, true }; Index: gcc/real.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/real.h,v retrieving revision 1.59 diff -u -p -r1.59 real.h --- gcc/real.h 22 Oct 2002 00:17:15 -0000 1.59 +++ gcc/real.h 26 Dec 2002 00:06:52 -0000 @@ -118,6 +118,11 @@ struct real_format /* Size of the significand in digits of radix B. */ int p; + /* Size of the significand of a denormalized number, in digits of + radix B. If zero, implies denormalized numbers are not + available. */ + int denorm_p; + /* The minimum negative integer, x, such that b**(x-1) is normalized. */ int emin; @@ -127,7 +132,6 @@ struct real_format /* Properties of the format. */ bool has_nans; bool has_inf; - bool has_denorm; bool has_signed_zero; bool qnan_msb_set; }; Index: gcc/rtl.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/rtl.c,v retrieving revision 1.120 diff -u -p -r1.120 rtl.c --- gcc/rtl.c 14 Oct 2002 02:36:25 -0000 1.120 +++ gcc/rtl.c 26 Dec 2002 00:06:52 -0000 @@ -396,29 +396,6 @@ shallow_copy_rtx (orig) return copy; } - -/* Return the alignment of MODE. This will be bounded by 1 and - BIGGEST_ALIGNMENT. */ - -unsigned int -get_mode_alignment (mode) - enum machine_mode mode; -{ - unsigned int alignment; - - if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT - || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT) - alignment = GET_MODE_UNIT_SIZE (mode); - else - alignment = GET_MODE_SIZE (mode); - - /* Extract the LSB of the size. */ - alignment = alignment & -alignment; - alignment *= BITS_PER_UNIT; - - alignment = MIN (BIGGEST_ALIGNMENT, MAX (1, alignment)); - return alignment; -} \f /* This is 1 until after the rtl generation pass. */ int rtx_equal_function_value_matters; Index: gcc/stor-layout.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/stor-layout.c,v retrieving revision 1.134 diff -u -p -r1.134 stor-layout.c --- gcc/stor-layout.c 20 Nov 2002 10:09:00 -0000 1.134 +++ gcc/stor-layout.c 26 Dec 2002 00:06:53 -0000 @@ -298,6 +298,29 @@ int_mode_for_mode (mode) return mode; } +/* Return the alignment of MODE. This will be bounded by 1 and + BIGGEST_ALIGNMENT. */ + +unsigned int +get_mode_alignment (mode) + enum machine_mode mode; +{ + unsigned int alignment; + + if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT + || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT) + alignment = GET_MODE_UNIT_SIZE (mode); + else + alignment = GET_MODE_SIZE (mode); + + /* Extract the LSB of the size. */ + alignment = alignment & -alignment; + alignment *= BITS_PER_UNIT; + + alignment = MIN (BIGGEST_ALIGNMENT, MAX (1, alignment)); + return alignment; +} + /* Return the value of VALUE, rounded up to a multiple of DIVISOR. This can only be applied to objects of a sizetype. */ Index: gcc/config/fp-bit.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/fp-bit.c,v retrieving revision 1.36 diff -u -p -r1.36 fp-bit.c --- gcc/config/fp-bit.c 7 Oct 2002 08:47:09 -0000 1.36 +++ gcc/config/fp-bit.c 26 Dec 2002 00:06:55 -0000 @@ -130,6 +130,10 @@ void __lttf2 (void) { abort(); } const fp_number_type __thenan_sf = { CLASS_SNAN, 0, 0, {(fractype) 0} }; #elif defined L_thenan_df const fp_number_type __thenan_df = { CLASS_SNAN, 0, 0, {(fractype) 0} }; +#elif defined L_thenan_tf +const fp_number_type __thenan_tf = { CLASS_SNAN, 0, 0, {(fractype) 0} }; +#elif defined TFLOAT +extern const fp_number_type __thenan_tf; #elif defined FLOAT extern const fp_number_type __thenan_sf; #else @@ -141,7 +145,9 @@ static fp_number_type * nan (void) { /* Discard the const qualifier... */ -#ifdef FLOAT +#ifdef TFLOAT + return (fp_number_type *) (& __thenan_tf); +#elif defined FLOAT return (fp_number_type *) (& __thenan_sf); #else return (fp_number_type *) (& __thenan_df); @@ -180,7 +186,7 @@ flip_sign ( fp_number_type * x) extern FLO_type pack_d ( fp_number_type * ); -#if defined(L_pack_df) || defined(L_pack_sf) +#if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf) FLO_type pack_d ( fp_number_type * src) { @@ -316,24 +322,76 @@ pack_d ( fp_number_type * src) dst.bits.exp = exp; dst.bits.sign = sign; #else +# if defined TFLOAT && defined HALFFRACBITS + { + halffractype high, low; + + high = (fraction >> (FRACBITS - HALFFRACBITS)); + high &= (((fractype)1) << HALFFRACBITS) - 1; + high |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << HALFFRACBITS; + high |= ((fractype) (sign & 1)) << (HALFFRACBITS | EXPBITS); + + low = (halffractype)fraction & + ((((halffractype)1) << (FRACBITS - HALFFRACBITS)) - 1); + + if (exp == EXPMAX || exp == 0 || low == 0) + low = 0; + else + { + exp -= HALFFRACBITS + 1; + + while (low < ((halffractype)1 << HALFFRACBITS)) + { + low <<= 1; + exp--; + } + + if (exp < -HALFFRACBITS) + low = exp = sign = 0; + else if (exp < 0) + { + low >>= -exp; + exp = 0; + } + + low &= ((halffractype)1 << HALFFRACBITS) - 1; + low |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << HALFFRACBITS; + low |= ((fractype) (sign & 1)) << (HALFFRACBITS | EXPBITS); + } + + dst.value_raw = (((fractype) high) << HALFSHIFT) | low; + } +# else dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1); dst.value_raw |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << FRACBITS; dst.value_raw |= ((fractype) (sign & 1)) << (FRACBITS | EXPBITS); +# endif #endif #if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT) +#ifdef TFLOAT + { + qrtrfractype tmp1 = dst.words[0]; + qrtrfractype tmp2 = dst.words[1]; + dst.words[0] = dst.words[3]; + dst.words[1] = dst.words[2]; + dst.words[2] = tmp2; + dst.words[3] = tmp1; + } +#else { halffractype tmp = dst.words[0]; dst.words[0] = dst.words[1]; dst.words[1] = tmp; } #endif +#endif return dst.value; } #endif -#if defined(L_unpack_df) || defined(L_unpack_sf) +#if defined(L_unpack_df) || defined(L_unpack_sf) || defined(L_unpack_tf) void unpack_d (FLO_union_type * src, fp_number_type * dst) { @@ -347,8 +405,15 @@ unpack_d (FLO_union_type * src, fp_numbe #if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT) FLO_union_type swapped; +#ifdef TFLOAT + swapped.words[0] = src->words[3]; + swapped.words[1] = src->words[2]; + swapped.words[2] = src->words[1]; + swapped.words[3] = src->words[0]; +#else swapped.words[0] = src->words[1]; swapped.words[1] = src->words[0]; +#endif src = &swapped; #endif @@ -357,9 +422,34 @@ unpack_d (FLO_union_type * src, fp_numbe exp = src->bits.exp; sign = src->bits.sign; #else - fraction = src->value_raw & ((((fractype)1) << FRACBITS) - (fractype)1); +# if defined TFLOAT && defined HALFFRACBITS + { + halffractype high, low; + + high = src->value_raw >> HALFSHIFT; + low = src->value_raw & (((fractype)1 << HALFSHIFT) - 1); + + fraction = high & ((((fractype)1) << HALFFRACBITS) - 1); + fraction <<= FRACBITS - HALFFRACBITS; + exp = ((int)(high >> HALFFRACBITS)) & ((1 << EXPBITS) - 1); + sign = ((int)(high >> (((HALFFRACBITS + EXPBITS))))) & 1; + + if (exp != EXPMAX && exp != 0 && low != 0) + { + int lowexp = ((int)(low >> HALFFRACBITS)) & ((1 << EXPBITS) - 1); + + low &= (((fractype)1) << HALFFRACBITS) - 1; + if (lowexp) + low |= ((halffractype)1) << HALFFRACBITS; + fraction += ((fractype)low << (FRACBITS - HALFFRACBITS)) + >> (exp - lowexp); + } + } +# else + fraction = src->value_raw & ((((fractype)1) << FRACBITS) - 1); exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1); sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1; +# endif #endif dst->sign = sign; @@ -427,7 +517,7 @@ unpack_d (FLO_union_type * src, fp_numbe } #endif /* L_unpack_df || L_unpack_sf */ -#if defined(L_addsub_sf) || defined(L_addsub_df) +#if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf) static fp_number_type * _fpadd_parts (fp_number_type * a, fp_number_type * b, @@ -611,7 +701,7 @@ sub (FLO_type arg_a, FLO_type arg_b) } #endif /* L_addsub_sf || L_addsub_df */ -#if defined(L_mul_sf) || defined(L_mul_df) +#if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf) static inline __attribute__ ((__always_inline__)) fp_number_type * _fpmul_parts ( fp_number_type * a, fp_number_type * b, @@ -660,7 +750,7 @@ _fpmul_parts ( fp_number_type * a, /* Calculate the mantissa by multiplying both numbers to get a twice-as-wide number. */ { -#if defined(NO_DI_MODE) +#if defined(NO_DI_MODE) || defined(TFLOAT) { fractype x = a->fraction.ll; fractype ylow = b->fraction.ll; @@ -725,7 +815,9 @@ _fpmul_parts ( fp_number_type * a, tmp->normal_exp = a->normal_exp + b->normal_exp; tmp->sign = a->sign != b->sign; -#ifdef FLOAT +#ifdef TFLOAT + tmp->normal_exp += 6; /* ??????????????? */ +#elif defined FLOAT tmp->normal_exp += 2; /* ??????????????? */ #else tmp->normal_exp += 4; /* ??????????????? */ @@ -803,7 +895,7 @@ multiply (FLO_type arg_a, FLO_type arg_b } #endif /* L_mul_sf || L_mul_df */ -#if defined(L_div_sf) || defined(L_div_df) +#if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf) static inline __attribute__ ((__always_inline__)) fp_number_type * _fpdiv_parts (fp_number_type * a, fp_number_type * b) @@ -913,7 +1005,8 @@ divide (FLO_type arg_a, FLO_type arg_b) } #endif /* L_div_sf || L_div_df */ -#if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) +#if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) \ + || defined(L_fpcmp_parts_tf) /* according to the demo, fpcmp returns a comparison with 0... thus a<b -> -1 a==b -> 0 @@ -998,7 +1091,7 @@ __fpcmp_parts (fp_number_type * a, fp_nu } #endif -#if defined(L_compare_sf) || defined(L_compare_df) +#if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compoare_tf) CMPtype compare (FLO_type arg_a, FLO_type arg_b) { @@ -1020,7 +1113,7 @@ compare (FLO_type arg_a, FLO_type arg_b) /* These should be optimized for their specific tasks someday. */ -#if defined(L_eq_sf) || defined(L_eq_df) +#if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf) CMPtype _eq_f2 (FLO_type arg_a, FLO_type arg_b) { @@ -1041,7 +1134,7 @@ _eq_f2 (FLO_type arg_a, FLO_type arg_b) } #endif /* L_eq_sf || L_eq_df */ -#if defined(L_ne_sf) || defined(L_ne_df) +#if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf) CMPtype _ne_f2 (FLO_type arg_a, FLO_type arg_b) { @@ -1062,7 +1155,7 @@ _ne_f2 (FLO_type arg_a, FLO_type arg_b) } #endif /* L_ne_sf || L_ne_df */ -#if defined(L_gt_sf) || defined(L_gt_df) +#if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf) CMPtype _gt_f2 (FLO_type arg_a, FLO_type arg_b) { @@ -1083,7 +1176,7 @@ _gt_f2 (FLO_type arg_a, FLO_type arg_b) } #endif /* L_gt_sf || L_gt_df */ -#if defined(L_ge_sf) || defined(L_ge_df) +#if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf) CMPtype _ge_f2 (FLO_type arg_a, FLO_type arg_b) { @@ -1103,7 +1196,7 @@ _ge_f2 (FLO_type arg_a, FLO_type arg_b) } #endif /* L_ge_sf || L_ge_df */ -#if defined(L_lt_sf) || defined(L_lt_df) +#if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf) CMPtype _lt_f2 (FLO_type arg_a, FLO_type arg_b) { @@ -1124,7 +1217,7 @@ _lt_f2 (FLO_type arg_a, FLO_type arg_b) } #endif /* L_lt_sf || L_lt_df */ -#if defined(L_le_sf) || defined(L_le_df) +#if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf) CMPtype _le_f2 (FLO_type arg_a, FLO_type arg_b) { @@ -1147,7 +1240,7 @@ _le_f2 (FLO_type arg_a, FLO_type arg_b) #endif /* ! US_SOFTWARE_GOFAST */ -#if defined(L_unord_sf) || defined(L_unord_df) +#if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf) CMPtype _unord_f2 (FLO_type arg_a, FLO_type arg_b) { @@ -1165,7 +1258,7 @@ _unord_f2 (FLO_type arg_a, FLO_type arg_ } #endif /* L_unord_sf || L_unord_df */ -#if defined(L_si_to_sf) || defined(L_si_to_df) +#if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf) FLO_type si_to_float (SItype arg_a) { @@ -1193,7 +1286,7 @@ si_to_float (SItype arg_a) else in.fraction.ll = arg_a; - while (in.fraction.ll < (1LL << (FRACBITS + NGARDS))) + while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS))) { in.fraction.ll <<= 1; in.normal_exp -= 1; @@ -1203,7 +1296,7 @@ si_to_float (SItype arg_a) } #endif /* L_si_to_sf || L_si_to_df */ -#if defined(L_usi_to_sf) || defined(L_usi_to_df) +#if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf) FLO_type usi_to_float (USItype arg_a) { @@ -1220,12 +1313,12 @@ usi_to_float (USItype arg_a) in.normal_exp = FRACBITS + NGARDS; in.fraction.ll = arg_a; - while (in.fraction.ll > (1LL << (FRACBITS + NGARDS))) + while (in.fraction.ll > ((fractype)1 << (FRACBITS + NGARDS))) { in.fraction.ll >>= 1; in.normal_exp += 1; } - while (in.fraction.ll < (1LL << (FRACBITS + NGARDS))) + while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS))) { in.fraction.ll <<= 1; in.normal_exp -= 1; @@ -1235,7 +1328,7 @@ usi_to_float (USItype arg_a) } #endif -#if defined(L_sf_to_si) || defined(L_df_to_si) +#if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si) SItype float_to_si (FLO_type arg_a) { @@ -1263,8 +1356,8 @@ float_to_si (FLO_type arg_a) } #endif /* L_sf_to_si || L_df_to_si */ -#if defined(L_sf_to_usi) || defined(L_df_to_usi) -#ifdef US_SOFTWARE_GOFAST +#if defined(L_sf_to_usi) || defined(L_df_to_usi) || defined(L_tf_to_usi) +#if defined US_SOFTWARE_GOFAST || defined(L_tf_to_usi) /* While libgcc2.c defines its own __fixunssfsi and __fixunsdfsi routines, we also define them for GOFAST because the ones in libgcc2.c have the wrong names and I'd rather define these here and keep GOFAST CYG-LOC's @@ -1303,7 +1396,7 @@ float_to_usi (FLO_type arg_a) #endif /* US_SOFTWARE_GOFAST */ #endif /* L_sf_to_usi || L_df_to_usi */ -#if defined(L_negate_sf) || defined(L_negate_df) +#if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf) FLO_type negate (FLO_type arg_a) { @@ -1359,6 +1452,21 @@ sf_to_df (SFtype arg_a) } #endif /* L_sf_to_df */ +#if defined(L_sf_to_tf) && defined(TMODES) +TFtype +sf_to_tf (SFtype arg_a) +{ + fp_number_type in; + FLO_union_type au; + + au.value = arg_a; + unpack_d (&au, &in); + + return __make_tp (in.class, in.sign, in.normal_exp, + ((UTItype) in.fraction.ll) << F_T_BITOFF); +} +#endif /* L_sf_to_df */ + #endif /* ! FLOAT_ONLY */ #endif /* FLOAT */ @@ -1401,6 +1509,85 @@ df_to_sf (DFtype arg_a) return __make_fp (in.class, in.sign, in.normal_exp, sffrac); } #endif /* L_df_to_sf */ + +#if defined(L_df_to_tf) && defined(TMODES) \ + && !defined(FLOAT) && !defined(TFLOAT) +TFtype +df_to_tf (DFtype arg_a) +{ + fp_number_type in; + FLO_union_type au; + + au.value = arg_a; + unpack_d (&au, &in); + + return __make_tp (in.class, in.sign, in.normal_exp, + ((UTItype) in.fraction.ll) << D_T_BITOFF); +} +#endif /* L_sf_to_df */ + +#ifdef TFLOAT +#if defined(L_make_tf) +TFtype +__make_tp(fp_class_type class, + unsigned int sign, + int exp, + UTItype frac) +{ + fp_number_type in; + + in.class = class; + in.sign = sign; + in.normal_exp = exp; + in.fraction.ll = frac; + return pack_d (&in); +} +#endif /* L_make_tf */ + +#if defined(L_tf_to_df) +DFtype +tf_to_df (TFtype arg_a) +{ + fp_number_type in; + UDItype sffrac; + FLO_union_type au; + + au.value = arg_a; + unpack_d (&au, &in); + + sffrac = in.fraction.ll >> D_T_BITOFF; + + /* We set the lowest guard bit in SFFRAC if we discarded any non + zero bits. */ + if ((in.fraction.ll & (((UTItype) 1 << D_T_BITOFF) - 1)) != 0) + sffrac |= 1; + + return __make_dp (in.class, in.sign, in.normal_exp, sffrac); +} +#endif /* L_tf_to_df */ + +#if defined(L_tf_to_sf) +SFtype +tf_to_sf (TFtype arg_a) +{ + fp_number_type in; + USItype sffrac; + FLO_union_type au; + + au.value = arg_a; + unpack_d (&au, &in); + + sffrac = in.fraction.ll >> F_T_BITOFF; + + /* We set the lowest guard bit in SFFRAC if we discarded any non + zero bits. */ + if ((in.fraction.ll & (((UTItype) 1 << F_T_BITOFF) - 1)) != 0) + sffrac |= 1; + + return __make_fp (in.class, in.sign, in.normal_exp, sffrac); +} +#endif /* L_tf_to_sf */ +#endif /* TFLOAT */ #endif /* ! FLOAT */ #endif /* !EXTENDED_FLOAT_STUBS */ Index: gcc/config/fp-bit.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/fp-bit.h,v retrieving revision 1.7 diff -u -p -r1.7 fp-bit.h --- gcc/config/fp-bit.h 19 Jun 2002 23:01:59 -0000 1.7 +++ gcc/config/fp-bit.h 26 Dec 2002 00:06:55 -0000 @@ -1,5 +1,5 @@ /* Header file for fp-bit.c. */ -/* Copyright (C) 2000 +/* Copyright (C) 2000, 2002 Free Software Foundation, Inc. This file is part of GNU CC. @@ -87,12 +87,22 @@ Boston, MA 02111-1307, USA. */ #endif #endif /* ! FINE_GRAINED_LIBRARIES */ +#if __LDBL_MANT_DIG__ == 113 || __LDBL_MANT_DIG__ == 106 +# define TMODES +#endif + typedef float SFtype __attribute__ ((mode (SF))); typedef float DFtype __attribute__ ((mode (DF))); +#ifdef TMODES +typedef float TFtype __attribute__ ((mode (TF))); +#endif typedef int HItype __attribute__ ((mode (HI))); typedef int SItype __attribute__ ((mode (SI))); typedef int DItype __attribute__ ((mode (DI))); +#ifdef TMODES +typedef int TItype __attribute__ ((mode (TI))); +#endif /* The type of the result of a fp compare */ #ifndef CMPtype @@ -102,16 +112,68 @@ typedef int DItype __attribute__ ((mode typedef unsigned int UHItype __attribute__ ((mode (HI))); typedef unsigned int USItype __attribute__ ((mode (SI))); typedef unsigned int UDItype __attribute__ ((mode (DI))); +#ifdef TMODES +typedef unsigned int UTItype __attribute__ ((mode (TI))); +#endif #define MAX_USI_INT (~(USItype)0) #define MAX_SI_INT ((SItype) (MAX_USI_INT >> 1)) #define BITS_PER_SI (4 * BITS_PER_UNIT) +#ifdef TMODES +#define MAX_UDI_INT (~(UDItype)0) +#define MAX_DI_INT ((DItype) (MAX_UDI_INT >> 1)) +#define BITS_PER_DI (8 * BITS_PER_UNIT) +#endif #ifdef FLOAT_ONLY #define NO_DI_MODE #endif -#ifdef FLOAT +#ifdef TFLOAT +# ifndef TMODES +# error "TFLOAT requires long double to have 113 bits of mantissa" +# endif + +# define PREFIXFPDP tp +# define PREFIXSFDF tf +# define NGARDS 10L /* Is this right? */ +# define GARDROUND 0x1ff +# define GARDMASK 0x3ff +# define GARDMSB 0x200 +# define FRAC_NBITS 128 + +# if __LDBL_MANT_DIG__ == 113 /* IEEE quad */ +# define EXPBITS 15 +# define EXPBIAS 16383 +# define EXPMAX (0x7fff) +# define QUIET_NAN ((TItype)0x8 << 108) +# define FRACHIGH ((TItype)0x8 << 124) +# define FRACHIGH2 ((TItype)0xc << 124) +# define FRACBITS 112 +# endif + +# if __LDBL_MANT_DIG__ == 106 /* IBM extended (double+double) */ +# define EXPBITS 11 +# define EXPBIAS 1023 +# define EXPMAX (0x7ff) +# define QUIET_NAN ((TItype)0x8 << (48 + 64)) +# define FRACHIGH ((TItype)0x8 << 124) +# define FRACHIGH2 ((TItype)0xc << 124) +# define FRACBITS 105 +# define HALFFRACBITS 52 +# define HALFSHIFT 64 +# endif + +# define pack_d __pack_t +# define unpack_d __unpack_t +# define __fpcmp_parts __fpcmp_parts_t + typedef UTItype fractype; + typedef UDItype halffractype; + typedef USItype qrtrfractype; +#define qrtrfractype qrtrfractype + typedef TFtype FLO_type; + typedef TItype intfrac; +#elif defined FLOAT # define NGARDS 7L # define GARDROUND 0x3f # define GARDMASK 0x7f @@ -157,7 +219,9 @@ typedef unsigned int UDItype __attribute #endif /* FLOAT */ #ifdef US_SOFTWARE_GOFAST -# ifdef FLOAT +# ifdef TFLOAT +# error "GOFAST TFmode not supported" +# elif defined FLOAT # define add fpadd # define sub fpsub # define multiply fpmul @@ -170,8 +234,8 @@ typedef unsigned int UDItype __attribute # define float_to_usi fptoui # define negate __negsf2 # define sf_to_df fptodp -# define dptofp dptofp -#else +# define sf_to_tf __extendsftf2 +# else # define add dpadd # define sub dpsub # define multiply dpmul @@ -184,9 +248,30 @@ typedef unsigned int UDItype __attribute # define float_to_usi dptoul # define negate __negdf2 # define df_to_sf dptofp +# define df_to_tf __extenddftf2 # endif /* FLOAT */ #else -# ifdef FLOAT +# ifdef TFLOAT +# define add __addtf3 +# define sub __subtf3 +# define multiply __multf3 +# define divide __divtf3 +# define compare __cmptf2 +# define _eq_f2 __eqtf2 +# define _ne_f2 __netf2 +# define _gt_f2 __gttf2 +# define _ge_f2 __getf2 +# define _lt_f2 __lttf2 +# define _le_f2 __letf2 +# define _unord_f2 __unordtf2 +# define usi_to_float __floatunsitf +# define si_to_float __floatsitf +# define float_to_si __fixtfsi +# define float_to_usi __fixunstfsi +# define negate __negtf2 +# define tf_to_sf __trunctfsf2 +# define tf_to_df __trunctfdf2 +# elif defined FLOAT # define add __addsf3 # define sub __subsf3 # define multiply __mulsf3 @@ -205,7 +290,8 @@ typedef unsigned int UDItype __attribute # define float_to_usi __fixunssfsi # define negate __negsf2 # define sf_to_df __extendsfdf2 -#else +# define sf_to_tf __extendsftf2 +# else # define add __adddf3 # define sub __subdf3 # define multiply __muldf3 @@ -224,6 +310,7 @@ typedef unsigned int UDItype __attribute # define float_to_usi __fixunsdfsi # define negate __negdf2 # define df_to_sf __truncdfsf2 +# define df_to_tf __extenddftf2 # endif /* FLOAT */ #endif /* US_SOFTWARE_GOFAST */ @@ -241,10 +328,15 @@ typedef unsigned int UDItype __attribute */ #define F_D_BITOFF (52+8-(23+7)) +#ifdef TMODES +# define F_T_BITOFF (__LDBL_MANT_DIG__-1+10-(23+7)) +# define D_T_BITOFF (__LDBL_MANT_DIG__-1+10-(52+8)) +#endif + #define NORMAL_EXPMIN (-(EXPBIAS)+1) -#define IMPLICIT_1 (1LL<<(FRACBITS+NGARDS)) -#define IMPLICIT_2 (1LL<<(FRACBITS+1+NGARDS)) +#define IMPLICIT_1 ((fractype)1<<(FRACBITS+NGARDS)) +#define IMPLICIT_2 ((fractype)1<<(FRACBITS+1+NGARDS)) /* common types */ @@ -282,7 +374,11 @@ typedef union fractype value_raw; #ifndef FLOAT +# ifdef qrtrfractype + qrtrfractype qwords[4]; +# else halffractype words[2]; +# endif #endif #ifdef FLOAT_BIT_ORDER_MISMATCH @@ -317,82 +413,82 @@ FLO_union_type; /* Prototypes */ -#if defined(L_pack_df) || defined(L_pack_sf) +#if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf) extern FLO_type pack_d (fp_number_type *); #endif extern void unpack_d (FLO_union_type *, fp_number_type *); -#if defined(L_addsub_sf) || defined(L_addsub_df) +#if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf) extern FLO_type add (FLO_type, FLO_type); extern FLO_type sub (FLO_type, FLO_type); #endif -#if defined(L_mul_sf) || defined(L_mul_df) +#if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf) extern FLO_type multiply (FLO_type, FLO_type); #endif -#if defined(L_div_sf) || defined(L_div_df) +#if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf) extern FLO_type divide (FLO_type, FLO_type); #endif extern int __fpcmp_parts (fp_number_type *, fp_number_type *); -#if defined(L_compare_sf) || defined(L_compare_df) +#if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compare_tf) extern CMPtype compare (FLO_type, FLO_type); #endif #ifndef US_SOFTWARE_GOFAST -#if defined(L_eq_sf) || defined(L_eq_df) +#if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf) extern CMPtype _eq_f2 (FLO_type, FLO_type); #endif -#if defined(L_ne_sf) || defined(L_ne_df) +#if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf) extern CMPtype _ne_f2 (FLO_type, FLO_type); #endif -#if defined(L_gt_sf) || defined(L_gt_df) +#if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf) extern CMPtype _gt_f2 (FLO_type, FLO_type); #endif -#if defined(L_ge_sf) || defined(L_ge_df) +#if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf) extern CMPtype _ge_f2 (FLO_type, FLO_type); #endif -#if defined(L_lt_sf) || defined(L_lt_df) +#if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf) extern CMPtype _lt_f2 (FLO_type, FLO_type); #endif -#if defined(L_le_sf) || defined(L_le_df) +#if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf) extern CMPtype _le_f2 (FLO_type, FLO_type); #endif -#if defined(L_unord_sf) || defined(L_unord_df) +#if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf) extern CMPtype _unord_f2 (FLO_type, FLO_type); #endif #endif /* ! US_SOFTWARE_GOFAST */ -#if defined(L_si_to_sf) || defined(L_si_to_df) +#if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf) extern FLO_type si_to_float (SItype); #endif -#if defined(L_sf_to_si) || defined(L_df_to_si) +#if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si) extern SItype float_to_si (FLO_type); #endif -#if defined(L_sf_to_usi) || defined(L_df_to_usi) +#if defined(L_sf_to_usi) || defined(L_df_to_usi) || defined(L_tf_to_usi) #ifdef US_SOFTWARE_GOFAST extern USItype float_to_usi (FLO_type); #endif #endif -#if defined(L_usi_to_sf) || defined(L_usi_to_df) +#if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf) extern FLO_type usi_to_float (USItype); #endif -#if defined(L_negate_sf) || defined(L_negate_df) +#if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf) extern FLO_type negate (FLO_type); #endif @@ -405,6 +501,9 @@ extern DFtype __make_dp (fp_class_type, #if defined(L_sf_to_df) extern DFtype sf_to_df (SFtype); #endif +#if defined(L_sf_to_tf) && defined(TMODES) +extern TFtype sf_to_tf (SFtype); +#endif #endif /* ! FLOAT_ONLY */ #endif /* FLOAT */ @@ -416,6 +515,24 @@ extern DFtype __make_dp (fp_class_type, #if defined(L_df_to_sf) extern SFtype df_to_sf (DFtype); #endif +#if defined(L_df_to_tf) && defined(TMODES) +extern TFtype df_to_tf (DFtype); +#endif #endif /* ! FLOAT */ + +#ifdef TMODES +extern TFtype __make_tp (fp_class_type, unsigned int, int, UTItype); +#ifdef TFLOAT +#if defined(L_tf_to_sf) +extern SFtype tf_to_sf (TFtype); +#endif +#if defined(L_tf_to_df) +extern DFtype tf_to_df (TFtype); +#endif +#if defined(L_di_to_tf) +extern TFtype di_to_df (DItype); +#endif +#endif /* TFLOAT */ +#endif /* TMODES */ #endif /* ! GCC_FP_BIT_H */ Index: gcc/config/mips/_tilib.c =================================================================== RCS file: gcc/config/mips/_tilib.c diff -N gcc/config/mips/_tilib.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gcc/config/mips/_tilib.c 26 Dec 2002 00:06:55 -0000 @@ -0,0 +1,154 @@ +/* A few TImode functions needed for TFmode emulated arithmetic. + Copyright 2002 Free Software Foundation, Inc. + Contributed by Alexandre Oliva <aoliva@redhat.com> + +This file is part of GNU CC. + +GNU CC 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. + +GNU CC 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 GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + + +#include "tconfig.h" +#include "tsystem.h" + +#ifndef LIBGCC2_WORDS_BIG_ENDIAN +#define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN +#endif + +#if _MIPS_SIM == 2 /* N32 */ || _MIPS_SIM == 3 /* 64 */ + +typedef int TItype __attribute__ ((mode (TI))); +typedef int DItype __attribute__ ((mode (DI))); +typedef int SItype __attribute__ ((mode (SI))); + +typedef unsigned int UDItype __attribute__ ((mode (DI))); + +typedef union +{ + struct TIstruct { +#if LIBGCC2_WORDS_BIG_ENDIAN + DItype high, low; +#else + DItype low, high; +#endif + } s; + TItype ll; +} TIunion; + +TItype +__negti2 (TItype u) +{ + TIunion w; + TIunion uu; + + uu.ll = u; + + w.s.low = -uu.s.low; + w.s.high = -uu.s.high - ((UDItype) w.s.low > 0); + + return w.ll; +} + +TItype +__ashlti3 (TItype u, int b) +{ + TIunion w; + int bm; + TIunion uu; + + if (b == 0) + return u; + + uu.ll = u; + + bm = (sizeof (DItype) * BITS_PER_UNIT) - b; + if (bm <= 0) + { + w.s.low = 0; + w.s.high = (UDItype) uu.s.low << -bm; + } + else + { + UDItype carries = (UDItype) uu.s.low >> bm; + + w.s.low = (UDItype) uu.s.low << b; + w.s.high = ((UDItype) uu.s.high << b) | carries; + } + + return w.ll; +} + +#if 0 +TItype +__ashrti3 (TItype u, int b) +{ + TIunion w; + int bm; + TIunion uu; + + if (b == 0) + return u; + + uu.ll = u; + + bm = (sizeof (DItype) * BITS_PER_UNIT) - b; + if (bm <= 0) + { + /* w.s.high = 1..1 or 0..0 */ + w.s.high = uu.s.high >> (sizeof (DItype) * BITS_PER_UNIT - 1); + w.s.low = uu.s.high >> -bm; + } + else + { + UDItype carries = (UDItype) uu.s.high << bm; + + w.s.high = uu.s.high >> b; + w.s.low = ((UDItype) uu.s.low >> b) | carries; + } + + return w.ll; +} +#endif + +TItype +__lshrti3 (TItype u, int b) +{ + TIunion w; + int bm; + TIunion uu; + + if (b == 0) + return u; + + uu.ll = u; + + bm = (sizeof (DItype) * BITS_PER_UNIT) - b; + if (bm <= 0) + { + w.s.high = 0; + w.s.low = (UDItype) uu.s.high >> -bm; + } + else + { + UDItype carries = (UDItype) uu.s.high << bm; + + w.s.high = (UDItype) uu.s.high >> b; + w.s.low = ((UDItype) uu.s.low >> b) | carries; + } + + return w.ll; +} + +#endif /* N32 or N64 */ Index: gcc/config/mips/mips.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.c,v retrieving revision 1.241 diff -u -p -r1.241 mips.c --- gcc/config/mips/mips.c 12 Dec 2002 05:13:03 -0000 1.241 +++ gcc/config/mips/mips.c 26 Dec 2002 00:07:02 -0000 @@ -4286,7 +4286,9 @@ mips_arg_info (cum, mode, type, named, i info->fpr_p = false; if (GET_MODE_CLASS (mode) == MODE_FLOAT - && GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE) + && GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE * ((mips_abi == ABI_N32 + || mips_abi == ABI_64) + ? 2 : 1)) { switch (mips_abi) { @@ -4321,9 +4323,11 @@ mips_arg_info (cum, mode, type, named, i is a double, but $f14 if it is a single. Otherwise, on a 32-bit double-float machine, each FP argument must start in a new register pair. */ - even_reg_p = ((mips_abi == ABI_O64 && mode == SFmode) || FP_INC > 1); + even_reg_p = (GET_MODE_SIZE (mode) > UNITS_PER_FPVALUE /* TFmode */ + || (mips_abi == ABI_O64 && mode == SFmode) + || FP_INC > 1); } - else if (!TARGET_64BIT) + else if (!TARGET_64BIT || mips_abi == ABI_N32 || mips_abi == ABI_64) { if (GET_MODE_CLASS (mode) == MODE_INT || GET_MODE_CLASS (mode) == MODE_FLOAT) @@ -5007,7 +5011,10 @@ mips_va_arg (valist, type) that alignments <= UNITS_PER_WORD are preserved by the va_arg increment mechanism. */ - if (TARGET_64BIT) + if ((mips_abi == ABI_N32 || mips_abi == ABI_64) + && TYPE_ALIGN (type) > 64) + align = 16; + else if (TARGET_64BIT) align = 8; else if (TYPE_ALIGN (type) > 32) align = 8; @@ -5365,6 +5372,8 @@ override_options () else mips16 = 0; + real_format_for_mode[TFmode - QFmode] = &ibm_extended_format; + mips_print_operand_punct['?'] = 1; mips_print_operand_punct['#'] = 1; mips_print_operand_punct['&'] = 1; @@ -5454,7 +5463,10 @@ override_options () register. */ || (mips_abi == ABI_MEABI && size <= 4)) && (((class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT) - && size <= UNITS_PER_FPVALUE) + && size <= (UNITS_PER_FPVALUE + * ((mips_abi == ABI_N32 + || mips_abi == ABI_64) + ? 2 : 1))) /* Allow integer modes that fit into a single register. We need to put integers into FPRs when using instructions like cvt and trunc. */ @@ -8271,8 +8283,24 @@ mips_function_value (valtype, func, mode } mclass = GET_MODE_CLASS (mode); - if (mclass == MODE_FLOAT && GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE) + if (mclass == MODE_FLOAT + && GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE) reg = FP_RETURN; + + else if (mclass == MODE_FLOAT + && mode == TFmode + && (mips_abi == ABI_N32 || mips_abi == ABI_64)) + /* long doubles are really split between f0 and f2, not f1. Eek. */ + return gen_rtx_PARALLEL + (VOIDmode, + gen_rtvec (2, + gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_REG (DImode, FP_RETURN), + GEN_INT (0)), + gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_REG (DImode, FP_RETURN + 2), + GEN_INT (GET_MODE_SIZE (mode) / 2)))); + else if (mclass == MODE_COMPLEX_FLOAT && GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE * 2) Index: gcc/config/mips/mips.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.h,v retrieving revision 1.227 diff -u -p -r1.227 mips.h --- gcc/config/mips/mips.h 5 Nov 2002 12:41:52 -0000 1.227 +++ gcc/config/mips/mips.h 26 Dec 2002 00:07:05 -0000 @@ -1535,7 +1535,21 @@ do { \ /* A C expression for the size in bits of the type `long double' on the target machine. If you don't define this, the default is two words. */ -#define LONG_DOUBLE_TYPE_SIZE 64 +#define LONG_DOUBLE_TYPE_SIZE \ + (mips_abi == ABI_N32 || mips_abi == ABI_64 ? 128 : 64) + +/* long double is not a fixed mode, but the idea is that, if we + support long double, we also want a 128-bit integer type. */ +#define MAX_FIXED_MODE_SIZE LONG_DOUBLE_TYPE_SIZE + +#ifdef IN_LIBGCC2 +#if (defined _ABIN32 && _MIPS_SIM == _ABIN32) \ + || (defined _ABI64 && _MIPS_SIM == _ABI64) +# define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 128 +# else +# define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64 +# endif +#endif /* Width in bits of a pointer. See also the macro `Pmode' defined below. */ @@ -1562,7 +1576,8 @@ do { \ #define STRUCTURE_SIZE_BOUNDARY 8 /* There is no point aligning anything to a rounder boundary than this. */ -#define BIGGEST_ALIGNMENT 64 +#define BIGGEST_ALIGNMENT ((mips_abi == ABI_N32 || mips_abi == ABI_64) \ + ? 128 : 64) /* Set this nonzero if move instructions will actually fail to work when given unaligned data. */ @@ -2624,7 +2639,9 @@ extern enum reg_class mips_char_to_class On the MIPS, R2 R3 and F0 F2 are the only register thus used. Currently, R2 and F0 are only implemented here (C has no complex type) */ -#define FUNCTION_VALUE_REGNO_P(N) ((N) == GP_RETURN || (N) == FP_RETURN) +#define FUNCTION_VALUE_REGNO_P(N) ((N) == GP_RETURN || (N) == FP_RETURN \ + || ((mips_abi == ABI_N32 || mips_abi == ABI_64) && FP_RETURN != GP_RETURN \ + && (N) == FP_RETURN + 2)) /* 1 if N is a possible register number for function argument passing. We have no FP argument registers when soft-float. When FP registers Index: gcc/config/mips/t-iris6 =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/mips/t-iris6,v retrieving revision 1.16 diff -u -p -r1.16 t-iris6 --- gcc/config/mips/t-iris6 12 Nov 2002 11:15:48 -0000 1.16 +++ gcc/config/mips/t-iris6 26 Dec 2002 00:07:05 -0000 @@ -18,3 +18,16 @@ CRTSTUFF_T_CFLAGS=-g1 # This is only needed in the static libgcc as a band-aid until gcc correctly # implements the N32/N64 ABI structure passing conventions LIB2FUNCS_STATIC_EXTRA = $(srcdir)/config/mips/irix6-libc-compat.c + +LIB2FUNCS_EXTRA = $(srcdir)/config/mips/_tilib.c + +TPBIT = tp-bit.c + +tp-bit.c: $(srcdir)/config/fp-bit.c + echo '#ifdef __MIPSEL__' > tp-bit.c + echo '# define FLOAT_BIT_ORDER_MISMATCH' >> tp-bit.c + echo '#endif' >> tp-bit.c + echo '#if __LDBL_MANT_DIG__ == 106' >> tp-bit.c + echo '# define TFLOAT' >> tp-bit.c + cat $(srcdir)/config/fp-bit.c >> tp-bit.c + echo '#endif' >> tp-bit.c [-- Attachment #3: Type: text/plain, Size: 289 bytes --] -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2002-12-26 13:48 ` Alexandre Oliva @ 2002-12-27 7:06 ` Alexandre Oliva 2002-12-29 0:22 ` Kaveh R. Ghazi 2003-01-07 22:57 ` Richard Henderson 0 siblings, 2 replies; 72+ messages in thread From: Alexandre Oliva @ 2002-12-27 7:06 UTC (permalink / raw) To: Kaveh R. Ghazi; +Cc: gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro [-- Attachment #1: Type: text/plain, Size: 1519 bytes --] On Dec 26, 2002, Alexandre Oliva <aoliva@redhat.com> wrote: > I doubt these further tweaks might have actually introduced any > regressions, so... Famous last words... Kaveh sent me in private a list of regressions, caused by: > instead of keeping even more excess precision for the emulation > of IRIX' long double to internally use the same number of bits as IEEE > 854 128-bit long doubles, which would probably cause rounding problems > unless I explicitly handled it, I arranged for the emulation library > to already keep 106 bits of mantissa. This broke the ``magic'' exponent adjustments in _fpmul_parts(), which forced me to figure out where the heck those magic constants came from, so I could clean them up. > Or even when the exponent is so small that the most-significant > double is normal but the least-significant one isn't. In this case, > I believe we should do some rounding, but I was not sure it actually > mattered, so I just left it out. And now I put it in, and fixed the representation and rounding of denormals in the least-significant double, that was formerly a bit off. I used two additional programs to verify that denormals were correct, and that they were being rounded correctly; for reference, they're attached after the patch. This patch fixes all failures that Kaveh pointed out in private, in all optimization levels. It's now undergoing a bootstrap&test cycle, that should be done, well, some day :-) In case it succeeds, ok for mainline (with Kaveh's patch) and 3.3? [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: gcc-mips-tfmode-emul-take4.patch --] [-- Type: text/x-patch, Size: 52593 bytes --] Index: gcc/ChangeLog from Alexandre Oliva <aoliva@redhat.com> * config/mips/mips.h (LONG_DUBLE_TYPE_SIZE): Set to 128 on N32 and N64. (MAX_FIXED_MODE_SIZE): Define to LONG_DOUBLE_TYPE_SIZE. (LIBGCC2_LONG_DOUBLE_TYPE_SIZE): Define. (BIGGEST_ALIGNMENT): Same as LONG_DOUBLE_TYPE_SIZE. (FUNCTION_VALUE_REGNO_P): Set for FP_RETURN+2 on N32 and N64. * config/mips/mips.c (mips_arg_info): Pass TFmode values in even FP registers on N32 and N64. (mips_va_start): Adjust alignment of ARG_POINTER_REGNUM. (mips_va_arg): Impose additional even-register-like alignment to 128-bit arguments. (override_options): Set TFmode format. Set it as allowable in FP registers. (mips_function_value): Return TFmode in $f0 and $f2 on N32 or N64. * config/mips/_tilib.c (__negti2, __ashlti3, __lshrti3): New. * config/mips/t-iris6 (LIB2FUNCS_EXTRA): Add _tilib.c. (TPBIT): Set to tp-bit.c. (tp-bit.c): Create out of fp-bit.c. * Makefile.in (FPBIT_FUNCS): Added _sf_to_tf. (DBBIT_FUNCS): Added _df_to_tf. (TPBIT_FUNCS): New. (libgcc.mk): Pass TPBIT and TPBIT_FUNCS down. (LIBGCC_DEPS): Added TPBIT. * mklibgcc.in: Support TPBIT and TPBIT_FUNCS. * fp-bit.h: Define macros for TFmode floating-point constants in IEEE and IBM-extended TFmode types. Declare functions according to L_ macros. (TMODES): Define if __LDBL_MANT_DIG__ has one of the newly-supported widths. (TFtype, TItype, UTItype): Define if TMODES is defined. (MAX_UDI_INT, MAX_DI_INT, BITS_PER_DI): Likewise. (F_T_BITOFF, D_T_BITOFF): Define. (IMPLICIT_1, IMPLICIT_2): Cast constants to types that are guaranteed to be wide enough. * config/fp-bit.c: Check for L_ macros for tf functions. (__thenan_tf): New. (nan): Adjust. (pack_d, unpack_d): Support IEEE 854 and IBM-extended TFmode types. (_fpmul_parts): Support TFmode. Compute exponent adjustment from FRAC_NBITS, FRAC_BITS and NGARDS. (usi_to_float): Cast constants to be shifted to fractype instead of assuming long long is wide enough. (sf_to_tf, df_to_tf, __make_tp, tf_to_df, tf_to_sf): New. * print-rtl.c (print_rtx): Don't print MEM details in GENERATOR_FILEs. * rtl.c (get_mode_alignment): Moved to... * stor-layout.c: ... here. * calls.c (emit_library_call_value_1): Handle return values in a PARALLEL. * expr.c (emit_group_store): Initialize dst with CONST0_RTX for the appropriate mode. * optabs.c (expand_binop) <add, sub>: Return xtarget if we haven't been able to move the result to target. * real.h (struct real_format): Add denorm_p, remove has_denorm. * real.c: Adjust all formats and references to has_denorm. * c-common.c (builtin_define_float_constants): Use denorm_p to define DENORM_MIN. Index: gcc/Makefile.in =================================================================== RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v retrieving revision 1.958 diff -u -p -r1.958 Makefile.in --- gcc/Makefile.in 24 Nov 2002 20:43:01 -0000 1.958 +++ gcc/Makefile.in 27 Dec 2002 13:11:06 -0000 @@ -796,12 +796,17 @@ LIB2FUNCS_ST = _eprintf _bb __gcc_bcmp FPBIT_FUNCS = _pack_sf _unpack_sf _addsub_sf _mul_sf _div_sf \ _fpcmp_parts_sf _compare_sf _eq_sf _ne_sf _gt_sf _ge_sf \ _lt_sf _le_sf _unord_sf _si_to_sf _sf_to_si _negate_sf _make_sf \ - _sf_to_df _thenan_sf _sf_to_usi _usi_to_sf + _sf_to_df _sf_to_tf _thenan_sf _sf_to_usi _usi_to_sf DPBIT_FUNCS = _pack_df _unpack_df _addsub_df _mul_df _div_df \ _fpcmp_parts_df _compare_df _eq_df _ne_df _gt_df _ge_df \ _lt_df _le_df _unord_df _si_to_df _df_to_si _negate_df _make_df \ - _df_to_sf _thenan_df _df_to_usi _usi_to_df + _df_to_sf _df_to_tf _thenan_df _df_to_usi _usi_to_df + +TPBIT_FUNCS = _pack_tf _unpack_tf _addsub_tf _mul_tf _div_tf \ + _fpcmp_parts_tf _compare_tf _eq_tf _ne_tf _gt_tf _ge_tf \ + _lt_tf _le_tf _unord_tf _si_to_tf _tf_to_si _negate_tf _make_tf \ + _tf_to_df _tf_to_sf _thenan_tf _tf_to_usi _usi_to_tf # These might cause a divide overflow trap and so are compiled with # unwinder info. @@ -1021,6 +1026,8 @@ libgcc.mk: config.status Makefile mklibg LIB2_DIVMOD_FUNCS='$(LIB2_DIVMOD_FUNCS)' \ DPBIT='$(DPBIT)' \ DPBIT_FUNCS='$(DPBIT_FUNCS)' \ + TPBIT='$(TPBIT)' \ + TPBIT_FUNCS='$(TPBIT_FUNCS)' \ MULTILIBS=`$(GCC_FOR_TARGET) --print-multi-lib` \ EXTRA_MULTILIB_PARTS='$(EXTRA_MULTILIB_PARTS)' \ SHLIB_LINK='$(SHLIB_LINK)' \ @@ -1040,8 +1047,9 @@ libgcc.mk: config.status Makefile mklibg LIBGCC_DEPS = $(GCC_PASSES) $(LANGUAGES) stmp-int-hdrs $(STMP_FIXPROTO) \ libgcc.mk $(srcdir)/libgcc2.c $(TCONFIG_H) \ $(MACHMODE_H) longlong.h gbl-ctors.h config.status stmp-int-hdrs \ - tsystem.h $(FPBIT) $(DPBIT) $(LIB2ADD) $(LIB2ADD_ST) $(LIB2ADDEH) \ - $(LIB2ADDEHDEP) $(EXTRA_PARTS) $(srcdir)/config/$(LIB1ASMSRC) + tsystem.h $(FPBIT) $(DPBIT) $(TPBIT) $(LIB2ADD) \ + $(LIB2ADD_ST) $(LIB2ADDEH) $(LIB2ADDEHDEP) $(EXTRA_PARTS) \ + $(srcdir)/config/$(LIB1ASMSRC) libgcc.a: $(LIBGCC_DEPS) $(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \ Index: gcc/c-common.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/c-common.c,v retrieving revision 1.393 diff -u -p -r1.393 c-common.c --- gcc/c-common.c 11 Dec 2002 06:36:04 -0000 1.393 +++ gcc/c-common.c 27 Dec 2002 13:11:10 -0000 @@ -4866,9 +4866,9 @@ builtin_define_float_constants (name_pre positive floating-point number, b**(emin-p). Zero for formats that don't support denormals. */ sprintf (name, "__%s_DENORM_MIN__", name_prefix); - if (fmt->has_denorm) + if (fmt->denorm_p) { - sprintf (buf, "0x1p%d", (fmt->emin - fmt->p) * fmt->log2_b); + sprintf (buf, "0x1p%d", (fmt->emin - fmt->denorm_p) * fmt->log2_b); builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix); } Index: gcc/calls.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/calls.c,v retrieving revision 1.244 diff -u -p -r1.244 calls.c --- gcc/calls.c 9 Dec 2002 17:54:03 -0000 1.244 +++ gcc/calls.c 27 Dec 2002 13:11:13 -0000 @@ -4131,7 +4131,7 @@ emit_library_call_value_1 (retval, orgfu { rtx insns; - if (valreg == 0 || GET_CODE (valreg) == PARALLEL) + if (valreg == 0) { insns = get_insns (); end_sequence (); @@ -4140,9 +4140,18 @@ emit_library_call_value_1 (retval, orgfu else { rtx note = 0; - rtx temp = gen_reg_rtx (GET_MODE (valreg)); + rtx temp; int i; + if (GET_CODE (valreg) == PARALLEL) + { + temp = gen_reg_rtx (outmode); + emit_group_store (temp, valreg, outmode); + valreg = temp; + } + + temp = gen_reg_rtx (GET_MODE (valreg)); + /* Construct an "equal form" for the value which mentions all the arguments in order as well as the function name. */ for (i = 0; i < nargs; i++) @@ -4175,6 +4184,12 @@ emit_library_call_value_1 (retval, orgfu value = mem_value; if (value != mem_value) emit_move_insn (value, mem_value); + } + else if (GET_CODE (valreg) == PARALLEL) + { + if (value == 0) + value = gen_reg_rtx (outmode); + emit_group_store (value, valreg, outmode); } else if (value != 0) emit_move_insn (value, valreg); Index: gcc/expr.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/expr.c,v retrieving revision 1.498.2.1 diff -u -p -r1.498.2.1 expr.c --- gcc/expr.c 23 Dec 2002 16:47:20 -0000 1.498.2.1 +++ gcc/expr.c 27 Dec 2002 13:11:20 -0000 @@ -2436,7 +2436,7 @@ emit_group_store (orig_dst, src, ssize) { dst = gen_reg_rtx (GET_MODE (orig_dst)); /* Make life a bit easier for combine. */ - emit_move_insn (dst, const0_rtx); + emit_move_insn (dst, CONST0_RTX (GET_MODE (orig_dst))); } /* Process the pieces. */ Index: gcc/mklibgcc.in =================================================================== RCS file: /cvs/gcc/gcc/gcc/mklibgcc.in,v retrieving revision 1.48 diff -u -p -r1.48 mklibgcc.in --- gcc/mklibgcc.in 3 Oct 2002 20:35:13 -0000 1.48 +++ gcc/mklibgcc.in 27 Dec 2002 13:11:20 -0000 @@ -21,6 +21,8 @@ # LIB2_DIVMOD_FUNCS # DPBIT # DPBIT_FUNCS +# TPBIT +# TPBIT_FUNCS # LIBGCC # MULTILIBS # EXTRA_MULTILIB_PARTS @@ -169,6 +171,21 @@ if [ "$DPBIT" ]; then echo $out: $DPBIT $fpbit_c_dep echo " $gcc_compile" -DFINE_GRAINED_LIBRARIES $flags -DL$name \ -c $DPBIT -o $out + done + libgcc2_objs="$libgcc2_objs ${name}${objext}" + done +fi + +if [ "$TPBIT" ]; then + for name in $TPBIT_FUNCS; do + for ml in $MULTILIBS; do + dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'` + flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`; + out="libgcc/${dir}/${name}${objext}" + + echo $out: $TPBIT $fpbit_c_dep + echo " $gcc_compile" -DFINE_GRAINED_LIBRARIES $flags -DL$name \ + -c $TPBIT -o $out done libgcc2_objs="$libgcc2_objs ${name}${objext}" done Index: gcc/optabs.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/optabs.c,v retrieving revision 1.153 diff -u -p -r1.153 optabs.c --- gcc/optabs.c 20 Nov 2002 21:52:59 -0000 1.153 +++ gcc/optabs.c 27 Dec 2002 13:11:22 -0000 @@ -1306,6 +1306,8 @@ expand_binop (mode, binoptab, op0, op1, copy_rtx (xop0), copy_rtx (xop1))); } + else + target = xtarget; return target; } Index: gcc/print-rtl.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/print-rtl.c,v retrieving revision 1.91 diff -u -p -r1.91 print-rtl.c --- gcc/print-rtl.c 16 Oct 2002 00:40:27 -0000 1.91 +++ gcc/print-rtl.c 27 Dec 2002 13:11:23 -0000 @@ -1,5 +1,5 @@ /* Print RTL for GNU C Compiler. - Copyright (C) 1987, 1988, 1992, 1997, 1998, 1999, 2000 + Copyright (C) 1987, 1988, 1992, 1997, 1998, 1999, 2000, 2002 Free Software Foundation, Inc. This file is part of GCC. @@ -491,6 +491,7 @@ print_rtx (in_rtx) switch (GET_CODE (in_rtx)) { +#ifndef GENERATOR_FILE case MEM: fputs (" [", outfile); fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, MEM_ALIAS_SET (in_rtx)); @@ -518,7 +519,6 @@ print_rtx (in_rtx) fputc (']', outfile); break; -#ifndef GENERATOR_FILE case CONST_DOUBLE: if (FLOAT_MODE_P (GET_MODE (in_rtx))) { Index: gcc/real.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/real.c,v retrieving revision 1.105 diff -u -p -r1.105 real.c --- gcc/real.c 17 Nov 2002 20:20:39 -0000 1.105 +++ gcc/real.c 27 Dec 2002 13:11:24 -0000 @@ -2353,7 +2353,7 @@ round_for_format (fmt, r) { int diff; - if (!fmt->has_denorm) + if (!fmt->denorm_p) { /* Don't underflow completely until we've had a chance to round. */ if (r->exp < emin2m1) @@ -2676,7 +2676,7 @@ decode_ieee_single (fmt, r, buf) if (exp == 0) { - if (image && fmt->has_denorm) + if (image && fmt->denorm_p) { r->class = rvc_normal; r->sign = sign; @@ -2719,12 +2719,12 @@ const struct real_format ieee_single_for 2, 1, 24, + 24, -125, 128, true, true, true, - true, true }; @@ -2845,7 +2845,7 @@ decode_ieee_double (fmt, r, buf) if (exp == 0) { - if ((image_hi || image_lo) && fmt->has_denorm) + if ((image_hi || image_lo) && fmt->denorm_p) { r->class = rvc_normal; r->sign = sign; @@ -2912,12 +2912,12 @@ const struct real_format ieee_double_for 2, 1, 53, + 53, -1021, 1024, true, true, true, - true, true }; @@ -3084,7 +3084,7 @@ decode_ieee_extended (fmt, r, buf) if (exp == 0) { - if ((sig_hi || sig_lo) && fmt->has_denorm) + if ((sig_hi || sig_lo) && fmt->denorm_p) { r->class = rvc_normal; r->sign = sign; @@ -3167,12 +3167,12 @@ const struct real_format ieee_extended_m 2, 1, 64, + 64, -16382, 16384, true, true, true, - true, true }; @@ -3183,12 +3183,12 @@ const struct real_format ieee_extended_i 2, 1, 64, + 64, -16381, 16384, true, true, true, - true, true }; @@ -3199,12 +3199,12 @@ const struct real_format ieee_extended_i 2, 1, 64, + 64, -16381, 16384, true, true, true, - true, true }; @@ -3292,12 +3292,12 @@ const struct real_format ibm_extended_fo 2, 1, 53 + 53, + 53, -1021, 1024, true, true, true, - true, true }; @@ -3461,7 +3461,7 @@ decode_ieee_quad (fmt, r, buf) if (exp == 0) { - if ((image3 | image2 | image1 | image0) && fmt->has_denorm) + if ((image3 | image2 | image1 | image0) && fmt->denorm_p) { r->class = rvc_normal; r->sign = sign; @@ -3545,12 +3545,12 @@ const struct real_format ieee_quad_forma 2, 1, 113, + 113, -16381, 16384, true, true, true, - true, true }; \f @@ -3852,12 +3852,12 @@ const struct real_format vax_f_format = 2, 1, 24, + 0, -127, 127, false, false, false, - false, false }; @@ -3868,12 +3868,12 @@ const struct real_format vax_d_format = 2, 1, 56, + 0, -127, 127, false, false, false, - false, false }; @@ -3884,12 +3884,12 @@ const struct real_format vax_g_format = 2, 1, 53, + 0, -1023, 1023, false, false, false, - false, false }; \f @@ -4065,12 +4065,12 @@ const struct real_format i370_single_for 16, 4, 6, + 0, /* ??? The encoding does allow for "unnormals". */ -64, 63, false, false, false, /* ??? The encoding does allow for "unnormals". */ - false, /* ??? The encoding does allow for "unnormals". */ false }; @@ -4081,12 +4081,12 @@ const struct real_format i370_double_for 16, 4, 14, + 0, /* ??? The encoding does allow for "unnormals". */ -64, 63, false, false, false, /* ??? The encoding does allow for "unnormals". */ - false, /* ??? The encoding does allow for "unnormals". */ false }; \f @@ -4295,12 +4295,12 @@ const struct real_format c4x_single_form 2, 1, 24, + 0, -126, 128, false, false, false, - false, false }; @@ -4311,12 +4311,12 @@ const struct real_format c4x_extended_fo 2, 1, 32, + 0, -126, 128, false, false, false, - false, false }; @@ -4356,11 +4356,11 @@ const struct real_format real_internal_f 2, 1, SIGNIFICAND_BITS - 2, + 0, -MAX_EXP, MAX_EXP, true, true, - false, true, true }; Index: gcc/real.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/real.h,v retrieving revision 1.59 diff -u -p -r1.59 real.h --- gcc/real.h 22 Oct 2002 00:17:15 -0000 1.59 +++ gcc/real.h 27 Dec 2002 13:11:25 -0000 @@ -118,6 +118,11 @@ struct real_format /* Size of the significand in digits of radix B. */ int p; + /* One plus the size of the significand of a denormalized number, in + digits of radix B. If zero, implies denormalized numbers are not + available. */ + int denorm_p; + /* The minimum negative integer, x, such that b**(x-1) is normalized. */ int emin; @@ -127,7 +132,6 @@ struct real_format /* Properties of the format. */ bool has_nans; bool has_inf; - bool has_denorm; bool has_signed_zero; bool qnan_msb_set; }; Index: gcc/rtl.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/rtl.c,v retrieving revision 1.120 diff -u -p -r1.120 rtl.c --- gcc/rtl.c 14 Oct 2002 02:36:25 -0000 1.120 +++ gcc/rtl.c 27 Dec 2002 13:11:25 -0000 @@ -396,29 +396,6 @@ shallow_copy_rtx (orig) return copy; } - -/* Return the alignment of MODE. This will be bounded by 1 and - BIGGEST_ALIGNMENT. */ - -unsigned int -get_mode_alignment (mode) - enum machine_mode mode; -{ - unsigned int alignment; - - if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT - || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT) - alignment = GET_MODE_UNIT_SIZE (mode); - else - alignment = GET_MODE_SIZE (mode); - - /* Extract the LSB of the size. */ - alignment = alignment & -alignment; - alignment *= BITS_PER_UNIT; - - alignment = MIN (BIGGEST_ALIGNMENT, MAX (1, alignment)); - return alignment; -} \f /* This is 1 until after the rtl generation pass. */ int rtx_equal_function_value_matters; Index: gcc/stor-layout.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/stor-layout.c,v retrieving revision 1.134 diff -u -p -r1.134 stor-layout.c --- gcc/stor-layout.c 20 Nov 2002 10:09:00 -0000 1.134 +++ gcc/stor-layout.c 27 Dec 2002 13:11:26 -0000 @@ -298,6 +298,29 @@ int_mode_for_mode (mode) return mode; } +/* Return the alignment of MODE. This will be bounded by 1 and + BIGGEST_ALIGNMENT. */ + +unsigned int +get_mode_alignment (mode) + enum machine_mode mode; +{ + unsigned int alignment; + + if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT + || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT) + alignment = GET_MODE_UNIT_SIZE (mode); + else + alignment = GET_MODE_SIZE (mode); + + /* Extract the LSB of the size. */ + alignment = alignment & -alignment; + alignment *= BITS_PER_UNIT; + + alignment = MIN (BIGGEST_ALIGNMENT, MAX (1, alignment)); + return alignment; +} + /* Return the value of VALUE, rounded up to a multiple of DIVISOR. This can only be applied to objects of a sizetype. */ Index: gcc/config/fp-bit.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/fp-bit.c,v retrieving revision 1.36 diff -u -p -r1.36 fp-bit.c --- gcc/config/fp-bit.c 7 Oct 2002 08:47:09 -0000 1.36 +++ gcc/config/fp-bit.c 27 Dec 2002 13:11:28 -0000 @@ -130,6 +130,10 @@ void __lttf2 (void) { abort(); } const fp_number_type __thenan_sf = { CLASS_SNAN, 0, 0, {(fractype) 0} }; #elif defined L_thenan_df const fp_number_type __thenan_df = { CLASS_SNAN, 0, 0, {(fractype) 0} }; +#elif defined L_thenan_tf +const fp_number_type __thenan_tf = { CLASS_SNAN, 0, 0, {(fractype) 0} }; +#elif defined TFLOAT +extern const fp_number_type __thenan_tf; #elif defined FLOAT extern const fp_number_type __thenan_sf; #else @@ -141,7 +145,9 @@ static fp_number_type * nan (void) { /* Discard the const qualifier... */ -#ifdef FLOAT +#ifdef TFLOAT + return (fp_number_type *) (& __thenan_tf); +#elif defined FLOAT return (fp_number_type *) (& __thenan_sf); #else return (fp_number_type *) (& __thenan_df); @@ -180,7 +186,7 @@ flip_sign ( fp_number_type * x) extern FLO_type pack_d ( fp_number_type * ); -#if defined(L_pack_df) || defined(L_pack_sf) +#if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf) FLO_type pack_d ( fp_number_type * src) { @@ -316,24 +322,92 @@ pack_d ( fp_number_type * src) dst.bits.exp = exp; dst.bits.sign = sign; #else +# if defined TFLOAT && defined HALFFRACBITS + { + halffractype high, low; + + high = (fraction >> (FRACBITS - HALFFRACBITS)); + high &= (((fractype)1) << HALFFRACBITS) - 1; + high |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << HALFFRACBITS; + high |= ((fractype) (sign & 1)) << (HALFFRACBITS | EXPBITS); + + low = (halffractype)fraction & + ((((halffractype)1) << (FRACBITS - HALFFRACBITS)) - 1); + + if (exp == EXPMAX || exp == 0 || low == 0) + low = 0; + else + { + exp -= HALFFRACBITS + 1; + + while (exp > 0 + && low < ((halffractype)1 << HALFFRACBITS)) + { + low <<= 1; + exp--; + } + + if (exp <= 0) + { + halffractype roundmsb, round; + + exp = -exp + 1; + + roundmsb = (1 << (exp - 1)); + round = low & ((roundmsb << 1) - 1); + + low >>= exp; + exp = 0; + + if (round > roundmsb || (round == roundmsb && (low & 1))) + { + low++; + if (low >= ((halffractype)1 << HALFFRACBITS)) + /* We don't shift left, since it has just become the + smallest normal number, whose implicit 1 bit is + now indicated by the non-zero exponent. */ + exp++; + } + } + + low &= ((halffractype)1 << HALFFRACBITS) - 1; + low |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << HALFFRACBITS; + low |= ((fractype) (sign & 1)) << (HALFFRACBITS | EXPBITS); + } + + dst.value_raw = (((fractype) high) << HALFSHIFT) | low; + } +# else dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1); dst.value_raw |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << FRACBITS; dst.value_raw |= ((fractype) (sign & 1)) << (FRACBITS | EXPBITS); +# endif #endif #if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT) +#ifdef TFLOAT + { + qrtrfractype tmp1 = dst.words[0]; + qrtrfractype tmp2 = dst.words[1]; + dst.words[0] = dst.words[3]; + dst.words[1] = dst.words[2]; + dst.words[2] = tmp2; + dst.words[3] = tmp1; + } +#else { halffractype tmp = dst.words[0]; dst.words[0] = dst.words[1]; dst.words[1] = tmp; } #endif +#endif return dst.value; } #endif -#if defined(L_unpack_df) || defined(L_unpack_sf) +#if defined(L_unpack_df) || defined(L_unpack_sf) || defined(L_unpack_tf) void unpack_d (FLO_union_type * src, fp_number_type * dst) { @@ -347,8 +421,15 @@ unpack_d (FLO_union_type * src, fp_numbe #if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT) FLO_union_type swapped; +#ifdef TFLOAT + swapped.words[0] = src->words[3]; + swapped.words[1] = src->words[2]; + swapped.words[2] = src->words[1]; + swapped.words[3] = src->words[0]; +#else swapped.words[0] = src->words[1]; swapped.words[1] = src->words[0]; +#endif src = &swapped; #endif @@ -357,9 +438,42 @@ unpack_d (FLO_union_type * src, fp_numbe exp = src->bits.exp; sign = src->bits.sign; #else - fraction = src->value_raw & ((((fractype)1) << FRACBITS) - (fractype)1); +# if defined TFLOAT && defined HALFFRACBITS + { + halffractype high, low; + + high = src->value_raw >> HALFSHIFT; + low = src->value_raw & (((fractype)1 << HALFSHIFT) - 1); + + fraction = high & ((((fractype)1) << HALFFRACBITS) - 1); + fraction <<= FRACBITS - HALFFRACBITS; + exp = ((int)(high >> HALFFRACBITS)) & ((1 << EXPBITS) - 1); + sign = ((int)(high >> (((HALFFRACBITS + EXPBITS))))) & 1; + + if (exp != EXPMAX && exp != 0 && low != 0) + { + int lowexp = ((int)(low >> HALFFRACBITS)) & ((1 << EXPBITS) - 1); + int shift; + fractype xlow; + + xlow = low & ((((fractype)1) << HALFFRACBITS) - 1); + if (lowexp) + xlow |= (((halffractype)1) << HALFFRACBITS); + else + lowexp = 1; + shift = (FRACBITS - HALFFRACBITS) - (exp - lowexp); + if (shift > 0) + xlow <<= shift; + else if (shift < 0) + xlow >>= -shift; + fraction += xlow; + } + } +# else + fraction = src->value_raw & ((((fractype)1) << FRACBITS) - 1); exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1); sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1; +# endif #endif dst->sign = sign; @@ -427,7 +541,7 @@ unpack_d (FLO_union_type * src, fp_numbe } #endif /* L_unpack_df || L_unpack_sf */ -#if defined(L_addsub_sf) || defined(L_addsub_df) +#if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf) static fp_number_type * _fpadd_parts (fp_number_type * a, fp_number_type * b, @@ -611,7 +725,7 @@ sub (FLO_type arg_a, FLO_type arg_b) } #endif /* L_addsub_sf || L_addsub_df */ -#if defined(L_mul_sf) || defined(L_mul_df) +#if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf) static inline __attribute__ ((__always_inline__)) fp_number_type * _fpmul_parts ( fp_number_type * a, fp_number_type * b, @@ -660,7 +774,7 @@ _fpmul_parts ( fp_number_type * a, /* Calculate the mantissa by multiplying both numbers to get a twice-as-wide number. */ { -#if defined(NO_DI_MODE) +#if defined(NO_DI_MODE) || defined(TFLOAT) { fractype x = a->fraction.ll; fractype ylow = b->fraction.ll; @@ -723,13 +837,9 @@ _fpmul_parts ( fp_number_type * a, #endif } - tmp->normal_exp = a->normal_exp + b->normal_exp; + tmp->normal_exp = a->normal_exp + b->normal_exp + + FRAC_NBITS - (FRACBITS + NGARDS); tmp->sign = a->sign != b->sign; -#ifdef FLOAT - tmp->normal_exp += 2; /* ??????????????? */ -#else - tmp->normal_exp += 4; /* ??????????????? */ -#endif while (high >= IMPLICIT_2) { tmp->normal_exp++; @@ -803,7 +913,7 @@ multiply (FLO_type arg_a, FLO_type arg_b } #endif /* L_mul_sf || L_mul_df */ -#if defined(L_div_sf) || defined(L_div_df) +#if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf) static inline __attribute__ ((__always_inline__)) fp_number_type * _fpdiv_parts (fp_number_type * a, fp_number_type * b) @@ -913,7 +1023,8 @@ divide (FLO_type arg_a, FLO_type arg_b) } #endif /* L_div_sf || L_div_df */ -#if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) +#if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) \ + || defined(L_fpcmp_parts_tf) /* according to the demo, fpcmp returns a comparison with 0... thus a<b -> -1 a==b -> 0 @@ -998,7 +1109,7 @@ __fpcmp_parts (fp_number_type * a, fp_nu } #endif -#if defined(L_compare_sf) || defined(L_compare_df) +#if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compoare_tf) CMPtype compare (FLO_type arg_a, FLO_type arg_b) { @@ -1020,7 +1131,7 @@ compare (FLO_type arg_a, FLO_type arg_b) /* These should be optimized for their specific tasks someday. */ -#if defined(L_eq_sf) || defined(L_eq_df) +#if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf) CMPtype _eq_f2 (FLO_type arg_a, FLO_type arg_b) { @@ -1041,7 +1152,7 @@ _eq_f2 (FLO_type arg_a, FLO_type arg_b) } #endif /* L_eq_sf || L_eq_df */ -#if defined(L_ne_sf) || defined(L_ne_df) +#if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf) CMPtype _ne_f2 (FLO_type arg_a, FLO_type arg_b) { @@ -1062,7 +1173,7 @@ _ne_f2 (FLO_type arg_a, FLO_type arg_b) } #endif /* L_ne_sf || L_ne_df */ -#if defined(L_gt_sf) || defined(L_gt_df) +#if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf) CMPtype _gt_f2 (FLO_type arg_a, FLO_type arg_b) { @@ -1083,7 +1194,7 @@ _gt_f2 (FLO_type arg_a, FLO_type arg_b) } #endif /* L_gt_sf || L_gt_df */ -#if defined(L_ge_sf) || defined(L_ge_df) +#if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf) CMPtype _ge_f2 (FLO_type arg_a, FLO_type arg_b) { @@ -1103,7 +1214,7 @@ _ge_f2 (FLO_type arg_a, FLO_type arg_b) } #endif /* L_ge_sf || L_ge_df */ -#if defined(L_lt_sf) || defined(L_lt_df) +#if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf) CMPtype _lt_f2 (FLO_type arg_a, FLO_type arg_b) { @@ -1124,7 +1235,7 @@ _lt_f2 (FLO_type arg_a, FLO_type arg_b) } #endif /* L_lt_sf || L_lt_df */ -#if defined(L_le_sf) || defined(L_le_df) +#if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf) CMPtype _le_f2 (FLO_type arg_a, FLO_type arg_b) { @@ -1147,7 +1258,7 @@ _le_f2 (FLO_type arg_a, FLO_type arg_b) #endif /* ! US_SOFTWARE_GOFAST */ -#if defined(L_unord_sf) || defined(L_unord_df) +#if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf) CMPtype _unord_f2 (FLO_type arg_a, FLO_type arg_b) { @@ -1165,7 +1276,7 @@ _unord_f2 (FLO_type arg_a, FLO_type arg_ } #endif /* L_unord_sf || L_unord_df */ -#if defined(L_si_to_sf) || defined(L_si_to_df) +#if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf) FLO_type si_to_float (SItype arg_a) { @@ -1193,7 +1304,7 @@ si_to_float (SItype arg_a) else in.fraction.ll = arg_a; - while (in.fraction.ll < (1LL << (FRACBITS + NGARDS))) + while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS))) { in.fraction.ll <<= 1; in.normal_exp -= 1; @@ -1203,7 +1314,7 @@ si_to_float (SItype arg_a) } #endif /* L_si_to_sf || L_si_to_df */ -#if defined(L_usi_to_sf) || defined(L_usi_to_df) +#if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf) FLO_type usi_to_float (USItype arg_a) { @@ -1220,12 +1331,12 @@ usi_to_float (USItype arg_a) in.normal_exp = FRACBITS + NGARDS; in.fraction.ll = arg_a; - while (in.fraction.ll > (1LL << (FRACBITS + NGARDS))) + while (in.fraction.ll > ((fractype)1 << (FRACBITS + NGARDS))) { in.fraction.ll >>= 1; in.normal_exp += 1; } - while (in.fraction.ll < (1LL << (FRACBITS + NGARDS))) + while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS))) { in.fraction.ll <<= 1; in.normal_exp -= 1; @@ -1235,7 +1346,7 @@ usi_to_float (USItype arg_a) } #endif -#if defined(L_sf_to_si) || defined(L_df_to_si) +#if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si) SItype float_to_si (FLO_type arg_a) { @@ -1263,8 +1374,8 @@ float_to_si (FLO_type arg_a) } #endif /* L_sf_to_si || L_df_to_si */ -#if defined(L_sf_to_usi) || defined(L_df_to_usi) -#ifdef US_SOFTWARE_GOFAST +#if defined(L_sf_to_usi) || defined(L_df_to_usi) || defined(L_tf_to_usi) +#if defined US_SOFTWARE_GOFAST || defined(L_tf_to_usi) /* While libgcc2.c defines its own __fixunssfsi and __fixunsdfsi routines, we also define them for GOFAST because the ones in libgcc2.c have the wrong names and I'd rather define these here and keep GOFAST CYG-LOC's @@ -1303,7 +1414,7 @@ float_to_usi (FLO_type arg_a) #endif /* US_SOFTWARE_GOFAST */ #endif /* L_sf_to_usi || L_df_to_usi */ -#if defined(L_negate_sf) || defined(L_negate_df) +#if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf) FLO_type negate (FLO_type arg_a) { @@ -1359,6 +1470,21 @@ sf_to_df (SFtype arg_a) } #endif /* L_sf_to_df */ +#if defined(L_sf_to_tf) && defined(TMODES) +TFtype +sf_to_tf (SFtype arg_a) +{ + fp_number_type in; + FLO_union_type au; + + au.value = arg_a; + unpack_d (&au, &in); + + return __make_tp (in.class, in.sign, in.normal_exp, + ((UTItype) in.fraction.ll) << F_T_BITOFF); +} +#endif /* L_sf_to_df */ + #endif /* ! FLOAT_ONLY */ #endif /* FLOAT */ @@ -1401,6 +1527,85 @@ df_to_sf (DFtype arg_a) return __make_fp (in.class, in.sign, in.normal_exp, sffrac); } #endif /* L_df_to_sf */ + +#if defined(L_df_to_tf) && defined(TMODES) \ + && !defined(FLOAT) && !defined(TFLOAT) +TFtype +df_to_tf (DFtype arg_a) +{ + fp_number_type in; + FLO_union_type au; + + au.value = arg_a; + unpack_d (&au, &in); + + return __make_tp (in.class, in.sign, in.normal_exp, + ((UTItype) in.fraction.ll) << D_T_BITOFF); +} +#endif /* L_sf_to_df */ + +#ifdef TFLOAT +#if defined(L_make_tf) +TFtype +__make_tp(fp_class_type class, + unsigned int sign, + int exp, + UTItype frac) +{ + fp_number_type in; + + in.class = class; + in.sign = sign; + in.normal_exp = exp; + in.fraction.ll = frac; + return pack_d (&in); +} +#endif /* L_make_tf */ + +#if defined(L_tf_to_df) +DFtype +tf_to_df (TFtype arg_a) +{ + fp_number_type in; + UDItype sffrac; + FLO_union_type au; + + au.value = arg_a; + unpack_d (&au, &in); + + sffrac = in.fraction.ll >> D_T_BITOFF; + + /* We set the lowest guard bit in SFFRAC if we discarded any non + zero bits. */ + if ((in.fraction.ll & (((UTItype) 1 << D_T_BITOFF) - 1)) != 0) + sffrac |= 1; + + return __make_dp (in.class, in.sign, in.normal_exp, sffrac); +} +#endif /* L_tf_to_df */ + +#if defined(L_tf_to_sf) +SFtype +tf_to_sf (TFtype arg_a) +{ + fp_number_type in; + USItype sffrac; + FLO_union_type au; + + au.value = arg_a; + unpack_d (&au, &in); + + sffrac = in.fraction.ll >> F_T_BITOFF; + + /* We set the lowest guard bit in SFFRAC if we discarded any non + zero bits. */ + if ((in.fraction.ll & (((UTItype) 1 << F_T_BITOFF) - 1)) != 0) + sffrac |= 1; + + return __make_fp (in.class, in.sign, in.normal_exp, sffrac); +} +#endif /* L_tf_to_sf */ +#endif /* TFLOAT */ #endif /* ! FLOAT */ #endif /* !EXTENDED_FLOAT_STUBS */ Index: gcc/config/fp-bit.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/fp-bit.h,v retrieving revision 1.7 diff -u -p -r1.7 fp-bit.h --- gcc/config/fp-bit.h 19 Jun 2002 23:01:59 -0000 1.7 +++ gcc/config/fp-bit.h 27 Dec 2002 13:11:28 -0000 @@ -1,5 +1,5 @@ /* Header file for fp-bit.c. */ -/* Copyright (C) 2000 +/* Copyright (C) 2000, 2002 Free Software Foundation, Inc. This file is part of GNU CC. @@ -87,12 +87,22 @@ Boston, MA 02111-1307, USA. */ #endif #endif /* ! FINE_GRAINED_LIBRARIES */ +#if __LDBL_MANT_DIG__ == 113 || __LDBL_MANT_DIG__ == 106 +# define TMODES +#endif + typedef float SFtype __attribute__ ((mode (SF))); typedef float DFtype __attribute__ ((mode (DF))); +#ifdef TMODES +typedef float TFtype __attribute__ ((mode (TF))); +#endif typedef int HItype __attribute__ ((mode (HI))); typedef int SItype __attribute__ ((mode (SI))); typedef int DItype __attribute__ ((mode (DI))); +#ifdef TMODES +typedef int TItype __attribute__ ((mode (TI))); +#endif /* The type of the result of a fp compare */ #ifndef CMPtype @@ -102,16 +112,68 @@ typedef int DItype __attribute__ ((mode typedef unsigned int UHItype __attribute__ ((mode (HI))); typedef unsigned int USItype __attribute__ ((mode (SI))); typedef unsigned int UDItype __attribute__ ((mode (DI))); +#ifdef TMODES +typedef unsigned int UTItype __attribute__ ((mode (TI))); +#endif #define MAX_USI_INT (~(USItype)0) #define MAX_SI_INT ((SItype) (MAX_USI_INT >> 1)) #define BITS_PER_SI (4 * BITS_PER_UNIT) +#ifdef TMODES +#define MAX_UDI_INT (~(UDItype)0) +#define MAX_DI_INT ((DItype) (MAX_UDI_INT >> 1)) +#define BITS_PER_DI (8 * BITS_PER_UNIT) +#endif #ifdef FLOAT_ONLY #define NO_DI_MODE #endif -#ifdef FLOAT +#ifdef TFLOAT +# ifndef TMODES +# error "TFLOAT requires long double to have 113 bits of mantissa" +# endif + +# define PREFIXFPDP tp +# define PREFIXSFDF tf +# define NGARDS 10L /* Is this right? */ +# define GARDROUND 0x1ff +# define GARDMASK 0x3ff +# define GARDMSB 0x200 +# define FRAC_NBITS 128 + +# if __LDBL_MANT_DIG__ == 113 /* IEEE quad */ +# define EXPBITS 15 +# define EXPBIAS 16383 +# define EXPMAX (0x7fff) +# define QUIET_NAN ((TItype)0x8 << 108) +# define FRACHIGH ((TItype)0x8 << 124) +# define FRACHIGH2 ((TItype)0xc << 124) +# define FRACBITS 112 +# endif + +# if __LDBL_MANT_DIG__ == 106 /* IBM extended (double+double) */ +# define EXPBITS 11 +# define EXPBIAS 1023 +# define EXPMAX (0x7ff) +# define QUIET_NAN ((TItype)0x8 << (48 + 64)) +# define FRACHIGH ((TItype)0x8 << 124) +# define FRACHIGH2 ((TItype)0xc << 124) +# define FRACBITS 105 +# define HALFFRACBITS 52 +# define HALFSHIFT 64 +# endif + +# define pack_d __pack_t +# define unpack_d __unpack_t +# define __fpcmp_parts __fpcmp_parts_t + typedef UTItype fractype; + typedef UDItype halffractype; + typedef USItype qrtrfractype; +#define qrtrfractype qrtrfractype + typedef TFtype FLO_type; + typedef TItype intfrac; +#elif defined FLOAT # define NGARDS 7L # define GARDROUND 0x3f # define GARDMASK 0x7f @@ -157,7 +219,9 @@ typedef unsigned int UDItype __attribute #endif /* FLOAT */ #ifdef US_SOFTWARE_GOFAST -# ifdef FLOAT +# ifdef TFLOAT +# error "GOFAST TFmode not supported" +# elif defined FLOAT # define add fpadd # define sub fpsub # define multiply fpmul @@ -170,8 +234,8 @@ typedef unsigned int UDItype __attribute # define float_to_usi fptoui # define negate __negsf2 # define sf_to_df fptodp -# define dptofp dptofp -#else +# define sf_to_tf __extendsftf2 +# else # define add dpadd # define sub dpsub # define multiply dpmul @@ -184,9 +248,30 @@ typedef unsigned int UDItype __attribute # define float_to_usi dptoul # define negate __negdf2 # define df_to_sf dptofp +# define df_to_tf __extenddftf2 # endif /* FLOAT */ #else -# ifdef FLOAT +# ifdef TFLOAT +# define add __addtf3 +# define sub __subtf3 +# define multiply __multf3 +# define divide __divtf3 +# define compare __cmptf2 +# define _eq_f2 __eqtf2 +# define _ne_f2 __netf2 +# define _gt_f2 __gttf2 +# define _ge_f2 __getf2 +# define _lt_f2 __lttf2 +# define _le_f2 __letf2 +# define _unord_f2 __unordtf2 +# define usi_to_float __floatunsitf +# define si_to_float __floatsitf +# define float_to_si __fixtfsi +# define float_to_usi __fixunstfsi +# define negate __negtf2 +# define tf_to_sf __trunctfsf2 +# define tf_to_df __trunctfdf2 +# elif defined FLOAT # define add __addsf3 # define sub __subsf3 # define multiply __mulsf3 @@ -205,7 +290,8 @@ typedef unsigned int UDItype __attribute # define float_to_usi __fixunssfsi # define negate __negsf2 # define sf_to_df __extendsfdf2 -#else +# define sf_to_tf __extendsftf2 +# else # define add __adddf3 # define sub __subdf3 # define multiply __muldf3 @@ -224,6 +310,7 @@ typedef unsigned int UDItype __attribute # define float_to_usi __fixunsdfsi # define negate __negdf2 # define df_to_sf __truncdfsf2 +# define df_to_tf __extenddftf2 # endif /* FLOAT */ #endif /* US_SOFTWARE_GOFAST */ @@ -241,10 +328,15 @@ typedef unsigned int UDItype __attribute */ #define F_D_BITOFF (52+8-(23+7)) +#ifdef TMODES +# define F_T_BITOFF (__LDBL_MANT_DIG__-1+10-(23+7)) +# define D_T_BITOFF (__LDBL_MANT_DIG__-1+10-(52+8)) +#endif + #define NORMAL_EXPMIN (-(EXPBIAS)+1) -#define IMPLICIT_1 (1LL<<(FRACBITS+NGARDS)) -#define IMPLICIT_2 (1LL<<(FRACBITS+1+NGARDS)) +#define IMPLICIT_1 ((fractype)1<<(FRACBITS+NGARDS)) +#define IMPLICIT_2 ((fractype)1<<(FRACBITS+1+NGARDS)) /* common types */ @@ -282,7 +374,11 @@ typedef union fractype value_raw; #ifndef FLOAT +# ifdef qrtrfractype + qrtrfractype qwords[4]; +# else halffractype words[2]; +# endif #endif #ifdef FLOAT_BIT_ORDER_MISMATCH @@ -317,82 +413,82 @@ FLO_union_type; /* Prototypes */ -#if defined(L_pack_df) || defined(L_pack_sf) +#if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf) extern FLO_type pack_d (fp_number_type *); #endif extern void unpack_d (FLO_union_type *, fp_number_type *); -#if defined(L_addsub_sf) || defined(L_addsub_df) +#if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf) extern FLO_type add (FLO_type, FLO_type); extern FLO_type sub (FLO_type, FLO_type); #endif -#if defined(L_mul_sf) || defined(L_mul_df) +#if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf) extern FLO_type multiply (FLO_type, FLO_type); #endif -#if defined(L_div_sf) || defined(L_div_df) +#if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf) extern FLO_type divide (FLO_type, FLO_type); #endif extern int __fpcmp_parts (fp_number_type *, fp_number_type *); -#if defined(L_compare_sf) || defined(L_compare_df) +#if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compare_tf) extern CMPtype compare (FLO_type, FLO_type); #endif #ifndef US_SOFTWARE_GOFAST -#if defined(L_eq_sf) || defined(L_eq_df) +#if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf) extern CMPtype _eq_f2 (FLO_type, FLO_type); #endif -#if defined(L_ne_sf) || defined(L_ne_df) +#if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf) extern CMPtype _ne_f2 (FLO_type, FLO_type); #endif -#if defined(L_gt_sf) || defined(L_gt_df) +#if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf) extern CMPtype _gt_f2 (FLO_type, FLO_type); #endif -#if defined(L_ge_sf) || defined(L_ge_df) +#if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf) extern CMPtype _ge_f2 (FLO_type, FLO_type); #endif -#if defined(L_lt_sf) || defined(L_lt_df) +#if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf) extern CMPtype _lt_f2 (FLO_type, FLO_type); #endif -#if defined(L_le_sf) || defined(L_le_df) +#if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf) extern CMPtype _le_f2 (FLO_type, FLO_type); #endif -#if defined(L_unord_sf) || defined(L_unord_df) +#if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf) extern CMPtype _unord_f2 (FLO_type, FLO_type); #endif #endif /* ! US_SOFTWARE_GOFAST */ -#if defined(L_si_to_sf) || defined(L_si_to_df) +#if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf) extern FLO_type si_to_float (SItype); #endif -#if defined(L_sf_to_si) || defined(L_df_to_si) +#if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si) extern SItype float_to_si (FLO_type); #endif -#if defined(L_sf_to_usi) || defined(L_df_to_usi) +#if defined(L_sf_to_usi) || defined(L_df_to_usi) || defined(L_tf_to_usi) #ifdef US_SOFTWARE_GOFAST extern USItype float_to_usi (FLO_type); #endif #endif -#if defined(L_usi_to_sf) || defined(L_usi_to_df) +#if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf) extern FLO_type usi_to_float (USItype); #endif -#if defined(L_negate_sf) || defined(L_negate_df) +#if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf) extern FLO_type negate (FLO_type); #endif @@ -405,6 +501,9 @@ extern DFtype __make_dp (fp_class_type, #if defined(L_sf_to_df) extern DFtype sf_to_df (SFtype); #endif +#if defined(L_sf_to_tf) && defined(TMODES) +extern TFtype sf_to_tf (SFtype); +#endif #endif /* ! FLOAT_ONLY */ #endif /* FLOAT */ @@ -416,6 +515,24 @@ extern DFtype __make_dp (fp_class_type, #if defined(L_df_to_sf) extern SFtype df_to_sf (DFtype); #endif +#if defined(L_df_to_tf) && defined(TMODES) +extern TFtype df_to_tf (DFtype); +#endif #endif /* ! FLOAT */ + +#ifdef TMODES +extern TFtype __make_tp (fp_class_type, unsigned int, int, UTItype); +#ifdef TFLOAT +#if defined(L_tf_to_sf) +extern SFtype tf_to_sf (TFtype); +#endif +#if defined(L_tf_to_df) +extern DFtype tf_to_df (TFtype); +#endif +#if defined(L_di_to_tf) +extern TFtype di_to_df (DItype); +#endif +#endif /* TFLOAT */ +#endif /* TMODES */ #endif /* ! GCC_FP_BIT_H */ Index: gcc/config/mips/_tilib.c =================================================================== RCS file: gcc/config/mips/_tilib.c diff -N gcc/config/mips/_tilib.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gcc/config/mips/_tilib.c 27 Dec 2002 13:11:28 -0000 @@ -0,0 +1,154 @@ +/* A few TImode functions needed for TFmode emulated arithmetic. + Copyright 2002 Free Software Foundation, Inc. + Contributed by Alexandre Oliva <aoliva@redhat.com> + +This file is part of GNU CC. + +GNU CC 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. + +GNU CC 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 GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + + +#include "tconfig.h" +#include "tsystem.h" + +#ifndef LIBGCC2_WORDS_BIG_ENDIAN +#define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN +#endif + +#if _MIPS_SIM == 2 /* N32 */ || _MIPS_SIM == 3 /* 64 */ + +typedef int TItype __attribute__ ((mode (TI))); +typedef int DItype __attribute__ ((mode (DI))); +typedef int SItype __attribute__ ((mode (SI))); + +typedef unsigned int UDItype __attribute__ ((mode (DI))); + +typedef union +{ + struct TIstruct { +#if LIBGCC2_WORDS_BIG_ENDIAN + DItype high, low; +#else + DItype low, high; +#endif + } s; + TItype ll; +} TIunion; + +TItype +__negti2 (TItype u) +{ + TIunion w; + TIunion uu; + + uu.ll = u; + + w.s.low = -uu.s.low; + w.s.high = -uu.s.high - ((UDItype) w.s.low > 0); + + return w.ll; +} + +TItype +__ashlti3 (TItype u, int b) +{ + TIunion w; + int bm; + TIunion uu; + + if (b == 0) + return u; + + uu.ll = u; + + bm = (sizeof (DItype) * BITS_PER_UNIT) - b; + if (bm <= 0) + { + w.s.low = 0; + w.s.high = (UDItype) uu.s.low << -bm; + } + else + { + UDItype carries = (UDItype) uu.s.low >> bm; + + w.s.low = (UDItype) uu.s.low << b; + w.s.high = ((UDItype) uu.s.high << b) | carries; + } + + return w.ll; +} + +#if 0 +TItype +__ashrti3 (TItype u, int b) +{ + TIunion w; + int bm; + TIunion uu; + + if (b == 0) + return u; + + uu.ll = u; + + bm = (sizeof (DItype) * BITS_PER_UNIT) - b; + if (bm <= 0) + { + /* w.s.high = 1..1 or 0..0 */ + w.s.high = uu.s.high >> (sizeof (DItype) * BITS_PER_UNIT - 1); + w.s.low = uu.s.high >> -bm; + } + else + { + UDItype carries = (UDItype) uu.s.high << bm; + + w.s.high = uu.s.high >> b; + w.s.low = ((UDItype) uu.s.low >> b) | carries; + } + + return w.ll; +} +#endif + +TItype +__lshrti3 (TItype u, int b) +{ + TIunion w; + int bm; + TIunion uu; + + if (b == 0) + return u; + + uu.ll = u; + + bm = (sizeof (DItype) * BITS_PER_UNIT) - b; + if (bm <= 0) + { + w.s.high = 0; + w.s.low = (UDItype) uu.s.high >> -bm; + } + else + { + UDItype carries = (UDItype) uu.s.high << bm; + + w.s.high = (UDItype) uu.s.high >> b; + w.s.low = ((UDItype) uu.s.low >> b) | carries; + } + + return w.ll; +} + +#endif /* N32 or N64 */ Index: gcc/config/mips/mips.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.c,v retrieving revision 1.241 diff -u -p -r1.241 mips.c --- gcc/config/mips/mips.c 12 Dec 2002 05:13:03 -0000 1.241 +++ gcc/config/mips/mips.c 27 Dec 2002 13:11:35 -0000 @@ -4286,7 +4286,9 @@ mips_arg_info (cum, mode, type, named, i info->fpr_p = false; if (GET_MODE_CLASS (mode) == MODE_FLOAT - && GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE) + && GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE * ((mips_abi == ABI_N32 + || mips_abi == ABI_64) + ? 2 : 1)) { switch (mips_abi) { @@ -4321,9 +4323,11 @@ mips_arg_info (cum, mode, type, named, i is a double, but $f14 if it is a single. Otherwise, on a 32-bit double-float machine, each FP argument must start in a new register pair. */ - even_reg_p = ((mips_abi == ABI_O64 && mode == SFmode) || FP_INC > 1); + even_reg_p = (GET_MODE_SIZE (mode) > UNITS_PER_FPVALUE /* TFmode */ + || (mips_abi == ABI_O64 && mode == SFmode) + || FP_INC > 1); } - else if (!TARGET_64BIT) + else if (!TARGET_64BIT || mips_abi == ABI_N32 || mips_abi == ABI_64) { if (GET_MODE_CLASS (mode) == MODE_INT || GET_MODE_CLASS (mode) == MODE_FLOAT) @@ -4712,6 +4716,15 @@ mips_va_start (valist, nextarg) { const CUMULATIVE_ARGS *cum = ¤t_function_args_info; + /* ARG_POINTER_REGNUM is initialized to STACK_POINTER_BOUNDARY, but + since the stack is aligned for a pair of argument-passing slots, + and the beginning of a variable argument list may be an odd slot, + we have to decrease its alignment. */ + if (cfun && cfun->emit->regno_pointer_align) + while (((current_function_pretend_args_size * BITS_PER_UNIT) + & (REGNO_POINTER_ALIGN (ARG_POINTER_REGNUM) - 1)) != 0) + REGNO_POINTER_ALIGN (ARG_POINTER_REGNUM) /= 2; + if (mips_abi == ABI_EABI) { int gpr_save_area_size; @@ -5007,7 +5020,10 @@ mips_va_arg (valist, type) that alignments <= UNITS_PER_WORD are preserved by the va_arg increment mechanism. */ - if (TARGET_64BIT) + if ((mips_abi == ABI_N32 || mips_abi == ABI_64) + && TYPE_ALIGN (type) > 64) + align = 16; + else if (TARGET_64BIT) align = 8; else if (TYPE_ALIGN (type) > 32) align = 8; @@ -5365,6 +5381,8 @@ override_options () else mips16 = 0; + real_format_for_mode[TFmode - QFmode] = &ibm_extended_format; + mips_print_operand_punct['?'] = 1; mips_print_operand_punct['#'] = 1; mips_print_operand_punct['&'] = 1; @@ -5454,7 +5472,10 @@ override_options () register. */ || (mips_abi == ABI_MEABI && size <= 4)) && (((class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT) - && size <= UNITS_PER_FPVALUE) + && size <= (UNITS_PER_FPVALUE + * ((mips_abi == ABI_N32 + || mips_abi == ABI_64) + ? 2 : 1))) /* Allow integer modes that fit into a single register. We need to put integers into FPRs when using instructions like cvt and trunc. */ @@ -8271,8 +8292,24 @@ mips_function_value (valtype, func, mode } mclass = GET_MODE_CLASS (mode); - if (mclass == MODE_FLOAT && GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE) + if (mclass == MODE_FLOAT + && GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE) reg = FP_RETURN; + + else if (mclass == MODE_FLOAT + && mode == TFmode + && (mips_abi == ABI_N32 || mips_abi == ABI_64)) + /* long doubles are really split between f0 and f2, not f1. Eek. */ + return gen_rtx_PARALLEL + (VOIDmode, + gen_rtvec (2, + gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_REG (DImode, FP_RETURN), + GEN_INT (0)), + gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_REG (DImode, FP_RETURN + 2), + GEN_INT (GET_MODE_SIZE (mode) / 2)))); + else if (mclass == MODE_COMPLEX_FLOAT && GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE * 2) Index: gcc/config/mips/mips.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.h,v retrieving revision 1.227 diff -u -p -r1.227 mips.h --- gcc/config/mips/mips.h 5 Nov 2002 12:41:52 -0000 1.227 +++ gcc/config/mips/mips.h 27 Dec 2002 13:11:38 -0000 @@ -1535,7 +1535,21 @@ do { \ /* A C expression for the size in bits of the type `long double' on the target machine. If you don't define this, the default is two words. */ -#define LONG_DOUBLE_TYPE_SIZE 64 +#define LONG_DOUBLE_TYPE_SIZE \ + (mips_abi == ABI_N32 || mips_abi == ABI_64 ? 128 : 64) + +/* long double is not a fixed mode, but the idea is that, if we + support long double, we also want a 128-bit integer type. */ +#define MAX_FIXED_MODE_SIZE LONG_DOUBLE_TYPE_SIZE + +#ifdef IN_LIBGCC2 +#if (defined _ABIN32 && _MIPS_SIM == _ABIN32) \ + || (defined _ABI64 && _MIPS_SIM == _ABI64) +# define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 128 +# else +# define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64 +# endif +#endif /* Width in bits of a pointer. See also the macro `Pmode' defined below. */ @@ -1562,7 +1576,8 @@ do { \ #define STRUCTURE_SIZE_BOUNDARY 8 /* There is no point aligning anything to a rounder boundary than this. */ -#define BIGGEST_ALIGNMENT 64 +#define BIGGEST_ALIGNMENT ((mips_abi == ABI_N32 || mips_abi == ABI_64) \ + ? 128 : 64) /* Set this nonzero if move instructions will actually fail to work when given unaligned data. */ @@ -2624,7 +2639,9 @@ extern enum reg_class mips_char_to_class On the MIPS, R2 R3 and F0 F2 are the only register thus used. Currently, R2 and F0 are only implemented here (C has no complex type) */ -#define FUNCTION_VALUE_REGNO_P(N) ((N) == GP_RETURN || (N) == FP_RETURN) +#define FUNCTION_VALUE_REGNO_P(N) ((N) == GP_RETURN || (N) == FP_RETURN \ + || ((mips_abi == ABI_N32 || mips_abi == ABI_64) && FP_RETURN != GP_RETURN \ + && (N) == FP_RETURN + 2)) /* 1 if N is a possible register number for function argument passing. We have no FP argument registers when soft-float. When FP registers Index: gcc/config/mips/t-iris6 =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/mips/t-iris6,v retrieving revision 1.16 diff -u -p -r1.16 t-iris6 --- gcc/config/mips/t-iris6 12 Nov 2002 11:15:48 -0000 1.16 +++ gcc/config/mips/t-iris6 27 Dec 2002 13:11:38 -0000 @@ -18,3 +18,16 @@ CRTSTUFF_T_CFLAGS=-g1 # This is only needed in the static libgcc as a band-aid until gcc correctly # implements the N32/N64 ABI structure passing conventions LIB2FUNCS_STATIC_EXTRA = $(srcdir)/config/mips/irix6-libc-compat.c + +LIB2FUNCS_EXTRA = $(srcdir)/config/mips/_tilib.c + +TPBIT = tp-bit.c + +tp-bit.c: $(srcdir)/config/fp-bit.c + echo '#ifdef __MIPSEL__' > tp-bit.c + echo '# define FLOAT_BIT_ORDER_MISMATCH' >> tp-bit.c + echo '#endif' >> tp-bit.c + echo '#if __LDBL_MANT_DIG__ == 106' >> tp-bit.c + echo '# define TFLOAT' >> tp-bit.c + cat $(srcdir)/config/fp-bit.c >> tp-bit.c + echo '#endif' >> tp-bit.c [-- Attachment #3: Type: text/plain, Size: 289 bytes --] -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2002-12-27 7:06 ` Alexandre Oliva @ 2002-12-29 0:22 ` Kaveh R. Ghazi 2002-12-29 6:06 ` Alexandre Oliva 2003-01-07 22:57 ` Richard Henderson 1 sibling, 1 reply; 72+ messages in thread From: Kaveh R. Ghazi @ 2002-12-29 0:22 UTC (permalink / raw) To: aoliva; +Cc: gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro > From: Alexandre Oliva <aoliva@redhat.com> > > In case it succeeds, ok for mainline (with Kaveh's patch) and 3.3? > > Index: gcc/ChangeLog > from Alexandre Oliva <aoliva@redhat.com> > > * config/mips/mips.h (LONG_DUBLE_TYPE_SIZE): Set to 128 on N32 > and N64. > [...] Success! This one worked for me w/3.3, no regressions and the original 27_io/ostream_inserter_arith now passes. Thanks a bunch Alexandre :-) --Kaveh -- Kaveh R. Ghazi ghazi@caip.rutgers.edu ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2002-12-29 0:22 ` Kaveh R. Ghazi @ 2002-12-29 6:06 ` Alexandre Oliva 0 siblings, 0 replies; 72+ messages in thread From: Alexandre Oliva @ 2002-12-29 6:06 UTC (permalink / raw) To: Kaveh R. Ghazi; +Cc: gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro On Dec 29, 2002, "Kaveh R. Ghazi" <ghazi@caip.rutgers.edu> wrote: >> From: Alexandre Oliva <aoliva@redhat.com> >> >> In case it succeeds, ok for mainline (with Kaveh's patch) and 3.3? >> >> Index: gcc/ChangeLog >> from Alexandre Oliva <aoliva@redhat.com> >> >> * config/mips/mips.h (LONG_DUBLE_TYPE_SIZE): Set to 128 on N32 >> and N64. >> [...] > Success! This one worked for me w/3.3, no regressions and the > original 27_io/ostream_inserter_arith now passes. Yay! I got such results too, so I think we're safe here. Now, does anyone with global write privileges care to review this? > Thanks a bunch Alexandre :-) And thank you for all the testing! It helped very much! -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2002-12-27 7:06 ` Alexandre Oliva 2002-12-29 0:22 ` Kaveh R. Ghazi @ 2003-01-07 22:57 ` Richard Henderson 2003-01-08 18:16 ` Alexandre Oliva ` (9 more replies) 1 sibling, 10 replies; 72+ messages in thread From: Richard Henderson @ 2003-01-07 22:57 UTC (permalink / raw) To: Alexandre Oliva Cc: Kaveh R. Ghazi, gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro This should have been split into several smaller patches. On Fri, Dec 27, 2002 at 11:47:15AM -0200, Alexandre Oliva wrote: > * Makefile.in (FPBIT_FUNCS): Added _sf_to_tf. > (DBBIT_FUNCS): Added _df_to_tf. > (TPBIT_FUNCS): New. > (libgcc.mk): Pass TPBIT and TPBIT_FUNCS down. > (LIBGCC_DEPS): Added TPBIT. > * mklibgcc.in: Support TPBIT and TPBIT_FUNCS. Ok. > * fp-bit.h: Define macros for TFmode floating-point constants > in IEEE and IBM-extended TFmode types. Declare functions > according to L_ macros. > (TMODES): Define if __LDBL_MANT_DIG__ has one of > the newly-supported widths. > (TFtype, TItype, UTItype): Define if TMODES is defined. > (MAX_UDI_INT, MAX_DI_INT, BITS_PER_DI): Likewise. > (F_T_BITOFF, D_T_BITOFF): Define. > (IMPLICIT_1, IMPLICIT_2): Cast constants to types that are > guaranteed to be wide enough. > * config/fp-bit.c: Check for L_ macros for tf functions. > (__thenan_tf): New. > (nan): Adjust. > (pack_d, unpack_d): Support IEEE 854 and IBM-extended TFmode > types. > (_fpmul_parts): Support TFmode. Compute exponent adjustment > from FRAC_NBITS, FRAC_BITS and NGARDS. > (usi_to_float): Cast constants to be shifted to fractype > instead of assuming long long is wide enough. > (sf_to_tf, df_to_tf, __make_tp, tf_to_df, tf_to_sf): New. Ok, I guess. I'd kinda prefer that we use different names for the routines than __addtf etc for the IBM format. This would allow the IBM double-double format and the IEEE quad format routines to co-exist on one platform, which would allow non-Irix to use a more sensible format unambiguously. I won't insist on this though. > * print-rtl.c (print_rtx): Don't print MEM details in > GENERATOR_FILEs. Ok. > * rtl.c (get_mode_alignment): Moved to... > * stor-layout.c: ... here. Ok. > * calls.c (emit_library_call_value_1): Handle return values > in a PARALLEL. Ok. Yet another clue that these routines should be removed, and replaced with the generic call functions. > * expr.c (emit_group_store): Initialize dst with CONST0_RTX > for the appropriate mode. Ok. > * optabs.c (expand_binop) <add, sub>: Return xtarget if we haven't > been able to move the result to target. Ok, I guess. How does this come up? > * real.h (struct real_format): Add denorm_p, remove has_denorm. > * real.c: Adjust all formats and references to has_denorm. > * c-common.c (builtin_define_float_constants): Use denorm_p to > define DENORM_MIN. This one's sticky. Strictly speaking, the double-double format isn't LIA-1 compliant (too few denormal bits), and so libstdc++ ought to be setting denorm_min to zero. On the other hand, I can see that this value might still be useful for some people. Run it by the libstdc++ language lawyers. r~ ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-07 22:57 ` Richard Henderson @ 2003-01-08 18:16 ` Alexandre Oliva 2003-01-08 22:19 ` Richard Henderson 2003-01-10 1:18 ` Alexandre Oliva ` (8 subsequent siblings) 9 siblings, 1 reply; 72+ messages in thread From: Alexandre Oliva @ 2003-01-08 18:16 UTC (permalink / raw) To: Richard Henderson Cc: Kaveh R. Ghazi, gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro On Jan 7, 2003, Richard Henderson <rth@redhat.com> wrote: >> * real.h (struct real_format): Add denorm_p, remove has_denorm. >> * real.c: Adjust all formats and references to has_denorm. >> * c-common.c (builtin_define_float_constants): Use denorm_p to >> define DENORM_MIN. > This one's sticky. Strictly speaking, the double-double format > isn't LIA-1 compliant (too few denormal bits) I've no idea of what LIA-1 is, but it does have as many denormal bits as normal bits, it's just that the minimum exponent for a denormal is higher than that of a plain doubles, since denormals start with the higher double still being normal. -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-08 18:16 ` Alexandre Oliva @ 2003-01-08 22:19 ` Richard Henderson 2003-01-09 9:29 ` Alexandre Oliva 0 siblings, 1 reply; 72+ messages in thread From: Richard Henderson @ 2003-01-08 22:19 UTC (permalink / raw) To: Alexandre Oliva Cc: Kaveh R. Ghazi, gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro On Wed, Jan 08, 2003 at 03:17:49PM -0200, Alexandre Oliva wrote: > I've no idea of what LIA-1 is, but it does have as many denormal bits > as normal bits, it's just that the minimum exponent for a denormal is > higher than that of a plain doubles, since denormals start with the > higher double still being normal. Huh? No it doesn't. The minimum normalized double-double is { DBL_MIN_FLT, 0 }. r~ ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-08 22:19 ` Richard Henderson @ 2003-01-09 9:29 ` Alexandre Oliva 2003-01-09 9:38 ` Alexandre Oliva 0 siblings, 1 reply; 72+ messages in thread From: Alexandre Oliva @ 2003-01-09 9:29 UTC (permalink / raw) To: Richard Henderson Cc: Kaveh R. Ghazi, gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro On Jan 8, 2003, Richard Henderson <rth@redhat.com> wrote: > On Wed, Jan 08, 2003 at 03:17:49PM -0200, Alexandre Oliva wrote: >> I've no idea of what LIA-1 is, but it does have as many denormal bits >> as normal bits, it's just that the minimum exponent for a denormal is >> higher than that of a plain doubles, since denormals start with the >> higher double still being normal. > Huh? No it doesn't. The minimum normalized double-double is > { DBL_MIN_FLT, 0 }. Nevermind, I was thinking having a denormal in the lower double would make the whole thing denormal, but in this case the lower double definitely isn't denormal. Anyway, without this hunk, we get an incorrect DENORM_MIN, and tests fail. DENORM_MIN isn't as low as MIN_FLT / 2**106, and that's the problem. This was the cleanest way I found to introduce the possibility of having fewer denorm bits than mantissa bits, which is exactly the case of this FP format. Any better suggestions on how to accomplish this? I think claiming we don't have denormals is not the right answer either. -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-09 9:29 ` Alexandre Oliva @ 2003-01-09 9:38 ` Alexandre Oliva 0 siblings, 0 replies; 72+ messages in thread From: Alexandre Oliva @ 2003-01-09 9:38 UTC (permalink / raw) To: Richard Henderson Cc: Kaveh R. Ghazi, gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro On Jan 9, 2003, Alexandre Oliva <aoliva@redhat.com> wrote: > On Jan 8, 2003, Richard Henderson <rth@redhat.com> wrote: >> On Wed, Jan 08, 2003 at 03:17:49PM -0200, Alexandre Oliva wrote: >>> I've no idea of what LIA-1 is, but it does have as many denormal bits >>> as normal bits, it's just that the minimum exponent for a denormal is >>> higher than that of a plain doubles, since denormals start with the >>> higher double still being normal. >> Huh? No it doesn't. The minimum normalized double-double is >> { DBL_MIN_FLT, 0 }. > Nevermind, I was thinking having a denormal in the lower double would > make the whole thing denormal, but in this case the lower double > definitely isn't denormal. On third thought :-), it actually is a denormal, not in the double representation, but in the notion that implies that denormals don't have as much precision as normals. Even though there is an implicit one in the representation of the first double, if you represented the mantissa as a sequence of 106 bits, you'd get this implicit one within the denormal range. The fact that you can represent it as a normal is just an artifact of the long double representation. Well, not really, since the exponent range still enables you to represent it as normal, but it really depends on which aspects of denormals matter. My thought is that loss of mantissa bits is more important than whether there is an implied one next to the MSB of the mantissa, so I'm now trying to model that. This means LDBL_MIN_FLT should be bumped up to represent this fact too, but I suspect this would trigger other sorts of problems, so... There's no Right Thing (TM) to do... Darn, who came up with this long double representation, and why? :-( -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-07 22:57 ` Richard Henderson 2003-01-08 18:16 ` Alexandre Oliva @ 2003-01-10 1:18 ` Alexandre Oliva 2003-01-10 2:29 ` Richard Henderson 2003-01-10 1:37 ` Alexandre Oliva ` (7 subsequent siblings) 9 siblings, 1 reply; 72+ messages in thread From: Alexandre Oliva @ 2003-01-10 1:18 UTC (permalink / raw) To: Richard Henderson Cc: Kaveh R. Ghazi, gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro On Jan 7, 2003, Richard Henderson <rth@redhat.com> wrote: >> * real.h (struct real_format): Add denorm_p, remove has_denorm. >> * real.c: Adjust all formats and references to has_denorm. >> * c-common.c (builtin_define_float_constants): Use denorm_p to >> define DENORM_MIN. > This one's sticky. Strictly speaking, the double-double format > isn't LIA-1 compliant (too few denormal bits), and so libstdc++ > ought to be setting denorm_min to zero. On the other hand, I > can see that this value might still be useful for some people. > Run it by the libstdc++ language lawyers. I've just gone through the C++ Standard's numeric_limits definitions and the C99's float.h specification, and I couldn't find any reason to not use the definitions the way I've introduced them. The fact that they get the libstdc++-v3 testsuite to pass in cases it didn't before seems to be a good indication that it is good enough. Ok to check it all in? -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-10 1:18 ` Alexandre Oliva @ 2003-01-10 2:29 ` Richard Henderson 2003-01-19 21:02 ` Kaveh R. Ghazi 0 siblings, 1 reply; 72+ messages in thread From: Richard Henderson @ 2003-01-10 2:29 UTC (permalink / raw) To: Alexandre Oliva Cc: Kaveh R. Ghazi, gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro On Thu, Jan 09, 2003 at 09:53:55PM -0200, Alexandre Oliva wrote: > I've just gone through the C++ Standard's numeric_limits definitions > and the C99's float.h specification, and I couldn't find any reason > to not use the definitions the way I've introduced them. Irritatingly, I think my copy of LIA-1 is at home on a machine that's powered off. But C++ references it, so I think you have to look there and not in the C++ standard directly. What I remember is that min denormal must be 2**-p below the min normalized number. Which isn't satisfied in this case. > The fact > that they get the libstdc++-v3 testsuite to pass in cases it didn't > before seems to be a good indication that it is good enough. Feh. I wrote those test cases. Don't take them as definitive. r~ ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-10 2:29 ` Richard Henderson @ 2003-01-19 21:02 ` Kaveh R. Ghazi 2003-01-19 22:15 ` Alexandre Oliva 0 siblings, 1 reply; 72+ messages in thread From: Kaveh R. Ghazi @ 2003-01-19 21:02 UTC (permalink / raw) To: aoliva; +Cc: gcc-bugs, gcc-patches, gcc, ghazi, libstdc++, oldham, ro, rth So, what happened to the irix6 long double patch? --Kaveh -- Kaveh R. Ghazi ghazi@caip.rutgers.edu ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-19 21:02 ` Kaveh R. Ghazi @ 2003-01-19 22:15 ` Alexandre Oliva 2003-01-26 13:00 ` Alexandre Oliva 2003-01-26 15:20 ` Alexandre Oliva 0 siblings, 2 replies; 72+ messages in thread From: Alexandre Oliva @ 2003-01-19 22:15 UTC (permalink / raw) To: Kaveh R. Ghazi; +Cc: gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro, rth On Jan 19, 2003, "Kaveh R. Ghazi" <ghazi@caip.rutgers.edu> wrote: > So, what happened to the irix6 long double patch? It will require some changes, after all. As per my reading of LIA (this morning, talk about coincidence :-), the minimum normal exponent should be set such that all 107 significant bits are available (and it's 107, not 106, as I implemented it) for normals. This means we'll consider denormals even numbers that have only the lower double as a denormal. Which is in line with one of the approaches I had suggested (not that it counts much; I've probably enumerated all approaches that could possibly make sense, and most that couldn't :-D This conclusion was drawn based on the formal definition of the normalized and denormalized sets, as well as the informal definitions of normalized (those values of a floating point type F that provide the full precision allowed by that type) and denormalized (those that don't), regardless of the actual representation. I believe this settles it. Now it just needs someone to implement these changes. Unfortunately, the mips64-linux-gnu port I'd been working on, that looked like would need IRIX compatibility in terms of floating point format, ended up with a different format, so I no longer have a good reason to put work time into finishing the patch. I've been trying to find spare time to do it in a voluntary basis, but spare time is approaching non-existence from the negative range :-) Anyway, if I had the time, I'd start by adding 53 to the minimum exponent range in real.c and fp-bit.h, bumping up the mantissa size by 1 and reverting the denorm_p changes I made in real.c and c-common.c. This would probably require some tweaks in the functions that convert into and out of ibm_extended_format in real.c, such that the change in the minimum exponent doesn't change the representation of any numbers, and probably some similar fixes in fp-bit.c, for the same reason. Would you like to give it a try? Or would you rather my cobble up some day a new version of the patch for you to try? Please let me know. -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-19 22:15 ` Alexandre Oliva @ 2003-01-26 13:00 ` Alexandre Oliva 2003-01-28 17:32 ` Alexandre Oliva 2003-01-26 15:20 ` Alexandre Oliva 1 sibling, 1 reply; 72+ messages in thread From: Alexandre Oliva @ 2003-01-26 13:00 UTC (permalink / raw) To: Kaveh R. Ghazi; +Cc: gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro, rth [-- Attachment #1: Type: text/plain, Size: 571 bytes --] On Jan 19, 2003, Alexandre Oliva <aoliva@redhat.com> wrote: > the minimum normal exponent should be set such that all 107 > significant bits are available (and it's 107, not 106, as I > implemented it) for normals. It can't possibly be 107. IRIX must be doing something wrong in setting LDBL_MANT_DIG to 107, since there are only 53 bits of precision in each double, even if you count the implicit 1s. Besides, the emulation I implemented worked correctly down to the least significant bits with IRIX's printf, so I'm checking these bits in too, per rth's approval. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: gcc-mips-tfmode-fp-bit-ibmext.patch --] [-- Type: text/x-patch, Size: 4851 bytes --] Index: gcc/ChangeLog from Alexandre Oliva <aoliva@redhat.com> * fp-bit.h: Define macros for TFmode floating-point constants in IBM-extended TFmode types. (TMODES): Define if __LDBL_MANT_DIG__ has the newly-supported widths. * config/fp-bit.c (pack_d, unpack_d): Support IBM-extended TFmode type. Index: gcc/config/fp-bit.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/fp-bit.c,v retrieving revision 1.36.4.1 diff -u -p -r1.36.4.1 fp-bit.c --- gcc/config/fp-bit.c 26 Jan 2003 09:30:38 -0000 1.36.4.1 +++ gcc/config/fp-bit.c 26 Jan 2003 10:01:20 -0000 @@ -322,9 +322,66 @@ pack_d ( fp_number_type * src) dst.bits.exp = exp; dst.bits.sign = sign; #else +# if defined TFLOAT && defined HALFFRACBITS + { + halffractype high, low; + + high = (fraction >> (FRACBITS - HALFFRACBITS)); + high &= (((fractype)1) << HALFFRACBITS) - 1; + high |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << HALFFRACBITS; + high |= ((fractype) (sign & 1)) << (HALFFRACBITS | EXPBITS); + + low = (halffractype)fraction & + ((((halffractype)1) << (FRACBITS - HALFFRACBITS)) - 1); + + if (exp == EXPMAX || exp == 0 || low == 0) + low = 0; + else + { + exp -= HALFFRACBITS + 1; + + while (exp > 0 + && low < ((halffractype)1 << HALFFRACBITS)) + { + low <<= 1; + exp--; + } + + if (exp <= 0) + { + halffractype roundmsb, round; + + exp = -exp + 1; + + roundmsb = (1 << (exp - 1)); + round = low & ((roundmsb << 1) - 1); + + low >>= exp; + exp = 0; + + if (round > roundmsb || (round == roundmsb && (low & 1))) + { + low++; + if (low >= ((halffractype)1 << HALFFRACBITS)) + /* We don't shift left, since it has just become the + smallest normal number, whose implicit 1 bit is + now indicated by the non-zero exponent. */ + exp++; + } + } + + low &= ((halffractype)1 << HALFFRACBITS) - 1; + low |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << HALFFRACBITS; + low |= ((fractype) (sign & 1)) << (HALFFRACBITS | EXPBITS); + } + + dst.value_raw = (((fractype) high) << HALFSHIFT) | low; + } +# else dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1); dst.value_raw |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << FRACBITS; dst.value_raw |= ((fractype) (sign & 1)) << (FRACBITS | EXPBITS); +# endif #endif #if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT) @@ -381,9 +438,42 @@ unpack_d (FLO_union_type * src, fp_numbe exp = src->bits.exp; sign = src->bits.sign; #else +# if defined TFLOAT && defined HALFFRACBITS + { + halffractype high, low; + + high = src->value_raw >> HALFSHIFT; + low = src->value_raw & (((fractype)1 << HALFSHIFT) - 1); + + fraction = high & ((((fractype)1) << HALFFRACBITS) - 1); + fraction <<= FRACBITS - HALFFRACBITS; + exp = ((int)(high >> HALFFRACBITS)) & ((1 << EXPBITS) - 1); + sign = ((int)(high >> (((HALFFRACBITS + EXPBITS))))) & 1; + + if (exp != EXPMAX && exp != 0 && low != 0) + { + int lowexp = ((int)(low >> HALFFRACBITS)) & ((1 << EXPBITS) - 1); + int shift; + fractype xlow; + + xlow = low & ((((fractype)1) << HALFFRACBITS) - 1); + if (lowexp) + xlow |= (((halffractype)1) << HALFFRACBITS); + else + lowexp = 1; + shift = (FRACBITS - HALFFRACBITS) - (exp - lowexp); + if (shift > 0) + xlow <<= shift; + else if (shift < 0) + xlow >>= -shift; + fraction += xlow; + } + } +# else fraction = src->value_raw & ((((fractype)1) << FRACBITS) - 1); exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1); sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1; +# endif #endif dst->sign = sign; Index: gcc/config/fp-bit.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/fp-bit.h,v retrieving revision 1.7.18.1 diff -u -p -r1.7.18.1 fp-bit.h --- gcc/config/fp-bit.h 26 Jan 2003 09:30:38 -0000 1.7.18.1 +++ gcc/config/fp-bit.h 26 Jan 2003 10:01:20 -0000 @@ -87,7 +87,7 @@ Boston, MA 02111-1307, USA. */ #endif #endif /* ! FINE_GRAINED_LIBRARIES */ -#if __LDBL_MANT_DIG__ == 113 +#if __LDBL_MANT_DIG__ == 113 || __LDBL_MANT_DIG__ == 106 # define TMODES #endif @@ -150,6 +150,18 @@ typedef unsigned int UTItype __attribute # define FRACHIGH ((TItype)0x8 << 124) # define FRACHIGH2 ((TItype)0xc << 124) # define FRACBITS 112 +# endif + +# if __LDBL_MANT_DIG__ == 106 /* IBM extended (double+double) */ +# define EXPBITS 11 +# define EXPBIAS 1023 +# define EXPMAX (0x7ff) +# define QUIET_NAN ((TItype)0x8 << (48 + 64)) +# define FRACHIGH ((TItype)0x8 << 124) +# define FRACHIGH2 ((TItype)0xc << 124) +# define FRACBITS 105 +# define HALFFRACBITS 52 +# define HALFSHIFT 64 # endif # define pack_d __pack_t [-- Attachment #3: Type: text/plain, Size: 289 bytes --] -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-26 13:00 ` Alexandre Oliva @ 2003-01-28 17:32 ` Alexandre Oliva 2003-01-28 23:38 ` Alexandre Oliva 0 siblings, 1 reply; 72+ messages in thread From: Alexandre Oliva @ 2003-01-28 17:32 UTC (permalink / raw) To: Kaveh R. Ghazi; +Cc: gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro, rth On Jan 26, 2003, Alexandre Oliva <aoliva@redhat.com> wrote: > On Jan 19, 2003, Alexandre Oliva <aoliva@redhat.com> wrote: >> the minimum normal exponent should be set such that all 107 >> significant bits are available (and it's 107, not 106, as I >> implemented it) for normals. > It can't possibly be 107. On second (or rather nth) thought, it possibly can, if you take advantage of the sign bit of the second double. But then you have to allow it to be different from the sign of the first double, which we don't, and the conversion routines would have to be tweaked to take advantage of it without losing the additional bit of precision. Furthermore, a way to implement most of the emulation without having to use integers has occurred to me. Here's the idea. For addition of two long-doubles composed of a pair of doubles - add the most significant double of each number. If the result is infinity, NaN, copy it to the second double of the result and you're done - otherwise, figure out which of the numbers you're adding has the biggest exponent. Take a copy of the result obtained so far into a temporary say tmp and, from it, subtract the most significant double of each of the input operands. Now this temporary contains the negated value of whatever bits there were in the high doubles that had to be thrown away due to rounding or limited precision from the high part of the result. - assign to the low part of the result the result of adding the negated temporary, the low doubles of the input operands, highest exponent first in pseudo-code (untested): long double tfadd (long double in1, long double in2) { long double result; double tmp; result.high = in1.high + in2.high; if (isinf (result.high) || isnan (result.high)) { result.low = result.high; return result; } result.low = in1.low + in2.low; if (in1.exponent < in2.exponent) result.low -= result.high - in1.high - in2.high; else result.low -= result.high - in2.high - in1.high; return result; } For negation, just negate each double individually. For subtraction, negate the second operand and add. For widening multiplication (double x double -> long double): - multiply the doubles into the high part of the result - if the result is infinity, a nan or zero, copy the high part of the low part and stop. - divide the result by one of the input doubles into tmp1 - subtract the other input double from tmp1 into tmp2 - multiply tmp2 by the other input double into the low part of the result long double tfdfmult (double in1, double in2) { long double result; result.high = in1 * in2; if (isinf (result.high) || isnan (result.high) || result.high == 0.0) result.low = result.high; else result.low = (result.high / in1 - in2) * in1; return result; } For multiplication of two long doubles: - widen-multiply each pair of doubles, and add the results from least to most significant. long double tfmult (long double in1, long double in2) { if (exponent (in1) < exponent (in2)) swap (in1, in2); return tfdfmult (in1.low, in2.low) + tfdfmult (in1.low, in2.high) + tfdfmult (in1.high, in2.low) + tfdfmult (in1.high, in2.high); } To invert: ??? this is the missing bit :-( To divide, invert the divisor and multiply. For the numerical experts, are there any flaws in the procedures above? Any ideas on how to implement inversion without losing (much) precision? -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-28 17:32 ` Alexandre Oliva @ 2003-01-28 23:38 ` Alexandre Oliva 0 siblings, 0 replies; 72+ messages in thread From: Alexandre Oliva @ 2003-01-28 23:38 UTC (permalink / raw) To: Kaveh R. Ghazi; +Cc: gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro, rth On Jan 28, 2003, Alexandre Oliva <aoliva@redhat.com> wrote: > To invert: ??? this is the missing bit :-( > To divide, invert the divisor and multiply. Just figured out how to do division, using addition, subtraction and multiplication: - obtain an initial estimate of the result by dividing the high parts - compute a residue by subtracting from the dividend the result of multiplying the result estimate and the divisor - divide the high part of the residue by the high part of the divisor, and add it to the result - repeat the last two steps until the result stops changing I think it doesn't take more than 2 iterations for the result to stabilize. Here's the pseudo code: long double divide(long double in1, long double in2) { long double result, prev; result.high = in1.high / in2.high; if (isinf (result.high) || isnan (result.high)) { result.low = result.high; return result; } result.low = 0.0; do { long double partial; prev = result; partial.high = (in1 - result * in2).high / in2.high; partial.low = 0.0; result += partial; } while (result != prev); return result; } Other operations, such as extending from double, compares, etc, are pretty obvious, so I'll refrain from posting them here. Conversion to/from int can be done with extension to/truncation from double, and conversion to/from long long takes a bit more work to use all 64 bits, but that's it. Wheee! Any candidates to implement say gcc/config/tp-ibmext-bit.c using these ideas, even though we have no immediate use for them? -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-19 22:15 ` Alexandre Oliva 2003-01-26 13:00 ` Alexandre Oliva @ 2003-01-26 15:20 ` Alexandre Oliva 2003-01-26 16:14 ` Alexandre Oliva 1 sibling, 1 reply; 72+ messages in thread From: Alexandre Oliva @ 2003-01-26 15:20 UTC (permalink / raw) To: Kaveh R. Ghazi; +Cc: gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro, rth [-- Attachment #1: Type: text/plain, Size: 1693 bytes --] On Jan 19, 2003, Alexandre Oliva <aoliva@redhat.com> wrote: > This means we'll consider denormals even numbers that have only the > lower double as a denormal. Which is in line with one of the > approaches I had suggested (not that it counts much; I've probably > enumerated all approaches that could possibly make sense, and most > that couldn't :-D > This conclusion was drawn based on the formal definition of the > normalized and denormalized sets, as well as the informal definitions > of normalized (those values of a floating point type F that provide > the full precision allowed by that type) and denormalized (those that > don't), regardless of the actual representation. I believe this > settles it. > Anyway, if I had the time, I'd start by adding 53 to the minimum > exponent range in real.c This patch implements this change. I've already done some testing on IRIX, and it appears to give correct results, but bootstrap and libstdc++ testing is still running. Ok to install in 3.3 and mainline if it completes? > and fp-bit.h There's no such thing there. The code already works as expected. > bumping up the mantissa size by 1 Wrong, as explained in another e-mail. > and reverting the denorm_p changes I made in real.c and c-common.c. Or rather not even putting them in. > This would probably require some tweaks in the functions that convert > into and out of ibm_extended_format in real.c, It doesn't, they're simple enough that the change in the minimum exponent doesn't affect them at all. > and probably some similar fixes in fp-bit.c No changes needed there either. It's not really concerned about where the boundary between normals and denormals is. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: gcc-mips-tfmode-ibmext-minexp.patch --] [-- Type: text/x-patch, Size: 545 bytes --] Index: gcc/ChangeLog from Alexandre Oliva <aoliva@redhat.com> * real.c (ibm_extended_format): Add 53 to minimum exponent. Index: gcc/real.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/real.c,v retrieving revision 1.105 diff -u -p -r1.105 real.c --- gcc/real.c 17 Nov 2002 20:20:39 -0000 1.105 +++ gcc/real.c 26 Jan 2003 10:47:06 -0000 @@ -3292,7 +3292,7 @@ const struct real_format ibm_extended_fo 2, 1, 53 + 53, - -1021, + -1021 + 53, 1024, true, true, [-- Attachment #3: Type: text/plain, Size: 289 bytes --] -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-26 15:20 ` Alexandre Oliva @ 2003-01-26 16:14 ` Alexandre Oliva 2003-01-26 18:40 ` Kaveh R. Ghazi ` (2 more replies) 0 siblings, 3 replies; 72+ messages in thread From: Alexandre Oliva @ 2003-01-26 16:14 UTC (permalink / raw) To: Kaveh R. Ghazi; +Cc: gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro, rth [-- Attachment #1: Type: text/plain, Size: 435 bytes --] On Jan 26, 2003, Alexandre Oliva <aoliva@redhat.com> wrote: > * real.c (ibm_extended_format): Add 53 to minimum exponent. Turned out this got encode_ibm_extended very confused when presented with denormals, not only numbers that had to be represented as denormal doubles, but also those that could still use a normal double for the upper part. This new patch fixes it, and actually passes the numeric_limits test. Ok to install? [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: gcc-mips-tfmode-ibmext-minexp.patch --] [-- Type: text/x-patch, Size: 1748 bytes --] Index: gcc/ChangeLog from Alexandre Oliva <aoliva@redhat.com> * real.c (ibm_extended_format): Add 53 to minimum exponent. (encode_ibm_extended): Adjust. Index: gcc/real.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/real.c,v retrieving revision 1.105 diff -u -p -r1.105 real.c --- gcc/real.c 17 Nov 2002 20:20:39 -0000 1.105 +++ gcc/real.c 26 Jan 2003 12:43:40 -0000 @@ -1,6 +1,6 @@ /* real.c - software floating point emulation. Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2002 Free Software Foundation, Inc. + 1999, 2000, 2002, 2003 Free Software Foundation, Inc. Contributed by Stephen L. Moshier (moshier@world.std.com). Re-written by Richard Henderson <rth@redhat.com> @@ -3254,8 +3254,23 @@ encode_ibm_extended (fmt, buf, r) u = *r; clear_significand_below (&u, SIGNIFICAND_BITS - 53); - /* v = remainder containing additional 53 bits of significand. */ - do_add (&v, r, &u, 1); + normalize (&u); + /* If the upper double is zero, we have a denormal double, so + move it to the first double and leave the second as zero. */ + if (u.class == rvc_zero) + { + v = u; + u = *r; + normalize (&u); + } + else + { + /* v = remainder containing additional 53 bits of significand. */ + do_add (&v, r, &u, 1); + round_for_format (&ieee_double_format, &v); + } + + round_for_format (&ieee_double_format, &u); encode_ieee_double (&ieee_double_format, &buf[0], &u); encode_ieee_double (&ieee_double_format, &buf[2], &v); @@ -3292,7 +3307,7 @@ const struct real_format ibm_extended_fo 2, 1, 53 + 53, - -1021, + -1021 + 53, 1024, true, true, [-- Attachment #3: Type: text/plain, Size: 289 bytes --] -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-26 16:14 ` Alexandre Oliva @ 2003-01-26 18:40 ` Kaveh R. Ghazi 2003-01-26 21:24 ` Kaveh R. Ghazi 2003-01-26 21:54 ` Richard Henderson 2 siblings, 0 replies; 72+ messages in thread From: Kaveh R. Ghazi @ 2003-01-26 18:40 UTC (permalink / raw) To: aoliva; +Cc: gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro, rth > From: Alexandre Oliva <aoliva@redhat.com> > > On Jan 26, 2003, Alexandre Oliva <aoliva@redhat.com> wrote: > > > * real.c (ibm_extended_format): Add 53 to minimum exponent. > > Turned out this got encode_ibm_extended very confused when presented > with denormals, not only numbers that had to be represented as > denormal doubles, but also those that could still use a normal double > for the upper part. This new patch fixes it, and actually passes the > numeric_limits test. Ok to install? Great Alexandre, thanks! I'm going to try and test this on irix6.5. I took a 3.3 checkout from this morning plus the following three patches: http://gcc.gnu.org/ml/gcc-patches/2003-01/msg02039.html http://gcc.gnu.org/ml/gcc-patches/2003-01/msg02026.html http://gcc.gnu.org/ml/gcc-patches/2003-01/msg02041.html Is that the correct set? (Results should be done tonight.) --Kaveh -- Kaveh R. Ghazi ghazi@caip.rutgers.edu ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-26 16:14 ` Alexandre Oliva 2003-01-26 18:40 ` Kaveh R. Ghazi @ 2003-01-26 21:24 ` Kaveh R. Ghazi 2003-01-26 21:25 ` Alexandre Oliva 2003-01-27 9:17 ` Kaveh R. Ghazi 2003-01-26 21:54 ` Richard Henderson 2 siblings, 2 replies; 72+ messages in thread From: Kaveh R. Ghazi @ 2003-01-26 21:24 UTC (permalink / raw) To: aoliva; +Cc: gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro, rth > I'm going to try and test this on irix6.5. I took a 3.3 checkout from > this morning plus the following three patches: > > http://gcc.gnu.org/ml/gcc-patches/2003-01/msg02039.html > http://gcc.gnu.org/ml/gcc-patches/2003-01/msg02026.html > http://gcc.gnu.org/ml/gcc-patches/2003-01/msg02041.html > > Is that the correct set? (Results should be done tonight.) Well that was a dismal failure. It bootstrapped but I get 178 libstdc++-v3 execute errors and 18_support/numeric_limits.cc fails compilation: ld32: ERROR 33 : Unresolved text symbol "__gttf2" -- 1st referenced by /var/tmp//cc40eXre.o. Use linker option -v to see when and which objects, archives and dsos are loaded. ld32: ERROR 33 : Unresolved text symbol "__addtf3" -- 1st referenced by /var/tmp//cc40eXre.o. Use linker option -v to see when and which objects, archives and dsos are loaded. ld32: ERROR 33 : Unresolved text symbol "__eqtf2" -- 1st referenced by /var/tmp//cc40eXre.o. Use linker option -v to see when and which objects, archives and dsos are loaded. ld32: ERROR 33 : Unresolved text symbol "__netf2" -- 1st referenced by /var/tmp//cc40eXre.o. Use linker option -v to see when and which objects, archives and dsos are loaded. ld32: INFO 152: Output file removed because of error. collect2: ld returned 2 exit status It's quite possible I misapplied the patches... -- Kaveh R. Ghazi ghazi@caip.rutgers.edu ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-26 21:24 ` Kaveh R. Ghazi @ 2003-01-26 21:25 ` Alexandre Oliva 2003-01-27 9:17 ` Kaveh R. Ghazi 1 sibling, 0 replies; 72+ messages in thread From: Alexandre Oliva @ 2003-01-26 21:25 UTC (permalink / raw) To: Kaveh R. Ghazi; +Cc: gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro, rth On Jan 26, 2003, "Kaveh R. Ghazi" <ghazi@caip.rutgers.edu> wrote: > ld32: ERROR 33 : Unresolved text symbol "__gttf2" -- 1st referenced > by /var/tmp//cc40eXre.o. Hmm... This could result from your check-out not having the second round of changes to gcc/config/fp-bit.[ch]. Does it? -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-26 21:24 ` Kaveh R. Ghazi 2003-01-26 21:25 ` Alexandre Oliva @ 2003-01-27 9:17 ` Kaveh R. Ghazi 2003-01-27 10:40 ` Alexandre Oliva 2003-01-27 10:41 ` Alexandre Oliva 1 sibling, 2 replies; 72+ messages in thread From: Kaveh R. Ghazi @ 2003-01-27 9:17 UTC (permalink / raw) To: aoliva; +Cc: gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro, rth > From: Alexandre Oliva > > On Jan 26, 2003, "Kaveh R. Ghazi" <ghazi@caip.rutgers.edu> wrote: > > > ld32: ERROR 33 : Unresolved text symbol "__gttf2" -- 1st referenced > > by /var/tmp//cc40eXre.o. > > Hmm... This could result from your check-out not having the second > round of changes to gcc/config/fp-bit.[ch]. Does it? I think it did, but I'll try again with a fresh cvs update. I'm using the patch below against 3.3. If it's not correct, would you please send me your combined diffs and tell me whether I should use a 3.3 or 3.4 snapshot? Thanks, --Kaveh PS: what were your results on irix6? diff -rup orig/egcc-CVS20030126/gcc/config/mips/_tilib.c egcc-CVS20030126/gcc/config/mips/_tilib.c --- orig/egcc-CVS20030126/gcc/config/mips/_tilib.c 2003-01-26 09:08:00.770641267 -0500 +++ egcc-CVS20030126/gcc/config/mips/_tilib.c 2003-01-26 09:07:10.494518827 -0500 @@ -0,0 +1,154 @@ +/* A few TImode functions needed for TFmode emulated arithmetic. + Copyright 2002, 2003 Free Software Foundation, Inc. + Contributed by Alexandre Oliva <aoliva@redhat.com> + +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, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + + +#include "tconfig.h" +#include "tsystem.h" + +#ifndef LIBGCC2_WORDS_BIG_ENDIAN +#define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN +#endif + +#if _MIPS_SIM == 2 /* N32 */ || _MIPS_SIM == 3 /* 64 */ + +typedef int TItype __attribute__ ((mode (TI))); +typedef int DItype __attribute__ ((mode (DI))); +typedef int SItype __attribute__ ((mode (SI))); + +typedef unsigned int UDItype __attribute__ ((mode (DI))); + +typedef union +{ + struct TIstruct { +#if LIBGCC2_WORDS_BIG_ENDIAN + DItype high, low; +#else + DItype low, high; +#endif + } s; + TItype ll; +} TIunion; + +TItype +__negti2 (TItype u) +{ + TIunion w; + TIunion uu; + + uu.ll = u; + + w.s.low = -uu.s.low; + w.s.high = -uu.s.high - ((UDItype) w.s.low > 0); + + return w.ll; +} + +TItype +__ashlti3 (TItype u, int b) +{ + TIunion w; + int bm; + TIunion uu; + + if (b == 0) + return u; + + uu.ll = u; + + bm = (sizeof (DItype) * BITS_PER_UNIT) - b; + if (bm <= 0) + { + w.s.low = 0; + w.s.high = (UDItype) uu.s.low << -bm; + } + else + { + UDItype carries = (UDItype) uu.s.low >> bm; + + w.s.low = (UDItype) uu.s.low << b; + w.s.high = ((UDItype) uu.s.high << b) | carries; + } + + return w.ll; +} + +#if 0 +TItype +__ashrti3 (TItype u, int b) +{ + TIunion w; + int bm; + TIunion uu; + + if (b == 0) + return u; + + uu.ll = u; + + bm = (sizeof (DItype) * BITS_PER_UNIT) - b; + if (bm <= 0) + { + /* w.s.high = 1..1 or 0..0 */ + w.s.high = uu.s.high >> (sizeof (DItype) * BITS_PER_UNIT - 1); + w.s.low = uu.s.high >> -bm; + } + else + { + UDItype carries = (UDItype) uu.s.high << bm; + + w.s.high = uu.s.high >> b; + w.s.low = ((UDItype) uu.s.low >> b) | carries; + } + + return w.ll; +} +#endif + +TItype +__lshrti3 (TItype u, int b) +{ + TIunion w; + int bm; + TIunion uu; + + if (b == 0) + return u; + + uu.ll = u; + + bm = (sizeof (DItype) * BITS_PER_UNIT) - b; + if (bm <= 0) + { + w.s.high = 0; + w.s.low = (UDItype) uu.s.high >> -bm; + } + else + { + UDItype carries = (UDItype) uu.s.high << bm; + + w.s.high = (UDItype) uu.s.high >> b; + w.s.low = ((UDItype) uu.s.low >> b) | carries; + } + + return w.ll; +} + +#endif /* N32 or N64 */ diff -rup orig/egcc-CVS20030126/gcc/config/mips/mips.c egcc-CVS20030126/gcc/config/mips/mips.c --- orig/egcc-CVS20030126/gcc/config/mips/mips.c 2003-01-19 16:00:13.000000000 -0500 +++ egcc-CVS20030126/gcc/config/mips/mips.c 2003-01-26 09:07:10.534508498 -0500 @@ -4280,7 +4280,9 @@ mips_arg_info (cum, mode, type, named, i info->fpr_p = false; if (GET_MODE_CLASS (mode) == MODE_FLOAT - && GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE) + && GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE * ((mips_abi == ABI_N32 + || mips_abi == ABI_64) + ? 2 : 1)) { switch (mips_abi) { @@ -4315,9 +4317,11 @@ mips_arg_info (cum, mode, type, named, i is a double, but $f14 if it is a single. Otherwise, on a 32-bit double-float machine, each FP argument must start in a new register pair. */ - even_reg_p = ((mips_abi == ABI_O64 && mode == SFmode) || FP_INC > 1); + even_reg_p = (GET_MODE_SIZE (mode) > UNITS_PER_FPVALUE /* TFmode */ + || (mips_abi == ABI_O64 && mode == SFmode) + || FP_INC > 1); } - else if (!TARGET_64BIT) + else if (!TARGET_64BIT || mips_abi == ABI_N32 || mips_abi == ABI_64) { if (GET_MODE_CLASS (mode) == MODE_INT || GET_MODE_CLASS (mode) == MODE_FLOAT) @@ -4706,6 +4710,15 @@ mips_va_start (valist, nextarg) { const CUMULATIVE_ARGS *cum = ¤t_function_args_info; + /* ARG_POINTER_REGNUM is initialized to STACK_POINTER_BOUNDARY, but + since the stack is aligned for a pair of argument-passing slots, + and the beginning of a variable argument list may be an odd slot, + we have to decrease its alignment. */ + if (cfun && cfun->emit->regno_pointer_align) + while (((current_function_pretend_args_size * BITS_PER_UNIT) + & (REGNO_POINTER_ALIGN (ARG_POINTER_REGNUM) - 1)) != 0) + REGNO_POINTER_ALIGN (ARG_POINTER_REGNUM) /= 2; + if (mips_abi == ABI_EABI) { int gpr_save_area_size; @@ -4998,7 +5011,10 @@ mips_va_arg (valist, type) that alignments <= UNITS_PER_WORD are preserved by the va_arg increment mechanism. */ - if (TARGET_64BIT) + if ((mips_abi == ABI_N32 || mips_abi == ABI_64) + && TYPE_ALIGN (type) > 64) + align = 16; + else if (TARGET_64BIT) align = 8; else if (TYPE_ALIGN (type) > 32) align = 8; @@ -5452,7 +5468,10 @@ override_options () register. */ || (mips_abi == ABI_MEABI && size <= 4)) && (((class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT) - && size <= UNITS_PER_FPVALUE) + && size <= (UNITS_PER_FPVALUE + * ((mips_abi == ABI_N32 + || mips_abi == ABI_64) + ? 2 : 1))) /* Allow integer modes that fit into a single register. We need to put integers into FPRs when using instructions like cvt and trunc. */ @@ -8264,9 +8283,25 @@ mips_function_value (valtype, func, mode } mclass = GET_MODE_CLASS (mode); - if (mclass == MODE_FLOAT && GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE) + if (mclass == MODE_FLOAT + && GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE) reg = FP_RETURN; + else if (mclass == MODE_FLOAT + && mode == TFmode + && (mips_abi == ABI_N32 || mips_abi == ABI_64)) + /* long doubles are really split between f0 and f2, not f1. Eek. */ + return gen_rtx_PARALLEL + (VOIDmode, + gen_rtvec (2, + gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_REG (DImode, FP_RETURN), + GEN_INT (0)), + gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_REG (DImode, FP_RETURN + 2), + GEN_INT (GET_MODE_SIZE (mode) / 2)))); + + else if (mclass == MODE_COMPLEX_FLOAT && GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE * 2) { diff -rup orig/egcc-CVS20030126/gcc/config/mips/mips.h egcc-CVS20030126/gcc/config/mips/mips.h --- orig/egcc-CVS20030126/gcc/config/mips/mips.h 2003-01-19 16:00:13.000000000 -0500 +++ egcc-CVS20030126/gcc/config/mips/mips.h 2003-01-26 09:07:10.554508315 -0500 @@ -1565,7 +1565,21 @@ do { \ /* A C expression for the size in bits of the type `long double' on the target machine. If you don't define this, the default is two words. */ -#define LONG_DOUBLE_TYPE_SIZE 64 +#define LONG_DOUBLE_TYPE_SIZE \ + (mips_abi == ABI_N32 || mips_abi == ABI_64 ? 128 : 64) + +/* long double is not a fixed mode, but the idea is that, if we + support long double, we also want a 128-bit integer type. */ +#define MAX_FIXED_MODE_SIZE LONG_DOUBLE_TYPE_SIZE + +#ifdef IN_LIBGCC2 +#if (defined _ABIN32 && _MIPS_SIM == _ABIN32) \ + || (defined _ABI64 && _MIPS_SIM == _ABI64) +# define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 128 +# else +# define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64 +# endif +#endif /* Width in bits of a pointer. See also the macro `Pmode' defined below. */ @@ -1592,7 +1606,8 @@ do { \ #define STRUCTURE_SIZE_BOUNDARY 8 /* There is no point aligning anything to a rounder boundary than this. */ -#define BIGGEST_ALIGNMENT 64 +#define BIGGEST_ALIGNMENT ((mips_abi == ABI_N32 || mips_abi == ABI_64) \ + ? 128 : 64) /* Set this nonzero if move instructions will actually fail to work when given unaligned data. */ @@ -2654,7 +2669,9 @@ extern enum reg_class mips_char_to_class On the MIPS, R2 R3 and F0 F2 are the only register thus used. Currently, R2 and F0 are only implemented here (C has no complex type) */ -#define FUNCTION_VALUE_REGNO_P(N) ((N) == GP_RETURN || (N) == FP_RETURN) +#define FUNCTION_VALUE_REGNO_P(N) ((N) == GP_RETURN || (N) == FP_RETURN \ + || ((mips_abi == ABI_N32 || mips_abi == ABI_64) && FP_RETURN != GP_RETURN \ + && (N) == FP_RETURN + 2)) /* 1 if N is a possible register number for function argument passing. We have no FP argument registers when soft-float. When FP registers diff -rup orig/egcc-CVS20030126/gcc/config/mips/t-iris6 egcc-CVS20030126/gcc/config/mips/t-iris6 --- orig/egcc-CVS20030126/gcc/config/mips/t-iris6 2002-11-12 07:00:49.000000000 -0500 +++ egcc-CVS20030126/gcc/config/mips/t-iris6 2003-01-26 09:07:23.483427752 -0500 @@ -18,3 +18,16 @@ CRTSTUFF_T_CFLAGS=-g1 # This is only needed in the static libgcc as a band-aid until gcc correctly # implements the N32/N64 ABI structure passing conventions LIB2FUNCS_STATIC_EXTRA = $(srcdir)/config/mips/irix6-libc-compat.c + +LIB2FUNCS_EXTRA = $(srcdir)/config/mips/_tilib.c + +TPBIT = tp-bit.c + +tp-bit.c: $(srcdir)/config/fp-bit.c + echo '#ifdef __MIPSEL__' > tp-bit.c + echo '# define FLOAT_BIT_ORDER_MISMATCH' >> tp-bit.c + echo '#endif' >> tp-bit.c + echo '#if __LDBL_MANT_DIG__ == 106' >> tp-bit.c + echo '# define TFLOAT' >> tp-bit.c + cat $(srcdir)/config/fp-bit.c >> tp-bit.c + echo '#endif' >> tp-bit.c diff -rup orig/egcc-CVS20030126/gcc/real.c egcc-CVS20030126/gcc/real.c --- orig/egcc-CVS20030126/gcc/real.c 2003-01-15 13:59:54.000000000 -0500 +++ egcc-CVS20030126/gcc/real.c 2003-01-26 09:06:02.199729192 -0500 @@ -3261,8 +3261,23 @@ encode_ibm_extended (fmt, buf, r) u = *r; clear_significand_below (&u, SIGNIFICAND_BITS - 53); - /* v = remainder containing additional 53 bits of significand. */ - do_add (&v, r, &u, 1); + normalize (&u); + /* If the upper double is zero, we have a denormal double, so + move it to the first double and leave the second as zero. */ + if (u.class == rvc_zero) + { + v = u; + u = *r; + normalize (&u); + } + else + { + /* v = remainder containing additional 53 bits of significand. */ + do_add (&v, r, &u, 1); + round_for_format (&ieee_double_format, &v); + } + + round_for_format (&ieee_double_format, &u); encode_ieee_double (&ieee_double_format, &buf[0], &u); encode_ieee_double (&ieee_double_format, &buf[2], &v); @@ -3299,7 +3314,7 @@ const struct real_format ibm_extended_fo 2, 1, 53 + 53, - -1021, + -1021 + 53, 1024, -1, true, ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-27 9:17 ` Kaveh R. Ghazi @ 2003-01-27 10:40 ` Alexandre Oliva 2003-01-28 4:52 ` Kaveh R. Ghazi 2003-01-27 10:41 ` Alexandre Oliva 1 sibling, 1 reply; 72+ messages in thread From: Alexandre Oliva @ 2003-01-27 10:40 UTC (permalink / raw) To: Kaveh R. Ghazi; +Cc: gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro, rth On Jan 27, 2003, "Kaveh R. Ghazi" <ghazi@caip.rutgers.edu> wrote: >> From: Alexandre Oliva >> >> On Jan 26, 2003, "Kaveh R. Ghazi" <ghazi@caip.rutgers.edu> wrote: >> >> > ld32: ERROR 33 : Unresolved text symbol "__gttf2" -- 1st referenced >> > by /var/tmp//cc40eXre.o. >> >> Hmm... This could result from your check-out not having the second >> round of changes to gcc/config/fp-bit.[ch]. Does it? > I think it did, but I'll try again with a fresh cvs update. > I'm using the patch below against 3.3. Ah, you're missing one little bit that has already made it to mainline (in a slightly different form, along with the rest of the mips64-linux-gnu port), that I still had in my tree and in the patch for 3.3, but I ended up posting the patch for mainline, it seems. Sorry about that. Index: gcc/config/mips/mips.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.c,v retrieving revision 1.241 diff -u -p -r1.241 mips.c --- gcc/config/mips/mips.c 12 Dec 2002 05:13:03 -0000 1.241 +++ gcc/config/mips/mips.c 15 Jan 2003 09:18:58 -0000 @@ -5365,6 +5381,8 @@ override_options () else mips16 = 0; + real_format_for_mode[TFmode - QFmode] = &ibm_extended_format; + mips_print_operand_punct['?'] = 1; mips_print_operand_punct['#'] = 1; mips_print_operand_punct['&'] = 1; -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-27 10:40 ` Alexandre Oliva @ 2003-01-28 4:52 ` Kaveh R. Ghazi 2003-01-28 17:31 ` Alexandre Oliva 0 siblings, 1 reply; 72+ messages in thread From: Kaveh R. Ghazi @ 2003-01-28 4:52 UTC (permalink / raw) To: aoliva; +Cc: gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro, rth > From: Alexandre Oliva <aoliva@redhat.com> > > Ah, you're missing one little bit that has already made it to mainline > (in a slightly different form, along with the rest of the > mips64-linux-gnu port), that I still had in my tree and in the patch > for 3.3, but I ended up posting the patch for mainline, it seems. > Sorry about that. Yup that was it, 3.3 testsuite looks good now. Thanks again! PS: over here: http://gcc.gnu.org/ml/gcc/2002-12/msg01310.html you mentioned something about using the native irix library for some of the math to speed it up. What needs to be done there? Can you explain it to me (somewhat verbosely? :-) -- Kaveh R. Ghazi ghazi@caip.rutgers.edu ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-28 4:52 ` Kaveh R. Ghazi @ 2003-01-28 17:31 ` Alexandre Oliva 2003-01-28 19:11 ` Kaveh R. Ghazi 0 siblings, 1 reply; 72+ messages in thread From: Alexandre Oliva @ 2003-01-28 17:31 UTC (permalink / raw) To: Kaveh R. Ghazi; +Cc: gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro, rth On Jan 28, 2003, "Kaveh R. Ghazi" <ghazi@caip.rutgers.edu> wrote: > PS: over here: > http://gcc.gnu.org/ml/gcc/2002-12/msg01310.html > you mentioned something about using the native irix library for some > of the math to speed it up. What needs to be done there? Can you > explain it to me (somewhat verbosely? :-) Have a look at the macro GOFAST_RENAME_LIBCALLS in gcc/config/gofast.h. gofast is a FP emulation library that uses entry points different from those used by GCC, so GOFAST_RENAME_LIBCALLS arranges for GCC to issue calls using these entry points instead of those it traditionally does. You assignment :-) is to: (i) find out the name of the functions that IRIX uses for long double floating-point operations and (ii) add similar assignments to the optab arrays and libfunc variables such that we issue calls to the IRIX-specific names. An optional (iii) is to change the name of the functions emitted for the emulation library in gcc/config/fp-bit.h in the case of __LDBL_MANT_DIG__ == 106, and/or disable it completely on IRIX (removing tp-bit.c from t-iris6), so that we use only the native implementation. Please let me know if you could use some further clarification of any of the items above, and thanks in advance if you have a chance of looking into them. -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-28 17:31 ` Alexandre Oliva @ 2003-01-28 19:11 ` Kaveh R. Ghazi 2003-01-28 19:23 ` Kaveh R. Ghazi 0 siblings, 1 reply; 72+ messages in thread From: Kaveh R. Ghazi @ 2003-01-28 19:11 UTC (permalink / raw) To: aoliva; +Cc: gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro, rth > From: Alexandre Oliva <aoliva@redhat.com> > > On Jan 28, 2003, "Kaveh R. Ghazi" <ghazi@caip.rutgers.edu> wrote: > > > PS: over here: > > http://gcc.gnu.org/ml/gcc/2002-12/msg01310.html > > you mentioned something about using the native irix library for some > > of the math to speed it up. What needs to be done there? Can you > > explain it to me (somewhat verbosely? :-) > > Have a look at the macro GOFAST_RENAME_LIBCALLS in > gcc/config/gofast.h. gofast is a FP emulation library that uses entry > points different from those used by GCC, so GOFAST_RENAME_LIBCALLS > arranges for GCC to issue calls using these entry points instead of > those it traditionally does. > > You assignment :-) is to: (i) find out the name of the functions that > IRIX uses for long double floating-point operations Well I tried man pages, sgi's website and search engines without any luck. So instead I tried reverse engineering by compiling a small program with cc -n32 -S and seeing what I got. I used this code: extern TYPE foo(double a, TYPE b) { TYPE x = a OP b; return x; } My knowledge of assembly is limited and I'm certainly no floating point expert. But it seems to me that the routines for * / + and - are named __q_mul, __q_div, __q_add and __q_sub. There are widening routines named __q_ext and __q_extd for widening a float and a double respectively. Is there any other operation we need to figure out? Also I'm sure the calling convention needs to be understood to see if these are drop in replacements for our own, but I'd like some help on that. I've included the assembly for TYPE='long double' and OP='*'. It's pretty easy to follow especially given the helpful comments inserted by the irix cc compiler. Is this enough info to proceed? Thanks, --Kaveh .set noreorder .set noat # /usr/lib32/cmplrs/be::7.30 #ism 1275524910 #----------------------------------------------------------- # Compiling f2.c (/tmp/ctmB.BAAa5-Hr-) #----------------------------------------------------------- #----------------------------------------------------------- # Options: #----------------------------------------------------------- # Target:R10000, ISA:mips4, Pointer Size:32 # -O0 (Optimization level) # -g0 (Debug level) # -m1 (Report warnings) #----------------------------------------------------------- .file 1 "/a/teal/caip5/ghazi/f2.c" .section .text, 1, 0x00000006, 4, 16 .text: .section .text # Program Unit: foo .ent foo .globl foo foo: # 0x0 .dynsym foo sto_default .frame $sp, 64, $31 .mask 0x80000000, -48 # x = 0 # lcl_spill_temp_0 = 16 # lcl_spill_temp_1 = 24 .loc 1 2 1 # 1 extern TYPE foo(double a, TYPE b) # 2 { .BB1.foo: # 0x0 addiu $sp,$sp,-64 # sd $gp,24($sp) # lcl_spill_temp_1 sd $31,16($sp) # lcl_spill_temp_0 lui $1,%hi(%neg(%gp_rel(foo))) # foo addiu $1,$1,%lo(%neg(%gp_rel(foo))) # foo addu $gp,$25,$1 # sdc1 $f12,32($sp) # a sdc1 $f14,48($sp) # b sdc1 $f15,56($sp) # b+8 .loc 1 3 8 # 3 TYPE x = a OP b; ldc1 $f12,32($sp) # a lw $25,%call16(__q_extd)($gp) # __q_extd jalr $25 # __q_extd nop # .BB2.foo: # 0x34 mov.d $f12,$f0 # mov.d $f13,$f2 # ldc1 $f14,48($sp) # b ldc1 $f15,56($sp) # b+8 lw $25,%call16(__q_mul)($gp) # __q_mul jalr $25 # __q_mul nop # .BB3.foo: # 0x50 sdc1 $f0,0($sp) # x sdc1 $f2,8($sp) # x+8 .loc 1 4 3 # 4 return x; ldc1 $f0,0($sp) # x ldc1 $f2,8($sp) # x+8 ld $gp,24($sp) # lcl_spill_temp_1 ld $31,16($sp) # lcl_spill_temp_0 addiu $sp,$sp,64 # jr $31 # nop # .end foo .section .text .align 4 .gpvalue 30720 ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-28 19:11 ` Kaveh R. Ghazi @ 2003-01-28 19:23 ` Kaveh R. Ghazi 2003-01-28 19:47 ` Rainer Orth [not found] ` <15926.49701.3! 59482.666471@xayide.TechFak.Uni-Bielefeld.DE> 0 siblings, 2 replies; 72+ messages in thread From: Kaveh R. Ghazi @ 2003-01-28 19:23 UTC (permalink / raw) To: aoliva; +Cc: gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro, rth > From: "Kaveh R. Ghazi" > > My knowledge of assembly is limited and I'm certainly no floating > point expert. But it seems to me that the routines for * / + and - > are named __q_mul, __q_div, __q_add and __q_sub. There are widening > routines named __q_ext and __q_extd for widening a float and a double > respectively. Is there any other operation we need to figure out? Poking around some more turned up these routines in libc.so. [662] | 263004512| 40|FUNC |GLOB |DEFAULT |MIPS_TEXT|__q_ext [663] | 263004592| 44|FUNC |GLOB |DEFAULT |MIPS_TEXT|__q_floti [664] | 263004636| 44|FUNC |GLOB |DEFAULT |MIPS_TEXT|__q_flotj [665] | 263004680| 52|FUNC |GLOB |DEFAULT |MIPS_TEXT|__q_flotju [666] | 263004800| 112|FUNC |GLOB |DEFAULT |MIPS_TEXT|__q_flotku [667] | 263005200| 48|FUNC |GLOB |DEFAULT |MIPS_TEXT|__q_ne [668] | 263005248| 28|FUNC |GLOB |DEFAULT |MIPS_TEXT|__q_neg [672] | 262962368| 1236|FUNC |GLOB |DEFAULT |MIPS_TEXT|__q_mul [3293] | 263003000| 1464|FUNC |GLOB |DEFAULT |MIPS_TEXT|__q_div [3294] | 263004464| 48|FUNC |GLOB |DEFAULT |MIPS_TEXT|__q_eq [3295] | 263004552| 40|FUNC |GLOB |DEFAULT |MIPS_TEXT|__q_extd [3296] | 263004732| 68|FUNC |GLOB |DEFAULT |MIPS_TEXT|__q_flotk [3297] | 263004912| 72|FUNC |GLOB |DEFAULT |MIPS_TEXT|__q_ge [3298] | 263004984| 72|FUNC |GLOB |DEFAULT |MIPS_TEXT|__q_gt [3299] | 263005056| 72|FUNC |GLOB |DEFAULT |MIPS_TEXT|__q_le [3300] | 263005128| 72|FUNC |GLOB |DEFAULT |MIPS_TEXT|__q_lt [3301] | 262961324| 1044|FUNC |GLOB |DEFAULT |MIPS_TEXT|__q_add [3302] | 262963604| 1052|FUNC |GLOB |DEFAULT |MIPS_TEXT|__q_sub I think it's obvious some are comparison operators. The ones with __q_flot* seem to be integer conversions, but I'm not sure what each one does specifically. -- Kaveh R. Ghazi ghazi@caip.rutgers.edu ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-28 19:23 ` Kaveh R. Ghazi @ 2003-01-28 19:47 ` Rainer Orth [not found] ` <15926.49701.3! 59482.666471@xayide.TechFak.Uni-Bielefeld.DE> 1 sibling, 0 replies; 72+ messages in thread From: Rainer Orth @ 2003-01-28 19:47 UTC (permalink / raw) To: Kaveh R. Ghazi Cc: aoliva, gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro, rth Kaveh R. Ghazi writes: > I think it's obvious some are comparison operators. The ones with > __q_flot* seem to be integer conversions, but I'm not sure what each > one does specifically. There's the MIPS Processor ABI Conformance Guide Version 3.0 Draft 4 (dated: July 18, 1997) a.k.a. The Black Book. It used to be available from www.mipsabi.org, but this site has been closed down when the MIPS ABI group dissolved. I couldn't locate a copy on the Web, but have a local copy here. Maybe SGI could make it available again? Their Dave Anderson has always been quite helpful getting all sorts of ABI and toolset information. Here's the relevant section from Appendix D: Platform Implementation Notes, D4-5: Support for long double Datatype NOTE The routines described here are for support of a 128-bit (quad-word) long double datatype in the 64-bit 3 ABI. The 32-bit ABI uses a 64-bit long double and does not require these routines. Figure D-3: libc Contents, Internal Routines for long double Support __q_add __q_div __q_eq __q_ext 3 __q_extd __q_floti __q_flotj __q_flotju 3 __q_flotk __q_flotku __q_ge __q_gt 3 __q_le __q_lt __q_mul __q_ne 3 __q_neg __q_sub __sngl_q __dble_q 3 __ii_qint __ji_qint __ji_quint __ki_qint 3 __ki_quint _qtoa 3 Data Definitions for long double Datatype The following prototypes are provided for system implementors. They do not appear in any standard system 3 header file. Figure D-4: Prototypes for Internal long double Support Routines long double __q_add( double, double, double, double ); 3 long double __q_div( double, double, double, double ); 3 int32_t __q_eq( double, double, double, double ); 3 long double __q_ext( float ); 3 long double __q_extd( double ); 3 long double __q_floti( int16_t ); 3 long double __q_flotj( int32_t ); 3 long double __q_flotju( uint32_t ); 3 long double __q_flotk( int64_t ); 3 long double __q_flotku( uint64_t ); 3 int32_t __q_ge( double, double, double, double ); 3 int32_t __q_gt( double, double, double, double ); 3 int32_t __q_le( double, double, double, double ); 3 int32_t __q_lt( double, double, double, double ); 3 long double __q_mul( double, double, double, double ); 3 int32_t __q_ne( double, double, double, double ); 3 long double __q_neg( double, double ); 3 long double __q_sub( double, double, double, double ); 3 float __sngl_q( double, double ); 3 double __dble_q( double, double ); 3 int16_t __ii_qint( double, double ); 3 int32_t __ji_qint( double, double ); 3 uint32_t __ji_quint( double, double ); 3 int64_t __ki_qint( double, double ); 3 uint64_t __ki_quint( double, double ); 3 int _qtoa( char *, int, long double, int ); 3 This is all I've been able to locate in publicly available documentation. Rainer ----------------------------------------------------------------------------- Rainer Orth, Faculty of Technology, Bielefeld University ^ permalink raw reply [flat|nested] 72+ messages in thread
[parent not found: <15926.49701.3! 59482.666471@xayide.TechFak.Uni-Bielefeld.DE>]
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) [not found] ` <15926.49701.3! 59482.666471@xayide.TechFak.Uni-Bielefeld.DE> @ 2003-01-29 6:56 ` Kaveh R. Ghazi 2003-01-29 10:07 ` Richard Henderson 0 siblings, 1 reply; 72+ messages in thread From: Kaveh R. Ghazi @ 2003-01-29 6:56 UTC (permalink / raw) To: ro; +Cc: aoliva, gcc-bugs, gcc-patches, gcc, libstdc++, oldham, rth > From: Rainer Orth <ro@TechFak.Uni-Bielefeld.DE> > > There's the MIPS Processor ABI Conformance Guide Version 3.0 Draft 4 > (dated: July 18, 1997) a.k.a. The Black Book. It used to be available from > www.mipsabi.org, but this site has been closed down when the MIPS ABI group > dissolved. I couldn't locate a copy on the Web, but have a local copy > here. Maybe SGI could make it available again? Their Dave Anderson has > always been quite helpful getting all sorts of ABI and toolset information. > > Here's the relevant section from Appendix D: Platform Implementation Notes, > D4-5: Thanks! That was exactly what I needed. Here's something I'm currently testing. I think I'm on the right track, my preliminary tests shows it works and yields timing results comparable to cc. Notes: 1. Rainer's list included the following functions for which I couldn't glean a corresponding optabs entry: long double __q_floti( int16_t ); 3 long double __q_flotju( uint32_t ); 3 long double __q_flotku( uint64_t ); 3 long double __q_neg( double, double ); 3 int16_t __ii_qint( double, double ); 3 2. Conversely, there were several optabs TF entries for which I couldn't determine something in the irix libc list. There were: unordtf2_libfunc floattitf_libfunc fixtfti_libfunc fixunstfti_libfunc cmp_optab->handlers[(int) TFmode].libfunc (E.g. set by gofast) 3. I notice neither irix nor optabs seems to have functions to convert *unsigned* ints to floating points. Yet it seems to work. Perhaps the C promotion rules mandate some intermediate type conversion that already exists. Anyway, any comments on the notes or the patch? Thanks. diff -rup orig/egcc-3.3-CVS20030127/gcc/config/mips/iris6.h egcc-3.3-CVS20030127/gcc/config/mips/iris6.h --- orig/egcc-3.3-CVS20030127/gcc/config/mips/iris6.h 2003-01-27 22:31:46.000000000 -0500 +++ egcc-3.3-CVS20030127/gcc/config/mips/iris6.h 2003-01-28 16:27:13.521707000 -0500 @@ -511,3 +511,31 @@ do { \ %{mabi=32: -32}%{mabi=n32: -n32}%{mabi=64: -64}%{!mabi*: -n32}" #define MIPS_TFMODE_FORMAT ibm_extended_format + +#define INIT_NATIVE_TFP_OPTABS \ +do { \ + add_optab->handlers[(int) TFmode].libfunc = init_one_libfunc ("__q_add"); \ + sub_optab->handlers[(int) TFmode].libfunc = init_one_libfunc ("__q_sub"); \ + smul_optab->handlers[(int) TFmode].libfunc = init_one_libfunc ("__q_mul"); \ + sdiv_optab->handlers[(int) TFmode].libfunc = init_one_libfunc ("__q_div"); \ +\ + extendsftf2_libfunc = init_one_libfunc ("__q_ext"); \ + extenddftf2_libfunc = init_one_libfunc ("__q_extd"); \ + trunctfsf2_libfunc = init_one_libfunc ("__sngl_q"); \ + trunctfdf2_libfunc = init_one_libfunc ("__dble_q"); \ +\ + eqtf2_libfunc = init_one_libfunc ("__q_eq"); \ + netf2_libfunc = init_one_libfunc ("__q_ne"); \ + gttf2_libfunc = init_one_libfunc ("__q_gt"); \ + getf2_libfunc = init_one_libfunc ("__q_ge"); \ + lttf2_libfunc = init_one_libfunc ("__q_lt"); \ + letf2_libfunc = init_one_libfunc ("__q_le"); \ +\ + fixtfsi_libfunc = init_one_libfunc ("__ji_qint"); \ + fixtfdi_libfunc = init_one_libfunc ("__ki_qint"); \ + fixunstfsi_libfunc = init_one_libfunc ("__ji_quint"); \ + fixunstfdi_libfunc = init_one_libfunc ("__ki_quint"); \ +\ + floatsitf_libfunc = init_one_libfunc ("__q_flotj"); \ + floatditf_libfunc = init_one_libfunc ("__q_flotk"); \ +} while (0) diff -rup orig/egcc-3.3-CVS20030127/gcc/config.gcc egcc-3.3-CVS20030127/gcc/config.gcc --- orig/egcc-3.3-CVS20030127/gcc/config.gcc 2003-01-04 17:00:25.000000000 -0500 +++ egcc-3.3-CVS20030127/gcc/config.gcc 2003-01-28 14:39:51.670349000 -0500 @@ -2879,6 +2879,7 @@ mips*-*-*) tm_file="gofast.h $tm_file" tmake_file="mips/t-gofast $tmake_file" else + tm_defines="INIT_SUBTARGET_OPTABS=INIT_NATIVE_TFP_OPTABS $tm_defines" tmake_file="mips/t-mips $tmake_file" fi ;; ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-29 6:56 ` Kaveh R. Ghazi @ 2003-01-29 10:07 ` Richard Henderson 2003-01-29 13:39 ` Alexandre Oliva ` (2 more replies) 0 siblings, 3 replies; 72+ messages in thread From: Richard Henderson @ 2003-01-29 10:07 UTC (permalink / raw) To: Kaveh R. Ghazi; +Cc: ro, aoliva, gcc-bugs, gcc-patches, gcc, libstdc++, oldham On Tue, Jan 28, 2003 at 08:32:19PM -0500, Kaveh R. Ghazi wrote: > long double __q_floti( int16_t ); 3 > long double __q_flotju( uint32_t ); 3 > long double __q_flotku( uint64_t ); 3 floathitf2 floatunssitf2 floatunsditf2 > long double __q_neg( double, double ); 3 negtf2 > int16_t __ii_qint( double, double ); 3 fix_trunctfhi2 > 2. Conversely, there were several optabs TF entries for which I couldn't > determine something in the irix libc list. There were: > > unordtf2_libfunc This one may be a problem. We don't know what the actual return values are for the comparison functions. By rights it ought to be a tri-state value off of EQ or NE. > floattitf_libfunc > fixtfti_libfunc > fixunstfti_libfunc There were no TImode functions listed. > 3. I notice neither irix nor optabs seems to have functions to > convert *unsigned* ints to floating points. For gcc, see "floatuns<MI><MF>2". For Irix, see __q_flotju as opposed to __q_flotj. r~ ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-29 10:07 ` Richard Henderson @ 2003-01-29 13:39 ` Alexandre Oliva 2003-01-29 17:26 ` Kaveh R. Ghazi 2003-01-30 8:05 ` Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) Kaveh R. Ghazi 2 siblings, 0 replies; 72+ messages in thread From: Alexandre Oliva @ 2003-01-29 13:39 UTC (permalink / raw) To: Richard Henderson Cc: Kaveh R. Ghazi, ro, gcc-bugs, gcc-patches, gcc, libstdc++, oldham On Jan 29, 2003, Richard Henderson <rth@redhat.com> wrote: >> unordtf2_libfunc > This one may be a problem. GCC knows what to do if it's not defined, unless you actually use the unord builtin (or maybe even if we do). Remember that gofast has the same problem, and we do generate correct code for it regardless. -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-29 10:07 ` Richard Henderson 2003-01-29 13:39 ` Alexandre Oliva @ 2003-01-29 17:26 ` Kaveh R. Ghazi 2003-01-29 18:10 ` Richard Henderson 2003-01-30 8:05 ` Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) Kaveh R. Ghazi 2 siblings, 1 reply; 72+ messages in thread From: Kaveh R. Ghazi @ 2003-01-29 17:26 UTC (permalink / raw) To: rth; +Cc: aoliva, gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro > From: Richard Henderson <rth@redhat.com> > > On Tue, Jan 28, 2003 at 08:32:19PM -0500, Kaveh R. Ghazi wrote: > > floathitf2 > floatunssitf2 > floatunsditf2 > negtf2 > fix_trunctfhi2 Sorry I wasn't clear. I can conceptually come up with the names, what I don't see are entries for them in libfuncs.h so I assume I can't just start using them. Is it safe to simply add the appropriate entries to enum libfunc_index and magically everything will work? > > > 3. I notice neither irix nor optabs seems to have functions to > > convert *unsigned* ints to floating points. > > For gcc, see "floatuns<MI><MF>2". > r~ Ditto above. Thanks, --Kaveh -- Kaveh R. Ghazi ghazi@caip.rutgers.edu ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-29 17:26 ` Kaveh R. Ghazi @ 2003-01-29 18:10 ` Richard Henderson 2003-01-30 23:31 ` Irix6 native long double libcalls progress report (and problem) Kaveh R. Ghazi 0 siblings, 1 reply; 72+ messages in thread From: Richard Henderson @ 2003-01-29 18:10 UTC (permalink / raw) To: Kaveh R. Ghazi; +Cc: aoliva, gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro On Wed, Jan 29, 2003 at 11:15:02AM -0500, Kaveh R. Ghazi wrote: > > From: Richard Henderson <rth@redhat.com> > > > > On Tue, Jan 28, 2003 at 08:32:19PM -0500, Kaveh R. Ghazi wrote: > > > > floathitf2 > > floatunssitf2 > > floatunsditf2 > > negtf2 > > fix_trunctfhi2 > > Sorry I wasn't clear. I can conceptually come up with the names, what > I don't see are entries for them in libfuncs.h so I assume I can't > just start using them. > > Is it safe to simply add the appropriate entries to enum libfunc_index > and magically everything will work? No, you'd have to modify code as well. See how the _libfuncs are used in optabs.c. Probably no sense in adding the HImode bits. The unsigned conversions on the other hand... Well, a little rearrangement of the code is needed. GCC does not itself provide unsigned->float conversion routines (which is silly) and so it synthesizes with libcall + extra code. r~ ^ permalink raw reply [flat|nested] 72+ messages in thread
* Irix6 native long double libcalls progress report (and problem) 2003-01-29 18:10 ` Richard Henderson @ 2003-01-30 23:31 ` Kaveh R. Ghazi 2003-01-30 23:49 ` Richard Henderson 0 siblings, 1 reply; 72+ messages in thread From: Kaveh R. Ghazi @ 2003-01-30 23:31 UTC (permalink / raw) To: rth; +Cc: aoliva, gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro I got pretty far getting Irix6 to use it's native libc long double routines. I managed to come up with a patch and run some timing tests, for long double ops in isolation I'm getting speedups from 5x to 20x over the gcc routines depending on the operation performed. So far so good. In the case of the comparison ops, they don't have the same return values that gcc expects, so I commented them out. And in another case, the gcc routines are better, so I commented out those too. What's left is in the patch at the end of this message. When I ran the testsuite however, I get one new failure in execute/conversion.c. The problem boils down to this: > long double > ull2ld(u) > unsigned long long int u; > { > return u; > } > Then we crash on this code: > if (ull2ld(~0ULL) != (long double) ~0ULL) > abort(); I.e. supposedly the value passed through and converted in a function is different than the same constant cast inline. I added some code to check out what we're actually getting: > #include <stdio.h> > extern void abort(void); > > long double > ull2ld(u) > unsigned long long int u; > { > return u; > } > > int main() > { > fprintf (stderr, "%.25Le\n%.25Le\n%Le\n", ull2ld(~0ULL), > (long double) ~0ULL, ull2ld(~0ULL) - (long double) ~0ULL); > { > union f { long double ld; unsigned long long ll[2]; } > f1 = { ull2ld(~0ULL) }, f2 = { (long double) ~0ULL }; > > fprintf (stderr, "%llx %016llx\n%llx %016llx\n", > f1.ll[0], f1.ll[1], f2.ll[0], f2.ll[1]); > } > > if (ull2ld(~0ULL) != (long double) ~0ULL) > abort(); > > return 0; > } > With gcc-3.3 from last night plus the patch, it yields: 1.8446744073709551615000000e+19 1.8446744073709551615000000e+19 0.000000e+00 43f0000000000000 bff0000000000000 43efffffffffffff 409ffc0000000000 Abort (core dumped) As you can see, the numbers are equal in value. To see whether the value was different in some far out Nth decimal place, I subtracted them and it results in zero point zero. But the bit patterns are different! And I'm guessing that this confuses the gcc comparison function. What's going on here? Ideas? Thanks, --Kaveh 2003-01-30 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> * mips/iris6.h (INIT_NATIVE_TFP_OPTABS): Define. * config.gcc: Set INIT_SUBTARGET_OPTABS to INIT_NATIVE_TFP_OPTABS for irix6 when not enabling "gofast" routines. diff -rup orig/egcc-3.3-CVS20030129/gcc/config/mips/iris6.h egcc-3.3-CVS20030129/gcc/config/mips/iris6.h --- orig/egcc-3.3-CVS20030129/gcc/config/mips/iris6.h Mon Jan 27 22:31:46 2003 +++ egcc-3.3-CVS20030129/gcc/config/mips/iris6.h Thu Jan 30 08:56:54 2003 @@ -511,3 +511,35 @@ do { \ %{mabi=32: -32}%{mabi=n32: -n32}%{mabi=64: -64}%{!mabi*: -n32}" #define MIPS_TFMODE_FORMAT ibm_extended_format + +/* Faster long double routines from irix6 libc. */ +#define INIT_NATIVE_TFP_OPTABS \ +do { \ + add_optab->handlers[(int) TFmode].libfunc = init_one_libfunc ("__q_add"); \ + sub_optab->handlers[(int) TFmode].libfunc = init_one_libfunc ("__q_sub"); \ + smul_optab->handlers[(int) TFmode].libfunc = init_one_libfunc ("__q_mul"); \ + sdiv_optab->handlers[(int) TFmode].libfunc = init_one_libfunc ("__q_div"); \ + neg_optab->handlers[(int) TFmode].libfunc = init_one_libfunc ("__q_neg"); \ +\ + extendsftf2_libfunc = init_one_libfunc ("__q_ext"); \ + extenddftf2_libfunc = init_one_libfunc ("__q_extd"); \ + trunctfsf2_libfunc = init_one_libfunc ("__sngl_q"); \ + trunctfdf2_libfunc = init_one_libfunc ("__dble_q"); \ +\ + /* These routines return 0/1, we need tri-state -1,0.1. */ \ + /*eqtf2_libfunc = init_one_libfunc ("__q_eq");*/ \ + /*netf2_libfunc = init_one_libfunc ("__q_ne");*/ \ + /*gttf2_libfunc = init_one_libfunc ("__q_gt");*/ \ + /*getf2_libfunc = init_one_libfunc ("__q_ge");*/ \ + /*lttf2_libfunc = init_one_libfunc ("__q_lt");*/ \ + /*letf2_libfunc = init_one_libfunc ("__q_le");*/ \ +\ + /* These two routines are actually slower. */ \ + /*fixtfsi_libfunc = init_one_libfunc ("__ji_qint");*/ \ + /*fixunstfsi_libfunc = init_one_libfunc ("__ji_quint");*/ \ + fixtfdi_libfunc = init_one_libfunc ("__ki_qint"); \ + fixunstfdi_libfunc = init_one_libfunc ("__ki_quint"); \ +\ + floatsitf_libfunc = init_one_libfunc ("__q_flotj"); \ + floatditf_libfunc = init_one_libfunc ("__q_flotk"); \ +} while (0) diff -rup orig/egcc-3.3-CVS20030127/gcc/config.gcc egcc-3.3-CVS20030127/gcc/config.gcc --- orig/egcc-3.3-CVS20030127/gcc/config.gcc 2003-01-04 17:00:25.000000000 -0500 +++ egcc-3.3-CVS20030127/gcc/config.gcc 2003-01-28 14:39:51.670349000 -0500 @@ -2879,6 +2879,7 @@ mips*-*-*) tm_file="gofast.h $tm_file" tmake_file="mips/t-gofast $tmake_file" else + tm_defines="INIT_SUBTARGET_OPTABS=INIT_NATIVE_TFP_OPTABS $tm_defines" tmake_file="mips/t-mips $tmake_file" fi ;; ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 native long double libcalls progress report (and problem) 2003-01-30 23:31 ` Irix6 native long double libcalls progress report (and problem) Kaveh R. Ghazi @ 2003-01-30 23:49 ` Richard Henderson 2003-02-03 13:22 ` Alexandre Oliva 0 siblings, 1 reply; 72+ messages in thread From: Richard Henderson @ 2003-01-30 23:49 UTC (permalink / raw) To: Kaveh R. Ghazi; +Cc: aoliva, gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro On Thu, Jan 30, 2003 at 04:51:45PM -0500, Kaveh R. Ghazi wrote: > 43f0000000000000 bff0000000000000 > 43efffffffffffff 409ffc0000000000 Hmm. They seem to be doing some of what Alex proposed a while ago -- making use of the sign bit. Theirs is (2**64, -1), ours is (0xfffffffffffff800, 0x7ff). > But the bit patterns are different! And I'm guessing that this > confuses the gcc comparison function. Almost certainly. As for using SGI's comparison routines, you can do that from expanders in the backend, with direct calls to emit_library_call etc. That's what I do for Tru64's long double library. r~ ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 native long double libcalls progress report (and problem) 2003-01-30 23:49 ` Richard Henderson @ 2003-02-03 13:22 ` Alexandre Oliva 0 siblings, 0 replies; 72+ messages in thread From: Alexandre Oliva @ 2003-02-03 13:22 UTC (permalink / raw) To: Richard Henderson Cc: Kaveh R. Ghazi, gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro On Jan 30, 2003, Richard Henderson <rth@redhat.com> wrote: > On Thu, Jan 30, 2003 at 04:51:45PM -0500, Kaveh R. Ghazi wrote: >> 43f0000000000000 bff0000000000000 >> 43efffffffffffff 409ffc0000000000 > Hmm. They seem to be doing some of what Alex proposed a while > ago -- making use of the sign bit. Yup. I've been debating how to fix this with Kaveh in private, but I thought I'd post some of the thoughts here, for the record. One relatively easy ways out is to just introduce a new, 107-bit format in real.c, tell GCC to use that on IRIX, In (a copy of) encode_ibm_extended, instead of clear_significant_below, you'll want normalize and round_for_format ieee_double_format. The copy of decode_ibm_extended can be an exact copy, and the definition of ibm_extended_format just need the `+ 53's changed to `+ 54'. There's some weirdness you'll probably run into having to do with the maximum number that can be represented. Even though, by the definition of 11 bits of exponent and 106 of mantissa (plus the implicit 1), you'd expect to be able to represent a number with 106 ones in the mantissa and the maximum exponent, you actually can't, because the addition of a smaller double can't get us there, and subtracting from a larger first double doesn't work either, since incrementing it would overflow. Oops. Anyway, that's something that can be worked around somehow when we get to that point. I have some ideas, but I don't quite like any of them. Maybe bring it up in the list? Another simple fix that has just occurred to me is to tweak unpack_d in fp-bit.c so as to compare the sign bits of the upper and lower doubles and, instead of blindly doing `fraction += xlow', doing `fraction -= xlow' if the sign bits differ. This won't get us quite there in terms of supporting 107 bits of precision (which is impossible anyway, since for a ``nearly-infinite'' upper double you get only 106 bits anyway), but should be close enough for the emulation to be called functional. Something like this: --- fp-bit.c.~1.39.~ 2003-01-26 08:06:25.000000000 -0200 +++ fp-bit.c 2003-02-03 11:18:35.000000000 -0200 @@ -455,6 +455,7 @@ unpack_d (FLO_union_type * src, fp_numbe if (exp != EXPMAX && exp != 0 && low != 0) { int lowexp = ((int)(low >> HALFFRACBITS)) & ((1 << EXPBITS) - 1); + int lowsign = ((int)(low >> (((HALFFRACBITS + EXPBITS))))) & 1; int shift; fractype xlow; @@ -468,7 +469,10 @@ unpack_d (FLO_union_type * src, fp_numbe xlow <<= shift; else if (shift < 0) xlow >>= -shift; - fraction += xlow; + if (sign == lowsign) + fraction += xlow; + else + fraction -= xlow; } } # else -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-29 10:07 ` Richard Henderson 2003-01-29 13:39 ` Alexandre Oliva 2003-01-29 17:26 ` Kaveh R. Ghazi @ 2003-01-30 8:05 ` Kaveh R. Ghazi 2003-02-03 13:07 ` Alexandre Oliva 2 siblings, 1 reply; 72+ messages in thread From: Kaveh R. Ghazi @ 2003-01-30 8:05 UTC (permalink / raw) To: rth; +Cc: aoliva, gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro > From: Richard Henderson <rth@redhat.com> > > > > unordtf2_libfunc > > This one may be a problem. We don't know what the actual > return values are for the comparison functions. By rights > it ought to be a tri-state value off of EQ or NE. I'm not sure what you mean. Are you saying that all the gcc comparison functions are tri-state (-1,0,1) or just the unord one? The Irix native comparison ops all return 0 or 1 (true/false). I tested them all manually. They don't seem to work when I use them as replacements for the gcc comparison ops. I get funky results when I try test programs, not sure why. --Kaveh -- Kaveh R. Ghazi ghazi@caip.rutgers.edu ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-30 8:05 ` Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) Kaveh R. Ghazi @ 2003-02-03 13:07 ` Alexandre Oliva 2003-02-03 15:18 ` Kaveh R. Ghazi 0 siblings, 1 reply; 72+ messages in thread From: Alexandre Oliva @ 2003-02-03 13:07 UTC (permalink / raw) To: Kaveh R. Ghazi; +Cc: rth, gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro On Jan 30, 2003, "Kaveh R. Ghazi" <ghazi@caip.rutgers.edu> wrote: >> From: Richard Henderson <rth@redhat.com> >> > >> > unordtf2_libfunc >> >> This one may be a problem. We don't know what the actual >> return values are for the comparison functions. By rights >> it ought to be a tri-state value off of EQ or NE. > I'm not sure what you mean. Are you saying that all the gcc > comparison functions are tri-state (-1,0,1) or just the unord one? There is L_compare_[sdt]f, that is tri-state, but none of the others are, it's just that you sometimes can't distinguish unord from false on the others, such as those of gofast. If there's no equivalent to the tri-state compare on IRIX, just set the corresponding entry in optabs NULL, and GCC will find other ways to implement it, using eq, ne, gt, ge, lt and le. -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-02-03 13:07 ` Alexandre Oliva @ 2003-02-03 15:18 ` Kaveh R. Ghazi 2003-02-03 16:37 ` Alexandre Oliva 0 siblings, 1 reply; 72+ messages in thread From: Kaveh R. Ghazi @ 2003-02-03 15:18 UTC (permalink / raw) To: aoliva; +Cc: gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro, rth > From: Alexandre Oliva <aoliva@redhat.com> > > On Jan 30, 2003, "Kaveh R. Ghazi" <ghazi@caip.rutgers.edu> wrote: > > >> From: Richard Henderson <rth@redhat.com> > >> > > >> > unordtf2_libfunc > >> > >> This one may be a problem. We don't know what the actual > >> return values are for the comparison functions. By rights > >> it ought to be a tri-state value off of EQ or NE. > > > I'm not sure what you mean. Are you saying that all the gcc > > comparison functions are tri-state (-1,0,1) or just the unord one? > > There is L_compare_[sdt]f, that is tri-state, but none of the others > are, it's just that you sometimes can't distinguish unord from false > on the others, such as those of gofast. If there's no equivalent to > the tri-state compare on IRIX, just set the corresponding entry in > optabs NULL, and GCC will find other ways to implement it, using eq, > ne, gt, ge, lt and le. Sorry, I'm seeing something different. First looking at fp-bit.c, all of the comparison ops (e.g. _eq_f2) call __fpcmp_parts which returns a tri-state value. I.e. it's not just L_compare_[sdt]f. Second, looking at prepare_float_lib_cmp in optabs.c if the optabs are NULL, it'll only swap GE <-> LE and GT <-> LT in both directions. So if at least one or the other isn't defined how will it work? Anyway, I just found FLOAT_LIB_COMPARE_RETURNS_BOOL in tm.texi which, judging by the name, appears to be exactly what I need. :-) --Kaveh -- Kaveh R. Ghazi ghazi@caip.rutgers.edu ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-02-03 15:18 ` Kaveh R. Ghazi @ 2003-02-03 16:37 ` Alexandre Oliva 0 siblings, 0 replies; 72+ messages in thread From: Alexandre Oliva @ 2003-02-03 16:37 UTC (permalink / raw) To: Kaveh R. Ghazi; +Cc: gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro, rth On Feb 3, 2003, "Kaveh R. Ghazi" <ghazi@caip.rutgers.edu> wrote: > Sorry, I'm seeing something different. First looking at fp-bit.c, all > of the comparison ops (e.g. _eq_f2) call __fpcmp_parts which returns a > tri-state value. I.e. it's not just L_compare_[sdt]f. Right, but GCC doesn't really care about the 3 states, only about the truth conditions being met. > Second, looking at prepare_float_lib_cmp in optabs.c if the optabs are > NULL, it'll only swap GE <-> LE and GT <-> LT in both directions. So > if at least one or the other isn't defined how will it work? It won't. I believe this should be enough to get you going, though. > Anyway, I just found FLOAT_LIB_COMPARE_RETURNS_BOOL in tm.texi which, > judging by the name, appears to be exactly what I need. :-) Oh. How nice. I didn't realize we had something like this. In fact, I hadn't realized that our compare functions weren't bool-like before I looked at them again today :-) -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-27 9:17 ` Kaveh R. Ghazi 2003-01-27 10:40 ` Alexandre Oliva @ 2003-01-27 10:41 ` Alexandre Oliva 1 sibling, 0 replies; 72+ messages in thread From: Alexandre Oliva @ 2003-01-27 10:41 UTC (permalink / raw) To: Kaveh R. Ghazi; +Cc: gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro, rth On Jan 27, 2003, "Kaveh R. Ghazi" <ghazi@caip.rutgers.edu> wrote: > PS: what were your results on irix6? No regressions. In particular, the numeric_limits (sp?) libstdc++-v3 test passed. -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-26 16:14 ` Alexandre Oliva 2003-01-26 18:40 ` Kaveh R. Ghazi 2003-01-26 21:24 ` Kaveh R. Ghazi @ 2003-01-26 21:54 ` Richard Henderson 2 siblings, 0 replies; 72+ messages in thread From: Richard Henderson @ 2003-01-26 21:54 UTC (permalink / raw) To: Alexandre Oliva Cc: Kaveh R. Ghazi, gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro On Sun, Jan 26, 2003 at 10:48:18AM -0200, Alexandre Oliva wrote: > * real.c (ibm_extended_format): Add 53 to minimum exponent. > (encode_ibm_extended): Adjust. Ok. Thanks for working out a proper definition of "denormal" for this fp type. Someone might want to look at the AIX headers and file a bug with IBM if the value doesn't correspond. ;-) r~ ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-07 22:57 ` Richard Henderson 2003-01-08 18:16 ` Alexandre Oliva 2003-01-10 1:18 ` Alexandre Oliva @ 2003-01-10 1:37 ` Alexandre Oliva 2003-01-26 10:07 ` Alexandre Oliva ` (6 subsequent siblings) 9 siblings, 0 replies; 72+ messages in thread From: Alexandre Oliva @ 2003-01-10 1:37 UTC (permalink / raw) To: Richard Henderson Cc: Kaveh R. Ghazi, gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro On Jan 7, 2003, Richard Henderson <rth@redhat.com> wrote: >> * optabs.c (expand_binop) <add, sub>: Return xtarget if we haven't >> been able to move the result to target. > Ok, I guess. How does this come up? There's no movti insn, so the test that decides whether it's possible to move the result to the final location fails and we omit the move at that point. It ends up being emitted as a multi-insn move sequence upstream, as long as we return the correct location of the result. FWIW, I had movti patterns in my patch at some point, that split into pairs of DI moves, but it proved to be pointless, so I took it out. -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-07 22:57 ` Richard Henderson ` (2 preceding siblings ...) 2003-01-10 1:37 ` Alexandre Oliva @ 2003-01-26 10:07 ` Alexandre Oliva 2003-01-26 10:42 ` Alexandre Oliva ` (5 subsequent siblings) 9 siblings, 0 replies; 72+ messages in thread From: Alexandre Oliva @ 2003-01-26 10:07 UTC (permalink / raw) To: Richard Henderson Cc: Kaveh R. Ghazi, gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro [-- Attachment #1: Type: text/plain, Size: 354 bytes --] I'm going to check in the hunks that you've approved that make sense by themselves, in both 3.3 branch and mainline, leaving out the IRIX-specific hunks that still require some fixing. On Jan 7, 2003, Richard Henderson <rth@redhat.com> wrote: >> * print-rtl.c (print_rtx): Don't print MEM details in >> GENERATOR_FILEs. > Ok. I'm checking this in. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: gcc-mips-tfmode-print-rtl.patch --] [-- Type: text/x-patch, Size: 1072 bytes --] Index: gcc/ChangeLog from Alexandre Oliva <aoliva@redhat.com> * print-rtl.c (print_rtx): Don't print MEM details in GENERATOR_FILEs. Index: gcc/print-rtl.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/print-rtl.c,v retrieving revision 1.91 diff -u -p -r1.91 print-rtl.c --- gcc/print-rtl.c 16 Oct 2002 00:40:27 -0000 1.91 +++ gcc/print-rtl.c 26 Jan 2003 08:57:03 -0000 @@ -1,5 +1,5 @@ /* Print RTL for GNU C Compiler. - Copyright (C) 1987, 1988, 1992, 1997, 1998, 1999, 2000 + Copyright (C) 1987, 1988, 1992, 1997, 1998, 1999, 2000, 2002, 2003 Free Software Foundation, Inc. This file is part of GCC. @@ -491,6 +491,7 @@ print_rtx (in_rtx) switch (GET_CODE (in_rtx)) { +#ifndef GENERATOR_FILE case MEM: fputs (" [", outfile); fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, MEM_ALIAS_SET (in_rtx)); @@ -518,7 +519,6 @@ print_rtx (in_rtx) fputc (']', outfile); break; -#ifndef GENERATOR_FILE case CONST_DOUBLE: if (FLOAT_MODE_P (GET_MODE (in_rtx))) { [-- Attachment #3: Type: text/plain, Size: 289 bytes --] -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-07 22:57 ` Richard Henderson ` (3 preceding siblings ...) 2003-01-26 10:07 ` Alexandre Oliva @ 2003-01-26 10:42 ` Alexandre Oliva 2003-01-26 10:45 ` Alexandre Oliva ` (4 subsequent siblings) 9 siblings, 0 replies; 72+ messages in thread From: Alexandre Oliva @ 2003-01-26 10:42 UTC (permalink / raw) To: Richard Henderson Cc: Kaveh R. Ghazi, gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro [-- Attachment #1: Type: text/plain, Size: 156 bytes --] On Jan 7, 2003, Richard Henderson <rth@redhat.com> wrote: >> * rtl.c (get_mode_alignment): Moved to... >> * stor-layout.c: ... here. > Ok. Checked in. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: gcc-mips-tfmode-get-mode-align.patch --] [-- Type: text/x-patch, Size: 2809 bytes --] Index: gcc/ChangeLog from Alexandre Oliva <aoliva@redhat.com> * rtl.c (get_mode_alignment): Moved to... * stor-layout.c: ... here. Index: gcc/rtl.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/rtl.c,v retrieving revision 1.120 diff -u -p -r1.120 rtl.c --- gcc/rtl.c 14 Oct 2002 02:36:25 -0000 1.120 +++ gcc/rtl.c 26 Jan 2003 09:01:24 -0000 @@ -1,6 +1,6 @@ /* RTL utility routines. - Copyright (C) 1987, 1988, 1991, 1994, 1997, 1998, 1999, 2000, 2001, 2002 - Free Software Foundation, Inc. + Copyright (C) 1987, 1988, 1991, 1994, 1997, 1998, 1999, 2000, 2001, 2002, + 2003 Free Software Foundation, Inc. This file is part of GCC. @@ -395,29 +395,6 @@ shallow_copy_rtx (orig) sizeof (struct rtx_def) + sizeof (rtunion) * (n - 1)); return copy; -} - -/* Return the alignment of MODE. This will be bounded by 1 and - BIGGEST_ALIGNMENT. */ - -unsigned int -get_mode_alignment (mode) - enum machine_mode mode; -{ - unsigned int alignment; - - if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT - || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT) - alignment = GET_MODE_UNIT_SIZE (mode); - else - alignment = GET_MODE_SIZE (mode); - - /* Extract the LSB of the size. */ - alignment = alignment & -alignment; - alignment *= BITS_PER_UNIT; - - alignment = MIN (BIGGEST_ALIGNMENT, MAX (1, alignment)); - return alignment; } \f /* This is 1 until after the rtl generation pass. */ Index: gcc/stor-layout.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/stor-layout.c,v retrieving revision 1.134 diff -u -p -r1.134 stor-layout.c --- gcc/stor-layout.c 20 Nov 2002 10:09:00 -0000 1.134 +++ gcc/stor-layout.c 26 Jan 2003 09:01:25 -0000 @@ -1,6 +1,6 @@ /* C-compiler utilities for types and variables storage layout Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1996, 1998, - 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GCC. @@ -296,6 +296,29 @@ int_mode_for_mode (mode) } return mode; +} + +/* Return the alignment of MODE. This will be bounded by 1 and + BIGGEST_ALIGNMENT. */ + +unsigned int +get_mode_alignment (mode) + enum machine_mode mode; +{ + unsigned int alignment; + + if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT + || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT) + alignment = GET_MODE_UNIT_SIZE (mode); + else + alignment = GET_MODE_SIZE (mode); + + /* Extract the LSB of the size. */ + alignment = alignment & -alignment; + alignment *= BITS_PER_UNIT; + + alignment = MIN (BIGGEST_ALIGNMENT, MAX (1, alignment)); + return alignment; } /* Return the value of VALUE, rounded up to a multiple of DIVISOR. [-- Attachment #3: Type: text/plain, Size: 289 bytes --] -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-07 22:57 ` Richard Henderson ` (4 preceding siblings ...) 2003-01-26 10:42 ` Alexandre Oliva @ 2003-01-26 10:45 ` Alexandre Oliva 2003-01-26 10:53 ` Alexandre Oliva ` (3 subsequent siblings) 9 siblings, 0 replies; 72+ messages in thread From: Alexandre Oliva @ 2003-01-26 10:45 UTC (permalink / raw) To: Richard Henderson Cc: Kaveh R. Ghazi, gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro [-- Attachment #1: Type: text/plain, Size: 165 bytes --] On Jan 7, 2003, Richard Henderson <rth@redhat.com> wrote: >> * calls.c (emit_library_call_value_1): Handle return values >> in a PARALLEL. > Ok. Checking in... [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: gcc-mips-tfmode-calls.patch --] [-- Type: text/x-patch, Size: 1866 bytes --] Index: gcc/ChangeLog from Alexandre Oliva <aoliva@redhat.com> * calls.c (emit_library_call_value_1): Handle return values in a PARALLEL. Index: gcc/calls.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/calls.c,v retrieving revision 1.244.2.2 diff -u -p -r1.244.2.2 calls.c --- gcc/calls.c 24 Jan 2003 23:15:23 -0000 1.244.2.2 +++ gcc/calls.c 26 Jan 2003 09:04:28 -0000 @@ -1,6 +1,6 @@ /* Convert function calls to rtl insns, for GNU C compiler. Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998 - 1999, 2000, 2001 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GCC. @@ -4142,7 +4142,7 @@ emit_library_call_value_1 (retval, orgfu { rtx insns; - if (valreg == 0 || GET_CODE (valreg) == PARALLEL) + if (valreg == 0) { insns = get_insns (); end_sequence (); @@ -4151,9 +4151,18 @@ emit_library_call_value_1 (retval, orgfu else { rtx note = 0; - rtx temp = gen_reg_rtx (GET_MODE (valreg)); + rtx temp; int i; + if (GET_CODE (valreg) == PARALLEL) + { + temp = gen_reg_rtx (outmode); + emit_group_store (temp, valreg, outmode); + valreg = temp; + } + + temp = gen_reg_rtx (GET_MODE (valreg)); + /* Construct an "equal form" for the value which mentions all the arguments in order as well as the function name. */ for (i = 0; i < nargs; i++) @@ -4186,6 +4195,12 @@ emit_library_call_value_1 (retval, orgfu value = mem_value; if (value != mem_value) emit_move_insn (value, mem_value); + } + else if (GET_CODE (valreg) == PARALLEL) + { + if (value == 0) + value = gen_reg_rtx (outmode); + emit_group_store (value, valreg, outmode); } else if (value != 0) emit_move_insn (value, valreg); [-- Attachment #3: Type: text/plain, Size: 289 bytes --] -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-07 22:57 ` Richard Henderson ` (5 preceding siblings ...) 2003-01-26 10:45 ` Alexandre Oliva @ 2003-01-26 10:53 ` Alexandre Oliva 2003-01-26 12:07 ` Alexandre Oliva ` (2 subsequent siblings) 9 siblings, 0 replies; 72+ messages in thread From: Alexandre Oliva @ 2003-01-26 10:53 UTC (permalink / raw) To: Richard Henderson Cc: Kaveh R. Ghazi, gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro [-- Attachment #1: Type: text/plain, Size: 176 bytes --] On Jan 7, 2003, Richard Henderson <rth@redhat.com> wrote: >> * expr.c (emit_group_store): Initialize dst with CONST0_RTX >> for the appropriate mode. > Ok. Checking in... [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: gcc-mips-tfmode-expr.patch --] [-- Type: text/x-patch, Size: 739 bytes --] Index: gcc/ChangeLog from Alexandre Oliva <aoliva@redhat.com> * expr.c (emit_group_store): Initialize dst with CONST0_RTX for the appropriate mode. Index: gcc/expr.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/expr.c,v retrieving revision 1.498.2.2 diff -u -p -r1.498.2.2 expr.c --- gcc/expr.c 11 Jan 2003 22:43:52 -0000 1.498.2.2 +++ gcc/expr.c 26 Jan 2003 09:08:05 -0000 @@ -2436,7 +2436,7 @@ emit_group_store (orig_dst, src, ssize) { dst = gen_reg_rtx (GET_MODE (orig_dst)); /* Make life a bit easier for combine. */ - emit_move_insn (dst, const0_rtx); + emit_move_insn (dst, CONST0_RTX (GET_MODE (orig_dst))); } /* Process the pieces. */ [-- Attachment #3: Type: text/plain, Size: 289 bytes --] -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-07 22:57 ` Richard Henderson ` (6 preceding siblings ...) 2003-01-26 10:53 ` Alexandre Oliva @ 2003-01-26 12:07 ` Alexandre Oliva 2003-01-26 12:20 ` Alexandre Oliva 2003-01-26 12:50 ` Alexandre Oliva 9 siblings, 0 replies; 72+ messages in thread From: Alexandre Oliva @ 2003-01-26 12:07 UTC (permalink / raw) To: Richard Henderson Cc: Kaveh R. Ghazi, gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro [-- Attachment #1: Type: text/plain, Size: 196 bytes --] On Jan 7, 2003, Richard Henderson <rth@redhat.com> wrote: >> * optabs.c (expand_binop) <add, sub>: Return xtarget if we haven't >> been able to move the result to target. > Ok Checking in... [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: gcc-mips-tfmode-optabs.patch --] [-- Type: text/x-patch, Size: 964 bytes --] Index: gcc/ChangeLog from Alexandre Oliva <aoliva@redhat.com> * optabs.c (expand_binop) <add, sub>: Return xtarget if we haven't been able to move the result to target. Index: gcc/optabs.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/optabs.c,v retrieving revision 1.153.2.1 diff -u -p -r1.153.2.1 optabs.c --- gcc/optabs.c 9 Jan 2003 12:40:44 -0000 1.153.2.1 +++ gcc/optabs.c 26 Jan 2003 09:10:23 -0000 @@ -1,6 +1,6 @@ /* Expand the basic unary and binary arithmetic operations, for GNU compiler. Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2003 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GCC. @@ -1307,6 +1307,8 @@ expand_binop (mode, binoptab, op0, op1, copy_rtx (xop0), copy_rtx (xop1))); } + else + target = xtarget; return target; } [-- Attachment #3: Type: text/plain, Size: 289 bytes --] -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-07 22:57 ` Richard Henderson ` (7 preceding siblings ...) 2003-01-26 12:07 ` Alexandre Oliva @ 2003-01-26 12:20 ` Alexandre Oliva 2003-01-26 12:50 ` Alexandre Oliva 9 siblings, 0 replies; 72+ messages in thread From: Alexandre Oliva @ 2003-01-26 12:20 UTC (permalink / raw) To: Richard Henderson Cc: Kaveh R. Ghazi, gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro [-- Attachment #1: Type: text/plain, Size: 387 bytes --] On Jan 7, 2003, Richard Henderson <rth@redhat.com> wrote: > On Fri, Dec 27, 2002 at 11:47:15AM -0200, Alexandre Oliva wrote: >> * Makefile.in (FPBIT_FUNCS): Added _sf_to_tf. >> (DBBIT_FUNCS): Added _df_to_tf. >> (TPBIT_FUNCS): New. >> (libgcc.mk): Pass TPBIT and TPBIT_FUNCS down. >> (LIBGCC_DEPS): Added TPBIT. >> * mklibgcc.in: Support TPBIT and TPBIT_FUNCS. > Ok. Checking in... [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: gcc-mips-tfmode-makefiles.patch --] [-- Type: text/x-patch, Size: 3910 bytes --] Index: gcc/ChangeLog from Alexandre Oliva <aoliva@redhat.com> * Makefile.in (FPBIT_FUNCS): Added _sf_to_tf. (DBBIT_FUNCS): Added _df_to_tf. (TPBIT_FUNCS): New. (libgcc.mk): Pass TPBIT and TPBIT_FUNCS down. (LIBGCC_DEPS): Added TPBIT. * mklibgcc.in: Support TPBIT and TPBIT_FUNCS. Index: gcc/Makefile.in =================================================================== RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v retrieving revision 1.958.2.2 diff -u -p -r1.958.2.2 Makefile.in --- gcc/Makefile.in 9 Jan 2003 12:40:43 -0000 1.958.2.2 +++ gcc/Makefile.in 26 Jan 2003 09:14:44 -0000 @@ -798,12 +798,17 @@ LIB2FUNCS_ST = _eprintf _bb __gcc_bcmp FPBIT_FUNCS = _pack_sf _unpack_sf _addsub_sf _mul_sf _div_sf \ _fpcmp_parts_sf _compare_sf _eq_sf _ne_sf _gt_sf _ge_sf \ _lt_sf _le_sf _unord_sf _si_to_sf _sf_to_si _negate_sf _make_sf \ - _sf_to_df _thenan_sf _sf_to_usi _usi_to_sf + _sf_to_df _sf_to_tf _thenan_sf _sf_to_usi _usi_to_sf DPBIT_FUNCS = _pack_df _unpack_df _addsub_df _mul_df _div_df \ _fpcmp_parts_df _compare_df _eq_df _ne_df _gt_df _ge_df \ _lt_df _le_df _unord_df _si_to_df _df_to_si _negate_df _make_df \ - _df_to_sf _thenan_df _df_to_usi _usi_to_df + _df_to_sf _df_to_tf _thenan_df _df_to_usi _usi_to_df + +TPBIT_FUNCS = _pack_tf _unpack_tf _addsub_tf _mul_tf _div_tf \ + _fpcmp_parts_tf _compare_tf _eq_tf _ne_tf _gt_tf _ge_tf \ + _lt_tf _le_tf _unord_tf _si_to_tf _tf_to_si _negate_tf _make_tf \ + _tf_to_df _tf_to_sf _thenan_tf _tf_to_usi _usi_to_tf # These might cause a divide overflow trap and so are compiled with # unwinder info. @@ -1023,6 +1028,8 @@ libgcc.mk: config.status Makefile mklibg LIB2_DIVMOD_FUNCS='$(LIB2_DIVMOD_FUNCS)' \ DPBIT='$(DPBIT)' \ DPBIT_FUNCS='$(DPBIT_FUNCS)' \ + TPBIT='$(TPBIT)' \ + TPBIT_FUNCS='$(TPBIT_FUNCS)' \ MULTILIBS=`$(GCC_FOR_TARGET) --print-multi-lib` \ EXTRA_MULTILIB_PARTS='$(EXTRA_MULTILIB_PARTS)' \ SHLIB_LINK='$(SHLIB_LINK)' \ @@ -1042,8 +1049,9 @@ libgcc.mk: config.status Makefile mklibg LIBGCC_DEPS = $(GCC_PASSES) $(LANGUAGES) stmp-int-hdrs $(STMP_FIXPROTO) \ libgcc.mk $(srcdir)/libgcc2.c $(TCONFIG_H) \ $(MACHMODE_H) longlong.h gbl-ctors.h config.status stmp-int-hdrs \ - tsystem.h $(FPBIT) $(DPBIT) $(LIB2ADD) $(LIB2ADD_ST) $(LIB2ADDEH) \ - $(LIB2ADDEHDEP) $(EXTRA_PARTS) $(srcdir)/config/$(LIB1ASMSRC) + tsystem.h $(FPBIT) $(DPBIT) $(TPBIT) $(LIB2ADD) \ + $(LIB2ADD_ST) $(LIB2ADDEH) $(LIB2ADDEHDEP) $(EXTRA_PARTS) \ + $(srcdir)/config/$(LIB1ASMSRC) libgcc.a: $(LIBGCC_DEPS) $(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \ Index: gcc/mklibgcc.in =================================================================== RCS file: /cvs/gcc/gcc/gcc/mklibgcc.in,v retrieving revision 1.48 diff -u -p -r1.48 mklibgcc.in --- gcc/mklibgcc.in 3 Oct 2002 20:35:13 -0000 1.48 +++ gcc/mklibgcc.in 26 Jan 2003 09:14:44 -0000 @@ -1,6 +1,6 @@ #!/bin/sh # Construct makefile for libgcc. -# Copyright (C) 2000, 2002 Free Software Foundation, Inc. +# Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc. # # This file is part of GCC. @@ -21,6 +21,8 @@ # LIB2_DIVMOD_FUNCS # DPBIT # DPBIT_FUNCS +# TPBIT +# TPBIT_FUNCS # LIBGCC # MULTILIBS # EXTRA_MULTILIB_PARTS @@ -169,6 +171,21 @@ if [ "$DPBIT" ]; then echo $out: $DPBIT $fpbit_c_dep echo " $gcc_compile" -DFINE_GRAINED_LIBRARIES $flags -DL$name \ -c $DPBIT -o $out + done + libgcc2_objs="$libgcc2_objs ${name}${objext}" + done +fi + +if [ "$TPBIT" ]; then + for name in $TPBIT_FUNCS; do + for ml in $MULTILIBS; do + dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'` + flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`; + out="libgcc/${dir}/${name}${objext}" + + echo $out: $TPBIT $fpbit_c_dep + echo " $gcc_compile" -DFINE_GRAINED_LIBRARIES $flags -DL$name \ + -c $TPBIT -o $out done libgcc2_objs="$libgcc2_objs ${name}${objext}" done [-- Attachment #3: Type: text/plain, Size: 289 bytes --] -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-07 22:57 ` Richard Henderson ` (8 preceding siblings ...) 2003-01-26 12:20 ` Alexandre Oliva @ 2003-01-26 12:50 ` Alexandre Oliva 9 siblings, 0 replies; 72+ messages in thread From: Alexandre Oliva @ 2003-01-26 12:50 UTC (permalink / raw) To: Richard Henderson Cc: Kaveh R. Ghazi, gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro [-- Attachment #1: Type: text/plain, Size: 1112 bytes --] On Jan 7, 2003, Richard Henderson <rth@redhat.com> wrote: >> * fp-bit.h: Define macros for TFmode floating-point constants >> in IEEE and IBM-extended TFmode types. Declare functions >> according to L_ macros. >> (TMODES): Define if __LDBL_MANT_DIG__ has one of >> the newly-supported widths. >> (TFtype, TItype, UTItype): Define if TMODES is defined. >> (MAX_UDI_INT, MAX_DI_INT, BITS_PER_DI): Likewise. >> (F_T_BITOFF, D_T_BITOFF): Define. >> (IMPLICIT_1, IMPLICIT_2): Cast constants to types that are >> guaranteed to be wide enough. >> * config/fp-bit.c: Check for L_ macros for tf functions. >> (__thenan_tf): New. >> (nan): Adjust. >> (pack_d, unpack_d): Support IEEE 854 and IBM-extended TFmode >> types. >> (_fpmul_parts): Support TFmode. Compute exponent adjustment >> from FRAC_NBITS, FRAC_BITS and NGARDS. >> (usi_to_float): Cast constants to be shifted to fractype >> instead of assuming long long is wide enough. >> (sf_to_tf, df_to_tf, __make_tp, tf_to_df, tf_to_sf): New. > Ok I'm checking this in, leaving out the parts that support the IBM extended format, that still need some tweaking. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: gcc-mips-tfmode-fp-bit.patch --] [-- Type: text/x-patch, Size: 22550 bytes --] Index: gcc/ChangeLog from Alexandre Oliva <aoliva@redhat.com> * config/fp-bit.h: Define macros for TFmode floating-point constants in IEEE quad TFmode type. Declare functions according to L_ macros. (TMODES): Define if __LDBL_MANT_DIG__ is 113. (TFtype, TItype, UTItype): Define if TMODES is defined. (MAX_UDI_INT, MAX_DI_INT, BITS_PER_DI): Likewise. (F_T_BITOFF, D_T_BITOFF): Define. (IMPLICIT_1, IMPLICIT_2): Cast constants to types that are guaranteed to be wide enough. * config/fp-bit.c: Check for L_ macros for tf functions. (__thenan_tf): New. (nan): Adjust. (pack_d, unpack_d): Support IEEE 854 quad type. (_fpmul_parts): Support TFmode. Compute exponent adjustment from FRAC_NBITS, FRAC_BITS and NGARDS. (usi_to_float): Cast constants to be shifted to fractype instead of assuming long long is wide enough. (sf_to_tf, df_to_tf, __make_tp, tf_to_df, tf_to_sf): New. Index: gcc/config/fp-bit.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/fp-bit.c,v retrieving revision 1.36 diff -u -p -r1.36 fp-bit.c --- gcc/config/fp-bit.c 7 Oct 2002 08:47:09 -0000 1.36 +++ gcc/config/fp-bit.c 26 Jan 2003 09:26:55 -0000 @@ -1,6 +1,6 @@ /* This is a software floating point library which can be used for targets without hardware floating point. - Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002 + Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This file is free software; you can redistribute it and/or modify it @@ -130,6 +130,10 @@ void __lttf2 (void) { abort(); } const fp_number_type __thenan_sf = { CLASS_SNAN, 0, 0, {(fractype) 0} }; #elif defined L_thenan_df const fp_number_type __thenan_df = { CLASS_SNAN, 0, 0, {(fractype) 0} }; +#elif defined L_thenan_tf +const fp_number_type __thenan_tf = { CLASS_SNAN, 0, 0, {(fractype) 0} }; +#elif defined TFLOAT +extern const fp_number_type __thenan_tf; #elif defined FLOAT extern const fp_number_type __thenan_sf; #else @@ -141,7 +145,9 @@ static fp_number_type * nan (void) { /* Discard the const qualifier... */ -#ifdef FLOAT +#ifdef TFLOAT + return (fp_number_type *) (& __thenan_tf); +#elif defined FLOAT return (fp_number_type *) (& __thenan_sf); #else return (fp_number_type *) (& __thenan_df); @@ -180,7 +186,7 @@ flip_sign ( fp_number_type * x) extern FLO_type pack_d ( fp_number_type * ); -#if defined(L_pack_df) || defined(L_pack_sf) +#if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf) FLO_type pack_d ( fp_number_type * src) { @@ -322,18 +328,29 @@ pack_d ( fp_number_type * src) #endif #if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT) +#ifdef TFLOAT + { + qrtrfractype tmp1 = dst.words[0]; + qrtrfractype tmp2 = dst.words[1]; + dst.words[0] = dst.words[3]; + dst.words[1] = dst.words[2]; + dst.words[2] = tmp2; + dst.words[3] = tmp1; + } +#else { halffractype tmp = dst.words[0]; dst.words[0] = dst.words[1]; dst.words[1] = tmp; } #endif +#endif return dst.value; } #endif -#if defined(L_unpack_df) || defined(L_unpack_sf) +#if defined(L_unpack_df) || defined(L_unpack_sf) || defined(L_unpack_tf) void unpack_d (FLO_union_type * src, fp_number_type * dst) { @@ -347,8 +364,15 @@ unpack_d (FLO_union_type * src, fp_numbe #if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT) FLO_union_type swapped; +#ifdef TFLOAT + swapped.words[0] = src->words[3]; + swapped.words[1] = src->words[2]; + swapped.words[2] = src->words[1]; + swapped.words[3] = src->words[0]; +#else swapped.words[0] = src->words[1]; swapped.words[1] = src->words[0]; +#endif src = &swapped; #endif @@ -357,7 +381,7 @@ unpack_d (FLO_union_type * src, fp_numbe exp = src->bits.exp; sign = src->bits.sign; #else - fraction = src->value_raw & ((((fractype)1) << FRACBITS) - (fractype)1); + fraction = src->value_raw & ((((fractype)1) << FRACBITS) - 1); exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1); sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1; #endif @@ -427,7 +451,7 @@ unpack_d (FLO_union_type * src, fp_numbe } #endif /* L_unpack_df || L_unpack_sf */ -#if defined(L_addsub_sf) || defined(L_addsub_df) +#if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf) static fp_number_type * _fpadd_parts (fp_number_type * a, fp_number_type * b, @@ -611,7 +635,7 @@ sub (FLO_type arg_a, FLO_type arg_b) } #endif /* L_addsub_sf || L_addsub_df */ -#if defined(L_mul_sf) || defined(L_mul_df) +#if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf) static inline __attribute__ ((__always_inline__)) fp_number_type * _fpmul_parts ( fp_number_type * a, fp_number_type * b, @@ -660,7 +684,7 @@ _fpmul_parts ( fp_number_type * a, /* Calculate the mantissa by multiplying both numbers to get a twice-as-wide number. */ { -#if defined(NO_DI_MODE) +#if defined(NO_DI_MODE) || defined(TFLOAT) { fractype x = a->fraction.ll; fractype ylow = b->fraction.ll; @@ -723,13 +747,9 @@ _fpmul_parts ( fp_number_type * a, #endif } - tmp->normal_exp = a->normal_exp + b->normal_exp; + tmp->normal_exp = a->normal_exp + b->normal_exp + + FRAC_NBITS - (FRACBITS + NGARDS); tmp->sign = a->sign != b->sign; -#ifdef FLOAT - tmp->normal_exp += 2; /* ??????????????? */ -#else - tmp->normal_exp += 4; /* ??????????????? */ -#endif while (high >= IMPLICIT_2) { tmp->normal_exp++; @@ -803,7 +823,7 @@ multiply (FLO_type arg_a, FLO_type arg_b } #endif /* L_mul_sf || L_mul_df */ -#if defined(L_div_sf) || defined(L_div_df) +#if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf) static inline __attribute__ ((__always_inline__)) fp_number_type * _fpdiv_parts (fp_number_type * a, fp_number_type * b) @@ -913,7 +933,8 @@ divide (FLO_type arg_a, FLO_type arg_b) } #endif /* L_div_sf || L_div_df */ -#if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) +#if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) \ + || defined(L_fpcmp_parts_tf) /* according to the demo, fpcmp returns a comparison with 0... thus a<b -> -1 a==b -> 0 @@ -998,7 +1019,7 @@ __fpcmp_parts (fp_number_type * a, fp_nu } #endif -#if defined(L_compare_sf) || defined(L_compare_df) +#if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compoare_tf) CMPtype compare (FLO_type arg_a, FLO_type arg_b) { @@ -1020,7 +1041,7 @@ compare (FLO_type arg_a, FLO_type arg_b) /* These should be optimized for their specific tasks someday. */ -#if defined(L_eq_sf) || defined(L_eq_df) +#if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf) CMPtype _eq_f2 (FLO_type arg_a, FLO_type arg_b) { @@ -1041,7 +1062,7 @@ _eq_f2 (FLO_type arg_a, FLO_type arg_b) } #endif /* L_eq_sf || L_eq_df */ -#if defined(L_ne_sf) || defined(L_ne_df) +#if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf) CMPtype _ne_f2 (FLO_type arg_a, FLO_type arg_b) { @@ -1062,7 +1083,7 @@ _ne_f2 (FLO_type arg_a, FLO_type arg_b) } #endif /* L_ne_sf || L_ne_df */ -#if defined(L_gt_sf) || defined(L_gt_df) +#if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf) CMPtype _gt_f2 (FLO_type arg_a, FLO_type arg_b) { @@ -1083,7 +1104,7 @@ _gt_f2 (FLO_type arg_a, FLO_type arg_b) } #endif /* L_gt_sf || L_gt_df */ -#if defined(L_ge_sf) || defined(L_ge_df) +#if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf) CMPtype _ge_f2 (FLO_type arg_a, FLO_type arg_b) { @@ -1103,7 +1124,7 @@ _ge_f2 (FLO_type arg_a, FLO_type arg_b) } #endif /* L_ge_sf || L_ge_df */ -#if defined(L_lt_sf) || defined(L_lt_df) +#if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf) CMPtype _lt_f2 (FLO_type arg_a, FLO_type arg_b) { @@ -1124,7 +1145,7 @@ _lt_f2 (FLO_type arg_a, FLO_type arg_b) } #endif /* L_lt_sf || L_lt_df */ -#if defined(L_le_sf) || defined(L_le_df) +#if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf) CMPtype _le_f2 (FLO_type arg_a, FLO_type arg_b) { @@ -1147,7 +1168,7 @@ _le_f2 (FLO_type arg_a, FLO_type arg_b) #endif /* ! US_SOFTWARE_GOFAST */ -#if defined(L_unord_sf) || defined(L_unord_df) +#if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf) CMPtype _unord_f2 (FLO_type arg_a, FLO_type arg_b) { @@ -1165,7 +1186,7 @@ _unord_f2 (FLO_type arg_a, FLO_type arg_ } #endif /* L_unord_sf || L_unord_df */ -#if defined(L_si_to_sf) || defined(L_si_to_df) +#if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf) FLO_type si_to_float (SItype arg_a) { @@ -1193,7 +1214,7 @@ si_to_float (SItype arg_a) else in.fraction.ll = arg_a; - while (in.fraction.ll < (1LL << (FRACBITS + NGARDS))) + while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS))) { in.fraction.ll <<= 1; in.normal_exp -= 1; @@ -1203,7 +1224,7 @@ si_to_float (SItype arg_a) } #endif /* L_si_to_sf || L_si_to_df */ -#if defined(L_usi_to_sf) || defined(L_usi_to_df) +#if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf) FLO_type usi_to_float (USItype arg_a) { @@ -1220,12 +1241,12 @@ usi_to_float (USItype arg_a) in.normal_exp = FRACBITS + NGARDS; in.fraction.ll = arg_a; - while (in.fraction.ll > (1LL << (FRACBITS + NGARDS))) + while (in.fraction.ll > ((fractype)1 << (FRACBITS + NGARDS))) { in.fraction.ll >>= 1; in.normal_exp += 1; } - while (in.fraction.ll < (1LL << (FRACBITS + NGARDS))) + while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS))) { in.fraction.ll <<= 1; in.normal_exp -= 1; @@ -1235,7 +1256,7 @@ usi_to_float (USItype arg_a) } #endif -#if defined(L_sf_to_si) || defined(L_df_to_si) +#if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si) SItype float_to_si (FLO_type arg_a) { @@ -1263,8 +1284,8 @@ float_to_si (FLO_type arg_a) } #endif /* L_sf_to_si || L_df_to_si */ -#if defined(L_sf_to_usi) || defined(L_df_to_usi) -#ifdef US_SOFTWARE_GOFAST +#if defined(L_sf_to_usi) || defined(L_df_to_usi) || defined(L_tf_to_usi) +#if defined US_SOFTWARE_GOFAST || defined(L_tf_to_usi) /* While libgcc2.c defines its own __fixunssfsi and __fixunsdfsi routines, we also define them for GOFAST because the ones in libgcc2.c have the wrong names and I'd rather define these here and keep GOFAST CYG-LOC's @@ -1303,7 +1324,7 @@ float_to_usi (FLO_type arg_a) #endif /* US_SOFTWARE_GOFAST */ #endif /* L_sf_to_usi || L_df_to_usi */ -#if defined(L_negate_sf) || defined(L_negate_df) +#if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf) FLO_type negate (FLO_type arg_a) { @@ -1359,6 +1380,21 @@ sf_to_df (SFtype arg_a) } #endif /* L_sf_to_df */ +#if defined(L_sf_to_tf) && defined(TMODES) +TFtype +sf_to_tf (SFtype arg_a) +{ + fp_number_type in; + FLO_union_type au; + + au.value = arg_a; + unpack_d (&au, &in); + + return __make_tp (in.class, in.sign, in.normal_exp, + ((UTItype) in.fraction.ll) << F_T_BITOFF); +} +#endif /* L_sf_to_df */ + #endif /* ! FLOAT_ONLY */ #endif /* FLOAT */ @@ -1401,6 +1437,85 @@ df_to_sf (DFtype arg_a) return __make_fp (in.class, in.sign, in.normal_exp, sffrac); } #endif /* L_df_to_sf */ + +#if defined(L_df_to_tf) && defined(TMODES) \ + && !defined(FLOAT) && !defined(TFLOAT) +TFtype +df_to_tf (DFtype arg_a) +{ + fp_number_type in; + FLO_union_type au; + + au.value = arg_a; + unpack_d (&au, &in); + + return __make_tp (in.class, in.sign, in.normal_exp, + ((UTItype) in.fraction.ll) << D_T_BITOFF); +} +#endif /* L_sf_to_df */ + +#ifdef TFLOAT +#if defined(L_make_tf) +TFtype +__make_tp(fp_class_type class, + unsigned int sign, + int exp, + UTItype frac) +{ + fp_number_type in; + + in.class = class; + in.sign = sign; + in.normal_exp = exp; + in.fraction.ll = frac; + return pack_d (&in); +} +#endif /* L_make_tf */ + +#if defined(L_tf_to_df) +DFtype +tf_to_df (TFtype arg_a) +{ + fp_number_type in; + UDItype sffrac; + FLO_union_type au; + + au.value = arg_a; + unpack_d (&au, &in); + + sffrac = in.fraction.ll >> D_T_BITOFF; + + /* We set the lowest guard bit in SFFRAC if we discarded any non + zero bits. */ + if ((in.fraction.ll & (((UTItype) 1 << D_T_BITOFF) - 1)) != 0) + sffrac |= 1; + + return __make_dp (in.class, in.sign, in.normal_exp, sffrac); +} +#endif /* L_tf_to_df */ + +#if defined(L_tf_to_sf) +SFtype +tf_to_sf (TFtype arg_a) +{ + fp_number_type in; + USItype sffrac; + FLO_union_type au; + + au.value = arg_a; + unpack_d (&au, &in); + + sffrac = in.fraction.ll >> F_T_BITOFF; + + /* We set the lowest guard bit in SFFRAC if we discarded any non + zero bits. */ + if ((in.fraction.ll & (((UTItype) 1 << F_T_BITOFF) - 1)) != 0) + sffrac |= 1; + + return __make_fp (in.class, in.sign, in.normal_exp, sffrac); +} +#endif /* L_tf_to_sf */ +#endif /* TFLOAT */ #endif /* ! FLOAT */ #endif /* !EXTENDED_FLOAT_STUBS */ Index: gcc/config/fp-bit.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/fp-bit.h,v retrieving revision 1.7 diff -u -p -r1.7 fp-bit.h --- gcc/config/fp-bit.h 19 Jun 2002 23:01:59 -0000 1.7 +++ gcc/config/fp-bit.h 26 Jan 2003 09:26:55 -0000 @@ -1,5 +1,5 @@ /* Header file for fp-bit.c. */ -/* Copyright (C) 2000 +/* Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc. This file is part of GNU CC. @@ -87,12 +87,22 @@ Boston, MA 02111-1307, USA. */ #endif #endif /* ! FINE_GRAINED_LIBRARIES */ +#if __LDBL_MANT_DIG__ == 113 +# define TMODES +#endif + typedef float SFtype __attribute__ ((mode (SF))); typedef float DFtype __attribute__ ((mode (DF))); +#ifdef TMODES +typedef float TFtype __attribute__ ((mode (TF))); +#endif typedef int HItype __attribute__ ((mode (HI))); typedef int SItype __attribute__ ((mode (SI))); typedef int DItype __attribute__ ((mode (DI))); +#ifdef TMODES +typedef int TItype __attribute__ ((mode (TI))); +#endif /* The type of the result of a fp compare */ #ifndef CMPtype @@ -102,16 +112,56 @@ typedef int DItype __attribute__ ((mode typedef unsigned int UHItype __attribute__ ((mode (HI))); typedef unsigned int USItype __attribute__ ((mode (SI))); typedef unsigned int UDItype __attribute__ ((mode (DI))); +#ifdef TMODES +typedef unsigned int UTItype __attribute__ ((mode (TI))); +#endif #define MAX_USI_INT (~(USItype)0) #define MAX_SI_INT ((SItype) (MAX_USI_INT >> 1)) #define BITS_PER_SI (4 * BITS_PER_UNIT) +#ifdef TMODES +#define MAX_UDI_INT (~(UDItype)0) +#define MAX_DI_INT ((DItype) (MAX_UDI_INT >> 1)) +#define BITS_PER_DI (8 * BITS_PER_UNIT) +#endif #ifdef FLOAT_ONLY #define NO_DI_MODE #endif -#ifdef FLOAT +#ifdef TFLOAT +# ifndef TMODES +# error "TFLOAT requires long double to have 113 bits of mantissa" +# endif + +# define PREFIXFPDP tp +# define PREFIXSFDF tf +# define NGARDS 10L /* Is this right? */ +# define GARDROUND 0x1ff +# define GARDMASK 0x3ff +# define GARDMSB 0x200 +# define FRAC_NBITS 128 + +# if __LDBL_MANT_DIG__ == 113 /* IEEE quad */ +# define EXPBITS 15 +# define EXPBIAS 16383 +# define EXPMAX (0x7fff) +# define QUIET_NAN ((TItype)0x8 << 108) +# define FRACHIGH ((TItype)0x8 << 124) +# define FRACHIGH2 ((TItype)0xc << 124) +# define FRACBITS 112 +# endif + +# define pack_d __pack_t +# define unpack_d __unpack_t +# define __fpcmp_parts __fpcmp_parts_t + typedef UTItype fractype; + typedef UDItype halffractype; + typedef USItype qrtrfractype; +#define qrtrfractype qrtrfractype + typedef TFtype FLO_type; + typedef TItype intfrac; +#elif defined FLOAT # define NGARDS 7L # define GARDROUND 0x3f # define GARDMASK 0x7f @@ -157,7 +207,9 @@ typedef unsigned int UDItype __attribute #endif /* FLOAT */ #ifdef US_SOFTWARE_GOFAST -# ifdef FLOAT +# ifdef TFLOAT +# error "GOFAST TFmode not supported" +# elif defined FLOAT # define add fpadd # define sub fpsub # define multiply fpmul @@ -170,8 +222,8 @@ typedef unsigned int UDItype __attribute # define float_to_usi fptoui # define negate __negsf2 # define sf_to_df fptodp -# define dptofp dptofp -#else +# define sf_to_tf __extendsftf2 +# else # define add dpadd # define sub dpsub # define multiply dpmul @@ -184,9 +236,30 @@ typedef unsigned int UDItype __attribute # define float_to_usi dptoul # define negate __negdf2 # define df_to_sf dptofp +# define df_to_tf __extenddftf2 # endif /* FLOAT */ #else -# ifdef FLOAT +# ifdef TFLOAT +# define add __addtf3 +# define sub __subtf3 +# define multiply __multf3 +# define divide __divtf3 +# define compare __cmptf2 +# define _eq_f2 __eqtf2 +# define _ne_f2 __netf2 +# define _gt_f2 __gttf2 +# define _ge_f2 __getf2 +# define _lt_f2 __lttf2 +# define _le_f2 __letf2 +# define _unord_f2 __unordtf2 +# define usi_to_float __floatunsitf +# define si_to_float __floatsitf +# define float_to_si __fixtfsi +# define float_to_usi __fixunstfsi +# define negate __negtf2 +# define tf_to_sf __trunctfsf2 +# define tf_to_df __trunctfdf2 +# elif defined FLOAT # define add __addsf3 # define sub __subsf3 # define multiply __mulsf3 @@ -205,7 +278,8 @@ typedef unsigned int UDItype __attribute # define float_to_usi __fixunssfsi # define negate __negsf2 # define sf_to_df __extendsfdf2 -#else +# define sf_to_tf __extendsftf2 +# else # define add __adddf3 # define sub __subdf3 # define multiply __muldf3 @@ -224,6 +298,7 @@ typedef unsigned int UDItype __attribute # define float_to_usi __fixunsdfsi # define negate __negdf2 # define df_to_sf __truncdfsf2 +# define df_to_tf __extenddftf2 # endif /* FLOAT */ #endif /* US_SOFTWARE_GOFAST */ @@ -241,10 +316,15 @@ typedef unsigned int UDItype __attribute */ #define F_D_BITOFF (52+8-(23+7)) +#ifdef TMODES +# define F_T_BITOFF (__LDBL_MANT_DIG__-1+10-(23+7)) +# define D_T_BITOFF (__LDBL_MANT_DIG__-1+10-(52+8)) +#endif + #define NORMAL_EXPMIN (-(EXPBIAS)+1) -#define IMPLICIT_1 (1LL<<(FRACBITS+NGARDS)) -#define IMPLICIT_2 (1LL<<(FRACBITS+1+NGARDS)) +#define IMPLICIT_1 ((fractype)1<<(FRACBITS+NGARDS)) +#define IMPLICIT_2 ((fractype)1<<(FRACBITS+1+NGARDS)) /* common types */ @@ -282,7 +362,11 @@ typedef union fractype value_raw; #ifndef FLOAT +# ifdef qrtrfractype + qrtrfractype qwords[4]; +# else halffractype words[2]; +# endif #endif #ifdef FLOAT_BIT_ORDER_MISMATCH @@ -317,82 +401,82 @@ FLO_union_type; /* Prototypes */ -#if defined(L_pack_df) || defined(L_pack_sf) +#if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf) extern FLO_type pack_d (fp_number_type *); #endif extern void unpack_d (FLO_union_type *, fp_number_type *); -#if defined(L_addsub_sf) || defined(L_addsub_df) +#if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf) extern FLO_type add (FLO_type, FLO_type); extern FLO_type sub (FLO_type, FLO_type); #endif -#if defined(L_mul_sf) || defined(L_mul_df) +#if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf) extern FLO_type multiply (FLO_type, FLO_type); #endif -#if defined(L_div_sf) || defined(L_div_df) +#if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf) extern FLO_type divide (FLO_type, FLO_type); #endif extern int __fpcmp_parts (fp_number_type *, fp_number_type *); -#if defined(L_compare_sf) || defined(L_compare_df) +#if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compare_tf) extern CMPtype compare (FLO_type, FLO_type); #endif #ifndef US_SOFTWARE_GOFAST -#if defined(L_eq_sf) || defined(L_eq_df) +#if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf) extern CMPtype _eq_f2 (FLO_type, FLO_type); #endif -#if defined(L_ne_sf) || defined(L_ne_df) +#if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf) extern CMPtype _ne_f2 (FLO_type, FLO_type); #endif -#if defined(L_gt_sf) || defined(L_gt_df) +#if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf) extern CMPtype _gt_f2 (FLO_type, FLO_type); #endif -#if defined(L_ge_sf) || defined(L_ge_df) +#if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf) extern CMPtype _ge_f2 (FLO_type, FLO_type); #endif -#if defined(L_lt_sf) || defined(L_lt_df) +#if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf) extern CMPtype _lt_f2 (FLO_type, FLO_type); #endif -#if defined(L_le_sf) || defined(L_le_df) +#if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf) extern CMPtype _le_f2 (FLO_type, FLO_type); #endif -#if defined(L_unord_sf) || defined(L_unord_df) +#if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf) extern CMPtype _unord_f2 (FLO_type, FLO_type); #endif #endif /* ! US_SOFTWARE_GOFAST */ -#if defined(L_si_to_sf) || defined(L_si_to_df) +#if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf) extern FLO_type si_to_float (SItype); #endif -#if defined(L_sf_to_si) || defined(L_df_to_si) +#if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si) extern SItype float_to_si (FLO_type); #endif -#if defined(L_sf_to_usi) || defined(L_df_to_usi) +#if defined(L_sf_to_usi) || defined(L_df_to_usi) || defined(L_tf_to_usi) #ifdef US_SOFTWARE_GOFAST extern USItype float_to_usi (FLO_type); #endif #endif -#if defined(L_usi_to_sf) || defined(L_usi_to_df) +#if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf) extern FLO_type usi_to_float (USItype); #endif -#if defined(L_negate_sf) || defined(L_negate_df) +#if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf) extern FLO_type negate (FLO_type); #endif @@ -405,6 +489,9 @@ extern DFtype __make_dp (fp_class_type, #if defined(L_sf_to_df) extern DFtype sf_to_df (SFtype); #endif +#if defined(L_sf_to_tf) && defined(TMODES) +extern TFtype sf_to_tf (SFtype); +#endif #endif /* ! FLOAT_ONLY */ #endif /* FLOAT */ @@ -416,6 +503,24 @@ extern DFtype __make_dp (fp_class_type, #if defined(L_df_to_sf) extern SFtype df_to_sf (DFtype); #endif +#if defined(L_df_to_tf) && defined(TMODES) +extern TFtype df_to_tf (DFtype); +#endif #endif /* ! FLOAT */ + +#ifdef TMODES +extern TFtype __make_tp (fp_class_type, unsigned int, int, UTItype); +#ifdef TFLOAT +#if defined(L_tf_to_sf) +extern SFtype tf_to_sf (TFtype); +#endif +#if defined(L_tf_to_df) +extern DFtype tf_to_df (TFtype); +#endif +#if defined(L_di_to_tf) +extern TFtype di_to_df (DItype); +#endif +#endif /* TFLOAT */ +#endif /* TMODES */ #endif /* ! GCC_FP_BIT_H */ [-- Attachment #3: Type: text/plain, Size: 289 bytes --] -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2002-12-23 9:46 ` Alexandre Oliva 2002-12-24 11:07 ` Kaveh R. Ghazi @ 2002-12-24 18:15 ` Kaveh R. Ghazi 2003-01-07 22:16 ` Richard Henderson 2003-01-07 22:40 ` Richard Henderson 2 siblings, 1 reply; 72+ messages in thread From: Kaveh R. Ghazi @ 2002-12-24 18:15 UTC (permalink / raw) To: aoliva; +Cc: gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro > Also the original test 27_io/ostream_inserter_arith still fails. > However it looks as if it's in a different place, I'll check further > and provide details. Scratch that, I think 27_io/ostream_inserter_arith is failing in the same place. On another issue, I'm also getting this new failure: > FAIL: 18_support/numeric_limits.cc execution test This one is dying in the test: > test_denorm_min<long double>(); I think the value tested here is mistakenly indistinguishable from zero. --Kaveh -- Kaveh R. Ghazi ghazi@caip.rutgers.edu ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2002-12-24 18:15 ` Kaveh R. Ghazi @ 2003-01-07 22:16 ` Richard Henderson 0 siblings, 0 replies; 72+ messages in thread From: Richard Henderson @ 2003-01-07 22:16 UTC (permalink / raw) To: Kaveh R. Ghazi; +Cc: aoliva, gcc-bugs, gcc-patches, gcc, libstdc++, oldham, ro On Tue, Dec 24, 2002 at 02:07:19PM -0500, Kaveh R. Ghazi wrote: > > test_denorm_min<long double>(); > > I think the value tested here is mistakenly indistinguishable from > zero. Correct. The double-double format doesn't support denormals in an LIA-1 conformant way. r~ ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2002-12-23 9:46 ` Alexandre Oliva 2002-12-24 11:07 ` Kaveh R. Ghazi 2002-12-24 18:15 ` Kaveh R. Ghazi @ 2003-01-07 22:40 ` Richard Henderson 2003-01-08 18:04 ` Alexandre Oliva 2 siblings, 1 reply; 72+ messages in thread From: Richard Henderson @ 2003-01-07 22:40 UTC (permalink / raw) To: Alexandre Oliva Cc: Kaveh R. Ghazi, gcc-patches, gcc-bugs, gcc, libstdc++, oldham, ro On Mon, Dec 23, 2002 at 02:12:55PM -0200, Alexandre Oliva wrote: > > ? gcc/config/mips/_tilib.c Why don't these routines come from libgcc2.c? r~ ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-07 22:40 ` Richard Henderson @ 2003-01-08 18:04 ` Alexandre Oliva 2003-01-08 22:29 ` Richard Henderson 0 siblings, 1 reply; 72+ messages in thread From: Alexandre Oliva @ 2003-01-08 18:04 UTC (permalink / raw) To: Richard Henderson Cc: Kaveh R. Ghazi, gcc-patches, gcc-bugs, gcc, libstdc++, oldham, ro On Jan 7, 2003, Richard Henderson <rth@redhat.com> wrote: > On Mon, Dec 23, 2002 at 02:12:55PM -0200, Alexandre Oliva wrote: >> > ? gcc/config/mips/_tilib.c > Why don't these routines come from libgcc2.c? I didn't feel like implementing all of TImode emulation in libgcc. We don't fully support TImode, only as little as needed to get the TFmode emulation to compile. It could be folded into libgcc2, for sure. Should it? -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-08 18:04 ` Alexandre Oliva @ 2003-01-08 22:29 ` Richard Henderson 2003-01-08 22:46 ` Zack Weinberg 2003-01-09 7:27 ` Alexandre Oliva 0 siblings, 2 replies; 72+ messages in thread From: Richard Henderson @ 2003-01-08 22:29 UTC (permalink / raw) To: Alexandre Oliva Cc: Kaveh R. Ghazi, gcc-patches, gcc-bugs, gcc, libstdc++, oldham, ro On Wed, Jan 08, 2003 at 03:12:52PM -0200, Alexandre Oliva wrote: > I didn't feel like implementing all of TImode emulation in libgcc. We > don't fully support TImode, only as little as needed to get the TFmode > emulation to compile. It could be folded into libgcc2, for sure. > Should it? Ug. No. I didn't realize this was TImode support for 32-bit. Ideally you wouldn't need TImode at all. I realize it probably made things easier with the existing fp-bit.c. Blah. I suggest that these routines _not_ be exported from libgcc.so. They only exist to support the TFmode bits. r~ ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-08 22:29 ` Richard Henderson @ 2003-01-08 22:46 ` Zack Weinberg 2003-01-08 23:13 ` Richard Henderson 2003-01-09 7:27 ` Alexandre Oliva 1 sibling, 1 reply; 72+ messages in thread From: Zack Weinberg @ 2003-01-08 22:46 UTC (permalink / raw) To: Richard Henderson Cc: Alexandre Oliva, Kaveh R. Ghazi, gcc-patches, gcc-bugs, gcc, libstdc++, oldham, ro Richard Henderson <rth@redhat.com> writes: > Ideally you wouldn't need TImode at all. I realize it probably > made things easier with the existing fp-bit.c. Maybe this is a good excuse to dust off Teje's ieeelib.c? zw ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-08 22:46 ` Zack Weinberg @ 2003-01-08 23:13 ` Richard Henderson 0 siblings, 0 replies; 72+ messages in thread From: Richard Henderson @ 2003-01-08 23:13 UTC (permalink / raw) To: Zack Weinberg Cc: Alexandre Oliva, Kaveh R. Ghazi, gcc-patches, gcc-bugs, gcc, libstdc++, oldham, ro On Wed, Jan 08, 2003 at 02:18:50PM -0800, Zack Weinberg wrote: > Maybe this is a good excuse to dust off Teje's ieeelib.c? Either that or copy the code from glibc that Jakub and I worked on. r~ ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) 2003-01-08 22:29 ` Richard Henderson 2003-01-08 22:46 ` Zack Weinberg @ 2003-01-09 7:27 ` Alexandre Oliva 1 sibling, 0 replies; 72+ messages in thread From: Alexandre Oliva @ 2003-01-09 7:27 UTC (permalink / raw) To: Richard Henderson Cc: Kaveh R. Ghazi, gcc-patches, gcc-bugs, gcc, libstdc++, oldham, ro On Jan 8, 2003, Richard Henderson <rth@redhat.com> wrote: > I suggest that these routines _not_ be exported from libgcc.so. > They only exist to support the TFmode bits. Right. I thought the default was to not export. Isn't it? -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 72+ messages in thread
* RE: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) @ 2002-12-17 0:18 Billinghurst, David (CRTS) 0 siblings, 0 replies; 72+ messages in thread From: Billinghurst, David (CRTS) @ 2002-12-17 0:18 UTC (permalink / raw) To: Kaveh R. Ghazi, aoliva; +Cc: gcc, libstdc++ I'd prefer that it was correct, even if this means breaking the gcc ABI. -----Original Message----- From: Kaveh R. Ghazi [mailto:ghazi@caip.rutgers.edu] Sent: Tuesday, 17 December 2002 4:32 PM To: aoliva@redhat.com Cc: gcc-bugs@gcc.gnu.org; gcc@gcc.gnu.org; libstdc++@gcc.gnu.org; oldham@codesourcery.com; ro@TechFak.Uni-Bielefeld.DE Subject: Re: Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) > From: Alexandre Oliva <aoliva@redhat.com> > > On Dec 14, 2002, "Kaveh R. Ghazi" <ghazi@caip.rutgers.edu> wrote: > > > Does anyone have any thoughts on this? (Or better yet a fix?) > > I've been working on a patch that will enable us to switch to 128-bit > long doubles on mips n32 and n64, but I still need a little bit of > polishing and checking (I know that my current patch still doesn't > pass long double arguments in the right registers). I expect to have > it finished in the next few days. Excellent! Let me know if I can be of service testing your patch. > That said, I'm not sure it would be wise to break the gcc ABI on IRIX > 6 by introducing this change. It's not like long double is the most > widely used type, but still, I'm a bit concerned about changing it. > Opinions? Considering the current irix libc incompatibility, one cannot currently input or output long doubles using stdio. What good is that? :-) I definitely support fixing the ABI, perhaps even on the 3.3 branch if the patch is not too invasive. Thanks, --Kaveh -- Kaveh R. Ghazi ghazi@caip.rutgers.edu ^ permalink raw reply [flat|nested] 72+ messages in thread
end of thread, other threads:[~2003-02-03 16:37 UTC | newest] Thread overview: 72+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2002-12-14 14:09 Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) Kaveh R. Ghazi 2002-12-16 9:24 ` Rainer Orth 2002-12-16 9:51 ` Alexandre Oliva 2002-12-16 9:52 ` Rainer Orth 2002-12-16 12:23 ` Eric Christopher 2002-12-16 21:58 ` Kaveh R. Ghazi 2002-12-21 10:45 ` Alexandre Oliva 2002-12-22 6:02 ` Kaveh R. Ghazi 2002-12-22 10:24 ` Alexandre Oliva 2002-12-22 10:35 ` Alexandre Oliva 2002-12-23 9:46 ` Alexandre Oliva 2002-12-24 11:07 ` Kaveh R. Ghazi 2002-12-25 8:04 ` Alexandre Oliva 2002-12-26 13:48 ` Alexandre Oliva 2002-12-27 7:06 ` Alexandre Oliva 2002-12-29 0:22 ` Kaveh R. Ghazi 2002-12-29 6:06 ` Alexandre Oliva 2003-01-07 22:57 ` Richard Henderson 2003-01-08 18:16 ` Alexandre Oliva 2003-01-08 22:19 ` Richard Henderson 2003-01-09 9:29 ` Alexandre Oliva 2003-01-09 9:38 ` Alexandre Oliva 2003-01-10 1:18 ` Alexandre Oliva 2003-01-10 2:29 ` Richard Henderson 2003-01-19 21:02 ` Kaveh R. Ghazi 2003-01-19 22:15 ` Alexandre Oliva 2003-01-26 13:00 ` Alexandre Oliva 2003-01-28 17:32 ` Alexandre Oliva 2003-01-28 23:38 ` Alexandre Oliva 2003-01-26 15:20 ` Alexandre Oliva 2003-01-26 16:14 ` Alexandre Oliva 2003-01-26 18:40 ` Kaveh R. Ghazi 2003-01-26 21:24 ` Kaveh R. Ghazi 2003-01-26 21:25 ` Alexandre Oliva 2003-01-27 9:17 ` Kaveh R. Ghazi 2003-01-27 10:40 ` Alexandre Oliva 2003-01-28 4:52 ` Kaveh R. Ghazi 2003-01-28 17:31 ` Alexandre Oliva 2003-01-28 19:11 ` Kaveh R. Ghazi 2003-01-28 19:23 ` Kaveh R. Ghazi 2003-01-28 19:47 ` Rainer Orth [not found] ` <15926.49701.3! 59482.666471@xayide.TechFak.Uni-Bielefeld.DE> 2003-01-29 6:56 ` Kaveh R. Ghazi 2003-01-29 10:07 ` Richard Henderson 2003-01-29 13:39 ` Alexandre Oliva 2003-01-29 17:26 ` Kaveh R. Ghazi 2003-01-29 18:10 ` Richard Henderson 2003-01-30 23:31 ` Irix6 native long double libcalls progress report (and problem) Kaveh R. Ghazi 2003-01-30 23:49 ` Richard Henderson 2003-02-03 13:22 ` Alexandre Oliva 2003-01-30 8:05 ` Irix6 long doubles implemented wrong? (27_io/ostream_inserter_arith) Kaveh R. Ghazi 2003-02-03 13:07 ` Alexandre Oliva 2003-02-03 15:18 ` Kaveh R. Ghazi 2003-02-03 16:37 ` Alexandre Oliva 2003-01-27 10:41 ` Alexandre Oliva 2003-01-26 21:54 ` Richard Henderson 2003-01-10 1:37 ` Alexandre Oliva 2003-01-26 10:07 ` Alexandre Oliva 2003-01-26 10:42 ` Alexandre Oliva 2003-01-26 10:45 ` Alexandre Oliva 2003-01-26 10:53 ` Alexandre Oliva 2003-01-26 12:07 ` Alexandre Oliva 2003-01-26 12:20 ` Alexandre Oliva 2003-01-26 12:50 ` Alexandre Oliva 2002-12-24 18:15 ` Kaveh R. Ghazi 2003-01-07 22:16 ` Richard Henderson 2003-01-07 22:40 ` Richard Henderson 2003-01-08 18:04 ` Alexandre Oliva 2003-01-08 22:29 ` Richard Henderson 2003-01-08 22:46 ` Zack Weinberg 2003-01-08 23:13 ` Richard Henderson 2003-01-09 7:27 ` Alexandre Oliva 2002-12-17 0:18 Billinghurst, David (CRTS)
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).