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