1/*	Id: macdefs.h,v 1.93 2015/11/24 17:35:11 ragge Exp 	*/
2/*	$NetBSD: macdefs.h,v 1.1.1.6 2016/02/09 20:28:16 plunky Exp $	*/
3/*
4 * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 *    derived from this software without specific prior written permission
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/*
31 * Machine-dependent defines for both passes.
32 */
33
34/*
35 * Convert (multi-)character constant to integer.
36 */
37#define makecc(val,i)	lastcon = (lastcon<<8)|((val<<24)>>24);
38
39#define ARGINIT		64	/* # bits above fp where arguments start */
40#define AUTOINIT	0	/* # bits below fp where automatics start */
41
42/*
43 * Storage space requirements
44 */
45#define SZCHAR		8
46#define SZBOOL		8
47#define SZINT		32
48#define SZFLOAT		32
49#define SZDOUBLE	64
50#ifdef MACHOABI
51#define SZLDOUBLE	128
52#else
53#define SZLDOUBLE	96
54#endif
55#define SZLONG		32
56#define SZSHORT		16
57#define SZLONGLONG	64
58#define SZPOINT(t)	32
59
60/*
61 * Alignment constraints
62 */
63#define ALCHAR		8
64#define ALBOOL		8
65#define ALINT		32
66#define ALFLOAT		32
67#define ALDOUBLE	32
68#ifdef MACHOABI
69#define ALLDOUBLE	128
70#else
71#define ALLDOUBLE	32
72#endif
73#define ALLONG		32
74#define ALLONGLONG	32
75#define ALSHORT		16
76#define ALPOINT		32
77#undef ALSTRUCT		/* Not defined if ELF ABI */
78#define ALSTACK		32
79#define	ALMAX		128	/* not yet supported type */
80
81/*
82 * Min/max values.
83 */
84#define	MIN_CHAR	-128
85#define	MAX_CHAR	127
86#define	MAX_UCHAR	255
87#define	MIN_SHORT	-32768
88#define	MAX_SHORT	32767
89#define	MAX_USHORT	65535
90#define	MIN_INT		(-0x7fffffff-1)
91#define	MAX_INT		0x7fffffff
92#define	MAX_UNSIGNED	0xffffffff
93#define	MIN_LONG	MIN_INT
94#define	MAX_LONG	MAX_INT
95#define	MAX_ULONG	MAX_UNSIGNED
96#define	MIN_LONGLONG	0x8000000000000000LL
97#define	MAX_LONGLONG	0x7fffffffffffffffLL
98#define	MAX_ULONGLONG	0xffffffffffffffffULL
99
100/* Default char is signed */
101#undef	CHAR_UNSIGNED
102#define	BOOL_TYPE	UCHAR	/* what used to store _Bool */
103#undef UNALIGNED_ACCESS
104/*
105 * Use large-enough types.
106 */
107typedef	long long CONSZ;
108typedef	unsigned long long U_CONSZ;
109typedef long long OFFSZ;
110
111#define CONFMT	"%lld"		/* format for printing constants */
112#if defined(ELFABI)
113#define LABFMT	".L%d"		/* format for printing labels */
114#define	STABLBL	".LL%d"		/* format for stab (debugging) labels */
115#else
116#define LABFMT	"L%d"		/* format for printing labels */
117#define	STABLBL	"LL%d"		/* format for stab (debugging) labels */
118#endif
119#ifdef LANG_F77
120#define BLANKCOMMON "_BLNK_"
121#define MSKIREG  (M(TYSHORT)|M(TYLONG))
122#define TYIREG TYLONG
123#define FSZLENG  FSZLONG
124#define	AUTOREG	EBP
125#define	ARGREG	EBP
126#define ARGOFFSET 8
127#endif
128
129#ifdef MACHOABI
130#define STAB_LINE_ABSOLUTE	/* S_LINE fields use absolute addresses */
131#define	MYALIGN			/* user power-of-2 alignment */
132#endif
133
134#define BACKAUTO 		/* stack grows negatively for automatics */
135#define BACKTEMP 		/* stack grows negatively for temporaries */
136
137#undef	FIELDOPS		/* no bit-field instructions */
138#define TARGET_ENDIAN TARGET_LE
139
140#define FINDMOPS	/* i386 has instructions that modifies memory */
141#define	CC_DIV_0	/* division by zero is safe in the compiler */
142
143/* Definitions mostly used in pass2 */
144
145#define BYTEOFF(x)	((x)&03)
146#define wdal(k)		(BYTEOFF(k)==0)
147
148#define STOARG(p)
149#define STOFARG(p)
150#define STOSTARG(p)
151#define genfcall(a,b)	gencall(a,b)
152
153#define	szty(t)	(((t) == DOUBLE || (t) == FLOAT || \
154	(t) == LONGLONG || (t) == ULONGLONG) ? 2 : (t) == LDOUBLE ? 3 : 1)
155
156/*
157 * The x86 has a bunch of register classes, most of them interfering
158 * with each other.  All registers are given a sequential number to
159 * identify it which must match rnames[] in local2.c.
160 * Class membership and overlaps are defined in the macros RSTATUS
161 * and ROVERLAP below.
162 *
163 * The classes used on x86 are:
164 *	A - short and int regs
165 *	B - char regs
166 *	C - long long regs
167 *	D - floating point
168 */
169#define	EAX	000	/* Scratch and return register */
170#define	EDX	001	/* Scratch and secondary return register */
171#define	ECX	002	/* Scratch (and shift count) register */
172#define	EBX	003	/* GDT pointer or callee-saved temporary register */
173#define	ESI	004	/* Callee-saved temporary register */
174#define	EDI	005	/* Callee-saved temporary register */
175#define	EBP	006	/* Frame pointer */
176#define	ESP	007	/* Stack pointer */
177
178#define	AL	010
179#define	AH	011
180#define	DL	012
181#define	DH	013
182#define	CL	014
183#define	CH	015
184#define	BL	016
185#define	BH	017
186
187#define	EAXEDX	020
188#define	EAXECX	021
189#define	EAXEBX	022
190#define	EAXESI	023
191#define	EAXEDI	024
192#define	EDXECX	025
193#define	EDXEBX	026
194#define	EDXESI	027
195#define	EDXEDI	030
196#define	ECXEBX	031
197#define	ECXESI	032
198#define	ECXEDI	033
199#define	EBXESI	034
200#define	EBXEDI	035
201#define	ESIEDI	036
202
203/* The 8 math registers in class D lacks names */
204
205#define	MAXREGS	047	/* 39 registers */
206
207#define	RSTATUS	\
208	SAREG|TEMPREG, SAREG|TEMPREG, SAREG|TEMPREG, SAREG|PERMREG,	\
209	SAREG|PERMREG, SAREG|PERMREG, 0, 0,	 			\
210	SBREG, SBREG, SBREG, SBREG, SBREG, SBREG, SBREG, SBREG,		\
211	SCREG, SCREG, SCREG, SCREG, SCREG, SCREG, SCREG, SCREG, 	\
212	SCREG, SCREG, SCREG, SCREG, SCREG, SCREG, SCREG,		\
213	SDREG, SDREG, SDREG, SDREG,  SDREG, SDREG, SDREG, SDREG,
214
215#define	ROVERLAP \
216	/* 8 basic registers */\
217	{ AL, AH, EAXEDX, EAXECX, EAXEBX, EAXESI, EAXEDI, -1 },\
218	{ DL, DH, EAXEDX, EDXECX, EDXEBX, EDXESI, EDXEDI, -1 },\
219	{ CL, CH, EAXECX, EDXECX, ECXEBX, ECXESI, ECXEDI, -1 },\
220	{ BL, BH, EAXEBX, EDXEBX, ECXEBX, EBXESI, EBXEDI, -1 },\
221	{ EAXESI, EDXESI, ECXESI, EBXESI, ESIEDI, -1 },\
222	{ EAXEDI, EDXEDI, ECXEDI, EBXEDI, ESIEDI, -1 },\
223	{ -1 },\
224	{ -1 },\
225\
226	/* 8 char registers */\
227	{ EAX, EAXEDX, EAXECX, EAXEBX, EAXESI, EAXEDI, -1 },\
228	{ EAX, EAXEDX, EAXECX, EAXEBX, EAXESI, EAXEDI, -1 },\
229	{ EDX, EAXEDX, EDXECX, EDXEBX, EDXESI, EDXEDI, -1 },\
230	{ EDX, EAXEDX, EDXECX, EDXEBX, EDXESI, EDXEDI, -1 },\
231	{ ECX, EAXECX, EDXECX, ECXEBX, ECXESI, ECXEDI, -1 },\
232	{ ECX, EAXECX, EDXECX, ECXEBX, ECXESI, ECXEDI, -1 },\
233	{ EBX, EAXEBX, EDXEBX, ECXEBX, EBXESI, EBXEDI, -1 },\
234	{ EBX, EAXEBX, EDXEBX, ECXEBX, EBXESI, EBXEDI, -1 },\
235\
236	/* 15 long-long-emulating registers */\
237	{ EAX, AL, AH, EDX, DL, DH, EAXECX, EAXEBX, EAXESI,	/* eaxedx */\
238	  EAXEDI, EDXECX, EDXEBX, EDXESI, EDXEDI, -1, },\
239	{ EAX, AL, AH, ECX, CL, CH, EAXEDX, EAXEBX, EAXESI,	/* eaxecx */\
240	  EAXEDI, EDXECX, ECXEBX, ECXESI, ECXEDI, -1 },\
241	{ EAX, AL, AH, EBX, BL, BH, EAXEDX, EAXECX, EAXESI,	/* eaxebx */\
242	  EAXEDI, EDXEBX, ECXEBX, EBXESI, EBXEDI, -1 },\
243	{ EAX, AL, AH, ESI, EAXEDX, EAXECX, EAXEBX, EAXEDI,	/* eaxesi */\
244	  EDXESI, ECXESI, EBXESI, ESIEDI, -1 },\
245	{ EAX, AL, AH, EDI, EAXEDX, EAXECX, EAXEBX, EAXESI,	/* eaxedi */\
246	  EDXEDI, ECXEDI, EBXEDI, ESIEDI, -1 },\
247	{ EDX, DL, DH, ECX, CL, CH, EAXEDX, EAXECX, EDXEBX,	/* edxecx */\
248	  EDXESI, EDXEDI, ECXEBX, ECXESI, ECXEDI, -1 },\
249	{ EDX, DL, DH, EBX, BL, BH, EAXEDX, EDXECX, EDXESI,	/* edxebx */\
250	  EDXEDI, EAXEBX, ECXEBX, EBXESI, EBXEDI, -1 },\
251	{ EDX, DL, DH, ESI, EAXEDX, EDXECX, EDXEBX, EDXEDI,	/* edxesi */\
252	  EAXESI, ECXESI, EBXESI, ESIEDI, -1 },\
253	{ EDX, DL, DH, EDI, EAXEDX, EDXECX, EDXEBX, EDXESI,	/* edxedi */\
254	  EAXEDI, ECXEDI, EBXEDI, ESIEDI, -1 },\
255	{ ECX, CL, CH, EBX, BL, BH, EAXECX, EDXECX, ECXESI,	/* ecxebx */\
256	  ECXEDI, EAXEBX, EDXEBX, EBXESI, EBXEDI, -1 },\
257	{ ECX, CL, CH, ESI, EAXECX, EDXECX, ECXEBX, ECXEDI,	/* ecxesi */\
258	  EAXESI, EDXESI, EBXESI, ESIEDI, -1 },\
259	{ ECX, CL, CH, EDI, EAXECX, EDXECX, ECXEBX, ECXESI,	/* ecxedi */\
260	  EAXEDI, EDXEDI, EBXEDI, ESIEDI, -1 },\
261	{ EBX, BL, BH, ESI, EAXEBX, EDXEBX, ECXEBX, EBXEDI,	/* ebxesi */\
262	  EAXESI, EDXESI, ECXESI, ESIEDI, -1 },\
263	{ EBX, BL, BH, EDI, EAXEBX, EDXEBX, ECXEBX, EBXESI,	/* ebxedi */\
264	  EAXEDI, EDXEDI, ECXEDI, ESIEDI, -1 },\
265	{ ESI, EDI, EAXESI, EDXESI, ECXESI, EBXESI,		/* esiedi */\
266	  EAXEDI, EDXEDI, ECXEDI, EBXEDI, -1 },\
267\
268	/* The fp registers do not overlap with anything */\
269	{ -1 },\
270	{ -1 },\
271	{ -1 },\
272	{ -1 },\
273	{ -1 },\
274	{ -1 },\
275	{ -1 },\
276	{ -1 },
277
278
279/* Return a register class based on the type of the node */
280#define PCLASS(p) (p->n_type <= UCHAR ? SBREG : \
281		  (p->n_type == LONGLONG || p->n_type == ULONGLONG ? SCREG : \
282		  (p->n_type >= FLOAT && p->n_type <= LDOUBLE ? SDREG : SAREG)))
283
284#define	NUMCLASS 	4	/* highest number of reg classes used */
285
286int COLORMAP(int c, int *r);
287#define	GCLASS(x) (x < 8 ? CLASSA : x < 16 ? CLASSB : x < 31 ? CLASSC : CLASSD)
288#define DECRA(x,y)	(((x) >> (y*6)) & 63)	/* decode encoded regs */
289#define	ENCRD(x)	(x)		/* Encode dest reg in n_reg */
290#define ENCRA1(x)	((x) << 6)	/* A1 */
291#define ENCRA2(x)	((x) << 12)	/* A2 */
292#define ENCRA(x,y)	((x) << (6+y*6))	/* encode regs in int */
293/* XXX - return char in al? */
294#define	RETREG(x)	(x == CHAR || x == UCHAR ? AL : \
295			 x == LONGLONG || x == ULONGLONG ? EAXEDX : \
296			 x == FLOAT || x == DOUBLE || x == LDOUBLE ? 31 : EAX)
297
298#if 0
299#define R2REGS	1	/* permit double indexing */
300#endif
301
302/* XXX - to die */
303#define FPREG	EBP	/* frame pointer */
304#define STKREG	ESP	/* stack pointer */
305
306#define	SHSTR		(MAXSPECIAL+1)	/* short struct */
307#define	SFUNCALL	(MAXSPECIAL+2)	/* struct assign after function call */
308#define	SPCON		(MAXSPECIAL+3)	/* positive nonnamed constant */
309
310/*
311 * Specials that indicate the applicability of machine idioms.
312 */
313#define SMIXOR		(MAXSPECIAL+4)
314#define SMILWXOR	(MAXSPECIAL+5)
315#define SMIHWXOR	(MAXSPECIAL+6)
316
317/*
318 * i386-specific symbol table flags.
319 */
320#define	SSECTION	SLOCAL1
321#define SSTDCALL	SLOCAL2
322#define SDLLINDIRECT	SLOCAL3
323
324/*
325 * i386-specific interpass stuff.
326 */
327
328#define TARGET_IPP_MEMBERS			\
329	int ipp_argstacksize;
330
331#define	target_members_print_prolog(ipp) printf("%d", ipp->ipp_argstacksize)
332#define	target_members_print_epilog(ipp) printf("%d", ipp->ipp_argstacksize)
333#define target_members_read_prolog(ipp) ipp->ipp_argstacksize = rdint(&p)
334#define target_members_read_epilog(ipp) ipp->ipp_argstacksize = rdint(&p)
335
336#define	HAVE_WEAKREF
337#define	TARGET_FLT_EVAL_METHOD	2	/* all as long double */
338
339/*
340 * Extended assembler macros.
341 */
342void targarg(char *w, void *arg);
343#define	XASM_TARGARG(w, ary)	\
344	(w[1] == 'b' || w[1] == 'h' || w[1] == 'w' || w[1] == 'k' ? \
345	w++, targarg(w, ary), 1 : 0)
346int numconv(void *ip, void *p, void *q);
347#define	XASM_NUMCONV(ip, p, q)	numconv(ip, p, q)
348int xasmconstregs(char *);
349#define	XASMCONSTREGS(x) xasmconstregs(x)
350#define	MYSETXARG if (XASMVAL(cw) == 'q') {	\
351	c = 'r'; addalledges(&ablock[ESI]); addalledges(&ablock[EDI]); }
352
353#if defined(MACHOABI)
354struct stub {
355	struct { struct stub *q_forw, *q_back; } link;
356	char *name;
357};
358extern struct stub stublist;
359extern struct stub nlplist;
360void addstub(struct stub *list, char *name);
361#endif
362
363/* -m flags */
364extern int msettings;
365#define	MI386	0x001
366#define	MI486	0x002
367#define	MI586	0x004
368#define	MI686	0x008
369#define	MCPUMSK	0x00f
370
371/* target specific attributes */
372#define	ATTR_MI_TARGET	ATTR_I386_FCMPLRET, ATTR_I386_FPPOP
373#define NATIVE_FLOATING_POINT
374