Commit ba89da8f authored by Vasili Skurydzin's avatar Vasili Skurydzin Committed by Commit Bot

s390: cleanup the disassembler by instruction formats.

Change-Id: I5d20ea5efb76a24c6569e56caf2e22638141ce95
Reviewed-on: https://chromium-review.googlesource.com/1117602
Commit-Queue: Junliang Yan <jyan@ca.ibm.com>
Reviewed-by: 's avatarJunliang Yan <jyan@ca.ibm.com>
Cr-Commit-Position: refs/heads/master@{#54420}
parent 6b4ba741
......@@ -1331,6 +1331,46 @@ inline void ss_a_format(Opcode op, int f1, int f2, int f3, int f4, int f5) {
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
......
......@@ -278,23 +278,15 @@ typedef uint64_t SixByteInstr;
#define S390_RRF_A_OPCODE_LIST(V) \
V(ipte, IPTE, 0xB221) /* type = RRF_A INVALIDATE PAGE TABLE ENTRY */ \
V(mdtr, MDTR, 0xB3D0) /* type = RRF_A MULTIPLY (long DFP) */ \
V(mdtra, MDTRA, 0xB3D0) /* type = RRF_A MULTIPLY (long DFP) */ \
V(ddtr, DDTR, 0xB3D1) /* type = RRF_A DIVIDE (long DFP) */ \
V(ddtra, DDTRA, 0xB3D1) /* type = RRF_A DIVIDE (long DFP) */ \
V(adtr, ADTR, 0xB3D2) /* type = RRF_A ADD (long DFP) */ \
V(adtra, ADTRA, 0xB3D2) /* type = RRF_A ADD (long DFP) */ \
V(sdtr, SDTR, 0xB3D3) /* type = RRF_A SUBTRACT (long DFP) */ \
V(sdtra, SDTRA, 0xB3D3) /* type = RRF_A SUBTRACT (long DFP) */ \
V(mxtr, MXTR, 0xB3D8) /* type = RRF_A MULTIPLY (extended DFP) */ \
V(mxtra, MXTRA, 0xB3D8) /* type = RRF_A MULTIPLY (extended DFP) */ \
V(msrkc, MSRKC, 0xB9FD) /* type = RRF_A MULTIPLY (32)*/ \
V(msgrkc, MSGRKC, 0xB9ED) /* type = RRF_A MULTIPLY (64)*/ \
V(dxtr, DXTR, 0xB3D9) /* type = RRF_A DIVIDE (extended DFP) */ \
V(dxtra, DXTRA, 0xB3D9) /* type = RRF_A DIVIDE (extended DFP) */ \
V(axtr, AXTR, 0xB3DA) /* type = RRF_A ADD (extended DFP) */ \
V(axtra, AXTRA, 0xB3DA) /* type = RRF_A ADD (extended DFP) */ \
V(sxtr, SXTR, 0xB3DB) /* type = RRF_A SUBTRACT (extended DFP) */ \
V(sxtra, SXTRA, 0xB3DB) /* type = RRF_A SUBTRACT (extended DFP) */ \
V(ahhhr, AHHHR, 0xB9C8) /* type = RRF_A ADD HIGH (32) */ \
V(shhhr, SHHHR, 0xB9C9) /* type = RRF_A SUBTRACT HIGH (32) */ \
......@@ -370,9 +362,7 @@ typedef uint64_t SixByteInstr;
#define S390_RRF_C_OPCODE_LIST(V) \
V(sske, SSKE, 0xB22B) /* type = RRF_C SET STORAGE KEY EXTENDED */ \
V(cuutf, CUUTF, 0xB2A6) /* type = RRF_C CONVERT UNICODE TO UTF-8 */ \
V(cu21, CU21, 0xB2A6) /* type = RRF_C CONVERT UTF-16 TO UTF-8 */ \
V(cutfu, CUTFU, 0xB2A7) /* type = RRF_C CONVERT UTF-8 TO UNICODE */ \
V(cu12, CU12, 0xB2A7) /* type = RRF_C CONVERT UTF-8 TO UTF-16 */ \
V(ppa, PPA, 0xB2E8) /* type = RRF_C PERFORM PROCESSOR ASSIST */ \
V(cgrt, CGRT, 0xB960) /* type = RRF_C COMPARE AND TRAP (64) */ \
......@@ -412,14 +402,11 @@ typedef uint64_t SixByteInstr;
0xB345) /* type = RRF_E LOAD ROUNDED (extended to long BFP) */ \
V(lexbra, LEXBRA, \
0xB346) /* type = RRF_E LOAD ROUNDED (extended to short BFP) */ \
V(fixbr, FIXBR, 0xB347) /* type = RRF_E LOAD FP INTEGER (extended BFP) */ \
V(fixbra, FIXBRA, 0xB347) /* type = RRF_E LOAD FP INTEGER (extended BFP) */ \
V(tbedr, TBEDR, \
0xB350) /* type = RRF_E CONVERT HFP TO BFP (long to short) */ \
V(tbdr, TBDR, 0xB351) /* type = RRF_E CONVERT HFP TO BFP (long) */ \
V(fiebr, FIEBR, 0xB357) /* type = RRF_E LOAD FP INTEGER (short BFP) */ \
V(fiebra, FIEBRA, 0xB357) /* type = RRF_E LOAD FP INTEGER (short BFP) */ \
V(fidbr, FIDBR, 0xB35F) /* type = RRF_E LOAD FP INTEGER (long BFP) */ \
V(fidbra, FIDBRA, 0xB35F) /* type = RRF_E LOAD FP INTEGER (long BFP) */ \
V(celfbr, CELFBR, \
0xB390) /* type = RRF_E CONVERT FROM LOGICAL (32 to short BFP) */ \
......@@ -433,15 +420,10 @@ typedef uint64_t SixByteInstr;
0xB395) /* type = RRF_E CONVERT FROM FIXED (32 to long BFP) */ \
V(cxfbra, CXFBRA, \
0xB396) /* type = RRF_E CONVERT FROM FIXED (32 to extended BFP) */ \
V(cfebr, CFEBR, \
0xB398) /* type = RRF_E CONVERT TO FIXED (short BFP to 32) */ \
V(cfebra, CFEBRA, \
0xB398) /* type = RRF_E CONVERT TO FIXED (short BFP to 32) */ \
V(cfdbr, CFDBR, 0xB399) /* type = RRF_E CONVERT TO FIXED (long BFP to 32) */ \
V(cfdbra, CFDBRA, \
0xB399) /* type = RRF_E CONVERT TO FIXED (long BFP to 32) */ \
V(cfxbr, CFXBR, \
0xB39A) /* type = RRF_E CONVERT TO FIXED (extended BFP to 32) */ \
V(cfxbra, CFXBRA, \
0xB39A) /* type = RRF_E CONVERT TO FIXED (extended BFP to 32) */ \
V(clfebr, CLFEBR, \
......@@ -462,15 +444,10 @@ typedef uint64_t SixByteInstr;
0xB3A5) /* type = RRF_E CONVERT FROM FIXED (64 to long BFP) */ \
V(cxgbra, CXGBRA, \
0xB3A6) /* type = RRF_E CONVERT FROM FIXED (64 to extended BFP) */ \
V(cgebr, CGEBR, \
0xB3A8) /* type = RRF_E CONVERT TO FIXED (short BFP to 64) */ \
V(cgebra, CGEBRA, \
0xB3A8) /* type = RRF_E CONVERT TO FIXED (short BFP to 64) */ \
V(cgdbr, CGDBR, 0xB3A9) /* type = RRF_E CONVERT TO FIXED (long BFP to 64) */ \
V(cgdbra, CGDBRA, \
0xB3A9) /* type = RRF_E CONVERT TO FIXED (long BFP to 64) */ \
V(cgxbr, CGXBR, \
0xB3AA) /* type = RRF_E CONVERT TO FIXED (extended BFP to 64) */ \
V(cgxbra, CGXBRA, \
0xB3AA) /* type = RRF_E CONVERT TO FIXED (extended BFP to 64) */ \
V(clgebr, CLGEBR, \
......@@ -492,11 +469,8 @@ typedef uint64_t SixByteInstr;
V(ldxtr, LDXTR, \
0xB3DD) /* type = RRF_E LOAD ROUNDED (extended to long DFP) */ \
V(fixtr, FIXTR, 0xB3DF) /* type = RRF_E LOAD FP INTEGER (extended DFP) */ \
V(cgdtr, CGDTR, 0xB3E1) /* type = RRF_E CONVERT TO FIXED (long DFP to 64) */ \
V(cgdtra, CGDTRA, \
0xB3E1) /* type = RRF_E CONVERT TO FIXED (long DFP to 64) */ \
V(cgxtr, CGXTR, \
0xB3E9) /* type = RRF_E CONVERT TO FIXED (extended DFP to 64) */ \
V(cgxtra, CGXTRA, \
0xB3E9) /* type = RRF_E CONVERT TO FIXED (extended DFP to 64) */ \
V(cdgtra, CDGTRA, \
......@@ -841,9 +815,7 @@ typedef uint64_t SixByteInstr;
V(llilh, LLILH, 0xA5E) /* type = RI_A LOAD LOGICAL IMMEDIATE (low high) */ \
V(llill, LLILL, 0xA5F) /* type = RI_A LOAD LOGICAL IMMEDIATE (low low) */ \
V(tmlh, TMLH, 0xA70) /* type = RI_A TEST UNDER MASK (low high) */ \
V(tmh, TMH, 0xA70) /* type = RI_A TEST UNDER MASK HIGH */ \
V(tmll, TMLL, 0xA71) /* type = RI_A TEST UNDER MASK (low low) */ \
V(tml, TML, 0xA71) /* type = RI_A TEST UNDER MASK LOW */ \
V(tmhh, TMHH, 0xA72) /* type = RI_A TEST UNDER MASK (high high) */ \
V(tmhl, TMHL, 0xA73) /* type = RI_A TEST UNDER MASK (high low) */ \
V(lhi, LHI, 0xA78) /* type = RI_A LOAD HALFWORD IMMEDIATE (32)<-16 */ \
......@@ -1199,7 +1171,6 @@ typedef uint64_t SixByteInstr;
V(ae, AE, 0x7A) /* type = RX_A ADD NORMALIZED (short HFP) */ \
V(se, SE, 0x7B) /* type = RX_A SUBTRACT NORMALIZED (short HFP) */ \
V(mde, MDE, 0x7C) /* type = RX_A MULTIPLY (short to long HFP) */ \
V(me, ME, 0x7C) /* type = RX_A MULTIPLY (short to long HFP) */ \
V(de, DE, 0x7D) /* type = RX_A DIVIDE (short HFP) */ \
V(au, AU, 0x7E) /* type = RX_A ADD UNNORMALIZED (short HFP) */ \
V(su, SU, 0x7F) /* type = RX_A SUBTRACT UNNORMALIZED (short HFP) */ \
......@@ -1330,11 +1301,6 @@ typedef uint64_t SixByteInstr;
V(lnxbr, LNXBR, 0xB341) /* type = RRE LOAD NEGATIVE (extended BFP) */ \
V(ltxbr, LTXBR, 0xB342) /* type = RRE LOAD AND TEST (extended BFP) */ \
V(lcxbr, LCXBR, 0xB343) /* type = RRE LOAD COMPLEMENT (extended BFP) */ \
V(ledbr, LEDBR, 0xB344) /* type = RRE LOAD ROUNDED (long to short BFP) */ \
V(ldxbr, LDXBR, \
0xB345) /* type = RRE LOAD ROUNDED (extended to long BFP) */ \
V(lexbr, LEXBR, \
0xB346) /* type = RRE LOAD ROUNDED (extended to short BFP) */ \
V(kxbr, KXBR, 0xB348) /* type = RRE COMPARE AND SIGNAL (extended BFP) */ \
V(cxbr, CXBR, 0xB349) /* type = RRE COMPARE (extended BFP) */ \
V(axbr, AXBR, 0xB34A) /* type = RRE ADD (extended BFP) */ \
......@@ -1364,18 +1330,6 @@ typedef uint64_t SixByteInstr;
V(sfpc, SFPC, 0xB384) /* type = RRE SET FPC */ \
V(sfasr, SFASR, 0xB385) /* type = RRE SET FPC AND SIGNAL */ \
V(efpc, EFPC, 0xB38C) /* type = RRE EXTRACT FPC */ \
V(cefbr, CEFBR, \
0xB394) /* type = RRE CONVERT FROM FIXED (32 to short BFP) */ \
V(cdfbr, CDFBR, \
0xB395) /* type = RRE CONVERT FROM FIXED (32 to long BFP) */ \
V(cxfbr, CXFBR, \
0xB396) /* type = RRE CONVERT FROM FIXED (32 to extended BFP) */ \
V(cegbr, CEGBR, \
0xB3A4) /* type = RRE CONVERT FROM FIXED (64 to short BFP) */ \
V(cdgbr, CDGBR, \
0xB3A5) /* type = RRE CONVERT FROM FIXED (64 to long BFP) */ \
V(cxgbr, CXGBR, \
0xB3A6) /* type = RRE CONVERT FROM FIXED (64 to extended BFP) */ \
V(cefr, CEFR, \
0xB3B4) /* type = RRE CONVERT FROM FIXED (32 to short HFP) */ \
V(cdfr, CDFR, 0xB3B5) /* type = RRE CONVERT FROM FIXED (32 to long HFP) */ \
......@@ -1407,16 +1361,12 @@ typedef uint64_t SixByteInstr;
0xB3ED) /* type = RRE EXTRACT BIASED EXPONENT (extended DFP to 64) */ \
V(esxtr, ESXTR, \
0xB3EF) /* type = RRE EXTRACT SIGNIFICANCE (extended DFP to 64) */ \
V(cdgtr, CDGTR, \
0xB3F1) /* type = RRE CONVERT FROM FIXED (64 to long DFP) */ \
V(cdutr, CDUTR, \
0xB3F2) /* type = RRE CONVERT FROM UNSIGNED PACKED (64 to long DFP) */ \
V(cdstr, CDSTR, \
0xB3F3) /* type = RRE CONVERT FROM SIGNED PACKED (64 to long DFP) */ \
V(cedtr, CEDTR, \
0xB3F4) /* type = RRE COMPARE BIASED EXPONENT (long DFP) */ \
V(cxgtr, CXGTR, \
0xB3F9) /* type = RRE CONVERT FROM FIXED (64 to extended DFP) */ \
V(cxutr, CXUTR, \
0xB3FA) /* type = RRE CONVERT FROM UNSIGNED PACKED (128 to ext. DFP) */ \
V(cxstr, CXSTR, 0xB3FB) /* type = RRE CONVERT FROM SIGNED PACKED (128 to*/ \
......@@ -1578,7 +1528,6 @@ typedef uint64_t SixByteInstr;
V(lcdr, LCDR, 0x23) /* type = RR LOAD COMPLEMENT (long HFP) */ \
V(hdr, HDR, 0x24) /* type = RR HALVE (long HFP) */ \
V(ldxr, LDXR, 0x25) /* type = RR LOAD ROUNDED (extended to long HFP) */ \
V(lrdr, LRDR, 0x25) /* type = RR LOAD ROUNDED (extended to long HFP) */ \
V(mxr, MXR, 0x26) /* type = RR MULTIPLY (extended HFP) */ \
V(mxdr, MXDR, 0x27) /* type = RR MULTIPLY (long to extended HFP) */ \
V(ldr, LDR, 0x28) /* type = RR LOAD (long) */ \
......@@ -1594,7 +1543,6 @@ typedef uint64_t SixByteInstr;
V(lcer, LCER, 0x33) /* type = RR LOAD COMPLEMENT (short HFP) */ \
V(her_z, HER_Z, 0x34) /* type = RR HALVE (short HFP) */ \
V(ledr, LEDR, 0x35) /* type = RR LOAD ROUNDED (long to short HFP) */ \
V(lrer, LRER, 0x35) /* type = RR LOAD ROUNDED (long to short HFP) */ \
V(axr, AXR, 0x36) /* type = RR ADD NORMALIZED (extended HFP) */ \
V(sxr, SXR, 0x37) /* type = RR SUBTRACT NORMALIZED (extended HFP) */ \
V(ler, LER, 0x38) /* type = RR LOAD (short) */ \
......@@ -1602,7 +1550,6 @@ typedef uint64_t SixByteInstr;
V(aer, AER, 0x3A) /* type = RR ADD NORMALIZED (short HFP) */ \
V(ser, SER, 0x3B) /* type = RR SUBTRACT NORMALIZED (short HFP) */ \
V(mder, MDER, 0x3C) /* type = RR MULTIPLY (short to long HFP) */ \
V(mer, MER, 0x3C) /* type = RR MULTIPLY (short to long HFP) */ \
V(der, DER, 0x3D) /* type = RR DIVIDE (short HFP) */ \
V(aur, AUR, 0x3E) /* type = RR ADD UNNORMALIZED (short HFP) */ \
V(sur, SUR, 0x3F) /* type = RR SUBTRACT UNNORMALIZED (short HFP) */
......
......@@ -78,9 +78,8 @@ class Decoder {
void Unknown(Instruction* instr);
void UnknownFormat(Instruction* instr, const char* opcname);
bool DecodeTwoByte(Instruction* instr);
bool DecodeFourByte(Instruction* instr);
bool DecodeSixByte(Instruction* instr);
bool DecodeSpecial(Instruction* instr);
bool DecodeGeneric(Instruction* instr);
const disasm::NameConverter& converter_;
Vector<char> out_buffer_;
......@@ -143,13 +142,11 @@ int Decoder::FormatRegister(Instruction* instr, const char* format) {
DCHECK_EQ(format[0], 'r');
if (format[1] == '1') { // 'r1: register resides in bit 8-11
RRInstruction* rrinstr = reinterpret_cast<RRInstruction*>(instr);
int reg = rrinstr->R1Value();
int reg = instr->Bits<SixByteInstr, int>(39, 36);
PrintRegister(reg);
return 2;
} else if (format[1] == '2') { // 'r2: register resides in bit 12-15
RRInstruction* rrinstr = reinterpret_cast<RRInstruction*>(instr);
int reg = rrinstr->R2Value();
int reg = instr->Bits<SixByteInstr, int>(35, 32);
// indicating it is a r0 for displacement, in which case the offset
// should be 0.
if (format[2] == 'd') {
......@@ -161,28 +158,23 @@ int Decoder::FormatRegister(Instruction* instr, const char* format) {
return 2;
}
} else if (format[1] == '3') { // 'r3: register resides in bit 16-19
RSInstruction* rsinstr = reinterpret_cast<RSInstruction*>(instr);
int reg = rsinstr->B2Value();
int reg = instr->Bits<SixByteInstr, int>(31, 28);
PrintRegister(reg);
return 2;
} else if (format[1] == '4') { // 'r4: register resides in bit 20-23
RSInstruction* rsinstr = reinterpret_cast<RSInstruction*>(instr);
int reg = rsinstr->B2Value();
int reg = instr->Bits<SixByteInstr, int>(27, 24);
PrintRegister(reg);
return 2;
} else if (format[1] == '5') { // 'r5: register resides in bit 24-28
RREInstruction* rreinstr = reinterpret_cast<RREInstruction*>(instr);
int reg = rreinstr->R1Value();
} else if (format[1] == '5') { // 'r5: register resides in bit 24-27
int reg = instr->Bits<SixByteInstr, int>(23, 20);
PrintRegister(reg);
return 2;
} else if (format[1] == '6') { // 'r6: register resides in bit 29-32
RREInstruction* rreinstr = reinterpret_cast<RREInstruction*>(instr);
int reg = rreinstr->R2Value();
} else if (format[1] == '6') { // 'r6: register resides in bit 28-31
int reg = instr->Bits<SixByteInstr, int>(19, 16);
PrintRegister(reg);
return 2;
} else if (format[1] == '7') { // 'r6: register resides in bit 32-35
SSInstruction* ssinstr = reinterpret_cast<SSInstruction*>(instr);
int reg = ssinstr->B2Value();
int reg = instr->Bits<SixByteInstr, int>(15, 12);
PrintRegister(reg);
return 2;
}
......@@ -493,449 +485,120 @@ void Decoder::UnknownFormat(Instruction* instr, const char* name) {
Format(instr, buffer);
}
// Disassembles Two Byte S390 Instructions
// @return true if successfully decoded
bool Decoder::DecodeTwoByte(Instruction* instr) {
// Print the Instruction bits.
out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%04x ",
instr->InstructionBits<TwoByteInstr>());
#undef VERIFY
#undef STRING_STARTS_WITH
// Handles special cases of instructions;
// @return true if successfully decoded
bool Decoder::DecodeSpecial(Instruction* instr) {
Opcode opcode = instr->S390OpcodeValue();
switch (opcode) {
case AR:
Format(instr, "ar\t'r1,'r2");
case BKPT:
Format(instr, "bkpt");
break;
case SR:
Format(instr, "sr\t'r1,'r2");
case DUMY:
Format(instr, "dumy\t'r1, 'd2 ( 'r2d, 'r3 )");
break;
case MR:
Format(instr, "mr\t'r1,'r2");
/* RR format */
case LDR:
Format(instr, "ldr\t'f1,'f2");
break;
case DR:
Format(instr, "dr\t'r1,'r2");
case BCR:
Format(instr, "bcr\t'm1,'r2");
break;
case OR:
Format(instr, "or\t'r1,'r2");
break;
case NR:
Format(instr, "nr\t'r1,'r2");
break;
case XR:
Format(instr, "xr\t'r1,'r2");
break;
case LR:
Format(instr, "lr\t'r1,'r2");
break;
case CR:
Format(instr, "cr\t'r1,'r2");
break;
case CLR:
Format(instr, "clr\t'r1,'r2");
break;
case BCR:
Format(instr, "bcr\t'm1,'r2");
break;
case LTR:
Format(instr, "ltr\t'r1,'r2");
break;
case ALR:
Format(instr, "alr\t'r1,'r2");
break;
case SLR:
Format(instr, "slr\t'r1,'r2");
break;
case LNR:
Format(instr, "lnr\t'r1,'r2");
break;
case LCR:
Format(instr, "lcr\t'r1,'r2");
break;
case BASR:
Format(instr, "basr\t'r1,'r2");
break;
case LDR:
Format(instr, "ldr\t'f1,'f2");
break;
case BKPT:
Format(instr, "bkpt");
break;
case LPR:
Format(instr, "lpr\t'r1, 'r2");
break;
default:
return false;
}
return true;
}
// Disassembles Four Byte S390 Instructions
// @return true if successfully decoded
bool Decoder::DecodeFourByte(Instruction* instr) {
// Print the Instruction bits.
out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%08x ",
instr->InstructionBits<FourByteInstr>());
Opcode opcode = instr->S390OpcodeValue();
switch (opcode) {
case AHI:
Format(instr, "ahi\t'r1,'i1");
break;
case AGHI:
Format(instr, "aghi\t'r1,'i1");
break;
case LHI:
Format(instr, "lhi\t'r1,'i1");
break;
case LGHI:
Format(instr, "lghi\t'r1,'i1");
break;
case MHI:
Format(instr, "mhi\t'r1,'i1");
break;
case MGHI:
Format(instr, "mghi\t'r1,'i1");
break;
case CHI:
Format(instr, "chi\t'r1,'i1");
case MR:
Format(instr, "mr\t'r1,'r2");
break;
case CGHI:
Format(instr, "cghi\t'r1,'i1");
case HER_Z:
Format(instr, "her\t'r1,'r2");
break;
/* RI-b format */
case BRAS:
Format(instr, "bras\t'r1,'i1");
break;
case BRC:
Format(instr, "brc\t'm1,'i4");
break;
case BRCT:
Format(instr, "brct\t'r1,'i4");
break;
case BRCTG:
Format(instr, "brctg\t'r1,'i4");
break;
case IIHH:
Format(instr, "iihh\t'r1,'i1");
break;
case IIHL:
Format(instr, "iihl\t'r1,'i1");
break;
case IILH:
Format(instr, "iilh\t'r1,'i1");
break;
case IILL:
Format(instr, "iill\t'r1,'i1");
break;
case OILL:
Format(instr, "oill\t'r1,'i1");
break;
case TMLL:
Format(instr, "tmll\t'r1,'i1");
break;
case STM:
Format(instr, "stm\t'r1,'r2,'d1('r3)");
break;
case LM:
Format(instr, "lm\t'r1,'r2,'d1('r3)");
break;
case CS:
Format(instr, "cs\t'r1,'r2,'d1('r3)");
break;
case SLL:
Format(instr, "sll\t'r1,'d1('r3)");
break;
case SRL:
Format(instr, "srl\t'r1,'d1('r3)");
break;
case SLA:
Format(instr, "sla\t'r1,'d1('r3)");
break;
case SRA:
Format(instr, "sra\t'r1,'d1('r3)");
break;
case SLDL:
Format(instr, "sldl\t'r1,'d1('r3)");
break;
case AGR:
Format(instr, "agr\t'r5,'r6");
break;
case AGFR:
Format(instr, "agfr\t'r5,'r6");
break;
case ARK:
Format(instr, "ark\t'r5,'r6,'r3");
break;
case AGRK:
Format(instr, "agrk\t'r5,'r6,'r3");
break;
case SGR:
Format(instr, "sgr\t'r5,'r6");
break;
case SGFR:
Format(instr, "sgfr\t'r5,'r6");
break;
case SRK:
Format(instr, "srk\t'r5,'r6,'r3");
break;
case SGRK:
Format(instr, "sgrk\t'r5,'r6,'r3");
break;
case NGR:
Format(instr, "ngr\t'r5,'r6");
break;
case NRK:
Format(instr, "nrk\t'r5,'r6,'r3");
break;
case NGRK:
Format(instr, "ngrk\t'r5,'r6,'r3");
break;
case NILL:
Format(instr, "nill\t'r1,'i1");
break;
case NILH:
Format(instr, "nilh\t'r1,'i1");
break;
case OGR:
Format(instr, "ogr\t'r5,'r6");
break;
case ORK:
Format(instr, "ork\t'r5,'r6,'r3");
break;
case OGRK:
Format(instr, "ogrk\t'r5,'r6,'r3");
break;
case XGR:
Format(instr, "xgr\t'r5,'r6");
break;
case XRK:
Format(instr, "xrk\t'r5,'r6,'r3");
break;
case XGRK:
Format(instr, "xgrk\t'r5,'r6,'r3");
break;
case CGFR:
Format(instr, "cgfr\t'r5,'r6");
break;
case CGR:
Format(instr, "cgr\t'r5,'r6");
break;
case CLGR:
Format(instr, "clgr\t'r5,'r6");
break;
case LLGFR:
Format(instr, "llgfr\t'r5,'r6");
/* RRE format */
case MDBR:
Format(instr, "mdbr\t'f5,'f6");
break;
case POPCNT_Z:
Format(instr, "popcnt\t'r5,'r6");
case SDBR:
Format(instr, "sdbr\t'f5,'f6");
break;
case LLGCR:
Format(instr, "llgcr\t'r5,'r6");
case ADBR:
Format(instr, "adbr\t'f5,'f6");
break;
case LLCR:
Format(instr, "llcr\t'r5,'r6");
case CDBR:
Format(instr, "cdbr\t'f5,'f6");
break;
case LBR:
Format(instr, "lbr\t'r5,'r6");
case MEEBR:
Format(instr, "meebr\t'f5,'f6");
break;
case LEDBR:
Format(instr, "ledbr\t'f5,'f6");
case SQDBR:
Format(instr, "sqdbr\t'f5,'f6");
break;
case LDEBR:
Format(instr, "ldebr\t'f5,'f6");
case SQEBR:
Format(instr, "sqebr\t'f5,'f6");
break;
case LTGR:
Format(instr, "ltgr\t'r5,'r6");
case LCDBR:
Format(instr, "lcdbr\t'f5,'f6");
break;
case LTDBR:
Format(instr, "ltdbr\t'f5,'f6");
case LCEBR:
Format(instr, "lcebr\t'f5,'f6");
break;
case LTEBR:
Format(instr, "ltebr\t'f5,'f6");
break;
case LRVR:
Format(instr, "lrvr\t'r5,'r6");
break;
case LRVGR:
Format(instr, "lrvgr\t'r5,'r6");
break;
case LGR:
Format(instr, "lgr\t'r5,'r6");
break;
case LGDR:
Format(instr, "lgdr\t'r5,'f6");
break;
case LGFR:
Format(instr, "lgfr\t'r5,'r6");
break;
case LTGFR:
Format(instr, "ltgfr\t'r5,'r6");
break;
case LCGR:
Format(instr, "lcgr\t'r5,'r6");
break;
case MSR:
Format(instr, "msr\t'r5,'r6");
break;
case MSRKC:
Format(instr, "msrkc\t'r5,'r6,'r3");
case LDEBR:
Format(instr, "ldebr\t'f5,'f6");
break;
case LGBR:
Format(instr, "lgbr\t'r5,'r6");
case CEBR:
Format(instr, "cebr\t'f5,'f6");
break;
case LGHR:
Format(instr, "lghr\t'r5,'r6");
case AEBR:
Format(instr, "aebr\t'f5,'f6");
break;
case MSGR:
Format(instr, "msgr\t'r5,'r6");
case SEBR:
Format(instr, "sebr\t'f5,'f6");
break;
case MSGRKC:
Format(instr, "msgrkc\t'r5,'r6,'r3");
case DEBR:
Format(instr, "debr\t'f5,'f6");
break;
case DSGR:
Format(instr, "dsgr\t'r5,'r6");
case LTDBR:
Format(instr, "ltdbr\t'f5,'f6");
break;
case DSGFR:
Format(instr, "dsgfr\t'r5,'r6");
case LDGR:
Format(instr, "ldgr\t'f5,'f6");
break;
case MSGFR:
Format(instr, "msgfr\t'r5,'r6");
case DDBR:
Format(instr, "ddbr\t'f5,'f6");
break;
case LZDR:
Format(instr, "lzdr\t'f5");
break;
case MLR:
Format(instr, "mlr\t'r5,'r6");
break;
case MLGR:
Format(instr, "mlgr\t'r5,'r6");
break;
case ALCR:
Format(instr, "alcr\t'r5,'r6");
break;
case ALGR:
Format(instr, "algr\t'r5,'r6");
break;
case ALRK:
Format(instr, "alrk\t'r5,'r6,'r3");
break;
case ALGRK:
Format(instr, "algrk\t'r5,'r6,'r3");
break;
case SLGR:
Format(instr, "slgr\t'r5,'r6");
break;
case SLBR:
Format(instr, "slbr\t'r5,'r6");
break;
case DLR:
Format(instr, "dlr\t'r5,'r6");
break;
case DLGR:
Format(instr, "dlgr\t'r5,'r6");
break;
case SLRK:
Format(instr, "slrk\t'r5,'r6,'r3");
break;
case SLGRK:
Format(instr, "slgrk\t'r5,'r6,'r3");
break;
case LHR:
Format(instr, "lhr\t'r5,'r6");
break;
case LLHR:
Format(instr, "llhr\t'r5,'r6");
break;
case LLGHR:
Format(instr, "llghr\t'r5,'r6");
break;
case LOCR:
Format(instr, "locr\t'r5,'r6,'m2");
break;
case LOCGR:
Format(instr, "locgr\t'r5,'r6,'m2");
break;
case LNGR:
Format(instr, "lngr\t'r5,'r6");
break;
case A:
Format(instr, "a\t'r1,'d1('r2d,'r3)");
break;
case S:
Format(instr, "s\t'r1,'d1('r2d,'r3)");
break;
case M:
Format(instr, "m\t'r1,'d1('r2d,'r3)");
break;
case D:
Format(instr, "d\t'r1,'d1('r2d,'r3)");
break;
case O:
Format(instr, "o\t'r1,'d1('r2d,'r3)");
break;
case N:
Format(instr, "n\t'r1,'d1('r2d,'r3)");
break;
case L:
Format(instr, "l\t'r1,'d1('r2d,'r3)");
break;
case C:
Format(instr, "c\t'r1,'d1('r2d,'r3)");
break;
case AH:
Format(instr, "ah\t'r1,'d1('r2d,'r3)");
break;
case SH:
Format(instr, "sh\t'r1,'d1('r2d,'r3)");
break;
case MH:
Format(instr, "mh\t'r1,'d1('r2d,'r3)");
break;
case AL:
Format(instr, "al\t'r1,'d1('r2d,'r3)");
break;
case SL:
Format(instr, "sl\t'r1,'d1('r2d,'r3)");
break;
case LA:
Format(instr, "la\t'r1,'d1('r2d,'r3)");
break;
case CH:
Format(instr, "ch\t'r1,'d1('r2d,'r3)");
break;
case CL:
Format(instr, "cl\t'r1,'d1('r2d,'r3)");
break;
case CLI:
Format(instr, "cli\t'd1('r3),'i8");
break;
case TM:
Format(instr, "tm\t'd1('r3),'i8");
break;
case BC:
Format(instr, "bc\t'm1,'d1('r2d,'r3)");
break;
case BCT:
Format(instr, "bct\t'r1,'d1('r2d,'r3)");
break;
case ST:
Format(instr, "st\t'r1,'d1('r2d,'r3)");
/* RRF-e format */
case FIEBRA:
Format(instr, "fiebra\t'f5,'m2,'f6,'m3");
break;
case STC:
Format(instr, "stc\t'r1,'d1('r2d,'r3)");
case FIDBRA:
Format(instr, "fidbra\t'f5,'m2,'f6,'m3");
break;
/* RX-a format */
case IC_z:
Format(instr, "ic\t'r1,'d1('r2d,'r3)");
break;
case LD:
Format(instr, "ld\t'f1,'d1('r2d,'r3)");
case AL:
Format(instr, "al\t'r1,'d1('r2d,'r3)");
break;
case LE:
Format(instr, "le\t'f1,'d1('r2d,'r3)");
break;
case LDGR:
Format(instr, "ldgr\t'f5,'r6");
break;
case MS:
Format(instr, "ms\t'r1,'d1('r2d,'r3)");
case LD:
Format(instr, "ld\t'f1,'d1('r2d,'r3)");
break;
case STE:
Format(instr, "ste\t'f1,'d1('r2d,'r3)");
......@@ -943,570 +606,318 @@ bool Decoder::DecodeFourByte(Instruction* instr) {
case STD:
Format(instr, "std\t'f1,'d1('r2d,'r3)");
break;
case CFDBR:
Format(instr, "cfdbr\t'r5,'m2,'f6");
break;
case CDFBR:
Format(instr, "cdfbr\t'f5,'m2,'r6");
break;
case CFEBR:
Format(instr, "cfebr\t'r5,'m2,'f6");
break;
case CEFBR:
Format(instr, "cefbr\t'f5,'m2,'r6");
break;
case CELFBR:
Format(instr, "celfbr\t'f5,'m2,'r6");
break;
case CGEBR:
Format(instr, "cgebr\t'r5,'m2,'f6");
break;
case CGDBR:
Format(instr, "cgdbr\t'r5,'m2,'f6");
break;
case CEGBR:
Format(instr, "cegbr\t'f5,'m2,'r6");
break;
case CDGBR:
Format(instr, "cdgbr\t'f5,'m2,'r6");
break;
case CDLFBR:
Format(instr, "cdlfbr\t'f5,'m2,'r6");
break;
case CDLGBR:
Format(instr, "cdlgbr\t'f5,'m2,'r6");
break;
case CELGBR:
Format(instr, "celgbr\t'f5,'m2,'r6");
break;
case CLFDBR:
Format(instr, "clfdbr\t'r5,'m2,'f6");
break;
case CLFEBR:
Format(instr, "clfebr\t'r5,'m2,'f6");
break;
case CLGEBR:
Format(instr, "clgebr\t'r5,'m2,'f6");
break;
case CLGDBR:
Format(instr, "clgdbr\t'r5,'m2,'f6");
break;
case AEBR:
Format(instr, "aebr\t'f5,'f6");
break;
case SEBR:
Format(instr, "sebr\t'f5,'f6");
break;
case MEEBR:
Format(instr, "meebr\t'f5,'f6");
break;
case DEBR:
Format(instr, "debr\t'f5,'f6");
break;
case ADBR:
Format(instr, "adbr\t'f5,'f6");
break;
case SDBR:
Format(instr, "sdbr\t'f5,'f6");
break;
case MDBR:
Format(instr, "mdbr\t'f5,'f6");
break;
case DDBR:
Format(instr, "ddbr\t'f5,'f6");
break;
case CDBR:
Format(instr, "cdbr\t'f5,'f6");
break;
case CEBR:
Format(instr, "cebr\t'f5,'f6");
break;
case SQDBR:
Format(instr, "sqdbr\t'f5,'f6");
break;
case SQEBR:
Format(instr, "sqebr\t'f5,'f6");
break;
case LCDBR:
Format(instr, "lcdbr\t'f5,'f6");
break;
case LCEBR:
Format(instr, "lcebr\t'f5,'f6");
break;
case STH:
Format(instr, "sth\t'r1,'d1('r2d,'r3)");
break;
case SRDA:
Format(instr, "srda\t'r1,'d1('r3)");
break;
case SRDL:
Format(instr, "srdl\t'r1,'d1('r3)");
break;
case MADBR:
Format(instr, "madbr\t'f3,'f5,'f6");
break;
case MSDBR:
Format(instr, "msdbr\t'f3,'f5,'f6");
break;
case FLOGR:
Format(instr, "flogr\t'r5,'r6");
break;
case FIEBRA:
Format(instr, "fiebra\t'f5,'m2,'f6,'m3");
break;
case FIDBRA:
Format(instr, "fidbra\t'f5,'m2,'f6,'m3");
break;
/* S format */
// TRAP4 is used in calling to native function. it will not be generated
// in native code.
case TRAP4: {
case TRAP4:
Format(instr, "trap4");
break;
}
case LPGR:
Format(instr, "lpgr\t'r5,'r6");
break;
case LPGFR:
Format(instr, "lpgfr\t'r5,'r6");
break;
case BRXH:
Format(instr, "brxh\t'r1,'r2,'i4");
break;
default:
return false;
}
return true;
}
// Disassembles Six Byte S390 Instructions
// @return true if successfully decoded
bool Decoder::DecodeSixByte(Instruction* instr) {
// Print the Instruction bits.
out_buffer_pos_ +=
SNPrintF(out_buffer_ + out_buffer_pos_, "%012" PRIx64 " ",
instr->InstructionBits<SixByteInstr>());
Opcode opcode = instr->S390OpcodeValue();
switch (opcode) {
case DUMY:
Format(instr, "dumy\t'r1, 'd2 ( 'r2d, 'r3 )");
break;
#define DECODE_VRR_C_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'f1,'f2,'f3"); \
break;
S390_VRR_C_OPCODE_LIST(DECODE_VRR_C_INSTRUCTIONS)
#undef DECODE_VRR_C_INSTRUCTIONS
case LLILF:
Format(instr, "llilf\t'r1,'i7");
break;
case LLIHF:
Format(instr, "llihf\t'r1,'i7");
break;
case AFI:
Format(instr, "afi\t'r1,'i7");
break;
case AIH:
Format(instr, "aih\t'r1,'i7");
break;
case ASI:
Format(instr, "asi\t'd2('r3),'ic");
break;
case AGSI:
Format(instr, "agsi\t'd2('r3),'ic");
break;
case ALFI:
Format(instr, "alfi\t'r1,'i7");
break;
case AHIK:
Format(instr, "ahik\t'r1,'r2,'i1");
break;
case AGHIK:
Format(instr, "aghik\t'r1,'r2,'i1");
break;
case CLGFI:
Format(instr, "clgfi\t'r1,'i7");
break;
case CLFI:
Format(instr, "clfi\t'r1,'i7");
break;
case CLIH:
Format(instr, "clih\t'r1,'i7");
break;
case CIH:
Format(instr, "cih\t'r1,'i2");
break;
/* RIL-a format */
case CFI:
Format(instr, "cfi\t'r1,'i2");
break;
case CGFI:
Format(instr, "cgfi\t'r1,'i2");
break;
case BRASL:
Format(instr, "brasl\t'r1,'ie");
break;
case BRCL:
Format(instr, "brcl\t'm1,'i5");
break;
case IIHF:
Format(instr, "iihf\t'r1,'i7");
break;
case LGFI:
Format(instr, "lgfi\t'r1,'i7");
break;
case IILF:
Format(instr, "iilf\t'r1,'i7");
break;
case XIHF:
Format(instr, "xihf\t'r1,'i7");
break;
case XILF:
Format(instr, "xilf\t'r1,'i7");
break;
case SLLK:
Format(instr, "sllk\t'r1,'r2,'d2('r3)");
break;
case SLLG:
Format(instr, "sllg\t'r1,'r2,'d2('r3)");
break;
case RLL:
Format(instr, "rll\t'r1,'r2,'d2('r3)");
break;
case RLLG:
Format(instr, "rllg\t'r1,'r2,'d2('r3)");
break;
case SRLK:
Format(instr, "srlk\t'r1,'r2,'d2('r3)");
break;
case SRLG:
Format(instr, "srlg\t'r1,'r2,'d2('r3)");
break;
case SLAK:
Format(instr, "slak\t'r1,'r2,'d2('r3)");
break;
case SLAG:
Format(instr, "slag\t'r1,'r2,'d2('r3)");
break;
case SRAK:
Format(instr, "srak\t'r1,'r2,'d2('r3)");
break;
case SRAG:
Format(instr, "srag\t'r1,'r2,'d2('r3)");
case AFI:
Format(instr, "afi\t'r1,'i2");
break;
case RISBG:
Format(instr, "risbg\t'r1,'r2,'i9,'ia,'ib");
case AGFI:
Format(instr, "agfi\t'r1,'i2");
break;
case RISBGN:
Format(instr, "risbgn\t'r1,'r2,'i9,'ia,'ib");
case MSFI:
Format(instr, "msfi\t'r1,'i2");
break;
case LOCG:
Format(instr, "locg\t'm2,'r1,'d2('r3)");
case MSGFI:
Format(instr, "msgfi\t'r1,'i2");
break;
case LOC:
Format(instr, "loc\t'm2,'r1,'d2('r3)");
case ALSIH:
Format(instr, "alsih\t'r1,'i2");
break;
case LMY:
Format(instr, "lmy\t'r1,'r2,'d2('r3)");
case ALSIHN:
Format(instr, "alsihn\t'r1,'i2");
break;
case LMG:
Format(instr, "lmg\t'r1,'r2,'d2('r3)");
case CIH:
Format(instr, "cih\t'r1,'i2");
break;
case CSY:
Format(instr, "csy\t'r1,'r2,'d2('r3)");
case AIH:
Format(instr, "aih\t'r1,'i2");
break;
case CSG:
Format(instr, "csg\t'r1,'r2,'d2('r3)");
case LGFI:
Format(instr, "lgfi\t'r1,'i2");
break;
case STMY:
Format(instr, "stmy\t'r1,'r2,'d2('r3)");
/* SIY format */
case ASI:
Format(instr, "asi\t'd2('r3),'ic");
break;
case STMG:
Format(instr, "stmg\t'r1,'r2,'d2('r3)");
case AGSI:
Format(instr, "agsi\t'd2('r3),'ic");
break;
/* RXY-a format */
case LT:
Format(instr, "lt\t'r1,'d2('r2d,'r3)");
break;
case LTG:
Format(instr, "ltg\t'r1,'d2('r2d,'r3)");
break;
case ML:
Format(instr, "ml\t'r1,'d2('r2d,'r3)");
break;
case AY:
Format(instr, "ay\t'r1,'d2('r2d,'r3)");
break;
case SY:
Format(instr, "sy\t'r1,'d2('r2d,'r3)");
break;
case NY:
Format(instr, "ny\t'r1,'d2('r2d,'r3)");
break;
case OY:
Format(instr, "oy\t'r1,'d2('r2d,'r3)");
break;
case XY:
Format(instr, "xy\t'r1,'d2('r2d,'r3)");
break;
case CY:
Format(instr, "cy\t'r1,'d2('r2d,'r3)");
break;
case AHY:
Format(instr, "ahy\t'r1,'d2('r2d,'r3)");
break;
case SHY:
Format(instr, "shy\t'r1,'d2('r2d,'r3)");
break;
case LGH:
Format(instr, "lgh\t'r1,'d2('r2d,'r3)");
break;
case AG:
Format(instr, "ag\t'r1,'d2('r2d,'r3)");
break;
case AGF:
Format(instr, "agf\t'r1,'d2('r2d,'r3)");
break;
case SG:
Format(instr, "sg\t'r1,'d2('r2d,'r3)");
break;
case NG:
Format(instr, "ng\t'r1,'d2('r2d,'r3)");
break;
case OG:
Format(instr, "og\t'r1,'d2('r2d,'r3)");
break;
case XG:
Format(instr, "xg\t'r1,'d2('r2d,'r3)");
break;
case CG:
Format(instr, "cg\t'r1,'d2('r2d,'r3)");
break;
case LB:
Format(instr, "lb\t'r1,'d2('r2d,'r3)");
break;
case LRVH:
Format(instr, "lrvh\t'r1,'d2('r2d,'r3)");
break;
case LRV:
Format(instr, "lrv\t'r1,'d2('r2d,'r3)");
break;
case LRVG:
Format(instr, "lrvg\t'r1,'d2('r2d,'r3)");
break;
case LG:
Format(instr, "lg\t'r1,'d2('r2d,'r3)");
break;
case LGF:
Format(instr, "lgf\t'r1,'d2('r2d,'r3)");
break;
case LLGF:
Format(instr, "llgf\t'r1,'d2('r2d,'r3)");
break;
case LY:
Format(instr, "ly\t'r1,'d2('r2d,'r3)");
break;
case ALY:
Format(instr, "aly\t'r1,'d2('r2d,'r3)");
break;
case ALG:
Format(instr, "alg\t'r1,'d2('r2d,'r3)");
break;
case SLG:
Format(instr, "slg\t'r1,'d2('r2d,'r3)");
break;
case SGF:
Format(instr, "sgf\t'r1,'d2('r2d,'r3)");
break;
case SLY:
Format(instr, "sly\t'r1,'d2('r2d,'r3)");
break;
case LLH:
Format(instr, "llh\t'r1,'d2('r2d,'r3)");
break;
case LLGH:
Format(instr, "llgh\t'r1,'d2('r2d,'r3)");
break;
case LLC:
Format(instr, "llc\t'r1,'d2('r2d,'r3)");
break;
case LLGC:
Format(instr, "llgc\t'r1,'d2('r2d,'r3)");
break;
case LDEB:
Format(instr, "ldeb\t'f1,'d2('r2d,'r3)");
break;
case LAY:
Format(instr, "lay\t'r1,'d2('r2d,'r3)");
break;
case LARL:
Format(instr, "larl\t'r1,'i5");
break;
case LGB:
Format(instr, "lgb\t'r1,'d2('r2d,'r3)");
break;
case CHY:
Format(instr, "chy\t'r1,'d2('r2d,'r3)");
break;
case CLY:
Format(instr, "cly\t'r1,'d2('r2d,'r3)");
break;
case CLIY:
Format(instr, "cliy\t'd2('r3),'i8");
break;
case TMY:
Format(instr, "tmy\t'd2('r3),'i8");
break;
case CLG:
Format(instr, "clg\t'r1,'d2('r2d,'r3)");
break;
case BCTG:
Format(instr, "bctg\t'r1,'d2('r2d,'r3)");
break;
case STY:
Format(instr, "sty\t'r1,'d2('r2d,'r3)");
break;
case STRVH:
Format(instr, "strvh\t'r1,'d2('r2d,'r3)");
break;
case STRV:
Format(instr, "strv\t'r1,'d2('r2d,'r3)");
break;
case STRVG:
Format(instr, "strvg\t'r1,'d2('r2d,'r3)");
break;
case STG:
Format(instr, "stg\t'r1,'d2('r2d,'r3)");
break;
case ICY:
Format(instr, "icy\t'r1,'d2('r2d,'r3)");
break;
case MVC:
Format(instr, "mvc\t'd3('i8,'r3),'d4('r7)");
break;
case MVHI:
Format(instr, "mvhi\t'd3('r3),'id");
break;
case MVGHI:
Format(instr, "mvghi\t'd3('r3),'id");
break;
case ALGFI:
Format(instr, "algfi\t'r1,'i7");
break;
case SLGFI:
Format(instr, "slgfi\t'r1,'i7");
break;
case SLFI:
Format(instr, "slfi\t'r1,'i7");
break;
case NIHF:
Format(instr, "nihf\t'r1,'i7");
break;
case NILF:
Format(instr, "nilf\t'r1,'i7");
break;
case OIHF:
Format(instr, "oihf\t'r1,'i7");
break;
case OILF:
Format(instr, "oilf\t'r1,'i7");
break;
case MSFI:
Format(instr, "msfi\t'r1,'i7");
break;
case MSGFI:
Format(instr, "msgfi\t'r1,'i7");
break;
case LDY:
Format(instr, "ldy\t'f1,'d2('r2d,'r3)");
break;
case LEY:
Format(instr, "ley\t'f1,'d2('r2d,'r3)");
break;
case MSG:
Format(instr, "msg\t'r1,'d2('r2d,'r3)");
break;
case DSG:
Format(instr, "dsg\t'r1,'d2('r2d,'r3)");
break;
case DSGF:
Format(instr, "dsgf\t'r1,'d2('r2d,'r3)");
break;
case MSGF:
Format(instr, "msgf\t'r1,'d2('r2d,'r3)");
break;
case MSY:
Format(instr, "msy\t'r1,'d2('r2d,'r3)");
break;
case MSC:
Format(instr, "msc\t'r1,'d2('r2d,'r3)");
break;
case MSGC:
Format(instr, "msgc\t'r1,'d2('r2d,'r3)");
case STDY:
Format(instr, "stdy\t'f1,'d2('r2d,'r3)");
break;
case STEY:
Format(instr, "stey\t'f1,'d2('r2d,'r3)");
break;
case STDY:
Format(instr, "stdy\t'f1,'d2('r2d,'r3)");
/* RXE format */
case LDEB:
Format(instr, "ldeb\t'f1,'d2('r2d,'r3)");
break;
case ADB:
Format(instr, "adb\t'f1,'d1('r2d, 'r3)");
default:
return false;
}
return true;
}
// Handles common cases of instructions;
// @return true if successfully decoded
bool Decoder::DecodeGeneric(Instruction* instr) {
Opcode opcode = instr->S390OpcodeValue();
switch (opcode) {
/* 2 bytes */
#define DECODE_RR_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'r1,'r2"); \
break;
S390_RR_OPCODE_LIST(DECODE_RR_INSTRUCTIONS)
#undef DECODE_RR_INSTRUCTIONS
/* 4 bytes */
#define DECODE_RS_A_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'r1,'r2,'d1('r3)"); \
break;
case AEB:
Format(instr, "aeb\t'f1,'d1('r2d, 'r3)");
S390_RS_A_OPCODE_LIST(DECODE_RS_A_INSTRUCTIONS)
#undef DECODE_RS_A_INSTRUCTIONS
#define DECODE_RSI_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'r1,'r2,'i4"); \
break;
case CDB:
Format(instr, "cdb\t'f1,'d1('r2d, 'r3)");
S390_RSI_OPCODE_LIST(DECODE_RSI_INSTRUCTIONS)
#undef DECODE_RSI_INSTRUCTIONS
#define DECODE_RI_A_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'r1,'i1"); \
break;
case CEB:
Format(instr, "ceb\t'f1,'d1('r2d, 'r3)");
S390_RI_A_OPCODE_LIST(DECODE_RI_A_INSTRUCTIONS)
#undef DECODE_RI_A_INSTRUCTIONS
#define DECODE_RI_B_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'r1,'i4"); \
break;
case SDB:
Format(instr, "sdb\t'r1,'d1('r2d, 'r3)");
S390_RI_B_OPCODE_LIST(DECODE_RI_B_INSTRUCTIONS)
#undef DECODE_RI_B_INSTRUCTIONS
#define DECODE_RI_C_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'm1,'i4"); \
break;
case SEB:
Format(instr, "seb\t'r1,'d1('r2d, 'r3)");
S390_RI_C_OPCODE_LIST(DECODE_RI_C_INSTRUCTIONS)
#undef DECODE_RI_C_INSTRUCTIONS
#define DECODE_RRE_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'r5,'r6"); \
break;
case MDB:
Format(instr, "mdb\t'r1,'d1('r2d, 'r3)");
S390_RRE_OPCODE_LIST(DECODE_RRE_INSTRUCTIONS)
#undef DECODE_RRE_INSTRUCTIONS
#define DECODE_RRF_A_INSTRUCTIONS(name, opcode_name, opcode_val) \
case opcode_name: \
Format(instr, #name "\t'r5,'r6,'r3"); \
break;
case MEEB:
Format(instr, "meeb\t'r1,'d1('r2d, 'r3)");
S390_RRF_A_OPCODE_LIST(DECODE_RRF_A_INSTRUCTIONS)
#undef DECODE_RRF_A_INSTRUCTIONS
#define DECODE_RRF_C_INSTRUCTIONS(name, opcode_name, opcode_val) \
case opcode_name: \
Format(instr, #name "\t'r5,'r6,'m2"); \
break;
case DDB:
Format(instr, "ddb\t'r1,'d1('r2d, 'r3)");
S390_RRF_C_OPCODE_LIST(DECODE_RRF_C_INSTRUCTIONS)
#undef DECODE_RRF_C_INSTRUCTIONS
#define DECODE_RRF_E_INSTRUCTIONS(name, opcode_name, opcode_val) \
case opcode_name: \
Format(instr, #name "\t'r5,'m2,'f6"); \
break;
case DEB:
Format(instr, "deb\t'r1,'d1('r2d, 'r3)");
S390_RRF_E_OPCODE_LIST(DECODE_RRF_E_INSTRUCTIONS)
#undef DECODE_RRF_E_INSTRUCTIONS
#define DECODE_RX_A_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'r1,'d1('r2d,'r3)"); \
break;
case SQDB:
Format(instr, "sqdb\t'r1,'d1('r2d, 'r3)");
S390_RX_A_OPCODE_LIST(DECODE_RX_A_INSTRUCTIONS)
#undef DECODE_RX_A_INSTRUCTIONS
#define DECODE_RX_B_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'm1,'d1('r2d,'r3)"); \
break;
case PFD:
Format(instr, "pfd\t'm1,'d2('r2d,'r3)");
S390_RX_B_OPCODE_LIST(DECODE_RX_B_INSTRUCTIONS)
#undef DECODE_RX_B_INSTRUCTIONS
#define DECODE_RRD_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'f3,'f5,'f6"); \
break;
case BRXHG:
Format(instr, "brxhg\t'r1,'r2,'i4");
S390_RRD_OPCODE_LIST(DECODE_RRD_INSTRUCTIONS)
#undef DECODE_RRD_INSTRUCTIONS
#define DECODE_SI_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'd1('r3),'i8"); \
break;
S390_SI_OPCODE_LIST(DECODE_SI_INSTRUCTIONS)
#undef DECODE_SI_INSTRUCTIONS
/* 6 bytes */
#define DECODE_VRR_C_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'f1,'f2,'f3"); \
break;
S390_VRR_C_OPCODE_LIST(DECODE_VRR_C_INSTRUCTIONS)
#undef DECODE_VRR_C_INSTRUCTIONS
#define DECODE_RIL_A_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'r1,'i7"); \
break;
S390_RIL_A_OPCODE_LIST(DECODE_RIL_A_INSTRUCTIONS)
#undef DECODE_RIL_A_INSTRUCTIONS
#define DECODE_RIL_B_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'r1,'ie"); \
break;
S390_RIL_B_OPCODE_LIST(DECODE_RIL_B_INSTRUCTIONS)
#undef DECODE_RIL_B_INSTRUCTIONS
#define DECODE_RIL_C_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'm1,'ie"); \
break;
S390_RIL_C_OPCODE_LIST(DECODE_RIL_C_INSTRUCTIONS)
#undef DECODE_RIL_C_INSTRUCTIONS
#define DECODE_SIY_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'd2('r3),'i8"); \
break;
S390_SIY_OPCODE_LIST(DECODE_SIY_INSTRUCTIONS)
#undef DECODE_SIY_INSTRUCTIONS
#define DECODE_RIE_D_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'r1,'r2,'i1"); \
break;
S390_RIE_D_OPCODE_LIST(DECODE_RIE_D_INSTRUCTIONS)
#undef DECODE_RIE_D_INSTRUCTIONS
#define DECODE_RIE_E_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'r1,'r2,'i4"); \
break;
S390_RIE_E_OPCODE_LIST(DECODE_RIE_E_INSTRUCTIONS)
#undef DECODE_RIE_E_INSTRUCTIONS
#define DECODE_RIE_F_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'r1,'r2,'i9,'ia,'ib"); \
break;
S390_RIE_F_OPCODE_LIST(DECODE_RIE_F_INSTRUCTIONS)
#undef DECODE_RIE_F_INSTRUCTIONS
#define DECODE_RSY_A_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'r1,'r2,'d2('r3)"); \
break;
S390_RSY_A_OPCODE_LIST(DECODE_RSY_A_INSTRUCTIONS)
#undef DECODE_RSY_A_INSTRUCTIONS
#define DECODE_RSY_B_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'm2,'r1,'d2('r3)"); \
break;
S390_RSY_B_OPCODE_LIST(DECODE_RSY_B_INSTRUCTIONS)
#undef DECODE_RSY_B_INSTRUCTIONS
#define DECODE_RXY_A_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'r1,'d2('r2d,'r3)"); \
break;
S390_RXY_A_OPCODE_LIST(DECODE_RXY_A_INSTRUCTIONS)
#undef DECODE_RXY_A_INSTRUCTIONS
#define DECODE_RXY_B_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'm1,'d2('r2d,'r3)"); \
break;
S390_RXY_B_OPCODE_LIST(DECODE_RXY_B_INSTRUCTIONS)
#undef DECODE_RXY_B_INSTRUCTIONS
#define DECODE_RXE_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'f1,'d1('r2d, 'r3)"); \
break;
S390_RXE_OPCODE_LIST(DECODE_RXE_INSTRUCTIONS)
#undef DECODE_RXE_INSTRUCTIONS
#define DECODE_SIL_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'd3('r3),'id"); \
break;
S390_SIL_OPCODE_LIST(DECODE_SIL_INSTRUCTIONS)
#undef DECODE_SIL_INSTRUCTIONS
#define DECODE_SS_A_INSTRUCTIONS(name, opcode_name, opcode_value) \
case opcode_name: \
Format(instr, #name "\t'd3('i8,'r3),'d4('r7)"); \
break;
S390_SS_A_OPCODE_LIST(DECODE_SS_A_INSTRUCTIONS)
#undef DECODE_SS_A_INSTRUCTIONS
default:
return false;
}
return true;
}
#undef VERIFIY
// Disassemble the instruction at *instr_ptr into the output buffer.
int Decoder::InstructionDecode(byte* instr_ptr) {
Instruction* instr = Instruction::At(instr_ptr);
int instrLength = instr->InstructionLength();
if (2 == instrLength)
DecodeTwoByte(instr);
else if (4 == instrLength)
DecodeFourByte(instr);
else
DecodeSixByte(instr);
// Print the Instruction bits.
if (instrLength == 2) {
out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
"%04x ", instr->InstructionBits<TwoByteInstr>());
} else if (instrLength == 4) {
out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
"%08x ", instr->InstructionBits<FourByteInstr>());
} else {
out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
"%012" PRIx64 " ", instr->InstructionBits<SixByteInstr>());
}
bool decoded = DecodeSpecial(instr);
if (!decoded)
decoded = DecodeGeneric(instr);
if (!decoded)
Unknown(instr);
return instrLength;
}
......
......@@ -998,8 +998,6 @@ void Simulator::EvalTableInit() {
EvalTable[STFPC] = &Simulator::Evaluate_STFPC;
EvalTable[LFPC] = &Simulator::Evaluate_LFPC;
EvalTable[TRE] = &Simulator::Evaluate_TRE;
EvalTable[CUUTF] = &Simulator::Evaluate_CUUTF;
EvalTable[CUTFU] = &Simulator::Evaluate_CUTFU;
EvalTable[STFLE] = &Simulator::Evaluate_STFLE;
EvalTable[SRNMB] = &Simulator::Evaluate_SRNMB;
EvalTable[SRNMT] = &Simulator::Evaluate_SRNMT;
......@@ -1105,7 +1103,6 @@ void Simulator::EvalTableInit() {
EvalTable[CGDR] = &Simulator::Evaluate_CGDR;
EvalTable[CGXR] = &Simulator::Evaluate_CGXR;
EvalTable[LGDR] = &Simulator::Evaluate_LGDR;
EvalTable[MDTR] = &Simulator::Evaluate_MDTR;
EvalTable[MDTRA] = &Simulator::Evaluate_MDTRA;
EvalTable[DDTRA] = &Simulator::Evaluate_DDTRA;
EvalTable[ADTRA] = &Simulator::Evaluate_ADTRA;
......@@ -5291,18 +5288,6 @@ EVALUATE(TRE) {
return 0;
}
EVALUATE(CUUTF) {
UNIMPLEMENTED();
USE(instr);
return 0;
}
EVALUATE(CUTFU) {
UNIMPLEMENTED();
USE(instr);
return 0;
}
EVALUATE(STFLE) {
UNIMPLEMENTED();
USE(instr);
......@@ -6412,12 +6397,6 @@ EVALUATE(LGDR) {
return length;
}
EVALUATE(MDTR) {
UNIMPLEMENTED();
USE(instr);
return 0;
}
EVALUATE(MDTRA) {
UNIMPLEMENTED();
USE(instr);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment