Library stub code can be generated in C files with a simple macro during compile...
[AROS.git] / arch / m68k-all / include / aros / cpu.h
blob06ab7aea23d6619f3877f51d49467e2f7666ab16
1 #ifndef AROS_M68K_CPU_H
2 #define AROS_M68K_CPU_H
4 #include <aros/config.h>
6 /*
7 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
8 $Id$
10 NOTE: This file must compile *without* any other header !
12 Desc: machine.h
13 Lang: english
16 #define EnableSetFunction 1
18 /* Information about size and alignment,
19 * the defines have to be numeric constants */
20 #define AROS_STACK_GROWS_DOWNWARDS 1 /* Stack direction */
21 #define AROS_BIG_ENDIAN 1 /* Big or little endian */
22 #define AROS_SIZEOFULONG 4 /* Size of an ULONG */
23 #define AROS_SIZEOFPTR 4 /* Size of a PTR */
24 #define AROS_WORDALIGN 2 /* Alignment for WORD */
25 #define AROS_LONGALIGN 2 /* Alignment for LONG */
26 #define AROS_QUADALIGN 2 /* Alignment for QUAD */
27 #define AROS_PTRALIGN 2 /* Alignment for PTR */
28 #define AROS_IPTRALIGN 2 /* Alignment for IPTR */
29 #define AROS_DOUBLEALIGN 2 /* Alignment for double */
30 #define AROS_WORSTALIGN 4 /* Worst case alignment */
32 #define AROS_NOFPU 1
34 /* do we need a function attribute to get parameters on the stack? */
35 #define __stackparm
37 #define STACKED
39 /* types and limits for sig_atomic_t */
40 #define AROS_SIG_ATOMIC_T int
41 #define AROS_SIG_ATOMIC_MIN (-0x7fffffff-1)
42 #define AROS_SIG_ATOMIC_MAX 0x7fffffff
44 #define AROS_GET_SP ({register unsigned char * sp asm("%sp"); sp;})
47 One entry in a libraries' jumptable. For assembler compatibility, the
48 field jmp should contain the code for an absolute jmp to a 32bit
49 address. There are also a couple of macros which you should use to
50 access the vector table from C.
52 struct JumpVec
54 unsigned short jmp;
55 void *vec;
59 /* Any jump to an unimplemented vector will cause an access to this address */
60 #define _aros_empty_vector 0xc0edbabe
62 /* Internal macros */
63 #define __AROS_ASMJMP 0x4EF9
64 #define __AROS_SET_VEC(v,a) ((v)->vec=(a))
65 #define __AROS_GET_VEC(v) ((v)->vec)
67 struct FullJumpVec
69 unsigned short jmp;
70 void *vec;
72 #define __AROS_SET_FULLJMP(v,a) \
73 do \
74 { \
75 struct FullJumpVec *_v = v; \
76 _v->jmp = __AROS_ASMJMP; \
77 _v->vec = ((void *)(a)); \
78 } while(0)
81 /* Use these to acces a vector table */
82 #define LIB_VECTSIZE (sizeof (struct JumpVec))
83 #define __AROS_GETJUMPVEC(lib,n) (&(((struct JumpVec *)(lib))[-(n)]))
84 #if (AROS_FLAVOUR & AROS_FLAVOUR_BINCOMPAT)
85 #define __AROS_GETVECADDR(lib,n) ((void *)__AROS_GETJUMPVEC(lib,n))
86 #else
87 #define __AROS_GETVECADDR(lib,n) (__AROS_GET_VEC(__AROS_GETJUMPVEC(lib,n)))
88 #endif
89 #define __AROS_SETVECADDR(lib,n,addr) (__AROS_SET_VEC(__AROS_GETJUMPVEC(lib,n),(APTR)(addr)))
90 #define __AROS_INITVEC(lib,n) __AROS_GETJUMPVEC(lib,n)->jmp = __AROS_ASMJMP, \
91 __AROS_SETVECADDR(lib,n,_aros_empty_vector)
94 #define SIZEOF_ALL_REGISTERS (20*4)
97 /* Macros for generating library stub functions and aliases. */
99 /* Macro: AROS_LIBFUNCSTUB(functionname, libbasename, lvo)
100 This macro will generate code for a stub function for
101 the function 'functionname' of lirary with libbase
102 'libbasename' and 'lvo' number of the function in the
103 vector table. lvo has to be a constant value (not a variable)
105 Internals: a dummy function is used that will generate some
106 unused junk code but otherwise we can't pass input arguments
107 to the asm statement
109 #define __AROS_LIBFUNCSTUB(fname, libbasename, lvo) \
110 void __ ## fname ## _ ## libbasename ## _wrapper(void) \
112 asm volatile( \
113 ".globl " #fname "\n" \
114 "\t" #fname ":\n" \
115 "\tmovl " #libbasename ",%%a0\n" \
116 "\tlea.l %c0(%%a0),%%a0\n" \
117 "\tjmp (%%a0)\n" \
118 : : "i" ((-lvo*LIB_VECTSIZE)) \
119 ); \
121 #define AROS_LIBFUNCSTUB(fname, libbasename, lvo) \
122 __AROS_LIBFUNCSTUB(fname, libbasename, lvo)
124 /* Macro: AROS_FUNCALIAS(functionname, alias)
125 This macro will generate an alias 'alias' for function
126 'functionname'
128 #define __AROS_FUNCALIAS(fname, alias) \
129 asm(".weak " #alias "\n" \
130 "\t.set " #alias "," #fname \
132 #define AROS_FUNCALIAS(fname, alias) \
133 __AROS_FUNCALIAS(fname, alias)
136 We want to activate the execstubs and preserve all registers
137 when calling obtainsemaphore, obtainsemaphoreshared, releasesemaphore,
138 getcc, permit, forbid, enable, disable
140 #undef UseExecstubs
141 //#define UseExecstubs 1
143 /* Macros to test/set failure of AllocEntry() */
144 #define AROS_ALLOCENTRY_FAILED(memType) \
145 ((struct MemList *)((IPTR)(memType) | 0x80ul<<(sizeof(APTR)-1)*8))
146 #define AROS_CHECK_ALLOCENTRY(memList) \
147 (!((IPTR)(memList) & 0x80ul<<(sizeof(APTR)-1)*8))
150 Find the next valid alignment for a structure if the next x bytes must
151 be skipped.
153 #define AROS_ALIGN(x) (((x)+AROS_WORSTALIGN-1)&-AROS_WORSTALIGN)
155 /* Prototypes */
156 extern void _aros_not_implemented ();
157 extern void aros_not_implemented ();
160 How much stack do we need ? Lots :-) ?
161 Not so much, I think (schulz) ;-))
164 #define AROS_STACKSIZE 0x4000
166 //#define AROS_NEEDS___MAIN
168 /* How to map function arguments to CPU registers */
170 /* Prefix for library function in header, prototype and call */
171 #define __AROS_LH_PREFIX /* eps */
172 #define __AROS_LP_PREFIX /* eps */
173 #define __AROS_LC_PREFIX /* eps */
174 #define __AROS_LD_PREFIX /* eps */
175 #define __AROS_UFH_PREFIX /* eps */
176 #define __AROS_UFP_PREFIX /* eps */
177 #define __AROS_UFC_PREFIX /* eps */
178 #define __AROS_UFD_PREFIX /* eps */
180 #define AROS_COMPAT_SETD0(x) do { asm volatile ( "move.l %0,%%d0\n" : "=g" (x)); return; } while (0)
182 #define A0 a0
183 #define A1 a1
184 #define A2 a2
185 #define A3 a3
186 #define A4 a4
187 #define A5 a5
188 #define A6 a6
189 #define D0 d0
190 #define D1 d1
191 #define D2 d2
192 #define D3 d3
193 #define D4 d4
194 #define D5 d5
195 #define D6 d6
196 #define D7 d7
198 #ifdef CONFIG_GCC_FP_A6
199 #define __AROS_FP_REG A6
200 #define __AROS_FP_SREG "A6"
201 #else
202 #define __AROS_FP_REG A5
203 #define __AROS_FP_SREG "A5"
204 #endif
206 #define ___AROS_ISREG(reg,regcmp) (0x##reg == 0x##regcmp)
207 #define __AROS_ISREG(type,name,reg,regcmp) ___AROS_ISREG(reg,regcmp)
209 /* What to do with the library base in header, prototype and call */
210 #define __AROS_LH_BASE(basetype,basename) basetype basename
211 #define __AROS_LP_BASE(basetype,basename) basetype
212 #define __AROS_LC_BASE(basetype,basename) basename
213 #define __AROS_LD_BASE(basetype,basename) basetype
215 /* Get the register from a triplet */
216 #define __AROS_LRA(type,name,reg) reg
217 #define __AROS_UFRA(type,name,reg) reg
218 #define __AROS_LRAQUAD1(type,name,reg1,reg2) reg1
219 #define __AROS_LRAQUAD2(type,name,reg1,reg2) reg2
221 /* Temporary variables */
222 #define __AROS_LTA(type,name,reg) reg##_tmp
223 #define __AROS_UFTA(type,name,reg) reg##_tmp
224 #define __AROS_LTAQUAD(type,name,reg1,reg2) reg1##_##reg2##_tmp
225 #define __AROS_LTAQUAD1(type,name,reg1,reg2) reg1##_tmp
226 #define __AROS_LTAQUAD2(type,name,reg1,reg2) reg2##_tmp
228 /* Get the register as a string from the triplet */
229 #define __AROS_LSA(type,name,reg) "%"#reg
230 #define __AROS_UFSA(type,name,reg) "%"#reg
231 #define __AROS_LSAQUAD1(type,name,reg1,reg2) "%"#reg1
232 #define __AROS_LSAQUAD2(type,name,reg1,reg2) "%"#reg2
234 /* How to transform an argument in header, opt prototype, call and forced
235 prototype. */
236 #define __AROS_LHA(type,name,reg) type name
237 #define __AROS_LPA(type,name,reg) type
238 #define __AROS_LCA(type,name,reg) (name)
239 #define __AROS_LDA(type,name,reg) type
240 #define __AROS_UFHA(type,name,reg) type name
241 #define __AROS_UFPA(type,name,reg) type
242 #define __AROS_UFCA(type,name,reg) (name)
243 #define __AROS_UFDA(type,name,reg) type
244 #define __AROS_LHAQUAD(type,name,reg1,reg2) type name
245 #define __AROS_LPAQUAD(type,name,reg1,reg2) type
246 #define __AROS_LCAQUAD(type,name,reg1,reg2) (name)
247 #define __AROS_LDAQUAD(type,name,reg1,reg2) type
249 /* Call a libary function which requires the libbase */
250 #include <aros/m68k/libcall.h>
252 #define AROS_LHQUAD1(t,n,a1,bt,bn,o,s) \
253 AROS_LH2(t,n, \
254 AROS_LHA(ULONG, __AROS_LTAQUAD1(a1), __AROS_LRAQUAD1(a1)), \
255 AROS_LHA(ULONG, __AROS_LTAQUAD2(a1), __AROS_LRAQUAD2(a1)), \
256 bt, bn, o, s) \
257 union { \
258 __AROS_LPAQUAD(a1) val; \
259 ULONG reg[2]; \
260 } __AROS_LTAQUAD(a1); \
261 __AROS_LTAQUAD(a1).reg[0] = __AROS_LTAQUAD1(a1); \
262 __AROS_LTAQUAD(a1).reg[1] = __AROS_LTAQUAD2(a1); \
263 __AROS_LPAQUAD(a1) __attribute__((unused)) __AROS_LCAQUAD(a1) = __AROS_LTAQUAD(a1).val;
265 #define AROS_LHQUAD2(t,n,a1,a2,bt,bn,o,s) \
266 AROS_LH4(t,n, \
267 AROS_LHA(ULONG, __AROS_LTAQUAD1(a1), __AROS_LRAQUAD1(a1)), \
268 AROS_LHA(ULONG, __AROS_LTAQUAD2(a1), __AROS_LRAQUAD2(a1)), \
269 AROS_LHA(ULONG, __AROS_LTAQUAD1(a2), __AROS_LRAQUAD1(a2)), \
270 AROS_LHA(ULONG, __AROS_LTAQUAD2(a2), __AROS_LRAQUAD2(a2)), \
271 bt, bn, o, s) \
272 union { \
273 __AROS_LPAQUAD(a1) val; \
274 ULONG reg[2]; \
275 } __AROS_LTAQUAD(a1); \
276 union { \
277 __AROS_LPAQUAD(a2) val; \
278 ULONG reg[2]; \
279 } __AROS_LTAQUAD(a2); \
280 __AROS_LTAQUAD(a1).reg[0] = __AROS_LTAQUAD1(a1); \
281 __AROS_LTAQUAD(a1).reg[1] = __AROS_LTAQUAD2(a1); \
282 __AROS_LPAQUAD(a1) __attribute__((unused)) __AROS_LCAQUAD(a1) = __AROS_LTAQUAD(a1).val; \
283 __AROS_LTAQUAD(a2).reg[0] = __AROS_LTAQUAD1(a2); \
284 __AROS_LTAQUAD(a2).reg[1] = __AROS_LTAQUAD2(a2); \
285 __AROS_LPAQUAD(a2) __attribute__((unused)) __AROS_LCAQUAD(a2) = __AROS_LTAQUAD(a2).val;
288 #define AROS_LCQUAD1(t,n,a1,bt,bn,o,s) \
289 ({ \
290 union { \
291 __AROS_LPAQUAD(a1) val; \
292 ULONG reg[2]; \
293 } _q1 = { .val = __AROS_LCAQUAD(a1) }; \
294 AROS_LC2D(t, n, \
295 AROS_LCA(ULONG, _q1.reg[0], __AROS_LRAQUAD1(a1)), \
296 AROS_LCA(ULONG, _q1.reg[1], __AROS_LRAQUAD2(a1)), \
297 bt, bn, o, s); \
300 #define AROS_LCQUAD2(t,n,a1,a2,bt,bn,o,s) \
301 ({ \
302 union { \
303 __AROS_LPAQUAD(a1) val; \
304 ULONG reg[2]; \
305 } _q1 = { .val = __AROS_LCAQUAD(a1) }; \
306 union { \
307 __AROS_LPAQUAD(a2) val; \
308 ULONG reg[2]; \
309 } _q2 = { .val = __AROS_LCAQUAD(a2) }; \
310 AROS_LC4D(t, n, \
311 AROS_LCA(ULONG, _q1.reg[0], __AROS_LRAQUAD1(a1)), \
312 AROS_LCA(ULONG, _q1.reg[1], __AROS_LRAQUAD2(a1)), \
313 AROS_LCA(ULONG, _q2.reg[0], __AROS_LRAQUAD1(a2)), \
314 AROS_LCA(ULONG, _q2.reg[1], __AROS_LRAQUAD2(a2)), \
315 bt, bn, o, s); \
319 # define AROS_LDQUAD1(t,n,a1,bt,bn,o,s) \
320 __AROS_LD_PREFIX t AROS_SLIB_ENTRY(n,s) ( \
321 __AROS_LDAQUAD(a1), __AROS_LD_BASE(bt,bn))
322 # define AROS_LDQUAD2(t,n,a1,a2,bt,bn,o,s) \
323 __AROS_LD_PREFIX t AROS_SLIB_ENTRY(n,s) ( \
324 __AROS_LDAQUAD(a1), \
325 __AROS_LDAQUAD(a2),__AROS_LD_BASE(bt,bn))
327 #define AROS_LPQUAD1(t,n,a1,bt,bn,o,s) \
328 t n (__AROS_LPAQUAD(a1))
329 #define AROS_LPQUAD2(t,n,a1,a2,bt,bn,o,s) \
330 t n (__AROS_LPAQUAD(a1), __AROS_LPAQUAD(a2))
332 /* Function declaration for program startup style code
334 #define AROS_ENTRY(t, n, a1, a2, bt, bn) \
335 AROS_UFH2(t, n, AROS_UFHA(a1), AROS_UFHA(a2)) \
336 bt bn = *((bt *)4);
338 #endif /* AROS_M68K_CPU_H */