--- 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);