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 (at) 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 43 ST_IN HReg hregARM_R4 ( void ) { return mkHReg(False, HRcInt32, 4, 0); } 44 ST_IN HReg hregARM_R5 ( void ) { return mkHReg(False, HRcInt32, 5, 1); } 45 ST_IN HReg hregARM_R6 ( void ) { return mkHReg(False, HRcInt32, 6, 2); } 46 ST_IN HReg hregARM_R7 ( void ) { return mkHReg(False, HRcInt32, 7, 3); } 47 ST_IN HReg hregARM_R10 ( void ) { return mkHReg(False, HRcInt32, 10, 4); } 48 ST_IN HReg hregARM_R11 ( void ) { return mkHReg(False, HRcInt32, 11, 5); } 49 50 ST_IN HReg hregARM_R0 ( void ) { return mkHReg(False, HRcInt32, 0, 6); } 51 ST_IN HReg hregARM_R1 ( void ) { return mkHReg(False, HRcInt32, 1, 7); } 52 ST_IN HReg hregARM_R2 ( void ) { return mkHReg(False, HRcInt32, 2, 8); } 53 ST_IN HReg hregARM_R3 ( void ) { return mkHReg(False, HRcInt32, 3, 9); } 54 ST_IN HReg hregARM_R9 ( void ) { return mkHReg(False, HRcInt32, 9, 10); } 55 56 ST_IN HReg hregARM_D8 ( void ) { return mkHReg(False, HRcFlt64, 8, 11); } 57 ST_IN HReg hregARM_D9 ( void ) { return mkHReg(False, HRcFlt64, 9, 12); } 58 ST_IN HReg hregARM_D10 ( void ) { return mkHReg(False, HRcFlt64, 10, 13); } 59 ST_IN HReg hregARM_D11 ( void ) { return mkHReg(False, HRcFlt64, 11, 14); } 60 ST_IN HReg hregARM_D12 ( void ) { return mkHReg(False, HRcFlt64, 12, 15); } 61 62 ST_IN HReg hregARM_S26 ( void ) { return mkHReg(False, HRcFlt32, 26, 16); } 63 ST_IN HReg hregARM_S27 ( void ) { return mkHReg(False, HRcFlt32, 27, 17); } 64 ST_IN HReg hregARM_S28 ( void ) { return mkHReg(False, HRcFlt32, 28, 18); } 65 ST_IN HReg hregARM_S29 ( void ) { return mkHReg(False, HRcFlt32, 29, 19); } 66 ST_IN HReg hregARM_S30 ( void ) { return mkHReg(False, HRcFlt32, 30, 20); } 67 68 ST_IN HReg hregARM_Q8 ( void ) { return mkHReg(False, HRcVec128, 8, 21); } 69 ST_IN HReg hregARM_Q9 ( void ) { return mkHReg(False, HRcVec128, 9, 22); } 70 ST_IN HReg hregARM_Q10 ( void ) { return mkHReg(False, HRcVec128, 10, 23); } 71 ST_IN HReg hregARM_Q11 ( void ) { return mkHReg(False, HRcVec128, 11, 24); } 72 ST_IN HReg hregARM_Q12 ( void ) { return mkHReg(False, HRcVec128, 12, 25); } 73 74 ST_IN HReg hregARM_R8 ( void ) { return mkHReg(False, HRcInt32, 8, 26); } 75 ST_IN HReg hregARM_R12 ( void ) { return mkHReg(False, HRcInt32, 12, 27); } 76 ST_IN HReg hregARM_R13 ( void ) { return mkHReg(False, HRcInt32, 13, 28); } 77 ST_IN HReg hregARM_R14 ( void ) { return mkHReg(False, HRcInt32, 14, 29); } 78 ST_IN HReg hregARM_R15 ( void ) { return mkHReg(False, HRcInt32, 15, 30); } 79 ST_IN HReg hregARM_Q13 ( void ) { return mkHReg(False, HRcVec128, 13, 31); } 80 ST_IN HReg hregARM_Q14 ( void ) { return mkHReg(False, HRcVec128, 14, 32); } 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