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