mirror of
https://github.com/bebbo/amigaos-cross-toolchain.git
synced 2025-12-08 22:38:24 +00:00
93 lines
3.1 KiB
Diff
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;
|