|
@@ -0,0 +1,7225 @@
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/attribs.c gcc-3.3.3.tigcc8/gcc/attribs.c
|
|
|
+--- gcc-3.3.3.orig/gcc/attribs.c Mon Aug 5 20:46:32 2002
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/attribs.c Thu Feb 19 21:20:00 2004
|
|
|
+@@ -231,7 +231,54 @@
|
|
|
+ || TREE_CODE (TREE_TYPE (*anode)) == METHOD_TYPE))
|
|
|
+ {
|
|
|
+ if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
|
|
|
+- *anode = build_type_copy (*anode);
|
|
|
++ {
|
|
|
++/* (TIGCC) Neither build_type_copy nor build_type_attribute_variant are
|
|
|
++ applicable here, so we use a slightly modified version of the code in
|
|
|
++ build_type_attribute_variant.
|
|
|
++ The FSF GCC source uses build_type_copy, but that causes attributes
|
|
|
++ to function pointers to simply get lost! */
|
|
|
++
|
|
|
++ unsigned int hashcode;
|
|
|
++ tree ntype;
|
|
|
++
|
|
|
++ ntype = copy_node (*anode);
|
|
|
++
|
|
|
++ TYPE_POINTER_TO (ntype) = 0;
|
|
|
++ TYPE_REFERENCE_TO (ntype) = 0;
|
|
|
++
|
|
|
++ /* Create a new main variant of TYPE. */
|
|
|
++ TYPE_MAIN_VARIANT (ntype) = ntype;
|
|
|
++ TYPE_NEXT_VARIANT (ntype) = 0;
|
|
|
++ TYPE_READONLY (ntype) = 0;
|
|
|
++ TYPE_VOLATILE (ntype) = 0;
|
|
|
++ TYPE_RESTRICT (ntype) = 0;
|
|
|
++
|
|
|
++ hashcode = (TYPE_HASH (TREE_CODE (ntype))
|
|
|
++ + TYPE_HASH (TREE_TYPE (ntype))
|
|
|
++ + attribute_hash_list (TYPE_ATTRIBUTES (ntype)));
|
|
|
++
|
|
|
++ switch (TREE_CODE (ntype))
|
|
|
++ {
|
|
|
++ case FUNCTION_TYPE:
|
|
|
++ hashcode += TYPE_HASH (TYPE_ARG_TYPES (ntype));
|
|
|
++ break;
|
|
|
++ case ARRAY_TYPE:
|
|
|
++ hashcode += TYPE_HASH (TYPE_DOMAIN (ntype));
|
|
|
++ break;
|
|
|
++ case INTEGER_TYPE:
|
|
|
++ hashcode += TYPE_HASH (TYPE_MAX_VALUE (ntype));
|
|
|
++ break;
|
|
|
++ case REAL_TYPE:
|
|
|
++ hashcode += TYPE_HASH (TYPE_PRECISION (ntype));
|
|
|
++ break;
|
|
|
++ default:
|
|
|
++ break;
|
|
|
++ }
|
|
|
++
|
|
|
++ ntype = type_hash_canon (hashcode, ntype);
|
|
|
++ *anode = build_qualified_type (ntype, TYPE_QUALS (*anode));
|
|
|
++/* (END TIGCC) */
|
|
|
++ }
|
|
|
+ anode = &TREE_TYPE (*anode);
|
|
|
+ }
|
|
|
+ else if (flags & (int) ATTR_FLAG_FUNCTION_NEXT)
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/bb-reorder.c gcc-3.3.3.tigcc8/gcc/bb-reorder.c
|
|
|
+--- gcc-3.3.3.orig/gcc/bb-reorder.c Fri Mar 21 23:56:58 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/bb-reorder.c Thu Feb 19 21:20:00 2004
|
|
|
+@@ -95,7 +95,9 @@
|
|
|
+ /* Local function prototypes. */
|
|
|
+ static void make_reorder_chain PARAMS ((void));
|
|
|
+ static basic_block make_reorder_chain_1 PARAMS ((basic_block, basic_block));
|
|
|
++#if 0 /* (TIGCC 20030607) See below. */
|
|
|
+ static basic_block maybe_duplicate_computed_goto_succ PARAMS ((basic_block));
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Compute an ordering for a subgraph beginning with block BB. Record the
|
|
|
+ ordering in RBI()->index and chained through RBI()->next. */
|
|
|
+@@ -132,6 +134,23 @@
|
|
|
+ RBI (prev)->next = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0 /* (TIGCC 20030607) Revert the following patch:
|
|
|
++
|
|
|
++2003-03-21 Richard Henderson <rth@redhat.com>
|
|
|
++
|
|
|
++ PR opt/2001
|
|
|
++ * bb-reorder.c (maybe_duplicate_computed_goto_succ): New.
|
|
|
++ (make_reorder_chain_1): Call it.
|
|
|
++
|
|
|
++ * function.h (struct function): Add computed_goto_common_label,
|
|
|
++ computed_goto_common_reg.
|
|
|
++ * function.c (free_after_compilation): Zap them.
|
|
|
++ * stmt.c (expand_computed_goto): Use them to produce one
|
|
|
++ indirect branch per function.
|
|
|
++
|
|
|
++because it breaks ER_throw, whereas PR opt/2001 is a compilation slowness
|
|
|
++problem (in an extreme case) only. -- Kevin Kofler */
|
|
|
++
|
|
|
+ /* If the successor is our artificial computed_jump block, duplicate it. */
|
|
|
+
|
|
|
+ static inline basic_block
|
|
|
+@@ -170,6 +189,7 @@
|
|
|
+
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* A helper function for make_reorder_chain.
|
|
|
+
|
|
|
+@@ -247,9 +267,11 @@
|
|
|
+ next = ((taken && e_taken) ? e_taken : e_fall)->dest;
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0 /* (TIGCC 20030607) See above. */
|
|
|
+ /* If the successor is our artificial computed_jump block, duplicate it. */
|
|
|
+ else
|
|
|
+ next = maybe_duplicate_computed_goto_succ (bb);
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* In the absence of a prediction, disturb things as little as possible
|
|
|
+ by selecting the old "next" block from the list of successors. If
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/builtin-attrs.def gcc-3.3.3.tigcc8/gcc/builtin-attrs.def
|
|
|
+--- gcc-3.3.3.orig/gcc/builtin-attrs.def Tue Mar 4 14:37:20 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/builtin-attrs.def Thu Feb 19 21:20:00 2004
|
|
|
+@@ -63,6 +63,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. */
|
|
|
+@@ -75,6 +76,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 tress for identifiers. */
|
|
|
+@@ -108,6 +111,8 @@
|
|
|
+ ATTR_NOTHROW_LIST)
|
|
|
+ DEF_ATTR_TREE_LIST (ATTR_NONNULL_3, ATTR_NONNULL, ATTR_LIST_3, \
|
|
|
+ ATTR_NOTHROW_LIST)
|
|
|
++DEF_ATTR_TREE_LIST (ATTR_NONNULL_4, ATTR_NONNULL, ATTR_LIST_4, \
|
|
|
++ ATTR_NOTHROW_LIST)
|
|
|
+
|
|
|
+ /* Construct a tree for a format attribute. */
|
|
|
+ #define DEF_FORMAT_ATTRIBUTE(TYPE, FA, VALUES) \
|
|
|
+@@ -125,6 +130,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
|
|
|
+@@ -152,9 +161,24 @@
|
|
|
+
|
|
|
+ /* Functions from ISO/IEC 9899:1990. */
|
|
|
+ #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 (strftime, ATTR_FORMAT_STRFTIME_3_0)
|
|
|
++/* (TIGCC 20040219) */
|
|
|
++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)
|
|
|
+ #undef DEF_C89_ATTR
|
|
|
+
|
|
|
+ /* ISO C99 adds the snprintf and vscanf family functions. */
|
|
|
+@@ -162,7 +186,13 @@
|
|
|
+ DEF_FN_ATTR_IDENT (NAME, ATTRS, \
|
|
|
+ (flag_hosted \
|
|
|
+ && (flag_isoc99 || flag_noniso_default_format_attributes)))
|
|
|
++DEF_C99_ATTR (snprintf, ATTR_FORMAT_PRINTF_3_4)
|
|
|
++DEF_C99_ATTR (vsnprintf, ATTR_FORMAT_PRINTF_3_0)
|
|
|
++#if 0 /* (TIGCC 20040219) Moved these to C89, as we always define them. */
|
|
|
++DEF_C99_ATTR (vscanf, ATTR_FORMAT_SCANF_1_0)
|
|
|
+ DEF_C99_ATTR (vfscanf, ATTR_FORMAT_SCANF_2_0)
|
|
|
++DEF_C99_ATTR (vsscanf, ATTR_FORMAT_SCANF_2_0)
|
|
|
++#endif
|
|
|
+ #undef DEF_C99_ATTR
|
|
|
+
|
|
|
+ /* Functions not in any version of ISO C. */
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/builtins.c gcc-3.3.3.tigcc8/gcc/builtins.c
|
|
|
+--- gcc-3.3.3.orig/gcc/builtins.c Sun Jan 11 19:13:02 2004
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/builtins.c Thu Feb 19 21:20:00 2004
|
|
|
+@@ -143,13 +143,17 @@
|
|
|
+ static rtx expand_builtin_alloca PARAMS ((tree, rtx));
|
|
|
+ static rtx expand_builtin_ffs PARAMS ((tree, rtx, rtx));
|
|
|
+ static rtx expand_builtin_frame_address PARAMS ((tree));
|
|
|
++#if 0
|
|
|
+ static rtx expand_builtin_fputs PARAMS ((tree, int, int));
|
|
|
++#endif /* 0 */
|
|
|
+ static tree stabilize_va_list PARAMS ((tree, int));
|
|
|
+ static rtx expand_builtin_expect PARAMS ((tree, rtx));
|
|
|
+ static tree fold_builtin_constant_p PARAMS ((tree));
|
|
|
+ static tree fold_builtin_classify_type PARAMS ((tree));
|
|
|
++#if 0
|
|
|
+ static tree fold_builtin_inf PARAMS ((tree, int));
|
|
|
+ static tree fold_builtin_nan PARAMS ((tree, tree, int));
|
|
|
++#endif /* 0 */
|
|
|
+ static tree build_function_call_expr PARAMS ((tree, tree));
|
|
|
+ static int validate_arglist PARAMS ((tree, ...));
|
|
|
+
|
|
|
+@@ -915,7 +919,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. */
|
|
|
+ {
|
|
|
+ /* Search for the proper mode for copying this register's
|
|
|
+ value. I'm not sure this is right, but it works so far. */
|
|
|
+@@ -3517,6 +3527,7 @@
|
|
|
+ /* If the string passed to fputs is a constant and is one character
|
|
|
+ long, we attempt to transform this call into __builtin_fputc(). */
|
|
|
+
|
|
|
++#if 0
|
|
|
+ static rtx
|
|
|
+ expand_builtin_fputs (arglist, ignore, unlocked)
|
|
|
+ tree arglist;
|
|
|
+@@ -3596,6 +3607,7 @@
|
|
|
+ (ignore ? const0_rtx : NULL_RTX),
|
|
|
+ VOIDmode, EXPAND_NORMAL);
|
|
|
+ }
|
|
|
++#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
|
|
|
+@@ -3828,6 +3840,7 @@
|
|
|
+ case BUILT_IN_STRCSPN:
|
|
|
+ case BUILT_IN_STRCMP:
|
|
|
+ case BUILT_IN_FFS:
|
|
|
++#if 0
|
|
|
+ case BUILT_IN_PUTCHAR:
|
|
|
+ case BUILT_IN_PUTS:
|
|
|
+ case BUILT_IN_PRINTF:
|
|
|
+@@ -3840,6 +3853,7 @@
|
|
|
+ case BUILT_IN_FPUTC_UNLOCKED:
|
|
|
+ case BUILT_IN_FPUTS_UNLOCKED:
|
|
|
+ case BUILT_IN_FWRITE_UNLOCKED:
|
|
|
++#endif /* 0 */
|
|
|
+ return expand_call (exp, target, ignore);
|
|
|
+
|
|
|
+ default:
|
|
|
+@@ -4115,6 +4129,7 @@
|
|
|
+ expand_builtin_trap ();
|
|
|
+ return const0_rtx;
|
|
|
+
|
|
|
++#if 0
|
|
|
+ case BUILT_IN_FPUTS:
|
|
|
+ target = expand_builtin_fputs (arglist, ignore,/*unlocked=*/ 0);
|
|
|
+ if (target)
|
|
|
+@@ -4125,6 +4140,7 @@
|
|
|
+ if (target)
|
|
|
+ return target;
|
|
|
+ break;
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Various hooks for the DWARF 2 __throw routine. */
|
|
|
+ case BUILT_IN_UNWIND_INIT:
|
|
|
+@@ -4230,6 +4246,7 @@
|
|
|
+ return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0);
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Fold a call to __builtin_inf or __builtin_huge_val. */
|
|
|
+
|
|
|
+ static tree
|
|
|
+@@ -4267,6 +4284,7 @@
|
|
|
+
|
|
|
+ return build_real (type, real);
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Used by constant folding to eliminate some builtin calls early. EXP is
|
|
|
+ the CALL_EXPR of a call to a builtin function. */
|
|
|
+@@ -4304,6 +4322,7 @@
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
++#if 0
|
|
|
+ case BUILT_IN_INF:
|
|
|
+ case BUILT_IN_INFF:
|
|
|
+ case BUILT_IN_INFL:
|
|
|
+@@ -4323,6 +4342,7 @@
|
|
|
+ case BUILT_IN_NANSF:
|
|
|
+ case BUILT_IN_NANSL:
|
|
|
+ return fold_builtin_nan (arglist, TREE_TYPE (TREE_TYPE (fndecl)), false);
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/builtins.def gcc-3.3.3.tigcc8/gcc/builtins.def
|
|
|
+--- gcc-3.3.3.orig/gcc/builtins.def Mon May 5 18:59:18 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/builtins.def Thu Feb 19 21:20:00 2004
|
|
|
+@@ -525,6 +525,7 @@
|
|
|
+ BT_FN_VOID_CONST_PTR_VAR,
|
|
|
+ ATTR_NULL)
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* stdio.h builtins (without FILE *). */
|
|
|
+
|
|
|
+ DEF_FRONT_END_LIB_BUILTIN(BUILT_IN_PRINTF,
|
|
|
+@@ -639,6 +640,7 @@
|
|
|
+ "__builtin_fprintf_unlocked",
|
|
|
+ BT_FN_INT_PTR_CONST_STRING_VAR,
|
|
|
+ ATTR_FORMAT_PRINTF_2_3)
|
|
|
++#endif
|
|
|
+
|
|
|
+ /* ISO C99 floating point unordered comparisons. */
|
|
|
+ DEF_GCC_BUILTIN(BUILT_IN_ISGREATER,
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/c-common.c gcc-3.3.3.tigcc8/gcc/c-common.c
|
|
|
+--- gcc-3.3.3.orig/gcc/c-common.c Sun Jun 8 00:13:24 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/c-common.c Thu Feb 19 21:20:00 2004
|
|
|
+@@ -784,9 +784,11 @@
|
|
|
+ int));
|
|
|
+ static void builtin_define_with_int_value PARAMS ((const char *,
|
|
|
+ HOST_WIDE_INT));
|
|
|
++#if 0
|
|
|
+ static void builtin_define_with_hex_fp_value PARAMS ((const char *, tree,
|
|
|
+ int, const char *,
|
|
|
+ const char *));
|
|
|
++#endif /* 0 */
|
|
|
+ static void builtin_define_type_max PARAMS ((const char *, tree, int));
|
|
|
+ static void builtin_define_type_precision PARAMS ((const char *, tree));
|
|
|
+ static void builtin_define_float_constants PARAMS ((const char *,
|
|
|
+@@ -1319,12 +1321,16 @@
|
|
|
+ return value;
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0
|
|
|
+ static int is_valid_printf_arglist PARAMS ((tree));
|
|
|
++#endif /* 0 */
|
|
|
+ static rtx c_expand_builtin PARAMS ((tree, rtx, enum machine_mode, enum expand_modifier));
|
|
|
++#if 0
|
|
|
+ static rtx c_expand_builtin_printf PARAMS ((tree, rtx, enum machine_mode,
|
|
|
+ enum expand_modifier, int, int));
|
|
|
+ static rtx c_expand_builtin_fprintf PARAMS ((tree, rtx, enum machine_mode,
|
|
|
+ enum expand_modifier, int, int));
|
|
|
++#endif
|
|
|
+
|
|
|
+ /* Print a warning if a constant expression had overflow in folding.
|
|
|
+ Invoke this function on every expression that the language
|
|
|
+@@ -4427,6 +4433,7 @@
|
|
|
+
|
|
|
+ switch (fcode)
|
|
|
+ {
|
|
|
++#if 0
|
|
|
+ case BUILT_IN_PRINTF:
|
|
|
+ target = c_expand_builtin_printf (arglist, target, tmode,
|
|
|
+ modifier, ignore, /*unlocked=*/ 0);
|
|
|
+@@ -4454,6 +4461,7 @@
|
|
|
+ if (target)
|
|
|
+ return target;
|
|
|
+ break;
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ default: /* just do library call, if unknown builtin */
|
|
|
+ error ("built-in function `%s' not currently supported",
|
|
|
+@@ -4465,6 +4473,7 @@
|
|
|
+ return expand_call (exp, target, ignore);
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Check an arglist to *printf for problems. The arglist should start
|
|
|
+ at the format specifier, with the remaining arguments immediately
|
|
|
+ following it. */
|
|
|
+@@ -4686,6 +4695,7 @@
|
|
|
+ (ignore ? const0_rtx : target),
|
|
|
+ tmode, modifier);
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+
|
|
|
+ /* Given a boolean expression ARG, return a tree representing an increment
|
|
|
+@@ -4744,6 +4754,7 @@
|
|
|
+ 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
|
|
|
+@@ -4899,6 +4910,7 @@
|
|
|
+ sprintf (buf, "0.0%s", fp_suffix);
|
|
|
+ builtin_define_with_value (name, buf, 0);
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Hook that registers front end and target-specific built-ins. */
|
|
|
+@@ -5099,6 +5111,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 (macro, type, digits, hex_str, fp_suffix)
|
|
|
+@@ -5127,6 +5140,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-3.3.3.orig/gcc/c-decl.c gcc-3.3.3.tigcc8/gcc/c-decl.c
|
|
|
+--- gcc-3.3.3.orig/gcc/c-decl.c Sat Sep 6 16:44:14 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/c-decl.c Thu Feb 19 21:20:00 2004
|
|
|
+@@ -3225,8 +3225,10 @@
|
|
|
+ record the given order of parms in `parm_order'. */
|
|
|
+
|
|
|
+ void
|
|
|
+-push_parm_decl (parm)
|
|
|
+- tree parm;
|
|
|
++/* begin-TIGCC-local (regparms): explicit register specification for parameters */
|
|
|
++push_parm_decl (parm, asmspec)
|
|
|
++ tree parm, asmspec;
|
|
|
++/* end-TIGCC-local (regparms) */
|
|
|
+ {
|
|
|
+ tree decl;
|
|
|
+ int old_immediate_size_expand = immediate_size_expand;
|
|
|
+@@ -3248,6 +3250,78 @@
|
|
|
+ }
|
|
|
+ #endif
|
|
|
+
|
|
|
++ /* 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_2_wide(regnum, 0), NULL_TREE), NULL_TREE);
|
|
|
++#else
|
|
|
++ attrs=tree_cons(get_identifier("asm"),
|
|
|
++ build_int_2_wide(regnum, 0), 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_type_copy(type);
|
|
|
++ TYPE_ATTRIBUTES(type)=attrs;
|
|
|
++ }
|
|
|
++#endif
|
|
|
++ TREE_TYPE(decl)=type;
|
|
|
++/* pop_obstacks(); */
|
|
|
++ }
|
|
|
++ else
|
|
|
++ error_with_decl(decl,
|
|
|
++ "register number for `%s' isn't suitable for the data type");
|
|
|
++ }
|
|
|
++ 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);
|
|
|
+
|
|
|
+ immediate_size_expand = old_immediate_size_expand;
|
|
|
+@@ -3279,6 +3353,21 @@
|
|
|
+ tree type;
|
|
|
+ tree init;
|
|
|
+ {
|
|
|
++ /* (TIGCC) If -fglobal-compound-literals (on by default) is given, for
|
|
|
++ constant constructors, the compound literal is just the constructor itself.
|
|
|
++ For variable constructors, we use the new code, since they have to be
|
|
|
++ created on the stack anyway, and since the new code allows taking their
|
|
|
++ address. */
|
|
|
++if (flag_global_compound_literals && TREE_CONSTANT (init)) {
|
|
|
++ if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
|
|
|
++ {
|
|
|
++ int failure = complete_array_type (type, init, 1);
|
|
|
++ if (failure)
|
|
|
++ abort ();
|
|
|
++ }
|
|
|
++
|
|
|
++ return init;
|
|
|
++} else {
|
|
|
+ /* We do not use start_decl here because we have a type, not a declarator;
|
|
|
+ and do not use finish_decl because the decl should be stored inside
|
|
|
+ the COMPOUND_LITERAL_EXPR rather than added elsewhere as a DECL_STMT. */
|
|
|
+@@ -3329,6 +3418,7 @@
|
|
|
+ }
|
|
|
+
|
|
|
+ return complit;
|
|
|
++}
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Make TYPE a complete type based on INITIAL_VALUE.
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/c-format.c gcc-3.3.3.tigcc8/gcc/c-format.c
|
|
|
+--- gcc-3.3.3.orig/gcc/c-format.c Sun Dec 1 17:51:44 2002
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/c-format.c Wed Jul 28 00:18:00 2004
|
|
|
+@@ -559,30 +559,22 @@
|
|
|
+ } 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 }
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
+-/* 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 }
|
|
|
+ };
|
|
|
+
|
|
|
+@@ -596,6 +588,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 },
|
|
|
+@@ -603,8 +598,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 },
|
|
|
+@@ -621,14 +617,13 @@
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
++/* (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 }
|
|
|
+ };
|
|
|
+
|
|
|
+@@ -742,46 +737,37 @@
|
|
|
+ #define T_UIM &uintmax_type_node
|
|
|
+ #define T99_UIM { STD_C99, "uintmax_t", T_UIM }
|
|
|
+
|
|
|
++/* (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" },
|
|
|
+- { "oxX", 0, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "-wp0#", "i" },
|
|
|
+- { "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" },
|
|
|
+- { "fgG", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#'", "" },
|
|
|
+- { "eE", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "" },
|
|
|
+- { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "" },
|
|
|
+- { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR" },
|
|
|
+- { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c" },
|
|
|
+- { "n", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, T99_PD, T99_IM }, "", "W" },
|
|
|
+- /* C99 conversion specifiers. */
|
|
|
+- { "F", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#'", "" },
|
|
|
+- { "aA", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "" },
|
|
|
+- /* X/Open conversion specifiers. */
|
|
|
+- { "C", 0, STD_EXT, { TEX_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "" },
|
|
|
+- { "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "R" },
|
|
|
+- /* GNU conversion specifiers. */
|
|
|
+- { "m", 0, STD_EXT, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "" },
|
|
|
++ { "di", 0, STD_C89, { T89_S, BADLEN, T89_S, T89_L, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +|z", "i" },
|
|
|
++ { "xX", 0, STD_C89, { T89_US, BADLEN, T89_US, T89_UL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0#|z", "i" },
|
|
|
++ { "u", 0, STD_C89, { T89_US, BADLEN, T89_US, T89_UL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0|z", "i" },
|
|
|
++ { "fgG", 0, STD_C89, { T89_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#^|z", "" },
|
|
|
++ { "eE", 0, STD_C89, { T89_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#^|z", "" },
|
|
|
++ { "rR", 0, STD_EXT, { T89_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#^|z", "" },
|
|
|
++ { "yY", 0, STD_EXT, { T89_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#^|z", "" },
|
|
|
++ { "c", 0, STD_C89, { T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w|z", "" },
|
|
|
++ { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp|z", "cR" },
|
|
|
++ { "p", 1, STD_C89, { BADLEN, BADLEN, BADLEN, T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w|z", "c" },
|
|
|
+ { NULL, 0, 0, NOLENGTHS, 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" },
|
|
|
+- { "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" },
|
|
|
++ { "di", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, TEX_LL, T99_SST, T99_PD, T99_IM }, "*w", "W" },
|
|
|
++ { "u", 1, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "*w", "W" },
|
|
|
+ { "oxX", 1, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "*w", "W" },
|
|
|
+- { "efgEG", 1, STD_C89, { T89_F, BADLEN, BADLEN, T89_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "*w'", "W" },
|
|
|
++ { "efgEG", 1, STD_C89, { T89_F, BADLEN, BADLEN, T89_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "*w", "W" },
|
|
|
+ { "c", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "cW" },
|
|
|
+ { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW" },
|
|
|
+ { "[", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW[" },
|
|
|
+ { "p", 2, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W" },
|
|
|
+- { "n", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, T99_PD, T99_IM }, "", "W" },
|
|
|
+- /* C99 conversion specifiers. */
|
|
|
+- { "FaA", 1, STD_C99, { T99_F, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN }, "*w'", "W" },
|
|
|
+- /* X/Open conversion specifiers. */
|
|
|
+- { "C", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W" },
|
|
|
+- { "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "W" },
|
|
|
+ { NULL, 0, 0, NOLENGTHS, NULL, NULL }
|
|
|
+ };
|
|
|
+
|
|
|
+@@ -820,15 +806,16 @@
|
|
|
+
|
|
|
+
|
|
|
+ /* 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[] =
|
|
|
+ {
|
|
|
+- { "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',
|
|
|
+ &integer_type_node, &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',
|
|
|
+@@ -2275,6 +2262,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;
|
|
|
+@@ -2289,12 +2287,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))
|
|
|
+ && (TREE_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-3.3.3.orig/gcc/c-lex.c gcc-3.3.3.tigcc8/gcc/c-lex.c
|
|
|
+--- gcc-3.3.3.orig/gcc/c-lex.c Sun Sep 14 15:26:34 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/c-lex.c Thu Feb 19 21:20:00 2004
|
|
|
+@@ -929,8 +929,7 @@
|
|
|
+ memcpy (copy, token->val.str.text, copylen);
|
|
|
+ copy[copylen] = '\0';
|
|
|
+
|
|
|
+- real_from_string (&real, copy);
|
|
|
+- real_convert (&real, TYPE_MODE (type), &real);
|
|
|
++ real = REAL_VALUE_ATOF (copy, TYPE_MODE (type));
|
|
|
+
|
|
|
+ /* A diagnostic is required for "soft" overflow by some ISO C
|
|
|
+ testsuites. This is not pedwarn, because some people don't want
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/c-opts.c gcc-3.3.3.tigcc8/gcc/c-opts.c
|
|
|
+--- gcc-3.3.3.orig/gcc/c-opts.c Thu Jun 12 13:58:30 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/c-opts.c Thu Feb 19 21:20:00 2004
|
|
|
+@@ -193,6 +193,7 @@
|
|
|
+ OPT("fall-virtual", CL_CXX, OPT_fall_virtual) \
|
|
|
+ OPT("falt-external-templates",CL_CXX, OPT_falt_external_templates) \
|
|
|
+ OPT("fasm", CL_ALL, OPT_fasm) \
|
|
|
++ OPT("fauto-octals", CL_ALL, OPT_fauto_octals) \
|
|
|
+ OPT("fbuiltin", CL_ALL, OPT_fbuiltin) \
|
|
|
+ OPT("fbuiltin-", CL_ALL | CL_JOINED, OPT_fbuiltin_) \
|
|
|
+ OPT("fcheck-new", CL_CXX, OPT_fcheck_new) \
|
|
|
+@@ -1339,6 +1340,10 @@
|
|
|
+
|
|
|
+ case OPT_v:
|
|
|
+ cpp_opts->verbose = 1;
|
|
|
++ break;
|
|
|
++
|
|
|
++ case OPT_fauto_octals:
|
|
|
++ cpp_opts->no_auto_octals = !on;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/c-parse.in gcc-3.3.3.tigcc8/gcc/c-parse.in
|
|
|
+--- gcc-3.3.3.orig/gcc/c-parse.in Tue Jan 28 01:54:02 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/c-parse.in Thu Feb 19 21:20:02 2004
|
|
|
+@@ -29,7 +29,7 @@
|
|
|
+ written by AT&T, but I have never seen it. */
|
|
|
+
|
|
|
+ ifc
|
|
|
+-%expect 10 /* shift/reduce conflicts, and no reduce/reduce conflicts. */
|
|
|
++%expect 11 /* shift/reduce conflicts, and no reduce/reduce conflicts. */
|
|
|
+ end ifc
|
|
|
+
|
|
|
+ %{
|
|
|
+@@ -225,7 +225,7 @@
|
|
|
+ %type <ttype> enumlist enumerator
|
|
|
+ %type <ttype> struct_head union_head enum_head
|
|
|
+ %type <ttype> typename absdcl absdcl1 absdcl1_ea absdcl1_noea
|
|
|
+-%type <ttype> direct_absdcl1 absdcl_maybe_attribute
|
|
|
++%type <ttype> direct_absdcl1 /*(TIGCC)*/ absdcl_maybeasm_maybe_attribute
|
|
|
+ %type <ttype> xexpr parms parm firstparm identifiers
|
|
|
+
|
|
|
+ %type <ttype> parmlist parmlist_1 parmlist_2
|
|
|
+@@ -1943,20 +1943,22 @@
|
|
|
+ | absdcl1
|
|
|
+ ;
|
|
|
+
|
|
|
+-absdcl_maybe_attribute: /* absdcl maybe_attribute, but not just attributes */
|
|
|
+- /* empty */
|
|
|
+- { $$ = build_tree_list (build_tree_list (current_declspecs,
|
|
|
++/* begin-TIGCC-local (regparms): explicit register specification for parameters */
|
|
|
++absdcl_maybeasm_maybe_attribute: /* absdcl maybeasm maybe_attribute, but not just attributes */
|
|
|
++ maybeasm
|
|
|
++ { $$ = build_tree_list (build_tree_list (build_tree_list (current_declspecs,
|
|
|
+ NULL_TREE),
|
|
|
+- all_prefix_attributes); }
|
|
|
+- | absdcl1
|
|
|
+- { $$ = build_tree_list (build_tree_list (current_declspecs,
|
|
|
++ all_prefix_attributes), $1); }
|
|
|
++ | absdcl1 maybeasm
|
|
|
++ { $$ = build_tree_list (build_tree_list (build_tree_list (current_declspecs,
|
|
|
+ $1),
|
|
|
+- all_prefix_attributes); }
|
|
|
+- | absdcl1_noea attributes
|
|
|
+- { $$ = build_tree_list (build_tree_list (current_declspecs,
|
|
|
++ all_prefix_attributes), $2); }
|
|
|
++ | absdcl1_noea maybeasm attributes
|
|
|
++ { $$ = build_tree_list (build_tree_list (build_tree_list (current_declspecs,
|
|
|
+ $1),
|
|
|
+- chainon ($2, all_prefix_attributes)); }
|
|
|
++ chainon ($3, all_prefix_attributes)), $2); }
|
|
|
+ ;
|
|
|
++ /* end-TIGCC-local (regparms) */
|
|
|
+
|
|
|
+ absdcl1: /* a nonempty absolute declarator */
|
|
|
+ absdcl1_ea
|
|
|
+@@ -2552,34 +2554,38 @@
|
|
|
+
|
|
|
+ parms:
|
|
|
+ firstparm
|
|
|
+- { push_parm_decl ($1); }
|
|
|
++/* begin-TIGCC-local (regparms): explicit register specification for parameters */
|
|
|
++ { push_parm_decl (TREE_PURPOSE($1), TREE_VALUE($1)); }
|
|
|
+ | parms ',' parm
|
|
|
+- { push_parm_decl ($3); }
|
|
|
++ { push_parm_decl (TREE_PURPOSE($3), TREE_VALUE($3)); }
|
|
|
+ ;
|
|
|
+
|
|
|
+ /* A single parameter declaration or parameter type name,
|
|
|
+ as found in a parmlist. */
|
|
|
+ parm:
|
|
|
+- declspecs_ts setspecs parm_declarator maybe_attribute
|
|
|
+- { $$ = build_tree_list (build_tree_list (current_declspecs,
|
|
|
++ declspecs_ts setspecs parm_declarator maybeasm maybe_attribute
|
|
|
++ { $$ = build_tree_list (
|
|
|
++ build_tree_list (build_tree_list (current_declspecs,
|
|
|
+ $3),
|
|
|
+- chainon ($4, all_prefix_attributes));
|
|
|
++ chainon ($5, all_prefix_attributes)), $4);
|
|
|
+ POP_DECLSPEC_STACK; }
|
|
|
+- | declspecs_ts setspecs notype_declarator maybe_attribute
|
|
|
+- { $$ = build_tree_list (build_tree_list (current_declspecs,
|
|
|
++ | declspecs_ts setspecs notype_declarator maybeasm maybe_attribute
|
|
|
++ { $$ = build_tree_list (
|
|
|
++ build_tree_list (build_tree_list (current_declspecs,
|
|
|
+ $3),
|
|
|
+- chainon ($4, all_prefix_attributes));
|
|
|
++ chainon ($5, all_prefix_attributes)), $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
|
|
|
+- { $$ = build_tree_list (build_tree_list (current_declspecs,
|
|
|
++ | declspecs_nots setspecs notype_declarator maybeasm maybe_attribute
|
|
|
++ { $$ = build_tree_list (
|
|
|
++ build_tree_list (build_tree_list (current_declspecs,
|
|
|
+ $3),
|
|
|
+- chainon ($4, all_prefix_attributes));
|
|
|
++ chainon ($5, all_prefix_attributes)), $4);
|
|
|
+ POP_DECLSPEC_STACK; }
|
|
|
+
|
|
|
+- | declspecs_nots setspecs absdcl_maybe_attribute
|
|
|
++ | declspecs_nots setspecs absdcl_maybeasm_maybe_attribute
|
|
|
+ { $$ = $3;
|
|
|
+ POP_DECLSPEC_STACK; }
|
|
|
+ ;
|
|
|
+@@ -2587,29 +2593,33 @@
|
|
|
+ /* 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
|
|
|
+- { $$ = build_tree_list (build_tree_list (current_declspecs,
|
|
|
++ declspecs_ts_nosa setspecs_fp parm_declarator maybeasm maybe_attribute
|
|
|
++ { $$ = build_tree_list (
|
|
|
++ build_tree_list (build_tree_list (current_declspecs,
|
|
|
+ $3),
|
|
|
+- chainon ($4, all_prefix_attributes));
|
|
|
++ chainon ($5, all_prefix_attributes)), $4);
|
|
|
+ POP_DECLSPEC_STACK; }
|
|
|
+- | declspecs_ts_nosa setspecs_fp notype_declarator maybe_attribute
|
|
|
+- { $$ = build_tree_list (build_tree_list (current_declspecs,
|
|
|
++ | declspecs_ts_nosa setspecs_fp notype_declarator maybeasm maybe_attribute
|
|
|
++ { $$ = build_tree_list (
|
|
|
++ build_tree_list (build_tree_list (current_declspecs,
|
|
|
+ $3),
|
|
|
+- chainon ($4, all_prefix_attributes));
|
|
|
++ chainon ($5, all_prefix_attributes)), $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
|
|
|
+- { $$ = build_tree_list (build_tree_list (current_declspecs,
|
|
|
++ | declspecs_nots_nosa setspecs_fp notype_declarator maybeasm maybe_attribute
|
|
|
++ { $$ = build_tree_list (
|
|
|
++ build_tree_list (build_tree_list (current_declspecs,
|
|
|
+ $3),
|
|
|
+- chainon ($4, all_prefix_attributes));
|
|
|
++ chainon ($5, all_prefix_attributes)), $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
|
|
|
+@@ -3084,26 +3094,30 @@
|
|
|
+
|
|
|
+ myparms:
|
|
|
+ myparm
|
|
|
+- { push_parm_decl ($1); }
|
|
|
+- | myparms ',' myparm
|
|
|
+- { push_parm_decl ($3); }
|
|
|
++/* begin-TIGCC-local (regparms): explicit register specification for parameters */
|
|
|
++ { push_parm_decl (TREE_PURPOSE($1), TREE_VALUE($1)); }
|
|
|
++ | myparms ',' myparm
|
|
|
++ { push_parm_decl (TREE_PURPOSE($3), TREE_VALUE($3)); }
|
|
|
+ ;
|
|
|
+
|
|
|
+ /* A single parameter declaration or parameter type name,
|
|
|
+- as found in a parmlist. DOES NOT ALLOW AN INITIALIZER OR ASMSPEC */
|
|
|
++ as found in a parmlist. DOES NOT ALLOW AN INITIALIZER */
|
|
|
+
|
|
|
+ myparm:
|
|
|
+- parm_declarator maybe_attribute
|
|
|
+- { $$ = build_tree_list (build_tree_list (current_declspecs,
|
|
|
++ parm_declarator maybeasm maybe_attribute
|
|
|
++ { $$ = build_tree_list (
|
|
|
++ build_tree_list (build_tree_list (current_declspecs,
|
|
|
+ $1),
|
|
|
+- chainon ($2, all_prefix_attributes)); }
|
|
|
+- | notype_declarator maybe_attribute
|
|
|
+- { $$ = build_tree_list (build_tree_list (current_declspecs,
|
|
|
++ chainon ($3, all_prefix_attributes)), $2); }
|
|
|
++ | notype_declarator maybeasm maybe_attribute
|
|
|
++ { $$ = build_tree_list (
|
|
|
++ build_tree_list (build_tree_list (current_declspecs,
|
|
|
+ $1),
|
|
|
+- chainon ($2, all_prefix_attributes)); }
|
|
|
+- | absdcl_maybe_attribute
|
|
|
++ chainon ($3, all_prefix_attributes)), $2); }
|
|
|
++ | absdcl_maybeasm_maybe_attribute
|
|
|
+ { $$ = $1; }
|
|
|
+ ;
|
|
|
++/* end-TIGCC-local (regparms) */
|
|
|
+
|
|
|
+ optparmlist:
|
|
|
+ /* empty */
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/c-pretty-print.c gcc-3.3.3.tigcc8/gcc/c-pretty-print.c
|
|
|
+--- gcc-3.3.3.orig/gcc/c-pretty-print.c Wed Oct 16 02:40:26 2002
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/c-pretty-print.c Thu Feb 19 21:20:02 2004
|
|
|
+@@ -469,9 +469,8 @@
|
|
|
+ c_pretty_printer ppi;
|
|
|
+ tree r;
|
|
|
+ {
|
|
|
+- real_to_decimal (pp_buffer (ppi)->digit_buffer, &TREE_REAL_CST (r),
|
|
|
+- sizeof (pp_buffer (ppi)->digit_buffer), 0, 1);
|
|
|
+- pp_identifier (ppi, pp_buffer(ppi)->digit_buffer);
|
|
|
++ REAL_VALUE_TO_STRING (TREE_REAL_CST (r), pp_buffer (ppi)->digit_buffer);
|
|
|
++ pp_identifier (ppi, pp_buffer (ppi)->digit_buffer);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/c-tree.h gcc-3.3.3.tigcc8/gcc/c-tree.h
|
|
|
+--- gcc-3.3.3.orig/gcc/c-tree.h Mon Sep 16 20:33:18 2002
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/c-tree.h Thu Feb 19 21:20:02 2004
|
|
|
+@@ -222,7 +222,9 @@
|
|
|
+ extern void c_pop_function_context PARAMS ((struct function *));
|
|
|
+ extern void pop_label_level PARAMS ((void));
|
|
|
+ extern void push_label_level PARAMS ((void));
|
|
|
+-extern void push_parm_decl PARAMS ((tree));
|
|
|
++/* begin-TIGCC-local (regparms): explicit register specification for parameters */
|
|
|
++extern void push_parm_decl PARAMS ((tree, tree));
|
|
|
++/* end-TIGCC-local (regparms) */
|
|
|
+ extern tree pushdecl_top_level PARAMS ((tree));
|
|
|
+ extern void pushtag PARAMS ((tree, tree));
|
|
|
+ extern tree set_array_declarator_type PARAMS ((tree, tree, int));
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/c-typeck.c gcc-3.3.3.tigcc8/gcc/c-typeck.c
|
|
|
+--- gcc-3.3.3.orig/gcc/c-typeck.c Tue Dec 23 06:23:32 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/c-typeck.c Thu Feb 19 21:20:02 2004
|
|
|
+@@ -47,9 +47,6 @@
|
|
|
+ message within this initializer. */
|
|
|
+ static int missing_braces_mentioned;
|
|
|
+
|
|
|
+-/* 1 if we explained undeclared var errors. */
|
|
|
+-static int undeclared_variable_notice;
|
|
|
+-
|
|
|
+ static tree qualify_type PARAMS ((tree, tree));
|
|
|
+ static int comp_target_types PARAMS ((tree, tree, int));
|
|
|
+ static int function_types_compatible_p PARAMS ((tree, tree));
|
|
|
+@@ -876,7 +873,10 @@
|
|
|
+ }
|
|
|
+
|
|
|
+ lvalue_array_p = !not_lvalue && lvalue_p (exp);
|
|
|
+- if (!flag_isoc99 && !lvalue_array_p)
|
|
|
++
|
|
|
++ if (!flag_isoc99 && !lvalue_array_p
|
|
|
++ && !(flag_global_compound_literals
|
|
|
++ && (TREE_CODE (exp) == CONSTRUCTOR && TREE_STATIC (exp))) )
|
|
|
+ {
|
|
|
+ /* Before C99, non-lvalue arrays do not decay to pointers.
|
|
|
+ Normally, using such an array would be invalid; but it can
|
|
|
+@@ -1417,13 +1417,6 @@
|
|
|
+ {
|
|
|
+ error ("`%s' undeclared (first use in this function)",
|
|
|
+ IDENTIFIER_POINTER (id));
|
|
|
+-
|
|
|
+- if (! undeclared_variable_notice)
|
|
|
+- {
|
|
|
+- error ("(Each undeclared identifier is reported only once");
|
|
|
+- error ("for each function it appears in.)");
|
|
|
+- undeclared_variable_notice = 1;
|
|
|
+- }
|
|
|
+ }
|
|
|
+ IDENTIFIER_GLOBAL_VALUE (id) = error_mark_node;
|
|
|
+ IDENTIFIER_ERROR_LOCUS (id) = current_function_decl;
|
|
|
+@@ -3033,6 +3026,12 @@
|
|
|
+ }
|
|
|
+ #endif
|
|
|
+
|
|
|
++ /* (TIGCC) In global compound literal mode, allow the address of a
|
|
|
++ constructor if all the elements are constant. */
|
|
|
++ if (flag_global_compound_literals
|
|
|
++ && (TREE_CODE (arg) == CONSTRUCTOR && TREE_CONSTANT (arg)))
|
|
|
++ ;
|
|
|
++
|
|
|
+ /* Anything not already handled and not a true memory reference
|
|
|
+ or a non-lvalue array is an error. */
|
|
|
+ else if (typecode != FUNCTION_TYPE && !flag
|
|
|
+@@ -4646,10 +4645,11 @@
|
|
|
+ {
|
|
|
+ char *ofwhat;
|
|
|
+
|
|
|
+- error ("%s", _(msgid));
|
|
|
+ ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
|
|
|
+ if (*ofwhat)
|
|
|
+- error ("(near initialization for `%s')", ofwhat);
|
|
|
++ error ("%s (near initialization for `%s')", _(msgid), ofwhat);
|
|
|
++ else
|
|
|
++ error ("%s", _(msgid));
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Issue a pedantic warning for a bad initializer component.
|
|
|
+@@ -4662,10 +4662,11 @@
|
|
|
+ {
|
|
|
+ char *ofwhat;
|
|
|
+
|
|
|
+- pedwarn ("%s", _(msgid));
|
|
|
+ ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
|
|
|
+ if (*ofwhat)
|
|
|
+- pedwarn ("(near initialization for `%s')", ofwhat);
|
|
|
++ pedwarn ("%s (near initialization for `%s')", _(msgid), ofwhat);
|
|
|
++ else
|
|
|
++ pedwarn ("%s", _(msgid));
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Issue a warning for a bad initializer component.
|
|
|
+@@ -4678,10 +4679,11 @@
|
|
|
+ {
|
|
|
+ char *ofwhat;
|
|
|
+
|
|
|
+- warning ("%s", _(msgid));
|
|
|
+ ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
|
|
|
+ if (*ofwhat)
|
|
|
+- warning ("(near initialization for `%s')", ofwhat);
|
|
|
++ warning ("%s (near initialization for `%s')", _(msgid), ofwhat);
|
|
|
++ else
|
|
|
++ warning ("%s", _(msgid));
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Digest the parser output INIT as an initializer for type TYPE.
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/collect2.c gcc-3.3.3.tigcc8/gcc/collect2.c
|
|
|
+--- gcc-3.3.3.orig/gcc/collect2.c Mon Dec 8 19:02:38 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/collect2.c Thu Feb 19 21:20:02 2004
|
|
|
+@@ -161,6 +161,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
|
|
|
+@@ -444,7 +502,11 @@
|
|
|
+ #endif
|
|
|
+
|
|
|
+ signal (signo, SIG_DFL);
|
|
|
++#ifndef __MINGW32__
|
|
|
+ kill (getpid (), signo);
|
|
|
++#else
|
|
|
++ ExitProcess(signo);
|
|
|
++#endif
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+@@ -2111,6 +2173,7 @@
|
|
|
+ fflush (stderr);
|
|
|
+
|
|
|
+ /* Spawn child nm on pipe */
|
|
|
++#ifndef __MINGW32__
|
|
|
+ pid = vfork ();
|
|
|
+ if (pid == -1)
|
|
|
+ fatal_perror (VFORK_STRING);
|
|
|
+@@ -2130,6 +2193,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 (*) PARAMS ((int))) signal (SIGINT, SIG_IGN);
|
|
|
+@@ -2552,6 +2620,7 @@
|
|
|
+ fflush (stderr);
|
|
|
+
|
|
|
+ /* Spawn child ldd on pipe */
|
|
|
++#ifndef __MINGW32__
|
|
|
+ pid = vfork ();
|
|
|
+ if (pid == -1)
|
|
|
+ fatal_perror (VFORK_STRING);
|
|
|
+@@ -2571,6 +2640,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 (*) PARAMS ((int))) signal (SIGINT, SIG_IGN);
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/combine.c gcc-3.3.3.tigcc8/gcc/combine.c
|
|
|
+--- gcc-3.3.3.orig/gcc/combine.c Fri Jan 23 20:42:48 2004
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/combine.c Thu Feb 19 21:20:02 2004
|
|
|
+@@ -1477,10 +1477,19 @@
|
|
|
+ if (! INSN_P (insn))
|
|
|
+ return 1;
|
|
|
+
|
|
|
+- /* Never combine loads and stores involving hard regs. The register
|
|
|
+- allocator can usually handle such reg-reg moves by tying. If we allow
|
|
|
+- the combiner to make substitutions of hard regs, we risk aborting in
|
|
|
+- reload on machines that have SMALL_REGISTER_CLASSES.
|
|
|
++/* (TIGCC 20040219) Backport from mainline:
|
|
|
++2003-04-16 J"orn Rennecke <joern.rennecke@superh.com>
|
|
|
++
|
|
|
++ Re-apply this patch:
|
|
|
++
|
|
|
++ 2002-05-16 Dale Johannesen <dalej@apple.com>
|
|
|
++ * combine.c (cant_combine_insn_p): Reenable combinations
|
|
|
++ involving hard regs unless CLASS_LIKELY_SPILLED_P.
|
|
|
++-- Kevin Kofler */
|
|
|
++ /* Never combine loads and stores involving hard regs that are likely
|
|
|
++ to be spilled. The register allocator can usually handle such
|
|
|
++ reg-reg moves by tying. If we allow the combiner to make
|
|
|
++ substitutions of likely-spilled regs, we may abort in reload.
|
|
|
+ As an exception, we allow combinations involving fixed regs; these are
|
|
|
+ not available to the register allocator so there's no risk involved. */
|
|
|
+
|
|
|
+@@ -1495,9 +1504,11 @@
|
|
|
+ dest = SUBREG_REG (dest);
|
|
|
+ if (REG_P (src) && REG_P (dest)
|
|
|
+ && ((REGNO (src) < FIRST_PSEUDO_REGISTER
|
|
|
+- && ! fixed_regs[REGNO (src)])
|
|
|
++ && ! fixed_regs[REGNO (src)]
|
|
|
++ && CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (REGNO (src))))
|
|
|
+ || (REGNO (dest) < FIRST_PSEUDO_REGISTER
|
|
|
+- && ! fixed_regs[REGNO (dest)])))
|
|
|
++ && ! fixed_regs[REGNO (dest)]
|
|
|
++ && CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (REGNO (dest))))))
|
|
|
+ return 1;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/config/dbxcoff.h gcc-3.3.3.tigcc8/gcc/config/dbxcoff.h
|
|
|
+--- gcc-3.3.3.orig/gcc/config/dbxcoff.h Sun Sep 29 15:16:44 2002
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/config/dbxcoff.h Thu Feb 19 21:20:02 2004
|
|
|
+@@ -53,13 +53,20 @@
|
|
|
+
|
|
|
+ /* 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. */
|
|
|
+
|
|
|
+ #undef ASM_OUTPUT_SOURCE_LINE
|
|
|
+ #define ASM_OUTPUT_SOURCE_LINE(FILE, LINE) \
|
|
|
+ { if (write_symbols == SDB_DEBUG) { \
|
|
|
+ fprintf ((FILE), "\t.ln\t%d\n", \
|
|
|
+- ((sdb_begin_function_line > -1) \
|
|
|
+- ? (LINE) - sdb_begin_function_line : 1)); \
|
|
|
++ TARGET_COFFABSLINES \
|
|
|
++ ? (LINE) \
|
|
|
++ : ((sdb_begin_function_line > -1) \
|
|
|
++ ? (LINE) - sdb_begin_function_line : 1)); \
|
|
|
+ } else if (write_symbols == DBX_DEBUG) { \
|
|
|
+ static int sym_lineno = 1; \
|
|
|
+ char buffer[256]; \
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/config/m68k/m68k-coff.h gcc-3.3.3.tigcc8/gcc/config/m68k/m68k-coff.h
|
|
|
+--- gcc-3.3.3.orig/gcc/config/m68k/m68k-coff.h Fri Sep 3 19:10:48 1999
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/config/m68k/m68k-coff.h Thu Feb 19 21:20:02 2004
|
|
|
+@@ -24,8 +24,16 @@
|
|
|
+ #define USE_GAS
|
|
|
+ #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)
|
|
|
++
|
|
|
+ #include "m68k/m68k-none.h"
|
|
|
+-#include "m68k/m68kemb.h"
|
|
|
+ #include "m68k/coff.h"
|
|
|
++#include "m68k/m68k-ti.h"
|
|
|
+
|
|
|
+ /* end of m68k-coff.h */
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/config/m68k/m68k-protos.h gcc-3.3.3.tigcc8/gcc/config/m68k/m68k-protos.h
|
|
|
+--- gcc-3.3.3.orig/gcc/config/m68k/m68k-protos.h Mon Oct 21 00:37:10 2002
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/config/m68k/m68k-protos.h Sun Feb 22 04:44:16 2004
|
|
|
+@@ -61,6 +61,8 @@
|
|
|
+ extern int nonimmediate_src_operand PARAMS ((rtx, enum machine_mode));
|
|
|
+ extern int memory_src_operand PARAMS ((rtx, enum machine_mode));
|
|
|
+ extern int pcrel_address PARAMS ((rtx, enum machine_mode));
|
|
|
++/* (TIGCC 20040222) used in the indirect_jump pattern -- Kevin Kofler */
|
|
|
++extern int extended_address_operand PARAMS ((rtx, enum machine_mode));
|
|
|
+ extern rtx legitimize_pic_address PARAMS ((rtx, enum machine_mode, rtx));
|
|
|
+ #endif /* RTX_CODE */
|
|
|
+
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/config/m68k/m68k-ti.h gcc-3.3.3.tigcc8/gcc/config/m68k/m68k-ti.h
|
|
|
+--- gcc-3.3.3.orig/gcc/config/m68k/m68k-ti.h Thu Jan 1 01:00:00 1970
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/config/m68k/m68k-ti.h Sat Jun 19 16:06:24 2004
|
|
|
+@@ -0,0 +1,225 @@
|
|
|
++/* 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. */
|
|
|
++
|
|
|
++/* Include special SMAP II BCD floating point support */
|
|
|
++#include <smapbcd.h>
|
|
|
++
|
|
|
++/* Define the output of the target version */
|
|
|
++
|
|
|
++#undef TARGET_VERSION
|
|
|
++#define TARGET_VERSION fprintf (stderr, " (MC68000 TI with COFF output)");
|
|
|
++
|
|
|
++/* Pass the right values to functions whose prototypes contain "char"
|
|
|
++ or "short". */
|
|
|
++
|
|
|
++#undef PROMOTE_PROTOTYPES
|
|
|
++
|
|
|
++/* 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", (ROUNDED)); \
|
|
|
++ fputs ("\t.even\n", (FILE)); \
|
|
|
++ } \
|
|
|
++ else \
|
|
|
++ { \
|
|
|
++ fputs (".comm ", (FILE)); \
|
|
|
++ assemble_name ((FILE), (NAME)); \
|
|
|
++ fprintf ((FILE), ",%u\n", (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", (ROUNDED)); \
|
|
|
++ fputs ("\t.even\n", (FILE)); \
|
|
|
++ } \
|
|
|
++ else \
|
|
|
++ { \
|
|
|
++ fputs (".lcomm ", (FILE)); \
|
|
|
++ assemble_name ((FILE), (NAME)); \
|
|
|
++ fprintf ((FILE), ",%u\n", (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
|
|
|
++
|
|
|
++/* 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. */
|
|
|
++
|
|
|
++#undef ASM_FILE_START
|
|
|
++#define ASM_FILE_START(FILE) \
|
|
|
++do { \
|
|
|
++ output_file_directive ((FILE), main_input_filename); \
|
|
|
++ fprintf ((FILE), "#NO_APP\n"); \
|
|
|
++ if (TARGET_REG_RELATIVE) \
|
|
|
++ fprintf ((FILE), "\t.set __relation,__ld_entry_point_plus_0x8000\n\t.xdef __ref_all___reg_relative_%s\n", TARGET_RELATION_REG); \
|
|
|
++ fprintf ((FILE), (TARGET_MERGE_SECTIONS?(TARGET_MERGE_TO_DATA?"\t.data\ntigcc_compiled.:\n":"\t.text\ntigcc_compiled.:\n"):"tigcc_compiled.:\n")); \
|
|
|
++} while (0)
|
|
|
++
|
|
|
++/* 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)
|
|
|
++
|
|
|
++/* end of m68k-ti.h */
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/config/m68k/m68k.c gcc-3.3.3.tigcc8/gcc/config/m68k/m68k.c
|
|
|
+--- gcc-3.3.3.orig/gcc/config/m68k/m68k.c Sat Jun 28 02:27:04 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/config/m68k/m68k.c Sat Sep 25 00:28:06 2004
|
|
|
+@@ -43,6 +43,9 @@
|
|
|
+ /* Needed for use_return_insn. */
|
|
|
+ #include "flags.h"
|
|
|
+
|
|
|
++/* TIGCC register for reg-relative code. */
|
|
|
++char TARGET_RELATION_REG[10] = "a4";
|
|
|
++
|
|
|
+ #ifdef SUPPORT_SUN_FPA
|
|
|
+
|
|
|
+ /* Index into this array by (register number >> 3) to find the
|
|
|
+@@ -68,6 +71,12 @@
|
|
|
+ static void m68k_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
|
|
|
+ HOST_WIDE_INT, tree));
|
|
|
+ static int m68k_save_reg PARAMS ((unsigned int));
|
|
|
++
|
|
|
++static int comp_m68k_type_attributes PARAMS ((tree, tree));
|
|
|
++static int comp_amigaos_type_attributes PARAMS ((tree, tree));
|
|
|
++const struct attribute_spec m68k_attribute_table[];
|
|
|
++static tree m68k_handle_stkparm_attribute PARAMS ((tree *, tree, tree, int, bool *));
|
|
|
++static tree m68k_handle_regparm_attribute PARAMS ((tree *, tree, tree, int, bool *));
|
|
|
+
|
|
|
+
|
|
|
+ /* Alignment to use for loops and jumps */
|
|
|
+@@ -77,6 +86,8 @@
|
|
|
+ const char *m68k_align_jumps_string;
|
|
|
+ /* Specify power of two alignment used for functions. */
|
|
|
+ const char *m68k_align_funcs_string;
|
|
|
++/* Specify number of registers for integer, pointer and float arguments. */
|
|
|
++const char *m68k_regparm_string;
|
|
|
+
|
|
|
+ /* Specify power of two alignment used for loops. */
|
|
|
+ int m68k_align_loops;
|
|
|
+@@ -84,6 +95,8 @@
|
|
|
+ int m68k_align_jumps;
|
|
|
+ /* Specify power of two alignment used for functions. */
|
|
|
+ int m68k_align_funcs;
|
|
|
++/* 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
|
|
|
+@@ -91,6 +104,11 @@
|
|
|
+ int m68k_last_compare_had_fp_operands;
|
|
|
+
|
|
|
+ /* Initialize the GCC target structure. */
|
|
|
++#undef TARGET_ATTRIBUTE_TABLE
|
|
|
++#define TARGET_ATTRIBUTE_TABLE m68k_attribute_table
|
|
|
++
|
|
|
++#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
|
|
|
+@@ -173,6 +191,20 @@
|
|
|
+
|
|
|
+ /* Validate -malign-functions= value, or provide default */
|
|
|
+ m68k_align_funcs = def_align;
|
|
|
++
|
|
|
++ /* 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;
|
|
|
++
|
|
|
+ if (m68k_align_funcs_string)
|
|
|
+ {
|
|
|
+ i = atoi (m68k_align_funcs_string);
|
|
|
+@@ -204,8 +236,10 @@
|
|
|
+
|
|
|
+ SUBTARGET_OVERRIDE_OPTIONS;
|
|
|
+
|
|
|
++#if 0 /* (TIGCC) We are not using ANY flavor of XFmode. */
|
|
|
+ /* Tell the compiler which flavor of XFmode we're using. */
|
|
|
+ real_format_for_mode[XFmode - QFmode] = &ieee_extended_motorola_format;
|
|
|
++#endif /* 0 */
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Return 1 if we need to save REGNO. */
|
|
|
+@@ -1736,7 +1770,14 @@
|
|
|
+ #else
|
|
|
+ return "moveq %1,%0";
|
|
|
+ #endif
|
|
|
++/* (TIGCC 20040211) Backport from mainline:
|
|
|
++2004-01-11 Andreas Schwab <schwab@suse.de>
|
|
|
++
|
|
|
++ * config/m68k/m68k.c (output_move_const_into_data_reg): Clear cc
|
|
|
++ status for NOTB/NOTW/NEGW methods.
|
|
|
++-- Kevin Kofler */
|
|
|
+ case NOTB :
|
|
|
++ CC_STATUS_INIT;
|
|
|
+ operands[1] = GEN_INT (i ^ 0xff);
|
|
|
+ #if defined (MOTOROLA) && !defined (CRDS)
|
|
|
+ return "moveq%.l %1,%0\n\tnot%.b %0";
|
|
|
+@@ -1744,6 +1785,7 @@
|
|
|
+ return "moveq %1,%0\n\tnot%.b %0";
|
|
|
+ #endif
|
|
|
+ case NOTW :
|
|
|
++ CC_STATUS_INIT;
|
|
|
+ operands[1] = GEN_INT (i ^ 0xffff);
|
|
|
+ #if defined (MOTOROLA) && !defined (CRDS)
|
|
|
+ return "moveq%.l %1,%0\n\tnot%.w %0";
|
|
|
+@@ -1751,6 +1793,7 @@
|
|
|
+ return "moveq %1,%0\n\tnot%.w %0";
|
|
|
+ #endif
|
|
|
+ case NEGW :
|
|
|
++ CC_STATUS_INIT;
|
|
|
+ #if defined (MOTOROLA) && !defined (CRDS)
|
|
|
+ return "moveq%.l %#-128,%0\n\tneg%.w %0";
|
|
|
+ #else
|
|
|
+@@ -1774,6 +1817,25 @@
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
++char *
|
|
|
++output_move_himode_const (operands)
|
|
|
++ 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_simode_const (operands)
|
|
|
+ rtx *operands;
|
|
|
+@@ -1995,6 +2057,15 @@
|
|
|
+ for moving operands[1] into operands[0] as a fullword. */
|
|
|
+
|
|
|
+ static const char *
|
|
|
++halfsinglemove_string (operands)
|
|
|
++ rtx *operands;
|
|
|
++{
|
|
|
++ if (GET_CODE (operands[1]) == CONST_INT)
|
|
|
++ return output_move_himode_const (operands);
|
|
|
++ return "move%.w %1,%0";
|
|
|
++}
|
|
|
++
|
|
|
++static const char *
|
|
|
+ singlemove_string (operands)
|
|
|
+ rtx *operands;
|
|
|
+ {
|
|
|
+@@ -2075,10 +2146,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
|
|
|
+@@ -2090,10 +2165,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
|
|
|
+@@ -2129,7 +2208,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
|
|
|
+ {
|
|
|
+@@ -2145,7 +2224,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)
|
|
|
+ {
|
|
|
+@@ -2177,8 +2256,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);
|
|
|
+@@ -2203,7 +2340,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
|
|
|
+@@ -2231,6 +2377,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]);
|
|
|
+@@ -2261,6 +2413,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. */
|
|
|
+@@ -2284,21 +2460,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)
|
|
|
+@@ -2306,7 +2485,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)
|
|
|
+@@ -2324,7 +2503,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);
|
|
|
+@@ -2341,19 +2520,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);
|
|
|
+@@ -2762,6 +2944,8 @@
|
|
|
+ floating_exact_log2 (x)
|
|
|
+ rtx x;
|
|
|
+ {
|
|
|
++abort();
|
|
|
++#if 0
|
|
|
+ REAL_VALUE_TYPE r, r1;
|
|
|
+ int exp;
|
|
|
+
|
|
|
+@@ -2776,6 +2960,7 @@
|
|
|
+ return exp;
|
|
|
+
|
|
|
+ return 0;
|
|
|
++#endif /* 0 */
|
|
|
+ }
|
|
|
+
|
|
|
+ #ifdef SUPPORT_SUN_FPA
|
|
|
+@@ -2986,6 +3171,8 @@
|
|
|
+ CONST_DOUBLE's as SunFPA constant RAM registers if
|
|
|
+ possible, so it should not be used except for the SunFPA.
|
|
|
+
|
|
|
++(TIGCC 20040222) 'A' like 'o', but for addresses.
|
|
|
++
|
|
|
+ */
|
|
|
+
|
|
|
+ void
|
|
|
+@@ -3062,6 +3249,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)
|
|
|
+ {
|
|
|
+ #ifdef SUPPORT_SUN_FPA
|
|
|
+@@ -3086,6 +3281,15 @@
|
|
|
+ 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
|
|
|
+@@ -3098,6 +3302,7 @@
|
|
|
+ fprintf (file, ":l");
|
|
|
+ #endif
|
|
|
+ }
|
|
|
++ }
|
|
|
+ }
|
|
|
+ #ifdef SUPPORT_SUN_FPA
|
|
|
+ else if ((letter == 'y' || letter == 'w')
|
|
|
+@@ -3107,6 +3312,7 @@
|
|
|
+ fprintf (file, "%%%d", i & 0x1ff);
|
|
|
+ }
|
|
|
+ #endif
|
|
|
++#if 0
|
|
|
+ else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == SFmode)
|
|
|
+ {
|
|
|
+ REAL_VALUE_TYPE r;
|
|
|
+@@ -3125,6 +3331,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'
|
|
|
+@@ -3564,7 +3771,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
|
|
|
+ }
|
|
|
+
|
|
|
+@@ -3709,13 +3916,317 @@
|
|
|
+ || 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 (op, mode)
|
|
|
++ 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. */
|
|
|
++
|
|
|
++void
|
|
|
++m68k_init_cumulative_args (cum, fntype)
|
|
|
++ CUMULATIVE_ARGS *cum;
|
|
|
++ tree fntype;
|
|
|
++{
|
|
|
++ 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);
|
|
|
++ }
|
|
|
++ }
|
|
|
++ 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 (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)))
|
|
|
++ cum->regs_already_used |= (1 << STRUCT_VALUE_REGNUM);
|
|
|
++#endif
|
|
|
++}
|
|
|
++
|
|
|
++/* Update the data in CUM to advance over an argument. */
|
|
|
++
|
|
|
++void
|
|
|
++m68k_function_arg_advance (cum)
|
|
|
++ 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. */
|
|
|
++
|
|
|
++struct rtx_def *
|
|
|
++m68k_function_arg (cum, mode, type)
|
|
|
++ 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;
|
|
|
++}
|
|
|
++
|
|
|
++/* (TIGCC) Attributes support. */
|
|
|
++
|
|
|
++/* Table of valid machine attributes. */
|
|
|
++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 },
|
|
|
++ /* The name NULL means the attribute list ends here. */
|
|
|
++ { NULL, 0, 0, false, false, false, NULL }
|
|
|
++};
|
|
|
++
|
|
|
++/* Handle a "stkparm" attribute;
|
|
|
++ arguments as in struct attribute_spec.handler. */
|
|
|
++static tree
|
|
|
++m68k_handle_stkparm_attribute (node, name, args, flags, no_add_attrs)
|
|
|
++ 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 (node, name, args, flags, no_add_attrs)
|
|
|
++ 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 (type1, type2)
|
|
|
++ tree type1, 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;
|
|
|
++}
|
|
|
++
|
|
|
+ const char *
|
|
|
+ output_andsi3 (operands)
|
|
|
+ rtx *operands;
|
|
|
+ {
|
|
|
+ int logval;
|
|
|
+ if (GET_CODE (operands[2]) == CONST_INT
|
|
|
+- && (INTVAL (operands[2]) | 0xffff) == 0xffffffff
|
|
|
++/* (TIGCC 20040925) This is a backport of a 64-bit cross fix from mainline by
|
|
|
++ Andreas Schwab. As he says, "((HOST_WIDE_INT) -43691 | 0xffff) can never
|
|
|
++ equal 0xffffffff when HOST_WIDE_INT has more than 32 bits. -- Kevin Kofler */
|
|
|
++ && (INTVAL (operands[2]) | 0xffff) == -1
|
|
|
+ && (DATA_REG_P (operands[0])
|
|
|
+ || offsettable_memref_p (operands[0]))
|
|
|
+ && !TARGET_5200)
|
|
|
+@@ -3831,13 +4342,28 @@
|
|
|
+ unsigned int flags;
|
|
|
+ {
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+
|
|
|
+ #ifdef CTOR_LIST_BEGIN
|
|
|
+@@ -3900,7 +4426,7 @@
|
|
|
+ if (flag_pic)
|
|
|
+ {
|
|
|
+ if (TARGET_PCREL)
|
|
|
+- fmt = "bra.l %o0";
|
|
|
++ fmt = "jra %o0"; /* (TIGCC 20040222) */
|
|
|
+ else
|
|
|
+ {
|
|
|
+ #ifdef MOTOROLA
|
|
|
+@@ -3937,3 +4463,105 @@
|
|
|
+
|
|
|
+ output_asm_insn (fmt, xops);
|
|
|
+ }
|
|
|
++
|
|
|
++/* 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)
|
|
|
++{
|
|
|
++ m68k_init_cumulative_args(cum, fntype);
|
|
|
++
|
|
|
++ 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) */
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/config/m68k/m68k.h gcc-3.3.3.tigcc8/gcc/config/m68k/m68k.h
|
|
|
+--- gcc-3.3.3.orig/gcc/config/m68k/m68k.h Tue Dec 3 19:45:30 2002
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/config/m68k/m68k.h Sun Aug 8 11:06:40 2004
|
|
|
+@@ -79,10 +79,8 @@
|
|
|
+ #define MASK_RTD 8
|
|
|
+ #define TARGET_RTD (target_flags & MASK_RTD)
|
|
|
+
|
|
|
+-/* Compile passing first two args in regs 0 and 1.
|
|
|
+- This exists only to test compiler features that will
|
|
|
+- be needed for RISC chips. It is not usable
|
|
|
+- and is not intended to be usable on this cpu. */
|
|
|
++/* Compile using the first 'm68k_regparm' data, address and float
|
|
|
++ registers for arguments passing. */
|
|
|
+ #define MASK_REGPARM 16
|
|
|
+ #define TARGET_REGPARM (target_flags & MASK_REGPARM)
|
|
|
+
|
|
|
+@@ -151,6 +149,39 @@
|
|
|
+ #define MASK_NO_STRICT_ALIGNMENT 16384
|
|
|
+ #define TARGET_STRICT_ALIGNMENT (~target_flags & MASK_NO_STRICT_ALIGNMENT)
|
|
|
+
|
|
|
++/* Use the TIOS calling convention */
|
|
|
++#define MASK_TIOS 32768
|
|
|
++#define TARGET_TIOS (target_flags & MASK_TIOS)
|
|
|
++
|
|
|
++/* Use the TIOS return convention for floats (not yet supported) */
|
|
|
++#define MASK_DIRECTFLOAT 65536
|
|
|
++#define TARGET_DIRECTFLOAT (target_flags & MASK_DIRECTFLOAT)
|
|
|
++
|
|
|
++/* Access everything in relation to a specific register */
|
|
|
++#define MASK_REG_RELATIVE 131072
|
|
|
++#define TARGET_REG_RELATIVE (target_flags & MASK_REG_RELATIVE)
|
|
|
++
|
|
|
++/* Use absolute line numbers in COFF debugging format */
|
|
|
++#define MASK_COFFABSLINES 524288
|
|
|
++#define TARGET_COFFABSLINES (target_flags & MASK_COFFABSLINES)
|
|
|
++
|
|
|
++/* Merge .text and .data sections (to .text) */
|
|
|
++#define MASK_MERGE_SECTIONS 2097152
|
|
|
++#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 4194304
|
|
|
++#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 8388608
|
|
|
++#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 16777216
|
|
|
++#define TARGET_NO_BSS (target_flags & MASK_NO_BSS)
|
|
|
++
|
|
|
+ /* Macro to define tables used to set the flags.
|
|
|
+ This is a list in braces of pairs in braces,
|
|
|
+ each pair being { "NAME", VALUE }
|
|
|
+@@ -180,8 +211,16 @@
|
|
|
+ N_("Use normal calling convention") }, \
|
|
|
+ { "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") }, \
|
|
|
+ { "fpa", -(MASK_SKY|MASK_68040_ONLY|MASK_68881), \
|
|
|
+ N_("Generate code for a Sun FPA") }, \
|
|
|
+ { "fpa", MASK_FPA, "" }, \
|
|
|
+@@ -237,14 +276,58 @@
|
|
|
+ { "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") }, \
|
|
|
+ { "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, \
|
|
|
+ N_("Use unaligned memory references") }, \
|
|
|
++ { "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 sun*.h and isi.h, etc. */
|
|
|
+@@ -265,6 +348,8 @@
|
|
|
+ N_("Jump targets are aligned to this power of 2") }, \
|
|
|
+ { "align-functions=", &m68k_align_funcs_string, \
|
|
|
+ N_("Function starts are aligned to this power of 2") }, \
|
|
|
++ { "regparm=", &m68k_regparm_string, \
|
|
|
++ N_("Number of register parameters of each register type") }, \
|
|
|
+ SUBTARGET_OPTIONS \
|
|
|
+ }
|
|
|
+
|
|
|
+@@ -284,6 +369,8 @@
|
|
|
+ #define SUBTARGET_OPTIONS
|
|
|
+ #define SUBTARGET_OVERRIDE_OPTIONS
|
|
|
+
|
|
|
++extern char TARGET_RELATION_REG[];
|
|
|
++
|
|
|
+ /* target machine storage layout */
|
|
|
+
|
|
|
+ /* Define for XFmode extended real floating point support. */
|
|
|
+@@ -316,7 +403,7 @@
|
|
|
+ #define UNITS_PER_WORD 4
|
|
|
+
|
|
|
+ /* Allocation boundary (in *bits*) for storing arguments in argument list. */
|
|
|
+-#define PARM_BOUNDARY (TARGET_SHORT ? 16 : 32)
|
|
|
++#define PARM_BOUNDARY 16
|
|
|
+
|
|
|
+ /* Boundary (in *bits*) on which stack pointer should be aligned. */
|
|
|
+ #define STACK_BOUNDARY 16
|
|
|
+@@ -817,6 +904,9 @@
|
|
|
+ `Q' means address register indirect addressing mode.
|
|
|
+ `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. */
|
|
|
++/* (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') \
|
|
|
+@@ -827,7 +917,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)) \
|
|
|
+@@ -998,10 +1088,17 @@
|
|
|
+
|
|
|
+ #define PCC_STATIC_STRUCT_RETURN
|
|
|
+
|
|
|
+-/* 1 if N is a possible register number for function argument passing.
|
|
|
+- On the 68000, no registers are used in this way. */
|
|
|
++/* Define this if explicit register specification for parameters
|
|
|
++ is supported. */
|
|
|
++
|
|
|
++#define EXPLICIT_REGPARM
|
|
|
+
|
|
|
+-#define FUNCTION_ARG_REGNO_P(N) 0
|
|
|
++/* 1 if N is a possible register number for function argument passing. */
|
|
|
++
|
|
|
++#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))
|
|
|
+
|
|
|
+ /* Define a data type for recording info about an argument list
|
|
|
+ during the scan of that argument list. This data type should
|
|
|
+@@ -1009,28 +1106,54 @@
|
|
|
+ and about the args processed so far, enough to enable macros
|
|
|
+ such as FUNCTION_ARG to determine where the next arg should go.
|
|
|
+
|
|
|
+- On the m68k, this is a single integer, which is a number of bytes
|
|
|
+- of arguments scanned so far. */
|
|
|
++ 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 7, so d0-d6, a0-a6 and fp0-fp6 can be used. */
|
|
|
++
|
|
|
++#define M68K_MAX_REGPARM 6 /* was 4 in the original patch */
|
|
|
+
|
|
|
+-#define CUMULATIVE_ARGS int
|
|
|
++/* 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 */
|
|
|
+
|
|
|
+ /* 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.
|
|
|
+-
|
|
|
+- On the m68k, the offset starts at 0. */
|
|
|
++ For a library call, FNTYPE is 0. */
|
|
|
+
|
|
|
+ #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) \
|
|
|
+- ((CUM) = 0)
|
|
|
++ (amigaos_init_cumulative_args (&(CUM), (FNTYPE)))
|
|
|
+
|
|
|
+ /* Update the data in CUM to advance over an argument
|
|
|
+ of mode MODE and data type TYPE.
|
|
|
+ (TYPE is null for libcalls where that information may not be available.) */
|
|
|
+
|
|
|
+ #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)))
|
|
|
+
|
|
|
+ /* Define where to put the arguments to a function.
|
|
|
+ Value is zero to push the argument on the stack,
|
|
|
+@@ -1045,24 +1168,14 @@
|
|
|
+ NAMED is nonzero if this argument is a named parameter
|
|
|
+ (otherwise it is an extra parameter matching an ellipsis). */
|
|
|
+
|
|
|
+-/* On the 68000 all args are pushed, except if -mregparm is specified
|
|
|
+- then the first two words of arguments are passed in d0, d1.
|
|
|
+- *NOTE* -mregparm does not work.
|
|
|
+- It exists only to test register calling conventions. */
|
|
|
+-
|
|
|
+ #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
|
|
|
+-((TARGET_REGPARM && (CUM) < 8) ? gen_rtx_REG ((MODE), (CUM) / 4) : 0)
|
|
|
++ ((struct rtx_def *)amigaos_function_arg (&(CUM), (MODE), (TYPE)))
|
|
|
+
|
|
|
+ /* For an arg passed partly in registers and partly in memory,
|
|
|
+ this is the number of registers used.
|
|
|
+ For args passed entirely in registers or entirely in memory, zero. */
|
|
|
+
|
|
|
+-#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
|
|
|
+-((TARGET_REGPARM && (CUM) < 8 \
|
|
|
+- && 8 < ((CUM) + ((MODE) == BLKmode \
|
|
|
+- ? int_size_in_bytes (TYPE) \
|
|
|
+- : GET_MODE_SIZE (MODE)))) \
|
|
|
+- ? 2 - (CUM) / 4 : 0)
|
|
|
++#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) (0)
|
|
|
+
|
|
|
+ /* Output assembler code to FILE to increment profiler label # LABELNO
|
|
|
+ for profiling a function entry. */
|
|
|
+@@ -1256,8 +1369,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. */
|
|
|
++/* (TIGCC 20040808) If reg-relative, we need to reject "constants" of the #label
|
|
|
++ or #label+const form. -- Kevin Kofler */
|
|
|
+
|
|
|
+-#define LEGITIMATE_CONSTANT_P(X) 1
|
|
|
++#define LEGITIMATE_CONSTANT_P(X) (!TARGET_REG_RELATIVE \
|
|
|
++ || !pcrel_address (X, VOIDmode))
|
|
|
+
|
|
|
+ /* Nonzero if the constant value X is a legitimate general operand
|
|
|
+ when generating PIC code. It is given that flag_pic is on and
|
|
|
+@@ -1554,8 +1670,13 @@
|
|
|
+ taking away a little more because sometimes move insns are needed. */
|
|
|
+ /* div?.w is relatively cheaper on 68000 counted in COSTS_N_INSNS terms. */
|
|
|
+ #define MULL_COST (TARGET_68060 ? 2 : TARGET_68040 ? 5 : 13)
|
|
|
+-#define MULW_COST (TARGET_68060 ? 2 : TARGET_68040 ? 3 : TARGET_68020 ? 8 : 5)
|
|
|
+-#define DIVW_COST (TARGET_68020 ? 27 : 12)
|
|
|
++/* (TIGCC 20030705) Decrease multiplication/division cost under -Os, so that
|
|
|
++ muls/divs/divu gets preferred over large expansions of
|
|
|
++ shifts & adds.
|
|
|
++ -- Kevin Kofler */
|
|
|
++#define MULW_COST (optimize_size ? 3 : (TARGET_68060 ? 2 : TARGET_68040 ? 3 : TARGET_68020 ? 8 : 5))
|
|
|
++#define DIVW_COST (optimize_size ? 3 : (TARGET_68020 ? 27 : 12))
|
|
|
++#define UDIVW_COST (optimize_size ? 6 : (TARGET_68020 ? 27 : 12))
|
|
|
+
|
|
|
+ #define RTX_COSTS(X,CODE,OUTER_CODE) \
|
|
|
+ case PLUS: \
|
|
|
+@@ -1579,11 +1700,12 @@
|
|
|
+ { \
|
|
|
+ if (GET_CODE (XEXP (X, 1)) == CONST_INT) \
|
|
|
+ { \
|
|
|
++/* (TIGCC 20030705) shifts costs under -Os are instruction counts, not cycle counts -- Kevin Kofler */ \
|
|
|
+ if (INTVAL (XEXP (X, 1)) < 16) \
|
|
|
+- return COSTS_N_INSNS (2) + INTVAL (XEXP (X, 1)) / 2; \
|
|
|
++ return COSTS_N_INSNS (2) + INTVAL (XEXP (X, 1)) / (optimize_size ? 9 : 2); \
|
|
|
+ else \
|
|
|
+ /* We're using clrw + swap for these cases. */ \
|
|
|
+- return COSTS_N_INSNS (4) + (INTVAL (XEXP (X, 1)) - 16) / 2; \
|
|
|
++ return COSTS_N_INSNS (4) + (INTVAL (XEXP (X, 1)) - 16) / (optimize_size ? 9 : 2); \
|
|
|
+ } \
|
|
|
+ return COSTS_N_INSNS (10); /* worst case */ \
|
|
|
+ } \
|
|
|
+@@ -1605,12 +1727,17 @@
|
|
|
+ return COSTS_N_INSNS (MULW_COST); \
|
|
|
+ else \
|
|
|
+ return COSTS_N_INSNS (MULL_COST); \
|
|
|
++/* (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) \
|
|
|
+ return COSTS_N_INSNS (DIVW_COST); /* div.w */ \
|
|
|
++ return COSTS_N_INSNS (43); /* div.l */ \
|
|
|
++ case UDIV: \
|
|
|
++ case UMOD: \
|
|
|
++ if (GET_MODE (X) == QImode || GET_MODE (X) == HImode) \
|
|
|
++ return COSTS_N_INSNS (UDIVW_COST); /* div.w */ \
|
|
|
+ return COSTS_N_INSNS (43); /* div.l */
|
|
|
+
|
|
|
+ /* Tell final.c how to eliminate redundant test instructions. */
|
|
|
+@@ -1812,18 +1939,22 @@
|
|
|
+ /* This says how to output an assembler line
|
|
|
+ to define a global common symbol. */
|
|
|
+
|
|
|
++#ifndef ASM_OUTPUT_COMMON
|
|
|
+ #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
|
|
|
+ ( fputs (".comm ", (FILE)), \
|
|
|
+ assemble_name ((FILE), (NAME)), \
|
|
|
+ fprintf ((FILE), ",%u\n", (ROUNDED)))
|
|
|
++#endif
|
|
|
+
|
|
|
+ /* This says how to output an assembler line
|
|
|
+ to define a local common symbol. */
|
|
|
+
|
|
|
++#ifndef ASM_OUTPUT_LOCAL
|
|
|
+ #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
|
|
|
+ ( fputs (".lcomm ", (FILE)), \
|
|
|
+ assemble_name ((FILE), (NAME)), \
|
|
|
+ fprintf ((FILE), ",%u\n", (ROUNDED)))
|
|
|
++#endif
|
|
|
+
|
|
|
+ /* Store in OUTPUT a string (made with alloca) containing
|
|
|
+ an assembler-name for a local static variable named NAME.
|
|
|
+@@ -1935,13 +2066,36 @@
|
|
|
+
|
|
|
+ #define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
|
|
|
+
|
|
|
++/* Attributes support. */
|
|
|
++
|
|
|
++#if 0 /* This has moved to TARGET_INITIALIZER, initialized in m68k.c. */
|
|
|
++
|
|
|
++/* A C expression whose value is nonzero if IDENTIFIER with arguments
|
|
|
++ ARGS is a valid machine specific attribute for TYPE. The attributes
|
|
|
++ in ATTRIBUTES have previously been assigned to TYPE. */
|
|
|
++
|
|
|
++#define VALID_MACHINE_TYPE_ATTRIBUTE(TYPE, ATTRIBUTES, IDENTIFIER, ARGS) \
|
|
|
++ (valid_m68k_type_attribute ((TYPE), (ATTRIBUTES), (IDENTIFIER), (ARGS)))
|
|
|
++
|
|
|
++/* A C expression whose value is 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). */
|
|
|
++
|
|
|
++#define COMP_TYPE_ATTRIBUTES(TYPE1, TYPE2) \
|
|
|
++ (comp_amigaos_type_attributes ((TYPE1), (TYPE2)))
|
|
|
++
|
|
|
++#endif
|
|
|
++
|
|
|
++
|
|
|
+ /* Variables in m68k.c */
|
|
|
+ extern const char *m68k_align_loops_string;
|
|
|
+ extern const char *m68k_align_jumps_string;
|
|
|
+ extern const char *m68k_align_funcs_string;
|
|
|
++extern const char *m68k_regparm_string;
|
|
|
+ extern int m68k_align_loops;
|
|
|
+ extern int m68k_align_jumps;
|
|
|
+ extern int m68k_align_funcs;
|
|
|
++extern int m68k_regparm;
|
|
|
+ extern int m68k_last_compare_had_fp_operands;
|
|
|
+
|
|
|
+
|
|
|
+@@ -1958,7 +2112,11 @@
|
|
|
+ {"const_sint32_operand", {CONST_INT}}, \
|
|
|
+ {"valid_dbcc_comparison_p", {EQ, NE, GTU, LTU, GEU, LEU, \
|
|
|
+ GT, LT, GE, LE}}, \
|
|
|
+- {"extend_operator", {SIGN_EXTEND, ZERO_EXTEND}},
|
|
|
++ {"extend_operator", {SIGN_EXTEND, ZERO_EXTEND}}, \
|
|
|
++ /* (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, ADDRESSOF, \
|
|
|
++ PLUS, MINUS, MULT}},
|
|
|
+
|
|
|
+ /*
|
|
|
+ Local variables:
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/config/m68k/m68k.md gcc-3.3.3.tigcc8/gcc/config/m68k/m68k.md
|
|
|
+--- gcc-3.3.3.orig/gcc/config/m68k/m68k.md Thu Jun 12 23:56:58 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/config/m68k/m68k.md Sun Aug 8 10:25:16 2004
|
|
|
+@@ -522,6 +522,8 @@
|
|
|
+ "!TARGET_5200"
|
|
|
+ "*
|
|
|
+ {
|
|
|
++/* (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)
|
|
|
+ #ifdef SGS_CMP_ORDER
|
|
|
+ return \"cmpm%.l %0,%1\";
|
|
|
+@@ -532,9 +534,9 @@
|
|
|
+ || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
|
|
|
+ { cc_status.flags |= CC_REVERSED;
|
|
|
+ #ifdef SGS_CMP_ORDER
|
|
|
+- return \"cmp%.l %d1,%d0\";
|
|
|
++ return \"cmp%.l %1,%0\";
|
|
|
+ #else
|
|
|
+- return \"cmp%.l %d0,%d1\";
|
|
|
++ return \"cmp%.l %0,%1\";
|
|
|
+ #endif
|
|
|
+ }
|
|
|
+ if (ADDRESS_REG_P (operands[0])
|
|
|
+@@ -549,9 +551,9 @@
|
|
|
+ #endif
|
|
|
+ }
|
|
|
+ #ifdef SGS_CMP_ORDER
|
|
|
+- return \"cmp%.l %d0,%d1\";
|
|
|
++ return \"cmp%.l %0,%1\";
|
|
|
+ #else
|
|
|
+- return \"cmp%.l %d1,%d0\";
|
|
|
++ return \"cmp%.l %1,%0\";
|
|
|
+ #endif
|
|
|
+ }")
|
|
|
+
|
|
|
+@@ -578,20 +580,28 @@
|
|
|
+ #endif
|
|
|
+ }")
|
|
|
+
|
|
|
++;; (TIGCC 20040808) Don't allow non-source 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_5200"
|
|
|
+ "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_5200"
|
|
|
+ "*
|
|
|
+ {
|
|
|
++/* (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)
|
|
|
+ #ifdef SGS_CMP_ORDER
|
|
|
+ return \"cmpm%.w %0,%1\";
|
|
|
+@@ -602,32 +612,34 @@
|
|
|
+ || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
|
|
|
+ { cc_status.flags |= CC_REVERSED;
|
|
|
+ #ifdef SGS_CMP_ORDER
|
|
|
+- return \"cmp%.w %d1,%d0\";
|
|
|
++ return \"cmp%.w %1,%0\";
|
|
|
+ #else
|
|
|
+- return \"cmp%.w %d0,%d1\";
|
|
|
++ return \"cmp%.w %0,%1\";
|
|
|
+ #endif
|
|
|
+ }
|
|
|
+ #ifdef SGS_CMP_ORDER
|
|
|
+- return \"cmp%.w %d0,%d1\";
|
|
|
++ return \"cmp%.w %0,%1\";
|
|
|
+ #else
|
|
|
+- return \"cmp%.w %d1,%d0\";
|
|
|
++ return \"cmp%.w %1,%0\";
|
|
|
+ #endif
|
|
|
+ }")
|
|
|
+
|
|
|
+ (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_5200"
|
|
|
+ "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_5200"
|
|
|
+ "*
|
|
|
+ {
|
|
|
++/* (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)
|
|
|
+ #ifdef SGS_CMP_ORDER
|
|
|
+ return \"cmpm%.b %0,%1\";
|
|
|
+@@ -638,15 +650,15 @@
|
|
|
+ || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
|
|
|
+ { cc_status.flags |= CC_REVERSED;
|
|
|
+ #ifdef SGS_CMP_ORDER
|
|
|
+- return \"cmp%.b %d1,%d0\";
|
|
|
++ return \"cmp%.b %1,%0\";
|
|
|
+ #else
|
|
|
+- return \"cmp%.b %d0,%d1\";
|
|
|
++ return \"cmp%.b %0,%1\";
|
|
|
+ #endif
|
|
|
+ }
|
|
|
+-#ifdef SGS_CMP_ORDER
|
|
|
+- return \"cmp%.b %d0,%d1\";
|
|
|
++#ifdef SGS_CMP_ORDER
|
|
|
++ return \"cmp%.b %0,%1\";
|
|
|
+ #else
|
|
|
+- return \"cmp%.b %d1,%d0\";
|
|
|
++ return \"cmp%.b %1,%0\";
|
|
|
+ #endif
|
|
|
+ }")
|
|
|
+
|
|
|
+@@ -998,10 +1010,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))
|
|
|
+@@ -1251,6 +1264,31 @@
|
|
|
+ "TARGET_5200"
|
|
|
+ "* return output_move_double (operands);")
|
|
|
+
|
|
|
++(define_expand "movbf"
|
|
|
++ ;; SMAP BCD
|
|
|
++ [(set (match_operand:BF 0 "nonimmediate_operand" "")
|
|
|
++ (match_operand:BF 1 "general_operand" ""))]
|
|
|
++ ""
|
|
|
++ "
|
|
|
++{
|
|
|
++ if (CONSTANT_P (operands[1]))
|
|
|
++ {
|
|
|
++ operands[1] = force_const_mem (BFmode, operands[1]);
|
|
|
++ if (! memory_address_p (BFmode, XEXP (operands[1], 0))
|
|
|
++ && ! reload_in_progress)
|
|
|
++ operands[1] = adjust_address (operands[1], BFmode, 0);
|
|
|
++ }
|
|
|
++ if (flag_pic && TARGET_PCREL && ! reload_in_progress)
|
|
|
++ {
|
|
|
++ /* 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" ""))]
|
|
|
+@@ -1317,6 +1355,48 @@
|
|
|
+ ")
|
|
|
+
|
|
|
+ (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_5200"
|
|
|
++ "*
|
|
|
++{
|
|
|
++ 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_5200"
|
|
|
+@@ -4844,7 +4924,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\";
|
|
|
+ }
|
|
|
+ } ")
|
|
|
+@@ -7318,7 +7402,7 @@
|
|
|
+ if (GET_CODE (operands[0]) == MEM
|
|
|
+ && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
|
|
|
+ {
|
|
|
+- if (TARGET_PCREL) return \"bsr.l %o0\";
|
|
|
++ if (TARGET_PCREL) return \"jbsr %o0\"; /* (TIGCC 20040222) */
|
|
|
+ #ifdef MOTOROLA
|
|
|
+ #ifdef HPUX_ASM
|
|
|
+ return \"bsr.l %0\";
|
|
|
+@@ -7388,7 +7472,7 @@
|
|
|
+ if (GET_CODE (operands[1]) == MEM
|
|
|
+ && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
|
|
|
+ {
|
|
|
+- if (TARGET_PCREL) return \"bsr.l %o1\";
|
|
|
++ if (TARGET_PCREL) return \"jbsr %o1\"; /* (TIGCC 20040222) */
|
|
|
+ #ifdef MOTOROLA
|
|
|
+ #ifdef HPUX_ASM
|
|
|
+ return \"bsr.l %1\";
|
|
|
+@@ -7475,10 +7559,13 @@
|
|
|
+ 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
|
|
|
+ (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")
|
|
|
++ "jra %A0")
|
|
|
+
|
|
|
+ ;; This should not be used unless the add/sub insns can't be.
|
|
|
+
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/config/smapbcd.h gcc-3.3.3.tigcc8/gcc/config/smapbcd.h
|
|
|
+--- gcc-3.3.3.orig/gcc/config/smapbcd.h Thu Jan 1 01:00:00 1970
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/config/smapbcd.h Thu Feb 19 21:20:02 2004
|
|
|
+@@ -0,0 +1,507 @@
|
|
|
++/* 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
|
|
|
++
|
|
|
++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. */
|
|
|
++
|
|
|
++#include <math.h> /* finite() */
|
|
|
++#undef NAN
|
|
|
++
|
|
|
++#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))
|
|
|
++
|
|
|
++#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_ISFINITE (x) \
|
|
|
++ && REAL_VALUE_ISFINITE (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) \
|
|
|
++ (strchr(string,'p') ? REAL_VALUE_HTOF(string,mode) \
|
|
|
++ : REAL_VALUE_DTOF(string,mode))
|
|
|
++
|
|
|
++#undef REAL_VALUE_DTOF
|
|
|
++#define REAL_VALUE_DTOF(string,mode) \
|
|
|
++__extension__ ({ \
|
|
|
++ REAL_VALUE_TYPE r; \
|
|
|
++ 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 = 0x4000; \
|
|
|
++ r.mantissa = 0; \
|
|
|
++ while (strpart && *strpart) \
|
|
|
++ { \
|
|
|
++ switch (state) \
|
|
|
++ { \
|
|
|
++ case 0: \
|
|
|
++ if (*strpart == '.') \
|
|
|
++ { \
|
|
|
++ state = 1; \
|
|
|
++ break; \
|
|
|
++ } \
|
|
|
++ else if (*strpart == '+') \
|
|
|
++ expadd = 0x4000; \
|
|
|
++ else if (*strpart == '-') \
|
|
|
++ expadd = 0xC000; \
|
|
|
++ else if (((*strpart) >= '0' && (*strpart) <= '9') && ((r.mantissa) || (*strpart != '0'))) \
|
|
|
++ expshift++; \
|
|
|
++ else if ((*strpart == 'i') || (*strpart == 'I')) \
|
|
|
++ { \
|
|
|
++ if (expadd == 0xC000) \
|
|
|
++ r = NEGATIVE_INF; \
|
|
|
++ else \
|
|
|
++ r = POSITIVE_INF; \
|
|
|
++ expadd = 0x7FFF; \
|
|
|
++ strpart = 0; \
|
|
|
++ } \
|
|
|
++ else if ((*strpart == 'n') || (*strpart == 'N')) \
|
|
|
++ { \
|
|
|
++ r = NAN; \
|
|
|
++ expadd = 0x7FFF; \
|
|
|
++ strpart = 0; \
|
|
|
++ } \
|
|
|
++ case 1: \
|
|
|
++ if ((*strpart == 'e') || (*strpart == 'E')) \
|
|
|
++ state = 2; \
|
|
|
++ else if ((*strpart) >= '0' && (*strpart) <= '9') \
|
|
|
++ { \
|
|
|
++ r.mantissa |= (*strpart - '0') * mpmul; \
|
|
|
++ 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) \
|
|
|
++ ((unsigned long) (strpart))++; \
|
|
|
++ else \
|
|
|
++ break; \
|
|
|
++ } \
|
|
|
++ if (!(r.mantissa)) \
|
|
|
++ r = ZERO; \
|
|
|
++ else if (expadd != 0x7FFF) \
|
|
|
++ r.exponent = exp * expmul + expadd + expshift; \
|
|
|
++ r; \
|
|
|
++})
|
|
|
++
|
|
|
++#undef REAL_VALUE_HTOF
|
|
|
++#define REAL_VALUE_HTOF(string,mode) \
|
|
|
++__extension__ ({ \
|
|
|
++ REAL_VALUE_TYPE res; \
|
|
|
++ char tempstr [100]; \
|
|
|
++ double r = 0.0; \
|
|
|
++ char *strpart = string; \
|
|
|
++ signed char state = -1; \
|
|
|
++ unsigned long rdiv = 1; \
|
|
|
++ unsigned int negative = 0; \
|
|
|
++ unsigned short exp = 0; \
|
|
|
++ unsigned short expsign = 1; \
|
|
|
++ unsigned long exp2 = 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')) \
|
|
|
++ r *= 16.0; \
|
|
|
++ case 1: \
|
|
|
++ if (state == 1) \
|
|
|
++ rdiv *= 16; \
|
|
|
++ if ((*strpart == 'p') || (*strpart == 'P')) \
|
|
|
++ state = 2; \
|
|
|
++ else if (*strpart >= '0' && *strpart <= '9') \
|
|
|
++ r += ((double) (*strpart - '0')) / ((double) rdiv); \
|
|
|
++ else if (*strpart >= 'a' && *strpart <= 'f') \
|
|
|
++ r += ((double) (*strpart - 'a' + 0xA)) / ((double) rdiv); \
|
|
|
++ else if (*strpart >= 'A' && *strpart <= 'F') \
|
|
|
++ r += ((double) (*strpart - 'A' + 0xA)) / ((double) rdiv); \
|
|
|
++ break; \
|
|
|
++ case 2: \
|
|
|
++ if (*strpart == '+') \
|
|
|
++ expsign = 1; \
|
|
|
++ else if (*strpart == '-') \
|
|
|
++ expsign = -1; \
|
|
|
++ if ((*strpart) >= '0' && (*strpart) <= '9') \
|
|
|
++ { \
|
|
|
++ exp *= 10; \
|
|
|
++ exp += (*strpart - '0'); \
|
|
|
++ } \
|
|
|
++ break; \
|
|
|
++ } \
|
|
|
++ ((unsigned long) (strpart))++; \
|
|
|
++ } \
|
|
|
++ while (exp) \
|
|
|
++ { \
|
|
|
++ exp2 *= 2; \
|
|
|
++ exp--; \
|
|
|
++ } \
|
|
|
++ if (expsign == 1) \
|
|
|
++ r *= (double) exp2; \
|
|
|
++ else \
|
|
|
++ r /= (double) exp2; \
|
|
|
++ if (negative) \
|
|
|
++ r = -r; \
|
|
|
++ if (!finite(r)) {sorry("floating point constant too large for host double"); abort();} \
|
|
|
++ sprintf (tempstr, "%.32e", r); \
|
|
|
++ res = REAL_VALUE_DTOF (tempstr, mode); \
|
|
|
++ res; \
|
|
|
++})
|
|
|
++
|
|
|
++#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_VALUE_TO_INT ereal_to_int
|
|
|
++
|
|
|
++#define REAL_VALUE_FROM_INT(d, lo, hi, mode) \
|
|
|
++ ereal_from_int (&d, (HOST_WIDE_INT) (lo), (HOST_WIDE_INT) (hi), mode)
|
|
|
++
|
|
|
++#define REAL_VALUE_FROM_UNSIGNED_INT(d, lo, hi, mode) \
|
|
|
++ ereal_from_uint (&d, lo, hi, mode)
|
|
|
++
|
|
|
++#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_ISFINITE (f)) \
|
|
|
++ { \
|
|
|
++ long exp; \
|
|
|
++ int neg = REAL_VALUE_ISNEGATIVE (f); \
|
|
|
++ if (neg) \
|
|
|
++ exp = f.exponent - 0xC000; \
|
|
|
++ else \
|
|
|
++ exp = f.exponent - 0x4000; \
|
|
|
++ sprintf ((OUT), "%s0.%08lx%08lxe%d\n", neg ? "-" : "", (unsigned long) (f.mantissa / 0x100000000), (unsigned long) (f.mantissa), (short) (exp + 1)); \
|
|
|
++ } \
|
|
|
++ else \
|
|
|
++ sprintf ((OUT), "Error"); \
|
|
|
++} 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)
|
|
|
++
|
|
|
++/* end of smapbcd.h */
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/cppdefault.c gcc-3.3.3.tigcc8/gcc/cppdefault.c
|
|
|
+--- gcc-3.3.3.orig/gcc/cppdefault.c Thu Nov 6 23:13:30 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/cppdefault.c Thu Feb 19 21:20:02 2004
|
|
|
+@@ -31,6 +31,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 },
|
|
|
+@@ -70,11 +71,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-3.3.3.orig/gcc/cppexp.c gcc-3.3.3.tigcc8/gcc/cppexp.c
|
|
|
+--- gcc-3.3.3.orig/gcc/cppexp.c Sun Aug 3 17:58:06 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/cppexp.c Thu Feb 19 21:20:02 2004
|
|
|
+@@ -178,6 +178,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. */
|
|
|
+@@ -212,11 +219,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)
|
|
|
+ {
|
|
|
+@@ -298,6 +309,8 @@
|
|
|
+ result |= CPP_N_DECIMAL;
|
|
|
+ else if (radix == 16)
|
|
|
+ result |= CPP_N_HEX;
|
|
|
++ else if (radix == 2)
|
|
|
++ result |= CPP_N_BINARY;
|
|
|
+ else
|
|
|
+ result |= CPP_N_OCTAL;
|
|
|
+
|
|
|
+@@ -348,6 +361,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-3.3.3.orig/gcc/cpphash.h gcc-3.3.3.tigcc8/gcc/cpphash.h
|
|
|
+--- gcc-3.3.3.orig/gcc/cpphash.h Tue Dec 2 01:56:18 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/cpphash.h Thu Feb 19 21:20:02 2004
|
|
|
+@@ -385,6 +385,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). */
|
|
|
++ unsigned int mls_line;
|
|
|
++ unsigned int mls_col;
|
|
|
++
|
|
|
+ /* Buffer to hold macro definition string. */
|
|
|
+ unsigned char *macro_buffer;
|
|
|
+ unsigned int macro_buffer_len;
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/cppinit.c gcc-3.3.3.tigcc8/gcc/cppinit.c
|
|
|
+--- gcc-3.3.3.orig/gcc/cppinit.c Tue Nov 18 22:23:46 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/cppinit.c Thu Feb 19 21:20:02 2004
|
|
|
+@@ -543,6 +543,7 @@
|
|
|
+ CPP_OPTION (pfile, int_precision) = CHAR_BIT * sizeof (int);
|
|
|
+ CPP_OPTION (pfile, unsigned_char) = 0;
|
|
|
+ CPP_OPTION (pfile, unsigned_wchar) = 1;
|
|
|
++ CPP_OPTION (pfile, no_auto_octals) = 0; /* (TIGCC) */
|
|
|
+
|
|
|
+ /* Initialize the line map. Start at logical line 1, so we can use
|
|
|
+ a line number of zero for special states. */
|
|
|
+@@ -982,7 +983,9 @@
|
|
|
+ _cpp_init_hashtable (pfile, table);
|
|
|
+
|
|
|
+ /* Set up the include search path now. */
|
|
|
+- if (! CPP_OPTION (pfile, no_standard_includes))
|
|
|
++ /* (TIGCC 20031007) We don't want any "standard" include directories.
|
|
|
++ -- Kevin Kofler */
|
|
|
++ if (0 /*! CPP_OPTION (pfile, no_standard_includes)*/)
|
|
|
+ init_standard_includes (pfile);
|
|
|
+
|
|
|
+ merge_include_chains (pfile);
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/cpplex.c gcc-3.3.3.tigcc8/gcc/cpplex.c
|
|
|
+--- gcc-3.3.3.orig/gcc/cpplex.c Fri Sep 27 00:25:12 2002
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/cpplex.c Thu Feb 19 21:20:02 2004
|
|
|
+@@ -75,6 +75,7 @@
|
|
|
+ static void parse_number PARAMS ((cpp_reader *, cpp_string *, int));
|
|
|
+ static int unescaped_terminator_p PARAMS ((cpp_reader *, const uchar *));
|
|
|
+ static void parse_string PARAMS ((cpp_reader *, cpp_token *, cppchar_t));
|
|
|
++static void unterminated PARAMS ((cpp_reader *, int));
|
|
|
+ static bool trigraph_p PARAMS ((cpp_reader *));
|
|
|
+ static void save_comment PARAMS ((cpp_reader *, cpp_token *, const uchar *,
|
|
|
+ cppchar_t));
|
|
|
+@@ -597,6 +598,22 @@
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
++/* Subroutine of parse_string. Emits error for unterminated strings. */
|
|
|
++static void
|
|
|
++unterminated (pfile, term)
|
|
|
++ cpp_reader *pfile;
|
|
|
++ int term;
|
|
|
++{
|
|
|
++ cpp_error (pfile, DL_ERROR, "missing terminating %c character", term);
|
|
|
++
|
|
|
++ if (term == '\"' && pfile->mls_line && pfile->mls_line != pfile->line)
|
|
|
++ {
|
|
|
++ cpp_error_with_line (pfile, DL_ERROR, pfile->mls_line, pfile->mls_col,
|
|
|
++ "possible start of unterminated string literal");
|
|
|
++ pfile->mls_line = 0;
|
|
|
++ }
|
|
|
++}
|
|
|
++
|
|
|
+ /* Subroutine of parse_string. */
|
|
|
+ static int
|
|
|
+ unescaped_terminator_p (pfile, dest)
|
|
|
+@@ -623,6 +640,7 @@
|
|
|
+ name. Handles embedded trigraphs and escaped newlines. The stored
|
|
|
+ string is guaranteed NUL-terminated, but it is not guaranteed that
|
|
|
+ this is the first NUL since embedded NULs are preserved.
|
|
|
++ Multi-line strings are allowed as a TIGCC extension (deprecated in the FSF GCC).
|
|
|
+
|
|
|
+ When this function returns, buffer->cur points to the next
|
|
|
+ character to be processed. */
|
|
|
+@@ -689,21 +707,43 @@
|
|
|
+ }
|
|
|
+ else if (is_vspace (c))
|
|
|
+ {
|
|
|
+- /* No string literal may extend over multiple lines. In
|
|
|
+- assembly language, suppress the error except for <>
|
|
|
+- includes. This is a kludge around not knowing where
|
|
|
+- comments are. */
|
|
|
+- unterminated:
|
|
|
+- if (CPP_OPTION (pfile, lang) != CLK_ASM || terminator == '>')
|
|
|
+- cpp_error (pfile, DL_ERROR, "missing terminating %c character",
|
|
|
+- (int) terminator);
|
|
|
+- buffer->cur--;
|
|
|
+- break;
|
|
|
++ /* 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 != '>')
|
|
|
++ {
|
|
|
++ buffer->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)
|
|
|
++ {
|
|
|
++ unterminated (pfile, terminator);
|
|
|
++ buffer->cur--;
|
|
|
++ break;
|
|
|
++ }
|
|
|
++
|
|
|
++ if (pfile->mls_line == 0)
|
|
|
++ {
|
|
|
++ pfile->mls_line = token->line;
|
|
|
++ pfile->mls_col = token->col;
|
|
|
++ }
|
|
|
++
|
|
|
++ handle_newline (pfile);
|
|
|
++ c = '\n';
|
|
|
+ }
|
|
|
+ else if (c == '\0')
|
|
|
+ {
|
|
|
+ if (buffer->cur - 1 == buffer->rlimit)
|
|
|
+- goto unterminated;
|
|
|
++ {
|
|
|
++ unterminated (pfile, terminator);
|
|
|
++ buffer->cur--;
|
|
|
++ break;
|
|
|
++ }
|
|
|
+ if (!warned_nulls)
|
|
|
+ {
|
|
|
+ warned_nulls = true;
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/cpplib.c gcc-3.3.3.tigcc8/gcc/cpplib.c
|
|
|
+--- gcc-3.3.3.orig/gcc/cpplib.c Thu Sep 25 01:52:30 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/cpplib.c Thu Feb 19 21:20:02 2004
|
|
|
+@@ -1076,6 +1076,7 @@
|
|
|
+ cpp_reader *pfile;
|
|
|
+ {
|
|
|
+ /* Pragmas in the global namespace. */
|
|
|
++ cpp_register_pragma (pfile, 0, "poison", do_pragma_poison); /* (TIGCC) */
|
|
|
+ cpp_register_pragma (pfile, 0, "once", do_pragma_once);
|
|
|
+
|
|
|
+ /* New GCC-specific pragmas should be put in the GCC namespace. */
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/cpplib.h gcc-3.3.3.tigcc8/gcc/cpplib.h
|
|
|
+--- gcc-3.3.3.orig/gcc/cpplib.h Thu Nov 6 23:13:30 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/cpplib.h Thu Feb 19 21:20:02 2004
|
|
|
+@@ -379,6 +379,9 @@
|
|
|
+ /* True for traditional preprocessing. */
|
|
|
+ unsigned char traditional;
|
|
|
+
|
|
|
++ /* (TIGCC) True if numbers starting with zero should NOT be octal. */
|
|
|
++ unsigned char no_auto_octals;
|
|
|
++
|
|
|
+ /* Dependency generation. */
|
|
|
+ struct
|
|
|
+ {
|
|
|
+@@ -630,6 +633,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
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/cppmacro.c gcc-3.3.3.tigcc8/gcc/cppmacro.c
|
|
|
+--- gcc-3.3.3.orig/gcc/cppmacro.c Thu Jun 19 07:40:28 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/cppmacro.c Thu Feb 19 21:20:02 2004
|
|
|
+@@ -816,6 +816,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
|
|
|
+@@ -849,6 +854,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 *));
|
|
|
+@@ -935,7 +967,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. */
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/cppmain.c gcc-3.3.3.tigcc8/gcc/cppmain.c
|
|
|
+--- gcc-3.3.3.orig/gcc/cppmain.c Sun Sep 14 15:26:36 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/cppmain.c Thu Feb 19 21:20:02 2004
|
|
|
+@@ -177,7 +177,8 @@
|
|
|
+ pfile->print.prev = token;
|
|
|
+ cpp_output_token (token, pfile->print.outf);
|
|
|
+
|
|
|
+- if (token->type == CPP_COMMENT)
|
|
|
++ if (token->type == CPP_STRING || token->type == CPP_WSTRING
|
|
|
++ || token->type == CPP_COMMENT)
|
|
|
+ account_for_newlines (pfile, token->val.str.text, token->val.str.len);
|
|
|
+ }
|
|
|
+ }
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/diagnostic.c gcc-3.3.3.tigcc8/gcc/diagnostic.c
|
|
|
+--- gcc-3.3.3.orig/gcc/diagnostic.c Thu May 29 21:09:54 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/diagnostic.c Thu Feb 19 21:20:02 2004
|
|
|
+@@ -1205,9 +1205,7 @@
|
|
|
+ VA_CLOSE (ap);
|
|
|
+
|
|
|
+ fnotice (stderr,
|
|
|
+-"Please submit a full bug report,\n\
|
|
|
+-with preprocessed source if appropriate.\n\
|
|
|
+-See %s for instructions.\n", bug_report_url);
|
|
|
++"Please fill out a bug report form at %s.\n", bug_report_url);
|
|
|
+ exit (FATAL_EXIT_CODE);
|
|
|
+ }
|
|
|
+
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/dwarf2out.c gcc-3.3.3.tigcc8/gcc/dwarf2out.c
|
|
|
+--- gcc-3.3.3.orig/gcc/dwarf2out.c Wed Oct 1 18:58:30 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/dwarf2out.c Thu Feb 19 21:20:02 2004
|
|
|
+@@ -9125,6 +9125,10 @@
|
|
|
+ REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, array);
|
|
|
+ break;
|
|
|
+
|
|
|
++ case BFmode:
|
|
|
++ REAL_VALUE_TO_TARGET_SMAP_BCD (rv, array);
|
|
|
++ break;
|
|
|
++
|
|
|
+ default:
|
|
|
+ abort ();
|
|
|
+ }
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/emit-rtl.c gcc-3.3.3.tigcc8/gcc/emit-rtl.c
|
|
|
+--- gcc-3.3.3.orig/gcc/emit-rtl.c Wed Dec 10 17:37:18 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/emit-rtl.c Thu Feb 19 21:20:02 2004
|
|
|
+@@ -247,8 +247,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 *). */
|
|
|
+@@ -1035,6 +1035,7 @@
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* The floating-point emulator can handle all conversions between
|
|
|
+ FP and integer operands. This simplifies reload because it
|
|
|
+ doesn't have to deal with constructs like (subreg:DI
|
|
|
+@@ -1135,6 +1136,19 @@
|
|
|
+ mode);
|
|
|
+ #endif
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
++ else if (mode == BFmode
|
|
|
++ && GET_CODE (x) == CONST_INT)
|
|
|
++ {
|
|
|
++ REAL_VALUE_TYPE r;
|
|
|
++ HOST_WIDE_INT i;
|
|
|
++ char s[25];
|
|
|
++
|
|
|
++ i = INTVAL (x);
|
|
|
++ sprintf (s, "%ld", (long) i);
|
|
|
++ r = REAL_VALUE_ATOF (s, mode);
|
|
|
++ return CONST_DOUBLE_FROM_REAL_VALUE (r, mode);
|
|
|
++ }
|
|
|
+
|
|
|
+ /* Otherwise, we can't do this. */
|
|
|
+ return 0;
|
|
|
+@@ -1369,6 +1383,7 @@
|
|
|
+ && GET_MODE_SIZE (mode) == UNITS_PER_WORD)
|
|
|
+ return op;
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* The output is some bits, the width of the target machine's word.
|
|
|
+ A wider-word host can surely hold them in a CONST_INT. A narrower-word
|
|
|
+ host can't. */
|
|
|
+@@ -1447,10 +1462,12 @@
|
|
|
+ else
|
|
|
+ abort ();
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Single word float is a little harder, since single- and double-word
|
|
|
+ values often do not have the same high-order bits. We have already
|
|
|
+ verified that we want the only defined word of the single-word value. */
|
|
|
++#if 0
|
|
|
+ if (GET_MODE_CLASS (mode) == MODE_FLOAT
|
|
|
+ && GET_MODE_BITSIZE (mode) == 32
|
|
|
+ && GET_CODE (op) == CONST_DOUBLE)
|
|
|
+@@ -1474,6 +1491,7 @@
|
|
|
+
|
|
|
+ return GEN_INT (val);
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* The only remaining cases that we can handle are integers.
|
|
|
+ Convert to proper endianness now since these cases need it.
|
|
|
+@@ -1553,10 +1571,63 @@
|
|
|
+ && (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);
|
|
|
++ RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (op);
|
|
|
++
|
|
|
++ return new;
|
|
|
++ }
|
|
|
++ else if (GET_CODE (op) == REG)
|
|
|
++ {
|
|
|
++ 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)
|
|
|
++ && rtx_equal_function_value_matters)
|
|
|
++ || 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 (GET_CODE (op) == MEM)
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/explow.c gcc-3.3.3.tigcc8/gcc/explow.c
|
|
|
+--- gcc-3.3.3.orig/gcc/explow.c Wed Dec 24 16:04:46 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/explow.c Thu Feb 19 21:20:02 2004
|
|
|
+@@ -738,6 +738,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))
|
|
|
+@@ -747,6 +751,7 @@
|
|
|
+ abort ();
|
|
|
+ if (x != temp)
|
|
|
+ emit_move_insn (temp, x);
|
|
|
++ }
|
|
|
+ return temp;
|
|
|
+ }
|
|
|
+
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/expr.c gcc-3.3.3.tigcc8/gcc/expr.c
|
|
|
+--- gcc-3.3.3.orig/gcc/expr.c Tue Dec 23 18:40:40 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/expr.c Thu Feb 19 21:20:02 2004
|
|
|
+@@ -644,6 +644,13 @@
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ #endif
|
|
|
++#ifdef HAVE_truncbfqf2
|
|
|
++ if (HAVE_truncbfqf2 && from_mode == BFmode && to_mode == QFmode)
|
|
|
++ {
|
|
|
++ emit_unop_insn (CODE_FOR_truncbfqf2, to, from, UNKNOWN);
|
|
|
++ return;
|
|
|
++ }
|
|
|
++#endif
|
|
|
+ #ifdef HAVE_truncxfqf2
|
|
|
+ if (HAVE_truncxfqf2 && from_mode == XFmode && to_mode == QFmode)
|
|
|
+ {
|
|
|
+@@ -680,6 +687,13 @@
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ #endif
|
|
|
++#ifdef HAVE_truncbfhf2
|
|
|
++ if (HAVE_truncbfhf2 && from_mode == BFmode && to_mode == HFmode)
|
|
|
++ {
|
|
|
++ emit_unop_insn (CODE_FOR_truncbfhf2, to, from, UNKNOWN);
|
|
|
++ return;
|
|
|
++ }
|
|
|
++#endif
|
|
|
+ #ifdef HAVE_truncxfhf2
|
|
|
+ if (HAVE_truncxfhf2 && from_mode == XFmode && to_mode == HFmode)
|
|
|
+ {
|
|
|
+@@ -709,6 +723,13 @@
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ #endif
|
|
|
++#ifdef HAVE_truncbftqf2
|
|
|
++ if (HAVE_truncbftqf2 && from_mode == BFmode && to_mode == TQFmode)
|
|
|
++ {
|
|
|
++ emit_unop_insn (CODE_FOR_truncbftqf2, to, from, UNKNOWN);
|
|
|
++ return;
|
|
|
++ }
|
|
|
++#endif
|
|
|
+ #ifdef HAVE_truncxftqf2
|
|
|
+ if (HAVE_truncxftqf2 && from_mode == XFmode && to_mode == TQFmode)
|
|
|
+ {
|
|
|
+@@ -731,6 +752,13 @@
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ #endif
|
|
|
++#ifdef HAVE_truncbfsf2
|
|
|
++ if (HAVE_truncbfsf2 && from_mode == BFmode && to_mode == SFmode)
|
|
|
++ {
|
|
|
++ emit_unop_insn (CODE_FOR_truncbfsf2, to, from, UNKNOWN);
|
|
|
++ return;
|
|
|
++ }
|
|
|
++#endif
|
|
|
+ #ifdef HAVE_truncxfsf2
|
|
|
+ if (HAVE_truncxfsf2 && from_mode == XFmode && to_mode == SFmode)
|
|
|
+ {
|
|
|
+@@ -745,6 +773,13 @@
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ #endif
|
|
|
++#ifdef HAVE_truncbfdf2
|
|
|
++ if (HAVE_truncbfdf2 && from_mode == BFmode && to_mode == DFmode)
|
|
|
++ {
|
|
|
++ emit_unop_insn (CODE_FOR_truncbfdf2, to, from, UNKNOWN);
|
|
|
++ return;
|
|
|
++ }
|
|
|
++#endif
|
|
|
+ #ifdef HAVE_truncxfdf2
|
|
|
+ if (HAVE_truncxfdf2 && from_mode == XFmode && to_mode == DFmode)
|
|
|
+ {
|
|
|
+@@ -759,6 +794,20 @@
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ #endif
|
|
|
++#ifdef HAVE_truncxfbf2
|
|
|
++ if (HAVE_truncxfbf2 && from_mode == XFmode && to_mode == BFmode)
|
|
|
++ {
|
|
|
++ emit_unop_insn (CODE_FOR_truncxfbf2, to, from, UNKNOWN);
|
|
|
++ return;
|
|
|
++ }
|
|
|
++#endif
|
|
|
++#ifdef HAVE_trunctfbf2
|
|
|
++ if (HAVE_trunctfbf2 && from_mode == TFmode && to_mode == BFmode)
|
|
|
++ {
|
|
|
++ emit_unop_insn (CODE_FOR_trunctfbf2, to, from, UNKNOWN);
|
|
|
++ return;
|
|
|
++ }
|
|
|
++#endif
|
|
|
+
|
|
|
+ libcall = (rtx) 0;
|
|
|
+ switch (from_mode)
|
|
|
+@@ -770,6 +819,10 @@
|
|
|
+ libcall = extendsfdf2_libfunc;
|
|
|
+ break;
|
|
|
+
|
|
|
++ case BFmode:
|
|
|
++ libcall = extendsfbf2_libfunc;
|
|
|
++ break;
|
|
|
++
|
|
|
+ case XFmode:
|
|
|
+ libcall = extendsfxf2_libfunc;
|
|
|
+ break;
|
|
|
+@@ -790,6 +843,10 @@
|
|
|
+ libcall = truncdfsf2_libfunc;
|
|
|
+ break;
|
|
|
+
|
|
|
++ case BFmode:
|
|
|
++ libcall = extenddfbf2_libfunc;
|
|
|
++ break;
|
|
|
++
|
|
|
+ case XFmode:
|
|
|
+ libcall = extenddfxf2_libfunc;
|
|
|
+ break;
|
|
|
+@@ -803,6 +860,22 @@
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
++ case BFmode:
|
|
|
++ switch (to_mode)
|
|
|
++ {
|
|
|
++ case SFmode:
|
|
|
++ libcall = truncbfsf2_libfunc;
|
|
|
++ break;
|
|
|
++
|
|
|
++ case DFmode:
|
|
|
++ libcall = truncbfdf2_libfunc;
|
|
|
++ break;
|
|
|
++
|
|
|
++ default:
|
|
|
++ break;
|
|
|
++ }
|
|
|
++ break;
|
|
|
++
|
|
|
+ case XFmode:
|
|
|
+ switch (to_mode)
|
|
|
+ {
|
|
|
+@@ -814,6 +887,10 @@
|
|
|
+ libcall = truncxfdf2_libfunc;
|
|
|
+ break;
|
|
|
+
|
|
|
++ case BFmode:
|
|
|
++ libcall = truncxfbf2_libfunc;
|
|
|
++ break;
|
|
|
++
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+@@ -1357,7 +1434,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
|
|
|
+@@ -1940,7 +2017,9 @@
|
|
|
+ if (TARGET_MEM_FUNCTIONS)
|
|
|
+ size_mode = TYPE_MODE (sizetype);
|
|
|
+ else
|
|
|
+- size_mode = TYPE_MODE (unsigned_type_node);
|
|
|
++ /* TIGCC Patch: The bcopy libcall expects short integers even with
|
|
|
++ -mlong. */
|
|
|
++ size_mode = TYPE_MODE (short_unsigned_type_node);
|
|
|
+ size = convert_to_mode (size_mode, size, 1);
|
|
|
+ size = copy_to_mode_reg (size_mode, size);
|
|
|
+
|
|
|
+@@ -1950,15 +2029,19 @@
|
|
|
+ targets where libcalls and normal calls have different conventions
|
|
|
+ for returning pointers, we could end up generating incorrect code.
|
|
|
+
|
|
|
+- For convenience, we generate the call to bcopy this way as well. */
|
|
|
++ For convenience, we generate the call to bcopy this way as well.
|
|
|
++ (TIGCC 20030315) NO, we CANNOT, because this generates incorrect code! */
|
|
|
+
|
|
|
+ dst_tree = make_tree (ptr_type_node, dst);
|
|
|
+ src_tree = make_tree (ptr_type_node, src);
|
|
|
+ if (TARGET_MEM_FUNCTIONS)
|
|
|
+ size_tree = make_tree (sizetype, size);
|
|
|
+ else
|
|
|
+- size_tree = make_tree (unsigned_type_node, size);
|
|
|
++ /* TIGCC Patch: The bcopy libcall expects short integers even with
|
|
|
++ -mlong. */
|
|
|
++ size_tree = make_tree (short_unsigned_type_node, size);
|
|
|
+
|
|
|
++#if 0
|
|
|
+ fn = emit_block_move_libcall_fn (true);
|
|
|
+ arg_list = tree_cons (NULL_TREE, size_tree, NULL_TREE);
|
|
|
+ if (TARGET_MEM_FUNCTIONS)
|
|
|
+@@ -1979,6 +2062,13 @@
|
|
|
+ TREE_SIDE_EFFECTS (call_expr) = 1;
|
|
|
+
|
|
|
+ retval = expand_expr (call_expr, NULL_RTX, VOIDmode, 0);
|
|
|
++#endif /* 0 */
|
|
|
++
|
|
|
++ emit_library_call (bcopy_libfunc, LCT_NORMAL,
|
|
|
++ VOIDmode, 3, src, Pmode, dst, Pmode,
|
|
|
++ convert_to_mode (TYPE_MODE (short_integer_type_node), size,
|
|
|
++ TREE_UNSIGNED (short_integer_type_node)),
|
|
|
++ TYPE_MODE (short_integer_type_node));
|
|
|
+
|
|
|
+ /* If we are initializing a readonly value, show the above call
|
|
|
+ clobbered it. Otherwise, a load from it may erroneously be
|
|
|
+@@ -2014,8 +2104,10 @@
|
|
|
+ else
|
|
|
+ {
|
|
|
+ fn = get_identifier ("bcopy");
|
|
|
++ /* TIGCC Patch: The bcopy libcall expects short integers even with
|
|
|
++ -mlong. */
|
|
|
+ args = build_function_type_list (void_type_node, const_ptr_type_node,
|
|
|
+- ptr_type_node, unsigned_type_node,
|
|
|
++ ptr_type_node, short_unsigned_type_node,
|
|
|
+ NULL_TREE);
|
|
|
+ }
|
|
|
+
|
|
|
+@@ -3054,7 +3146,9 @@
|
|
|
+ if (TARGET_MEM_FUNCTIONS)
|
|
|
+ size_mode = TYPE_MODE (sizetype);
|
|
|
+ else
|
|
|
+- size_mode = TYPE_MODE (unsigned_type_node);
|
|
|
++ /* TIGCC Patch: The bzero libcall expects short integers even with
|
|
|
++ -mlong. */
|
|
|
++ size_mode = TYPE_MODE (short_unsigned_type_node);
|
|
|
+ size = convert_to_mode (size_mode, size, 1);
|
|
|
+ size = copy_to_mode_reg (size_mode, size);
|
|
|
+
|
|
|
+@@ -3064,14 +3158,18 @@
|
|
|
+ targets where libcalls and normal calls have different conventions
|
|
|
+ for returning pointers, we could end up generating incorrect code.
|
|
|
+
|
|
|
+- For convenience, we generate the call to bzero this way as well. */
|
|
|
++ For convenience, we generate the call to bzero this way as well.
|
|
|
++ (TIGCC 20030315) NO, we CANNOT, because this generates incorrect code! */
|
|
|
+
|
|
|
+ object_tree = make_tree (ptr_type_node, object);
|
|
|
+ if (TARGET_MEM_FUNCTIONS)
|
|
|
+ size_tree = make_tree (sizetype, size);
|
|
|
+ else
|
|
|
+- size_tree = make_tree (unsigned_type_node, size);
|
|
|
++ /* TIGCC Patch: The bzero libcall expects short integers even with
|
|
|
++ -mlong. */
|
|
|
++ size_tree = make_tree (short_unsigned_type_node, size);
|
|
|
+
|
|
|
++#if 0
|
|
|
+ fn = clear_storage_libcall_fn (true);
|
|
|
+ arg_list = tree_cons (NULL_TREE, size_tree, NULL_TREE);
|
|
|
+ if (TARGET_MEM_FUNCTIONS)
|
|
|
+@@ -3085,6 +3183,11 @@
|
|
|
+ TREE_SIDE_EFFECTS (call_expr) = 1;
|
|
|
+
|
|
|
+ retval = expand_expr (call_expr, NULL_RTX, VOIDmode, 0);
|
|
|
++#endif /* 0 */
|
|
|
++
|
|
|
++ emit_library_call (bzero_libfunc, LCT_NORMAL,
|
|
|
++ VOIDmode, 2, object, Pmode, size,
|
|
|
++ TYPE_MODE (short_integer_type_node));
|
|
|
+
|
|
|
+ /* If we are initializing a readonly value, show the above call
|
|
|
+ clobbered it. Otherwise, a load from it may erroneously be
|
|
|
+@@ -3120,8 +3223,10 @@
|
|
|
+ else
|
|
|
+ {
|
|
|
+ fn = get_identifier ("bzero");
|
|
|
++ /* TIGCC Patch: The bzero libcall expects short integers even with
|
|
|
++ -mlong. */
|
|
|
+ args = build_function_type_list (void_type_node, ptr_type_node,
|
|
|
+- unsigned_type_node, NULL_TREE);
|
|
|
++ short_unsigned_type_node, NULL_TREE);
|
|
|
+ }
|
|
|
+
|
|
|
+ fn = build_decl (FUNCTION_DECL, fn, args);
|
|
|
+@@ -3522,6 +3627,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))
|
|
|
+@@ -3561,6 +3669,7 @@
|
|
|
+
|
|
|
+ return last_insn;
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ return NULL_RTX;
|
|
|
+ }
|
|
|
+@@ -3882,7 +3991,8 @@
|
|
|
+ int not_stack;
|
|
|
+ /* # words 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;
|
|
|
+
|
|
|
+@@ -4257,13 +4367,15 @@
|
|
|
+ size, TREE_UNSIGNED (sizetype)),
|
|
|
+ TYPE_MODE (sizetype));
|
|
|
+ else
|
|
|
++ /* TIGCC Patch: The bcopy libcall expects short integers even with
|
|
|
++ -mlong. */
|
|
|
+ emit_library_call (bcopy_libfunc, LCT_NORMAL,
|
|
|
+ VOIDmode, 3, XEXP (from_rtx, 0), Pmode,
|
|
|
+ XEXP (to_rtx, 0), Pmode,
|
|
|
+- convert_to_mode (TYPE_MODE (integer_type_node),
|
|
|
++ convert_to_mode (TYPE_MODE (short_integer_type_node),
|
|
|
+ size,
|
|
|
+- TREE_UNSIGNED (integer_type_node)),
|
|
|
+- TYPE_MODE (integer_type_node));
|
|
|
++ TREE_UNSIGNED (short_integer_type_node)),
|
|
|
++ TYPE_MODE (short_integer_type_node));
|
|
|
+
|
|
|
+ preserve_temp_slots (to_rtx);
|
|
|
+ free_temp_slots ();
|
|
|
+@@ -4692,7 +4804,7 @@
|
|
|
+ is_zeros_p (TREE_REALPART (exp)) && is_zeros_p (TREE_IMAGPART (exp));
|
|
|
+
|
|
|
+ case REAL_CST:
|
|
|
+- return REAL_VALUES_IDENTICAL (TREE_REAL_CST (exp), dconst0);
|
|
|
++ return REAL_VALUE_ISZERO (TREE_REAL_CST (exp));
|
|
|
+
|
|
|
+ case VECTOR_CST:
|
|
|
+ for (elt = TREE_VECTOR_CST_ELTS (exp); elt;
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/final.c gcc-3.3.3.tigcc8/gcc/final.c
|
|
|
+--- gcc-3.3.3.orig/gcc/final.c Mon Dec 1 08:18:36 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/final.c Sun Aug 8 12:11:32 2004
|
|
|
+@@ -2909,7 +2909,19 @@
|
|
|
+ /* simplify_subreg does not remove subreg from volatile references.
|
|
|
+ We are required to. */
|
|
|
+ if (GET_CODE (y) == MEM)
|
|
|
+- *xp = adjust_address (y, GET_MODE (x), SUBREG_BYTE (x));
|
|
|
++ {
|
|
|
++ /* (TIGCC 20030220) On big-endian machines, adjust offset of paradoxical
|
|
|
++ subregs of memory to point to the correct place.
|
|
|
++ I don't know for sure whether this is needed for the
|
|
|
++ non-paradoxical case as well, but as far as I can
|
|
|
++ tell, non-paradoxical memory subregs are simplified
|
|
|
++ elsewhere than here. -- Kevin Kofler */
|
|
|
++ int x_size = GET_MODE_SIZE (GET_MODE (x));
|
|
|
++ int y_size = GET_MODE_SIZE (GET_MODE (y));
|
|
|
++ int offset = SUBREG_BYTE (x);
|
|
|
++ if (BYTES_BIG_ENDIAN && (x_size > y_size)) offset-=(x_size-y_size);
|
|
|
++ *xp = adjust_address (y, GET_MODE (x), offset);
|
|
|
++ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ rtx new = simplify_subreg (GET_MODE (x), y, GET_MODE (y),
|
|
|
+@@ -3405,11 +3417,23 @@
|
|
|
+ else if (letter == 'l')
|
|
|
+ output_asm_label (operands[c]);
|
|
|
+ else if (letter == 'a')
|
|
|
++ {
|
|
|
+ output_address (operands[c]);
|
|
|
++ /* 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[c]) == SYMBOL_REF || GET_CODE (operands[c]) == LABEL_REF || GET_CODE (operands[c]) == CODE_LABEL || GET_CODE (operands[c]) == CONST))
|
|
|
++ fprintf (asm_out_file, "-__relation(%%%s)", TARGET_RELATION_REG);
|
|
|
++ }
|
|
|
+ else if (letter == 'c')
|
|
|
+ {
|
|
|
+ if (CONSTANT_ADDRESS_P (operands[c]))
|
|
|
++ {
|
|
|
+ output_addr_const (asm_out_file, operands[c]);
|
|
|
++ /* TIGCC Patch: See above */
|
|
|
++ if (TARGET_REG_RELATIVE && (GET_CODE (operands[c]) == SYMBOL_REF || GET_CODE (operands[c]) == LABEL_REF || GET_CODE (operands[c]) == CODE_LABEL || GET_CODE (operands[c]) == CONST))
|
|
|
++ fprintf (asm_out_file, "-__relation(%%%s)", TARGET_RELATION_REG);
|
|
|
++ }
|
|
|
+ else
|
|
|
+ output_operand (operands[c], 'c');
|
|
|
+ }
|
|
|
+@@ -3422,6 +3446,9 @@
|
|
|
+ {
|
|
|
+ putc ('-', asm_out_file);
|
|
|
+ output_addr_const (asm_out_file, operands[c]);
|
|
|
++ /* TIGCC Patch: See above */
|
|
|
++ if (TARGET_REG_RELATIVE && (GET_CODE (operands[c]) == SYMBOL_REF || GET_CODE (operands[c]) == LABEL_REF || GET_CODE (operands[c]) == CODE_LABEL))
|
|
|
++ fprintf (asm_out_file, "-__relation(%%%s)", TARGET_RELATION_REG);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+@@ -3939,6 +3966,8 @@
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
++ abort ();
|
|
|
++#if 0
|
|
|
+ REAL_VALUE_TYPE r;
|
|
|
+ long l[2];
|
|
|
+ REAL_VALUE_FROM_CONST_DOUBLE (r, value);
|
|
|
+@@ -3967,6 +3996,7 @@
|
|
|
+
|
|
|
+ *first = GEN_INT ((HOST_WIDE_INT) l[0]);
|
|
|
+ *second = GEN_INT ((HOST_WIDE_INT) l[1]);
|
|
|
++#endif /* 0 */
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/flags.h gcc-3.3.3.tigcc8/gcc/flags.h
|
|
|
+--- gcc-3.3.3.orig/gcc/flags.h Fri Jun 20 23:18:40 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/flags.h Tue Jul 27 12:34:52 2004
|
|
|
+@@ -690,4 +690,10 @@
|
|
|
+ #define HONOR_SIGN_DEPENDENT_ROUNDING(MODE) \
|
|
|
+ (MODE_HAS_SIGN_DEPENDENT_ROUNDING (MODE) && !flag_unsafe_math_optimizations)
|
|
|
+
|
|
|
++/* (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-3.3.3.orig/gcc/flow.c gcc-3.3.3.tigcc8/gcc/flow.c
|
|
|
+--- gcc-3.3.3.orig/gcc/flow.c Wed Jul 30 02:57:24 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/flow.c Thu Feb 19 21:20:02 2004
|
|
|
+@@ -2382,11 +2382,13 @@
|
|
|
+ if (n_basic_blocks == 0
|
|
|
+ || (regno < FIRST_PSEUDO_REGISTER
|
|
|
+ && (global_regs[regno]
|
|
|
+- || fixed_regs[regno]
|
|
|
+- || FUNCTION_ARG_REGNO_P (regno))))
|
|
|
++/* begin-TIGCC-local (regparms): explicit register specification for parameters */
|
|
|
++ || fixed_regs[regno])))
|
|
|
+ return 0;
|
|
|
+
|
|
|
+- return REGNO_REG_SET_P (ENTRY_BLOCK_PTR->next_bb->global_live_at_start, regno);
|
|
|
++ return (REGNO_REG_SET_P (ENTRY_BLOCK_PTR->next_bb->global_live_at_start, regno)
|
|
|
++ && (regno >= FIRST_PSEUDO_REGISTER || ! function_arg_regno_p (regno)));
|
|
|
++/* end-TIGCC-local (regparms) */
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 1 if register REGNO was alive at a place where `setjmp' was called
|
|
|
+@@ -2710,6 +2712,14 @@
|
|
|
+ #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
|
|
|
+ && ! (regno_first == ARG_POINTER_REGNUM && fixed_regs[regno_first])
|
|
|
+ #endif
|
|
|
++/* (TIGCC 20030316) Applied the following proposed patch for PR 7871 (and 7595):
|
|
|
++
|
|
|
++ 2003-03-10 James E Wilson <wilson@tuliptree.org>
|
|
|
++
|
|
|
++ * flow.c (mark_set_1): Handle global_regs like the frame pointer.
|
|
|
++
|
|
|
++ -- Kevin Kofler */
|
|
|
++ && ! (regno_first < FIRST_PSEUDO_REGISTER && global_regs[regno_first])
|
|
|
+ )
|
|
|
+ {
|
|
|
+ int some_was_live = 0, some_was_dead = 0;
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/fold-const.c gcc-3.3.3.tigcc8/gcc/fold-const.c
|
|
|
+--- gcc-3.3.3.orig/gcc/fold-const.c Thu Jan 1 04:44:52 2004
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/fold-const.c Thu Feb 19 21:20:02 2004
|
|
|
+@@ -1244,7 +1244,7 @@
|
|
|
+ REAL_ARITHMETIC (value, code, d1, d2);
|
|
|
+
|
|
|
+ t = build_real (TREE_TYPE (arg1),
|
|
|
+- real_value_truncate (TYPE_MODE (TREE_TYPE (arg1)),
|
|
|
++ REAL_VALUE_TRUNCATE (TYPE_MODE (TREE_TYPE (arg1)),
|
|
|
+ value));
|
|
|
+
|
|
|
+ TREE_OVERFLOW (t)
|
|
|
+@@ -1548,6 +1548,7 @@
|
|
|
+ TREE_CONSTANT_OVERFLOW (t)
|
|
|
+ = TREE_OVERFLOW (t) | TREE_CONSTANT_OVERFLOW (arg1);
|
|
|
+ }
|
|
|
++#if 0
|
|
|
+ else if (TREE_CODE (arg1) == REAL_CST)
|
|
|
+ {
|
|
|
+ /* Don't initialize these, use assignments.
|
|
|
+@@ -1591,6 +1592,7 @@
|
|
|
+ TREE_CONSTANT_OVERFLOW (t)
|
|
|
+ = TREE_OVERFLOW (t) | TREE_CONSTANT_OVERFLOW (arg1);
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+ TREE_TYPE (t) = type;
|
|
|
+ }
|
|
|
+ else if (TREE_CODE (type) == REAL_TYPE)
|
|
|
+@@ -1609,7 +1611,7 @@
|
|
|
+ }
|
|
|
+
|
|
|
+ t = build_real (type,
|
|
|
+- real_value_truncate (TYPE_MODE (type),
|
|
|
++ REAL_VALUE_TRUNCATE (TYPE_MODE (type),
|
|
|
+ TREE_REAL_CST (arg1)));
|
|
|
+
|
|
|
+ TREE_OVERFLOW (t)
|
|
|
+@@ -5041,7 +5043,11 @@
|
|
|
+ = TREE_OVERFLOW (t) | TREE_CONSTANT_OVERFLOW (arg0);
|
|
|
+ }
|
|
|
+ else if (TREE_CODE (arg0) == 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);
|
|
|
++ }
|
|
|
+ }
|
|
|
+ else if (TREE_CODE (arg0) == NEGATE_EXPR)
|
|
|
+ return TREE_OPERAND (arg0, 0);
|
|
|
+@@ -5086,9 +5092,10 @@
|
|
|
+ }
|
|
|
+ else if (TREE_CODE (arg0) == REAL_CST)
|
|
|
+ {
|
|
|
+- if (REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg0)))
|
|
|
++ REAL_VALUE_TYPE x = TREE_REAL_CST (arg0);
|
|
|
++ if (REAL_VALUE_NEGATIVE (x))
|
|
|
+ t = build_real (type,
|
|
|
+- REAL_VALUE_NEGATE (TREE_REAL_CST (arg0)));
|
|
|
++ REAL_VALUE_NEGATE (x));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (TREE_CODE (arg0) == ABS_EXPR || TREE_CODE (arg0) == NEGATE_EXPR)
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/function.c gcc-3.3.3.tigcc8/gcc/function.c
|
|
|
+--- gcc-3.3.3.orig/gcc/function.c Thu Dec 11 07:57:54 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/function.c Thu Feb 19 21:20:04 2004
|
|
|
+@@ -454,8 +454,25 @@
|
|
|
+ f->x_nonlocal_goto_stack_level = NULL;
|
|
|
+ f->x_cleanup_label = NULL;
|
|
|
+ f->x_return_label = NULL;
|
|
|
++#if 0 /* (TIGCC 20030607) Revert the following patch:
|
|
|
++
|
|
|
++2003-03-21 Richard Henderson <rth@redhat.com>
|
|
|
++
|
|
|
++ PR opt/2001
|
|
|
++ * bb-reorder.c (maybe_duplicate_computed_goto_succ): New.
|
|
|
++ (make_reorder_chain_1): Call it.
|
|
|
++
|
|
|
++ * function.h (struct function): Add computed_goto_common_label,
|
|
|
++ computed_goto_common_reg.
|
|
|
++ * function.c (free_after_compilation): Zap them.
|
|
|
++ * stmt.c (expand_computed_goto): Use them to produce one
|
|
|
++ indirect branch per function.
|
|
|
++
|
|
|
++because it breaks ER_throw, whereas PR opt/2001 is a compilation slowness
|
|
|
++problem (in an extreme case) only. -- Kevin Kofler */
|
|
|
+ f->computed_goto_common_label = NULL;
|
|
|
+ f->computed_goto_common_reg = NULL;
|
|
|
++#endif /* 0 */
|
|
|
+ f->x_save_expr_regs = NULL;
|
|
|
+ f->x_stack_slot_list = NULL;
|
|
|
+ f->x_rtl_expr_chain = NULL;
|
|
|
+@@ -8004,3 +8021,29 @@
|
|
|
+ }
|
|
|
+
|
|
|
+ #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 (regno)
|
|
|
++ 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-3.3.3.orig/gcc/function.h gcc-3.3.3.tigcc8/gcc/function.h
|
|
|
+--- gcc-3.3.3.orig/gcc/function.h Fri Nov 14 06:46:08 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/function.h Thu Feb 19 21:20:04 2004
|
|
|
+@@ -273,9 +273,28 @@
|
|
|
+ on machines which require execution of the epilogue on all returns. */
|
|
|
+ rtx x_return_label;
|
|
|
+
|
|
|
+- /* Label and register for unswitching computed gotos. */
|
|
|
++/* (TIGCC 20030607) Revert the following patch:
|
|
|
++
|
|
|
++2003-03-21 Richard Henderson <rth@redhat.com>
|
|
|
++
|
|
|
++ PR opt/2001
|
|
|
++ * bb-reorder.c (maybe_duplicate_computed_goto_succ): New.
|
|
|
++ (make_reorder_chain_1): Call it.
|
|
|
++
|
|
|
++ * function.h (struct function): Add computed_goto_common_label,
|
|
|
++ computed_goto_common_reg.
|
|
|
++ * function.c (free_after_compilation): Zap them.
|
|
|
++ * stmt.c (expand_computed_goto): Use them to produce one
|
|
|
++ indirect branch per function.
|
|
|
++
|
|
|
++because it breaks ER_throw, whereas PR opt/2001 is a compilation slowness
|
|
|
++problem (in an extreme case) only. -- Kevin Kofler
|
|
|
++
|
|
|
++ ** Label and register for unswitching computed gotos. **
|
|
|
+ rtx computed_goto_common_label;
|
|
|
+ rtx computed_goto_common_reg;
|
|
|
++
|
|
|
++(END TIGCC 20030607) */
|
|
|
+
|
|
|
+ /* List (chain of EXPR_LISTs) of pseudo-regs of SAVE_EXPRs.
|
|
|
+ So we can mark them all live at the end of the function, if nonopt. */
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/gcc.c gcc-3.3.3.tigcc8/gcc/gcc.c
|
|
|
+--- gcc-3.3.3.orig/gcc/gcc.c Sat Dec 6 03:53:02 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/gcc.c Thu Feb 19 21:20:04 2004
|
|
|
+@@ -1326,6 +1326,7 @@
|
|
|
+ #define MD_STARTFILE_PREFIX_1 ""
|
|
|
+ #endif
|
|
|
+
|
|
|
++#if 0 /* (TIGCC 20040104) Don't hardcode any prefix at compile time. */
|
|
|
+ /* Supply defaults for the standard prefixes. */
|
|
|
+
|
|
|
+ #ifndef STANDARD_EXEC_PREFIX
|
|
|
+@@ -1352,6 +1353,7 @@
|
|
|
+ static const char *tooldir_prefix;
|
|
|
+
|
|
|
+ static const char *const standard_bindir_prefix = STANDARD_BINDIR_PREFIX;
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Subdirectory to use for locating libraries. Set by
|
|
|
+ set_multilib_dir based on the compilation options. */
|
|
|
+@@ -1419,10 +1421,12 @@
|
|
|
+ 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),
|
|
|
++#endif /* 0 */
|
|
|
+ };
|
|
|
+
|
|
|
+ #ifdef EXTRA_SPECS /* additional specs needed */
|
|
|
+@@ -2869,8 +2873,10 @@
|
|
|
+ /* Used to track if none of the -B paths are used. */
|
|
|
+ static int warn_B;
|
|
|
+
|
|
|
++#if 0 /* (TIGCC 20040104) Don't hardcode any prefix at compile time. */
|
|
|
+ /* Gives value to pass as "warn" to add_prefix for standard prefixes. */
|
|
|
+ static int *warn_std_ptr = 0;
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ #if defined(HAVE_TARGET_OBJECT_SUFFIX) || defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
|
|
|
+
|
|
|
+@@ -3053,7 +3059,9 @@
|
|
|
+ const char *const *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;
|
|
|
+@@ -3065,7 +3073,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;
|
|
|
+@@ -3142,7 +3152,7 @@
|
|
|
+ /* Set up the default search paths. If there is no GCC_EXEC_PREFIX,
|
|
|
+ see if we can create it from the pathname specified in argv[0]. */
|
|
|
+
|
|
|
+-#ifndef VMS
|
|
|
++#if 0
|
|
|
+ /* FIXME: make_relative_prefix doesn't yet work for VMS. */
|
|
|
+ if (!gcc_exec_prefix)
|
|
|
+ {
|
|
|
+@@ -3153,6 +3163,7 @@
|
|
|
+ }
|
|
|
+ #endif
|
|
|
+
|
|
|
++#if 0 /* (TIGCC 20040104) Don't use environment variables. */
|
|
|
+ if (gcc_exec_prefix)
|
|
|
+ {
|
|
|
+ int len = strlen (gcc_exec_prefix);
|
|
|
+@@ -3277,6 +3288,7 @@
|
|
|
+ endp++;
|
|
|
+ }
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Convert new-style -- options to old-style. */
|
|
|
+ translate_options (&argc, &argv);
|
|
|
+@@ -3673,11 +3685,12 @@
|
|
|
+
|
|
|
+ /* 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,
|
|
|
+ as well as trying the machine and the version. */
|
|
|
+-#ifndef OS2
|
|
|
++#ifndef OS2
|
|
|
+ add_prefix (&exec_prefixes, standard_exec_prefix, "GCC",
|
|
|
+ PREFIX_PRIORITY_LAST, 1, warn_std_ptr, 0);
|
|
|
+ add_prefix (&exec_prefixes, standard_exec_prefix, "BINUTILS",
|
|
|
+@@ -3730,6 +3743,7 @@
|
|
|
+ add_prefix (&startfile_prefixes,
|
|
|
+ concat (tooldir_prefix, "lib", dir_separator_str, NULL),
|
|
|
+ "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ #if defined(TARGET_SYSTEM_ROOT_RELOCATABLE) && !defined(VMS)
|
|
|
+ /* If the normal TARGET_SYSTEM_ROOT is inside of $exec_prefix,
|
|
|
+@@ -6057,6 +6071,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 = (char *) alloca (strlen (standard_exec_prefix)
|
|
|
+@@ -6068,7 +6083,9 @@
|
|
|
+ strcat (specs_file, "specs");
|
|
|
+ if (access (specs_file, R_OK) == 0)
|
|
|
+ read_specs (specs_file, TRUE);
|
|
|
++#endif
|
|
|
+
|
|
|
++#if 0 /* (TIGCC 20040104) Don't hardcode any prefix at compile time. */
|
|
|
+ /* If not cross-compiling, look for executables in the standard
|
|
|
+ places. */
|
|
|
+ if (*cross_compile == '0')
|
|
|
+@@ -6132,6 +6149,7 @@
|
|
|
+ PREFIX_PRIORITY_LAST, 1, NULL, 0);
|
|
|
+ #endif
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Process any user specified specs in the order given on the command
|
|
|
+ line. */
|
|
|
+@@ -6142,10 +6160,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. */
|
|
|
+@@ -6166,7 +6186,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-3.3.3.orig/gcc/gcse.c gcc-3.3.3.tigcc8/gcc/gcse.c
|
|
|
+--- gcc-3.3.3.orig/gcc/gcse.c Sat Dec 20 19:59:50 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/gcse.c Thu Feb 19 21:20:04 2004
|
|
|
+@@ -4327,11 +4327,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 (GET_CODE (x) == REG
|
|
|
+ && (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-3.3.3.orig/gcc/ifcvt.c gcc-3.3.3.tigcc8/gcc/ifcvt.c
|
|
|
+--- gcc-3.3.3.orig/gcc/ifcvt.c Sun Dec 21 16:08:04 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/ifcvt.c Sat Sep 25 03:05:22 2004
|
|
|
+@@ -1688,6 +1688,16 @@
|
|
|
+ if (GET_CODE (op) == MEM)
|
|
|
+ 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;
|
|
|
+
|
|
|
+@@ -2973,6 +2983,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-3.3.3.orig/gcc/libfuncs.h gcc-3.3.3.tigcc8/gcc/libfuncs.h
|
|
|
+--- gcc-3.3.3.orig/gcc/libfuncs.h Tue Jun 4 09:07:50 2002
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/libfuncs.h Thu Feb 19 21:20:04 2004
|
|
|
+@@ -25,16 +25,22 @@
|
|
|
+ enum libfunc_index
|
|
|
+ {
|
|
|
+ LTI_extendsfdf2,
|
|
|
++ LTI_extendsfbf2,
|
|
|
+ LTI_extendsfxf2,
|
|
|
+ LTI_extendsftf2,
|
|
|
++ LTI_extenddfbf2,
|
|
|
+ LTI_extenddfxf2,
|
|
|
+ LTI_extenddftf2,
|
|
|
++ LTI_extendbfxf2,
|
|
|
+
|
|
|
+ LTI_truncdfsf2,
|
|
|
++ LTI_truncbfsf2,
|
|
|
+ LTI_truncxfsf2,
|
|
|
+ LTI_trunctfsf2,
|
|
|
++ LTI_truncbfdf2,
|
|
|
+ LTI_truncxfdf2,
|
|
|
+ LTI_trunctfdf2,
|
|
|
++ LTI_truncxfbf2,
|
|
|
+
|
|
|
+ LTI_abort,
|
|
|
+ LTI_memcpy,
|
|
|
+@@ -76,6 +82,14 @@
|
|
|
+ LTI_ledf2,
|
|
|
+ LTI_unorddf2,
|
|
|
+
|
|
|
++ LTI_eqbf2,
|
|
|
++ LTI_nebf2,
|
|
|
++ LTI_gtbf2,
|
|
|
++ LTI_gebf2,
|
|
|
++ LTI_ltbf2,
|
|
|
++ LTI_lebf2,
|
|
|
++ LTI_unordbf2,
|
|
|
++
|
|
|
+ LTI_eqxf2,
|
|
|
+ LTI_nexf2,
|
|
|
+ LTI_gtxf2,
|
|
|
+@@ -100,6 +114,10 @@
|
|
|
+ LTI_floatdidf,
|
|
|
+ LTI_floattidf,
|
|
|
+
|
|
|
++ LTI_floatsibf,
|
|
|
++ LTI_floatdibf,
|
|
|
++ LTI_floattibf,
|
|
|
++
|
|
|
+ LTI_floatsixf,
|
|
|
+ LTI_floatdixf,
|
|
|
+ LTI_floattixf,
|
|
|
+@@ -116,6 +134,10 @@
|
|
|
+ LTI_fixdfdi,
|
|
|
+ LTI_fixdfti,
|
|
|
+
|
|
|
++ LTI_fixbfsi,
|
|
|
++ LTI_fixbfdi,
|
|
|
++ LTI_fixbfti,
|
|
|
++
|
|
|
+ LTI_fixxfsi,
|
|
|
+ LTI_fixxfdi,
|
|
|
+ LTI_fixxfti,
|
|
|
+@@ -132,6 +154,10 @@
|
|
|
+ LTI_fixunsdfdi,
|
|
|
+ LTI_fixunsdfti,
|
|
|
+
|
|
|
++ LTI_fixunsbfsi,
|
|
|
++ LTI_fixunsbfdi,
|
|
|
++ LTI_fixunsbfti,
|
|
|
++
|
|
|
+ LTI_fixunsxfsi,
|
|
|
+ LTI_fixunsxfdi,
|
|
|
+ LTI_fixunsxfti,
|
|
|
+@@ -152,16 +178,22 @@
|
|
|
+
|
|
|
+ /* Accessor macros for libfunc_table. */
|
|
|
+ #define extendsfdf2_libfunc (libfunc_table[LTI_extendsfdf2])
|
|
|
++#define extendsfbf2_libfunc (libfunc_table[LTI_extendsfbf2])
|
|
|
+ #define extendsfxf2_libfunc (libfunc_table[LTI_extendsfxf2])
|
|
|
+ #define extendsftf2_libfunc (libfunc_table[LTI_extendsftf2])
|
|
|
++#define extenddfbf2_libfunc (libfunc_table[LTI_extenddfbf2])
|
|
|
+ #define extenddfxf2_libfunc (libfunc_table[LTI_extenddfxf2])
|
|
|
+ #define extenddftf2_libfunc (libfunc_table[LTI_extenddftf2])
|
|
|
++#define extendbfxf2_libfunc (libfunc_table[LTI_extendbfxf2])
|
|
|
+
|
|
|
+ #define truncdfsf2_libfunc (libfunc_table[LTI_truncdfsf2])
|
|
|
++#define truncbfsf2_libfunc (libfunc_table[LTI_truncbfsf2])
|
|
|
+ #define truncxfsf2_libfunc (libfunc_table[LTI_truncxfsf2])
|
|
|
+ #define trunctfsf2_libfunc (libfunc_table[LTI_trunctfsf2])
|
|
|
++#define truncbfdf2_libfunc (libfunc_table[LTI_truncbfdf2])
|
|
|
+ #define truncxfdf2_libfunc (libfunc_table[LTI_truncxfdf2])
|
|
|
+ #define trunctfdf2_libfunc (libfunc_table[LTI_trunctfdf2])
|
|
|
++#define truncxfbf2_libfunc (libfunc_table[LTI_truncxfbf2])
|
|
|
+
|
|
|
+ #define abort_libfunc (libfunc_table[LTI_abort])
|
|
|
+ #define memcpy_libfunc (libfunc_table[LTI_memcpy])
|
|
|
+@@ -204,6 +236,14 @@
|
|
|
+ #define ledf2_libfunc (libfunc_table[LTI_ledf2])
|
|
|
+ #define unorddf2_libfunc (libfunc_table[LTI_unorddf2])
|
|
|
+
|
|
|
++#define eqbf2_libfunc (libfunc_table[LTI_eqbf2])
|
|
|
++#define nebf2_libfunc (libfunc_table[LTI_nebf2])
|
|
|
++#define gtbf2_libfunc (libfunc_table[LTI_gtbf2])
|
|
|
++#define gebf2_libfunc (libfunc_table[LTI_gebf2])
|
|
|
++#define ltbf2_libfunc (libfunc_table[LTI_ltbf2])
|
|
|
++#define lebf2_libfunc (libfunc_table[LTI_lebf2])
|
|
|
++#define unordbf2_libfunc (libfunc_table[LTI_unordbf2])
|
|
|
++
|
|
|
+ #define eqxf2_libfunc (libfunc_table[LTI_eqxf2])
|
|
|
+ #define nexf2_libfunc (libfunc_table[LTI_nexf2])
|
|
|
+ #define gtxf2_libfunc (libfunc_table[LTI_gtxf2])
|
|
|
+@@ -228,6 +268,10 @@
|
|
|
+ #define floatdidf_libfunc (libfunc_table[LTI_floatdidf])
|
|
|
+ #define floattidf_libfunc (libfunc_table[LTI_floattidf])
|
|
|
+
|
|
|
++#define floatsibf_libfunc (libfunc_table[LTI_floatsibf])
|
|
|
++#define floatdibf_libfunc (libfunc_table[LTI_floatdibf])
|
|
|
++#define floattibf_libfunc (libfunc_table[LTI_floattibf])
|
|
|
++
|
|
|
+ #define floatsixf_libfunc (libfunc_table[LTI_floatsixf])
|
|
|
+ #define floatdixf_libfunc (libfunc_table[LTI_floatdixf])
|
|
|
+ #define floattixf_libfunc (libfunc_table[LTI_floattixf])
|
|
|
+@@ -244,6 +288,10 @@
|
|
|
+ #define fixdfdi_libfunc (libfunc_table[LTI_fixdfdi])
|
|
|
+ #define fixdfti_libfunc (libfunc_table[LTI_fixdfti])
|
|
|
+
|
|
|
++#define fixbfsi_libfunc (libfunc_table[LTI_fixbfsi])
|
|
|
++#define fixbfdi_libfunc (libfunc_table[LTI_fixbfdi])
|
|
|
++#define fixbfti_libfunc (libfunc_table[LTI_fixbfti])
|
|
|
++
|
|
|
+ #define fixxfsi_libfunc (libfunc_table[LTI_fixxfsi])
|
|
|
+ #define fixxfdi_libfunc (libfunc_table[LTI_fixxfdi])
|
|
|
+ #define fixxfti_libfunc (libfunc_table[LTI_fixxfti])
|
|
|
+@@ -259,6 +307,10 @@
|
|
|
+ #define fixunsdfsi_libfunc (libfunc_table[LTI_fixunsdfsi])
|
|
|
+ #define fixunsdfdi_libfunc (libfunc_table[LTI_fixunsdfdi])
|
|
|
+ #define fixunsdfti_libfunc (libfunc_table[LTI_fixunsdfti])
|
|
|
++
|
|
|
++#define fixunsbfsi_libfunc (libfunc_table[LTI_fixunsbfsi])
|
|
|
++#define fixunsbfdi_libfunc (libfunc_table[LTI_fixunsbfdi])
|
|
|
++#define fixunsbfti_libfunc (libfunc_table[LTI_fixunsbfti])
|
|
|
+
|
|
|
+ #define fixunsxfsi_libfunc (libfunc_table[LTI_fixunsxfsi])
|
|
|
+ #define fixunsxfdi_libfunc (libfunc_table[LTI_fixunsxfdi])
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/machmode.def gcc-3.3.3.tigcc8/gcc/machmode.def
|
|
|
+--- gcc-3.3.3.orig/gcc/machmode.def Tue Sep 17 15:03:40 2002
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/machmode.def Thu Feb 19 21:20:04 2004
|
|
|
+@@ -93,7 +93,8 @@
|
|
|
+ DEF_MACHMODE (HFmode, "HF", MODE_FLOAT, BITS_PER_UNIT*2, 2, 2, TQFmode, VOIDmode)
|
|
|
+ DEF_MACHMODE (TQFmode, "TQF", MODE_FLOAT, BITS_PER_UNIT*3, 3, 3, SFmode, VOIDmode) /* MIL-STD-1750A */
|
|
|
+ DEF_MACHMODE (SFmode, "SF", MODE_FLOAT, BITS_PER_UNIT*4, 4, 4, DFmode, VOIDmode)
|
|
|
+-DEF_MACHMODE (DFmode, "DF", MODE_FLOAT, BITS_PER_UNIT*8, 8, 8, XFmode, VOIDmode)
|
|
|
++DEF_MACHMODE (DFmode, "DF", MODE_FLOAT, BITS_PER_UNIT*8, 8, 8, BFmode, VOIDmode)
|
|
|
++DEF_MACHMODE (BFmode, "BF", MODE_FLOAT, BITS_PER_UNIT*10, 10, 10, XFmode, VOIDmode) /* SMAP II BCD (inserted for TIGCC) */
|
|
|
+ DEF_MACHMODE (XFmode, "XF", MODE_FLOAT, BITS_PER_UNIT*12, 12, 12, TFmode, VOIDmode) /* IEEE extended */
|
|
|
+ DEF_MACHMODE (TFmode, "TF", MODE_FLOAT, BITS_PER_UNIT*16, 16, 16, VOIDmode, VOIDmode)
|
|
|
+
|
|
|
+@@ -101,7 +102,8 @@
|
|
|
+ DEF_MACHMODE (QCmode, "QC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*2, 2, 1, HCmode, QFmode)
|
|
|
+ DEF_MACHMODE (HCmode, "HC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*4, 4, 2, SCmode, HFmode)
|
|
|
+ DEF_MACHMODE (SCmode, "SC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*8, 8, 4, DCmode, SFmode)
|
|
|
+-DEF_MACHMODE (DCmode, "DC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*16, 16, 8, XCmode, DFmode)
|
|
|
++DEF_MACHMODE (DCmode, "DC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*16, 16, 8, BCmode, DFmode)
|
|
|
++DEF_MACHMODE (BCmode, "BC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*20, 20, 10, XCmode, BFmode)
|
|
|
+ DEF_MACHMODE (XCmode, "XC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*24, 24, 12, TCmode, XFmode)
|
|
|
+ DEF_MACHMODE (TCmode, "TC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*32, 32, 16, VOIDmode, TFmode)
|
|
|
+
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/optabs.c gcc-3.3.3.tigcc8/gcc/optabs.c
|
|
|
+--- gcc-3.3.3.orig/gcc/optabs.c Sat Jul 19 02:25:24 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/optabs.c Thu Feb 19 21:20:04 2004
|
|
|
+@@ -1833,7 +1833,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))
|
|
|
+@@ -2282,7 +2282,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))
|
|
|
+@@ -2410,7 +2410,7 @@
|
|
|
+
|
|
|
+ /* It can't be done in this mode. Can we open-code 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))
|
|
|
+ {
|
|
|
+@@ -2551,7 +2551,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))
|
|
|
+@@ -3875,6 +3875,40 @@
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
++ else if (mode == BFmode)
|
|
|
++ switch (comparison)
|
|
|
++ {
|
|
|
++ case EQ:
|
|
|
++ libfunc = eqbf2_libfunc;
|
|
|
++ break;
|
|
|
++
|
|
|
++ case NE:
|
|
|
++ libfunc = nebf2_libfunc;
|
|
|
++ break;
|
|
|
++
|
|
|
++ case GT:
|
|
|
++ libfunc = gtbf2_libfunc;
|
|
|
++ break;
|
|
|
++
|
|
|
++ case GE:
|
|
|
++ libfunc = gebf2_libfunc;
|
|
|
++ break;
|
|
|
++
|
|
|
++ case LT:
|
|
|
++ libfunc = ltbf2_libfunc;
|
|
|
++ break;
|
|
|
++
|
|
|
++ case LE:
|
|
|
++ libfunc = lebf2_libfunc;
|
|
|
++ break;
|
|
|
++
|
|
|
++ case UNORDERED:
|
|
|
++ libfunc = unordbf2_libfunc;
|
|
|
++ break;
|
|
|
++
|
|
|
++ default:
|
|
|
++ break;
|
|
|
++ }
|
|
|
+ else if (mode == XFmode)
|
|
|
+ switch (comparison)
|
|
|
+ {
|
|
|
+@@ -4530,6 +4564,7 @@
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Unsigned integer, and no way to convert directly.
|
|
|
+ Convert as signed, then conditionally adjust the result. */
|
|
|
+ if (unsignedp)
|
|
|
+@@ -4642,6 +4677,7 @@
|
|
|
+ emit_label (label);
|
|
|
+ goto done;
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* No hardware instruction available; call a library routine to convert from
|
|
|
+ SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
|
|
|
+@@ -4681,6 +4717,17 @@
|
|
|
+ else
|
|
|
+ abort ();
|
|
|
+ }
|
|
|
++ else if (GET_MODE (to) == BFmode)
|
|
|
++ {
|
|
|
++ if (GET_MODE (from) == SImode)
|
|
|
++ libfcn = floatsibf_libfunc;
|
|
|
++ else if (GET_MODE (from) == DImode)
|
|
|
++ libfcn = floatdibf_libfunc;
|
|
|
++ else if (GET_MODE (from) == TImode)
|
|
|
++ libfcn = floattibf_libfunc;
|
|
|
++ else
|
|
|
++ abort ();
|
|
|
++ }
|
|
|
+ else if (GET_MODE (to) == XFmode)
|
|
|
+ {
|
|
|
+ if (GET_MODE (from) == SImode)
|
|
|
+@@ -4792,6 +4839,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
|
|
|
+@@ -4871,6 +4919,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
|
|
|
+@@ -4904,6 +4953,17 @@
|
|
|
+ else
|
|
|
+ abort ();
|
|
|
+ }
|
|
|
++ else if (GET_MODE (from) == BFmode)
|
|
|
++ {
|
|
|
++ if (GET_MODE (to) == SImode)
|
|
|
++ libfcn = unsignedp ? fixunsbfsi_libfunc : fixbfsi_libfunc;
|
|
|
++ else if (GET_MODE (to) == DImode)
|
|
|
++ libfcn = unsignedp ? fixunsbfdi_libfunc : fixbfdi_libfunc;
|
|
|
++ else if (GET_MODE (to) == TImode)
|
|
|
++ libfcn = unsignedp ? fixunsbfti_libfunc : fixbfti_libfunc;
|
|
|
++ else
|
|
|
++ abort ();
|
|
|
++ }
|
|
|
+ else if (GET_MODE (from) == XFmode)
|
|
|
+ {
|
|
|
+ if (GET_MODE (to) == SImode)
|
|
|
+@@ -5327,16 +5387,22 @@
|
|
|
+ = init_one_libfunc ("ffs");
|
|
|
+
|
|
|
+ extendsfdf2_libfunc = init_one_libfunc ("__extendsfdf2");
|
|
|
++ extendsfbf2_libfunc = init_one_libfunc ("__extendsfbf2");
|
|
|
+ extendsfxf2_libfunc = init_one_libfunc ("__extendsfxf2");
|
|
|
+ extendsftf2_libfunc = init_one_libfunc ("__extendsftf2");
|
|
|
++ extenddfbf2_libfunc = init_one_libfunc ("__extenddfbf2");
|
|
|
+ extenddfxf2_libfunc = init_one_libfunc ("__extenddfxf2");
|
|
|
+ extenddftf2_libfunc = init_one_libfunc ("__extenddftf2");
|
|
|
++ extendbfxf2_libfunc = init_one_libfunc ("__extendbfxf2");
|
|
|
+
|
|
|
+ truncdfsf2_libfunc = init_one_libfunc ("__truncdfsf2");
|
|
|
++ truncbfsf2_libfunc = init_one_libfunc ("__truncbfsf2");
|
|
|
+ truncxfsf2_libfunc = init_one_libfunc ("__truncxfsf2");
|
|
|
+ trunctfsf2_libfunc = init_one_libfunc ("__trunctfsf2");
|
|
|
++ truncbfdf2_libfunc = init_one_libfunc ("__truncbfdf2");
|
|
|
+ truncxfdf2_libfunc = init_one_libfunc ("__truncxfdf2");
|
|
|
+ trunctfdf2_libfunc = init_one_libfunc ("__trunctfdf2");
|
|
|
++ truncxfbf2_libfunc = init_one_libfunc ("__truncxfbf2");
|
|
|
+
|
|
|
+ abort_libfunc = init_one_libfunc ("abort");
|
|
|
+ memcpy_libfunc = init_one_libfunc ("memcpy");
|
|
|
+@@ -5385,6 +5451,14 @@
|
|
|
+ ledf2_libfunc = init_one_libfunc ("__ledf2");
|
|
|
+ unorddf2_libfunc = init_one_libfunc ("__unorddf2");
|
|
|
+
|
|
|
++ eqbf2_libfunc = init_one_libfunc ("__eqbf2");
|
|
|
++ nebf2_libfunc = init_one_libfunc ("__nebf2");
|
|
|
++ gtbf2_libfunc = init_one_libfunc ("__gtbf2");
|
|
|
++ gebf2_libfunc = init_one_libfunc ("__gebf2");
|
|
|
++ ltbf2_libfunc = init_one_libfunc ("__ltbf2");
|
|
|
++ lebf2_libfunc = init_one_libfunc ("__lebf2");
|
|
|
++ unordbf2_libfunc = init_one_libfunc ("__unordbf2");
|
|
|
++
|
|
|
+ eqxf2_libfunc = init_one_libfunc ("__eqxf2");
|
|
|
+ nexf2_libfunc = init_one_libfunc ("__nexf2");
|
|
|
+ gtxf2_libfunc = init_one_libfunc ("__gtxf2");
|
|
|
+@@ -5409,6 +5483,10 @@
|
|
|
+ floatdidf_libfunc = init_one_libfunc ("__floatdidf");
|
|
|
+ floattidf_libfunc = init_one_libfunc ("__floattidf");
|
|
|
+
|
|
|
++ floatsibf_libfunc = init_one_libfunc ("__floatsibf");
|
|
|
++ floatdibf_libfunc = init_one_libfunc ("__floatdibf");
|
|
|
++ floattibf_libfunc = init_one_libfunc ("__floattibf");
|
|
|
++
|
|
|
+ floatsixf_libfunc = init_one_libfunc ("__floatsixf");
|
|
|
+ floatdixf_libfunc = init_one_libfunc ("__floatdixf");
|
|
|
+ floattixf_libfunc = init_one_libfunc ("__floattixf");
|
|
|
+@@ -5425,6 +5503,10 @@
|
|
|
+ fixdfdi_libfunc = init_one_libfunc ("__fixdfdi");
|
|
|
+ fixdfti_libfunc = init_one_libfunc ("__fixdfti");
|
|
|
+
|
|
|
++ fixbfsi_libfunc = init_one_libfunc ("__fixbfsi");
|
|
|
++ fixbfdi_libfunc = init_one_libfunc ("__fixbfdi");
|
|
|
++ fixbfti_libfunc = init_one_libfunc ("__fixbfti");
|
|
|
++
|
|
|
+ fixxfsi_libfunc = init_one_libfunc ("__fixxfsi");
|
|
|
+ fixxfdi_libfunc = init_one_libfunc ("__fixxfdi");
|
|
|
+ fixxfti_libfunc = init_one_libfunc ("__fixxfti");
|
|
|
+@@ -5440,6 +5522,10 @@
|
|
|
+ fixunsdfsi_libfunc = init_one_libfunc ("__fixunsdfsi");
|
|
|
+ fixunsdfdi_libfunc = init_one_libfunc ("__fixunsdfdi");
|
|
|
+ fixunsdfti_libfunc = init_one_libfunc ("__fixunsdfti");
|
|
|
++
|
|
|
++ fixunsbfsi_libfunc = init_one_libfunc ("__fixunsbfsi");
|
|
|
++ fixunsbfdi_libfunc = init_one_libfunc ("__fixunsbfdi");
|
|
|
++ fixunsbfti_libfunc = init_one_libfunc ("__fixunsbfti");
|
|
|
+
|
|
|
+ fixunsxfsi_libfunc = init_one_libfunc ("__fixunsxfsi");
|
|
|
+ fixunsxfdi_libfunc = init_one_libfunc ("__fixunsxfdi");
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/print-rtl.c gcc-3.3.3.tigcc8/gcc/print-rtl.c
|
|
|
+--- gcc-3.3.3.orig/gcc/print-rtl.c Sun Jan 26 08:59:38 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/print-rtl.c Thu Feb 19 21:20:04 2004
|
|
|
+@@ -524,6 +524,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);
|
|
|
+@@ -531,6 +534,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-3.3.3.orig/gcc/print-tree.c gcc-3.3.3.tigcc8/gcc/print-tree.c
|
|
|
+--- gcc-3.3.3.orig/gcc/print-tree.c Thu Mar 6 23:35:06 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/print-tree.c Thu Feb 19 21:20:04 2004
|
|
|
+@@ -132,7 +132,7 @@
|
|
|
+ else
|
|
|
+ {
|
|
|
+ char string[60];
|
|
|
+- real_to_decimal (string, &d, sizeof (string), 0, 1);
|
|
|
++ REAL_VALUE_TO_STRING (d, string);
|
|
|
+ fprintf (file, " %s", string);
|
|
|
+ }
|
|
|
+ }
|
|
|
+@@ -686,7 +686,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-3.3.3.orig/gcc/real.c gcc-3.3.3.tigcc8/gcc/real.c
|
|
|
+--- gcc-3.3.3.orig/gcc/real.c Thu Nov 6 00:08:56 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/real.c Thu Feb 19 21:20:04 2004
|
|
|
+@@ -23,11 +23,28 @@
|
|
|
+
|
|
|
+ #include "config.h"
|
|
|
+ #include "system.h"
|
|
|
++#include <setjmp.h>
|
|
|
+ #include "tree.h"
|
|
|
+ #include "toplev.h"
|
|
|
+ #include "real.h"
|
|
|
+ #include "tm_p.h"
|
|
|
+
|
|
|
++#ifndef NULL_PTR
|
|
|
++#define NULL_PTR ((PTR) 0)
|
|
|
++#endif
|
|
|
++
|
|
|
++/* TIGCC Patch (for SMAP II BCD support): Define this if you want
|
|
|
++ to get info about real arithmetic calculations. */
|
|
|
++/* #define PRINT_REAL_DEBUG_INFO */
|
|
|
++
|
|
|
++#ifdef PRINT_REAL_DEBUG_INFO
|
|
|
++#define REAL_DEBUG_INFO(info_args...) warning (info_args)
|
|
|
++#define REAL_DEBUG_SPRINTF(sprintf_args...) sprintf (sprintf_args)
|
|
|
++#else
|
|
|
++#define REAL_DEBUG_INFO(info_args...) do {} while (0)
|
|
|
++#define REAL_DEBUG_SPRINTF(sprintf_args...) do {} while (0)
|
|
|
++#endif
|
|
|
++
|
|
|
+ /* The floating point model used internally is not exactly IEEE 754
|
|
|
+ compliant, and close to the description in the ISO C standard,
|
|
|
+ section 5.2.4.2.2 Characteristics of floating types.
|
|
|
+@@ -77,6 +94,7 @@
|
|
|
+ #error "Some constant folding done by hand to avoid shift count warnings"
|
|
|
+ #endif
|
|
|
+
|
|
|
++#if 0
|
|
|
+ static void get_zero PARAMS ((REAL_VALUE_TYPE *, int));
|
|
|
+ static void get_canonical_qnan PARAMS ((REAL_VALUE_TYPE *, int));
|
|
|
+ static void get_canonical_snan PARAMS ((REAL_VALUE_TYPE *, int));
|
|
|
+@@ -134,7 +152,9 @@
|
|
|
+
|
|
|
+ static void round_for_format PARAMS ((const struct real_format *,
|
|
|
+ REAL_VALUE_TYPE *));
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Initialize R with a positive zero. */
|
|
|
+
|
|
|
+ static inline void
|
|
|
+@@ -1002,6 +1022,625 @@
|
|
|
+ abort ();
|
|
|
+ }
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
++
|
|
|
++/* Add 1 unit in the last place to a positive SMAP II BCD float. */
|
|
|
++static smap_bcd_float bcdpadd1ulp PARAMS((smap_bcd_float op));
|
|
|
++static smap_bcd_float bcdpadd1ulp(op) 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 */
|
|
|
++ if (op.mantissa != 0xA000000000000000ull) abort(); /* 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 */
|
|
|
++ return POSITIVE_INF;
|
|
|
++ }
|
|
|
++ return op;
|
|
|
++}
|
|
|
++
|
|
|
++/* Add 2 positive SMAP II BCD floats. */
|
|
|
++static smap_bcd_float bcdppadd PARAMS((smap_bcd_float op0, smap_bcd_float op1));
|
|
|
++static smap_bcd_float bcdppadd(op0, op1) smap_bcd_float op0, 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 */
|
|
|
++ result = bcdpadd1ulp(result);
|
|
|
++ return result;
|
|
|
++ }
|
|
|
++}
|
|
|
++
|
|
|
++/* Subtract 2 positive SMAP II BCD floats. */
|
|
|
++static smap_bcd_float bcdppsub PARAMS((smap_bcd_float op0, smap_bcd_float op1));
|
|
|
++static smap_bcd_float bcdppsub(op0, op1) smap_bcd_float op0, 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;
|
|
|
++ }
|
|
|
++ if (carry) abort(); /* 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. */
|
|
|
++ if (!c && result.mantissa>=0xA000000000000000ull) abort();
|
|
|
++ }
|
|
|
++ 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. */
|
|
|
++ if (result.mantissa==0x1000000000000000ull) abort();
|
|
|
++ 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). */
|
|
|
++ if (!c && result.mantissa>=0xA000000000000000ull) abort();
|
|
|
++ }
|
|
|
++ }
|
|
|
++ return result;
|
|
|
++ }
|
|
|
++}
|
|
|
++
|
|
|
++/* Add 2 SMAP II BCD floats. */
|
|
|
++static smap_bcd_float bcdadd PARAMS((smap_bcd_float op0, smap_bcd_float op1));
|
|
|
++static smap_bcd_float bcdadd(op0, op1) smap_bcd_float op0, 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)) /* both positive, both negative or both
|
|
|
++ unsigned */
|
|
|
++ return op0;
|
|
|
++ else /* differing signs yield unsigned infinity */
|
|
|
++ return UNSIGNED_INF;
|
|
|
++ } 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 PARAMS((smap_bcd_float op0, smap_bcd_float op1));
|
|
|
++static smap_bcd_float bcdsub(op0, op1) smap_bcd_float op0, op1;
|
|
|
++{
|
|
|
++ return bcdadd(op0,REAL_VALUE_NEGATE(op1));
|
|
|
++}
|
|
|
++
|
|
|
++/* Multiply 2 positive SMAP II BCD floats. */
|
|
|
++static smap_bcd_float bcdppmul PARAMS((smap_bcd_float op0, smap_bcd_float op1));
|
|
|
++static smap_bcd_float bcdppmul(op0, op1) smap_bcd_float op0, 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 */
|
|
|
++ if (resultl>=10000000000000000ull) abort();
|
|
|
++
|
|
|
++ /* 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 PARAMS((smap_bcd_float op0, smap_bcd_float op1));
|
|
|
++static smap_bcd_float bcdmul(op0, op1) smap_bcd_float op0, 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 PARAMS((smap_bcd_float op0, smap_bcd_float op1, int *exactresult));
|
|
|
++static smap_bcd_float bcdppdiv(op0, op1, exactresult) smap_bcd_float op0, 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 PARAMS((smap_bcd_float op0, smap_bcd_float op1, int *exactresult));
|
|
|
++static smap_bcd_float bcddiv(op0, op1, exactresult) smap_bcd_float op0, 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 PARAMS((smap_bcd_float op0, smap_bcd_float op1));
|
|
|
++static smap_bcd_float bcdmin(op0, op1) smap_bcd_float op0, 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 PARAMS((smap_bcd_float op0, smap_bcd_float op1));
|
|
|
++static smap_bcd_float bcdmax(op0, op1) smap_bcd_float op0, 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. */
|
|
|
+@@ -1012,6 +1651,37 @@
|
|
|
+ int icode;
|
|
|
+ const REAL_VALUE_TYPE *op0, *op1;
|
|
|
+ {
|
|
|
++ switch (icode)
|
|
|
++ {
|
|
|
++ case PLUS_EXPR:
|
|
|
++ *r = bcdadd (*op0, *op1);
|
|
|
++ return;
|
|
|
++
|
|
|
++ case MINUS_EXPR:
|
|
|
++ *r = bcdsub (*op0, *op1);
|
|
|
++ return;
|
|
|
++
|
|
|
++ case MULT_EXPR:
|
|
|
++ *r = bcdmul (*op0, *op1);
|
|
|
++ return;
|
|
|
++
|
|
|
++ case RDIV_EXPR:
|
|
|
++ *r = bcddiv (*op0, *op1, NULL);
|
|
|
++ return;
|
|
|
++
|
|
|
++ case MIN_EXPR:
|
|
|
++ *r = bcdmin (*op0, *op1);
|
|
|
++ return;
|
|
|
++
|
|
|
++ case MAX_EXPR:
|
|
|
++ *r = bcdmax (*op0, *op1);
|
|
|
++ return;
|
|
|
++
|
|
|
++ default:
|
|
|
++ abort ();
|
|
|
++ }
|
|
|
++
|
|
|
++#if 0
|
|
|
+ enum tree_code code = icode;
|
|
|
+
|
|
|
+ switch (code)
|
|
|
+@@ -1067,6 +1737,7 @@
|
|
|
+ default:
|
|
|
+ abort ();
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Legacy. Similar, but return the result directly. */
|
|
|
+@@ -1081,6 +1752,7 @@
|
|
|
+ return r;
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0
|
|
|
+ bool
|
|
|
+ real_compare (icode, op0, op1)
|
|
|
+ int icode;
|
|
|
+@@ -1244,6 +1916,7 @@
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Try to change R into its exact multiplicative inverse in machine
|
|
|
+ mode MODE. Return true if successful. */
|
|
|
+@@ -1253,6 +1926,13 @@
|
|
|
+ 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;
|
|
|
+@@ -1282,8 +1962,10 @@
|
|
|
+
|
|
|
+ *r = u;
|
|
|
+ return true;
|
|
|
++#endif /* 0 */
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Render R as an integer. */
|
|
|
+
|
|
|
+ HOST_WIDE_INT
|
|
|
+@@ -1407,7 +2089,29 @@
|
|
|
+ *plow = low;
|
|
|
+ *phigh = high;
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
++
|
|
|
++/* REAL_VALUE_TO_INT macro. */
|
|
|
++
|
|
|
++void
|
|
|
++ereal_to_int (low, high, rr)
|
|
|
++ HOST_WIDE_INT *low, *high;
|
|
|
++ REAL_VALUE_TYPE rr;
|
|
|
++{
|
|
|
++ char s[100];
|
|
|
++ REAL_DEBUG_INFO ("ereal_to_int rr: %x:%lx-%lx", rr.exponent, (unsigned long) (rr.mantissa >> 32), (unsigned long) (rr.mantissa));
|
|
|
++ REAL_VALUE_TO_STRING (rr, s);
|
|
|
++ REAL_DEBUG_INFO ("ereal_to_int s: %s", s);
|
|
|
++ *low = (HOST_WIDE_INT) (atof (s));
|
|
|
++ if (*low < 0)
|
|
|
++ *high = -1;
|
|
|
++ else
|
|
|
++ *high = 0;
|
|
|
++ REAL_DEBUG_INFO ("ereal_to_int high: %ld", (long) *high);
|
|
|
++ REAL_DEBUG_INFO ("ereal_to_int low: %ld", (long) *low);
|
|
|
++}
|
|
|
+
|
|
|
++#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
|
|
|
+@@ -2045,7 +2749,39 @@
|
|
|
+ if (mode != VOIDmode)
|
|
|
+ real_convert (r, mode, r);
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
++
|
|
|
++/* REAL_VALUE_FROM_INT macro. */
|
|
|
++
|
|
|
++void
|
|
|
++ereal_from_int (d, i, j, mode)
|
|
|
++ REAL_VALUE_TYPE *d;
|
|
|
++ HOST_WIDE_INT i, j;
|
|
|
++ enum machine_mode mode;
|
|
|
++{
|
|
|
++ char s[20];
|
|
|
++ sprintf (s, "%ld", (long) i);
|
|
|
++ REAL_DEBUG_INFO ("ereal_from_int s: %s", s);
|
|
|
++ *d = REAL_VALUE_ATOF (s, mode);
|
|
|
++ REAL_DEBUG_INFO ("ereal_from_int d: %x:%lx-%lx", d->exponent, (unsigned long) (d->mantissa >> 32), (unsigned long) (d->mantissa));
|
|
|
++}
|
|
|
+
|
|
|
++/* REAL_VALUE_FROM_UNSIGNED_INT macro. */
|
|
|
++
|
|
|
++void
|
|
|
++ereal_from_uint (d, i, j, mode)
|
|
|
++ REAL_VALUE_TYPE *d;
|
|
|
++ unsigned HOST_WIDE_INT i, j;
|
|
|
++ enum machine_mode mode;
|
|
|
++{
|
|
|
++ char s[20];
|
|
|
++ sprintf (s, "%lu", (unsigned long) i);
|
|
|
++ REAL_DEBUG_INFO ("ereal_from_uint s: %s", s);
|
|
|
++ *d = REAL_VALUE_ATOF (s, mode);
|
|
|
++ REAL_DEBUG_INFO ("ereal_from_uint d: %x:%lx-%lx", d->exponent, (unsigned long) (d->mantissa >> 32), (unsigned long) (d->mantissa));
|
|
|
++}
|
|
|
++
|
|
|
++#if 0
|
|
|
+ /* Returns 10**2**N. */
|
|
|
+
|
|
|
+ static const REAL_VALUE_TYPE *
|
|
|
+@@ -2556,6 +3292,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,
|
|
|
+@@ -2565,6 +3302,12 @@
|
|
|
+ real_hash (r)
|
|
|
+ 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;
|
|
|
+
|
|
|
+@@ -2596,8 +3339,10 @@
|
|
|
+ }
|
|
|
+
|
|
|
+ return h;
|
|
|
++#endif /* 0 */
|
|
|
+ }
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* IEEE single-precision format. */
|
|
|
+
|
|
|
+ static void encode_ieee_single PARAMS ((const struct real_format *fmt,
|
|
|
+@@ -4414,3 +5159,5 @@
|
|
|
+ NULL, /* XFmode */
|
|
|
+ &ieee_quad_format /* TFmode */
|
|
|
+ };
|
|
|
++#endif /* 0 */
|
|
|
++
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/real.h gcc-3.3.3.tigcc8/gcc/real.h
|
|
|
+--- gcc-3.3.3.orig/gcc/real.h Wed Jul 2 03:28:44 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/real.h Thu Feb 19 21:20:04 2004
|
|
|
+@@ -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 <smapbcd.h>
|
|
|
++#define SMAP_BCD_FLOAT_FORMAT 5
|
|
|
++
|
|
|
+ #include "machmode.h"
|
|
|
+
|
|
|
+ /* An expanded form of the represented number. */
|
|
|
+@@ -40,6 +56,7 @@
|
|
|
+ #define SIGSZ (SIGNIFICAND_BITS / HOST_BITS_PER_LONG)
|
|
|
+ #define SIG_MSB ((unsigned long)1 << (HOST_BITS_PER_LONG - 1))
|
|
|
+
|
|
|
++/*
|
|
|
+ struct real_value GTY(())
|
|
|
+ {
|
|
|
+ ENUM_BITFIELD (real_value_class) class : 2;
|
|
|
+@@ -47,7 +64,9 @@
|
|
|
+ signed int exp : EXP_BITS;
|
|
|
+ unsigned long sig[SIGSZ];
|
|
|
+ };
|
|
|
++*/
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Various headers condition prototypes on #ifdef REAL_VALUE_TYPE, so it
|
|
|
+ needs to be a macro. We do need to continue to have a structure tag
|
|
|
+ so that other headers can forward declare it. */
|
|
|
+@@ -65,6 +84,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
|
|
|
+@@ -100,6 +122,7 @@
|
|
|
+ #endif
|
|
|
+
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Describes the properties of the specific target format in use. */
|
|
|
+ struct real_format
|
|
|
+ {
|
|
|
+@@ -136,6 +159,7 @@
|
|
|
+ /* The target format used for each floating floating point mode.
|
|
|
+ Indexed by MODE - QFmode. */
|
|
|
+ extern const struct real_format *real_format_for_mode[TFmode - QFmode + 1];
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+
|
|
|
+ /* Declare functions in real.c. */
|
|
|
+@@ -145,6 +169,7 @@
|
|
|
+ const REAL_VALUE_TYPE *,
|
|
|
+ const REAL_VALUE_TYPE *));
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* Compare reals by tree_code. */
|
|
|
+ extern bool real_compare PARAMS ((int, const REAL_VALUE_TYPE *,
|
|
|
+ const REAL_VALUE_TYPE *));
|
|
|
+@@ -212,9 +237,19 @@
|
|
|
+ int, enum machine_mode));
|
|
|
+
|
|
|
+ extern void real_2expN PARAMS ((REAL_VALUE_TYPE *, int));
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ extern unsigned int real_hash PARAMS ((const REAL_VALUE_TYPE *));
|
|
|
+
|
|
|
++extern void ereal_from_int PARAMS ((REAL_VALUE_TYPE *,
|
|
|
++ HOST_WIDE_INT, HOST_WIDE_INT,
|
|
|
++ enum machine_mode));
|
|
|
++extern void ereal_from_uint PARAMS ((REAL_VALUE_TYPE *,
|
|
|
++ unsigned HOST_WIDE_INT,
|
|
|
++ unsigned HOST_WIDE_INT,
|
|
|
++ enum machine_mode));
|
|
|
++extern void ereal_to_int PARAMS ((HOST_WIDE_INT *, HOST_WIDE_INT *,
|
|
|
++ REAL_VALUE_TYPE));
|
|
|
+
|
|
|
+ /* Target formats defined in real.c. */
|
|
|
+ extern const struct real_format ieee_single_format;
|
|
|
+@@ -235,6 +270,7 @@
|
|
|
+ extern const struct real_format real_internal_format;
|
|
|
+
|
|
|
+
|
|
|
++#if 0
|
|
|
+ /* ====================================================================== */
|
|
|
+ /* Crap. */
|
|
|
+
|
|
|
+@@ -318,6 +354,7 @@
|
|
|
+ const REAL_VALUE_TYPE *, int));
|
|
|
+
|
|
|
+ /* **** End of software floating point emulator interface macros **** */
|
|
|
++#endif /* 0 */
|
|
|
+
|
|
|
+ /* Constant real values 0, 1, 2, and -1. */
|
|
|
+
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/sdbout.c gcc-3.3.3.tigcc8/gcc/sdbout.c
|
|
|
+--- gcc-3.3.3.orig/gcc/sdbout.c Tue Sep 17 08:05:52 2002
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/sdbout.c Thu Feb 19 21:20:04 2004
|
|
|
+@@ -1596,9 +1596,7 @@
|
|
|
+ #ifdef ASM_OUTPUT_SOURCE_LINE
|
|
|
+ ASM_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", last_linenum);
|
|
|
+ #endif
|
|
|
+ }
|
|
|
+ }
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/simplify-rtx.c gcc-3.3.3.tigcc8/gcc/simplify-rtx.c
|
|
|
+--- gcc-3.3.3.orig/gcc/simplify-rtx.c Thu Jul 3 09:38:22 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/simplify-rtx.c Thu Feb 19 21:20:04 2004
|
|
|
+@@ -435,7 +435,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
|
|
|
+@@ -463,7 +463,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);
|
|
|
+ }
|
|
|
+
|
|
|
+@@ -660,7 +660,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. */
|
|
|
+@@ -809,8 +809,8 @@
|
|
|
+
|
|
|
+ REAL_VALUE_FROM_CONST_DOUBLE (f0, trueop0);
|
|
|
+ REAL_VALUE_FROM_CONST_DOUBLE (f1, trueop1);
|
|
|
+- f0 = real_value_truncate (mode, f0);
|
|
|
+- f1 = real_value_truncate (mode, f1);
|
|
|
++ f0 = REAL_VALUE_TRUNCATE (mode, f0);
|
|
|
++ f1 = REAL_VALUE_TRUNCATE (mode, f1);
|
|
|
+
|
|
|
+ if (code == DIV
|
|
|
+ && !MODE_HAS_INFINITIES (mode)
|
|
|
+@@ -819,7 +819,7 @@
|
|
|
+
|
|
|
+ REAL_ARITHMETIC (value, rtx_to_tree_code (code), f0, f1);
|
|
|
+
|
|
|
+- value = real_value_truncate (mode, value);
|
|
|
++ value = REAL_VALUE_TRUNCATE (mode, value);
|
|
|
+ return CONST_DOUBLE_FROM_REAL_VALUE (value, mode);
|
|
|
+ }
|
|
|
+
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/stmt.c gcc-3.3.3.tigcc8/gcc/stmt.c
|
|
|
+--- gcc-3.3.3.orig/gcc/stmt.c Thu Aug 21 03:50:02 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/stmt.c Mon Jul 19 05:31:36 2004
|
|
|
+@@ -542,6 +542,22 @@
|
|
|
+
|
|
|
+ emit_queue ();
|
|
|
+
|
|
|
++#if 0 /* (TIGCC 20030607) Revert the following patch:
|
|
|
++
|
|
|
++2003-03-21 Richard Henderson <rth@redhat.com>
|
|
|
++
|
|
|
++ PR opt/2001
|
|
|
++ * bb-reorder.c (maybe_duplicate_computed_goto_succ): New.
|
|
|
++ (make_reorder_chain_1): Call it.
|
|
|
++
|
|
|
++ * function.h (struct function): Add computed_goto_common_label,
|
|
|
++ computed_goto_common_reg.
|
|
|
++ * function.c (free_after_compilation): Zap them.
|
|
|
++ * stmt.c (expand_computed_goto): Use them to produce one
|
|
|
++ indirect branch per function.
|
|
|
++
|
|
|
++because it breaks ER_throw, whereas PR opt/2001 is a compilation slowness
|
|
|
++problem (in an extreme case) only. -- Kevin Kofler */
|
|
|
+ if (! cfun->computed_goto_common_label)
|
|
|
+ {
|
|
|
+ cfun->computed_goto_common_reg = copy_to_mode_reg (Pmode, x);
|
|
|
+@@ -558,6 +574,12 @@
|
|
|
+ emit_move_insn (cfun->computed_goto_common_reg, x);
|
|
|
+ emit_jump (cfun->computed_goto_common_label);
|
|
|
+ }
|
|
|
++#else /* not 0 */
|
|
|
++ do_pending_stack_adjust ();
|
|
|
++ emit_indirect_jump (x);
|
|
|
++
|
|
|
++ current_function_has_computed_jump = 1;
|
|
|
++#endif /* 0 */
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Handle goto statements and the labels that they can go to. */
|
|
|
+@@ -5381,8 +5403,12 @@
|
|
|
+ If the switch-index is a constant, do it this way
|
|
|
+ because we can optimize it. */
|
|
|
+
|
|
|
++/* (TIGCC 20030906) Backport fix for PR middle-end/11823 from mainline (3.4):
|
|
|
++ Only use jump tables for dense switch statements when
|
|
|
++ optimizing for size. */
|
|
|
+ else if (count < case_values_threshold ()
|
|
|
+- || compare_tree_int (range, 10 * count) > 0
|
|
|
++ || compare_tree_int (range,
|
|
|
++ (optimize_size ? 3 : 10) * count) > 0
|
|
|
+ /* RANGE may be signed, and really large ranges will show up
|
|
|
+ as negative numbers. */
|
|
|
+ || compare_tree_int (range, 0) < 0
|
|
|
+@@ -5466,6 +5492,9 @@
|
|
|
+ use_cost_table
|
|
|
+ = (TREE_CODE (orig_type) != ENUMERAL_TYPE
|
|
|
+ && estimate_case_costs (thiscase->data.case_stmt.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 (&thiscase->data.case_stmt.case_list, NULL);
|
|
|
+ emit_case_nodes (index, thiscase->data.case_stmt.case_list,
|
|
|
+ default_label, index_type);
|
|
|
+@@ -6101,10 +6130,17 @@
|
|
|
+ Omit the conditional branch to default if we it avoid only one
|
|
|
+ right child; it costs 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-3.3.3.orig/gcc/toplev.c gcc-3.3.3.tigcc8/gcc/toplev.c
|
|
|
+--- gcc-3.3.3.orig/gcc/toplev.c Tue Dec 23 06:28:28 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/toplev.c Tue Jul 27 12:34:40 2004
|
|
|
+@@ -804,7 +804,7 @@
|
|
|
+ #endif
|
|
|
+
|
|
|
+ /* Nonzero means put zero initialized data in the bss section. */
|
|
|
+-int flag_zero_initialized_in_bss = 1;
|
|
|
++int flag_zero_initialized_in_bss = 0; /* (TIGCC 20031012) */
|
|
|
+
|
|
|
+ /* Enable SSA. */
|
|
|
+ int flag_ssa = 0;
|
|
|
+@@ -883,6 +883,12 @@
|
|
|
+
|
|
|
+ int flag_tracer = 0;
|
|
|
+
|
|
|
++/* (TIGCC) Make compound literals (cast constructors) global for backwards compatibility. */
|
|
|
++int flag_global_compound_literals = 1;
|
|
|
++
|
|
|
++/* (TIGCC 20040727) When merging constants, also merge constant pools. */
|
|
|
++int flag_merge_constant_pools = 1;
|
|
|
++
|
|
|
+ /* Values of the -falign-* flags: how much to align labels in code.
|
|
|
+ 0 means `use default', 1 means `don't align'.
|
|
|
+ For each variable, there is an _log variant which is the power
|
|
|
+@@ -1184,10 +1190,16 @@
|
|
|
+ N_("Report time taken by each compiler pass at end of run") },
|
|
|
+ {"mem-report", &mem_report, 1,
|
|
|
+ N_("Report on permanent memory allocation at end of run") },
|
|
|
+- { "trapv", &flag_trapv, 1,
|
|
|
++ {"trapv", &flag_trapv, 1,
|
|
|
+ N_("Trap for signed overflow in addition / subtraction / multiplication") },
|
|
|
+- { "new-ra", &flag_new_regalloc, 1,
|
|
|
++ {"new-ra", &flag_new_regalloc, 1,
|
|
|
+ N_("Use graph coloring register allocation.") },
|
|
|
++ {"global-compound-literals", &flag_global_compound_literals, 1,
|
|
|
++ N_("Make compound literals (cast constructors) global for backwards compatibility") },
|
|
|
++ {"global-cast-constructors", &flag_global_compound_literals, 1,
|
|
|
++ N_("Make compound literals (cast constructors) global for backwards compatibility") },
|
|
|
++ {"merge-constant-pools", &flag_merge_constant_pools, 1,
|
|
|
++ N_("When merging constants, also merge constant pools") },
|
|
|
+ };
|
|
|
+
|
|
|
+ /* Table of language-specific options. */
|
|
|
+@@ -2692,7 +2704,14 @@
|
|
|
+ | (flag_thread_jumps ? CLEANUP_THREADING : 0));
|
|
|
+
|
|
|
+ /* CFG is no longer maintained up-to-date. */
|
|
|
+- if (optimize)
|
|
|
++ /* (TIGCC 20030421) Reverted the following patch, which is a pessimization in
|
|
|
++ our tests:
|
|
|
++ Wed Mar 5 15:45:40 CET 2003 Jan Hubicka <jh@suse.cz>
|
|
|
++
|
|
|
++ * toplev.c (rest_of_compilation): Do duplicate loop headers when
|
|
|
++ optimizing for size.
|
|
|
++ -- Kevin Kofler */
|
|
|
++ if (optimize && !optimize_size)
|
|
|
+ {
|
|
|
+ free_bb_for_insn ();
|
|
|
+ copy_loop_headers (insns);
|
|
|
+@@ -4021,6 +4040,12 @@
|
|
|
+ fix_register (option_value, 0, 1);
|
|
|
+ else if ((option_value = skip_leading_substring (arg, "call-saved-")))
|
|
|
+ fix_register (option_value, 0, 0);
|
|
|
++ else if ((option_value = skip_leading_substring (arg, "reg-relative-")))
|
|
|
++ {
|
|
|
++ fix_register (option_value, 1, 1);
|
|
|
++ target_flags |= MASK_REG_RELATIVE;
|
|
|
++ strcpy (TARGET_RELATION_REG, option_value);
|
|
|
++ }
|
|
|
+ else if ((option_value = skip_leading_substring (arg, "align-loops=")))
|
|
|
+ align_loops = read_integral_parameter (option_value, arg - 2, align_loops);
|
|
|
+ else if ((option_value = skip_leading_substring (arg, "align-functions=")))
|
|
|
+@@ -5020,6 +5045,11 @@
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
++ /* TIGCC Patch: Register d2 is used by the TIOS calling convention.
|
|
|
++ See "call-used-" further up in this file. */
|
|
|
++ if (TARGET_TIOS)
|
|
|
++ fix_register ("d2", 0, 1);
|
|
|
++
|
|
|
+ if (flag_no_inline == 2)
|
|
|
+ flag_no_inline = 0;
|
|
|
+ else
|
|
|
+@@ -5215,7 +5245,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-3.3.3.orig/gcc/tree-inline.c gcc-3.3.3.tigcc8/gcc/tree-inline.c
|
|
|
+--- gcc-3.3.3.orig/gcc/tree-inline.c Wed Jul 23 09:13:36 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/tree-inline.c Sat Sep 25 00:47:22 2004
|
|
|
+@@ -1180,6 +1180,48 @@
|
|
|
+ return NULL_TREE;
|
|
|
+ }
|
|
|
+
|
|
|
++ /* (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)))
|
|
|
++ return NULL_TREE;
|
|
|
++
|
|
|
++ /* 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)))
|
|
|
++ return NULL_TREE;
|
|
|
++
|
|
|
++ from_arg = TREE_CHAIN (from_arg);
|
|
|
++ to_arg = TREE_CHAIN (to_arg);
|
|
|
++ }
|
|
|
++ }
|
|
|
++ }
|
|
|
++
|
|
|
+ if (! (*lang_hooks.tree_inlining.start_inlining) (fn))
|
|
|
+ return NULL_TREE;
|
|
|
+
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/tree.c gcc-3.3.3.tigcc8/gcc/tree.c
|
|
|
+--- gcc-3.3.3.orig/gcc/tree.c Thu Jan 29 18:58:12 2004
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/tree.c Thu Feb 19 21:20:04 2004
|
|
|
+@@ -830,7 +830,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))));
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/unroll.c gcc-3.3.3.tigcc8/gcc/unroll.c
|
|
|
+--- gcc-3.3.3.orig/gcc/unroll.c Mon Dec 1 22:00:12 2003
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/unroll.c Thu Feb 19 21:20:04 2004
|
|
|
+@@ -326,6 +326,11 @@
|
|
|
+ #ifdef HAVE_cc0
|
|
|
+ rtx prev = PREV_INSN (last_loop_insn);
|
|
|
+ #endif
|
|
|
++
|
|
|
++/* (TIGCC 20030605) Moved this up in order to prevent reachable insns from
|
|
|
++ being mistaken as unreachable. -- Kevin Kofler */
|
|
|
++ delete_related_insns (ujump);
|
|
|
++
|
|
|
+ delete_related_insns (last_loop_insn);
|
|
|
+ #ifdef HAVE_cc0
|
|
|
+ /* The immediately preceding insn may be a compare which must be
|
|
|
+@@ -334,8 +339,6 @@
|
|
|
+ delete_related_insns (prev);
|
|
|
+ #endif
|
|
|
+
|
|
|
+- delete_related_insns (ujump);
|
|
|
+-
|
|
|
+ /* Remove the loop notes since this is no longer a loop. */
|
|
|
+ if (loop->vtop)
|
|
|
+ delete_related_insns (loop->vtop);
|
|
|
+@@ -3933,6 +3936,23 @@
|
|
|
+ (abs_diff + abs_inc - 1) / abs_inc, provided care was taken to
|
|
|
+ handle potential overflow of the summation. */
|
|
|
+ loop_info->n_iterations = abs_diff / abs_inc + ((abs_diff % abs_inc) != 0);
|
|
|
++
|
|
|
++ /* (TIGCC 20031228) If the first instruction in the loop is a jump to cont,
|
|
|
++ then we actually have 1 iteration less.
|
|
|
++ And if we end up with no iteration at all, delete the jump
|
|
|
++ at the end of the loop so the dead code elimination passes
|
|
|
++ will eliminate the useless loop. -- Kevin Kofler */
|
|
|
++ if (loop->cont) {
|
|
|
++ rtx first_loop_insn = NEXT_INSN (loop->start);
|
|
|
++ if (GET_CODE (first_loop_insn) == JUMP_INSN
|
|
|
++ && INSN_LUID (JUMP_LABEL (first_loop_insn))
|
|
|
++ == INSN_LUID (NEXT_INSN (loop->cont))) {
|
|
|
++ loop_info->n_iterations--;
|
|
|
++ if (!loop_info->n_iterations)
|
|
|
++ delete_related_insns (last_loop_insn);
|
|
|
++ }
|
|
|
++ }
|
|
|
++
|
|
|
+ return loop_info->n_iterations;
|
|
|
+ }
|
|
|
+
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/varasm.c gcc-3.3.3.tigcc8/gcc/varasm.c
|
|
|
+--- gcc-3.3.3.orig/gcc/varasm.c Mon Jan 12 18:23:08 2004
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/varasm.c Sun Aug 8 07:27:00 2004
|
|
|
+@@ -221,6 +221,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
|
|
|
+@@ -590,7 +630,26 @@
|
|
|
+ unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
|
|
|
+ unsigned int flags ATTRIBUTE_UNUSED;
|
|
|
+ {
|
|
|
+-#ifdef HAVE_GAS_SHF_MERGE
|
|
|
++/* (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 /*def HAVE_GAS_SHF_MERGE*/
|
|
|
+ if (flag_merge_constants
|
|
|
+ && TREE_CODE (decl) == STRING_CST
|
|
|
+ && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
|
|
|
+@@ -665,7 +724,25 @@
|
|
|
+ unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
|
|
|
+ unsigned int flags ATTRIBUTE_UNUSED;
|
|
|
+ {
|
|
|
+-#ifdef HAVE_GAS_SHF_MERGE
|
|
|
++/* (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 /*def HAVE_GAS_SHF_MERGE*/
|
|
|
+ unsigned int modesize = GET_MODE_BITSIZE (mode);
|
|
|
+
|
|
|
+ if (flag_merge_constants
|
|
|
+@@ -1368,7 +1445,15 @@
|
|
|
+
|
|
|
+ if (destination == asm_dest_bss)
|
|
|
+ globalize_decl (decl);
|
|
|
+- 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));
|
|
|
+
|
|
|
+ if (flag_shared_data)
|
|
|
+ {
|
|
|
+@@ -1569,7 +1654,15 @@
|
|
|
+ reloc = contains_pointers_p (TREE_TYPE (decl)) ? 3 : 0;
|
|
|
+ else if (DECL_INITIAL (decl))
|
|
|
+ reloc = output_addressed_constants (DECL_INITIAL (decl));
|
|
|
+- resolve_unique_section (decl, reloc, flag_data_sections);
|
|
|
++ /* (TIGCC 20040620) See the note about common symbols above. -- Kevin Kofler */
|
|
|
++ 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));
|
|
|
+
|
|
|
+ /* Handle uninitialized definitions. */
|
|
|
+
|
|
|
+@@ -2023,6 +2116,13 @@
|
|
|
+ assemble_integer (GEN_INT (data[2]), 4, nalign, 1);
|
|
|
+ assemble_integer (GEN_INT (data[3]), 4, nalign, 1);
|
|
|
+ break;
|
|
|
++ case BFmode:
|
|
|
++ /* 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);
|
|
|
++ break;
|
|
|
+ default:
|
|
|
+ abort ();
|
|
|
+ }
|
|
|
+@@ -2251,6 +2351,9 @@
|
|
|
+ int len, i;
|
|
|
+ enum tree_code code = TREE_CODE (exp);
|
|
|
+
|
|
|
++ if (!code)
|
|
|
++ abort();
|
|
|
++
|
|
|
+ /* Either set P and LEN to the address and len of something to hash and
|
|
|
+ exit the switch or return a value. */
|
|
|
+
|
|
|
+@@ -2953,6 +3056,9 @@
|
|
|
+
|
|
|
+ value->mode = GET_MODE (x);
|
|
|
+
|
|
|
++ value->un.du.exponent = r->exponent;
|
|
|
++ value->un.du.mantissa = r->mantissa;
|
|
|
++#if 0
|
|
|
+ /* Copy the REAL_VALUE_TYPE by members so that we don't
|
|
|
+ copy garbage from the original structure into our
|
|
|
+ carefully cleaned hashing structure. */
|
|
|
+@@ -2972,6 +3078,7 @@
|
|
|
+ default:
|
|
|
+ abort ();
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+@@ -3016,6 +3123,9 @@
|
|
|
+ /* Copy the REAL_VALUE_TYPE by members so that we don't
|
|
|
+ copy garbage from the original structure into our
|
|
|
+ carefully cleaned hashing structure. */
|
|
|
++ d->exponent = r->exponent;
|
|
|
++ d->mantissa = r->mantissa;
|
|
|
++#if 0
|
|
|
+ d->class = r->class;
|
|
|
+ d->sign = r->sign;
|
|
|
+ switch (r->class)
|
|
|
+@@ -3032,6 +3142,7 @@
|
|
|
+ default:
|
|
|
+ abort ();
|
|
|
+ }
|
|
|
++#endif /* 0 */
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+@@ -3445,7 +3556,18 @@
|
|
|
+ }
|
|
|
+
|
|
|
+ /* First switch to correct section. */
|
|
|
+- (*targetm.asm_out.select_rtx_section) (pool->mode, x, pool->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) (pool->mode, x, pool->align);
|
|
|
+
|
|
|
+ #ifdef ASM_OUTPUT_SPECIAL_POOL_ENTRY
|
|
|
+ ASM_OUTPUT_SPECIAL_POOL_ENTRY (asm_out_file, x, pool->mode,
|
|
|
+@@ -3724,10 +3846,18 @@
|
|
|
+ case MINUS_EXPR:
|
|
|
+ reloc = output_addressed_constants (TREE_OPERAND (exp, 0));
|
|
|
+ reloc2 = output_addressed_constants (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;
|
|
|
+
|
|
|
+@@ -4929,6 +5059,19 @@
|
|
|
+ || 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;
|
|
|
++ }
|
|
|
++
|
|
|
+ return flags;
|
|
|
+ }
|
|
|
+
|
|
|
+@@ -5066,6 +5209,21 @@
|
|
|
+ {
|
|
|
+ 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 (decl_readonly_section (decl, reloc))
|
|
|
+@@ -5073,11 +5231,24 @@
|
|
|
+ }
|
|
|
+ else if (TREE_CODE (decl) == CONSTRUCTOR)
|
|
|
+ {
|
|
|
+- if (! ((flag_pic && reloc)
|
|
|
+- || !TREE_READONLY (decl)
|
|
|
++ /* (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) && !flag_global_compound_literals)
|
|
|
+ || TREE_SIDE_EFFECTS (decl)
|
|
|
+ || !TREE_CONSTANT (decl)))
|
|
|
+- readonly = true;
|
|
|
++ {
|
|
|
++ mergeable_constant_section (DECL_MODE (decl), align, 0);
|
|
|
++ break;
|
|
|
++ }
|
|
|
++ }
|
|
|
++ /* (TIGCC 20040727) Put complex literals in mergeable sections.
|
|
|
++ -- Kevin Kofler */
|
|
|
++ else if (TREE_CODE (decl) == COMPLEX_CST)
|
|
|
++ {
|
|
|
++ mergeable_constant_section (DECL_MODE (decl), align, 0);
|
|
|
++ break;
|
|
|
+ }
|
|
|
+ else if (TREE_CODE (decl) == STRING_CST)
|
|
|
+ readonly = !flag_writable_strings;
|
|
|
+@@ -5088,48 +5259,12 @@
|
|
|
+ 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 PARAMS ((tree, int, int));
|
|
|
+-
|
|
|
+ static enum section_category
|
|
|
+ categorize_decl_for_section (decl, reloc, shlib)
|
|
|
+ tree decl;
|
|
|
+@@ -5150,7 +5285,12 @@
|
|
|
+ else if (TREE_CODE (decl) == VAR_DECL)
|
|
|
+ {
|
|
|
+ if (DECL_INITIAL (decl) == NULL
|
|
|
+- || DECL_INITIAL (decl) == error_mark_node)
|
|
|
++ || DECL_INITIAL (decl) == error_mark_node
|
|
|
++/* (TIGCC 20040620) Someone forgot about -fzero-initialized-in-bss here...
|
|
|
++ -- Kevin Kofler */
|
|
|
++ || (flag_zero_initialized_in_bss
|
|
|
++ && !TREE_READONLY (decl)
|
|
|
++ && initializer_zerop (DECL_INITIAL (decl))))
|
|
|
+ ret = SECCAT_BSS;
|
|
|
+ else if (! TREE_READONLY (decl)
|
|
|
+ || TREE_SIDE_EFFECTS (decl)
|
|
|
+diff -Naur gcc-3.3.3.orig/gcc/version.c gcc-3.3.3.tigcc8/gcc/version.c
|
|
|
+--- gcc-3.3.3.orig/gcc/version.c Sat Feb 14 20:20:58 2004
|
|
|
++++ gcc-3.3.3.tigcc8/gcc/version.c Sat Sep 25 00:22:34 2004
|
|
|
+@@ -6,7 +6,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[] = "3.3.3";
|
|
|
++const char version_string[] = "3.3.3-tigcc-8";
|
|
|
+
|
|
|
+ /* This is the location of the online document giving instructions for
|
|
|
+ reporting bugs. If you distribute a modified version of GCC,
|
|
|
+@@ -15,4 +15,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/";
|