xref: /netbsd/external/bsd/pcc/dist/pcc/arch/amd64/macdefs.h (revision 6550d01e)
1 /*	Id: macdefs.h,v 1.10 2010/04/18 19:34:14 ragge Exp 	*/
2 /*	$NetBSD: macdefs.h,v 1.1.1.2 2010/06/03 18:57:08 plunky Exp $	*/
3 /*
4  * Copyright (c) 2008 Michael Shalayeff
5  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 /*
32  * Machine-dependent defines for both passes.
33  */
34 
35 /*
36  * Convert (multi-)character constant to integer.
37  */
38 #define makecc(val,i)	lastcon = (lastcon<<8)|((val<<24)>>24);
39 
40 #define ARGINIT		128	/* # bits above fp where arguments start */
41 #define AUTOINIT	0	/* # bits below fp where automatics start */
42 
43 /*
44  * Storage space requirements
45  */
46 #define SZCHAR		8
47 #define SZBOOL		8
48 #define SZSHORT		16
49 #define SZINT		32
50 #define SZLONG		64
51 #define SZPOINT(t)	64
52 #define SZLONGLONG	64
53 #define SZFLOAT		32
54 #define SZDOUBLE	64
55 #define SZLDOUBLE	128
56 
57 /*
58  * Alignment constraints
59  */
60 #define ALCHAR		8
61 #define ALBOOL		8
62 #define ALSHORT		16
63 #define ALINT		32
64 #define ALLONG		64
65 #define ALPOINT		64
66 #define ALLONGLONG	64
67 #define ALFLOAT		32
68 #define ALDOUBLE	64
69 #define ALLDOUBLE	128
70 /* #undef ALSTRUCT	amd64 struct alignment is member defined */
71 #define ALSTACK		64
72 #define ALMAX		128
73 
74 /*
75  * Min/max values.
76  */
77 #define	MIN_CHAR	-128
78 #define	MAX_CHAR	127
79 #define	MAX_UCHAR	255
80 #define	MIN_SHORT	-32768
81 #define	MAX_SHORT	32767
82 #define	MAX_USHORT	65535
83 #define	MIN_INT		(-0x7fffffff-1)
84 #define	MAX_INT		0x7fffffff
85 #define	MAX_UNSIGNED	0xffffffff
86 #define	MIN_LONG	MIN_LONGLONG
87 #define	MAX_LONG	MAX_LONGLONG
88 #define	MAX_ULONG	MAX_ULONGLONG
89 #define	MIN_LONGLONG	0x8000000000000000LL
90 #define	MAX_LONGLONG	0x7fffffffffffffffLL
91 #define	MAX_ULONGLONG	0xffffffffffffffffULL
92 
93 /* Default char is signed */
94 #undef	CHAR_UNSIGNED
95 #define	BOOL_TYPE	CHAR	/* what used to store _Bool */
96 
97 /*
98  * Use large-enough types.
99  */
100 typedef	long long CONSZ;
101 typedef	unsigned long long U_CONSZ;
102 typedef long long OFFSZ;
103 
104 #define CONFMT	"%lld"		/* format for printing constants */
105 #define LABFMT	".L%d"		/* format for printing labels */
106 #define	STABLBL	".LL%d"		/* format for stab (debugging) labels */
107 #ifdef LANG_F77
108 #define BLANKCOMMON "_BLNK_"
109 #define MSKIREG  (M(TYSHORT)|M(TYLONG))
110 #define TYIREG TYLONG
111 #define FSZLENG  FSZLONG
112 #define	AUTOREG	EBP
113 #define	ARGREG	EBP
114 #define ARGOFFSET 8
115 #endif
116 
117 #define BACKAUTO 		/* stack grows negatively for automatics */
118 #define BACKTEMP 		/* stack grows negatively for temporaries */
119 
120 #undef	FIELDOPS		/* no bit-field instructions */
121 #define	RTOLBYTES		/* bytes are numbered right to left */
122 
123 #define ENUMSIZE(high,low) INT	/* enums are always stored in full int */
124 
125 #define FINDMOPS	/* i386 has instructions that modifies memory */
126 
127 /* Definitions mostly used in pass2 */
128 
129 #define BYTEOFF(x)	((x)&07)
130 #define wdal(k)		(BYTEOFF(k)==0)
131 #define BITOOR(x)	(x)	/* bit offset to oreg offset XXX die! */
132 
133 #define STOARG(p)
134 #define STOFARG(p)
135 #define STOSTARG(p)
136 #define genfcall(a,b)	gencall(a,b)
137 
138 /* How many integer registers are needed? (used for stack allocation) */
139 #define	szty(t)	(t < LONG || t == FLOAT ? 1 : t == LDOUBLE ? 4 : 2)
140 
141 /*
142  * The amd64 architecture has a much cleaner interface to its registers
143  * than the x86, even though a part of the register block comes from
144  * the x86 architecture.  Therefore currently only two non-overlapping
145  * register classes are used; integer and xmm registers.
146  *
147  * All registers are given a sequential number to
148  * identify it which must match rnames[] in local2.c.
149  *
150  * The classes used on amd64 are:
151  *	A - integer registers
152  *	B - xmm registers
153  */
154 #define	RAX	000
155 #define	RDX	001
156 #define	RCX	002
157 #define	RBX	003
158 #define	RSI	004
159 #define	RDI	005
160 #define	RBP	006
161 #define	RSP	007
162 #define	R08	010
163 #define	R09	011
164 #define	R10	012
165 #define	R11	013
166 #define	R12	014
167 #define	R13	015
168 #define	R14	016
169 #define	R15	017
170 
171 #define	XMM0	020
172 #define	XMM1	021
173 #define	XMM2	022
174 #define	XMM3	023
175 #define	XMM4	024
176 #define	XMM5	025
177 #define	XMM6	026
178 #define	XMM7	027
179 #define	XMM8	030
180 #define	XMM9	031
181 #define	XMM10	032
182 #define	XMM11	033
183 #define	XMM12	034
184 #define	XMM13	035
185 #define	XMM14	036
186 #define	XMM15	037
187 
188 #define	MAXREGS	040	/* 32 registers */
189 
190 #define	RSTATUS	\
191 	SAREG|TEMPREG, SAREG|TEMPREG, SAREG|TEMPREG, SAREG|PERMREG,	\
192 	SAREG|TEMPREG, SAREG|TEMPREG, 0, 0,	 			\
193 	SAREG|TEMPREG, SAREG|TEMPREG, SAREG|TEMPREG, SAREG|TEMPREG,	\
194 	SAREG|PERMREG, SAREG|PERMREG, SAREG|PERMREG, SAREG|PERMREG, 	\
195 	SBREG|TEMPREG, SBREG|TEMPREG, SBREG|TEMPREG, SBREG|TEMPREG,	\
196 	SBREG|TEMPREG, SBREG|TEMPREG, SBREG|TEMPREG, SBREG|TEMPREG,	\
197 	SBREG|TEMPREG, SBREG|TEMPREG, SBREG|TEMPREG, SBREG|TEMPREG,	\
198 	SBREG|TEMPREG, SBREG|TEMPREG, SBREG|TEMPREG, SBREG|TEMPREG,
199 
200 /* no overlapping registers at all */
201 #define	ROVERLAP \
202 	{ -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, \
203 	{ -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, \
204 	{ -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, \
205 	{ -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 },
206 
207 
208 /* Return a register class based on the type of the node */
209 #define PCLASS(p) (p->n_type >= FLOAT && p->n_type <= LDOUBLE ? SBREG : SAREG)
210 
211 #define	NUMCLASS 	2	/* highest number of reg classes used */
212 
213 int COLORMAP(int c, int *r);
214 #define	GCLASS(x) (x < 16 ? CLASSA : CLASSB)
215 #define DECRA(x,y)	(((x) >> (y*8)) & 255)	/* decode encoded regs */
216 #define	ENCRD(x)	(x)		/* Encode dest reg in n_reg */
217 #define ENCRA1(x)	((x) << 8)	/* A1 */
218 #define ENCRA2(x)	((x) << 16)	/* A2 */
219 #define ENCRA(x,y)	((x) << (8+y*8))	/* encode regs in int */
220 
221 #define	RETREG(x)	(x == FLOAT || x == DOUBLE || x == LDOUBLE ? XMM0 : RAX)
222 
223 /* XXX - to die */
224 #define FPREG	RBP	/* frame pointer */
225 #define STKREG	RSP	/* stack pointer */
226 
227 #define	SHSTR		(MAXSPECIAL+1)	/* short struct */
228 #define	SFUNCALL	(MAXSPECIAL+2)	/* struct assign after function call */
229 #define	SPCON		(MAXSPECIAL+3)	/* positive nonnamed constant */
230 
231 /*
232  * Specials that indicate the applicability of machine idioms.
233  */
234 #define SMIXOR		(MAXSPECIAL+4)
235 #define SMILWXOR	(MAXSPECIAL+5)
236 #define SMIHWXOR	(MAXSPECIAL+6)
237 #define SCON32		(MAXSPECIAL+7)	/* 32-bit constant */
238 
239 /*
240  * i386-specific symbol table flags.
241  */
242 #define	SSECTION	SLOCAL1
243 #define	STLS		SLOCAL2
244 #define	SNOUNDERSCORE	SLOCAL3
245 #define SSTDCALL	SLOCAL2
246 #define SDLLINDIRECT	SLOCAL3
247 
248 /*
249  * i386-specific node flags.
250  */
251 #define FSTDCALL	0x01
252 
253 /*
254  * i386-specific interpass stuff.
255  */
256 
257 #define TARGET_IPP_MEMBERS			\
258 	int ipp_argstacksize;
259 
260 /*
261  * Extended assembler macros.
262  */
263 void targarg(char *w, void *arg);
264 #define	XASM_TARGARG(w, ary)	\
265 	(w[1] == 'b' || w[1] == 'h' || w[1] == 'w' || w[1] == 'k' ? \
266 	w++, targarg(w, ary), 1 : 0)
267 int numconv(void *ip, void *p, void *q);
268 #define	XASM_NUMCONV(ip, p, q)	numconv(ip, p, q)
269 
270 /*
271  * builtins.
272  */
273 #define TARGET_VALIST
274 #define TARGET_STDARGS
275 #define TARGET_BUILTINS							\
276 	{ "__builtin_stdarg_start", amd64_builtin_stdarg_start, 2 },	\
277 	{ "__builtin_va_start", amd64_builtin_stdarg_start, 2 },	\
278 	{ "__builtin_va_arg", amd64_builtin_va_arg, 2 },		\
279 	{ "__builtin_va_end", amd64_builtin_va_end, 1 },		\
280 	{ "__builtin_va_copy", amd64_builtin_va_copy, 2 },		\
281 	{ "__builtin_frame_address", i386_builtin_frame_address, -1 },	\
282 	{ "__builtin_return_address", i386_builtin_return_address, -1 },
283 
284 #define NODE struct node
285 struct node;
286 NODE *amd64_builtin_stdarg_start(NODE *f, NODE *a);
287 NODE *amd64_builtin_va_arg(NODE *f, NODE *a);
288 NODE *amd64_builtin_va_end(NODE *f, NODE *a);
289 NODE *amd64_builtin_va_copy(NODE *f, NODE *a);
290 NODE *i386_builtin_frame_address(NODE *f, NODE *a);
291 NODE *i386_builtin_return_address(NODE *f, NODE *a);
292 #undef NODE
293