summaryrefslogtreecommitdiff
path: root/deps/v8/src/s390/assembler-s390.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/s390/assembler-s390.h')
-rw-r--r--deps/v8/src/s390/assembler-s390.h1110
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;
};