Rune - Further Object abstraction work
[rune.git] / librune / insn.h
1 /*
2  * INSN.H
3  *
4  * (c)Copyright 2015-2021, Matthew Dillon, All Rights Reserved.
5  */
6
7 /*
8  * Code generator pseudo machine register and effective-address
9  * specifications.
10  */
11 #define EA_UNKNOWN      0
12 #define EA_DIRECT       1
13 #define EA_MEMORY       2
14 #define EA_UNUSED03     3
15 #define EA_IMMEDIATE    4
16 #define EA_IMMEDIATE16  5       /* 128-bit immediate */
17 #define EA_BAD          0x80U
18
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
24
25 #define REG_FIRSTTMP    100
26
27 #define REG_NEWDAT      ((uint32_t)-1 & REGF_MASK)
28 #define REG_NEWPTR      (REGF_PTR | ((uint32_t)-1 & REGF_MASK))
29
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 */
38
39 #define REG_ZERO        0
40 #define REG_NULL        (REGF_PTR | 0)
41 #define REG_ABS         REG_NULL
42
43 /*
44  * Control bits determine capabilities and restrictions.
45  */
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 */
65
66 #define INSNF_INSN      0x80000000U     /* used by RAS only, must be bit 31 */
67
68 /*
69  * Instructions (12 bits | flags)
70  *
71  * Note that some instruction codes are repeated with different flags.
72  */
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)
89
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)
96
97 #define INSN_INC        (0x0016)
98 #define INSN_DEC        (0x0017)
99
100 /*
101  * CMP (note mask 0x0F00 indicates condition, DO NOT CHANGE)
102  */
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)
113
114 /*
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.
118  */
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)
126
127 /*
128  * NOTE: BZERO uses the passed-in destination type alignment for
129  * optimizations.
130  */
131 #define INSN_BCOPY      (0x0028 | INSNF_ALIGN | INSNF_LEAM | INSNF_LEAD)
132 #define INSN_BZERO      (0x0029 | INSNF_ALIGN | INSNF_LEAD)
133
134 #define INSN_CMPTYPE    (0x002A | INSNF_COND | INSNF_LEAS | INSNF_LEAM)
135 #define INSN_TSCHED     (0x002B)
136
137 /*
138  * CMPA (note mask 0x0F00 indicates condition, DO NOT CHANGE)
139  */
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)
150
151 /*
152  * Casts - signed/unsigned/pointer specification is for source.
153  *
154  * CAST*        [s/u]integer<->integer CASTP    pointer -> integer
155  */
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)
159
160 /*
161  * ReferenceStor, LValueStor, and RefStor handling.
162  *
163  *
164  * These work on ReferenceStor's, typically operating on s_Info or
165  * s_Info->in_RefStor.
166  *
167  * LVALLOC      Allocate lvalue declared variable/field
168  * BCHECK       Bounds-check an array using an index and extent
169  *
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
176  *
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
183  */
184
185 /* 40-41 avail */
186 /* 4A-4F avail */
187
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)
201
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)
212
213 #define INSN_LVALLOC    (0x0058)
214 #define INSN_BCHECK     (0x005D)
215 #define INSN_BND_TRAP   (0x005F)
216
217 /*
218  * CALL target,argea,retea
219  *
220  * CALL/TCALL/LCALL - Native Rune calls QCALL       - System call RCALL     -
221  * RunTime_*() call
222  */
223 #define INSN_CALL       (0x0061 | INSNF_LEAS | INSNF_LEAM | INSNF_LEAD | \
224                                   INSNF_UNSIZED)
225 #define INSN_TCALL      (0x0062 | INSNF_LEAS | INSNF_LEAM | INSNF_LEAD | \
226                                   INSNF_UNSIZED)
227 #define INSN_LCALL      (0x0063 | INSNF_LEAS | INSNF_LEAM | INSNF_LEAD | \
228                                   INSNF_UNSIZED)
229 #define INSN_QCALL      (0x0064 | INSNF_LEAS | INSNF_LEAM | INSNF_LEAD | \
230                                   INSNF_UNSIZED)
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 | \
235                                   INSNF_UNSIZED)
236
237 /*
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))
240  *
241  * (note mask 0x0F00 indicates condition, DO NOT CHANGE)
242  */
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)
246
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)
252
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)
258
259 /*
260  * INSN_*ITOF   [s/u]integer to float
261  * INSN_FTOI*   float to [s/u]integer
262  * CASTF        float to float
263  *
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.
266  */
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)
272
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)