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