xref: /netbsd-src/external/bsd/pcc/dist/pcc/arch/i86/macdefs.h (revision 411dcbec990c8aa9c57d3bd2f4bcacadec0b1ab5)
1 /*	Id: macdefs.h,v 1.6 2015/11/24 17:35:11 ragge Exp 	*/
2 /*	$NetBSD: macdefs.h,v 1.1.1.1 2016/02/09 20:28:39 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		16
48 #define SZFLOAT		32
49 #define SZDOUBLE	64
50 #define SZLDOUBLE	96
51 #define SZLONG		32
52 #define SZSHORT		16
53 #define SZLONGLONG	64	/* Doesn't work usefully yet */
54 #define SZPOINT(t)	16	/* FIXME: 32 for large model work */
55 
56 /*
57  * Alignment constraints
58  */
59 #define ALCHAR		8
60 #define ALBOOL		8
61 #define ALINT		16
62 #define ALFLOAT		32
63 #define ALDOUBLE	32
64 #define ALLDOUBLE	32
65 #define ALLONG		16
66 #define ALLONGLONG	16
67 #define ALSHORT		16
68 #define ALPOINT		16
69 #undef ALSTRUCT		/* Not defined if ELF ABI */
70 #define ALSTACK		16
71 #define	ALMAX		128	/* not yet supported type */
72 
73 /*
74  * Min/max values.
75  */
76 #define	MIN_CHAR	-128
77 #define	MAX_CHAR	127
78 #define	MAX_UCHAR	255
79 #define	MIN_SHORT	-32768
80 #define	MAX_SHORT	32767
81 #define	MAX_USHORT	65535
82 #define	MIN_INT		MIN_SHORT
83 #define	MAX_INT		MAX_SHORT
84 #define	MAX_UNSIGNED	MAX_USHORT
85 #define	MIN_LONG	(-0x7fffffff-1)
86 #define	MAX_LONG	0x7fffffff
87 #define	MAX_ULONG	0xffffffff
88 #define	MIN_LONGLONG	MIN_LONG
89 #define	MAX_LONGLONG	MAX_LONG
90 #define	MAX_ULONGLONG	MAX_ULONG
91 
92 /* Default char is signed */
93 #undef	CHAR_UNSIGNED
94 #define	BOOL_TYPE	UCHAR	/* what used to store _Bool */
95 #undef UNALIGNED_ACCESS
96 /*
97  * Use large-enough types.
98  */
99 typedef	long long CONSZ;
100 typedef	unsigned long long U_CONSZ;
101 typedef long long OFFSZ;
102 
103 #define CONFMT	"%lld"		/* format for printing constants */
104 #define LABFMT	"L%d"		/* format for printing labels */
105 #define	STABLBL	"LL%d"		/* format for stab (debugging) labels */
106 #ifdef LANG_F77
107 #define BLANKCOMMON "_BLNK_"
108 #define MSKIREG  (M(TYSHORT)|M(TYLONG))
109 #define TYIREG TYLONG
110 #define FSZLENG  FSZLONG
111 #define	AUTOREG	BP
112 #define	ARGREG	BP
113 #define ARGOFFSET 4
114 #endif
115 
116 #define BACKAUTO 		/* stack grows negatively for automatics */
117 #define BACKTEMP 		/* stack grows negatively for temporaries */
118 
119 #undef	FIELDOPS		/* no bit-field instructions */
120 #define TARGET_ENDIAN TARGET_LE
121 
122 #define FINDMOPS	/* i86 has instructions that modifies memory */
123 #define	CC_DIV_0	/* division by zero is safe in the compiler */
124 
125 /* Definitions mostly used in pass2 */
126 
127 #define BYTEOFF(x)	((x)&03)
128 #define wdal(k)		(BYTEOFF(k)==0)
129 
130 #define STOARG(p)
131 #define STOFARG(p)
132 #define STOSTARG(p)
133 #define genfcall(a,b)	gencall(a,b)
134 
135 /* FIXME: float sizes wrong at this point ? */
136 #define	szty(t)	(((t) == DOUBLE || (t) == FLOAT || \
137 	(t) == LONG || t == ULONG || (t) == LONGLONG || (t) == ULONGLONG) ? 2 : (t) == LDOUBLE ? 3 : 1)
138 
139 /*
140  * The x86 has a bunch of register classes, most of them interfering
141  * with each other.  All registers are given a sequential number to
142  * identify it which must match rnames[] in local2.c.
143  * Class membership and overlaps are defined in the macros RSTATUS
144  * and ROVERLAP below.
145  *
146  * The classes used on x86 are:
147  *	A - short and int regs
148  *	B - char regs
149  *	C - long and longlong regs
150  *	D - floating point
151  */
152 #define	AX	000	/* Scratch and return register */
153 #define	DX	001	/* Scratch and secondary return register */
154 #define	CX	002	/* Scratch (and shift count) register */
155 #define	BX	003	/* GDT pointer or callee-saved temporary register */
156 #define	SI	004	/* Callee-saved temporary register */
157 #define	DI	005	/* Callee-saved temporary register */
158 #define	BP	006	/* Frame pointer */
159 #define	SP	007	/* Stack pointer */
160 
161 #define	AL	010
162 #define	AH	011
163 #define	DL	012
164 #define	DH	013
165 #define	CL	014
166 #define	CH	015
167 #define	BL	016
168 #define	BH	017
169 
170 #define	AXDX	020
171 #define	AXCX	021
172 #define	AXBX	022
173 #define	AXSI	023
174 #define	AXDI	024
175 #define	DXCX	025
176 #define	DXBX	026
177 #define	DXSI	027
178 #define	DXDI	030
179 #define	CXBX	031
180 #define	CXSI	032
181 #define	CXDI	033
182 #define	BXSI	034
183 #define	BXDI	035
184 #define	SIDI	036
185 
186 /* The 8 math registers in class D lacks names */
187 
188 #define	MAXREGS	047	/* 39 registers */
189 
190 #define	RSTATUS	\
191 	SAREG|TEMPREG, SAREG|TEMPREG, SAREG|TEMPREG, SAREG|PERMREG,	\
192 	SAREG|PERMREG, SAREG|PERMREG, 0, 0,	 			\
193 	SBREG, SBREG, SBREG, SBREG, SBREG, SBREG, SBREG, SBREG,		\
194 	SCREG, SCREG, SCREG, SCREG, SCREG, SCREG, SCREG, SCREG, 	\
195 	SCREG, SCREG, SCREG, SCREG, SCREG, SCREG, SCREG,		\
196 	SDREG, SDREG, SDREG, SDREG,  SDREG, SDREG, SDREG, SDREG,
197 
198 #define	ROVERLAP \
199 	/* 8 basic registers */\
200 	{ AL, AH, AXDX, AXCX, AXBX, AXSI, AXDI, -1 },\
201 	{ DL, DH, AXDX, DXCX, DXBX, DXSI, DXDI, -1 },\
202 	{ CL, CH, AXCX, DXCX, CXBX, CXSI, CXDI, -1 },\
203 	{ BL, BH, AXBX, DXBX, CXBX, BXSI, BXDI, -1 },\
204 	{ AXSI, DXSI, CXSI, BXSI, SIDI, -1 },\
205 	{ AXDI, DXDI, CXDI, BXDI, SIDI, -1 },\
206 	{ -1 },\
207 	{ -1 },\
208 \
209 	/* 8 char registers */\
210 	{ AX, AXDX, AXCX, AXBX, AXSI, AXDI, -1 },\
211 	{ AX, AXDX, AXCX, AXBX, AXSI, AXDI, -1 },\
212 	{ DX, AXDX, DXCX, DXBX, DXSI, DXDI, -1 },\
213 	{ DX, AXDX, DXCX, DXBX, DXSI, DXDI, -1 },\
214 	{ CX, AXCX, DXCX, CXBX, CXSI, CXDI, -1 },\
215 	{ CX, AXCX, DXCX, CXBX, CXSI, CXDI, -1 },\
216 	{ BX, AXBX, DXBX, CXBX, BXSI, BXDI, -1 },\
217 	{ BX, AXBX, DXBX, CXBX, BXSI, BXDI, -1 },\
218 \
219 	/* 15 long emulating registers */\
220 	{ AX, AL, AH, DX, DL, DH, AXCX, AXBX, AXSI,	/* axdx */\
221 	  AXDI, DXCX, DXBX, DXSI, DXDI, -1, },\
222 	{ AX, AL, AH, CX, CL, CH, AXDX, AXBX, AXSI,	/* axcx */\
223 	  AXDI, DXCX, CXBX, CXSI, CXDI, -1 },\
224 	{ AX, AL, AH, BX, BL, BH, AXDX, AXCX, AXSI,	/* axbx */\
225 	  AXDI, DXBX, CXBX, BXSI, BXDI, -1 },\
226 	{ AX, AL, AH, SI, AXDX, AXCX, AXBX, AXDI,	/* axsi */\
227 	  DXSI, CXSI, BXSI, SIDI, -1 },\
228 	{ AX, AL, AH, DI, AXDX, AXCX, AXBX, AXSI,	/* axdi */\
229 	  DXDI, CXDI, BXDI, SIDI, -1 },\
230 	{ DX, DL, DH, CX, CL, CH, AXDX, AXCX, DXBX,	/* dxcx */\
231 	  DXSI, DXDI, CXBX, CXSI, CXDI, -1 },\
232 	{ DX, DL, DH, BX, BL, BH, AXDX, DXCX, DXSI,	/* dxbx */\
233 	  DXDI, AXBX, CXBX, BXSI, BXDI, -1 },\
234 	{ DX, DL, DH, SI, AXDX, DXCX, DXBX, DXDI,	/* dxsi */\
235 	  AXSI, CXSI, BXSI, SIDI, -1 },\
236 	{ DX, DL, DH, DI, AXDX, DXCX, DXBX, DXSI,	/* dxdi */\
237 	  AXDI, CXDI, BXDI, SIDI, -1 },\
238 	{ CX, CL, CH, BX, BL, BH, AXCX, DXCX, CXSI,	/* cxbx */\
239 	  CXDI, AXBX, DXBX, BXSI, BXDI, -1 },\
240 	{ CX, CL, CH, SI, AXCX, DXCX, CXBX, CXDI,	/* cxsi */\
241 	  AXSI, DXSI, BXSI, SIDI, -1 },\
242 	{ CX, CL, CH, DI, AXCX, DXCX, CXBX, CXSI,	/* cxdi */\
243 	  AXDI, DXDI, BXDI, SIDI, -1 },\
244 	{ BX, BL, BH, SI, AXBX, DXBX, CXBX, BXDI,	/* bxsi */\
245 	  AXSI, DXSI, CXSI, SIDI, -1 },\
246 	{ BX, BL, BH, DI, AXBX, DXBX, CXBX, BXSI,	/* bxdi */\
247 	  AXDI, DXDI, CXDI, SIDI, -1 },\
248 	{ SI, DI, AXSI, DXSI, CXSI, BXSI,		/* sidi */\
249 	  AXDI, DXDI, CXDI, BXDI, -1 },\
250 \
251 	/* The fp registers do not overlap with anything */\
252 	{ -1 },\
253 	{ -1 },\
254 	{ -1 },\
255 	{ -1 },\
256 	{ -1 },\
257 	{ -1 },\
258 	{ -1 },\
259 	{ -1 },
260 
261 
262 /* Return a register class based on the type of the node */
263 /* FIXME: <= UCHAR includes long ?? check */
264 #define PCLASS(p) (p->n_type <= UCHAR ? SBREG : \
265 		  (p->n_type == LONG || p->n_type == ULONG || p->n_type == LONGLONG || p->n_type == ULONGLONG ? SCREG : \
266 		  (p->n_type >= FLOAT && p->n_type <= LDOUBLE ? SDREG : SAREG)))
267 
268 #define	NUMCLASS 	4	/* highest number of reg classes used */
269 
270 int COLORMAP(int c, int *r);
271 #define	GCLASS(x) (x < 8 ? CLASSA : x < 16 ? CLASSB : x < 31 ? CLASSC : CLASSD)
272 #define DECRA(x,y)	(((x) >> (y*6)) & 63)	/* decode encoded regs */
273 #define	ENCRD(x)	(x)		/* Encode dest reg in n_reg */
274 #define ENCRA1(x)	((x) << 6)	/* A1 */
275 #define ENCRA2(x)	((x) << 12)	/* A2 */
276 #define ENCRA(x,y)	((x) << (6+y*6))	/* encode regs in int */
277 /* XXX - return char in al? */
278 #define	RETREG(x)	(x == CHAR || x == UCHAR ? AL : \
279 			 x == LONG || x == ULONG || x == LONGLONG || x == ULONGLONG ? AXDX : \
280 			 x == FLOAT || x == DOUBLE || x == LDOUBLE ? 31 : AX)
281 
282 #if 0
283 #define R2REGS	1	/* permit double indexing */
284 #endif
285 
286 /* XXX - to die */
287 #define FPREG	BP	/* frame pointer */
288 #define STKREG	SP	/* stack pointer */
289 
290 #define	SHSTR		(MAXSPECIAL+1)	/* short struct */
291 #define	SFUNCALL	(MAXSPECIAL+2)	/* struct assign after function call */
292 #define	SPCON		(MAXSPECIAL+3)	/* positive nonnamed constant */
293 
294 /*
295  * Specials that indicate the applicability of machine idioms.
296  */
297 #define SMIXOR		(MAXSPECIAL+4)
298 #define SMILWXOR	(MAXSPECIAL+5)
299 #define SMIHWXOR	(MAXSPECIAL+6)
300 #define	STWO		(MAXSPECIAL+7)	/* exactly two */
301 #define	SMTWO		(MAXSPECIAL+8)	/* exactly minus two */
302 
303 /*
304  * i86-specific symbol table flags.
305  */
306 #define	SSECTION	SLOCAL1
307 #define SSTDCALL	SLOCAL2
308 #define SDLLINDIRECT	SLOCAL3
309 
310 /*
311  * i86-specific interpass stuff.
312  */
313 
314 #define TARGET_IPP_MEMBERS			\
315 	int ipp_argstacksize;
316 
317 #define	HAVE_WEAKREF
318 #define	TARGET_FLT_EVAL_METHOD	2	/* all as long double */
319 
320 /*
321  * Extended assembler macros.
322  */
323 void targarg(char *w, void *arg);
324 #define	XASM_TARGARG(w, ary)	\
325 	(w[1] == 'b' || w[1] == 'h' || w[1] == 'w' || w[1] == 'k' ? \
326 	w++, targarg(w, ary), 1 : 0)
327 int numconv(void *ip, void *p, void *q);
328 #define	XASM_NUMCONV(ip, p, q)	numconv(ip, p, q)
329 int xasmconstregs(char *);
330 #define	XASMCONSTREGS(x) xasmconstregs(x)
331 #define	MYSETXARG if (XASMVAL(cw) == 'q') {	\
332 	c = 'r'; addalledges(&ablock[SI]); addalledges(&ablock[DI]); }
333 
334 /* target specific attributes */
335 #define	ATTR_MI_TARGET	ATTR_I86_FPPOP
336 #define NATIVE_FLOATING_POINT
337