1 // Copyright (c) 1994-2006 Sun Microsystems Inc. 2 // All Rights Reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions 6 // are met: 7 // 8 // - Redistributions of source code must retain the above copyright notice, 9 // this list of conditions and the following disclaimer. 10 // 11 // - Redistribution in binary form must reproduce the above copyright 12 // notice, this list of conditions and the following disclaimer in the 13 // documentation and/or other materials provided with the 14 // distribution. 15 // 16 // - Neither the name of Sun Microsystems or the names of contributors may 17 // be used to endorse or promote products derived from this software without 18 // specific prior written permission. 19 // 20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24 // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 29 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 31 // OF THE POSSIBILITY OF SUCH DAMAGE. 32 33 // The original source code covered by the above license above has been 34 // modified significantly by Google Inc. 35 // Copyright 2014 the V8 project authors. All rights reserved. 36 37 // A light-weight S390 Assembler 38 // Generates user mode instructions for z/Architecture 39 40 #ifndef V8_S390_ASSEMBLER_S390_H_ 41 #define V8_S390_ASSEMBLER_S390_H_ 42 #include <stdio.h> 43 #if V8_HOST_ARCH_S390 44 // elf.h include is required for auxv check for STFLE facility used 45 // for hardware detection, which is sensible only on s390 hosts. 46 #include <elf.h> 47 #endif 48 49 #include <fcntl.h> 50 #include <unistd.h> 51 #include "src/assembler.h" 52 #include "src/s390/constants-s390.h" 53 54 #define ABI_USES_FUNCTION_DESCRIPTORS 0 55 56 #define ABI_PASSES_HANDLES_IN_REGS 1 57 58 // ObjectPair is defined under runtime/runtime-util.h. 59 // On 31-bit, ObjectPair == uint64_t. ABI dictates long long 60 // be returned with the lower addressed half in r2 61 // and the higher addressed half in r3. (Returns in Regs) 62 // On 64-bit, ObjectPair is a Struct. ABI dictaes Structs be 63 // returned in a storage buffer allocated by the caller, 64 // with the address of this buffer passed as a hidden 65 // argument in r2. (Does NOT return in Regs) 66 // For x86 linux, ObjectPair is returned in registers. 67 #if V8_TARGET_ARCH_S390X 68 #define ABI_RETURNS_OBJECTPAIR_IN_REGS 0 69 #else 70 #define ABI_RETURNS_OBJECTPAIR_IN_REGS 1 71 #endif 72 73 #define ABI_CALL_VIA_IP 1 74 75 #define INSTR_AND_DATA_CACHE_COHERENCY LWSYNC 76 77 namespace v8 { 78 namespace internal { 79 80 // clang-format off 81 #define GENERAL_REGISTERS(V) \ 82 V(r0) V(r1) V(r2) V(r3) V(r4) V(r5) V(r6) V(r7) \ 83 V(r8) V(r9) V(r10) V(fp) V(ip) V(r13) V(r14) V(sp) 84 85 #define ALLOCATABLE_GENERAL_REGISTERS(V) \ 86 V(r2) V(r3) V(r4) V(r5) V(r6) V(r7) \ 87 V(r8) V(r9) V(r13) 88 89 #define DOUBLE_REGISTERS(V) \ 90 V(d0) V(d1) V(d2) V(d3) V(d4) V(d5) V(d6) V(d7) \ 91 V(d8) V(d9) V(d10) V(d11) V(d12) V(d13) V(d14) V(d15) 92 93 #define FLOAT_REGISTERS DOUBLE_REGISTERS 94 95 #define ALLOCATABLE_DOUBLE_REGISTERS(V) \ 96 V(d1) V(d2) V(d3) V(d4) V(d5) V(d6) V(d7) \ 97 V(d8) V(d9) V(d10) V(d11) V(d12) V(d15) V(d0) 98 // clang-format on 99 100 // CPU Registers. 101 // 102 // 1) We would prefer to use an enum, but enum values are assignment- 103 // compatible with int, which has caused code-generation bugs. 104 // 105 // 2) We would prefer to use a class instead of a struct but we don't like 106 // the register initialization to depend on the particular initialization 107 // order (which appears to be different on OS X, Linux, and Windows for the 108 // installed versions of C++ we tried). Using a struct permits C-style 109 // "initialization". Also, the Register objects cannot be const as this 110 // forces initialization stubs in MSVC, making us dependent on initialization 111 // order. 112 // 113 // 3) By not using an enum, we are possibly preventing the compiler from 114 // doing certain constant folds, which may significantly reduce the 115 // code generated for some assembly instructions (because they boil down 116 // to a few constants). If this is a problem, we could change the code 117 // such that we use an enum in optimized mode, and the struct in debug 118 // mode. This way we get the compile-time error checking in debug mode 119 // and best performance in optimized code. 120 121 struct Register { 122 enum Code { 123 #define REGISTER_CODE(R) kCode_##R, 124 GENERAL_REGISTERS(REGISTER_CODE) 125 #undef REGISTER_CODE 126 kAfterLast, 127 kCode_no_reg = -1 128 }; 129 static const int kNumRegisters = Code::kAfterLast; 130 131 #define REGISTER_COUNT(R) 1 + 132 static const int kNumAllocatable = 133 ALLOCATABLE_GENERAL_REGISTERS(REGISTER_COUNT) 0; 134 #undef REGISTER_COUNT 135 136 #define REGISTER_BIT(R) 1 << kCode_##R | 137 static const RegList kAllocatable = 138 ALLOCATABLE_GENERAL_REGISTERS(REGISTER_BIT) 0; 139 #undef REGISTER_BIT 140 from_codeRegister141 static Register from_code(int code) { 142 DCHECK(code >= 0); 143 DCHECK(code < kNumRegisters); 144 Register r = {code}; 145 return r; 146 } 147 is_validRegister148 bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; } isRegister149 bool is(Register reg) const { return reg_code == reg.reg_code; } codeRegister150 int code() const { 151 DCHECK(is_valid()); 152 return reg_code; 153 } bitRegister154 int bit() const { 155 DCHECK(is_valid()); 156 return 1 << reg_code; 157 } 158 set_codeRegister159 void set_code(int code) { 160 reg_code = code; 161 DCHECK(is_valid()); 162 } 163 164 #if V8_TARGET_LITTLE_ENDIAN 165 static const int kMantissaOffset = 0; 166 static const int kExponentOffset = 4; 167 #else 168 static const int kMantissaOffset = 4; 169 static const int kExponentOffset = 0; 170 #endif 171 172 // Unfortunately we can't make this private in a struct. 173 int reg_code; 174 }; 175 176 typedef struct Register Register; 177 178 #define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R}; 179 GENERAL_REGISTERS(DECLARE_REGISTER) 180 #undef DECLARE_REGISTER 181 const Register no_reg = {Register::kCode_no_reg}; 182 183 // Register aliases 184 const Register kLithiumScratch = r1; // lithium scratch. 185 const Register kRootRegister = r10; // Roots array pointer. 186 const Register cp = r13; // JavaScript context pointer. 187 188 static const bool kSimpleFPAliasing = true; 189 190 // Double word FP register. 191 struct DoubleRegister { 192 enum Code { 193 #define REGISTER_CODE(R) kCode_##R, 194 DOUBLE_REGISTERS(REGISTER_CODE) 195 #undef REGISTER_CODE 196 kAfterLast, 197 kCode_no_reg = -1 198 }; 199 200 static const int kNumRegisters = Code::kAfterLast; 201 static const int kMaxNumRegisters = kNumRegisters; 202 is_validDoubleRegister203 bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; } isDoubleRegister204 bool is(DoubleRegister reg) const { return reg_code == reg.reg_code; } 205 codeDoubleRegister206 int code() const { 207 DCHECK(is_valid()); 208 return reg_code; 209 } 210 bitDoubleRegister211 int bit() const { 212 DCHECK(is_valid()); 213 return 1 << reg_code; 214 } 215 from_codeDoubleRegister216 static DoubleRegister from_code(int code) { 217 DoubleRegister r = {code}; 218 return r; 219 } 220 221 int reg_code; 222 }; 223 224 typedef DoubleRegister FloatRegister; 225 226 // TODO(john.yan) Define SIMD registers. 227 typedef DoubleRegister Simd128Register; 228 229 #define DECLARE_REGISTER(R) \ 230 const DoubleRegister R = {DoubleRegister::kCode_##R}; 231 DOUBLE_REGISTERS(DECLARE_REGISTER) 232 #undef DECLARE_REGISTER 233 const Register no_dreg = {Register::kCode_no_reg}; 234 235 // Aliases for double registers. Defined using #define instead of 236 // "static const DoubleRegister&" because Clang complains otherwise when a 237 // compilation unit that includes this header doesn't use the variables. 238 #define kDoubleRegZero d14 239 #define kScratchDoubleReg d13 240 241 Register ToRegister(int num); 242 243 // Coprocessor register 244 struct CRegister { is_validCRegister245 bool is_valid() const { return 0 <= reg_code && reg_code < 8; } isCRegister246 bool is(CRegister creg) const { return reg_code == creg.reg_code; } codeCRegister247 int code() const { 248 DCHECK(is_valid()); 249 return reg_code; 250 } bitCRegister251 int bit() const { 252 DCHECK(is_valid()); 253 return 1 << reg_code; 254 } 255 256 // Unfortunately we can't make this private in a struct. 257 int reg_code; 258 }; 259 260 const CRegister no_creg = {-1}; 261 262 const CRegister cr0 = {0}; 263 const CRegister cr1 = {1}; 264 const CRegister cr2 = {2}; 265 const CRegister cr3 = {3}; 266 const CRegister cr4 = {4}; 267 const CRegister cr5 = {5}; 268 const CRegister cr6 = {6}; 269 const CRegister cr7 = {7}; 270 271 // ----------------------------------------------------------------------------- 272 // Machine instruction Operands 273 274 #if V8_TARGET_ARCH_S390X 275 const RelocInfo::Mode kRelocInfo_NONEPTR = RelocInfo::NONE64; 276 #else 277 const RelocInfo::Mode kRelocInfo_NONEPTR = RelocInfo::NONE32; 278 #endif 279 280 // Class Operand represents a shifter operand in data processing instructions 281 // defining immediate numbers and masks 282 typedef uint8_t Length; 283 284 struct Mask { 285 uint8_t mask; valueMask286 uint8_t value() { return mask; } from_valueMask287 static Mask from_value(uint8_t input) { 288 DCHECK(input <= 0x0F); 289 Mask m = {input}; 290 return m; 291 } 292 }; 293 294 class Operand BASE_EMBEDDED { 295 public: 296 // immediate 297 INLINE(explicit Operand(intptr_t immediate, 298 RelocInfo::Mode rmode = kRelocInfo_NONEPTR)); INLINE(static Operand Zero ())299 INLINE(static Operand Zero()) { return Operand(static_cast<intptr_t>(0)); } 300 INLINE(explicit Operand(const ExternalReference& f)); 301 explicit Operand(Handle<Object> handle); 302 INLINE(explicit Operand(Smi* value)); 303 304 // rm 305 INLINE(explicit Operand(Register rm)); 306 307 // Return true if this is a register operand. 308 INLINE(bool is_reg() const); 309 310 bool must_output_reloc_info(const Assembler* assembler) const; 311 immediate()312 inline intptr_t immediate() const { 313 DCHECK(!rm_.is_valid()); 314 return imm_; 315 } 316 setBits(int n)317 inline void setBits(int n) { 318 imm_ = (static_cast<uint32_t>(imm_) << (32 - n)) >> (32 - n); 319 } 320 rm()321 Register rm() const { return rm_; } 322 323 private: 324 Register rm_; 325 intptr_t imm_; // valid if rm_ == no_reg 326 RelocInfo::Mode rmode_; 327 328 friend class Assembler; 329 friend class MacroAssembler; 330 }; 331 332 typedef int32_t Disp; 333 334 // Class MemOperand represents a memory operand in load and store instructions 335 // On S390, we have various flavours of memory operands: 336 // 1) a base register + 16 bit unsigned displacement 337 // 2) a base register + index register + 16 bit unsigned displacement 338 // 3) a base register + index register + 20 bit signed displacement 339 class MemOperand BASE_EMBEDDED { 340 public: 341 explicit MemOperand(Register rx, Disp offset = 0); 342 explicit MemOperand(Register rx, Register rb, Disp offset = 0); 343 offset()344 int32_t offset() const { return offset_; } getDisplacement()345 uint32_t getDisplacement() const { return offset(); } 346 347 // Base register rb()348 Register rb() const { 349 DCHECK(!baseRegister.is(no_reg)); 350 return baseRegister; 351 } 352 getBaseRegister()353 Register getBaseRegister() const { return rb(); } 354 355 // Index Register rx()356 Register rx() const { 357 DCHECK(!indexRegister.is(no_reg)); 358 return indexRegister; 359 } getIndexRegister()360 Register getIndexRegister() const { return rx(); } 361 362 private: 363 Register baseRegister; // base 364 Register indexRegister; // index 365 int32_t offset_; // offset 366 367 friend class Assembler; 368 }; 369 370 class DeferredRelocInfo { 371 public: DeferredRelocInfo()372 DeferredRelocInfo() {} DeferredRelocInfo(int position,RelocInfo::Mode rmode,intptr_t data)373 DeferredRelocInfo(int position, RelocInfo::Mode rmode, intptr_t data) 374 : position_(position), rmode_(rmode), data_(data) {} 375 position()376 int position() const { return position_; } rmode()377 RelocInfo::Mode rmode() const { return rmode_; } data()378 intptr_t data() const { return data_; } 379 380 private: 381 int position_; 382 RelocInfo::Mode rmode_; 383 intptr_t data_; 384 }; 385 386 class Assembler : public AssemblerBase { 387 public: 388 // Create an assembler. Instructions and relocation information are emitted 389 // into a buffer, with the instructions starting from the beginning and the 390 // relocation information starting from the end of the buffer. See CodeDesc 391 // for a detailed comment on the layout (globals.h). 392 // 393 // If the provided buffer is NULL, the assembler allocates and grows its own 394 // buffer, and buffer_size determines the initial buffer size. The buffer is 395 // owned by the assembler and deallocated upon destruction of the assembler. 396 // 397 // If the provided buffer is not NULL, the assembler uses the provided buffer 398 // for code generation and assumes its size to be buffer_size. If the buffer 399 // is too small, a fatal error occurs. No deallocation of the buffer is done 400 // upon destruction of the assembler. 401 Assembler(Isolate* isolate, void* buffer, int buffer_size); ~Assembler()402 virtual ~Assembler() {} 403 404 // GetCode emits any pending (non-emitted) code and fills the descriptor 405 // desc. GetCode() is idempotent; it returns the same result if no other 406 // Assembler functions are invoked in between GetCode() calls. 407 void GetCode(CodeDesc* desc); 408 409 // Label operations & relative jumps (PPUM Appendix D) 410 // 411 // Takes a branch opcode (cc) and a label (L) and generates 412 // either a backward branch or a forward branch and links it 413 // to the label fixup chain. Usage: 414 // 415 // Label L; // unbound label 416 // j(cc, &L); // forward branch to unbound label 417 // bind(&L); // bind label to the current pc 418 // j(cc, &L); // backward branch to bound label 419 // bind(&L); // illegal: a label may be bound only once 420 // 421 // Note: The same Label can be used for forward and backward branches 422 // but it may be bound only once. 423 424 void bind(Label* L); // binds an unbound label L to the current code position 425 426 // Links a label at the current pc_offset(). If already bound, returns the 427 // bound position. If already linked, returns the position of the prior link. 428 // Otherwise, returns the current pc_offset(). 429 int link(Label* L); 430 431 // Determines if Label is bound and near enough so that a single 432 // branch instruction can be used to reach it. 433 bool is_near(Label* L, Condition cond); 434 435 // Returns the branch offset to the given label from the current code position 436 // Links the label to the current position if it is still unbound branch_offset(Label * L)437 int branch_offset(Label* L) { return link(L) - pc_offset(); } 438 439 // Puts a labels target address at the given position. 440 // The high 8 bits are set to zero. 441 void label_at_put(Label* L, int at_offset); 442 void load_label_offset(Register r1, Label* L); 443 444 // Read/Modify the code target address in the branch/call instruction at pc. 445 INLINE(static Address target_address_at(Address pc, Address constant_pool)); 446 INLINE(static void set_target_address_at( 447 Isolate* isolate, Address pc, Address constant_pool, Address target, 448 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)); INLINE(static Address target_address_at (Address pc,Code * code))449 INLINE(static Address target_address_at(Address pc, Code* code)) { 450 Address constant_pool = NULL; 451 return target_address_at(pc, constant_pool); 452 } INLINE(static void set_target_address_at (Isolate * isolate,Address pc,Code * code,Address target,ICacheFlushMode icache_flush_mode=FLUSH_ICACHE_IF_NEEDED))453 INLINE(static void set_target_address_at( 454 Isolate* isolate, Address pc, Code* code, Address target, 455 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)) { 456 Address constant_pool = NULL; 457 set_target_address_at(isolate, pc, constant_pool, target, 458 icache_flush_mode); 459 } 460 461 // Return the code target address at a call site from the return address 462 // of that call in the instruction stream. 463 inline static Address target_address_from_return_address(Address pc); 464 465 // Given the address of the beginning of a call, return the address 466 // in the instruction stream that the call will return to. 467 INLINE(static Address return_address_from_call_start(Address pc)); 468 469 inline Handle<Object> code_target_object_handle_at(Address pc); 470 // This sets the branch destination. 471 // This is for calls and branches within generated code. 472 inline static void deserialization_set_special_target_at( 473 Isolate* isolate, Address instruction_payload, Code* code, 474 Address target); 475 476 // This sets the internal reference at the pc. 477 inline static void deserialization_set_target_internal_reference_at( 478 Isolate* isolate, Address pc, Address target, 479 RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE); 480 481 // Here we are patching the address in the IIHF/IILF instruction pair. 482 // These values are used in the serialization process and must be zero for 483 // S390 platform, as Code, Embedded Object or External-reference pointers 484 // are split across two consecutive instructions and don't exist separately 485 // in the code, so the serializer should not step forwards in memory after 486 // a target is resolved and written. 487 static const int kSpecialTargetSize = 0; 488 489 // Number of bytes for instructions used to store pointer sized constant. 490 #if V8_TARGET_ARCH_S390X 491 static const int kBytesForPtrConstant = 12; // IIHF + IILF 492 #else 493 static const int kBytesForPtrConstant = 6; // IILF 494 #endif 495 496 // Distance between the instruction referring to the address of the call 497 // target and the return address. 498 499 // Offset between call target address and return address 500 // for BRASL calls 501 // Patch will be appiled to other FIXED_SEQUENCE call 502 static const int kCallTargetAddressOffset = 6; 503 504 // The length of FIXED_SEQUENCE call 505 // iihf r8, <address_hi> // <64-bit only> 506 // iilf r8, <address_lo> 507 // basr r14, r8 508 #if V8_TARGET_ARCH_S390X 509 static const int kCallSequenceLength = 14; 510 #else 511 static const int kCallSequenceLength = 8; 512 #endif 513 514 // This is the length of the BreakLocationIterator::SetDebugBreakAtReturn() 515 // code patch FIXED_SEQUENCE in bytes! 516 // JS Return Sequence = Call Sequence + BKPT 517 // static const int kJSReturnSequenceLength = kCallSequenceLength + 2; 518 519 // This is the length of the code sequence from SetDebugBreakAtSlot() 520 // FIXED_SEQUENCE in bytes! 521 static const int kDebugBreakSlotLength = kCallSequenceLength; 522 static const int kPatchDebugBreakSlotReturnOffset = kCallTargetAddressOffset; 523 524 // Length to patch between the start of the JS return sequence 525 // from SetDebugBreakAtReturn and the address from 526 // break_address_from_return_address. 527 // 528 // frame->pc() in Debug::SetAfterBreakTarget will point to BKPT in 529 // JS return sequence, so the length to patch will not include BKPT 530 // instruction length. 531 // static const int kPatchReturnSequenceAddressOffset = 532 // kCallSequenceLength - kPatchDebugBreakSlotReturnOffset; 533 534 // Length to patch between the start of the FIXED call sequence from 535 // SetDebugBreakAtSlot() and the the address from 536 // break_address_from_return_address. 537 static const int kPatchDebugBreakSlotAddressOffset = 538 kDebugBreakSlotLength - kPatchDebugBreakSlotReturnOffset; 539 encode_crbit(const CRegister & cr,enum CRBit crbit)540 static inline int encode_crbit(const CRegister& cr, enum CRBit crbit) { 541 return ((cr.code() * CRWIDTH) + crbit); 542 } 543 544 // --------------------------------------------------------------------------- 545 // Code generation 546 547 // Helper for unconditional branch to Label with update to save register b(Register r,Label * l)548 void b(Register r, Label* l) { 549 int32_t halfwords = branch_offset(l) / 2; 550 brasl(r, Operand(halfwords)); 551 } 552 553 // Conditional Branch Instruction - Generates either BRC / BRCL 554 void branchOnCond(Condition c, int branch_offset, bool is_bound = false); 555 556 // Helpers for conditional branch to Label 557 void b(Condition cond, Label* l, Label::Distance dist = Label::kFar) { 558 branchOnCond(cond, branch_offset(l), 559 l->is_bound() || (dist == Label::kNear)); 560 } 561 562 void bc_short(Condition cond, Label* l, Label::Distance dist = Label::kFar) { 563 b(cond, l, Label::kNear); 564 } 565 // Helpers for conditional branch to Label 566 void beq(Label* l, Label::Distance dist = Label::kFar) { b(eq, l, dist); } 567 void bne(Label* l, Label::Distance dist = Label::kFar) { b(ne, l, dist); } 568 void blt(Label* l, Label::Distance dist = Label::kFar) { b(lt, l, dist); } 569 void ble(Label* l, Label::Distance dist = Label::kFar) { b(le, l, dist); } 570 void bgt(Label* l, Label::Distance dist = Label::kFar) { b(gt, l, dist); } 571 void bge(Label* l, Label::Distance dist = Label::kFar) { b(ge, l, dist); } 572 void b(Label* l, Label::Distance dist = Label::kFar) { b(al, l, dist); } 573 void jmp(Label* l, Label::Distance dist = Label::kFar) { b(al, l, dist); } 574 void bunordered(Label* l, Label::Distance dist = Label::kFar) { 575 b(unordered, l, dist); 576 } 577 void bordered(Label* l, Label::Distance dist = Label::kFar) { 578 b(ordered, l, dist); 579 } 580 581 // Helpers for conditional indirect branch off register b(Condition cond,Register r)582 void b(Condition cond, Register r) { bcr(cond, r); } beq(Register r)583 void beq(Register r) { b(eq, r); } bne(Register r)584 void bne(Register r) { b(ne, r); } blt(Register r)585 void blt(Register r) { b(lt, r); } ble(Register r)586 void ble(Register r) { b(le, r); } bgt(Register r)587 void bgt(Register r) { b(gt, r); } bge(Register r)588 void bge(Register r) { b(ge, r); } b(Register r)589 void b(Register r) { b(al, r); } jmp(Register r)590 void jmp(Register r) { b(al, r); } bunordered(Register r)591 void bunordered(Register r) { b(unordered, r); } bordered(Register r)592 void bordered(Register r) { b(ordered, r); } 593 594 // --------------------------------------------------------------------------- 595 // Code generation 596 597 // Insert the smallest number of nop instructions 598 // possible to align the pc offset to a multiple 599 // of m. m must be a power of 2 (>= 4). 600 void Align(int m); 601 // Insert the smallest number of zero bytes possible to align the pc offset 602 // to a mulitple of m. m must be a power of 2 (>= 2). 603 void DataAlign(int m); 604 // Aligns code to something that's optimal for a jump target for the platform. 605 void CodeTargetAlign(); 606 breakpoint(bool do_print)607 void breakpoint(bool do_print) { 608 if (do_print) { 609 PrintF("DebugBreak is inserted to %p\n", static_cast<void*>(pc_)); 610 } 611 #if V8_HOST_ARCH_64_BIT 612 int64_t value = reinterpret_cast<uint64_t>(&v8::base::OS::DebugBreak); 613 int32_t hi_32 = static_cast<int64_t>(value) >> 32; 614 int32_t lo_32 = static_cast<int32_t>(value); 615 616 iihf(r1, Operand(hi_32)); 617 iilf(r1, Operand(lo_32)); 618 #else 619 iilf(r1, Operand(reinterpret_cast<uint32_t>(&v8::base::OS::DebugBreak))); 620 #endif 621 basr(r14, r1); 622 } 623 624 void call(Handle<Code> target, RelocInfo::Mode rmode, 625 TypeFeedbackId ast_id = TypeFeedbackId::None()); 626 void jump(Handle<Code> target, RelocInfo::Mode rmode, Condition cond); 627 628 // S390 instruction generation 629 #define I_FORM(name) void name(const Operand& i) 630 631 #define RR_FORM(name) void name(Register r1, Register r2) 632 633 #define RR2_FORM(name) void name(Condition m1, Register r2) 634 635 #define RX_FORM(name) \ 636 void name(Register r1, Register x2, Register b2, Disp d2); \ 637 void name(Register r1, const MemOperand& opnd) 638 639 #define RI1_FORM(name) void name(Register r, const Operand& i) 640 641 #define RI2_FORM(name) void name(Condition m, const Operand& i) 642 643 #define RIE_FORM(name) void name(Register r1, Register R3, const Operand& i) 644 645 #define RIE_F_FORM(name) \ 646 void name(Register r1, Register r2, const Operand& i3, const Operand& i4, \ 647 const Operand& i5) 648 649 #define RIL1_FORM(name) void name(Register r1, const Operand& i2) 650 651 #define RIL2_FORM(name) void name(Condition m1, const Operand& i2) 652 653 #define RXE_FORM(name) \ 654 void name(Register r1, const MemOperand& opnd); \ 655 void name(Register r1, Register b2, Register x2, Disp d2) 656 657 #define RXF_FORM(name) \ 658 void name(Register r1, Register r3, const MemOperand& opnd); \ 659 void name(Register r1, Register r3, Register b2, Register x2, Disp d2) 660 661 #define RXY_FORM(name) \ 662 void name(Register r1, Register x2, Register b2, Disp d2); \ 663 void name(Register r1, const MemOperand& opnd) 664 665 #define RSI_FORM(name) void name(Register r1, Register r3, const Operand& i) 666 667 #define RIS_FORM(name) \ 668 void name(Register r1, Condition m3, Register b4, Disp d4, \ 669 const Operand& i2); \ 670 void name(Register r1, const Operand& i2, Condition m3, \ 671 const MemOperand& opnd) 672 673 #define SI_FORM(name) \ 674 void name(const MemOperand& opnd, const Operand& i); \ 675 void name(const Operand& i2, Register b1, Disp d1) 676 677 #define SIL_FORM(name) \ 678 void name(Register b1, Disp d1, const Operand& i2); \ 679 void name(const MemOperand& opnd, const Operand& i2) 680 681 #define RRE_FORM(name) void name(Register r1, Register r2) 682 683 #define RRF1_FORM(name) void name(Register r1, Register r2, Register r3) 684 685 #define RRF2_FORM(name) void name(Condition m1, Register r1, Register r2) 686 687 #define RRF3_FORM(name) \ 688 void name(Register r3, Condition m4, Register r1, Register r2) 689 690 #define RS1_FORM(name) \ 691 void name(Register r1, Register r3, const MemOperand& opnd); \ 692 void name(Register r1, Register r3, Register b2, Disp d2) 693 694 #define RS2_FORM(name) \ 695 void name(Register r1, Condition m3, const MemOperand& opnd); \ 696 void name(Register r1, Condition m3, Register b2, Disp d2) 697 698 #define RSE_FORM(name) \ 699 void name(Register r1, Register r3, const MemOperand& opnd); \ 700 void name(Register r1, Register r3, Register b2, Disp d2) 701 702 #define RSL_FORM(name) \ 703 void name(Length l, Register b2, Disp d2); \ 704 void name(const MemOperand& opnd) 705 706 #define RSY1_FORM(name) \ 707 void name(Register r1, Register r3, Register b2, Disp d2); \ 708 void name(Register r1, Register r3, const MemOperand& opnd) 709 710 #define RSY2_FORM(name) \ 711 void name(Register r1, Condition m3, Register b2, Disp d2); \ 712 void name(Register r1, Condition m3, const MemOperand& opnd) 713 714 #define RRD_FORM(name) void name(Register r1, Register r3, Register r2) 715 716 #define RRS_FORM(name) \ 717 void name(Register r1, Register r2, Register b4, Disp d4, Condition m3); \ 718 void name(Register r1, Register r2, Condition m3, const MemOperand& opnd) 719 720 #define S_FORM(name) \ 721 void name(Register b2, Disp d2); \ 722 void name(const MemOperand& opnd) 723 724 #define SIY_FORM(name) \ 725 void name(const Operand& i2, Register b1, Disp d1); \ 726 void name(const MemOperand& opnd, const Operand& i) 727 728 #define SS1_FORM(name) \ 729 void name(Register b1, Disp d1, Register b3, Disp d2, Length length); \ 730 void name(const MemOperand& opnd1, const MemOperand& opnd2, Length length) 731 732 #define SS2_FORM(name) \ 733 void name(const MemOperand& opnd1, const MemOperand& opnd2, Length length1, \ 734 Length length2); \ 735 void name(Register b1, Disp d1, Register b2, Disp d2, Length l1, Length l2) 736 737 #define SS3_FORM(name) \ 738 void name(const MemOperand& opnd1, const MemOperand& opnd2, Length length); \ 739 void name(const Operand& i3, Register b1, Disp d1, Register b2, Disp d2, \ 740 Length l1) 741 742 #define SS4_FORM(name) \ 743 void name(const MemOperand& opnd1, const MemOperand& opnd2); \ 744 void name(Register r1, Register r3, Register b1, Disp d1, Register b2, \ 745 Disp d2) 746 747 #define SS5_FORM(name) \ 748 void name(const MemOperand& opnd1, const MemOperand& opnd2); \ 749 void name(Register r1, Register r3, Register b3, Disp d2, Register b4, \ 750 Disp d4) 751 752 #define SSE_FORM(name) \ 753 void name(Register b1, Disp d1, Register b2, Disp d2); \ 754 void name(const MemOperand& opnd1, const MemOperand& opnd2) 755 756 #define SSF_FORM(name) \ 757 void name(Register r3, Register b1, Disp d1, Register b2, Disp d2); \ 758 void name(Register r3, const MemOperand& opnd1, const MemOperand& opnd2) 759 760 // S390 instruction sets 761 RX_FORM(bc); 762 RR_FORM(bctr); 763 RX_FORM(cd); 764 RRE_FORM(cdr); 765 RXE_FORM(cdb); 766 RXE_FORM(ceb); 767 RRE_FORM(cefbr); 768 RXE_FORM(ddb); 769 RRE_FORM(ddbr); 770 SS1_FORM(ed); 771 RRE_FORM(epair); 772 RX_FORM(ex); 773 RRF2_FORM(fidbr); 774 RRE_FORM(flogr); 775 RX_FORM(ic_z); 776 RXY_FORM(icy); 777 RIL1_FORM(iihf); 778 RI1_FORM(iihh); 779 RI1_FORM(iihl); 780 RIL1_FORM(iilf); 781 RI1_FORM(iilh); 782 RI1_FORM(iill); 783 RRE_FORM(lcgr); 784 RR_FORM(lcr); 785 RX_FORM(le_z); 786 RXY_FORM(ley); 787 RIL1_FORM(llihf); 788 RIL1_FORM(llilf); 789 RRE_FORM(lngr); 790 RR_FORM(lnr); 791 RSY1_FORM(loc); 792 RXY_FORM(lrv); 793 RXY_FORM(lrvh); 794 RXE_FORM(mdb); 795 RRE_FORM(mdbr); 796 SS4_FORM(mvck); 797 SSF_FORM(mvcos); 798 SS4_FORM(mvcs); 799 SS1_FORM(mvn); 800 SS1_FORM(nc); 801 SI_FORM(ni); 802 RIL1_FORM(nihf); 803 RIL1_FORM(nilf); 804 RI1_FORM(nilh); 805 RI1_FORM(nill); 806 RIL1_FORM(oihf); 807 RIL1_FORM(oilf); 808 RI1_FORM(oill); 809 RRE_FORM(popcnt); 810 RXE_FORM(sdb); 811 RRE_FORM(sdbr); 812 RIL1_FORM(slfi); 813 RXY_FORM(slgf); 814 RIL1_FORM(slgfi); 815 RS1_FORM(srdl); 816 RX_FORM(ste); 817 RXY_FORM(stey); 818 RXY_FORM(strv); 819 RI1_FORM(tmll); 820 SS1_FORM(tr); 821 S_FORM(ts); 822 RIL1_FORM(xihf); 823 RIL1_FORM(xilf); 824 825 // Load Address Instructions 826 void la(Register r, const MemOperand& opnd); 827 void lay(Register r, const MemOperand& opnd); 828 void larl(Register r1, const Operand& opnd); 829 void larl(Register r, Label* l); 830 831 // Load Instructions 832 void lb(Register r, const MemOperand& src); 833 void lbr(Register r1, Register r2); 834 void lgb(Register r, const MemOperand& src); 835 void lgbr(Register r1, Register r2); 836 void lh(Register r, const MemOperand& src); 837 void lhy(Register r, const MemOperand& src); 838 void lhr(Register r1, Register r2); 839 void lgh(Register r, const MemOperand& src); 840 void lghr(Register r1, Register r2); 841 void l(Register r, const MemOperand& src); 842 void ly(Register r, const MemOperand& src); 843 void lr(Register r1, Register r2); 844 void lg(Register r, const MemOperand& src); 845 void lgr(Register r1, Register r2); 846 void lgf(Register r, const MemOperand& src); 847 void lgfr(Register r1, Register r2); 848 void lhi(Register r, const Operand& imm); 849 void lghi(Register r, const Operand& imm); 850 851 // Load And Test Instructions 852 void lt_z(Register r, const MemOperand& src); 853 void ltg(Register r, const MemOperand& src); 854 void ltr(Register r1, Register r2); 855 void ltgr(Register r1, Register r2); 856 void ltgfr(Register r1, Register r2); 857 858 // Load Logical Instructions 859 void llc(Register r, const MemOperand& src); 860 void llgc(Register r, const MemOperand& src); 861 void llgf(Register r, const MemOperand& src); 862 void llgfr(Register r1, Register r2); 863 void llh(Register r, const MemOperand& src); 864 void llgh(Register r, const MemOperand& src); 865 void llhr(Register r1, Register r2); 866 void llghr(Register r1, Register r2); 867 868 // Load Multiple Instructions 869 void lm(Register r1, Register r2, const MemOperand& src); 870 void lmy(Register r1, Register r2, const MemOperand& src); 871 void lmg(Register r1, Register r2, const MemOperand& src); 872 873 // Store Instructions 874 void st(Register r, const MemOperand& src); 875 void stc(Register r, const MemOperand& src); 876 void stcy(Register r, const MemOperand& src); 877 void stg(Register r, const MemOperand& src); 878 void sth(Register r, const MemOperand& src); 879 void sthy(Register r, const MemOperand& src); 880 void sty(Register r, const MemOperand& src); 881 882 // Store Multiple Instructions 883 void stm(Register r1, Register r2, const MemOperand& src); 884 void stmy(Register r1, Register r2, const MemOperand& src); 885 void stmg(Register r1, Register r2, const MemOperand& src); 886 887 // Compare Instructions 888 void c(Register r, const MemOperand& opnd); 889 void cy(Register r, const MemOperand& opnd); 890 void cr_z(Register r1, Register r2); 891 void cg(Register r, const MemOperand& opnd); 892 void cgr(Register r1, Register r2); 893 void ch(Register r, const MemOperand& opnd); 894 void chy(Register r, const MemOperand& opnd); 895 void chi(Register r, const Operand& opnd); 896 void cghi(Register r, const Operand& opnd); 897 void cfi(Register r, const Operand& opnd); 898 void cgfi(Register r, const Operand& opnd); 899 900 // Compare Logical Instructions 901 void cl(Register r, const MemOperand& opnd); 902 void cly(Register r, const MemOperand& opnd); 903 void clr(Register r1, Register r2); 904 void clg(Register r, const MemOperand& opnd); 905 void clgr(Register r1, Register r2); 906 void clfi(Register r, const Operand& opnd); 907 void clgfi(Register r, const Operand& opnd); 908 void cli(const MemOperand& mem, const Operand& imm); 909 void cliy(const MemOperand& mem, const Operand& imm); 910 void clc(const MemOperand& opnd1, const MemOperand& opnd2, Length length); 911 912 // Test Under Mask Instructions 913 void tm(const MemOperand& mem, const Operand& imm); 914 void tmy(const MemOperand& mem, const Operand& imm); 915 916 // Rotate Instructions 917 void rll(Register r1, Register r3, Register opnd); 918 void rll(Register r1, Register r3, const Operand& opnd); 919 void rll(Register r1, Register r3, Register r2, const Operand& opnd); 920 void rllg(Register r1, Register r3, const Operand& opnd); 921 void rllg(Register r1, Register r3, const Register opnd); 922 void rllg(Register r1, Register r3, Register r2, const Operand& opnd); 923 924 // Shift Instructions (32) 925 void sll(Register r1, Register opnd); 926 void sll(Register r1, const Operand& opnd); 927 void sllk(Register r1, Register r3, Register opnd); 928 void sllk(Register r1, Register r3, const Operand& opnd); 929 void srl(Register r1, Register opnd); 930 void srl(Register r1, const Operand& opnd); 931 void srlk(Register r1, Register r3, Register opnd); 932 void srlk(Register r1, Register r3, const Operand& opnd); 933 void sra(Register r1, Register opnd); 934 void sra(Register r1, const Operand& opnd); 935 void srak(Register r1, Register r3, Register opnd); 936 void srak(Register r1, Register r3, const Operand& opnd); 937 void sla(Register r1, Register opnd); 938 void sla(Register r1, const Operand& opnd); 939 void slak(Register r1, Register r3, Register opnd); 940 void slak(Register r1, Register r3, const Operand& opnd); 941 942 // Shift Instructions (64) 943 void sllg(Register r1, Register r3, const Operand& opnd); 944 void sllg(Register r1, Register r3, const Register opnd); 945 void srlg(Register r1, Register r3, const Operand& opnd); 946 void srlg(Register r1, Register r3, const Register opnd); 947 void srag(Register r1, Register r3, const Operand& opnd); 948 void srag(Register r1, Register r3, const Register opnd); 949 void srda(Register r1, const Operand& opnd); 950 void srdl(Register r1, const Operand& opnd); 951 void slag(Register r1, Register r3, const Operand& opnd); 952 void slag(Register r1, Register r3, const Register opnd); 953 void sldl(Register r1, Register b2, const Operand& opnd); 954 void srdl(Register r1, Register b2, const Operand& opnd); 955 void srda(Register r1, Register b2, const Operand& opnd); 956 957 // Rotate and Insert Selected Bits 958 void risbg(Register dst, Register src, const Operand& startBit, 959 const Operand& endBit, const Operand& shiftAmt, 960 bool zeroBits = true); 961 void risbgn(Register dst, Register src, const Operand& startBit, 962 const Operand& endBit, const Operand& shiftAmt, 963 bool zeroBits = true); 964 965 // Move Character (Mem to Mem) 966 void mvc(const MemOperand& opnd1, const MemOperand& opnd2, uint32_t length); 967 968 // Branch Instructions 969 void basr(Register r1, Register r2); 970 void bcr(Condition m, Register target); 971 void bct(Register r, const MemOperand& opnd); 972 void bctg(Register r, const MemOperand& opnd); 973 void bras(Register r, const Operand& opnd); 974 void brasl(Register r, const Operand& opnd); 975 void brc(Condition c, const Operand& opnd); 976 void brcl(Condition m, const Operand& opnd, bool isCodeTarget = false); 977 void brct(Register r1, const Operand& opnd); 978 void brctg(Register r1, const Operand& opnd); 979 980 // 32-bit Add Instructions 981 void a(Register r1, const MemOperand& opnd); 982 void ay(Register r1, const MemOperand& opnd); 983 void afi(Register r1, const Operand& opnd); 984 void ah(Register r1, const MemOperand& opnd); 985 void ahy(Register r1, const MemOperand& opnd); 986 void ahi(Register r1, const Operand& opnd); 987 void ahik(Register r1, Register r3, const Operand& opnd); 988 void ar(Register r1, Register r2); 989 void ark(Register r1, Register r2, Register r3); 990 void asi(const MemOperand&, const Operand&); 991 992 // 64-bit Add Instructions 993 void ag(Register r1, const MemOperand& opnd); 994 void agf(Register r1, const MemOperand& opnd); 995 void agfi(Register r1, const Operand& opnd); 996 void agfr(Register r1, Register r2); 997 void aghi(Register r1, const Operand& opnd); 998 void aghik(Register r1, Register r3, const Operand& opnd); 999 void agr(Register r1, Register r2); 1000 void agrk(Register r1, Register r2, Register r3); 1001 void agsi(const MemOperand&, const Operand&); 1002 1003 // 32-bit Add Logical Instructions 1004 void al_z(Register r1, const MemOperand& opnd); 1005 void aly(Register r1, const MemOperand& opnd); 1006 void alfi(Register r1, const Operand& opnd); 1007 void alr(Register r1, Register r2); 1008 void alcr(Register r1, Register r2); 1009 void alrk(Register r1, Register r2, Register r3); 1010 1011 // 64-bit Add Logical Instructions 1012 void alg(Register r1, const MemOperand& opnd); 1013 void algfi(Register r1, const Operand& opnd); 1014 void algr(Register r1, Register r2); 1015 void algrk(Register r1, Register r2, Register r3); 1016 1017 // 32-bit Subtract Instructions 1018 void s(Register r1, const MemOperand& opnd); 1019 void sy(Register r1, const MemOperand& opnd); 1020 void sh(Register r1, const MemOperand& opnd); 1021 void shy(Register r1, const MemOperand& opnd); 1022 void sr(Register r1, Register r2); 1023 void srk(Register r1, Register r2, Register r3); 1024 1025 // 64-bit Subtract Instructions 1026 void sg(Register r1, const MemOperand& opnd); 1027 void sgf(Register r1, const MemOperand& opnd); 1028 void sgr(Register r1, Register r2); 1029 void sgfr(Register r1, Register r2); 1030 void sgrk(Register r1, Register r2, Register r3); 1031 1032 // 32-bit Subtract Logical Instructions 1033 void sl(Register r1, const MemOperand& opnd); 1034 void sly(Register r1, const MemOperand& opnd); 1035 void slr(Register r1, Register r2); 1036 void slrk(Register r1, Register r2, Register r3); 1037 void slbr(Register r1, Register r2); 1038 1039 // 64-bit Subtract Logical Instructions 1040 void slg(Register r1, const MemOperand& opnd); 1041 void slgr(Register r1, Register r2); 1042 void slgrk(Register r1, Register r2, Register r3); 1043 1044 // 32-bit Multiply Instructions 1045 void m(Register r1, const MemOperand& opnd); 1046 void mr_z(Register r1, Register r2); 1047 void ml(Register r1, const MemOperand& opnd); 1048 void mlr(Register r1, Register r2); 1049 void ms(Register r1, const MemOperand& opnd); 1050 void msy(Register r1, const MemOperand& opnd); 1051 void msfi(Register r1, const Operand& opnd); 1052 void msr(Register r1, Register r2); 1053 void mh(Register r1, const MemOperand& opnd); 1054 void mhy(Register r1, const MemOperand& opnd); 1055 void mhi(Register r1, const Operand& opnd); 1056 1057 // 64-bit Multiply Instructions 1058 void mlg(Register r1, const MemOperand& opnd); 1059 void mlgr(Register r1, Register r2); 1060 void mghi(Register r1, const Operand& opnd); 1061 void msgfi(Register r1, const Operand& opnd); 1062 void msg(Register r1, const MemOperand& opnd); 1063 void msgr(Register r1, Register r2); 1064 1065 // 32-bit Divide Instructions 1066 void d(Register r1, const MemOperand& opnd); 1067 void dr(Register r1, Register r2); 1068 void dl(Register r1, const MemOperand& opnd); 1069 void dlr(Register r1, Register r2); 1070 1071 // 64-bit Divide Instructions 1072 void dlgr(Register r1, Register r2); 1073 void dsgr(Register r1, Register r2); 1074 1075 // Bitwise Instructions (AND / OR / XOR) 1076 void n(Register r1, const MemOperand& opnd); 1077 void ny(Register r1, const MemOperand& opnd); 1078 void nr(Register r1, Register r2); 1079 void nrk(Register r1, Register r2, Register r3); 1080 void ng(Register r1, const MemOperand& opnd); 1081 void ngr(Register r1, Register r2); 1082 void ngrk(Register r1, Register r2, Register r3); 1083 void o(Register r1, const MemOperand& opnd); 1084 void oy(Register r1, const MemOperand& opnd); 1085 void or_z(Register r1, Register r2); 1086 void ork(Register r1, Register r2, Register r3); 1087 void og(Register r1, const MemOperand& opnd); 1088 void ogr(Register r1, Register r2); 1089 void ogrk(Register r1, Register r2, Register r3); 1090 void x(Register r1, const MemOperand& opnd); 1091 void xy(Register r1, const MemOperand& opnd); 1092 void xr(Register r1, Register r2); 1093 void xrk(Register r1, Register r2, Register r3); 1094 void xg(Register r1, const MemOperand& opnd); 1095 void xgr(Register r1, Register r2); 1096 void xgrk(Register r1, Register r2, Register r3); 1097 void xc(const MemOperand& opnd1, const MemOperand& opnd2, Length length); 1098 1099 // Bitwise GPR <-> FPR Conversion Instructions 1100 void lgdr(Register r1, DoubleRegister f2); 1101 void ldgr(DoubleRegister f1, Register r2); 1102 1103 // Floating Point Load / Store Instructions 1104 void ld(DoubleRegister r1, const MemOperand& opnd); 1105 void ldy(DoubleRegister r1, const MemOperand& opnd); 1106 void le_z(DoubleRegister r1, const MemOperand& opnd); 1107 void ley(DoubleRegister r1, const MemOperand& opnd); 1108 void ldr(DoubleRegister r1, DoubleRegister r2); 1109 void ltdbr(DoubleRegister r1, DoubleRegister r2); 1110 void ltebr(DoubleRegister r1, DoubleRegister r2); 1111 void std(DoubleRegister r1, const MemOperand& opnd); 1112 void stdy(DoubleRegister r1, const MemOperand& opnd); 1113 void ste(DoubleRegister r1, const MemOperand& opnd); 1114 void stey(DoubleRegister r1, const MemOperand& opnd); 1115 1116 // Floating Point Load Rounded/Positive Instructions 1117 void ledbr(DoubleRegister r1, DoubleRegister r2); 1118 void ldebr(DoubleRegister r1, DoubleRegister r2); 1119 void lpebr(DoubleRegister r1, DoubleRegister r2); 1120 void lpdbr(DoubleRegister r1, DoubleRegister r2); 1121 1122 // Floating <-> Fixed Point Conversion Instructions 1123 void cdlfbr(Condition m3, Condition m4, DoubleRegister fltReg, 1124 Register fixReg); 1125 void cdlgbr(Condition m3, Condition m4, DoubleRegister fltReg, 1126 Register fixReg); 1127 void celgbr(Condition m3, Condition m4, DoubleRegister fltReg, 1128 Register fixReg); 1129 void celfbr(Condition m3, Condition m4, DoubleRegister fltReg, 1130 Register fixReg); 1131 void clfdbr(Condition m3, Condition m4, Register fixReg, 1132 DoubleRegister fltReg); 1133 void clfebr(Condition m3, Condition m4, Register fixReg, 1134 DoubleRegister fltReg); 1135 void clgdbr(Condition m3, Condition m4, Register fixReg, 1136 DoubleRegister fltReg); 1137 void clgebr(Condition m3, Condition m4, Register fixReg, 1138 DoubleRegister fltReg); 1139 void cfdbr(Condition m, Register fixReg, DoubleRegister fltReg); 1140 void cdfbr(DoubleRegister fltReg, Register fixReg); 1141 void cgebr(Condition m, Register fixReg, DoubleRegister fltReg); 1142 void cgdbr(Condition m, Register fixReg, DoubleRegister fltReg); 1143 void cegbr(DoubleRegister fltReg, Register fixReg); 1144 void cdgbr(DoubleRegister fltReg, Register fixReg); 1145 void cfebr(Condition m3, Register fixReg, DoubleRegister fltReg); 1146 void cefbr(DoubleRegister fltReg, Register fixReg); 1147 1148 // Floating Point Compare Instructions 1149 void cebr(DoubleRegister r1, DoubleRegister r2); 1150 void cdb(DoubleRegister r1, const MemOperand& opnd); 1151 void cdbr(DoubleRegister r1, DoubleRegister r2); 1152 1153 // Floating Point Arithmetic Instructions 1154 void aebr(DoubleRegister r1, DoubleRegister r2); 1155 void adb(DoubleRegister r1, const MemOperand& opnd); 1156 void adbr(DoubleRegister r1, DoubleRegister r2); 1157 void lzdr(DoubleRegister r1); 1158 void sebr(DoubleRegister r1, DoubleRegister r2); 1159 void sdb(DoubleRegister r1, const MemOperand& opnd); 1160 void sdbr(DoubleRegister r1, DoubleRegister r2); 1161 void meebr(DoubleRegister r1, DoubleRegister r2); 1162 void mdb(DoubleRegister r1, const MemOperand& opnd); 1163 void mdbr(DoubleRegister r1, DoubleRegister r2); 1164 void debr(DoubleRegister r1, DoubleRegister r2); 1165 void ddb(DoubleRegister r1, const MemOperand& opnd); 1166 void ddbr(DoubleRegister r1, DoubleRegister r2); 1167 void madbr(DoubleRegister r1, DoubleRegister r2, DoubleRegister r3); 1168 void msdbr(DoubleRegister r1, DoubleRegister r2, DoubleRegister r3); 1169 void sqebr(DoubleRegister r1, DoubleRegister r2); 1170 void sqdb(DoubleRegister r1, const MemOperand& opnd); 1171 void sqdbr(DoubleRegister r1, DoubleRegister r2); 1172 void lcdbr(DoubleRegister r1, DoubleRegister r2); 1173 void ldeb(DoubleRegister r1, const MemOperand& opnd); 1174 1175 enum FIDBRA_MASK3 { 1176 FIDBRA_CURRENT_ROUNDING_MODE = 0, 1177 FIDBRA_ROUND_TO_NEAREST_AWAY_FROM_0 = 1, 1178 // ... 1179 FIDBRA_ROUND_TOWARD_0 = 5, 1180 FIDBRA_ROUND_TOWARD_POS_INF = 6, 1181 FIDBRA_ROUND_TOWARD_NEG_INF = 7 1182 }; 1183 void fiebra(DoubleRegister d1, DoubleRegister d2, FIDBRA_MASK3 m3); 1184 void fidbra(DoubleRegister d1, DoubleRegister d2, FIDBRA_MASK3 m3); 1185 1186 // Move integer 1187 void mvhi(const MemOperand& opnd1, const Operand& i2); 1188 void mvghi(const MemOperand& opnd1, const Operand& i2); 1189 1190 // Exception-generating instructions and debugging support 1191 void stop(const char* msg, Condition cond = al, 1192 int32_t code = kDefaultStopCode, CRegister cr = cr7); 1193 1194 void bkpt(uint32_t imm16); // v5 and above 1195 1196 // Different nop operations are used by the code generator to detect certain 1197 // states of the generated code. 1198 enum NopMarkerTypes { 1199 NON_MARKING_NOP = 0, 1200 GROUP_ENDING_NOP, 1201 DEBUG_BREAK_NOP, 1202 // IC markers. 1203 PROPERTY_ACCESS_INLINED, 1204 PROPERTY_ACCESS_INLINED_CONTEXT, 1205 PROPERTY_ACCESS_INLINED_CONTEXT_DONT_DELETE, 1206 // Helper values. 1207 LAST_CODE_MARKER, 1208 FIRST_IC_MARKER = PROPERTY_ACCESS_INLINED 1209 }; 1210 1211 void nop(int type = 0); // 0 is the default non-marking type. 1212 1213 // Check the code size generated from label to here. SizeOfCodeGeneratedSince(Label * label)1214 int SizeOfCodeGeneratedSince(Label* label) { 1215 return pc_offset() - label->pos(); 1216 } 1217 1218 // Debugging 1219 1220 // Mark generator continuation. 1221 void RecordGeneratorContinuation(); 1222 1223 // Mark address of a debug break slot. 1224 void RecordDebugBreakSlot(RelocInfo::Mode mode); 1225 1226 // Record the AST id of the CallIC being compiled, so that it can be placed 1227 // in the relocation information. SetRecordedAstId(TypeFeedbackId ast_id)1228 void SetRecordedAstId(TypeFeedbackId ast_id) { recorded_ast_id_ = ast_id; } 1229 RecordedAstId()1230 TypeFeedbackId RecordedAstId() { 1231 // roohack - another issue??? DCHECK(!recorded_ast_id_.IsNone()); 1232 return recorded_ast_id_; 1233 } 1234 ClearRecordedAstId()1235 void ClearRecordedAstId() { recorded_ast_id_ = TypeFeedbackId::None(); } 1236 1237 // Record a comment relocation entry that can be used by a disassembler. 1238 // Use --code-comments to enable. 1239 void RecordComment(const char* msg); 1240 1241 // Record a deoptimization reason that can be used by a log or cpu profiler. 1242 // Use --trace-deopt to enable. 1243 void RecordDeoptReason(const int reason, int raw_position, int id); 1244 1245 // Writes a single byte or word of data in the code stream. Used 1246 // for inline tables, e.g., jump-tables. 1247 void db(uint8_t data); 1248 void dd(uint32_t data); 1249 void dq(uint64_t data); 1250 void dp(uintptr_t data); 1251 positions_recorder()1252 AssemblerPositionsRecorder* positions_recorder() { 1253 return &positions_recorder_; 1254 } 1255 PatchConstantPoolAccessInstruction(int pc_offset,int offset,ConstantPoolEntry::Access access,ConstantPoolEntry::Type type)1256 void PatchConstantPoolAccessInstruction(int pc_offset, int offset, 1257 ConstantPoolEntry::Access access, 1258 ConstantPoolEntry::Type type) { 1259 // No embedded constant pool support. 1260 UNREACHABLE(); 1261 } 1262 1263 // Read/patch instructions instr_at(int pos)1264 SixByteInstr instr_at(int pos) { 1265 return Instruction::InstructionBits(buffer_ + pos); 1266 } 1267 template <typename T> instr_at_put(int pos,T instr)1268 void instr_at_put(int pos, T instr) { 1269 Instruction::SetInstructionBits<T>(buffer_ + pos, instr); 1270 } 1271 1272 // Decodes instruction at pos, and returns its length instr_length_at(int pos)1273 int32_t instr_length_at(int pos) { 1274 return Instruction::InstructionLength(buffer_ + pos); 1275 } 1276 instr_at(byte * pc)1277 static SixByteInstr instr_at(byte* pc) { 1278 return Instruction::InstructionBits(pc); 1279 } 1280 1281 static Condition GetCondition(Instr instr); 1282 1283 static bool IsBranch(Instr instr); 1284 #if V8_TARGET_ARCH_S390X 1285 static bool Is64BitLoadIntoIP(SixByteInstr instr1, SixByteInstr instr2); 1286 #else 1287 static bool Is32BitLoadIntoIP(SixByteInstr instr); 1288 #endif 1289 1290 static bool IsCmpRegister(Instr instr); 1291 static bool IsCmpImmediate(Instr instr); 1292 static bool IsNop(SixByteInstr instr, int type = NON_MARKING_NOP); 1293 1294 // The code currently calls CheckBuffer() too often. This has the side 1295 // effect of randomly growing the buffer in the middle of multi-instruction 1296 // sequences. 1297 // 1298 // This function allows outside callers to check and grow the buffer 1299 void EnsureSpaceFor(int space_needed); 1300 1301 void EmitRelocations(); 1302 void emit_label_addr(Label* label); 1303 1304 public: buffer_pos()1305 byte* buffer_pos() const { return buffer_; } 1306 1307 protected: 1308 // Relocation for a type-recording IC has the AST id added to it. This 1309 // member variable is a way to pass the information from the call site to 1310 // the relocation info. 1311 TypeFeedbackId recorded_ast_id_; 1312 buffer_space()1313 int buffer_space() const { return reloc_info_writer.pos() - pc_; } 1314 1315 // Decode instruction(s) at pos and return backchain to previous 1316 // label reference or kEndOfChain. 1317 int target_at(int pos); 1318 1319 // Patch instruction(s) at pos to target target_pos (e.g. branch) 1320 void target_at_put(int pos, int target_pos, bool* is_branch = nullptr); 1321 1322 // Record reloc info for current pc_ 1323 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); 1324 1325 private: 1326 // Code generation 1327 // The relocation writer's position is at least kGap bytes below the end of 1328 // the generated instructions. This is so that multi-instruction sequences do 1329 // not have to check for overflow. The same is true for writes of large 1330 // relocation info entries. 1331 static const int kGap = 32; 1332 1333 // Relocation info generation 1334 // Each relocation is encoded as a variable size value 1335 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; 1336 RelocInfoWriter reloc_info_writer; 1337 std::vector<DeferredRelocInfo> relocations_; 1338 1339 // The bound position, before this we cannot do instruction elimination. 1340 int last_bound_pos_; 1341 1342 // Code emission 1343 inline void CheckBuffer(); 1344 void GrowBuffer(int needed = 0); 1345 inline void TrackBranch(); 1346 inline void UntrackBranch(); 1347 1348 inline int32_t emit_code_target( 1349 Handle<Code> target, RelocInfo::Mode rmode, 1350 TypeFeedbackId ast_id = TypeFeedbackId::None()); 1351 1352 // Helpers to emit binary encoding of 2/4/6 byte instructions. 1353 inline void emit2bytes(uint16_t x); 1354 inline void emit4bytes(uint32_t x); 1355 inline void emit6bytes(uint64_t x); 1356 1357 // Helpers to emit binary encoding for various instruction formats. 1358 1359 inline void rr_form(Opcode op, Register r1, Register r2); 1360 inline void rr_form(Opcode op, DoubleRegister r1, DoubleRegister r2); 1361 inline void rr_form(Opcode op, Condition m1, Register r2); 1362 inline void rr2_form(uint8_t op, Condition m1, Register r2); 1363 1364 inline void rx_form(Opcode op, Register r1, Register x2, Register b2, 1365 Disp d2); 1366 inline void rx_form(Opcode op, DoubleRegister r1, Register x2, Register b2, 1367 Disp d2); 1368 1369 inline void ri_form(Opcode op, Register r1, const Operand& i2); 1370 inline void ri_form(Opcode op, Condition m1, const Operand& i2); 1371 1372 inline void rie_form(Opcode op, Register r1, Register r3, const Operand& i2); 1373 inline void rie_f_form(Opcode op, Register r1, Register r2, const Operand& i3, 1374 const Operand& i4, const Operand& i5); 1375 1376 inline void ril_form(Opcode op, Register r1, const Operand& i2); 1377 inline void ril_form(Opcode op, Condition m1, const Operand& i2); 1378 1379 inline void ris_form(Opcode op, Register r1, Condition m3, Register b4, 1380 Disp d4, const Operand& i2); 1381 1382 inline void rrd_form(Opcode op, Register r1, Register r3, Register r2); 1383 1384 inline void rre_form(Opcode op, Register r1, Register r2); 1385 inline void rre_form(Opcode op, DoubleRegister r1, DoubleRegister r2); 1386 1387 inline void rrf1_form(Opcode op, Register r1, Register r2, Register r3); 1388 inline void rrf1_form(uint32_t x); 1389 inline void rrf2_form(uint32_t x); 1390 inline void rrf3_form(uint32_t x); 1391 inline void rrfe_form(Opcode op, Condition m3, Condition m4, Register r1, 1392 Register r2); 1393 1394 inline void rrs_form(Opcode op, Register r1, Register r2, Register b4, 1395 Disp d4, Condition m3); 1396 1397 inline void rs_form(Opcode op, Register r1, Condition m3, Register b2, 1398 const Disp d2); 1399 inline void rs_form(Opcode op, Register r1, Register r3, Register b2, 1400 const Disp d2); 1401 1402 inline void rsi_form(Opcode op, Register r1, Register r3, const Operand& i2); 1403 inline void rsl_form(Opcode op, Length l1, Register b2, Disp d2); 1404 1405 inline void rsy_form(Opcode op, Register r1, Register r3, Register b2, 1406 const Disp d2); 1407 inline void rsy_form(Opcode op, Register r1, Condition m3, Register b2, 1408 const Disp d2); 1409 1410 inline void rxe_form(Opcode op, Register r1, Register x2, Register b2, 1411 Disp d2); 1412 1413 inline void rxf_form(Opcode op, Register r1, Register r3, Register b2, 1414 Register x2, Disp d2); 1415 1416 inline void rxy_form(Opcode op, Register r1, Register x2, Register b2, 1417 Disp d2); 1418 inline void rxy_form(Opcode op, DoubleRegister r1, Register x2, Register b2, 1419 Disp d2); 1420 1421 inline void s_form(Opcode op, Register b1, Disp d2); 1422 1423 inline void si_form(Opcode op, const Operand& i2, Register b1, Disp d1); 1424 inline void siy_form(Opcode op, const Operand& i2, Register b1, Disp d1); 1425 1426 inline void sil_form(Opcode op, Register b1, Disp d1, const Operand& i2); 1427 1428 inline void ss_form(Opcode op, Length l, Register b1, Disp d1, Register b2, 1429 Disp d2); 1430 inline void ss_form(Opcode op, Length l1, Length l2, Register b1, Disp d1, 1431 Register b2, Disp d2); 1432 inline void ss_form(Opcode op, Length l1, const Operand& i3, Register b1, 1433 Disp d1, Register b2, Disp d2); 1434 inline void ss_form(Opcode op, Register r1, Register r2, Register b1, Disp d1, 1435 Register b2, Disp d2); 1436 inline void sse_form(Opcode op, Register b1, Disp d1, Register b2, Disp d2); 1437 inline void ssf_form(Opcode op, Register r3, Register b1, Disp d1, 1438 Register b2, Disp d2); 1439 1440 // Labels 1441 void print(Label* L); 1442 int max_reach_from(int pos); 1443 void bind_to(Label* L, int pos); 1444 void next(Label* L); 1445 1446 friend class RegExpMacroAssemblerS390; 1447 friend class RelocInfo; 1448 friend class CodePatcher; 1449 1450 List<Handle<Code> > code_targets_; 1451 1452 AssemblerPositionsRecorder positions_recorder_; 1453 friend class AssemblerPositionsRecorder; 1454 friend class EnsureSpace; 1455 }; 1456 1457 class EnsureSpace BASE_EMBEDDED { 1458 public: EnsureSpace(Assembler * assembler)1459 explicit EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); } 1460 }; 1461 1462 } // namespace internal 1463 } // namespace v8 1464 1465 #endif // V8_S390_ASSEMBLER_S390_H_ 1466