2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
5 /* This program generates the libcall.h macroset for gcc-4.5.1 m68k-elf
7 * WARNING: The header generated by this program is designed
8 * to work with GCC 4.5.1 and GCC 4.6.1 m68k-elf ONLY.
10 * If it breaks, you get to keep both pieces.
15 #define GENCALL_MAX (13 + 1) /* Max number of arguments */
17 /* NOTE: For all 'call' macros, ie AROS_LC5(), the
18 * 'bt' parameter is frequently garbled by
19 * callers who use '#define's like:
21 * #define UtilityBase mydata->utilitybase
23 * this makes a 'bt' parameter of 'struct UtilityBase *'
24 * turn into 'struct mydata->utilitybase *'.
26 * Unhappiness ensues. So, we must use 'void *'
27 * for all 'bt' arguments in the call macros.
30 #define FLAG_BN (1 << 0)
31 #define FLAG_DOUBLE (1 << 1)
33 void aros_ufp(int id
, int is_static
)
37 printf("#define AROS_UFP%d%s(t,n", id
, is_static
? "S" : "");
38 for (i
= 0; i
< id
; i
++)
39 printf(",a%d", i
+ 1);
41 printf("\t%st n (void)\n", is_static
? "static " : "");
44 void aros_ufh(int id
, int is_static
)
48 printf("#define AROS_UFH%d%s(t,n", id
, is_static
? "S" : "");
49 for (i
= 0; i
< id
; i
++)
50 printf(",a%d", i
+ 1);
52 printf("\t%st n (void) {%s\n", is_static
? "static " : "", (i
==0) ? "" : " \\");
53 for (i
= 0; i
< id
; i
++)
54 printf(" \\\n\t__AROS_UFPA(a%d) __attribute__((unused)) __AROS_UFCA(a%d) = __AROS_ISREG(a%d,__AROS_FP_REG) ? (__AROS_UFPA(a%d))(ULONG)__builtin_frame_address(1) : ({register ULONG __r asm(__AROS_LSA(a%d));(__AROS_UFPA(a%d))__r;});", i
+1, i
+1, i
+1, i
+1, i
+1, i
+1);
58 static void asm_regs_init(int id
, int flags
, const char *jmp
, const char *addr
)
61 int has_bn
= (flags
& FLAG_BN
);
62 int ret_d
= (flags
& FLAG_DOUBLE
);
65 for (i
= 0; i
< id
; i
++)
66 printf("\t ULONG _arg%d = (ULONG)__AROS_LCA(a%d); \\\n",
70 printf("\t ULONG _bn_arg = (ULONG)bn; \\\n");
72 /* Define registers */
73 printf("\t register volatile ULONG _ret0 asm(\"%%d0\"); \\\n");
75 printf("\t register volatile ULONG _ret1 asm(\"%%d1\"); \\\n");
76 for (i
= 0; i
< id
; i
++)
77 printf("\t register volatile ULONG __AROS_LTA(a%d) asm(__AROS_LSA(a%d)); \\\n",
81 printf("\t register volatile ULONG _bn asm(\"%%a6\"); \\\n");
84 /* Set registers (non FP) */
85 for (i
= 1; i
<= id
; i
++)
86 printf("\t if (! __AROS_ISREG(a%d,__AROS_FP_REG)) { \\\n"
87 "\t __AROS_LTA(a%d) = _arg%d; } \\\n",
91 printf("\t if (! __AROS_ISREG(bt,bn,A6,__AROS_FP_REG)) { \\\n"
92 "\t _bn = _bn_arg; } \\\n"
96 for (i
= 1; i
<= id
; i
++)
99 printf("\t if ( __AROS_ISREG(a%d,__AROS_FP_REG)) { \\\n"
100 "\t asm volatile (\"move.l %%%%\" __AROS_FP_SREG \",%%%%sp@-\\nmove.l %%0,%%%%\" __AROS_FP_SREG \"\\n%s\\nmove.l %%%%sp@+,%%%%\" __AROS_FP_SREG \"\\n\" : : \"r\" (_arg%d), %s \\\n",
103 for (j
= 0; j
< id
; j
++)
104 printf("\t\t, \"r\" (__AROS_LTA(a%d)) \\\n", j
+ 1);
105 printf("\t ); }\\\n");
110 printf("\t if ( __AROS_ISREG(bt,bn,A6,__AROS_FP_REG)) { \\\n"
111 "\t asm volatile (\"move.l %%%%\" __AROS_FP_SREG \",%%%%sp@-\\nmove.l %%0,%%%%\" __AROS_FP_SREG \"\\n%s\\nmove.l %%%%sp@+,%%%%\" __AROS_FP_SREG \"\\n\" : : \"r\" (_bn_arg), %s \\\n", jmp
, addr
113 for (j
= 0; j
< id
; j
++)
114 printf("\t\t, \"r\" (__AROS_LTA(a%d)) \\\n", j
+ 1);
115 printf("\t ); }\\\n");
117 if (has_bn
|| id
> 0)
120 printf("\t if (!(0");
122 printf(" || __AROS_ISREG(bt,bn,A6,__AROS_FP_REG)");
123 for (i
= 0; i
< id
; i
++)
124 printf(" || __AROS_ISREG(a%d,__AROS_FP_REG)", i
+1);
126 "\t asm volatile (\"%s\\n\" : : \"i\" (0), %s \\\n", jmp
, addr
128 for (j
= 0; j
< id
; j
++)
129 printf("\t\t, \"r\" (__AROS_LTA(a%d)) \\\n", j
+ 1);
130 printf("\t ); }\\\n");
134 static void asm_regs_exit(int id
, int flags
)
136 int ret_d
= (flags
& FLAG_DOUBLE
);
138 /* Get the return code */
141 printf("\t asm volatile (\"\" : \"=r\" (_ret0), \"=r\" (_ret1) : : \"%%a0\", \"%%a1\", \"cc\", \"memory\"); \\\n");
142 printf("\t (t)({union { struct { ULONG r0,r1; } v; double d; } rv;\\\n");
143 printf("\t rv.v.r0 = _ret0; rv.v.r1 = _ret1; rv.d; });\\\n");
147 printf("\t asm volatile (\"\" : \"=r\" (_ret0) : : \"%%d1\", \"%%a0\", \"%%a1\", \"cc\", \"memory\"); \\\n");
148 printf("\t (t)_ret0; \\\n");
152 static void aros_ufc(int id
)
157 printf("#define AROS_UFC%d(t,n", id
);
158 for (i
= 0; i
< id
; i
++)
159 printf(",a%d", i
+ 1);
161 printf("\t({ APTR _n = (n);\\\n");
162 snprintf(jmp
, sizeof(jmp
),
164 "move.l %%1, %%%%sp@-\\n"
168 jmp
[sizeof(jmp
)-1]=0;
169 asm_regs_init(i
, 0, jmp
, "\"r\" (_n), \"i\" (__LINE__)");
175 void aros_lc(int id
, int is_double
)
178 int flags
= FLAG_BN
| (is_double
? FLAG_DOUBLE
: 0);
180 printf("#define AROS_LC%d%s(t,n,", id
, is_double
? "D" : "");
181 for (i
= 0; i
< id
; i
++)
182 printf("a%d,", i
+ 1);
183 printf("bt,bn,o,s) \\\n");
185 asm_regs_init(id
, flags
, "jsr %c1(%%a6)", "\"i\" (-1 * (o) * LIB_VECTSIZE), \"r\" (_bn)");
186 asm_regs_exit(id
, flags
);
190 void aros_lp(int id
, int is_ignored
)
194 printf("#define AROS_LP%d%s(t,n,", id
, is_ignored
? "I" : "");
195 for (i
= 0; i
< id
; i
++)
196 printf("a%d,", i
+ 1);
197 printf("bt,bn,o,s) \\\n");
199 for (i
= 0; i
< id
; i
++)
200 printf("__AROS_LHA(a%d)%s",
202 ((i
+ 1) == id
) ? "" : ", \\\n\t"
209 void aros_lh(int id
, int is_ignored
)
213 printf("#define AROS_LH%d%s(t,n,", id
, is_ignored
? "I" : "");
214 for (i
= 0; i
< id
; i
++)
215 printf("a%d,", i
+ 1);
216 printf("bt,bn,o,s) \\\n");
217 printf("\tt AROS_SLIB_ENTRY(n,s,o) (void) {");
218 for (i
= 0; i
< id
; i
++)
219 printf(" \\\n\t__AROS_LPA(a%d) __attribute__((unused)) __AROS_LCA(a%d) = __AROS_ISREG(a%d,__AROS_FP_REG) ? (__AROS_LPA(a%d))(ULONG)__builtin_frame_address(1) : ({register ULONG __r asm(__AROS_LSA(a%d));(__AROS_LPA(a%d))__r;});", i
+1, i
+1, i
+1, i
+1, i
+1, i
+1);
221 printf(" \\\n\tregister bt __attribute__((unused)) bn = __AROS_ISREG(bn,bt,A6,__AROS_FP_REG) ? (bt)(ULONG)__builtin_frame_address(1) : ({register ULONG __r asm(\"%%a6\");(bt)__r;});");
225 static void aros_lcnr(int id
)
227 printf("#define AROS_LC%dNR AROS_LC%d\n", id
, id
);
230 static void aros_call(int id
)
233 printf("#define AROS_CALL%d(t,n,", id
);
234 for (i
= 0; i
< id
; i
++)
235 printf("a%d,", i
+ 1);
236 printf("bt,bn) \\\n");
237 printf("\tAROS_UFC%d(t,n", id
+ 1);
238 for (i
= 0; i
< id
; i
++)
240 printf(",AROS_UFCA(a%d)", i
+ 1);
242 printf(",AROS_UFCA(bt,bn,A6))\n");
245 static void aros_callnr(int id
)
247 printf("#define AROS_CALL%dNR AROS_CALL%d\n", id
, id
);
250 static void aros_lvo_call(int id
)
253 printf("#define AROS_LVO_CALL%d(t,", id
);
254 for (i
= 0; i
< id
; i
++)
255 printf("a%d,", i
+ 1);
256 printf("bt,bn,o,s) \\\n");
257 printf("\tAROS_CALL%d(t,__AROS_GETVECADDR(bn,o), \\\n", id
);
258 for (i
= 0; i
< id
; i
++)
259 printf("\t\tAROS_LCA(a%d), \\\n", i
+ 1);
260 printf("\t\tbt,bn)\n");
263 static void aros_lvo_callnr(int id
)
266 printf("#define AROS_LVO_CALL%dNR(t,", id
);
267 for (i
= 0; i
< id
; i
++)
268 printf("a%d,", i
+ 1);
269 printf("bt,bn,o,s) \\\n");
270 printf("\tAROS_CALL%dNR(t,__AROS_GETVECADDR(bn,o), \\\n", id
);
271 for (i
= 0; i
< id
; i
++)
272 printf("\t\tAROS_LCA(a%d), \\\n", i
+ 1);
273 printf("\t\tbt,bn)\n");
276 static void aros_ld(int id
, int is_ignored
)
280 printf("#define AROS_LD%d%s(t,n,", id
, is_ignored
? "I" : "");
281 for (i
= 0; i
< id
; i
++)
282 printf("a%d,", i
+ 1);
283 printf("bt,bn,o,s) \\\n");
284 printf("\t__AROS_LD_PREFIX t AROS_SLIB_ENTRY(n,s,o) (void)\n");
287 int main(int argc
, char **argv
)
291 printf("/* AUTOGENERATED by arch/m68k-all/include/gencall.c */\n");
292 printf("/* If you can get this to work for anything other */\n");
293 printf("/* than gcc-4.5.1 m68k-elf, it would be surprising. */\n");
295 printf("#ifndef AROS_M68K_LIBCALL_H\n");
296 printf("#define AROS_M68K_LIBCALL_H\n");
298 printf("/* Call a libary function which requires the libbase */\n");
300 printf("#define __AROS_CPU_SPECIFIC_ASMCALLS\n\n");
302 for (i
= 0; i
< GENCALL_MAX
; i
++)
305 for (i
= 0; i
< GENCALL_MAX
; i
++)
308 for (i
= 0; i
< GENCALL_MAX
; i
++)
311 for (i
= 0; i
< GENCALL_MAX
; i
++)
314 for (i
= 0; i
< GENCALL_MAX
; i
++)
317 printf("#define __AROS_CPU_SPECIFIC_LP\n\n");
319 for (i
= 0; i
< GENCALL_MAX
; i
++)
322 for (i
= 0; i
< GENCALL_MAX
; i
++)
326 printf("#define __AROS_CPU_SPECIFIC_LH\n\n");
328 for (i
= 0; i
< GENCALL_MAX
; i
++)
331 for (i
= 0; i
< GENCALL_MAX
; i
++)
335 printf("#define __AROS_CPU_SPECIFIC_LC\n\n");
337 for (i
= 0; i
< GENCALL_MAX
; i
++)
340 /* For double return AROS_LC2D..AROS_LC4D */
345 for (i
= 0; i
< GENCALL_MAX
; i
++)
348 for (i
= 0; i
< GENCALL_MAX
; i
++)
351 for (i
= 0; i
< GENCALL_MAX
; i
++)
354 for (i
= 0; i
< GENCALL_MAX
; i
++)
357 for (i
= 0; i
< GENCALL_MAX
; i
++)
361 printf("#define __AROS_CPU_SPECIFIC_LD\n\n");
363 for (i
= 0; i
< GENCALL_MAX
; i
++)
366 for (i
= 0; i
< GENCALL_MAX
; i
++)
369 printf("#endif /* AROS_M68K_LIBCALL_H */\n");