138451Smsmith/*	Id: macdefs.h,v 1.21 2011/06/23 13:41:25 ragge Exp 	*/
238451Smsmith/*	$NetBSD$	*/
338451Smsmith/*
438451Smsmith * Copyright (c) 2008 Michael Shalayeff
538451Smsmith * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
638451Smsmith * All rights reserved.
738451Smsmith *
838451Smsmith * Redistribution and use in source and binary forms, with or without
938451Smsmith * modification, are permitted provided that the following conditions
1038451Smsmith * are met:
1138451Smsmith * 1. Redistributions of source code must retain the above copyright
1238451Smsmith *    notice, this list of conditions and the following disclaimer.
1338451Smsmith * 2. Redistributions in binary form must reproduce the above copyright
1438451Smsmith *    notice, this list of conditions and the following disclaimer in the
1538451Smsmith *    documentation and/or other materials provided with the distribution.
1638451Smsmith * 3. The name of the author may not be used to endorse or promote products
1738451Smsmith *    derived from this software without specific prior written permission
1838451Smsmith *
1938451Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2038451Smsmith * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2138451Smsmith * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2238451Smsmith * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2338451Smsmith * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2438451Smsmith * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2538451Smsmith * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2638451Smsmith * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2784221Sdillon * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2884221Sdillon * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2984221Sdillon */
3038451Smsmith
3138451Smsmith/*
3238451Smsmith * Machine-dependent defines for both passes.
3338451Smsmith */
3438451Smsmith
3538451Smsmith/*
3638451Smsmith * Convert (multi-)character constant to integer.
3738451Smsmith */
3838451Smsmith#define makecc(val,i)	lastcon = (lastcon<<8)|((val<<24)>>24);
3938451Smsmith
4038451Smsmith#define ARGINIT		128	/* # bits above fp where arguments start */
4138451Smsmith#define AUTOINIT	0	/* # bits below fp where automatics start */
4238451Smsmith
4338451Smsmith/*
4438451Smsmith * Storage space requirements
4538451Smsmith */
4638451Smsmith#define SZCHAR		8
4738451Smsmith#define SZBOOL		8
4838451Smsmith#define SZSHORT		16
4938451Smsmith#define SZINT		32
5038451Smsmith#define SZLONG		64
5138451Smsmith#define SZPOINT(t)	64
5238451Smsmith#define SZLONGLONG	64
5338451Smsmith#define SZFLOAT		32
5438451Smsmith#define SZDOUBLE	64
5538451Smsmith#define SZLDOUBLE	128
5638451Smsmith
5738451Smsmith/*
5838451Smsmith * Alignment constraints
5938451Smsmith */
6038451Smsmith#define ALCHAR		8
6138451Smsmith#define ALBOOL		8
62218909Sbrucec#define ALSHORT		16
6338451Smsmith#define ALINT		32
6438451Smsmith#define ALLONG		64
6538451Smsmith#define ALPOINT		64
6638451Smsmith#define ALLONGLONG	64
6764185Sjhb#define ALFLOAT		32
6864185Sjhb#define ALDOUBLE	64
6938451Smsmith#define ALLDOUBLE	128
7038451Smsmith/* #undef ALSTRUCT	amd64 struct alignment is member defined */
7138451Smsmith#define ALSTACK		64
7238451Smsmith#define ALMAX		128
7338451Smsmith
7438451Smsmith/*
7538451Smsmith * Min/max values.
7638451Smsmith */
7738451Smsmith#define	MIN_CHAR	-128
78259561Smarcel#define	MAX_CHAR	127
79259561Smarcel#define	MAX_UCHAR	255
80259561Smarcel#define	MIN_SHORT	-32768
81259561Smarcel#define	MAX_SHORT	32767
82259561Smarcel#define	MAX_USHORT	65535
83259561Smarcel#define	MIN_INT		(-0x7fffffff-1)
84259561Smarcel#define	MAX_INT		0x7fffffff
85259561Smarcel#define	MAX_UNSIGNED	0xffffffffU
8638451Smsmith#define	MIN_LONG	0x8000000000000000L
8739665Smsmith#define	MAX_LONG	0x7fffffffffffffffL
8839665Smsmith#define	MAX_ULONG	0xffffffffffffffffUL
8939665Smsmith#define	MIN_LONGLONG	0x8000000000000000LL
9039665Smsmith#define	MAX_LONGLONG	0x7fffffffffffffffLL
9138451Smsmith#define	MAX_ULONGLONG	0xffffffffffffffffULL
9238451Smsmith
9338451Smsmith/* Default char is signed */
94259561Smarcel#undef	CHAR_UNSIGNED
9538451Smsmith#define	BOOL_TYPE	UCHAR	/* what used to store _Bool */
9638451Smsmith
9738451Smsmith/*
9839665Smsmith * Use large-enough types.
9939665Smsmith */
10039665Smsmithtypedef	long long CONSZ;
10139665Smsmithtypedef	unsigned long long U_CONSZ;
10239665Smsmithtypedef long long OFFSZ;
10339665Smsmith
10439665Smsmith#define CONFMT	"%lld"		/* format for printing constants */
10539665Smsmith#define LABFMT	".L%d"		/* format for printing labels */
10639665Smsmith#define	STABLBL	".LL%d"		/* format for stab (debugging) labels */
10739665Smsmith#ifdef LANG_F77
10839665Smsmith#define BLANKCOMMON "_BLNK_"
10939665Smsmith#define MSKIREG  (M(TYSHORT)|M(TYLONG))
11039665Smsmith#define TYIREG TYLONG
11139665Smsmith#define FSZLENG  FSZLONG
11239665Smsmith#define	AUTOREG	EBP
11339665Smsmith#define	ARGREG	EBP
11439665Smsmith#define ARGOFFSET 8
11539665Smsmith#endif
11639665Smsmith
11739665Smsmith#define BACKAUTO 		/* stack grows negatively for automatics */
11839665Smsmith#define BACKTEMP 		/* stack grows negatively for temporaries */
11939665Smsmith
12039665Smsmith#undef	FIELDOPS		/* no bit-field instructions */
12139665Smsmith#define	TARGET_ENDIAN TARGET_LE	/* little-endian only */
12239665Smsmith
12339665Smsmith#define FINDMOPS	/* i386 has instructions that modifies memory */
12439665Smsmith
12539665Smsmith#define	CC_DIV_0	/* division by zero is safe in the compiler */
12639665Smsmith
12738451Smsmith/* Definitions mostly used in pass2 */
12838451Smsmith
12938451Smsmith#define BYTEOFF(x)	((x)&07)
13038451Smsmith#define wdal(k)		(BYTEOFF(k)==0)
13138451Smsmith#define BITOOR(x)	(x)	/* bit offset to oreg offset XXX die! */
132259561Smarcel
13338451Smsmith#define STOARG(p)
134168348Skan#define STOFARG(p)
135259561Smarcel#define STOSTARG(p)
13638451Smsmith#define genfcall(a,b)	gencall(a,b)
13738451Smsmith
13838451Smsmith/* How many integer registers are needed? (used for stack allocation) */
13938451Smsmith#define	szty(t)	(t < LONG || t == FLOAT ? 1 : t == LDOUBLE ? 4 : 2)
14038451Smsmith
141329183Skevans/*
14238451Smsmith * The amd64 architecture has a much cleaner interface to its registers
14338451Smsmith * than the x86, even though a part of the register block comes from
14438451Smsmith * the x86 architecture.  Therefore currently only two non-overlapping
14538451Smsmith * register classes are used; integer and xmm registers.
14638451Smsmith *
14738451Smsmith * All registers are given a sequential number to
14838451Smsmith * identify it which must match rnames[] in local2.c.
14938451Smsmith *
15038451Smsmith * The classes used on amd64 are:
15138451Smsmith *	A - integer registers
15238451Smsmith *	B - xmm registers
15338451Smsmith *	C - x87 registers
15438451Smsmith */
15538451Smsmith#define	RAX	000
15638451Smsmith#define	RDX	001
15764185Sjhb#define	RCX	002
15838451Smsmith#define	RBX	003
15938451Smsmith#define	RSI	004
16038451Smsmith#define	RDI	005
16138451Smsmith#define	RBP	006
16238451Smsmith#define	RSP	007
16338451Smsmith#define	R08	010
16438451Smsmith#define	R09	011
16538451Smsmith#define	R10	012
166329114Skevans#define	R11	013
16738451Smsmith#define	R12	014
16839665Smsmith#define	R13	015
16939665Smsmith#define	R14	016
17038451Smsmith#define	R15	017
17139665Smsmith
17239665Smsmith#define	XMM0	020
17338451Smsmith#define	XMM1	021
17439665Smsmith#define	XMM2	022
17539665Smsmith#define	XMM3	023
17639665Smsmith#define	XMM4	024
17738451Smsmith#define	XMM5	025
17838451Smsmith#define	XMM6	026
17938451Smsmith#define	XMM7	027
18038451Smsmith#define	XMM8	030
18138451Smsmith#define	XMM9	031
18238451Smsmith#define	XMM10	032
18338451Smsmith#define	XMM11	033
18438451Smsmith#define	XMM12	034
18538451Smsmith#define	XMM13	035
18638451Smsmith#define	XMM14	036
18738451Smsmith#define	XMM15	037
18838451Smsmith
18938451Smsmith#define	MAXREGS	050	/* 40 registers */
19038451Smsmith
19138451Smsmith#define	RSTATUS	\
19238451Smsmith	SAREG|TEMPREG, SAREG|TEMPREG, SAREG|TEMPREG, SAREG|PERMREG,	\
19338451Smsmith	SAREG|TEMPREG, SAREG|TEMPREG, 0, 0,	 			\
19438451Smsmith	SAREG|TEMPREG, SAREG|TEMPREG, SAREG|TEMPREG, SAREG|TEMPREG,	\
19538451Smsmith	SAREG|PERMREG, SAREG|PERMREG, SAREG|PERMREG, SAREG|PERMREG, 	\
19638451Smsmith	SBREG|TEMPREG, SBREG|TEMPREG, SBREG|TEMPREG, SBREG|TEMPREG,	\
19738451Smsmith	SBREG|TEMPREG, SBREG|TEMPREG, SBREG|TEMPREG, SBREG|TEMPREG,	\
19838451Smsmith	SBREG|TEMPREG, SBREG|TEMPREG, SBREG|TEMPREG, SBREG|TEMPREG,	\
19938451Smsmith	SBREG|TEMPREG, SBREG|TEMPREG, SBREG|TEMPREG, SBREG|TEMPREG,	\
20038451Smsmith	SCREG, SCREG, SCREG, SCREG,  SCREG, SCREG, SCREG, SCREG,
20138451Smsmith
20238451Smsmith
20338451Smsmith/* no overlapping registers at all */
20438451Smsmith#define	ROVERLAP \
20538451Smsmith	{ -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, \
20638451Smsmith	{ -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, \
20738451Smsmith	{ -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, \
208259561Smarcel	{ -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, \
20938451Smsmith	{ -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 },
21038451Smsmith
21138451Smsmith
21238451Smsmith/* Return a register class based on the type of the node */
21338451Smsmith#define PCLASS(p) (p->n_type == FLOAT || p->n_type == DOUBLE ? SBREG : \
214221358Srodrigc		   p->n_type == LDOUBLE ? SCREG : SAREG)
215221358Srodrigc
21638451Smsmith#define	NUMCLASS 	3	/* highest number of reg classes used */
21738451Smsmith
21838451Smsmithint COLORMAP(int c, int *r);
21938451Smsmith#define	GCLASS(x) (x < 16 ? CLASSA : x < 32 ? CLASSB : CLASSC)
22038451Smsmith#define DECRA(x,y)	(((x) >> (y*8)) & 255)	/* decode encoded regs */
221221358Srodrigc#define	ENCRD(x)	(x)		/* Encode dest reg in n_reg */
22238451Smsmith#define ENCRA1(x)	((x) << 8)	/* A1 */
22338451Smsmith#define ENCRA2(x)	((x) << 16)	/* A2 */
22438451Smsmith#define ENCRA(x,y)	((x) << (8+y*8))	/* encode regs in int */
225
226#define	RETREG(x)	(x == FLOAT || x == DOUBLE ? XMM0 : \
227			 x == LDOUBLE ? 32 : RAX)
228
229/* XXX - to die */
230#define FPREG	RBP	/* frame pointer */
231#define STKREG	RSP	/* stack pointer */
232
233#define	SHSTR		(MAXSPECIAL+1)	/* short struct */
234#define	SFUNCALL	(MAXSPECIAL+2)	/* struct assign after function call */
235#define	SPCON		(MAXSPECIAL+3)	/* positive nonnamed constant */
236
237/*
238 * Specials that indicate the applicability of machine idioms.
239 */
240#define SMIXOR		(MAXSPECIAL+4)
241#define SMILWXOR	(MAXSPECIAL+5)
242#define SMIHWXOR	(MAXSPECIAL+6)
243#define SCON32		(MAXSPECIAL+7)	/* 32-bit constant */
244
245/*
246 * i386-specific symbol table flags.
247 */
248#define SBEENHERE	SLOCAL1
249
250/*
251 * Extended assembler macros.
252 */
253int xasmconstregs(char *);
254void targarg(char *w, void *arg, int n);
255#define	XASM_TARGARG(w, ary)	\
256	(w[1] == 'b' || w[1] == 'h' || w[1] == 'w' || w[1] == 'k' ? \
257	w++, targarg(w, ary, n), 1 : 0)
258int numconv(void *ip, void *p, void *q);
259#define	XASM_NUMCONV(ip, p, q)	numconv(ip, p, q)
260#define	XASMCONSTREGS(x)	xasmconstregs(x)
261
262/*
263 * builtins.
264 */
265#define TARGET_VALIST
266#define TARGET_STDARGS
267#define TARGET_BUILTINS							\
268	{ "__builtin_stdarg_start", amd64_builtin_stdarg_start, 2 },	\
269	{ "__builtin_va_start", amd64_builtin_stdarg_start, 2 },	\
270	{ "__builtin_va_arg", amd64_builtin_va_arg, 2 },		\
271	{ "__builtin_va_end", amd64_builtin_va_end, 1 },		\
272	{ "__builtin_va_copy", amd64_builtin_va_copy, 2 },		\
273	{ "__builtin_frame_address", i386_builtin_frame_address, -1 },	\
274	{ "__builtin_return_address", i386_builtin_return_address, -1 },
275
276#define NODE struct node
277struct node;
278NODE *amd64_builtin_stdarg_start(NODE *f, NODE *a, unsigned int);
279NODE *amd64_builtin_va_arg(NODE *f, NODE *a, unsigned int);
280NODE *amd64_builtin_va_end(NODE *f, NODE *a, unsigned int);
281NODE *amd64_builtin_va_copy(NODE *f, NODE *a, unsigned int);
282NODE *i386_builtin_frame_address(NODE *f, NODE *a, unsigned int);
283NODE *i386_builtin_return_address(NODE *f, NODE *a, unsigned int);
284#undef NODE
285