mirror of
https://github.com/bebbo/amigaos-cross-toolchain.git
synced 2025-12-08 22:38:24 +00:00
88 lines
3.0 KiB
Diff
88 lines
3.0 KiB
Diff
--- gcc-3.4.6/gcc/c-decl.c 2013-05-19 20:09:27.000000000 +0200
|
|
+++ gcc-3.4.6-patched/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);
|