1 /*---------------------------------------------------------------*/
2 /*--- begin host_arm_defs.h ---*/
3 /*---------------------------------------------------------------*/
4
5 /*
6 This file is part of Valgrind, a dynamic binary instrumentation
7 framework.
8
9 Copyright (C) 2004-2017 OpenWorks LLP
10 info@open-works.net
11
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation; either version 2 of the
15 License, or (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful, but
18 WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 02110-1301, USA.
26
27 The GNU General Public License is contained in the file COPYING.
28 */
29
30 #ifndef __VEX_HOST_ARM_DEFS_H
31 #define __VEX_HOST_ARM_DEFS_H
32
33 #include "libvex_basictypes.h"
34 #include "libvex.h" // VexArch
35 #include "host_generic_regs.h" // HReg
36
37 extern UInt arm_hwcaps;
38
39
40 /* --------- Registers. --------- */
41
42 #define ST_IN static inline
hregARM_R4(void)43 ST_IN HReg hregARM_R4 ( void ) { return mkHReg(False, HRcInt32, 4, 0); }
hregARM_R5(void)44 ST_IN HReg hregARM_R5 ( void ) { return mkHReg(False, HRcInt32, 5, 1); }
hregARM_R6(void)45 ST_IN HReg hregARM_R6 ( void ) { return mkHReg(False, HRcInt32, 6, 2); }
hregARM_R7(void)46 ST_IN HReg hregARM_R7 ( void ) { return mkHReg(False, HRcInt32, 7, 3); }
hregARM_R10(void)47 ST_IN HReg hregARM_R10 ( void ) { return mkHReg(False, HRcInt32, 10, 4); }
hregARM_R11(void)48 ST_IN HReg hregARM_R11 ( void ) { return mkHReg(False, HRcInt32, 11, 5); }
49
hregARM_R0(void)50 ST_IN HReg hregARM_R0 ( void ) { return mkHReg(False, HRcInt32, 0, 6); }
hregARM_R1(void)51 ST_IN HReg hregARM_R1 ( void ) { return mkHReg(False, HRcInt32, 1, 7); }
hregARM_R2(void)52 ST_IN HReg hregARM_R2 ( void ) { return mkHReg(False, HRcInt32, 2, 8); }
hregARM_R3(void)53 ST_IN HReg hregARM_R3 ( void ) { return mkHReg(False, HRcInt32, 3, 9); }
hregARM_R9(void)54 ST_IN HReg hregARM_R9 ( void ) { return mkHReg(False, HRcInt32, 9, 10); }
55
hregARM_D8(void)56 ST_IN HReg hregARM_D8 ( void ) { return mkHReg(False, HRcFlt64, 8, 11); }
hregARM_D9(void)57 ST_IN HReg hregARM_D9 ( void ) { return mkHReg(False, HRcFlt64, 9, 12); }
hregARM_D10(void)58 ST_IN HReg hregARM_D10 ( void ) { return mkHReg(False, HRcFlt64, 10, 13); }
hregARM_D11(void)59 ST_IN HReg hregARM_D11 ( void ) { return mkHReg(False, HRcFlt64, 11, 14); }
hregARM_D12(void)60 ST_IN HReg hregARM_D12 ( void ) { return mkHReg(False, HRcFlt64, 12, 15); }
61
hregARM_S26(void)62 ST_IN HReg hregARM_S26 ( void ) { return mkHReg(False, HRcFlt32, 26, 16); }
hregARM_S27(void)63 ST_IN HReg hregARM_S27 ( void ) { return mkHReg(False, HRcFlt32, 27, 17); }
hregARM_S28(void)64 ST_IN HReg hregARM_S28 ( void ) { return mkHReg(False, HRcFlt32, 28, 18); }
hregARM_S29(void)65 ST_IN HReg hregARM_S29 ( void ) { return mkHReg(False, HRcFlt32, 29, 19); }
hregARM_S30(void)66 ST_IN HReg hregARM_S30 ( void ) { return mkHReg(False, HRcFlt32, 30, 20); }
67
hregARM_Q8(void)68 ST_IN HReg hregARM_Q8 ( void ) { return mkHReg(False, HRcVec128, 8, 21); }
hregARM_Q9(void)69 ST_IN HReg hregARM_Q9 ( void ) { return mkHReg(False, HRcVec128, 9, 22); }
hregARM_Q10(void)70 ST_IN HReg hregARM_Q10 ( void ) { return mkHReg(False, HRcVec128, 10, 23); }
hregARM_Q11(void)71 ST_IN HReg hregARM_Q11 ( void ) { return mkHReg(False, HRcVec128, 11, 24); }
hregARM_Q12(void)72 ST_IN HReg hregARM_Q12 ( void ) { return mkHReg(False, HRcVec128, 12, 25); }
73
hregARM_R8(void)74 ST_IN HReg hregARM_R8 ( void ) { return mkHReg(False, HRcInt32, 8, 26); }
hregARM_R12(void)75 ST_IN HReg hregARM_R12 ( void ) { return mkHReg(False, HRcInt32, 12, 27); }
hregARM_R13(void)76 ST_IN HReg hregARM_R13 ( void ) { return mkHReg(False, HRcInt32, 13, 28); }
hregARM_R14(void)77 ST_IN HReg hregARM_R14 ( void ) { return mkHReg(False, HRcInt32, 14, 29); }
hregARM_R15(void)78 ST_IN HReg hregARM_R15 ( void ) { return mkHReg(False, HRcInt32, 15, 30); }
hregARM_Q13(void)79 ST_IN HReg hregARM_Q13 ( void ) { return mkHReg(False, HRcVec128, 13, 31); }
hregARM_Q14(void)80 ST_IN HReg hregARM_Q14 ( void ) { return mkHReg(False, HRcVec128, 14, 32); }
hregARM_Q15(void)81 ST_IN HReg hregARM_Q15 ( void ) { return mkHReg(False, HRcVec128, 15, 33); }
82 #undef ST_IN
83
84 extern void ppHRegARM ( HReg );
85
86 /* Number of registers used arg passing in function calls */
87 #define ARM_N_ARGREGS 4 /* r0, r1, r2, r3 */
88
89
90 /* --------- Condition codes. --------- */
91
92 typedef
93 enum {
94 ARMcc_EQ = 0, /* equal : Z=1 */
95 ARMcc_NE = 1, /* not equal : Z=0 */
96
97 ARMcc_HS = 2, /* >=u (higher or same) : C=1 */
98 ARMcc_LO = 3, /* <u (lower) : C=0 */
99
100 ARMcc_MI = 4, /* minus (negative) : N=1 */
101 ARMcc_PL = 5, /* plus (zero or +ve) : N=0 */
102
103 ARMcc_VS = 6, /* overflow : V=1 */
104 ARMcc_VC = 7, /* no overflow : V=0 */
105
106 ARMcc_HI = 8, /* >u (higher) : C=1 && Z=0 */
107 ARMcc_LS = 9, /* <=u (lower or same) : C=0 || Z=1 */
108
109 ARMcc_GE = 10, /* >=s (signed greater or equal) : N=V */
110 ARMcc_LT = 11, /* <s (signed less than) : N!=V */
111
112 ARMcc_GT = 12, /* >s (signed greater) : Z=0 && N=V */
113 ARMcc_LE = 13, /* <=s (signed less or equal) : Z=1 || N!=V */
114
115 ARMcc_AL = 14, /* always (unconditional) */
116 ARMcc_NV = 15 /* never (basically undefined meaning), deprecated */
117 }
118 ARMCondCode;
119
120 extern const HChar* showARMCondCode ( ARMCondCode );
121
122
123
124 /* --------- Memory address expressions (amodes). --------- */
125
126 /* --- Addressing Mode 1 --- */
127 typedef
128 enum {
129 ARMam1_RI=1, /* reg +/- imm12 */
130 ARMam1_RRS /* reg1 + (reg2 << 0, 1 2 or 3) */
131 }
132 ARMAMode1Tag;
133
134 typedef
135 struct {
136 ARMAMode1Tag tag;
137 union {
138 struct {
139 HReg reg;
140 Int simm13; /* -4095 .. +4095 */
141 } RI;
142 struct {
143 HReg base;
144 HReg index;
145 UInt shift; /* 0, 1 2 or 3 */
146 } RRS;
147 } ARMam1;
148 }
149 ARMAMode1;
150
151 extern ARMAMode1* ARMAMode1_RI ( HReg reg, Int simm13 );
152 extern ARMAMode1* ARMAMode1_RRS ( HReg base, HReg index, UInt shift );
153
154 extern void ppARMAMode1 ( ARMAMode1* );
155
156
157 /* --- Addressing Mode 2 --- */
158 typedef
159 enum {
160 ARMam2_RI=3, /* reg +/- imm8 */
161 ARMam2_RR /* reg1 + reg2 */
162 }
163 ARMAMode2Tag;
164
165 typedef
166 struct {
167 ARMAMode2Tag tag;
168 union {
169 struct {
170 HReg reg;
171 Int simm9; /* -255 .. 255 */
172 } RI;
173 struct {
174 HReg base;
175 HReg index;
176 } RR;
177 } ARMam2;
178 }
179 ARMAMode2;
180
181 extern ARMAMode2* ARMAMode2_RI ( HReg reg, Int simm9 );
182 extern ARMAMode2* ARMAMode2_RR ( HReg base, HReg index );
183
184 extern void ppARMAMode2 ( ARMAMode2* );
185
186
187 /* --- Addressing Mode suitable for VFP --- */
188 /* The simm11 is encoded as 8 bits + 1 sign bit,
189 so can only be 0 % 4. */
190 typedef
191 struct {
192 HReg reg;
193 Int simm11; /* -1020, -1016 .. 1016, 1020 */
194 }
195 ARMAModeV;
196
197 extern ARMAModeV* mkARMAModeV ( HReg reg, Int simm11 );
198
199 extern void ppARMAModeV ( ARMAModeV* );
200
201 /* --- Addressing Mode suitable for Neon --- */
202 typedef
203 enum {
204 ARMamN_R=5,
205 ARMamN_RR
206 /* ... */
207 }
208 ARMAModeNTag;
209
210 typedef
211 struct {
212 ARMAModeNTag tag;
213 union {
214 struct {
215 HReg rN;
216 HReg rM;
217 } RR;
218 struct {
219 HReg rN;
220 } R;
221 /* ... */
222 } ARMamN;
223 }
224 ARMAModeN;
225
226 extern ARMAModeN* mkARMAModeN_RR ( HReg, HReg );
227 extern ARMAModeN* mkARMAModeN_R ( HReg );
228 extern void ppARMAModeN ( ARMAModeN* );
229
230 /* --------- Reg or imm-8x4 operands --------- */
231 /* a.k.a (a very restricted form of) Shifter Operand,
232 in the ARM parlance. */
233
234 typedef
235 enum {
236 ARMri84_I84=7, /* imm8 `ror` (2 * imm4) */
237 ARMri84_R /* reg */
238 }
239 ARMRI84Tag;
240
241 typedef
242 struct {
243 ARMRI84Tag tag;
244 union {
245 struct {
246 UShort imm8;
247 UShort imm4;
248 } I84;
249 struct {
250 HReg reg;
251 } R;
252 } ARMri84;
253 }
254 ARMRI84;
255
256 extern ARMRI84* ARMRI84_I84 ( UShort imm8, UShort imm4 );
257 extern ARMRI84* ARMRI84_R ( HReg );
258
259 extern void ppARMRI84 ( ARMRI84* );
260
261
262 /* --------- Reg or imm5 operands --------- */
263 typedef
264 enum {
265 ARMri5_I5=9, /* imm5, 1 .. 31 only (no zero!) */
266 ARMri5_R /* reg */
267 }
268 ARMRI5Tag;
269
270 typedef
271 struct {
272 ARMRI5Tag tag;
273 union {
274 struct {
275 UInt imm5;
276 } I5;
277 struct {
278 HReg reg;
279 } R;
280 } ARMri5;
281 }
282 ARMRI5;
283
284 extern ARMRI5* ARMRI5_I5 ( UInt imm5 );
285 extern ARMRI5* ARMRI5_R ( HReg );
286
287 extern void ppARMRI5 ( ARMRI5* );
288
289 /* -------- Neon Immediate operand -------- */
290
291 /* imm8 = abcdefgh, B = NOT(b);
292
293 type | value (64bit binary)
294 -----+-------------------------------------------------------------------------
295 0 | 00000000 00000000 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh
296 1 | 00000000 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh 00000000
297 2 | 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh 00000000 00000000
298 3 | abcdefgh 00000000 00000000 00000000 abcdefgh 00000000 00000000 00000000
299 4 | 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh
300 5 | abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000
301 6 | abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh
302 7 | 00000000 00000000 abcdefgh 11111111 00000000 00000000 abcdefgh 11111111
303 8 | 00000000 abcdefgh 11111111 11111111 00000000 abcdefgh 11111111 11111111
304 9 | aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
305 10 | aBbbbbbc defgh000 00000000 00000000 aBbbbbbc defgh000 00000000 00000000
306 -----+-------------------------------------------------------------------------
307
308 Type 10 is:
309 (-1)^S * 2^exp * mantissa
310 where S = a, exp = UInt(B:c:d) - 3, mantissa = (16 + UInt(e:f:g:h)) / 16
311 */
312
313 typedef
314 struct {
315 UInt type;
316 UInt imm8;
317 }
318 ARMNImm;
319
320 extern ARMNImm* ARMNImm_TI ( UInt type, UInt imm8 );
321 extern ULong ARMNImm_to_Imm64 ( ARMNImm* );
322 extern ARMNImm* Imm64_to_ARMNImm ( ULong );
323
324 extern void ppARMNImm ( ARMNImm* );
325
326 /* ------ Neon Register or Scalar Operand ------ */
327
328 typedef
329 enum {
330 ARMNRS_Reg=11,
331 ARMNRS_Scalar
332 }
333 ARMNRS_tag;
334
335 typedef
336 struct {
337 ARMNRS_tag tag;
338 HReg reg;
339 UInt index;
340 }
341 ARMNRS;
342
343 extern ARMNRS* mkARMNRS(ARMNRS_tag, HReg reg, UInt index);
344 extern void ppARMNRS ( ARMNRS* );
345
346 /* --------- Instructions. --------- */
347
348 /* --------- */
349 typedef
350 enum {
351 ARMalu_ADD=20, /* plain 32-bit add */
352 ARMalu_ADDS, /* 32-bit add, and set the flags */
353 ARMalu_ADC, /* 32-bit add with carry */
354 ARMalu_SUB, /* plain 32-bit subtract */
355 ARMalu_SUBS, /* 32-bit subtract, and set the flags */
356 ARMalu_SBC, /* 32-bit subtract with carry */
357 ARMalu_AND,
358 ARMalu_BIC,
359 ARMalu_OR,
360 ARMalu_XOR
361 }
362 ARMAluOp;
363
364 extern const HChar* showARMAluOp ( ARMAluOp op );
365
366
367 typedef
368 enum {
369 ARMsh_SHL=40,
370 ARMsh_SHR,
371 ARMsh_SAR
372 }
373 ARMShiftOp;
374
375 extern const HChar* showARMShiftOp ( ARMShiftOp op );
376
377
378 typedef
379 enum {
380 ARMun_NEG=50,
381 ARMun_NOT,
382 ARMun_CLZ
383 }
384 ARMUnaryOp;
385
386 extern const HChar* showARMUnaryOp ( ARMUnaryOp op );
387
388
389 typedef
390 enum {
391 ARMmul_PLAIN=60,
392 ARMmul_ZX,
393 ARMmul_SX
394 }
395 ARMMulOp;
396
397 extern const HChar* showARMMulOp ( ARMMulOp op );
398
399
400 typedef
401 enum {
402 ARMvfp_ADD=70,
403 ARMvfp_SUB,
404 ARMvfp_MUL,
405 ARMvfp_DIV
406 }
407 ARMVfpOp;
408
409 extern const HChar* showARMVfpOp ( ARMVfpOp op );
410
411
412 typedef
413 enum {
414 ARMvfpu_COPY=80,
415 ARMvfpu_NEG,
416 ARMvfpu_ABS,
417 ARMvfpu_SQRT
418 }
419 ARMVfpUnaryOp;
420
421 extern const HChar* showARMVfpUnaryOp ( ARMVfpUnaryOp op );
422
423 typedef
424 enum {
425 ARMneon_VAND=90,
426 ARMneon_VORR,
427 ARMneon_VXOR,
428 ARMneon_VADD,
429 ARMneon_VADDFP,
430 ARMneon_VRHADDS,
431 ARMneon_VRHADDU,
432 ARMneon_VPADDFP,
433 ARMneon_VABDFP,
434 ARMneon_VSUB,
435 ARMneon_VSUBFP,
436 ARMneon_VMAXU,
437 ARMneon_VMAXS,
438 ARMneon_VMAXF,
439 ARMneon_VMINU,
440 ARMneon_VMINS,
441 ARMneon_VMINF,
442 ARMneon_VQADDU,
443 ARMneon_VQADDS,
444 ARMneon_VQSUBU,
445 ARMneon_VQSUBS,
446 ARMneon_VCGTU,
447 ARMneon_VCGTS,
448 ARMneon_VCGEU,
449 ARMneon_VCGES,
450 ARMneon_VCGTF,
451 ARMneon_VCGEF,
452 ARMneon_VCEQ,
453 ARMneon_VCEQF,
454 ARMneon_VEXT,
455 ARMneon_VMUL,
456 ARMneon_VMULFP,
457 ARMneon_VMULLU,
458 ARMneon_VMULLS,
459 ARMneon_VMULP,
460 ARMneon_VMULLP,
461 ARMneon_VQDMULH,
462 ARMneon_VQRDMULH,
463 ARMneon_VPADD,
464 ARMneon_VPMINU,
465 ARMneon_VPMINS,
466 ARMneon_VPMINF,
467 ARMneon_VPMAXU,
468 ARMneon_VPMAXS,
469 ARMneon_VPMAXF,
470 ARMneon_VTBL,
471 ARMneon_VQDMULL,
472 ARMneon_VRECPS,
473 ARMneon_VRSQRTS,
474 ARMneon_INVALID
475 /* ... */
476 }
477 ARMNeonBinOp;
478
479 typedef
480 enum {
481 ARMneon_VSHL=150,
482 ARMneon_VSAL, /* Yah, not SAR but SAL */
483 ARMneon_VQSHL,
484 ARMneon_VQSAL
485 }
486 ARMNeonShiftOp;
487
488 typedef
489 enum {
490 ARMneon_COPY=160,
491 ARMneon_COPYLU,
492 ARMneon_COPYLS,
493 ARMneon_COPYN,
494 ARMneon_COPYQNSS,
495 ARMneon_COPYQNUS,
496 ARMneon_COPYQNUU,
497 ARMneon_NOT,
498 ARMneon_EQZ,
499 ARMneon_DUP,
500 ARMneon_PADDLS,
501 ARMneon_PADDLU,
502 ARMneon_CNT,
503 ARMneon_CLZ,
504 ARMneon_CLS,
505 ARMneon_VCVTxFPxINT,
506 ARMneon_VQSHLNSS,
507 ARMneon_VQSHLNUU,
508 ARMneon_VQSHLNUS,
509 ARMneon_VCVTFtoU,
510 ARMneon_VCVTFtoS,
511 ARMneon_VCVTUtoF,
512 ARMneon_VCVTStoF,
513 ARMneon_VCVTFtoFixedU,
514 ARMneon_VCVTFtoFixedS,
515 ARMneon_VCVTFixedUtoF,
516 ARMneon_VCVTFixedStoF,
517 ARMneon_VCVTF16toF32,
518 ARMneon_VCVTF32toF16,
519 ARMneon_REV16,
520 ARMneon_REV32,
521 ARMneon_REV64,
522 ARMneon_ABS,
523 ARMneon_VNEGF,
524 ARMneon_VRECIP,
525 ARMneon_VRECIPF,
526 ARMneon_VABSFP,
527 ARMneon_VRSQRTEFP,
528 ARMneon_VRSQRTE
529 /* ... */
530 }
531 ARMNeonUnOp;
532
533 typedef
534 enum {
535 ARMneon_SETELEM=200,
536 ARMneon_GETELEMU,
537 ARMneon_GETELEMS,
538 ARMneon_VDUP,
539 }
540 ARMNeonUnOpS;
541
542 typedef
543 enum {
544 ARMneon_TRN=210,
545 ARMneon_ZIP,
546 ARMneon_UZP
547 /* ... */
548 }
549 ARMNeonDualOp;
550
551 extern const HChar* showARMNeonBinOp ( ARMNeonBinOp op );
552 extern const HChar* showARMNeonUnOp ( ARMNeonUnOp op );
553 extern const HChar* showARMNeonUnOpS ( ARMNeonUnOpS op );
554 extern const HChar* showARMNeonShiftOp ( ARMNeonShiftOp op );
555 extern const HChar* showARMNeonDualOp ( ARMNeonDualOp op );
556 extern const HChar* showARMNeonBinOpDataType ( ARMNeonBinOp op );
557 extern const HChar* showARMNeonUnOpDataType ( ARMNeonUnOp op );
558 extern const HChar* showARMNeonUnOpSDataType ( ARMNeonUnOpS op );
559 extern const HChar* showARMNeonShiftOpDataType ( ARMNeonShiftOp op );
560 extern const HChar* showARMNeonDualOpDataType ( ARMNeonDualOp op );
561
562 typedef
563 enum {
564 /* baseline */
565 ARMin_Alu=220,
566 ARMin_Shift,
567 ARMin_Unary,
568 ARMin_CmpOrTst,
569 ARMin_Mov,
570 ARMin_Imm32,
571 ARMin_LdSt32,
572 ARMin_LdSt16,
573 ARMin_LdSt8U,
574 ARMin_Ld8S,
575 ARMin_XDirect, /* direct transfer to GA */
576 ARMin_XIndir, /* indirect transfer to GA */
577 ARMin_XAssisted, /* assisted transfer to GA */
578 ARMin_CMov,
579 ARMin_Call,
580 ARMin_Mul,
581 ARMin_LdrEX,
582 ARMin_StrEX,
583 /* vfp */
584 ARMin_VLdStD,
585 ARMin_VLdStS,
586 ARMin_VAluD,
587 ARMin_VAluS,
588 ARMin_VUnaryD,
589 ARMin_VUnaryS,
590 ARMin_VCmpD,
591 ARMin_VCMovD,
592 ARMin_VCMovS,
593 ARMin_VCvtSD,
594 ARMin_VXferQ,
595 ARMin_VXferD,
596 ARMin_VXferS,
597 ARMin_VCvtID,
598 ARMin_VRIntR,
599 ARMin_VMinMaxNum,
600 ARMin_FPSCR,
601 ARMin_MFence,
602 ARMin_CLREX,
603 /* Neon */
604 ARMin_NLdStQ,
605 ARMin_NLdStD,
606 ARMin_NUnary,
607 ARMin_NUnaryS,
608 ARMin_NDual,
609 ARMin_NBinary,
610 ARMin_NBinaryS,
611 ARMin_NShift,
612 ARMin_NShl64, // special case 64-bit shift of Dreg by immediate
613 ARMin_NeonImm,
614 ARMin_NCMovQ,
615 /* This is not a NEON instruction. Actually there is no corresponding
616 instruction in ARM instruction set at all. We need this one to
617 generate spill/reload of 128-bit registers since current register
618 allocator demands them to consist of no more than two instructions.
619 We will split this instruction into 2 or 3 ARM instructions on the
620 emiting phase.
621 NOTE: source and destination registers should be different! */
622 ARMin_Add32,
623 ARMin_EvCheck, /* Event check */
624 ARMin_ProfInc /* 64-bit profile counter increment */
625 }
626 ARMInstrTag;
627
628 /* Destinations are on the LEFT (first operand) */
629
630 typedef
631 struct {
632 ARMInstrTag tag;
633 union {
634 /* ADD/SUB/AND/OR/XOR, vanilla ALU op */
635 struct {
636 ARMAluOp op;
637 HReg dst;
638 HReg argL;
639 ARMRI84* argR;
640 } Alu;
641 /* SHL/SHR/SAR, 2nd arg is reg or imm */
642 struct {
643 ARMShiftOp op;
644 HReg dst;
645 HReg argL;
646 ARMRI5* argR;
647 } Shift;
648 /* NOT/NEG/CLZ */
649 struct {
650 ARMUnaryOp op;
651 HReg dst;
652 HReg src;
653 } Unary;
654 /* CMP/TST; subtract/and, discard result, set NZCV */
655 struct {
656 Bool isCmp;
657 HReg argL;
658 ARMRI84* argR;
659 } CmpOrTst;
660 /* MOV dst, src -- reg-reg (or reg-imm8x4) move */
661 struct {
662 HReg dst;
663 ARMRI84* src;
664 } Mov;
665 /* Pseudo-insn; make a 32-bit immediate */
666 struct {
667 HReg dst;
668 UInt imm32;
669 } Imm32;
670 /* 32-bit load or store, may be conditional */
671 struct {
672 ARMCondCode cc; /* ARMcc_NV is not allowed */
673 Bool isLoad;
674 HReg rD;
675 ARMAMode1* amode;
676 } LdSt32;
677 /* 16-bit load or store, may be conditional */
678 struct {
679 ARMCondCode cc; /* ARMcc_NV is not allowed */
680 Bool isLoad;
681 Bool signedLoad;
682 HReg rD;
683 ARMAMode2* amode;
684 } LdSt16;
685 /* 8-bit (unsigned) load or store, may be conditional */
686 struct {
687 ARMCondCode cc; /* ARMcc_NV is not allowed */
688 Bool isLoad;
689 HReg rD;
690 ARMAMode1* amode;
691 } LdSt8U;
692 /* 8-bit signed load, may be conditional */
693 struct {
694 ARMCondCode cc; /* ARMcc_NV is not allowed */
695 HReg rD;
696 ARMAMode2* amode;
697 } Ld8S;
698 /* Update the guest R15T value, then exit requesting to chain
699 to it. May be conditional. Urr, use of Addr32 implicitly
700 assumes that wordsize(guest) == wordsize(host). */
701 struct {
702 Addr32 dstGA; /* next guest address */
703 ARMAMode1* amR15T; /* amode in guest state for R15T */
704 ARMCondCode cond; /* can be ARMcc_AL */
705 Bool toFastEP; /* chain to the slow or fast point? */
706 } XDirect;
707 /* Boring transfer to a guest address not known at JIT time.
708 Not chainable. May be conditional. */
709 struct {
710 HReg dstGA;
711 ARMAMode1* amR15T;
712 ARMCondCode cond; /* can be ARMcc_AL */
713 } XIndir;
714 /* Assisted transfer to a guest address, most general case.
715 Not chainable. May be conditional. */
716 struct {
717 HReg dstGA;
718 ARMAMode1* amR15T;
719 ARMCondCode cond; /* can be ARMcc_AL */
720 IRJumpKind jk;
721 } XAssisted;
722 /* Mov src to dst on the given condition, which may not
723 be ARMcc_AL. */
724 struct {
725 ARMCondCode cond;
726 HReg dst;
727 ARMRI84* src;
728 } CMov;
729 /* Pseudo-insn. Call target (an absolute address), on given
730 condition (which could be ARMcc_AL). */
731 struct {
732 ARMCondCode cond;
733 Addr32 target;
734 Int nArgRegs; /* # regs carrying args: 0 .. 4 */
735 RetLoc rloc; /* where the return value will be */
736 } Call;
737 /* (PLAIN) 32 * 32 -> 32: r0 = r2 * r3
738 (ZX) 32 *u 32 -> 64: r1:r0 = r2 *u r3
739 (SX) 32 *s 32 -> 64: r1:r0 = r2 *s r3
740 Why hardwired registers? Because the ARM ARM specifies
741 (eg for straight MUL) the result (Rd) and the left arg (Rm)
742 may not be the same register. That's not a constraint we
743 can enforce in the register allocator (without mucho extra
744 complexity). Hence hardwire it. At least using caller-saves
745 registers, which are less likely to be in use. */
746 struct {
747 ARMMulOp op;
748 } Mul;
749 /* LDREX{,H,B} r2, [r4] and
750 LDREXD r2, r3, [r4] (on LE hosts, transferred value is r3:r2)
751 Again, hardwired registers since this is not performance
752 critical, and there are possibly constraints on the
753 registers that we can't express in the register allocator.*/
754 struct {
755 Int szB; /* 1, 2, 4 or 8 */
756 } LdrEX;
757 /* STREX{,H,B} r0, r2, [r4] and
758 STREXD r0, r2, r3, [r4] (on LE hosts, transferred value is r3:r2)
759 r0 = SC( [r4] = r2 ) (8, 16, 32 bit transfers)
760 r0 = SC( [r4] = r3:r2) (64 bit transfers)
761 Ditto comment re fixed registers. */
762 struct {
763 Int szB; /* 1, 2, 4 or 8 */
764 } StrEX;
765 /* VFP INSTRUCTIONS */
766 /* 64-bit Fp load/store */
767 struct {
768 Bool isLoad;
769 HReg dD;
770 ARMAModeV* amode;
771 } VLdStD;
772 /* 32-bit Fp load/store */
773 struct {
774 Bool isLoad;
775 HReg fD;
776 ARMAModeV* amode;
777 } VLdStS;
778 /* 64-bit FP binary arithmetic */
779 struct {
780 ARMVfpOp op;
781 HReg dst;
782 HReg argL;
783 HReg argR;
784 } VAluD;
785 /* 32-bit FP binary arithmetic */
786 struct {
787 ARMVfpOp op;
788 HReg dst;
789 HReg argL;
790 HReg argR;
791 } VAluS;
792 /* 64-bit FP unary, also reg-reg move */
793 struct {
794 ARMVfpUnaryOp op;
795 HReg dst;
796 HReg src;
797 } VUnaryD;
798 /* 32-bit FP unary, also reg-reg move */
799 struct {
800 ARMVfpUnaryOp op;
801 HReg dst;
802 HReg src;
803 } VUnaryS;
804 /* 64-bit FP compare and move results to CPSR (FCMPD;FMSTAT) */
805 struct {
806 HReg argL;
807 HReg argR;
808 } VCmpD;
809 /* 64-bit FP mov src to dst on the given condition, which may
810 not be ARMcc_AL. */
811 struct {
812 ARMCondCode cond;
813 HReg dst;
814 HReg src;
815 } VCMovD;
816 /* 32-bit FP mov src to dst on the given condition, which may
817 not be ARMcc_AL. */
818 struct {
819 ARMCondCode cond;
820 HReg dst;
821 HReg src;
822 } VCMovS;
823 /* Convert between 32-bit and 64-bit FP values (both ways).
824 (FCVTSD, FCVTDS) */
825 struct {
826 Bool sToD; /* True: F32->F64. False: F64->F32 */
827 HReg dst;
828 HReg src;
829 } VCvtSD;
830 /* Transfer a NEON Q reg to/from two D registers (VMOV x 2) */
831 struct {
832 Bool toQ;
833 HReg qD;
834 HReg dHi;
835 HReg dLo;
836 } VXferQ;
837 /* Transfer a VFP D reg to/from two integer registers (VMOV) */
838 struct {
839 Bool toD;
840 HReg dD;
841 HReg rHi;
842 HReg rLo;
843 } VXferD;
844 /* Transfer a VFP S reg to/from an integer register (VMOV) */
845 struct {
846 Bool toS;
847 HReg fD;
848 HReg rLo;
849 } VXferS;
850 /* Convert between 32-bit ints and 64-bit FP values (both ways
851 and both signednesses). (FSITOD, FUITOD, FTOSID, FTOUID) */
852 struct {
853 Bool iToD; /* True: I32->F64. False: F64->I32 */
854 Bool syned; /* True: I32 is signed. False: I32 is unsigned */
855 HReg dst;
856 HReg src;
857 } VCvtID;
858 /* Round a F32 or F64 value to the nearest integral value,
859 according to the FPSCR.RM. For ARM >= V8 hosts only. */
860 struct {
861 Bool isF64;
862 HReg dst;
863 HReg src;
864 } VRIntR;
865 /* Do Min/Max of F32 or F64 values, propagating the numerical arg
866 if the other is a qNaN. For ARM >= V8 hosts only. */
867 struct {
868 Bool isF64;
869 Bool isMax;
870 HReg dst;
871 HReg srcL;
872 HReg srcR;
873 } VMinMaxNum;
874 /* Move a 32-bit value to/from the FPSCR (FMXR, FMRX) */
875 struct {
876 Bool toFPSCR;
877 HReg iReg;
878 } FPSCR;
879 /* Mem fence. An insn which fences all loads and stores as
880 much as possible before continuing. On ARM we emit the
881 sequence
882 mcr 15,0,r0,c7,c10,4 (DSB)
883 mcr 15,0,r0,c7,c10,5 (DMB)
884 mcr 15,0,r0,c7,c5,4 (ISB)
885 which is probably total overkill, but better safe than
886 sorry.
887 */
888 struct {
889 } MFence;
890 /* A CLREX instruction. */
891 struct {
892 } CLREX;
893 /* Neon data processing instruction: 3 registers of the same
894 length */
895 struct {
896 ARMNeonBinOp op;
897 HReg dst;
898 HReg argL;
899 HReg argR;
900 UInt size;
901 Bool Q;
902 } NBinary;
903 struct {
904 ARMNeonBinOp op;
905 ARMNRS* dst;
906 ARMNRS* argL;
907 ARMNRS* argR;
908 UInt size;
909 Bool Q;
910 } NBinaryS;
911 struct {
912 ARMNeonShiftOp op;
913 HReg dst;
914 HReg argL;
915 HReg argR;
916 UInt size;
917 Bool Q;
918 } NShift;
919 struct {
920 HReg dst;
921 HReg src;
922 UInt amt; /* 1..63 only */
923 } NShl64;
924 struct {
925 Bool isLoad;
926 HReg dQ;
927 ARMAModeN *amode;
928 } NLdStQ;
929 struct {
930 Bool isLoad;
931 HReg dD;
932 ARMAModeN *amode;
933 } NLdStD;
934 struct {
935 ARMNeonUnOpS op;
936 ARMNRS* dst;
937 ARMNRS* src;
938 UInt size;
939 Bool Q;
940 } NUnaryS;
941 struct {
942 ARMNeonUnOp op;
943 HReg dst;
944 HReg src;
945 UInt size;
946 Bool Q;
947 } NUnary;
948 /* Takes two arguments and modifies them both. */
949 struct {
950 ARMNeonDualOp op;
951 HReg arg1;
952 HReg arg2;
953 UInt size;
954 Bool Q;
955 } NDual;
956 struct {
957 HReg dst;
958 ARMNImm* imm;
959 } NeonImm;
960 /* 128-bit Neon move src to dst on the given condition, which
961 may not be ARMcc_AL. */
962 struct {
963 ARMCondCode cond;
964 HReg dst;
965 HReg src;
966 } NCMovQ;
967 struct {
968 /* Note: rD != rN */
969 HReg rD;
970 HReg rN;
971 UInt imm32;
972 } Add32;
973 struct {
974 ARMAMode1* amCounter;
975 ARMAMode1* amFailAddr;
976 } EvCheck;
977 struct {
978 /* No fields. The address of the counter to inc is
979 installed later, post-translation, by patching it in,
980 as it is not known at translation time. */
981 } ProfInc;
982 } ARMin;
983 }
984 ARMInstr;
985
986
987 extern ARMInstr* ARMInstr_Alu ( ARMAluOp, HReg, HReg, ARMRI84* );
988 extern ARMInstr* ARMInstr_Shift ( ARMShiftOp, HReg, HReg, ARMRI5* );
989 extern ARMInstr* ARMInstr_Unary ( ARMUnaryOp, HReg, HReg );
990 extern ARMInstr* ARMInstr_CmpOrTst ( Bool isCmp, HReg, ARMRI84* );
991 extern ARMInstr* ARMInstr_Mov ( HReg, ARMRI84* );
992 extern ARMInstr* ARMInstr_Imm32 ( HReg, UInt );
993 extern ARMInstr* ARMInstr_LdSt32 ( ARMCondCode,
994 Bool isLoad, HReg, ARMAMode1* );
995 extern ARMInstr* ARMInstr_LdSt16 ( ARMCondCode,
996 Bool isLoad, Bool signedLoad,
997 HReg, ARMAMode2* );
998 extern ARMInstr* ARMInstr_LdSt8U ( ARMCondCode,
999 Bool isLoad, HReg, ARMAMode1* );
1000 extern ARMInstr* ARMInstr_Ld8S ( ARMCondCode, HReg, ARMAMode2* );
1001 extern ARMInstr* ARMInstr_XDirect ( Addr32 dstGA, ARMAMode1* amR15T,
1002 ARMCondCode cond, Bool toFastEP );
1003 extern ARMInstr* ARMInstr_XIndir ( HReg dstGA, ARMAMode1* amR15T,
1004 ARMCondCode cond );
1005 extern ARMInstr* ARMInstr_XAssisted ( HReg dstGA, ARMAMode1* amR15T,
1006 ARMCondCode cond, IRJumpKind jk );
1007 extern ARMInstr* ARMInstr_CMov ( ARMCondCode, HReg dst, ARMRI84* src );
1008 extern ARMInstr* ARMInstr_Call ( ARMCondCode, Addr32, Int nArgRegs,
1009 RetLoc rloc );
1010 extern ARMInstr* ARMInstr_Mul ( ARMMulOp op );
1011 extern ARMInstr* ARMInstr_LdrEX ( Int szB );
1012 extern ARMInstr* ARMInstr_StrEX ( Int szB );
1013 extern ARMInstr* ARMInstr_VLdStD ( Bool isLoad, HReg, ARMAModeV* );
1014 extern ARMInstr* ARMInstr_VLdStS ( Bool isLoad, HReg, ARMAModeV* );
1015 extern ARMInstr* ARMInstr_VAluD ( ARMVfpOp op, HReg, HReg, HReg );
1016 extern ARMInstr* ARMInstr_VAluS ( ARMVfpOp op, HReg, HReg, HReg );
1017 extern ARMInstr* ARMInstr_VUnaryD ( ARMVfpUnaryOp, HReg dst, HReg src );
1018 extern ARMInstr* ARMInstr_VUnaryS ( ARMVfpUnaryOp, HReg dst, HReg src );
1019 extern ARMInstr* ARMInstr_VCmpD ( HReg argL, HReg argR );
1020 extern ARMInstr* ARMInstr_VCMovD ( ARMCondCode, HReg dst, HReg src );
1021 extern ARMInstr* ARMInstr_VCMovS ( ARMCondCode, HReg dst, HReg src );
1022 extern ARMInstr* ARMInstr_VCvtSD ( Bool sToD, HReg dst, HReg src );
1023 extern ARMInstr* ARMInstr_VXferQ ( Bool toQ, HReg qD, HReg dHi, HReg dLo );
1024 extern ARMInstr* ARMInstr_VXferD ( Bool toD, HReg dD, HReg rHi, HReg rLo );
1025 extern ARMInstr* ARMInstr_VXferS ( Bool toS, HReg fD, HReg rLo );
1026 extern ARMInstr* ARMInstr_VCvtID ( Bool iToD, Bool syned,
1027 HReg dst, HReg src );
1028 extern ARMInstr* ARMInstr_VRIntR ( Bool isF64, HReg dst, HReg src );
1029 extern ARMInstr* ARMInstr_VMinMaxNum ( Bool isF64, Bool isMax,
1030 HReg dst, HReg srcL, HReg srcR );
1031 extern ARMInstr* ARMInstr_FPSCR ( Bool toFPSCR, HReg iReg );
1032 extern ARMInstr* ARMInstr_MFence ( void );
1033 extern ARMInstr* ARMInstr_CLREX ( void );
1034 extern ARMInstr* ARMInstr_NLdStQ ( Bool isLoad, HReg, ARMAModeN* );
1035 extern ARMInstr* ARMInstr_NLdStD ( Bool isLoad, HReg, ARMAModeN* );
1036 extern ARMInstr* ARMInstr_NUnary ( ARMNeonUnOp, HReg, HReg, UInt, Bool );
1037 extern ARMInstr* ARMInstr_NUnaryS ( ARMNeonUnOpS, ARMNRS*, ARMNRS*,
1038 UInt, Bool );
1039 extern ARMInstr* ARMInstr_NDual ( ARMNeonDualOp, HReg, HReg, UInt, Bool );
1040 extern ARMInstr* ARMInstr_NBinary ( ARMNeonBinOp, HReg, HReg, HReg,
1041 UInt, Bool );
1042 extern ARMInstr* ARMInstr_NShift ( ARMNeonShiftOp, HReg, HReg, HReg,
1043 UInt, Bool );
1044 extern ARMInstr* ARMInstr_NShl64 ( HReg, HReg, UInt );
1045 extern ARMInstr* ARMInstr_NeonImm ( HReg, ARMNImm* );
1046 extern ARMInstr* ARMInstr_NCMovQ ( ARMCondCode, HReg, HReg );
1047 extern ARMInstr* ARMInstr_Add32 ( HReg rD, HReg rN, UInt imm32 );
1048 extern ARMInstr* ARMInstr_EvCheck ( ARMAMode1* amCounter,
1049 ARMAMode1* amFailAddr );
1050 extern ARMInstr* ARMInstr_ProfInc ( void );
1051
1052 extern void ppARMInstr ( const ARMInstr* );
1053
1054
1055 /* Some functions that insulate the register allocator from details
1056 of the underlying instruction set. */
1057 extern void getRegUsage_ARMInstr ( HRegUsage*, const ARMInstr*, Bool );
1058 extern void mapRegs_ARMInstr ( HRegRemap*, ARMInstr*, Bool );
1059 extern Bool isMove_ARMInstr ( const ARMInstr*, HReg*, HReg* );
1060 extern Int emit_ARMInstr ( /*MB_MOD*/Bool* is_profInc,
1061 UChar* buf, Int nbuf, const ARMInstr* i,
1062 Bool mode64,
1063 VexEndness endness_host,
1064 const void* disp_cp_chain_me_to_slowEP,
1065 const void* disp_cp_chain_me_to_fastEP,
1066 const void* disp_cp_xindir,
1067 const void* disp_cp_xassisted );
1068
1069 extern void genSpill_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
1070 HReg rreg, Int offset, Bool );
1071 extern void genReload_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
1072 HReg rreg, Int offset, Bool );
1073
1074 extern const RRegUniverse* getRRegUniverse_ARM ( void );
1075
1076 extern HInstrArray* iselSB_ARM ( const IRSB*,
1077 VexArch,
1078 const VexArchInfo*,
1079 const VexAbiInfo*,
1080 Int offs_Host_EvC_Counter,
1081 Int offs_Host_EvC_FailAddr,
1082 Bool chainingAllowed,
1083 Bool addProfInc,
1084 Addr max_ga );
1085
1086 /* How big is an event check? This is kind of a kludge because it
1087 depends on the offsets of host_EvC_FAILADDR and
1088 host_EvC_COUNTER. */
1089 extern Int evCheckSzB_ARM (void);
1090
1091 /* Perform a chaining and unchaining of an XDirect jump. */
1092 extern VexInvalRange chainXDirect_ARM ( VexEndness endness_host,
1093 void* place_to_chain,
1094 const void* disp_cp_chain_me_EXPECTED,
1095 const void* place_to_jump_to );
1096
1097 extern VexInvalRange unchainXDirect_ARM ( VexEndness endness_host,
1098 void* place_to_unchain,
1099 const void* place_to_jump_to_EXPECTED,
1100 const void* disp_cp_chain_me );
1101
1102 /* Patch the counter location into an existing ProfInc point. */
1103 extern VexInvalRange patchProfInc_ARM ( VexEndness endness_host,
1104 void* place_to_patch,
1105 const ULong* location_of_counter );
1106
1107
1108 #endif /* ndef __VEX_HOST_ARM_DEFS_H */
1109
1110 /*---------------------------------------------------------------*/
1111 /*--- end host_arm_defs.h ---*/
1112 /*---------------------------------------------------------------*/
1113