s390: clean up RR/RRE/RRD/RIL format in Assembler

R=joransiu@ca.ibm.com, bjaideep@ca.ibm.com
BUG=

Review-Url: https://codereview.chromium.org/2589063002
Cr-Commit-Position: refs/heads/master@{#41864}
This commit is contained in:
jyan 2016-12-20 07:03:49 -08:00 committed by Commit bot
parent 058f188715
commit 2d7f1c2c55
6 changed files with 174 additions and 685 deletions

View File

@ -2724,11 +2724,11 @@ void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
#if V8_TARGET_ARCH_S390X
static const FourByteInstr kInterruptBranchInstruction = 0xA7A40011;
static const FourByteInstr kOSRBranchInstruction = 0xA7040011;
static const int16_t kBackEdgeBranchOffset = 0x11 * 2;
static const int16_t kBackEdgeBranchOffsetInHalfWords = 0x11;
#else
static const FourByteInstr kInterruptBranchInstruction = 0xA7A4000D;
static const FourByteInstr kOSRBranchInstruction = 0xA704000D;
static const int16_t kBackEdgeBranchOffset = 0xD * 2;
static const int16_t kBackEdgeBranchOffsetInHalfWords = 0xD;
#endif
void BackEdgeTable::PatchAt(Code* unoptimized_code, Address pc,
@ -2746,7 +2746,7 @@ void BackEdgeTable::PatchAt(Code* unoptimized_code, Address pc,
// brasrl r14, <interrupt stub address>
// <reset profiling counter>
// ok-label
patcher.masm()->brc(ge, Operand(kBackEdgeBranchOffset));
patcher.masm()->brc(ge, Operand(kBackEdgeBranchOffsetInHalfWords));
break;
}
case ON_STACK_REPLACEMENT:
@ -2755,7 +2755,7 @@ void BackEdgeTable::PatchAt(Code* unoptimized_code, Address pc,
// brasrl r14, <interrupt stub address>
// <reset profiling counter>
// ok-label ----- pc_after points here
patcher.masm()->brc(CC_NOP, Operand(kBackEdgeBranchOffset));
patcher.masm()->brc(CC_NOP, Operand(kBackEdgeBranchOffsetInHalfWords));
break;
}

View File

@ -358,13 +358,13 @@ void PatchInlinedSmiCode(Isolate* isolate, Address address,
cc = static_cast<Condition>((branch_instr & 0x00f00000) >> 20);
DCHECK((cc == ne) || (cc == eq));
cc = (cc == ne) ? eq : ne;
patcher.masm()->brc(cc, Operand((branch_instr & 0xffff) << 1));
patcher.masm()->brc(cc, Operand(branch_instr & 0xffff));
} else if (Instruction::S390OpcodeValue(branch_address) == BRCL) {
cc = static_cast<Condition>(
(branch_instr & (static_cast<uint64_t>(0x00f0) << 32)) >> 36);
DCHECK((cc == ne) || (cc == eq));
cc = (cc == ne) ? eq : ne;
patcher.masm()->brcl(cc, Operand((branch_instr & 0xffffffff) << 1));
patcher.masm()->brcl(cc, Operand(branch_instr & 0xffffffff));
} else {
DCHECK(false);
}

View File

@ -528,11 +528,11 @@ void Assembler::load_label_offset(Register r1, Label* L) {
// Pseudo op - branch on condition
void Assembler::branchOnCond(Condition c, int branch_offset, bool is_bound) {
int offset = branch_offset;
if (is_bound && is_int16(offset)) {
brc(c, Operand(offset & 0xFFFF)); // short jump
int offset_in_halfwords = branch_offset / 2;
if (is_bound && is_int16(offset_in_halfwords)) {
brc(c, Operand(offset_in_halfwords & 0xFFFF)); // short jump
} else {
brcl(c, Operand(offset)); // long jump
brcl(c, Operand(offset_in_halfwords)); // long jump
}
}
@ -586,38 +586,6 @@ void Assembler::nop(int type) {
}
}
// RR format: <insn> R1,R2
// +--------+----+----+
// | OpCode | R1 | R2 |
// +--------+----+----+
// 0 8 12 15
#define RR_FORM_EMIT(name, op) \
void Assembler::name(Register r1, Register r2) { rr_form(op, r1, r2); }
void Assembler::rr_form(Opcode op, Register r1, Register r2) {
DCHECK(is_uint8(op));
emit2bytes(op * B8 | r1.code() * B4 | r2.code());
}
void Assembler::rr_form(Opcode op, DoubleRegister r1, DoubleRegister r2) {
DCHECK(is_uint8(op));
emit2bytes(op * B8 | r1.code() * B4 | r2.code());
}
// RR2 format: <insn> M1,R2
// +--------+----+----+
// | OpCode | M1 | R2 |
// +--------+----+----+
// 0 8 12 15
#define RR2_FORM_EMIT(name, op) \
void Assembler::name(Condition m1, Register r2) { rr_form(op, m1, r2); }
void Assembler::rr_form(Opcode op, Condition m1, Register r2) {
DCHECK(is_uint8(op));
DCHECK(is_uint4(m1));
emit2bytes(op * B8 | m1 * B4 | r2.code());
}
// RX format: <insn> R1,D2(X2,B2)
// +--------+----+----+----+-------------+
// | OpCode | R1 | X2 | B2 | D2 |
@ -722,75 +690,6 @@ void Assembler::rie_form(Opcode op, Register r1, Register r3,
emit6bytes(code);
}
// RIL1 format: <insn> R1,I2
// +--------+----+----+------------------------------------+
// | OpCode | R1 |OpCd| I2 |
// +--------+----+----+------------------------------------+
// 0 8 12 16 47
#define RIL1_FORM_EMIT(name, op) \
void Assembler::name(Register r, const Operand& i2) { ril_form(op, r, i2); }
void Assembler::ril_form(Opcode op, Register r1, const Operand& i2) {
DCHECK(is_uint12(op));
uint64_t code = (static_cast<uint64_t>(op & 0xFF0)) * B36 |
(static_cast<uint64_t>(r1.code())) * B36 |
(static_cast<uint64_t>(op & 0x00F)) * B32 |
(static_cast<uint64_t>(i2.imm_) & 0xFFFFFFFF);
emit6bytes(code);
}
// RIL2 format: <insn> M1,I2
// +--------+----+----+------------------------------------+
// | OpCode | M1 |OpCd| I2 |
// +--------+----+----+------------------------------------+
// 0 8 12 16 47
#define RIL2_FORM_EMIT(name, op) \
void Assembler::name(Condition m1, const Operand& i2) { \
ril_form(op, m1, i2); \
}
void Assembler::ril_form(Opcode op, Condition m1, const Operand& i2) {
DCHECK(is_uint12(op));
DCHECK(is_uint4(m1));
uint64_t code = (static_cast<uint64_t>(op & 0xFF0)) * B36 |
(static_cast<uint64_t>(m1)) * B36 |
(static_cast<uint64_t>(op & 0x00F)) * B32 |
(static_cast<uint64_t>(i2.imm_ & 0xFFFFFFFF));
emit6bytes(code);
}
// RRE format: <insn> R1,R2
// +------------------+--------+----+----+
// | OpCode |////////| R1 | R2 |
// +------------------+--------+----+----+
// 0 16 24 28 31
#define RRE_FORM_EMIT(name, op) \
void Assembler::name(Register r1, Register r2) { rre_form(op, r1, r2); }
void Assembler::rre_form(Opcode op, Register r1, Register r2) {
DCHECK(is_uint16(op));
emit4bytes(op << 16 | r1.code() * B4 | r2.code());
}
void Assembler::rre_form(Opcode op, DoubleRegister r1, DoubleRegister r2) {
DCHECK(is_uint16(op));
emit4bytes(op << 16 | r1.code() * B4 | r2.code());
}
// RRD format: <insn> R1,R3, R2
// +------------------+----+----+----+----+
// | OpCode | R1 |////| R3 | R2 |
// +------------------+----+----+----+----+
// 0 16 20 24 28 31
#define RRD_FORM_EMIT(name, op) \
void Assembler::name(Register r1, Register r3, Register r2) { \
rrd_form(op, r1, r3, r2); \
}
void Assembler::rrd_form(Opcode op, Register r1, Register r3, Register r2) {
emit4bytes(op << 16 | r1.code() * B12 | r3.code() * B4 | r2.code());
}
// RS1 format: <insn> R1,R3,D2(B2)
// +--------+----+----+----+-------------+
// | OpCode | R1 | R3 | B2 | D2 |
@ -1424,46 +1323,27 @@ void Assembler::rrfe_form(Opcode op, Condition m3, Condition m4, Register r1,
// start of S390 instruction
RX_FORM_EMIT(bc, BC)
RR_FORM_EMIT(bctr, BCTR)
RXE_FORM_EMIT(ceb, CEB)
SS1_FORM_EMIT(ed, ED)
RX_FORM_EMIT(ex, EX)
RRE_FORM_EMIT(flogr, FLOGR)
RRE_FORM_EMIT(lcgr, LCGR)
RR_FORM_EMIT(lcr, LCR)
RX_FORM_EMIT(le_z, LE)
RXY_FORM_EMIT(ley, LEY)
RIL1_FORM_EMIT(llihf, LLIHF)
RIL1_FORM_EMIT(llilf, LLILF)
RRE_FORM_EMIT(lngr, LNGR)
RR_FORM_EMIT(lnr, LNR)
RRE_FORM_EMIT(lrvr, LRVR)
RRE_FORM_EMIT(lrvgr, LRVGR)
RXY_FORM_EMIT(lrv, LRV)
RXY_FORM_EMIT(lrvg, LRVG)
RXY_FORM_EMIT(lrvh, LRVH)
SS1_FORM_EMIT(mvn, MVN)
SS1_FORM_EMIT(nc, NC)
SI_FORM_EMIT(ni, NI)
RIL1_FORM_EMIT(nihf, NIHF)
RIL1_FORM_EMIT(nilf, NILF)
RI1_FORM_EMIT(nilh, NILH)
RI1_FORM_EMIT(nill, NILL)
RIL1_FORM_EMIT(oihf, OIHF)
RIL1_FORM_EMIT(oilf, OILF)
RI1_FORM_EMIT(oill, OILL)
RRE_FORM_EMIT(popcnt, POPCNT_Z)
RIL1_FORM_EMIT(slfi, SLFI)
RXY_FORM_EMIT(slgf, SLGF)
RIL1_FORM_EMIT(slgfi, SLGFI)
RXY_FORM_EMIT(strvh, STRVH)
RXY_FORM_EMIT(strv, STRV)
RXY_FORM_EMIT(strvg, STRVG)
RI1_FORM_EMIT(tmll, TMLL)
SS1_FORM_EMIT(tr, TR)
S_FORM_EMIT(ts, TS)
RIL1_FORM_EMIT(xihf, XIHF)
RIL1_FORM_EMIT(xilf, XILF)
// -------------------------
// Load Address Instructions
@ -1478,11 +1358,6 @@ void Assembler::lay(Register r1, const MemOperand& opnd) {
rxy_form(LAY, r1, opnd.rx(), opnd.rb(), opnd.offset());
}
// Load Address Relative Long
void Assembler::larl(Register r1, const Operand& opnd) {
ril_form(LARL, r1, opnd);
}
// Load Address Relative Long
void Assembler::larl(Register r1, Label* l) {
larl(r1, Operand(branch_offset(l)));
@ -1496,17 +1371,11 @@ void Assembler::lb(Register r, const MemOperand& src) {
rxy_form(LB, r, src.rx(), src.rb(), src.offset());
}
// Load Byte Register-Register (32<-8)
void Assembler::lbr(Register r1, Register r2) { rre_form(LBR, r1, r2); }
// Load Byte Register-Storage (64<-8)
void Assembler::lgb(Register r, const MemOperand& src) {
rxy_form(LGB, r, src.rx(), src.rb(), src.offset());
}
// Load Byte Register-Register (64<-8)
void Assembler::lgbr(Register r1, Register r2) { rre_form(LGBR, r1, r2); }
// Load Halfword Register-Storage (32<-16)
void Assembler::lh(Register r, const MemOperand& src) {
rx_form(LH, r, src.rx(), src.rb(), src.offset());
@ -1517,17 +1386,11 @@ void Assembler::lhy(Register r, const MemOperand& src) {
rxy_form(LHY, r, src.rx(), src.rb(), src.offset());
}
// Load Halfword Register-Register (32<-16)
void Assembler::lhr(Register r1, Register r2) { rre_form(LHR, r1, r2); }
// Load Halfword Register-Storage (64<-16)
void Assembler::lgh(Register r, const MemOperand& src) {
rxy_form(LGH, r, src.rx(), src.rb(), src.offset());
}
// Load Halfword Register-Register (64<-16)
void Assembler::lghr(Register r1, Register r2) { rre_form(LGHR, r1, r2); }
// Load Register-Storage (32)
void Assembler::l(Register r, const MemOperand& src) {
rx_form(L, r, src.rx(), src.rb(), src.offset());
@ -1538,25 +1401,16 @@ void Assembler::ly(Register r, const MemOperand& src) {
rxy_form(LY, r, src.rx(), src.rb(), src.offset());
}
// Load Register-Register (32)
void Assembler::lr(Register r1, Register r2) { rr_form(LR, r1, r2); }
// Load Register-Storage (64)
void Assembler::lg(Register r, const MemOperand& src) {
rxy_form(LG, r, src.rx(), src.rb(), src.offset());
}
// Load Register-Register (64)
void Assembler::lgr(Register r1, Register r2) { rre_form(LGR, r1, r2); }
// Load Register-Storage (64<-32)
void Assembler::lgf(Register r, const MemOperand& src) {
rxy_form(LGF, r, src.rx(), src.rb(), src.offset());
}
// Load Sign Extended Register-Register (64<-32)
void Assembler::lgfr(Register r1, Register r2) { rre_form(LGFR, r1, r2); }
// Load Halfword Immediate (32)
void Assembler::lhi(Register r, const Operand& imm) { ri_form(LHI, r, imm); }
@ -1576,15 +1430,6 @@ void Assembler::ltg(Register r1, const MemOperand& opnd) {
rxy_form(LTG, r1, opnd.rx(), opnd.rb(), opnd.offset());
}
// Load and Test Register-Register (32)
void Assembler::ltr(Register r1, Register r2) { rr_form(LTR, r1, r2); }
// Load and Test Register-Register (64)
void Assembler::ltgr(Register r1, Register r2) { rre_form(LTGR, r1, r2); }
// Load and Test Register-Register (64<-32)
void Assembler::ltgfr(Register r1, Register r2) { rre_form(LTGFR, r1, r2); }
// -------------------------
// Load Logical Instructions
// -------------------------
@ -1603,9 +1448,6 @@ void Assembler::llgf(Register r1, const MemOperand& opnd) {
rxy_form(LLGF, r1, opnd.rx(), opnd.rb(), opnd.offset());
}
// Load Logical Register-Register (64<-32)
void Assembler::llgfr(Register r1, Register r2) { rre_form(LLGFR, r1, r2); }
// Load Logical halfword Register-Storage (32)
void Assembler::llh(Register r1, const MemOperand& opnd) {
rxy_form(LLH, r1, opnd.rx(), opnd.rb(), opnd.offset());
@ -1616,12 +1458,6 @@ void Assembler::llgh(Register r1, const MemOperand& opnd) {
rxy_form(LLGH, r1, opnd.rx(), opnd.rb(), opnd.offset());
}
// Load Logical halfword Register-Register (32)
void Assembler::llhr(Register r1, Register r2) { rre_form(LLHR, r1, r2); }
// Load Logical halfword Register-Register (64)
void Assembler::llghr(Register r1, Register r2) { rre_form(LLGHR, r1, r2); }
// Load On Condition R-R (32)
void Assembler::locr(Condition m3, Register r1, Register r2) {
rrf2_form(LOCR << 16 | m3 * B12 | r1.code() * B4 | r2.code());
@ -1645,11 +1481,6 @@ void Assembler::locg(Condition m3, Register r1, const MemOperand& src) {
// -------------------
// Branch Instructions
// -------------------
// Branch and Save
void Assembler::basr(Register r1, Register r2) { rr_form(BASR, r1, r2); }
// Indirect Conditional Branch via register
void Assembler::bcr(Condition m, Register target) { rr_form(BCR, m, target); }
// Branch on Count (32)
void Assembler::bct(Register r, const MemOperand& opnd) {
@ -1666,31 +1497,8 @@ void Assembler::bras(Register r, const Operand& opnd) {
ri_form(BRAS, r, opnd);
}
// Branch Relative and Save (64)
void Assembler::brasl(Register r, const Operand& opnd) {
ril_form(BRASL, r, opnd);
}
// Branch relative on Condition (32)
void Assembler::brc(Condition c, const Operand& opnd) {
// BRC actually encodes # of halfwords, so divide by 2.
int16_t numHalfwords = static_cast<int16_t>(opnd.immediate()) / 2;
Operand halfwordOp = Operand(numHalfwords);
halfwordOp.setBits(16);
ri_form(BRC, c, halfwordOp);
}
// Branch Relative on Condition (64)
void Assembler::brcl(Condition c, const Operand& opnd, bool isCodeTarget) {
Operand halfwordOp = opnd;
// Operand for code targets will be index to code_targets_
if (!isCodeTarget) {
// BRCL actually encodes # of halfwords, so divide by 2.
int32_t numHalfwords = static_cast<int32_t>(opnd.immediate()) / 2;
halfwordOp = Operand(numHalfwords);
}
ril_form(BRCL, c, halfwordOp);
}
void Assembler::brc(Condition c, const Operand& opnd) { ri_form(BRC, c, opnd); }
// Branch On Count (32)
void Assembler::brct(Register r1, const Operand& imm) {
@ -1723,17 +1531,11 @@ void Assembler::cy(Register r, const MemOperand& opnd) {
rxy_form(CY, r, opnd.rx(), opnd.rb(), opnd.offset());
}
// Compare Register-Register (32)
void Assembler::cr_z(Register r1, Register r2) { rr_form(CR, r1, r2); }
// Compare Register-Storage (64)
void Assembler::cg(Register r, const MemOperand& opnd) {
rxy_form(CG, r, opnd.rx(), opnd.rb(), opnd.offset());
}
// Compare Register-Register (64)
void Assembler::cgr(Register r1, Register r2) { rre_form(CGR, r1, r2); }
// Compare Halfword Register-Storage (32)
void Assembler::ch(Register r, const MemOperand& opnd) {
rx_form(CH, r, opnd.rx(), opnd.rb(), opnd.offset());
@ -1752,14 +1554,6 @@ void Assembler::cghi(Register r, const Operand& opnd) {
ri_form(CGHI, r, opnd);
}
// Compare Immediate (32)
void Assembler::cfi(Register r, const Operand& opnd) { ril_form(CFI, r, opnd); }
// Compare Immediate (64)
void Assembler::cgfi(Register r, const Operand& opnd) {
ril_form(CGFI, r, opnd);
}
// ----------------------------
// Compare Logical Instructions
// ----------------------------
@ -1773,25 +1567,11 @@ void Assembler::cly(Register r, const MemOperand& opnd) {
rxy_form(CLY, r, opnd.rx(), opnd.rb(), opnd.offset());
}
// Compare Logical Register-Register (32)
void Assembler::clr(Register r1, Register r2) { rr_form(CLR, r1, r2); }
// Compare Logical Register-Storage (64)
void Assembler::clg(Register r, const MemOperand& opnd) {
rxy_form(CLG, r, opnd.rx(), opnd.rb(), opnd.offset());
}
// Compare Logical Register-Register (64)
void Assembler::clgr(Register r1, Register r2) { rre_form(CLGR, r1, r2); }
// Compare Logical Immediate (32)
void Assembler::clfi(Register r1, const Operand& i2) { ril_form(CLFI, r1, i2); }
// Compare Logical Immediate (64<32)
void Assembler::clgfi(Register r1, const Operand& i2) {
ril_form(CLGFI, r1, i2);
}
// Compare Immediate (Mem - Imm) (8)
void Assembler::cli(const MemOperand& opnd, const Operand& imm) {
si_form(CLI, imm, opnd.rb(), opnd.offset());
@ -1872,11 +1652,6 @@ void Assembler::ay(Register r1, const MemOperand& opnd) {
rxy_form(AY, r1, opnd.rx(), opnd.rb(), opnd.offset());
}
// Add Immediate (32)
void Assembler::afi(Register r1, const Operand& opnd) {
ril_form(AFI, r1, opnd);
}
// Add Halfword Register-Storage (32)
void Assembler::ah(Register r1, const MemOperand& opnd) {
rx_form(AH, r1, opnd.rx(), opnd.rb(), opnd.offset());
@ -1895,9 +1670,6 @@ void Assembler::ahik(Register r1, Register r3, const Operand& i2) {
rie_form(AHIK, r1, r3, i2);
}
// Add Register (32)
void Assembler::ar(Register r1, Register r2) { rr_form(AR, r1, r2); }
// Add Register-Register-Register (32)
void Assembler::ark(Register r1, Register r2, Register r3) {
rrf1_form(ARK, r1, r2, r3);
@ -1923,14 +1695,6 @@ void Assembler::agf(Register r1, const MemOperand& opnd) {
rxy_form(AGF, r1, opnd.rx(), opnd.rb(), opnd.offset());
}
// Add Immediate (64)
void Assembler::agfi(Register r1, const Operand& opnd) {
ril_form(AGFI, r1, opnd);
}
// Add Register-Register (64<-32)
void Assembler::agfr(Register r1, Register r2) { rre_form(AGFR, r1, r2); }
// Add Halfword Immediate (64)
void Assembler::aghi(Register r1, const Operand& i2) { ri_form(AGHI, r1, i2); }
@ -1939,9 +1703,6 @@ void Assembler::aghik(Register r1, Register r3, const Operand& i2) {
rie_form(AGHIK, r1, r3, i2);
}
// Add Register (64)
void Assembler::agr(Register r1, Register r2) { rre_form(AGR, r1, r2); }
// Add Register-Register-Register (64)
void Assembler::agrk(Register r1, Register r2, Register r3) {
rrf1_form(AGRK, r1, r2, r3);
@ -1967,17 +1728,6 @@ void Assembler::aly(Register r1, const MemOperand& opnd) {
rxy_form(ALY, r1, opnd.rx(), opnd.rb(), opnd.offset());
}
// Add Logical Immediate (32)
void Assembler::alfi(Register r1, const Operand& opnd) {
ril_form(ALFI, r1, opnd);
}
// Add Logical Register-Register (32)
void Assembler::alr(Register r1, Register r2) { rr_form(ALR, r1, r2); }
// Add Logical With Carry Register-Register (32)
void Assembler::alcr(Register r1, Register r2) { rre_form(ALCR, r1, r2); }
// Add Logical Register-Register-Register (32)
void Assembler::alrk(Register r1, Register r2, Register r3) {
rrf1_form(ALRK, r1, r2, r3);
@ -1991,14 +1741,6 @@ void Assembler::alg(Register r1, const MemOperand& opnd) {
rxy_form(ALG, r1, opnd.rx(), opnd.rb(), opnd.offset());
}
// Add Logical Immediate (64)
void Assembler::algfi(Register r1, const Operand& opnd) {
ril_form(ALGFI, r1, opnd);
}
// Add Logical Register-Register (64)
void Assembler::algr(Register r1, Register r2) { rre_form(ALGR, r1, r2); }
// Add Logical Register-Register-Register (64)
void Assembler::algrk(Register r1, Register r2, Register r3) {
rrf1_form(ALGRK, r1, r2, r3);
@ -2027,9 +1769,6 @@ void Assembler::shy(Register r1, const MemOperand& opnd) {
rxy_form(SHY, r1, opnd.rx(), opnd.rb(), opnd.offset());
}
// Subtract Register (32)
void Assembler::sr(Register r1, Register r2) { rr_form(SR, r1, r2); }
// Subtract Register-Register-Register (32)
void Assembler::srk(Register r1, Register r2, Register r3) {
rrf1_form(SRK, r1, r2, r3);
@ -2048,12 +1787,6 @@ void Assembler::sgf(Register r1, const MemOperand& opnd) {
rxy_form(SGF, r1, opnd.rx(), opnd.rb(), opnd.offset());
}
// Subtract Register (64)
void Assembler::sgr(Register r1, Register r2) { rre_form(SGR, r1, r2); }
// Subtract Register (64<-32)
void Assembler::sgfr(Register r1, Register r2) { rre_form(SGFR, r1, r2); }
// Subtract Register-Register-Register (64)
void Assembler::sgrk(Register r1, Register r2, Register r3) {
rrf1_form(SGRK, r1, r2, r3);
@ -2072,12 +1805,6 @@ void Assembler::sly(Register r1, const MemOperand& opnd) {
rxy_form(SLY, r1, opnd.rx(), opnd.rb(), opnd.offset());
}
// Subtract Logical Register-Register (32)
void Assembler::slr(Register r1, Register r2) { rr_form(SLR, r1, r2); }
// Subtract Logical With Borrow Register-Register (32)
void Assembler::slbr(Register r1, Register r2) { rre_form(SLBR, r1, r2); }
// Subtract Logical Register-Register-Register (32)
void Assembler::slrk(Register r1, Register r2, Register r3) {
rrf1_form(SLRK, r1, r2, r3);
@ -2091,9 +1818,6 @@ void Assembler::slg(Register r1, const MemOperand& opnd) {
rxy_form(SLG, r1, opnd.rx(), opnd.rb(), opnd.offset());
}
// Subtract Logical Register-Register (64)
void Assembler::slgr(Register r1, Register r2) { rre_form(SLGR, r1, r2); }
// Subtract Logical Register-Register-Register (64)
void Assembler::slgrk(Register r1, Register r2, Register r3) {
rrf1_form(SLGRK, r1, r2, r3);
@ -2113,23 +1837,11 @@ void Assembler::mfy(Register r1, const MemOperand& opnd) {
rxy_form(MFY, r1, opnd.rx(), opnd.rb(), opnd.offset());
}
// Multiply Register (64<32)
void Assembler::mr_z(Register r1, Register r2) {
DCHECK(r1.code() % 2 == 0);
rr_form(MR, r1, r2);
}
// Multiply Logical Register-Storage (64<32)
void Assembler::ml(Register r1, const MemOperand& opnd) {
rxy_form(ML, r1, opnd.rx(), opnd.rb(), opnd.offset());
}
// Multiply Logical Register (64<32)
void Assembler::mlr(Register r1, Register r2) {
DCHECK(r1.code() % 2 == 0);
rre_form(MLR, r1, r2);
}
// Multiply Single Register-Storage (32)
void Assembler::ms(Register r1, const MemOperand& opnd) {
rx_form(MS, r1, opnd.rx(), opnd.rb(), opnd.offset());
@ -2140,14 +1852,6 @@ void Assembler::msy(Register r1, const MemOperand& opnd) {
rxy_form(MSY, r1, opnd.rx(), opnd.rb(), opnd.offset());
}
// Multiply Single Immediate (32)
void Assembler::msfi(Register r1, const Operand& opnd) {
ril_form(MSFI, r1, opnd);
}
// Multiply Single Register (64<32)
void Assembler::msr(Register r1, Register r2) { rre_form(MSR, r1, r2); }
// Multiply Halfword Register-Storage (32)
void Assembler::mh(Register r1, const MemOperand& opnd) {
rx_form(MH, r1, opnd.rx(), opnd.rb(), opnd.offset());
@ -2171,27 +1875,16 @@ void Assembler::mlg(Register r1, const MemOperand& opnd) {
rxy_form(MLG, r1, opnd.rx(), opnd.rb(), opnd.offset());
}
// Multiply Register (128<64)
void Assembler::mlgr(Register r1, Register r2) { rre_form(MLGR, r1, r2); }
// Multiply Halfword Immediate (64)
void Assembler::mghi(Register r1, const Operand& opnd) {
ri_form(MGHI, r1, opnd);
}
// Multiply Single Immediate (64)
void Assembler::msgfi(Register r1, const Operand& opnd) {
ril_form(MSGFI, r1, opnd);
}
// Multiply Single Register-Storage (64)
void Assembler::msg(Register r1, const MemOperand& opnd) {
rxy_form(MSG, r1, opnd.rx(), opnd.rb(), opnd.offset());
}
// Multiply Single Register-Register (64)
void Assembler::msgr(Register r1, Register r2) { rre_form(MSGR, r1, r2); }
// --------------------------
// 32-bit Divide Instructions
// --------------------------
@ -2200,29 +1893,11 @@ void Assembler::d(Register r1, const MemOperand& opnd) {
rx_form(D, r1, opnd.rx(), opnd.rb(), opnd.offset());
}
// Divide Register (32<-64)
void Assembler::dr(Register r1, Register r2) {
DCHECK(r1.code() % 2 == 0);
rr_form(DR, r1, r2);
}
// Divide Logical Register-Storage (32<-64)
void Assembler::dl(Register r1, const MemOperand& opnd) {
rx_form(DL, r1, opnd.rx(), opnd.rb(), opnd.offset());
}
// Divide Logical Register (32<-64)
void Assembler::dlr(Register r1, Register r2) { rre_form(DLR, r1, r2); }
// --------------------------
// 64-bit Divide Instructions
// --------------------------
// Divide Logical Register (64<-128)
void Assembler::dlgr(Register r1, Register r2) { rre_form(DLGR, r1, r2); }
// Divide Single Register (64<-32)
void Assembler::dsgr(Register r1, Register r2) { rre_form(DSGR, r1, r2); }
// --------------------
// Bitwise Instructions
// --------------------
@ -2236,9 +1911,6 @@ void Assembler::ny(Register r1, const MemOperand& opnd) {
rxy_form(NY, r1, opnd.rx(), opnd.rb(), opnd.offset());
}
// AND Register (32)
void Assembler::nr(Register r1, Register r2) { rr_form(NR, r1, r2); }
// AND Register-Register-Register (32)
void Assembler::nrk(Register r1, Register r2, Register r3) {
rrf1_form(NRK, r1, r2, r3);
@ -2249,9 +1921,6 @@ void Assembler::ng(Register r1, const MemOperand& opnd) {
rxy_form(NG, r1, opnd.rx(), opnd.rb(), opnd.offset());
}
// AND Register (64)
void Assembler::ngr(Register r1, Register r2) { rre_form(NGR, r1, r2); }
// AND Register-Register-Register (64)
void Assembler::ngrk(Register r1, Register r2, Register r3) {
rrf1_form(NGRK, r1, r2, r3);
@ -2267,9 +1936,6 @@ void Assembler::oy(Register r1, const MemOperand& opnd) {
rxy_form(OY, r1, opnd.rx(), opnd.rb(), opnd.offset());
}
// OR Register (32)
void Assembler::or_z(Register r1, Register r2) { rr_form(OR, r1, r2); }
// OR Register-Register-Register (32)
void Assembler::ork(Register r1, Register r2, Register r3) {
rrf1_form(ORK, r1, r2, r3);
@ -2280,9 +1946,6 @@ void Assembler::og(Register r1, const MemOperand& opnd) {
rxy_form(OG, r1, opnd.rx(), opnd.rb(), opnd.offset());
}
// OR Register (64)
void Assembler::ogr(Register r1, Register r2) { rre_form(OGR, r1, r2); }
// OR Register-Register-Register (64)
void Assembler::ogrk(Register r1, Register r2, Register r3) {
rrf1_form(OGRK, r1, r2, r3);
@ -2298,9 +1961,6 @@ void Assembler::xy(Register r1, const MemOperand& opnd) {
rxy_form(XY, r1, opnd.rx(), opnd.rb(), opnd.offset());
}
// XOR Register (32)
void Assembler::xr(Register r1, Register r2) { rr_form(XR, r1, r2); }
// XOR Register-Register-Register (32)
void Assembler::xrk(Register r1, Register r2, Register r3) {
rrf1_form(XRK, r1, r2, r3);
@ -2311,9 +1971,6 @@ void Assembler::xg(Register r1, const MemOperand& opnd) {
rxy_form(XG, r1, opnd.rx(), opnd.rb(), opnd.offset());
}
// XOR Register (64)
void Assembler::xgr(Register r1, Register r2) { rre_form(XGR, r1, r2); }
// XOR Register-Register-Register (64)
void Assembler::xgrk(Register r1, Register r2, Register r3) {
rrf1_form(XGRK, r1, r2, r3);
@ -2326,19 +1983,6 @@ void Assembler::xc(const MemOperand& opnd1, const MemOperand& opnd2,
opnd2.getBaseRegister(), opnd2.getDisplacement());
}
// -------------------------------------------
// Bitwise GPR <-> FPR Conversion Instructions
// -------------------------------------------
// Load GR from FPR (64 <- L)
void Assembler::lgdr(Register r1, DoubleRegister f2) {
rre_form(LGDR, r1, Register::from_code(f2.code()));
}
// Load FPR from FR (L <- 64)
void Assembler::ldgr(DoubleRegister f1, Register r2) {
rre_form(LDGR, Register::from_code(f1.code()), r2);
}
void Assembler::EnsureSpaceFor(int space_needed) {
if (buffer_space() <= (kGap + space_needed)) {
GrowBuffer(space_needed);
@ -2553,7 +2197,7 @@ void Assembler::jump(Handle<Code> target, RelocInfo::Mode rmode,
EnsureSpace ensure_space(this);
int32_t target_index = emit_code_target(target, rmode);
brcl(cond, Operand(target_index), true);
brcl(cond, Operand(target_index));
}
// Store (32)
@ -2627,16 +2271,6 @@ void Assembler::icy(Register r1, const MemOperand& opnd) {
rxy_form(ICY, r1, opnd.rx(), opnd.rb(), opnd.offset());
}
// Insert Immediate (High)
void Assembler::iihf(Register r1, const Operand& opnd) {
ril_form(IIHF, r1, opnd);
}
// Insert Immediate (low)
void Assembler::iilf(Register r1, const Operand& opnd) {
ril_form(IILF, r1, opnd);
}
// Insert Immediate (high high)
void Assembler::iihh(Register r1, const Operand& opnd) {
ri_form(IIHH, r1, opnd);
@ -2657,164 +2291,46 @@ void Assembler::iill(Register r1, const Operand& opnd) {
ri_form(IILL, r1, opnd);
}
// Load Immediate 32->64
void Assembler::lgfi(Register r1, const Operand& opnd) {
ril_form(LGFI, r1, opnd);
}
// GPR <-> FPR Instructions
// Floating point instructions
//
// Load zero Register (64)
void Assembler::lzdr(DoubleRegister r1) {
rre_form(LZDR, Register::from_code(r1.code()), Register::from_code(0));
}
// Add Register-Register (LB)
void Assembler::aebr(DoubleRegister r1, DoubleRegister r2) {
rre_form(AEBR, Register::from_code(r1.code()),
Register::from_code(r2.code()));
}
// Add Register-Storage (LB)
void Assembler::adb(DoubleRegister r1, const MemOperand& opnd) {
rxe_form(ADB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(),
opnd.offset());
}
// Add Register-Register (LB)
void Assembler::adbr(DoubleRegister r1, DoubleRegister r2) {
rre_form(ADBR, Register::from_code(r1.code()),
Register::from_code(r2.code()));
}
// Compare Register-Register (LB)
void Assembler::cebr(DoubleRegister r1, DoubleRegister r2) {
rre_form(CEBR, Register::from_code(r1.code()),
Register::from_code(r2.code()));
}
// Compare Register-Storage (LB)
void Assembler::cdb(DoubleRegister r1, const MemOperand& opnd) {
rx_form(CD, Register::from_code(r1.code()), opnd.rx(), opnd.rb(),
opnd.offset());
}
// Compare Register-Register (LB)
void Assembler::cdbr(DoubleRegister r1, DoubleRegister r2) {
rre_form(CDBR, Register::from_code(r1.code()),
Register::from_code(r2.code()));
}
// Divide Register-Register (LB)
void Assembler::debr(DoubleRegister r1, DoubleRegister r2) {
rre_form(DEBR, Register::from_code(r1.code()),
Register::from_code(r2.code()));
}
// Divide Register-Storage (LB)
void Assembler::ddb(DoubleRegister r1, const MemOperand& opnd) {
rxe_form(DDB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(),
opnd.offset());
}
// Divide Register-Register (LB)
void Assembler::ddbr(DoubleRegister r1, DoubleRegister r2) {
rre_form(DDBR, Register::from_code(r1.code()),
Register::from_code(r2.code()));
}
// Multiply Register-Register (LB)
void Assembler::meebr(DoubleRegister r1, DoubleRegister r2) {
rre_form(MEEBR, Register::from_code(r1.code()),
Register::from_code(r2.code()));
}
// Multiply Register-Storage (LB)
void Assembler::mdb(DoubleRegister r1, const MemOperand& opnd) {
rxe_form(MDB, Register::from_code(r1.code()), opnd.rb(), opnd.rx(),
opnd.offset());
}
// Multiply Register-Register (LB)
void Assembler::mdbr(DoubleRegister r1, DoubleRegister r2) {
rre_form(MDBR, Register::from_code(r1.code()),
Register::from_code(r2.code()));
}
// Subtract Register-Register (LB)
void Assembler::sebr(DoubleRegister r1, DoubleRegister r2) {
rre_form(SEBR, Register::from_code(r1.code()),
Register::from_code(r2.code()));
}
// Subtract Register-Storage (LB)
void Assembler::sdb(DoubleRegister r1, const MemOperand& opnd) {
rxe_form(SDB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(),
opnd.offset());
}
// Subtract Register-Register (LB)
void Assembler::sdbr(DoubleRegister r1, DoubleRegister r2) {
rre_form(SDBR, Register::from_code(r1.code()),
Register::from_code(r2.code()));
}
// Square Root (LB)
void Assembler::sqdb(DoubleRegister r1, const MemOperand& opnd) {
rxe_form(SQDB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(),
opnd.offset());
}
// Square Root Register-Register (LB)
void Assembler::sqebr(DoubleRegister r1, DoubleRegister r2) {
rre_form(SQEBR, Register::from_code(r1.code()),
Register::from_code(r2.code()));
}
// Square Root Register-Register (LB)
void Assembler::sqdbr(DoubleRegister r1, DoubleRegister r2) {
rre_form(SQDBR, Register::from_code(r1.code()),
Register::from_code(r2.code()));
}
// Load Rounded (double -> float)
void Assembler::ledbr(DoubleRegister r1, DoubleRegister r2) {
rre_form(LEDBR, Register::from_code(r1.code()),
Register::from_code(r2.code()));
}
// Load Lengthen (float -> double)
void Assembler::ldebr(DoubleRegister r1, DoubleRegister r2) {
rre_form(LDEBR, Register::from_code(r1.code()),
Register::from_code(r2.code()));
}
// Load Complement Register-Register (LB)
void Assembler::lcdbr(DoubleRegister r1, DoubleRegister r2) {
rre_form(LCDBR, Register::from_code(r1.code()),
Register::from_code(r2.code()));
}
// Load Complement Register-Register (LB)
void Assembler::lcebr(DoubleRegister r1, DoubleRegister r2) {
rre_form(LCEBR, Register::from_code(r1.code()),
Register::from_code(r2.code()));
}
// Load Positive Register-Register (LB)
void Assembler::lpebr(DoubleRegister r1, DoubleRegister r2) {
rre_form(LPEBR, Register::from_code(r1.code()),
Register::from_code(r2.code()));
}
// Load Positive Register-Register (LB)
void Assembler::lpdbr(DoubleRegister r1, DoubleRegister r2) {
rre_form(LPDBR, Register::from_code(r1.code()),
Register::from_code(r2.code()));
}
// Store Double (64)
void Assembler::std(DoubleRegister r1, const MemOperand& opnd) {
rx_form(STD, r1, opnd.rx(), opnd.rb(), opnd.offset());
@ -2861,21 +2377,6 @@ void Assembler::ley(DoubleRegister r1, const MemOperand& opnd) {
rxy_form(LEY, r1, opnd.rx(), opnd.rb(), opnd.offset());
}
// Load Double Register-Register (64)
void Assembler::ldr(DoubleRegister r1, DoubleRegister r2) {
rr_form(LDR, r1, r2);
}
// Load And Test Register-Register (L)
void Assembler::ltebr(DoubleRegister r1, DoubleRegister r2) {
rre_form(LTEBR, r1, r2);
}
// Load And Test Register-Register (L)
void Assembler::ltdbr(DoubleRegister r1, DoubleRegister r2) {
rre_form(LTDBR, r1, r2);
}
// Convert to Fixed point (64<-S)
void Assembler::cgebr(Condition m, Register r1, DoubleRegister r2) {
rrfe_form(CGEBR, m, Condition(0), r1, Register::from_code(r2.code()));
@ -2891,21 +2392,6 @@ void Assembler::cfdbr(Condition m, Register r1, DoubleRegister r2) {
rrfe_form(CFDBR, m, Condition(0), r1, Register::from_code(r2.code()));
}
// Convert from Fixed point (L<-64)
void Assembler::cegbr(DoubleRegister r1, Register r2) {
rre_form(CEGBR, Register::from_code(r1.code()), r2);
}
// Convert from Fixed point (L<-64)
void Assembler::cdgbr(DoubleRegister r1, Register r2) {
rre_form(CDGBR, Register::from_code(r1.code()), r2);
}
// Convert from Fixed point (L<-32)
void Assembler::cdfbr(DoubleRegister r1, Register r2) {
rre_form(CDFBR, Register::from_code(r1.code()), r2);
}
// Convert to Fixed Logical (64<-L)
void Assembler::clgdbr(Condition m3, Condition m4, Register r1,
DoubleRegister r2) {
@ -2994,20 +2480,6 @@ void Assembler::fidbra(DoubleRegister d1, DoubleRegister d2, FIDBRA_MASK3 m3) {
rrf2_form(FIDBRA << 16 | m3 * B12 | d1.code() * B4 | d2.code());
}
// Multiply and Add - MADBR R1, R3, R2
// R1 = R3 * R2 + R1
void Assembler::madbr(DoubleRegister d1, DoubleRegister d3, DoubleRegister d2) {
rrd_form(MADBR, Register::from_code(d1.code()),
Register::from_code(d3.code()), Register::from_code(d2.code()));
}
// Multiply and Subtract - MSDBR R1, R3, R2
// R1 = R3 * R2 - R1
void Assembler::msdbr(DoubleRegister d1, DoubleRegister d3, DoubleRegister d2) {
rrd_form(MSDBR, Register::from_code(d1.code()),
Register::from_code(d3.code()), Register::from_code(d2.code()));
}
// end of S390instructions
bool Assembler::IsNop(SixByteInstr instr, int type) {

View File

@ -545,6 +545,163 @@ class Assembler : public AssemblerBase {
// ---------------------------------------------------------------------------
// Code generation
template <class T, int size, int lo, int hi>
inline T getfield(T value) {
DCHECK(lo < hi);
DCHECK(size > 0);
int mask = hi - lo;
int shift = size * 8 - hi;
uint32_t mask_value = (mask == 32) ? 0xffffffff : (1 << mask) - 1;
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) { \
ril_format(op_name, r1.code(), i2.immediate()); \
}
#define DECLARE_S390_RIL_C_INSTRUCTIONS(name, op_name, op_value) \
inline void name(Condition m1, const Operand& i2) { \
ril_format(op_name, m1, i2.immediate()); \
}
inline void ril_format(Opcode opcode, int f1, int f2) {
uint32_t op1 = opcode >> 4;
uint32_t op2 = opcode & 0xf;
emit6bytes(
getfield<uint64_t, 6, 0, 8>(op1) | getfield<uint64_t, 6, 8, 12>(f1) |
getfield<uint64_t, 6, 12, 16>(op2) | getfield<uint64_t, 6, 16, 48>(f2));
}
S390_RIL_A_OPCODE_LIST(DECLARE_S390_RIL_AB_INSTRUCTIONS)
S390_RIL_B_OPCODE_LIST(DECLARE_S390_RIL_AB_INSTRUCTIONS)
S390_RIL_C_OPCODE_LIST(DECLARE_S390_RIL_C_INSTRUCTIONS)
#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()); \
} \
inline void name(DoubleRegister r1, DoubleRegister r2) { \
rr_format(op_name, r1.code(), r2.code()); \
} \
inline void name(Condition m1, Register r2) { \
rr_format(op_name, m1, r2.code()); \
}
inline void rr_format(Opcode opcode, int f1, int f2) {
emit2bytes(getfield<uint16_t, 2, 0, 8>(opcode) |
getfield<uint16_t, 2, 8, 12>(f1) |
getfield<uint16_t, 2, 12, 16>(f2));
}
S390_RR_OPCODE_LIST(DECLARE_S390_RR_INSTRUCTIONS)
#undef DECLARE_S390_RR_INSTRUCTIONS
#define DECLARE_S390_RRD_INSTRUCTIONS(name, op_name, op_value) \
template <class R1, class R2, class R3> \
inline void name(R1 r1, R3 r3, R2 r2) { \
rrd_format(op_name, r1.code(), r3.code(), r2.code()); \
}
inline void rrd_format(Opcode opcode, int f1, int f2, int f3) {
emit4bytes(getfield<uint32_t, 4, 0, 16>(opcode) |
getfield<uint32_t, 4, 16, 20>(f1) |
getfield<uint32_t, 4, 24, 28>(f2) |
getfield<uint32_t, 4, 28, 32>(f3));
}
S390_RRD_OPCODE_LIST(DECLARE_S390_RRD_INSTRUCTIONS)
#undef DECLARE_S390_RRD_INSTRUCTIONS
#define DECLARE_S390_RRE_INSTRUCTIONS(name, op_name, op_value) \
template <class R1, class R2> \
inline void name(R1 r1, R2 r2) { \
rre_format(op_name, r1.code(), r2.code()); \
}
inline void rre_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));
}
S390_RRE_OPCODE_LIST(DECLARE_S390_RRE_INSTRUCTIONS)
// Special format
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));
}
// Helper for unconditional branch to Label with update to save register
void b(Register r, Label* l) {
int32_t halfwords = branch_offset(l) / 2;
@ -647,10 +804,6 @@ class Assembler : public AssemblerBase {
void name(Register r1, Register r2, const Operand& i3, const Operand& i4, \
const Operand& i5)
#define RIL1_FORM(name) void name(Register r1, const Operand& i2)
#define RIL2_FORM(name) void name(Condition m1, const Operand& i2)
#define RXE_FORM(name) \
void name(Register r1, const MemOperand& opnd); \
void name(Register r1, Register b2, Register x2, Disp d2)
@ -679,8 +832,6 @@ class Assembler : public AssemblerBase {
void name(Register b1, Disp d1, const Operand& i2); \
void name(const MemOperand& opnd, const Operand& i2)
#define RRE_FORM(name) void name(Register r1, Register r2)
#define RRF1_FORM(name) void name(Register r1, Register r2, Register r3)
#define RRF2_FORM(name) void name(Condition m1, Register r1, Register r2)
@ -712,8 +863,6 @@ class Assembler : public AssemblerBase {
void name(Register r1, Condition m3, Register b2, Disp d2); \
void name(Register r1, Condition m3, const MemOperand& opnd)
#define RRD_FORM(name) void name(Register r1, Register r3, Register r2)
#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)
@ -809,62 +958,37 @@ class Assembler : public AssemblerBase {
// S390 instruction sets
RX_FORM(bc);
RR_FORM(bctr);
RX_FORM(cd);
RRE_FORM(cdr);
RXE_FORM(cdb);
RXE_FORM(ceb);
RXE_FORM(ddb);
RRE_FORM(ddbr);
SS1_FORM(ed);
RRE_FORM(epair);
RX_FORM(ex);
RRF2_FORM(fidbr);
RRE_FORM(flogr);
RX_FORM(ic_z);
RXY_FORM(icy);
RIL1_FORM(iihf);
RI1_FORM(iihh);
RI1_FORM(iihl);
RIL1_FORM(iilf);
RIL1_FORM(lgfi);
RI1_FORM(iilh);
RI1_FORM(iill);
RRE_FORM(lcgr);
RR_FORM(lcr);
RX_FORM(le_z);
RXY_FORM(ley);
RIL1_FORM(llihf);
RIL1_FORM(llilf);
RRE_FORM(lngr);
RR_FORM(lnr);
RSY1_FORM(loc);
RXY_FORM(lrv);
RRE_FORM(lrvr);
RRE_FORM(lrvgr);
RXY_FORM(lrvh);
RXY_FORM(lrvg);
RXE_FORM(mdb);
RRE_FORM(mdbr);
SS4_FORM(mvck);
SSF_FORM(mvcos);
SS4_FORM(mvcs);
SS1_FORM(mvn);
SS1_FORM(nc);
SI_FORM(ni);
RIL1_FORM(nihf);
RIL1_FORM(nilf);
RI1_FORM(nilh);
RI1_FORM(nill);
RIL1_FORM(oihf);
RIL1_FORM(oilf);
RI1_FORM(oill);
RRE_FORM(popcnt);
RXE_FORM(sdb);
RRE_FORM(sdbr);
RIL1_FORM(slfi);
RXY_FORM(slgf);
RIL1_FORM(slgfi);
RS1_FORM(srdl);
RX_FORM(ste);
RXY_FORM(stey);
@ -874,51 +998,35 @@ class Assembler : public AssemblerBase {
RI1_FORM(tmll);
SS1_FORM(tr);
S_FORM(ts);
RIL1_FORM(xihf);
RIL1_FORM(xilf);
// Load Address Instructions
void la(Register r, const MemOperand& opnd);
void lay(Register r, const MemOperand& opnd);
void larl(Register r1, const Operand& opnd);
void larl(Register r, Label* l);
// Load Instructions
void lb(Register r, const MemOperand& src);
void lbr(Register r1, Register r2);
void lgb(Register r, const MemOperand& src);
void lgbr(Register r1, Register r2);
void lh(Register r, const MemOperand& src);
void lhy(Register r, const MemOperand& src);
void lhr(Register r1, Register r2);
void lgh(Register r, const MemOperand& src);
void lghr(Register r1, Register r2);
void l(Register r, const MemOperand& src);
void ly(Register r, const MemOperand& src);
void lr(Register r1, Register r2);
void lg(Register r, const MemOperand& src);
void lgr(Register r1, Register r2);
void lgf(Register r, const MemOperand& src);
void lgfr(Register r1, Register r2);
void lhi(Register r, const Operand& imm);
void lghi(Register r, const Operand& imm);
// Load And Test Instructions
void lt_z(Register r, const MemOperand& src);
void ltg(Register r, const MemOperand& src);
void ltr(Register r1, Register r2);
void ltgr(Register r1, Register r2);
void ltgfr(Register r1, Register r2);
// Load Logical Instructions
void llc(Register r, const MemOperand& src);
void llgc(Register r, const MemOperand& src);
void llgf(Register r, const MemOperand& src);
void llgfr(Register r1, Register r2);
void llh(Register r, const MemOperand& src);
void llgh(Register r, const MemOperand& src);
void llhr(Register r1, Register r2);
void llghr(Register r1, Register r2);
// Load Multiple Instructions
void lm(Register r1, Register r2, const MemOperand& src);
@ -948,24 +1056,16 @@ class Assembler : public AssemblerBase {
// Compare Instructions
void c(Register r, const MemOperand& opnd);
void cy(Register r, const MemOperand& opnd);
void cr_z(Register r1, Register r2);
void cg(Register r, const MemOperand& opnd);
void cgr(Register r1, Register r2);
void ch(Register r, const MemOperand& opnd);
void chy(Register r, const MemOperand& opnd);
void chi(Register r, const Operand& opnd);
void cghi(Register r, const Operand& opnd);
void cfi(Register r, const Operand& opnd);
void cgfi(Register r, const Operand& opnd);
// Compare Logical Instructions
void cl(Register r, const MemOperand& opnd);
void cly(Register r, const MemOperand& opnd);
void clr(Register r1, Register r2);
void clg(Register r, const MemOperand& opnd);
void clgr(Register r1, Register r2);
void clfi(Register r, const Operand& opnd);
void clgfi(Register r, const Operand& opnd);
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);
@ -1027,52 +1127,38 @@ class Assembler : public AssemblerBase {
void mvc(const MemOperand& opnd1, const MemOperand& opnd2, uint32_t length);
// Branch Instructions
void basr(Register r1, Register r2);
void bcr(Condition m, Register target);
void bct(Register r, const MemOperand& opnd);
void bctg(Register r, const MemOperand& opnd);
void bras(Register r, const Operand& opnd);
void brasl(Register r, const Operand& opnd);
void brc(Condition c, const Operand& opnd);
void brcl(Condition m, const Operand& opnd, bool isCodeTarget = false);
void brct(Register r1, const Operand& opnd);
void brctg(Register r1, const Operand& opnd);
// 32-bit Add Instructions
void a(Register r1, const MemOperand& opnd);
void ay(Register r1, const MemOperand& opnd);
void afi(Register r1, const Operand& opnd);
void ah(Register r1, const MemOperand& opnd);
void ahy(Register r1, const MemOperand& opnd);
void ahi(Register r1, const Operand& opnd);
void ahik(Register r1, Register r3, const Operand& opnd);
void ar(Register r1, Register r2);
void ark(Register r1, Register r2, Register r3);
void asi(const MemOperand&, const Operand&);
// 64-bit Add Instructions
void ag(Register r1, const MemOperand& opnd);
void agf(Register r1, const MemOperand& opnd);
void agfi(Register r1, const Operand& opnd);
void agfr(Register r1, Register r2);
void aghi(Register r1, const Operand& opnd);
void aghik(Register r1, Register r3, const Operand& opnd);
void agr(Register r1, Register r2);
void agrk(Register r1, Register r2, Register r3);
void agsi(const MemOperand&, const Operand&);
// 32-bit Add Logical Instructions
void al_z(Register r1, const MemOperand& opnd);
void aly(Register r1, const MemOperand& opnd);
void alfi(Register r1, const Operand& opnd);
void alr(Register r1, Register r2);
void alcr(Register r1, Register r2);
void alrk(Register r1, Register r2, Register r3);
// 64-bit Add Logical Instructions
void alg(Register r1, const MemOperand& opnd);
void algfi(Register r1, const Operand& opnd);
void algr(Register r1, Register r2);
void algrk(Register r1, Register r2, Register r3);
// 32-bit Subtract Instructions
@ -1080,107 +1166,69 @@ class Assembler : public AssemblerBase {
void sy(Register r1, const MemOperand& opnd);
void sh(Register r1, const MemOperand& opnd);
void shy(Register r1, const MemOperand& opnd);
void sr(Register r1, Register r2);
void srk(Register r1, Register r2, Register r3);
// 64-bit Subtract Instructions
void sg(Register r1, const MemOperand& opnd);
void sgf(Register r1, const MemOperand& opnd);
void sgr(Register r1, Register r2);
void sgfr(Register r1, Register r2);
void sgrk(Register r1, Register r2, Register r3);
// 32-bit Subtract Logical Instructions
void sl(Register r1, const MemOperand& opnd);
void sly(Register r1, const MemOperand& opnd);
void slr(Register r1, Register r2);
void slrk(Register r1, Register r2, Register r3);
void slbr(Register r1, Register r2);
// 64-bit Subtract Logical Instructions
void slg(Register r1, const MemOperand& opnd);
void slgr(Register r1, Register r2);
void slgrk(Register r1, Register r2, Register r3);
// 32-bit Multiply Instructions
void m(Register r1, const MemOperand& opnd);
void mfy(Register r1, const MemOperand& opnd);
void mr_z(Register r1, Register r2);
void ml(Register r1, const MemOperand& opnd);
void mlr(Register r1, Register r2);
void ms(Register r1, const MemOperand& opnd);
void msy(Register r1, const MemOperand& opnd);
void msfi(Register r1, const Operand& opnd);
void msr(Register r1, Register r2);
void mh(Register r1, const MemOperand& opnd);
void mhy(Register r1, const MemOperand& opnd);
void mhi(Register r1, const Operand& opnd);
// 64-bit Multiply Instructions
void mlg(Register r1, const MemOperand& opnd);
void mlgr(Register r1, Register r2);
void mghi(Register r1, const Operand& opnd);
void msgfi(Register r1, const Operand& opnd);
void msg(Register r1, const MemOperand& opnd);
void msgr(Register r1, Register r2);
// 32-bit Divide Instructions
void d(Register r1, const MemOperand& opnd);
void dr(Register r1, Register r2);
void dl(Register r1, const MemOperand& opnd);
void dlr(Register r1, Register r2);
// 64-bit Divide Instructions
void dlgr(Register r1, Register r2);
void dsgr(Register r1, Register r2);
// Bitwise Instructions (AND / OR / XOR)
void n(Register r1, const MemOperand& opnd);
void ny(Register r1, const MemOperand& opnd);
void nr(Register r1, Register r2);
void nrk(Register r1, Register r2, Register r3);
void ng(Register r1, const MemOperand& opnd);
void ngr(Register r1, Register r2);
void ngrk(Register r1, Register r2, Register r3);
void o(Register r1, const MemOperand& opnd);
void oy(Register r1, const MemOperand& opnd);
void or_z(Register r1, Register r2);
void ork(Register r1, Register r2, Register r3);
void og(Register r1, const MemOperand& opnd);
void ogr(Register r1, Register r2);
void ogrk(Register r1, Register r2, Register r3);
void x(Register r1, const MemOperand& opnd);
void xy(Register r1, const MemOperand& opnd);
void xr(Register r1, Register r2);
void xrk(Register r1, Register r2, Register r3);
void xg(Register r1, const MemOperand& opnd);
void xgr(Register r1, Register r2);
void xgrk(Register r1, Register r2, Register r3);
void xc(const MemOperand& opnd1, const MemOperand& opnd2, Length length);
// Bitwise GPR <-> FPR Conversion Instructions
void lgdr(Register r1, DoubleRegister f2);
void ldgr(DoubleRegister f1, Register r2);
// Floating Point Load / Store Instructions
void ld(DoubleRegister r1, const MemOperand& opnd);
void ldy(DoubleRegister r1, const MemOperand& opnd);
void le_z(DoubleRegister r1, const MemOperand& opnd);
void ley(DoubleRegister r1, const MemOperand& opnd);
void ldr(DoubleRegister r1, DoubleRegister r2);
void ltdbr(DoubleRegister r1, DoubleRegister r2);
void ltebr(DoubleRegister r1, DoubleRegister r2);
void std(DoubleRegister r1, const MemOperand& opnd);
void stdy(DoubleRegister r1, const MemOperand& opnd);
void ste(DoubleRegister r1, const MemOperand& opnd);
void stey(DoubleRegister r1, const MemOperand& opnd);
// Floating Point Load Rounded/Positive Instructions
void ledbr(DoubleRegister r1, DoubleRegister r2);
void ldebr(DoubleRegister r1, DoubleRegister r2);
void lpebr(DoubleRegister r1, DoubleRegister r2);
void lpdbr(DoubleRegister r1, DoubleRegister r2);
// Floating <-> Fixed Point Conversion Instructions
void cdlfbr(Condition m3, Condition m4, DoubleRegister fltReg,
Register fixReg);
@ -1199,40 +1247,20 @@ class Assembler : public AssemblerBase {
void clgebr(Condition m3, Condition m4, Register fixReg,
DoubleRegister fltReg);
void cfdbr(Condition m, Register fixReg, DoubleRegister fltReg);
void cdfbr(DoubleRegister fltReg, Register fixReg);
void cgebr(Condition m, Register fixReg, DoubleRegister fltReg);
void cgdbr(Condition m, Register fixReg, DoubleRegister fltReg);
void cegbr(DoubleRegister fltReg, Register fixReg);
void cdgbr(DoubleRegister fltReg, Register fixReg);
void cfebr(Condition m3, Register fixReg, DoubleRegister fltReg);
void cefbr(Condition m3, DoubleRegister fltReg, Register fixReg);
// Floating Point Compare Instructions
void cebr(DoubleRegister r1, DoubleRegister r2);
void cdb(DoubleRegister r1, const MemOperand& opnd);
void cdbr(DoubleRegister r1, DoubleRegister r2);
// Floating Point Arithmetic Instructions
void aebr(DoubleRegister r1, DoubleRegister r2);
void adb(DoubleRegister r1, const MemOperand& opnd);
void adbr(DoubleRegister r1, DoubleRegister r2);
void lzdr(DoubleRegister r1);
void sebr(DoubleRegister r1, DoubleRegister r2);
void sdb(DoubleRegister r1, const MemOperand& opnd);
void sdbr(DoubleRegister r1, DoubleRegister r2);
void meebr(DoubleRegister r1, DoubleRegister r2);
void mdb(DoubleRegister r1, const MemOperand& opnd);
void mdbr(DoubleRegister r1, DoubleRegister r2);
void debr(DoubleRegister r1, DoubleRegister r2);
void ddb(DoubleRegister r1, const MemOperand& opnd);
void ddbr(DoubleRegister r1, DoubleRegister r2);
void madbr(DoubleRegister r1, DoubleRegister r2, DoubleRegister r3);
void msdbr(DoubleRegister r1, DoubleRegister r2, DoubleRegister r3);
void sqebr(DoubleRegister r1, DoubleRegister r2);
void sqdb(DoubleRegister r1, const MemOperand& opnd);
void sqdbr(DoubleRegister r1, DoubleRegister r2);
void lcdbr(DoubleRegister r1, DoubleRegister r2);
void lcebr(DoubleRegister r1, DoubleRegister r2);
void ldeb(DoubleRegister r1, const MemOperand& opnd);
enum FIDBRA_MASK3 {
@ -1415,9 +1443,6 @@ class Assembler : public AssemblerBase {
// Helpers to emit binary encoding for various instruction formats.
inline void rr_form(Opcode op, Register r1, Register r2);
inline void rr_form(Opcode op, DoubleRegister r1, DoubleRegister r2);
inline void rr_form(Opcode op, Condition m1, Register r2);
inline void rr2_form(uint8_t op, Condition m1, Register r2);
inline void rx_form(Opcode op, Register r1, Register x2, Register b2,
@ -1432,17 +1457,9 @@ class Assembler : public AssemblerBase {
inline void rie_f_form(Opcode op, Register r1, Register r2, const Operand& i3,
const Operand& i4, const Operand& i5);
inline void ril_form(Opcode op, Register r1, const Operand& i2);
inline void ril_form(Opcode op, Condition m1, const Operand& i2);
inline void ris_form(Opcode op, Register r1, Condition m3, Register b4,
Disp d4, const Operand& i2);
inline void rrd_form(Opcode op, Register r1, Register r3, Register r2);
inline void rre_form(Opcode op, Register r1, Register r2);
inline void rre_form(Opcode op, DoubleRegister r1, DoubleRegister r2);
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);

View File

@ -1542,13 +1542,13 @@ typedef uint64_t SixByteInstr;
V(lcr, LCR, 0x13) /* type = RR LOAD COMPLEMENT (32) */ \
V(nr, NR, 0x14) /* type = RR AND (32) */ \
V(clr, CLR, 0x15) /* type = RR COMPARE LOGICAL (32) */ \
V(or, OR, 0x16) /* type = RR OR (32) */ \
V(or_z, OR, 0x16) /* type = RR OR (32) */ \
V(xr, XR, 0x17) /* type = RR EXCLUSIVE OR (32) */ \
V(lr, LR, 0x18) /* type = RR LOAD (32) */ \
V(cr, CR, 0x19) /* type = RR COMPARE (32) */ \
V(cr_z, CR, 0x19) /* type = RR COMPARE (32) */ \
V(ar, AR, 0x1A) /* type = RR ADD (32) */ \
V(sr, SR, 0x1B) /* type = RR SUBTRACT (32) */ \
V(mr, MR, 0x1C) /* type = RR MULTIPLY (64<-32) */ \
V(mr_z, MR, 0x1C) /* type = RR MULTIPLY (64<-32) */ \
V(dr, DR, 0x1D) /* type = RR DIVIDE (32<-64) */ \
V(alr, ALR, 0x1E) /* type = RR ADD LOGICAL (32) */ \
V(slr, SLR, 0x1F) /* type = RR SUBTRACT LOGICAL (32) */ \

View File

@ -194,8 +194,8 @@ TEST(3) {
__ ay(r13, MemOperand(r1, r2, 123));
__ brc(Condition(14), Operand(123));
__ brc(Condition(14), Operand(-123));
__ brcl(Condition(14), Operand(123), false);
__ brcl(Condition(14), Operand(-123), false);
__ brcl(Condition(14), Operand(123));
__ brcl(Condition(14), Operand(-123));
__ iilf(r13, Operand(123456789));
__ iihf(r13, Operand(-123456789));
__ mvc(MemOperand(r0, 123), MemOperand(r4, 567), 89);