Rune - Change regsave burden for syscalls
[rune.git] / librune / insn.h
1 /*
2  * INSN.H
3  *
4  * (c)Copyright 2015, Matthew Dillon, All Rights Reserved.  See the  
5  *    COPYRIGHT file at the base of the distribution.
6  */
7
8 /*
9  * Control bits determine capabilities and restrictions.
10  */
11 #define INSNF_ALIGN     0x00001000      /* size ext is for alignment */
12 #define INSNF_SSIZE     0x00002000      /* type sizes can be different */
13 #define INSNF_U0        0x00004000      /* implied instruction */
14 #define INSNF_U1        0x00008000      /* unary 1-op */
15 #define INSNF_U2        0x00010000      /* unary 2-op */
16 #define INSNF_CAST      0x00020000      /* operand size differences ok */
17 #define INSNF_B2        0x00040000      /* binary 2-op */
18 #define INSNF_B3        0x00080000      /* binary 3-op */
19 #define INSNF_LEAS      0x00100000      /* data1 is lea */
20 #define INSNF_LEAM      0x00200000      /* data2 is lea */
21 #define INSNF_LEAD      0x00400000      /* data3 is lea */
22 #define INSNF_BOOLD     0x00800000      /* destination operand is BOOL */
23 #define INSNF_LABELD    0x01000000      /* destination operand is a label */
24 #define INSNF_UNSIZED   0x02000000      /* unsized opcode */
25 #define INSNF_FLOAT     0x04000000      /* FP unit involved */
26 #define INSNF_PTRS      0x08000000      /* source must be a raw pointer */
27 #define INSNF_DISCARDS  0x10000000      /* discard src ok if dest not used */
28 #define INSNF_PTRD      0x20000000      /* destination must be a raw pointer */
29 #define INSNF_COND      0x40000000      /* label or boolean arg3 */
30
31 #define INSNF_INSN      0x80000000U     /* used by RAS only, must be bit 31 */
32
33 /*
34  * Instructions (12 bits | flags)
35  *
36  * Note that some instruction codes are repeated with different flags.
37  */
38 #define INSN_LABEL      (0x0000)        /* used by RAS only */
39 #define INSN_MOVE       (0x0001 | INSNF_DISCARDS)
40 #define INSN_ADD        (0x0002)
41 #define INSN_SUB        (0x0003)
42 #define INSN_AND        (0x0004)
43 #define INSN_OR         (0x0005)
44 #define INSN_XOR        (0x0006)
45 #define INSN_NOT        (0x0007 | INSNF_SSIZE)
46 #define INSN_COM        (0x0008)
47 #define INSN_NEG        (0x0009)
48 #define INSN_POS        (0x000A)
49 #define INSN_ASL        (0x000B | INSNF_SSIZE)
50 #define INSN_ASR        (0x000C | INSNF_SSIZE)
51 #define INSN_LSR        (0x000D | INSNF_SSIZE)
52 #define INSN_ADDC       (0x000E)
53 #define INSN_SUBC       (0x000F)
54
55 #define INSN_MULU       (0x0010)
56 #define INSN_MULS       (0x0011)
57 #define INSN_DIVU       (0x0012)
58 #define INSN_DIVS       (0x0013)
59 #define INSN_MODU       (0x0014)
60 #define INSN_MODS       (0x0015)
61
62 #define INSN_INC        (0x0016)
63 #define INSN_DEC        (0x0017)
64
65 /*
66  * CMP (note mask 0x0F00 indicates condition, DO NOT CHANGE)
67  */
68 #define INSN_CMP_EQ     (0x001F | INSNF_COND)
69 #define INSN_CMP_NE     (0x011F | INSNF_COND)
70 #define INSN_CMP_UGT    (0x021F | INSNF_COND)
71 #define INSN_CMP_UGE    (0x031F | INSNF_COND)
72 #define INSN_CMP_ULT    (0x041F | INSNF_COND)
73 #define INSN_CMP_ULE    (0x051F | INSNF_COND)
74 #define INSN_CMP_SGT    (0x061F | INSNF_COND)
75 #define INSN_CMP_SGE    (0x071F | INSNF_COND)
76 #define INSN_CMP_SLT    (0x081F | INSNF_COND)
77 #define INSN_CMP_SLE    (0x091F | INSNF_COND)
78
79 /*
80  * Special (C-style) pointer handling insns.  Typically passed &CVoidPtrType
81  * (do not pass the fat PointerType!), and can be used to add/sub integers
82  * of different sizes to the pointer.
83  */
84 #define INSN_MOVEA      (0x0020 | INSNF_SSIZE | INSNF_PTRD | INSNF_DISCARDS)
85 #define INSN_ADDA       (0x0021 | INSNF_SSIZE | INSNF_PTRD)
86 #define INSN_SUBA       (0x0022 | INSNF_SSIZE | INSNF_PTRD)
87 #define INSN_ADDAU      (0x0023 | INSNF_SSIZE | INSNF_PTRD)
88 #define INSN_SUBAU      (0x0024 | INSNF_SSIZE | INSNF_PTRD)
89 #define INSN_SUBAA      (0x0025 | INSNF_SSIZE | INSNF_PTRD)
90 #define INSN_LEA        (0x0026 | INSNF_LEAS | INSNF_PTRD | INSNF_DISCARDS)
91
92 /*
93  * NOTE: BZERO uses the passed-in destination type alignment for optimizations.
94  */
95 #define INSN_BCOPY      (0x0028 | INSNF_ALIGN | INSNF_LEAM | INSNF_LEAD)
96 #define INSN_BZERO      (0x0029 | INSNF_ALIGN | INSNF_LEAD)
97
98 #define INSN_CMPTYPE    (0x002A | INSNF_COND | INSNF_LEAS | INSNF_LEAM)
99 #define INSN_TSCHED     (0x002B)
100
101 /*
102  * CMPA (note mask 0x0F00 indicates condition, DO NOT CHANGE)
103  */
104 #define INSN_CMPA_EQ    (0x002F | INSNF_COND)
105 #define INSN_CMPA_NE    (0x012F | INSNF_COND)
106 #define INSN_CMPA_UGT   (0x022F | INSNF_COND)
107 #define INSN_CMPA_UGE   (0x032F | INSNF_COND)
108 #define INSN_CMPA_ULT   (0x042F | INSNF_COND)
109 #define INSN_CMPA_ULE   (0x052F | INSNF_COND)
110 #define INSN_CMPA_SGT   (0x062F | INSNF_COND)
111 #define INSN_CMPA_SGE   (0x072F | INSNF_COND)
112 #define INSN_CMPA_SLT   (0x082F | INSNF_COND)
113 #define INSN_CMPA_SLE   (0x092F | INSNF_COND)
114
115 /*
116  * Casts - signed/unsigned/pointer specification is for source.
117  *
118  * CAST*        [s/u]integer<->integer
119  * CASTP        pointer -> integer
120  */
121 #define INSN_CASTU      (0x0030 | INSNF_CAST | INSNF_SSIZE)
122 #define INSN_CASTS      (0x0031 | INSNF_CAST | INSNF_SSIZE)
123 #define INSN_CASTP      (0x0032 | INSNF_CAST | INSNF_SSIZE | INSNF_PTRS)
124
125 /*
126  * PointerStor, LValueStor, and RefStor handling.
127  *
128  *
129  *              These work on PointerStor's, typically operating on
130  *              s_Info or s_Info->in_RefStor.
131  *
132  * PCOPY        Copy a PointerStor, does not adjust refs/locks or Info.
133  * PCHECK       Bounds-check a PointerStor using ps->s_Info->in_*
134  * BCHECK       Bounds-check an array using an index and extent
135  *
136  * PGET[H]      ++Refs,Lock
137  * PPUT[H]      Unlock,--Refs
138  * PREF         ++refs
139  * PREL         --refs
140  * PLOCK[H]     Lock (no change to refs)
141  * PUNLOCK[H]   Unlock (no change to refs)
142  *
143  * PATOM        Atomize (make s_Info unique) and extract s_Info,
144  *              derefs original info, replacement info will have
145  *              one ref.
146  *
147  * PIGET[H]     PGET but extracts, ++Refs,Lock, and returns s_Info
148  *
149  * IGET[H]      These work directly on PointerInfo's
150  * IPUT[H]      ...
151  * IREF         ...
152  * IREL         ...
153  * ILOCK[H]     ...
154  * IUNLOCK[H]   ...
155  * IATOM        Allocate a new PointerInfo structure using an old one
156  *              as as template.  The old info is not dereferenced.  The
157  *              new info has one reference and a ref is added to the RefStor.
158  *
159  * STKIGET[H]   ++Refs,Lock the stack, return its PointerInfo
160  * STKIREF      ++Refs the stack, return its PointerInfo
161  * SRSGET       (implied) ++Refs,Lock the stack
162  * SRSPUT       (implied) UnLock,--Refs the stack
163  */
164 #define INSN_PCOPY      (0x0040 | INSNF_LEAS | INSNF_LEAD)
165 #define INSN_PCHECK     (0x0041 | INSNF_PTRS | INSNF_LEAD)
166
167 #define INSN_PGET       (0x0042 | INSNF_LEAS)
168 #define INSN_PGETH      (0x0142 | INSNF_LEAS)
169 #define INSN_PPUT       (0x0043 | INSNF_LEAS)
170 #define INSN_PPUTH      (0x0143 | INSNF_LEAS)
171 #define INSN_PREF       (0x0044 | INSNF_LEAS)
172 #define INSN_PREL       (0x0045 | INSNF_LEAS)
173 #define INSN_PLOCK      (0x0046 | INSNF_LEAS)
174 #define INSN_PLOCKH     (0x0146 | INSNF_LEAS)
175 #define INSN_PUNLOCK    (0x0047 | INSNF_LEAS)
176 #define INSN_PUNLOCKH   (0x0147 | INSNF_LEAS)
177 #define INSN_PATOM      (0x0048 | INSNF_LEAS | INSNF_PTRD)
178 #define INSN_PIGET      (0x0049 | INSNF_LEAS | INSNF_PTRD)
179 #define INSN_PIGETH     (0x0149 | INSNF_LEAS | INSNF_PTRD)
180                         /* 4A-4F avail */
181
182 #define INSN_IGET       (0x0050 | INSNF_PTRS)
183 #define INSN_IGETH      (0x0150 | INSNF_PTRS)
184 #define INSN_IPUT       (0x0051 | INSNF_PTRS)
185 #define INSN_IPUTH      (0x0151 | INSNF_PTRS)
186 #define INSN_IREF       (0x0052 | INSNF_PTRS)
187 #define INSN_IREL       (0x0053 | INSNF_PTRS)
188 #define INSN_ILOCK      (0x0054 | INSNF_PTRS)
189 #define INSN_ILOCKH     (0x0154 | INSNF_PTRS)
190 #define INSN_IUNLOCK    (0x0055 | INSNF_PTRS)
191 #define INSN_IUNLOCKH   (0x0155 | INSNF_PTRS)
192 #define INSN_INEW       (0x0056 | INSNF_PTRD)
193 #define INSN_IATOM      (0x0057 | INSNF_PTRS | INSNF_PTRD)
194
195 #define INSN_LVALLOC    (0x0058 | INSNF_LEAS | INSNF_LEAM | INSNF_BOOLD)
196 #define INSN_STKIGET    (0x0059 | INSNF_PTRD)
197 #define INSN_STKIGETH   (0x0159 | INSNF_PTRD)
198 #define INSN_STKIREF    (0x005A | INSNF_PTRD)
199
200 #define INSN_SRSGET     (0x005B)
201 #define INSN_SRSGETH    (0x015B)
202 #define INSN_SRSPUT     (0x005C)
203 #define INSN_SRSPUTH    (0x015C)
204 #define INSN_BCHECK     (0x005D)
205
206 #define INSN_BND_TRAP   (0x005F)
207
208 /*
209  * CALL target,argea,retea
210  *
211  * CALL/TCALL/LCALL - Native Rune calls
212  * QCALL            - System call
213  * RCALL            - RunTime_*() call
214  */
215 #define INSN_CALL       (0x0061 | INSNF_LEAS | INSNF_LEAM | INSNF_LEAD | \
216                                   INSNF_UNSIZED)
217 #define INSN_TCALL      (0x0062 | INSNF_LEAS | INSNF_LEAM | INSNF_LEAD | \
218                                   INSNF_UNSIZED)
219 #define INSN_LCALL      (0x0063 | INSNF_LEAS | INSNF_LEAM | INSNF_LEAD | \
220                                   INSNF_UNSIZED)
221 #define INSN_QCALL      (0x0064 | INSNF_LEAS | INSNF_LEAM | INSNF_LEAD | \
222                                   INSNF_UNSIZED)
223 #define INSN_RET        (0x0067)
224 #define INSN_LINK       (0x0068)
225 #define INSN_DET        (0x0069)
226 #define INSN_RCALL      (0x006A | INSNF_LEAS | INSNF_LEAM | INSNF_LEAD | \
227                                   INSNF_UNSIZED)
228
229 /*
230  * TEST_EQ - Test if equals zero        (If B3, test (a & b))
231  * TEST_NE - Test if not equals zero    (If B3, test (a & b))
232  *
233  * (note mask 0x0F00 indicates condition, DO NOT CHANGE)
234  */
235 #define INSN_JMP        (0x007E | INSNF_COND | INSNF_LABELD)
236 #define INSN_TEST_EQ    (0x007F | INSNF_COND)
237 #define INSN_TEST_NE    (0x017F | INSNF_COND)
238
239 #define INSN_FMOVE      (0x0080 | INSNF_FLOAT)
240 #define INSN_FADD       (0x0081 | INSNF_FLOAT)
241 #define INSN_FSUB       (0x0082 | INSNF_FLOAT)
242 #define INSN_FMUL       (0x0083 | INSNF_FLOAT)
243 #define INSN_FDIV       (0x0084 | INSNF_FLOAT)
244
245 #define INSN_FINC       (0x0090 | INSNF_FLOAT)
246 #define INSN_FDEC       (0x0091 | INSNF_FLOAT)
247 #define INSN_FNEG       (0x0092 | INSNF_FLOAT)
248 #define INSN_FPOS       (0x0093 | INSNF_FLOAT)
249 #define INSN_FNOT       (0x0094 | INSNF_FLOAT | INSNF_SSIZE)
250
251 /*
252  * *ITOF        [s/u]integer to float
253  * FTOI*        float to [s/u]integer
254  * CASTF        float to float
255  *
256  * NOTE: INSNF_FLOAT is not set for UITOF or SITOF, we use the flag as a hint
257  *       for $immediate value computation and the source is an integer.
258  */
259 #define INSN_UITOF      (0x0096 | INSNF_CAST | INSNF_SSIZE)
260 #define INSN_SITOF      (0x0097 | INSNF_CAST | INSNF_SSIZE)
261 #define INSN_FTOUI      (0x0098 | INSNF_CAST | INSNF_FLOAT | INSNF_SSIZE)
262 #define INSN_FTOSI      (0x0099 | INSNF_CAST | INSNF_FLOAT | INSNF_SSIZE)
263 #define INSN_CASTF      (0x009A | INSNF_CAST | INSNF_FLOAT | INSNF_SSIZE)
264
265 #define INSN_FCMP_UEQ   (0x009F | INSNF_COND | INSNF_FLOAT)
266 #define INSN_FCMP_UGT   (0x029F | INSNF_COND | INSNF_FLOAT)
267 #define INSN_FCMP_UGE   (0x039F | INSNF_COND | INSNF_FLOAT)
268 #define INSN_FCMP_ULT   (0x049F | INSNF_COND | INSNF_FLOAT)
269 #define INSN_FCMP_ULE   (0x059F | INSNF_COND | INSNF_FLOAT)
270 #define INSN_FCMP_UNE   (0x019F | INSNF_COND | INSNF_FLOAT)
271