diff options
Diffstat (limited to 'm68k-unknown-amigaos/recipes/patches/gcc/gcc.c-decl.c.p')
-rw-r--r-- | m68k-unknown-amigaos/recipes/patches/gcc/gcc.c-decl.c.p | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc.c-decl.c.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.c-decl.c.p new file mode 100644 index 0000000..6e7e353 --- /dev/null +++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc.c-decl.c.p @@ -0,0 +1,87 @@ +--- gcc-3.4.6/gcc/c-decl.c 2013-05-19 20:09:27.000000000 +0200 ++++ gcc/c-decl.c 2013-05-19 20:23:32.000000000 +0200 +@@ -2960,7 +2960,7 @@ + and push that on the current scope. */ + + void +-push_parm_decl (tree parm) ++push_parm_decl (tree parm, tree asmspec) + { + tree decl; + int old_dont_save_pending_sizes_p = 0; +@@ -2983,6 +2983,75 @@ + PARM, 0, NULL); + decl_attributes (&decl, TREE_VALUE (parm), 0); + ++ /* begin-GG-local: explicit register specification for parameters */ ++ if (asmspec) ++#ifdef TARGET_AMIGAOS ++ { ++ 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; ++ /* 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, COMPARE_STRICT)==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; ++ } ++ else ++ error ("%Jregister specified for '%D' isn't suitable for data type", ++ decl, decl); ++ } ++ else ++ error ("invalid register name `%s'", regname); ++ } ++#else /* !TARGET_AMIGAOS */ ++ error("explicit register specification for parameters is not supported for this target"); ++#endif /* !TARGET_AMIGAOS */ ++ /* end-GG-local */ ++ + decl = pushdecl (decl); + + finish_decl (decl, NULL_TREE, NULL_TREE); |