2
0
mirror of https://github.com/bebbo/amigaos-cross-toolchain.git synced 2025-12-08 22:38:24 +00:00
Files
amigaos-cross-toolchain6/patches/gcc-2.95.3/gcc/c-decl.c.diff
Krystian Bacławski da2d7bde0e Update patches.
2012-08-04 13:01:59 +02:00

93 lines
3.1 KiB
Diff

--- gcc-2.95.3/gcc/c-decl.c 2001-01-25 15:02:59.000000000 +0100
+++ gcc-2.95.3/gcc/c-decl.c 2012-08-04 11:53:28.000000000 +0200
@@ -4227,8 +4227,9 @@
record the given order of parms in `parm_order'. */
void
-push_parm_decl (parm)
- tree parm;
+/* Amiga: explicit register specification for parameters */
+push_parm_decl (parm, asmspec)
+ tree parm, asmspec;
{
tree decl;
int old_immediate_size_expand = immediate_size_expand;
@@ -4253,6 +4254,77 @@
}
#endif
+ /* Amiga: explicit register specification for parameters */
+ if (asmspec)
+#ifdef TARGET_AMIGAOS
+ {
+ 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 /* !TARGET_AMIGAOS */
+ error("explicit register specification for parameters is not supported for this target");
+#endif /* !TARGET_AMIGAOS */
+
decl = pushdecl (decl);
immediate_size_expand = old_immediate_size_expand;