blob: 1901e80b941b11c5bdaed6284632ac7c8e034c83 [file] [log] [blame]
cerion05782872004-12-16 11:50:19 +00001
2/*---------------------------------------------------------------*/
sewardj752f9062010-05-03 21:38:49 +00003/*--- begin host_arm_defs.h ---*/
cerion05782872004-12-16 11:50:19 +00004/*---------------------------------------------------------------*/
5
6/*
sewardj752f9062010-05-03 21:38:49 +00007 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
cerion05782872004-12-16 11:50:19 +00009
sewardj752f9062010-05-03 21:38:49 +000010 Copyright (C) 2004-2010 OpenWorks LLP
11 info@open-works.net
cerion05782872004-12-16 11:50:19 +000012
sewardj752f9062010-05-03 21:38:49 +000013 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.
cerion05782872004-12-16 11:50:19 +000017
sewardj752f9062010-05-03 21:38:49 +000018 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
sewardj7bd6ffe2005-08-03 16:07:36 +000026 02110-1301, USA.
27
sewardj752f9062010-05-03 21:38:49 +000028 The GNU General Public License is contained in the file COPYING.
cerion05782872004-12-16 11:50:19 +000029*/
30
sewardjcef7d3e2009-07-02 12:21:59 +000031#ifndef __VEX_HOST_ARM_DEFS_H
32#define __VEX_HOST_ARM_DEFS_H
cerion05782872004-12-16 11:50:19 +000033
sewardj6c60b322010-08-22 12:48:28 +000034extern UInt arm_hwcaps;
35
cerion05782872004-12-16 11:50:19 +000036
37/* --------- Registers. --------- */
38
cerion1df83112004-12-16 12:10:59 +000039/* The usual HReg abstraction.
40 There are 16 general purpose regs.
cerion05782872004-12-16 11:50:19 +000041*/
42
43extern void ppHRegARM ( HReg );
44
sewardj6c299f32009-12-31 18:00:12 +000045extern HReg hregARM_R0 ( void );
46extern HReg hregARM_R1 ( void );
47extern HReg hregARM_R2 ( void );
48extern HReg hregARM_R3 ( void );
49extern HReg hregARM_R4 ( void );
50extern HReg hregARM_R5 ( void );
51extern HReg hregARM_R6 ( void );
52extern HReg hregARM_R7 ( void );
53extern HReg hregARM_R8 ( void );
54extern HReg hregARM_R9 ( void );
cerion05782872004-12-16 11:50:19 +000055extern HReg hregARM_R10 ( void );
56extern HReg hregARM_R11 ( void );
57extern HReg hregARM_R12 ( void );
58extern HReg hregARM_R13 ( void );
59extern HReg hregARM_R14 ( void );
60extern HReg hregARM_R15 ( void );
sewardj6c299f32009-12-31 18:00:12 +000061extern HReg hregARM_D8 ( void );
62extern HReg hregARM_D9 ( void );
63extern HReg hregARM_D10 ( void );
64extern HReg hregARM_D11 ( void );
65extern HReg hregARM_D12 ( void );
66extern HReg hregARM_S26 ( void );
67extern HReg hregARM_S27 ( void );
68extern HReg hregARM_S28 ( void );
69extern HReg hregARM_S29 ( void );
70extern HReg hregARM_S30 ( void );
sewardj6c60b322010-08-22 12:48:28 +000071extern HReg hregARM_Q8 ( void );
72extern HReg hregARM_Q9 ( void );
73extern HReg hregARM_Q10 ( void );
74extern HReg hregARM_Q11 ( void );
75extern HReg hregARM_Q12 ( void );
76extern HReg hregARM_Q13 ( void );
77extern HReg hregARM_Q14 ( void );
78extern HReg hregARM_Q15 ( void );
sewardj6c299f32009-12-31 18:00:12 +000079
80/* Number of registers used arg passing in function calls */
81#define ARM_N_ARGREGS 4 /* r0, r1, r2, r3 */
cerion05782872004-12-16 11:50:19 +000082
83
sewardj6c299f32009-12-31 18:00:12 +000084/* --------- Condition codes. --------- */
cerion05782872004-12-16 11:50:19 +000085
86typedef
87 enum {
sewardj6c299f32009-12-31 18:00:12 +000088 ARMcc_EQ = 0, /* equal : Z=1 */
89 ARMcc_NE = 1, /* not equal : Z=0 */
cerion05782872004-12-16 11:50:19 +000090
sewardj6c299f32009-12-31 18:00:12 +000091 ARMcc_HS = 2, /* >=u (higher or same) : C=1 */
92 ARMcc_LO = 3, /* <u (lower) : C=0 */
cerion05782872004-12-16 11:50:19 +000093
sewardj6c299f32009-12-31 18:00:12 +000094 ARMcc_MI = 4, /* minus (negative) : N=1 */
95 ARMcc_PL = 5, /* plus (zero or +ve) : N=0 */
cerion05782872004-12-16 11:50:19 +000096
sewardj6c299f32009-12-31 18:00:12 +000097 ARMcc_VS = 6, /* overflow : V=1 */
98 ARMcc_VC = 7, /* no overflow : V=0 */
cerion05782872004-12-16 11:50:19 +000099
sewardj6c299f32009-12-31 18:00:12 +0000100 ARMcc_HI = 8, /* >u (higher) : C=1 && Z=0 */
101 ARMcc_LS = 9, /* <=u (lower or same) : C=0 || Z=1 */
cerion05782872004-12-16 11:50:19 +0000102
sewardj6c299f32009-12-31 18:00:12 +0000103 ARMcc_GE = 10, /* >=s (signed greater or equal) : N=V */
104 ARMcc_LT = 11, /* <s (signed less than) : N!=V */
cerion05782872004-12-16 11:50:19 +0000105
sewardj6c299f32009-12-31 18:00:12 +0000106 ARMcc_GT = 12, /* >s (signed greater) : Z=0 && N=V */
107 ARMcc_LE = 13, /* <=s (signed less or equal) : Z=1 || N!=V */
cerion05782872004-12-16 11:50:19 +0000108
sewardj6c299f32009-12-31 18:00:12 +0000109 ARMcc_AL = 14, /* always (unconditional) */
110 ARMcc_NV = 15 /* never (basically undefined meaning), deprecated */
cerion05782872004-12-16 11:50:19 +0000111 }
112 ARMCondCode;
113
114extern HChar* showARMCondCode ( ARMCondCode );
115
116
117
cerion05782872004-12-16 11:50:19 +0000118/* --------- Memory address expressions (amodes). --------- */
119
120/* --- Addressing Mode 1 --- */
121typedef
122 enum {
sewardj6c299f32009-12-31 18:00:12 +0000123 ARMam1_RI=1, /* reg +/- imm12 */
124 ARMam1_RRS /* reg1 + (reg2 << 0, 1 2 or 3) */
cerion05782872004-12-16 11:50:19 +0000125 }
126 ARMAMode1Tag;
127
128typedef
129 struct {
sewardj6c299f32009-12-31 18:00:12 +0000130 ARMAMode1Tag tag;
131 union {
132 struct {
133 HReg reg;
134 Int simm13; /* -4095 .. +4095 */
135 } RI;
136 struct {
137 HReg base;
138 HReg index;
139 UInt shift; /* 0, 1 2 or 3 */
140 } RRS;
141 } ARMam1;
cerion05782872004-12-16 11:50:19 +0000142 }
143 ARMAMode1;
144
sewardj6c299f32009-12-31 18:00:12 +0000145extern ARMAMode1* ARMAMode1_RI ( HReg reg, Int simm13 );
146extern ARMAMode1* ARMAMode1_RRS ( HReg base, HReg index, UInt shift );
cerion05782872004-12-16 11:50:19 +0000147
148extern void ppARMAMode1 ( ARMAMode1* );
149
150
cerion05782872004-12-16 11:50:19 +0000151/* --- Addressing Mode 2 --- */
152typedef
153 enum {
sewardj6c299f32009-12-31 18:00:12 +0000154 ARMam2_RI=3, /* reg +/- imm8 */
155 ARMam2_RR /* reg1 + reg2 */
cerion05782872004-12-16 11:50:19 +0000156 }
157 ARMAMode2Tag;
158
159typedef
160 struct {
161 ARMAMode2Tag tag;
162 union {
163 struct {
sewardj6c299f32009-12-31 18:00:12 +0000164 HReg reg;
165 Int simm9; /* -255 .. 255 */
cerion05782872004-12-16 11:50:19 +0000166 } RI;
167 struct {
sewardj6c299f32009-12-31 18:00:12 +0000168 HReg base;
169 HReg index;
170 } RR;
cerion82edbb32004-12-16 14:06:34 +0000171 } ARMam2;
cerion05782872004-12-16 11:50:19 +0000172 }
173 ARMAMode2;
174
sewardj6c299f32009-12-31 18:00:12 +0000175extern ARMAMode2* ARMAMode2_RI ( HReg reg, Int simm9 );
176extern ARMAMode2* ARMAMode2_RR ( HReg base, HReg index );
cerion05782872004-12-16 11:50:19 +0000177
178extern void ppARMAMode2 ( ARMAMode2* );
179
180
sewardj6c299f32009-12-31 18:00:12 +0000181/* --- Addressing Mode suitable for VFP --- */
182/* The simm11 is encoded as 8 bits + 1 sign bit,
183 so can only be 0 % 4. */
184typedef
185 struct {
186 HReg reg;
187 Int simm11; /* -1020, -1016 .. 1016, 1020 */
188 }
189 ARMAModeV;
190
191extern ARMAModeV* mkARMAModeV ( HReg reg, Int simm11 );
192
193extern void ppARMAModeV ( ARMAModeV* );
194
sewardj6c60b322010-08-22 12:48:28 +0000195/* --- Addressing Mode suitable for Neon --- */
196typedef
197 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000198 ARMamN_R=5,
sewardj6c60b322010-08-22 12:48:28 +0000199 ARMamN_RR
200 /* ... */
201 }
202 ARMAModeNTag;
203
204typedef
205 struct {
206 ARMAModeNTag tag;
207 union {
208 struct {
209 HReg rN;
210 HReg rM;
211 } RR;
212 struct {
213 HReg rN;
214 } R;
215 /* ... */
216 } ARMamN;
217 }
218 ARMAModeN;
219
220extern ARMAModeN* mkARMAModeN_RR ( HReg, HReg );
221extern ARMAModeN* mkARMAModeN_R ( HReg );
222extern void ppARMAModeN ( ARMAModeN* );
sewardj6c299f32009-12-31 18:00:12 +0000223
224/* --------- Reg or imm-8x4 operands --------- */
225/* a.k.a (a very restricted form of) Shifter Operand,
226 in the ARM parlance. */
227
cerion05782872004-12-16 11:50:19 +0000228typedef
229 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000230 ARMri84_I84=7, /* imm8 `ror` (2 * imm4) */
sewardj6c299f32009-12-31 18:00:12 +0000231 ARMri84_R /* reg */
cerion05782872004-12-16 11:50:19 +0000232 }
sewardj6c299f32009-12-31 18:00:12 +0000233 ARMRI84Tag;
cerion05782872004-12-16 11:50:19 +0000234
235typedef
236 struct {
sewardj6c299f32009-12-31 18:00:12 +0000237 ARMRI84Tag tag;
cerion05782872004-12-16 11:50:19 +0000238 union {
239 struct {
sewardj6c299f32009-12-31 18:00:12 +0000240 UShort imm8;
241 UShort imm4;
242 } I84;
cerion05782872004-12-16 11:50:19 +0000243 struct {
sewardj6c299f32009-12-31 18:00:12 +0000244 HReg reg;
245 } R;
246 } ARMri84;
cerion05782872004-12-16 11:50:19 +0000247 }
sewardj6c299f32009-12-31 18:00:12 +0000248 ARMRI84;
249
250extern ARMRI84* ARMRI84_I84 ( UShort imm8, UShort imm4 );
251extern ARMRI84* ARMRI84_R ( HReg );
252
253extern void ppARMRI84 ( ARMRI84* );
cerion05782872004-12-16 11:50:19 +0000254
255
sewardj6c299f32009-12-31 18:00:12 +0000256/* --------- Reg or imm5 operands --------- */
cerion05782872004-12-16 11:50:19 +0000257typedef
258 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000259 ARMri5_I5=9, /* imm5, 1 .. 31 only (no zero!) */
sewardj6c299f32009-12-31 18:00:12 +0000260 ARMri5_R /* reg */
cerion05782872004-12-16 11:50:19 +0000261 }
sewardj6c299f32009-12-31 18:00:12 +0000262 ARMRI5Tag;
cerion05782872004-12-16 11:50:19 +0000263
264typedef
sewardj6c299f32009-12-31 18:00:12 +0000265 struct {
266 ARMRI5Tag tag;
cerion05782872004-12-16 11:50:19 +0000267 union {
sewardj6c299f32009-12-31 18:00:12 +0000268 struct {
269 UInt imm5;
270 } I5;
271 struct {
272 HReg reg;
273 } R;
274 } ARMri5;
275 }
276 ARMRI5;
cerion05782872004-12-16 11:50:19 +0000277
sewardj6c299f32009-12-31 18:00:12 +0000278extern ARMRI5* ARMRI5_I5 ( UInt imm5 );
279extern ARMRI5* ARMRI5_R ( HReg );
cerion82edbb32004-12-16 14:06:34 +0000280
sewardj6c299f32009-12-31 18:00:12 +0000281extern void ppARMRI5 ( ARMRI5* );
cerion05782872004-12-16 11:50:19 +0000282
sewardj6c60b322010-08-22 12:48:28 +0000283/* -------- Neon Immediate operand -------- */
284
285/* imm8 = abcdefgh, B = NOT(b);
286
287type | value (64bit binary)
288-----+-------------------------------------------------------------------------
289 0 | 00000000 00000000 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh
290 1 | 00000000 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh 00000000
291 2 | 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh 00000000 00000000
292 3 | abcdefgh 00000000 00000000 00000000 abcdefgh 00000000 00000000 00000000
293 4 | 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh
294 5 | abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000
295 6 | abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh
296 7 | 00000000 00000000 abcdefgh 11111111 00000000 00000000 abcdefgh 11111111
297 8 | 00000000 abcdefgh 11111111 11111111 00000000 abcdefgh 11111111 11111111
298 9 | aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
299 10 | aBbbbbbc defgh000 00000000 00000000 aBbbbbbc defgh000 00000000 00000000
300-----+-------------------------------------------------------------------------
301
302Type 10 is:
303 (-1)^S * 2^exp * mantissa
304where S = a, exp = UInt(B:c:d) - 3, mantissa = (16 + UInt(e:f:g:h)) / 16
305*/
306
307typedef
308 struct {
309 UInt type;
310 UInt imm8;
311 }
312 ARMNImm;
313
314extern ARMNImm* ARMNImm_TI ( UInt type, UInt imm8 );
315extern ULong ARMNImm_to_Imm64 ( ARMNImm* );
316extern ARMNImm* Imm64_to_ARMNImm ( ULong );
317
318extern void ppARMNImm ( ARMNImm* );
319
320/* ------ Neon Register or Scalar Operand ------ */
321
322typedef
323 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000324 ARMNRS_Reg=11,
sewardj6c60b322010-08-22 12:48:28 +0000325 ARMNRS_Scalar
326 }
327 ARMNRS_tag;
328
329typedef
330 struct {
331 ARMNRS_tag tag;
332 HReg reg;
333 UInt index;
334 }
335 ARMNRS;
336
337extern ARMNRS* mkARMNRS(ARMNRS_tag, HReg reg, UInt index);
338extern void ppARMNRS ( ARMNRS* );
cerion05782872004-12-16 11:50:19 +0000339
340/* --------- Instructions. --------- */
341
cerion05782872004-12-16 11:50:19 +0000342/* --------- */
343typedef
344 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000345 ARMalu_ADD=20, /* plain 32-bit add */
sewardj6c299f32009-12-31 18:00:12 +0000346 ARMalu_ADDS, /* 32-bit add, and set the flags */
347 ARMalu_ADC, /* 32-bit add with carry */
348 ARMalu_SUB, /* plain 32-bit subtract */
349 ARMalu_SUBS, /* 32-bit subtract, and set the flags */
350 ARMalu_SBC, /* 32-bit subtract with carry */
351 ARMalu_AND,
352 ARMalu_BIC,
353 ARMalu_OR,
354 ARMalu_XOR
355 }
356 ARMAluOp;
cerion05782872004-12-16 11:50:19 +0000357
sewardj6c299f32009-12-31 18:00:12 +0000358extern HChar* showARMAluOp ( ARMAluOp op );
cerion05782872004-12-16 11:50:19 +0000359
sewardj6c299f32009-12-31 18:00:12 +0000360
361typedef
362 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000363 ARMsh_SHL=40,
sewardj6c299f32009-12-31 18:00:12 +0000364 ARMsh_SHR,
365 ARMsh_SAR
366 }
367 ARMShiftOp;
368
369extern HChar* showARMShiftOp ( ARMShiftOp op );
370
371
372typedef
373 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000374 ARMun_NEG=50,
sewardj6c299f32009-12-31 18:00:12 +0000375 ARMun_NOT,
376 ARMun_CLZ
377 }
378 ARMUnaryOp;
379
380extern HChar* showARMUnaryOp ( ARMUnaryOp op );
381
382
383typedef
384 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000385 ARMmul_PLAIN=60,
sewardj6c299f32009-12-31 18:00:12 +0000386 ARMmul_ZX,
387 ARMmul_SX
388 }
389 ARMMulOp;
390
391extern HChar* showARMMulOp ( ARMMulOp op );
392
393
394typedef
395 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000396 ARMvfp_ADD=70,
sewardj6c299f32009-12-31 18:00:12 +0000397 ARMvfp_SUB,
398 ARMvfp_MUL,
399 ARMvfp_DIV
400 }
401 ARMVfpOp;
402
403extern HChar* showARMVfpOp ( ARMVfpOp op );
404
405
406typedef
407 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000408 ARMvfpu_COPY=80,
sewardj6c299f32009-12-31 18:00:12 +0000409 ARMvfpu_NEG,
410 ARMvfpu_ABS,
411 ARMvfpu_SQRT
412 }
413 ARMVfpUnaryOp;
414
415extern HChar* showARMVfpUnaryOp ( ARMVfpUnaryOp op );
416
sewardj6c60b322010-08-22 12:48:28 +0000417typedef
418 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000419 ARMneon_VAND=90,
sewardj6c60b322010-08-22 12:48:28 +0000420 ARMneon_VORR,
421 ARMneon_VXOR,
422 ARMneon_VADD,
423 ARMneon_VADDFP,
424 ARMneon_VRHADDS,
425 ARMneon_VRHADDU,
426 ARMneon_VPADDFP,
427 ARMneon_VABDFP,
428 ARMneon_VSUB,
429 ARMneon_VSUBFP,
430 ARMneon_VMAXU,
431 ARMneon_VMAXS,
432 ARMneon_VMAXF,
433 ARMneon_VMINU,
434 ARMneon_VMINS,
435 ARMneon_VMINF,
436 ARMneon_VQADDU,
437 ARMneon_VQADDS,
438 ARMneon_VQSUBU,
439 ARMneon_VQSUBS,
440 ARMneon_VCGTU,
441 ARMneon_VCGTS,
442 ARMneon_VCGEU,
443 ARMneon_VCGES,
444 ARMneon_VCGTF,
445 ARMneon_VCGEF,
446 ARMneon_VCEQ,
447 ARMneon_VCEQF,
448 ARMneon_VEXT,
449 ARMneon_VMUL,
450 ARMneon_VMULFP,
451 ARMneon_VMULLU,
452 ARMneon_VMULLS,
453 ARMneon_VMULP,
454 ARMneon_VMULLP,
455 ARMneon_VQDMULH,
456 ARMneon_VQRDMULH,
457 ARMneon_VPADD,
458 ARMneon_VPMINU,
459 ARMneon_VPMINS,
460 ARMneon_VPMINF,
461 ARMneon_VPMAXU,
462 ARMneon_VPMAXS,
463 ARMneon_VPMAXF,
464 ARMneon_VTBL,
465 ARMneon_VQDMULL,
sewardj6c60b322010-08-22 12:48:28 +0000466 ARMneon_VRECPS,
sewardj6c60b322010-08-22 12:48:28 +0000467 ARMneon_VRSQRTS,
sewardj6c60b322010-08-22 12:48:28 +0000468 /* ... */
469 }
470 ARMNeonBinOp;
471
472typedef
473 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000474 ARMneon_VSHL=150,
sewardj6c60b322010-08-22 12:48:28 +0000475 ARMneon_VSAL, /* Yah, not SAR but SAL */
476 ARMneon_VQSHL,
477 ARMneon_VQSAL
478 }
479 ARMNeonShiftOp;
480
481typedef
482 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000483 ARMneon_COPY=160,
sewardj6c60b322010-08-22 12:48:28 +0000484 ARMneon_COPYLU,
485 ARMneon_COPYLS,
486 ARMneon_COPYN,
487 ARMneon_COPYQNSS,
488 ARMneon_COPYQNUS,
489 ARMneon_COPYQNUU,
490 ARMneon_NOT,
491 ARMneon_EQZ,
492 ARMneon_DUP,
493 ARMneon_PADDLS,
494 ARMneon_PADDLU,
495 ARMneon_CNT,
496 ARMneon_CLZ,
497 ARMneon_CLS,
498 ARMneon_VCVTxFPxINT,
499 ARMneon_VQSHLNSS,
500 ARMneon_VQSHLNUU,
501 ARMneon_VQSHLNUS,
502 ARMneon_VCVTFtoU,
503 ARMneon_VCVTFtoS,
504 ARMneon_VCVTUtoF,
505 ARMneon_VCVTStoF,
506 ARMneon_VCVTFtoFixedU,
507 ARMneon_VCVTFtoFixedS,
508 ARMneon_VCVTFixedUtoF,
509 ARMneon_VCVTFixedStoF,
510 ARMneon_VCVTF16toF32,
511 ARMneon_VCVTF32toF16,
512 ARMneon_REV16,
513 ARMneon_REV32,
514 ARMneon_REV64,
515 ARMneon_ABS,
516 ARMneon_VNEGF,
sewardj6aa87a62010-10-06 20:34:53 +0000517 ARMneon_VRECIP,
518 ARMneon_VRECIPF,
519 ARMneon_VABSFP,
520 ARMneon_VRSQRTEFP,
521 ARMneon_VRSQRTE
sewardj6c60b322010-08-22 12:48:28 +0000522 /* ... */
523 }
524 ARMNeonUnOp;
525
526typedef
527 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000528 ARMneon_SETELEM=200,
sewardj6c60b322010-08-22 12:48:28 +0000529 ARMneon_GETELEMU,
sewardj6aa87a62010-10-06 20:34:53 +0000530 ARMneon_GETELEMS,
531 ARMneon_VDUP,
sewardj6c60b322010-08-22 12:48:28 +0000532 }
533 ARMNeonUnOpS;
534
535typedef
536 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000537 ARMneon_TRN=210,
sewardj6c60b322010-08-22 12:48:28 +0000538 ARMneon_ZIP,
539 ARMneon_UZP
540 /* ... */
541 }
542 ARMNeonDualOp;
543
544extern HChar* showARMNeonBinOp ( ARMNeonBinOp op );
545extern HChar* showARMNeonUnOp ( ARMNeonUnOp op );
546extern HChar* showARMNeonUnOpS ( ARMNeonUnOpS op );
547extern HChar* showARMNeonShiftOp ( ARMNeonShiftOp op );
548extern HChar* showARMNeonDualOp ( ARMNeonDualOp op );
549extern HChar* showARMNeonBinOpDataType ( ARMNeonBinOp op );
550extern HChar* showARMNeonUnOpDataType ( ARMNeonUnOp op );
551extern HChar* showARMNeonUnOpSDataType ( ARMNeonUnOpS op );
552extern HChar* showARMNeonShiftOpDataType ( ARMNeonShiftOp op );
553extern HChar* showARMNeonDualOpDataType ( ARMNeonDualOp op );
sewardj6c299f32009-12-31 18:00:12 +0000554
555typedef
556 enum {
557 /* baseline */
sewardjb48eddb2010-10-04 09:34:46 +0000558 ARMin_Alu=220,
sewardj6c299f32009-12-31 18:00:12 +0000559 ARMin_Shift,
560 ARMin_Unary,
561 ARMin_CmpOrTst,
562 ARMin_Mov,
563 ARMin_Imm32,
564 ARMin_LdSt32,
565 ARMin_LdSt16,
566 ARMin_LdSt8U,
567 ARMin_Ld8S,
568 ARMin_Goto,
569 ARMin_CMov,
570 ARMin_Call,
571 ARMin_Mul,
572 ARMin_LdrEX,
573 ARMin_StrEX,
574 /* vfp */
575 ARMin_VLdStD,
576 ARMin_VLdStS,
577 ARMin_VAluD,
578 ARMin_VAluS,
579 ARMin_VUnaryD,
580 ARMin_VUnaryS,
581 ARMin_VCmpD,
582 ARMin_VCMovD,
583 ARMin_VCMovS,
584 ARMin_VCvtSD,
585 ARMin_VXferD,
586 ARMin_VXferS,
587 ARMin_VCvtID,
sewardj412098c2010-05-04 08:48:43 +0000588 ARMin_FPSCR,
sewardj6c60b322010-08-22 12:48:28 +0000589 ARMin_MFence,
590 /* Neon */
591 ARMin_NLdStQ,
592 ARMin_NLdStD,
593 ARMin_NUnary,
594 ARMin_NUnaryS,
595 ARMin_NDual,
596 ARMin_NBinary,
597 ARMin_NBinaryS,
598 ARMin_NShift,
599 ARMin_NeonImm,
600 ARMin_NCMovQ,
601 /* This is not a NEON instruction. Actually there is no corresponding
602 instruction in ARM instruction set at all. We need this one to
603 generate spill/reload of 128-bit registers since current register
604 allocator demands them to consist of no more than two instructions.
605 We will split this instruction into 2 or 3 ARM instructions on the
606 emiting phase.
607
608 NOTE: source and destination registers should be different! */
609 ARMin_Add32
cerion05782872004-12-16 11:50:19 +0000610 }
611 ARMInstrTag;
612
sewardj6c299f32009-12-31 18:00:12 +0000613/* Destinations are on the LEFT (first operand) */
cerion05782872004-12-16 11:50:19 +0000614
615typedef
616 struct {
617 ARMInstrTag tag;
618 union {
sewardj6c299f32009-12-31 18:00:12 +0000619 /* ADD/SUB/AND/OR/XOR, vanilla ALU op */
620 struct {
621 ARMAluOp op;
622 HReg dst;
623 HReg argL;
624 ARMRI84* argR;
625 } Alu;
626 /* SHL/SHR/SAR, 2nd arg is reg or imm */
627 struct {
628 ARMShiftOp op;
629 HReg dst;
630 HReg argL;
631 ARMRI5* argR;
632 } Shift;
633 /* NOT/NEG/CLZ */
634 struct {
635 ARMUnaryOp op;
636 HReg dst;
637 HReg src;
638 } Unary;
639 /* CMP/TST; subtract/and, discard result, set NZCV */
640 struct {
641 Bool isCmp;
642 HReg argL;
643 ARMRI84* argR;
644 } CmpOrTst;
645 /* MOV dst, src -- reg-reg (or reg-imm8x4) move */
646 struct {
647 HReg dst;
648 ARMRI84* src;
649 } Mov;
650 /* Pseudo-insn; make a 32-bit immediate */
651 struct {
652 HReg dst;
653 UInt imm32;
654 } Imm32;
655 /* 32-bit load or store */
656 struct {
657 Bool isLoad;
658 HReg rD;
659 ARMAMode1* amode;
660 } LdSt32;
661 /* 16-bit load or store */
662 struct {
663 Bool isLoad;
664 Bool signedLoad;
665 HReg rD;
666 ARMAMode2* amode;
667 } LdSt16;
668 /* 8-bit (unsigned) load or store */
669 struct {
670 Bool isLoad;
671 HReg rD;
672 ARMAMode1* amode;
673 } LdSt8U;
674 /* 8-bit signed load */
675 struct {
676 HReg rD;
677 ARMAMode2* amode;
678 } Ld8S;
679 /* Pseudo-insn. Go to guest address gnext, on given
680 condition, which could be ARMcc_AL. */
681 struct {
682 IRJumpKind jk;
683 ARMCondCode cond;
684 HReg gnext;
685 } Goto;
686 /* Mov src to dst on the given condition, which may not
687 be ARMcc_AL. */
688 struct {
689 ARMCondCode cond;
690 HReg dst;
691 ARMRI84* src;
692 } CMov;
693 /* Pseudo-insn. Call target (an absolute address), on given
694 condition (which could be ARMcc_AL). */
695 struct {
696 ARMCondCode cond;
697 HWord target;
698 Int nArgRegs; /* # regs carrying args: 0 .. 4 */
699 } Call;
700 /* (PLAIN) 32 * 32 -> 32: r0 = r2 * r3
701 (ZX) 32 *u 32 -> 64: r1:r0 = r2 *u r3
702 (SX) 32 *s 32 -> 64: r1:r0 = r2 *s r3
703 Why hardwired registers? Because the ARM ARM specifies
704 (eg for straight MUL) the result (Rd) and the left arg (Rm)
705 may not be the same register. That's not a constraint we
706 can enforce in the register allocator (without mucho extra
707 complexity). Hence hardwire it. At least using caller-saves
708 registers, which are less likely to be in use. */
709 struct {
710 ARMMulOp op;
711 } Mul;
712 /* LDREX{,H,B} r0, [r1]
713 Again, hardwired registers since this is not performance
714 critical, and there are possibly constraints on the
715 registers that we can't express in the register allocator.*/
716 struct {
717 Int szB; /* currently only 4 is allowed */
718 } LdrEX;
719 /* STREX{,H,B} r0, r1, [r2]
720 r0 = SC( [r2] = r1 )
721 Ditto comment re fixed registers. */
722 struct {
723 Int szB; /* currently only 4 is allowed */
724 } StrEX;
725 /* VFP INSTRUCTIONS */
726 /* 64-bit Fp load/store */
727 struct {
728 Bool isLoad;
729 HReg dD;
730 ARMAModeV* amode;
731 } VLdStD;
732 /* 32-bit Fp load/store */
733 struct {
734 Bool isLoad;
735 HReg fD;
736 ARMAModeV* amode;
737 } VLdStS;
738 /* 64-bit FP binary arithmetic */
739 struct {
740 ARMVfpOp op;
741 HReg dst;
742 HReg argL;
743 HReg argR;
744 } VAluD;
745 /* 32-bit FP binary arithmetic */
746 struct {
747 ARMVfpOp op;
748 HReg dst;
749 HReg argL;
750 HReg argR;
751 } VAluS;
752 /* 64-bit FP unary, also reg-reg move */
753 struct {
754 ARMVfpUnaryOp op;
755 HReg dst;
756 HReg src;
757 } VUnaryD;
758 /* 32-bit FP unary, also reg-reg move */
759 struct {
760 ARMVfpUnaryOp op;
761 HReg dst;
762 HReg src;
763 } VUnaryS;
764 /* 64-bit FP compare and move results to CPSR (FCMPD;FMSTAT) */
765 struct {
766 HReg argL;
767 HReg argR;
768 } VCmpD;
769 /* 64-bit FP mov src to dst on the given condition, which may
770 not be ARMcc_AL. */
771 struct {
772 ARMCondCode cond;
773 HReg dst;
774 HReg src;
775 } VCMovD;
776 /* 32-bit FP mov src to dst on the given condition, which may
777 not be ARMcc_AL. */
778 struct {
779 ARMCondCode cond;
780 HReg dst;
781 HReg src;
782 } VCMovS;
783 /* Convert between 32-bit and 64-bit FP values (both ways).
784 (FCVTSD, FCVTDS) */
785 struct {
786 Bool sToD; /* True: F32->F64. False: F64->F32 */
787 HReg dst;
788 HReg src;
789 } VCvtSD;
790 /* Transfer a VFP D reg to/from two integer registers (VMOV) */
791 struct {
792 Bool toD;
793 HReg dD;
794 HReg rHi;
795 HReg rLo;
796 } VXferD;
797 /* Transfer a VFP S reg to/from an integer register (VMOV) */
798 struct {
799 Bool toS;
800 HReg fD;
801 HReg rLo;
802 } VXferS;
803 /* Convert between 32-bit ints and 64-bit FP values (both ways
804 and both signednesses). (FSITOD, FUITOD, FTOSID, FTOUID) */
805 struct {
806 Bool iToD; /* True: I32->F64. False: F64->I32 */
807 Bool syned; /* True: I32 is signed. False: I32 is unsigned */
808 HReg dst;
809 HReg src;
810 } VCvtID;
811 /* Move a 32-bit value to/from the FPSCR (FMXR, FMRX) */
812 struct {
813 Bool toFPSCR;
814 HReg iReg;
815 } FPSCR;
sewardj412098c2010-05-04 08:48:43 +0000816 /* Mem fence. An insn which fences all loads and stores as
817 much as possible before continuing. On ARM we emit the
818 sequence
819 mcr 15,0,r0,c7,c10,4 (DSB)
820 mcr 15,0,r0,c7,c10,5 (DMB)
821 mcr 15,0,r0,c7,c5,4 (ISB)
822 which is probably total overkill, but better safe than
823 sorry.
824 */
825 struct {
826 } MFence;
sewardj6c60b322010-08-22 12:48:28 +0000827 /* Neon data processing instruction: 3 registers of the same
828 length */
829 struct {
830 ARMNeonBinOp op;
831 HReg dst;
832 HReg argL;
833 HReg argR;
834 UInt size;
835 Bool Q;
836 } NBinary;
837 struct {
838 ARMNeonBinOp op;
839 ARMNRS* dst;
840 ARMNRS* argL;
841 ARMNRS* argR;
842 UInt size;
843 Bool Q;
844 } NBinaryS;
845 struct {
846 ARMNeonShiftOp op;
847 HReg dst;
848 HReg argL;
849 HReg argR;
850 UInt size;
851 Bool Q;
852 } NShift;
853 struct {
854 Bool isLoad;
855 HReg dQ;
856 ARMAModeN *amode;
857 } NLdStQ;
858 struct {
859 Bool isLoad;
860 HReg dD;
861 ARMAModeN *amode;
862 } NLdStD;
863 struct {
sewardj6aa87a62010-10-06 20:34:53 +0000864 ARMNeonUnOpS op;
sewardj6c60b322010-08-22 12:48:28 +0000865 ARMNRS* dst;
866 ARMNRS* src;
867 UInt size;
868 Bool Q;
869 } NUnaryS;
870 struct {
871 ARMNeonUnOp op;
872 HReg dst;
873 HReg src;
874 UInt size;
875 Bool Q;
876 } NUnary;
877 /* Takes two arguments and modifies them both. */
878 struct {
879 ARMNeonDualOp op;
880 HReg arg1;
881 HReg arg2;
882 UInt size;
883 Bool Q;
884 } NDual;
885 struct {
886 HReg dst;
887 ARMNImm* imm;
888 } NeonImm;
889 /* 128-bit Neon move src to dst on the given condition, which
890 may not be ARMcc_AL. */
891 struct {
892 ARMCondCode cond;
893 HReg dst;
894 HReg src;
895 } NCMovQ;
896 struct {
897 /* Note: rD != rN */
898 HReg rD;
899 HReg rN;
900 UInt imm32;
901 } Add32;
cerion05782872004-12-16 11:50:19 +0000902 } ARMin;
903 }
904 ARMInstr;
905
cerion05782872004-12-16 11:50:19 +0000906
sewardj6c299f32009-12-31 18:00:12 +0000907extern ARMInstr* ARMInstr_Alu ( ARMAluOp, HReg, HReg, ARMRI84* );
908extern ARMInstr* ARMInstr_Shift ( ARMShiftOp, HReg, HReg, ARMRI5* );
909extern ARMInstr* ARMInstr_Unary ( ARMUnaryOp, HReg, HReg );
910extern ARMInstr* ARMInstr_CmpOrTst ( Bool isCmp, HReg, ARMRI84* );
911extern ARMInstr* ARMInstr_Mov ( HReg, ARMRI84* );
912extern ARMInstr* ARMInstr_Imm32 ( HReg, UInt );
913extern ARMInstr* ARMInstr_LdSt32 ( Bool isLoad, HReg, ARMAMode1* );
914extern ARMInstr* ARMInstr_LdSt16 ( Bool isLoad, Bool signedLoad,
915 HReg, ARMAMode2* );
916extern ARMInstr* ARMInstr_LdSt8U ( Bool isLoad, HReg, ARMAMode1* );
917extern ARMInstr* ARMInstr_Ld8S ( HReg, ARMAMode2* );
918extern ARMInstr* ARMInstr_Goto ( IRJumpKind, ARMCondCode, HReg gnext );
919extern ARMInstr* ARMInstr_CMov ( ARMCondCode, HReg dst, ARMRI84* src );
920extern ARMInstr* ARMInstr_Call ( ARMCondCode, HWord, Int nArgRegs );
921extern ARMInstr* ARMInstr_Mul ( ARMMulOp op );
922extern ARMInstr* ARMInstr_LdrEX ( Int szB );
923extern ARMInstr* ARMInstr_StrEX ( Int szB );
924extern ARMInstr* ARMInstr_VLdStD ( Bool isLoad, HReg, ARMAModeV* );
925extern ARMInstr* ARMInstr_VLdStS ( Bool isLoad, HReg, ARMAModeV* );
926extern ARMInstr* ARMInstr_VAluD ( ARMVfpOp op, HReg, HReg, HReg );
927extern ARMInstr* ARMInstr_VAluS ( ARMVfpOp op, HReg, HReg, HReg );
928extern ARMInstr* ARMInstr_VUnaryD ( ARMVfpUnaryOp, HReg dst, HReg src );
929extern ARMInstr* ARMInstr_VUnaryS ( ARMVfpUnaryOp, HReg dst, HReg src );
930extern ARMInstr* ARMInstr_VCmpD ( HReg argL, HReg argR );
931extern ARMInstr* ARMInstr_VCMovD ( ARMCondCode, HReg dst, HReg src );
932extern ARMInstr* ARMInstr_VCMovS ( ARMCondCode, HReg dst, HReg src );
933extern ARMInstr* ARMInstr_VCvtSD ( Bool sToD, HReg dst, HReg src );
934extern ARMInstr* ARMInstr_VXferD ( Bool toD, HReg dD, HReg rHi, HReg rLo );
935extern ARMInstr* ARMInstr_VXferS ( Bool toS, HReg fD, HReg rLo );
936extern ARMInstr* ARMInstr_VCvtID ( Bool iToD, Bool syned,
937 HReg dst, HReg src );
938extern ARMInstr* ARMInstr_FPSCR ( Bool toFPSCR, HReg iReg );
sewardj412098c2010-05-04 08:48:43 +0000939extern ARMInstr* ARMInstr_MFence ( void );
sewardj6c60b322010-08-22 12:48:28 +0000940extern ARMInstr* ARMInstr_NLdStQ ( Bool isLoad, HReg, ARMAModeN* );
941extern ARMInstr* ARMInstr_NLdStD ( Bool isLoad, HReg, ARMAModeN* );
942extern ARMInstr* ARMInstr_NUnary ( ARMNeonUnOp, HReg, HReg, UInt, Bool );
943extern ARMInstr* ARMInstr_NUnaryS ( ARMNeonUnOp, ARMNRS*, ARMNRS*,
944 UInt, Bool );
945extern ARMInstr* ARMInstr_NDual ( ARMNeonDualOp, HReg, HReg, UInt, Bool );
946extern ARMInstr* ARMInstr_NBinary ( ARMNeonBinOp, HReg, HReg, HReg,
947 UInt, Bool );
948extern ARMInstr* ARMInstr_NShift ( ARMNeonShiftOp, HReg, HReg, HReg,
949 UInt, Bool );
950extern ARMInstr* ARMInstr_NeonImm ( HReg, ARMNImm* );
951extern ARMInstr* ARMInstr_NCMovQ ( ARMCondCode, HReg, HReg );
952extern ARMInstr* ARMInstr_Add32 ( HReg rD, HReg rN, UInt imm32 );
cerion05782872004-12-16 11:50:19 +0000953
954extern void ppARMInstr ( ARMInstr* );
955
956
cerion05782872004-12-16 11:50:19 +0000957/* Some functions that insulate the register allocator from details
958 of the underlying instruction set. */
sewardj6c299f32009-12-31 18:00:12 +0000959extern void getRegUsage_ARMInstr ( HRegUsage*, ARMInstr*, Bool );
960extern void mapRegs_ARMInstr ( HRegRemap*, ARMInstr*, Bool );
961extern Bool isMove_ARMInstr ( ARMInstr*, HReg*, HReg* );
962extern Int emit_ARMInstr ( UChar* buf, Int nbuf, ARMInstr*,
963 Bool, void* dispatch );
964
965extern void genSpill_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
966 HReg rreg, Int offset, Bool );
967extern void genReload_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
968 HReg rreg, Int offset, Bool );
969
970extern void getAllocableRegs_ARM ( Int*, HReg** );
971extern HInstrArray* iselSB_ARM ( IRSB*, VexArch,
972 VexArchInfo*, VexAbiInfo* );
cerion05782872004-12-16 11:50:19 +0000973
sewardjcef7d3e2009-07-02 12:21:59 +0000974#endif /* ndef __VEX_HOST_ARM_DEFS_H */
cerion05782872004-12-16 11:50:19 +0000975
976/*---------------------------------------------------------------*/
sewardjcef7d3e2009-07-02 12:21:59 +0000977/*--- end host_arm_defs.h ---*/
cerion05782872004-12-16 11:50:19 +0000978/*---------------------------------------------------------------*/