|
@@ -0,0 +1,8753 @@
|
|
|
+diff -Naur gcc-4.0-20050319.orig/config.guess gcc-4.0-20050319-src/config.guess
|
|
|
+--- gcc-4.0-20050319.orig/config.guess Tue Nov 16 01:57:00 2004
|
|
|
++++ gcc-4.0-20050319-src/config.guess Wed Mar 23 01:21:00 2005
|
|
|
+@@ -784,7 +784,7 @@
|
|
|
+ echo ${UNAME_MACHINE}-pc-cygwin
|
|
|
+ exit 0 ;;
|
|
|
+ i*:MINGW*:*)
|
|
|
+- echo ${UNAME_MACHINE}-pc-mingw32
|
|
|
++ echo i386-pc-mingw32
|
|
|
+ exit 0 ;;
|
|
|
+ i*:PW*:*)
|
|
|
+ echo ${UNAME_MACHINE}-pc-pw32
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/attribs.c gcc-4.0-20050319-src/gcc/attribs.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/attribs.c Thu Dec 9 23:55:40 2004
|
|
|
++++ gcc-4.0-20050319-src/gcc/attribs.c Wed Mar 23 01:21:00 2005
|
|
|
+@@ -131,7 +131,11 @@
|
|
|
+ information, in the form of a bitwise OR of flags in enum attribute_flags
|
|
|
+ from tree.h. Depending on these flags, some attributes may be
|
|
|
+ returned to be applied at a later stage (for example, to apply
|
|
|
+- a decl attribute to the declaration rather than to its type). */
|
|
|
++ a decl attribute to the declaration rather than to its type). If
|
|
|
++ ATTR_FLAG_BUILT_IN is not set and *NODE is a DECL, then also consider
|
|
|
++ whether there might be some default attributes to apply to this DECL;
|
|
|
++ if so, decl_attributes will be called recursively with those attributes
|
|
|
++ and ATTR_FLAG_BUILT_IN set. */
|
|
|
+
|
|
|
+ tree
|
|
|
+ decl_attributes (tree *node, tree attributes, int flags)
|
|
|
+@@ -143,6 +147,10 @@
|
|
|
+ init_attributes ();
|
|
|
+
|
|
|
+ targetm.insert_attributes (*node, &attributes);
|
|
|
++
|
|
|
++ if (DECL_P (*node) && TREE_CODE (*node) == FUNCTION_DECL
|
|
|
++ && !(flags & (int) ATTR_FLAG_BUILT_IN))
|
|
|
++ (*lang_hooks.insert_default_attributes) (*node);
|
|
|
+
|
|
|
+ for (a = attributes; a; a = TREE_CHAIN (a))
|
|
|
+ {
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/builtin-attrs.def gcc-4.0-20050319-src/gcc/builtin-attrs.def
|
|
|
+--- gcc-4.0-20050319.orig/gcc/builtin-attrs.def Fri Oct 15 17:47:06 2004
|
|
|
++++ gcc-4.0-20050319-src/gcc/builtin-attrs.def Wed Mar 23 01:21:00 2005
|
|
|
+@@ -55,6 +55,7 @@
|
|
|
+ DEF_ATTR_FOR_INT (2)
|
|
|
+ DEF_ATTR_FOR_INT (3)
|
|
|
+ DEF_ATTR_FOR_INT (4)
|
|
|
++DEF_ATTR_FOR_INT (5)
|
|
|
+ #undef DEF_ATTR_FOR_INT
|
|
|
+
|
|
|
+ /* Construct a tree for a list of two integers. */
|
|
|
+@@ -67,6 +68,8 @@
|
|
|
+ DEF_LIST_INT_INT (2,3)
|
|
|
+ DEF_LIST_INT_INT (3,0)
|
|
|
+ DEF_LIST_INT_INT (3,4)
|
|
|
++DEF_LIST_INT_INT (4,0)
|
|
|
++DEF_LIST_INT_INT (4,5)
|
|
|
+ #undef DEF_LIST_INT_INT
|
|
|
+
|
|
|
+ /* Construct trees for identifiers. */
|
|
|
+@@ -117,6 +120,8 @@
|
|
|
+ ATTR_NOTHROW_LIST)
|
|
|
+ DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_3, ATTR_NONNULL, ATTR_LIST_3, \
|
|
|
+ ATTR_NOTHROW_LIST)
|
|
|
++DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_4, ATTR_NONNULL, ATTR_LIST_4, \
|
|
|
++ ATTR_NOTHROW_LIST)
|
|
|
+ /* Nothrow functions whose first and second parameters are nonnull pointers. */
|
|
|
+ DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_1_2, ATTR_NONNULL, ATTR_LIST_2, \
|
|
|
+ ATTR_NOTHROW_NONNULL_1)
|
|
|
+@@ -152,6 +157,10 @@
|
|
|
+ DEF_FORMAT_ATTRIBUTE(SCANF,1,1_2)
|
|
|
+ DEF_FORMAT_ATTRIBUTE(SCANF,2,2_0)
|
|
|
+ DEF_FORMAT_ATTRIBUTE(SCANF,2,2_3)
|
|
|
++DEF_FORMAT_ATTRIBUTE(SCANF,3,3_0)
|
|
|
++DEF_FORMAT_ATTRIBUTE(SCANF,3,3_4)
|
|
|
++DEF_FORMAT_ATTRIBUTE(SCANF,4,4_0)
|
|
|
++DEF_FORMAT_ATTRIBUTE(SCANF,4,4_5)
|
|
|
+ DEF_FORMAT_ATTRIBUTE(STRFTIME,3,3_0)
|
|
|
+ DEF_FORMAT_ATTRIBUTE(STRFMON,3,3_4)
|
|
|
+ #undef DEF_FORMAT_ATTRIBUTE
|
|
|
+@@ -163,4 +172,26 @@
|
|
|
+ DEF_FORMAT_ARG_ATTRIBUTE(1)
|
|
|
+ DEF_FORMAT_ARG_ATTRIBUTE(2)
|
|
|
+ #undef DEF_FORMAT_ARG_ATTRIBUTE
|
|
|
++
|
|
|
++/* (TIGCC 20040219, 20050205) Default attributes. */
|
|
|
++#define DEF_FN_ATTR_IDENT(NAME, ATTRS, PREDICATE) \
|
|
|
++ DEF_ATTR_IDENT (ATTR_ ## NAME, #NAME) \
|
|
|
++ DEF_FN_ATTR (ATTR_ ## NAME, ATTRS, PREDICATE)
|
|
|
++#define DEF_C89_ATTR(NAME, ATTRS) DEF_FN_ATTR_IDENT (NAME, ATTRS, flag_hosted)
|
|
|
++DEF_C89_ATTR (printf, ATTR_FORMAT_PRINTF_1_2)
|
|
|
++DEF_C89_ATTR (fprintf, ATTR_FORMAT_PRINTF_2_3)
|
|
|
++DEF_C89_ATTR (sprintf, ATTR_FORMAT_PRINTF_2_3)
|
|
|
++DEF_C89_ATTR (scanf, ATTR_FORMAT_SCANF_1_2)
|
|
|
++DEF_C89_ATTR (fscanf, ATTR_FORMAT_SCANF_2_3)
|
|
|
++DEF_C89_ATTR (sscanf, ATTR_FORMAT_SCANF_2_3)
|
|
|
++DEF_C89_ATTR (vprintf, ATTR_FORMAT_PRINTF_1_0)
|
|
|
++DEF_C89_ATTR (vfprintf, ATTR_FORMAT_PRINTF_2_0)
|
|
|
++DEF_C89_ATTR (vsprintf, ATTR_FORMAT_PRINTF_2_0)
|
|
|
++DEF_C89_ATTR (vcbprintf, ATTR_FORMAT_PRINTF_3_0)
|
|
|
++DEF_C89_ATTR (cbprintf, ATTR_FORMAT_PRINTF_3_4)
|
|
|
++DEF_C89_ATTR (vcbscanf, ATTR_FORMAT_SCANF_4_0)
|
|
|
++DEF_C89_ATTR (cbscanf, ATTR_FORMAT_SCANF_4_5)
|
|
|
++DEF_C89_ATTR (vscanf, ATTR_FORMAT_SCANF_1_0)
|
|
|
++DEF_C89_ATTR (vfscanf, ATTR_FORMAT_SCANF_2_0)
|
|
|
++DEF_C89_ATTR (vsscanf, ATTR_FORMAT_SCANF_2_0)
|
|
|
+
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/builtins.c gcc-4.0-20050319-src/gcc/builtins.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/builtins.c Thu Feb 24 21:00:04 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/builtins.c Wed Mar 23 01:21:00 2005
|
|
|
+@@ -47,6 +47,7 @@
|
|
|
+ #include "langhooks.h"
|
|
|
+ #include "basic-block.h"
|
|
|
+ #include "tree-mudflap.h"
|
|
|
++#include "ggc.h"
|
|
|
+
|
|
|
+ #define CALLED_AS_BUILT_IN(NODE) \
|
|
|
+ (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10))
|
|
|
+@@ -79,7 +80,9 @@
|
|
|
+ static rtx c_readstr (const char *, enum machine_mode);
|
|
|
+ static int target_char_cast (tree, char *);
|
|
|
+ static rtx get_memory_rtx (tree);
|
|
|
++#if 0
|
|
|
+ static tree build_string_literal (int, const char *);
|
|
|
++#endif /* 0 */
|
|
|
+ static int apply_args_size (void);
|
|
|
+ static int apply_result_size (void);
|
|
|
+ #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
|
|
|
+@@ -94,24 +97,31 @@
|
|
|
+ static void expand_builtin_return (rtx);
|
|
|
+ static enum type_class type_to_class (tree);
|
|
|
+ static rtx expand_builtin_classify_type (tree);
|
|
|
++#if 0
|
|
|
+ static void expand_errno_check (tree, rtx);
|
|
|
+ static rtx expand_builtin_mathfn (tree, rtx, rtx);
|
|
|
+ static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
|
|
|
+ static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
|
|
|
++#endif /* 0 */
|
|
|
+ static rtx expand_builtin_args_info (tree);
|
|
|
+ static rtx expand_builtin_next_arg (void);
|
|
|
+ static rtx expand_builtin_va_start (tree);
|
|
|
+ static rtx expand_builtin_va_end (tree);
|
|
|
+ static rtx expand_builtin_va_copy (tree);
|
|
|
++#if 0
|
|
|
+ static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
|
|
|
+ static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
|
|
|
+ static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
|
|
|
++#endif /* 0 */
|
|
|
+ static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
|
|
|
++#if 0
|
|
|
+ static rtx expand_builtin_strcat (tree, tree, rtx, enum machine_mode);
|
|
|
+ static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
|
|
|
+ static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
|
|
|
+ static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
|
|
|
++#endif /* 0 */
|
|
|
+ static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
|
|
|
++#if 0
|
|
|
+ static rtx expand_builtin_mempcpy (tree, tree, rtx, enum machine_mode, int);
|
|
|
+ static rtx expand_builtin_memmove (tree, tree, rtx, enum machine_mode);
|
|
|
+ static rtx expand_builtin_bcopy (tree, tree);
|
|
|
+@@ -119,33 +129,43 @@
|
|
|
+ static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
|
|
|
+ static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
|
|
|
+ static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
|
|
|
++#endif /* 0 */
|
|
|
+ static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
|
|
|
+ static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
|
|
|
+ static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
|
|
|
++#if 0
|
|
|
+ static rtx expand_builtin_bzero (tree);
|
|
|
+ static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
|
|
|
+ static rtx expand_builtin_strstr (tree, tree, rtx, enum machine_mode);
|
|
|
+ static rtx expand_builtin_strpbrk (tree, tree, rtx, enum machine_mode);
|
|
|
+ static rtx expand_builtin_strchr (tree, tree, rtx, enum machine_mode);
|
|
|
+ static rtx expand_builtin_strrchr (tree, tree, rtx, enum machine_mode);
|
|
|
++#endif /* 0 */
|
|
|
+ static rtx expand_builtin_alloca (tree, rtx);
|
|
|
+ static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
|
|
|
+ static rtx expand_builtin_frame_address (tree, tree);
|
|
|
++#if 0
|
|
|
+ static rtx expand_builtin_fputs (tree, rtx, bool);
|
|
|
+ static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
|
|
|
+ static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
|
|
|
+ static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
|
|
|
++#endif /* 0 */
|
|
|
+ static tree stabilize_va_list (tree, int);
|
|
|
+ static rtx expand_builtin_expect (tree, rtx);
|
|
|
+ static tree fold_builtin_constant_p (tree);
|
|
|
+ static tree fold_builtin_classify_type (tree);
|
|
|
++#if 0
|
|
|
+ static tree fold_builtin_strlen (tree);
|
|
|
+ static tree fold_builtin_inf (tree, int);
|
|
|
+ static tree fold_builtin_nan (tree, tree, int);
|
|
|
++#endif /* 0 */
|
|
|
+ static int validate_arglist (tree, ...);
|
|
|
++#if 0
|
|
|
+ static bool integer_valued_real_p (tree);
|
|
|
+ static tree fold_trunc_transparent_mathfn (tree);
|
|
|
++#endif /* 0 */
|
|
|
+ static bool readonly_data_expr (tree);
|
|
|
++#if 0
|
|
|
+ static rtx expand_builtin_fabs (tree, rtx, rtx);
|
|
|
+ static rtx expand_builtin_signbit (tree, rtx);
|
|
|
+ static tree fold_builtin_cabs (tree, tree);
|
|
|
+@@ -162,7 +182,9 @@
|
|
|
+ static tree fold_builtin_ceil (tree);
|
|
|
+ static tree fold_builtin_round (tree);
|
|
|
+ static tree fold_builtin_bitop (tree);
|
|
|
++#endif /* 0 */
|
|
|
+ static tree fold_builtin_memcpy (tree);
|
|
|
++#if 0
|
|
|
+ static tree fold_builtin_mempcpy (tree, tree, int);
|
|
|
+ static tree fold_builtin_memmove (tree, tree);
|
|
|
+ static tree fold_builtin_strchr (tree, tree);
|
|
|
+@@ -177,8 +199,10 @@
|
|
|
+ static tree fold_builtin_fabs (tree, tree);
|
|
|
+ static tree fold_builtin_abs (tree, tree);
|
|
|
+ static tree fold_builtin_unordered_cmp (tree, enum tree_code, enum tree_code);
|
|
|
++#endif /* 0 */
|
|
|
+ static tree fold_builtin_1 (tree, bool);
|
|
|
+
|
|
|
++#if 0
|
|
|
+ static tree fold_builtin_strpbrk (tree, tree);
|
|
|
+ static tree fold_builtin_strstr (tree, tree);
|
|
|
+ static tree fold_builtin_strrchr (tree, tree);
|
|
|
+@@ -187,7 +211,10 @@
|
|
|
+ static tree fold_builtin_strspn (tree);
|
|
|
+ static tree fold_builtin_strcspn (tree);
|
|
|
+ static tree fold_builtin_sprintf (tree, int);
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
++/* (TIGCC 20050206) Implement ER_throw. */
|
|
|
++static void expand_builtin_ER_throw (tree);
|
|
|
+
|
|
|
+ /* Return the alignment in bits of EXP, a pointer valued expression.
|
|
|
+ But don't return more than MAX_ALIGN no matter what.
|
|
|
+@@ -1058,7 +1085,13 @@
|
|
|
+ size += GET_MODE_SIZE (Pmode);
|
|
|
+
|
|
|
+ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
|
|
|
+- if (FUNCTION_ARG_REGNO_P (regno))
|
|
|
++ if (0 /*FUNCTION_ARG_REGNO_P (regno)*/)
|
|
|
++ /* (TIGCC) Do NOT use register passing for __builtin_apply since:
|
|
|
++ 1. It doesn't work: ALL registers are POSSIBLE registers for
|
|
|
++ function parameters, so this code uses up all
|
|
|
++ registers.
|
|
|
++ 2. It significantly increases code size.
|
|
|
++ 3. The default calling convention is stkparm anyway. */
|
|
|
+ {
|
|
|
+ mode = reg_raw_mode[regno];
|
|
|
+
|
|
|
+@@ -1512,6 +1545,7 @@
|
|
|
+ tree
|
|
|
+ mathfn_built_in (tree type, enum built_in_function fn)
|
|
|
+ {
|
|
|
++#if 0
|
|
|
+ enum built_in_function fcode, fcodef, fcodel;
|
|
|
+
|
|
|
+ switch (fn)
|
|
|
+@@ -1602,9 +1636,11 @@
|
|
|
+ else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
|
|
|
+ return implicit_built_in_decls[fcodel];
|
|
|
+ else
|
|
|
++#endif /* 0 */
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* If errno must be maintained, expand the RTL to check if the result,
|
|
|
+ TARGET, of a built-in function call, EXP, is NaN, and if so set
|
|
|
+ errno to EDOM. */
|
|
|
+@@ -2599,6 +2635,7 @@
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
|
|
|
+ bytes from constant string DATA + OFFSET and return it as target
|
|
|
+@@ -2690,6 +2727,7 @@
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
|
|
|
+ Return 0 if we failed the caller should emit a normal call,
|
|
|
+ otherwise try to get the result in TARGET, if convenient (and in
|
|
|
+@@ -3108,6 +3146,7 @@
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
|
|
|
+ bytes from constant string DATA + OFFSET and return it as target
|
|
|
+@@ -3255,6 +3294,7 @@
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Expand expression EXP, which is a call to the bzero builtin. Return 0
|
|
|
+ if we failed the caller should emit a normal call. */
|
|
|
+
|
|
|
+@@ -3750,6 +3790,7 @@
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Expand a call to __builtin_saveregs, generating the result in TARGET,
|
|
|
+ if that's convenient. */
|
|
|
+@@ -4302,6 +4343,7 @@
|
|
|
+ return convert_to_mode (target_mode, target, 0);
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* If the string passed to fputs is a constant and is one character
|
|
|
+ long, we attempt to transform this call into __builtin_fputc(). */
|
|
|
+
|
|
|
+@@ -4318,6 +4360,7 @@
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Expand a call to __builtin_expect. We return our argument and emit a
|
|
|
+ NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
|
|
|
+@@ -4490,6 +4533,35 @@
|
|
|
+ emit_barrier ();
|
|
|
+ }
|
|
|
+
|
|
|
++/* (TIGCC 20050206) Implement ER_throw. */
|
|
|
++static void
|
|
|
++expand_builtin_ER_throw (tree arglist)
|
|
|
++{
|
|
|
++ tree arg;
|
|
|
++ char buffer[40];
|
|
|
++
|
|
|
++ if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
|
|
|
++ {
|
|
|
++ error ("invalid argument list for ER_throw");
|
|
|
++ return;
|
|
|
++ }
|
|
|
++
|
|
|
++ arg = TREE_VALUE (arglist);
|
|
|
++
|
|
|
++ if (TREE_CODE (arg) != INTEGER_CST)
|
|
|
++ {
|
|
|
++ error ("argument to ER_throw must be a constant");
|
|
|
++ return;
|
|
|
++ }
|
|
|
++
|
|
|
++ sprintf (buffer, ".word _A_LINE+%d", (int) TREE_INT_CST_LOW (arg));
|
|
|
++
|
|
|
++ emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ggc_strdup (buffer)));
|
|
|
++
|
|
|
++ emit_barrier ();
|
|
|
++}
|
|
|
++
|
|
|
++#if 0
|
|
|
+ /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
|
|
|
+ Return 0 if a normal call should be emitted rather than expanding
|
|
|
+ the function inline. If convenient, the result should be placed
|
|
|
+@@ -4840,6 +4912,7 @@
|
|
|
+
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Expand a call to either the entry or exit function profiler. */
|
|
|
+
|
|
|
+@@ -4944,6 +5017,7 @@
|
|
|
+ return tramp;
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Expand a call to the built-in signbit, signbitf or signbitl function.
|
|
|
+ Return NULL_RTX if a normal call should be emitted rather than expanding
|
|
|
+ the function in-line. EXP is the expression that is a call to the builtin
|
|
|
+@@ -5097,6 +5171,7 @@
|
|
|
+
|
|
|
+ return expand_call (call, target, ignore);
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Expand an expression EXP that calls a built-in function,
|
|
|
+ with result going to TARGET if that's convenient
|
|
|
+@@ -5156,6 +5231,7 @@
|
|
|
+
|
|
|
+ switch (fcode)
|
|
|
+ {
|
|
|
++#if 0
|
|
|
+ case BUILT_IN_FABS:
|
|
|
+ case BUILT_IN_FABSF:
|
|
|
+ case BUILT_IN_FABSL:
|
|
|
+@@ -5301,6 +5377,7 @@
|
|
|
+ if (target)
|
|
|
+ return target;
|
|
|
+ break;
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ case BUILT_IN_APPLY_ARGS:
|
|
|
+ return expand_builtin_apply_args ();
|
|
|
+@@ -5437,6 +5514,7 @@
|
|
|
+ return target;
|
|
|
+ break;
|
|
|
+
|
|
|
++#if 0
|
|
|
+ case BUILT_IN_STRLEN:
|
|
|
+ target = expand_builtin_strlen (arglist, target, target_mode);
|
|
|
+ if (target)
|
|
|
+@@ -5510,6 +5588,7 @@
|
|
|
+ if (target)
|
|
|
+ return target;
|
|
|
+ break;
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ case BUILT_IN_MEMCPY:
|
|
|
+ target = expand_builtin_memcpy (exp, target, mode);
|
|
|
+@@ -5517,6 +5596,7 @@
|
|
|
+ return target;
|
|
|
+ break;
|
|
|
+
|
|
|
++#if 0
|
|
|
+ case BUILT_IN_MEMPCPY:
|
|
|
+ target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
|
|
|
+ if (target)
|
|
|
+@@ -5534,6 +5614,7 @@
|
|
|
+ if (target)
|
|
|
+ return target;
|
|
|
+ break;
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ case BUILT_IN_MEMSET:
|
|
|
+ target = expand_builtin_memset (arglist, target, mode);
|
|
|
+@@ -5541,6 +5622,7 @@
|
|
|
+ return target;
|
|
|
+ break;
|
|
|
+
|
|
|
++#if 0
|
|
|
+ case BUILT_IN_BZERO:
|
|
|
+ target = expand_builtin_bzero (arglist);
|
|
|
+ if (target)
|
|
|
+@@ -5565,6 +5647,7 @@
|
|
|
+ if (target)
|
|
|
+ return target;
|
|
|
+ break;
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ case BUILT_IN_SETJMP:
|
|
|
+ target = expand_builtin_setjmp (arglist, target);
|
|
|
+@@ -5618,6 +5701,7 @@
|
|
|
+ expand_builtin_trap ();
|
|
|
+ return const0_rtx;
|
|
|
+
|
|
|
++#if 0
|
|
|
+ case BUILT_IN_PRINTF:
|
|
|
+ target = expand_builtin_printf (arglist, target, mode, false);
|
|
|
+ if (target)
|
|
|
+@@ -5666,6 +5750,7 @@
|
|
|
+ if (target)
|
|
|
+ return target;
|
|
|
+ break;
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Various hooks for the DWARF 2 __throw routine. */
|
|
|
+ case BUILT_IN_UNWIND_INIT:
|
|
|
+@@ -5718,6 +5803,7 @@
|
|
|
+ case BUILT_IN_ADJUST_TRAMPOLINE:
|
|
|
+ return expand_builtin_adjust_trampoline (arglist);
|
|
|
+
|
|
|
++#if 0
|
|
|
+ case BUILT_IN_FORK:
|
|
|
+ case BUILT_IN_EXECL:
|
|
|
+ case BUILT_IN_EXECV:
|
|
|
+@@ -5729,6 +5815,11 @@
|
|
|
+ if (target)
|
|
|
+ return target;
|
|
|
+ break;
|
|
|
++#endif /* 0 */
|
|
|
++
|
|
|
++ case BUILT_IN_ER_THROW:
|
|
|
++ expand_builtin_ER_throw (arglist);
|
|
|
++ return const0_rtx;
|
|
|
+
|
|
|
+ default: /* just do library call, if unknown builtin */
|
|
|
+ break;
|
|
|
+@@ -5748,6 +5839,7 @@
|
|
|
+ enum built_in_function
|
|
|
+ builtin_mathfn_code (tree t)
|
|
|
+ {
|
|
|
++#if 0
|
|
|
+ tree fndecl, arglist, parmlist;
|
|
|
+ tree argtype, parmtype;
|
|
|
+
|
|
|
+@@ -5802,13 +5894,16 @@
|
|
|
+ return END_BUILTINS;
|
|
|
+ }
|
|
|
+ else
|
|
|
++#endif /* 0 */
|
|
|
+ return END_BUILTINS;
|
|
|
++#if 0
|
|
|
+
|
|
|
+ arglist = TREE_CHAIN (arglist);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Variable-length argument list. */
|
|
|
+ return DECL_FUNCTION_CODE (fndecl);
|
|
|
++#endif /* 0 */
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
|
|
|
+@@ -5901,6 +5996,7 @@
|
|
|
+ type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Fold a call to __builtin_strlen. */
|
|
|
+
|
|
|
+ static tree
|
|
|
+@@ -6603,6 +6699,7 @@
|
|
|
+
|
|
|
+ return fold_fixed_mathfn (exp);
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Fold function call to builtin ffs, clz, ctz, popcount and parity
|
|
|
+ and their long and long long variants (i.e. ffsl and ffsll).
|
|
|
+@@ -6710,6 +6807,7 @@
|
|
|
+ return NULL_TREE;
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Return true if EXPR is the real constant contained in VALUE. */
|
|
|
+
|
|
|
+ static bool
|
|
|
+@@ -7086,6 +7184,7 @@
|
|
|
+
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Fold function call to builtin memcpy. Return
|
|
|
+ NULL_TREE if no simplification can be made. */
|
|
|
+@@ -7115,6 +7214,7 @@
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Fold function call to builtin mempcpy. Return
|
|
|
+ NULL_TREE if no simplification can be made. */
|
|
|
+
|
|
|
+@@ -7842,6 +7942,7 @@
|
|
|
+ return fold (build1 (TRUTH_NOT_EXPR, type,
|
|
|
+ fold (build2 (code, type, arg0, arg1))));
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Fold a call to one of the external complex multiply libcalls. */
|
|
|
+
|
|
|
+@@ -7900,6 +8001,7 @@
|
|
|
+ fcode = DECL_FUNCTION_CODE (fndecl);
|
|
|
+ switch (fcode)
|
|
|
+ {
|
|
|
++#if 0
|
|
|
+ case BUILT_IN_FPUTS:
|
|
|
+ return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
|
|
|
+
|
|
|
+@@ -7950,6 +8052,7 @@
|
|
|
+
|
|
|
+ case BUILT_IN_SPRINTF:
|
|
|
+ return fold_builtin_sprintf (arglist, ignore);
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ case BUILT_IN_CONSTANT_P:
|
|
|
+ {
|
|
|
+@@ -7971,6 +8074,7 @@
|
|
|
+ case BUILT_IN_CLASSIFY_TYPE:
|
|
|
+ return fold_builtin_classify_type (arglist);
|
|
|
+
|
|
|
++#if 0
|
|
|
+ case BUILT_IN_STRLEN:
|
|
|
+ return fold_builtin_strlen (arglist);
|
|
|
+
|
|
|
+@@ -8149,6 +8253,7 @@
|
|
|
+ case BUILT_IN_LLRINTF:
|
|
|
+ case BUILT_IN_LLRINTL:
|
|
|
+ return fold_fixed_mathfn (exp);
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ case BUILT_IN_FFS:
|
|
|
+ case BUILT_IN_FFSL:
|
|
|
+@@ -8170,6 +8275,7 @@
|
|
|
+ case BUILT_IN_MEMCPY:
|
|
|
+ return fold_builtin_memcpy (exp);
|
|
|
+
|
|
|
++#if 0
|
|
|
+ case BUILT_IN_MEMPCPY:
|
|
|
+ return fold_builtin_mempcpy (arglist, type, /*endp=*/1);
|
|
|
+
|
|
|
+@@ -8222,6 +8328,7 @@
|
|
|
+ return fold_builtin_unordered_cmp (exp, UNEQ_EXPR, EQ_EXPR);
|
|
|
+ case BUILT_IN_ISUNORDERED:
|
|
|
+ return fold_builtin_unordered_cmp (exp, UNORDERED_EXPR, NOP_EXPR);
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* We do the folding for va_start in the expander. */
|
|
|
+ case BUILT_IN_VA_START:
|
|
|
+@@ -8365,6 +8472,7 @@
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Simplify a call to the strstr builtin.
|
|
|
+
|
|
|
+ Return 0 if no simplification was possible, otherwise return the
|
|
|
+@@ -8895,6 +9003,7 @@
|
|
|
+ hence there's no need to cast the result to integer_type_node. */
|
|
|
+ return build_function_call_expr (fn, arglist);
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
|
|
|
+ produced. False otherwise. This is done so that we don't output the error
|
|
|
+@@ -8964,6 +9073,7 @@
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Simplify a call to the sprintf builtin.
|
|
|
+
|
|
|
+ Return 0 if no simplification was possible, otherwise return the
|
|
|
+@@ -9045,3 +9155,5 @@
|
|
|
+ else
|
|
|
+ return call;
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
++
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/builtins.def gcc-4.0-20050319-src/gcc/builtins.def
|
|
|
+--- gcc-4.0-20050319.orig/gcc/builtins.def Thu Feb 10 19:59:04 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/builtins.def Wed Mar 23 01:21:00 2005
|
|
|
+@@ -477,6 +477,7 @@
|
|
|
+ DEF_LIB_BUILTIN (BUILT_IN_STRSPN, "strspn", BT_FN_SIZE_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_1_2)
|
|
|
+ DEF_LIB_BUILTIN (BUILT_IN_STRSTR, "strstr", BT_FN_STRING_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_1_2)
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Category: stdio builtins. */
|
|
|
+ DEF_LIB_BUILTIN (BUILT_IN_FPRINTF, "fprintf", BT_FN_INT_FILEPTR_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_2_3)
|
|
|
+ DEF_EXT_LIB_BUILTIN (BUILT_IN_FPRINTF_UNLOCKED, "fprintf_unlocked", BT_FN_INT_FILEPTR_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_2_3)
|
|
|
+@@ -538,6 +539,7 @@
|
|
|
+ DEF_C94_BUILTIN (BUILT_IN_ISWXDIGIT, "iswxdigit", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LIST)
|
|
|
+ DEF_C94_BUILTIN (BUILT_IN_TOWLOWER, "towlower", BT_FN_WINT_WINT, ATTR_PURE_NOTHROW_LIST)
|
|
|
+ DEF_C94_BUILTIN (BUILT_IN_TOWUPPER, "towupper", BT_FN_WINT_WINT, ATTR_PURE_NOTHROW_LIST)
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Category: miscellaneous builtins. */
|
|
|
+ DEF_LIB_BUILTIN (BUILT_IN_ABORT, "abort", BT_FN_VOID, ATTR_NORETURN_NOTHROW_LIST)
|
|
|
+@@ -547,7 +549,9 @@
|
|
|
+ DEF_GCC_BUILTIN (BUILT_IN_APPLY, "apply", BT_FN_PTR_PTR_FN_VOID_VAR_PTR_SIZE, ATTR_NULL)
|
|
|
+ DEF_GCC_BUILTIN (BUILT_IN_APPLY_ARGS, "apply_args", BT_FN_PTR_VAR, ATTR_NULL)
|
|
|
+ DEF_GCC_BUILTIN (BUILT_IN_ARGS_INFO, "args_info", BT_FN_INT_INT, ATTR_NULL)
|
|
|
++#if 0
|
|
|
+ DEF_LIB_BUILTIN (BUILT_IN_CALLOC, "calloc", BT_FN_PTR_SIZE_SIZE, ATTR_MALLOC_NOTHROW_LIST)
|
|
|
++#endif /* 0 */
|
|
|
+ DEF_GCC_BUILTIN (BUILT_IN_CLASSIFY_TYPE, "classify_type", BT_FN_INT_VAR, ATTR_NULL)
|
|
|
+ DEF_GCC_BUILTIN (BUILT_IN_CLZ, "clz", BT_FN_INT_UINT, ATTR_CONST_NOTHROW_LIST)
|
|
|
+ DEF_GCC_BUILTIN (BUILT_IN_CLZIMAX, "clzimax", BT_FN_INT_UINTMAX, ATTR_CONST_NOTHROW_LIST)
|
|
|
+@@ -628,6 +632,9 @@
|
|
|
+ DEF_GCC_BUILTIN (BUILT_IN_VA_START, "va_start", BT_FN_VOID_VALIST_REF_VAR, ATTR_NULL)
|
|
|
+ DEF_EXT_LIB_BUILTIN (BUILT_IN__EXIT, "_exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LIST)
|
|
|
+ DEF_C99_BUILTIN (BUILT_IN__EXIT2, "_Exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LIST)
|
|
|
++
|
|
|
++/* (TIGCC 20050206) Implement ER_throw. */
|
|
|
++DEF_GCC_BUILTIN (BUILT_IN_ER_THROW, "ER_throw", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LIST)
|
|
|
+
|
|
|
+ /* Implementing nested functions. */
|
|
|
+ DEF_BUILTIN_STUB (BUILT_IN_INIT_TRAMPOLINE, "__builtin_init_trampoline")
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/c-common.c gcc-4.0-20050319-src/gcc/c-common.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/c-common.c Tue Feb 22 21:10:44 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/c-common.c Wed Mar 23 01:21:00 2005
|
|
|
+@@ -2884,16 +2884,20 @@
|
|
|
+ #define DEF_ATTR_INT(ENUM, VALUE) ENUM,
|
|
|
+ #define DEF_ATTR_IDENT(ENUM, STRING) ENUM,
|
|
|
+ #define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) ENUM,
|
|
|
++#define DEF_FN_ATTR(NAME, ATTRS, PREDICATE) /* No entry needed in enum. */
|
|
|
+ #include "builtin-attrs.def"
|
|
|
+ #undef DEF_ATTR_NULL_TREE
|
|
|
+ #undef DEF_ATTR_INT
|
|
|
+ #undef DEF_ATTR_IDENT
|
|
|
+ #undef DEF_ATTR_TREE_LIST
|
|
|
++#undef DEF_FN_ATTR
|
|
|
+ ATTR_LAST
|
|
|
+ };
|
|
|
+
|
|
|
+ static GTY(()) tree built_in_attributes[(int) ATTR_LAST];
|
|
|
+
|
|
|
++static bool c_attrs_initialized = false;
|
|
|
++
|
|
|
+ static void c_init_attributes (void);
|
|
|
+
|
|
|
+ /* Build tree nodes and builtin functions common to both C and C++ language
|
|
|
+@@ -3221,7 +3225,8 @@
|
|
|
+ #undef DEF_FUNCTION_TYPE_VAR_3
|
|
|
+ #undef DEF_POINTER_TYPE
|
|
|
+
|
|
|
+- c_init_attributes ();
|
|
|
++ if (!c_attrs_initialized)
|
|
|
++ c_init_attributes ();
|
|
|
+
|
|
|
+ #define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, FALLBACK_P, \
|
|
|
+ NONANSI_P, ATTRS, IMPLICIT, COND) \
|
|
|
+@@ -3905,11 +3910,40 @@
|
|
|
+ = tree_cons (built_in_attributes[(int) PURPOSE], \
|
|
|
+ built_in_attributes[(int) VALUE], \
|
|
|
+ built_in_attributes[(int) CHAIN]);
|
|
|
++#define DEF_FN_ATTR(NAME, ATTRS, PREDICATE) /* No initialization needed. */
|
|
|
++#include "builtin-attrs.def"
|
|
|
++#undef DEF_ATTR_NULL_TREE
|
|
|
++#undef DEF_ATTR_INT
|
|
|
++#undef DEF_ATTR_IDENT
|
|
|
++#undef DEF_ATTR_TREE_LIST
|
|
|
++#undef DEF_FN_ATTR
|
|
|
++ c_attrs_initialized = true;
|
|
|
++}
|
|
|
++
|
|
|
++/* Depending on the name of DECL, apply default attributes to it. */
|
|
|
++
|
|
|
++void
|
|
|
++c_common_insert_default_attributes (tree decl)
|
|
|
++{
|
|
|
++ tree name = DECL_NAME (decl);
|
|
|
++
|
|
|
++ if (!c_attrs_initialized)
|
|
|
++ c_init_attributes ();
|
|
|
++
|
|
|
++#define DEF_ATTR_NULL_TREE(ENUM) /* Nothing needed after initialization. */
|
|
|
++#define DEF_ATTR_INT(ENUM, VALUE)
|
|
|
++#define DEF_ATTR_IDENT(ENUM, STRING)
|
|
|
++#define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN)
|
|
|
++#define DEF_FN_ATTR(NAME, ATTRS, PREDICATE) \
|
|
|
++ if ((PREDICATE) && name == built_in_attributes[(int) NAME]) \
|
|
|
++ decl_attributes (&decl, built_in_attributes[(int) ATTRS], \
|
|
|
++ ATTR_FLAG_BUILT_IN);
|
|
|
+ #include "builtin-attrs.def"
|
|
|
+ #undef DEF_ATTR_NULL_TREE
|
|
|
+ #undef DEF_ATTR_INT
|
|
|
+ #undef DEF_ATTR_IDENT
|
|
|
+ #undef DEF_ATTR_TREE_LIST
|
|
|
++#undef DEF_FN_ATTR
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Attribute handlers common to C front ends. */
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/c-common.h gcc-4.0-20050319-src/gcc/c-common.h
|
|
|
+--- gcc-4.0-20050319.orig/gcc/c-common.h Sun Feb 20 18:01:14 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/c-common.h Wed Mar 23 01:21:00 2005
|
|
|
+@@ -631,6 +631,7 @@
|
|
|
+ extern void set_Wformat (int);
|
|
|
+ extern tree handle_format_attribute (tree *, tree, tree, int, bool *);
|
|
|
+ extern tree handle_format_arg_attribute (tree *, tree, tree, int, bool *);
|
|
|
++extern void c_common_insert_default_attributes (tree);
|
|
|
+ extern int c_common_handle_option (size_t code, const char *arg, int value);
|
|
|
+ extern bool c_common_missing_argument (const char *opt, size_t code);
|
|
|
+ extern tree c_common_type_for_mode (enum machine_mode, int);
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/c-cppbuiltin.c gcc-4.0-20050319-src/gcc/c-cppbuiltin.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/c-cppbuiltin.c Fri Jan 21 17:57:02 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/c-cppbuiltin.c Wed Mar 23 01:21:00 2005
|
|
|
+@@ -51,9 +51,11 @@
|
|
|
+ static void builtin_define_with_value_n (const char *, const char *,
|
|
|
+ size_t);
|
|
|
+ static void builtin_define_with_int_value (const char *, HOST_WIDE_INT);
|
|
|
++#if 0
|
|
|
+ static void builtin_define_with_hex_fp_value (const char *, tree,
|
|
|
+ int, const char *,
|
|
|
+ const char *);
|
|
|
++#endif /* 0 */
|
|
|
+ static void builtin_define_stdint_macros (void);
|
|
|
+ static void builtin_define_type_max (const char *, tree, int);
|
|
|
+ static void builtin_define_type_precision (const char *, tree);
|
|
|
+@@ -72,6 +74,7 @@
|
|
|
+ static void
|
|
|
+ builtin_define_float_constants (const char *name_prefix, const char *fp_suffix, tree type)
|
|
|
+ {
|
|
|
++#if 0 /* (TIGCC) Do nothing. We have our own float.h! */
|
|
|
+ /* Used to convert radix-based values to base 10 values in several cases.
|
|
|
+
|
|
|
+ In the max_exp -> max_10_exp conversion for 128-bit IEEE, we need at
|
|
|
+@@ -254,6 +257,7 @@
|
|
|
+ NaN has quiet NaNs. */
|
|
|
+ sprintf (name, "__%s_HAS_QUIET_NAN__", name_prefix);
|
|
|
+ builtin_define_with_int_value (name, MODE_HAS_NANS (TYPE_MODE (type)));
|
|
|
++#endif /* 0 */
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Define __GNUC__, __GNUC_MINOR__ and __GNUC_PATCHLEVEL__. */
|
|
|
+@@ -563,6 +567,7 @@
|
|
|
+ cpp_define (parse_in, buf);
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Pass an object-like macro a hexadecimal floating-point value. */
|
|
|
+ static void
|
|
|
+ builtin_define_with_hex_fp_value (const char *macro,
|
|
|
+@@ -588,6 +593,7 @@
|
|
|
+ sprintf (buf, "%s=%s%s", macro, dec_str, fp_suffix);
|
|
|
+ cpp_define (parse_in, buf);
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Define MAX for TYPE based on the precision of the type. IS_LONG is
|
|
|
+ 1 for type "long" and 2 for "long long". We have to handle
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/c-decl.c gcc-4.0-20050319-src/gcc/c-decl.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/c-decl.c Thu Feb 3 03:20:44 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/c-decl.c Wed Mar 23 01:21:00 2005
|
|
|
+@@ -2316,7 +2316,6 @@
|
|
|
+ void
|
|
|
+ undeclared_variable (tree id)
|
|
|
+ {
|
|
|
+- static bool already = false;
|
|
|
+ struct c_scope *scope;
|
|
|
+
|
|
|
+ if (current_function_decl == 0)
|
|
|
+@@ -2328,13 +2327,6 @@
|
|
|
+ {
|
|
|
+ error ("%qE undeclared (first use in this function)", id);
|
|
|
+
|
|
|
+- if (!already)
|
|
|
+- {
|
|
|
+- error ("(Each undeclared identifier is reported only once");
|
|
|
+- error ("for each function it appears in.)");
|
|
|
+- already = true;
|
|
|
+- }
|
|
|
+-
|
|
|
+ /* If we are parsing old-style parameter decls, current_function_decl
|
|
|
+ will be nonnull but current_function_scope will be null. */
|
|
|
+ scope = current_function_scope ? current_function_scope : current_scope;
|
|
|
+@@ -2623,7 +2615,7 @@
|
|
|
+
|
|
|
+ input_location = save_loc;
|
|
|
+
|
|
|
+- pedantic_lvalues = true;
|
|
|
++ pedantic_lvalues = pedantic;
|
|
|
+
|
|
|
+ make_fname_decl = c_make_fname_decl;
|
|
|
+ start_fname_decls ();
|
|
|
+@@ -2717,6 +2709,18 @@
|
|
|
+
|
|
|
+ return decl;
|
|
|
+ }
|
|
|
++
|
|
|
++/* Apply default attributes to a function, if a system function with default
|
|
|
++ attributes. */
|
|
|
++
|
|
|
++void
|
|
|
++c_insert_default_attributes (decl)
|
|
|
++ tree decl;
|
|
|
++{
|
|
|
++ if (!TREE_PUBLIC (decl))
|
|
|
++ return;
|
|
|
++ c_common_insert_default_attributes (decl);
|
|
|
++}
|
|
|
+
|
|
|
+ /* Called when a declaration is seen that contains no names to declare.
|
|
|
+ If its type is a reference to a structure, union or enum inherited
|
|
|
+@@ -3441,10 +3445,86 @@
|
|
|
+ push_parm_decl (const struct c_parm *parm)
|
|
|
+ {
|
|
|
+ tree decl;
|
|
|
++/* begin-TIGCC-local (regparms): explicit register specification for parameters */
|
|
|
++ tree asmspec;
|
|
|
+
|
|
|
++ asmspec = parm->asmspec;
|
|
|
++/* end-TIGCC-local (regparms) */
|
|
|
+ decl = grokdeclarator (parm->declarator, parm->specs, PARM, false, NULL);
|
|
|
+ decl_attributes (&decl, parm->attrs, 0);
|
|
|
+
|
|
|
++ /* begin-TIGCC-local (regparms): explicit register specification for parameters */
|
|
|
++ if (asmspec)
|
|
|
++#ifdef EXPLICIT_REGPARM
|
|
|
++ {
|
|
|
++ const char *regname=TREE_STRING_POINTER(asmspec);
|
|
|
++ int regnum;
|
|
|
++ if ((regnum=decode_reg_name(regname))>=0)
|
|
|
++ {
|
|
|
++ tree type=TREE_TYPE(decl);
|
|
|
++ if (HARD_REGNO_MODE_OK(regnum, TYPE_MODE(type)))
|
|
|
++ {
|
|
|
++ tree t, attrs;
|
|
|
++/* push_obstacks_nochange();
|
|
|
++ end_temporary_allocation(); */
|
|
|
++ /* Build tree for __attribute__ ((asm(regnum))). */
|
|
|
++#if 0
|
|
|
++ /* This doesn't work well because of a bug in
|
|
|
++ attribute_list_contained(), which passes list of arguments to
|
|
|
++ simple_cst_equal() instead of passing every argument
|
|
|
++ separately. */
|
|
|
++ attrs=tree_cons(get_identifier("asm"), tree_cons(NULL_TREE,
|
|
|
++ build_int_cstu(NULL_TREE, regnum), NULL_TREE), NULL_TREE);
|
|
|
++#else
|
|
|
++ attrs=tree_cons(get_identifier("asm"),
|
|
|
++ build_int_cstu(NULL_TREE, regnum), NULL_TREE);
|
|
|
++#endif
|
|
|
++#if 0
|
|
|
++ /* build_type_attribute_variant() would seem to be more
|
|
|
++ appropriate here. However, that function does not support
|
|
|
++ attributes for parameters properly. It modifies
|
|
|
++ TYPE_MAIN_VARIANT of a new type. As a result, comptypes()
|
|
|
++ thinks that types of parameters in prototype and definition
|
|
|
++ are different and issues error messages. See also comment
|
|
|
++ below. */
|
|
|
++ type=build_type_attribute_variant(type, attrs);
|
|
|
++#else
|
|
|
++ /* First check whether such a type already exists - if yes, use
|
|
|
++ that one. This is very important, since otherwise
|
|
|
++ common_type() would think that it sees two different
|
|
|
++ types and would try to merge them - this could result in
|
|
|
++ warning messages. */
|
|
|
++ for (t=TYPE_MAIN_VARIANT(type); t; t=TYPE_NEXT_VARIANT(t))
|
|
|
++ if (comptypes(t, type)==1
|
|
|
++ && attribute_list_equal(TYPE_ATTRIBUTES(t), attrs))
|
|
|
++ break;
|
|
|
++ if (t)
|
|
|
++ type=t;
|
|
|
++ else
|
|
|
++ {
|
|
|
++ /* Create a new variant, with differing attributes.
|
|
|
++ (Hack! Type with differing attributes should no longer be
|
|
|
++ a variant of its main type. See comment above for
|
|
|
++ explanation why this was necessary). */
|
|
|
++ type=build_variant_type_copy(type);
|
|
|
++ TYPE_ATTRIBUTES(type)=attrs;
|
|
|
++ }
|
|
|
++#endif
|
|
|
++ TREE_TYPE(decl)=type;
|
|
|
++/* pop_obstacks(); */
|
|
|
++ }
|
|
|
++ else
|
|
|
++ error("%Jregister number for `%s' isn't suitable for the data type",
|
|
|
++ decl);
|
|
|
++ }
|
|
|
++ else
|
|
|
++ error("invalid register name `%s'", regname);
|
|
|
++ }
|
|
|
++#else /* !EXPLICIT_REGPARM */
|
|
|
++ error("explicit register specification for parameters is not supported for this target");
|
|
|
++#endif
|
|
|
++ /* end-TIGCC-local (regparms) */
|
|
|
++
|
|
|
+ decl = pushdecl (decl);
|
|
|
+
|
|
|
+ finish_decl (decl, NULL_TREE, NULL_TREE);
|
|
|
+@@ -3496,7 +3576,11 @@
|
|
|
+ DECL_CONTEXT (decl) = current_function_decl;
|
|
|
+ TREE_USED (decl) = 1;
|
|
|
+ TREE_TYPE (decl) = type;
|
|
|
+- TREE_READONLY (decl) = TYPE_READONLY (type);
|
|
|
++ /* (TIGCC 20050206) If -fglobal-compound-literals (on by default) is given,
|
|
|
++ for constant constructors, the compound literal is written out as if it was
|
|
|
++ const, which gets GCC to output it as a global, avoiding the copy. */
|
|
|
++ TREE_READONLY (decl) = TYPE_READONLY (type)
|
|
|
++ || (flag_global_compound_literals && TREE_CONSTANT (init));
|
|
|
+ store_init_value (decl, init);
|
|
|
+
|
|
|
+ if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
|
|
|
+@@ -6658,12 +6742,13 @@
|
|
|
+
|
|
|
+ struct c_parm *
|
|
|
+ build_c_parm (struct c_declspecs *specs, tree attrs,
|
|
|
+- struct c_declarator *declarator)
|
|
|
++ struct c_declarator *declarator, tree asmspec)
|
|
|
+ {
|
|
|
+ struct c_parm *ret = XOBNEW (&parser_obstack, struct c_parm);
|
|
|
+ ret->specs = specs;
|
|
|
+ ret->attrs = attrs;
|
|
|
+ ret->declarator = declarator;
|
|
|
++ ret->asmspec = asmspec; /* (TIGCC 20050203) */
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/c-format.c gcc-4.0-20050319-src/gcc/c-format.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/c-format.c Tue Nov 9 11:20:08 2004
|
|
|
++++ gcc-4.0-20050319-src/gcc/c-format.c Wed Mar 23 01:21:02 2005
|
|
|
+@@ -284,16 +284,12 @@
|
|
|
+ } format_wanted_type;
|
|
|
+
|
|
|
+
|
|
|
++/* (TIGCC 20040219) AMS doesn't support any C99 or extended modifiers.
|
|
|
++ -- Kevin Kofler */
|
|
|
+ static const format_length_info printf_length_specs[] =
|
|
|
+ {
|
|
|
+- { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99 },
|
|
|
+- { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C9L },
|
|
|
+- { "q", FMT_LEN_ll, STD_EXT, NULL, 0, 0 },
|
|
|
+- { "L", FMT_LEN_L, STD_C89, NULL, 0, 0 },
|
|
|
+- { "z", FMT_LEN_z, STD_C99, NULL, 0, 0 },
|
|
|
+- { "Z", FMT_LEN_z, STD_EXT, NULL, 0, 0 },
|
|
|
+- { "t", FMT_LEN_t, STD_C99, NULL, 0, 0 },
|
|
|
+- { "j", FMT_LEN_j, STD_C99, NULL, 0, 0 },
|
|
|
++ { "h", FMT_LEN_h, STD_C89, NULL, 0, 0 },
|
|
|
++ { "l", FMT_LEN_l, STD_C89, NULL, 0, 0 },
|
|
|
+ { NULL, 0, 0, NULL, 0, 0 }
|
|
|
+ };
|
|
|
+
|
|
|
+@@ -317,16 +313,12 @@
|
|
|
+ #define gcc_cdiag_length_specs gcc_diag_length_specs
|
|
|
+ #define gcc_cxxdiag_length_specs gcc_diag_length_specs
|
|
|
+
|
|
|
+-/* This differs from printf_length_specs only in that "Z" is not accepted. */
|
|
|
++/* (TIGCC 20040219) My *scanf doesn't support any C99 or extended modifiers.
|
|
|
++ -- Kevin Kofler */
|
|
|
+ static const format_length_info scanf_length_specs[] =
|
|
|
+ {
|
|
|
+- { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99 },
|
|
|
+- { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C9L },
|
|
|
+- { "q", FMT_LEN_ll, STD_EXT, NULL, 0, 0 },
|
|
|
+- { "L", FMT_LEN_L, STD_C89, NULL, 0, 0 },
|
|
|
+- { "z", FMT_LEN_z, STD_C99, NULL, 0, 0 },
|
|
|
+- { "t", FMT_LEN_t, STD_C99, NULL, 0, 0 },
|
|
|
+- { "j", FMT_LEN_j, STD_C99, NULL, 0, 0 },
|
|
|
++ { "h", FMT_LEN_h, STD_C89, NULL, 0, 0 },
|
|
|
++ { "l", FMT_LEN_l, STD_C89, NULL, 0, 0 },
|
|
|
+ { NULL, 0, 0, NULL, 0, 0 }
|
|
|
+ };
|
|
|
+
|
|
|
+@@ -340,6 +332,9 @@
|
|
|
+ { NULL, 0, 0, NULL, 0, 0 }
|
|
|
+ };
|
|
|
+
|
|
|
++/* (TIGCC 20040219) AMS doesn't support any of the GNU extended modifiers.
|
|
|
++ However, it supports some of its own.
|
|
|
++ -- Kevin Kofler */
|
|
|
+ static const format_flag_spec printf_flag_specs[] =
|
|
|
+ {
|
|
|
+ { ' ', 0, 0, N_("' ' flag"), N_("the ' ' printf flag"), STD_C89 },
|
|
|
+@@ -347,8 +342,9 @@
|
|
|
+ { '#', 0, 0, N_("'#' flag"), N_("the '#' printf flag"), STD_C89 },
|
|
|
+ { '0', 0, 0, N_("'0' flag"), N_("the '0' printf flag"), STD_C89 },
|
|
|
+ { '-', 0, 0, N_("'-' flag"), N_("the '-' printf flag"), STD_C89 },
|
|
|
+- { '\'', 0, 0, N_("''' flag"), N_("the ''' printf flag"), STD_EXT },
|
|
|
+- { 'I', 0, 0, N_("'I' flag"), N_("the 'I' printf flag"), STD_EXT },
|
|
|
++ { 'z', 0, 0, N_("'z' flag"), N_("the 'z' printf flag"), STD_EXT },
|
|
|
++ { '^', 0, 0, N_("'^' flag"), N_("the '^' printf flag"), STD_EXT },
|
|
|
++ { '|', 0, 0, N_("'|' flag"), N_("the '|' printf flag"), STD_EXT },
|
|
|
+ { 'w', 0, 0, N_("field width"), N_("field width in printf format"), STD_C89 },
|
|
|
+ { 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 },
|
|
|
+ { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
|
|
|
+@@ -413,14 +409,13 @@
|
|
|
+ { 0, 0, 0, NULL, NULL, 0 }
|
|
|
+ };
|
|
|
+
|
|
|
++/* (TIGCC 20040219) My *scanf doesn't support any extended modifiers.
|
|
|
++ -- Kevin Kofler */
|
|
|
+ static const format_flag_spec scanf_flag_specs[] =
|
|
|
+ {
|
|
|
+ { '*', 0, 0, N_("assignment suppression"), N_("the assignment suppression scanf feature"), STD_C89 },
|
|
|
+- { 'a', 0, 0, N_("'a' flag"), N_("the 'a' scanf flag"), STD_EXT },
|
|
|
+ { 'w', 0, 0, N_("field width"), N_("field width in scanf format"), STD_C89 },
|
|
|
+ { 'L', 0, 0, N_("length modifier"), N_("length modifier in scanf format"), STD_C89 },
|
|
|
+- { '\'', 0, 0, N_("''' flag"), N_("the ''' scanf flag"), STD_EXT },
|
|
|
+- { 'I', 0, 0, N_("'I' flag"), N_("the 'I' scanf flag"), STD_EXT },
|
|
|
+ { 0, 0, 0, NULL, NULL, 0 }
|
|
|
+ };
|
|
|
+
|
|
|
+@@ -480,26 +475,22 @@
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
++/* (TIGCC 20040219) AMS doesn't support any of the C99 or GNU extended
|
|
|
++ modifiers. However, it supports some of its own.
|
|
|
++ -- Kevin Kofler */
|
|
|
+ static const format_char_info print_char_table[] =
|
|
|
+ {
|
|
|
+ /* C89 conversion specifiers. */
|
|
|
+- { "di", 0, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, TEX_LL, T99_SST, T99_PD, T99_IM }, "-wp0 +'I", "i", NULL },
|
|
|
+- { "oxX", 0, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "-wp0#", "i", NULL },
|
|
|
+- { "u", 0, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "-wp0'I", "i", NULL },
|
|
|
+- { "fgG", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#'I", "", NULL },
|
|
|
+- { "eE", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#I", "", NULL },
|
|
|
+- { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL },
|
|
|
+- { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL },
|
|
|
+- { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c", NULL },
|
|
|
+- { "n", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, T99_PD, T99_IM }, "", "W", NULL },
|
|
|
+- /* C99 conversion specifiers. */
|
|
|
+- { "F", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#'I", "", NULL },
|
|
|
+- { "aA", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "", NULL },
|
|
|
+- /* X/Open conversion specifiers. */
|
|
|
+- { "C", 0, STD_EXT, { TEX_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL },
|
|
|
+- { "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "R", NULL },
|
|
|
+- /* GNU conversion specifiers. */
|
|
|
+- { "m", 0, STD_EXT, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "", NULL },
|
|
|
++ { "di", 0, STD_C89, { T89_S, BADLEN, T89_S, T89_L, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +|z", "i", NULL },
|
|
|
++ { "xX", 0, STD_C89, { T89_US, BADLEN, T89_US, T89_UL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0#|z", "i", NULL },
|
|
|
++ { "u", 0, STD_C89, { T89_US, BADLEN, T89_US, T89_UL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0|z", "i", NULL },
|
|
|
++ { "fgG", 0, STD_C89, { T89_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#^|z", "", NULL },
|
|
|
++ { "eE", 0, STD_C89, { T89_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#^|z", "", NULL },
|
|
|
++ { "rR", 0, STD_EXT, { T89_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#^|z", "", NULL },
|
|
|
++ { "yY", 0, STD_EXT, { T89_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#^|z", "", NULL },
|
|
|
++ { "c", 0, STD_C89, { T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w|z", "", NULL },
|
|
|
++ { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp|z", "cR", NULL },
|
|
|
++ { "p", 1, STD_C89, { BADLEN, BADLEN, BADLEN, T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w|z", "c", NULL },
|
|
|
+ { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL }
|
|
|
+ };
|
|
|
+
|
|
|
+@@ -595,23 +586,18 @@
|
|
|
+ { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL }
|
|
|
+ };
|
|
|
+
|
|
|
++/* (TIGCC 20040219) My *scanf doesn't support any extended modifiers. -- Kevin Kofler */
|
|
|
+ static const format_char_info scan_char_table[] =
|
|
|
+ {
|
|
|
+ /* C89 conversion specifiers. */
|
|
|
+- { "di", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, TEX_LL, T99_SST, T99_PD, T99_IM }, "*w'I", "W", NULL },
|
|
|
+- { "u", 1, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "*w'I", "W", NULL },
|
|
|
+- { "oxX", 1, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "*w", "W", NULL },
|
|
|
+- { "efgEG", 1, STD_C89, { T89_F, BADLEN, BADLEN, T89_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL },
|
|
|
++ { "di", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, TEX_LL, T99_SST, T99_PD, T99_IM }, "*w", "W", NULL },
|
|
|
++ { "u", 1, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "*w", "W", NULL },
|
|
|
++ { "oxX", 1, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "*w", "W", NULL },
|
|
|
++ { "efgEG", 1, STD_C89, { T89_F, BADLEN, BADLEN, T89_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL },
|
|
|
+ { "c", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "cW", NULL },
|
|
|
+ { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW", NULL },
|
|
|
+ { "[", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW[", NULL },
|
|
|
+ { "p", 2, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL },
|
|
|
+- { "n", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, T99_PD, T99_IM }, "", "W", NULL },
|
|
|
+- /* C99 conversion specifiers. */
|
|
|
+- { "FaA", 1, STD_C99, { T99_F, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL },
|
|
|
+- /* X/Open conversion specifiers. */
|
|
|
+- { "C", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL },
|
|
|
+- { "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "W", NULL },
|
|
|
+ { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL }
|
|
|
+ };
|
|
|
+
|
|
|
+@@ -649,9 +635,10 @@
|
|
|
+ };
|
|
|
+
|
|
|
+ /* This must be in the same order as enum format_type. */
|
|
|
++/* (TIGCC 20040219) Changed the flag chars. See the *f_flag_specs comments. */
|
|
|
+ static const format_kind_info format_types_orig[] =
|
|
|
+ {
|
|
|
+- { "printf", printf_length_specs, print_char_table, " +#0-'I", NULL,
|
|
|
++ { "printf", printf_length_specs, print_char_table, " +#0-z^|", NULL,
|
|
|
+ printf_flag_specs, printf_flag_pairs,
|
|
|
+ FMT_FLAG_ARG_CONVERT|FMT_FLAG_DOLLAR_MULTIPLE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_EMPTY_PREC_OK,
|
|
|
+ 'w', 0, 'p', 0, 'L',
|
|
|
+@@ -681,7 +668,7 @@
|
|
|
+ 0, 0, 'p', 0, 'L',
|
|
|
+ NULL, &integer_type_node
|
|
|
+ },
|
|
|
+- { "scanf", scanf_length_specs, scan_char_table, "*'I", NULL,
|
|
|
++ { "scanf", scanf_length_specs, scan_char_table, "*", NULL,
|
|
|
+ scanf_flag_specs, scanf_flag_pairs,
|
|
|
+ FMT_FLAG_ARG_CONVERT|FMT_FLAG_SCANF_A_KLUDGE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_ZERO_WIDTH_BAD|FMT_FLAG_DOLLAR_GAP_POINTER_OK,
|
|
|
+ 'w', 0, 0, '*', 'L',
|
|
|
+@@ -2136,6 +2123,17 @@
|
|
|
+ || cur_type == signed_char_type_node
|
|
|
+ || cur_type == unsigned_char_type_node);
|
|
|
+
|
|
|
++ /* (TIGCC) Account for *printf and *scanf not actually supporting -mlong. */
|
|
|
++ if (!TARGET_SHORT) {
|
|
|
++ if (cur_type == short_integer_type_node
|
|
|
++ || cur_type == integer_type_node)
|
|
|
++ orig_cur_type = cur_type = long_integer_type_node;
|
|
|
++
|
|
|
++ if (cur_type == short_unsigned_type_node
|
|
|
++ || cur_type == unsigned_type_node)
|
|
|
++ orig_cur_type = cur_type = long_unsigned_type_node;
|
|
|
++ }
|
|
|
++
|
|
|
+ /* Check the type of the "real" argument, if there's a type we want. */
|
|
|
+ if (wanted_type == cur_type)
|
|
|
+ continue;
|
|
|
+@@ -2150,12 +2148,18 @@
|
|
|
+ -pedantic. With -pedantic, warn if the type is a pointer
|
|
|
+ target and not a character type, and for character types at
|
|
|
+ a second level of indirection. */
|
|
|
+- if (TREE_CODE (wanted_type) == INTEGER_TYPE
|
|
|
++ /* TIGCC Patch: Don't warn about differences in floating point
|
|
|
++ format; they're all the same.
|
|
|
++ (TIGCC 20040728) But do warn if someone passes an integer where a float
|
|
|
++ is expected! -- Kevin Kofler */
|
|
|
++ if ((TREE_CODE (wanted_type) == REAL_TYPE
|
|
|
++ && TREE_CODE (cur_type) == REAL_TYPE)
|
|
|
++ || (TREE_CODE (wanted_type) == INTEGER_TYPE
|
|
|
+ && TREE_CODE (cur_type) == INTEGER_TYPE
|
|
|
+ && (!pedantic || i == 0 || (i == 1 && char_type_flag))
|
|
|
+ && (TYPE_UNSIGNED (wanted_type)
|
|
|
+ ? wanted_type == c_common_unsigned_type (cur_type)
|
|
|
+- : wanted_type == c_common_signed_type (cur_type)))
|
|
|
++ : wanted_type == c_common_signed_type (cur_type))))
|
|
|
+ continue;
|
|
|
+ /* Likewise, "signed char", "unsigned char" and "char" are
|
|
|
+ equivalent but the above test won't consider them equivalent. */
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/c-incpath.c gcc-4.0-20050319-src/gcc/c-incpath.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/c-incpath.c Sun Jan 23 16:05:26 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/c-incpath.c Wed Mar 23 01:21:02 2005
|
|
|
+@@ -335,9 +335,13 @@
|
|
|
+ function does not recognize a directory that ends in a backslash
|
|
|
+ (unless it is a drive root dir, such "c:\"). Forward slashes,
|
|
|
+ trailing or otherwise, cause no problems for stat(). */
|
|
|
++ /* (TIGCC 20050206) This is entirely backwards! We need backslashes.
|
|
|
++ Forward-slashes are no good. But we need to get rid of
|
|
|
++ trailing backslashes. -- Kevin Kofler */
|
|
|
+ char* c;
|
|
|
+ for (c = path; *c; c++)
|
|
|
+- if (*c == '\\') *c = '/';
|
|
|
++ if (*c == '/') *c = '\\';
|
|
|
++ if (c[strlen(c)-1] == '\\') c[strlen(c)-1] = '\0';
|
|
|
+ #endif
|
|
|
+
|
|
|
+ p = xmalloc (sizeof (cpp_dir));
|
|
|
+@@ -360,6 +364,7 @@
|
|
|
+ const char *iprefix, int stdinc, int cxx_stdinc,
|
|
|
+ int verbose)
|
|
|
+ {
|
|
|
++#if 0 /* (TIGCC 20050205) Don't use environment variables. */
|
|
|
+ static const char *const lang_env_vars[] =
|
|
|
+ { "C_INCLUDE_PATH", "CPLUS_INCLUDE_PATH",
|
|
|
+ "OBJC_INCLUDE_PATH", "OBJCPLUS_INCLUDE_PATH" };
|
|
|
+@@ -375,11 +380,14 @@
|
|
|
+ include chain. */
|
|
|
+ add_env_var_paths ("CPATH", BRACKET);
|
|
|
+ add_env_var_paths (lang_env_vars[idx], SYSTEM);
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ target_c_incpath.extra_pre_includes (sysroot, iprefix, stdinc);
|
|
|
+
|
|
|
+ /* Finally chain on the standard directories. */
|
|
|
+- if (stdinc)
|
|
|
++ /* (TIGCC 20031007) We don't want any "standard" include directories.
|
|
|
++ -- Kevin Kofler */
|
|
|
++ if (0 /*stdinc*/)
|
|
|
+ add_standard_paths (sysroot, iprefix, cxx_stdinc);
|
|
|
+
|
|
|
+ target_c_incpath.extra_includes (sysroot, iprefix, stdinc);
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/c-lang.c gcc-4.0-20050319-src/gcc/c-lang.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/c-lang.c Tue Jan 18 12:35:58 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/c-lang.c Wed Mar 23 01:21:02 2005
|
|
|
+@@ -45,6 +45,8 @@
|
|
|
+ #define LANG_HOOKS_NAME "GNU C"
|
|
|
+ #undef LANG_HOOKS_INIT
|
|
|
+ #define LANG_HOOKS_INIT c_objc_common_init
|
|
|
++#undef LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES
|
|
|
++#define LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES c_insert_default_attributes
|
|
|
+
|
|
|
+ /* Each front end provides its own lang hook initializer. */
|
|
|
+ const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/c-lex.c gcc-4.0-20050319-src/gcc/c-lex.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/c-lex.c Wed Oct 27 20:24:20 2004
|
|
|
++++ gcc-4.0-20050319-src/gcc/c-lex.c Wed Mar 23 01:21:02 2005
|
|
|
+@@ -432,7 +432,7 @@
|
|
|
+ cppchar_t c = tok->val.str.text[0];
|
|
|
+
|
|
|
+ if (c == '"' || c == '\'')
|
|
|
+- error ("missing terminating %c character", (int) c);
|
|
|
++ cpp_unterminated (parse_in, c);
|
|
|
+ else if (ISGRAPH (c))
|
|
|
+ error ("stray %qc in program", (int) c);
|
|
|
+ else
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/c-opts.c gcc-4.0-20050319-src/gcc/c-opts.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/c-opts.c Fri Mar 4 16:28:40 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/c-opts.c Wed Mar 23 01:21:02 2005
|
|
|
+@@ -219,6 +219,9 @@
|
|
|
+ before passing on command-line options to cpplib. */
|
|
|
+ cpp_opts->warn_dollars = 0;
|
|
|
+
|
|
|
++ /* (TIGCC 20050217) Enable -fms-extensions by default. */
|
|
|
++ flag_ms_extensions = 1;
|
|
|
++
|
|
|
+ flag_const_strings = c_dialect_cxx ();
|
|
|
+ flag_exceptions = c_dialect_cxx ();
|
|
|
+ warn_pointer_arith = c_dialect_cxx ();
|
|
|
+@@ -303,7 +306,9 @@
|
|
|
+ error ("-I- specified twice");
|
|
|
+ quote_chain_split = true;
|
|
|
+ split_quote_chain ();
|
|
|
++#if 0 /* (TIGCC 20050206) */
|
|
|
+ inform ("obsolete option -I- used, please use -iquote instead");
|
|
|
++#endif /* 0 */
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+@@ -848,6 +853,8 @@
|
|
|
+ case OPT_pedantic:
|
|
|
+ cpp_opts->pedantic = 1;
|
|
|
+ cpp_opts->warn_endif_labels = 1;
|
|
|
++ /* (TIGCC 20050217) No Microsoft extensions if -pedantic. */
|
|
|
++ flag_ms_extensions = 0;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OPT_print_objc_runtime_info:
|
|
|
+@@ -904,6 +911,10 @@
|
|
|
+ case OPT_v:
|
|
|
+ verbose = true;
|
|
|
+ break;
|
|
|
++
|
|
|
++ case OPT_fauto_octals:
|
|
|
++ cpp_opts->no_auto_octals = !value;
|
|
|
++ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+@@ -978,10 +989,12 @@
|
|
|
+ if (warn_missing_format_attribute && !warn_format)
|
|
|
+ warning ("-Wmissing-format-attribute ignored without -Wformat");
|
|
|
+
|
|
|
++#if 0 /* (TIGCC 20050306) Disable as we don't have these libcalls. */
|
|
|
+ /* C99 requires special handling of complex multiplication and division;
|
|
|
+ -ffast-math and -fcx-limited-range are handled in process_options. */
|
|
|
+ if (flag_isoc99)
|
|
|
+ flag_complex_method = 2;
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ if (flag_preprocess_only)
|
|
|
+ {
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/c-parse.in gcc-4.0-20050319-src/gcc/c-parse.in
|
|
|
+--- gcc-4.0-20050319.orig/gcc/c-parse.in Wed Jan 5 18:08:34 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/c-parse.in Wed Mar 23 01:21:02 2005
|
|
|
+@@ -29,7 +29,7 @@
|
|
|
+ written by AT&T, but I have never seen it. */
|
|
|
+
|
|
|
+ @@ifc
|
|
|
+-%expect 13 /* shift/reduce conflicts, and no reduce/reduce conflicts. */
|
|
|
++%expect 14 /* shift/reduce conflicts, and no reduce/reduce conflicts. */
|
|
|
+ @@end_ifc
|
|
|
+
|
|
|
+ %{
|
|
|
+@@ -233,7 +233,7 @@
|
|
|
+ %type <ttype> struct_head union_head enum_head
|
|
|
+ %type <typenametype> typename
|
|
|
+ %type <dtrtype> absdcl absdcl1 absdcl1_ea absdcl1_noea direct_absdcl1
|
|
|
+-%type <parmtype> absdcl_maybe_attribute
|
|
|
++%type <parmtype> /*(TIGCC)*/ absdcl_maybeasm_maybe_attribute
|
|
|
+ %type <ttype> condition xexpr for_cond_expr for_incr_expr
|
|
|
+ %type <parmtype> parm firstparm
|
|
|
+ %type <ttype> identifiers
|
|
|
+@@ -1862,18 +1862,20 @@
|
|
|
+ | absdcl1
|
|
|
+ ;
|
|
|
+
|
|
|
+-absdcl_maybe_attribute: /* absdcl maybe_attribute, but not just attributes */
|
|
|
+- /* empty */
|
|
|
++/* begin-TIGCC-local (regparms): explicit register specification for parameters */
|
|
|
++absdcl_maybeasm_maybe_attribute: /* absdcl maybe_attribute, but not just attributes */
|
|
|
++ maybeasm
|
|
|
+ { $$ = build_c_parm (current_declspecs, all_prefix_attributes,
|
|
|
+- build_id_declarator (NULL_TREE)); }
|
|
|
+- | absdcl1
|
|
|
++ build_id_declarator (NULL_TREE), $1); }
|
|
|
++ | absdcl1 maybeasm
|
|
|
+ { $$ = build_c_parm (current_declspecs, all_prefix_attributes,
|
|
|
+- $1); }
|
|
|
+- | absdcl1_noea attributes
|
|
|
++ $1, $2); }
|
|
|
++ | absdcl1_noea maybeasm attributes
|
|
|
+ { $$ = build_c_parm (current_declspecs,
|
|
|
+- chainon ($2, all_prefix_attributes),
|
|
|
+- $1); }
|
|
|
++ chainon ($3, all_prefix_attributes),
|
|
|
++ $1, $2); }
|
|
|
+ ;
|
|
|
++/* end-TIGCC-local (regparms) */
|
|
|
+
|
|
|
+ absdcl1: /* a nonempty absolute declarator */
|
|
|
+ absdcl1_ea
|
|
|
+@@ -1936,7 +1938,7 @@
|
|
|
+ | lineno_stmt_decl_or_labels_ending_decl
|
|
|
+ | lineno_stmt_decl_or_labels_ending_label
|
|
|
+ {
|
|
|
+- error ("label at end of compound statement");
|
|
|
++ if (pedantic) pedwarn ("ISO C doesn't allow labels at the end of compound statements");
|
|
|
+ }
|
|
|
+ | lineno_stmt_decl_or_labels_ending_error
|
|
|
+ ;
|
|
|
+@@ -2506,23 +2508,24 @@
|
|
|
+ /* A single parameter declaration or parameter type name,
|
|
|
+ as found in a parmlist. */
|
|
|
+ parm:
|
|
|
+- declspecs_ts setspecs parm_declarator maybe_attribute
|
|
|
++/* begin-TIGCC-local (regparms): explicit register specification for parameters */
|
|
|
++ declspecs_ts setspecs parm_declarator maybeasm maybe_attribute
|
|
|
+ { $$ = build_c_parm (current_declspecs,
|
|
|
+- chainon ($4, all_prefix_attributes), $3);
|
|
|
++ chainon ($5, all_prefix_attributes), $3, $4);
|
|
|
+ POP_DECLSPEC_STACK; }
|
|
|
+- | declspecs_ts setspecs notype_declarator maybe_attribute
|
|
|
++ | declspecs_ts setspecs notype_declarator maybeasm maybe_attribute
|
|
|
+ { $$ = build_c_parm (current_declspecs,
|
|
|
+- chainon ($4, all_prefix_attributes), $3);
|
|
|
++ chainon ($5, all_prefix_attributes), $3, $4);
|
|
|
+ POP_DECLSPEC_STACK; }
|
|
|
+- | declspecs_ts setspecs absdcl_maybe_attribute
|
|
|
++ | declspecs_ts setspecs absdcl_maybeasm_maybe_attribute
|
|
|
+ { $$ = $3;
|
|
|
+ POP_DECLSPEC_STACK; }
|
|
|
+- | declspecs_nots setspecs notype_declarator maybe_attribute
|
|
|
++ | declspecs_nots setspecs notype_declarator maybeasm maybe_attribute
|
|
|
+ { $$ = build_c_parm (current_declspecs,
|
|
|
+- chainon ($4, all_prefix_attributes), $3);
|
|
|
++ chainon ($5, all_prefix_attributes), $3, $4);
|
|
|
+ POP_DECLSPEC_STACK; }
|
|
|
+
|
|
|
+- | declspecs_nots setspecs absdcl_maybe_attribute
|
|
|
++ | declspecs_nots setspecs absdcl_maybeasm_maybe_attribute
|
|
|
+ { $$ = $3;
|
|
|
+ POP_DECLSPEC_STACK; }
|
|
|
+ ;
|
|
|
+@@ -2530,26 +2533,27 @@
|
|
|
+ /* The first parm, which must suck attributes from off the top of the parser
|
|
|
+ stack. */
|
|
|
+ firstparm:
|
|
|
+- declspecs_ts_nosa setspecs_fp parm_declarator maybe_attribute
|
|
|
++ declspecs_ts_nosa setspecs_fp parm_declarator maybeasm maybe_attribute
|
|
|
+ { $$ = build_c_parm (current_declspecs,
|
|
|
+- chainon ($4, all_prefix_attributes), $3);
|
|
|
++ chainon ($5, all_prefix_attributes), $3, $4);
|
|
|
+ POP_DECLSPEC_STACK; }
|
|
|
+- | declspecs_ts_nosa setspecs_fp notype_declarator maybe_attribute
|
|
|
++ | declspecs_ts_nosa setspecs_fp notype_declarator maybeasm maybe_attribute
|
|
|
+ { $$ = build_c_parm (current_declspecs,
|
|
|
+- chainon ($4, all_prefix_attributes), $3);
|
|
|
++ chainon ($5, all_prefix_attributes), $3, $4);
|
|
|
+ POP_DECLSPEC_STACK; }
|
|
|
+- | declspecs_ts_nosa setspecs_fp absdcl_maybe_attribute
|
|
|
++ | declspecs_ts_nosa setspecs_fp absdcl_maybeasm_maybe_attribute
|
|
|
+ { $$ = $3;
|
|
|
+ POP_DECLSPEC_STACK; }
|
|
|
+- | declspecs_nots_nosa setspecs_fp notype_declarator maybe_attribute
|
|
|
++ | declspecs_nots_nosa setspecs_fp notype_declarator maybeasm maybe_attribute
|
|
|
+ { $$ = build_c_parm (current_declspecs,
|
|
|
+- chainon ($4, all_prefix_attributes), $3);
|
|
|
++ chainon ($5, all_prefix_attributes), $3, $4);
|
|
|
+ POP_DECLSPEC_STACK; }
|
|
|
+
|
|
|
+- | declspecs_nots_nosa setspecs_fp absdcl_maybe_attribute
|
|
|
++ | declspecs_nots_nosa setspecs_fp absdcl_maybeasm_maybe_attribute
|
|
|
+ { $$ = $3;
|
|
|
+ POP_DECLSPEC_STACK; }
|
|
|
+ ;
|
|
|
++/* end-TIGCC-local (regparms) */
|
|
|
+
|
|
|
+ setspecs_fp:
|
|
|
+ setspecs
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/c-ppoutput.c gcc-4.0-20050319-src/gcc/c-ppoutput.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/c-ppoutput.c Mon Nov 29 00:29:40 2004
|
|
|
++++ gcc-4.0-20050319-src/gcc/c-ppoutput.c Wed Mar 23 01:21:02 2005
|
|
|
+@@ -174,7 +174,8 @@
|
|
|
+ print.prev = token;
|
|
|
+ cpp_output_token (token, print.outf);
|
|
|
+
|
|
|
+- if (token->type == CPP_COMMENT)
|
|
|
++ if (token->type == CPP_STRING || token->type == CPP_WSTRING
|
|
|
++ || token->type == CPP_COMMENT)
|
|
|
+ account_for_newlines (token->val.str.text, token->val.str.len);
|
|
|
+ }
|
|
|
+ }
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/c-pretty-print.c gcc-4.0-20050319-src/gcc/c-pretty-print.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/c-pretty-print.c Mon Feb 21 15:39:46 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/c-pretty-print.c Wed Mar 23 01:21:02 2005
|
|
|
+@@ -872,8 +872,7 @@
|
|
|
+ static void
|
|
|
+ pp_c_floating_constant (c_pretty_printer *pp, tree r)
|
|
|
+ {
|
|
|
+- real_to_decimal (pp_buffer (pp)->digit_buffer, &TREE_REAL_CST (r),
|
|
|
+- sizeof (pp_buffer (pp)->digit_buffer), 0, 1);
|
|
|
++ REAL_VALUE_TO_STRING (TREE_REAL_CST (r), pp_buffer (pp)->digit_buffer);
|
|
|
+ pp_string (pp, pp_buffer(pp)->digit_buffer);
|
|
|
+ if (TREE_TYPE (r) == float_type_node)
|
|
|
+ pp_character (pp, 'f');
|
|
|
+@@ -1923,6 +1922,17 @@
|
|
|
+
|
|
|
+ case TARGET_EXPR:
|
|
|
+ pp_postfix_expression (pp, TREE_OPERAND (e, 1));
|
|
|
++ break;
|
|
|
++
|
|
|
++ /* (TIGCC 20050210) Get pp_c_expression to print statement expressions
|
|
|
++ correctly. We only print the last statement of a list,
|
|
|
++ because that's the result of the statement expression. */
|
|
|
++ case BIND_EXPR:
|
|
|
++ pp_c_expression (pp, BIND_EXPR_BODY (e));
|
|
|
++ break;
|
|
|
++
|
|
|
++ case STATEMENT_LIST:
|
|
|
++ pp_c_expression (pp, STATEMENT_LIST_TAIL (e)->stmt);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/c-tree.h gcc-4.0-20050319-src/gcc/c-tree.h
|
|
|
+--- gcc-4.0-20050319.orig/gcc/c-tree.h Sat Feb 12 16:17:50 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/c-tree.h Wed Mar 23 01:21:02 2005
|
|
|
+@@ -325,6 +325,8 @@
|
|
|
+ tree attrs;
|
|
|
+ /* The declarator. */
|
|
|
+ struct c_declarator *declarator;
|
|
|
++ /* (TIGCC 20050203) The asmspec. */
|
|
|
++ tree asmspec;
|
|
|
+ };
|
|
|
+
|
|
|
+ /* Save and restore the variables in this file and elsewhere
|
|
|
+@@ -364,6 +366,7 @@
|
|
|
+ extern tree pushdecl (tree);
|
|
|
+ extern void c_expand_body (tree);
|
|
|
+
|
|
|
++extern void c_insert_default_attributes (tree);
|
|
|
+ extern void c_init_decl_processing (void);
|
|
|
+ extern void c_dup_lang_specific_decl (tree);
|
|
|
+ extern void c_print_identifier (FILE *, tree, int);
|
|
|
+@@ -412,7 +415,7 @@
|
|
|
+ extern struct c_typespec parser_xref_tag (enum tree_code, tree);
|
|
|
+ extern int c_expand_decl (tree);
|
|
|
+ extern struct c_parm *build_c_parm (struct c_declspecs *, tree,
|
|
|
+- struct c_declarator *);
|
|
|
++ struct c_declarator *, tree /* (TIGCC 20050203) */);
|
|
|
+ extern struct c_declarator *build_attrs_declarator (tree,
|
|
|
+ struct c_declarator *);
|
|
|
+ extern struct c_declarator *build_function_declarator (struct c_arg_info *,
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/c-typeck.c gcc-4.0-20050319-src/gcc/c-typeck.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/c-typeck.c Sat Feb 19 01:26:30 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/c-typeck.c Wed Mar 23 01:21:02 2005
|
|
|
+@@ -81,6 +81,8 @@
|
|
|
+ static tree lookup_field (tree, tree);
|
|
|
+ static tree convert_arguments (tree, tree, tree, tree);
|
|
|
+ static tree pointer_diff (tree, tree);
|
|
|
++static tree unary_complex_lvalue (enum tree_code, tree, int);
|
|
|
++static void pedantic_lvalue_warning (enum tree_code);
|
|
|
+ static tree convert_for_assignment (tree, tree, enum impl_conv, tree, tree,
|
|
|
+ int);
|
|
|
+ static tree valid_compound_expr_initializer (tree, tree);
|
|
|
+@@ -1994,6 +1996,7 @@
|
|
|
+ /* fntype now gets the type of function pointed to. */
|
|
|
+ fntype = TREE_TYPE (fntype);
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Check that the function is called through a compatible prototype.
|
|
|
+ If it is not, replace the call by a trap, wrapped up in a compound
|
|
|
+ expression if necessary. This has the nice side-effect to prevent
|
|
|
+@@ -2038,6 +2041,7 @@
|
|
|
+ return build2 (COMPOUND_EXPR, return_type, trap, rhs);
|
|
|
+ }
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Convert the parameters to the types declared in the
|
|
|
+ function prototype, or apply default promotions. */
|
|
|
+@@ -2584,6 +2588,12 @@
|
|
|
+ case POSTINCREMENT_EXPR:
|
|
|
+ case PREDECREMENT_EXPR:
|
|
|
+ case POSTDECREMENT_EXPR:
|
|
|
++ /* Handle complex lvalues (when permitted)
|
|
|
++ by reduction to simpler cases. */
|
|
|
++
|
|
|
++ val = unary_complex_lvalue (code, arg, 0);
|
|
|
++ if (val != 0)
|
|
|
++ return val;
|
|
|
+
|
|
|
+ /* Increment or decrement the real part of the value,
|
|
|
+ and don't change the imaginary part. */
|
|
|
+@@ -2652,6 +2662,57 @@
|
|
|
+
|
|
|
+ inc = convert (argtype, inc);
|
|
|
+
|
|
|
++ /* Handle incrementing a cast-expression. */
|
|
|
++
|
|
|
++ while (1)
|
|
|
++ switch (TREE_CODE (arg))
|
|
|
++ {
|
|
|
++ case NOP_EXPR:
|
|
|
++ case CONVERT_EXPR:
|
|
|
++ case FLOAT_EXPR:
|
|
|
++ case FIX_TRUNC_EXPR:
|
|
|
++ case FIX_FLOOR_EXPR:
|
|
|
++ case FIX_ROUND_EXPR:
|
|
|
++ case FIX_CEIL_EXPR:
|
|
|
++ pedantic_lvalue_warning (CONVERT_EXPR);
|
|
|
++ /* If the real type has the same machine representation
|
|
|
++ as the type it is cast to, we can make better output
|
|
|
++ by adding directly to the inside of the cast. */
|
|
|
++ if ((TREE_CODE (TREE_TYPE (arg))
|
|
|
++ == TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 0))))
|
|
|
++ && (TYPE_MODE (TREE_TYPE (arg))
|
|
|
++ == TYPE_MODE (TREE_TYPE (TREE_OPERAND (arg, 0)))))
|
|
|
++ arg = TREE_OPERAND (arg, 0);
|
|
|
++ else
|
|
|
++ {
|
|
|
++ tree incremented, modify, value;
|
|
|
++ if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE)
|
|
|
++ value = boolean_increment (code, arg);
|
|
|
++ else
|
|
|
++ {
|
|
|
++ arg = stabilize_reference (arg);
|
|
|
++ if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
|
|
|
++ value = arg;
|
|
|
++ else
|
|
|
++ value = save_expr (arg);
|
|
|
++ incremented = build (((code == PREINCREMENT_EXPR
|
|
|
++ || code == POSTINCREMENT_EXPR)
|
|
|
++ ? PLUS_EXPR : MINUS_EXPR),
|
|
|
++ argtype, value, inc);
|
|
|
++ TREE_SIDE_EFFECTS (incremented) = 1;
|
|
|
++ modify = build_modify_expr (arg, NOP_EXPR, incremented);
|
|
|
++ value = build (COMPOUND_EXPR, TREE_TYPE (arg), modify, value);
|
|
|
++ }
|
|
|
++ TREE_USED (value) = 1;
|
|
|
++ return value;
|
|
|
++ }
|
|
|
++ break;
|
|
|
++
|
|
|
++ default:
|
|
|
++ goto give_up;
|
|
|
++ }
|
|
|
++ give_up:
|
|
|
++
|
|
|
+ /* Complain about anything else that is not a true lvalue. */
|
|
|
+ if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR
|
|
|
+ || code == POSTINCREMENT_EXPR)
|
|
|
+@@ -2698,6 +2759,12 @@
|
|
|
+ TREE_OPERAND (arg, 1), 1);
|
|
|
+ }
|
|
|
+
|
|
|
++ /* Handle complex lvalues (when permitted)
|
|
|
++ by reduction to simpler cases. */
|
|
|
++ val = unary_complex_lvalue (code, arg, flag);
|
|
|
++ if (val != 0)
|
|
|
++ return val;
|
|
|
++
|
|
|
+ /* Anything not already handled and not a true memory reference
|
|
|
+ or a non-lvalue array is an error. */
|
|
|
+ else if (typecode != FUNCTION_TYPE && !flag
|
|
|
+@@ -2786,6 +2853,69 @@
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
++/* Apply unary lvalue-demanding operator CODE to the expression ARG
|
|
|
++ for certain kinds of expressions which are not really lvalues
|
|
|
++ but which we can accept as lvalues. If FLAG is nonzero, then
|
|
|
++ non-lvalues are OK since we may be converting a non-lvalue array to
|
|
|
++ a pointer in C99.
|
|
|
++
|
|
|
++ If ARG is not a kind of expression we can handle, return zero. */
|
|
|
++
|
|
|
++static tree
|
|
|
++unary_complex_lvalue (enum tree_code code, tree arg, int flag)
|
|
|
++{
|
|
|
++ /* Handle (a, b) used as an "lvalue". */
|
|
|
++ if (TREE_CODE (arg) == COMPOUND_EXPR)
|
|
|
++ {
|
|
|
++ tree real_result = build_unary_op (code, TREE_OPERAND (arg, 1), 0);
|
|
|
++
|
|
|
++ /* If this returns a function type, it isn't really being used as
|
|
|
++ an lvalue, so don't issue a warning about it. */
|
|
|
++ if (TREE_CODE (TREE_TYPE (arg)) != FUNCTION_TYPE && !flag)
|
|
|
++ pedantic_lvalue_warning (COMPOUND_EXPR);
|
|
|
++
|
|
|
++ return build (COMPOUND_EXPR, TREE_TYPE (real_result),
|
|
|
++ TREE_OPERAND (arg, 0), real_result);
|
|
|
++ }
|
|
|
++
|
|
|
++ /* Handle (a ? b : c) used as an "lvalue". */
|
|
|
++ if (TREE_CODE (arg) == COND_EXPR)
|
|
|
++ {
|
|
|
++ if (!flag)
|
|
|
++ pedantic_lvalue_warning (COND_EXPR);
|
|
|
++ if (TREE_CODE (TREE_TYPE (arg)) != FUNCTION_TYPE && !flag)
|
|
|
++ pedantic_lvalue_warning (COMPOUND_EXPR);
|
|
|
++
|
|
|
++ return (build_conditional_expr
|
|
|
++ (TREE_OPERAND (arg, 0),
|
|
|
++ build_unary_op (code, TREE_OPERAND (arg, 1), flag),
|
|
|
++ build_unary_op (code, TREE_OPERAND (arg, 2), flag)));
|
|
|
++ }
|
|
|
++
|
|
|
++ return 0;
|
|
|
++}
|
|
|
++
|
|
|
++/* If pedantic, warn about improper lvalue. CODE is either COND_EXPR
|
|
|
++ COMPOUND_EXPR, or CONVERT_EXPR (for casts). */
|
|
|
++
|
|
|
++static void
|
|
|
++pedantic_lvalue_warning (enum tree_code code)
|
|
|
++{
|
|
|
++ if (pedantic)
|
|
|
++ switch (code)
|
|
|
++ {
|
|
|
++ case COND_EXPR:
|
|
|
++ pedwarn ("ISO C forbids use of conditional expressions as lvalues");
|
|
|
++ break;
|
|
|
++ case COMPOUND_EXPR:
|
|
|
++ pedwarn ("ISO C forbids use of compound expressions as lvalues");
|
|
|
++ break;
|
|
|
++ default:
|
|
|
++ pedwarn ("ISO C forbids use of cast expressions as lvalues");
|
|
|
++ break;
|
|
|
++ }
|
|
|
++}
|
|
|
++
|
|
|
+ /* Give an error for storing in something that is 'const'. */
|
|
|
+
|
|
|
+ static void
|
|
|
+@@ -3051,7 +3181,7 @@
|
|
|
+ op2 = convert_and_check (result_type, op2);
|
|
|
+
|
|
|
+ if (TREE_CODE (ifexp) == INTEGER_CST)
|
|
|
+- return non_lvalue (integer_zerop (ifexp) ? op2 : op1);
|
|
|
++ return pedantic_non_lvalue (integer_zerop (ifexp) ? op2 : op1);
|
|
|
+
|
|
|
+ return fold (build3 (COND_EXPR, result_type, ifexp, op1, op2));
|
|
|
+ }
|
|
|
+@@ -3304,8 +3434,8 @@
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+- /* Don't let a cast be an lvalue. */
|
|
|
+- if (value == expr)
|
|
|
++ /* If pedantic, don't let a cast be an lvalue. */
|
|
|
++ if (value == expr && pedantic)
|
|
|
+ value = non_lvalue (value);
|
|
|
+
|
|
|
+ return value;
|
|
|
+@@ -3357,6 +3487,45 @@
|
|
|
+
|
|
|
+ newrhs = rhs;
|
|
|
+
|
|
|
++ /* Handle control structure constructs used as "lvalues". */
|
|
|
++
|
|
|
++ switch (TREE_CODE (lhs))
|
|
|
++ {
|
|
|
++ /* Handle (a, b) used as an "lvalue". */
|
|
|
++ case COMPOUND_EXPR:
|
|
|
++ pedantic_lvalue_warning (COMPOUND_EXPR);
|
|
|
++ newrhs = build_modify_expr (TREE_OPERAND (lhs, 1), modifycode, rhs);
|
|
|
++ if (TREE_CODE (newrhs) == ERROR_MARK)
|
|
|
++ return error_mark_node;
|
|
|
++ return build (COMPOUND_EXPR, lhstype,
|
|
|
++ TREE_OPERAND (lhs, 0), newrhs);
|
|
|
++
|
|
|
++ /* Handle (a ? b : c) used as an "lvalue". */
|
|
|
++ case COND_EXPR:
|
|
|
++ pedantic_lvalue_warning (COND_EXPR);
|
|
|
++ rhs = save_expr (rhs);
|
|
|
++ {
|
|
|
++ /* Produce (a ? (b = rhs) : (c = rhs))
|
|
|
++ except that the RHS goes through a save-expr
|
|
|
++ so the code to compute it is only emitted once. */
|
|
|
++ tree cond
|
|
|
++ = build_conditional_expr (TREE_OPERAND (lhs, 0),
|
|
|
++ build_modify_expr (TREE_OPERAND (lhs, 1),
|
|
|
++ modifycode, rhs),
|
|
|
++ build_modify_expr (TREE_OPERAND (lhs, 2),
|
|
|
++ modifycode, rhs));
|
|
|
++ if (TREE_CODE (cond) == ERROR_MARK)
|
|
|
++ return cond;
|
|
|
++ /* Make sure the code to compute the rhs comes out
|
|
|
++ before the split. */
|
|
|
++ return build (COMPOUND_EXPR, TREE_TYPE (lhs),
|
|
|
++ /* But cast it to void to avoid an "unused" error. */
|
|
|
++ convert (void_type_node, rhs), cond);
|
|
|
++ }
|
|
|
++ default:
|
|
|
++ break;
|
|
|
++ }
|
|
|
++
|
|
|
+ /* If a binary op has been requested, combine the old LHS value with the RHS
|
|
|
+ producing the value we should actually store into the LHS. */
|
|
|
+
|
|
|
+@@ -3366,6 +3535,42 @@
|
|
|
+ newrhs = build_binary_op (modifycode, lhs, rhs, 1);
|
|
|
+ }
|
|
|
+
|
|
|
++ /* Handle a cast used as an "lvalue".
|
|
|
++ We have already performed any binary operator using the value as cast.
|
|
|
++ Now convert the result to the cast type of the lhs,
|
|
|
++ and then true type of the lhs and store it there;
|
|
|
++ then convert result back to the cast type to be the value
|
|
|
++ of the assignment. */
|
|
|
++
|
|
|
++ switch (TREE_CODE (lhs))
|
|
|
++ {
|
|
|
++ case NOP_EXPR:
|
|
|
++ case CONVERT_EXPR:
|
|
|
++ case FLOAT_EXPR:
|
|
|
++ case FIX_TRUNC_EXPR:
|
|
|
++ case FIX_FLOOR_EXPR:
|
|
|
++ case FIX_ROUND_EXPR:
|
|
|
++ case FIX_CEIL_EXPR:
|
|
|
++ newrhs = default_function_array_conversion (newrhs);
|
|
|
++ {
|
|
|
++ tree inner_lhs = TREE_OPERAND (lhs, 0);
|
|
|
++ tree result;
|
|
|
++ result = build_modify_expr (inner_lhs, NOP_EXPR,
|
|
|
++ convert (TREE_TYPE (inner_lhs),
|
|
|
++ convert (lhstype, newrhs)));
|
|
|
++ if (TREE_CODE (result) == ERROR_MARK)
|
|
|
++ return result;
|
|
|
++ pedantic_lvalue_warning (CONVERT_EXPR);
|
|
|
++ return convert (TREE_TYPE (lhs), result);
|
|
|
++ }
|
|
|
++
|
|
|
++ default:
|
|
|
++ break;
|
|
|
++ }
|
|
|
++
|
|
|
++ /* Now we have handled acceptable kinds of LHS that are not truly lvalues.
|
|
|
++ Reject anything strange now. */
|
|
|
++
|
|
|
+ if (!lvalue_or_else (lhs, lv_assign))
|
|
|
+ return error_mark_node;
|
|
|
+
|
|
|
+@@ -4083,10 +4288,11 @@
|
|
|
+ {
|
|
|
+ char *ofwhat;
|
|
|
+
|
|
|
+- error ("%s", _(msgid));
|
|
|
+ ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
|
|
|
+ if (*ofwhat)
|
|
|
+- error ("(near initialization for %qs)", ofwhat);
|
|
|
++ error ("%s (near initialization for %qs)", _(msgid), ofwhat);
|
|
|
++ else
|
|
|
++ error ("%s", _(msgid));
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Issue a pedantic warning for a bad initializer component.
|
|
|
+@@ -4098,10 +4304,11 @@
|
|
|
+ {
|
|
|
+ char *ofwhat;
|
|
|
+
|
|
|
+- pedwarn ("%s", _(msgid));
|
|
|
+ ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
|
|
|
+ if (*ofwhat)
|
|
|
+- pedwarn ("(near initialization for %qs)", ofwhat);
|
|
|
++ pedwarn ("%s (near initialization for %qs)", _(msgid), ofwhat);
|
|
|
++ else
|
|
|
++ pedwarn ("%s", _(msgid));
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Issue a warning for a bad initializer component.
|
|
|
+@@ -4113,10 +4320,11 @@
|
|
|
+ {
|
|
|
+ char *ofwhat;
|
|
|
+
|
|
|
+- warning ("%s", _(msgid));
|
|
|
+ ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
|
|
|
+ if (*ofwhat)
|
|
|
+- warning ("(near initialization for %qs)", ofwhat);
|
|
|
++ warning ("%s (near initialization for %qs)", _(msgid), ofwhat);
|
|
|
++ else
|
|
|
++ warning ("%s", _(msgid));
|
|
|
+ }
|
|
|
+
|
|
|
+ /* If TYPE is an array type and EXPR is a parenthesized string
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/c.opt gcc-4.0-20050319-src/gcc/c.opt
|
|
|
+--- gcc-4.0-20050319.orig/gcc/c.opt Sat Mar 19 21:26:50 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/c.opt Wed Mar 23 01:21:02 2005
|
|
|
+@@ -431,7 +431,7 @@
|
|
|
+ Give strings the type \"array of char\"
|
|
|
+
|
|
|
+ Wpointer-sign
|
|
|
+-C ObjC Var(warn_pointer_sign) Init(1)
|
|
|
++C ObjC Var(warn_pointer_sign) Init(0)
|
|
|
+ Warn when a pointer differs in signedness in an assignment.
|
|
|
+
|
|
|
+ ansi
|
|
|
+@@ -456,6 +456,10 @@
|
|
|
+ fasm
|
|
|
+ C ObjC C++ ObjC++
|
|
|
+ Recognize the \"asm\" keyword
|
|
|
++
|
|
|
++fauto-octals
|
|
|
++C ObjC C++ ObjC++
|
|
|
++Numbers starting with zero should be octal (default on).
|
|
|
+
|
|
|
+ fbuiltin
|
|
|
+ C ObjC C++ ObjC++
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/cfgexpand.c gcc-4.0-20050319-src/gcc/cfgexpand.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/cfgexpand.c Thu Feb 24 22:47:18 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/cfgexpand.c Wed Mar 23 01:21:02 2005
|
|
|
+@@ -1129,6 +1129,23 @@
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
++ /* (TIGCC 20050206) If -fno-function-cse, restore function call
|
|
|
++ sequences to their expected form. */
|
|
|
++ if (flag_no_function_cse && TREE_CODE (stmt) == MODIFY_EXPR)
|
|
|
++ {
|
|
|
++ block_stmt_iterator bsi2 = bsi;
|
|
|
++ bsi_next (&bsi2);
|
|
|
++ if (!bsi_end_p (bsi2))
|
|
|
++ {
|
|
|
++ tree call = get_call_expr_in (bsi_stmt (bsi2));
|
|
|
++ if (call && TREE_OPERAND (stmt, 0) == TREE_OPERAND (call, 0)
|
|
|
++ && !TREE_SIDE_EFFECTS (TREE_OPERAND (stmt, 0))
|
|
|
++ && !TREE_SIDE_EFFECTS (TREE_OPERAND (stmt, 1)))
|
|
|
++ {
|
|
|
++ TREE_OPERAND (call, 0) = TREE_OPERAND (stmt, 1);
|
|
|
++ }
|
|
|
++ }
|
|
|
++ }
|
|
|
+ last = get_last_insn ();
|
|
|
+ expand_expr_stmt (stmt);
|
|
|
+ maybe_dump_rtl_for_tree_stmt (stmt, last);
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/collect2.c gcc-4.0-20050319-src/gcc/collect2.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/collect2.c Tue Jan 18 12:36:00 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/collect2.c Wed Mar 23 01:21:02 2005
|
|
|
+@@ -143,6 +143,64 @@
|
|
|
+ #define SCAN_LIBRARIES
|
|
|
+ #endif
|
|
|
+
|
|
|
++/* Patch to allow collect2 to build on MinGW by Lev Serebryakov */
|
|
|
++#ifdef __MINGW32__
|
|
|
++/* We are being compiled with mingw32 as host, so we should prepare some
|
|
|
++ win32 replaces for pipe(), kill(getpid(),...) and vfork() + execv()
|
|
|
++*/
|
|
|
++#include <io.h>
|
|
|
++#include <fcntl.h>
|
|
|
++
|
|
|
++#define pipe(fildes) _pipe((fildes),1024*16,_O_BINARY)
|
|
|
++
|
|
|
++#define WIN32_LEAN_AND_MEAN
|
|
|
++#include <windows.h>
|
|
|
++
|
|
|
++int vfork_execv(char *cmdname, char **argv, int fdout);
|
|
|
++
|
|
|
++/* Helper function for vfork() + execv() replacement. */
|
|
|
++int vfork_execv(char *cmdname, char **argv, int fdout)
|
|
|
++{
|
|
|
++ STARTUPINFO SI;
|
|
|
++ PROCESS_INFORMATION PI;
|
|
|
++ char *params;
|
|
|
++ int plen = 0;
|
|
|
++ int i;
|
|
|
++ BOOL bRes;
|
|
|
++
|
|
|
++ /* Prepare one line with arguments */
|
|
|
++ for(i=0;argv[i];i++) plen += strlen(argv[i]) + 1;
|
|
|
++ plen++;
|
|
|
++ params = xmalloc(plen);
|
|
|
++ strcpy(params,argv[0]);
|
|
|
++ for(i=1;argv[i];i++) strcat(strcat(params," "),argv[i]);
|
|
|
++
|
|
|
++ /* Prepare startup info -- for pipes redirection */
|
|
|
++ memset(&SI,0,sizeof(SI));
|
|
|
++ SI.cb = sizeof(SI);
|
|
|
++ SI.dwFlags = STARTF_USESTDHANDLES;
|
|
|
++ SI.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
|
|
|
++ SI.hStdOutput = (HANDLE)_get_osfhandle(fdout);
|
|
|
++ SI.hStdError = GetStdHandle(STD_ERROR_HANDLE);
|
|
|
++
|
|
|
++ /* Create new process in same console, with redirected (piped) stdout */
|
|
|
++ bRes = CreateProcess(cmdname,params,
|
|
|
++ NULL,NULL, /* Security attributes */
|
|
|
++ FALSE, /* Handle inheritance */
|
|
|
++ 0, /* Flags -- default, in this console, etc */
|
|
|
++ NULL, /* Invironment */
|
|
|
++ NULL, /* CWD */
|
|
|
++ &SI, /* Startup info */
|
|
|
++ &PI); /* Process info */
|
|
|
++ if(!bRes) return -1;
|
|
|
++ CloseHandle(PI.hProcess);
|
|
|
++ CloseHandle(PI.hThread);
|
|
|
++ return 0;
|
|
|
++}
|
|
|
++
|
|
|
++/* END-OF-WIN32-SECTION */
|
|
|
++#endif
|
|
|
++
|
|
|
+ #ifdef USE_COLLECT2
|
|
|
+ int do_collecting = 1;
|
|
|
+ #else
|
|
|
+@@ -420,7 +478,11 @@
|
|
|
+ #endif
|
|
|
+
|
|
|
+ signal (signo, SIG_DFL);
|
|
|
++#ifndef __MINGW32__
|
|
|
+ kill (getpid (), signo);
|
|
|
++#else
|
|
|
++ ExitProcess(signo);
|
|
|
++#endif
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+@@ -2078,6 +2140,7 @@
|
|
|
+ fflush (stderr);
|
|
|
+
|
|
|
+ /* Spawn child nm on pipe. */
|
|
|
++#ifndef __MINGW32__
|
|
|
+ pid = vfork ();
|
|
|
+ if (pid == -1)
|
|
|
+ fatal_perror (VFORK_STRING);
|
|
|
+@@ -2097,6 +2160,11 @@
|
|
|
+ execv (nm_file_name, real_nm_argv);
|
|
|
+ fatal_perror ("execv %s", nm_file_name);
|
|
|
+ }
|
|
|
++#else
|
|
|
++ if(vfork_execv(nm_file_name, real_nm_argv, pipe_fd[1])) {
|
|
|
++ fatal_perror ("vfork+execv %s", nm_file_name);
|
|
|
++ }
|
|
|
++#endif
|
|
|
+
|
|
|
+ /* Parent context from here on. */
|
|
|
+ int_handler = (void (*) (int)) signal (SIGINT, SIG_IGN);
|
|
|
+@@ -2244,6 +2312,7 @@
|
|
|
+ fflush (stderr);
|
|
|
+
|
|
|
+ /* Spawn child ldd on pipe. */
|
|
|
++#ifndef __MINGW32__
|
|
|
+ pid = vfork ();
|
|
|
+ if (pid == -1)
|
|
|
+ fatal_perror (VFORK_STRING);
|
|
|
+@@ -2263,6 +2332,11 @@
|
|
|
+ execv (ldd_file_name, real_ldd_argv);
|
|
|
+ fatal_perror ("execv %s", ldd_file_name);
|
|
|
+ }
|
|
|
++#else
|
|
|
++ if(vfork_execv(ldd_file_name, real_ldd_argv, pipe_fd[1])) {
|
|
|
++ fatal_perror ("vfork+execv %s", nm_file_name);
|
|
|
++ }
|
|
|
++#endif
|
|
|
+
|
|
|
+ /* Parent context from here on. */
|
|
|
+ int_handler = (void (*) (int)) signal (SIGINT, SIG_IGN);
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/combine.c gcc-4.0-20050319-src/gcc/combine.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/combine.c Thu Mar 10 22:29:40 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/combine.c Wed Mar 23 01:21:02 2005
|
|
|
+@@ -4255,8 +4255,10 @@
|
|
|
+ /* x - 0 is the same as x unless x's mode has signed zeros and
|
|
|
+ allows rounding towards -infinity. Under those conditions,
|
|
|
+ 0 - 0 is -0. */
|
|
|
++ /* (TIGCC 20050210) This is invalid independently of the rounding mode
|
|
|
++ for 3-sign-zeros. */
|
|
|
+ if (!(HONOR_SIGNED_ZEROS (GET_MODE (XEXP (x, 0)))
|
|
|
+- && HONOR_SIGN_DEPENDENT_ROUNDING (GET_MODE (XEXP (x, 0))))
|
|
|
++ /*&& HONOR_SIGN_DEPENDENT_ROUNDING (GET_MODE (XEXP (x, 0)))*/)
|
|
|
+ && XEXP (x, 1) == CONST0_RTX (GET_MODE (XEXP (x, 0))))
|
|
|
+ return XEXP (x, 0);
|
|
|
+ break;
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/common.opt gcc-4.0-20050319-src/gcc/common.opt
|
|
|
+--- gcc-4.0-20050319.orig/gcc/common.opt Thu Feb 24 10:24:12 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/common.opt Wed Mar 23 01:21:02 2005
|
|
|
+@@ -424,6 +424,14 @@
|
|
|
+ Perform global common subexpression elimination after register allocation
|
|
|
+ has finished.
|
|
|
+
|
|
|
++fglobal-cast-constructors
|
|
|
++Common Report Var(flag_global_compound_literals) Init(1)
|
|
|
++Make compound literals (cast constructors) global for backwards compatibility
|
|
|
++
|
|
|
++fglobal-compound-literals
|
|
|
++Common Report Var(flag_global_compound_literals) VarExists
|
|
|
++Make compound literals (cast constructors) global for backwards compatibility
|
|
|
++
|
|
|
+ fguess-branch-probability
|
|
|
+ Common Report Var(flag_guess_branch_prob)
|
|
|
+ Enable guessing of branch probabilities
|
|
|
+@@ -515,6 +523,10 @@
|
|
|
+ Common Report Var(flag_merge_constants,2) Init(1)
|
|
|
+ Attempt to merge identical constants and constant variables
|
|
|
+
|
|
|
++fmerge-constant-pools
|
|
|
++Common Report Var(flag_merge_constant_pools) Init(1)
|
|
|
++When merging constants, also merge constant pools
|
|
|
++
|
|
|
+ fmerge-constants
|
|
|
+ Common Report Var(flag_merge_constants,1) VarExists
|
|
|
+ Attempt to merge identical constants across compilation units
|
|
|
+@@ -543,6 +555,10 @@
|
|
|
+ Common RejectNegative Report Var(flag_mudflap_ignore_reads)
|
|
|
+ Ignore read operations when inserting mudflap instrumentation.
|
|
|
+
|
|
|
++freg-relative-
|
|
|
++Common Joined RejectNegative
|
|
|
++-freg-relative-<register> Emit code relative to the base register <register>
|
|
|
++
|
|
|
+ freschedule-modulo-scheduled-loops
|
|
|
+ Common Report Var(flag_resched_modulo_sched)
|
|
|
+ Enable/Disable the traditional scheduling in loops that already passed modulo scheduling
|
|
|
+@@ -952,7 +968,7 @@
|
|
|
+ Assume signed arithmetic overflow wraps around
|
|
|
+
|
|
|
+ fzero-initialized-in-bss
|
|
|
+-Common Report Var(flag_zero_initialized_in_bss) Init(1)
|
|
|
++Common Report Var(flag_zero_initialized_in_bss) Init(0)
|
|
|
+ Put zero initialized data in the bss section
|
|
|
+
|
|
|
+ g
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/config/dbxcoff.h gcc-4.0-20050319-src/gcc/config/dbxcoff.h
|
|
|
+--- gcc-4.0-20050319.orig/gcc/config/dbxcoff.h Sun Oct 24 04:42:46 2004
|
|
|
++++ gcc-4.0-20050319-src/gcc/config/dbxcoff.h Wed Mar 23 01:21:02 2005
|
|
|
+@@ -48,8 +48,13 @@
|
|
|
+
|
|
|
+ /* Like block addresses, stabs line numbers are relative to the
|
|
|
+ current function. */
|
|
|
++/* TIGCC Patch: We don't want COFF line numbers to be function-relative.
|
|
|
++ That's why we write '.ln LINE'. This will break support for existing
|
|
|
++ debuggers, but there are none for TIGCC. The line numbers can be
|
|
|
++ extracted from the .s file, plus they are passed on to the object file
|
|
|
++ symbol table. */
|
|
|
+
|
|
|
+-#define DBX_LINES_FUNCTION_RELATIVE 1
|
|
|
++#define DBX_LINES_FUNCTION_RELATIVE (!TARGET_COFFABSLINES)
|
|
|
+
|
|
|
+ /* When generating stabs debugging, use N_BINCL entries. */
|
|
|
+
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/config/i386/xm-mingw32.h gcc-4.0-20050319-src/gcc/config/i386/xm-mingw32.h
|
|
|
+--- gcc-4.0-20050319.orig/gcc/config/i386/xm-mingw32.h Wed Nov 24 05:31:58 2004
|
|
|
++++ gcc-4.0-20050319-src/gcc/config/i386/xm-mingw32.h Wed Mar 23 01:21:02 2005
|
|
|
+@@ -20,6 +20,10 @@
|
|
|
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|
|
+ 02111-1307, USA. */
|
|
|
+
|
|
|
++/* Mingw32 does not try to hide the underlying DOS-based file system
|
|
|
++ like Cygwin does. */
|
|
|
++#define HAVE_DOS_BASED_FILE_SYSTEM
|
|
|
++
|
|
|
+ #define HOST_EXECUTABLE_SUFFIX ".exe"
|
|
|
+
|
|
|
+ #undef PATH_SEPARATOR
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/config/m68k/m68k-modes.def gcc-4.0-20050319-src/gcc/config/m68k/m68k-modes.def
|
|
|
+--- gcc-4.0-20050319.orig/gcc/config/m68k/m68k-modes.def Sun Oct 17 21:09:40 2004
|
|
|
++++ gcc-4.0-20050319-src/gcc/config/m68k/m68k-modes.def Wed Mar 23 01:21:02 2005
|
|
|
+@@ -18,5 +18,6 @@
|
|
|
+ the Free Software Foundation, 59 Temple Place - Suite 330,
|
|
|
+ Boston, MA 02111-1307, USA. */
|
|
|
+
|
|
|
+-/* 80-bit floating point (IEEE extended, in a 96-bit field) */
|
|
|
+-FRACTIONAL_FLOAT_MODE (XF, 80, 12, ieee_extended_motorola_format);
|
|
|
++FLOAT_MODE (BF, 10, 0);
|
|
|
++FLOAT_MODE (XF, 12, 0);
|
|
|
++
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/config/m68k/m68k-none.h gcc-4.0-20050319-src/gcc/config/m68k/m68k-none.h
|
|
|
+--- gcc-4.0-20050319.orig/gcc/config/m68k/m68k-none.h Sat Oct 11 06:06:44 2003
|
|
|
++++ gcc-4.0-20050319-src/gcc/config/m68k/m68k-none.h Wed Mar 23 01:21:02 2005
|
|
|
+@@ -18,10 +18,12 @@
|
|
|
+ the Free Software Foundation, 59 Temple Place - Suite 330,
|
|
|
+ Boston, MA 02111-1307, USA. */
|
|
|
+
|
|
|
+-/* Default to m68k (m68020). */
|
|
|
+-#ifndef TARGET_CPU_DEFAULT
|
|
|
+-#define TARGET_CPU_DEFAULT M68K_CPU_m68k
|
|
|
+-#endif
|
|
|
++/* Define the appropriate flags for the TI's architecture */
|
|
|
++#undef TARGET_CPU_DEFAULT
|
|
|
++#define TARGET_CPU_DEFAULT M68K_CPU_m68000
|
|
|
++
|
|
|
++#undef TARGET_DEFAULT
|
|
|
++#define TARGET_DEFAULT ((TARGET_CPU_DEFAULT >> 4) | MASK_SHORT | MASK_TIOS | MASK_MERGE_SECTIONS)
|
|
|
+
|
|
|
+ /* These are values set by the configure script in TARGET_CPU_DEFAULT.
|
|
|
+ They are (sequential integer + (desired value for TARGET_DEFAULT) << 4). */
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/config/m68k/m68k-protos.h gcc-4.0-20050319-src/gcc/config/m68k/m68k-protos.h
|
|
|
+--- gcc-4.0-20050319.orig/gcc/config/m68k/m68k-protos.h Fri Oct 22 15:47:24 2004
|
|
|
++++ gcc-4.0-20050319-src/gcc/config/m68k/m68k-protos.h Wed Mar 23 01:21:02 2005
|
|
|
+@@ -44,6 +44,13 @@
|
|
|
+ extern int floating_exact_log2 (rtx);
|
|
|
+ extern bool strict_low_part_peephole_ok (enum machine_mode mode, rtx first_insn, rtx target);
|
|
|
+
|
|
|
++/* begin-TIGCC-local (regparms): explicit register specification for parameters */
|
|
|
++void amigaos_init_cumulative_args(struct m68k_args *, tree, tree);
|
|
|
++void amigaos_function_arg_advance(struct m68k_args *);
|
|
|
++struct rtx_def *amigaos_function_arg(struct m68k_args *, enum machine_mode, tree);
|
|
|
++/* end-TIGCC-local (regparms) */
|
|
|
++void m68k_asm_file_start(void);
|
|
|
++
|
|
|
+ /* Functions from m68k.c used in macros. */
|
|
|
+ extern int standard_68881_constant_p (rtx);
|
|
|
+ extern void print_operand_address (FILE *, rtx);
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/config/m68k/m68k-ti.h gcc-4.0-20050319-src/gcc/config/m68k/m68k-ti.h
|
|
|
+--- gcc-4.0-20050319.orig/gcc/config/m68k/m68k-ti.h Thu Jan 1 01:00:00 1970
|
|
|
++++ gcc-4.0-20050319-src/gcc/config/m68k/m68k-ti.h Wed Mar 23 01:21:02 2005
|
|
|
+@@ -0,0 +1,206 @@
|
|
|
++/* Definitions of target machine for GNU compiler.
|
|
|
++ TI-68k architecture (68000),
|
|
|
++ COFF object files and debugging version.
|
|
|
++ Derived in part from m68kemb.h and other files.
|
|
|
++ Copyright (C) 1994 Free Software Foundation, Inc.
|
|
|
++ Copyright (C) 2000 mmu_man (François Revol)
|
|
|
++ (Modified by Sebastian Reichelt for the Windows release of TIGCC)
|
|
|
++
|
|
|
++This file is part of TIGCC.
|
|
|
++
|
|
|
++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. */
|
|
|
++
|
|
|
++/* Define the output of the target version */
|
|
|
++
|
|
|
++#undef TARGET_VERSION
|
|
|
++#define TARGET_VERSION fprintf (stderr, " (MC68000 TI with COFF output)");
|
|
|
++
|
|
|
++/* Even if we compile with -mlong, we want only 16-bit alignment. */
|
|
|
++
|
|
|
++#undef PARM_BOUNDARY
|
|
|
++#define PARM_BOUNDARY 16
|
|
|
++
|
|
|
++/* Don't default to pcc-struct-return, so that we can return small
|
|
|
++ structures and unions in registers, which is slightly more
|
|
|
++ efficient. There are probably no TIOS routines returning structs;
|
|
|
++ if there are, the appropriate program will have to be compiled
|
|
|
++ with the "-fpcc-struct-return" option. But that option will cause
|
|
|
++ problems with ROM_CALLs returning a HSym, which is defined as a
|
|
|
++ structure in TIGCC. */
|
|
|
++
|
|
|
++#undef DEFAULT_PCC_STRUCT_RETURN
|
|
|
++#define DEFAULT_PCC_STRUCT_RETURN 0
|
|
|
++
|
|
|
++/* In order for bitfields to work on a 68000, or with -mnobitfield, we must
|
|
|
++ define either PCC_BITFIELD_TYPE_MATTERS or STRUCTURE_SIZE_BOUNDARY.
|
|
|
++ Defining STRUCTURE_SIZE_BOUNDARY results in structure packing problems,
|
|
|
++ so we define PCC_BITFIELD_TYPE_MATTERS. */
|
|
|
++
|
|
|
++#define PCC_BITFIELD_TYPE_MATTERS 1
|
|
|
++
|
|
|
++/* Undefine PCC_STATIC_STRUCT_RETURN so that we get a re-entrant
|
|
|
++ calling convention (whatever that means). */
|
|
|
++
|
|
|
++#undef PCC_STATIC_STRUCT_RETURN
|
|
|
++
|
|
|
++/* Define how to generate (in the callee) the output value of a
|
|
|
++ function and how to find (in the caller) the value returned by a
|
|
|
++ function. VALTYPE is the data type of the value (as a tree). If
|
|
|
++ the precise function being called is known, FUNC is its
|
|
|
++ FUNCTION_DECL; otherwise, FUNC is 0. When calling TIOS functions,
|
|
|
++ find the result in d0 or a0 as appropriate. */
|
|
|
++
|
|
|
++#undef FUNCTION_VALUE
|
|
|
++#define FUNCTION_VALUE(VALTYPE, FUNC) \
|
|
|
++ (((TARGET_TIOS) && (POINTER_TYPE_P (VALTYPE))) \
|
|
|
++ ? gen_rtx_REG (TYPE_MODE (VALTYPE), 8) \
|
|
|
++ : LIBCALL_VALUE (TYPE_MODE (VALTYPE)))
|
|
|
++
|
|
|
++/* Define how to find a library call return value. Usually the value will be
|
|
|
++ in d0 (thru d1 or d2), but floats should be assumed to be returned in a
|
|
|
++ stack frame. This happens automatically if the specified register (d1 in
|
|
|
++ this case) is not a possible register for returning the value, because
|
|
|
++ floats take up 3 registers. Never use direct floats if d3 is clobbered
|
|
|
++ by function calls. */
|
|
|
++
|
|
|
++#undef LIBCALL_VALUE
|
|
|
++#define LIBCALL_VALUE(MODE) \
|
|
|
++ (((TARGET_DIRECTFLOAT) && ((MODE) == BFmode)) \
|
|
|
++ ? gen_rtx_REG (MODE, 1) \
|
|
|
++ : gen_rtx_REG (MODE, 0))
|
|
|
++
|
|
|
++/* 1 if N is a possible register number for a function value. For
|
|
|
++ calling TIOS functions, allow a0 in addition to d0 (see above). */
|
|
|
++
|
|
|
++#undef FUNCTION_VALUE_REGNO_P
|
|
|
++#define FUNCTION_VALUE_REGNO_P(N) \
|
|
|
++ (((N) == 0) || (TARGET_TIOS && ((N) == 8)) || (TARGET_DIRECTFLOAT && ((N) == 1)))
|
|
|
++
|
|
|
++/* Define this to be true when FUNCTION_VALUE_REGNO_P is true for
|
|
|
++ more than one register (see above). */
|
|
|
++
|
|
|
++#undef NEEDS_UNTYPED_CALL
|
|
|
++#define NEEDS_UNTYPED_CALL (TARGET_TIOS || TARGET_DIRECTFLOAT)
|
|
|
++
|
|
|
++/* This says how to output an assembler line
|
|
|
++ to define a global common symbol. */
|
|
|
++
|
|
|
++#undef ASM_OUTPUT_COMMON
|
|
|
++#define ASM_OUTPUT_COMMON(FILE,NAME,SIZE,ROUNDED) \
|
|
|
++do { \
|
|
|
++ if (TARGET_NO_BSS && ((NAME) [0] != '_')) \
|
|
|
++ { \
|
|
|
++ long i; \
|
|
|
++ fputs (".globl ", (FILE)); \
|
|
|
++ assemble_name ((FILE), (NAME)); \
|
|
|
++ fputs ("\n\t.even\n", (FILE)); \
|
|
|
++ assemble_name ((FILE), (NAME)); \
|
|
|
++ fputs (":\n", (FILE)); \
|
|
|
++ fprintf ((FILE), "\t.space %u\n", (unsigned)(ROUNDED)); \
|
|
|
++ fputs ("\t.even\n", (FILE)); \
|
|
|
++ } \
|
|
|
++ else \
|
|
|
++ { \
|
|
|
++ fputs (".comm ", (FILE)); \
|
|
|
++ assemble_name ((FILE), (NAME)); \
|
|
|
++ fprintf ((FILE), ",%u\n", (unsigned)(ROUNDED)); \
|
|
|
++ } \
|
|
|
++} while (0)
|
|
|
++
|
|
|
++/* This says how to output an assembler line
|
|
|
++ to define a local common symbol. */
|
|
|
++
|
|
|
++#undef ASM_OUTPUT_LOCAL
|
|
|
++#define ASM_OUTPUT_LOCAL(FILE,NAME,SIZE,ROUNDED) \
|
|
|
++do { \
|
|
|
++ if (TARGET_NO_BSS) \
|
|
|
++ { \
|
|
|
++ long i; \
|
|
|
++ fputs ("\t.even\n", (FILE)); \
|
|
|
++ assemble_name ((FILE), (NAME)); \
|
|
|
++ fputs (":\n", (FILE)); \
|
|
|
++ fprintf ((FILE), "\t.space %u\n", (unsigned)(ROUNDED)); \
|
|
|
++ fputs ("\t.even\n", (FILE)); \
|
|
|
++ } \
|
|
|
++ else \
|
|
|
++ { \
|
|
|
++ fputs (".lcomm ", (FILE)); \
|
|
|
++ assemble_name ((FILE), (NAME)); \
|
|
|
++ fprintf ((FILE), ",%u\n", (unsigned)(ROUNDED)); \
|
|
|
++ } \
|
|
|
++} while (0)
|
|
|
++
|
|
|
++/* If TARGET_MERGE_SECTIONS is set (on by default): if TARGET_MERGE_TO_DATA is
|
|
|
++ set, only use data sections, otherwise only use text sections. Both code and
|
|
|
++ data in RAM programs on a TI-89/92+/V200 are always writable; that's why it
|
|
|
++ does not make sense to have different data and text sections.
|
|
|
++ Those cannot be set to an empty string, since a number may follow, etc.
|
|
|
++ Anyway, better more than less. */
|
|
|
++
|
|
|
++#undef TEXT_SECTION_ASM_OP
|
|
|
++#define TEXT_SECTION_ASM_OP ((TARGET_MERGE_SECTIONS && TARGET_MERGE_TO_DATA)? \
|
|
|
++ "\t.data":"\t.text")
|
|
|
++
|
|
|
++#undef DATA_SECTION_ASM_OP
|
|
|
++#define DATA_SECTION_ASM_OP ((TARGET_MERGE_SECTIONS && !TARGET_MERGE_TO_DATA)? \
|
|
|
++ "\t.text":"\t.data")
|
|
|
++
|
|
|
++/* If TARGET_NO_BSS is set (off by default), use the data section here.
|
|
|
++ Otherwise use the BSS section. */
|
|
|
++
|
|
|
++#undef BSS_SECTION_ASM_OP
|
|
|
++#define BSS_SECTION_ASM_OP (TARGET_NO_BSS?DATA_SECTION_ASM_OP:"\t.section .bss")
|
|
|
++
|
|
|
++/* When not merging sections, put read-only data into .data unless
|
|
|
++ TARGET_RODATA_TO_TEXT is set. But jump tables do NOT qualify for going into
|
|
|
++ the data section! */
|
|
|
++#define READONLY_DATA_SECTION() (TARGET_RODATA_TO_TEXT ? text_section() \
|
|
|
++ : data_section())
|
|
|
++#define JUMP_TABLES_IN_TEXT_SECTION 1
|
|
|
++
|
|
|
++/* Define "__INT_SHORT__" if short ints are set, e.g. if the "-mlong" switch
|
|
|
++ is not used. This is necessary for the TIGCC Library, since INT_MAX and
|
|
|
++ others need to be constants. */
|
|
|
++
|
|
|
++#undef CPP_SUBTARGET_SPEC
|
|
|
++#if (defined(__CYGWIN__) || defined(__WIN32__))
|
|
|
++#define CPP_SUBTARGET_SPEC "-D__TIGCC_ENV__ -D__TIGCC_WIN_ENV__ %{!mlong:%{!mnoshort:%{!mno-short:-D__INT_SHORT__ }}}"
|
|
|
++#else
|
|
|
++#define CPP_SUBTARGET_SPEC "-D__TIGCC_ENV__ %{!mlong:%{!mnoshort:%{!mno-short:-D__INT_SHORT__ }}}"
|
|
|
++#endif
|
|
|
++
|
|
|
++/* Trampolines are code on the stack, so we need to add 0x40000 to their address
|
|
|
++ for it to work on a TI-89/92+/V200 HW2. On HW3, we should NOT add that
|
|
|
++ address. Moreover, EXECUTE_IN_GHOST_SPACE is required for it to work
|
|
|
++ correctly. Therefore, I am emitting a libcall and letting TIGCCLIB worry
|
|
|
++ about the details.
|
|
|
++ (code partially lifted from gcc/config/sh/sh.h) */
|
|
|
++#define TRAMPOLINE_ADJUST_ADDRESS(TRAMP) do \
|
|
|
++{ \
|
|
|
++ (TRAMP) = expand_simple_binop (Pmode, PLUS, (TRAMP), \
|
|
|
++ emit_library_call_value (gen_rtx_SYMBOL_REF (\
|
|
|
++ Pmode, \
|
|
|
++ "__trampoline_offset"), \
|
|
|
++ NULL_RTX, LCT_CONST, \
|
|
|
++ Pmode, 0), \
|
|
|
++ gen_reg_rtx (Pmode), 0, \
|
|
|
++ OPTAB_LIB_WIDEN); \
|
|
|
++} while (0)
|
|
|
++
|
|
|
++/* We want -fomit-frame-pointer by default. */
|
|
|
++#define CAN_DEBUG_WITHOUT_FP
|
|
|
++
|
|
|
++/* end of m68k-ti.h */
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/config/m68k/m68k.c gcc-4.0-20050319-src/gcc/config/m68k/m68k.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/config/m68k/m68k.c Thu Feb 24 02:50:32 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/config/m68k/m68k.c Wed Mar 23 01:21:02 2005
|
|
|
+@@ -43,6 +43,11 @@
|
|
|
+ #include "target-def.h"
|
|
|
+ #include "debug.h"
|
|
|
+ #include "flags.h"
|
|
|
++#include "c-pragma.h"
|
|
|
++#include "cgraph.h"
|
|
|
++
|
|
|
++/* TIGCC register for reg-relative code. */
|
|
|
++char TARGET_RELATION_REG[10] = "a4";
|
|
|
+
|
|
|
+ enum reg_class regno_reg_class[] =
|
|
|
+ {
|
|
|
+@@ -121,10 +126,19 @@
|
|
|
+ static bool m68k_save_reg (unsigned int regno, bool interrupt_handler);
|
|
|
+ static int const_int_cost (rtx);
|
|
|
+ static bool m68k_rtx_costs (rtx, int, int, int *);
|
|
|
++
|
|
|
++static int comp_m68k_type_attributes (tree, tree);
|
|
|
++static int comp_amigaos_type_attributes (tree, tree);
|
|
|
++static tree m68k_handle_stkparm_attribute (tree *, tree, tree, int, bool *);
|
|
|
++static tree m68k_handle_regparm_attribute (tree *, tree, tree, int, bool *);
|
|
|
+
|
|
|
+
|
|
|
+ /* Specify the identification number of the library being built */
|
|
|
+ const char *m68k_library_id_string;
|
|
|
++/* Specify number of registers for integer, pointer and float arguments. */
|
|
|
++const char *m68k_regparm_string;
|
|
|
++/* Specify number of registers for integer, pointer and float arguments. */
|
|
|
++int m68k_regparm;
|
|
|
+
|
|
|
+ /* Nonzero if the last compare/test insn had FP operands. The
|
|
|
+ sCC expanders peek at this to determine what to do for the
|
|
|
+@@ -132,6 +146,8 @@
|
|
|
+ int m68k_last_compare_had_fp_operands;
|
|
|
+
|
|
|
+ /* Initialize the GCC target structure. */
|
|
|
++#undef TARGET_COMP_TYPE_ATTRIBUTES
|
|
|
++#define TARGET_COMP_TYPE_ATTRIBUTES comp_amigaos_type_attributes
|
|
|
+
|
|
|
+ #if INT_OP_GROUP == INT_OP_DOT_WORD
|
|
|
+ #undef TARGET_ASM_ALIGNED_HI_OP
|
|
|
+@@ -180,15 +196,29 @@
|
|
|
+ #undef TARGET_ATTRIBUTE_TABLE
|
|
|
+ #define TARGET_ATTRIBUTE_TABLE m68k_attribute_table
|
|
|
+
|
|
|
++/* Pass the right values to functions whose prototypes contain "char"
|
|
|
++ or "short". */
|
|
|
++#if 0
|
|
|
+ #undef TARGET_PROMOTE_PROTOTYPES
|
|
|
+ #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ #undef TARGET_STRUCT_VALUE_RTX
|
|
|
+ #define TARGET_STRUCT_VALUE_RTX m68k_struct_value_rtx
|
|
|
+
|
|
|
++#undef TARGET_ASM_FILE_START
|
|
|
++#define TARGET_ASM_FILE_START m68k_asm_file_start
|
|
|
++
|
|
|
+ static const struct attribute_spec m68k_attribute_table[] =
|
|
|
+ {
|
|
|
+ /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
|
|
|
++ /* The stkparm attribute means a function takes its parameters on the stack
|
|
|
++ (AMS calling convention). */
|
|
|
++ { "stkparm", 0, 0, false, true, true, m68k_handle_stkparm_attribute },
|
|
|
++ /* The regparm attribute means a function takes its parameters in registers.
|
|
|
++ Its optional argument specifies the maximum number of arguments to be
|
|
|
++ passed in each category of registers (data registers, address registers). */
|
|
|
++ { "regparm", 0, 1, false, true, true, m68k_handle_regparm_attribute },
|
|
|
+ { "interrupt_handler", 0, 0, true, false, false, m68k_handle_fndecl_attribute },
|
|
|
+ { NULL, 0, 0, false, false, false, NULL }
|
|
|
+ };
|
|
|
+@@ -226,6 +256,19 @@
|
|
|
+ current library. */
|
|
|
+ m68k_library_id_string = "_current_shared_library_a5_offset_";
|
|
|
+
|
|
|
++ /* Validate -mregparm and -mregparm= value. */
|
|
|
++ if (m68k_regparm_string)
|
|
|
++ {
|
|
|
++ m68k_regparm = atoi (m68k_regparm_string);
|
|
|
++ if (m68k_regparm < 1 || m68k_regparm > M68K_MAX_REGPARM)
|
|
|
++ error ("-mregparm=%d is not between 1 and %d",
|
|
|
++ m68k_regparm, M68K_MAX_REGPARM);
|
|
|
++ target_flags |= MASK_REGPARM;
|
|
|
++ }
|
|
|
++ else
|
|
|
++ if (TARGET_REGPARM)
|
|
|
++ m68k_regparm = M68K_DEFAULT_REGPARM;
|
|
|
++
|
|
|
+ /* Sanity check to ensure that msep-data and mid-sahred-library are not
|
|
|
+ * both specified together. Doing so simply doesn't make sense.
|
|
|
+ */
|
|
|
+@@ -261,6 +304,116 @@
|
|
|
+ SUBTARGET_OVERRIDE_OPTIONS;
|
|
|
+ }
|
|
|
+
|
|
|
++/* Handle a "stkparm" attribute;
|
|
|
++ arguments as in struct attribute_spec.handler. */
|
|
|
++static tree
|
|
|
++m68k_handle_stkparm_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
|
|
|
++ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
|
|
|
++{
|
|
|
++ if (lookup_attribute ("regparm", TYPE_ATTRIBUTES (*node)))
|
|
|
++ {
|
|
|
++ error ("`regparm' and `stkparm' are mutually exclusive");
|
|
|
++ *no_add_attrs = true;
|
|
|
++ }
|
|
|
++
|
|
|
++ if (TREE_CODE (*node) != FUNCTION_TYPE
|
|
|
++ && TREE_CODE (*node) != METHOD_TYPE
|
|
|
++ && TREE_CODE (*node) != FIELD_DECL
|
|
|
++ && TREE_CODE (*node) != TYPE_DECL)
|
|
|
++ {
|
|
|
++ warning ("`%s' attribute only applies to functions",
|
|
|
++ IDENTIFIER_POINTER (name));
|
|
|
++ *no_add_attrs = true;
|
|
|
++ }
|
|
|
++
|
|
|
++ return NULL_TREE;
|
|
|
++}
|
|
|
++
|
|
|
++/* Handle a "regparm" attribute;
|
|
|
++ arguments as in struct attribute_spec.handler. */
|
|
|
++static tree
|
|
|
++m68k_handle_regparm_attribute (tree *node, tree name, tree args,
|
|
|
++ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
|
|
|
++{
|
|
|
++ if (lookup_attribute ("stkparm", TYPE_ATTRIBUTES (*node)))
|
|
|
++ {
|
|
|
++ error ("`regparm' and `stkparm' are mutually exclusive");
|
|
|
++ *no_add_attrs = true;
|
|
|
++ }
|
|
|
++
|
|
|
++ if (TREE_CODE (*node) != FUNCTION_TYPE
|
|
|
++ && TREE_CODE (*node) != METHOD_TYPE
|
|
|
++ && TREE_CODE (*node) != FIELD_DECL
|
|
|
++ && TREE_CODE (*node) != TYPE_DECL)
|
|
|
++ {
|
|
|
++ warning ("`%s' attribute only applies to functions",
|
|
|
++ IDENTIFIER_POINTER (name));
|
|
|
++ *no_add_attrs = true;
|
|
|
++ }
|
|
|
++ else
|
|
|
++ {
|
|
|
++ /* 'regparm' accepts one optional argument - number of registers per
|
|
|
++ single class (data, address) that should be used to pass arguments. */
|
|
|
++ if (args && TREE_CODE (args) == TREE_LIST)
|
|
|
++ {
|
|
|
++ tree numofregs = TREE_VALUE (args);
|
|
|
++ if (numofregs)
|
|
|
++ if (TREE_CODE (numofregs) != INTEGER_CST
|
|
|
++ || TREE_INT_CST_HIGH (numofregs)
|
|
|
++ || TREE_INT_CST_LOW (numofregs) < 1
|
|
|
++ || TREE_INT_CST_LOW (numofregs) > M68K_MAX_REGPARM)
|
|
|
++ {
|
|
|
++ error ("invalid argument to `regparm' attribute");
|
|
|
++ *no_add_attrs = true;
|
|
|
++ }
|
|
|
++ }
|
|
|
++ }
|
|
|
++
|
|
|
++ return NULL_TREE;
|
|
|
++}
|
|
|
++
|
|
|
++/* Return zero if the attributes on TYPE1 and TYPE2 are incompatible,
|
|
|
++ one if they are compatible, and two if they are nearly compatible
|
|
|
++ (which causes a warning to be generated). */
|
|
|
++
|
|
|
++int
|
|
|
++comp_m68k_type_attributes (tree type1, tree type2)
|
|
|
++{
|
|
|
++ /* Functions or methods are incompatible if they specify mutually
|
|
|
++ exclusive ways of passing arguments. */
|
|
|
++ if (TREE_CODE (type1) == FUNCTION_TYPE || TREE_CODE (type1) == METHOD_TYPE)
|
|
|
++ {
|
|
|
++ tree arg1, arg2;
|
|
|
++ if (!! lookup_attribute ("stkparm", TYPE_ATTRIBUTES (type1)) !=
|
|
|
++ !! lookup_attribute ("stkparm", TYPE_ATTRIBUTES (type2))
|
|
|
++ || !! lookup_attribute ("regparm", TYPE_ATTRIBUTES (type1)) !=
|
|
|
++ !! lookup_attribute ("regparm", TYPE_ATTRIBUTES (type2)))
|
|
|
++ return 0; /* 'regparm' and 'stkparm' are mutually exclusive. */
|
|
|
++
|
|
|
++ arg1 = lookup_attribute ("regparm", TYPE_ATTRIBUTES (type1));
|
|
|
++ arg2 = lookup_attribute ("regparm", TYPE_ATTRIBUTES (type2));
|
|
|
++ if (arg1 && arg2)
|
|
|
++ {
|
|
|
++ int num1 = 0, num2 = 0;
|
|
|
++ if (TREE_VALUE (arg1) && TREE_CODE (TREE_VALUE (arg1)) == TREE_LIST)
|
|
|
++ {
|
|
|
++ tree numofregs = TREE_VALUE (TREE_VALUE (arg1));
|
|
|
++ if (numofregs)
|
|
|
++ num1 = TREE_INT_CST_LOW (numofregs);
|
|
|
++ }
|
|
|
++ if (TREE_VALUE (arg2) && TREE_CODE (TREE_VALUE (arg2)) == TREE_LIST)
|
|
|
++ {
|
|
|
++ tree numofregs = TREE_VALUE (TREE_VALUE (arg2));
|
|
|
++ if (numofregs)
|
|
|
++ num2 = TREE_INT_CST_LOW (numofregs);
|
|
|
++ }
|
|
|
++ if (num1 != num2)
|
|
|
++ return 0; /* Different numbers, or no number in one type. */
|
|
|
++ }
|
|
|
++ }
|
|
|
++ return 1;
|
|
|
++}
|
|
|
++
|
|
|
+ /* Return nonzero if FUNC is an interrupt function as specified by the
|
|
|
+ "interrupt_handler" attribute. */
|
|
|
+ static bool
|
|
|
+@@ -371,6 +524,11 @@
|
|
|
+ static bool
|
|
|
+ m68k_save_reg (unsigned int regno, bool interrupt_handler)
|
|
|
+ {
|
|
|
++ /* (TIGCC 20050208) Handle OPTIMIZE_ROM_CALLS. Register #13 is %a5. */
|
|
|
++ if (interrupt_handler && regno == 13 && global_regs[13]
|
|
|
++ && cpp_defined (parse_in, "OPTIMIZE_ROM_CALLS", 18))
|
|
|
++ return true;
|
|
|
++
|
|
|
+ if (flag_pic && regno == PIC_OFFSET_TABLE_REGNUM)
|
|
|
+ {
|
|
|
+ if (current_function_uses_pic_offset_table)
|
|
|
+@@ -631,6 +789,11 @@
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
++
|
|
|
++ /* (TIGCC 20050208) Handle OPTIMIZE_ROM_CALLS. Register #13 is %a5. */
|
|
|
++ if (global_regs[13] && m68k_interrupt_function_p (current_function_decl)
|
|
|
++ && cpp_defined (parse_in, "OPTIMIZE_ROM_CALLS", 18))
|
|
|
++ asm_fprintf (stream, "\tmove.l 200.w,%%a5\n");
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Return true if this function's epilogue can be output as RTL. */
|
|
|
+@@ -670,9 +833,11 @@
|
|
|
+ insn = prev_nonnote_insn (insn);
|
|
|
+ if (insn && GET_CODE (insn) == BARRIER)
|
|
|
+ {
|
|
|
++#if 0 /* (TIGCC 20050206) */
|
|
|
+ /* Output just a no-op so that debuggers don't get confused
|
|
|
+ about which function the pc is in at this address. */
|
|
|
+ fprintf (stream, "\tnop\n");
|
|
|
++#endif /* 0 */
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+@@ -969,8 +1134,17 @@
|
|
|
+ * We'll use the -Os command-line flag to decide which to generate.
|
|
|
+ * Both sequences take the same time to execute on the ColdFire.
|
|
|
+ */
|
|
|
++/* (TIGCC 20040222, 20050204) No long branches please... */
|
|
|
++/* (TIGCC 20050209) FIXME: This should really be handled fully in one place.
|
|
|
++ Currently, part of this logic is in the patching code
|
|
|
++ and part is in GCC. It should be all in GCC IMHO. */
|
|
|
++ else if (TARGET_PCREL && GET_CODE (dest) == MEM
|
|
|
++ && GET_CODE (XEXP (dest, 0)) == SYMBOL_REF
|
|
|
++ && (!strncmp(XSTR (XEXP (dest, 0), 0),"_ROM_CALL_",10)
|
|
|
++ || !strncmp(XSTR (XEXP (dest, 0), 0),"_RAM_CALL_",10)))
|
|
|
++ out = "jbsr %o0";
|
|
|
+ else if (TARGET_PCREL)
|
|
|
+- out = "bsr.l %o0";
|
|
|
++ out = "bsr %o0";
|
|
|
+ else if ((flag_pic == 1) || TARGET_68020)
|
|
|
+ #if defined(USE_GAS)
|
|
|
+ out = "bsr.l %0@PLTPC";
|
|
|
+@@ -1423,11 +1597,11 @@
|
|
|
+
|
|
|
+ typedef enum { MOVL, SWAP, NEGW, NOTW, NOTB, MOVQ, MVS, MVZ } CONST_METHOD;
|
|
|
+
|
|
|
+-static CONST_METHOD const_method (rtx);
|
|
|
++CONST_METHOD const_method (rtx);
|
|
|
+
|
|
|
+ #define USE_MOVQ(i) ((unsigned)((i) + 128) <= 255)
|
|
|
+
|
|
|
+-static CONST_METHOD
|
|
|
++CONST_METHOD
|
|
|
+ const_method (rtx constant)
|
|
|
+ {
|
|
|
+ int i;
|
|
|
+@@ -1529,10 +1703,15 @@
|
|
|
+ for add and the time for shift, taking away a little more because
|
|
|
+ sometimes move insns are needed. */
|
|
|
+ /* div?.w is relatively cheaper on 68000 counted in COSTS_N_INSNS terms. */
|
|
|
++ /* (TIGCC 20030705) Decrease multiplication/division cost under -Os, so that
|
|
|
++ muls/divs/divu gets preferred over large expansions of
|
|
|
++ shifts & adds.
|
|
|
++ -- Kevin Kofler */
|
|
|
+ #define MULL_COST (TARGET_68060 ? 2 : TARGET_68040 ? 5 : (TARGET_COLDFIRE && !TARGET_5200) ? 3 : TARGET_COLDFIRE ? 10 : 13)
|
|
|
+-#define MULW_COST (TARGET_68060 ? 2 : TARGET_68040 ? 3 : TARGET_68020 ? 8 : \
|
|
|
+- (TARGET_COLDFIRE && !TARGET_5200) ? 2 : 5)
|
|
|
+-#define DIVW_COST (TARGET_68020 ? 27 : TARGET_CF_HWDIV ? 11 : 12)
|
|
|
++#define MULW_COST (optimize_size ? 3 : (TARGET_68060 ? 2 : TARGET_68040 ? 3 : TARGET_68020 ? 8 : \
|
|
|
++ (TARGET_COLDFIRE && !TARGET_5200) ? 2 : 5))
|
|
|
++#define DIVW_COST (optimize_size ? 3 : (TARGET_68020 ? 27 : TARGET_CF_HWDIV ? 11 : 12))
|
|
|
++#define UDIVW_COST (optimize_size ? 6 : (TARGET_68020 ? 27 : TARGET_CF_HWDIV ? 11 : 12))
|
|
|
+
|
|
|
+ case PLUS:
|
|
|
+ /* An lea costs about three times as much as a simple add. */
|
|
|
+@@ -1563,11 +1742,15 @@
|
|
|
+ {
|
|
|
+ if (GET_CODE (XEXP (x, 1)) == CONST_INT)
|
|
|
+ {
|
|
|
++/* (TIGCC 20030705) shifts costs under -Os are instruction counts, not cycle counts -- Kevin Kofler */ \
|
|
|
++/* (TIGCC 20050210) lsl #2 is cheaper than 2 adds even when optimizing for speed.
|
|
|
++ This ugly hack (making long shifts "cost less" than word
|
|
|
++ shifts) accounts for that. */ \
|
|
|
+ if (INTVAL (XEXP (x, 1)) < 16)
|
|
|
+- *total = COSTS_N_INSNS (2) + INTVAL (XEXP (x, 1)) / 2;
|
|
|
++ *total = COSTS_N_INSNS (2) + INTVAL (XEXP (x, 1)) / (optimize_size ? 9 : GET_MODE (x) == SImode ? 3 : 2);
|
|
|
+ else
|
|
|
+ /* We're using clrw + swap for these cases. */
|
|
|
+- *total = COSTS_N_INSNS (4) + (INTVAL (XEXP (x, 1)) - 16) / 2;
|
|
|
++ *total = COSTS_N_INSNS (4) + (INTVAL (XEXP (x, 1)) - 16) / (optimize_size ? 9 : GET_MODE (x) == SImode ? 3 : 2);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ *total = COSTS_N_INSNS (10); /* worst case */
|
|
|
+@@ -1600,10 +1783,10 @@
|
|
|
+ *total = COSTS_N_INSNS (MULL_COST);
|
|
|
+ return true;
|
|
|
+
|
|
|
++/* (TIGCC 20030705) distinguish signed vs. unsigned division */ \
|
|
|
++/* - ext is cheaper than the unsigned equivalent -- Kevin Kofler */ \
|
|
|
+ case DIV:
|
|
|
+- case UDIV:
|
|
|
+ case MOD:
|
|
|
+- case UMOD:
|
|
|
+ if (GET_MODE (x) == QImode || GET_MODE (x) == HImode)
|
|
|
+ *total = COSTS_N_INSNS (DIVW_COST); /* div.w */
|
|
|
+ else if (TARGET_CF_HWDIV)
|
|
|
+@@ -1612,6 +1795,16 @@
|
|
|
+ *total = COSTS_N_INSNS (43); /* div.l */
|
|
|
+ return true;
|
|
|
+
|
|
|
++ case UDIV: \
|
|
|
++ case UMOD: \
|
|
|
++ if (GET_MODE (x) == QImode || GET_MODE (x) == HImode)
|
|
|
++ *total = COSTS_N_INSNS (UDIVW_COST); /* div.w */
|
|
|
++ else if (TARGET_CF_HWDIV)
|
|
|
++ *total = COSTS_N_INSNS (18);
|
|
|
++ else
|
|
|
++ *total = COSTS_N_INSNS (43); /* div.l */
|
|
|
++ return true;
|
|
|
++
|
|
|
+ default:
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+@@ -1828,6 +2021,24 @@
|
|
|
+ return "move%.b %1,%0";
|
|
|
+ }
|
|
|
+
|
|
|
++static const char *
|
|
|
++output_move_himode_const (rtx *operands)
|
|
|
++{
|
|
|
++ if (operands[1] == const0_rtx
|
|
|
++ && (DATA_REG_P (operands[0])
|
|
|
++ || GET_CODE (operands[0]) == MEM)
|
|
|
++ /* clr insns on 68000 read before writing.
|
|
|
++ This isn't so on the 68010, but we have no TARGET_68010. */
|
|
|
++ && ((TARGET_68020 || TARGET_5200)
|
|
|
++ || !(GET_CODE (operands[0]) == MEM
|
|
|
++ && MEM_VOLATILE_P (operands[0]))))
|
|
|
++ return "clr%.w %0";
|
|
|
++ else if (operands[1] == const0_rtx
|
|
|
++ && ADDRESS_REG_P (operands[0]))
|
|
|
++ return "sub%.w %0,%0";
|
|
|
++ return "move%.w %1,%0";
|
|
|
++}
|
|
|
++
|
|
|
+ const char *
|
|
|
+ output_move_stricthi (rtx *operands)
|
|
|
+ {
|
|
|
+@@ -1852,6 +2063,17 @@
|
|
|
+ return "move%.b %1,%0";
|
|
|
+ }
|
|
|
+
|
|
|
++/* (TIGCC) Return the best assembler insn template
|
|
|
++ for moving operands[1] into operands[0] as a halfword. */
|
|
|
++
|
|
|
++static const char *
|
|
|
++halfsinglemove_string (rtx *operands)
|
|
|
++{
|
|
|
++ if (GET_CODE (operands[1]) == CONST_INT)
|
|
|
++ return output_move_himode_const (operands);
|
|
|
++ return "move%.w %1,%0";
|
|
|
++}
|
|
|
++
|
|
|
+ /* Return the best assembler insn template
|
|
|
+ for moving operands[1] into operands[0] as a fullword. */
|
|
|
+
|
|
|
+@@ -1930,10 +2152,14 @@
|
|
|
+ operands[0] = XEXP (XEXP (operands[0], 0), 0);
|
|
|
+ if (size == 12)
|
|
|
+ output_asm_insn ("sub%.l #12,%0", operands);
|
|
|
++ else if (size == 10)
|
|
|
++ output_asm_insn ("sub%.l #10,%0", operands);
|
|
|
+ else
|
|
|
+ output_asm_insn ("subq%.l #8,%0", operands);
|
|
|
+- if (GET_MODE (operands[1]) == XFmode)
|
|
|
++ if (GET_MODE (operands[0]) == XFmode)
|
|
|
+ operands[0] = gen_rtx_MEM (XFmode, operands[0]);
|
|
|
++ else if (GET_MODE (operands[0]) == BFmode)
|
|
|
++ operands[0] = gen_rtx_MEM (BFmode, operands[0]);
|
|
|
+ else if (GET_MODE (operands[0]) == DFmode)
|
|
|
+ operands[0] = gen_rtx_MEM (DFmode, operands[0]);
|
|
|
+ else
|
|
|
+@@ -1945,10 +2171,14 @@
|
|
|
+ operands[1] = XEXP (XEXP (operands[1], 0), 0);
|
|
|
+ if (size == 12)
|
|
|
+ output_asm_insn ("sub%.l #12,%1", operands);
|
|
|
++ else if (size == 10)
|
|
|
++ output_asm_insn ("sub%.l #10,%1", operands);
|
|
|
+ else
|
|
|
+ output_asm_insn ("subq%.l #8,%1", operands);
|
|
|
+ if (GET_MODE (operands[1]) == XFmode)
|
|
|
+ operands[1] = gen_rtx_MEM (XFmode, operands[1]);
|
|
|
++ else if (GET_MODE (operands[1]) == BFmode)
|
|
|
++ operands[1] = gen_rtx_MEM (BFmode, operands[1]);
|
|
|
+ else if (GET_MODE (operands[1]) == DFmode)
|
|
|
+ operands[1] = gen_rtx_MEM (DFmode, operands[1]);
|
|
|
+ else
|
|
|
+@@ -1984,7 +2214,7 @@
|
|
|
+ else if (optype0 == OFFSOP)
|
|
|
+ {
|
|
|
+ middlehalf[0] = adjust_address (operands[0], SImode, 4);
|
|
|
+- latehalf[0] = adjust_address (operands[0], SImode, size - 4);
|
|
|
++ latehalf[0] = adjust_address (operands[0], SImode, 8);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+@@ -2000,7 +2230,7 @@
|
|
|
+ else if (optype1 == OFFSOP)
|
|
|
+ {
|
|
|
+ middlehalf[1] = adjust_address (operands[1], SImode, 4);
|
|
|
+- latehalf[1] = adjust_address (operands[1], SImode, size - 4);
|
|
|
++ latehalf[1] = adjust_address (operands[1], SImode, 8);
|
|
|
+ }
|
|
|
+ else if (optype1 == CNSTOP)
|
|
|
+ {
|
|
|
+@@ -2032,8 +2262,66 @@
|
|
|
+ latehalf[1] = operands[1];
|
|
|
+ }
|
|
|
+ }
|
|
|
+- else
|
|
|
+- /* size is not 12: */
|
|
|
++ else if (size == 10)
|
|
|
++ {
|
|
|
++ if (optype0 == REGOP)
|
|
|
++ {
|
|
|
++ latehalf[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 2);
|
|
|
++ middlehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
|
|
|
++ }
|
|
|
++ else if (optype0 == OFFSOP)
|
|
|
++ {
|
|
|
++ middlehalf[0] = adjust_address (operands[0], SImode, 4);
|
|
|
++ latehalf[0] = adjust_address (operands[0], SImode, 8);
|
|
|
++ }
|
|
|
++ else
|
|
|
++ {
|
|
|
++ middlehalf[0] = operands[0];
|
|
|
++ latehalf[0] = operands[0];
|
|
|
++ }
|
|
|
++
|
|
|
++ if (optype1 == REGOP)
|
|
|
++ {
|
|
|
++ latehalf[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 2);
|
|
|
++ middlehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
|
|
|
++ }
|
|
|
++ else if (optype1 == OFFSOP)
|
|
|
++ {
|
|
|
++ middlehalf[1] = adjust_address (operands[1], SImode, 4);
|
|
|
++ latehalf[1] = adjust_address (operands[1], SImode, 8);
|
|
|
++ }
|
|
|
++ else if (optype1 == CNSTOP)
|
|
|
++ {
|
|
|
++ if (GET_CODE (operands[1]) == CONST_DOUBLE)
|
|
|
++ {
|
|
|
++ REAL_VALUE_TYPE r;
|
|
|
++ long l[3];
|
|
|
++
|
|
|
++ abort ();
|
|
|
++ REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
|
|
|
++ REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
|
|
|
++ operands[1] = GEN_INT (l[0]);
|
|
|
++ middlehalf[1] = GEN_INT (l[1]);
|
|
|
++ latehalf[1] = GEN_INT (l[2]);
|
|
|
++ }
|
|
|
++ else if (CONSTANT_P (operands[1]))
|
|
|
++ {
|
|
|
++ /* actually, no non-CONST_DOUBLE constant should ever
|
|
|
++ appear here. */
|
|
|
++ abort ();
|
|
|
++ if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
|
|
|
++ latehalf[1] = constm1_rtx;
|
|
|
++ else
|
|
|
++ latehalf[1] = const0_rtx;
|
|
|
++ }
|
|
|
++ }
|
|
|
++ else
|
|
|
++ {
|
|
|
++ middlehalf[1] = operands[1];
|
|
|
++ latehalf[1] = operands[1];
|
|
|
++ }
|
|
|
++ }
|
|
|
++ else /* size is neither 12 or 10: */
|
|
|
+ {
|
|
|
+ if (optype0 == REGOP)
|
|
|
+ latehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
|
|
|
+@@ -2058,7 +2346,16 @@
|
|
|
+ if (optype0 == PUSHOP
|
|
|
+ && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
|
|
|
+ && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
|
|
|
++ {
|
|
|
++ if (size==10) {
|
|
|
++ /* (TIGCC 20040219) The above is not quite right for size==10. What we
|
|
|
++ have to do here is: (1) move.w operands[1]+8,-(%sp);
|
|
|
++ (2) move.l operands[1]+6,-(%sp); (3) move.l operands[1]+6,-(%sp).
|
|
|
++ -- Kevin Kofler */
|
|
|
++ operands[1] = middlehalf[1] = adjust_address (operands[1], SImode, 6);
|
|
|
++ } else
|
|
|
+ operands[1] = middlehalf[1] = latehalf[1];
|
|
|
++ }
|
|
|
+
|
|
|
+ /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)),
|
|
|
+ if the upper part of reg N does not appear in the MEM, arrange to
|
|
|
+@@ -2086,6 +2383,12 @@
|
|
|
+ middlehalf[1] = adjust_address (operands[1], DImode, size - 8);
|
|
|
+ latehalf[1] = adjust_address (operands[1], DImode, size - 4);
|
|
|
+ }
|
|
|
++ else if( GET_MODE (operands[1]) == BFmode )
|
|
|
++ {
|
|
|
++ operands[1] = gen_rtx_MEM (BFmode, latehalf[0]);
|
|
|
++ middlehalf[1] = adjust_address (operands[1], DImode, 4);
|
|
|
++ latehalf[1] = adjust_address (operands[1], DImode, 8);
|
|
|
++ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ operands[1] = gen_rtx_MEM (DImode, latehalf[0]);
|
|
|
+@@ -2116,6 +2419,30 @@
|
|
|
+ output_asm_insn (singlemove_string (middlehalf), middlehalf);
|
|
|
+ return "";
|
|
|
+ }
|
|
|
++ else if (size == 10
|
|
|
++ && reg_overlap_mentioned_p (middlehalf[0],
|
|
|
++ XEXP (operands[1], 0)))
|
|
|
++ {
|
|
|
++ /* Check for two regs used by both source and dest.
|
|
|
++ Note that this can't happen if the dest is all data regs.
|
|
|
++ It can happen if the dest is d6, d7, a0.
|
|
|
++ But in that case, latehalf is an addr reg, so
|
|
|
++ the code at compadr does ok. */
|
|
|
++
|
|
|
++ if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0))
|
|
|
++ || reg_overlap_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
|
|
|
++ goto compadr;
|
|
|
++
|
|
|
++ /* JRV says this can't happen: */
|
|
|
++ if (addreg0 || addreg1)
|
|
|
++ abort ();
|
|
|
++
|
|
|
++ /* Only the middle reg conflicts; simply put it last. */
|
|
|
++ output_asm_insn (singlemove_string (operands), operands);
|
|
|
++ output_asm_insn (halfsinglemove_string (latehalf), latehalf);
|
|
|
++ output_asm_insn (singlemove_string (middlehalf), middlehalf);
|
|
|
++ return "";
|
|
|
++ }
|
|
|
+ else if (reg_overlap_mentioned_p (testlow, XEXP (operands[1], 0)))
|
|
|
+ /* If the low half of dest is mentioned in the source memory
|
|
|
+ address, the arrange to emit the move late half first. */
|
|
|
+@@ -2139,21 +2466,24 @@
|
|
|
+ /* Make any unoffsettable addresses point at high-numbered word. */
|
|
|
+ if (addreg0)
|
|
|
+ {
|
|
|
+- if (size == 12)
|
|
|
++ if (size == 12 || size == 10)
|
|
|
+ output_asm_insn ("addq%.l #8,%0", &addreg0);
|
|
|
+ else
|
|
|
+ output_asm_insn ("addq%.l #4,%0", &addreg0);
|
|
|
+ }
|
|
|
+ if (addreg1)
|
|
|
+ {
|
|
|
+- if (size == 12)
|
|
|
++ if (size == 12 || size == 10)
|
|
|
+ output_asm_insn ("addq%.l #8,%0", &addreg1);
|
|
|
+ else
|
|
|
+ output_asm_insn ("addq%.l #4,%0", &addreg1);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Do that word. */
|
|
|
+- output_asm_insn (singlemove_string (latehalf), latehalf);
|
|
|
++ if (size == 10)
|
|
|
++ output_asm_insn (halfsinglemove_string (latehalf), latehalf);
|
|
|
++ else
|
|
|
++ output_asm_insn (singlemove_string (latehalf), latehalf);
|
|
|
+
|
|
|
+ /* Undo the adds we just did. */
|
|
|
+ if (addreg0)
|
|
|
+@@ -2161,7 +2491,7 @@
|
|
|
+ if (addreg1)
|
|
|
+ output_asm_insn ("subq%.l #4,%0", &addreg1);
|
|
|
+
|
|
|
+- if (size == 12)
|
|
|
++ if (size == 12 || size == 10)
|
|
|
+ {
|
|
|
+ output_asm_insn (singlemove_string (middlehalf), middlehalf);
|
|
|
+ if (addreg0)
|
|
|
+@@ -2179,7 +2509,7 @@
|
|
|
+ output_asm_insn (singlemove_string (operands), operands);
|
|
|
+
|
|
|
+ /* Do the middle one of the three words for long double */
|
|
|
+- if (size == 12)
|
|
|
++ if (size == 12 || size == 10)
|
|
|
+ {
|
|
|
+ if (addreg0)
|
|
|
+ output_asm_insn ("addq%.l #4,%0", &addreg0);
|
|
|
+@@ -2196,19 +2526,22 @@
|
|
|
+ output_asm_insn ("addq%.l #4,%0", &addreg1);
|
|
|
+
|
|
|
+ /* Do that word. */
|
|
|
+- output_asm_insn (singlemove_string (latehalf), latehalf);
|
|
|
++ if (size == 10)
|
|
|
++ output_asm_insn (halfsinglemove_string (latehalf), latehalf);
|
|
|
++ else
|
|
|
++ output_asm_insn (singlemove_string (latehalf), latehalf);
|
|
|
+
|
|
|
+ /* Undo the adds we just did. */
|
|
|
+ if (addreg0)
|
|
|
+ {
|
|
|
+- if (size == 12)
|
|
|
++ if (size == 12 || size == 10)
|
|
|
+ output_asm_insn ("subq%.l #8,%0", &addreg0);
|
|
|
+ else
|
|
|
+ output_asm_insn ("subq%.l #4,%0", &addreg0);
|
|
|
+ }
|
|
|
+ if (addreg1)
|
|
|
+ {
|
|
|
+- if (size == 12)
|
|
|
++ if (size == 12 || size == 10)
|
|
|
+ output_asm_insn ("subq%.l #8,%0", &addreg1);
|
|
|
+ else
|
|
|
+ output_asm_insn ("subq%.l #4,%0", &addreg1);
|
|
|
+@@ -2539,6 +2872,8 @@
|
|
|
+ int
|
|
|
+ floating_exact_log2 (rtx x)
|
|
|
+ {
|
|
|
++abort();
|
|
|
++#if 0
|
|
|
+ REAL_VALUE_TYPE r, r1;
|
|
|
+ int exp;
|
|
|
+
|
|
|
+@@ -2553,6 +2888,7 @@
|
|
|
+ return exp;
|
|
|
+
|
|
|
+ return 0;
|
|
|
++#endif /* 0 */
|
|
|
+ }
|
|
|
+
|
|
|
+ /* A C compound statement to output to stdio stream STREAM the
|
|
|
+@@ -2599,6 +2935,8 @@
|
|
|
+ 'x' for float insn (print a CONST_DOUBLE as a float rather than in hex),
|
|
|
+ or print pair of registers as rx:ry.
|
|
|
+
|
|
|
++(TIGCC 20040222) 'A' like 'o', but for addresses.
|
|
|
++
|
|
|
+ */
|
|
|
+
|
|
|
+ void
|
|
|
+@@ -2639,6 +2977,14 @@
|
|
|
+ abort ();
|
|
|
+ output_addr_const (file, XEXP (op, 0));
|
|
|
+ }
|
|
|
++ else if (letter == 'A') /* (TIGCC 20040222) */
|
|
|
++ {
|
|
|
++ if (TARGET_PCREL) {
|
|
|
++ target_flags&=~MASK_PCREL; /* ugly hack, but works */
|
|
|
++ print_operand_address(file,op);
|
|
|
++ target_flags|=MASK_PCREL;
|
|
|
++ } else print_operand_address(file,op);
|
|
|
++ }
|
|
|
+ else if (GET_CODE (op) == REG)
|
|
|
+ {
|
|
|
+ if (letter == 'R')
|
|
|
+@@ -2651,13 +2997,24 @@
|
|
|
+ else if (GET_CODE (op) == MEM)
|
|
|
+ {
|
|
|
+ output_address (XEXP (op, 0));
|
|
|
++ /* TIGCC Patch: This is a very bad try to implement addresses relative to a register.
|
|
|
++ Julien Muchembled says this should work.
|
|
|
++ At least it should if only one file is used.
|
|
|
++ (TIGCC 20040808) Added CONST. A MEM(CONST) is used for sym+const addressing. This
|
|
|
++ needs to be made reg-relative too. -- Kevin Kofler */
|
|
|
++ if (TARGET_REG_RELATIVE && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF || GET_CODE (XEXP (op, 0)) == LABEL_REF || GET_CODE (XEXP (op, 0)) == CODE_LABEL || GET_CODE (XEXP (op, 0)) == CONST))
|
|
|
++ fprintf (file, "-__relation(%%%s)", TARGET_RELATION_REG);
|
|
|
++ else
|
|
|
++ {
|
|
|
+ if (letter == 'd' && ! TARGET_68020
|
|
|
+ && CONSTANT_ADDRESS_P (XEXP (op, 0))
|
|
|
+ && !(GET_CODE (XEXP (op, 0)) == CONST_INT
|
|
|
+ && INTVAL (XEXP (op, 0)) < 0x8000
|
|
|
+ && INTVAL (XEXP (op, 0)) >= -0x8000))
|
|
|
+ fprintf (file, MOTOROLA ? ".l" : ":l");
|
|
|
++ }
|
|
|
+ }
|
|
|
++#if 0
|
|
|
+ else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == SFmode)
|
|
|
+ {
|
|
|
+ REAL_VALUE_TYPE r;
|
|
|
+@@ -2676,6 +3033,7 @@
|
|
|
+ REAL_VALUE_FROM_CONST_DOUBLE (r, op);
|
|
|
+ ASM_OUTPUT_DOUBLE_OPERAND (file, r);
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+ else
|
|
|
+ {
|
|
|
+ /* Use `print_operand_address' instead of `output_addr_const'
|
|
|
+@@ -3065,7 +3423,7 @@
|
|
|
+ && (INTVAL (op) >= 0 && INTVAL (op) <= 0xffffffffL));
|
|
|
+ #else
|
|
|
+ return (GET_CODE (op) == CONST_INT
|
|
|
+- || (GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_HIGH (op) == 0));
|
|
|
++ && INTVAL (op) >= 0);
|
|
|
+ #endif
|
|
|
+ }
|
|
|
+
|
|
|
+@@ -3212,6 +3570,176 @@
|
|
|
+ || GET_CODE (op) == CONST);
|
|
|
+ }
|
|
|
+
|
|
|
++/* (TIGCC 20040222) This function is used to allow straight labels in the
|
|
|
++ indirect_jump pattern. -- Kevin Kofler */
|
|
|
++int
|
|
|
++extended_address_operand (rtx op, enum machine_mode mode)
|
|
|
++{
|
|
|
++ if (TARGET_PCREL && CONSTANT_ADDRESS_P (op))
|
|
|
++ return 1;
|
|
|
++ return address_operand (op, mode);
|
|
|
++}
|
|
|
++
|
|
|
++/* Argument-passing support functions. */
|
|
|
++
|
|
|
++/* Initialize a variable CUM of type CUMULATIVE_ARGS
|
|
|
++ for a call to a function whose data type is FNTYPE.
|
|
|
++ For a library call, FNTYPE is 0. */
|
|
|
++
|
|
|
++static void
|
|
|
++m68k_init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, tree fndecl)
|
|
|
++{
|
|
|
++ cum->last_arg_reg = -1;
|
|
|
++ cum->regs_already_used = 0;
|
|
|
++ if (fntype)
|
|
|
++ {
|
|
|
++ if (lookup_attribute ("stkparm", TYPE_ATTRIBUTES (fntype)))
|
|
|
++ cum->num_of_regs = 0;
|
|
|
++ else
|
|
|
++ {
|
|
|
++ tree ratree = lookup_attribute ("regparm", TYPE_ATTRIBUTES (fntype));
|
|
|
++ if (ratree)
|
|
|
++ {
|
|
|
++ cum->num_of_regs = m68k_regparm ? m68k_regparm
|
|
|
++ : M68K_DEFAULT_REGPARM;
|
|
|
++ if (TREE_VALUE (ratree)
|
|
|
++ && TREE_CODE (TREE_VALUE (ratree)) == TREE_LIST)
|
|
|
++ {
|
|
|
++ tree num_of_regs = TREE_VALUE (TREE_VALUE (ratree));
|
|
|
++ cum->num_of_regs =
|
|
|
++ num_of_regs ? TREE_INT_CST_LOW (num_of_regs) :
|
|
|
++ (m68k_regparm ? m68k_regparm : M68K_DEFAULT_REGPARM);
|
|
|
++ }
|
|
|
++ }
|
|
|
++/* (TIGCC 20050208) Use register calling convention for local functions when
|
|
|
++ possible. Partially copied from i386.c. */
|
|
|
++ else if (fndecl && flag_unit_at_a_time)
|
|
|
++ {
|
|
|
++ struct cgraph_local_info *i = cgraph_local_info (fndecl);
|
|
|
++ if (i && i->local)
|
|
|
++ {
|
|
|
++ cum->num_of_regs = m68k_regparm ? m68k_regparm
|
|
|
++ : M68K_DEFAULT_REGPARM;
|
|
|
++ }
|
|
|
++ else
|
|
|
++ cum->num_of_regs = m68k_regparm;
|
|
|
++ }
|
|
|
++ else
|
|
|
++ cum->num_of_regs = m68k_regparm;
|
|
|
++ }
|
|
|
++ }
|
|
|
++ else /* Libcall. */
|
|
|
++ cum->num_of_regs = 0;
|
|
|
++
|
|
|
++ if (cum->num_of_regs)
|
|
|
++ {
|
|
|
++ /* If this is a vararg call, put all arguments on stack. */
|
|
|
++ tree param, next_param;
|
|
|
++ for (param = TYPE_ARG_TYPES (fntype); param; param = next_param)
|
|
|
++ {
|
|
|
++ next_param = TREE_CHAIN (param);
|
|
|
++ if (!next_param && TREE_VALUE (param) != void_type_node)
|
|
|
++ cum->num_of_regs = 0;
|
|
|
++ }
|
|
|
++ }
|
|
|
++
|
|
|
++#if ! defined (PCC_STATIC_STRUCT_RETURN) && defined (M68K_STRUCT_VALUE_REGNUM)
|
|
|
++ /* If return value is a structure, and we pass the buffer address in a
|
|
|
++ register, we can't use this register for our own purposes.
|
|
|
++ FIXME: Something similar would be useful for static chain. */
|
|
|
++ if (fntype && aggregate_value_p (TREE_TYPE (fntype), fntype))
|
|
|
++ cum->regs_already_used |= (1 << M68K_STRUCT_VALUE_REGNUM);
|
|
|
++#endif
|
|
|
++}
|
|
|
++
|
|
|
++/* Update the data in CUM to advance over an argument. */
|
|
|
++
|
|
|
++static void
|
|
|
++m68k_function_arg_advance (CUMULATIVE_ARGS *cum)
|
|
|
++{
|
|
|
++ if (cum->last_arg_reg != -1)
|
|
|
++ {
|
|
|
++ int count;
|
|
|
++ for (count = 0; count < cum->last_arg_len; count++)
|
|
|
++ cum->regs_already_used |= (1 << (cum->last_arg_reg + count));
|
|
|
++ cum->last_arg_reg = -1;
|
|
|
++ }
|
|
|
++}
|
|
|
++
|
|
|
++/* Define where to put the arguments to a function.
|
|
|
++ Value is zero to push the argument on the stack,
|
|
|
++ or a hard register in which to store the argument.
|
|
|
++
|
|
|
++ MODE is the argument's machine mode.
|
|
|
++ TYPE is the data type of the argument (as a tree).
|
|
|
++ This is null for libcalls where that information may
|
|
|
++ not be available.
|
|
|
++ CUM is a variable of type CUMULATIVE_ARGS which gives info about
|
|
|
++ the preceding args and about the function being called. */
|
|
|
++
|
|
|
++static struct rtx_def *
|
|
|
++m68k_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type)
|
|
|
++{
|
|
|
++ if (cum->num_of_regs)
|
|
|
++ {
|
|
|
++ int regbegin = -1, altregbegin = -1, len;
|
|
|
++
|
|
|
++ /* FIXME: The last condition below is a workaround for a bug. */
|
|
|
++ if (TARGET_68881 && FLOAT_MODE_P (mode) &&
|
|
|
++ GET_MODE_UNIT_SIZE (mode) <= 12 &&
|
|
|
++ (GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT || mode == SCmode))
|
|
|
++ {
|
|
|
++ regbegin = 16; /* FPx */
|
|
|
++ len = GET_MODE_NUNITS (mode);
|
|
|
++ }
|
|
|
++ /* FIXME: Two last conditions below are workarounds for bugs. */
|
|
|
++ else if (INTEGRAL_MODE_P (mode) && mode !=CQImode && mode != CHImode)
|
|
|
++ {
|
|
|
++ if (POINTER_TYPE_P (type))
|
|
|
++ regbegin = 8; /* Ax */
|
|
|
++ else
|
|
|
++ regbegin = 0; /* Dx */
|
|
|
++ altregbegin = 8 - regbegin;
|
|
|
++ len = (GET_MODE_SIZE (mode) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
|
|
|
++ }
|
|
|
++
|
|
|
++ if (regbegin != -1)
|
|
|
++ {
|
|
|
++ int reg;
|
|
|
++ long mask;
|
|
|
++
|
|
|
++look_for_reg:
|
|
|
++ mask = 1 << regbegin;
|
|
|
++ for (reg = 0; reg < cum->num_of_regs; reg++, mask <<= 1)
|
|
|
++ if (!(cum->regs_already_used & mask))
|
|
|
++ {
|
|
|
++ int end;
|
|
|
++ for (end = reg; end < cum->num_of_regs && end < reg + len;
|
|
|
++ end++, mask <<= 1)
|
|
|
++ if (cum->regs_already_used & mask)
|
|
|
++ break;
|
|
|
++ if (end == reg + len)
|
|
|
++ {
|
|
|
++ cum->last_arg_reg = reg + regbegin;
|
|
|
++ cum->last_arg_len = len;
|
|
|
++ break;
|
|
|
++ }
|
|
|
++ }
|
|
|
++
|
|
|
++ if (reg == cum->num_of_regs && altregbegin != -1)
|
|
|
++ {
|
|
|
++ regbegin = altregbegin;
|
|
|
++ altregbegin = -1;
|
|
|
++ goto look_for_reg;
|
|
|
++ }
|
|
|
++ }
|
|
|
++
|
|
|
++ if (cum->last_arg_reg != -1)
|
|
|
++ return gen_rtx_REG (mode, cum->last_arg_reg);
|
|
|
++ }
|
|
|
++ return 0;
|
|
|
++}
|
|
|
++
|
|
|
+ const char *
|
|
|
+ output_andsi3 (rtx *operands)
|
|
|
+ {
|
|
|
+@@ -3332,13 +3860,28 @@
|
|
|
+ tree decl ATTRIBUTE_UNUSED)
|
|
|
+ {
|
|
|
+ char flagchar;
|
|
|
+-
|
|
|
+- if (flags & SECTION_WRITE)
|
|
|
++ /* (TIGCC 20040725) Constant/string merging flags for TIGCC-extended COFF.
|
|
|
++ SECTION_STRINGS is abused for the unaligned flag. */
|
|
|
++ const char *xflags = "";
|
|
|
++
|
|
|
++ /* (TIGCC 20040619) Handle BSS sections properly with -fdata-sections.
|
|
|
++ -- Kevin Kofler*/
|
|
|
++ if ((flags & SECTION_BSS) && !TARGET_NO_BSS)
|
|
|
++ flagchar = 'b';
|
|
|
++ /* (TIGCC 20040620) Handle rodata sections properly with -fdata-sections.
|
|
|
++ -- Kevin Kofler*/
|
|
|
++ else if ((flags & SECTION_WRITE)
|
|
|
++ || (!TARGET_RODATA_TO_TEXT && !(flags & SECTION_CODE)))
|
|
|
+ flagchar = 'd';
|
|
|
+ else
|
|
|
+ flagchar = 'x';
|
|
|
+
|
|
|
+- fprintf (asm_out_file, "\t.section\t%s,\"%c\"\n", name, flagchar);
|
|
|
++ if (flags & SECTION_MERGE)
|
|
|
++ xflags = (flags & SECTION_STRINGS)?"mu":"m";
|
|
|
++ else if (flags & SECTION_STRINGS)
|
|
|
++ xflags = "u";
|
|
|
++
|
|
|
++ fprintf (asm_out_file, "\t.section\t%s,\"%c%s\"\n", name, flagchar, xflags);
|
|
|
+ }
|
|
|
+
|
|
|
+ #endif /* M68K_TARGET_COFF */
|
|
|
+@@ -3391,7 +3934,7 @@
|
|
|
+ if (flag_pic)
|
|
|
+ {
|
|
|
+ if (TARGET_PCREL)
|
|
|
+- fmt = "bra.l %o0";
|
|
|
++ fmt = "bra %o0"; /* (TIGCC 20040222, 20050204) No long branches please... */
|
|
|
+ else if ((flag_pic == 1) || TARGET_68020)
|
|
|
+ {
|
|
|
+ if (MOTOROLA)
|
|
|
+@@ -3449,3 +3992,119 @@
|
|
|
+
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
++
|
|
|
++/* begin-TIGCC-local (regparms): explicit register specification for parameters */
|
|
|
++
|
|
|
++/* Initialize a variable CUM of type CUMULATIVE_ARGS
|
|
|
++ for a call to a function whose data type is FNTYPE.
|
|
|
++ For a library call, FNTYPE is 0. */
|
|
|
++
|
|
|
++void
|
|
|
++amigaos_init_cumulative_args(CUMULATIVE_ARGS *cum, tree fntype, tree fndecl)
|
|
|
++{
|
|
|
++ m68k_init_cumulative_args(cum, fntype, fndecl);
|
|
|
++
|
|
|
++ if (fntype)
|
|
|
++ cum->formal_type=TYPE_ARG_TYPES(fntype);
|
|
|
++ else /* Call to compiler-support function. */
|
|
|
++ cum->formal_type=0;
|
|
|
++}
|
|
|
++
|
|
|
++/* Update the data in CUM to advance over an argument. */
|
|
|
++
|
|
|
++void
|
|
|
++amigaos_function_arg_advance(CUMULATIVE_ARGS *cum)
|
|
|
++{
|
|
|
++ m68k_function_arg_advance(cum);
|
|
|
++
|
|
|
++ if (cum->formal_type)
|
|
|
++ cum->formal_type=TREE_CHAIN((tree)cum->formal_type);
|
|
|
++}
|
|
|
++
|
|
|
++/* A C expression that controls whether a function argument is passed
|
|
|
++ in a register, and which register. */
|
|
|
++
|
|
|
++struct rtx_def *
|
|
|
++amigaos_function_arg(CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
|
|
++ tree type)
|
|
|
++{
|
|
|
++ tree asmtree;
|
|
|
++ if (cum->formal_type && TREE_VALUE((tree)cum->formal_type)
|
|
|
++ && (asmtree=lookup_attribute("asm",
|
|
|
++ TYPE_ATTRIBUTES(TREE_VALUE((tree)cum->formal_type)))))
|
|
|
++ {
|
|
|
++ int i;
|
|
|
++#if 0
|
|
|
++ /* See c-decl.c/push_parm_decl for an explanation why this doesn't work.
|
|
|
++ */
|
|
|
++ cum->last_arg_reg=TREE_INT_CST_LOW(TREE_VALUE(TREE_VALUE(asmtree)));
|
|
|
++#else
|
|
|
++ cum->last_arg_reg=TREE_INT_CST_LOW(TREE_VALUE(asmtree));
|
|
|
++#endif
|
|
|
++ cum->last_arg_len=HARD_REGNO_NREGS(cum->last_arg_reg, mode);
|
|
|
++
|
|
|
++ for (i=0; i<cum->last_arg_len; i++)
|
|
|
++ if (cum->regs_already_used & (1 << (cum->last_arg_reg+i)))
|
|
|
++ {
|
|
|
++ error("two parameters allocated for one register");
|
|
|
++ break;
|
|
|
++ }
|
|
|
++ return gen_rtx_REG (mode, cum->last_arg_reg);
|
|
|
++ }
|
|
|
++ else
|
|
|
++ return (struct rtx_def *)m68k_function_arg(cum, mode, type);
|
|
|
++}
|
|
|
++
|
|
|
++/* Return zero if the attributes on TYPE1 and TYPE2 are incompatible,
|
|
|
++ one if they are compatible, and two if they are nearly compatible
|
|
|
++ (which causes a warning to be generated). */
|
|
|
++
|
|
|
++int
|
|
|
++comp_amigaos_type_attributes(tree type1, tree type2)
|
|
|
++{
|
|
|
++ int ret;
|
|
|
++ if ((ret=comp_m68k_type_attributes(type1, type2))!=1)
|
|
|
++ return ret;
|
|
|
++
|
|
|
++ /* Functions or methods are incompatible if they specify mutually exclusive
|
|
|
++ ways of passing arguments. */
|
|
|
++ if (TREE_CODE(type1)==FUNCTION_TYPE || TREE_CODE(type1)==METHOD_TYPE)
|
|
|
++ {
|
|
|
++ tree arg1, arg2;
|
|
|
++ arg1=TYPE_ARG_TYPES(type1);
|
|
|
++ arg2=TYPE_ARG_TYPES(type2);
|
|
|
++ for (; arg1 && arg2; arg1=TREE_CHAIN(arg1), arg2=TREE_CHAIN(arg2))
|
|
|
++ if (TREE_VALUE(arg1) && TREE_VALUE(arg2))
|
|
|
++ {
|
|
|
++ tree asm1, asm2;
|
|
|
++ asm1=lookup_attribute("asm", TYPE_ATTRIBUTES(TREE_VALUE(arg1)));
|
|
|
++ asm2=lookup_attribute("asm", TYPE_ATTRIBUTES(TREE_VALUE(arg2)));
|
|
|
++ if (asm1 && asm2)
|
|
|
++ {
|
|
|
++ if (TREE_INT_CST_LOW(TREE_VALUE(asm1))!=
|
|
|
++ TREE_INT_CST_LOW(TREE_VALUE(asm2)))
|
|
|
++ return 0; /* Two different registers specified. */
|
|
|
++ }
|
|
|
++ else
|
|
|
++ if (asm1 || asm2)
|
|
|
++ return 0; /* "asm" used in only one type. */
|
|
|
++ }
|
|
|
++ }
|
|
|
++ return 1;
|
|
|
++}
|
|
|
++
|
|
|
++/* end-TIGCC-local (regparms) */
|
|
|
++
|
|
|
++/* (TIGCC) If TARGET_MERGE_SECTIONS is set (on by default), we need an explicit
|
|
|
++ '.text' or '.data' (depending on TARGET_MERGE_TO_DATA) statement at the
|
|
|
++ beginning of the file. */
|
|
|
++
|
|
|
++void m68k_asm_file_start(void)
|
|
|
++{
|
|
|
++ output_file_directive (asm_out_file, main_input_filename);
|
|
|
++ fprintf (asm_out_file, "#NO_APP\n");
|
|
|
++ if (TARGET_REG_RELATIVE)
|
|
|
++ fprintf (asm_out_file, "\t.set __relation,__ld_entry_point_plus_0x8000\n\t.xdef __ref_all___reg_relative_%s\n", TARGET_RELATION_REG);
|
|
|
++ fprintf (asm_out_file, (TARGET_MERGE_SECTIONS?(TARGET_MERGE_TO_DATA?"\t.data\ntigcc_compiled.:\n":"\t.text\ntigcc_compiled.:\n"):"tigcc_compiled.:\n"));
|
|
|
++}
|
|
|
++
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/config/m68k/m68k.h gcc-4.0-20050319-src/gcc/config/m68k/m68k.h
|
|
|
+--- gcc-4.0-20050319.orig/gcc/config/m68k/m68k.h Thu Dec 30 04:07:52 2004
|
|
|
++++ gcc-4.0-20050319-src/gcc/config/m68k/m68k.h Wed Mar 23 01:21:02 2005
|
|
|
+@@ -224,6 +224,44 @@
|
|
|
+ #define MASK_ID_SHARED_LIBRARY (1<<18)
|
|
|
+ #define TARGET_ID_SHARED_LIBRARY (target_flags & MASK_ID_SHARED_LIBRARY)
|
|
|
+
|
|
|
++/* Compile using the first 'm68k_regparm' data, address and float
|
|
|
++ registers for arguments passing. */
|
|
|
++#define MASK_REGPARM (1<<19)
|
|
|
++#define TARGET_REGPARM (target_flags & MASK_REGPARM)
|
|
|
++
|
|
|
++/* Use the TIOS calling convention */
|
|
|
++#define MASK_TIOS (1<<20)
|
|
|
++#define TARGET_TIOS (target_flags & MASK_TIOS)
|
|
|
++
|
|
|
++/* Use the TIOS return convention for floats (not yet supported) */
|
|
|
++#define MASK_DIRECTFLOAT (1<<21)
|
|
|
++#define TARGET_DIRECTFLOAT (target_flags & MASK_DIRECTFLOAT)
|
|
|
++
|
|
|
++/* Access everything in relation to a specific register */
|
|
|
++#define MASK_REG_RELATIVE (1<<22)
|
|
|
++#define TARGET_REG_RELATIVE (target_flags & MASK_REG_RELATIVE)
|
|
|
++
|
|
|
++/* Use absolute line numbers in COFF debugging format */
|
|
|
++#define MASK_COFFABSLINES (1<<23)
|
|
|
++#define TARGET_COFFABSLINES (target_flags & MASK_COFFABSLINES)
|
|
|
++
|
|
|
++/* Merge .text and .data sections (to .text) */
|
|
|
++#define MASK_MERGE_SECTIONS (1<<24)
|
|
|
++#define TARGET_MERGE_SECTIONS (target_flags & MASK_MERGE_SECTIONS)
|
|
|
++
|
|
|
++/* Merge sections to .data rather than to .text (ignored if MASK_MERGE_SECTIONS
|
|
|
++ is not set) */
|
|
|
++#define MASK_MERGE_TO_DATA (1<<25)
|
|
|
++#define TARGET_MERGE_TO_DATA (target_flags & MASK_MERGE_TO_DATA)
|
|
|
++
|
|
|
++/* When not merging sections, put read-only data into .text rather than .data */
|
|
|
++#define MASK_RODATA_TO_TEXT (1<<26)
|
|
|
++#define TARGET_RODATA_TO_TEXT (target_flags & MASK_RODATA_TO_TEXT)
|
|
|
++
|
|
|
++/* Never output any common or lcomm symbols, neither with nor without _nostub */
|
|
|
++#define MASK_NO_BSS (1<<27)
|
|
|
++#define TARGET_NO_BSS (target_flags & MASK_NO_BSS)
|
|
|
++
|
|
|
+ /* Compile for a CPU32. A 68020 without bitfields is a good
|
|
|
+ heuristic for a CPU32. */
|
|
|
+ #define TARGET_CPU32 (TARGET_68020 && !TARGET_BITFIELD)
|
|
|
+@@ -254,8 +292,16 @@
|
|
|
+ N_("Do not use the bit-field instructions") }, \
|
|
|
+ { "short", MASK_SHORT, \
|
|
|
+ N_("Consider type 'int' to be 16 bits wide") }, \
|
|
|
++ { "nolong", MASK_SHORT, \
|
|
|
++ N_("Consider type `int' to be 16 bits wide") }, \
|
|
|
++ { "no-long", MASK_SHORT, \
|
|
|
++ N_("Consider type `int' to be 16 bits wide") }, \
|
|
|
++ { "long", - MASK_SHORT, \
|
|
|
++ N_("Consider type `int' to be 32 bits wide") }, \
|
|
|
+ { "noshort", - MASK_SHORT, \
|
|
|
+ N_("Consider type 'int' to be 32 bits wide") }, \
|
|
|
++ { "no-short", - MASK_SHORT, \
|
|
|
++ N_("Consider type `int' to be 32 bits wide") }, \
|
|
|
+ { "68881", MASK_68881, "" }, \
|
|
|
+ { "soft-float", - MASK_68881, \
|
|
|
+ N_("Generate code with library calls for floating point") }, \
|
|
|
+@@ -314,6 +360,8 @@
|
|
|
+ { "cpu32", MASK_68020, "" }, \
|
|
|
+ { "align-int", MASK_ALIGN_INT, \
|
|
|
+ N_("Align variables on a 32-bit boundary") }, \
|
|
|
++ { "noalign-int", -MASK_ALIGN_INT, \
|
|
|
++ N_("Align variables on a 16-bit boundary") }, \
|
|
|
+ { "no-align-int", -MASK_ALIGN_INT, \
|
|
|
+ N_("Align variables on a 16-bit boundary") }, \
|
|
|
+ { "sep-data", MASK_SEP_DATA, \
|
|
|
+@@ -326,6 +374,10 @@
|
|
|
+ N_("Disable ID based shared library") }, \
|
|
|
+ { "pcrel", MASK_PCREL, \
|
|
|
+ N_("Generate pc-relative code") }, \
|
|
|
++ { "nopcrel", - MASK_PCREL, \
|
|
|
++ N_("Generate absolute code") }, \
|
|
|
++ { "no-pcrel", - MASK_PCREL, \
|
|
|
++ N_("Generate absolute code") }, \
|
|
|
+ { "strict-align", -MASK_NO_STRICT_ALIGNMENT, \
|
|
|
+ N_("Do not use unaligned memory references") }, \
|
|
|
+ { "no-strict-align", MASK_NO_STRICT_ALIGNMENT, \
|
|
|
+@@ -334,6 +386,44 @@
|
|
|
+ N_("Use different calling convention using 'rtd'") }, \
|
|
|
+ { "nortd", - MASK_RTD, \
|
|
|
+ N_("Use normal calling convention") }, \
|
|
|
++ { "tios", MASK_TIOS, \
|
|
|
++ N_("Enable TIOS interoperability") }, \
|
|
|
++ { "notios", - MASK_TIOS, \
|
|
|
++ N_("Disable TIOS interoperability") }, \
|
|
|
++ { "no-tios", - MASK_TIOS, \
|
|
|
++ N_("Disable TIOS interoperability") }, \
|
|
|
++ { "regparm", MASK_REGPARM, \
|
|
|
++ N_("Allow passing by registers") }, \
|
|
|
++ { "noregparm", - MASK_REGPARM, \
|
|
|
++ N_("Disallow passing by registers") }, \
|
|
|
++ { "no-regparm", - MASK_REGPARM, \
|
|
|
++ N_("Disallow passing by registers") }, \
|
|
|
++ { "merge-sections", MASK_MERGE_SECTIONS, \
|
|
|
++ N_("Merge the .text and .data sections") }, \
|
|
|
++ { "nomerge-sections", - MASK_MERGE_SECTIONS, \
|
|
|
++ N_("Do not merge the .text and .data sections") }, \
|
|
|
++ { "no-merge-sections", - MASK_MERGE_SECTIONS, \
|
|
|
++ N_("Do not merge the .text and .data sections") }, \
|
|
|
++ { "merge-to-data", MASK_MERGE_TO_DATA, \
|
|
|
++ N_("When merging sections, merge to .data rather than to .text") }, \
|
|
|
++ { "nomerge-to-data", - MASK_MERGE_TO_DATA, \
|
|
|
++ N_("When merging sections, merge to .text rather than to .data") }, \
|
|
|
++ { "no-merge-to-data", - MASK_MERGE_TO_DATA, \
|
|
|
++ N_("When merging sections, merge to .text rather than to .data") }, \
|
|
|
++ { "rodata-to-text", MASK_RODATA_TO_TEXT, \
|
|
|
++ N_("When not merging sections, put read-only data into .text rather than .data") }, \
|
|
|
++ { "norodata-to-text", - MASK_RODATA_TO_TEXT, \
|
|
|
++ N_("When not merging sections, put read-only data into .data rather than .text") }, \
|
|
|
++ { "no-rodata-to-text", - MASK_RODATA_TO_TEXT, \
|
|
|
++ N_("When not merging sections, put read-only data into .data rather than .text") }, \
|
|
|
++ { "bss", - MASK_NO_BSS, \
|
|
|
++ N_("Output common/lcomm (BSS) symbols for uninitialized data") }, \
|
|
|
++ { "nobss", MASK_NO_BSS, \
|
|
|
++ N_("Don't use common/lcomm (BSS) symbols for uninitialized data, zero-initialize it") }, \
|
|
|
++ { "no-bss", MASK_NO_BSS, \
|
|
|
++ N_("Don't use common/lcomm (BSS) symbols for uninitialized data, zero-initialize it") }, \
|
|
|
++ { "coff-abslines", MASK_COFFABSLINES, \
|
|
|
++ N_("Use absolute line numbers for COFF debugging") }, \
|
|
|
+ SUBTARGET_SWITCHES \
|
|
|
+ { "", TARGET_DEFAULT, "" }}
|
|
|
+ /* TARGET_DEFAULT is defined in m68k-none.h, netbsd.h, etc. */
|
|
|
+@@ -342,6 +432,8 @@
|
|
|
+ { \
|
|
|
+ { "shared-library-id=", &m68k_library_id_string, \
|
|
|
+ N_("ID of shared library to build"), 0}, \
|
|
|
++ { "regparm=", &m68k_regparm_string, \
|
|
|
++ N_("Number of register parameters of each register type"), 0 }, \
|
|
|
+ SUBTARGET_OPTIONS \
|
|
|
+ }
|
|
|
+
|
|
|
+@@ -352,6 +444,8 @@
|
|
|
+ #define SUBTARGET_OPTIONS
|
|
|
+ #define SUBTARGET_OVERRIDE_OPTIONS
|
|
|
+
|
|
|
++extern char TARGET_RELATION_REG[];
|
|
|
++
|
|
|
+ /* target machine storage layout */
|
|
|
+
|
|
|
+ #define LONG_DOUBLE_TYPE_SIZE 80
|
|
|
+@@ -367,7 +461,7 @@
|
|
|
+
|
|
|
+ #define UNITS_PER_WORD 4
|
|
|
+
|
|
|
+-#define PARM_BOUNDARY (TARGET_SHORT ? 16 : 32)
|
|
|
++#define PARM_BOUNDARY 16
|
|
|
+ #define STACK_BOUNDARY 16
|
|
|
+ #define FUNCTION_BOUNDARY 16
|
|
|
+ #define EMPTY_FIELD_BOUNDARY 16
|
|
|
+@@ -401,7 +495,9 @@
|
|
|
+ #define FIRST_PSEUDO_REGISTER 25
|
|
|
+
|
|
|
+ /* All m68k targets (except AmigaOS) use %a5 as the PIC register */
|
|
|
+-#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 13 : INVALID_REGNUM)
|
|
|
++/* (TIGCC 20050209) TIGCC doesn't use a PIC register, and besides this was
|
|
|
++ forgetting the -mpcrel case. */
|
|
|
++#define PIC_OFFSET_TABLE_REGNUM (INVALID_REGNUM)
|
|
|
+
|
|
|
+ /* 1 for registers that have pervasive standard uses
|
|
|
+ and are not available for the register allocator.
|
|
|
+@@ -604,6 +700,9 @@
|
|
|
+ `S' is for operands that satisfy 'm' when -mpcrel is in effect.
|
|
|
+ `T' is for operands that satisfy 's' when -mpcrel is not in effect.
|
|
|
+ `U' is for register offset addressing. */
|
|
|
++/* (TIGCC 20040808) Under -freg-relative-an, the same restrictions on 's'/'T' as
|
|
|
++ for -mpcrel apply. We can't use immediates as labels if
|
|
|
++ we need to output reg-relative code. -- Kevin Kofler */
|
|
|
+ #define EXTRA_CONSTRAINT(OP,CODE) \
|
|
|
+ (((CODE) == 'S') \
|
|
|
+ ? (TARGET_PCREL \
|
|
|
+@@ -613,7 +712,7 @@
|
|
|
+ || GET_CODE (XEXP (OP, 0)) == CONST)) \
|
|
|
+ : \
|
|
|
+ (((CODE) == 'T') \
|
|
|
+- ? ( !TARGET_PCREL \
|
|
|
++ ? ( (!TARGET_PCREL && !TARGET_REG_RELATIVE) \
|
|
|
+ && (GET_CODE (OP) == SYMBOL_REF \
|
|
|
+ || GET_CODE (OP) == LABEL_REF \
|
|
|
+ || GET_CODE (OP) == CONST)) \
|
|
|
+@@ -715,24 +814,59 @@
|
|
|
+
|
|
|
+ #define PCC_STATIC_STRUCT_RETURN
|
|
|
+
|
|
|
+-/* On the m68k, all arguments are usually pushed on the stack. */
|
|
|
+-#define FUNCTION_ARG_REGNO_P(N) 0
|
|
|
++/* Define this if explicit register specification for parameters
|
|
|
++ is supported. */
|
|
|
++
|
|
|
++#define EXPLICIT_REGPARM
|
|
|
++
|
|
|
++#define FUNCTION_ARG_REGNO_P(N) \
|
|
|
++ (((N) >= 0 && (N) < M68K_MAX_REGPARM) \
|
|
|
++ || ((N) >= 8 && (N) < 8 + M68K_MAX_REGPARM) \
|
|
|
++ || (TARGET_68881 && (N) >= 16 && (N) < 16 + M68K_MAX_REGPARM))
|
|
|
+
|
|
|
+-/* On the m68k, this is a single integer, which is a number of bytes
|
|
|
+- of arguments scanned so far. */
|
|
|
+-#define CUMULATIVE_ARGS int
|
|
|
+-
|
|
|
+-/* On the m68k, the offset starts at 0. */
|
|
|
+-#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
|
|
|
+- ((CUM) = 0)
|
|
|
++/* On the m68k, this is a structure:
|
|
|
++ num_of_regs: number of data, address and float registers to use for
|
|
|
++ arguments passing (if it's 2, than pass arguments in d0, d1, a0, a1,
|
|
|
++ fp0 and fp1). 0 - pass everything on stack. vararg calls are
|
|
|
++ always passed entirely on stack.
|
|
|
++ regs_already_used: bitmask of the already used registers.
|
|
|
++ last_arg_reg: register number of the most recently passed argument.
|
|
|
++ -1 if passed on stack.
|
|
|
++ last_arg_len: number of registers used by the most recently passed
|
|
|
++ argument.
|
|
|
++ formal_type: formal type of the current argument.
|
|
|
++*/
|
|
|
++
|
|
|
++struct m68k_args
|
|
|
++{
|
|
|
++ int num_of_regs;
|
|
|
++ long regs_already_used;
|
|
|
++ int last_arg_reg;
|
|
|
++ int last_arg_len;
|
|
|
++ void *formal_type;
|
|
|
++};
|
|
|
++
|
|
|
++#define CUMULATIVE_ARGS struct m68k_args
|
|
|
++
|
|
|
++/* Max. number of data, address and float registers to be used for passing
|
|
|
++ integer, pointer and float arguments when TARGET_REGPARM.
|
|
|
++ It's 6, so d0-d5, a0-a5 and fp0-fp5 can be used. */
|
|
|
++
|
|
|
++#define M68K_MAX_REGPARM 6 /* was 4 in the original patch */
|
|
|
++
|
|
|
++/* The default number of data, address and float registers to use when
|
|
|
++ user specified '-mregparm' switch, not '-mregparm=<value>' option. */
|
|
|
++
|
|
|
++#define M68K_DEFAULT_REGPARM 2 /* was 2 in the orginial patch */
|
|
|
++
|
|
|
++#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \
|
|
|
++ (amigaos_init_cumulative_args (&(CUM), (FNTYPE), (FNDECL)))
|
|
|
+
|
|
|
+ #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
|
|
|
+- ((CUM) += ((MODE) != BLKmode \
|
|
|
+- ? (GET_MODE_SIZE (MODE) + 3) & ~3 \
|
|
|
+- : (int_size_in_bytes (TYPE) + 3) & ~3))
|
|
|
++ (amigaos_function_arg_advance (&(CUM)))
|
|
|
+
|
|
|
+-/* On the m68k all args are always pushed. */
|
|
|
+-#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) 0
|
|
|
++#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
|
|
|
++ ((struct rtx_def *)amigaos_function_arg (&(CUM), (MODE), (TYPE)))
|
|
|
+
|
|
|
+ #define FUNCTION_PROFILER(FILE, LABELNO) \
|
|
|
+ asm_fprintf (FILE, "\tlea %LLP%d,%Ra0\n\tjsr mcount\n", (LABELNO))
|
|
|
+@@ -868,7 +1002,11 @@
|
|
|
+
|
|
|
+ /* Nonzero if the constant value X is a legitimate general operand.
|
|
|
+ It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
|
|
|
+-#define LEGITIMATE_CONSTANT_P(X) (GET_MODE (X) != XFmode)
|
|
|
++/* (TIGCC 20040808) If reg-relative, we need to reject "constants" of the #label
|
|
|
++ or #label+const form. -- Kevin Kofler */
|
|
|
++
|
|
|
++#define LEGITIMATE_CONSTANT_P(X) (!TARGET_REG_RELATIVE \
|
|
|
++ || !pcrel_address (X, VOIDmode))
|
|
|
+
|
|
|
+ #ifndef REG_OK_STRICT
|
|
|
+ #define PCREL_GENERAL_OPERAND_OK 0
|
|
|
+@@ -1179,15 +1317,19 @@
|
|
|
+ #define ASM_OUTPUT_SKIP(FILE,SIZE) \
|
|
|
+ fprintf (FILE, "\t.skip %u\n", (int)(SIZE))
|
|
|
+
|
|
|
++#ifndef ASM_OUTPUT_COMMON
|
|
|
+ #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
|
|
|
+ ( fputs (".comm ", (FILE)), \
|
|
|
+ assemble_name ((FILE), (NAME)), \
|
|
|
+ fprintf ((FILE), ",%u\n", (int)(ROUNDED)))
|
|
|
++#endif
|
|
|
+
|
|
|
++#ifndef ASM_OUTPUT_LOCAL
|
|
|
+ #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
|
|
|
+ ( fputs (".lcomm ", (FILE)), \
|
|
|
+ assemble_name ((FILE), (NAME)), \
|
|
|
+ fprintf ((FILE), ",%u\n", (int)(ROUNDED)))
|
|
|
++#endif
|
|
|
+
|
|
|
+ /* Output a float value (represented as a C double) as an immediate operand.
|
|
|
+ This macro is m68k-specific. */
|
|
|
+@@ -1259,6 +1401,8 @@
|
|
|
+
|
|
|
+ /* Variables in m68k.c */
|
|
|
+ extern const char *m68k_library_id_string;
|
|
|
++extern const char *m68k_regparm_string;
|
|
|
++extern int m68k_regparm;
|
|
|
+ extern int m68k_last_compare_had_fp_operands;
|
|
|
+
|
|
|
+
|
|
|
+@@ -1278,4 +1422,8 @@
|
|
|
+ {"extend_operator", {SIGN_EXTEND, ZERO_EXTEND}}, \
|
|
|
+ {"symbolic_operand", {SYMBOL_REF, LABEL_REF, CONST}}, \
|
|
|
+ {"post_inc_operand", {MEM}}, \
|
|
|
+- {"pre_dec_operand", {MEM}},
|
|
|
++ {"pre_dec_operand", {MEM}}, \
|
|
|
++ /* (TIGCC 20040222) used in the indirect_jump pattern -- Kevin Kofler */\
|
|
|
++ {"extended_address_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, \
|
|
|
++ LABEL_REF, SUBREG, REG, MEM, \
|
|
|
++ PLUS, MINUS, MULT}},
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/config/m68k/m68k.md gcc-4.0-20050319-src/gcc/config/m68k/m68k.md
|
|
|
+--- gcc-4.0-20050319.orig/gcc/config/m68k/m68k.md Fri Aug 6 10:14:56 2004
|
|
|
++++ gcc-4.0-20050319-src/gcc/config/m68k/m68k.md Wed Mar 23 01:21:02 2005
|
|
|
+@@ -327,20 +327,22 @@
|
|
|
+ (match_operand:SI 1 "general_src_operand" "mSr,mSa,KTr,Ksr,>")))]
|
|
|
+ "!TARGET_COLDFIRE"
|
|
|
+ {
|
|
|
++/* (TIGCC 20040222) This used %d0 and %d1 to force absolute addressing, which
|
|
|
++ doesn't make sense and breaks -mpcrel. -- Kevin Kofler */
|
|
|
+ if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
|
|
|
+ return "cmpm%.l %1,%0";
|
|
|
+ if (REG_P (operands[1])
|
|
|
+ || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
|
|
|
+ {
|
|
|
+ cc_status.flags |= CC_REVERSED;
|
|
|
+- return "cmp%.l %d0,%d1";
|
|
|
++ return "cmp%.l %0,%1";
|
|
|
+ }
|
|
|
+ if (ADDRESS_REG_P (operands[0])
|
|
|
+ && GET_CODE (operands[1]) == CONST_INT
|
|
|
+ && INTVAL (operands[1]) < 0x8000
|
|
|
+ && INTVAL (operands[1]) >= -0x8000)
|
|
|
+ return "cmp%.w %1,%0";
|
|
|
+- return "cmp%.l %d1,%d0";
|
|
|
++ return "cmp%.l %1,%0";
|
|
|
+ })
|
|
|
+
|
|
|
+ (define_insn ""
|
|
|
+@@ -358,52 +360,62 @@
|
|
|
+ return "cmp%.l %d1,%d0";
|
|
|
+ })
|
|
|
+
|
|
|
++;; (TIGCC 20040808) Don't allow source-only operands as the destination in the
|
|
|
++;; compare. We need to use nonimmediate_operand, not
|
|
|
++;; nonimmediate_src_operand. Otherwise, -mpcrel outputs invalid
|
|
|
++;; assembly code. The SImode patterns already got this right.
|
|
|
++;; -- Kevin Kofler
|
|
|
++
|
|
|
+ (define_expand "cmphi"
|
|
|
+ [(set (cc0)
|
|
|
+- (compare (match_operand:HI 0 "nonimmediate_src_operand" "")
|
|
|
++ (compare (match_operand:HI 0 "nonimmediate_operand" "")
|
|
|
+ (match_operand:HI 1 "general_src_operand" "")))]
|
|
|
+ "!TARGET_COLDFIRE"
|
|
|
+ "m68k_last_compare_had_fp_operands = 0;")
|
|
|
+
|
|
|
+ (define_insn ""
|
|
|
+ [(set (cc0)
|
|
|
+- (compare (match_operand:HI 0 "nonimmediate_src_operand" "rnmS,d,n,mS,>")
|
|
|
++ (compare (match_operand:HI 0 "nonimmediate_operand" "rnmS,d,n,mS,>")
|
|
|
+ (match_operand:HI 1 "general_src_operand" "d,rnmS,mS,n,>")))]
|
|
|
+ "!TARGET_COLDFIRE"
|
|
|
+ {
|
|
|
++/* (TIGCC 20040222) This used %d0 and %d1 to force absolute addressing, which
|
|
|
++ doesn't make sense and breaks -mpcrel. -- Kevin Kofler */
|
|
|
+ if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
|
|
|
+ return "cmpm%.w %1,%0";
|
|
|
+ if ((REG_P (operands[1]) && !ADDRESS_REG_P (operands[1]))
|
|
|
+ || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
|
|
|
+ {
|
|
|
+ cc_status.flags |= CC_REVERSED;
|
|
|
+- return "cmp%.w %d0,%d1";
|
|
|
++ return "cmp%.w %0,%1";
|
|
|
+ }
|
|
|
+- return "cmp%.w %d1,%d0";
|
|
|
++ return "cmp%.w %1,%0";
|
|
|
+ })
|
|
|
+
|
|
|
+ (define_expand "cmpqi"
|
|
|
+ [(set (cc0)
|
|
|
+- (compare (match_operand:QI 0 "nonimmediate_src_operand" "")
|
|
|
++ (compare (match_operand:QI 0 "nonimmediate_operand" "")
|
|
|
+ (match_operand:QI 1 "general_src_operand" "")))]
|
|
|
+ "!TARGET_COLDFIRE"
|
|
|
+ "m68k_last_compare_had_fp_operands = 0;")
|
|
|
+
|
|
|
+ (define_insn ""
|
|
|
+ [(set (cc0)
|
|
|
+- (compare (match_operand:QI 0 "nonimmediate_src_operand" "dn,dmS,>")
|
|
|
++ (compare (match_operand:QI 0 "nonimmediate_operand" "dn,dmS,>")
|
|
|
+ (match_operand:QI 1 "general_src_operand" "dmS,nd,>")))]
|
|
|
+ "!TARGET_COLDFIRE"
|
|
|
+ {
|
|
|
++/* (TIGCC 20040222) This used %d0 and %d1 to force absolute addressing, which
|
|
|
++ doesn't make sense and breaks -mpcrel. -- Kevin Kofler */
|
|
|
+ if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
|
|
|
+ return "cmpm%.b %1,%0";
|
|
|
+ if (REG_P (operands[1])
|
|
|
+ || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
|
|
|
+ {
|
|
|
+ cc_status.flags |= CC_REVERSED;
|
|
|
+- return "cmp%.b %d0,%d1";
|
|
|
++ return "cmp%.b %0,%1";
|
|
|
+ }
|
|
|
+- return "cmp%.b %d1,%d0";
|
|
|
++ return "cmp%.b %1,%0";
|
|
|
+ })
|
|
|
+
|
|
|
+ (define_expand "cmpdf"
|
|
|
+@@ -691,10 +703,11 @@
|
|
|
+
|
|
|
+ ;; Special case of fullword move, where we need to get a non-GOT PIC
|
|
|
+ ;; reference into an address register.
|
|
|
++;; (TIGCC 20040808) This is also needed for -freg-relative-an. -- Kevin Kofler
|
|
|
+ (define_insn ""
|
|
|
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=a<")
|
|
|
+ (match_operand:SI 1 "pcrel_address" ""))]
|
|
|
+- "TARGET_PCREL"
|
|
|
++ "TARGET_PCREL || TARGET_REG_RELATIVE"
|
|
|
+ {
|
|
|
+ if (push_operand (operands[0], SImode))
|
|
|
+ return "pea %a1";
|
|
|
+@@ -773,13 +786,49 @@
|
|
|
+ "TARGET_COLDFIRE"
|
|
|
+ "* return output_move_strictqi (operands);")
|
|
|
+
|
|
|
++;; (TIGCC 20050210) Distinguish nonmemory_operand vs. memory_operand here, and
|
|
|
++;; optimize pushes from nonmemory_operand to word pushes. We
|
|
|
++;; can't do that for memory operands because of odd addresses.
|
|
|
++;; The distinction between register_operand and
|
|
|
++;; const_int_operand is because of paradoxical subreg
|
|
|
++;; technicalities.
|
|
|
++
|
|
|
+ (define_expand "pushqi1"
|
|
|
++ [(match_operand:QI 0 "general_operand" "")]
|
|
|
++ "!TARGET_COLDFIRE"
|
|
|
++"{
|
|
|
++ if (const_int_operand (operands[0], QImode))
|
|
|
++ emit_insn (gen_pushqi1_imm (operands[0]));
|
|
|
++ else if (register_operand (operands[0], QImode)) {
|
|
|
++ if (GET_CODE (operands[0]) == SUBREG)
|
|
|
++ emit_insn (gen_pushqi1_reg (SUBREG_REG (operands[0])));
|
|
|
++ else
|
|
|
++ emit_insn (gen_pushqi1_reg (operands[0]));
|
|
|
++ } else
|
|
|
++ emit_insn (gen_pushqi1_mem (operands[0]));
|
|
|
++ DONE;
|
|
|
++}")
|
|
|
++
|
|
|
++(define_expand "pushqi1_mem"
|
|
|
+ [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -2)))
|
|
|
+ (set (mem:QI (plus:SI (reg:SI SP_REG) (const_int 1)))
|
|
|
+ (match_operand:QI 0 "general_operand" ""))]
|
|
|
+ "!TARGET_COLDFIRE"
|
|
|
+ "")
|
|
|
+
|
|
|
++(define_expand "pushqi1_imm"
|
|
|
++ [(set (mem:HI (pre_dec:SI (reg:SI SP_REG)))
|
|
|
++ (match_operand:HI 0 "const_int_operand" ""))]
|
|
|
++ "!TARGET_COLDFIRE"
|
|
|
++ "")
|
|
|
++
|
|
|
++;; Yes, this is a paradoxical subreg.
|
|
|
++(define_expand "pushqi1_reg"
|
|
|
++ [(set (mem:HI (pre_dec:SI (reg:SI SP_REG)))
|
|
|
++ (subreg:HI (match_operand:QI 0 "register_operand" "") 0))]
|
|
|
++ "!TARGET_COLDFIRE"
|
|
|
++ "")
|
|
|
++
|
|
|
+ (define_expand "movsf"
|
|
|
+ [(set (match_operand:SF 0 "nonimmediate_operand" "")
|
|
|
+ (match_operand:SF 1 "general_operand" ""))]
|
|
|
+@@ -895,6 +944,34 @@
|
|
|
+ ;; constants. Most but not all have output templates that handle constants.
|
|
|
+ ;; See also LEGITIMATE_CONSTANT_P.
|
|
|
+
|
|
|
++(define_expand "movbf"
|
|
|
++ ;; SMAP BCD
|
|
|
++ [(set (match_operand:BF 0 "nonimmediate_operand" "")
|
|
|
++ (match_operand:BF 1 "general_operand" ""))]
|
|
|
++ ""
|
|
|
++ "
|
|
|
++{
|
|
|
++ /* We can't rewrite operands during reload. */
|
|
|
++ if (! reload_in_progress)
|
|
|
++ {
|
|
|
++ if (CONSTANT_P (operands[1]))
|
|
|
++ {
|
|
|
++ operands[1] = force_const_mem (BFmode, operands[1]);
|
|
|
++ if (! memory_address_p (BFmode, XEXP (operands[1], 0)))
|
|
|
++ operands[1] = adjust_address (operands[1], BFmode, 0);
|
|
|
++ }
|
|
|
++ if (flag_pic && TARGET_PCREL)
|
|
|
++ {
|
|
|
++ /* Don't allow writes to memory except via a register; the
|
|
|
++ m68k doesn't consider PC-relative addresses to be writable. */
|
|
|
++ if (GET_CODE (operands[0]) == MEM
|
|
|
++ && symbolic_operand (XEXP (operands[0], 0), SImode))
|
|
|
++ operands[0] = gen_rtx_MEM (BFmode,
|
|
|
++ force_reg (SImode, XEXP (operands[0], 0)));
|
|
|
++ }
|
|
|
++ }
|
|
|
++}")
|
|
|
++
|
|
|
+ (define_expand "movxf"
|
|
|
+ [(set (match_operand:XF 0 "nonimmediate_operand" "")
|
|
|
+ (match_operand:XF 1 "general_operand" ""))]
|
|
|
+@@ -961,6 +1038,46 @@
|
|
|
+ })
|
|
|
+
|
|
|
+ (define_insn ""
|
|
|
++ ;; SMAP BCD
|
|
|
++ [(set (match_operand:BF 0 "nonimmediate_operand" "=rm,rf,&rof<>")
|
|
|
++ (match_operand:BF 1 "nonimmediate_operand" "rf,m,rof<>"))]
|
|
|
++ "! TARGET_68881 && ! TARGET_COLDFIRE"
|
|
|
++{
|
|
|
++ if (FP_REG_P (operands[0]))
|
|
|
++ {
|
|
|
++ if (FP_REG_P (operands[1]))
|
|
|
++ return "fmove%.x %1,%0";
|
|
|
++ if (REG_P (operands[1]))
|
|
|
++ {
|
|
|
++ rtx xoperands[2];
|
|
|
++ xoperands[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 2);
|
|
|
++ output_asm_insn ("move%.w %1,%-", xoperands);
|
|
|
++ xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
|
|
|
++ output_asm_insn ("move%.l %1,%-", xoperands);
|
|
|
++ output_asm_insn ("move%.l %1,%-", operands);
|
|
|
++ return "fmove%.x %+,%0";
|
|
|
++ }
|
|
|
++ if (GET_CODE (operands[1]) == CONST_DOUBLE)
|
|
|
++ return "fmove%.x %1,%0";
|
|
|
++ return "fmove%.x %f1,%0";
|
|
|
++ }
|
|
|
++ if (FP_REG_P (operands[1]))
|
|
|
++ {
|
|
|
++ if (REG_P (operands[0]))
|
|
|
++ {
|
|
|
++ output_asm_insn ("fmove%.x %f1,%-\;move%.l %+,%0", operands);
|
|
|
++ operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
|
|
|
++ output_asm_insn ("move%.l %+,%0", operands);
|
|
|
++ operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
|
|
|
++ return "move%.w %+,%0";
|
|
|
++ }
|
|
|
++ else
|
|
|
++ return "fmove%.x %f1,%0";
|
|
|
++ }
|
|
|
++ return output_move_double (operands);
|
|
|
++})
|
|
|
++
|
|
|
++(define_insn ""
|
|
|
+ [(set (match_operand:XF 0 "nonimmediate_operand" "=rm,rf,&rof<>")
|
|
|
+ (match_operand:XF 1 "nonimmediate_operand" "rf,m,rof<>"))]
|
|
|
+ "! TARGET_68881 && ! TARGET_COLDFIRE"
|
|
|
+@@ -1227,9 +1344,12 @@
|
|
|
+ "TARGET_CFV4"
|
|
|
+ "mvz%.w %1,%0")
|
|
|
+
|
|
|
++;; (TIGCC 20050210) We need to mark the register operand as earlyclobber in the
|
|
|
++;; case of memory operands to avoid having to split (see
|
|
|
++;; reg_mentioned_p below) things.
|
|
|
+ (define_insn "zero_extendhisi2"
|
|
|
+- [(set (match_operand:SI 0 "register_operand" "=d")
|
|
|
+- (zero_extend:SI (match_operand:HI 1 "nonimmediate_src_operand" "rmS")))]
|
|
|
++ [(set (match_operand:SI 0 "register_operand" "=d,&d")
|
|
|
++ (zero_extend:SI (match_operand:HI 1 "nonimmediate_src_operand" "r,mS")))]
|
|
|
+ ""
|
|
|
+ "#")
|
|
|
+
|
|
|
+@@ -1252,8 +1372,8 @@
|
|
|
+ "mvz%.b %1,%0")
|
|
|
+
|
|
|
+ (define_insn "zero_extendqisi2"
|
|
|
+- [(set (match_operand:SI 0 "register_operand" "=d")
|
|
|
+- (zero_extend:SI (match_operand:QI 1 "nonimmediate_src_operand" "dmS")))]
|
|
|
++ [(set (match_operand:SI 0 "register_operand" "=d,&d")
|
|
|
++ (zero_extend:SI (match_operand:QI 1 "nonimmediate_src_operand" "d,mS")))]
|
|
|
+ ""
|
|
|
+ "#")
|
|
|
+
|
|
|
+@@ -4125,7 +4245,11 @@
|
|
|
+ output_asm_insn (INTVAL (operands[2]) <= 8 ? "asr%.l %2,%0" :
|
|
|
+ "moveq %2,%1\;asr%.l %1,%0", operands);
|
|
|
+ output_asm_insn ("mov%.l %0,%1\;smi %0", operands);
|
|
|
+- return INTVAL (operands[2]) >= 15 ? "ext%.w %d0" :
|
|
|
++/* (TIGCC 20040222) The %d0 here was a typo or thinko. It means 'force absolute
|
|
|
++ addressing' in this context, not 'data register'. This
|
|
|
++ doesn't make sense in a context where only data registers
|
|
|
++ are allowed, so I removed it. -- Kevin Kofler */
|
|
|
++ return INTVAL (operands[2]) >= 15 ? "ext%.w %0" :
|
|
|
+ TARGET_68020 ? "extb%.l %0" : "ext%.w %0\;ext%.l %0";
|
|
|
+ }
|
|
|
+ })
|
|
|
+@@ -6333,10 +6457,19 @@
|
|
|
+ return "rtd %0";
|
|
|
+ })
|
|
|
+
|
|
|
++;; (TIGCC 20040222) Use jra instead of jmp here. Also don't add (%pc) under
|
|
|
++;; -mpcrel. Moreover, we need to handle extended address
|
|
|
++;; operands here. -- Kevin Kofler
|
|
|
++;; (TIGCC 20050204) Use plain bra for labels under -mpcrel to guarantee PC-rel
|
|
|
++;; code.
|
|
|
+ (define_insn "indirect_jump"
|
|
|
+- [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
|
|
|
++ [(set (pc) (match_operand:SI 0 "extended_address_operand" "p"))]
|
|
|
+ ""
|
|
|
+- "jmp %a0")
|
|
|
++{
|
|
|
++ return (TARGET_PCREL && GET_CODE (operands[0]) == MEM
|
|
|
++ && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)?
|
|
|
++ "bra %A0":"jra %A0";
|
|
|
++})
|
|
|
+
|
|
|
+ ;; This should not be used unless the add/sub insns can't be.
|
|
|
+
|
|
|
+@@ -6430,6 +6563,9 @@
|
|
|
+ })
|
|
|
+
|
|
|
+ ;; Speed up stack adjust followed by a fullword fixedpoint push.
|
|
|
++;; (TIGCC 20050211) Don't do this if pushing an immediate operand in range for
|
|
|
++;; a pea, and a stack adjust is needed anyway. That would
|
|
|
++;; generate bigger (or same size) and slower code.
|
|
|
+
|
|
|
+ (define_peephole
|
|
|
+ [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
|
|
|
+@@ -6437,7 +6573,8 @@
|
|
|
+ (set (match_operand:SI 1 "push_operand" "=m")
|
|
|
+ (match_operand:SI 2 "general_operand" "g"))]
|
|
|
+ "INTVAL (operands[0]) >= 4
|
|
|
+- && ! reg_mentioned_p (stack_pointer_rtx, operands[2])"
|
|
|
++ && ! reg_mentioned_p (stack_pointer_rtx, operands[2])
|
|
|
++ && !(INTVAL (operands[0]) > 4 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) && INTVAL (operands[2]) >= -0x8000 && INTVAL (operands[2]) < 0x8000)"
|
|
|
+ {
|
|
|
+ if (INTVAL (operands[0]) > 4)
|
|
|
+ {
|
|
|
+@@ -6473,6 +6610,77 @@
|
|
|
+ return "move%.l %2,%@";
|
|
|
+ })
|
|
|
+
|
|
|
++;; (TIGCC 20050207) Bundle 2 immediate word pushes to the stack into 1 immediate
|
|
|
++;; longword push.
|
|
|
++
|
|
|
++(define_peephole
|
|
|
++ [(set (match_operand:HI 0 "push_operand" "=m")
|
|
|
++ (match_operand:HI 1 "const_int_operand" "n"))
|
|
|
++ (set (match_operand:HI 2 "push_operand" "=m")
|
|
|
++ (match_operand:HI 3 "const_int_operand" "n"))]
|
|
|
++ ""
|
|
|
++{
|
|
|
++ rtx xoperands[2];
|
|
|
++ xoperands[0] = operands[0];
|
|
|
++ xoperands[1] = GEN_INT ((INTVAL (operands[1]) & 0xFFFF) + (INTVAL (operands[3]) << 16));
|
|
|
++ output_asm_insn (output_move_simode_const (xoperands), xoperands);
|
|
|
++ CC_STATUS_INIT; /* We clobbered the CC. */
|
|
|
++ return "";
|
|
|
++})
|
|
|
++
|
|
|
++;; (TIGCC 20050210) Same as above, but with a stack adjust.
|
|
|
++
|
|
|
++(define_peephole
|
|
|
++ [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
|
|
|
++ (match_operand:SI 0 "const_int_operand" "n")))
|
|
|
++ (set (mem:HI (reg:SI SP_REG))
|
|
|
++ (match_operand:HI 1 "const_int_operand" "n"))
|
|
|
++ (set (match_operand:HI 2 "push_operand" "=m")
|
|
|
++ (match_operand:HI 3 "const_int_operand" "n"))]
|
|
|
++ "INTVAL (operands[0]) >= 2"
|
|
|
++{
|
|
|
++ HOST_WIDE_INT longword = (INTVAL (operands[1]) & 0xFFFF) + (INTVAL (operands[3]) << 16);
|
|
|
++ bool usepea = longword && longword < 0x8000 && longword >= -0x8000
|
|
|
++ && INTVAL (operands[0]) > 2;
|
|
|
++ rtx xoperands[2];
|
|
|
++ if (INTVAL (operands[0]) > 2)
|
|
|
++ {
|
|
|
++ xoperands[0] = stack_pointer_rtx;
|
|
|
++ xoperands[1] = GEN_INT (INTVAL (operands[0]) + (usepea?2:-2));
|
|
|
++ if (INTVAL (xoperands[1]) <= 8)
|
|
|
++ {
|
|
|
++ if (!TARGET_COLDFIRE)
|
|
|
++ output_asm_insn ("addq%.w %1,%0", xoperands);
|
|
|
++ else
|
|
|
++ output_asm_insn ("addq%.l %1,%0", xoperands);
|
|
|
++ }
|
|
|
++ else if (TARGET_CPU32 && INTVAL (xoperands[1]) <= 16)
|
|
|
++ {
|
|
|
++ xoperands[1] = GEN_INT (INTVAL (xoperands[1]) - 8);
|
|
|
++ output_asm_insn ("addq%.w #8,%0\;addq%.w %1,%0", xoperands);
|
|
|
++ }
|
|
|
++ else if (INTVAL (xoperands[1]) <= 0x7FFF)
|
|
|
++ {
|
|
|
++ if (TARGET_68040)
|
|
|
++ output_asm_insn ("add%.w %1,%0", xoperands);
|
|
|
++ else if (MOTOROLA)
|
|
|
++ output_asm_insn ("lea (%c1,%0),%0", xoperands);
|
|
|
++ else
|
|
|
++ output_asm_insn ("lea %0@(%c1),%0", xoperands);
|
|
|
++ }
|
|
|
++ else
|
|
|
++ output_asm_insn ("add%.l %1,%0", xoperands);
|
|
|
++ }
|
|
|
++ if (usepea)
|
|
|
++ xoperands[0] = operands[2];
|
|
|
++ else
|
|
|
++ xoperands[0] = gen_rtx_MEM (SImode, stack_pointer_rtx);
|
|
|
++ xoperands[1] = GEN_INT (longword);
|
|
|
++ output_asm_insn (output_move_simode_const (xoperands), xoperands);
|
|
|
++ CC_STATUS_INIT; /* We clobbered the CC. */
|
|
|
++ return "";
|
|
|
++})
|
|
|
++
|
|
|
+ ;; Speed up pushing a single byte but leaving four bytes of space.
|
|
|
+
|
|
|
+ (define_peephole
|
|
|
+@@ -7107,3 +7315,166 @@
|
|
|
+ default: abort();
|
|
|
+ }
|
|
|
+ })
|
|
|
++
|
|
|
++;; (TIGCC 20050210) Optimize lea (4,%an),%am; move.l foo,-(%am) into
|
|
|
++;; move.l %an,%am; move.l foo,(%an)
|
|
|
++;; (TIGCC 20050211) Don't do this if foo is an immediate operand in range for
|
|
|
++;; a moveq (because the movsi insn won't like that).
|
|
|
++(define_peephole2
|
|
|
++ [(set (match_operand:SI 0 "register_operand" "")
|
|
|
++ (plus:SI (match_operand:SI 1 "register_operand" "")
|
|
|
++ (const_int 4)))
|
|
|
++ (set (mem:SI (pre_dec:SI (match_dup 0)))
|
|
|
++ (match_operand:SI 2 "general_operand" ""))]
|
|
|
++ "REG_P(operands[1]) && (REGNO (operands[1]) ^ 010) < 8 && ! reg_mentioned_p (operands[0], operands[2]) && !(GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) && INTVAL (operands[2]) >= -128 && INTVAL (operands[2]) < 128)"
|
|
|
++ [(set (match_dup 0) (match_dup 1))
|
|
|
++ (set (mem:SI (match_dup 1)) (match_dup 2))]
|
|
|
++ "")
|
|
|
++
|
|
|
++;; (TIGCC 20050211) Optimize lea (4,%an),%am; move.l #foo,-(%am), foo!=0,
|
|
|
++;; -128<=foo<128 into moveq.l #foo,%dx; move.l %an,%am;
|
|
|
++;; move.l %dx,(%an) if we have a free data register to do that.
|
|
|
++(define_peephole2
|
|
|
++ [(match_scratch:SI 0 "d")
|
|
|
++ (set (match_operand:SI 1 "register_operand" "")
|
|
|
++ (plus:SI (match_operand:SI 2 "register_operand" "")
|
|
|
++ (const_int 4)))
|
|
|
++ (match_dup 0)
|
|
|
++ (set (mem:SI (pre_dec:SI (match_dup 1)))
|
|
|
++ (match_operand:SI 3 "const_int_operand" ""))]
|
|
|
++ "REG_P(operands[2]) && (REGNO (operands[2]) ^ 010) < 8 && INTVAL (operands[3]) && INTVAL (operands[3]) >= -128 && INTVAL (operands[3]) < 128"
|
|
|
++ [(set (match_dup 0) (match_dup 3))
|
|
|
++ (set (match_dup 1) (match_dup 2))
|
|
|
++ (set (mem:SI (match_dup 2)) (match_dup 0))]
|
|
|
++ "")
|
|
|
++
|
|
|
++;; (TIGCC 20050210) Optimize lea (2,%an),%am; move.w foo,-(%am) into
|
|
|
++;; move.l %an,%am; move.w foo,(%an)
|
|
|
++(define_peephole2
|
|
|
++ [(set (match_operand:SI 0 "register_operand" "")
|
|
|
++ (plus:SI (match_operand:SI 1 "register_operand" "")
|
|
|
++ (const_int 2)))
|
|
|
++ (set (mem:HI (pre_dec:SI (match_dup 0)))
|
|
|
++ (match_operand:HI 2 "general_operand" ""))]
|
|
|
++ "REG_P(operands[1]) && (REGNO (operands[1]) ^ 010) < 8 && ! reg_mentioned_p (operands[0], operands[2])"
|
|
|
++ [(set (match_dup 0) (match_dup 1))
|
|
|
++ (set (mem:HI (match_dup 1)) (match_dup 2))]
|
|
|
++ "")
|
|
|
++
|
|
|
++;; (TIGCC 20050210) Optimize lea (1,%an),%am; move.w foo,-(%am), m!=7 into
|
|
|
++;; move.l %an,%am; move.b foo,(%an)
|
|
|
++(define_peephole2
|
|
|
++ [(set (match_operand:SI 0 "register_operand" "")
|
|
|
++ (plus:SI (match_operand:SI 1 "register_operand" "")
|
|
|
++ (const_int 1)))
|
|
|
++ (set (mem:QI (pre_dec:SI (match_dup 0)))
|
|
|
++ (match_operand:QI 2 "general_operand" ""))]
|
|
|
++ "REG_P(operands[1]) && (REGNO (operands[1]) ^ 010) < 8 && !(REG_P(operands[0]) && REGNO (operands[0]) == STACK_POINTER_REGNUM) && ! reg_mentioned_p (operands[0], operands[2])"
|
|
|
++ [(set (match_dup 0) (match_dup 1))
|
|
|
++ (set (mem:QI (match_dup 1)) (match_dup 2))]
|
|
|
++ "")
|
|
|
++
|
|
|
++;; (TIGCC 20050210) Optimize lea (x,%an),%am; move.l foo,-(%am), x!=4,
|
|
|
++;; x>=-0x7ffc into lea (x-4,%an),%am; move.l foo,(%am)
|
|
|
++;; (TIGCC 20050211) Don't do this if foo is an immediate operand in range for
|
|
|
++;; a pea (especially not if in range for a moveq, because the
|
|
|
++;; movsi insn won't like that).
|
|
|
++(define_peephole2
|
|
|
++ [(set (match_operand:SI 0 "register_operand" "")
|
|
|
++ (plus:SI (match_operand:SI 1 "register_operand" "")
|
|
|
++ (match_operand:SI 2 "const_int_operand" "")))
|
|
|
++ (set (mem:SI (pre_dec:SI (match_dup 0)))
|
|
|
++ (match_operand:SI 3 "general_operand" ""))]
|
|
|
++ "REG_P(operands[1]) && (REGNO (operands[1]) ^ 010) < 8 && ! reg_mentioned_p (operands[0], operands[3]) && INTVAL (operands[2]) != 4 && INTVAL (operands[2]) >= -0x7ffc && !(GET_CODE (operands[3]) == CONST_INT && INTVAL (operands[3]) && INTVAL (operands[3]) >= -0x8000 && INTVAL (operands[3]) < 0x8000)"
|
|
|
++ [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
|
|
|
++ (set (mem:SI (match_dup 0)) (match_dup 3))]
|
|
|
++ "operands[2] = GEN_INT (INTVAL (operands[2]) - 4);")
|
|
|
++
|
|
|
++;; (TIGCC 20050210) Optimize lea (x,%an),%am; move.w foo,-(%am), m!=7, x!=2,
|
|
|
++;; x>=-0x7ffe into lea (x-2,%an),%am; move.w foo,(%am)
|
|
|
++(define_peephole2
|
|
|
++ [(set (match_operand:SI 0 "register_operand" "")
|
|
|
++ (plus:SI (match_operand:SI 1 "register_operand" "")
|
|
|
++ (match_operand:SI 2 "const_int_operand" "")))
|
|
|
++ (set (mem:HI (pre_dec:SI (match_dup 0)))
|
|
|
++ (match_operand:HI 3 "general_operand" ""))]
|
|
|
++ "REG_P(operands[1]) && (REGNO (operands[1]) ^ 010) < 8 && ! reg_mentioned_p (operands[0], operands[3]) && INTVAL (operands[2]) != 2 && INTVAL (operands[2]) >= -0x7ffe"
|
|
|
++ [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
|
|
|
++ (set (mem:HI (match_dup 0)) (match_dup 3))]
|
|
|
++ "operands[2] = GEN_INT (INTVAL (operands[2]) - 2);")
|
|
|
++
|
|
|
++;; (TIGCC 20050210) Optimize lea (x,%an),%am; move.b foo,-(%am), m!=7, x!=1,
|
|
|
++;; x>=-0x7fff into lea (x-1,%an),%am; move.b foo,(%am)
|
|
|
++(define_peephole2
|
|
|
++ [(set (match_operand:SI 0 "register_operand" "")
|
|
|
++ (plus:SI (match_operand:SI 1 "register_operand" "")
|
|
|
++ (match_operand:SI 2 "const_int_operand" "")))
|
|
|
++ (set (mem:QI (pre_dec:SI (match_dup 0)))
|
|
|
++ (match_operand:QI 3 "general_operand" ""))]
|
|
|
++ "REG_P(operands[1]) && (REGNO (operands[1]) ^ 010) < 8 && !(REG_P(operands[0]) && REGNO (operands[0]) == STACK_POINTER_REGNUM) && ! reg_mentioned_p (operands[0], operands[3]) && INTVAL (operands[2]) != 1 && INTVAL (operands[2]) >= -0x7fff"
|
|
|
++ [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
|
|
|
++ (set (mem:QI (match_dup 0)) (match_dup 3))]
|
|
|
++ "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
|
|
|
++
|
|
|
++;; (TIGCC 20050213) Optimize and #const1,%dn; and #const2,%dn (generated by
|
|
|
++;; zero_extend) into and #const1&const2,%dn
|
|
|
++
|
|
|
++(define_peephole2
|
|
|
++ [(set (match_operand:SI 0 "register_operand" "")
|
|
|
++ (and:SI (match_dup 0)
|
|
|
++ (match_operand:SI 1 "const_int_operand" "")))
|
|
|
++ (set (match_dup 0)
|
|
|
++ (and:SI (match_dup 0)
|
|
|
++ (match_operand:SI 2 "const_int_operand" "")))]
|
|
|
++ ""
|
|
|
++ [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))]
|
|
|
++ "operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));")
|
|
|
++
|
|
|
++(define_peephole2
|
|
|
++ [(set (match_operand:HI 0 "register_operand" "")
|
|
|
++ (and:HI (match_dup 0)
|
|
|
++ (match_operand:HI 1 "const_int_operand" "")))
|
|
|
++ (set (match_dup 0)
|
|
|
++ (and:HI (match_dup 0)
|
|
|
++ (match_operand:HI 2 "const_int_operand" "")))]
|
|
|
++ ""
|
|
|
++ [(set (match_dup 0) (and:HI (match_dup 0) (match_dup 1)))]
|
|
|
++ "operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));")
|
|
|
++
|
|
|
++(define_peephole2
|
|
|
++ [(set (match_operand:QI 0 "register_operand" "")
|
|
|
++ (and:QI (match_dup 0)
|
|
|
++ (match_operand:QI 1 "const_int_operand" "")))
|
|
|
++ (set (match_dup 0)
|
|
|
++ (and:QI (match_dup 0)
|
|
|
++ (match_operand:QI 2 "const_int_operand" "")))]
|
|
|
++ ""
|
|
|
++ [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
|
|
|
++ "operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));")
|
|
|
++
|
|
|
++;; (TIGCC 20050213) Optimize and.l #65535,%dn; clr.w %dn (generated by
|
|
|
++;; zero_extend) into moveq #0,%dn
|
|
|
++
|
|
|
++(define_peephole2
|
|
|
++ [(set (match_operand:SI 0 "register_operand" "")
|
|
|
++ (and:SI (match_dup 0)
|
|
|
++ (const_int 65535)))
|
|
|
++ (set (strict_low_part (match_operand:HI 1 "register_operand" ""))
|
|
|
++ (const_int 0))]
|
|
|
++ "REG_P(operands[0]) && REG_P(operands[1]) && REGNO(operands[0]) == REGNO(operands[1])"
|
|
|
++ [(set (match_dup 0) (const_int 0))]
|
|
|
++ "")
|
|
|
++
|
|
|
++;; (TIGCC 20050213) Optimize and.w #255,%dn; clr.b %dn (generated by
|
|
|
++;; zero_extend) into clr.w %dn
|
|
|
++
|
|
|
++(define_peephole2
|
|
|
++ [(set (match_operand:HI 0 "register_operand" "")
|
|
|
++ (and:HI (match_dup 0)
|
|
|
++ (const_int 255)))
|
|
|
++ (set (strict_low_part (match_operand:QI 1 "register_operand" ""))
|
|
|
++ (const_int 0))]
|
|
|
++ "REG_P(operands[0]) && REG_P(operands[1]) && REGNO(operands[0]) == REGNO(operands[1])"
|
|
|
++ [(set (strict_low_part (match_dup 0)) (const_int 0))]
|
|
|
++ "")
|
|
|
++
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/config/smapbcd.h gcc-4.0-20050319-src/gcc/config/smapbcd.h
|
|
|
+--- gcc-4.0-20050319.orig/gcc/config/smapbcd.h Thu Jan 1 01:00:00 1970
|
|
|
++++ gcc-4.0-20050319-src/gcc/config/smapbcd.h Wed Mar 23 01:21:02 2005
|
|
|
+@@ -0,0 +1,369 @@
|
|
|
++/* Definitions for SMAP II BCD support in the GNU C Compiler.
|
|
|
++ These macros implement software BCD floating point support;
|
|
|
++ primary use will be TIGCC.
|
|
|
++ Copyright (C) 1994 Free Software Foundation, Inc.
|
|
|
++ Copyright (C) 2000 Sebastian Reichelt
|
|
|
++ Copyright (C) 2003-2005 Kevin Kofler
|
|
|
++
|
|
|
++This file is part of TIGCC.
|
|
|
++
|
|
|
++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. */
|
|
|
++
|
|
|
++#undef TARGET_FLOAT_FORMAT
|
|
|
++#define TARGET_FLOAT_FORMAT SMAP_BCD_FLOAT_FORMAT
|
|
|
++
|
|
|
++#ifndef __SMAP_BCD_FLOAT
|
|
|
++#define __SMAP_BCD_FLOAT
|
|
|
++
|
|
|
++typedef struct real_value smap_bcd_float;
|
|
|
++
|
|
|
++#endif
|
|
|
++
|
|
|
++#undef REAL_VALUE_TYPE
|
|
|
++#define REAL_VALUE_TYPE smap_bcd_float
|
|
|
++
|
|
|
++#undef FLOAT_TYPE_SIZE
|
|
|
++#undef DOUBLE_TYPE_SIZE
|
|
|
++#undef LONG_DOUBLE_TYPE_SIZE
|
|
|
++
|
|
|
++/* We have to define a special mode for this; one that handles 10 byte
|
|
|
++ floats. There have to be a lot of changes to other files; due to the
|
|
|
++ fact that they are so countless, it would be too hard to make them
|
|
|
++ compatible with a general-purpose GCC. */
|
|
|
++#define FLOAT_TYPE_SIZE 80
|
|
|
++#define DOUBLE_TYPE_SIZE 80
|
|
|
++#define LONG_DOUBLE_TYPE_SIZE 80
|
|
|
++
|
|
|
++#ifndef REAL_IS_NOT_DOUBLE
|
|
|
++#define REAL_IS_NOT_DOUBLE
|
|
|
++#endif
|
|
|
++
|
|
|
++#define ZERO (__extension__(smap_bcd_float){0x4000,0})
|
|
|
++#define UNSIGNED_ZERO (__extension__(smap_bcd_float){0x4000,0})
|
|
|
++#define POSITIVE_ZERO (__extension__(smap_bcd_float){0,0})
|
|
|
++#define NEGATIVE_ZERO (__extension__(smap_bcd_float){0x8000,0})
|
|
|
++
|
|
|
++#define UNSIGNED_INF (__extension__(smap_bcd_float){0x7FFF,0xAA00CC0000000000})
|
|
|
++#define POSITIVE_INF (__extension__(smap_bcd_float){0x7FFF,0xAA00BB0000000000})
|
|
|
++#define NEGATIVE_INF (__extension__(smap_bcd_float){0xFFFF,0xAA00BB0000000000})
|
|
|
++
|
|
|
++#define NAN (__extension__(smap_bcd_float){0x7FFF,0xAA00000000000000})
|
|
|
++
|
|
|
++#ifndef REAL_INFINITY
|
|
|
++#define REAL_INFINITY
|
|
|
++#endif
|
|
|
++
|
|
|
++#undef REAL_VALUE_ISNAN
|
|
|
++#define REAL_VALUE_ISNAN(x) \
|
|
|
++ (REAL_VALUES_IDENTICAL (x, NAN))
|
|
|
++
|
|
|
++#undef REAL_VALUE_ISINF
|
|
|
++#define REAL_VALUE_ISINF(x) \
|
|
|
++ ((REAL_VALUES_IDENTICAL (x, POSITIVE_INF)) \
|
|
|
++ || (REAL_VALUES_IDENTICAL (x, NEGATIVE_INF)) \
|
|
|
++ || (REAL_VALUES_IDENTICAL (x, UNSIGNED_INF)))
|
|
|
++
|
|
|
++#define REAL_VALUE_ISNANUINF(x) \
|
|
|
++ ((REAL_VALUE_ISNAN (x)) \
|
|
|
++ || (REAL_VALUES_IDENTICAL (x, UNSIGNED_INF)))
|
|
|
++
|
|
|
++#define REAL_VALUE_ISFINITE(x) \
|
|
|
++ (!(REAL_VALUE_ISNAN (x)) \
|
|
|
++ && !(REAL_VALUE_ISINF (x)))
|
|
|
++
|
|
|
++#define REAL_VALUE_ISZERO(x) \
|
|
|
++ (!((x).mantissa))
|
|
|
++
|
|
|
++#undef REAL_VALUE_MINUS_ZERO
|
|
|
++#define REAL_VALUE_MINUS_ZERO(x) \
|
|
|
++ (REAL_VALUES_IDENTICAL (x, NEGATIVE_ZERO))
|
|
|
++
|
|
|
++#define REAL_VALUE_ISPOSITIVE(x) \
|
|
|
++ (!(REAL_VALUE_ISNANUINF (x)) \
|
|
|
++ && ((x).exponent < 0x8000) \
|
|
|
++ && !(REAL_VALUE_ISZERO (x)))
|
|
|
++
|
|
|
++#define REAL_VALUE_ISNEGATIVE(x) \
|
|
|
++ (!(REAL_VALUE_ISNANUINF (x)) \
|
|
|
++ && ((x).exponent >= 0x8000) \
|
|
|
++ && !(REAL_VALUE_ISZERO (x)))
|
|
|
++
|
|
|
++#undef REAL_VALUE_POSITIVE
|
|
|
++#define REAL_VALUE_POSITIVE(x) \
|
|
|
++ (REAL_VALUE_ISPOSITIVE (x))
|
|
|
++
|
|
|
++#undef REAL_VALUE_NEGATIVE
|
|
|
++#define REAL_VALUE_NEGATIVE(x) \
|
|
|
++ (REAL_VALUE_ISNEGATIVE (x))
|
|
|
++
|
|
|
++#define real_isneg(x) \
|
|
|
++ (REAL_VALUE_ISNEGATIVE (*(x)))
|
|
|
++
|
|
|
++#undef REAL_VALUES_IDENTICAL
|
|
|
++#define REAL_VALUES_IDENTICAL(x, y) \
|
|
|
++ ((x).exponent == (y).exponent && (x).mantissa == (y).mantissa)
|
|
|
++
|
|
|
++#undef REAL_VALUES_EQUAL
|
|
|
++#define REAL_VALUES_EQUAL(x,y) \
|
|
|
++ (((REAL_VALUES_IDENTICAL (x, y)) \
|
|
|
++ && !REAL_VALUE_ISNANUINF (x) \
|
|
|
++ && !REAL_VALUE_ISNANUINF (y)) \
|
|
|
++ || (REAL_VALUE_ISZERO (x) \
|
|
|
++ && REAL_VALUE_ISZERO (y)))
|
|
|
++
|
|
|
++#undef REAL_VALUES_LESS
|
|
|
++#define REAL_VALUES_LESS(x,y) \
|
|
|
++__extension__ ({ \
|
|
|
++ register int result = 0; \
|
|
|
++ if (REAL_VALUE_ISNANUINF (x) \
|
|
|
++ || REAL_VALUE_ISNANUINF (y) \
|
|
|
++ || REAL_VALUES_EQUAL (x, y) \
|
|
|
++ || (REAL_VALUE_ISPOSITIVE (x) && !(REAL_VALUE_ISPOSITIVE (y))) \
|
|
|
++ || (!(REAL_VALUE_ISNEGATIVE (x)) && REAL_VALUE_ISNEGATIVE (y))) \
|
|
|
++ result = 0; \
|
|
|
++ else if ((REAL_VALUE_ISNEGATIVE (x) && !(REAL_VALUE_ISNEGATIVE (y))) \
|
|
|
++ || (!(REAL_VALUE_ISPOSITIVE (x)) && REAL_VALUE_ISPOSITIVE (y))) \
|
|
|
++ result = 1; \
|
|
|
++ else \
|
|
|
++ { \
|
|
|
++ if ((x).exponent == (y).exponent) \
|
|
|
++ { \
|
|
|
++ if (REAL_VALUE_ISNEGATIVE (x)) \
|
|
|
++ result = ((x).mantissa > (y).mantissa); \
|
|
|
++ else \
|
|
|
++ result = ((x).mantissa < (y).mantissa); \
|
|
|
++ } \
|
|
|
++ else \
|
|
|
++ { \
|
|
|
++ if (REAL_VALUE_ISNEGATIVE (x)) \
|
|
|
++ result = ((x).exponent > (y).exponent); \
|
|
|
++ else \
|
|
|
++ result = ((x).exponent < (y).exponent); \
|
|
|
++ } \
|
|
|
++ } \
|
|
|
++ result; \
|
|
|
++})
|
|
|
++
|
|
|
++#undef REAL_VALUE_LDEXP
|
|
|
++#define REAL_VALUE_LDEXP(x,tempscale) \
|
|
|
++__extension__ ({ \
|
|
|
++ REAL_VALUE_TYPE __tempx = x; \
|
|
|
++ int scale; \
|
|
|
++ unsigned long long pmul; \
|
|
|
++ signed short carry, help; \
|
|
|
++ if (REAL_VALUE_ISFINITE (__tempx)) \
|
|
|
++ { \
|
|
|
++ if (tempscale > 0) \
|
|
|
++ for (scale = 0; scale < tempscale; scale++) \
|
|
|
++ { \
|
|
|
++ if (__tempx.mantissa >= 0x5000000000000000) \
|
|
|
++ { \
|
|
|
++ __tempx.mantissa /= 0x10; \
|
|
|
++ __tempx.exponent++; \
|
|
|
++ } \
|
|
|
++ carry = 0; \
|
|
|
++ for (pmul = 1; 1; pmul *= 0x10) \
|
|
|
++ { \
|
|
|
++ help = (__tempx.mantissa / pmul) & 0xF; \
|
|
|
++ __tempx.mantissa -= ((unsigned long long) help) * pmul; \
|
|
|
++ help *= 2; \
|
|
|
++ help += carry; \
|
|
|
++ carry = help / 10; \
|
|
|
++ __tempx.mantissa += ((unsigned long long) (help % 10)) * pmul; \
|
|
|
++ if (pmul >= 0x1000000000000000) \
|
|
|
++ break; \
|
|
|
++ } \
|
|
|
++ } \
|
|
|
++ else if (tempscale < 0) \
|
|
|
++ for (scale = 0; scale > tempscale; scale--) \
|
|
|
++ { \
|
|
|
++ carry = 0; \
|
|
|
++ for (pmul = 0x1000000000000000; pmul > 0; pmul /= 0x10) \
|
|
|
++ { \
|
|
|
++ help = (__tempx.mantissa / pmul) & 0xF; \
|
|
|
++ __tempx.mantissa -= ((unsigned long long) help) * pmul; \
|
|
|
++ help += carry; \
|
|
|
++ __tempx.mantissa += ((unsigned long long) (help / 2)) * pmul; \
|
|
|
++ carry = (help % 2) * 10; \
|
|
|
++ } \
|
|
|
++ if (__tempx.mantissa < 0x1000000000000000) \
|
|
|
++ { \
|
|
|
++ __tempx.mantissa *= 0x10; \
|
|
|
++ __tempx.mantissa += carry / 2; \
|
|
|
++ __tempx.exponent--; \
|
|
|
++ } \
|
|
|
++ } \
|
|
|
++ } \
|
|
|
++ __tempx; \
|
|
|
++})
|
|
|
++
|
|
|
++#undef REAL_VALUE_FIX
|
|
|
++#define REAL_VALUE_FIX(x) \
|
|
|
++ ((REAL_VALUE_ISNEGATIVE (x)) \
|
|
|
++ ? (-(REAL_VALUE_UNSIGNED_FIX (REAL_VALUE_NEGATE (x)))) \
|
|
|
++ : (REAL_VALUE_UNSIGNED_FIX (x)))
|
|
|
++
|
|
|
++#undef REAL_VALUE_UNSIGNED_FIX
|
|
|
++#define REAL_VALUE_UNSIGNED_FIX(x) \
|
|
|
++__extension__ ({ \
|
|
|
++ register unsigned int r = 0; \
|
|
|
++ signed char i; \
|
|
|
++ unsigned long long mpmul = 0x1000000000000000; \
|
|
|
++ if (((x.exponent & 0x7FFF) >= 0x4000) && ((x.exponent & 0x7FFF) < 0x4016)) \
|
|
|
++ { \
|
|
|
++ for (i = 0; i <= (x.exponent & 0x7FFF) - 0x4000; i++) \
|
|
|
++ if (mpmul) \
|
|
|
++ { \
|
|
|
++ r *= 10; \
|
|
|
++ r += (x.mantissa / mpmul) & 0xF; \
|
|
|
++ mpmul /= 0x10; \
|
|
|
++ } \
|
|
|
++ } \
|
|
|
++ r; \
|
|
|
++})
|
|
|
++
|
|
|
++#undef REAL_VALUE_RNDZINT
|
|
|
++#define REAL_VALUE_RNDZINT(x) \
|
|
|
++__extension__ ({ \
|
|
|
++ REAL_VALUE_TYPE r = ZERO; \
|
|
|
++ signed char i; \
|
|
|
++ unsigned long long mpmul = 0x1000000000000000; \
|
|
|
++ r.exponent = (x).exponent; \
|
|
|
++ if (((r.exponent & 0x7FFF) >= 0x4000) && ((r.exponent & 0x7FFF) < 0x4016)) \
|
|
|
++ { \
|
|
|
++ for (i = 0; i <= (r.exponent & 0x7FFF) - 0x4000; i++) \
|
|
|
++ if (mpmul) \
|
|
|
++ { \
|
|
|
++ r.mantissa += x.mantissa & (0xF * mpmul); \
|
|
|
++ mpmul /= 0x10; \
|
|
|
++ } \
|
|
|
++ } \
|
|
|
++ r; \
|
|
|
++})
|
|
|
++
|
|
|
++#undef REAL_VALUE_UNSIGNED_RNDZINT
|
|
|
++#define REAL_VALUE_UNSIGNED_RNDZINT(x) \
|
|
|
++ ((REAL_VALUE_ISPOSITIVE (x)) \
|
|
|
++ ? (REAL_VALUE_RNDZINT (x)) \
|
|
|
++ : (ZERO))
|
|
|
++
|
|
|
++#undef REAL_VALUE_ATOF
|
|
|
++#define REAL_VALUE_ATOF(string,mode) \
|
|
|
++ real_from_string2((string), (mode))
|
|
|
++
|
|
|
++#undef REAL_ARITHMETIC
|
|
|
++#define REAL_ARITHMETIC(value, code, d1, d2) \
|
|
|
++ real_arithmetic (&(value), (code), &(d1), &(d2))
|
|
|
++
|
|
|
++#undef REAL_VALUE_NEGATE
|
|
|
++#define REAL_VALUE_NEGATE(x) \
|
|
|
++__extension__ ({ \
|
|
|
++ REAL_VALUE_TYPE __tempx = x; \
|
|
|
++ if ((!(REAL_VALUE_ISNANUINF (__tempx))) && ((__tempx.mantissa) || (__tempx.exponent != 0x4000))) \
|
|
|
++ __tempx.exponent ^= 0x8000; \
|
|
|
++ __tempx; \
|
|
|
++})
|
|
|
++
|
|
|
++#undef REAL_VALUE_TRUNCATE
|
|
|
++#define REAL_VALUE_TRUNCATE(mode,x) \
|
|
|
++ (x)
|
|
|
++
|
|
|
++#define real_convert(r,mode,x) \
|
|
|
++ (*(r)=*(x))
|
|
|
++
|
|
|
++#define REAL_VALUE_TO_INT(lo, hi, r) real_to_integer2 ((lo), (hi), &(r))
|
|
|
++
|
|
|
++#define REAL_VALUE_FROM_INT(d, lo, hi, mode) \
|
|
|
++ real_from_integer (&(d), (mode), (lo), (hi), 0)
|
|
|
++
|
|
|
++#define REAL_VALUE_FROM_UNSIGNED_INT(d, lo, hi, mode) \
|
|
|
++ real_from_integer (&(d), (mode), (lo), (hi), 1)
|
|
|
++
|
|
|
++#undef REAL_VALUE_TO_TARGET_SINGLE
|
|
|
++#define REAL_VALUE_TO_TARGET_SINGLE(IN, OUT) \
|
|
|
++ abort();
|
|
|
++
|
|
|
++#undef REAL_VALUE_TO_TARGET_DOUBLE
|
|
|
++#define REAL_VALUE_TO_TARGET_DOUBLE(IN, OUT) \
|
|
|
++ abort();
|
|
|
++
|
|
|
++#undef REAL_VALUE_TO_TARGET_LONG_DOUBLE
|
|
|
++#define REAL_VALUE_TO_TARGET_LONG_DOUBLE(IN, OUT) \
|
|
|
++do { \
|
|
|
++ REAL_VALUE_TYPE f = (IN); \
|
|
|
++ (OUT)[0] = f.exponent * 0x10000 + ((unsigned short) (f.mantissa / 0x1000000000000)), (OUT)[1] = (unsigned long) (f.mantissa / 0x10000), (OUT)[2] = ((unsigned short) (f.mantissa)) * 0x10000; \
|
|
|
++} while (0)
|
|
|
++
|
|
|
++#undef REAL_VALUE_TO_TARGET_SMAP_BCD
|
|
|
++#define REAL_VALUE_TO_TARGET_SMAP_BCD(IN, OUT) \
|
|
|
++do { \
|
|
|
++ REAL_VALUE_TYPE f = (IN); \
|
|
|
++ (OUT)[0] = f.exponent, (OUT)[1] = (unsigned long) (f.mantissa / 0x100000000), (OUT)[2] = (unsigned long) (f.mantissa); \
|
|
|
++} while (0)
|
|
|
++
|
|
|
++#define REAL_VALUE_TO_STRING(IN, OUT) \
|
|
|
++do { \
|
|
|
++ REAL_VALUE_TYPE f = (IN); \
|
|
|
++ if (REAL_VALUE_ISNAN (f)) \
|
|
|
++ sprintf ((OUT), "NaN"); \
|
|
|
++ else if (REAL_VALUES_IDENTICAL (f, UNSIGNED_INF)) \
|
|
|
++ sprintf ((OUT), "Inf"); \
|
|
|
++ else if (REAL_VALUES_IDENTICAL (f, POSITIVE_INF)) \
|
|
|
++ sprintf ((OUT), "+Inf"); \
|
|
|
++ else if (REAL_VALUES_IDENTICAL (f, NEGATIVE_INF)) \
|
|
|
++ sprintf ((OUT), "-Inf"); \
|
|
|
++ else if (REAL_VALUES_IDENTICAL (f, UNSIGNED_ZERO)) \
|
|
|
++ sprintf ((OUT), "0.0"); \
|
|
|
++ else if (REAL_VALUES_IDENTICAL (f, POSITIVE_ZERO)) \
|
|
|
++ sprintf ((OUT), "+0.0"); \
|
|
|
++ else if (REAL_VALUES_IDENTICAL (f, NEGATIVE_ZERO)) \
|
|
|
++ sprintf ((OUT), "-0.0"); \
|
|
|
++ else \
|
|
|
++ { \
|
|
|
++ long exp; \
|
|
|
++ int neg = REAL_VALUE_ISNEGATIVE (f); \
|
|
|
++ if (neg) \
|
|
|
++ exp = f.exponent - 0xC000; \
|
|
|
++ else \
|
|
|
++ exp = f.exponent - 0x4000; \
|
|
|
++ sprintf ((OUT), "%s%lx.%07lx%08lxe%d", neg ? "-" : "", (unsigned long) (f.mantissa >> 60), (unsigned long) (f.mantissa >> 32) & 0x0ffffffful, (unsigned long) (f.mantissa), (int) (exp)); \
|
|
|
++ } \
|
|
|
++} while (0)
|
|
|
++
|
|
|
++#define REAL_VALUE_ABS(x) ((REAL_VALUE_ISNEGATIVE((x))\
|
|
|
++ || REAL_VALUE_MINUS_ZERO((x))\
|
|
|
++ || REAL_VALUES_IDENTICAL ((x), NEGATIVE_INF))?\
|
|
|
++ REAL_VALUE_NEGATE((x)):(x))
|
|
|
++
|
|
|
++/* WARNING: This is the number of bits we can represent, not the true size of
|
|
|
++ the mantissa. */
|
|
|
++#define significand_size(dummy) (53)
|
|
|
++
|
|
|
++#undef MODE_HAS_NANS
|
|
|
++#define MODE_HAS_NANS(MODE) ((MODE)==BFmode)
|
|
|
++
|
|
|
++#undef MODE_HAS_INFINITIES
|
|
|
++#define MODE_HAS_INFINITIES(MODE) ((MODE)==BFmode)
|
|
|
++
|
|
|
++/* FIXME: GCC expects this to mean that there is only 0 and -0. We actually have
|
|
|
++ 0, +0 and -0. This allows a few optimizations GCC is too cautious to
|
|
|
++ do in the presence of signed zeros. */
|
|
|
++#undef MODE_HAS_SIGNED_ZEROS
|
|
|
++#define MODE_HAS_SIGNED_ZEROS(MODE) ((MODE)==BFmode)
|
|
|
++
|
|
|
++#define REAL_MODE_FORMAT_COMPOSITE_P(dummy) (0)
|
|
|
++
|
|
|
++/* end of smapbcd.h */
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/config.gcc gcc-4.0-20050319-src/gcc/config.gcc
|
|
|
+--- gcc-4.0-20050319.orig/gcc/config.gcc Sat Mar 19 21:23:58 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/config.gcc Wed Mar 23 01:21:02 2005
|
|
|
+@@ -1291,7 +1291,7 @@
|
|
|
+ m68k-*-coff*)
|
|
|
+ tmake_file=m68k/t-m68kbare
|
|
|
+ tm_defines="MOTOROLA USE_GAS"
|
|
|
+- tm_file="m68k/m68k.h m68k/m68k-none.h m68k/m68kemb.h dbxcoff.h m68k/coff.h dbx.h"
|
|
|
++ tm_file="m68k/m68k.h m68k/m68k-none.h dbxcoff.h m68k/coff.h smapbcd.h m68k/m68k-ti.h dbx.h"
|
|
|
+ use_fixproto=yes
|
|
|
+ ;;
|
|
|
+ m68020-*-elf* | m68k-*-elf*)
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/convert.c gcc-4.0-20050319-src/gcc/convert.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/convert.c Fri Feb 18 00:56:38 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/convert.c Wed Mar 23 01:21:02 2005
|
|
|
+@@ -77,6 +77,9 @@
|
|
|
+ {
|
|
|
+ tree sub, expt, subt;
|
|
|
+
|
|
|
++/* (TIGCC 20050205) We do not implement exact_real_truncate and there is no
|
|
|
++ narrower float mode anyway. -- Kevin Kofler */
|
|
|
++#if 0
|
|
|
+ /* For floating point constant look up the narrowest type that can hold
|
|
|
+ it properly and handle it like (type)(narrowest_type)constant.
|
|
|
+ This way we can optimize for instance a=a*2.0 where "a" is float
|
|
|
+@@ -97,6 +100,7 @@
|
|
|
+ if (type)
|
|
|
+ return build_real (type, real_value_truncate (TYPE_MODE (type), orig));
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ if (TREE_CODE (exp) != NOP_EXPR
|
|
|
+ && TREE_CODE (exp) != CONVERT_EXPR)
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/cppdefault.c gcc-4.0-20050319-src/gcc/cppdefault.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/cppdefault.c Wed Nov 3 04:23:48 2004
|
|
|
++++ gcc-4.0-20050319-src/gcc/cppdefault.c Wed Mar 23 01:21:02 2005
|
|
|
+@@ -46,6 +46,7 @@
|
|
|
+ = INCLUDE_DEFAULTS;
|
|
|
+ #else
|
|
|
+ = {
|
|
|
++#if 0 /* (TIGCC 20040104) Don't hardcode any prefix at compile time. */
|
|
|
+ #ifdef GPLUSPLUS_INCLUDE_DIR
|
|
|
+ /* Pick up GNU C++ generic include files. */
|
|
|
+ { GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1, 0 },
|
|
|
+@@ -85,11 +86,12 @@
|
|
|
+ /* /usr/include comes dead last. */
|
|
|
+ { STANDARD_INCLUDE_DIR, STANDARD_INCLUDE_COMPONENT, 0, 0, 1 },
|
|
|
+ #endif
|
|
|
++#endif /* 0 */
|
|
|
+ { 0, 0, 0, 0, 0 }
|
|
|
+ };
|
|
|
+ #endif /* no INCLUDE_DEFAULTS */
|
|
|
+
|
|
|
+-#ifdef GCC_INCLUDE_DIR
|
|
|
++#if 0 /* (TIGCC 20040104) Don't hardcode any prefix at compile time. */
|
|
|
+ const char cpp_GCC_INCLUDE_DIR[] = GCC_INCLUDE_DIR;
|
|
|
+ const size_t cpp_GCC_INCLUDE_DIR_len = sizeof GCC_INCLUDE_DIR - 8;
|
|
|
+ #else
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/diagnostic.c gcc-4.0-20050319-src/gcc/diagnostic.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/diagnostic.c Mon Feb 7 16:53:26 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/diagnostic.c Wed Mar 23 01:21:02 2005
|
|
|
+@@ -234,9 +234,8 @@
|
|
|
+ if (context->abort_on_error)
|
|
|
+ real_abort ();
|
|
|
+
|
|
|
+- fnotice (stderr, "Please submit a full bug report,\n"
|
|
|
+- "with preprocessed source if appropriate.\n"
|
|
|
+- "See %s for instructions.\n", bug_report_url);
|
|
|
++ fnotice (stderr, "Please fill out a bug report form at %s.\n",
|
|
|
++ bug_report_url);
|
|
|
+ exit (FATAL_EXIT_CODE);
|
|
|
+
|
|
|
+ case DK_FATAL:
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/dwarf2out.c gcc-4.0-20050319-src/gcc/dwarf2out.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/dwarf2out.c Fri Mar 4 16:28:42 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/dwarf2out.c Wed Mar 23 01:21:02 2005
|
|
|
+@@ -9570,14 +9570,7 @@
|
|
|
+ int i;
|
|
|
+
|
|
|
+ REAL_VALUE_FROM_CONST_DOUBLE (rv, rtl);
|
|
|
+- real_to_target (val, &rv, GET_MODE (rtl));
|
|
|
+-
|
|
|
+- /* real_to_target puts 32-bit pieces in each long. Pack them. */
|
|
|
+- for (i = 0; i < GET_MODE_SIZE (GET_MODE (rtl)) / 4; i++)
|
|
|
+- {
|
|
|
+- insert_int (val[i], 4, array);
|
|
|
+- array += 4;
|
|
|
+- }
|
|
|
++ REAL_VALUE_TO_TARGET_SMAP_BCD (rv, array);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Attach a DW_AT_const_value attribute for a variable or a parameter which
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/emit-rtl.c gcc-4.0-20050319-src/gcc/emit-rtl.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/emit-rtl.c Fri Feb 18 07:58:34 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/emit-rtl.c Wed Mar 23 01:21:02 2005
|
|
|
+@@ -103,8 +103,10 @@
|
|
|
+ REAL_VALUE_TYPE dconstm2;
|
|
|
+ REAL_VALUE_TYPE dconsthalf;
|
|
|
+ REAL_VALUE_TYPE dconstthird;
|
|
|
++#if 0
|
|
|
+ REAL_VALUE_TYPE dconstpi;
|
|
|
+ REAL_VALUE_TYPE dconste;
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* All references to the following fixed hard registers go through
|
|
|
+ these unique rtl objects. On machines where the frame-pointer and
|
|
|
+@@ -239,8 +241,8 @@
|
|
|
+ return (CONST_DOUBLE_LOW (a) == CONST_DOUBLE_LOW (b)
|
|
|
+ && CONST_DOUBLE_HIGH (a) == CONST_DOUBLE_HIGH (b));
|
|
|
+ else
|
|
|
+- return real_identical (CONST_DOUBLE_REAL_VALUE (a),
|
|
|
+- CONST_DOUBLE_REAL_VALUE (b));
|
|
|
++ return REAL_VALUES_IDENTICAL (*CONST_DOUBLE_REAL_VALUE (a),
|
|
|
++ *CONST_DOUBLE_REAL_VALUE (b));
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Returns a hash code for X (which is a really a mem_attrs *). */
|
|
|
+@@ -1304,10 +1306,62 @@
|
|
|
+ && (GET_MODE_SIZE (mode) < UNITS_PER_WORD))
|
|
|
+ return 0;
|
|
|
+
|
|
|
+- /* If we want a word outside OP, return zero. */
|
|
|
++ /* If we want a word outside OP, return zero, except for special BFmode cases. */
|
|
|
+ if (mode != BLKmode
|
|
|
+ && (offset + 1) * UNITS_PER_WORD > GET_MODE_SIZE (mode))
|
|
|
++ {
|
|
|
++ if (mode == BFmode)
|
|
|
++ {
|
|
|
++ if (GET_CODE (op) == MEM)
|
|
|
++ {
|
|
|
++ rtx addr = plus_constant (XEXP (op, 0), offset * UNITS_PER_WORD);
|
|
|
++ rtx new;
|
|
|
++
|
|
|
++ if (validate_address)
|
|
|
++ {
|
|
|
++ if (reload_completed)
|
|
|
++ {
|
|
|
++ if (! strict_memory_address_p (HImode, addr))
|
|
|
++ return 0;
|
|
|
++ }
|
|
|
++ else
|
|
|
++ addr = memory_address (HImode, addr);
|
|
|
++ }
|
|
|
++
|
|
|
++ new = gen_rtx_MEM (HImode, addr);
|
|
|
++
|
|
|
++ MEM_COPY_ATTRIBUTES (new, op);
|
|
|
++ MEM_READONLY_P (new) = MEM_READONLY_P (op);
|
|
|
++
|
|
|
++ return new;
|
|
|
++ }
|
|
|
++ else if (REG_P (op))
|
|
|
++ {
|
|
|
++ if (REGNO (op) < FIRST_PSEUDO_REGISTER
|
|
|
++ && REGNO (op) + offset >= FIRST_PSEUDO_REGISTER)
|
|
|
++ return 0;
|
|
|
++
|
|
|
++ if (REGNO (op) < FIRST_PSEUDO_REGISTER
|
|
|
++ && (! HARD_REGNO_MODE_OK (REGNO (op), HImode)
|
|
|
++ || ! HARD_REGNO_MODE_OK (REGNO (op) + offset, HImode)))
|
|
|
++ return 0;
|
|
|
++ else if (REGNO (op) >= FIRST_PSEUDO_REGISTER
|
|
|
++ || (REG_FUNCTION_VALUE_P (op))
|
|
|
++ || op == frame_pointer_rtx
|
|
|
++#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
|
|
|
++ || op == arg_pointer_rtx
|
|
|
++#endif
|
|
|
++ || op == stack_pointer_rtx)
|
|
|
++ return gen_rtx_SUBREG (HImode, op, offset);
|
|
|
++ else
|
|
|
++ return gen_rtx_REG (HImode, REGNO (op) + offset);
|
|
|
++ }
|
|
|
++ else if (GET_CODE (op) == SUBREG)
|
|
|
++ return gen_rtx_SUBREG (HImode, SUBREG_REG (op), offset + SUBREG_BYTE (op) / UNITS_PER_WORD);
|
|
|
++ }
|
|
|
++ else
|
|
|
+ return const0_rtx;
|
|
|
++ }
|
|
|
+
|
|
|
+ /* Form a new MEM at the requested address. */
|
|
|
+ if (MEM_P (op))
|
|
|
+@@ -5257,17 +5311,17 @@
|
|
|
+ REAL_VALUE_FROM_INT (dconstm1, -1, -1, double_mode);
|
|
|
+ REAL_VALUE_FROM_INT (dconstm2, -2, -1, double_mode);
|
|
|
+
|
|
|
+- dconsthalf = dconst1;
|
|
|
+- SET_REAL_EXP (&dconsthalf, REAL_EXP (&dconsthalf) - 1);
|
|
|
+-
|
|
|
++ real_arithmetic (&dconsthalf, RDIV_EXPR, &dconst1, &dconst2);
|
|
|
+ real_arithmetic (&dconstthird, RDIV_EXPR, &dconst1, &dconst3);
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Initialize mathematical constants for constant folding builtins.
|
|
|
+ These constants need to be given to at least 160 bits precision. */
|
|
|
+ real_from_string (&dconstpi,
|
|
|
+ "3.1415926535897932384626433832795028841971693993751058209749445923078");
|
|
|
+ real_from_string (&dconste,
|
|
|
+ "2.7182818284590452353602874713526624977572470936999595749669676277241");
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ for (i = 0; i < (int) ARRAY_SIZE (const_tiny_rtx); i++)
|
|
|
+ {
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/explow.c gcc-4.0-20050319-src/gcc/explow.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/explow.c Tue Jan 18 12:36:08 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/explow.c Wed Mar 23 01:21:02 2005
|
|
|
+@@ -573,6 +573,10 @@
|
|
|
+ {
|
|
|
+ rtx temp = gen_reg_rtx (mode);
|
|
|
+
|
|
|
++ if (GET_MODE (x) == BFmode && mode != BFmode)
|
|
|
++ convert_move (x, temp, 0);
|
|
|
++ else
|
|
|
++ {
|
|
|
+ /* If not an operand, must be an address with PLUS and MULT so
|
|
|
+ do the computation. */
|
|
|
+ if (! general_operand (x, VOIDmode))
|
|
|
+@@ -581,6 +585,7 @@
|
|
|
+ gcc_assert (GET_MODE (x) == mode || GET_MODE (x) == VOIDmode);
|
|
|
+ if (x != temp)
|
|
|
+ emit_move_insn (temp, x);
|
|
|
++ }
|
|
|
+ return temp;
|
|
|
+ }
|
|
|
+
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/expr.c gcc-4.0-20050319-src/gcc/expr.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/expr.c Sat Mar 12 00:03:46 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/expr.c Wed Mar 23 02:42:18 2005
|
|
|
+@@ -720,7 +720,7 @@
|
|
|
+ if (GET_MODE (x) != VOIDmode)
|
|
|
+ oldmode = GET_MODE (x);
|
|
|
+
|
|
|
+- if (mode == oldmode)
|
|
|
++ if (mode == oldmode || oldmode == BFmode)
|
|
|
+ return x;
|
|
|
+
|
|
|
+ /* There is one case that we must handle specially: If we are converting
|
|
|
+@@ -1321,6 +1321,7 @@
|
|
|
+ dst_tree = make_tree (ptr_type_node, dst_addr);
|
|
|
+ src_tree = make_tree (ptr_type_node, src_addr);
|
|
|
+
|
|
|
++#if 0
|
|
|
+ size_mode = TYPE_MODE (sizetype);
|
|
|
+
|
|
|
+ size = convert_to_mode (size_mode, size, 1);
|
|
|
+@@ -1330,8 +1331,8 @@
|
|
|
+ memcpy in this context. This could be a user call to memcpy and
|
|
|
+ the user may wish to examine the return value from memcpy. For
|
|
|
+ targets where libcalls and normal calls have different conventions
|
|
|
+- for returning pointers, we could end up generating incorrect code. */
|
|
|
+-
|
|
|
++ for returning pointers, we could end up generating incorrect code.
|
|
|
++ (TIGCC 20050205) NO, the "incorrect" code is actually correct for us! */
|
|
|
+ size_tree = make_tree (sizetype, size);
|
|
|
+
|
|
|
+ fn = emit_block_move_libcall_fn (true);
|
|
|
+@@ -1345,6 +1346,14 @@
|
|
|
+ call_expr, arg_list, NULL_TREE);
|
|
|
+
|
|
|
+ retval = expand_expr (call_expr, NULL_RTX, VOIDmode, 0);
|
|
|
++#endif /* 0 */
|
|
|
++
|
|
|
++ emit_library_call_value (memcpy_libfunc, retval, LCT_NORMAL,
|
|
|
++ VOIDmode, 3, dst_addr, Pmode,
|
|
|
++ src_addr, Pmode,
|
|
|
++ convert_to_mode (TYPE_MODE (sizetype),
|
|
|
++ size, TYPE_UNSIGNED (sizetype)),
|
|
|
++ TYPE_MODE (sizetype));
|
|
|
+
|
|
|
+ return retval;
|
|
|
+ }
|
|
|
+@@ -2520,6 +2529,7 @@
|
|
|
+
|
|
|
+ object = copy_to_mode_reg (Pmode, XEXP (object, 0));
|
|
|
+
|
|
|
++#if 0
|
|
|
+ size_mode = TYPE_MODE (sizetype);
|
|
|
+ size = convert_to_mode (size_mode, size, 1);
|
|
|
+ size = copy_to_mode_reg (size_mode, size);
|
|
|
+@@ -2528,7 +2538,8 @@
|
|
|
+ memset in this context. This could be a user call to memset and
|
|
|
+ the user may wish to examine the return value from memset. For
|
|
|
+ targets where libcalls and normal calls have different conventions
|
|
|
+- for returning pointers, we could end up generating incorrect code. */
|
|
|
++ for returning pointers, we could end up generating incorrect code.
|
|
|
++ (TIGCC 20050205) NO, the "incorrect" code is actually correct for us! */
|
|
|
+
|
|
|
+ object_tree = make_tree (ptr_type_node, object);
|
|
|
+ size_tree = make_tree (sizetype, size);
|
|
|
+@@ -2544,6 +2555,15 @@
|
|
|
+ call_expr, arg_list, NULL_TREE);
|
|
|
+
|
|
|
+ retval = expand_expr (call_expr, NULL_RTX, VOIDmode, 0);
|
|
|
++#endif /* 0 */
|
|
|
++
|
|
|
++ /* Note: Our memset libcall expects a short integer zero even with -mlong. */
|
|
|
++ emit_library_call_value (memset_libfunc, retval, LCT_NORMAL,
|
|
|
++ VOIDmode, 3, object, Pmode,
|
|
|
++ const0_rtx, TYPE_MODE (short_integer_type_node),
|
|
|
++ convert_to_mode (TYPE_MODE (sizetype),
|
|
|
++ size, TYPE_UNSIGNED (sizetype)),
|
|
|
++ TYPE_MODE (sizetype));
|
|
|
+
|
|
|
+ return retval;
|
|
|
+ }
|
|
|
+@@ -2562,8 +2582,10 @@
|
|
|
+ tree fn, args;
|
|
|
+
|
|
|
+ fn = get_identifier ("memset");
|
|
|
++ /* TIGCC Patch: The memset libcall expects a short integer zero even with
|
|
|
++ -mlong. */
|
|
|
+ args = build_function_type_list (ptr_type_node, ptr_type_node,
|
|
|
+- integer_type_node, sizetype,
|
|
|
++ short_integer_type_node, sizetype,
|
|
|
+ NULL_TREE);
|
|
|
+
|
|
|
+ fn = build_decl (FUNCTION_DECL, fn, args);
|
|
|
+@@ -2877,14 +2899,21 @@
|
|
|
+ if (push_operand (x, mode))
|
|
|
+ return emit_move_complex_push (mode, x, y);
|
|
|
+
|
|
|
++ /* For memory to memory moves, optimal behavior can be had with the
|
|
|
++ existing block move logic. */
|
|
|
++ /* (TIGCC 20050323) ... and this is indeed the case for our target, despite
|
|
|
++ claims to the contrary in PR rtl-optimization/20306. -- Kevin Kofler */
|
|
|
++ if (MEM_P (x) && MEM_P (y))
|
|
|
++ {
|
|
|
++ emit_block_move (x, y, GEN_INT (GET_MODE_SIZE (mode)),
|
|
|
++ BLOCK_OP_NO_LIBCALL);
|
|
|
++ return get_last_insn ();
|
|
|
++ }
|
|
|
++
|
|
|
+ /* See if we can coerce the target into moving both values at once. */
|
|
|
+
|
|
|
+- /* Move floating point as parts. */
|
|
|
+- if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
|
|
|
+- && mov_optab->handlers[GET_MODE_INNER (mode)].insn_code != CODE_FOR_nothing)
|
|
|
+- try_int = false;
|
|
|
+ /* Not possible if the values are inherently not adjacent. */
|
|
|
+- else if (GET_CODE (x) == CONCAT || GET_CODE (y) == CONCAT)
|
|
|
++ if (GET_CODE (x) == CONCAT || GET_CODE (y) == CONCAT)
|
|
|
+ try_int = false;
|
|
|
+ /* Is possible if both are registers (or subregs of registers). */
|
|
|
+ else if (register_operand (x, mode) && register_operand (y, mode))
|
|
|
+@@ -2902,18 +2931,7 @@
|
|
|
+
|
|
|
+ if (try_int)
|
|
|
+ {
|
|
|
+- rtx ret;
|
|
|
+-
|
|
|
+- /* For memory to memory moves, optimal behavior can be had with the
|
|
|
+- existing block move logic. */
|
|
|
+- if (MEM_P (x) && MEM_P (y))
|
|
|
+- {
|
|
|
+- emit_block_move (x, y, GEN_INT (GET_MODE_SIZE (mode)),
|
|
|
+- BLOCK_OP_NO_LIBCALL);
|
|
|
+- return get_last_insn ();
|
|
|
+- }
|
|
|
+-
|
|
|
+- ret = emit_move_via_integer (mode, x, y);
|
|
|
++ rtx ret = emit_move_via_integer (mode, x, y);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+@@ -3147,6 +3165,9 @@
|
|
|
+
|
|
|
+ REAL_VALUE_FROM_CONST_DOUBLE (r, y);
|
|
|
+
|
|
|
++/* (TIGCC) We do not implement exact_real_truncate and there is no narrower
|
|
|
++ float mode anyway. -- Kevin Kofler */
|
|
|
++#if 0
|
|
|
+ for (srcmode = GET_CLASS_NARROWEST_MODE (GET_MODE_CLASS (orig_srcmode));
|
|
|
+ srcmode != orig_srcmode;
|
|
|
+ srcmode = GET_MODE_WIDER_MODE (srcmode))
|
|
|
+@@ -3185,6 +3206,7 @@
|
|
|
+
|
|
|
+ return last_insn;
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ return NULL_RTX;
|
|
|
+ }
|
|
|
+@@ -3520,7 +3542,8 @@
|
|
|
+ int not_stack;
|
|
|
+ /* # bytes of start of argument
|
|
|
+ that we must make space for but need not store. */
|
|
|
+- int offset = partial % (PARM_BOUNDARY / BITS_PER_WORD);
|
|
|
++ /* (TIGCC) This code is trying to take a modulus by zero. */
|
|
|
++ int offset = 0 /* partial % (PARM_BOUNDARY / BITS_PER_WORD) */;
|
|
|
+ int args_offset = INTVAL (args_so_far);
|
|
|
+ int skip;
|
|
|
+
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/final.c gcc-4.0-20050319-src/gcc/final.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/final.c Fri Nov 26 03:21:38 2004
|
|
|
++++ gcc-4.0-20050319-src/gcc/final.c Wed Mar 23 01:21:04 2005
|
|
|
+@@ -3114,11 +3114,23 @@
|
|
|
+ else if (letter == 'l')
|
|
|
+ output_asm_label (operands[opnum]);
|
|
|
+ else if (letter == 'a')
|
|
|
++ {
|
|
|
+ output_address (operands[opnum]);
|
|
|
++ /* TIGCC Patch: This is a very bad try to implement addresses
|
|
|
++ relative to a register. See m68k.c
|
|
|
++ (TIGCC 20040808) Added CONST here (and below) too. -- Kevin Kofler */
|
|
|
++ if (TARGET_REG_RELATIVE && (GET_CODE (operands[opnum]) == SYMBOL_REF || GET_CODE (operands[opnum]) == LABEL_REF || GET_CODE (operands[opnum]) == CODE_LABEL || GET_CODE (operands[opnum]) == CONST))
|
|
|
++ fprintf (asm_out_file, "-__relation(%%%s)", TARGET_RELATION_REG);
|
|
|
++ }
|
|
|
+ else if (letter == 'c')
|
|
|
+ {
|
|
|
+ if (CONSTANT_ADDRESS_P (operands[opnum]))
|
|
|
++ {
|
|
|
+ output_addr_const (asm_out_file, operands[opnum]);
|
|
|
++ /* TIGCC Patch: See above */
|
|
|
++ if (TARGET_REG_RELATIVE && (GET_CODE (operands[opnum]) == SYMBOL_REF || GET_CODE (operands[opnum]) == LABEL_REF || GET_CODE (operands[opnum]) == CODE_LABEL || GET_CODE (operands[opnum]) == CONST))
|
|
|
++ fprintf (asm_out_file, "-__relation(%%%s)", TARGET_RELATION_REG);
|
|
|
++ }
|
|
|
+ else
|
|
|
+ output_operand (operands[opnum], 'c');
|
|
|
+ }
|
|
|
+@@ -3131,6 +3143,9 @@
|
|
|
+ {
|
|
|
+ putc ('-', asm_out_file);
|
|
|
+ output_addr_const (asm_out_file, operands[opnum]);
|
|
|
++ /* TIGCC Patch: See above */
|
|
|
++ if (TARGET_REG_RELATIVE && (GET_CODE (operands[opnum]) == SYMBOL_REF || GET_CODE (operands[opnum]) == LABEL_REF || GET_CODE (operands[opnum]) == CODE_LABEL))
|
|
|
++ fprintf (asm_out_file, "-__relation(%%%s)", TARGET_RELATION_REG);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+@@ -3643,6 +3658,8 @@
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
++ gcc_unreachable ();
|
|
|
++#if 0
|
|
|
+ REAL_VALUE_TYPE r;
|
|
|
+ long l[2];
|
|
|
+ REAL_VALUE_FROM_CONST_DOUBLE (r, value);
|
|
|
+@@ -3671,6 +3688,7 @@
|
|
|
+
|
|
|
+ *first = GEN_INT (l[0]);
|
|
|
+ *second = GEN_INT (l[1]);
|
|
|
++#endif /* 0 */
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/flags.h gcc-4.0-20050319-src/gcc/flags.h
|
|
|
+--- gcc-4.0-20050319.orig/gcc/flags.h Sun Feb 13 20:05:02 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/flags.h Wed Mar 23 01:21:04 2005
|
|
|
+@@ -288,4 +288,10 @@
|
|
|
+ #define HONOR_SIGN_DEPENDENT_ROUNDING(MODE) \
|
|
|
+ (MODE_HAS_SIGN_DEPENDENT_ROUNDING (MODE) && flag_rounding_math)
|
|
|
+
|
|
|
++/* (TIGCC) Make compound literals (cast constructors) global for backwards compatibility. */
|
|
|
++extern int flag_global_compound_literals;
|
|
|
++
|
|
|
++/* (TIGCC 20040727) When merging constants, also merge constant pools. */
|
|
|
++extern int flag_merge_constant_pools;
|
|
|
++
|
|
|
+ #endif /* ! GCC_FLAGS_H */
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/fold-const.c gcc-4.0-20050319-src/gcc/fold-const.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/fold-const.c Sat Mar 19 18:29:48 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/fold-const.c Wed Mar 23 01:21:04 2005
|
|
|
+@@ -1523,7 +1523,7 @@
|
|
|
+ if ((flag_rounding_math
|
|
|
+ || (REAL_MODE_FORMAT_COMPOSITE_P (mode)
|
|
|
+ && !flag_unsafe_math_optimizations))
|
|
|
+- && (inexact || !real_identical (&result, &value)))
|
|
|
++ && (inexact || !REAL_VALUES_IDENTICAL (result, value)))
|
|
|
+ return NULL_TREE;
|
|
|
+
|
|
|
+ t = build_real (type, result);
|
|
|
+@@ -1743,6 +1743,7 @@
|
|
|
+ FP-to-integer conversion is unspecified upon overflow. */
|
|
|
+
|
|
|
+ HOST_WIDE_INT high, low;
|
|
|
++#if 0
|
|
|
+ REAL_VALUE_TYPE r;
|
|
|
+ REAL_VALUE_TYPE x = TREE_REAL_CST (arg1);
|
|
|
+
|
|
|
+@@ -1767,9 +1768,12 @@
|
|
|
+ default:
|
|
|
+ gcc_unreachable ();
|
|
|
+ }
|
|
|
++#else
|
|
|
++ REAL_VALUE_TYPE r = TREE_REAL_CST (arg1);
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* If R is NaN, return zero and show we have an overflow. */
|
|
|
+- if (REAL_VALUE_ISNAN (r))
|
|
|
++ if (REAL_VALUE_ISNANUINF (r))
|
|
|
+ {
|
|
|
+ overflow = 1;
|
|
|
+ high = 0;
|
|
|
+@@ -2066,7 +2070,7 @@
|
|
|
+ /* When pedantic, return an expr equal to X but certainly not valid as a
|
|
|
+ pedantic lvalue. Otherwise, return X. */
|
|
|
+
|
|
|
+-static tree
|
|
|
++tree
|
|
|
+ pedantic_non_lvalue (tree x)
|
|
|
+ {
|
|
|
+ if (pedantic_lvalues)
|
|
|
+@@ -5530,6 +5534,10 @@
|
|
|
+ if (!HONOR_SIGNED_ZEROS (TYPE_MODE (type)))
|
|
|
+ return true;
|
|
|
+
|
|
|
++ /* (TIGCC 20050210) This is invalid independently of the rounding mode and the
|
|
|
++ type of the zero for 3-sign-zeros. */
|
|
|
++ return false;
|
|
|
++
|
|
|
+ /* Treat x + -0 as x - 0 and x - -0 as x + 0. */
|
|
|
+ if (TREE_CODE (addend) == REAL_CST
|
|
|
+ && REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (addend)))
|
|
|
+@@ -5715,6 +5723,7 @@
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
++#if 0 /* (TIGCC 20050205) */
|
|
|
+ case EQ_EXPR:
|
|
|
+ case GE_EXPR:
|
|
|
+ /* x == +Inf and x >= +Inf are always equal to x > DBL_MAX. */
|
|
|
+@@ -5743,6 +5752,7 @@
|
|
|
+ temp = fold (build2 (neg ? LT_EXPR : GT_EXPR, type,
|
|
|
+ arg0, build_real (TREE_TYPE (arg0), max)));
|
|
|
+ return fold (build1 (TRUTH_NOT_EXPR, type, temp));
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+@@ -6616,6 +6626,21 @@
|
|
|
+ return fold_complex_div_parts (type, ar, ai, br, bi, code);
|
|
|
+ }
|
|
|
+
|
|
|
++/* Return 1 if EXPR is the real constant UNSIGNED_ZERO. */
|
|
|
++
|
|
|
++static int
|
|
|
++real_uzerop (tree expr)
|
|
|
++{
|
|
|
++ STRIP_NOPS (expr);
|
|
|
++
|
|
|
++ return ((TREE_CODE (expr) == REAL_CST
|
|
|
++ && ! TREE_CONSTANT_OVERFLOW (expr)
|
|
|
++ && REAL_VALUES_IDENTICAL (TREE_REAL_CST (expr), UNSIGNED_ZERO))
|
|
|
++ || (TREE_CODE (expr) == COMPLEX_CST
|
|
|
++ && real_uzerop (TREE_REALPART (expr))
|
|
|
++ && real_uzerop (TREE_IMAGPART (expr))));
|
|
|
++}
|
|
|
++
|
|
|
+ /* Perform constant folding and related simplification of EXPR.
|
|
|
+ The related simplifications include x*1 => x, x*0 => 0, etc.,
|
|
|
+ and application of the associative law.
|
|
|
+@@ -7774,8 +7799,11 @@
|
|
|
+ when x is NaN, since x * 0 is also NaN. Nor are they the
|
|
|
+ same in modes with signed zeros, since multiplying a
|
|
|
+ negative value by 0 gives -0, not +0. */
|
|
|
++ /* (TIGCC 20050210) We can do this for UNSIGNED_ZERO even when honoring
|
|
|
++ signed zeros. */
|
|
|
+ if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0)))
|
|
|
+- && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg0)))
|
|
|
++ && (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg0)))
|
|
|
++ || real_uzerop (arg1))
|
|
|
+ && real_zerop (arg1))
|
|
|
+ return omit_one_operand (type, arg1, arg0);
|
|
|
+ /* In IEEE floating point, x*1 is not equivalent to x for snans. */
|
|
|
+@@ -8784,7 +8812,7 @@
|
|
|
+ build_real (TREE_TYPE (arg1), dconst0)));
|
|
|
+
|
|
|
+ /* x != NaN is always true, other ops are always false. */
|
|
|
+- if (REAL_VALUE_ISNAN (cst)
|
|
|
++ if (REAL_VALUE_ISNANUINF (cst)
|
|
|
+ && ! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1))))
|
|
|
+ {
|
|
|
+ tem = (code == NE_EXPR) ? integer_one_node : integer_zero_node;
|
|
|
+@@ -9557,7 +9585,7 @@
|
|
|
+
|
|
|
+ /* If the first operand is NaN, the result is constant. */
|
|
|
+ if (TREE_CODE (arg0) == REAL_CST
|
|
|
+- && REAL_VALUE_ISNAN (TREE_REAL_CST (arg0))
|
|
|
++ && REAL_VALUE_ISNANUINF (TREE_REAL_CST (arg0))
|
|
|
+ && (code != LTGT_EXPR || ! flag_trapping_math))
|
|
|
+ {
|
|
|
+ t1 = (code == ORDERED_EXPR || code == LTGT_EXPR)
|
|
|
+@@ -9568,7 +9596,7 @@
|
|
|
+
|
|
|
+ /* If the second operand is NaN, the result is constant. */
|
|
|
+ if (TREE_CODE (arg1) == REAL_CST
|
|
|
+- && REAL_VALUE_ISNAN (TREE_REAL_CST (arg1))
|
|
|
++ && REAL_VALUE_ISNANUINF (TREE_REAL_CST (arg1))
|
|
|
+ && (code != LTGT_EXPR || ! flag_trapping_math))
|
|
|
+ {
|
|
|
+ t1 = (code == ORDERED_EXPR || code == LTGT_EXPR)
|
|
|
+@@ -9768,12 +9796,12 @@
|
|
|
+ case COMPOUND_EXPR:
|
|
|
+ /* When pedantic, a compound expression can be neither an lvalue
|
|
|
+ nor an integer constant expression. */
|
|
|
+- if (TREE_SIDE_EFFECTS (arg0) || TREE_CONSTANT (arg1))
|
|
|
++ if (TREE_SIDE_EFFECTS (arg0) || pedantic)
|
|
|
+ return t;
|
|
|
+ /* Don't let (0, 0) be null pointer constant. */
|
|
|
+- tem = integer_zerop (arg1) ? build1 (NOP_EXPR, type, arg1)
|
|
|
+- : fold_convert (type, arg1);
|
|
|
+- return pedantic_non_lvalue (tem);
|
|
|
++ if (integer_zerop (arg1))
|
|
|
++ return build1 (NOP_EXPR, type, arg1);
|
|
|
++ return convert (type, arg1);
|
|
|
+
|
|
|
+ case COMPLEX_EXPR:
|
|
|
+ if (wins)
|
|
|
+@@ -10799,8 +10827,11 @@
|
|
|
+ if (! FLOAT_TYPE_P (type) && integer_zerop (op1))
|
|
|
+ return omit_one_operand (type, op1, op0);
|
|
|
+ else
|
|
|
++ /* (TIGCC 20050210) We can do this for UNSIGNED_ZERO even when honoring
|
|
|
++ signed zeros. */
|
|
|
+ if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (op0)))
|
|
|
+- && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (op0)))
|
|
|
++ && (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (op0)))
|
|
|
++ || real_uzerop (op1))
|
|
|
+ && real_zerop (op1))
|
|
|
+ return omit_one_operand (type, op1, op0);
|
|
|
+
|
|
|
+@@ -11148,7 +11179,11 @@
|
|
|
+ }
|
|
|
+
|
|
|
+ case REAL_CST:
|
|
|
+- t = build_real (type, REAL_VALUE_NEGATE (TREE_REAL_CST (arg0)));
|
|
|
++ {
|
|
|
++ REAL_VALUE_TYPE x = TREE_REAL_CST (arg0);
|
|
|
++ x = REAL_VALUE_NEGATE (x);
|
|
|
++ t = build_real (type, x);
|
|
|
++ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+@@ -11194,10 +11229,14 @@
|
|
|
+ break;
|
|
|
+
|
|
|
+ case REAL_CST:
|
|
|
+- if (REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg0)))
|
|
|
+- t = build_real (type, REAL_VALUE_NEGATE (TREE_REAL_CST (arg0)));
|
|
|
+- else
|
|
|
+- t = arg0;
|
|
|
++ {
|
|
|
++ REAL_VALUE_TYPE x = TREE_REAL_CST (arg0);
|
|
|
++ if (REAL_VALUE_NEGATIVE (x))
|
|
|
++ t = build_real (type,
|
|
|
++ REAL_VALUE_NEGATE (x));
|
|
|
++ else
|
|
|
++ t = arg0;
|
|
|
++ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+@@ -11245,7 +11284,7 @@
|
|
|
+ const REAL_VALUE_TYPE *c1 = TREE_REAL_CST_PTR (op1);
|
|
|
+
|
|
|
+ /* Handle the cases where either operand is a NaN. */
|
|
|
+- if (real_isnan (c0) || real_isnan (c1))
|
|
|
++ if (REAL_VALUE_ISNANUINF (*c0) || REAL_VALUE_ISNANUINF (*c1))
|
|
|
+ {
|
|
|
+ switch (code)
|
|
|
+ {
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/function.c gcc-4.0-20050319-src/gcc/function.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/function.c Thu Mar 10 16:11:04 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/function.c Wed Mar 23 01:21:04 2005
|
|
|
+@@ -5593,3 +5593,28 @@
|
|
|
+ }
|
|
|
+
|
|
|
+ #include "gt-function.h"
|
|
|
++
|
|
|
++/* begin-TIGCC-local (regparms): explicit register specification for parameters */
|
|
|
++/* Return 1 if an argument for the current function was passed in
|
|
|
++ register REGNO. */
|
|
|
++
|
|
|
++int
|
|
|
++function_arg_regno_p (int regno)
|
|
|
++{
|
|
|
++ tree parm = DECL_ARGUMENTS (current_function_decl);
|
|
|
++ for (; parm; parm = TREE_CHAIN (parm))
|
|
|
++ {
|
|
|
++ rtx incoming = DECL_INCOMING_RTL (parm);
|
|
|
++ if (GET_CODE (incoming) == REG)
|
|
|
++ {
|
|
|
++ int incoming_reg;
|
|
|
++ incoming_reg = REGNO (incoming);
|
|
|
++ if (regno >= incoming_reg &&
|
|
|
++ regno < incoming_reg + HARD_REGNO_NREGS (incoming_reg,
|
|
|
++ GET_MODE (incoming)))
|
|
|
++ return 1;
|
|
|
++ }
|
|
|
++ }
|
|
|
++ return 0;
|
|
|
++}
|
|
|
++/* end-TIGCC-local (regparms) */
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/function.h gcc-4.0-20050319-src/gcc/function.h
|
|
|
+--- gcc-4.0-20050319.orig/gcc/function.h Sun Feb 20 12:09:16 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/function.h Wed Mar 23 01:21:04 2005
|
|
|
+@@ -545,4 +545,10 @@
|
|
|
+ extern bool reference_callee_copied (CUMULATIVE_ARGS *, enum machine_mode,
|
|
|
+ tree, bool);
|
|
|
+
|
|
|
++/* begin-TIGCC-local (regparms): explicit register specification for parameters */
|
|
|
++/* Return 1 if an argument for the current function was passed in
|
|
|
++ register REGNO. */
|
|
|
++int function_arg_regno_p (int regno);
|
|
|
++/* end-TIGCC-local (regparms) */
|
|
|
++
|
|
|
+ #endif /* GCC_FUNCTION_H */
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/gcc.c gcc-4.0-20050319-src/gcc/gcc.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/gcc.c Thu Feb 24 00:11:06 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/gcc.c Wed Mar 23 01:21:04 2005
|
|
|
+@@ -1452,6 +1452,7 @@
|
|
|
+ #define MD_STARTFILE_PREFIX_1 ""
|
|
|
+ #endif
|
|
|
+
|
|
|
++#if 0 /* (TIGCC 20040104) Don't hardcode any prefix at compile time. */
|
|
|
+ static const char *const standard_exec_prefix = STANDARD_EXEC_PREFIX;
|
|
|
+ static const char *const standard_exec_prefix_1 = "/usr/libexec/gcc/";
|
|
|
+ static const char *const standard_exec_prefix_2 = "/usr/lib/gcc/";
|
|
|
+@@ -1469,6 +1470,7 @@
|
|
|
+ static const char *tooldir_prefix;
|
|
|
+
|
|
|
+ static const char *const standard_bindir_prefix = STANDARD_BINDIR_PREFIX;
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ static const char *standard_libexec_prefix = STANDARD_LIBEXEC_PREFIX;
|
|
|
+
|
|
|
+@@ -1539,12 +1541,14 @@
|
|
|
+ INIT_STATIC_SPEC ("multilib_options", &multilib_options),
|
|
|
+ INIT_STATIC_SPEC ("linker", &linker_name_spec),
|
|
|
+ INIT_STATIC_SPEC ("link_libgcc", &link_libgcc_spec),
|
|
|
++#if 0 /* (TIGCC 20040104) Don't hardcode any prefix at compile time. */
|
|
|
+ INIT_STATIC_SPEC ("md_exec_prefix", &md_exec_prefix),
|
|
|
+ INIT_STATIC_SPEC ("md_startfile_prefix", &md_startfile_prefix),
|
|
|
+ INIT_STATIC_SPEC ("md_startfile_prefix_1", &md_startfile_prefix_1),
|
|
|
+ INIT_STATIC_SPEC ("startfile_prefix_spec", &startfile_prefix_spec),
|
|
|
+ INIT_STATIC_SPEC ("sysroot_suffix_spec", &sysroot_suffix_spec),
|
|
|
+ INIT_STATIC_SPEC ("sysroot_hdrs_suffix_spec", &sysroot_hdrs_suffix_spec),
|
|
|
++#endif /* 0 */
|
|
|
+ };
|
|
|
+
|
|
|
+ #ifdef EXTRA_SPECS /* additional specs needed */
|
|
|
+@@ -3128,7 +3132,9 @@
|
|
|
+ process_command (int argc, const char **argv)
|
|
|
+ {
|
|
|
+ int i;
|
|
|
++#if 0 /* (TIGCC 20040104) Don't use environment variables. */
|
|
|
+ const char *temp;
|
|
|
++#endif /* 0 */
|
|
|
+ char *temp1;
|
|
|
+ const char *spec_lang = 0;
|
|
|
+ int last_language_n_infiles;
|
|
|
+@@ -3139,7 +3145,9 @@
|
|
|
+ int j;
|
|
|
+ #endif
|
|
|
+
|
|
|
++#if 0 /* (TIGCC 20040104) Don't use environment variables. */
|
|
|
+ GET_ENVIRONMENT (gcc_exec_prefix, "GCC_EXEC_PREFIX");
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ n_switches = 0;
|
|
|
+ n_infiles = 0;
|
|
|
+@@ -3217,7 +3225,7 @@
|
|
|
+ see if we can create it from the pathname specified in argv[0]. */
|
|
|
+
|
|
|
+ gcc_libexec_prefix = standard_libexec_prefix;
|
|
|
+-#ifndef VMS
|
|
|
++#if 0
|
|
|
+ /* FIXME: make_relative_prefix doesn't yet work for VMS. */
|
|
|
+ if (!gcc_exec_prefix)
|
|
|
+ {
|
|
|
+@@ -3236,6 +3244,7 @@
|
|
|
+ #else
|
|
|
+ #endif
|
|
|
+
|
|
|
++#if 0 /* (TIGCC 20040104) Don't use environment variables. */
|
|
|
+ if (gcc_exec_prefix)
|
|
|
+ {
|
|
|
+ int len = strlen (gcc_exec_prefix);
|
|
|
+@@ -3359,6 +3368,7 @@
|
|
|
+ endp++;
|
|
|
+ }
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Convert new-style -- options to old-style. */
|
|
|
+ translate_options (&argc, (const char *const **) &argv);
|
|
|
+@@ -3786,6 +3796,7 @@
|
|
|
+
|
|
|
+ /* Set up the search paths before we go looking for config files. */
|
|
|
+
|
|
|
++#if 0 /* (TIGCC 20040104) Don't hardcode any prefix at compile time. */
|
|
|
+ /* These come before the md prefixes so that we will find gcc's subcommands
|
|
|
+ (such as cpp) rather than those of the host system. */
|
|
|
+ /* Use 2 as fourth arg meaning try just the machine as a suffix,
|
|
|
+@@ -3847,6 +3858,7 @@
|
|
|
+ add_prefix (&startfile_prefixes,
|
|
|
+ concat (tooldir_prefix, "lib", dir_separator_str, NULL),
|
|
|
+ "BINUTILS", PREFIX_PRIORITY_LAST, 0, 1);
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ #if defined(TARGET_SYSTEM_ROOT_RELOCATABLE) && !defined(VMS)
|
|
|
+ /* If the normal TARGET_SYSTEM_ROOT is inside of $exec_prefix,
|
|
|
+@@ -6118,6 +6130,7 @@
|
|
|
+ else
|
|
|
+ init_spec ();
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* We need to check standard_exec_prefix/just_machine_suffix/specs
|
|
|
+ for any override of as, ld and libraries. */
|
|
|
+ specs_file = alloca (strlen (standard_exec_prefix)
|
|
|
+@@ -6151,7 +6164,9 @@
|
|
|
+ PREFIX_PRIORITY_LAST, 0, 0);
|
|
|
+ }
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
++#if 0 /* (TIGCC 20040104) Don't hardcode any prefix at compile time. */
|
|
|
+ /* Process sysroot_suffix_spec. */
|
|
|
+ if (*sysroot_suffix_spec != 0
|
|
|
+ && do_spec_2 (sysroot_suffix_spec) == 0)
|
|
|
+@@ -6232,6 +6247,7 @@
|
|
|
+ standard_startfile_prefix_2, "BINUTILS",
|
|
|
+ PREFIX_PRIORITY_LAST, 0, 1);
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Process any user specified specs in the order given on the command
|
|
|
+ line. */
|
|
|
+@@ -6242,10 +6258,12 @@
|
|
|
+ read_specs (filename ? filename : uptr->filename, FALSE);
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0 /* (TIGCC 20040104) Don't use environment variables. */
|
|
|
+ /* If we have a GCC_EXEC_PREFIX envvar, modify it for cpp's sake. */
|
|
|
+ if (gcc_exec_prefix)
|
|
|
+ gcc_exec_prefix = concat (gcc_exec_prefix, spec_machine, dir_separator_str,
|
|
|
+ spec_version, dir_separator_str, NULL);
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Now we have the specs.
|
|
|
+ Set the `valid' bits for switches that match anything in any spec. */
|
|
|
+@@ -6266,7 +6284,8 @@
|
|
|
+
|
|
|
+ if (print_search_dirs)
|
|
|
+ {
|
|
|
+- printf (_("install: %s%s\n"), standard_exec_prefix, machine_suffix);
|
|
|
++/* (TIGCC 20040104) Don't hardcode any prefix at compile time. */
|
|
|
++ printf (_("install: relocatable TIGCC installation\n"));
|
|
|
+ printf (_("programs: %s\n"), build_search_list (&exec_prefixes, "", 0));
|
|
|
+ printf (_("libraries: %s\n"), build_search_list (&startfile_prefixes, "", 0));
|
|
|
+ return (0);
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/gcse.c gcc-4.0-20050319-src/gcc/gcse.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/gcse.c Thu Feb 24 22:47:24 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/gcse.c Wed Mar 23 01:21:04 2005
|
|
|
+@@ -3035,11 +3035,14 @@
|
|
|
+ rtx newreg = NULL, newcnst = NULL;
|
|
|
+
|
|
|
+ /* Rule out USE instructions and ASM statements as we don't want to
|
|
|
+- change the hard registers mentioned. */
|
|
|
++ change the hard registers mentioned.
|
|
|
++ (TIGCC) The same thing goes for global register variables. CalcRogue gets
|
|
|
++ miscompiled without this patch. */
|
|
|
+ if (REG_P (x)
|
|
|
+ && (REGNO (x) >= FIRST_PSEUDO_REGISTER
|
|
|
+ || (GET_CODE (PATTERN (insn)) != USE
|
|
|
+- && asm_noperands (PATTERN (insn)) < 0)))
|
|
|
++ && asm_noperands (PATTERN (insn)) < 0
|
|
|
++ && ! global_regs[REGNO (x)])))
|
|
|
+ {
|
|
|
+ cselib_val *val = cselib_lookup (x, GET_MODE (x), 0);
|
|
|
+ struct elt_loc_list *l;
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/genmodes.c gcc-4.0-20050319-src/gcc/genmodes.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/genmodes.c Fri Oct 15 17:47:06 2004
|
|
|
++++ gcc-4.0-20050319-src/gcc/genmodes.c Wed Mar 23 01:21:04 2005
|
|
|
+@@ -1033,6 +1033,7 @@
|
|
|
+ static void
|
|
|
+ emit_real_format_for_mode (void)
|
|
|
+ {
|
|
|
++#if 0
|
|
|
+ struct mode_data *m;
|
|
|
+
|
|
|
+ /* The entities pointed to by this table are constant, whether
|
|
|
+@@ -1058,6 +1059,7 @@
|
|
|
+ tagged_printf ("&%s", m->format, m->name);
|
|
|
+
|
|
|
+ print_closer ();
|
|
|
++#endif /* 0 */
|
|
|
+ }
|
|
|
+
|
|
|
+ static void
|
|
|
+@@ -1142,10 +1144,12 @@
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Real mode formats don't have to propagate anywhere. */
|
|
|
+ for (a = adj_format; a; a = a->next)
|
|
|
+ printf ("\n /* %s:%d */\n REAL_MODE_FORMAT (%smode) = %s;\n",
|
|
|
+ a->file, a->line, a->mode->name, a->adjustment);
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ puts ("}");
|
|
|
+ }
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/gimplify.c gcc-4.0-20050319-src/gcc/gimplify.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/gimplify.c Mon Mar 14 21:34:40 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/gimplify.c Wed Mar 23 01:21:04 2005
|
|
|
+@@ -1781,6 +1781,7 @@
|
|
|
+ /* There is a sequence point before the call, so any side effects in
|
|
|
+ the calling expression must occur before the actual call. Force
|
|
|
+ gimplify_expr to use an internal post queue. */
|
|
|
++ if (!flag_no_function_cse)
|
|
|
+ ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, NULL,
|
|
|
+ is_gimple_call_addr, fb_rvalue);
|
|
|
+
|
|
|
+@@ -1798,6 +1799,12 @@
|
|
|
+ }
|
|
|
+ if (PUSH_ARGS_REVERSED)
|
|
|
+ TREE_OPERAND (*expr_p, 1) = nreverse (TREE_OPERAND (*expr_p, 1));
|
|
|
++
|
|
|
++ /* (TIGCC 20050206) Gimplify the function expression only after the arguments
|
|
|
++ if -fno-function-cse. */
|
|
|
++ if (flag_no_function_cse)
|
|
|
++ ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, NULL,
|
|
|
++ is_gimple_call_addr, fb_rvalue);
|
|
|
+
|
|
|
+ /* Try this again in case gimplification exposed something. */
|
|
|
+ if (ret != GS_ERROR && decl && DECL_BUILT_IN (decl))
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/ifcvt.c gcc-4.0-20050319-src/gcc/ifcvt.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/ifcvt.c Wed Jan 26 00:09:06 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/ifcvt.c Wed Mar 23 01:21:04 2005
|
|
|
+@@ -1898,6 +1898,16 @@
|
|
|
+ if (MEM_P (op))
|
|
|
+ return ! side_effects_p (XEXP (op, 0));
|
|
|
+
|
|
|
++ /* (TIGCC 20040925) Can't if-convert global register variables.
|
|
|
++ -- Kevin Kofler */
|
|
|
++ if (GET_CODE (op) == REG)
|
|
|
++ {
|
|
|
++ int regno;
|
|
|
++ regno = REGNO (op);
|
|
|
++ if (regno < FIRST_PSEUDO_REGISTER && global_regs[regno])
|
|
|
++ return FALSE;
|
|
|
++ }
|
|
|
++
|
|
|
+ if (side_effects_p (op))
|
|
|
+ return FALSE;
|
|
|
+
|
|
|
+@@ -3191,6 +3201,21 @@
|
|
|
+ TEST range. */
|
|
|
+ if (for_each_rtx (&PATTERN (insn), find_memory, NULL))
|
|
|
+ return FALSE;
|
|
|
++
|
|
|
++ /* (TIGCC 20040925) Can't if-convert global register variables.
|
|
|
++ -- Kevin Kofler */
|
|
|
++ if (GET_CODE (PATTERN (insn)) == SET)
|
|
|
++ {
|
|
|
++ rtx dest;
|
|
|
++ dest = SET_DEST (PATTERN (insn));
|
|
|
++ if (GET_CODE (dest) == REG)
|
|
|
++ {
|
|
|
++ int regno;
|
|
|
++ regno = REGNO (dest);
|
|
|
++ if (regno < FIRST_PSEUDO_REGISTER && global_regs[regno])
|
|
|
++ return FALSE;
|
|
|
++ }
|
|
|
++ }
|
|
|
+ }
|
|
|
+ if (insn == end)
|
|
|
+ break;
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/langhooks-def.h gcc-4.0-20050319-src/gcc/langhooks-def.h
|
|
|
+--- gcc-4.0-20050319.orig/gcc/langhooks-def.h Sun Feb 20 18:01:14 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/langhooks-def.h Wed Mar 23 01:21:04 2005
|
|
|
+@@ -106,6 +106,7 @@
|
|
|
+ #define LANG_HOOKS_SAFE_FROM_P lhd_safe_from_p
|
|
|
+ #define LANG_HOOKS_FINISH_INCOMPLETE_DECL lhd_do_nothing_t
|
|
|
+ #define LANG_HOOKS_STATICP lhd_staticp
|
|
|
++#define LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES lhd_do_nothing_t
|
|
|
+ #define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL lhd_do_nothing_t
|
|
|
+ #define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME lhd_set_decl_assembler_name
|
|
|
+ #define LANG_HOOKS_CAN_USE_BIT_FIELDS_P lhd_can_use_bit_fields_p
|
|
|
+@@ -268,6 +269,7 @@
|
|
|
+ LANG_HOOKS_EXPAND_EXPR, \
|
|
|
+ LANG_HOOKS_EXPAND_DECL, \
|
|
|
+ LANG_HOOKS_TRUTHVALUE_CONVERSION, \
|
|
|
++ LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES, \
|
|
|
+ LANG_HOOKS_SAFE_FROM_P, \
|
|
|
+ LANG_HOOKS_FINISH_INCOMPLETE_DECL, \
|
|
|
+ LANG_HOOKS_MARK_ADDRESSABLE, \
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/langhooks.h gcc-4.0-20050319-src/gcc/langhooks.h
|
|
|
+--- gcc-4.0-20050319.orig/gcc/langhooks.h Mon Feb 21 15:39:50 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/langhooks.h Wed Mar 23 01:21:04 2005
|
|
|
+@@ -290,6 +290,10 @@
|
|
|
+ error_mark_node). */
|
|
|
+ tree (*truthvalue_conversion) (tree);
|
|
|
+
|
|
|
++ /* Possibly apply default attributes to a function (represented by
|
|
|
++ a FUNCTION_DECL). */
|
|
|
++ void (*insert_default_attributes) PARAMS ((tree));
|
|
|
++
|
|
|
+ /* Hook called by safe_from_p for language-specific tree codes. It is
|
|
|
+ up to the language front-end to install a hook if it has any such
|
|
|
+ codes that safe_from_p needs to know about. Since same_from_p will
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/loop.c gcc-4.0-20050319-src/gcc/loop.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/loop.c Mon Jan 17 09:46:14 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/loop.c Wed Mar 23 01:21:04 2005
|
|
|
+@@ -1289,6 +1289,13 @@
|
|
|
+ == INSN_UID (regs->array[regno].single_usage))
|
|
|
+ && regs->array[regno].set_in_loop == 1
|
|
|
+ && GET_CODE (SET_SRC (set)) != ASM_OPERANDS
|
|
|
++ /* (TIGCC 20050206) Patch by Ian Lance Taylor regarding using hard
|
|
|
++ register variables as an asm input
|
|
|
++ See http://gcc.gnu.org/ml/gcc/2004-05/msg00678.html */
|
|
|
++ && (regno >= FIRST_PSEUDO_REGISTER
|
|
|
++ || asm_noperands (PATTERN (regs->array[regno]
|
|
|
++ .single_usage))
|
|
|
++ < 0)
|
|
|
+ && ! side_effects_p (SET_SRC (set))
|
|
|
+ && ! find_reg_note (p, REG_RETVAL, NULL_RTX)
|
|
|
+ && (! SMALL_REGISTER_CLASSES
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/machmode.def gcc-4.0-20050319-src/gcc/machmode.def
|
|
|
+--- gcc-4.0-20050319.orig/gcc/machmode.def Fri Oct 15 17:47:08 2004
|
|
|
++++ gcc-4.0-20050319-src/gcc/machmode.def Wed Mar 23 01:21:04 2005
|
|
|
+@@ -170,8 +170,8 @@
|
|
|
+ These are the IEEE mappings. They can be overridden with
|
|
|
+ RESET_FLOAT_FORMAT or at runtime (in OVERRIDE_OPTIONS). */
|
|
|
+
|
|
|
+-FLOAT_MODE (SF, 4, ieee_single_format);
|
|
|
+-FLOAT_MODE (DF, 8, ieee_double_format);
|
|
|
++FLOAT_MODE (SF, 4, 0);
|
|
|
++FLOAT_MODE (DF, 8, 0);
|
|
|
+
|
|
|
+ /* Basic CC modes.
|
|
|
+ FIXME define this only for targets that need it. */
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/optabs.c gcc-4.0-20050319-src/gcc/optabs.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/optabs.c Sat Feb 12 12:34:20 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/optabs.c Wed Mar 23 01:21:04 2005
|
|
|
+@@ -1653,7 +1653,7 @@
|
|
|
+ /* Look for a wider mode of the same class for which it appears we can do
|
|
|
+ the operation. */
|
|
|
+
|
|
|
+- if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
|
|
|
++ if (class == MODE_INT)
|
|
|
+ {
|
|
|
+ for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
|
|
|
+ wider_mode = GET_MODE_WIDER_MODE (wider_mode))
|
|
|
+@@ -1958,7 +1958,7 @@
|
|
|
+
|
|
|
+ /* It can't be done in this mode. Can we do it in a wider mode? */
|
|
|
+
|
|
|
+- if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
|
|
|
++ if (class == MODE_INT)
|
|
|
+ {
|
|
|
+ for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
|
|
|
+ wider_mode = GET_MODE_WIDER_MODE (wider_mode))
|
|
|
+@@ -2148,6 +2148,7 @@
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0 /* (TIGCC 20050216) */
|
|
|
+ /* Expand a floating point absolute value or negation operation via a
|
|
|
+ logical operation on the sign bit. */
|
|
|
+
|
|
|
+@@ -2252,6 +2253,7 @@
|
|
|
+
|
|
|
+ return target;
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Generate code to perform an operation specified by UNOPTAB
|
|
|
+ on operand OP0, with result having machine-mode MODE.
|
|
|
+@@ -2332,7 +2334,7 @@
|
|
|
+ goto try_libcall;
|
|
|
+ }
|
|
|
+
|
|
|
+- if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
|
|
|
++ if (class == MODE_INT)
|
|
|
+ for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
|
|
|
+ wider_mode = GET_MODE_WIDER_MODE (wider_mode))
|
|
|
+ {
|
|
|
+@@ -2406,13 +2408,16 @@
|
|
|
+
|
|
|
+ if (unoptab->code == NEG)
|
|
|
+ {
|
|
|
++#if 0
|
|
|
+ /* Try negating floating point values by flipping the sign bit. */
|
|
|
++ /* (TIGCC 20050205) Don't. We have unsigned zero and infinity. */
|
|
|
+ if (class == MODE_FLOAT)
|
|
|
+ {
|
|
|
+ temp = expand_absneg_bit (NEG, mode, op0, target);
|
|
|
+ if (temp)
|
|
|
+ return temp;
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* If there is no negation pattern, and we have no negative zero,
|
|
|
+ try subtracting from zero. */
|
|
|
+@@ -2469,7 +2474,7 @@
|
|
|
+
|
|
|
+ /* It can't be done in this mode. Can we do it in a wider mode? */
|
|
|
+
|
|
|
+- if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
|
|
|
++ if (class == MODE_INT)
|
|
|
+ {
|
|
|
+ for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
|
|
|
+ wider_mode = GET_MODE_WIDER_MODE (wider_mode))
|
|
|
+@@ -2558,13 +2563,16 @@
|
|
|
+ if (temp != 0)
|
|
|
+ return temp;
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* For floating point modes, try clearing the sign bit. */
|
|
|
++ /* (TIGCC 20050205) Don't. We have unsigned zero and infinity. */
|
|
|
+ if (GET_MODE_CLASS (mode) == MODE_FLOAT)
|
|
|
+ {
|
|
|
+ temp = expand_absneg_bit (ABS, mode, op0, target);
|
|
|
+ if (temp)
|
|
|
+ return temp;
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* If we have a MAX insn, we can do this as MAX (x, -x). */
|
|
|
+ if (smax_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing
|
|
|
+@@ -2738,6 +2746,7 @@
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* A subroutine of expand_copysign, perform the entire copysign operation
|
|
|
+ with integer bitmasks. BITPOS is the position of the sign bit; OP0_IS_ABS
|
|
|
+ is true if op0 is known to have its sign bit clear. */
|
|
|
+@@ -2890,6 +2899,7 @@
|
|
|
+
|
|
|
+ return expand_copysign_bit (mode, op0, op1, target, bitpos, op0_is_abs);
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Generate an instruction whose insn-code is INSN_CODE,
|
|
|
+ with two operands: an output TARGET and an input OP0.
|
|
|
+@@ -4285,6 +4295,7 @@
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Unsigned integer, and no way to convert directly.
|
|
|
+ Convert as signed, then conditionally adjust the result. */
|
|
|
+ if (unsignedp)
|
|
|
+@@ -4392,6 +4403,7 @@
|
|
|
+ emit_label (label);
|
|
|
+ goto done;
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* No hardware instruction available; call a library routine. */
|
|
|
+ {
|
|
|
+@@ -4486,6 +4498,7 @@
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* For an unsigned conversion, there is one more way to do it.
|
|
|
+ If we have a signed conversion, we generate code that compares
|
|
|
+ the real value to the largest representable positive number. If if
|
|
|
+@@ -4572,6 +4585,7 @@
|
|
|
+
|
|
|
+ return;
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* We can't do it with an insn, so use a library call. But first ensure
|
|
|
+ that the mode of TO is at least as wide as SImode, since those are the
|
|
|
+@@ -5142,6 +5156,9 @@
|
|
|
+
|
|
|
+ /* Conversions. */
|
|
|
+ init_interclass_conv_libfuncs (sfloat_optab, "float",
|
|
|
++ MODE_INT, MODE_FLOAT);
|
|
|
++ /* (TIGCC 20050208) Someone forgot this one... */
|
|
|
++ init_interclass_conv_libfuncs (ufloat_optab, "floatuns",
|
|
|
+ MODE_INT, MODE_FLOAT);
|
|
|
+ init_interclass_conv_libfuncs (sfix_optab, "fix",
|
|
|
+ MODE_FLOAT, MODE_INT);
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/opts.c gcc-4.0-20050319-src/gcc/opts.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/opts.c Thu Feb 24 10:24:12 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/opts.c Wed Mar 23 01:21:04 2005
|
|
|
+@@ -533,7 +533,12 @@
|
|
|
+ #endif
|
|
|
+ flag_regmove = 1;
|
|
|
+ flag_strict_aliasing = 1;
|
|
|
++#if 0 /* (TIGCC 20050213) Null pointer dereferences won't necessarily trigger
|
|
|
++ a trap. When reading, they definitely won't. When writing, they will
|
|
|
++ only when the variable being dereferenced is a scalar or a small
|
|
|
++ enough structure. */
|
|
|
+ flag_delete_null_pointer_checks = 1;
|
|
|
++#endif
|
|
|
+ flag_reorder_blocks = 1;
|
|
|
+ flag_reorder_functions = 1;
|
|
|
+ flag_unit_at_a_time = 1;
|
|
|
+@@ -550,6 +555,10 @@
|
|
|
+ flag_inline_functions = 1;
|
|
|
+ flag_unswitch_loops = 1;
|
|
|
+ flag_gcse_after_reload = 1;
|
|
|
++ /* (TIGCC 20050217) Halve maximum inline insns under -O3. Use -O4 to
|
|
|
++ override this. */
|
|
|
++ if (optimize == 3)
|
|
|
++ set_param_value ("max-inline-insns-auto", 60);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (optimize < 2 || optimize_size)
|
|
|
+@@ -570,12 +579,17 @@
|
|
|
+ flag_reorder_blocks_and_partition = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+- if (optimize_size)
|
|
|
++ /* (TIGCC 20050217) Do this at -O2 as well, as it improves both size and speed. */
|
|
|
++ if (optimize == 2 || optimize_size)
|
|
|
+ {
|
|
|
+ /* Inlining of very small functions usually reduces total size. */
|
|
|
+- set_param_value ("max-inline-insns-single", 5);
|
|
|
+ set_param_value ("max-inline-insns-auto", 5);
|
|
|
+ flag_inline_functions = 1;
|
|
|
++ }
|
|
|
++ if (optimize_size)
|
|
|
++ {
|
|
|
++ /* Inlining of very small functions usually reduces total size. */
|
|
|
++ set_param_value ("max-inline-insns-single", 5);
|
|
|
+
|
|
|
+ /* We want to crossjump as much as possible. */
|
|
|
+ set_param_value ("min-crossjump-insns", 1);
|
|
|
+@@ -610,6 +624,11 @@
|
|
|
+ if (flag_pic && !flag_pie)
|
|
|
+ flag_shlib = 1;
|
|
|
+
|
|
|
++ /* TIGCC Patch: Register d2 is used by the TIOS calling convention.
|
|
|
++ See "call-used-" further down in this file. */
|
|
|
++ if (TARGET_TIOS)
|
|
|
++ fix_register ("d2", 0, 1);
|
|
|
++
|
|
|
+ if (flag_no_inline == 2)
|
|
|
+ flag_no_inline = 0;
|
|
|
+ else
|
|
|
+@@ -870,6 +889,12 @@
|
|
|
+
|
|
|
+ case OPT_fprofile_values:
|
|
|
+ flag_profile_values_set = true;
|
|
|
++ break;
|
|
|
++
|
|
|
++ case OPT_freg_relative_:
|
|
|
++ fix_register (arg, 1, 1);
|
|
|
++ target_flags |= MASK_REG_RELATIVE;
|
|
|
++ strcpy (TARGET_RELATION_REG, arg);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OPT_fvisibility_:
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/output.h gcc-4.0-20050319-src/gcc/output.h
|
|
|
+--- gcc-4.0-20050319.orig/gcc/output.h Tue Jan 18 12:36:16 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/output.h Wed Mar 23 01:21:04 2005
|
|
|
+@@ -327,7 +327,7 @@
|
|
|
+ #define assemble_aligned_integer(SIZE, VALUE) \
|
|
|
+ assemble_integer (VALUE, SIZE, (SIZE) * BITS_PER_UNIT, 1)
|
|
|
+
|
|
|
+-#ifdef REAL_VALUE_TYPE_SIZE
|
|
|
++#ifdef REAL_WIDTH /* (TIGCC 20050205) */
|
|
|
+ /* Assemble the floating-point constant D into an object of size MODE. */
|
|
|
+ extern void assemble_real (REAL_VALUE_TYPE, enum machine_mode, unsigned);
|
|
|
+ #endif
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/postreload.c gcc-4.0-20050319-src/gcc/postreload.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/postreload.c Tue Jan 18 12:36:16 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/postreload.c Wed Mar 23 01:21:04 2005
|
|
|
+@@ -1188,6 +1188,9 @@
|
|
|
+ && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (OUTMODE), \
|
|
|
+ GET_MODE_BITSIZE (INMODE))))
|
|
|
+
|
|
|
++/* (TIGCC 20050213) Declare this target-dependent function. */
|
|
|
++int const_method (rtx);
|
|
|
++
|
|
|
+ static void
|
|
|
+ reload_cse_move2add (rtx first)
|
|
|
+ {
|
|
|
+@@ -1276,11 +1279,17 @@
|
|
|
+ narrow_mode != GET_MODE (reg);
|
|
|
+ narrow_mode = GET_MODE_WIDER_MODE (narrow_mode))
|
|
|
+ {
|
|
|
+- if (have_insn_for (STRICT_LOW_PART, narrow_mode)
|
|
|
++ /* (TIGCC 20050213) Don't do this for QImode. Byte moves aren't
|
|
|
++ any cheaper than word moves, they just kill chances to use a
|
|
|
++ moveq. Also don't turn long moves which can be done using
|
|
|
++ moveq into word moves. */
|
|
|
++ if (narrow_mode != QImode
|
|
|
++ && have_insn_for (STRICT_LOW_PART, narrow_mode)
|
|
|
+ && ((reg_offset[regno]
|
|
|
+ & ~GET_MODE_MASK (narrow_mode))
|
|
|
+ == (INTVAL (src)
|
|
|
+- & ~GET_MODE_MASK (narrow_mode))))
|
|
|
++ & ~GET_MODE_MASK (narrow_mode)))
|
|
|
++ && (GET_MODE (reg) != SImode || const_method (src)))
|
|
|
+ {
|
|
|
+ rtx narrow_reg = gen_rtx_REG (narrow_mode,
|
|
|
+ REGNO (reg));
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/print-rtl.c gcc-4.0-20050319-src/gcc/print-rtl.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/print-rtl.c Thu Sep 23 17:34:18 2004
|
|
|
++++ gcc-4.0-20050319-src/gcc/print-rtl.c Wed Mar 23 01:21:04 2005
|
|
|
+@@ -588,6 +588,9 @@
|
|
|
+ {
|
|
|
+ char s[60];
|
|
|
+
|
|
|
++ REAL_VALUE_TO_STRING (*CONST_DOUBLE_REAL_VALUE (in_rtx), s);
|
|
|
++ fprintf (outfile, " %s", s);
|
|
|
++#if 0
|
|
|
+ real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (in_rtx),
|
|
|
+ sizeof (s), 0, 1);
|
|
|
+ fprintf (outfile, " %s", s);
|
|
|
+@@ -595,6 +598,7 @@
|
|
|
+ real_to_hexadecimal (s, CONST_DOUBLE_REAL_VALUE (in_rtx),
|
|
|
+ sizeof (s), 0, 1);
|
|
|
+ fprintf (outfile, " [%s]", s);
|
|
|
++#endif /* 0 */
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ #endif
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/print-tree.c gcc-4.0-20050319-src/gcc/print-tree.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/print-tree.c Thu Feb 24 19:53:40 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/print-tree.c Wed Mar 23 01:21:04 2005
|
|
|
+@@ -133,7 +133,7 @@
|
|
|
+ else
|
|
|
+ {
|
|
|
+ char string[60];
|
|
|
+- real_to_decimal (string, &d, sizeof (string), 0, 1);
|
|
|
++ REAL_VALUE_TO_STRING (d, string);
|
|
|
+ fprintf (file, " %s", string);
|
|
|
+ }
|
|
|
+ }
|
|
|
+@@ -652,7 +652,7 @@
|
|
|
+ else
|
|
|
+ {
|
|
|
+ char string[64];
|
|
|
+- real_to_decimal (string, &d, sizeof (string), 0, 1);
|
|
|
++ REAL_VALUE_TO_STRING (d, string);
|
|
|
+ fprintf (file, " %s", string);
|
|
|
+ }
|
|
|
+ }
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/real.c gcc-4.0-20050319-src/gcc/real.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/real.c Tue Jan 25 21:21:54 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/real.c Wed Mar 23 01:21:04 2005
|
|
|
+@@ -72,6 +72,7 @@
|
|
|
+ adjust the significand to match. */
|
|
|
+
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Used to classify two numbers simultaneously. */
|
|
|
+ #define CLASS2(A, B) ((A) << 2 | (B))
|
|
|
+
|
|
|
+@@ -122,7 +123,9 @@
|
|
|
+ static void times_pten (REAL_VALUE_TYPE *, int);
|
|
|
+
|
|
|
+ static void round_for_format (const struct real_format *, REAL_VALUE_TYPE *);
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Initialize R with a positive zero. */
|
|
|
+
|
|
|
+ static inline void
|
|
|
+@@ -973,6 +976,614 @@
|
|
|
+ gcc_unreachable ();
|
|
|
+ }
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
++
|
|
|
++/* Add 1 unit in the last place to a positive SMAP II BCD float. */
|
|
|
++static void bcdpadd1ulp(smap_bcd_float *op)
|
|
|
++{
|
|
|
++ int i;
|
|
|
++ op->mantissa++; /* This will give a digit of 10 in some cases. */
|
|
|
++ for (i=0;i<60;i+=4) { /* for each digit except the first one */
|
|
|
++ int d=(op->mantissa>>i)&15;
|
|
|
++ if (d<10) /* if the digit is <10, we're done */
|
|
|
++ break;
|
|
|
++ op->mantissa += 6ull<<i; /* subtract 10 from the digit, add 1 to the next digit */
|
|
|
++ }
|
|
|
++ /* Now, we should have a carry only in one case: the mantissa was
|
|
|
++ 9999999999999999. So now, we have A000000000000000, where A is 10 in a
|
|
|
++ single digit. We can safely truncate the last digit because it is 0 (so
|
|
|
++ there is no risk of double-rounding here). */
|
|
|
++ if (op->mantissa >= 0xA000000000000000ull) { /* if we have a carry */
|
|
|
++ gcc_assert (op->mantissa == 0xA000000000000000ull); /* sanity check */
|
|
|
++ op->mantissa = 0x1000000000000000ull; /* A -> 10, drop the last digit */
|
|
|
++ op->exponent++; /* adjust the exponent */
|
|
|
++ if (op->exponent > 0x4000+16383) /* exponent too large, overflow to +infinity */
|
|
|
++ *op = POSITIVE_INF;
|
|
|
++ }
|
|
|
++}
|
|
|
++
|
|
|
++/* Add 2 positive SMAP II BCD floats. */
|
|
|
++static smap_bcd_float bcdppadd(smap_bcd_float op0, smap_bcd_float op1)
|
|
|
++{
|
|
|
++ int lastdigit=0;
|
|
|
++
|
|
|
++ if (op0.exponent < op1.exponent) {
|
|
|
++ /* If op0 does not contribute to the result, avoid shift count overflow by
|
|
|
++ returning op1 immediately. */
|
|
|
++ if (op1.exponent-op0.exponent>16) return op1;
|
|
|
++ /* Adjust op0 exponent to fit op1. */
|
|
|
++ op0.mantissa >>= ((op1.exponent-op0.exponent-1)<<2);
|
|
|
++ lastdigit = (op0.mantissa&15); /* save the last digit of op0 */
|
|
|
++ op0.mantissa >>= 4; /* drop the last digit of op0 */
|
|
|
++ op0.exponent = op1.exponent; /* adjust the exponent of op0 */
|
|
|
++ } else if (op1.exponent < op0.exponent) {
|
|
|
++ /* If op1 does not contribute to the result, avoid shift count overflow by
|
|
|
++ returning op0 immediately. */
|
|
|
++ if (op0.exponent-op1.exponent>16) return op0;
|
|
|
++ /* Adjust op1 exponent to fit op0. */
|
|
|
++ op1.mantissa >>= ((op0.exponent-op1.exponent-1)<<2);
|
|
|
++ lastdigit = (op1.mantissa&15); /* save the last digit of op1 */
|
|
|
++ op1.mantissa >>= 4; /* drop the last digit of op1 */
|
|
|
++ op1.exponent = op0.exponent; /* adjust the exponent of op1 */
|
|
|
++ }
|
|
|
++
|
|
|
++ /* Now do the addition in the BCD-coded mantissa. */
|
|
|
++ {
|
|
|
++ int i,d,carry=0;
|
|
|
++ smap_bcd_float result={0,0};result.exponent=op0.exponent;
|
|
|
++ for (i=0;i<64;i+=4) { /* for each digit */
|
|
|
++ d = (op0.mantissa&15)+(op1.mantissa&15)+carry;
|
|
|
++ carry = (d>=10); /* handle carry */
|
|
|
++ if (carry) d -= 10;
|
|
|
++ /* We are done with this digit of the mantissa. */
|
|
|
++ op0.mantissa >>= 4;
|
|
|
++ op1.mantissa >>= 4;
|
|
|
++ /* Store it into the resulting mantissa. */
|
|
|
++ result.mantissa += ((unsigned long long)d)<<i;
|
|
|
++ }
|
|
|
++ if (carry) { /* The mantissa overflowed, so we need to adjust the exponent. */
|
|
|
++ lastdigit = (result.mantissa&15); /* save the last digit of result,
|
|
|
++ dropping the previously saved last
|
|
|
++ digit */
|
|
|
++ result.mantissa >>= 4; /* drop the last digit of result */
|
|
|
++ result.exponent++; /* adjust the exponent of result */
|
|
|
++ if (result.exponent > 0x4000+16383) /* exponent too large, overflow to */
|
|
|
++ return POSITIVE_INF; /* +infinity */
|
|
|
++ /* prepend the first digit */
|
|
|
++ result.mantissa += ((unsigned long long)carry)<<60;
|
|
|
++ }
|
|
|
++ if (lastdigit>=5) /* now do the correct rounding */
|
|
|
++ bcdpadd1ulp(&result);
|
|
|
++ return result;
|
|
|
++ }
|
|
|
++}
|
|
|
++
|
|
|
++/* Subtract 2 positive SMAP II BCD floats. */
|
|
|
++static smap_bcd_float bcdppsub(smap_bcd_float op0, smap_bcd_float op1)
|
|
|
++{
|
|
|
++ unsigned long long lastdigits=0;
|
|
|
++
|
|
|
++ if (REAL_VALUES_LESS(op0,op1)) /* if op0<op1, subtract the other way round */
|
|
|
++ return REAL_VALUE_NEGATE(bcdppsub(op1,op0));
|
|
|
++ else if (REAL_VALUES_IDENTICAL(op0,op1)) /* if op0=op1, return unsigned 0 */
|
|
|
++ return UNSIGNED_ZERO;
|
|
|
++
|
|
|
++ /* Now, we can assume op0>op1. */
|
|
|
++ if (op1.exponent < op0.exponent) {
|
|
|
++ /* If op1 does not contribute to the result, avoid shift count overflow by
|
|
|
++ returning op0 immediately. */
|
|
|
++ if (op0.exponent-op1.exponent>16) return op0;
|
|
|
++ /* Adjust op1 exponent to fit op0.
|
|
|
++ Save all dropped digits, so we can round correctly. */
|
|
|
++ lastdigits = op1.mantissa << (64-((op0.exponent-op1.exponent)<<2));
|
|
|
++ if (op0.exponent-op1.exponent==16)
|
|
|
++ op1.mantissa = 0; /* special-cased because shifts by 64 aren't allowed */
|
|
|
++ else
|
|
|
++ op1.mantissa >>= ((op0.exponent-op1.exponent)<<2);
|
|
|
++ op1.exponent = op0.exponent; /* adjust the exponent of op1 */
|
|
|
++ }
|
|
|
++
|
|
|
++ /* Now do the subtraction in the BCD-coded mantissa. */
|
|
|
++ {
|
|
|
++ int i,d,carry=0;
|
|
|
++ smap_bcd_float result={0,0};result.exponent=op0.exponent;
|
|
|
++ for (i=0;i<64;i+=4) { /* for each digit */
|
|
|
++ d = (op0.mantissa&15)-((op1.mantissa&15)+carry);
|
|
|
++ carry = (d<0); /* handle carry */
|
|
|
++ if (carry) d += 10;
|
|
|
++ /* We are done with this digit of the mantissa. */
|
|
|
++ op0.mantissa >>= 4;
|
|
|
++ op1.mantissa >>= 4;
|
|
|
++ /* Store it into the resulting mantissa. */
|
|
|
++ result.mantissa += ((unsigned long long)d)<<i;
|
|
|
++ }
|
|
|
++ gcc_assert (!carry); /* Carry should be 0 here! */
|
|
|
++ /* Normalize and return the result (which is always positive here, since we
|
|
|
++ assumed op1>op0). Handle rounding and extra digits during normalization.
|
|
|
++ */
|
|
|
++ while ((result.mantissa<0x1000000000000000ull)
|
|
|
++ || ((result.mantissa==0x1000000000000000ull)
|
|
|
++ && ((lastdigits>0x5000000000000000ull)
|
|
|
++ || ((lastdigits>0x500000000000000ull)
|
|
|
++ && (result.exponent>0x4000-16383))))) {
|
|
|
++ /* while mantissa<1 */
|
|
|
++ int c = (result.mantissa==0x1000000000000000ull); /* used by the sanity
|
|
|
++ check below */
|
|
|
++ result.exponent--; /* decrease exponent by 1 */
|
|
|
++ if (result.exponent<0x4000-16383) /* exponent too small, underflow to +0 */
|
|
|
++ return POSITIVE_ZERO;
|
|
|
++ result.mantissa <<= 4; /* left-shift mantissa */
|
|
|
++ carry = !!(lastdigits>>60);
|
|
|
++ result.mantissa -= (lastdigits>>60)+(carry*6); /* Subtract extra digit. If
|
|
|
++ there is a carry, add 10 to the digit, subtract 1 from the next digit.
|
|
|
++ This can give digits of 15 in some cases. */
|
|
|
++ for (i=4;i<64;i+=4) { /* for each digit except the last one */
|
|
|
++ int d=(result.mantissa>>i)&15;
|
|
|
++ if (d<10) /* if the digit is <10, we're done */
|
|
|
++ break;
|
|
|
++ result.mantissa -= 6ull<<i; /* add 10 to the digit, subtract 1 from the
|
|
|
++ next digit */
|
|
|
++ /* There should be no carry in the first digit except if the mantissa
|
|
|
++ was exactly 1. */
|
|
|
++ gcc_assert (c || result.mantissa<0xA000000000000000ull);
|
|
|
++ }
|
|
|
++ lastdigits <<= 4; /* We handled an extra digit. */
|
|
|
++ }
|
|
|
++ /* Now do the rounding. */
|
|
|
++ if (lastdigits>0x5000000000000000ull) {
|
|
|
++ int c = !result.mantissa; /* used by the sanity check below */
|
|
|
++ /* This corner case should have been handled above. */
|
|
|
++ gcc_assert (result.mantissa!=0x1000000000000000ull);
|
|
|
++ result.mantissa--; /* Subtract 1. This can give digits of 15 in some cases. */
|
|
|
++ for (i=0;i<64;i+=4) { /* for each digit */
|
|
|
++ int d=(result.mantissa>>i)&15;
|
|
|
++ if (d<10) /* if the digit is <10, we're done */
|
|
|
++ break;
|
|
|
++ result.mantissa -= 6ull<<i; /* add 10 to the digit, subtract 1 from the
|
|
|
++ next digit */
|
|
|
++ /* There should be no carry in the first digit except if the mantissa was
|
|
|
++ 0 (which actually means 10^16 here). */
|
|
|
++ gcc_assert (c || result.mantissa<0xA000000000000000ull);
|
|
|
++ }
|
|
|
++ }
|
|
|
++ return result;
|
|
|
++ }
|
|
|
++}
|
|
|
++
|
|
|
++/* Add 2 SMAP II BCD floats. */
|
|
|
++static smap_bcd_float bcdadd(smap_bcd_float op0, smap_bcd_float op1)
|
|
|
++{
|
|
|
++ if (REAL_VALUE_ISNAN(op0) || REAL_VALUE_ISNAN(op1)) /* keep NAN */
|
|
|
++ return NAN;
|
|
|
++ else if (REAL_VALUE_ISINF(op0) && REAL_VALUE_ISINF(op1)) { /* both operands
|
|
|
++ are infinity */
|
|
|
++ if (!REAL_VALUES_IDENTICAL(op0,op1)
|
|
|
++ || REAL_VALUES_IDENTICAL(op0,UNSIGNED_INF)) /* differing signs or both
|
|
|
++ unsigned yield NAN */
|
|
|
++ return NAN;
|
|
|
++ else /* both positive or both negative */
|
|
|
++ return op0;
|
|
|
++ } else if (REAL_VALUE_ISINF(op0)) /* op0=inf, so op0+op1=inf+op1=inf=op0 */
|
|
|
++ return op0;
|
|
|
++ else if (REAL_VALUE_ISINF(op1)) /* op1=inf, so op0+op1=op0+inf=inf=op1 */
|
|
|
++ return op1;
|
|
|
++ else if (REAL_VALUE_ISZERO(op0) && REAL_VALUE_ISZERO(op1)) { /* both operands
|
|
|
++ are 0 */
|
|
|
++ if (REAL_VALUES_IDENTICAL(op0,op1)) /* both positive, both negative or both
|
|
|
++ unsigned */
|
|
|
++ return op0;
|
|
|
++ else /* differing signs yield unsigned zero */
|
|
|
++ return UNSIGNED_ZERO;
|
|
|
++ } else if (REAL_VALUE_ISZERO(op0)) /* op0=0, so op0+op1=0+op1=op1 */
|
|
|
++ return op1;
|
|
|
++ else if (REAL_VALUE_ISZERO(op1)) /* op1=0, so op0+op1=op0+0=op0 */
|
|
|
++ return op0;
|
|
|
++ else if (REAL_VALUE_ISPOSITIVE(op0) && REAL_VALUE_ISPOSITIVE(op1))
|
|
|
++ return bcdppadd(op0,op1);
|
|
|
++ else if (REAL_VALUE_ISPOSITIVE(op0)) /* and op1 negative */
|
|
|
++ return bcdppsub(op0,REAL_VALUE_NEGATE(op1));
|
|
|
++ else if (REAL_VALUE_ISPOSITIVE(op1)) /* and op0 negative */
|
|
|
++ return bcdppsub(op1,REAL_VALUE_NEGATE(op0));
|
|
|
++ else /* both negative */
|
|
|
++ return REAL_VALUE_NEGATE(bcdppadd(REAL_VALUE_NEGATE(op0),
|
|
|
++ REAL_VALUE_NEGATE(op1)));
|
|
|
++}
|
|
|
++
|
|
|
++/* Subtract 2 SMAP II BCD floats. */
|
|
|
++static smap_bcd_float bcdsub(smap_bcd_float op0, smap_bcd_float op1)
|
|
|
++{
|
|
|
++ return bcdadd(op0,REAL_VALUE_NEGATE(op1));
|
|
|
++}
|
|
|
++
|
|
|
++/* Multiply 2 positive SMAP II BCD floats. */
|
|
|
++static smap_bcd_float bcdppmul(smap_bcd_float op0, smap_bcd_float op1)
|
|
|
++{
|
|
|
++ /* Compute the result in 2 binary parts. The upper 16 decimal digits and the
|
|
|
++ lower ones. */
|
|
|
++ unsigned long long resulth=0, resultl=0;
|
|
|
++ int i,j,k,d0,d1,d32,exponent;
|
|
|
++ unsigned long long factor=1ull;
|
|
|
++ for (i=0;i<64;i+=4,factor*=10ull) { /* for each result digit <16 */
|
|
|
++ for (j=0;j<64;j+=4) { /* for each digit of op0 */
|
|
|
++ k = i-j; /* corresponding op1 digit */
|
|
|
++ if (k<0 || k>=64) continue; /* digit out of range */
|
|
|
++ d0 = (op0.mantissa>>j)&15; /* jth digit of op0 */
|
|
|
++ d1 = (op1.mantissa>>k)&15; /* kth digit of op0 */
|
|
|
++ resultl += (unsigned long long)(d0*d1)*factor;
|
|
|
++ while (resultl>=10000000000000000ull/*10^16*/) { /* carry into resulth */
|
|
|
++ resultl -= 10000000000000000ull/*10^16*/;
|
|
|
++ resulth++;
|
|
|
++ }
|
|
|
++ }
|
|
|
++ }
|
|
|
++ for (factor=1ull;i<128;i+=4,factor*=10ull) { /* for each result digit >=16 */
|
|
|
++ for (j=0;j<64;j+=4) { /* for each digit of op0 */
|
|
|
++ k = i-j; /* corresponding op1 digit */
|
|
|
++ if (k<0 || k>=64) continue; /* digit out of range */
|
|
|
++ d0 = (op0.mantissa>>j)&15; /* jth digit of op0 */
|
|
|
++ d1 = (op1.mantissa>>k)&15; /* kth digit of op0 */
|
|
|
++ resulth += (unsigned long long)(d0*d1)*factor;
|
|
|
++ }
|
|
|
++ }
|
|
|
++
|
|
|
++ /* resultl should always be <10^16 */
|
|
|
++ gcc_assert (resultl<10000000000000000ull);
|
|
|
++
|
|
|
++ /* Because of normalization, the result has either 31 or 32 digits. */
|
|
|
++ d32 = (resulth>=1000000000000000ull/*10^15*/
|
|
|
++ || (resulth==999999999999999ull/*10^15-1*/
|
|
|
++ && resultl>=9500000000000000ull/*9.5*10^15*/));
|
|
|
++ if (!d32) { /* if we have only 15 digits in resulth, take one from resultl */
|
|
|
++ resulth = resulth*10ull+resultl/1000000000000000ull/*10^15*/;
|
|
|
++ resultl = (resultl%1000000000000000ull/*10^15*/)*10ull;
|
|
|
++ }
|
|
|
++ if (resultl>=5000000000000000ull/*5*10^15*/) /* round resultl into resulth */
|
|
|
++ resulth++;
|
|
|
++
|
|
|
++ /* Now compute the exponent. */
|
|
|
++ exponent=op0.exponent+op1.exponent-0x4000+d32;
|
|
|
++ if (exponent>0x4000+16383) /* exponent too large, overflow to +infinity */
|
|
|
++ return POSITIVE_INF;
|
|
|
++ if (exponent<0x4000-16383) /* exponent too small, underflow to +0 */
|
|
|
++ return POSITIVE_ZERO;
|
|
|
++
|
|
|
++ /* Now convert resulth into a BCD mantissa. */
|
|
|
++ {
|
|
|
++ unsigned long long d;
|
|
|
++ smap_bcd_float result={0,0};result.exponent=exponent;
|
|
|
++ for (i=0;i<64;i+=4) { /* for each digit */
|
|
|
++ d = resulth%10ull; /* Extract the digit. */
|
|
|
++ resulth /= 10ull; /* We are done with this digit of the mantissa. */
|
|
|
++ result.mantissa += d<<i; /* Store it into the resulting mantissa. */
|
|
|
++ }
|
|
|
++ return result;
|
|
|
++ }
|
|
|
++}
|
|
|
++
|
|
|
++/* Multiply 2 SMAP II BCD floats. */
|
|
|
++static smap_bcd_float bcdmul(smap_bcd_float op0, smap_bcd_float op1)
|
|
|
++{
|
|
|
++ if (REAL_VALUE_ISNAN(op0) || REAL_VALUE_ISNAN(op1)
|
|
|
++ || (REAL_VALUE_ISINF(op0) && REAL_VALUE_ISZERO(op1))
|
|
|
++ || (REAL_VALUE_ISZERO(op0) && REAL_VALUE_ISINF(op1))) /* keep NAN,
|
|
|
++ 0*inf=NAN */
|
|
|
++ return NAN;
|
|
|
++ else if (REAL_VALUES_IDENTICAL(op0,UNSIGNED_INF)
|
|
|
++ || REAL_VALUES_IDENTICAL(op1,UNSIGNED_INF)) /* unsigned inf * non-0 =
|
|
|
++ unsigned inf */
|
|
|
++ return UNSIGNED_INF;
|
|
|
++ else if ((REAL_VALUES_IDENTICAL(op0,POSITIVE_INF)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,POSITIVE_INF)) /* +inf * +inf = +inf */
|
|
|
++ || (REAL_VALUES_IDENTICAL(op0,NEGATIVE_INF)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,NEGATIVE_INF))) /* -inf * -inf = +inf */
|
|
|
++ return POSITIVE_INF;
|
|
|
++ else if ((REAL_VALUES_IDENTICAL(op0,POSITIVE_INF)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,NEGATIVE_INF)) /* +inf * -inf = -inf */
|
|
|
++ || (REAL_VALUES_IDENTICAL(op0,NEGATIVE_INF)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,POSITIVE_INF))) /* -inf * +inf = -inf */
|
|
|
++ return NEGATIVE_INF;
|
|
|
++ /* Now we can assume that at least 1 value is finite, and that we don't have
|
|
|
++ an unsigned infinity, a NAN or an inf*0 indeterminate form. */
|
|
|
++ else if ((REAL_VALUES_IDENTICAL(op0,POSITIVE_INF)
|
|
|
++ && REAL_VALUE_ISPOSITIVE(op1)) /* +inf * +finite = +inf */
|
|
|
++ || (REAL_VALUE_ISPOSITIVE(op0)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,POSITIVE_INF)) /* +finite * +inf = +inf */
|
|
|
++ || (REAL_VALUES_IDENTICAL(op0,NEGATIVE_INF)
|
|
|
++ && REAL_VALUE_ISNEGATIVE(op1)) /* -inf * -finite = +inf */
|
|
|
++ || (REAL_VALUE_ISNEGATIVE(op0)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,NEGATIVE_INF))) /* -finite * -inf = +inf */
|
|
|
++ return POSITIVE_INF;
|
|
|
++ else if ((REAL_VALUES_IDENTICAL(op0,POSITIVE_INF)
|
|
|
++ && REAL_VALUE_ISNEGATIVE(op1)) /* +inf * -finite = -inf */
|
|
|
++ || (REAL_VALUE_ISPOSITIVE(op0)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,NEGATIVE_INF)) /* +finite * -inf = -inf */
|
|
|
++ || (REAL_VALUES_IDENTICAL(op0,NEGATIVE_INF)
|
|
|
++ && REAL_VALUE_ISPOSITIVE(op1)) /* -inf * +finite = -inf */
|
|
|
++ || (REAL_VALUE_ISNEGATIVE(op0)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,POSITIVE_INF))) /* -finite * +inf = -inf */
|
|
|
++ return NEGATIVE_INF;
|
|
|
++ /* Now we can assume that both values are finite. */
|
|
|
++ else if (REAL_VALUES_IDENTICAL(op0,UNSIGNED_ZERO)
|
|
|
++ || REAL_VALUES_IDENTICAL(op1,UNSIGNED_ZERO)) /* unsigned 0 * finite =
|
|
|
++ unsigned 0 */
|
|
|
++ return UNSIGNED_ZERO;
|
|
|
++ else if ((REAL_VALUES_IDENTICAL(op0,POSITIVE_ZERO)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,POSITIVE_ZERO)) /* +0 * +0 = +0 */
|
|
|
++ || (REAL_VALUES_IDENTICAL(op0,NEGATIVE_ZERO)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,NEGATIVE_ZERO))) /* -0 * -0 = +0 */
|
|
|
++ return POSITIVE_ZERO;
|
|
|
++ else if ((REAL_VALUES_IDENTICAL(op0,POSITIVE_ZERO)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,NEGATIVE_ZERO)) /* +0 * -0 = -0 */
|
|
|
++ || (REAL_VALUES_IDENTICAL(op0,NEGATIVE_ZERO)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,POSITIVE_ZERO))) /* -0 * +0 = -0 */
|
|
|
++ return NEGATIVE_ZERO;
|
|
|
++ /* Now we can assume that both values are finite, at least 1 value is non-0,
|
|
|
++ and that we don't have an unsigned 0. */
|
|
|
++ else if ((REAL_VALUES_IDENTICAL(op0,POSITIVE_ZERO)
|
|
|
++ && REAL_VALUE_ISPOSITIVE(op1)) /* +0 * +finite = +0 */
|
|
|
++ || (REAL_VALUE_ISPOSITIVE(op0)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,POSITIVE_ZERO)) /* +finite * +0 = +0 */
|
|
|
++ || (REAL_VALUES_IDENTICAL(op0,NEGATIVE_ZERO)
|
|
|
++ && REAL_VALUE_ISNEGATIVE(op1)) /* -0 * -finite = +0 */
|
|
|
++ || (REAL_VALUE_ISNEGATIVE(op0)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,NEGATIVE_ZERO))) /* -finite * -0 = +0 */
|
|
|
++ return POSITIVE_ZERO;
|
|
|
++ else if ((REAL_VALUES_IDENTICAL(op0,POSITIVE_ZERO)
|
|
|
++ && REAL_VALUE_ISNEGATIVE(op1)) /* +0 * -finite = -0 */
|
|
|
++ || (REAL_VALUE_ISPOSITIVE(op0)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,NEGATIVE_ZERO)) /* +finite * -0 = -0 */
|
|
|
++ || (REAL_VALUES_IDENTICAL(op0,NEGATIVE_ZERO)
|
|
|
++ && REAL_VALUE_ISPOSITIVE(op1)) /* -0 * +finite = -0 */
|
|
|
++ || (REAL_VALUE_ISNEGATIVE(op0)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,POSITIVE_ZERO))) /* -finite * +0 = -0 */
|
|
|
++ return NEGATIVE_ZERO;
|
|
|
++ /* Now we can assume that both values are finite and non-0. */
|
|
|
++ else if (REAL_VALUE_ISPOSITIVE(op0) && REAL_VALUE_ISPOSITIVE(op1))
|
|
|
++ return bcdppmul(op0,op1);
|
|
|
++ else if (REAL_VALUE_ISPOSITIVE(op0)) /* and op1 negative */
|
|
|
++ return REAL_VALUE_NEGATE(bcdppmul(op0,REAL_VALUE_NEGATE(op1)));
|
|
|
++ else if (REAL_VALUE_ISPOSITIVE(op1)) /* and op0 negative */
|
|
|
++ return REAL_VALUE_NEGATE(bcdppmul(REAL_VALUE_NEGATE(op0),op1));
|
|
|
++ else /* both negative */
|
|
|
++ return bcdppmul(REAL_VALUE_NEGATE(op0),REAL_VALUE_NEGATE(op1));
|
|
|
++}
|
|
|
++
|
|
|
++/* Divide 2 positive SMAP II BCD floats. Indicate if the computed result was exact. */
|
|
|
++static smap_bcd_float bcdppdiv(smap_bcd_float op0, smap_bcd_float op1, int *exactresult)
|
|
|
++{
|
|
|
++ /* The dividend is represented multiplied by 10^16, and in 2 binary parts. The
|
|
|
++ upper 64 bits and the lower ones. The divisor is represented in binary, in
|
|
|
++ 2 parts to allow shifting. Compute the result mantissa in binary. */
|
|
|
++ unsigned long long dividendh, dividendl=0, divisorh, divisorl=0, resultm=0;
|
|
|
++ int i,d17,exponent;
|
|
|
++ unsigned long long factor=1ull;
|
|
|
++ /* Convert the mantissa of op0 to binary. */
|
|
|
++ for (i=0;i<64;i+=4,factor*=10ull) /* for each digit of op0 */
|
|
|
++ dividendl += (unsigned long long)((op0.mantissa>>i)&15)*factor;
|
|
|
++ /* Multiply the dividend with 10^16. */
|
|
|
++ dividendh = dividendl>>48; /* multiply first 16 bits with 2^16 */
|
|
|
++ dividendh *= 152587890625ull; /* and with 5^16 */
|
|
|
++ dividendl &= 0xFFFFFFFFFFFFull; /* remove them from dividendl */
|
|
|
++ dividendl *= 15625ull; /* multiply the remaining 48 bits with 5^6
|
|
|
++ we still have to multiply them by 2^16*5^10 */
|
|
|
++ dividendh += (dividendl>>48)*9765625ull; /* multiply first 16 bits with 2^16*5^10 */
|
|
|
++ dividendl &= 0xFFFFFFFFFFFFull; /* remove them from dividendl */
|
|
|
++ dividendl *= 15625ull; /* multiply the remaining 48 bits with 5^6
|
|
|
++ we still have to multiply them by 2^16*5^4 */
|
|
|
++ dividendh += (dividendl>>48)*625ull; /* multiply first 16 bits with 2^16*5^4 */
|
|
|
++ dividendl &= 0xFFFFFFFFFFFFull; /* remove them from dividendl */
|
|
|
++ dividendl *= 625ull; /* multiply the remaining 48 bits with 5^4
|
|
|
++ we still have to multiply them by 2^16 */
|
|
|
++ dividendh += dividendl>>48; /* multiply first 16 bits with 2^16 */
|
|
|
++ dividendl <<= 16; /* multiply the remaining 48 bits with 2^16 */
|
|
|
++ /* Convert the mantissa of op1 to binary. */
|
|
|
++ for (i=0,factor=1ull;i<64;i+=4,factor*=10ull) /* for each digit of op1 */
|
|
|
++ divisorl += (unsigned long long)((op1.mantissa>>i)&15)*factor;
|
|
|
++ /* Multiply the divisor with 2^56. We know that, due to normalization, the
|
|
|
++ result is always <10^17, which is smaller than 2^57, so we don't have to go
|
|
|
++ through the full 128-bit division. */
|
|
|
++ divisorh = divisorl>>(64-56);
|
|
|
++ divisorl <<= 56;
|
|
|
++ /* Now do the 128-bit division. */
|
|
|
++ for (i=56;i>=0;i--) {
|
|
|
++ /* Shift the result to the left. */
|
|
|
++ resultm <<= 1;
|
|
|
++ /* Check if the divisor fits into the dividend. */
|
|
|
++ if (divisorh<dividendh || (divisorh==dividendh && divisorl<=dividendl)) {
|
|
|
++ /* Add 1 to the result. */
|
|
|
++ resultm++;
|
|
|
++ /* Subtract the divisor from the dividend. */
|
|
|
++ if (dividendl<divisorl) /* handle carry, use unsigned wraparound overflow */
|
|
|
++ dividendh--;
|
|
|
++ dividendl -= divisorl; /* now do the subtraction */
|
|
|
++ dividendh -= divisorh;
|
|
|
++ }
|
|
|
++ if (i) {
|
|
|
++ /* Shift the divisor to the right. */
|
|
|
++ divisorl = ((divisorh&1)<<63)+(divisorl>>1);
|
|
|
++ divisorh >>= 1;
|
|
|
++ }
|
|
|
++ }
|
|
|
++ /* dividendl now contains the remainder. It is always smaller than the
|
|
|
++ divisor, so it always fits into 64 bits. divisorl now contains the original
|
|
|
++ divisor. */
|
|
|
++
|
|
|
++ if (exactresult)
|
|
|
++ *exactresult = !dividendl; /* if there is a remainder, the result sure is
|
|
|
++ not exact, otherwise, let's assume it is for
|
|
|
++ a moment */
|
|
|
++
|
|
|
++ /* Because of normalization, the result has either 16 or 17 digits. */
|
|
|
++ d17 = (resultm>=10000000000000000ull/*10^16*/
|
|
|
++ || (resultm==9999999999999999ull/*10^16-1*/
|
|
|
++ && (dividendl<<1)>=divisorl) /* 2r>=d <=> r>=d/2 */);
|
|
|
++ if (d17) { /* if we have 17 digits in the result, drop one */
|
|
|
++ if (exactresult && (resultm%10ull)) /* if we are about to drop a non-0
|
|
|
++ digit, the result is not exact
|
|
|
++ anymore */
|
|
|
++ *exactresult = 0;
|
|
|
++ resultm = (resultm+5ull)/10ull; /* add 5 for correct rounding */
|
|
|
++ } else {
|
|
|
++ if ((dividendl<<1)>=divisorl /* r>=d/2 */) /* round remainder into result */
|
|
|
++ resultm++;
|
|
|
++ }
|
|
|
++
|
|
|
++ /* Now compute the exponent. */
|
|
|
++ exponent=op0.exponent-op1.exponent+0x4000-(!d17);
|
|
|
++ if (exactresult && (exponent>0x4000+16383 || exponent<0x4000-16383))
|
|
|
++ /* if we overflowed, the result is not exact anymore */
|
|
|
++ *exactresult = 0;
|
|
|
++ if (exponent>0x4000+16383) /* exponent too large, overflow to +infinity */
|
|
|
++ return POSITIVE_INF;
|
|
|
++ if (exponent<0x4000-16383) /* exponent too small, underflow to +0 */
|
|
|
++ return POSITIVE_ZERO;
|
|
|
++
|
|
|
++ /* Now convert resulth into a BCD mantissa. */
|
|
|
++ {
|
|
|
++ unsigned long long d;
|
|
|
++ smap_bcd_float result={0,0};result.exponent=exponent;
|
|
|
++ for (i=0;i<64;i+=4) { /* for each digit */
|
|
|
++ d = resultm%10ull; /* Extract the digit. */
|
|
|
++ resultm /= 10ull; /* We are done with this digit of the mantissa. */
|
|
|
++ result.mantissa += d<<i; /* Store it into the resulting mantissa. */
|
|
|
++ }
|
|
|
++ return result;
|
|
|
++ }
|
|
|
++}
|
|
|
++
|
|
|
++/* Divide 2 SMAP II BCD floats. Indicate if the computed result was exact. */
|
|
|
++static smap_bcd_float bcddiv(smap_bcd_float op0, smap_bcd_float op1, int *exactresult)
|
|
|
++{
|
|
|
++ if (exactresult) *exactresult=1; /* special cases are all exact */
|
|
|
++ if (REAL_VALUE_ISNAN(op0) || REAL_VALUE_ISNAN(op1)
|
|
|
++ || (REAL_VALUE_ISINF(op0) && REAL_VALUE_ISINF(op1))
|
|
|
++ || (REAL_VALUE_ISZERO(op0) && REAL_VALUE_ISZERO(op1))) /* keep NAN,
|
|
|
++ 0/0=inf/inf=NAN */
|
|
|
++ return NAN;
|
|
|
++ else if (REAL_VALUES_IDENTICAL(op0,UNSIGNED_INF)
|
|
|
++ || REAL_VALUES_IDENTICAL(op1,UNSIGNED_ZERO)) /* unsigned inf / finite
|
|
|
++ = non-0 / unsigned 0 = unsigned inf */
|
|
|
++ return UNSIGNED_INF;
|
|
|
++ else if ((REAL_VALUES_IDENTICAL(op0,POSITIVE_INF)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,POSITIVE_ZERO)) /* +inf / +0 = +inf */
|
|
|
++ || (REAL_VALUES_IDENTICAL(op0,NEGATIVE_INF)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,NEGATIVE_ZERO))) /* -inf / -0 = +inf */
|
|
|
++ return POSITIVE_INF;
|
|
|
++ else if ((REAL_VALUES_IDENTICAL(op0,POSITIVE_INF)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,NEGATIVE_ZERO)) /* +inf / -0 = -inf */
|
|
|
++ || (REAL_VALUES_IDENTICAL(op0,NEGATIVE_INF)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,POSITIVE_ZERO))) /* -inf / +0 = -inf */
|
|
|
++ return NEGATIVE_INF;
|
|
|
++ /* Now we can assume that at least 1 of op0 and 1/op1 is finite, and that we
|
|
|
++ don't have op0 = unsigned inf, op1 = unsigned 0, a NAN or an inf/inf or 0/0
|
|
|
++ indeterminate form. */
|
|
|
++ else if ((REAL_VALUES_IDENTICAL(op0,POSITIVE_INF)
|
|
|
++ && REAL_VALUE_ISPOSITIVE(op1)) /* +inf / +non-0 = +inf */
|
|
|
++ || (REAL_VALUE_ISPOSITIVE(op0)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,POSITIVE_ZERO)) /* +finite / +0 = +inf */
|
|
|
++ || (REAL_VALUES_IDENTICAL(op0,NEGATIVE_INF)
|
|
|
++ && REAL_VALUE_ISNEGATIVE(op1)) /* -inf / -non-0 = +inf */
|
|
|
++ || (REAL_VALUE_ISNEGATIVE(op0)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,NEGATIVE_ZERO))) /* -finite / -0 = +inf */
|
|
|
++ return POSITIVE_INF;
|
|
|
++ else if ((REAL_VALUES_IDENTICAL(op0,POSITIVE_INF)
|
|
|
++ && REAL_VALUE_ISNEGATIVE(op1)) /* +inf / -non-0 = -inf */
|
|
|
++ || (REAL_VALUE_ISPOSITIVE(op0)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,NEGATIVE_ZERO)) /* +finite / -0 = -inf */
|
|
|
++ || (REAL_VALUES_IDENTICAL(op0,NEGATIVE_INF)
|
|
|
++ && REAL_VALUE_ISPOSITIVE(op1)) /* -inf / +non-0 = -inf */
|
|
|
++ || (REAL_VALUE_ISNEGATIVE(op0)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,POSITIVE_ZERO))) /* -finite / +0 = -inf */
|
|
|
++ return NEGATIVE_INF;
|
|
|
++ /* Now we can assume that both of op0 and 1/op1 are finite. */
|
|
|
++ else if (REAL_VALUES_IDENTICAL(op0,UNSIGNED_ZERO)
|
|
|
++ || REAL_VALUES_IDENTICAL(op1,UNSIGNED_INF)) /* unsigned 0 / non-0 =
|
|
|
++ finite / unsigned inf = unsigned 0 */
|
|
|
++ return UNSIGNED_ZERO;
|
|
|
++ else if ((REAL_VALUES_IDENTICAL(op0,POSITIVE_ZERO)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,POSITIVE_INF)) /* +0 / +inf = +0 */
|
|
|
++ || (REAL_VALUES_IDENTICAL(op0,NEGATIVE_ZERO)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,NEGATIVE_INF))) /* -0 / -inf = +0 */
|
|
|
++ return POSITIVE_ZERO;
|
|
|
++ else if ((REAL_VALUES_IDENTICAL(op0,POSITIVE_ZERO)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,NEGATIVE_INF)) /* +0 / -inf = -0 */
|
|
|
++ || (REAL_VALUES_IDENTICAL(op0,NEGATIVE_ZERO)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,POSITIVE_INF))) /* -0 / +inf = -0 */
|
|
|
++ return NEGATIVE_ZERO;
|
|
|
++ /* Now we can assume that both of op0 and 1/op1 are finite, at least 1 of them
|
|
|
++ is non-0, and that neither of them is an unsigned 0. */
|
|
|
++ else if ((REAL_VALUES_IDENTICAL(op0,POSITIVE_ZERO)
|
|
|
++ && REAL_VALUE_ISPOSITIVE(op1)) /* +0 / +non-0 = +0 */
|
|
|
++ || (REAL_VALUE_ISPOSITIVE(op0)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,POSITIVE_INF)) /* +finite / +inf = +0 */
|
|
|
++ || (REAL_VALUES_IDENTICAL(op0,NEGATIVE_ZERO)
|
|
|
++ && REAL_VALUE_ISNEGATIVE(op1)) /* -0 / -non-0 = +0 */
|
|
|
++ || (REAL_VALUE_ISNEGATIVE(op0)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,NEGATIVE_INF))) /* -finite / -inf = +0 */
|
|
|
++ return POSITIVE_ZERO;
|
|
|
++ else if ((REAL_VALUES_IDENTICAL(op0,POSITIVE_ZERO)
|
|
|
++ && REAL_VALUE_ISNEGATIVE(op1)) /* +0 / -non-0 = -0 */
|
|
|
++ || (REAL_VALUE_ISPOSITIVE(op0)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,NEGATIVE_INF)) /* +finite / -inf = -0 */
|
|
|
++ || (REAL_VALUES_IDENTICAL(op0,NEGATIVE_ZERO)
|
|
|
++ && REAL_VALUE_ISPOSITIVE(op1)) /* -0 / +non-0 = -0 */
|
|
|
++ || (REAL_VALUE_ISNEGATIVE(op0)
|
|
|
++ && REAL_VALUES_IDENTICAL(op1,POSITIVE_INF))) /* -finite / +inf = -0 */
|
|
|
++ return NEGATIVE_ZERO;
|
|
|
++ /* Now we can assume that both values are finite and non-0. */
|
|
|
++ else if (REAL_VALUE_ISPOSITIVE(op0) && REAL_VALUE_ISPOSITIVE(op1))
|
|
|
++ return bcdppdiv(op0,op1,exactresult);
|
|
|
++ else if (REAL_VALUE_ISPOSITIVE(op0)) /* and op1 negative */
|
|
|
++ return REAL_VALUE_NEGATE(bcdppdiv(op0,REAL_VALUE_NEGATE(op1),exactresult));
|
|
|
++ else if (REAL_VALUE_ISPOSITIVE(op1)) /* and op0 negative */
|
|
|
++ return REAL_VALUE_NEGATE(bcdppdiv(REAL_VALUE_NEGATE(op0),op1,exactresult));
|
|
|
++ else /* both negative */
|
|
|
++ return bcdppdiv(REAL_VALUE_NEGATE(op0),REAL_VALUE_NEGATE(op1),exactresult);
|
|
|
++}
|
|
|
++
|
|
|
++/* Compute min of 2 SMAP II BCD floats. */
|
|
|
++static smap_bcd_float bcdmin(smap_bcd_float op0, smap_bcd_float op1)
|
|
|
++{
|
|
|
++ if (REAL_VALUE_ISNANUINF(op0) || REAL_VALUE_ISNANUINF(op1)) /* keep NAN,
|
|
|
++ UNSIGNED_INF is neither smaller nor larger than the other */
|
|
|
++ return NAN;
|
|
|
++ else if (REAL_VALUES_IDENTICAL(op0,NEGATIVE_INF)
|
|
|
++ || REAL_VALUES_IDENTICAL(op1,NEGATIVE_INF)) /* keep -infinity */
|
|
|
++ return NEGATIVE_INF;
|
|
|
++ else if (REAL_VALUES_IDENTICAL(op0,POSITIVE_INF)) /* all numbers are smaller
|
|
|
++ than +infinity */
|
|
|
++ return op1;
|
|
|
++ else if (REAL_VALUES_IDENTICAL(op1,POSITIVE_INF)) /* all numbers are smaller
|
|
|
++ than +infinity */
|
|
|
++ return op0;
|
|
|
++ /* Now, we can assume that all values are finite. */
|
|
|
++ else if (REAL_VALUES_LESS(op0,op1)) /* if op0<op1, return op0 */
|
|
|
++ return op0;
|
|
|
++ else /* if op0>=op1, return op1 */
|
|
|
++ return op1;
|
|
|
++}
|
|
|
++
|
|
|
++/* Compute max of 2 SMAP II BCD floats. */
|
|
|
++static smap_bcd_float bcdmax(smap_bcd_float op0, smap_bcd_float op1)
|
|
|
++{
|
|
|
++ if (REAL_VALUE_ISNANUINF(op0) || REAL_VALUE_ISNANUINF(op1)) /* keep NAN,
|
|
|
++ UNSIGNED_INF is neither smaller nor larger than the other */
|
|
|
++ return NAN;
|
|
|
++ else if (REAL_VALUES_IDENTICAL(op0,POSITIVE_INF)
|
|
|
++ || REAL_VALUES_IDENTICAL(op1,POSITIVE_INF)) /* keep +infinity */
|
|
|
++ return POSITIVE_INF;
|
|
|
++ else if (REAL_VALUES_IDENTICAL(op0,NEGATIVE_INF)) /* all numbers are smaller
|
|
|
++ than -infinity */
|
|
|
++ return op1;
|
|
|
++ else if (REAL_VALUES_IDENTICAL(op1,NEGATIVE_INF)) /* all numbers are smaller
|
|
|
++ than -infinity */
|
|
|
++ return op0;
|
|
|
++ /* Now, we can assume that all values are finite. */
|
|
|
++ else if (REAL_VALUES_LESS(op0,op1)) /* if op0<op1, return op1 */
|
|
|
++ return op1;
|
|
|
++ else /* if op0>=op1, return op0 */
|
|
|
++ return op0;
|
|
|
++}
|
|
|
+
|
|
|
+ /* Perform the binary or unary operation described by CODE.
|
|
|
+ For a unary operation, leave OP1 NULL. This function returns
|
|
|
+@@ -982,6 +1593,37 @@
|
|
|
+ real_arithmetic (REAL_VALUE_TYPE *r, int icode, const REAL_VALUE_TYPE *op0,
|
|
|
+ const REAL_VALUE_TYPE *op1)
|
|
|
+ {
|
|
|
++ switch (icode)
|
|
|
++ {
|
|
|
++ case PLUS_EXPR:
|
|
|
++ *r = bcdadd (*op0, *op1);
|
|
|
++ return true;
|
|
|
++
|
|
|
++ case MINUS_EXPR:
|
|
|
++ *r = bcdsub (*op0, *op1);
|
|
|
++ return true;
|
|
|
++
|
|
|
++ case MULT_EXPR:
|
|
|
++ *r = bcdmul (*op0, *op1);
|
|
|
++ return true;
|
|
|
++
|
|
|
++ case RDIV_EXPR:
|
|
|
++ *r = bcddiv (*op0, *op1, NULL);
|
|
|
++ return true;
|
|
|
++
|
|
|
++ case MIN_EXPR:
|
|
|
++ *r = bcdmin (*op0, *op1);
|
|
|
++ return false;
|
|
|
++
|
|
|
++ case MAX_EXPR:
|
|
|
++ *r = bcdmax (*op0, *op1);
|
|
|
++ return false;
|
|
|
++
|
|
|
++ default:
|
|
|
++ gcc_unreachable ();
|
|
|
++ }
|
|
|
++
|
|
|
++#if 0
|
|
|
+ enum tree_code code = icode;
|
|
|
+
|
|
|
+ switch (code)
|
|
|
+@@ -1033,9 +1675,11 @@
|
|
|
+ default:
|
|
|
+ gcc_unreachable ();
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Legacy. Similar, but return the result directly. */
|
|
|
+
|
|
|
+ REAL_VALUE_TYPE
|
|
|
+@@ -1046,6 +1690,7 @@
|
|
|
+ real_arithmetic (&r, icode, op0, op1);
|
|
|
+ return r;
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ bool
|
|
|
+ real_compare (int icode, const REAL_VALUE_TYPE *op0,
|
|
|
+@@ -1056,39 +1701,40 @@
|
|
|
+ switch (code)
|
|
|
+ {
|
|
|
+ case LT_EXPR:
|
|
|
+- return do_compare (op0, op1, 1) < 0;
|
|
|
++ return REAL_VALUES_LESS (*op0, *op1);
|
|
|
+ case LE_EXPR:
|
|
|
+- return do_compare (op0, op1, 1) <= 0;
|
|
|
++ return !real_compare (UNGT_EXPR, op0, op1);
|
|
|
+ case GT_EXPR:
|
|
|
+- return do_compare (op0, op1, -1) > 0;
|
|
|
++ return real_compare (LT_EXPR, op1, op0);
|
|
|
+ case GE_EXPR:
|
|
|
+- return do_compare (op0, op1, -1) >= 0;
|
|
|
++ return !real_compare (UNLT_EXPR, op0, op1);
|
|
|
+ case EQ_EXPR:
|
|
|
+- return do_compare (op0, op1, -1) == 0;
|
|
|
++ return REAL_VALUES_EQUAL (*op0, *op1);
|
|
|
+ case NE_EXPR:
|
|
|
+- return do_compare (op0, op1, -1) != 0;
|
|
|
++ return !real_compare (EQ_EXPR, op0, op1);
|
|
|
+ case UNORDERED_EXPR:
|
|
|
+- return op0->cl == rvc_nan || op1->cl == rvc_nan;
|
|
|
++ return REAL_VALUE_ISNANUINF (*op0) || REAL_VALUE_ISNANUINF (*op1);
|
|
|
+ case ORDERED_EXPR:
|
|
|
+- return op0->cl != rvc_nan && op1->cl != rvc_nan;
|
|
|
++ return !real_compare (UNORDERED_EXPR, op0, op1);
|
|
|
+ case UNLT_EXPR:
|
|
|
+- return do_compare (op0, op1, -1) < 0;
|
|
|
++ return real_compare (UNORDERED_EXPR, op0, op1) || real_compare (LT_EXPR, op0, op1);
|
|
|
+ case UNLE_EXPR:
|
|
|
+- return do_compare (op0, op1, -1) <= 0;
|
|
|
++ return !real_compare (GT_EXPR, op0, op1);
|
|
|
+ case UNGT_EXPR:
|
|
|
+- return do_compare (op0, op1, 1) > 0;
|
|
|
++ return real_compare (UNORDERED_EXPR, op0, op1) || real_compare (GT_EXPR, op0, op1);
|
|
|
+ case UNGE_EXPR:
|
|
|
+- return do_compare (op0, op1, 1) >= 0;
|
|
|
++ return !real_compare (LT_EXPR, op0, op1);
|
|
|
+ case UNEQ_EXPR:
|
|
|
+- return do_compare (op0, op1, 0) == 0;
|
|
|
++ return real_compare (UNORDERED_EXPR, op0, op1) || real_compare (EQ_EXPR, op0, op1);
|
|
|
+ case LTGT_EXPR:
|
|
|
+- return do_compare (op0, op1, 0) != 0;
|
|
|
++ return !real_compare (UNEQ_EXPR, op0, op1);
|
|
|
+
|
|
|
+ default:
|
|
|
+ gcc_unreachable ();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Return floor log2(R). */
|
|
|
+
|
|
|
+ int
|
|
|
+@@ -1209,6 +1855,7 @@
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Try to change R into its exact multiplicative inverse in machine
|
|
|
+ mode MODE. Return true if successful. */
|
|
|
+@@ -1216,6 +1863,13 @@
|
|
|
+ bool
|
|
|
+ exact_real_inverse (enum machine_mode mode, REAL_VALUE_TYPE *r)
|
|
|
+ {
|
|
|
++ int exactresult=0;
|
|
|
++ smap_bcd_float one={0x4000,0x1000000000000000ull}, invr;
|
|
|
++
|
|
|
++ invr = bcddiv(one,*r,&exactresult);
|
|
|
++ if (exactresult) *r=invr;
|
|
|
++ return exactresult;
|
|
|
++#if 0
|
|
|
+ const REAL_VALUE_TYPE *one = real_digit (1);
|
|
|
+ REAL_VALUE_TYPE u;
|
|
|
+ int i;
|
|
|
+@@ -1245,8 +1899,10 @@
|
|
|
+
|
|
|
+ *r = u;
|
|
|
+ return true;
|
|
|
++#endif /* 0 */
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Render R as an integer. */
|
|
|
+
|
|
|
+ HOST_WIDE_INT
|
|
|
+@@ -1298,6 +1954,7 @@
|
|
|
+ gcc_unreachable ();
|
|
|
+ }
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Likewise, but to an integer pair, HI+LOW. */
|
|
|
+
|
|
|
+@@ -1305,6 +1962,59 @@
|
|
|
+ real_to_integer2 (HOST_WIDE_INT *plow, HOST_WIDE_INT *phigh,
|
|
|
+ const REAL_VALUE_TYPE *r)
|
|
|
+ {
|
|
|
++ unsigned short exponent = (r->exponent & 0x7fff);
|
|
|
++ unsigned HOST_WIDE_INT low = 0, high = 0;
|
|
|
++ int e, i;
|
|
|
++ unsigned long long mantissa = r->mantissa;
|
|
|
++
|
|
|
++ /* Return 0 for transfinite, zero or |*r|<1 */
|
|
|
++ if (!REAL_VALUE_ISFINITE(*r) || REAL_VALUE_ISZERO(*r) || exponent < 0x4000) {
|
|
|
++ *plow = *phigh = 0;
|
|
|
++ return;
|
|
|
++ }
|
|
|
++
|
|
|
++ /* Compute the effective exponent */
|
|
|
++ e = (int)exponent - (0x4000+15);
|
|
|
++
|
|
|
++ /* Delete any digits following the decimal point right now */
|
|
|
++ if (e < 0) {
|
|
|
++ mantissa >>= ((-e)<<2);
|
|
|
++ e = 0;
|
|
|
++ } else if (e > 2*HOST_BITS_PER_WIDE_INT) {
|
|
|
++ /* We'll multiply by 10^(2*HBPWI)=5^(2*HBPWI)*2^(2*HBPWI). This will zero
|
|
|
++ out all digits. So avoid the long loop and return 0 right now. */
|
|
|
++ *plow = *phigh = 0;
|
|
|
++ return;
|
|
|
++ }
|
|
|
++
|
|
|
++ /* Convert the mantissa from BCD to binary */
|
|
|
++ for (i=60;i>=0;i-=4) {
|
|
|
++ /* Multiply by 10 using x*10=(x<<3)+(x<<1) */
|
|
|
++ high = (high<<3) + (low>>(HOST_BITS_PER_WIDE_INT-3)) /* (x<<3) */
|
|
|
++ + (high<<1) + (low>>(HOST_BITS_PER_WIDE_INT-1)) /* (x<<1) */
|
|
|
++ + ((low<<3) + (low<<1) < (low<<1)); /* (carry) */
|
|
|
++ low = (low<<3) + (low<<1);
|
|
|
++ low += (mantissa>>i)&15;
|
|
|
++ }
|
|
|
++
|
|
|
++ /* Multiply by 10^e */
|
|
|
++ for (i=0;i<e;i++) {
|
|
|
++ /* Multiply by 10 using x*10=(x<<3)+(x<<1) */
|
|
|
++ high = (high<<3) + (low>>(HOST_BITS_PER_WIDE_INT-3)) /* (x<<3) */
|
|
|
++ + (high<<1) + (low>>(HOST_BITS_PER_WIDE_INT-1)) /* (x<<1) */
|
|
|
++ + ((low<<3) + (low<<1) < (low<<1)); /* (carry) */
|
|
|
++ low = (low<<3) + (low<<1);
|
|
|
++ }
|
|
|
++
|
|
|
++ /* Negate the result if *r was negative */
|
|
|
++ if (r->exponent >= 0x8000) {
|
|
|
++ if (low == 0)
|
|
|
++ high = -high;
|
|
|
++ else
|
|
|
++ low = -low, high = ~high;
|
|
|
++ }
|
|
|
++
|
|
|
++#if 0
|
|
|
+ REAL_VALUE_TYPE t;
|
|
|
+ HOST_WIDE_INT low, high;
|
|
|
+ int exp;
|
|
|
+@@ -1370,11 +2080,13 @@
|
|
|
+ default:
|
|
|
+ gcc_unreachable ();
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ *plow = low;
|
|
|
+ *phigh = high;
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* A subroutine of real_to_decimal. Compute the quotient and remainder
|
|
|
+ of NUM / DEN. Return the quotient and place the remainder in NUM.
|
|
|
+ It is expected that NUM / DEN are close enough that the quotient is
|
|
|
+@@ -1749,6 +2461,327 @@
|
|
|
+
|
|
|
+ sprintf (p, "p%+d", exp);
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
++
|
|
|
++static void real_value_dtof (REAL_VALUE_TYPE *r, const char *string)
|
|
|
++{
|
|
|
++ const char *strpart = string;
|
|
|
++ unsigned char state = 0;
|
|
|
++ unsigned long long mpmul = 0x1000000000000000;
|
|
|
++ signed short expshift = -1;
|
|
|
++ unsigned short exp = 0;
|
|
|
++ unsigned short expmul = 1;
|
|
|
++ unsigned short expadd = 0;
|
|
|
++ int endrounding = -1;
|
|
|
++ r->mantissa = 0;
|
|
|
++ while (strpart && *strpart)
|
|
|
++ {
|
|
|
++ switch (state)
|
|
|
++ {
|
|
|
++ case 0:
|
|
|
++ if (*strpart == '.')
|
|
|
++ {
|
|
|
++ state = 1;
|
|
|
++ break;
|
|
|
++ }
|
|
|
++ else if (*strpart == '+')
|
|
|
++ expadd = 0;
|
|
|
++ else if (*strpart == '-')
|
|
|
++ expadd = 0x8000;
|
|
|
++ else if (((*strpart) >= '0' && (*strpart) <= '9') && ((r->mantissa) || (*strpart != '0')))
|
|
|
++ expshift++;
|
|
|
++ else if ((*strpart == 'i') || (*strpart == 'I'))
|
|
|
++ {
|
|
|
++ if (expadd == 0x8000)
|
|
|
++ *r = NEGATIVE_INF;
|
|
|
++ else
|
|
|
++ *r = POSITIVE_INF;
|
|
|
++ expadd = 0x3FFF;
|
|
|
++ strpart = 0;
|
|
|
++ }
|
|
|
++ else if ((*strpart == 'n') || (*strpart == 'N'))
|
|
|
++ {
|
|
|
++ *r = NAN;
|
|
|
++ expadd = 0x3FFF;
|
|
|
++ strpart = 0;
|
|
|
++ }
|
|
|
++ case 1:
|
|
|
++ if ((*strpart == 'e') || (*strpart == 'E'))
|
|
|
++ state = 2;
|
|
|
++ else if ((*strpart) >= '0' && (*strpart) <= '9')
|
|
|
++ {
|
|
|
++ if (mpmul)
|
|
|
++ r->mantissa |= (*strpart - '0') * mpmul;
|
|
|
++ else if (endrounding < 0)
|
|
|
++ endrounding = (*strpart >= '5');
|
|
|
++ if (r->mantissa)
|
|
|
++ mpmul /= 0x10;
|
|
|
++ else if (state)
|
|
|
++ expshift--;
|
|
|
++ }
|
|
|
++ break;
|
|
|
++ case 2:
|
|
|
++ if (*strpart == '+')
|
|
|
++ expmul = 1;
|
|
|
++ else if (*strpart == '-')
|
|
|
++ expmul = -1;
|
|
|
++ if ((*strpart) >= '0' && (*strpart) <= '9')
|
|
|
++ {
|
|
|
++ exp *= 10;
|
|
|
++ exp += (*strpart - '0');
|
|
|
++ }
|
|
|
++ break;
|
|
|
++ }
|
|
|
++ if (strpart)
|
|
|
++ strpart++;
|
|
|
++ else
|
|
|
++ break;
|
|
|
++ }
|
|
|
++ if (!(r->mantissa))
|
|
|
++ *r = ZERO;
|
|
|
++ else if (expadd != 0x3FFF)
|
|
|
++ {
|
|
|
++ r->exponent = exp * expmul + 0x4000 + expshift;
|
|
|
++ if (r->exponent>0x4000+16383) /* exponent too large, overflow to +infinity */
|
|
|
++ *r = POSITIVE_INF;
|
|
|
++ else if (r->exponent<0x4000-16383) /* exponent too small, underflow to +0 */
|
|
|
++ *r = POSITIVE_ZERO;
|
|
|
++ else if (endrounding > 0)
|
|
|
++ bcdpadd1ulp (r);
|
|
|
++ r->exponent += expadd;
|
|
|
++ }
|
|
|
++}
|
|
|
++
|
|
|
++typedef struct {
|
|
|
++ int ndigits;
|
|
|
++ unsigned char *digits;
|
|
|
++ long effexp;
|
|
|
++} arbprec_decimal;
|
|
|
++
|
|
|
++static void arbprec_pack (arbprec_decimal *r)
|
|
|
++{
|
|
|
++ unsigned char *p = r->digits;
|
|
|
++ if (r->ndigits) {
|
|
|
++ while (p < r->digits + r->ndigits && !*p) p++;
|
|
|
++ r->ndigits -= p - r->digits;
|
|
|
++ memmove (r->digits, p, r->ndigits);
|
|
|
++ if (r->ndigits) {
|
|
|
++ p = r->digits + r->ndigits - 1;
|
|
|
++ while (p > r->digits && !*p) {
|
|
|
++ p--;
|
|
|
++ r->effexp++;
|
|
|
++ }
|
|
|
++ r->ndigits = (p + 1) - r->digits;
|
|
|
++ }
|
|
|
++ r->digits = xrealloc (r->digits, r->ndigits);
|
|
|
++ }
|
|
|
++}
|
|
|
++
|
|
|
++static void arbprec_mul2 (arbprec_decimal *r)
|
|
|
++{
|
|
|
++ unsigned char *p;
|
|
|
++ unsigned char carry = 0;
|
|
|
++ r->ndigits++;
|
|
|
++ r->digits = xrealloc (r->digits, r->ndigits);
|
|
|
++ for (p = r->digits + r->ndigits - 1; p > r->digits; p--) {
|
|
|
++ unsigned char digit = (p[-1]<<1) + carry;
|
|
|
++ *p = digit % 10;
|
|
|
++ carry = digit / 10;
|
|
|
++ }
|
|
|
++ *p = carry;
|
|
|
++ arbprec_pack (r);
|
|
|
++}
|
|
|
++
|
|
|
++static void arbprec_div2 (arbprec_decimal *r)
|
|
|
++{
|
|
|
++ unsigned char *p;
|
|
|
++ unsigned char carry = 0;
|
|
|
++ r->ndigits++;
|
|
|
++ r->digits = xrealloc (r->digits, r->ndigits);
|
|
|
++ for (p = r->digits; p < r->digits + r->ndigits - 1; p++) {
|
|
|
++ unsigned char digit = (*p>>1) + carry;
|
|
|
++ carry = (*p&1)*5;
|
|
|
++ *p = digit;
|
|
|
++ }
|
|
|
++ *p = carry;
|
|
|
++ r->effexp--;
|
|
|
++ arbprec_pack (r);
|
|
|
++}
|
|
|
++
|
|
|
++static void arbprec_mul16 (arbprec_decimal *r)
|
|
|
++{
|
|
|
++ arbprec_mul2 (r);
|
|
|
++ arbprec_mul2 (r);
|
|
|
++ arbprec_mul2 (r);
|
|
|
++ arbprec_mul2 (r);
|
|
|
++}
|
|
|
++
|
|
|
++static void arbprec_div16 (arbprec_decimal *r)
|
|
|
++{
|
|
|
++ arbprec_div2 (r);
|
|
|
++ arbprec_div2 (r);
|
|
|
++ arbprec_div2 (r);
|
|
|
++ arbprec_div2 (r);
|
|
|
++}
|
|
|
++
|
|
|
++static void arbprec_add (arbprec_decimal *r1, arbprec_decimal *r2)
|
|
|
++{
|
|
|
++ if (!r2->ndigits)
|
|
|
++ return;
|
|
|
++ else if (!r1->ndigits) {
|
|
|
++ r1->digits = xrealloc (r1->digits, r2->ndigits);
|
|
|
++ memcpy (r1->digits, r2->digits, r2->ndigits);
|
|
|
++ r1->ndigits = r2->ndigits;
|
|
|
++ r1->effexp = r2->effexp;
|
|
|
++ } else {
|
|
|
++ if (r1->effexp > r2->effexp) {
|
|
|
++ long effexpdiff = r1->effexp - r2->effexp;
|
|
|
++ r1->digits = xrealloc (r1->digits, r1->ndigits + effexpdiff);
|
|
|
++ memset (r1->digits + r1->ndigits, 0, effexpdiff);
|
|
|
++ r1->ndigits += effexpdiff;
|
|
|
++ r1->effexp = r2->effexp;
|
|
|
++ } else if (r2->effexp > r1->effexp) {
|
|
|
++ long effexpdiff = r2->effexp - r1->effexp;
|
|
|
++ r2->digits = xrealloc (r2->digits, r2->ndigits + effexpdiff);
|
|
|
++ memset (r2->digits + r2->ndigits, 0, effexpdiff);
|
|
|
++ r2->ndigits += effexpdiff;
|
|
|
++ r2->effexp = r1->effexp;
|
|
|
++ }
|
|
|
++
|
|
|
++ {
|
|
|
++ int ndigits = MAX (r1->ndigits, r2->ndigits) + 1;
|
|
|
++ unsigned char *digits = xmalloc (ndigits);
|
|
|
++ unsigned char *p, *q1, *q2;
|
|
|
++ unsigned char carry = 0;
|
|
|
++ for (p = digits + ndigits - 1, q1 = r1->digits + r1->ndigits - 1,
|
|
|
++ q2 = r2->digits + r2->ndigits - 1; p > digits; p--, q1--, q2--) {
|
|
|
++ unsigned char digit = (q1>=r1->digits?*q1:0) + (q2>=r2->digits?*q2:0)
|
|
|
++ + carry;
|
|
|
++ *p = digit % 10;
|
|
|
++ carry = digit / 10;
|
|
|
++ }
|
|
|
++ *p = carry;
|
|
|
++ free (r1->digits);
|
|
|
++ r1->digits = digits;
|
|
|
++ r1->ndigits = ndigits;
|
|
|
++ arbprec_pack (r1);
|
|
|
++ arbprec_pack (r2);
|
|
|
++ }
|
|
|
++ }
|
|
|
++}
|
|
|
++
|
|
|
++static void arbprec_add_n_times (arbprec_decimal *r1, arbprec_decimal *r2, int n)
|
|
|
++{
|
|
|
++ int i;
|
|
|
++ for (i = 0; i < n; i++) arbprec_add (r1, r2);
|
|
|
++}
|
|
|
++
|
|
|
++static void arbprec_to_bcd (arbprec_decimal *a, smap_bcd_float *r)
|
|
|
++{
|
|
|
++ if (a->ndigits) {
|
|
|
++ long exponent = a->effexp + a->ndigits - 1;
|
|
|
++ if (exponent>16383) /* exponent too large, overflow to +infinity */
|
|
|
++ *r = POSITIVE_INF;
|
|
|
++ else if (exponent<-16383) /* exponent too small, underflow to +0 */
|
|
|
++ *r = POSITIVE_ZERO;
|
|
|
++ else {
|
|
|
++ int i;
|
|
|
++ r->exponent = 0x4000 + exponent;
|
|
|
++ r->mantissa = 0;
|
|
|
++ for (i = 0; i < a->ndigits && i < 16; i++) {
|
|
|
++ r->mantissa = (r->mantissa << 4) + a->digits[i];
|
|
|
++ }
|
|
|
++ for (; i < 16; i++) {
|
|
|
++ r->mantissa <<= 4;
|
|
|
++ }
|
|
|
++ if (a->ndigits > 16 && a->digits[16] >= 5)
|
|
|
++ bcdpadd1ulp (r);
|
|
|
++ }
|
|
|
++ } else {
|
|
|
++ *r = UNSIGNED_ZERO;
|
|
|
++ }
|
|
|
++}
|
|
|
++
|
|
|
++static void real_value_htof (REAL_VALUE_TYPE *res, const char *string)
|
|
|
++{
|
|
|
++ arbprec_decimal r = {0, NULL, 0};
|
|
|
++ const char *strpart = string;
|
|
|
++ signed char state = -1;
|
|
|
++ arbprec_decimal rdiv = {1, NULL, 0};
|
|
|
++ unsigned int negative = 0;
|
|
|
++ unsigned short exp = 0;
|
|
|
++ unsigned short expsign = 1;
|
|
|
++ unsigned long exp2 = 1;
|
|
|
++ rdiv.digits = xmalloc (1);
|
|
|
++ *(rdiv.digits) = 1;
|
|
|
++ while (strpart && *strpart)
|
|
|
++ {
|
|
|
++ switch (state)
|
|
|
++ {
|
|
|
++ case -1:
|
|
|
++ if (*strpart == 'x' || *strpart == 'X')
|
|
|
++ state = 0;
|
|
|
++ else if (*strpart == '+')
|
|
|
++ negative = 0;
|
|
|
++ else if (*strpart == '-')
|
|
|
++ negative = 1;
|
|
|
++ break;
|
|
|
++ case 0:
|
|
|
++ if (*strpart == '.')
|
|
|
++ {
|
|
|
++ state = 1;
|
|
|
++ break;
|
|
|
++ }
|
|
|
++ else if ((*strpart >= '0' && *strpart <= '9') || (*strpart >= 'a' && *strpart <= 'f') || (*strpart >= 'A' && *strpart <= 'F'))
|
|
|
++ arbprec_mul16 (&r);
|
|
|
++ case 1:
|
|
|
++ if (state == 1)
|
|
|
++ arbprec_div16 (&rdiv);
|
|
|
++ if ((*strpart == 'p') || (*strpart == 'P'))
|
|
|
++ state = 2;
|
|
|
++ else if (*strpart >= '0' && *strpart <= '9')
|
|
|
++ arbprec_add_n_times (&r, &rdiv, (*strpart - '0'));
|
|
|
++ else if (*strpart >= 'a' && *strpart <= 'f')
|
|
|
++ arbprec_add_n_times (&r, &rdiv, (*strpart - 'a' + 0xA));
|
|
|
++ else if (*strpart >= 'A' && *strpart <= 'F')
|
|
|
++ arbprec_add_n_times (&r, &rdiv, (*strpart - 'A' + 0xA));
|
|
|
++ break;
|
|
|
++ case 2:
|
|
|
++ if (*strpart == '+')
|
|
|
++ expsign = 1;
|
|
|
++ else if (*strpart == '-')
|
|
|
++ expsign = -1;
|
|
|
++ if ((*strpart) >= '0' && (*strpart) <= '9')
|
|
|
++ {
|
|
|
++ exp *= 10;
|
|
|
++ exp += (*strpart - '0');
|
|
|
++ }
|
|
|
++ break;
|
|
|
++ }
|
|
|
++ strpart++;
|
|
|
++ }
|
|
|
++ free (rdiv.digits);
|
|
|
++ if (expsign == 1)
|
|
|
++ {
|
|
|
++ while (exp)
|
|
|
++ {
|
|
|
++ arbprec_mul2 (&r);
|
|
|
++ exp--;
|
|
|
++ }
|
|
|
++ }
|
|
|
++ else
|
|
|
++ {
|
|
|
++ while (exp)
|
|
|
++ {
|
|
|
++ arbprec_div2 (&r);
|
|
|
++ exp--;
|
|
|
++ }
|
|
|
++ }
|
|
|
++ arbprec_to_bcd (&r, res);
|
|
|
++ free (r.digits);
|
|
|
++ if (negative)
|
|
|
++ *res = REAL_VALUE_NEGATE (*res);
|
|
|
++}
|
|
|
+
|
|
|
+ /* Initialize R from a decimal or hexadecimal string. The string is
|
|
|
+ assumed to have been syntax checked already. */
|
|
|
+@@ -1756,6 +2789,17 @@
|
|
|
+ void
|
|
|
+ real_from_string (REAL_VALUE_TYPE *r, const char *str)
|
|
|
+ {
|
|
|
++ const char *p = str;
|
|
|
++
|
|
|
++ if (*p == '-' || *p == '+')
|
|
|
++ p++;
|
|
|
++
|
|
|
++ if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X'))
|
|
|
++ real_value_htof (r, str);
|
|
|
++ else
|
|
|
++ real_value_dtof (r, str);
|
|
|
++
|
|
|
++#if 0
|
|
|
+ int exp = 0;
|
|
|
+ bool sign = false;
|
|
|
+
|
|
|
+@@ -1933,6 +2977,7 @@
|
|
|
+ overflow:
|
|
|
+ get_inf (r, sign);
|
|
|
+ return;
|
|
|
++#endif /* 0 */
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Legacy. Similar, but return the result directly. */
|
|
|
+@@ -1956,6 +3001,67 @@
|
|
|
+ unsigned HOST_WIDE_INT low, HOST_WIDE_INT high,
|
|
|
+ int unsigned_p)
|
|
|
+ {
|
|
|
++ int i, j, e = -1, lastdigit = 0;
|
|
|
++ bool negative = high < 0 && !unsigned_p;
|
|
|
++ unsigned HOST_WIDE_INT uhigh = (unsigned HOST_WIDE_INT)high;
|
|
|
++ unsigned HOST_WIDE_INT ulow = low;
|
|
|
++ unsigned HOST_WIDE_INT remainderh, remainderl, divisorh, divisorl;
|
|
|
++ unsigned long long mantissa = 0;
|
|
|
++
|
|
|
++ if (negative) {
|
|
|
++ uhigh = ~uhigh;
|
|
|
++ if (!ulow) uhigh++; else ulow = -ulow;
|
|
|
++ }
|
|
|
++
|
|
|
++ /* Convert the integer to BCD */
|
|
|
++ while (uhigh || ulow) {
|
|
|
++ remainderh = uhigh; remainderl = ulow;
|
|
|
++ divisorl = uhigh = ulow = 0;
|
|
|
++ divisorh = (HOST_WIDE_INT)10<<(HOST_BITS_PER_WIDE_INT-4);
|
|
|
++ /* Divide the pair of HOST_WIDE_INTs by 10 */
|
|
|
++ for (j=2*HOST_BITS_PER_WIDE_INT-4;j>=0;j--) {
|
|
|
++ /* Shift the result to the left. */
|
|
|
++ uhigh = (uhigh<<1) + (ulow>>(HOST_BITS_PER_WIDE_INT-1));
|
|
|
++ ulow <<= 1;
|
|
|
++ /* Check if the divisor 10 fits into the dividend. */
|
|
|
++ if (divisorh<remainderh || (divisorh==remainderh && divisorl<=remainderl)) {
|
|
|
++ /* Add 1 to the result. */
|
|
|
++ ulow++;
|
|
|
++ if (!ulow) uhigh++; /* handle carry */
|
|
|
++ /* Subtract the divisor from the dividend. */
|
|
|
++ if (remainderl<divisorl) /* handle carry, use unsigned wraparound overflow */
|
|
|
++ remainderh--;
|
|
|
++ remainderl -= divisorl; /* now do the subtraction */
|
|
|
++ remainderh -= divisorh;
|
|
|
++ }
|
|
|
++ if (j) {
|
|
|
++ /* Shift the divisor to the right. */
|
|
|
++ divisorl = ((divisorh&1)<<(HOST_BITS_PER_WIDE_INT-1))+(divisorl>>1);
|
|
|
++ divisorh >>= 1;
|
|
|
++ }
|
|
|
++ }
|
|
|
++ e++;
|
|
|
++ lastdigit = (mantissa&15);
|
|
|
++ mantissa = (mantissa>>4) + ((unsigned long long)remainderl<<60);
|
|
|
++ }
|
|
|
++
|
|
|
++ if (e >= 0) {
|
|
|
++ /* We have a nonnegative exponent. Do the correct rounding for the last
|
|
|
++ digit. */
|
|
|
++
|
|
|
++ r->exponent = e+0x4000;
|
|
|
++ r->mantissa = mantissa;
|
|
|
++
|
|
|
++ if (lastdigit >= 5) bcdpadd1ulp(r);
|
|
|
++ } else {
|
|
|
++ /* We don't have any digit, so our number is actually zero. */
|
|
|
++ *r = UNSIGNED_ZERO;
|
|
|
++ }
|
|
|
++
|
|
|
++ /* Negate *r if the integer was negative */
|
|
|
++ if (negative) *r = REAL_VALUE_NEGATE (*r);
|
|
|
++
|
|
|
++#if 0
|
|
|
+ if (low == 0 && high == 0)
|
|
|
+ get_zero (r, 0);
|
|
|
+ else
|
|
|
+@@ -1993,8 +3099,10 @@
|
|
|
+
|
|
|
+ if (mode != VOIDmode)
|
|
|
+ real_convert (r, mode, r);
|
|
|
++#endif /* 0 */
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Returns 10**2**N. */
|
|
|
+
|
|
|
+ static const REAL_VALUE_TYPE *
|
|
|
+@@ -2471,6 +3579,7 @@
|
|
|
+
|
|
|
+ return fmt->p * fmt->log2_b;
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Return a hash value for the given real value. */
|
|
|
+ /* ??? The "unsigned int" return value is intended to be hashval_t,
|
|
|
+@@ -2479,6 +3588,12 @@
|
|
|
+ unsigned int
|
|
|
+ real_hash (const REAL_VALUE_TYPE *r)
|
|
|
+ {
|
|
|
++ /* (TIGCC) Very naive hash for lack of something better. -- Kevin Kofler */
|
|
|
++ unsigned int h=r->exponent;
|
|
|
++ return h+(unsigned int)(r->mantissa >>
|
|
|
++ ((sizeof(unsigned long long)-sizeof(unsigned int))*8));
|
|
|
++
|
|
|
++#if 0
|
|
|
+ unsigned int h;
|
|
|
+ size_t i;
|
|
|
+
|
|
|
+@@ -2515,8 +3630,10 @@
|
|
|
+ h ^= r->sig[i];
|
|
|
+
|
|
|
+ return h;
|
|
|
++#endif /* 0 */
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* IEEE single-precision format. */
|
|
|
+
|
|
|
+ static void encode_ieee_single (const struct real_format *fmt,
|
|
|
+@@ -4666,4 +5783,5 @@
|
|
|
+ {
|
|
|
+ r->sign = x->sign;
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/real.h gcc-4.0-20050319-src/gcc/real.h
|
|
|
+--- gcc-4.0-20050319.orig/gcc/real.h Thu Feb 3 07:44:34 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/real.h Wed Mar 23 01:21:04 2005
|
|
|
+@@ -22,6 +22,22 @@
|
|
|
+ #ifndef GCC_REAL_H
|
|
|
+ #define GCC_REAL_H
|
|
|
+
|
|
|
++/* (TIGCC) smapbcd.h need this, but gengtype needs it to be in this file. */
|
|
|
++/* (TIGCC) Hack to make gengtype shut up while still packing the structure. */
|
|
|
++#define exponent exponent __attribute__((packed))
|
|
|
++#define mantissa mantissa __attribute__((packed))
|
|
|
++__attribute__ ((packed))
|
|
|
++struct real_value GTY(())
|
|
|
++{
|
|
|
++ unsigned short exponent;
|
|
|
++ unsigned long long mantissa;
|
|
|
++};
|
|
|
++#undef exponent
|
|
|
++#undef mantissa
|
|
|
++
|
|
|
++#include <config/smapbcd.h>
|
|
|
++#define SMAP_BCD_FLOAT_FORMAT 5
|
|
|
++
|
|
|
+ #include "machmode.h"
|
|
|
+
|
|
|
+ /* An expanded form of the represented number. */
|
|
|
+@@ -40,19 +56,22 @@
|
|
|
+ #define SIGSZ (SIGNIFICAND_BITS / HOST_BITS_PER_LONG)
|
|
|
+ #define SIG_MSB ((unsigned long)1 << (HOST_BITS_PER_LONG - 1))
|
|
|
+
|
|
|
++/*
|
|
|
+ struct real_value GTY(())
|
|
|
+ {
|
|
|
+- /* Use the same underlying type for all bit-fields, so as to make
|
|
|
++ ** Use the same underlying type for all bit-fields, so as to make
|
|
|
+ sure they're packed together, otherwise REAL_VALUE_TYPE_SIZE will
|
|
|
+- be miscomputed. */
|
|
|
+- unsigned int /* ENUM_BITFIELD (real_value_class) */ cl : 2;
|
|
|
++ be miscomputed. **
|
|
|
++ unsigned int ** ENUM_BITFIELD (real_value_class) ** cl : 2;
|
|
|
+ unsigned int sign : 1;
|
|
|
+ unsigned int signalling : 1;
|
|
|
+ unsigned int canonical : 1;
|
|
|
+ unsigned int uexp : EXP_BITS;
|
|
|
+ unsigned long sig[SIGSZ];
|
|
|
+ };
|
|
|
+-
|
|
|
++*/
|
|
|
++
|
|
|
++#if 0
|
|
|
+ #define REAL_EXP(REAL) \
|
|
|
+ ((int)((REAL)->uexp ^ (unsigned int)(1 << (EXP_BITS - 1))) \
|
|
|
+ - (1 << (EXP_BITS - 1)))
|
|
|
+@@ -76,6 +95,9 @@
|
|
|
+ /* Verify the guess. */
|
|
|
+ extern char test_real_width
|
|
|
+ [sizeof(REAL_VALUE_TYPE) <= REAL_WIDTH*sizeof(HOST_WIDE_INT) ? 1 : -1];
|
|
|
++#endif /* 0 */
|
|
|
++
|
|
|
++#define REAL_WIDTH (11*8 + HOST_BITS_PER_WIDE_INT)/HOST_BITS_PER_WIDE_INT
|
|
|
+
|
|
|
+ /* Calculate the format for CONST_DOUBLE. We need as many slots as
|
|
|
+ are necessary to overlay a REAL_VALUE_TYPE on them. This could be
|
|
|
+@@ -111,6 +133,7 @@
|
|
|
+ #endif
|
|
|
+
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Describes the properties of the specific target format in use. */
|
|
|
+ struct real_format
|
|
|
+ {
|
|
|
+@@ -162,6 +185,7 @@
|
|
|
+ case compile-time FP overflow may not model run-time overflow. */
|
|
|
+ #define REAL_MODE_FORMAT_COMPOSITE_P(MODE) \
|
|
|
+ ((REAL_MODE_FORMAT(MODE))->pnan < (REAL_MODE_FORMAT (MODE))->p)
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Declare functions in real.c. */
|
|
|
+
|
|
|
+@@ -172,6 +196,7 @@
|
|
|
+ /* Compare reals by tree_code. */
|
|
|
+ extern bool real_compare (int, const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Determine whether a floating-point value X is infinite. */
|
|
|
+ extern bool real_isinf (const REAL_VALUE_TYPE *);
|
|
|
+
|
|
|
+@@ -204,6 +229,7 @@
|
|
|
+
|
|
|
+ /* Render R as an integer. */
|
|
|
+ extern HOST_WIDE_INT real_to_integer (const REAL_VALUE_TYPE *);
|
|
|
++#endif /* 0 */
|
|
|
+ extern void real_to_integer2 (HOST_WIDE_INT *, HOST_WIDE_INT *,
|
|
|
+ const REAL_VALUE_TYPE *);
|
|
|
+
|
|
|
+@@ -214,6 +240,7 @@
|
|
|
+ extern void real_from_integer (REAL_VALUE_TYPE *, enum machine_mode,
|
|
|
+ unsigned HOST_WIDE_INT, HOST_WIDE_INT, int);
|
|
|
+
|
|
|
++#if 0
|
|
|
+ extern long real_to_target_fmt (long *, const REAL_VALUE_TYPE *,
|
|
|
+ const struct real_format *);
|
|
|
+ extern long real_to_target (long *, const REAL_VALUE_TYPE *, enum machine_mode);
|
|
|
+@@ -230,10 +257,12 @@
|
|
|
+ extern void real_maxval (REAL_VALUE_TYPE *, int, enum machine_mode);
|
|
|
+
|
|
|
+ extern void real_2expN (REAL_VALUE_TYPE *, int);
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ extern unsigned int real_hash (const REAL_VALUE_TYPE *);
|
|
|
+
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Target formats defined in real.c. */
|
|
|
+ extern const struct real_format ieee_single_format;
|
|
|
+ extern const struct real_format mips_single_format;
|
|
|
+@@ -313,9 +342,11 @@
|
|
|
+ real_arithmetic2 (ABS_EXPR, &(X), NULL)
|
|
|
+
|
|
|
+ extern int significand_size (enum machine_mode);
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ extern REAL_VALUE_TYPE real_from_string2 (const char *, enum machine_mode);
|
|
|
+
|
|
|
++#if 0
|
|
|
+ #define REAL_VALUE_ATOF(s, m) \
|
|
|
+ real_from_string2 (s, m)
|
|
|
+
|
|
|
+@@ -338,6 +369,7 @@
|
|
|
+ extern void real_ldexp (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, int);
|
|
|
+
|
|
|
+ /* **** End of software floating point emulator interface macros **** */
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Constant real values 0, 1, 2, 3, 10, -1, -2, 0.5 and 1/3. */
|
|
|
+
|
|
|
+@@ -350,8 +382,10 @@
|
|
|
+ extern REAL_VALUE_TYPE dconstm2;
|
|
|
+ extern REAL_VALUE_TYPE dconsthalf;
|
|
|
+ extern REAL_VALUE_TYPE dconstthird;
|
|
|
++#if 0
|
|
|
+ extern REAL_VALUE_TYPE dconstpi;
|
|
|
+ extern REAL_VALUE_TYPE dconste;
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Function to return a real value (not a tree node)
|
|
|
+ from a given integer constant. */
|
|
|
+@@ -372,6 +406,7 @@
|
|
|
+ /* In tree.c: wrap up a REAL_VALUE_TYPE in a tree node. */
|
|
|
+ extern tree build_real (tree, REAL_VALUE_TYPE);
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Calculate R as the square root of X in the given machine mode. */
|
|
|
+ extern bool real_sqrt (REAL_VALUE_TYPE *, enum machine_mode,
|
|
|
+ const REAL_VALUE_TYPE *);
|
|
|
+@@ -392,5 +427,6 @@
|
|
|
+
|
|
|
+ /* Set the sign of R to the sign of X. */
|
|
|
+ extern void real_copysign (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ #endif /* ! GCC_REAL_H */
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/sdbout.c gcc-4.0-20050319-src/gcc/sdbout.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/sdbout.c Thu Nov 4 14:23:18 2004
|
|
|
++++ gcc-4.0-20050319-src/gcc/sdbout.c Wed Mar 23 01:21:04 2005
|
|
|
+@@ -1539,9 +1539,7 @@
|
|
|
+ #ifdef SDB_OUTPUT_SOURCE_LINE
|
|
|
+ SDB_OUTPUT_SOURCE_LINE (asm_out_file, line);
|
|
|
+ #else
|
|
|
+- fprintf (asm_out_file, "\t.ln\t%d\n",
|
|
|
+- ((sdb_begin_function_line > -1)
|
|
|
+- ? line - sdb_begin_function_line : 1));
|
|
|
++ fprintf (asm_out_file, "\t.ln\t%d\n", line);
|
|
|
+ #endif
|
|
|
+ }
|
|
|
+ }
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/simplify-rtx.c gcc-4.0-20050319-src/gcc/simplify-rtx.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/simplify-rtx.c Thu Mar 10 23:21:58 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/simplify-rtx.c Wed Mar 23 01:21:04 2005
|
|
|
+@@ -436,7 +436,7 @@
|
|
|
+ lv = CONST_DOUBLE_LOW (trueop), hv = CONST_DOUBLE_HIGH (trueop);
|
|
|
+
|
|
|
+ REAL_VALUE_FROM_INT (d, lv, hv, mode);
|
|
|
+- d = real_value_truncate (mode, d);
|
|
|
++ d = REAL_VALUE_TRUNCATE (mode, d);
|
|
|
+ return CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
|
|
|
+ }
|
|
|
+ else if (code == UNSIGNED_FLOAT && GET_MODE (trueop) == VOIDmode
|
|
|
+@@ -464,7 +464,7 @@
|
|
|
+ hv = 0, lv &= GET_MODE_MASK (op_mode);
|
|
|
+
|
|
|
+ REAL_VALUE_FROM_UNSIGNED_INT (d, lv, hv, mode);
|
|
|
+- d = real_value_truncate (mode, d);
|
|
|
++ d = REAL_VALUE_TRUNCATE (mode, d);
|
|
|
+ return CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
|
|
|
+ }
|
|
|
+
|
|
|
+@@ -728,11 +728,7 @@
|
|
|
+ switch (code)
|
|
|
+ {
|
|
|
+ case SQRT:
|
|
|
+- if (HONOR_SNANS (mode) && real_isnan (&d))
|
|
|
+- return 0;
|
|
|
+- real_sqrt (&t, mode, &d);
|
|
|
+- d = t;
|
|
|
+- break;
|
|
|
++ return 0;
|
|
|
+ case ABS:
|
|
|
+ d = REAL_VALUE_ABS (d);
|
|
|
+ break;
|
|
|
+@@ -740,7 +736,7 @@
|
|
|
+ d = REAL_VALUE_NEGATE (d);
|
|
|
+ break;
|
|
|
+ case FLOAT_TRUNCATE:
|
|
|
+- d = real_value_truncate (mode, d);
|
|
|
++ d = REAL_VALUE_TRUNCATE (mode, d);
|
|
|
+ break;
|
|
|
+ case FLOAT_EXTEND:
|
|
|
+ /* All this does is change the mode. */
|
|
|
+@@ -750,6 +746,7 @@
|
|
|
+ break;
|
|
|
+ case NOT:
|
|
|
+ {
|
|
|
++#if 0
|
|
|
+ long tmp[4];
|
|
|
+ int i;
|
|
|
+
|
|
|
+@@ -757,6 +754,11 @@
|
|
|
+ for (i = 0; i < 4; i++)
|
|
|
+ tmp[i] = ~tmp[i];
|
|
|
+ real_from_target (&d, tmp, mode);
|
|
|
++#else
|
|
|
++ /* (TIGCC 20050205) Use SMAP BCD representation directly. */
|
|
|
++ d.exponent = ~d.exponent;
|
|
|
++ d.mantissa = ~d.mantissa;
|
|
|
++#endif /* 0 */
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+@@ -781,7 +783,7 @@
|
|
|
+ switch (code)
|
|
|
+ {
|
|
|
+ case FIX:
|
|
|
+- if (REAL_VALUE_ISNAN (x))
|
|
|
++ if (REAL_VALUE_ISNANUINF (x))
|
|
|
+ return const0_rtx;
|
|
|
+
|
|
|
+ /* Test against the signed upper bound. */
|
|
|
+@@ -826,7 +828,7 @@
|
|
|
+ break;
|
|
|
+
|
|
|
+ case UNSIGNED_FIX:
|
|
|
+- if (REAL_VALUE_ISNAN (x) || REAL_VALUE_NEGATIVE (x))
|
|
|
++ if (REAL_VALUE_ISNANUINF (x) || REAL_VALUE_NEGATIVE (x))
|
|
|
+ return const0_rtx;
|
|
|
+
|
|
|
+ /* Test against the unsigned upper bound. */
|
|
|
+@@ -968,14 +970,15 @@
|
|
|
+ both +0, (minus Y X) is the same as (minus X Y). If the
|
|
|
+ rounding mode is towards +infinity (or -infinity) then the two
|
|
|
+ expressions will be rounded differently. */
|
|
|
++ /* (TIGCC 20050210) This identity is valid for us thanks to unsigned 0. */
|
|
|
+ if (GET_CODE (op) == MINUS
|
|
|
+- && !HONOR_SIGNED_ZEROS (mode)
|
|
|
++ /*&& !HONOR_SIGNED_ZEROS (mode)*/
|
|
|
+ && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
|
|
|
+ return simplify_gen_binary (MINUS, mode, XEXP (op, 1),
|
|
|
+ XEXP (op, 0));
|
|
|
+
|
|
|
+ if (GET_CODE (op) == PLUS
|
|
|
+- && !HONOR_SIGNED_ZEROS (mode)
|
|
|
++ /*&& !HONOR_SIGNED_ZEROS (mode)*/
|
|
|
+ && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
|
|
|
+ {
|
|
|
+ /* (neg (plus A C)) is simplified to (minus -C A). */
|
|
|
+@@ -1258,6 +1261,7 @@
|
|
|
+ || code == IOR
|
|
|
+ || code == XOR)
|
|
|
+ {
|
|
|
++#if 0
|
|
|
+ long tmp0[4];
|
|
|
+ long tmp1[4];
|
|
|
+ REAL_VALUE_TYPE r;
|
|
|
+@@ -1285,6 +1289,30 @@
|
|
|
+ }
|
|
|
+ }
|
|
|
+ real_from_target (&r, tmp0, mode);
|
|
|
++#else
|
|
|
++ /* (TIGCC 20050205) Use SMAP BCD representation directly. */
|
|
|
++ REAL_VALUE_TYPE *tmp1, r;
|
|
|
++
|
|
|
++ r = *CONST_DOUBLE_REAL_VALUE (op0);
|
|
|
++ tmp1 = CONST_DOUBLE_REAL_VALUE (op1);
|
|
|
++ switch (code)
|
|
|
++ {
|
|
|
++ case AND:
|
|
|
++ r.exponent &= tmp1->exponent;
|
|
|
++ r.mantissa &= tmp1->mantissa;
|
|
|
++ break;
|
|
|
++ case IOR:
|
|
|
++ r.exponent |= tmp1->exponent;
|
|
|
++ r.mantissa |= tmp1->mantissa;
|
|
|
++ break;
|
|
|
++ case XOR:
|
|
|
++ r.exponent ^= tmp1->exponent;
|
|
|
++ r.mantissa ^= tmp1->mantissa;
|
|
|
++ break;
|
|
|
++ default:
|
|
|
++ gcc_unreachable ();
|
|
|
++ }
|
|
|
++#endif /* 0 */
|
|
|
+ return CONST_DOUBLE_FROM_REAL_VALUE (r, mode);
|
|
|
+ }
|
|
|
+ else
|
|
|
+@@ -1353,7 +1381,7 @@
|
|
|
+ if ((flag_rounding_math
|
|
|
+ || (REAL_MODE_FORMAT_COMPOSITE_P (mode)
|
|
|
+ && !flag_unsafe_math_optimizations))
|
|
|
+- && (inexact || !real_identical (&result, &value)))
|
|
|
++ && (inexact || !REAL_VALUES_IDENTICAL (result, value)))
|
|
|
+ return NULL_RTX;
|
|
|
+
|
|
|
+ return CONST_DOUBLE_FROM_REAL_VALUE (result, mode);
|
|
|
+@@ -1688,8 +1716,10 @@
|
|
|
+ /* Subtracting 0 has no effect unless the mode has signed zeros
|
|
|
+ and supports rounding towards -infinity. In such a case,
|
|
|
+ 0 - 0 is -0. */
|
|
|
++ /* (TIGCC 20050210) This is invalid independently of the rounding mode
|
|
|
++ for 3-sign-zeros. */
|
|
|
+ if (!(HONOR_SIGNED_ZEROS (mode)
|
|
|
+- && HONOR_SIGN_DEPENDENT_ROUNDING (mode))
|
|
|
++ /*&& HONOR_SIGN_DEPENDENT_ROUNDING (mode)*/)
|
|
|
+ && trueop1 == CONST0_RTX (mode))
|
|
|
+ return op0;
|
|
|
+
|
|
|
+@@ -1804,8 +1834,11 @@
|
|
|
+ x is NaN, since x * 0 is then also NaN. Nor is it valid
|
|
|
+ when the mode has signed zeros, since multiplying a negative
|
|
|
+ number by 0 will give -0, not 0. */
|
|
|
++ /* (TIGCC 20050210) We can do this for UNSIGNED_ZERO even when honoring
|
|
|
++ signed zeros.
|
|
|
++ Note: CONST0_RTX (BFmode) is UNSIGNED_ZERO. */
|
|
|
+ if (!HONOR_NANS (mode)
|
|
|
+- && !HONOR_SIGNED_ZEROS (mode)
|
|
|
++ /*&& !HONOR_SIGNED_ZEROS (mode)*/
|
|
|
+ && trueop1 == CONST0_RTX (mode)
|
|
|
+ && ! side_effects_p (op0))
|
|
|
+ return op1;
|
|
|
+@@ -2983,7 +3016,7 @@
|
|
|
+ REAL_VALUE_FROM_CONST_DOUBLE (d1, trueop1);
|
|
|
+
|
|
|
+ /* Comparisons are unordered iff at least one of the values is NaN. */
|
|
|
+- if (REAL_VALUE_ISNAN (d0) || REAL_VALUE_ISNAN (d1))
|
|
|
++ if (REAL_VALUE_ISNANUINF (d0) || REAL_VALUE_ISNANUINF (d1))
|
|
|
+ switch (code)
|
|
|
+ {
|
|
|
+ case UNEQ:
|
|
|
+@@ -3502,13 +3535,14 @@
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+- long tmp[max_bitsize / 32];
|
|
|
++ REAL_VALUE_TYPE *tmp;
|
|
|
+ int bitsize = GET_MODE_BITSIZE (GET_MODE (el));
|
|
|
+
|
|
|
+ gcc_assert (GET_MODE_CLASS (GET_MODE (el)) == MODE_FLOAT);
|
|
|
+ gcc_assert (bitsize <= elem_bitsize);
|
|
|
+ gcc_assert (bitsize % value_bit == 0);
|
|
|
+
|
|
|
++#if 0
|
|
|
+ real_to_target (tmp, CONST_DOUBLE_REAL_VALUE (el),
|
|
|
+ GET_MODE (el));
|
|
|
+
|
|
|
+@@ -3530,6 +3564,14 @@
|
|
|
+ zero. */
|
|
|
+ for (; i < elem_bitsize; i += value_bit)
|
|
|
+ *vp++ = 0;
|
|
|
++#else
|
|
|
++ /* (TIGCC 20050205) Use SMAP BCD representation directly. */
|
|
|
++ tmp = CONST_DOUBLE_REAL_VALUE (el);
|
|
|
++ *vp++ = tmp->exponent >> 8;
|
|
|
++ *vp++ = tmp->exponent;
|
|
|
++ for (i = 56; i >= 0; i -= 8)
|
|
|
++ *vp++ = tmp->mantissa >> i;
|
|
|
++#endif /* 0 */
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+@@ -3625,6 +3667,7 @@
|
|
|
+ case MODE_FLOAT:
|
|
|
+ {
|
|
|
+ REAL_VALUE_TYPE r;
|
|
|
++#if 0
|
|
|
+ long tmp[max_bitsize / 32];
|
|
|
+
|
|
|
+ /* real_from_target wants its input in words affected by
|
|
|
+@@ -3644,6 +3687,14 @@
|
|
|
+ }
|
|
|
+
|
|
|
+ real_from_target (&r, tmp, outer_submode);
|
|
|
++#else
|
|
|
++ /* (TIGCC 20050205) Use SMAP BCD representation directly. */
|
|
|
++ r.exponent = (*vp++ << 8);
|
|
|
++ r.exponent += *vp++;
|
|
|
++ r.mantissa = *vp++;
|
|
|
++ for (i = 0; i < 7; i++)
|
|
|
++ r.mantissa = (r.mantissa << 8) + *vp++;
|
|
|
++#endif /* 0 */
|
|
|
+ elems[elem] = CONST_DOUBLE_FROM_REAL_VALUE (r, outer_submode);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/stmt.c gcc-4.0-20050319-src/gcc/stmt.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/stmt.c Thu Mar 10 01:17:58 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/stmt.c Wed Mar 23 01:21:04 2005
|
|
|
+@@ -2491,6 +2491,9 @@
|
|
|
+ use_cost_table
|
|
|
+ = (TREE_CODE (orig_type) != ENUMERAL_TYPE
|
|
|
+ && estimate_case_costs (case_list));
|
|
|
++/* (TIGCC 20030907) Don't balance the tree when optimizing for size. A linear
|
|
|
++ decision tree gives far smaller code. -- Kevin Kofler */
|
|
|
++ if (!optimize_size)
|
|
|
+ balance_case_nodes (&case_list, NULL);
|
|
|
+ emit_case_nodes (index, case_list, default_label, index_type);
|
|
|
+ emit_jump (default_label);
|
|
|
+@@ -3054,10 +3057,17 @@
|
|
|
+ does not have any children and is single valued; it would
|
|
|
+ cost too much space to save so little time. */
|
|
|
+
|
|
|
++ /* (TIGCC 20030907) Also omit the conditional branch to default if we are
|
|
|
++ optimizing for size. -- Kevin Kofler
|
|
|
++ (TIGCC 20040719) But don't omit branches which are needed for
|
|
|
++ correctness in case ranges. -- Kevin Kofler */
|
|
|
++
|
|
|
+ if (node->right->right || node->right->left
|
|
|
+ || !tree_int_cst_equal (node->right->low, node->right->high))
|
|
|
+ {
|
|
|
+- if (!node_has_low_bound (node, index_type))
|
|
|
++ if (!node_has_low_bound (node, index_type)
|
|
|
++ && (!optimize_size
|
|
|
++ || !tree_int_cst_equal (node->right->low, node->right->high)))
|
|
|
+ {
|
|
|
+ emit_cmp_and_jump_insns (index,
|
|
|
+ convert_modes
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/system.h gcc-4.0-20050319-src/gcc/system.h
|
|
|
+--- gcc-4.0-20050319.orig/gcc/system.h Thu Feb 24 00:11:06 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/system.h Wed Mar 23 01:21:06 2005
|
|
|
+@@ -666,7 +666,7 @@
|
|
|
+
|
|
|
+ /* Hooks that are no longer used. */
|
|
|
+ #pragma GCC poison LANG_HOOKS_FUNCTION_MARK LANG_HOOKS_FUNCTION_FREE \
|
|
|
+- LANG_HOOKS_MARK_TREE LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES \
|
|
|
++ LANG_HOOKS_MARK_TREE \
|
|
|
+ LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS \
|
|
|
+ LANG_HOOKS_PUSHLEVEL LANG_HOOKS_SET_BLOCK \
|
|
|
+ LANG_HOOKS_MAYBE_BUILD_CLEANUP LANG_HOOKS_UPDATE_DECL_AFTER_SAVING \
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/toplev.c gcc-4.0-20050319-src/gcc/toplev.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/toplev.c Wed Mar 16 21:36:20 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/toplev.c Wed Mar 23 01:21:06 2005
|
|
|
+@@ -1937,7 +1937,7 @@
|
|
|
+ flag_prefetch_loop_arrays = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+-#ifndef OBJECT_FORMAT_ELF
|
|
|
++#if 0 /*ndef OBJECT_FORMAT_ELF*/ /* (TIGCC 20040619) Remove pointless warning. */
|
|
|
+ if (flag_function_sections && write_symbols != NO_DEBUG)
|
|
|
+ warning ("-ffunction-sections may affect debugging on some targets");
|
|
|
+ #endif
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/tree-inline.c gcc-4.0-20050319-src/gcc/tree-inline.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/tree-inline.c Thu Jan 27 15:36:16 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/tree-inline.c Wed Mar 23 01:21:06 2005
|
|
|
+@@ -1521,6 +1521,48 @@
|
|
|
+ verify_cgraph_node (edge->callee);
|
|
|
+ #endif
|
|
|
+
|
|
|
++ /* (TIGCC 20040926) The following code by Eric Botcazou fixes an ICE when
|
|
|
++ inlining tries to change the mode of parameters or the return value. Eric
|
|
|
++ Botcazou's comments explain the details. -- Kevin Kofler */
|
|
|
++ /* We can't inline functions at a calling point where they are viewed
|
|
|
++ with too different a prototype than the actual one, because the
|
|
|
++ calling convention may not be the same on both sides. */
|
|
|
++ if (TREE_CODE (TREE_OPERAND (t, 0)) == NOP_EXPR)
|
|
|
++ {
|
|
|
++ tree from_ftype = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
|
|
|
++ tree to_ftype = TREE_TYPE (fn);
|
|
|
++
|
|
|
++ if (from_ftype != to_ftype)
|
|
|
++ {
|
|
|
++ tree from_arg, to_arg;
|
|
|
++
|
|
|
++ /* If the calling point expects a return value and it is too
|
|
|
++ different from the one actually returned, don't inline. */
|
|
|
++ if (! VOID_TYPE_P (TREE_TYPE (from_ftype))
|
|
|
++ && TYPE_MODE (TREE_TYPE (from_ftype))
|
|
|
++ != TYPE_MODE (TREE_TYPE (to_ftype)))
|
|
|
++ goto egress;
|
|
|
++
|
|
|
++ /* If the calling point doesn't pass at least the correct
|
|
|
++ number of arguments with the correct modes, don't inline.
|
|
|
++ Objective-C appears to add a trailing void parameter at
|
|
|
++ the calling point under certain circumstances. */
|
|
|
++ from_arg = TYPE_ARG_TYPES (from_ftype);
|
|
|
++ to_arg = TYPE_ARG_TYPES (to_ftype);
|
|
|
++
|
|
|
++ while (to_arg)
|
|
|
++ {
|
|
|
++ if (! from_arg
|
|
|
++ || TYPE_MODE (TREE_VALUE (from_arg))
|
|
|
++ != TYPE_MODE (TREE_VALUE (to_arg)))
|
|
|
++ goto egress;
|
|
|
++
|
|
|
++ from_arg = TREE_CHAIN (from_arg);
|
|
|
++ to_arg = TREE_CHAIN (to_arg);
|
|
|
++ }
|
|
|
++ }
|
|
|
++ }
|
|
|
++
|
|
|
+ if (! lang_hooks.tree_inlining.start_inlining (fn))
|
|
|
+ goto egress;
|
|
|
+
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/tree-pretty-print.c gcc-4.0-20050319-src/gcc/tree-pretty-print.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/tree-pretty-print.c Thu Dec 9 11:54:36 2004
|
|
|
++++ gcc-4.0-20050319-src/gcc/tree-pretty-print.c Wed Mar 23 01:21:06 2005
|
|
|
+@@ -550,7 +550,7 @@
|
|
|
+ else
|
|
|
+ {
|
|
|
+ char string[100];
|
|
|
+- real_to_decimal (string, &d, sizeof (string), 0, 1);
|
|
|
++ REAL_VALUE_TO_STRING (d, string);
|
|
|
+ pp_string (buffer, string);
|
|
|
+ }
|
|
|
+ #else
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/tree-ssa-ccp.c gcc-4.0-20050319-src/gcc/tree-ssa-ccp.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/tree-ssa-ccp.c Thu Feb 24 19:58:04 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/tree-ssa-ccp.c Wed Mar 23 01:21:06 2005
|
|
|
+@@ -1919,6 +1919,7 @@
|
|
|
+ static tree
|
|
|
+ ccp_fold_builtin (tree stmt, tree fn)
|
|
|
+ {
|
|
|
++#if 0 /* (TIGCC 20050205) */
|
|
|
+ tree result, strlen_val[2];
|
|
|
+ tree callee, arglist, a;
|
|
|
+ int strlen_arg, i;
|
|
|
+@@ -2026,6 +2027,9 @@
|
|
|
+ if (result && ignore)
|
|
|
+ result = fold_ignored_result (result);
|
|
|
+ return result;
|
|
|
++#else
|
|
|
++ return NULL_TREE;
|
|
|
++#endif /* 0 */
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/tree-ssa-dom.c gcc-4.0-20050319-src/gcc/tree-ssa-dom.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/tree-ssa-dom.c Thu Feb 24 22:47:26 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/tree-ssa-dom.c Wed Mar 23 01:21:06 2005
|
|
|
+@@ -2966,6 +2966,19 @@
|
|
|
+ || TREE_CODE (stmt) == COND_EXPR
|
|
|
+ || TREE_CODE (stmt) == SWITCH_EXPR));
|
|
|
+
|
|
|
++ /* (TIGCC 20050206) If -fno-function-cse, keep function call sequences in
|
|
|
++ their expected form. */
|
|
|
++ if (flag_no_function_cse && may_optimize_p && TREE_CODE (stmt) == MODIFY_EXPR)
|
|
|
++ {
|
|
|
++ block_stmt_iterator bsi2 = si;
|
|
|
++ bsi_next (&bsi2);
|
|
|
++ if (!bsi_end_p (bsi2))
|
|
|
++ {
|
|
|
++ tree call = get_call_expr_in (bsi_stmt (bsi2));
|
|
|
++ if (call && TREE_OPERAND (stmt, 0) == TREE_OPERAND (call, 0)) may_optimize_p = false;
|
|
|
++ }
|
|
|
++ }
|
|
|
++
|
|
|
+ if (may_optimize_p)
|
|
|
+ may_have_exposed_new_symbols
|
|
|
+ |= eliminate_redundant_computations (walk_data, stmt, ann);
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/tree-ssa-pre.c gcc-4.0-20050319-src/gcc/tree-ssa-pre.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/tree-ssa-pre.c Thu Feb 17 17:19:46 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/tree-ssa-pre.c Wed Mar 23 01:21:06 2005
|
|
|
+@@ -1972,6 +1972,19 @@
|
|
|
+ tree *rhs_p = &TREE_OPERAND (stmt, 1);
|
|
|
+ tree sprime;
|
|
|
+
|
|
|
++ /* (TIGCC 20050216) If -fno-function-cse, keep function call sequences in
|
|
|
++ their expected form. */
|
|
|
++ if (flag_no_function_cse)
|
|
|
++ {
|
|
|
++ block_stmt_iterator bsi2 = i;
|
|
|
++ bsi_next (&bsi2);
|
|
|
++ if (!bsi_end_p (bsi2))
|
|
|
++ {
|
|
|
++ tree call = get_call_expr_in (bsi_stmt (bsi2));
|
|
|
++ if (call && TREE_OPERAND (stmt, 0) == TREE_OPERAND (call, 0)) continue;
|
|
|
++ }
|
|
|
++ }
|
|
|
++
|
|
|
+ sprime = bitmap_find_leader (AVAIL_OUT (b),
|
|
|
+ vn_lookup (lhs, NULL));
|
|
|
+ if (sprime
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/tree.c gcc-4.0-20050319-src/gcc/tree.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/tree.c Wed Mar 16 15:29:02 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/tree.c Wed Mar 23 01:21:06 2005
|
|
|
+@@ -1182,7 +1182,7 @@
|
|
|
+
|
|
|
+ return ((TREE_CODE (expr) == REAL_CST
|
|
|
+ && ! TREE_CONSTANT_OVERFLOW (expr)
|
|
|
+- && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst0))
|
|
|
++ && REAL_VALUE_ISZERO (TREE_REAL_CST (expr)))
|
|
|
+ || (TREE_CODE (expr) == COMPLEX_CST
|
|
|
+ && real_zerop (TREE_REALPART (expr))
|
|
|
+ && real_zerop (TREE_IMAGPART (expr))));
|
|
|
+@@ -6059,17 +6059,14 @@
|
|
|
+ return integer_zerop (init);
|
|
|
+
|
|
|
+ case REAL_CST:
|
|
|
+- /* ??? Note that this is not correct for C4X float formats. There,
|
|
|
+- a bit pattern of all zeros is 1.0; 0.0 is encoded with the most
|
|
|
+- negative exponent. */
|
|
|
+- return real_zerop (init)
|
|
|
+- && ! REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (init));
|
|
|
++ /* (TIGCC 20050210) For AMS, all zeros is POSITIVE_ZERO. This code tried
|
|
|
++ to use it for both POSITIVE_ZERO and UNSIGNED_ZERO. I fixed that. */
|
|
|
++ return REAL_VALUES_IDENTICAL (TREE_REAL_CST (init), POSITIVE_ZERO);
|
|
|
+
|
|
|
+ case COMPLEX_CST:
|
|
|
+ return integer_zerop (init)
|
|
|
+- || (real_zerop (init)
|
|
|
+- && ! REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (TREE_REALPART (init)))
|
|
|
+- && ! REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (TREE_IMAGPART (init))));
|
|
|
++ || (REAL_VALUES_IDENTICAL (TREE_REAL_CST (TREE_REALPART (init)), POSITIVE_ZERO)
|
|
|
++ && REAL_VALUES_IDENTICAL (TREE_REAL_CST (TREE_IMAGPART (init)), POSITIVE_ZERO));
|
|
|
+
|
|
|
+ case VECTOR_CST:
|
|
|
+ for (elt = TREE_VECTOR_CST_ELTS (init); elt; elt = TREE_CHAIN (elt))
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/tree.h gcc-4.0-20050319-src/gcc/tree.h
|
|
|
+--- gcc-4.0-20050319.orig/gcc/tree.h Wed Mar 16 21:36:28 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/tree.h Wed Mar 23 01:21:06 2005
|
|
|
+@@ -3162,6 +3162,7 @@
|
|
|
+ /* Return an expr equal to X but certainly not valid as an lvalue. */
|
|
|
+
|
|
|
+ extern tree non_lvalue (tree);
|
|
|
++extern tree pedantic_non_lvalue (tree);
|
|
|
+
|
|
|
+ extern tree convert (tree, tree);
|
|
|
+ extern unsigned int expr_align (tree);
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/varasm.c gcc-4.0-20050319-src/gcc/varasm.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/varasm.c Fri Mar 18 19:15:02 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/varasm.c Wed Mar 23 01:21:06 2005
|
|
|
+@@ -202,6 +202,46 @@
|
|
|
+ EXTRA_SECTION_FUNCTIONS
|
|
|
+ #endif
|
|
|
+
|
|
|
++/* (TIGCC 20040725) Moved these up. We need those upwards. And besides, they are
|
|
|
++ _declarations_, so what were they doing in the middle of the
|
|
|
++ file??? -- Kevin Kofler */
|
|
|
++enum section_category
|
|
|
++{
|
|
|
++ SECCAT_TEXT,
|
|
|
++
|
|
|
++ SECCAT_RODATA,
|
|
|
++ SECCAT_RODATA_MERGE_STR,
|
|
|
++ SECCAT_RODATA_MERGE_STR_INIT,
|
|
|
++ SECCAT_RODATA_MERGE_CONST,
|
|
|
++ SECCAT_SRODATA,
|
|
|
++
|
|
|
++ SECCAT_DATA,
|
|
|
++
|
|
|
++ /* To optimize loading of shared programs, define following subsections
|
|
|
++ of data section:
|
|
|
++ _REL Contains data that has relocations, so they get grouped
|
|
|
++ together and dynamic linker will visit fewer pages in memory.
|
|
|
++ _RO Contains data that is otherwise read-only. This is useful
|
|
|
++ with prelinking as most relocations won't be dynamically
|
|
|
++ linked and thus stay read only.
|
|
|
++ _LOCAL Marks data containing relocations only to local objects.
|
|
|
++ These relocations will get fully resolved by prelinking. */
|
|
|
++ SECCAT_DATA_REL,
|
|
|
++ SECCAT_DATA_REL_LOCAL,
|
|
|
++ SECCAT_DATA_REL_RO,
|
|
|
++ SECCAT_DATA_REL_RO_LOCAL,
|
|
|
++
|
|
|
++ SECCAT_SDATA,
|
|
|
++ SECCAT_TDATA,
|
|
|
++
|
|
|
++ SECCAT_BSS,
|
|
|
++ SECCAT_SBSS,
|
|
|
++ SECCAT_TBSS
|
|
|
++};
|
|
|
++
|
|
|
++static enum section_category
|
|
|
++categorize_decl_for_section PARAMS ((tree, int, int));
|
|
|
++
|
|
|
+ /* Tell assembler to switch to text section. */
|
|
|
+
|
|
|
+ void
|
|
|
+@@ -660,6 +700,26 @@
|
|
|
+ unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED,
|
|
|
+ unsigned int flags ATTRIBUTE_UNUSED)
|
|
|
+ {
|
|
|
++/* (TIGCC 20040725) Implement string merging for TIGCC-extended COFF.
|
|
|
++ We only handle 2 cases: aligned or unaligned.
|
|
|
++ SECTION_STRINGS is abused for the unaligned flag. */
|
|
|
++ if (flag_merge_constants
|
|
|
++ && TREE_CODE (decl) == STRING_CST
|
|
|
++ && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
|
|
|
++ {
|
|
|
++ if (align == 8)
|
|
|
++ {
|
|
|
++ named_section_flags (".rodata.__unalignedstr", flags | SECTION_MERGE | SECTION_STRINGS);
|
|
|
++ return;
|
|
|
++ }
|
|
|
++ else if (align == 16)
|
|
|
++ {
|
|
|
++ named_section_flags (".rodata.__alignedstr", flags | SECTION_MERGE);
|
|
|
++ return;
|
|
|
++ }
|
|
|
++ }
|
|
|
++
|
|
|
++#if 0
|
|
|
+ if (HAVE_GAS_SHF_MERGE && flag_merge_constants
|
|
|
+ && TREE_CODE (decl) == STRING_CST
|
|
|
+ && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
|
|
|
+@@ -722,6 +782,7 @@
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
++#endif
|
|
|
+
|
|
|
+ readonly_data_section ();
|
|
|
+ }
|
|
|
+@@ -733,6 +794,25 @@
|
|
|
+ unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED,
|
|
|
+ unsigned int flags ATTRIBUTE_UNUSED)
|
|
|
+ {
|
|
|
++/* (TIGCC 20040725) Implement constant merging for TIGCC-extended COFF.
|
|
|
++ We only handle 2 cases: aligned or unaligned.
|
|
|
++ SECTION_STRINGS is abused for the unaligned flag. */
|
|
|
++ if (flag_merge_constants
|
|
|
++ && mode != VOIDmode)
|
|
|
++ {
|
|
|
++ if (align == 8)
|
|
|
++ {
|
|
|
++ named_section_flags (".rodata.__unalignedcst", flags | SECTION_MERGE | SECTION_STRINGS);
|
|
|
++ return;
|
|
|
++ }
|
|
|
++ else if (align == 16)
|
|
|
++ {
|
|
|
++ named_section_flags (".rodata.__alignedcst", flags | SECTION_MERGE);
|
|
|
++ return;
|
|
|
++ }
|
|
|
++ }
|
|
|
++
|
|
|
++#if 0
|
|
|
+ unsigned int modesize = GET_MODE_BITSIZE (mode);
|
|
|
+
|
|
|
+ if (HAVE_GAS_SHF_MERGE && flag_merge_constants
|
|
|
+@@ -750,6 +830,7 @@
|
|
|
+ named_section_flags (name, flags);
|
|
|
+ return;
|
|
|
+ }
|
|
|
++#endif
|
|
|
+
|
|
|
+ readonly_data_section ();
|
|
|
+ }
|
|
|
+@@ -1445,7 +1526,15 @@
|
|
|
+
|
|
|
+ if (destination != asm_dest_common)
|
|
|
+ {
|
|
|
+- resolve_unique_section (decl, 0, flag_data_sections);
|
|
|
++ /* (TIGCC 20040620) Common symbols are handled by our linker as separate
|
|
|
++ sections, so there is no point in manually creating separate BSS sections
|
|
|
++ under -fdata-sections. The TARGET_NO_BSS check here is a hack (it should
|
|
|
++ not be in supposedly target-independent code), but it is necessary because
|
|
|
++ -mno-bss would otherwise compact everything into a single huge section.
|
|
|
++ -- Kevin Kofler */
|
|
|
++ resolve_unique_section (decl, 0, flag_data_sections
|
|
|
++ && ((destination == asm_dest_bss)
|
|
|
++ || TARGET_NO_BSS));
|
|
|
+ /* Custom sections don't belong here. */
|
|
|
+ if (DECL_SECTION_NAME (decl))
|
|
|
+ return false;
|
|
|
+@@ -1696,7 +1785,24 @@
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Switch to the appropriate section. */
|
|
|
+- resolve_unique_section (decl, reloc, flag_data_sections);
|
|
|
++ /* (TIGCC 20040620) See the note about common symbols above. -- Kevin Kofler */
|
|
|
++ /* (TIGCC 20050206) And always emit mergeable constructors into their own
|
|
|
++ sections so the linker can merge them, as GCC fails to do
|
|
|
++ it on its own. */
|
|
|
++ resolve_unique_section (decl, reloc, (flag_data_sections
|
|
|
++ && (!((!TREE_PUBLIC(decl) || DECL_COMMON(decl))
|
|
|
++ && (DECL_INITIAL (decl) == 0
|
|
|
++ || DECL_INITIAL (decl) == error_mark_node
|
|
|
++ || (flag_zero_initialized_in_bss
|
|
|
++ && !TREE_READONLY (decl)
|
|
|
++ && initializer_zerop (DECL_INITIAL (decl)))))
|
|
|
++ || TARGET_NO_BSS))
|
|
|
++ || (DECL_INITIAL (decl)
|
|
|
++ && TREE_CODE (DECL_INITIAL (decl)) == CONSTRUCTOR
|
|
|
++ && (! (reloc
|
|
|
++ || (!TREE_READONLY (decl))
|
|
|
++ || TREE_SIDE_EFFECTS (decl)
|
|
|
++ || !TREE_CONSTANT (DECL_INITIAL (decl))))));
|
|
|
+ variable_section (decl, reloc);
|
|
|
+
|
|
|
+ /* dbxout.c needs to know this. */
|
|
|
+@@ -2140,7 +2246,16 @@
|
|
|
+ void
|
|
|
+ assemble_real (REAL_VALUE_TYPE d, enum machine_mode mode, unsigned int align)
|
|
|
+ {
|
|
|
+- long data[4];
|
|
|
++ long data[3];
|
|
|
++ unsigned int nalign = min_align (align, 16);
|
|
|
++
|
|
|
++ /* This is how to output a SMAP BCD real constant. */
|
|
|
++ REAL_VALUE_TO_TARGET_SMAP_BCD (d, data);
|
|
|
++ assemble_integer (GEN_INT (data[0]), 2, align, 1);
|
|
|
++ assemble_integer (GEN_INT (data[1]), 4, nalign, 1);
|
|
|
++ assemble_integer (GEN_INT (data[2]), 4, nalign, 1);
|
|
|
++
|
|
|
++#if 0
|
|
|
+ int i;
|
|
|
+ int bitsize, nelts, nunits, units_per;
|
|
|
+
|
|
|
+@@ -2175,6 +2290,7 @@
|
|
|
+ assemble_integer (GEN_INT (data[i]), MIN (nunits, units_per), align, 1);
|
|
|
+ nunits -= units_per;
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Given an expression EXP with a constant value,
|
|
|
+@@ -3147,7 +3263,7 @@
|
|
|
+ /* Worker function for output_constant_pool. Emit POOL. */
|
|
|
+
|
|
|
+ static void
|
|
|
+-output_constant_pool_1 (struct constant_descriptor_rtx *desc)
|
|
|
++output_constant_pool_1 (const char *fnname, struct constant_descriptor_rtx *desc)
|
|
|
+ {
|
|
|
+ rtx x, tmp;
|
|
|
+
|
|
|
+@@ -3190,8 +3306,19 @@
|
|
|
+ }
|
|
|
+
|
|
|
+ /* First switch to correct section. */
|
|
|
+- targetm.asm_out.select_rtx_section (desc->mode, x, desc->align);
|
|
|
++ if (flag_merge_constants && flag_merge_constant_pools)
|
|
|
++ {
|
|
|
++ /* (TIGCC 20040727) If we want to merge constant pools, we need to
|
|
|
++ create a separate section for each constant pool.
|
|
|
++ -- Kevin Kofler */
|
|
|
++ char name[strlen(fnname)+15];
|
|
|
+
|
|
|
++ sprintf (name, ".rodata.%s.cpool", fnname);
|
|
|
++ named_section_flags (name, SECTION_MERGE);
|
|
|
++ }
|
|
|
++ else
|
|
|
++ targetm.asm_out.select_rtx_section (desc->mode, x, desc->align);
|
|
|
++
|
|
|
+ #ifdef ASM_OUTPUT_SPECIAL_POOL_ENTRY
|
|
|
+ ASM_OUTPUT_SPECIAL_POOL_ENTRY (asm_out_file, x, desc->mode,
|
|
|
+ desc->align, desc->labelno, done);
|
|
|
+@@ -3306,7 +3433,7 @@
|
|
|
+ /* Write all the constants in the constant pool. */
|
|
|
+
|
|
|
+ void
|
|
|
+-output_constant_pool (const char *fnname ATTRIBUTE_UNUSED,
|
|
|
++output_constant_pool (const char *fnname,
|
|
|
+ tree fndecl ATTRIBUTE_UNUSED)
|
|
|
+ {
|
|
|
+ struct rtx_constant_pool *pool = cfun->varasm->pool;
|
|
|
+@@ -3322,7 +3449,7 @@
|
|
|
+ #endif
|
|
|
+
|
|
|
+ for (desc = pool->first; desc ; desc = desc->next)
|
|
|
+- output_constant_pool_1 (desc);
|
|
|
++ output_constant_pool_1 (fnname, desc);
|
|
|
+
|
|
|
+ #ifdef ASM_OUTPUT_POOL_EPILOGUE
|
|
|
+ ASM_OUTPUT_POOL_EPILOGUE (asm_out_file, fnname, fndecl, pool->offset);
|
|
|
+@@ -3366,10 +3493,18 @@
|
|
|
+ case MINUS_EXPR:
|
|
|
+ reloc = compute_reloc_for_constant (TREE_OPERAND (exp, 0));
|
|
|
+ reloc2 = compute_reloc_for_constant (TREE_OPERAND (exp, 1));
|
|
|
++#if 0
|
|
|
+ /* The difference of two local labels is computable at link time. */
|
|
|
++ /* (TIGCC 20040808) That's true, but it is still not valid in a mergeable
|
|
|
++ section. GCC doesn't seem to accept that as a constant anyway (at least
|
|
|
++ in C), but it is never a good idea to let a latent problem just lie
|
|
|
++ around. And besides, this code is unsafe, consider (addr1+addr2)-addr3.
|
|
|
++ Still a potentially valid expression for the assembler and linker, but
|
|
|
++ mishandled awfully by this code. -- Kevin Kofler */
|
|
|
+ if (reloc == 1 && reloc2 == 1)
|
|
|
+ reloc = 0;
|
|
|
+ else
|
|
|
++#endif /* 0 */
|
|
|
+ reloc |= reloc2;
|
|
|
+ break;
|
|
|
+
|
|
|
+@@ -4741,6 +4876,31 @@
|
|
|
+ || strcmp (name, ".preinit_array") == 0))
|
|
|
+ flags |= SECTION_NOTYPE;
|
|
|
+
|
|
|
++/* (TIGCC 20040725) This was mostly copied out of the ELF section selector. It
|
|
|
++ handles mergeable sections. -- Kevin Kofler */
|
|
|
++ switch (categorize_decl_for_section (decl, reloc, shlib))
|
|
|
++ {
|
|
|
++ case SECCAT_RODATA_MERGE_STR:
|
|
|
++ case SECCAT_RODATA_MERGE_STR_INIT:
|
|
|
++ case SECCAT_RODATA_MERGE_CONST:
|
|
|
++ flags |= SECTION_MERGE;
|
|
|
++ break;
|
|
|
++ default:
|
|
|
++ break;
|
|
|
++ }
|
|
|
++
|
|
|
++ if (TREE_CODE (DECL_INITIAL (decl)) == CONSTRUCTOR)
|
|
|
++ {
|
|
|
++ /* (TIGCC 20040727) Put compound literals in mergeable sections in global
|
|
|
++ compound literal mode. -- Kevin Kofler
|
|
|
++ (TIGCC 20040808) But not if they contain relocations. -- Kevin Kofler */
|
|
|
++ if (! (reloc
|
|
|
++ || (!TREE_READONLY (decl))
|
|
|
++ || TREE_SIDE_EFFECTS (decl)
|
|
|
++ || !TREE_CONSTANT (DECL_INITIAL (decl))))
|
|
|
++ flags |= SECTION_MERGE;
|
|
|
++ }
|
|
|
++
|
|
|
+ return flags;
|
|
|
+ }
|
|
|
+
|
|
|
+@@ -4862,18 +5022,51 @@
|
|
|
+ {
|
|
|
+ bool readonly = false;
|
|
|
+
|
|
|
++/* (TIGCC 20040725) This was copied out of the ELF section selector. It handles
|
|
|
++ mergeable sections. -- Kevin Kofler */
|
|
|
++ switch (categorize_decl_for_section (decl, reloc, flag_pic))
|
|
|
++ {
|
|
|
++ case SECCAT_RODATA_MERGE_STR:
|
|
|
++ mergeable_string_section (decl, align, 0);
|
|
|
++ break;
|
|
|
++ case SECCAT_RODATA_MERGE_STR_INIT:
|
|
|
++ mergeable_string_section (DECL_INITIAL (decl), align, 0);
|
|
|
++ break;
|
|
|
++ case SECCAT_RODATA_MERGE_CONST:
|
|
|
++ mergeable_constant_section (DECL_MODE (decl), align, 0);
|
|
|
++ break;
|
|
|
++ default:
|
|
|
++
|
|
|
+ if (DECL_P (decl))
|
|
|
+ {
|
|
|
++#if 0
|
|
|
++/* (TIGCC 20050206) This doesn't work very well because GCC doesn't merge
|
|
|
++ the compound literals properly. So I emit them into
|
|
|
++ individual mergeable sections instead. */
|
|
|
++ if (TREE_CODE (DECL_INITIAL (decl)) == CONSTRUCTOR)
|
|
|
++ {
|
|
|
++ /* (TIGCC 20040727) Put compound literals in mergeable sections in global
|
|
|
++ compound literal mode. -- Kevin Kofler
|
|
|
++ (TIGCC 20040808) But not if they contain relocations. -- Kevin Kofler */
|
|
|
++ if (! (reloc
|
|
|
++ || (!TREE_READONLY (decl))
|
|
|
++ || TREE_SIDE_EFFECTS (decl)
|
|
|
++ || !TREE_CONSTANT (DECL_INITIAL (decl))))
|
|
|
++ {
|
|
|
++ mergeable_constant_section (DECL_MODE (decl), align, 0);
|
|
|
++ break;
|
|
|
++ }
|
|
|
++ }
|
|
|
++#endif /* 0 */
|
|
|
+ if (decl_readonly_section (decl, reloc))
|
|
|
+ readonly = true;
|
|
|
+ }
|
|
|
+- else if (TREE_CODE (decl) == CONSTRUCTOR)
|
|
|
++ /* (TIGCC 20040727) Put complex literals in mergeable sections.
|
|
|
++ -- Kevin Kofler */
|
|
|
++ else if (TREE_CODE (decl) == COMPLEX_CST)
|
|
|
+ {
|
|
|
+- if (! ((flag_pic && reloc)
|
|
|
+- || !TREE_READONLY (decl)
|
|
|
+- || TREE_SIDE_EFFECTS (decl)
|
|
|
+- || !TREE_CONSTANT (decl)))
|
|
|
+- readonly = true;
|
|
|
++ mergeable_constant_section (DECL_MODE (decl), align, 0);
|
|
|
++ break;
|
|
|
+ }
|
|
|
+ else if (TREE_CODE (decl) == STRING_CST)
|
|
|
+ readonly = true;
|
|
|
+@@ -4884,44 +5077,11 @@
|
|
|
+ readonly_data_section ();
|
|
|
+ else
|
|
|
+ data_section ();
|
|
|
++ } /* end of switch-case */
|
|
|
+ }
|
|
|
+
|
|
|
+ /* A helper function for default_elf_select_section and
|
|
|
+ default_elf_unique_section. Categorizes the DECL. */
|
|
|
+-
|
|
|
+-enum section_category
|
|
|
+-{
|
|
|
+- SECCAT_TEXT,
|
|
|
+-
|
|
|
+- SECCAT_RODATA,
|
|
|
+- SECCAT_RODATA_MERGE_STR,
|
|
|
+- SECCAT_RODATA_MERGE_STR_INIT,
|
|
|
+- SECCAT_RODATA_MERGE_CONST,
|
|
|
+- SECCAT_SRODATA,
|
|
|
+-
|
|
|
+- SECCAT_DATA,
|
|
|
+-
|
|
|
+- /* To optimize loading of shared programs, define following subsections
|
|
|
+- of data section:
|
|
|
+- _REL Contains data that has relocations, so they get grouped
|
|
|
+- together and dynamic linker will visit fewer pages in memory.
|
|
|
+- _RO Contains data that is otherwise read-only. This is useful
|
|
|
+- with prelinking as most relocations won't be dynamically
|
|
|
+- linked and thus stay read only.
|
|
|
+- _LOCAL Marks data containing relocations only to local objects.
|
|
|
+- These relocations will get fully resolved by prelinking. */
|
|
|
+- SECCAT_DATA_REL,
|
|
|
+- SECCAT_DATA_REL_LOCAL,
|
|
|
+- SECCAT_DATA_REL_RO,
|
|
|
+- SECCAT_DATA_REL_RO_LOCAL,
|
|
|
+-
|
|
|
+- SECCAT_SDATA,
|
|
|
+- SECCAT_TDATA,
|
|
|
+-
|
|
|
+- SECCAT_BSS,
|
|
|
+- SECCAT_SBSS,
|
|
|
+- SECCAT_TBSS
|
|
|
+-};
|
|
|
+
|
|
|
+ static enum section_category
|
|
|
+ categorize_decl_for_section (tree, int, int);
|
|
|
+diff -Naur gcc-4.0-20050319.orig/gcc/version.c gcc-4.0-20050319-src/gcc/version.c
|
|
|
+--- gcc-4.0-20050319.orig/gcc/version.c Sat Mar 19 01:16:14 2005
|
|
|
++++ gcc-4.0-20050319-src/gcc/version.c Wed Mar 23 01:32:46 2005
|
|
|
+@@ -5,7 +5,7 @@
|
|
|
+ please modify this string to indicate that, e.g. by putting your
|
|
|
+ organization's name in parentheses at the end of the string. */
|
|
|
+
|
|
|
+-const char version_string[] = "4.0.0 20050319 (prerelease)";
|
|
|
++const char version_string[] = "4.0.0 20050319 (TIGCC prerelease)";
|
|
|
+
|
|
|
+ /* This is the location of the online document giving instructions for
|
|
|
+ reporting bugs. If you distribute a modified version of GCC,
|
|
|
+@@ -14,4 +14,4 @@
|
|
|
+ forward us bugs reported to you, if you determine that they are
|
|
|
+ not bugs in your modifications.) */
|
|
|
+
|
|
|
+-const char bug_report_url[] = "<URL:http://gcc.gnu.org/bugs.html>";
|
|
|
++const char bug_report_url[] = "http://tigcc.ticalc.org/";
|
|
|
+diff -Naur gcc-4.0-20050319.orig/libcpp/directives.c gcc-4.0-20050319-src/libcpp/directives.c
|
|
|
+--- gcc-4.0-20050319.orig/libcpp/directives.c Mon Feb 28 20:25:22 2005
|
|
|
++++ gcc-4.0-20050319-src/libcpp/directives.c Wed Mar 23 01:21:06 2005
|
|
|
+@@ -1070,6 +1070,7 @@
|
|
|
+ _cpp_init_internal_pragmas (cpp_reader *pfile)
|
|
|
+ {
|
|
|
+ /* Pragmas in the global namespace. */
|
|
|
++ register_pragma (pfile, 0, "poison", do_pragma_poison, false, true); /* (TIGCC) */
|
|
|
+ register_pragma (pfile, 0, "once", do_pragma_once, false, true);
|
|
|
+
|
|
|
+ /* New GCC-specific pragmas should be put in the GCC namespace. */
|
|
|
+diff -Naur gcc-4.0-20050319.orig/libcpp/expr.c gcc-4.0-20050319-src/libcpp/expr.c
|
|
|
+--- gcc-4.0-20050319.orig/libcpp/expr.c Sun Jul 4 15:57:46 2004
|
|
|
++++ gcc-4.0-20050319-src/libcpp/expr.c Wed Mar 23 01:21:06 2005
|
|
|
+@@ -171,6 +171,13 @@
|
|
|
+ radix = 16;
|
|
|
+ str++;
|
|
|
+ }
|
|
|
++ /* Require at least one binary digit to classify it as binary. */
|
|
|
++ else if ((*str == 'b' || *str == 'B') && (str[1]=='0' || str[1]=='1'))
|
|
|
++ {
|
|
|
++ radix = 2;
|
|
|
++ str++;
|
|
|
++ }
|
|
|
++
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Now scan for a well-formed integer or float. */
|
|
|
+@@ -205,11 +212,15 @@
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+- if (float_flag != NOT_FLOAT && radix == 8)
|
|
|
++ if ((float_flag != NOT_FLOAT || CPP_OPTION(pfile,no_auto_octals)) && radix == 8)
|
|
|
+ radix = 10;
|
|
|
+
|
|
|
+- if (max_digit >= radix)
|
|
|
+- SYNTAX_ERROR2 ("invalid digit \"%c\" in octal constant", '0' + max_digit);
|
|
|
++ if (max_digit >= radix) {
|
|
|
++ if (radix == 2)
|
|
|
++ SYNTAX_ERROR2 ("invalid digit \"%c\" in binary constant", '0' + max_digit);
|
|
|
++ else
|
|
|
++ SYNTAX_ERROR2 ("invalid digit \"%c\" in octal constant", '0' + max_digit);
|
|
|
++ }
|
|
|
+
|
|
|
+ if (float_flag != NOT_FLOAT)
|
|
|
+ {
|
|
|
+@@ -293,6 +304,12 @@
|
|
|
+ result |= CPP_N_DECIMAL;
|
|
|
+ else if (radix == 16)
|
|
|
+ result |= CPP_N_HEX;
|
|
|
++ else if (radix == 2)
|
|
|
++ {
|
|
|
++ if (CPP_PEDANTIC (pfile))
|
|
|
++ cpp_error(pfile, CPP_DL_PEDWARN, "binary constants are a TIGCC extension");
|
|
|
++ result |= CPP_N_BINARY;
|
|
|
++ }
|
|
|
+ else
|
|
|
+ result |= CPP_N_OCTAL;
|
|
|
+
|
|
|
+@@ -341,6 +358,11 @@
|
|
|
+ else if ((type & CPP_N_RADIX) == CPP_N_HEX)
|
|
|
+ {
|
|
|
+ base = 16;
|
|
|
++ p += 2;
|
|
|
++ }
|
|
|
++ else if ((type & CPP_N_RADIX) == CPP_N_BINARY)
|
|
|
++ {
|
|
|
++ base = 2;
|
|
|
+ p += 2;
|
|
|
+ }
|
|
|
+
|
|
|
+diff -Naur gcc-4.0-20050319.orig/libcpp/files.c gcc-4.0-20050319-src/libcpp/files.c
|
|
|
+--- gcc-4.0-20050319.orig/libcpp/files.c Mon Feb 14 15:43:56 2005
|
|
|
++++ gcc-4.0-20050319-src/libcpp/files.c Wed Mar 23 01:21:06 2005
|
|
|
+@@ -47,6 +47,11 @@
|
|
|
+ # define set_stdin_to_binary_mode() /* Nothing */
|
|
|
+ #endif
|
|
|
+
|
|
|
++/* (TIGCC 20050205) FIXME: This should be handled by configure... */
|
|
|
++#ifdef _WIN32
|
|
|
++#define ssize_t int
|
|
|
++#endif
|
|
|
++
|
|
|
+ /* This structure represents a file searched for by CPP, whether it
|
|
|
+ exists or not. An instance may be pointed to by more than one
|
|
|
+ file_hash_entry; at present no reference count is kept. */
|
|
|
+diff -Naur gcc-4.0-20050319.orig/libcpp/include/cpplib.h gcc-4.0-20050319-src/libcpp/include/cpplib.h
|
|
|
+--- gcc-4.0-20050319.orig/libcpp/include/cpplib.h Sun Feb 20 18:01:32 2005
|
|
|
++++ gcc-4.0-20050319-src/libcpp/include/cpplib.h Wed Mar 23 01:21:06 2005
|
|
|
+@@ -379,6 +379,9 @@
|
|
|
+ /* True if dependencies should be restored from a precompiled header. */
|
|
|
+ bool restore_pch_deps;
|
|
|
+
|
|
|
++ /* (TIGCC) True if numbers starting with zero should NOT be octal. */
|
|
|
++ unsigned char no_auto_octals;
|
|
|
++
|
|
|
+ /* Dependency generation. */
|
|
|
+ struct
|
|
|
+ {
|
|
|
+@@ -709,6 +712,7 @@
|
|
|
+ #define CPP_N_DECIMAL 0x0100
|
|
|
+ #define CPP_N_HEX 0x0200
|
|
|
+ #define CPP_N_OCTAL 0x0400
|
|
|
++#define CPP_N_BINARY 0x0800
|
|
|
+
|
|
|
+ #define CPP_N_UNSIGNED 0x1000 /* Properties. */
|
|
|
+ #define CPP_N_IMAGINARY 0x2000
|
|
|
+@@ -772,6 +776,7 @@
|
|
|
+ string literal. Handles all relevant diagnostics. */
|
|
|
+ extern cppchar_t cpp_parse_escape (cpp_reader *, const unsigned char ** pstr,
|
|
|
+ const unsigned char *limit, int wide);
|
|
|
++extern void cpp_unterminated (cpp_reader *, int);
|
|
|
+
|
|
|
+ /* In cpphash.c */
|
|
|
+
|
|
|
+diff -Naur gcc-4.0-20050319.orig/libcpp/init.c gcc-4.0-20050319-src/libcpp/init.c
|
|
|
+--- gcc-4.0-20050319.orig/libcpp/init.c Mon Feb 14 15:43:56 2005
|
|
|
++++ gcc-4.0-20050319-src/libcpp/init.c Wed Mar 23 01:21:06 2005
|
|
|
+@@ -153,6 +153,7 @@
|
|
|
+ CPP_OPTION (pfile, dollars_in_ident) = 1;
|
|
|
+ CPP_OPTION (pfile, warn_dollars) = 1;
|
|
|
+ CPP_OPTION (pfile, warn_variadic_macros) = 1;
|
|
|
++ CPP_OPTION (pfile, no_auto_octals) = 0; /* (TIGCC) */
|
|
|
+
|
|
|
+ /* Default CPP arithmetic to something sensible for the host for the
|
|
|
+ benefit of dumb users like fix-header. */
|
|
|
+diff -Naur gcc-4.0-20050319.orig/libcpp/internal.h gcc-4.0-20050319-src/libcpp/internal.h
|
|
|
+--- gcc-4.0-20050319.orig/libcpp/internal.h Mon Feb 14 15:43:56 2005
|
|
|
++++ gcc-4.0-20050319-src/libcpp/internal.h Wed Mar 23 01:21:06 2005
|
|
|
+@@ -372,6 +372,11 @@
|
|
|
+ /* Error counter for exit code. */
|
|
|
+ unsigned int errors;
|
|
|
+
|
|
|
++ /* Line and column where a newline was first seen in a string
|
|
|
++ constant (multi-line strings). */
|
|
|
++ source_location mls_line;
|
|
|
++ unsigned int mls_col;
|
|
|
++
|
|
|
+ /* Buffer to hold macro definition string. */
|
|
|
+ unsigned char *macro_buffer;
|
|
|
+ unsigned int macro_buffer_len;
|
|
|
+diff -Naur gcc-4.0-20050319.orig/libcpp/lex.c gcc-4.0-20050319-src/libcpp/lex.c
|
|
|
+--- gcc-4.0-20050319.orig/libcpp/lex.c Thu Sep 9 22:16:54 2004
|
|
|
++++ gcc-4.0-20050319-src/libcpp/lex.c Wed Mar 23 01:21:06 2005
|
|
|
+@@ -215,7 +215,11 @@
|
|
|
+ }
|
|
|
+
|
|
|
+ done:
|
|
|
+- *d = '\n';
|
|
|
++ /* (TIGCC 20050212) Don't convert \r to \n, switch them instead. */
|
|
|
++ if (*d=='\r' && d[1]=='\n')
|
|
|
++ {*d='\n'; d[1]='\r';}
|
|
|
++ else
|
|
|
++ *d = '\n';
|
|
|
+ /* A sentinel note that should never be processed. */
|
|
|
+ add_line_note (buffer, d + 1, '\n');
|
|
|
+ buffer->next_line = s + 1;
|
|
|
+@@ -555,10 +559,19 @@
|
|
|
+ create_literal (cpp_reader *pfile, cpp_token *token, const uchar *base,
|
|
|
+ unsigned int len, enum cpp_ttype type)
|
|
|
+ {
|
|
|
++ char *p;
|
|
|
+ uchar *dest = _cpp_unaligned_alloc (pfile, len + 1);
|
|
|
+
|
|
|
+ memcpy (dest, base, len);
|
|
|
+ dest[len] = '\0';
|
|
|
++ /* (TIGCC 20050206) Delete \r characters in multi-line strings. */
|
|
|
++ p = (char *)dest;
|
|
|
++ while (p < (char *)dest + len) {
|
|
|
++ if (*p == '\r') {
|
|
|
++ memmove (p, p + 1, (char *)dest + len - p);
|
|
|
++ len--;
|
|
|
++ } else p++;
|
|
|
++ }
|
|
|
+ token->type = type;
|
|
|
+ token->val.str.len = len;
|
|
|
+ token->val.str.text = dest;
|
|
|
+@@ -570,7 +583,10 @@
|
|
|
+ literal, or CPP_OTHER if it was not properly terminated.
|
|
|
+
|
|
|
+ The spelling is NUL-terminated, but it is not guaranteed that this
|
|
|
+- is the first NUL since embedded NULs are preserved. */
|
|
|
++ is the first NUL since embedded NULs are preserved.
|
|
|
++
|
|
|
++ Multi-line strings are allowed as a TIGCC extension (removed in the FSF GCC
|
|
|
++ since version 3.3). */
|
|
|
+ static void
|
|
|
+ lex_string (cpp_reader *pfile, cpp_token *token, const uchar *base)
|
|
|
+ {
|
|
|
+@@ -578,7 +594,11 @@
|
|
|
+ const uchar *cur;
|
|
|
+ cppchar_t terminator;
|
|
|
+ enum cpp_ttype type;
|
|
|
++ cpp_buffer *buffer;
|
|
|
++ unsigned int startcol;
|
|
|
+
|
|
|
++ buffer = pfile->buffer;
|
|
|
++ startcol = CPP_BUF_COL (buffer);
|
|
|
+ cur = base;
|
|
|
+ terminator = *cur++;
|
|
|
+ if (terminator == 'L')
|
|
|
+@@ -601,9 +621,50 @@
|
|
|
+ break;
|
|
|
+ else if (c == '\n')
|
|
|
+ {
|
|
|
+- cur--;
|
|
|
+- type = CPP_OTHER;
|
|
|
+- break;
|
|
|
++ unsigned int cols;
|
|
|
++
|
|
|
++ /* In assembly language, silently terminate string and
|
|
|
++ character literals at end of line. This is a kludge
|
|
|
++ around not knowing where comments are. */
|
|
|
++ if (CPP_OPTION (pfile, lang) == CLK_ASM && terminator != '>')
|
|
|
++ {
|
|
|
++ cur--;
|
|
|
++ break;
|
|
|
++ }
|
|
|
++
|
|
|
++ /* Character constants and header names may not extend over
|
|
|
++ multiple lines. In Standard C, neither may strings.
|
|
|
++ In TIGCC, we accept multiline strings as an
|
|
|
++ extension, except in #include family directives. */
|
|
|
++ if (terminator != '"' || pfile->state.angled_headers)
|
|
|
++ {
|
|
|
++ cur--;
|
|
|
++ type = CPP_OTHER;
|
|
|
++ break;
|
|
|
++ }
|
|
|
++
|
|
|
++ if (CPP_PEDANTIC (pfile))
|
|
|
++ cpp_error(pfile, CPP_DL_PEDWARN, "ISO C forbids newline in string literal");
|
|
|
++ buffer->cur = cur - 1;
|
|
|
++ _cpp_process_line_notes (pfile, true);
|
|
|
++ if (buffer->next_line >= buffer->rlimit)
|
|
|
++ {
|
|
|
++ cur--;
|
|
|
++ type = CPP_OTHER;
|
|
|
++ break;
|
|
|
++ }
|
|
|
++ _cpp_clean_line (pfile);
|
|
|
++
|
|
|
++ cols = buffer->next_line - buffer->line_base;
|
|
|
++ CPP_INCREMENT_LINE (pfile, cols);
|
|
|
++
|
|
|
++ cur = buffer->cur;
|
|
|
++
|
|
|
++ if (pfile->mls_line == 0)
|
|
|
++ {
|
|
|
++ pfile->mls_line = token->src_loc;
|
|
|
++ pfile->mls_col = startcol;
|
|
|
++ }
|
|
|
+ }
|
|
|
+ else if (c == '\0')
|
|
|
+ saw_NUL = true;
|
|
|
+@@ -1589,3 +1650,18 @@
|
|
|
+ return CPP_TOKEN_FLD_NONE;
|
|
|
+ }
|
|
|
+ }
|
|
|
++
|
|
|
++/* Emits error for unterminated strings. */
|
|
|
++void
|
|
|
++cpp_unterminated (cpp_reader *pfile, int term)
|
|
|
++{
|
|
|
++ cpp_error (pfile, CPP_DL_ERROR, "missing terminating %c character", term);
|
|
|
++
|
|
|
++ if (term == '\"' && pfile->mls_line && pfile->mls_line != pfile->line_table->highest_line)
|
|
|
++ {
|
|
|
++ cpp_error_with_line (pfile, CPP_DL_ERROR, pfile->mls_line, pfile->mls_col,
|
|
|
++ "possible start of unterminated string literal");
|
|
|
++ pfile->mls_line = 0;
|
|
|
++ }
|
|
|
++}
|
|
|
++
|
|
|
+diff -Naur gcc-4.0-20050319.orig/libcpp/macro.c gcc-4.0-20050319-src/libcpp/macro.c
|
|
|
+--- gcc-4.0-20050319.orig/libcpp/macro.c Fri Mar 4 16:39:36 2005
|
|
|
++++ gcc-4.0-20050319-src/libcpp/macro.c Wed Mar 23 01:21:06 2005
|
|
|
+@@ -781,6 +781,11 @@
|
|
|
+ macro_arg *arg;
|
|
|
+ _cpp_buff *buff;
|
|
|
+
|
|
|
++ /* (TIGCC) If 'SYMSTR' is used with a string literal, it should be
|
|
|
++ converted automatically to 'SYMSTR_CONST'. */
|
|
|
++ cpp_hashnode *orig_node=node; /* save the original node in case we change it */
|
|
|
++ symstr_const: /* start again from here after changing SYMSTR to SYMSTR_CONST */
|
|
|
++
|
|
|
+ /* First, fully macro-expand arguments, calculating the number of
|
|
|
+ tokens in the final expansion as we go. The ordering of the if
|
|
|
+ statements below is subtle; we must handle stringification before
|
|
|
+@@ -814,6 +819,33 @@
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
++ if (!ustrcmp (node->ident.str, U"SYMSTR"))
|
|
|
++ {
|
|
|
++ /* Accept one or more literal strings. If there are multiple ones, they
|
|
|
++ concatenate. Ignore any padding.
|
|
|
++ Refuse any other argument type. */
|
|
|
++ unsigned int i;
|
|
|
++ cpp_hashnode *newnode;
|
|
|
++
|
|
|
++ for (i=0;i<args->expanded_count;i++)
|
|
|
++ {
|
|
|
++ if ((args->expanded[i]->type != CPP_STRING)
|
|
|
++ && (args->expanded[i]->type != CPP_PADDING)) goto notconststring;
|
|
|
++ }
|
|
|
++
|
|
|
++ /* Change the macro to SYMSTR_CONST, if it is defined. */
|
|
|
++ newnode = cpp_lookup (pfile, U"SYMSTR_CONST",
|
|
|
++ sizeof ("SYMSTR_CONST") - 1);
|
|
|
++ if (newnode->type == NT_MACRO) {
|
|
|
++ node = newnode;
|
|
|
++ macro = node->value.macro;
|
|
|
++ goto symstr_const; /* Start over from the beginning. */
|
|
|
++ }
|
|
|
++
|
|
|
++ notconststring:;
|
|
|
++ }
|
|
|
++ /* (END TIGCC) */
|
|
|
++
|
|
|
+ /* Now allocate space for the expansion, copy the tokens and replace
|
|
|
+ the arguments. */
|
|
|
+ buff = _cpp_get_buff (pfile, total * sizeof (cpp_token *));
|
|
|
+@@ -900,7 +932,10 @@
|
|
|
+ if (args[i].expanded)
|
|
|
+ free (args[i].expanded);
|
|
|
+
|
|
|
+- push_ptoken_context (pfile, node, buff, first, dest - first);
|
|
|
++ push_ptoken_context (pfile, orig_node, buff, first, dest - first);
|
|
|
++ /* (TIGCC) Always use the ORIGINAL node here, not the modified one. Doing
|
|
|
++ otherwise would make subsequent expansions of SYMSTR fail after
|
|
|
++ the first conversion to SYMSTR_CONST. */
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Return a special padding token, with padding inherited from SOURCE. */
|