summaryrefslogtreecommitdiff
path: root/src/lj_target_x86.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_target_x86.h')
-rw-r--r--src/lj_target_x86.h257
1 files changed, 257 insertions, 0 deletions
diff --git a/src/lj_target_x86.h b/src/lj_target_x86.h
new file mode 100644
index 00000000..3ee4fa00
--- /dev/null
+++ b/src/lj_target_x86.h
@@ -0,0 +1,257 @@
1/*
2** Definitions for x86 and x64 CPUs.
3** Copyright (C) 2005-2009 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_TARGET_X86_H
7#define _LJ_TARGET_X86_H
8
9/* -- Registers IDs ------------------------------------------------------- */
10
11#if LJ_64
12#define GPRDEF(_) \
13 _(EAX) _(ECX) _(EDX) _(EBX) _(ESP) _(EBP) _(ESI) _(EDI) \
14 _(R8D) _(R9D) _(R10D) _(R11D) _(R12D) _(R13D) _(R14D) _(R15D)
15#define FPRDEF(_) \
16 _(XMM0) _(XMM1) _(XMM2) _(XMM3) _(XMM4) _(XMM5) _(XMM6) _(XMM7) \
17 _(XMM8) _(XMM9) _(XMM10) _(XMM11) _(XMM12) _(XMM13) _(XMM14) _(XMM15)
18#else
19#define GPRDEF(_) \
20 _(EAX) _(ECX) _(EDX) _(EBX) _(ESP) _(EBP) _(ESI) _(EDI)
21#define FPRDEF(_) \
22 _(XMM0) _(XMM1) _(XMM2) _(XMM3) _(XMM4) _(XMM5) _(XMM6) _(XMM7)
23#endif
24
25#define RIDENUM(name) RID_##name,
26
27enum {
28 GPRDEF(RIDENUM) /* General-purpose registers (GPRs). */
29 FPRDEF(RIDENUM) /* Floating-point registers (FPRs). */
30 RID_MAX,
31 RID_MRM = RID_MAX, /* Pseudo-id for ModRM operand. */
32
33 /* Calling conventions. */
34 RID_RET = RID_EAX,
35
36 /* These definitions must match with the *.dasc file(s): */
37 RID_BASE = RID_EDX, /* Interpreter BASE. */
38 RID_PC = RID_ESI, /* Interpreter PC. */
39 RID_DISPATCH = RID_EBX, /* Interpreter DISPATCH table. */
40
41 /* Register ranges [min, max) and number of registers. */
42 RID_MIN_GPR = RID_EAX,
43 RID_MIN_FPR = RID_XMM0,
44 RID_MAX_GPR = RID_MIN_FPR,
45 RID_MAX_FPR = RID_MAX,
46 RID_NUM_GPR = RID_MAX_GPR - RID_MIN_GPR,
47 RID_NUM_FPR = RID_MAX_FPR - RID_MIN_FPR,
48};
49
50/* -- Register sets ------------------------------------------------------- */
51
52/* Make use of all registers, except the stack pointer. */
53#define RSET_GPR (RSET_RANGE(RID_MIN_GPR, RID_MAX_GPR)-RID2RSET(RID_ESP))
54#define RSET_FPR (RSET_RANGE(RID_MIN_FPR, RID_MAX_FPR))
55#define RSET_ALL (RSET_GPR|RSET_FPR)
56
57#if LJ_64
58/* Note: this requires the use of FORCE_REX! */
59#define RSET_GPR8 RSET_GPR
60#else
61#define RSET_GPR8 (RSET_RANGE(RID_EAX, RID_EBX+1))
62#endif
63
64/* ABI-specific register sets. */
65#define RSET_ACD (RID2RSET(RID_EAX)|RID2RSET(RID_ECX)|RID2RSET(RID_EDX))
66#if LJ_64
67#ifdef _WIN64
68/* Windows x64 ABI. */
69#define RSET_SCRATCH \
70 (RSET_ACD|RSET_RANGE(RID_R8D, RID_R11D+1)|RSET_RANGE(RID_XMM0, RID_XMM5+1))
71#else
72/* The rest of the civilized x64 world has a common ABI. */
73#define RSET_SCRATCH \
74 (RSET_ACD|RSET_RANGE(RID_ESI, RID_R11D+1)|RSET_FPR)
75#endif
76#else
77/* Common x86 ABI. */
78#define RSET_SCRATCH (RSET_ACD|RSET_FPR)
79#endif
80
81#if LJ_64
82/* Prefer the low 8 regs of each type to reduce REX prefixes. */
83#undef rset_picktop
84#define rset_picktop(rs) (lj_fls(lj_bswap(rs)) ^ 0x18)
85#endif
86
87/* -- Spill slots --------------------------------------------------------- */
88
89/* Stack layout for the compiled machine code (after stack adjustment). */
90enum {
91 SPS_TEMP1, /* Temps (3*dword) for calls and asm_x87load. */
92 SPS_TEMP2,
93 SPS_TEMP3,
94 SPS_FIRST, /* First spill slot for general use. */
95
96 /* This definition must match with the *.dasc file(s). */
97 SPS_FIXED = 6 /* Available fixed spill slots in interpreter frame. */
98};
99
100/* Spill slots are 32 bit wide. An even/odd pair is used for FPRs. */
101#define sps_scale(slot) (4 * (int32_t)(slot))
102#define sps_adjust(as) (sps_scale((as->evenspill-SPS_FIXED+3)&~3))
103
104/* -- Exit state ---------------------------------------------------------- */
105
106/* This definition must match with the *.dasc file(s). */
107typedef struct {
108 lua_Number fpr[RID_NUM_FPR]; /* Floating-point registers. */
109 int32_t gpr[RID_NUM_GPR]; /* General-purpose registers. */
110 int32_t spill[256]; /* Spill slots. */
111} ExitState;
112
113/* -- x86 ModRM operand encoding ------------------------------------------ */
114
115typedef enum {
116 XM_OFS0 = 0x00, XM_OFS8 = 0x40, XM_OFS32 = 0x80, XM_REG = 0xc0,
117 XM_SCALE1 = 0x00, XM_SCALE2 = 0x40, XM_SCALE4 = 0x80, XM_SCALE8 = 0xc0,
118 XM_MASK = 0xc0
119} x86Mode;
120
121/* Structure to hold variable ModRM operand. */
122typedef struct {
123 int32_t ofs; /* Offset. */
124 uint8_t base; /* Base register or RID_NONE. */
125 uint8_t idx; /* Index register or RID_NONE. */
126 uint8_t scale; /* Index scale (XM_SCALE1 .. XM_SCALE8). */
127} x86ModRM;
128
129/* -- Opcodes ------------------------------------------------------------- */
130
131/* Macros to construct variable-length x86 opcodes. -(len+1) is in LSB. */
132#define XO_(o) ((uint32_t)(0x0000fe + (0x##o<<24)))
133#define XO_FPU(a,b) ((uint32_t)(0x00fd + (0x##a<<16)+(0x##b<<24)))
134#define XO_0f(o) ((uint32_t)(0x0f00fd + (0x##o<<24)))
135#define XO_66(o) ((uint32_t)(0x6600fd + (0x##o<<24)))
136#define XO_660f(o) ((uint32_t)(0x0f66fc + (0x##o<<24)))
137#define XO_f20f(o) ((uint32_t)(0x0ff2fc + (0x##o<<24)))
138#define XO_f30f(o) ((uint32_t)(0x0ff3fc + (0x##o<<24)))
139
140/* This list of x86 opcodes is not intended to be complete. Opcodes are only
141** included when needed. Take a look at DynASM or jit.dis_x86 to see the
142** whole mess.
143*/
144typedef enum {
145 /* Fixed length opcodes. XI_* prefix. */
146 XI_NOP = 0x90,
147 XI_CALL = 0xe8,
148 XI_JMP = 0xe9,
149 XI_JMPs = 0xeb,
150 XI_JCCs = 0x70, /* Really 7x. */
151 XI_JCCn = 0x80, /* Really 0f8x. */
152 XI_LEA = 0x8d,
153 XI_MOVri = 0xb8, /* Really b8+r. */
154 XI_ARITHib = 0x80,
155 XI_ARITHi = 0x81,
156 XI_ARITHi8 = 0x83,
157 XI_PUSHi8 = 0x6a,
158 XI_TEST = 0x85,
159 XI_MOVmi = 0xc7,
160 XI_BSWAP = 0xc8, /* Really 0fc8+r. */
161
162 /* Note: little-endian byte-order! */
163 XI_FLDZ = 0xeed9,
164 XI_FLD1 = 0xe8d9,
165 XI_FLDLG2 = 0xecd9,
166 XI_FLDLN2 = 0xedd9,
167 XI_FPOP = 0xd8dd, /* Really fstp st0. */
168 XI_FPOP1 = 0xd9dd, /* Really fstp st1. */
169 XI_FRNDINT = 0xfcd9,
170 XI_FSIN = 0xfed9,
171 XI_FCOS = 0xffd9,
172 XI_FPTAN = 0xf2d9,
173 XI_FPATAN = 0xf3d9,
174 XI_FSCALE = 0xfdd9,
175 XI_FYL2X = 0xf1d9,
176
177 /* Variable-length opcodes. XO_* prefix. */
178 XO_MOV = XO_(8b),
179 XO_MOVto = XO_(89),
180 XO_MOVtow = XO_66(89),
181 XO_MOVtob = XO_(88),
182 XO_MOVmi = XO_(c7),
183 XO_MOVmib = XO_(c6),
184 XO_LEA = XO_(8d),
185 XO_ARITHib = XO_(80),
186 XO_ARITHi = XO_(81),
187 XO_ARITHi8 = XO_(83),
188 XO_SHIFTi = XO_(c1),
189 XO_SHIFT1 = XO_(d1),
190 XO_SHIFTcl = XO_(d3),
191 XO_IMULi8 = XO_(6b),
192 XO_CMP = XO_(3b),
193 XO_TEST = XO_(85),
194 XO_GROUP3b = XO_(f6),
195 XO_GROUP3 = XO_(f7),
196 XO_MOVZXb = XO_0f(b6),
197 XO_MOVZXw = XO_0f(b7),
198 XO_MOVSXb = XO_0f(be),
199 XO_MOVSXw = XO_0f(bf),
200
201 XO_MOVSD = XO_f20f(10),
202 XO_MOVSDto = XO_f20f(11),
203 XO_MOVLPD = XO_660f(12),
204 XO_MOVAPS = XO_0f(28),
205 XO_XORPS = XO_0f(57),
206 XO_ANDPS = XO_0f(54),
207 XO_ADDSD = XO_f20f(58),
208 XO_SUBSD = XO_f20f(5c),
209 XO_MULSD = XO_f20f(59),
210 XO_DIVSD = XO_f20f(5e),
211 XO_SQRTSD = XO_f20f(51),
212 XO_MINSD = XO_f20f(5d),
213 XO_MAXSD = XO_f20f(5f),
214 XO_ROUNDSD = 0x0b3a0ffc, /* Really 66 0f 3a 0b. See asm_fpmath. */
215 XO_UCOMISD = XO_660f(2e),
216 XO_CVTSI2SD = XO_f20f(2a),
217 XO_CVTSD2SI = XO_f20f(2d),
218 XO_CVTTSD2SI= XO_f20f(2c),
219 XO_MOVDto = XO_660f(7e),
220
221 XO_FLDq = XO_(dd), XOg_FLDq = 0,
222 XO_FILDd = XO_(db), XOg_FILDd = 0,
223 XO_FSTPq = XO_(dd), XOg_FSTPq = 3,
224 XO_FISTPq = XO_(df), XOg_FISTPq = 7,
225} x86Op;
226
227/* x86 opcode groups. */
228typedef uint32_t x86Group;
229
230#define XG_(i8, i, g) ((x86Group)(((i8) << 16) + ((i) << 8) + (g)))
231#define XG_ARITHi(g) XG_(XI_ARITHi8, XI_ARITHi, g)
232
233#define XO_ARITH(a) ((x86Op)(0x030000fe + ((a)<<27)))
234
235typedef enum {
236 XOg_ADD, XOg_OR, XOg_ADC, XOg_SBB, XOg_AND, XOg_SUB, XOg_XOR, XOg_CMP
237} x86Arith;
238
239typedef enum {
240 XOg_ROL, XOg_ROR, XOg_RCL, XOg_RCR, XOg_SHL, XOg_SHR, XOg_SAL, XOg_SAR
241} x86Shift;
242
243typedef enum {
244 XOg_TEST, XOg_TEST_, XOg_NOT, XOg_NEG, XOg_MUL, XOg_IMUL, XOg_DIV, XOg_IDIV
245} x86Group3;
246
247/* x86 condition codes. */
248typedef enum {
249 CC_O, CC_NO, CC_B, CC_NB, CC_E, CC_NE, CC_BE, CC_NBE,
250 CC_S, CC_NS, CC_P, CC_NP, CC_L, CC_NL, CC_LE, CC_NLE,
251 CC_C = CC_B, CC_NAE = CC_C, CC_NC = CC_NB, CC_AE = CC_NB,
252 CC_Z = CC_E, CC_NZ = CC_NE, CC_NA = CC_BE, CC_A = CC_NBE,
253 CC_PE = CC_P, CC_PO = CC_NP, CC_NGE = CC_L, CC_GE = CC_NL,
254 CC_NG = CC_LE, CC_G = CC_NLE
255} x86CC;
256
257#endif