diff options
Diffstat (limited to 'deps/v8/src/s390/assembler-s390.h')
-rw-r--r-- | deps/v8/src/s390/assembler-s390.h | 1110 |
1 files changed, 592 insertions, 518 deletions
diff --git a/deps/v8/src/s390/assembler-s390.h b/deps/v8/src/s390/assembler-s390.h index 9d9a04d34f..f73897d13e 100644 --- a/deps/v8/src/s390/assembler-s390.h +++ b/deps/v8/src/s390/assembler-s390.h @@ -347,43 +347,31 @@ C_REGISTERS(DECLARE_C_REGISTER) // Class Operand represents a shifter operand in data processing instructions // defining immediate numbers and masks -typedef uint8_t Length; - -struct Mask { - uint8_t mask; - uint8_t value() { return mask; } - static Mask from_value(uint8_t input) { - DCHECK_LE(input, 0x0F); - Mask m = {input}; - return m; - } -}; - class Operand BASE_EMBEDDED { public: // immediate - INLINE(explicit Operand(intptr_t immediate, - RelocInfo::Mode rmode = RelocInfo::NONE) - : rmode_(rmode)) { + V8_INLINE explicit Operand(intptr_t immediate, + RelocInfo::Mode rmode = RelocInfo::NONE) + : rmode_(rmode) { value_.immediate = immediate; } - INLINE(static Operand Zero()) { return Operand(static_cast<intptr_t>(0)); } - INLINE(explicit Operand(const ExternalReference& f) - : rmode_(RelocInfo::EXTERNAL_REFERENCE)) { + V8_INLINE static Operand Zero() { return Operand(static_cast<intptr_t>(0)); } + V8_INLINE explicit Operand(const ExternalReference& f) + : rmode_(RelocInfo::EXTERNAL_REFERENCE) { value_.immediate = static_cast<intptr_t>(f.address()); } explicit Operand(Handle<HeapObject> handle); - INLINE(explicit Operand(Smi* value) : rmode_(RelocInfo::NONE)) { + V8_INLINE explicit Operand(Smi* value) : rmode_(RelocInfo::NONE) { value_.immediate = reinterpret_cast<intptr_t>(value); } // rm - INLINE(explicit Operand(Register rm)); + V8_INLINE explicit Operand(Register rm); static Operand EmbeddedNumber(double value); // Smi or HeapNumber // Return true if this is a register operand. - INLINE(bool is_reg() const) { return rm_.is_valid(); } + V8_INLINE bool is_reg() const { return rm_.is_valid(); } bool must_output_reloc_info(const Assembler* assembler) const; @@ -500,9 +488,7 @@ class Assembler : public AssemblerBase { // buffer for code generation and assumes its size to be buffer_size. If the // buffer is too small, a fatal error occurs. No deallocation of the buffer is // done upon destruction of the assembler. - Assembler(Isolate* isolate, void* buffer, int buffer_size) - : Assembler(IsolateData(isolate), buffer, buffer_size) {} - Assembler(IsolateData isolate_data, void* buffer, int buffer_size); + Assembler(const AssemblerOptions& options, void* buffer, int buffer_size); virtual ~Assembler() {} // GetCode emits any pending (non-emitted) code and fills the descriptor @@ -547,10 +533,10 @@ class Assembler : public AssemblerBase { // Read/Modify the code target address in the branch/call instruction at pc. // The isolate argument is unused (and may be nullptr) when skipping flushing. - INLINE(static Address target_address_at(Address pc, Address constant_pool)); - INLINE(static void set_target_address_at( + V8_INLINE static Address target_address_at(Address pc, Address constant_pool); + V8_INLINE static void set_target_address_at( Address pc, Address constant_pool, Address target, - ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)); + ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED); // Return the code target address at a call site from the return address // of that call in the instruction stream. @@ -558,7 +544,7 @@ class Assembler : public AssemblerBase { // Given the address of the beginning of a call, return the address // in the instruction stream that the call will return to. - INLINE(static Address return_address_from_call_start(Address pc)); + V8_INLINE static Address return_address_from_call_start(Address pc); inline Handle<Object> code_target_object_handle_at(Address pc); // This sets the branch destination. @@ -608,10 +594,6 @@ class Assembler : public AssemblerBase { static constexpr int kCallSequenceLength = 8; #endif - static inline int encode_crbit(const CRegister& cr, enum CRBit crbit) { - return ((cr.code() * CRWIDTH) + crbit); - } - // --------------------------------------------------------------------------- // Code generation @@ -625,64 +607,6 @@ class Assembler : public AssemblerBase { return (value & mask_value) << shift; } - // Declare generic instruction formats by fields - inline void e_format(Opcode opcode) { - emit2bytes(getfield<uint16_t, 2, 0, 16>(opcode)); - } - - inline void i_format(Opcode opcode, int f1) { - emit2bytes(getfield<uint16_t, 2, 0, 8>(opcode) | - getfield<uint16_t, 2, 8, 16>(f1)); - } - - inline void ie_format(Opcode opcode, int f1, int f2) { - emit4bytes(getfield<uint32_t, 4, 0, 16>(opcode) | - getfield<uint32_t, 4, 24, 28>(f1) | - getfield<uint32_t, 4, 28, 32>(f2)); - } - inline void mii_format(Opcode opcode, int f1, int f2, int f3) { - emit6bytes( - getfield<uint64_t, 6, 0, 8>(opcode) | getfield<uint64_t, 6, 8, 12>(f1) | - getfield<uint64_t, 6, 12, 24>(f2) | getfield<uint64_t, 6, 24, 48>(f3)); - } - - inline void ri_format(Opcode opcode, int f1, int f2) { - uint32_t op1 = opcode >> 4; - uint32_t op2 = opcode & 0xf; - emit4bytes( - getfield<uint32_t, 4, 0, 8>(op1) | getfield<uint32_t, 4, 8, 12>(f1) | - getfield<uint32_t, 4, 12, 16>(op2) | getfield<uint32_t, 4, 16, 32>(f2)); - } - - inline void rie_1_format(Opcode opcode, int f1, int f2, int f3, int f4) { - uint32_t op1 = opcode >> 8; - uint32_t op2 = opcode & 0xff; - emit6bytes( - getfield<uint64_t, 6, 0, 8>(op1) | getfield<uint64_t, 6, 8, 12>(f1) | - getfield<uint64_t, 6, 12, 16>(f2) | getfield<uint64_t, 6, 16, 32>(f3) | - getfield<uint64_t, 6, 32, 36>(f4) | getfield<uint64_t, 6, 40, 48>(op2)); - } - - inline void rie_2_format(Opcode opcode, int f1, int f2, int f3, int f4) { - uint32_t op1 = opcode >> 8; - uint32_t op2 = opcode & 0xff; - emit6bytes( - getfield<uint64_t, 6, 0, 8>(op1) | getfield<uint64_t, 6, 8, 12>(f1) | - getfield<uint64_t, 6, 12, 16>(f2) | getfield<uint64_t, 6, 16, 32>(f3) | - getfield<uint64_t, 6, 32, 40>(f4) | getfield<uint64_t, 6, 40, 48>(op2)); - } - - inline void rie_3_format(Opcode opcode, int f1, int f2, int f3, int f4, - int f5) { - uint32_t op1 = opcode >> 8; - uint32_t op2 = opcode & 0xff; - emit6bytes( - getfield<uint64_t, 6, 0, 8>(op1) | getfield<uint64_t, 6, 8, 12>(f1) | - getfield<uint64_t, 6, 12, 16>(f2) | getfield<uint64_t, 6, 16, 24>(f3) | - getfield<uint64_t, 6, 24, 32>(f4) | getfield<uint64_t, 6, 32, 40>(f5) | - getfield<uint64_t, 6, 40, 48>(op2)); - } - #define DECLARE_S390_RIL_AB_INSTRUCTIONS(name, op_name, op_value) \ template <class R1> \ inline void name(R1 r1, const Operand& i2) { \ @@ -706,17 +630,6 @@ class Assembler : public AssemblerBase { #undef DECLARE_S390_RIL_AB_INSTRUCTIONS #undef DECLARE_S390_RIL_C_INSTRUCTIONS - inline void ris_format(Opcode opcode, int f1, int f2, int f3, int f4, - int f5) { - uint32_t op1 = opcode >> 8; - uint32_t op2 = opcode & 0xff; - emit6bytes( - getfield<uint64_t, 6, 0, 8>(op1) | getfield<uint64_t, 6, 8, 12>(f1) | - getfield<uint64_t, 6, 12, 16>(f2) | getfield<uint64_t, 6, 16, 20>(f3) | - getfield<uint64_t, 6, 20, 32>(f4) | getfield<uint64_t, 6, 32, 40>(f5) | - getfield<uint64_t, 6, 40, 48>(op2)); - } - #define DECLARE_S390_RR_INSTRUCTIONS(name, op_name, op_value) \ inline void name(Register r1, Register r2) { \ rr_format(op_name, r1.code(), r2.code()); \ @@ -765,22 +678,16 @@ class Assembler : public AssemblerBase { void lzdr(DoubleRegister r1) { rre_format(LZDR, r1.code(), 0); } #undef DECLARE_S390_RRE_INSTRUCTIONS - inline void rrf_format(Opcode opcode, int f1, int f2, int f3, int f4) { - emit4bytes( - getfield<uint32_t, 4, 0, 16>(opcode) | - getfield<uint32_t, 4, 16, 20>(f1) | getfield<uint32_t, 4, 20, 24>(f2) | - getfield<uint32_t, 4, 24, 28>(f3) | getfield<uint32_t, 4, 28, 32>(f4)); - } - -#define DECLARE_S390_RX_INSTRUCTIONS(name, op_name, op_value) \ - template <class R1> \ - inline void name(R1 r1, Register x2, Register b2, Disp d2) { \ - rx_format(op_name, r1.code(), x2.code(), b2.code(), d2); \ - } \ - template <class R1> \ - inline void name(R1 r1, const MemOperand& opnd) { \ - name(r1, opnd.getIndexRegister(), \ - opnd.getBaseRegister(), opnd.getDisplacement()); \ +#define DECLARE_S390_RX_INSTRUCTIONS(name, op_name, op_value) \ + template <class R1> \ + inline void name(R1 r1, Register x2, Register b2, const Operand& d2) { \ + rx_format(op_name, r1.code(), x2.code(), b2.code(), \ + d2.immediate()); \ + } \ + template <class R1> \ + inline void name(R1 r1, const MemOperand& opnd) { \ + name(r1, opnd.getIndexRegister(), opnd.getBaseRegister(), \ + Operand(opnd.getDisplacement())); \ } inline void rx_format(Opcode opcode, int f1, int f2, int f3, int f4) { @@ -796,22 +703,22 @@ class Assembler : public AssemblerBase { void bc(Condition cond, const MemOperand& opnd) { bc(cond, opnd.getIndexRegister(), - opnd.getBaseRegister(), opnd.getDisplacement()); + opnd.getBaseRegister(), Operand(opnd.getDisplacement())); } - void bc(Condition cond, Register x2, Register b2, Disp d2) { - rx_format(BC, cond, x2.code(), b2.code(), d2); + void bc(Condition cond, Register x2, Register b2, const Operand& d2) { + rx_format(BC, cond, x2.code(), b2.code(), d2.immediate()); } #undef DECLARE_S390_RX_INSTRUCTIONS -#define DECLARE_S390_RXY_INSTRUCTIONS(name, op_name, op_value) \ - template <class R1, class R2> \ - inline void name(R1 r1, R2 r2, Register b2, Disp d2) { \ - rxy_format(op_name, r1.code(), r2.code(), b2.code(), d2); \ - } \ - template <class R1> \ - inline void name(R1 r1, const MemOperand& opnd) { \ - name(r1, opnd.getIndexRegister(), \ - opnd.getBaseRegister(), opnd.getDisplacement()); \ +#define DECLARE_S390_RXY_INSTRUCTIONS(name, op_name, op_value) \ + template <class R1, class R2> \ + inline void name(R1 r1, R2 r2, Register b2, const Operand& d2) { \ + rxy_format(op_name, r1.code(), r2.code(), b2.code(), d2.immediate()); \ + } \ + template <class R1> \ + inline void name(R1 r1, const MemOperand& opnd) { \ + name(r1, opnd.getIndexRegister(), opnd.getBaseRegister(), \ + Operand(opnd.getDisplacement())); \ } inline void rxy_format(Opcode opcode, int f1, int f2, int f3, int f4) { @@ -829,14 +736,15 @@ class Assembler : public AssemblerBase { void pfd(Condition cond, const MemOperand& opnd) { pfd(cond, opnd.getIndexRegister(), - opnd.getBaseRegister(), opnd.getDisplacement()); + opnd.getBaseRegister(), Operand(opnd.getDisplacement())); } - void pfd(Condition cond, Register x2, Register b2, Disp d2) { - rxy_format(PFD, cond, x2.code(), b2.code(), d2); + void pfd(Condition cond, Register x2, Register b2, const Operand& d2) { + rxy_format(PFD, cond, x2.code(), b2.code(), d2.immediate()); } #undef DECLARE_S390_RXY_INSTRUCTIONS -inline void rsy_form(Opcode op, int f1, int f2, int f3, const int f4) { + +inline void rsy_format(Opcode op, int f1, int f2, int f3, int f4) { DCHECK(is_int20(f4)); DCHECK(is_uint16(op)); uint64_t code = (getfield<uint64_t, 6, 0, 8>(op >> 8) | @@ -850,28 +758,519 @@ inline void rsy_form(Opcode op, int f1, int f2, int f3, const int f4) { } #define DECLARE_S390_RSY_A_INSTRUCTIONS(name, op_name, op_value) \ - void name(Register r1, Register r3, Register b2, Disp d2 = 0) { \ - rsy_form(op_name, r1.code(), r3.code(), b2.code(), d2); \ + void name(Register r1, Register r3, Register b2, \ + const Operand& d2 = Operand::Zero()) { \ + rsy_format(op_name, r1.code(), r3.code(), b2.code(), d2.immediate()); \ } \ void name(Register r1, Register r3, Operand d2) { \ - name(r1, r3, r0, d2.immediate()); \ + name(r1, r3, r0, d2); \ } \ void name(Register r1, Register r3, const MemOperand& opnd) { \ - name(r1, r3, opnd.getBaseRegister(), opnd.getDisplacement()); \ + name(r1, r3, opnd.getBaseRegister(), Operand(opnd.getDisplacement())); \ } S390_RSY_A_OPCODE_LIST(DECLARE_S390_RSY_A_INSTRUCTIONS); #undef DECLARE_S390_RSY_A_INSTRUCTIONS #define DECLARE_S390_RSY_B_INSTRUCTIONS(name, op_name, op_value) \ - void name(Register r1, Condition m3, Register b2, Disp d2) { \ - rsy_form(op_name, r1.code(), m3, b2.code(), d2); \ + void name(Register r1, Condition m3, Register b2, const Operand& d2) { \ + rsy_format(op_name, r1.code(), m3, b2.code(), d2.immediate()); \ } \ void name(Register r1, Condition m3, const MemOperand& opnd) { \ - name(r1, m3, opnd.getBaseRegister(), opnd.getDisplacement()); \ + name(r1, m3, opnd.getBaseRegister(), Operand(opnd.getDisplacement())); \ } S390_RSY_B_OPCODE_LIST(DECLARE_S390_RSY_B_INSTRUCTIONS); #undef DECLARE_S390_RSY_B_INSTRUCTIONS + +inline void rs_format(Opcode op, int f1, int f2, int f3, const int f4) { + uint32_t code = getfield<uint32_t, 4, 0, 8>(op) | + getfield<uint32_t, 4, 8, 12>(f1) | + getfield<uint32_t, 4, 12, 16>(f2) | + getfield<uint32_t, 4, 16, 20>(f3) | + getfield<uint32_t, 4, 20, 32>(f4); + emit4bytes(code); +} + +#define DECLARE_S390_RS_A_INSTRUCTIONS(name, op_name, op_value) \ + void name(Register r1, Register r3, Register b2, const Operand& d2) { \ + rs_format(op_name, r1.code(), r3.code(), b2.code(), d2.immediate()); \ + } \ + void name(Register r1, Register r3, const MemOperand& opnd) { \ + name(r1, r3, opnd.getBaseRegister(), Operand(opnd.getDisplacement())); \ + } + S390_RS_A_OPCODE_LIST(DECLARE_S390_RS_A_INSTRUCTIONS); +#undef DECLARE_S390_RS_A_INSTRUCTIONS + +#define DECLARE_S390_RS_B_INSTRUCTIONS(name, op_name, op_value) \ + void name(Register r1, Condition m3, Register b2, const Operand& d2) { \ + rs_format(op_name, r1.code(), m3, b2.code(), d2.immediate()); \ + } \ + void name(Register r1, Condition m3, const MemOperand& opnd) { \ + name(r1, m3, opnd.getBaseRegister(), Operand(opnd.getDisplacement())); \ + } + S390_RS_B_OPCODE_LIST(DECLARE_S390_RS_B_INSTRUCTIONS); +#undef DECLARE_S390_RS_B_INSTRUCTIONS + +#define DECLARE_S390_RS_SHIFT_FORMAT(name, opcode) \ + void name(Register r1, Register r2, const Operand& opnd = \ + Operand::Zero()) { \ + DCHECK(r2 != r0); \ + rs_format(opcode, r1.code(), r0.code(), r2.code(), opnd.immediate()); \ + } \ + void name(Register r1, const Operand& opnd) { \ + rs_format(opcode, r1.code(), r0.code(), r0.code(), opnd.immediate()); \ + } + DECLARE_S390_RS_SHIFT_FORMAT(sll, SLL) + DECLARE_S390_RS_SHIFT_FORMAT(srl, SRL) + DECLARE_S390_RS_SHIFT_FORMAT(sla, SLA) + DECLARE_S390_RS_SHIFT_FORMAT(sra, SRA) + DECLARE_S390_RS_SHIFT_FORMAT(sldl, SLDL) + DECLARE_S390_RS_SHIFT_FORMAT(srda, SRDA) + DECLARE_S390_RS_SHIFT_FORMAT(srdl, SRDL) +#undef DECLARE_S390_RS_SHIFT_FORMAT + + +inline void rxe_format(Opcode op, int f1, int f2, int f3, int f4, int f5 = 0) { + DCHECK(is_uint12(f4)); + DCHECK(is_uint16(op)); + uint64_t code = (getfield<uint64_t, 6, 0, 8>(op >> 8) | + getfield<uint64_t, 6, 8, 12>(f1) | + getfield<uint64_t, 6, 12, 16>(f2) | + getfield<uint64_t, 6, 16, 20>(f3) | + getfield<uint64_t, 6, 20, 32>(f4 & 0x0fff) | + getfield<uint64_t, 6, 32, 36>(f5) | + getfield<uint64_t, 6, 40, 48>(op & 0xff)); + emit6bytes(code); +} + +#define DECLARE_S390_RXE_INSTRUCTIONS(name, op_name, op_value) \ + void name(Register r1, Register x2, Register b2, const Operand& d2, \ + Condition m3 = static_cast<Condition>(0)) { \ + rxe_format(op_name, r1.code(), x2.code(), b2.code(), d2.immediate(), \ + m3); \ + } \ + template<class _R1Type> \ + void name(_R1Type r1, const MemOperand& opnd) { \ + name(Register::from_code(r1.code()), opnd.rx(), opnd.rb(), \ + Operand(opnd.offset())); \ + } + S390_RXE_OPCODE_LIST(DECLARE_S390_RXE_INSTRUCTIONS); +#undef DECLARE_S390_RXE_INSTRUCTIONS + + +inline void ri_format(Opcode opcode, int f1, int f2) { + uint32_t op1 = opcode >> 4; + uint32_t op2 = opcode & 0xf; + emit4bytes(getfield<uint32_t, 4, 0, 8>(op1) | + getfield<uint32_t, 4, 8, 12>(f1) | + getfield<uint32_t, 4, 12, 16>(op2) | + getfield<uint32_t, 4, 16, 32>(f2)); +} + +#define DECLARE_S390_RI_A_INSTRUCTIONS(name, op_name, op_value) \ + void name(Register r, const Operand& i2) { \ + DCHECK(is_uint12(op_name)); \ + DCHECK(is_uint16(i2.immediate()) || is_int16(i2.immediate())); \ + ri_format(op_name, r.code(), i2.immediate()); \ + } + S390_RI_A_OPCODE_LIST(DECLARE_S390_RI_A_INSTRUCTIONS); +#undef DECLARE_S390_RI_A_INSTRUCTIONS + +#define DECLARE_S390_RI_B_INSTRUCTIONS(name, op_name, op_value) \ + void name(Register r1, const Operand& imm) { \ + /* 2nd argument encodes # of halfwords, so divide by 2. */ \ + int16_t numHalfwords = static_cast<int16_t>(imm.immediate()) / 2; \ + Operand halfwordOp = Operand(numHalfwords); \ + halfwordOp.setBits(16); \ + ri_format(op_name, r1.code(), halfwordOp.immediate()); \ + } + S390_RI_B_OPCODE_LIST(DECLARE_S390_RI_B_INSTRUCTIONS); +#undef DECLARE_S390_RI_B_INSTRUCTIONS + +#define DECLARE_S390_RI_C_INSTRUCTIONS(name, op_name, op_value) \ + void name(Condition m, const Operand& i2) { \ + DCHECK(is_uint12(op_name)); \ + DCHECK(is_uint4(m)); \ + DCHECK(op_name == BRC ? \ + is_int16(i2.immediate()) : is_uint16(i2.immediate())); \ + ri_format(op_name, m, i2.immediate()); \ + } + S390_RI_C_OPCODE_LIST(DECLARE_S390_RI_C_INSTRUCTIONS); +#undef DECLARE_S390_RI_C_INSTRUCTIONS + + +inline void rrf_format(Opcode op, int f1, int f2, int f3, int f4) { + uint32_t code = getfield<uint32_t, 4, 0, 16>(op) | + getfield<uint32_t, 4, 16, 20>(f1) | + getfield<uint32_t, 4, 20, 24>(f2) | + getfield<uint32_t, 4, 24, 28>(f3) | + getfield<uint32_t, 4, 28, 32>(f4); + emit4bytes(code); +} + +#define DECLARE_S390_RRF_A_INSTRUCTIONS(name, op_name, op_value) \ + void name(Register r1, Condition m4, Register r2, Register r3) { \ + rrf_format(op_name, r3.code(), m4, r1.code(), r2.code()); \ + } \ + void name(Register r1, Register r2, Register r3) { \ + name(r1, Condition(0), r2, r3); \ + } + S390_RRF_A_OPCODE_LIST(DECLARE_S390_RRF_A_INSTRUCTIONS); +#undef DECLARE_S390_RRF_A_INSTRUCTIONS + + +#define DECLARE_S390_RRF_B_INSTRUCTIONS(name, op_name, op_value) \ + void name(Register r1, Condition m4, Register r2, Register r3) { \ + rrf_format(op_name, r3.code(), m4, r1.code(), r2.code()); \ + } \ + void name(Register r1, Register r2, Register r3) { \ + name(r1, Condition(0), r2, r3); \ + } + S390_RRF_B_OPCODE_LIST(DECLARE_S390_RRF_B_INSTRUCTIONS); +#undef DECLARE_S390_RRF_B_INSTRUCTIONS + + +#define DECLARE_S390_RRF_C_INSTRUCTIONS(name, op_name, op_value) \ + template <class R1, class R2> \ + void name(Condition m3, Condition m4, R1 r1, R2 r2) { \ + rrf_format(op_name, m3, m4, r1.code(), r2.code()); \ + } \ + template <class R1, class R2> \ + void name(Condition m3, R1 r1, R2 r2) { \ + name(m3, Condition(0), r1, r2); \ + } + S390_RRF_C_OPCODE_LIST(DECLARE_S390_RRF_C_INSTRUCTIONS); +#undef DECLARE_S390_RRF_C_INSTRUCTIONS + + +#define DECLARE_S390_RRF_D_INSTRUCTIONS(name, op_name, op_value) \ + template <class R1, class R2> \ + void name(Condition m3, Condition m4, R1 r1, R2 r2) { \ + rrf_format(op_name, m3, m4, r1.code(), r2.code()); \ + } \ + template <class R1, class R2> \ + void name(Condition m3, R1 r1, R2 r2) { \ + name(m3, Condition(0), r1, r2); \ + } + S390_RRF_D_OPCODE_LIST(DECLARE_S390_RRF_D_INSTRUCTIONS); +#undef DECLARE_S390_RRF_D_INSTRUCTIONS + + +#define DECLARE_S390_RRF_E_INSTRUCTIONS(name, op_name, op_value) \ + template <class M3, class M4, class R1, class R2> \ + void name(M3 m3, M4 m4, R1 r1, R2 r2) { \ + rrf_format(op_name, m3, m4, r1.code(), r2.code()); \ + } \ + template <class M3, class R1, class R2> \ + void name(M3 m3, R1 r1, R2 r2) { \ + name(m3, Condition(0), r1, r2); \ + } + S390_RRF_E_OPCODE_LIST(DECLARE_S390_RRF_E_INSTRUCTIONS); +#undef DECLARE_S390_RRF_E_INSTRUCTIONS + +enum FIDBRA_FLAGS { + FIDBRA_CURRENT_ROUNDING_MODE = 0, + FIDBRA_ROUND_TO_NEAREST_AWAY_FROM_0 = 1, + // ... + FIDBRA_ROUND_TOWARD_0 = 5, + FIDBRA_ROUND_TOWARD_POS_INF = 6, + FIDBRA_ROUND_TOWARD_NEG_INF = 7 +}; + + +inline void rsi_format(Opcode op, int f1, int f2, int f3) { + DCHECK(is_uint8(op)); + DCHECK(is_uint16(f3) || is_int16(f3)); + uint32_t code = getfield<uint32_t, 4, 0, 8>(op) | + getfield<uint32_t, 4, 8, 12>(f1) | + getfield<uint32_t, 4, 12, 16>(f2) | + getfield<uint32_t, 4, 16, 32>(f3); + emit4bytes(code); +} + +#define DECLARE_S390_RSI_INSTRUCTIONS(name, op_name, op_value) \ + void name(Register r1, Register r3, const Operand& i2) { \ + rsi_format(op_name, r1.code(), r3.code(), i2.immediate()); \ + } + S390_RSI_OPCODE_LIST(DECLARE_S390_RSI_INSTRUCTIONS); +#undef DECLARE_S390_RSI_INSTRUCTIONS + + +inline void rsl_format(Opcode op, uint16_t f1, int f2, int f3, int f4, + int f5) { + DCHECK(is_uint16(op)); + uint64_t code = getfield<uint64_t, 6, 0, 8>(op >> 8) | + getfield<uint64_t, 6, 8, 16>(f1) | + getfield<uint64_t, 6, 16, 20>(f2) | + getfield<uint64_t, 6, 20, 32>(f3) | + getfield<uint64_t, 6, 32, 36>(f4) | + getfield<uint64_t, 6, 36, 40>(f5) | + getfield<uint64_t, 6, 40, 48>(op & 0x00FF); + emit6bytes(code); +} + +#define DECLARE_S390_RSL_A_INSTRUCTIONS(name, op_name, op_value) \ + void name(const Operand& l1, Register b1, const Operand& d1) { \ + uint16_t L = static_cast<uint16_t>(l1.immediate() << 8); \ + rsl_format(op_name, L, b1.code(), d1.immediate(), 0, 0); \ + } + S390_RSL_A_OPCODE_LIST(DECLARE_S390_RSL_A_INSTRUCTIONS); +#undef DECLARE_S390_RSL_A_INSTRUCTIONS + +#define DECLARE_S390_RSL_B_INSTRUCTIONS(name, op_name, op_value) \ + void name(const Operand& l2, Register b2, const Operand& d2, \ + Register r1, Condition m3) { \ + uint16_t L = static_cast<uint16_t>(l2.immediate()); \ + rsl_format(op_name, L, b2.code(), d2.immediate(), r1.code(), m3); \ + } + S390_RSL_B_OPCODE_LIST(DECLARE_S390_RSL_B_INSTRUCTIONS); +#undef DECLARE_S390_RSL_B_INSTRUCTIONS + + +inline void s_format(Opcode op, int f1, int f2) { + DCHECK_NE(op & 0xff00, 0); + DCHECK(is_uint12(f2)); + uint32_t code = getfield<uint32_t, 4, 0, 16>(op) | + getfield<uint32_t, 4, 16, 20>(f1) | + getfield<uint32_t, 4, 20, 32>(f2); + emit4bytes(code); +} + +#define DECLARE_S390_S_INSTRUCTIONS(name, op_name, op_value) \ + void name(Register b1, const Operand& d2) { \ + Opcode op = op_name; \ + if ((op & 0xFF00) == 0) { \ + op = (Opcode)(op << 8); \ + } \ + s_format(op, b1.code(), d2.immediate()); \ + } \ + void name(const MemOperand& opnd) { \ + Operand d2 = Operand(opnd.getDisplacement()); \ + name(opnd.getBaseRegister(), d2); \ + } + S390_S_OPCODE_LIST(DECLARE_S390_S_INSTRUCTIONS); +#undef DECLARE_S390_S_INSTRUCTIONS + + +inline void si_format(Opcode op, int f1, int f2, int f3) { + uint32_t code = getfield<uint32_t, 4, 0, 8>(op) | + getfield<uint32_t, 4, 8, 16>(f1) | + getfield<uint32_t, 4, 16, 20>(f2) | + getfield<uint32_t, 4, 20, 32>(f3); + emit4bytes(code); +} + +#define DECLARE_S390_SI_INSTRUCTIONS(name, op_name, op_value) \ + void name(const Operand& i2, Register b1, const Operand& d1) { \ + si_format(op_name, i2.immediate(), b1.code(), d1.immediate()); \ + } \ + void name(const MemOperand& opnd, const Operand& i2) { \ + name(i2, opnd.getBaseRegister(), Operand(opnd.getDisplacement())); \ + } + S390_SI_OPCODE_LIST(DECLARE_S390_SI_INSTRUCTIONS); +#undef DECLARE_S390_SI_INSTRUCTIONS + + +inline void siy_format(Opcode op, int f1, int f2, int f3) { + DCHECK(is_uint20(f3) || is_int20(f3)); + DCHECK(is_uint16(op)); + DCHECK(is_uint8(f1) || is_int8(f1)); + uint64_t code = getfield<uint64_t, 6, 0, 8>(op >> 8) | + getfield<uint64_t, 6, 8, 16>(f1) | + getfield<uint64_t, 6, 16, 20>(f2) | + getfield<uint64_t, 6, 20, 32>(f3) | + getfield<uint64_t, 6, 32, 40>(f3 >> 12) | + getfield<uint64_t, 6, 40, 48>(op & 0x00FF); + emit6bytes(code); +} + +#define DECLARE_S390_SIY_INSTRUCTIONS(name, op_name, op_value) \ + void name(const Operand& i2, Register b1, const Operand& d1) { \ + siy_format(op_name, i2.immediate(), b1.code(), d1.immediate()); \ + } \ + void name(const MemOperand& opnd, const Operand& i2) { \ + name(i2, opnd.getBaseRegister(), Operand(opnd.getDisplacement())); \ + } + S390_SIY_OPCODE_LIST(DECLARE_S390_SIY_INSTRUCTIONS); +#undef DECLARE_S390_SIY_INSTRUCTIONS + + +inline void rrs_format(Opcode op, int f1, int f2, int f3, int f4, int f5) { + DCHECK(is_uint12(f4)); + DCHECK(is_uint16(op)); + uint64_t code = getfield<uint64_t, 6, 0, 8>(op >> 8) | + getfield<uint64_t, 6, 8, 12>(f1) | + getfield<uint64_t, 6, 12, 16>(f2) | + getfield<uint64_t, 6, 16, 20>(f3) | + getfield<uint64_t, 6, 20, 32>(f4) | + getfield<uint64_t, 6, 32, 36>(f5) | + getfield<uint64_t, 6, 40, 48>(op & 0x00FF); + emit6bytes(code); +} + +#define DECLARE_S390_RRS_INSTRUCTIONS(name, op_name, op_value) \ + void name(Register r1, Register r2, Register b4, const Operand& d4, \ + Condition m3) { \ + rrs_format(op_name, r1.code(), r2.code(), b4.code(), d4.immediate(), \ + m3); \ + } \ + void name(Register r1, Register r2, Condition m3, \ + const MemOperand& opnd) { \ + name(r1, r2, opnd.getBaseRegister(), \ + Operand(opnd.getDisplacement()), m3); \ + } + S390_RRS_OPCODE_LIST(DECLARE_S390_RRS_INSTRUCTIONS); +#undef DECLARE_S390_RRS_INSTRUCTIONS + + +inline void ris_format(Opcode op, int f1, int f2, int f3, int f4, int f5) { + DCHECK(is_uint12(f3)); + DCHECK(is_uint16(op)); + DCHECK(is_uint8(f5)); + uint64_t code = getfield<uint64_t, 6, 0, 8>(op >> 8) | + getfield<uint64_t, 6, 8, 12>(f1) | + getfield<uint64_t, 6, 12, 16>(f2) | + getfield<uint64_t, 6, 16, 20>(f3) | + getfield<uint64_t, 6, 20, 32>(f4) | + getfield<uint64_t, 6, 32, 40>(f5) | + getfield<uint64_t, 6, 40, 48>(op & 0x00FF); + emit6bytes(code); +} + +#define DECLARE_S390_RIS_INSTRUCTIONS(name, op_name, op_value) \ + void name(Register r1, Condition m3, Register b4, const Operand& d4, \ + const Operand& i2) { \ + ris_format(op_name, r1.code(), m3, b4.code(), d4.immediate(), \ + i2.immediate()); \ + } \ + void name(Register r1, const Operand& i2, Condition m3, \ + const MemOperand& opnd) { \ + name(r1, m3, opnd.getBaseRegister(), \ + Operand(opnd.getDisplacement()), i2); \ + } + S390_RIS_OPCODE_LIST(DECLARE_S390_RIS_INSTRUCTIONS); +#undef DECLARE_S390_RIS_INSTRUCTIONS + + +inline void sil_format(Opcode op, int f1, int f2, int f3) { + DCHECK(is_uint12(f2)); + DCHECK(is_uint16(op)); + DCHECK(is_uint16(f3)); + uint64_t code = getfield<uint64_t, 6, 0, 16>(op) | + getfield<uint64_t, 6, 16, 20>(f1) | + getfield<uint64_t, 6, 20, 32>(f2) | + getfield<uint64_t, 6, 32, 48>(f3); + emit6bytes(code); +} + +#define DECLARE_S390_SIL_INSTRUCTIONS(name, op_name, op_value) \ + void name(Register b1, const Operand& d1, const Operand& i2) { \ + sil_format(op_name, b1.code(), d1.immediate(), i2.immediate()); \ + } \ + void name(const MemOperand& opnd, const Operand& i2) { \ + name(opnd.getBaseRegister(), Operand(opnd.getDisplacement()), i2); \ + } + S390_SIL_OPCODE_LIST(DECLARE_S390_SIL_INSTRUCTIONS); +#undef DECLARE_S390_SIL_INSTRUCTIONS + + +inline void rie_d_format(Opcode opcode, int f1, int f2, int f3, int f4) { + uint32_t op1 = opcode >> 8; + uint32_t op2 = opcode & 0xff; + uint64_t code = getfield<uint64_t, 6, 0, 8>(op1) | + getfield<uint64_t, 6, 8, 12>(f1) | + getfield<uint64_t, 6, 12, 16>(f2) | + getfield<uint64_t, 6, 16, 32>(f3) | + getfield<uint64_t, 6, 32, 40>(f4) | + getfield<uint64_t, 6, 40, 48>(op2); + emit6bytes(code); +} + +#define DECLARE_S390_RIE_D_INSTRUCTIONS(name, op_name, op_value) \ + void name(Register r1, Register r3, const Operand& i2) { \ + rie_d_format(op_name, r1.code(), r3.code(), i2.immediate(), 0); \ + } + S390_RIE_D_OPCODE_LIST(DECLARE_S390_RIE_D_INSTRUCTIONS) +#undef DECLARE_S390_RIE_D_INSTRUCTIONS + + +inline void rie_e_format(Opcode opcode, int f1, int f2, int f3) { + uint32_t op1 = opcode >> 8; + uint32_t op2 = opcode & 0xff; + uint64_t code = getfield<uint64_t, 6, 0, 8>(op1) | + getfield<uint64_t, 6, 8, 12>(f1) | + getfield<uint64_t, 6, 12, 16>(f2) | + getfield<uint64_t, 6, 16, 32>(f3) | + getfield<uint64_t, 6, 40, 48>(op2); + emit6bytes(code); +} + +#define DECLARE_S390_RIE_E_INSTRUCTIONS(name, op_name, op_value) \ + void name(Register r1, Register r3, const Operand& i2) { \ + rie_e_format(op_name, r1.code(), r3.code(), i2.immediate()); \ + } + S390_RIE_E_OPCODE_LIST(DECLARE_S390_RIE_E_INSTRUCTIONS) +#undef DECLARE_S390_RIE_E_INSTRUCTIONS + + +inline void rie_f_format(Opcode opcode, int f1, int f2, int f3, int f4, + int f5) { + uint32_t op1 = opcode >> 8; + uint32_t op2 = opcode & 0xff; + uint64_t code = getfield<uint64_t, 6, 0, 8>(op1) | + getfield<uint64_t, 6, 8, 12>(f1) | + getfield<uint64_t, 6, 12, 16>(f2) | + getfield<uint64_t, 6, 16, 24>(f3) | + getfield<uint64_t, 6, 24, 32>(f4) | + getfield<uint64_t, 6, 32, 40>(f5) | + getfield<uint64_t, 6, 40, 48>(op2); + emit6bytes(code); +} + +#define DECLARE_S390_RIE_F_INSTRUCTIONS(name, op_name, op_value) \ + void name(Register dst, Register src, const Operand& startBit, \ + const Operand& endBit, const Operand& shiftAmt) { \ + DCHECK(is_uint8(startBit.immediate())); \ + DCHECK(is_uint8(endBit.immediate())); \ + DCHECK(is_uint8(shiftAmt.immediate())); \ + rie_f_format(op_name, dst.code(), src.code(), startBit.immediate(), \ + endBit.immediate(), shiftAmt.immediate()); \ + } + S390_RIE_F_OPCODE_LIST(DECLARE_S390_RIE_F_INSTRUCTIONS) +#undef DECLARE_S390_RIE_F_INSTRUCTIONS + + +inline void ss_a_format(Opcode op, int f1, int f2, int f3, int f4, int f5) { + DCHECK(is_uint12(f5)); + DCHECK(is_uint12(f3)); + DCHECK(is_uint8(f1)); + DCHECK(is_uint8(op)); + uint64_t code = getfield<uint64_t, 6, 0, 8>(op) | + getfield<uint64_t, 6, 8, 16>(f1) | + getfield<uint64_t, 6, 16, 20>(f2) | + getfield<uint64_t, 6, 20, 32>(f3) | + getfield<uint64_t, 6, 32, 36>(f4) | + getfield<uint64_t, 6, 36, 48>(f5); + emit6bytes(code); +} + +#define DECLARE_S390_SS_A_INSTRUCTIONS(name, op_name, op_value) \ + void name(Register b1, const Operand& d1, Register b2, \ + const Operand& d2, const Operand& length) { \ + ss_a_format(op_name, length.immediate(), b1.code(), d1.immediate(), \ + b2.code(), d2.immediate()); \ + } \ + void name(const MemOperand& opnd1, const MemOperand& opnd2, \ + const Operand& length) { \ + ss_a_format(op_name, length.immediate(), \ + opnd1.getBaseRegister().code(), \ + opnd1.getDisplacement(), opnd2.getBaseRegister().code(), \ + opnd2.getDisplacement()); \ + } + S390_SS_A_OPCODE_LIST(DECLARE_S390_SS_A_INSTRUCTIONS) +#undef DECLARE_S390_SS_A_INSTRUCTIONS + + // Helper for unconditional branch to Label with update to save register void b(Register r, Label* l) { int32_t halfwords = branch_offset(l) / 2; @@ -919,6 +1318,59 @@ inline void rsy_form(Opcode op, int f1, int f2, int f3, const int f4) { void bunordered(Register r) { b(unordered, r); } void bordered(Register r) { b(ordered, r); } + // wrappers around asm instr + void brxh(Register dst, Register inc, Label* L) { + int offset_halfwords = branch_offset(L) / 2; + CHECK(is_int16(offset_halfwords)); + brxh(dst, inc, Operand(offset_halfwords)); + } + + void brxhg(Register dst, Register inc, Label* L) { + int offset_halfwords = branch_offset(L) / 2; + CHECK(is_int16(offset_halfwords)); + brxhg(dst, inc, Operand(offset_halfwords)); + } + + template <class R1, class R2> + void ledbr(R1 r1, R2 r2) { + ledbra(Condition(0), Condition(0), r1, r2); + } + + template <class R1, class R2> + void cdfbr(R1 r1, R2 r2) { + cdfbra(Condition(0), Condition(0), r1, r2); + } + + template <class R1, class R2> + void cdgbr(R1 r1, R2 r2) { + cdgbra(Condition(0), Condition(0), r1, r2); + } + + template <class R1, class R2> + void cegbr(R1 r1, R2 r2) { + cegbra(Condition(0), Condition(0), r1, r2); + } + + template <class R1, class R2> + void cgebr(Condition m3, R1 r1, R2 r2) { + cgebra(m3, Condition(0), r1, r2); + } + + template <class R1, class R2> + void cgdbr(Condition m3, R1 r1, R2 r2) { + cgdbra(m3, Condition(0), r1, r2); + } + + template <class R1, class R2> + void cfdbr(Condition m3, R1 r1, R2 r2) { + cfdbra(m3, Condition(0), r1, r2); + } + + template <class R1, class R2> + void cfebr(Condition m3, R1 r1, R2 r2) { + cfebra(m3, Condition(0), r1, r2); + } + // --------------------------------------------------------------------------- // Code generation @@ -954,121 +1406,6 @@ inline void rsy_form(Opcode op, int f1, int f2, int f3, const int f4) { void jump(Handle<Code> target, RelocInfo::Mode rmode, Condition cond); // S390 instruction generation -#define I_FORM(name) void name(const Operand& i) - -#define RR_FORM(name) void name(Register r1, Register r2) - -#define RR2_FORM(name) void name(Condition m1, Register r2) - -#define RI1_FORM(name) void name(Register r, const Operand& i) - -#define RI2_FORM(name) void name(Condition m, const Operand& i) - -#define RIE_FORM(name) void name(Register r1, Register R3, const Operand& i) - -#define RIE_F_FORM(name) \ - void name(Register r1, Register r2, const Operand& i3, const Operand& i4, \ - const Operand& i5) - -#define RXE_FORM(name) \ - void name(Register r1, const MemOperand& opnd); \ - void name(Register r1, Register b2, Register x2, Disp d2) - -#define RXF_FORM(name) \ - void name(Register r1, Register r3, const MemOperand& opnd); \ - void name(Register r1, Register r3, Register b2, Register x2, Disp d2) - -#define RSI_FORM(name) void name(Register r1, Register r3, const Operand& i) - -#define RIS_FORM(name) \ - void name(Register r1, Condition m3, Register b4, Disp d4, \ - const Operand& i2); \ - void name(Register r1, const Operand& i2, Condition m3, \ - const MemOperand& opnd) - -#define SI_FORM(name) \ - void name(const MemOperand& opnd, const Operand& i); \ - void name(const Operand& i2, Register b1, Disp d1) - -#define SIL_FORM(name) \ - void name(Register b1, Disp d1, const Operand& i2); \ - void name(const MemOperand& opnd, const Operand& i2) - -#define RRF1_FORM(name) void name(Register r1, Register r2, Register r3) - -#define RRF2_FORM(name) void name(Condition m1, Register r1, Register r2) - -#define RRF3_FORM(name) \ - void name(Register r3, Condition m4, Register r1, Register r2) - -#define RS1_FORM(name) \ - void name(Register r1, Register r3, const MemOperand& opnd); \ - void name(Register r1, Register r3, Register b2, Disp d2) - -#define RS2_FORM(name) \ - void name(Register r1, Condition m3, const MemOperand& opnd); \ - void name(Register r1, Condition m3, Register b2, Disp d2) - -#define RSE_FORM(name) \ - void name(Register r1, Register r3, const MemOperand& opnd); \ - void name(Register r1, Register r3, Register b2, Disp d2) - -#define RSL_FORM(name) \ - void name(Length l, Register b2, Disp d2); \ - void name(const MemOperand& opnd) - -#define RSY1_FORM(name) \ - void name(Register r1, Register r3, Register b2, Disp d2); \ - void name(Register r1, Register r3, const MemOperand& opnd) - -#define RSY2_FORM(name) \ - void name(Register r1, Condition m3, Register b2, Disp d2); \ - void name(Register r1, Condition m3, const MemOperand& opnd) - -#define RRS_FORM(name) \ - void name(Register r1, Register r2, Register b4, Disp d4, Condition m3); \ - void name(Register r1, Register r2, Condition m3, const MemOperand& opnd) - -#define S_FORM(name) \ - void name(Register b2, Disp d2); \ - void name(const MemOperand& opnd) - -#define SIY_FORM(name) \ - void name(const Operand& i2, Register b1, Disp d1); \ - void name(const MemOperand& opnd, const Operand& i) - -#define SS1_FORM(name) \ - void name(Register b1, Disp d1, Register b3, Disp d2, Length length); \ - void name(const MemOperand& opnd1, const MemOperand& opnd2, Length length) - -#define SS2_FORM(name) \ - void name(const MemOperand& opnd1, const MemOperand& opnd2, Length length1, \ - Length length2); \ - void name(Register b1, Disp d1, Register b2, Disp d2, Length l1, Length l2) - -#define SS3_FORM(name) \ - void name(const MemOperand& opnd1, const MemOperand& opnd2, Length length); \ - void name(const Operand& i3, Register b1, Disp d1, Register b2, Disp d2, \ - Length l1) - -#define SS4_FORM(name) \ - void name(const MemOperand& opnd1, const MemOperand& opnd2); \ - void name(Register r1, Register r3, Register b1, Disp d1, Register b2, \ - Disp d2) - -#define SS5_FORM(name) \ - void name(const MemOperand& opnd1, const MemOperand& opnd2); \ - void name(Register r1, Register r3, Register b3, Disp d2, Register b4, \ - Disp d4) - -#define SSE_FORM(name) \ - void name(Register b1, Disp d1, Register b2, Disp d2); \ - void name(const MemOperand& opnd1, const MemOperand& opnd2) - -#define SSF_FORM(name) \ - void name(Register r3, Register b1, Disp d1, Register b2, Disp d2); \ - void name(Register r3, const MemOperand& opnd1, const MemOperand& opnd2) - #define DECLARE_VRR_A_INSTRUCTIONS(name, opcode_name, opcode_value) \ void name(DoubleRegister v1, DoubleRegister v2, Condition m5, Condition m4, \ Condition m3) { \ @@ -1118,201 +1455,9 @@ inline void rsy_form(Opcode op, int f1, int f2, int f3, const int f4) { static_cast<Condition>(3)); } - // S390 instruction sets - RXE_FORM(ddb); - SS1_FORM(ed); - RRF2_FORM(fidbr); - RI1_FORM(iihh); - RI1_FORM(iihl); - RI1_FORM(iilh); - RI1_FORM(iill); - RSY1_FORM(loc); - RXE_FORM(mdb); - SS4_FORM(mvck); - SSF_FORM(mvcos); - SS4_FORM(mvcs); - SS1_FORM(mvn); - SS1_FORM(nc); - SI_FORM(ni); - RI1_FORM(nilh); - RI1_FORM(nill); - RI1_FORM(oill); - RXE_FORM(sdb); - RS1_FORM(srdl); - RI1_FORM(tmll); - SS1_FORM(tr); - S_FORM(ts); - // Load Address Instructions void larl(Register r, Label* l); - // Load Instructions - void lhi(Register r, const Operand& imm); - void lghi(Register r, const Operand& imm); - - // Load Multiple Instructions - void lm(Register r1, Register r2, const MemOperand& src); - - // Load On Condition Instructions - void locr(Condition m3, Register r1, Register r2); - void locgr(Condition m3, Register r1, Register r2); - - // Store Instructions - - // Store Multiple Instructions - void stm(Register r1, Register r2, const MemOperand& src); - - // Compare Instructions - void chi(Register r, const Operand& opnd); - void cghi(Register r, const Operand& opnd); - - // Compare Logical Instructions - void cli(const MemOperand& mem, const Operand& imm); - void cliy(const MemOperand& mem, const Operand& imm); - void clc(const MemOperand& opnd1, const MemOperand& opnd2, Length length); - - // Compare and Swap Instructions - void cs(Register r1, Register r2, const MemOperand& src); - - // Test Under Mask Instructions - void tm(const MemOperand& mem, const Operand& imm); - void tmy(const MemOperand& mem, const Operand& imm); - - // Shift Instructions (32) - void sll(Register r1, Register opnd); - void sll(Register r1, const Operand& opnd); - void srl(Register r1, Register opnd); - void srl(Register r1, const Operand& opnd); - void sra(Register r1, Register opnd); - void sra(Register r1, const Operand& opnd); - void sla(Register r1, Register opnd); - void sla(Register r1, const Operand& opnd); - - // Shift Instructions (64) - void srda(Register r1, const Operand& opnd); - void srdl(Register r1, const Operand& opnd); - void sldl(Register r1, Register b2, const Operand& opnd); - void srdl(Register r1, Register b2, const Operand& opnd); - void srda(Register r1, Register b2, const Operand& opnd); - - // Rotate and Insert Selected Bits - void risbg(Register dst, Register src, const Operand& startBit, - const Operand& endBit, const Operand& shiftAmt, - bool zeroBits = true); - void risbgn(Register dst, Register src, const Operand& startBit, - const Operand& endBit, const Operand& shiftAmt, - bool zeroBits = true); - - // Move Character (Mem to Mem) - void mvc(const MemOperand& opnd1, const MemOperand& opnd2, uint32_t length); - - // Branch Instructions - void bras(Register r, const Operand& opnd); - void brc(Condition c, const Operand& opnd); - void brct(Register r1, const Operand& opnd); - void brctg(Register r1, const Operand& opnd); - - // 32-bit Add Instructions - void ahi(Register r1, const Operand& opnd); - void ahik(Register r1, Register r3, const Operand& opnd); - void ark(Register r1, Register r2, Register r3); - void asi(const MemOperand&, const Operand&); - - // 64-bit Add Instructions - void aghi(Register r1, const Operand& opnd); - void aghik(Register r1, Register r3, const Operand& opnd); - void agrk(Register r1, Register r2, Register r3); - void agsi(const MemOperand&, const Operand&); - - // 32-bit Add Logical Instructions - void alrk(Register r1, Register r2, Register r3); - - // 64-bit Add Logical Instructions - void algrk(Register r1, Register r2, Register r3); - - // 32-bit Subtract Instructions - void srk(Register r1, Register r2, Register r3); - - // 64-bit Subtract Instructions - void sgrk(Register r1, Register r2, Register r3); - - // 32-bit Subtract Logical Instructions - void slrk(Register r1, Register r2, Register r3); - - // 64-bit Subtract Logical Instructions - void slgrk(Register r1, Register r2, Register r3); - - // 32-bit Multiply Instructions - void mhi(Register r1, const Operand& opnd); - void msrkc(Register r1, Register r2, Register r3); - void msgrkc(Register r1, Register r2, Register r3); - - // 64-bit Multiply Instructions - void mghi(Register r1, const Operand& opnd); - - // Bitwise Instructions (AND / OR / XOR) - void nrk(Register r1, Register r2, Register r3); - void ngrk(Register r1, Register r2, Register r3); - void ork(Register r1, Register r2, Register r3); - void ogrk(Register r1, Register r2, Register r3); - void xrk(Register r1, Register r2, Register r3); - void xgrk(Register r1, Register r2, Register r3); - void xc(const MemOperand& opnd1, const MemOperand& opnd2, Length length); - - // Floating <-> Fixed Point Conversion Instructions - void cdlfbr(Condition m3, Condition m4, DoubleRegister fltReg, - Register fixReg); - void cdlgbr(Condition m3, Condition m4, DoubleRegister fltReg, - Register fixReg); - void celgbr(Condition m3, Condition m4, DoubleRegister fltReg, - Register fixReg); - void celfbr(Condition m3, Condition m4, DoubleRegister fltReg, - Register fixReg); - void clfdbr(Condition m3, Condition m4, Register fixReg, - DoubleRegister fltReg); - void clfebr(Condition m3, Condition m4, Register fixReg, - DoubleRegister fltReg); - void clgdbr(Condition m3, Condition m4, Register fixReg, - DoubleRegister fltReg); - void clgebr(Condition m3, Condition m4, Register fixReg, - DoubleRegister fltReg); - void cfdbr(Condition m, Register fixReg, DoubleRegister fltReg); - void cgebr(Condition m, Register fixReg, DoubleRegister fltReg); - void cgdbr(Condition m, Register fixReg, DoubleRegister fltReg); - void cfebr(Condition m3, Register fixReg, DoubleRegister fltReg); - void cefbr(Condition m3, DoubleRegister fltReg, Register fixReg); - - // Floating Point Compare Instructions - void cdb(DoubleRegister r1, const MemOperand& opnd); - void ceb(DoubleRegister r1, const MemOperand& opnd); - - // Floating Point Arithmetic Instructions - void adb(DoubleRegister r1, const MemOperand& opnd); - void aeb(DoubleRegister r1, const MemOperand& opnd); - void sdb(DoubleRegister r1, const MemOperand& opnd); - void seb(DoubleRegister r1, const MemOperand& opnd); - void mdb(DoubleRegister r1, const MemOperand& opnd); - void meeb(DoubleRegister r1, const MemOperand& opnd); - void ddb(DoubleRegister r1, const MemOperand& opnd); - void deb(DoubleRegister r1, const MemOperand& opnd); - void sqdb(DoubleRegister r1, const MemOperand& opnd); - void ldeb(DoubleRegister r1, const MemOperand& opnd); - - enum FIDBRA_MASK3 { - FIDBRA_CURRENT_ROUNDING_MODE = 0, - FIDBRA_ROUND_TO_NEAREST_AWAY_FROM_0 = 1, - // ... - FIDBRA_ROUND_TOWARD_0 = 5, - FIDBRA_ROUND_TOWARD_POS_INF = 6, - FIDBRA_ROUND_TOWARD_NEG_INF = 7 - }; - void fiebra(DoubleRegister d1, DoubleRegister d2, FIDBRA_MASK3 m3); - void fidbra(DoubleRegister d1, DoubleRegister d2, FIDBRA_MASK3 m3); - - // Move integer - void mvhi(const MemOperand& opnd1, const Operand& i2); - void mvghi(const MemOperand& opnd1, const Operand& i2); - // Exception-generating instructions and debugging support void stop(const char* msg, Condition cond = al, int32_t code = kDefaultStopCode, CRegister cr = cr7); @@ -1409,7 +1554,6 @@ inline void rsy_form(Opcode op, int f1, int f2, int f3, const int f4) { public: byte* buffer_pos() const { return buffer_; } - void RequestHeapObject(HeapObjectRequest request); protected: int buffer_space() const { return reloc_info_writer.pos() - pc_; } @@ -1454,9 +1598,6 @@ inline void rsy_form(Opcode op, int f1, int f2, int f3, const int f4) { inline void TrackBranch(); inline void UntrackBranch(); - inline int32_t emit_code_target( - Handle<Code> target, RelocInfo::Mode rmode); - // Helper to emit the binary encoding of a 2 byte instruction void emit2bytes(uint16_t x) { CheckBuffer(); @@ -1510,83 +1651,16 @@ inline void rsy_form(Opcode op, int f1, int f2, int f3, const int f4) { pc_ += 6; } - // Helpers to emit binary encoding for various instruction formats. - - inline void rr2_form(uint8_t op, Condition m1, Register r2); - - inline void ri_form(Opcode op, Register r1, const Operand& i2); - inline void ri_form(Opcode op, Condition m1, const Operand& i2); - - inline void rie_form(Opcode op, Register r1, Register r3, const Operand& i2); - inline void rie_f_form(Opcode op, Register r1, Register r2, const Operand& i3, - const Operand& i4, const Operand& i5); - - inline void ris_form(Opcode op, Register r1, Condition m3, Register b4, - Disp d4, const Operand& i2); - - inline void rrf1_form(Opcode op, Register r1, Register r2, Register r3); - inline void rrf1_form(uint32_t x); - inline void rrf2_form(uint32_t x); - inline void rrf3_form(uint32_t x); - inline void rrfe_form(Opcode op, Condition m3, Condition m4, Register r1, - Register r2); - - inline void rrs_form(Opcode op, Register r1, Register r2, Register b4, - Disp d4, Condition m3); - - inline void rs_form(Opcode op, Register r1, Condition m3, Register b2, - const Disp d2); - inline void rs_form(Opcode op, Register r1, Register r3, Register b2, - const Disp d2); - - inline void rsi_form(Opcode op, Register r1, Register r3, const Operand& i2); - inline void rsl_form(Opcode op, Length l1, Register b2, Disp d2); - inline void rxe_form(Opcode op, Register r1, Register x2, Register b2, - Disp d2); - - inline void rxf_form(Opcode op, Register r1, Register r3, Register b2, - Register x2, Disp d2); - - inline void s_form(Opcode op, Register b1, Disp d2); - - inline void si_form(Opcode op, const Operand& i2, Register b1, Disp d1); - inline void siy_form(Opcode op, const Operand& i2, Register b1, Disp d1); - - inline void sil_form(Opcode op, Register b1, Disp d1, const Operand& i2); - - inline void ss_form(Opcode op, Length l, Register b1, Disp d1, Register b2, - Disp d2); - inline void ss_form(Opcode op, Length l1, Length l2, Register b1, Disp d1, - Register b2, Disp d2); - inline void ss_form(Opcode op, Length l1, const Operand& i3, Register b1, - Disp d1, Register b2, Disp d2); - inline void ss_form(Opcode op, Register r1, Register r2, Register b1, Disp d1, - Register b2, Disp d2); - inline void sse_form(Opcode op, Register b1, Disp d1, Register b2, Disp d2); - inline void ssf_form(Opcode op, Register r3, Register b1, Disp d1, - Register b2, Disp d2); - // Labels void print(Label* L); int max_reach_from(int pos); void bind_to(Label* L, int pos); void next(Label* L); - // The following functions help with avoiding allocations of embedded heap - // objects during the code assembly phase. {RequestHeapObject} records the - // need for a future heap number allocation or code stub generation. After - // code assembly, {AllocateAndInstallRequestedHeapObjects} will allocate these - // objects and place them where they are expected (determined by the pc offset - // associated with each request). That is, for each request, it will patch the - // dummy heap object handle that we emitted during code assembly with the - // actual heap object handle. void AllocateAndInstallRequestedHeapObjects(Isolate* isolate); - std::forward_list<HeapObjectRequest> heap_object_requests_; friend class RegExpMacroAssemblerS390; friend class RelocInfo; - - std::vector<Handle<Code>> code_targets_; friend class EnsureSpace; }; |