4 * (c)Copyright 2015-2021, Matthew Dillon, All Rights Reserved.
8 * Code generator pseudo machine register and effective-address
15 #define EA_IMMEDIATE 4
16 #define EA_IMMEDIATE16 5 /* 128-bit immediate */
19 #define REGF_PTR 0x80000000U
20 #define REGF_TREG 0x40000000U /* for llvm backend %Tn, not %Pn */
21 #define REGF_MASK 0x00FFFFFFU
22 #define REGF_USRMASK 0x0F000000U
23 #define REGF_USRBASE 0x01000000U
25 #define REG_FIRSTTMP 100
27 #define REG_NEWDAT ((uint32_t)-1 & REGF_MASK)
28 #define REG_NEWPTR (REGF_PTR | ((uint32_t)-1 & REGF_MASK))
30 #define REG_TMPPTR (REGF_PTR | 8) /* gen-level reusable temporary */
31 #define REG_SG (REGF_PTR | 9) /* semgroup pointer (varargs calls) */
32 #define REG_RP (REGF_PTR | 10) /* return data pointer */
33 #define REG_DB (REGF_PTR | 11) /* data & module base */
34 #define REG_TP (REGF_PTR | 12) /* thread pointer */
35 #define REG_AP (REGF_PTR | 13) /* argument pointer */
36 #define REG_FP (REGF_PTR | 14) /* frame pointer */
37 #define REG_PC (REGF_PTR | 15) /* program counter */
40 #define REG_NULL (REGF_PTR | 0)
41 #define REG_ABS REG_NULL
44 * Control bits determine capabilities and restrictions.
46 #define INSNF_ALIGN 0x00001000 /* size ext is for alignment */
47 #define INSNF_SSIZE 0x00002000 /* type sizes can be different */
48 #define INSNF_U0 0x00004000 /* implied instruction */
49 #define INSNF_U1 0x00008000 /* unary 1-op */
50 #define INSNF_U2 0x00010000 /* unary 2-op */
51 #define INSNF_CAST 0x00020000 /* operand size differences ok */
52 #define INSNF_B2 0x00040000 /* binary 2-op */
53 #define INSNF_B3 0x00080000 /* binary 3-op */
54 #define INSNF_LEAS 0x00100000 /* data1 is lea */
55 #define INSNF_LEAM 0x00200000 /* data2 is lea */
56 #define INSNF_LEAD 0x00400000 /* data3 is lea */
57 #define INSNF_BOOLD 0x00800000 /* destination operand is BOOL */
58 #define INSNF_LABELD 0x01000000 /* destination operand is a label */
59 #define INSNF_UNSIZED 0x02000000 /* unsized opcode */
60 #define INSNF_FLOAT 0x04000000 /* FP unit involved */
61 #define INSNF_PTRS 0x08000000 /* source must be a raw pointer */
62 #define INSNF_DISCARDS 0x10000000 /* discard src ok if dest not used */
63 #define INSNF_PTRD 0x20000000 /* destination must be a raw pointer */
64 #define INSNF_COND 0x40000000 /* label or boolean arg3 */
66 #define INSNF_INSN 0x80000000U /* used by RAS only, must be bit 31 */
69 * Instructions (12 bits | flags)
71 * Note that some instruction codes are repeated with different flags.
73 #define INSN_LABEL (0x0000) /* used by RAS only */
74 #define INSN_MOVE (0x0001 | INSNF_DISCARDS)
75 #define INSN_ADD (0x0002)
76 #define INSN_SUB (0x0003)
77 #define INSN_AND (0x0004)
78 #define INSN_OR (0x0005)
79 #define INSN_XOR (0x0006)
80 #define INSN_NOT (0x0007 | INSNF_SSIZE)
81 #define INSN_COM (0x0008)
82 #define INSN_NEG (0x0009)
83 #define INSN_POS (0x000A)
84 #define INSN_ASL (0x000B | INSNF_SSIZE)
85 #define INSN_ASR (0x000C | INSNF_SSIZE)
86 #define INSN_LSR (0x000D | INSNF_SSIZE)
87 #define INSN_ADDC (0x000E)
88 #define INSN_SUBC (0x000F)
90 #define INSN_MULU (0x0010)
91 #define INSN_MULS (0x0011)
92 #define INSN_DIVU (0x0012)
93 #define INSN_DIVS (0x0013)
94 #define INSN_MODU (0x0014)
95 #define INSN_MODS (0x0015)
97 #define INSN_INC (0x0016)
98 #define INSN_DEC (0x0017)
101 * CMP (note mask 0x0F00 indicates condition, DO NOT CHANGE)
103 #define INSN_CMP_EQ (0x001F | INSNF_COND)
104 #define INSN_CMP_NE (0x011F | INSNF_COND)
105 #define INSN_CMP_UGT (0x021F | INSNF_COND)
106 #define INSN_CMP_UGE (0x031F | INSNF_COND)
107 #define INSN_CMP_ULT (0x041F | INSNF_COND)
108 #define INSN_CMP_ULE (0x051F | INSNF_COND)
109 #define INSN_CMP_SGT (0x061F | INSNF_COND)
110 #define INSN_CMP_SGE (0x071F | INSNF_COND)
111 #define INSN_CMP_SLT (0x081F | INSNF_COND)
112 #define INSN_CMP_SLE (0x091F | INSNF_COND)
115 * Special (C-style) pointer handling insns. Typically passed &CVoidPtrType
116 * (do not pass the fat ReferenceType!), and can be used to add/sub integers
117 * of different sizes to the pointer.
119 #define INSN_MOVEA (0x0020 | INSNF_SSIZE | INSNF_PTRD | INSNF_DISCARDS)
120 #define INSN_ADDA (0x0021 | INSNF_SSIZE | INSNF_PTRD)
121 #define INSN_SUBA (0x0022 | INSNF_SSIZE | INSNF_PTRD)
122 #define INSN_ADDAU (0x0023 | INSNF_SSIZE | INSNF_PTRD)
123 #define INSN_SUBAU (0x0024 | INSNF_SSIZE | INSNF_PTRD)
124 #define INSN_SUBAA (0x0025 | INSNF_SSIZE | INSNF_PTRD)
125 #define INSN_LEA (0x0026 | INSNF_LEAS | INSNF_PTRD | INSNF_DISCARDS)
128 * NOTE: BZERO uses the passed-in destination type alignment for
131 #define INSN_BCOPY (0x0028 | INSNF_ALIGN | INSNF_LEAM | INSNF_LEAD)
132 #define INSN_BZERO (0x0029 | INSNF_ALIGN | INSNF_LEAD)
134 #define INSN_CMPTYPE (0x002A | INSNF_COND | INSNF_LEAS | INSNF_LEAM)
135 #define INSN_TSCHED (0x002B)
138 * CMPA (note mask 0x0F00 indicates condition, DO NOT CHANGE)
140 #define INSN_CMPA_EQ (0x002F | INSNF_COND)
141 #define INSN_CMPA_NE (0x012F | INSNF_COND)
142 #define INSN_CMPA_UGT (0x022F | INSNF_COND)
143 #define INSN_CMPA_UGE (0x032F | INSNF_COND)
144 #define INSN_CMPA_ULT (0x042F | INSNF_COND)
145 #define INSN_CMPA_ULE (0x052F | INSNF_COND)
146 #define INSN_CMPA_SGT (0x062F | INSNF_COND)
147 #define INSN_CMPA_SGE (0x072F | INSNF_COND)
148 #define INSN_CMPA_SLT (0x082F | INSNF_COND)
149 #define INSN_CMPA_SLE (0x092F | INSNF_COND)
152 * Casts - signed/unsigned/pointer specification is for source.
154 * CAST* [s/u]integer<->integer CASTP pointer -> integer
156 #define INSN_CASTU (0x0030 | INSNF_CAST | INSNF_SSIZE)
157 #define INSN_CASTS (0x0031 | INSNF_CAST | INSNF_SSIZE)
158 #define INSN_CASTP (0x0032 | INSNF_CAST | INSNF_SSIZE | INSNF_PTRS)
161 * ReferenceStor, LValueStor, and RefStor handling.
164 * These work on ReferenceStor's, typically operating on s_Info or
165 * s_Info->in_RefStor.
167 * LVALLOC Allocate lvalue declared variable/field
168 * BCHECK Bounds-check an array using an index and extent
170 * PGET[H] These work on pointers to references to objects
171 * PPUT[H] These work on pointers to references to objects
172 * PREF These work on pointers to references to objects
173 * PREL These work on pointers to references to objects
174 * PLOCK[H] These work on pointers to references to objects
175 * PUNLOCK[H] These work on pointers to references to objects
177 * IGET[H] These work on pointers to objects
178 * IPUT[H] These work on pointers to objects
179 * IREF These work on pointers to objects
180 * IREL These work on pointers to objects
181 * ILOCK[H] These work on pointers to objects
182 * IUNLOCK[H] These work on pointers to objects
188 #define INSN_PGET (0x0042 | INSNF_LEAS)
189 #define INSN_PGETH (0x0142 | INSNF_LEAS)
190 #define INSN_PPUT (0x0043 | INSNF_LEAS)
191 #define INSN_PPUTH (0x0143 | INSNF_LEAS)
192 #define INSN_PREF (0x0044 | INSNF_LEAS)
193 #define INSN_PREL (0x0045 | INSNF_LEAS)
194 #define INSN_PLOCK (0x0046 | INSNF_LEAS)
195 #define INSN_PLOCKH (0x0146 | INSNF_LEAS)
196 #define INSN_PUNLOCK (0x0047 | INSNF_LEAS)
197 #define INSN_PUNLOCKH (0x0147 | INSNF_LEAS)
198 #define INSN_PATOM (0x0048 | INSNF_LEAS | INSNF_PTRD)
199 #define INSN_PIGET (0x0049 | INSNF_LEAS | INSNF_PTRD)
200 #define INSN_PIGETH (0x0149 | INSNF_LEAS | INSNF_PTRD)
202 #define INSN_IGET (0x0050 | INSNF_PTRS)
203 #define INSN_IGETH (0x0150 | INSNF_PTRS)
204 #define INSN_IPUT (0x0051 | INSNF_PTRS)
205 #define INSN_IPUTH (0x0151 | INSNF_PTRS)
206 #define INSN_IREF (0x0052 | INSNF_PTRS)
207 #define INSN_IREL (0x0053 | INSNF_PTRS)
208 #define INSN_ILOCK (0x0054 | INSNF_PTRS)
209 #define INSN_ILOCKH (0x0154 | INSNF_PTRS)
210 #define INSN_IUNLOCK (0x0055 | INSNF_PTRS)
211 #define INSN_IUNLOCKH (0x0155 | INSNF_PTRS)
213 #define INSN_LVALLOC (0x0058)
214 #define INSN_BCHECK (0x005D)
215 #define INSN_BND_TRAP (0x005F)
218 * CALL target,argea,retea
220 * CALL/TCALL/LCALL - Native Rune calls QCALL - System call RCALL -
223 #define INSN_CALL (0x0061 | INSNF_LEAS | INSNF_LEAM | INSNF_LEAD | \
225 #define INSN_TCALL (0x0062 | INSNF_LEAS | INSNF_LEAM | INSNF_LEAD | \
227 #define INSN_LCALL (0x0063 | INSNF_LEAS | INSNF_LEAM | INSNF_LEAD | \
229 #define INSN_QCALL (0x0064 | INSNF_LEAS | INSNF_LEAM | INSNF_LEAD | \
231 #define INSN_RET (0x0067)
232 #define INSN_LINK (0x0068)
233 #define INSN_DET (0x0069)
234 #define INSN_RCALL (0x006A | INSNF_LEAS | INSNF_LEAM | INSNF_LEAD | \
238 * TEST_EQ - Test if equals zero (If B3, test (a & b)) TEST_NE - Test
239 * if not equals zero (If B3, test (a & b))
241 * (note mask 0x0F00 indicates condition, DO NOT CHANGE)
243 #define INSN_JMP (0x007E | INSNF_COND | INSNF_LABELD)
244 #define INSN_TEST_EQ (0x007F | INSNF_COND)
245 #define INSN_TEST_NE (0x017F | INSNF_COND)
247 #define INSN_FMOVE (0x0080 | INSNF_FLOAT)
248 #define INSN_FADD (0x0081 | INSNF_FLOAT)
249 #define INSN_FSUB (0x0082 | INSNF_FLOAT)
250 #define INSN_FMUL (0x0083 | INSNF_FLOAT)
251 #define INSN_FDIV (0x0084 | INSNF_FLOAT)
253 #define INSN_FINC (0x0090 | INSNF_FLOAT)
254 #define INSN_FDEC (0x0091 | INSNF_FLOAT)
255 #define INSN_FNEG (0x0092 | INSNF_FLOAT)
256 #define INSN_FPOS (0x0093 | INSNF_FLOAT)
257 #define INSN_FNOT (0x0094 | INSNF_FLOAT | INSNF_SSIZE)
260 * INSN_*ITOF [s/u]integer to float
261 * INSN_FTOI* float to [s/u]integer
262 * CASTF float to float
264 * NOTE: INSNF_FLOAT is not set for UITOF or SITOF, we use the flag as a hint
265 * for $immediate value computation and the source is an integer.
267 #define INSN_UITOF (0x0096 | INSNF_CAST | INSNF_SSIZE)
268 #define INSN_SITOF (0x0097 | INSNF_CAST | INSNF_SSIZE)
269 #define INSN_FTOUI (0x0098 | INSNF_CAST | INSNF_FLOAT | INSNF_SSIZE)
270 #define INSN_FTOSI (0x0099 | INSNF_CAST | INSNF_FLOAT | INSNF_SSIZE)
271 #define INSN_CASTF (0x009A | INSNF_CAST | INSNF_FLOAT | INSNF_SSIZE)
273 #define INSN_FCMP_UEQ (0x009F | INSNF_COND | INSNF_FLOAT)
274 #define INSN_FCMP_UGT (0x029F | INSNF_COND | INSNF_FLOAT)
275 #define INSN_FCMP_UGE (0x039F | INSNF_COND | INSNF_FLOAT)
276 #define INSN_FCMP_ULT (0x049F | INSNF_COND | INSNF_FLOAT)
277 #define INSN_FCMP_ULE (0x059F | INSNF_COND | INSNF_FLOAT)
278 #define INSN_FCMP_UNE (0x019F | INSNF_COND | INSNF_FLOAT)