blob: 14b2de6a41b5e5d2883c313d783fc24351f40aab [file] [log] [blame]
sewardjbbcf1882014-01-12 12:49:10 +00001
2/*---------------------------------------------------------------*/
3/*--- begin host_arm64_defs.h ---*/
4/*---------------------------------------------------------------*/
5
6/*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
Elliott Hughesed398002017-06-21 14:41:24 -070010 Copyright (C) 2013-2017 OpenWorks
sewardjbbcf1882014-01-12 12:49:10 +000011 info@open-works.net
12
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 02110-1301, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
31#ifndef __VEX_HOST_ARM64_DEFS_H
32#define __VEX_HOST_ARM64_DEFS_H
33
34#include "libvex_basictypes.h"
35#include "libvex.h" // VexArch
36#include "host_generic_regs.h" // HReg
37
sewardjbbcf1882014-01-12 12:49:10 +000038
39/* --------- Registers. --------- */
40
sewardja5b50222015-03-26 07:18:32 +000041#define ST_IN static inline
42ST_IN HReg hregARM64_X22 ( void ) { return mkHReg(False, HRcInt64, 22, 0); }
43ST_IN HReg hregARM64_X23 ( void ) { return mkHReg(False, HRcInt64, 23, 1); }
44ST_IN HReg hregARM64_X24 ( void ) { return mkHReg(False, HRcInt64, 24, 2); }
45ST_IN HReg hregARM64_X25 ( void ) { return mkHReg(False, HRcInt64, 25, 3); }
46ST_IN HReg hregARM64_X26 ( void ) { return mkHReg(False, HRcInt64, 26, 4); }
47ST_IN HReg hregARM64_X27 ( void ) { return mkHReg(False, HRcInt64, 27, 5); }
48ST_IN HReg hregARM64_X28 ( void ) { return mkHReg(False, HRcInt64, 28, 6); }
49
50ST_IN HReg hregARM64_X0 ( void ) { return mkHReg(False, HRcInt64, 0, 7); }
51ST_IN HReg hregARM64_X1 ( void ) { return mkHReg(False, HRcInt64, 1, 8); }
52ST_IN HReg hregARM64_X2 ( void ) { return mkHReg(False, HRcInt64, 2, 9); }
53ST_IN HReg hregARM64_X3 ( void ) { return mkHReg(False, HRcInt64, 3, 10); }
54ST_IN HReg hregARM64_X4 ( void ) { return mkHReg(False, HRcInt64, 4, 11); }
55ST_IN HReg hregARM64_X5 ( void ) { return mkHReg(False, HRcInt64, 5, 12); }
56ST_IN HReg hregARM64_X6 ( void ) { return mkHReg(False, HRcInt64, 6, 13); }
57ST_IN HReg hregARM64_X7 ( void ) { return mkHReg(False, HRcInt64, 7, 14); }
58
59ST_IN HReg hregARM64_Q16 ( void ) { return mkHReg(False, HRcVec128, 16, 15); }
60ST_IN HReg hregARM64_Q17 ( void ) { return mkHReg(False, HRcVec128, 17, 16); }
61ST_IN HReg hregARM64_Q18 ( void ) { return mkHReg(False, HRcVec128, 18, 17); }
62ST_IN HReg hregARM64_Q19 ( void ) { return mkHReg(False, HRcVec128, 19, 18); }
63ST_IN HReg hregARM64_Q20 ( void ) { return mkHReg(False, HRcVec128, 20, 19); }
64
65ST_IN HReg hregARM64_D8 ( void ) { return mkHReg(False, HRcFlt64, 8, 20); }
66ST_IN HReg hregARM64_D9 ( void ) { return mkHReg(False, HRcFlt64, 9, 21); }
67ST_IN HReg hregARM64_D10 ( void ) { return mkHReg(False, HRcFlt64, 10, 22); }
68ST_IN HReg hregARM64_D11 ( void ) { return mkHReg(False, HRcFlt64, 11, 23); }
69ST_IN HReg hregARM64_D12 ( void ) { return mkHReg(False, HRcFlt64, 12, 24); }
70ST_IN HReg hregARM64_D13 ( void ) { return mkHReg(False, HRcFlt64, 13, 25); }
71
72ST_IN HReg hregARM64_X8 ( void ) { return mkHReg(False, HRcInt64, 8, 26); }
73ST_IN HReg hregARM64_X9 ( void ) { return mkHReg(False, HRcInt64, 9, 27); }
74ST_IN HReg hregARM64_X21 ( void ) { return mkHReg(False, HRcInt64, 21, 28); }
75#undef ST_IN
sewardjbbcf1882014-01-12 12:49:10 +000076
77extern void ppHRegARM64 ( HReg );
78
sewardjbbcf1882014-01-12 12:49:10 +000079/* Number of registers used arg passing in function calls */
80#define ARM64_N_ARGREGS 8 /* x0 .. x7 */
81
82
83/* --------- Condition codes. --------- */
84
85typedef
86 enum {
87 ARM64cc_EQ = 0, /* equal : Z=1 */
88 ARM64cc_NE = 1, /* not equal : Z=0 */
89
90 ARM64cc_CS = 2, /* >=u (higher or same) : C=1 */
91 ARM64cc_CC = 3, /* <u (lower) : C=0 */
92
93 ARM64cc_MI = 4, /* minus (negative) : N=1 */
94 ARM64cc_PL = 5, /* plus (zero or +ve) : N=0 */
95
96 ARM64cc_VS = 6, /* overflow : V=1 */
97 ARM64cc_VC = 7, /* no overflow : V=0 */
98
99 ARM64cc_HI = 8, /* >u (higher) : C=1 && Z=0 */
100 ARM64cc_LS = 9, /* <=u (lower or same) : !(C=1 && Z=0) */
101
102 ARM64cc_GE = 10, /* >=s (signed greater or equal) : N=V */
103 ARM64cc_LT = 11, /* <s (signed less than) : !(N=V) */
104
105 ARM64cc_GT = 12, /* >s (signed greater) : Z=0 && N=V */
106 ARM64cc_LE = 13, /* <=s (signed less or equal) : !(Z=0 && N=V) */
107
108 ARM64cc_AL = 14, /* always (unconditional) */
109 ARM64cc_NV = 15 /* in 64-bit mode also means "always" */
110 }
111 ARM64CondCode;
112
113
114/* --------- Memory address expressions (amodes). --------- */
115
116typedef
117 enum {
sewardj606c4ba2014-01-26 19:11:14 +0000118 ARM64am_RI9=10, /* reg + simm9 */
sewardjbbcf1882014-01-12 12:49:10 +0000119 ARM64am_RI12, /* reg + uimm12 * szB (iow, scaled by access size) */
120 ARM64am_RR /* reg1 + reg2 */
121 }
122 ARM64AModeTag;
123
124typedef
125 struct {
126 ARM64AModeTag tag;
127 union {
128 struct {
129 HReg reg;
130 Int simm9; /* -256 .. +255 */
131 } RI9;
132 struct {
133 HReg reg;
134 UInt uimm12; /* 0 .. 4095 */
135 UChar szB; /* 1, 2, 4, 8 (16 ?) */
136 } RI12;
137 struct {
138 HReg base;
139 HReg index;
140 } RR;
141 } ARM64am;
142 }
143 ARM64AMode;
144
145extern ARM64AMode* ARM64AMode_RI9 ( HReg reg, Int simm9 );
146extern ARM64AMode* ARM64AMode_RI12 ( HReg reg, Int uimm12, UChar szB );
147extern ARM64AMode* ARM64AMode_RR ( HReg base, HReg index );
148
149
150/* --------- Reg or uimm12 or (uimm12 << 12) operands --------- */
151
152typedef
153 enum {
sewardj606c4ba2014-01-26 19:11:14 +0000154 ARM64riA_I12=20, /* uimm12 << 0 or 12 only */
155 ARM64riA_R /* reg */
sewardjbbcf1882014-01-12 12:49:10 +0000156 }
157 ARM64RIATag;
158
159typedef
160 struct {
161 ARM64RIATag tag;
162 union {
163 struct {
164 UShort imm12; /* 0 .. 4095 */
165 UChar shift; /* 0 or 12 only */
166 } I12;
167 struct {
168 HReg reg;
169 } R;
170 } ARM64riA;
171 }
172 ARM64RIA;
173
174extern ARM64RIA* ARM64RIA_I12 ( UShort imm12, UChar shift );
175extern ARM64RIA* ARM64RIA_R ( HReg );
176
177
178/* --------- Reg or "bitfield" (logic immediate) operands --------- */
179
180typedef
181 enum {
182 ARM64riL_I13=6, /* wierd-o bitfield immediate, 13 bits in total */
183 ARM64riL_R /* reg */
184 }
185 ARM64RILTag;
186
187typedef
188 struct {
189 ARM64RILTag tag;
190 union {
191 struct {
192 UChar bitN; /* 0 .. 1 */
193 UChar immR; /* 0 .. 63 */
194 UChar immS; /* 0 .. 63 */
195 } I13;
196 struct {
197 HReg reg;
198 } R;
199 } ARM64riL;
200 }
201 ARM64RIL;
202
203extern ARM64RIL* ARM64RIL_I13 ( UChar bitN, UChar immR, UChar immS );
204extern ARM64RIL* ARM64RIL_R ( HReg );
205
206
207/* --------------- Reg or uimm6 operands --------------- */
208
209typedef
210 enum {
sewardj606c4ba2014-01-26 19:11:14 +0000211 ARM64ri6_I6=30, /* uimm6, 1 .. 63 only */
sewardjbbcf1882014-01-12 12:49:10 +0000212 ARM64ri6_R /* reg */
213 }
214 ARM64RI6Tag;
215
216typedef
217 struct {
218 ARM64RI6Tag tag;
219 union {
220 struct {
221 UInt imm6; /* 1 .. 63 */
222 } I6;
223 struct {
224 HReg reg;
225 } R;
226 } ARM64ri6;
227 }
228 ARM64RI6;
229
230extern ARM64RI6* ARM64RI6_I6 ( UInt imm6 );
231extern ARM64RI6* ARM64RI6_R ( HReg );
232
233
234/* --------------------- Instructions --------------------- */
235
236typedef
237 enum {
sewardj606c4ba2014-01-26 19:11:14 +0000238 ARM64lo_AND=40,
sewardjbbcf1882014-01-12 12:49:10 +0000239 ARM64lo_OR,
240 ARM64lo_XOR
241 }
242 ARM64LogicOp;
243
244typedef
245 enum {
sewardj606c4ba2014-01-26 19:11:14 +0000246 ARM64sh_SHL=50,
sewardjbbcf1882014-01-12 12:49:10 +0000247 ARM64sh_SHR,
248 ARM64sh_SAR
249 }
250 ARM64ShiftOp;
251
252typedef
253 enum {
sewardj606c4ba2014-01-26 19:11:14 +0000254 ARM64un_NEG=60,
sewardjbbcf1882014-01-12 12:49:10 +0000255 ARM64un_NOT,
256 ARM64un_CLZ,
257 }
258 ARM64UnaryOp;
259
260typedef
261 enum {
sewardj606c4ba2014-01-26 19:11:14 +0000262 ARM64mul_PLAIN=70, /* lo64(64 * 64) */
sewardjbbcf1882014-01-12 12:49:10 +0000263 ARM64mul_ZX, /* hi64(64 *u 64) */
264 ARM64mul_SX /* hi64(64 *s 64) */
265 }
266 ARM64MulOp;
267
268typedef
269 /* These characterise an integer-FP conversion, but don't imply any
270 particular direction. */
271 enum {
sewardj606c4ba2014-01-26 19:11:14 +0000272 ARM64cvt_F32_I32S=80,
sewardjbbcf1882014-01-12 12:49:10 +0000273 ARM64cvt_F64_I32S,
274 ARM64cvt_F32_I64S,
275 ARM64cvt_F64_I64S,
276 ARM64cvt_F32_I32U,
277 ARM64cvt_F64_I32U,
278 ARM64cvt_F32_I64U,
279 ARM64cvt_F64_I64U,
280 ARM64cvt_INVALID
281 }
282 ARM64CvtOp;
283
284typedef
285 enum {
sewardj606c4ba2014-01-26 19:11:14 +0000286 ARM64fpb_ADD=100,
sewardjbbcf1882014-01-12 12:49:10 +0000287 ARM64fpb_SUB,
288 ARM64fpb_MUL,
289 ARM64fpb_DIV,
290 ARM64fpb_INVALID
291 }
292 ARM64FpBinOp;
293
294typedef
295 enum {
sewardj606c4ba2014-01-26 19:11:14 +0000296 ARM64fpu_NEG=110,
sewardjbbcf1882014-01-12 12:49:10 +0000297 ARM64fpu_ABS,
298 ARM64fpu_SQRT,
299 ARM64fpu_RINT,
sewardj89cefe42015-02-24 12:21:01 +0000300 ARM64fpu_RECPX,
sewardjbbcf1882014-01-12 12:49:10 +0000301 ARM64fpu_INVALID
302 }
303 ARM64FpUnaryOp;
304
sewardj606c4ba2014-01-26 19:11:14 +0000305typedef
306 enum {
sewardj25523c42014-06-15 19:36:29 +0000307 ARM64vecb_ADD64x2=120, ARM64vecb_ADD32x4,
308 ARM64vecb_ADD16x8, ARM64vecb_ADD8x16,
309 ARM64vecb_SUB64x2, ARM64vecb_SUB32x4,
310 ARM64vecb_SUB16x8, ARM64vecb_SUB8x16,
311 ARM64vecb_MUL32x4,
312 ARM64vecb_MUL16x8, ARM64vecb_MUL8x16,
313 ARM64vecb_FADD64x2, ARM64vecb_FADD32x4,
314 ARM64vecb_FSUB64x2, ARM64vecb_FSUB32x4,
315 ARM64vecb_FMUL64x2, ARM64vecb_FMUL32x4,
316 ARM64vecb_FDIV64x2, ARM64vecb_FDIV32x4,
sewardj76927e62014-11-17 11:21:21 +0000317 ARM64vecb_FMAX64x2, ARM64vecb_FMAX32x4,
318 ARM64vecb_FMIN64x2, ARM64vecb_FMIN32x4,
sewardj25523c42014-06-15 19:36:29 +0000319 ARM64vecb_UMAX32x4,
320 ARM64vecb_UMAX16x8, ARM64vecb_UMAX8x16,
321 ARM64vecb_UMIN32x4,
322 ARM64vecb_UMIN16x8, ARM64vecb_UMIN8x16,
323 ARM64vecb_SMAX32x4,
324 ARM64vecb_SMAX16x8, ARM64vecb_SMAX8x16,
325 ARM64vecb_SMIN32x4,
326 ARM64vecb_SMIN16x8, ARM64vecb_SMIN8x16,
sewardjecde6972014-02-05 11:01:19 +0000327 ARM64vecb_AND,
328 ARM64vecb_ORR,
sewardje520bb32014-02-17 11:00:53 +0000329 ARM64vecb_XOR,
sewardj25523c42014-06-15 19:36:29 +0000330 ARM64vecb_CMEQ64x2, ARM64vecb_CMEQ32x4,
331 ARM64vecb_CMEQ16x8, ARM64vecb_CMEQ8x16,
332 ARM64vecb_CMHI64x2, ARM64vecb_CMHI32x4, /* >u */
333 ARM64vecb_CMHI16x8, ARM64vecb_CMHI8x16,
334 ARM64vecb_CMGT64x2, ARM64vecb_CMGT32x4, /* >s */
335 ARM64vecb_CMGT16x8, ARM64vecb_CMGT8x16,
336 ARM64vecb_FCMEQ64x2, ARM64vecb_FCMEQ32x4,
337 ARM64vecb_FCMGE64x2, ARM64vecb_FCMGE32x4,
338 ARM64vecb_FCMGT64x2, ARM64vecb_FCMGT32x4,
sewardj92d0ae32014-04-03 13:48:54 +0000339 ARM64vecb_TBL1,
sewardj25523c42014-06-15 19:36:29 +0000340 ARM64vecb_UZP164x2, ARM64vecb_UZP132x4,
341 ARM64vecb_UZP116x8, ARM64vecb_UZP18x16,
342 ARM64vecb_UZP264x2, ARM64vecb_UZP232x4,
343 ARM64vecb_UZP216x8, ARM64vecb_UZP28x16,
344 ARM64vecb_ZIP132x4, ARM64vecb_ZIP116x8,
345 ARM64vecb_ZIP18x16, ARM64vecb_ZIP232x4,
346 ARM64vecb_ZIP216x8, ARM64vecb_ZIP28x16,
sewardj168c8bd2014-06-25 13:05:23 +0000347 ARM64vecb_PMUL8x16,
sewardj31b5a952014-06-26 07:41:14 +0000348 ARM64vecb_PMULL8x8,
sewardj6f312d02014-06-28 12:21:37 +0000349 ARM64vecb_UMULL2DSS,
350 ARM64vecb_UMULL4SHH, ARM64vecb_UMULL8HBB,
351 ARM64vecb_SMULL2DSS,
352 ARM64vecb_SMULL4SHH, ARM64vecb_SMULL8HBB,
sewardj51d012a2014-07-21 09:19:50 +0000353 ARM64vecb_SQADD64x2, ARM64vecb_SQADD32x4,
354 ARM64vecb_SQADD16x8, ARM64vecb_SQADD8x16,
355 ARM64vecb_UQADD64x2, ARM64vecb_UQADD32x4,
356 ARM64vecb_UQADD16x8, ARM64vecb_UQADD8x16,
357 ARM64vecb_SQSUB64x2, ARM64vecb_SQSUB32x4,
358 ARM64vecb_SQSUB16x8, ARM64vecb_SQSUB8x16,
359 ARM64vecb_UQSUB64x2, ARM64vecb_UQSUB32x4,
360 ARM64vecb_UQSUB16x8, ARM64vecb_UQSUB8x16,
361 ARM64vecb_SQDMULL2DSS,
362 ARM64vecb_SQDMULL4SHH,
sewardj54ffa1d2014-07-22 09:27:49 +0000363 ARM64vecb_SQDMULH32x4,
364 ARM64vecb_SQDMULH16x8,
365 ARM64vecb_SQRDMULH32x4,
366 ARM64vecb_SQRDMULH16x8,
sewardj12972182014-08-04 08:09:47 +0000367 ARM64vecb_SQSHL64x2, ARM64vecb_SQSHL32x4,
368 ARM64vecb_SQSHL16x8, ARM64vecb_SQSHL8x16,
369 ARM64vecb_UQSHL64x2, ARM64vecb_UQSHL32x4,
370 ARM64vecb_UQSHL16x8, ARM64vecb_UQSHL8x16,
371 ARM64vecb_SQRSHL64x2, ARM64vecb_SQRSHL32x4,
372 ARM64vecb_SQRSHL16x8, ARM64vecb_SQRSHL8x16,
373 ARM64vecb_UQRSHL64x2, ARM64vecb_UQRSHL32x4,
374 ARM64vecb_UQRSHL16x8, ARM64vecb_UQRSHL8x16,
sewardja6b61f02014-08-17 18:32:14 +0000375 ARM64vecb_SSHL64x2, ARM64vecb_SSHL32x4,
376 ARM64vecb_SSHL16x8, ARM64vecb_SSHL8x16,
377 ARM64vecb_USHL64x2, ARM64vecb_USHL32x4,
378 ARM64vecb_USHL16x8, ARM64vecb_USHL8x16,
379 ARM64vecb_SRSHL64x2, ARM64vecb_SRSHL32x4,
380 ARM64vecb_SRSHL16x8, ARM64vecb_SRSHL8x16,
381 ARM64vecb_URSHL64x2, ARM64vecb_URSHL32x4,
382 ARM64vecb_URSHL16x8, ARM64vecb_URSHL8x16,
sewardj89cefe42015-02-24 12:21:01 +0000383 ARM64vecb_FRECPS64x2, ARM64vecb_FRECPS32x4,
384 ARM64vecb_FRSQRTS64x2, ARM64vecb_FRSQRTS32x4,
sewardj606c4ba2014-01-26 19:11:14 +0000385 ARM64vecb_INVALID
386 }
387 ARM64VecBinOp;
388
sewardjfab09142014-02-10 10:28:13 +0000389typedef
390 enum {
sewardjfc261d92014-08-24 20:36:14 +0000391 ARM64vecmo_SUQADD64x2=300, ARM64vecmo_SUQADD32x4,
sewardjf7003bc2014-08-18 12:28:02 +0000392 ARM64vecmo_SUQADD16x8, ARM64vecmo_SUQADD8x16,
393 ARM64vecmo_USQADD64x2, ARM64vecmo_USQADD32x4,
394 ARM64vecmo_USQADD16x8, ARM64vecmo_USQADD8x16,
395 ARM64vecmo_INVALID
396 }
397 ARM64VecModifyOp;
398
399typedef
400 enum {
sewardjfc261d92014-08-24 20:36:14 +0000401 ARM64vecu_FNEG64x2=350, ARM64vecu_FNEG32x4,
sewardj25523c42014-06-15 19:36:29 +0000402 ARM64vecu_FABS64x2, ARM64vecu_FABS32x4,
sewardje520bb32014-02-17 11:00:53 +0000403 ARM64vecu_NOT,
sewardj25523c42014-06-15 19:36:29 +0000404 ARM64vecu_ABS64x2, ARM64vecu_ABS32x4,
405 ARM64vecu_ABS16x8, ARM64vecu_ABS8x16,
sewardj2b6fd5e2014-06-19 14:21:37 +0000406 ARM64vecu_CLS32x4, ARM64vecu_CLS16x8, ARM64vecu_CLS8x16,
407 ARM64vecu_CLZ32x4, ARM64vecu_CLZ16x8, ARM64vecu_CLZ8x16,
408 ARM64vecu_CNT8x16,
sewardj715d1622014-06-26 12:39:05 +0000409 ARM64vecu_RBIT,
410 ARM64vecu_REV1616B,
sewardjdf9d6d52014-06-27 10:43:22 +0000411 ARM64vecu_REV3216B, ARM64vecu_REV328H,
412 ARM64vecu_REV6416B, ARM64vecu_REV648H, ARM64vecu_REV644S,
sewardjfc261d92014-08-24 20:36:14 +0000413 ARM64vecu_URECPE32x4,
414 ARM64vecu_URSQRTE32x4,
sewardj89cefe42015-02-24 12:21:01 +0000415 ARM64vecu_FRECPE64x2, ARM64vecu_FRECPE32x4,
416 ARM64vecu_FRSQRTE64x2, ARM64vecu_FRSQRTE32x4,
sewardj4b21c3d2015-04-06 19:34:03 +0000417 ARM64vecu_FSQRT64x2, ARM64vecu_FSQRT32x4,
sewardjfab09142014-02-10 10:28:13 +0000418 ARM64vecu_INVALID
419 }
420 ARM64VecUnaryOp;
421
sewardje520bb32014-02-17 11:00:53 +0000422typedef
423 enum {
sewardjfc261d92014-08-24 20:36:14 +0000424 ARM64vecshi_USHR64x2=400, ARM64vecshi_USHR32x4,
sewardja6b61f02014-08-17 18:32:14 +0000425 ARM64vecshi_USHR16x8, ARM64vecshi_USHR8x16,
426 ARM64vecshi_SSHR64x2, ARM64vecshi_SSHR32x4,
427 ARM64vecshi_SSHR16x8, ARM64vecshi_SSHR8x16,
428 ARM64vecshi_SHL64x2, ARM64vecshi_SHL32x4,
429 ARM64vecshi_SHL16x8, ARM64vecshi_SHL8x16,
sewardjecedd982014-08-11 14:02:47 +0000430 /* These narrowing shifts zero out the top half of the destination
431 register. */
sewardja6b61f02014-08-17 18:32:14 +0000432 ARM64vecshi_SQSHRN2SD, ARM64vecshi_SQSHRN4HS, ARM64vecshi_SQSHRN8BH,
433 ARM64vecshi_UQSHRN2SD, ARM64vecshi_UQSHRN4HS, ARM64vecshi_UQSHRN8BH,
434 ARM64vecshi_SQSHRUN2SD, ARM64vecshi_SQSHRUN4HS, ARM64vecshi_SQSHRUN8BH,
435 ARM64vecshi_SQRSHRN2SD, ARM64vecshi_SQRSHRN4HS, ARM64vecshi_SQRSHRN8BH,
436 ARM64vecshi_UQRSHRN2SD, ARM64vecshi_UQRSHRN4HS, ARM64vecshi_UQRSHRN8BH,
437 ARM64vecshi_SQRSHRUN2SD, ARM64vecshi_SQRSHRUN4HS, ARM64vecshi_SQRSHRUN8BH,
sewardja97dddf2014-08-14 22:26:52 +0000438 /* Saturating left shifts, of various flavours. */
sewardja6b61f02014-08-17 18:32:14 +0000439 ARM64vecshi_UQSHL64x2, ARM64vecshi_UQSHL32x4,
440 ARM64vecshi_UQSHL16x8, ARM64vecshi_UQSHL8x16,
441 ARM64vecshi_SQSHL64x2, ARM64vecshi_SQSHL32x4,
442 ARM64vecshi_SQSHL16x8, ARM64vecshi_SQSHL8x16,
443 ARM64vecshi_SQSHLU64x2, ARM64vecshi_SQSHLU32x4,
444 ARM64vecshi_SQSHLU16x8, ARM64vecshi_SQSHLU8x16,
445 ARM64vecshi_INVALID
sewardje520bb32014-02-17 11:00:53 +0000446 }
sewardja6b61f02014-08-17 18:32:14 +0000447 ARM64VecShiftImmOp;
sewardje520bb32014-02-17 11:00:53 +0000448
sewardjbbcf1882014-01-12 12:49:10 +0000449typedef
450 enum {
sewardjfc261d92014-08-24 20:36:14 +0000451 ARM64vecna_XTN=450,
sewardjecedd982014-08-11 14:02:47 +0000452 ARM64vecna_SQXTN,
453 ARM64vecna_UQXTN,
454 ARM64vecna_SQXTUN,
455 ARM64vecna_INVALID
456 }
457 ARM64VecNarrowOp;
458
459typedef
460 enum {
sewardjbbcf1882014-01-12 12:49:10 +0000461 /* baseline */
462 ARM64in_Arith=1220,
463 ARM64in_Cmp,
464 ARM64in_Logic,
465 ARM64in_Test,
466 ARM64in_Shift,
467 ARM64in_Unary,
468 ARM64in_MovI, /* int reg-reg move */
469 ARM64in_Imm64,
470 ARM64in_LdSt64,
471 ARM64in_LdSt32, /* w/ ZX loads */
472 ARM64in_LdSt16, /* w/ ZX loads */
473 ARM64in_LdSt8, /* w/ ZX loads */
474 ARM64in_XDirect, /* direct transfer to GA */
475 ARM64in_XIndir, /* indirect transfer to GA */
476 ARM64in_XAssisted, /* assisted transfer to GA */
477 ARM64in_CSel,
478 ARM64in_Call,
479 ARM64in_AddToSP, /* move SP by small, signed constant */
480 ARM64in_FromSP, /* move SP to integer register */
481 ARM64in_Mul,
sewardj7d009132014-02-20 17:43:38 +0000482 ARM64in_LdrEX,
483 ARM64in_StrEX,
Elliott Hughesed398002017-06-21 14:41:24 -0700484 ARM64in_CAS,
sewardj7d009132014-02-20 17:43:38 +0000485 ARM64in_MFence,
Elliott Hughesa0664b92017-04-18 17:46:52 -0700486 ARM64in_ClrEX,
sewardj606c4ba2014-01-26 19:11:14 +0000487 /* ARM64in_V*: scalar ops involving vector registers */
sewardj400d6b92015-03-30 09:01:51 +0000488 ARM64in_VLdStH, /* ld/st to/from low 16 bits of vec reg, imm offset */
489 ARM64in_VLdStS, /* ld/st to/from low 32 bits of vec reg, imm offset */
490 ARM64in_VLdStD, /* ld/st to/from low 64 bits of vec reg, imm offset */
491 ARM64in_VLdStQ, /* ld/st to/from all 128 bits of vec reg, no offset */
sewardjbbcf1882014-01-12 12:49:10 +0000492 ARM64in_VCvtI2F,
493 ARM64in_VCvtF2I,
sewardj400d6b92015-03-30 09:01:51 +0000494 ARM64in_VCvtSD, /* scalar 32 bit FP <--> 64 bit FP */
495 ARM64in_VCvtHS, /* scalar 16 bit FP <--> 32 bit FP */
496 ARM64in_VCvtHD, /* scalar 16 bit FP <--> 64 bit FP */
sewardjbbcf1882014-01-12 12:49:10 +0000497 ARM64in_VUnaryD,
498 ARM64in_VUnaryS,
499 ARM64in_VBinD,
500 ARM64in_VBinS,
501 ARM64in_VCmpD,
502 ARM64in_VCmpS,
sewardje23ec112014-11-15 16:07:14 +0000503 ARM64in_VFCSel,
sewardjbbcf1882014-01-12 12:49:10 +0000504 ARM64in_FPCR,
sewardj12972182014-08-04 08:09:47 +0000505 ARM64in_FPSR,
sewardj606c4ba2014-01-26 19:11:14 +0000506 /* ARM64in_V*V: vector ops on vector registers */
507 ARM64in_VBinV,
sewardjf7003bc2014-08-18 12:28:02 +0000508 ARM64in_VModifyV,
sewardjfab09142014-02-10 10:28:13 +0000509 ARM64in_VUnaryV,
sewardj606c4ba2014-01-26 19:11:14 +0000510 ARM64in_VNarrowV,
sewardje520bb32014-02-17 11:00:53 +0000511 ARM64in_VShiftImmV,
sewardjab33a7a2014-06-19 22:20:47 +0000512 ARM64in_VExtV,
sewardjbbcf1882014-01-12 12:49:10 +0000513 ARM64in_VImmQ,
514 ARM64in_VDfromX, /* Move an Xreg to a Dreg */
sewardj12972182014-08-04 08:09:47 +0000515 ARM64in_VQfromX, /* Move an Xreg to a Qreg lo64, and zero hi64 */
sewardjbbcf1882014-01-12 12:49:10 +0000516 ARM64in_VQfromXX, /* Move 2 Xregs to a Qreg */
517 ARM64in_VXfromQ, /* Move half a Qreg to an Xreg */
sewardj85fbb022014-06-12 13:16:01 +0000518 ARM64in_VXfromDorS, /* Move Dreg or Sreg(ZX) to an Xreg */
sewardjbbcf1882014-01-12 12:49:10 +0000519 ARM64in_VMov, /* vector reg-reg move, 16, 8 or 4 bytes */
520 /* infrastructure */
sewardj0ad37a92014-08-29 21:58:03 +0000521 ARM64in_EvCheck, /* Event check */
522 ARM64in_ProfInc /* 64-bit profile counter increment */
sewardjbbcf1882014-01-12 12:49:10 +0000523 }
524 ARM64InstrTag;
525
526/* Destinations are on the LEFT (first operand) */
527
528typedef
529 struct {
530 ARM64InstrTag tag;
531 union {
532 /* --- INTEGER INSTRUCTIONS --- */
533 /* 64 bit ADD/SUB reg, reg or uimm12<<{0,12} */
534 struct {
535 HReg dst;
536 HReg argL;
537 ARM64RIA* argR;
538 Bool isAdd;
539 } Arith;
540 /* 64 or 32 bit CMP reg, reg or aimm (SUB and set flags) */
541 struct {
542 HReg argL;
543 ARM64RIA* argR;
544 Bool is64;
545 } Cmp;
546 /* 64 bit AND/OR/XOR reg, reg or bitfield-immediate */
547 struct {
548 HReg dst;
549 HReg argL;
550 ARM64RIL* argR;
551 ARM64LogicOp op;
552 } Logic;
553 /* 64 bit TST reg, reg or bimm (AND and set flags) */
554 struct {
555 HReg argL;
556 ARM64RIL* argR;
557 } Test;
558 /* 64 bit SHL/SHR/SAR, 2nd arg is reg or imm */
559 struct {
560 HReg dst;
561 HReg argL;
562 ARM64RI6* argR;
563 ARM64ShiftOp op;
564 } Shift;
565 /* NOT/NEG/CLZ, 64 bit only */
566 struct {
567 HReg dst;
568 HReg src;
569 ARM64UnaryOp op;
570 } Unary;
571 /* MOV dst, src -- reg-reg move for integer registers */
572 struct {
573 HReg dst;
574 HReg src;
575 } MovI;
576 /* Pseudo-insn; make a 64-bit immediate */
577 struct {
578 HReg dst;
579 ULong imm64;
580 } Imm64;
581 /* 64-bit load or store */
582 struct {
583 Bool isLoad;
584 HReg rD;
585 ARM64AMode* amode;
586 } LdSt64;
587 /* zx-32-to-64-bit load, or 32-bit store */
588 struct {
589 Bool isLoad;
590 HReg rD;
591 ARM64AMode* amode;
592 } LdSt32;
593 /* zx-16-to-64-bit load, or 16-bit store */
594 struct {
595 Bool isLoad;
596 HReg rD;
597 ARM64AMode* amode;
598 } LdSt16;
599 /* zx-8-to-64-bit load, or 8-bit store */
600 struct {
601 Bool isLoad;
602 HReg rD;
603 ARM64AMode* amode;
604 } LdSt8;
605 /* Update the guest PC value, then exit requesting to chain
606 to it. May be conditional. Urr, use of Addr64 implicitly
607 assumes that wordsize(guest) == wordsize(host). */
608 struct {
609 Addr64 dstGA; /* next guest address */
610 ARM64AMode* amPC; /* amode in guest state for PC */
611 ARM64CondCode cond; /* can be ARM64cc_AL */
612 Bool toFastEP; /* chain to the slow or fast point? */
613 } XDirect;
614 /* Boring transfer to a guest address not known at JIT time.
615 Not chainable. May be conditional. */
616 struct {
617 HReg dstGA;
618 ARM64AMode* amPC;
619 ARM64CondCode cond; /* can be ARM64cc_AL */
620 } XIndir;
621 /* Assisted transfer to a guest address, most general case.
622 Not chainable. May be conditional. */
623 struct {
624 HReg dstGA;
625 ARM64AMode* amPC;
626 ARM64CondCode cond; /* can be ARM64cc_AL */
627 IRJumpKind jk;
628 } XAssisted;
629 /* CSEL: dst = if cond then argL else argR. cond may be anything. */
630 struct {
631 HReg dst;
632 HReg argL;
633 HReg argR;
634 ARM64CondCode cond;
635 } CSel;
636 /* Pseudo-insn. Call target (an absolute address), on given
637 condition (which could be ARM64cc_AL). */
638 struct {
639 RetLoc rloc; /* where the return value will be */
florian93a09742015-01-07 20:14:48 +0000640 Addr64 target;
sewardjbbcf1882014-01-12 12:49:10 +0000641 ARM64CondCode cond;
642 Int nArgRegs; /* # regs carrying args: 0 .. 8 */
643 } Call;
644 /* move SP by small, signed constant */
645 struct {
646 Int simm; /* needs to be 0 % 16 and in the range -4095
647 .. 4095 inclusive */
648 } AddToSP;
649 /* move SP to integer register */
650 struct {
651 HReg dst;
652 } FromSP;
653 /* Integer multiply, with 3 variants:
654 (PLAIN) lo64(64 * 64)
655 (ZX) hi64(64 *u 64)
656 (SX) hi64(64 *s 64)
657 */
658 struct {
659 HReg dst;
660 HReg argL;
661 HReg argR;
662 ARM64MulOp op;
663 } Mul;
sewardj7d009132014-02-20 17:43:38 +0000664 /* LDXR{,H,B} x2, [x4] */
665 struct {
666 Int szB; /* 1, 2, 4 or 8 */
667 } LdrEX;
668 /* STXR{,H,B} w0, x2, [x4] */
669 struct {
670 Int szB; /* 1, 2, 4 or 8 */
671 } StrEX;
Elliott Hughesed398002017-06-21 14:41:24 -0700672 /* x1 = CAS(x3(addr), x5(expected) -> x7(new)),
673 where x1[8*szB-1 : 0] == x5[8*szB-1 : 0] indicates success,
674 x1[8*szB-1 : 0] != x5[8*szB-1 : 0] indicates failure.
675 Uses x8 as scratch (but that's not allocatable).
676 Hence: RD x3, x5, x7; WR x1
677
678 (szB=8) mov x8, x5
679 (szB=4) and x8, x5, #0xFFFFFFFF
680 (szB=2) and x8, x5, #0xFFFF
681 (szB=1) and x8, x5, #0xFF
682 -- x8 is correctly zero-extended expected value
683 ldxr x1, [x3]
684 -- x1 is correctly zero-extended actual value
685 cmp x1, x8
686 bne after
687 -- if branch taken, failure; x1[[8*szB-1 : 0] holds old value
688 -- attempt to store
689 stxr w1, x7, [x3]
690 -- if store successful, x1==0, so the eor is "x1 := x5"
691 -- if store failed, x1==1, so the eor makes x1 != x5
692 eor x1, x5, x1
693 after:
694 */
695 struct {
696 Int szB; /* 1, 2, 4 or 8 */
697 } CAS;
sewardj7d009132014-02-20 17:43:38 +0000698 /* Mem fence. An insn which fences all loads and stores as
699 much as possible before continuing. On ARM64 we emit the
700 sequence "dsb sy ; dmb sy ; isb sy", which is probably
701 total nuclear overkill, but better safe than sorry. */
702 struct {
703 } MFence;
Elliott Hughesa0664b92017-04-18 17:46:52 -0700704 /* A CLREX instruction. */
705 struct {
706 } ClrEX;
sewardjbbcf1882014-01-12 12:49:10 +0000707 /* --- INSTRUCTIONS INVOLVING VECTOR REGISTERS --- */
sewardj400d6b92015-03-30 09:01:51 +0000708 /* ld/st to/from low 16 bits of vec reg, imm offset */
709 struct {
710 Bool isLoad;
711 HReg hD;
712 HReg rN;
713 UInt uimm12; /* 0 .. 8190 inclusive, 0 % 2 */
714 } VLdStH;
715 /* ld/st to/from low 32 bits of vec reg, imm offset */
sewardjbbcf1882014-01-12 12:49:10 +0000716 struct {
717 Bool isLoad;
718 HReg sD;
719 HReg rN;
720 UInt uimm12; /* 0 .. 16380 inclusive, 0 % 4 */
721 } VLdStS;
sewardj400d6b92015-03-30 09:01:51 +0000722 /* ld/st to/from low 64 bits of vec reg, imm offset */
sewardjbbcf1882014-01-12 12:49:10 +0000723 struct {
724 Bool isLoad;
725 HReg dD;
726 HReg rN;
727 UInt uimm12; /* 0 .. 32760 inclusive, 0 % 8 */
728 } VLdStD;
sewardj400d6b92015-03-30 09:01:51 +0000729 /* ld/st to/from all 128 bits of vec reg, no offset */
sewardjbbcf1882014-01-12 12:49:10 +0000730 struct {
731 Bool isLoad;
732 HReg rQ; // data
733 HReg rN; // address
734 } VLdStQ;
735 /* Scalar conversion of int to float. */
736 struct {
737 ARM64CvtOp how;
738 HReg rD; // dst, a D or S register
739 HReg rS; // src, a W or X register
740 } VCvtI2F;
741 /* Scalar conversion of float to int, w/ specified RM. */
742 struct {
743 ARM64CvtOp how;
744 HReg rD; // dst, a W or X register
745 HReg rS; // src, a D or S register
746 UChar armRM; // ARM encoded RM:
747 // 00=nearest, 01=+inf, 10=-inf, 11=zero
748 } VCvtF2I;
sewardj400d6b92015-03-30 09:01:51 +0000749 /* Convert between 32-bit and 64-bit FP values (both ways). (FCVT) */
sewardjbbcf1882014-01-12 12:49:10 +0000750 struct {
751 Bool sToD; /* True: F32->F64. False: F64->F32 */
752 HReg dst;
753 HReg src;
754 } VCvtSD;
sewardj400d6b92015-03-30 09:01:51 +0000755 /* Convert between 16-bit and 32-bit FP values (both ways). (FCVT) */
756 struct {
757 Bool hToS; /* True: F16->F32. False: F32->F16 */
758 HReg dst;
759 HReg src;
760 } VCvtHS;
761 /* Convert between 16-bit and 64-bit FP values (both ways). (FCVT) */
762 struct {
763 Bool hToD; /* True: F16->F64. False: F64->F16 */
764 HReg dst;
765 HReg src;
766 } VCvtHD;
sewardjbbcf1882014-01-12 12:49:10 +0000767 /* 64-bit FP unary */
768 struct {
769 ARM64FpUnaryOp op;
770 HReg dst;
771 HReg src;
772 } VUnaryD;
773 /* 32-bit FP unary */
774 struct {
775 ARM64FpUnaryOp op;
776 HReg dst;
777 HReg src;
778 } VUnaryS;
779 /* 64-bit FP binary arithmetic */
780 struct {
781 ARM64FpBinOp op;
782 HReg dst;
783 HReg argL;
784 HReg argR;
785 } VBinD;
786 /* 32-bit FP binary arithmetic */
787 struct {
788 ARM64FpBinOp op;
789 HReg dst;
790 HReg argL;
791 HReg argR;
792 } VBinS;
793 /* 64-bit FP compare */
794 struct {
795 HReg argL;
796 HReg argR;
797 } VCmpD;
798 /* 32-bit FP compare */
799 struct {
800 HReg argL;
801 HReg argR;
802 } VCmpS;
sewardje23ec112014-11-15 16:07:14 +0000803 /* 32- or 64-bit FP conditional select */
804 struct {
805 HReg dst;
806 HReg argL;
807 HReg argR;
808 ARM64CondCode cond;
809 Bool isD;
810 }
811 VFCSel;
sewardjbbcf1882014-01-12 12:49:10 +0000812 /* Move a 32-bit value to/from the FPCR */
813 struct {
814 Bool toFPCR;
815 HReg iReg;
816 } FPCR;
sewardj12972182014-08-04 08:09:47 +0000817 /* Move a 32-bit value to/from the FPSR */
818 struct {
819 Bool toFPSR;
820 HReg iReg;
821 } FPSR;
sewardj606c4ba2014-01-26 19:11:14 +0000822 /* binary vector operation on vector registers */
823 struct {
824 ARM64VecBinOp op;
825 HReg dst;
826 HReg argL;
827 HReg argR;
828 } VBinV;
sewardjf7003bc2014-08-18 12:28:02 +0000829 /* binary vector operation on vector registers.
830 Dst reg is also a src. */
831 struct {
832 ARM64VecModifyOp op;
833 HReg mod;
834 HReg arg;
835 } VModifyV;
sewardjfab09142014-02-10 10:28:13 +0000836 /* unary vector operation on vector registers */
837 struct {
838 ARM64VecUnaryOp op;
839 HReg dst;
840 HReg arg;
841 } VUnaryV;
sewardj606c4ba2014-01-26 19:11:14 +0000842 /* vector narrowing, Q -> Q. Result goes in the bottom half
sewardjecedd982014-08-11 14:02:47 +0000843 of dst and the top half is zeroed out. Iow one of the
844 XTN family. */
sewardj606c4ba2014-01-26 19:11:14 +0000845 struct {
sewardjecedd982014-08-11 14:02:47 +0000846 ARM64VecNarrowOp op;
847 UInt dszBlg2; // 0: 16to8_x8 1: 32to16_x4 2: 64to32_x2
848 HReg dst; // Q reg
849 HReg src; // Q reg
sewardj606c4ba2014-01-26 19:11:14 +0000850 } VNarrowV;
sewardja97dddf2014-08-14 22:26:52 +0000851 /* Vector shift by immediate. For left shifts, |amt| must be
852 >= 0 and < implied lane size of |op|. For right shifts,
853 |amt| must be > 0 and <= implied lane size of |op|. Shifts
854 beyond these ranges are not allowed. */
sewardje520bb32014-02-17 11:00:53 +0000855 struct {
sewardja6b61f02014-08-17 18:32:14 +0000856 ARM64VecShiftImmOp op;
857 HReg dst;
858 HReg src;
859 UInt amt;
sewardje520bb32014-02-17 11:00:53 +0000860 } VShiftImmV;
sewardjab33a7a2014-06-19 22:20:47 +0000861 struct {
862 HReg dst;
863 HReg srcLo;
864 HReg srcHi;
865 UInt amtB;
866 } VExtV;
sewardjbbcf1882014-01-12 12:49:10 +0000867 struct {
868 HReg rQ;
869 UShort imm; /* Same 1-bit-per-byte encoding as IR */
870 } VImmQ;
871 struct {
872 HReg rD;
873 HReg rX;
874 } VDfromX;
875 struct {
876 HReg rQ;
sewardj12972182014-08-04 08:09:47 +0000877 HReg rXlo;
878 } VQfromX;
879 struct {
880 HReg rQ;
sewardjbbcf1882014-01-12 12:49:10 +0000881 HReg rXhi;
882 HReg rXlo;
883 } VQfromXX;
884 struct {
885 HReg rX;
886 HReg rQ;
887 UInt laneNo; /* either 0 or 1 */
888 } VXfromQ;
sewardj85fbb022014-06-12 13:16:01 +0000889 struct {
890 HReg rX;
891 HReg rDorS;
892 Bool fromD;
893 } VXfromDorS;
sewardjbbcf1882014-01-12 12:49:10 +0000894 /* MOV dst, src -- reg-reg move for vector registers */
895 struct {
896 UInt szB; // 16=mov qD,qS; 8=mov dD,dS; 4=mov sD,sS
897 HReg dst;
898 HReg src;
899 } VMov;
900 struct {
901 ARM64AMode* amCounter;
902 ARM64AMode* amFailAddr;
903 } EvCheck;
sewardj0ad37a92014-08-29 21:58:03 +0000904 struct {
905 /* No fields. The address of the counter to inc is
906 installed later, post-translation, by patching it in,
907 as it is not known at translation time. */
908 } ProfInc;
sewardjbbcf1882014-01-12 12:49:10 +0000909 } ARM64in;
910 }
911 ARM64Instr;
912
sewardj633d9db2014-06-25 12:19:02 +0000913
sewardjbbcf1882014-01-12 12:49:10 +0000914extern ARM64Instr* ARM64Instr_Arith ( HReg, HReg, ARM64RIA*, Bool isAdd );
915extern ARM64Instr* ARM64Instr_Cmp ( HReg, ARM64RIA*, Bool is64 );
916extern ARM64Instr* ARM64Instr_Logic ( HReg, HReg, ARM64RIL*, ARM64LogicOp );
917extern ARM64Instr* ARM64Instr_Test ( HReg, ARM64RIL* );
918extern ARM64Instr* ARM64Instr_Shift ( HReg, HReg, ARM64RI6*, ARM64ShiftOp );
919extern ARM64Instr* ARM64Instr_Unary ( HReg, HReg, ARM64UnaryOp );
sewardjbbcf1882014-01-12 12:49:10 +0000920extern ARM64Instr* ARM64Instr_MovI ( HReg, HReg );
921extern ARM64Instr* ARM64Instr_Imm64 ( HReg, ULong );
922extern ARM64Instr* ARM64Instr_LdSt64 ( Bool isLoad, HReg, ARM64AMode* );
923extern ARM64Instr* ARM64Instr_LdSt32 ( Bool isLoad, HReg, ARM64AMode* );
924extern ARM64Instr* ARM64Instr_LdSt16 ( Bool isLoad, HReg, ARM64AMode* );
925extern ARM64Instr* ARM64Instr_LdSt8 ( Bool isLoad, HReg, ARM64AMode* );
sewardjbbcf1882014-01-12 12:49:10 +0000926extern ARM64Instr* ARM64Instr_XDirect ( Addr64 dstGA, ARM64AMode* amPC,
927 ARM64CondCode cond, Bool toFastEP );
928extern ARM64Instr* ARM64Instr_XIndir ( HReg dstGA, ARM64AMode* amPC,
929 ARM64CondCode cond );
930extern ARM64Instr* ARM64Instr_XAssisted ( HReg dstGA, ARM64AMode* amPC,
931 ARM64CondCode cond, IRJumpKind jk );
932extern ARM64Instr* ARM64Instr_CSel ( HReg dst, HReg argL, HReg argR,
933 ARM64CondCode cond );
florian93a09742015-01-07 20:14:48 +0000934extern ARM64Instr* ARM64Instr_Call ( ARM64CondCode, Addr64, Int nArgRegs,
sewardjbbcf1882014-01-12 12:49:10 +0000935 RetLoc rloc );
936extern ARM64Instr* ARM64Instr_AddToSP ( Int simm );
937extern ARM64Instr* ARM64Instr_FromSP ( HReg dst );
938extern ARM64Instr* ARM64Instr_Mul ( HReg dst, HReg argL, HReg argR,
939 ARM64MulOp op );
sewardj7d009132014-02-20 17:43:38 +0000940extern ARM64Instr* ARM64Instr_LdrEX ( Int szB );
941extern ARM64Instr* ARM64Instr_StrEX ( Int szB );
Elliott Hughesed398002017-06-21 14:41:24 -0700942extern ARM64Instr* ARM64Instr_CAS ( Int szB );
sewardj7d009132014-02-20 17:43:38 +0000943extern ARM64Instr* ARM64Instr_MFence ( void );
Elliott Hughesa0664b92017-04-18 17:46:52 -0700944extern ARM64Instr* ARM64Instr_ClrEX ( void );
sewardj400d6b92015-03-30 09:01:51 +0000945extern ARM64Instr* ARM64Instr_VLdStH ( Bool isLoad, HReg sD, HReg rN,
946 UInt uimm12 /* 0 .. 8190, 0 % 2 */ );
sewardjbbcf1882014-01-12 12:49:10 +0000947extern ARM64Instr* ARM64Instr_VLdStS ( Bool isLoad, HReg sD, HReg rN,
948 UInt uimm12 /* 0 .. 16380, 0 % 4 */ );
949extern ARM64Instr* ARM64Instr_VLdStD ( Bool isLoad, HReg dD, HReg rN,
950 UInt uimm12 /* 0 .. 32760, 0 % 8 */ );
951extern ARM64Instr* ARM64Instr_VLdStQ ( Bool isLoad, HReg rQ, HReg rN );
952extern ARM64Instr* ARM64Instr_VCvtI2F ( ARM64CvtOp how, HReg rD, HReg rS );
953extern ARM64Instr* ARM64Instr_VCvtF2I ( ARM64CvtOp how, HReg rD, HReg rS,
954 UChar armRM );
955extern ARM64Instr* ARM64Instr_VCvtSD ( Bool sToD, HReg dst, HReg src );
sewardj400d6b92015-03-30 09:01:51 +0000956extern ARM64Instr* ARM64Instr_VCvtHS ( Bool hToS, HReg dst, HReg src );
957extern ARM64Instr* ARM64Instr_VCvtHD ( Bool hToD, HReg dst, HReg src );
sewardjbbcf1882014-01-12 12:49:10 +0000958extern ARM64Instr* ARM64Instr_VUnaryD ( ARM64FpUnaryOp op, HReg dst, HReg src );
959extern ARM64Instr* ARM64Instr_VUnaryS ( ARM64FpUnaryOp op, HReg dst, HReg src );
960extern ARM64Instr* ARM64Instr_VBinD ( ARM64FpBinOp op, HReg, HReg, HReg );
961extern ARM64Instr* ARM64Instr_VBinS ( ARM64FpBinOp op, HReg, HReg, HReg );
962extern ARM64Instr* ARM64Instr_VCmpD ( HReg argL, HReg argR );
963extern ARM64Instr* ARM64Instr_VCmpS ( HReg argL, HReg argR );
sewardje23ec112014-11-15 16:07:14 +0000964extern ARM64Instr* ARM64Instr_VFCSel ( HReg dst, HReg argL, HReg argR,
965 ARM64CondCode cond, Bool isD );
sewardjbbcf1882014-01-12 12:49:10 +0000966extern ARM64Instr* ARM64Instr_FPCR ( Bool toFPCR, HReg iReg );
sewardj12972182014-08-04 08:09:47 +0000967extern ARM64Instr* ARM64Instr_FPSR ( Bool toFPSR, HReg iReg );
sewardj606c4ba2014-01-26 19:11:14 +0000968extern ARM64Instr* ARM64Instr_VBinV ( ARM64VecBinOp op, HReg, HReg, HReg );
sewardjf7003bc2014-08-18 12:28:02 +0000969extern ARM64Instr* ARM64Instr_VModifyV ( ARM64VecModifyOp, HReg, HReg );
sewardjfab09142014-02-10 10:28:13 +0000970extern ARM64Instr* ARM64Instr_VUnaryV ( ARM64VecUnaryOp op, HReg, HReg );
sewardjecedd982014-08-11 14:02:47 +0000971extern ARM64Instr* ARM64Instr_VNarrowV ( ARM64VecNarrowOp op, UInt dszBlg2,
972 HReg dst, HReg src );
sewardja6b61f02014-08-17 18:32:14 +0000973extern ARM64Instr* ARM64Instr_VShiftImmV ( ARM64VecShiftImmOp op,
sewardje520bb32014-02-17 11:00:53 +0000974 HReg dst, HReg src, UInt amt );
sewardjab33a7a2014-06-19 22:20:47 +0000975extern ARM64Instr* ARM64Instr_VExtV ( HReg dst,
976 HReg srcLo, HReg srcHi, UInt amtB );
sewardjbbcf1882014-01-12 12:49:10 +0000977extern ARM64Instr* ARM64Instr_VImmQ ( HReg, UShort );
978extern ARM64Instr* ARM64Instr_VDfromX ( HReg rD, HReg rX );
sewardj12972182014-08-04 08:09:47 +0000979extern ARM64Instr* ARM64Instr_VQfromX ( HReg rQ, HReg rXlo );
sewardjbbcf1882014-01-12 12:49:10 +0000980extern ARM64Instr* ARM64Instr_VQfromXX( HReg rQ, HReg rXhi, HReg rXlo );
981extern ARM64Instr* ARM64Instr_VXfromQ ( HReg rX, HReg rQ, UInt laneNo );
sewardj85fbb022014-06-12 13:16:01 +0000982extern ARM64Instr* ARM64Instr_VXfromDorS ( HReg rX, HReg rDorS, Bool fromD );
sewardjbbcf1882014-01-12 12:49:10 +0000983extern ARM64Instr* ARM64Instr_VMov ( UInt szB, HReg dst, HReg src );
984
985extern ARM64Instr* ARM64Instr_EvCheck ( ARM64AMode* amCounter,
986 ARM64AMode* amFailAddr );
sewardj0ad37a92014-08-29 21:58:03 +0000987extern ARM64Instr* ARM64Instr_ProfInc ( void );
sewardjbbcf1882014-01-12 12:49:10 +0000988
floriand8c64e02014-10-08 08:54:44 +0000989extern void ppARM64Instr ( const ARM64Instr* );
sewardjbbcf1882014-01-12 12:49:10 +0000990
991
992/* Some functions that insulate the register allocator from details
993 of the underlying instruction set. */
floriand8c64e02014-10-08 08:54:44 +0000994extern void getRegUsage_ARM64Instr ( HRegUsage*, const ARM64Instr*, Bool );
sewardjbbcf1882014-01-12 12:49:10 +0000995extern void mapRegs_ARM64Instr ( HRegRemap*, ARM64Instr*, Bool );
floriand8c64e02014-10-08 08:54:44 +0000996extern Bool isMove_ARM64Instr ( const ARM64Instr*, HReg*, HReg* );
sewardjbbcf1882014-01-12 12:49:10 +0000997extern Int emit_ARM64Instr ( /*MB_MOD*/Bool* is_profInc,
floriand8c64e02014-10-08 08:54:44 +0000998 UChar* buf, Int nbuf, const ARM64Instr* i,
sewardjbbcf1882014-01-12 12:49:10 +0000999 Bool mode64,
sewardj9b769162014-07-24 12:42:03 +00001000 VexEndness endness_host,
florian8462d112014-09-24 15:18:09 +00001001 const void* disp_cp_chain_me_to_slowEP,
1002 const void* disp_cp_chain_me_to_fastEP,
1003 const void* disp_cp_xindir,
1004 const void* disp_cp_xassisted );
sewardjbbcf1882014-01-12 12:49:10 +00001005
1006extern void genSpill_ARM64 ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
1007 HReg rreg, Int offset, Bool );
1008extern void genReload_ARM64 ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
1009 HReg rreg, Int offset, Bool );
1010
sewardja5b50222015-03-26 07:18:32 +00001011extern const RRegUniverse* getRRegUniverse_ARM64 ( void );
1012
floriancacba8e2014-12-15 18:58:07 +00001013extern HInstrArray* iselSB_ARM64 ( const IRSB*,
sewardjbbcf1882014-01-12 12:49:10 +00001014 VexArch,
floriand8c64e02014-10-08 08:54:44 +00001015 const VexArchInfo*,
1016 const VexAbiInfo*,
sewardjbbcf1882014-01-12 12:49:10 +00001017 Int offs_Host_EvC_Counter,
1018 Int offs_Host_EvC_FailAddr,
1019 Bool chainingAllowed,
1020 Bool addProfInc,
floriandcd6d232015-01-02 17:32:21 +00001021 Addr max_ga );
sewardjbbcf1882014-01-12 12:49:10 +00001022
1023/* How big is an event check? This is kind of a kludge because it
1024 depends on the offsets of host_EvC_FAILADDR and
1025 host_EvC_COUNTER. */
florian7ce2cc82015-01-10 16:10:58 +00001026extern Int evCheckSzB_ARM64 (void);
sewardjbbcf1882014-01-12 12:49:10 +00001027
1028/* Perform a chaining and unchaining of an XDirect jump. */
sewardj9b769162014-07-24 12:42:03 +00001029extern VexInvalRange chainXDirect_ARM64 ( VexEndness endness_host,
1030 void* place_to_chain,
florian7d6f81d2014-09-22 21:43:37 +00001031 const void* disp_cp_chain_me_EXPECTED,
1032 const void* place_to_jump_to );
sewardjbbcf1882014-01-12 12:49:10 +00001033
sewardj9b769162014-07-24 12:42:03 +00001034extern VexInvalRange unchainXDirect_ARM64 ( VexEndness endness_host,
1035 void* place_to_unchain,
florian7d6f81d2014-09-22 21:43:37 +00001036 const void* place_to_jump_to_EXPECTED,
1037 const void* disp_cp_chain_me );
sewardjc6acaa42014-02-19 17:42:59 +00001038
sewardj0ad37a92014-08-29 21:58:03 +00001039/* Patch the counter location into an existing ProfInc point. */
1040extern VexInvalRange patchProfInc_ARM64 ( VexEndness endness_host,
1041 void* place_to_patch,
florian7d6f81d2014-09-22 21:43:37 +00001042 const ULong* location_of_counter );
sewardjbbcf1882014-01-12 12:49:10 +00001043
1044
1045#endif /* ndef __VEX_HOST_ARM64_DEFS_H */
1046
1047/*---------------------------------------------------------------*/
1048/*--- end host_arm64_defs.h ---*/
1049/*---------------------------------------------------------------*/