1/*
2 * Copyright (c) 2011 Janne Johansson <jj@openbsd.org>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17/*
18 * Machine-dependent defines for both passes.
19 */
20
21/*
22 * Convert (multi-)character constant to integer.
23 */
24#define makecc(val,i)  lastcon = i ? (val<<8)|lastcon : val
25
26#define ARGINIT		64	/* # bits above fp where arguments start */
27#define AUTOINIT	0	/* # bits below fp where automatics start */
28
29/*
30 * Storage space requirements
31 */
32#define SZCHAR		8
33#define SZBOOL		8
34#define SZSHORT		16
35#define SZINT		32
36#define SZLONG		32
37#define SZPOINT(t)	32
38#define SZLONGLONG	64
39#define SZFLOAT		32
40#define SZDOUBLE	64
41#define SZLDOUBLE	128
42
43/*
44 * Alignment constraints
45 */
46#define ALCHAR		8
47#define ALBOOL		8
48#define ALSHORT		16
49#define ALINT		32
50#define ALLONG		32
51#define ALPOINT		32
52#define ALLONGLONG	64
53#define ALFLOAT		32
54#define ALDOUBLE	64
55#define ALLDOUBLE	32	/* ???? */
56/* #undef ALSTRUCT	m68k struct alignment is member defined */
57#define ALSTACK		32
58#define ALMAX		64
59
60/*
61 * Min/max values.
62 */
63#define MIN_CHAR	-128
64#define MAX_CHAR	127
65#define MAX_UCHAR	255
66#define MIN_SHORT	-32768
67#define MAX_SHORT	32767
68#define MAX_USHORT	65535
69#define MIN_INT		(-0x7fffffff-1)
70#define MAX_INT		0x7fffffff
71#define MAX_UNSIGNED	0xffffffffU
72#define MIN_LONG	MIN_INT
73#define MAX_LONG	MAX_INT
74#define MAX_ULONG	MAX_UNSIGNED
75#define MIN_LONGLONG	0x8000000000000000LL
76#define MAX_LONGLONG	0x7fffffffffffffffLL
77#define MAX_ULONGLONG	0xffffffffffffffffULL
78
79/* Default char is signed */
80#undef	CHAR_UNSIGNED
81#define BOOL_TYPE	UCHAR	/* what used to store _Bool */
82
83/*
84 * Use large-enough types.
85 */
86typedef long long CONSZ;
87typedef unsigned long long U_CONSZ;
88typedef long long OFFSZ;
89
90#define CONFMT	"%lld"		/* format for printing constants */
91#define LABFMT	".L%d"		/* format for printing labels */
92#define STABLBL ".LL%d"		/* format for stab (debugging) labels */
93#ifdef LANG_F77
94#define BLANKCOMMON "_BLNK_"
95#define MSKIREG	 (M(TYSHORT)|M(TYLONG))
96#define TYIREG TYLONG
97#define FSZLENG	 FSZLONG
98#define AUTOREG EBP
99#define ARGREG	EBP
100#define ARGOFFSET 8
101#endif
102
103#define BACKAUTO		/* stack grows negatively for automatics */
104#define BACKTEMP		/* stack grows negatively for temporaries */
105
106#undef	FIELDOPS		/* no bit-field instructions */
107#define TARGET_ENDIAN TARGET_BE /* big-endian */
108
109#undef FINDMOPS /* XXX FIXME */
110
111#define CC_DIV_0	/* division by zero is safe in the compiler */
112
113/* Definitions mostly used in pass2 */
114
115#define BYTEOFF(x)	((x)&03)
116#define wdal(k)		(BYTEOFF(k)==0)
117
118#define STOARG(p)
119#define STOFARG(p)
120#define STOSTARG(p)
121#define genfcall(a,b)	gencall(a,b)
122
123/* How many integer registers are needed? (used for stack allocation) */
124#define szty(t) ((t) == LDOUBLE ? 3 : \
125	(t) == DOUBLE || DEUNSIGN(t) == LONGLONG ? 2 : 1)
126
127/*
128 * All registers are given a sequential number to
129 * identify it which must match rnames[] in local2.c.
130 *
131 * The classes used on m68k are:
132 *	A - 32-bit data registers
133 *	B - 32-bit address registers
134 *	C - 64-bit combined registers
135 *	D - 80-bit floating point registers
136 */
137#define D0	0
138#define D1	1
139#define D2	2
140#define D3	3
141#define D4	4
142#define D5	5
143#define D6	6
144#define D7	7
145
146/* no support yet for using A registers for data calculations */
147#define A0	8
148#define A1	9
149#define A2	10
150#define A3	11
151#define A4	12
152#define A5	13
153#define A6	14 /* frame pointer?  Isnt it A4 on amigaos.. */
154#define A7	15  /* Stack pointer */
155
156#define D0D1	16
157#define D1D2	17
158#define D2D3	18
159#define D3D4	19
160#define D4D5	20
161#define D5D6	21
162#define D6D7	22
163
164#define	FP0	23
165#define	FP1	24
166#define	FP2	25
167#define	FP3	26
168#define	FP4	27
169#define	FP5	28
170#define	FP6	29
171#define	FP7	30
172
173#define MAXREGS 31	/* 31 registers */
174
175#define RSTATUS \
176	SAREG|TEMPREG, SAREG|TEMPREG, SAREG|PERMREG, SAREG|PERMREG, \
177	SAREG|PERMREG, SAREG|PERMREG, SAREG|PERMREG, SAREG|PERMREG, \
178	SBREG|TEMPREG, SBREG|TEMPREG, SBREG|PERMREG, SBREG|PERMREG, \
179	SBREG|PERMREG, SBREG|PERMREG, 0, 0, /* fp and sp are ignored here */ \
180	SCREG, SCREG, SCREG, SCREG, SCREG, SCREG, SCREG, \
181	SDREG|TEMPREG, SDREG|TEMPREG, SDREG|PERMREG, SDREG|PERMREG, \
182	SDREG|PERMREG, SDREG|PERMREG, SDREG|PERMREG, SDREG|PERMREG,
183
184
185/* no overlapping registers at all */
186#define ROVERLAP \
187	/* 8 data registers */	 \
188	{ D0D1, -1},\
189	{ D1D2, D0D1, -1},\
190	{ D2D3, D1D2,-1},\
191	{ D3D4, D2D3,-1},\
192	{ D4D5, D3D4,-1},\
193	{ D5D6, D4D5,-1},\
194	{ D6D7, D5D6,-1},\
195	{ D6D7, -1},\
196	/* 8 adress registers */  \
197	{ -1}, \
198	{ -1}, \
199	{ -1}, \
200	{ -1}, \
201	{ -1}, \
202	{ -1}, \
203	{ -1}, \
204	{ -1}, \
205	{ D0, D1, D1D2, -1},	\
206	{ D1, D2, D0D1, D2D3, -1},	\
207	{ D2, D3, D1D2, D3D4, -1},	\
208	{ D3, D4, D2D3, D4D5, -1},	\
209	{ D4, D5, D3D4, D5D6, -1},	\
210	{ D5, D6, D4D5, D6D7, -1},	\
211	{ D6, D7, D5D6, -1},  \
212	{ -1}, \
213	{ -1}, \
214	{ -1}, \
215	{ -1}, \
216	{ -1}, \
217	{ -1}, \
218	{ -1}, \
219	{ -1},
220
221
222/* Return a register class based on the type of the node */
223#define PCLASS(p) (p->n_type == FLOAT || p->n_type == DOUBLE || \
224	p->n_type == LDOUBLE ? SDREG : p->n_type == LONGLONG || \
225	p->n_type == ULONGLONG ? SCREG : p->n_type > BTMASK ? SBREG : SAREG)
226
227#define NUMCLASS	4	/* highest number of reg classes used */
228
229int COLORMAP(int c, int *r);
230#define GCLASS(x) (x < 8 ? CLASSA : x < 16 ? CLASSB : x < 23 ? CLASSC : CLASSD)
231#define DECRA(x,y)	(((x) >> (y*6)) & 63)	/* decode encoded regs */
232#define ENCRD(x)	(x)		/* Encode dest reg in n_reg */
233#define ENCRA1(x)	((x) << 12)	/* A1 */
234#define ENCRA2(x)	((x) << 18)	/* A2 */
235#define ENCRA(x,y)	((x) << (6+y*6))	/* encode regs in int */
236
237#define RETREG(x)	((x) == FLOAT || (x) == DOUBLE || (x) == LDOUBLE ? FP0 : \
238	(x) == LONGLONG || (x) == ULONGLONG ? D0D1 : (x) > BTMASK ? A0 : D0)
239
240#define FPREG	A6	/* frame pointer */
241#define STKREG	A7	/* stack pointer */
242
243#define HAVE_WEAKREF
244#define TARGET_FLT_EVAL_METHOD	2	/* all as long double */
245
246/*
247 * Extended assembler macros.
248 */
249int targarg(char *w, void *arg);
250#define XASM_TARGARG(w, ary) (w[1] == 'b' ? w++, 0 : targarg(w, ary))
251
252#define NATIVE_FLOATING_POINT
253