Merge V8 5.3.332.45. DO NOT MERGE
Test: Manual
FPIIM-449
Change-Id: Id3254828b068abdea3cb10442e0172a8c9a98e03
(cherry picked from commit 13e2dadd00298019ed862f2b2fc5068bba730bcf)
diff --git a/src/s390/simulator-s390.cc b/src/s390/simulator-s390.cc
index e819556..434fbff 100644
--- a/src/s390/simulator-s390.cc
+++ b/src/s390/simulator-s390.cc
@@ -23,6 +23,8 @@
namespace v8 {
namespace internal {
+const auto GetRegConfig = RegisterConfiguration::Crankshaft;
+
// This macro provides a platform independent use of sscanf. The reason for
// SScanF not being implemented in a platform independent way through
// ::v8::internal::OS in the same way as SNPrintF is that the
@@ -331,7 +333,7 @@
for (int i = 0; i < kNumRegisters; i++) {
value = GetRegisterValue(i);
PrintF(" %3s: %08" V8PRIxPTR,
- Register::from_code(i).ToString(), value);
+ GetRegConfig()->GetGeneralRegisterName(i), value);
if ((argc == 3 && strcmp(arg2, "fp") == 0) && i < 8 &&
(i % 2) == 0) {
dvalue = GetRegisterPairDoubleValue(i);
@@ -346,7 +348,7 @@
for (int i = 0; i < kNumRegisters; i++) {
value = GetRegisterValue(i);
PrintF(" %3s: %08" V8PRIxPTR " %11" V8PRIdPTR,
- Register::from_code(i).ToString(), value, value);
+ GetRegConfig()->GetGeneralRegisterName(i), value, value);
if ((argc == 3 && strcmp(arg2, "fp") == 0) && i < 8 &&
(i % 2) == 0) {
dvalue = GetRegisterPairDoubleValue(i);
@@ -362,14 +364,15 @@
float fvalue = GetFPFloatRegisterValue(i);
uint32_t as_words = bit_cast<uint32_t>(fvalue);
PrintF("%3s: %f 0x%08x\n",
- DoubleRegister::from_code(i).ToString(), fvalue, as_words);
+ GetRegConfig()->GetDoubleRegisterName(i), fvalue,
+ as_words);
}
} else if (strcmp(arg1, "alld") == 0) {
for (int i = 0; i < DoubleRegister::kNumRegisters; i++) {
dvalue = GetFPDoubleRegisterValue(i);
uint64_t as_words = bit_cast<uint64_t>(dvalue);
PrintF("%3s: %f 0x%08x %08x\n",
- DoubleRegister::from_code(i).ToString(), dvalue,
+ GetRegConfig()->GetDoubleRegisterName(i), dvalue,
static_cast<uint32_t>(as_words >> 32),
static_cast<uint32_t>(as_words & 0xffffffff));
}
@@ -701,7 +704,7 @@
last_debugger_input_ = input;
}
-void Simulator::FlushICache(v8::internal::HashMap* i_cache, void* start_addr,
+void Simulator::FlushICache(base::HashMap* i_cache, void* start_addr,
size_t size) {
intptr_t start = reinterpret_cast<intptr_t>(start_addr);
int intra_line = (start & CachePage::kLineMask);
@@ -722,9 +725,8 @@
}
}
-CachePage* Simulator::GetCachePage(v8::internal::HashMap* i_cache, void* page) {
- v8::internal::HashMap::Entry* entry =
- i_cache->LookupOrInsert(page, ICacheHash(page));
+CachePage* Simulator::GetCachePage(base::HashMap* i_cache, void* page) {
+ base::HashMap::Entry* entry = i_cache->LookupOrInsert(page, ICacheHash(page));
if (entry->value == NULL) {
CachePage* new_page = new CachePage();
entry->value = new_page;
@@ -733,8 +735,7 @@
}
// Flush from start up to and not including start + size.
-void Simulator::FlushOnePage(v8::internal::HashMap* i_cache, intptr_t start,
- int size) {
+void Simulator::FlushOnePage(base::HashMap* i_cache, intptr_t start, int size) {
DCHECK(size <= CachePage::kPageSize);
DCHECK(AllOnOnePage(start, size - 1));
DCHECK((start & CachePage::kLineMask) == 0);
@@ -746,8 +747,7 @@
memset(valid_bytemap, CachePage::LINE_INVALID, size >> CachePage::kLineShift);
}
-void Simulator::CheckICache(v8::internal::HashMap* i_cache,
- Instruction* instr) {
+void Simulator::CheckICache(base::HashMap* i_cache, Instruction* instr) {
intptr_t address = reinterpret_cast<intptr_t>(instr);
void* page = reinterpret_cast<void*>(address & (~CachePage::kPageMask));
void* line = reinterpret_cast<void*>(address & (~CachePage::kLineMask));
@@ -1513,7 +1513,7 @@
Simulator::Simulator(Isolate* isolate) : isolate_(isolate) {
i_cache_ = isolate_->simulator_i_cache();
if (i_cache_ == NULL) {
- i_cache_ = new v8::internal::HashMap(&ICacheMatch);
+ i_cache_ = new base::HashMap(&ICacheMatch);
isolate_->set_simulator_i_cache(i_cache_);
}
Initialize(isolate);
@@ -1654,10 +1654,10 @@
};
// static
-void Simulator::TearDown(HashMap* i_cache, Redirection* first) {
+void Simulator::TearDown(base::HashMap* i_cache, Redirection* first) {
Redirection::DeleteChain(first);
if (i_cache != nullptr) {
- for (HashMap::Entry* entry = i_cache->Start(); entry != nullptr;
+ for (base::HashMap::Entry* entry = i_cache->Start(); entry != nullptr;
entry = i_cache->Next(entry)) {
delete static_cast<CachePage*>(entry->value);
}
@@ -2028,15 +2028,17 @@
case ExternalReference::BUILTIN_FP_FP_CALL:
case ExternalReference::BUILTIN_COMPARE_CALL:
PrintF("Call to host function at %p with args %f, %f",
- FUNCTION_ADDR(generic_target), dval0, dval1);
+ static_cast<void*>(FUNCTION_ADDR(generic_target)), dval0,
+ dval1);
break;
case ExternalReference::BUILTIN_FP_CALL:
PrintF("Call to host function at %p with arg %f",
- FUNCTION_ADDR(generic_target), dval0);
+ static_cast<void*>(FUNCTION_ADDR(generic_target)), dval0);
break;
case ExternalReference::BUILTIN_FP_INT_CALL:
PrintF("Call to host function at %p with args %f, %" V8PRIdPTR,
- FUNCTION_ADDR(generic_target), dval0, ival);
+ static_cast<void*>(FUNCTION_ADDR(generic_target)), dval0,
+ ival);
break;
default:
UNREACHABLE();
@@ -2178,8 +2180,8 @@
"Call to host function at %p,\n"
"\t\t\t\targs %08" V8PRIxPTR ", %08" V8PRIxPTR ", %08" V8PRIxPTR
", %08" V8PRIxPTR ", %08" V8PRIxPTR ", %08" V8PRIxPTR,
- FUNCTION_ADDR(target), arg[0], arg[1], arg[2], arg[3], arg[4],
- arg[5]);
+ static_cast<void*>(FUNCTION_ADDR(target)), arg[0], arg[1], arg[2],
+ arg[3], arg[4], arg[5]);
if (!stack_aligned) {
PrintF(" with unaligned stack %08" V8PRIxPTR "\n",
static_cast<intptr_t>(get_register(sp)));
@@ -5654,6 +5656,9 @@
}
void Simulator::CallInternal(byte* entry, int reg_arg_count) {
+ // Adjust JS-based stack limit to C-based stack limit.
+ isolate_->stack_guard()->AdjustStackLimitForSimulator();
+
// Prepare to execute the code at entry
if (ABI_USES_FUNCTION_DESCRIPTORS) {
// entry is the function descriptor
@@ -5736,6 +5741,9 @@
}
intptr_t Simulator::Call(byte* entry, int argument_count, ...) {
+ // Adjust JS-based stack limit to C-based stack limit.
+ isolate_->stack_guard()->AdjustStackLimitForSimulator();
+
// Remember the values of non-volatile registers.
int64_t r6_val = get_register(r6);
int64_t r7_val = get_register(r7);
@@ -5948,11 +5956,52 @@
uint8_t imm_val = AS(SIInstruction)->I2Value(); \
int length = 4;
+#define DECODE_SIL_INSTRUCTION(b1, d1, i2) \
+ int b1 = AS(SILInstruction)->B1Value(); \
+ intptr_t d1 = AS(SILInstruction)->D1Value(); \
+ int16_t i2 = AS(SILInstruction)->I2Value(); \
+ int length = 6;
+
+#define DECODE_SIY_INSTRUCTION(b1, d1, i2) \
+ int b1 = AS(SIYInstruction)->B1Value(); \
+ intptr_t d1 = AS(SIYInstruction)->D1Value(); \
+ uint8_t i2 = AS(SIYInstruction)->I2Value(); \
+ int length = 6;
+
#define DECODE_RRE_INSTRUCTION(r1, r2) \
int r1 = AS(RREInstruction)->R1Value(); \
int r2 = AS(RREInstruction)->R2Value(); \
int length = 4;
+#define DECODE_RRE_INSTRUCTION_M3(r1, r2, m3) \
+ int r1 = AS(RREInstruction)->R1Value(); \
+ int r2 = AS(RREInstruction)->R2Value(); \
+ int m3 = AS(RREInstruction)->M3Value(); \
+ int length = 4;
+
+#define DECODE_RRE_INSTRUCTION_NO_R2(r1) \
+ int r1 = AS(RREInstruction)->R1Value(); \
+ int length = 4;
+
+#define DECODE_RRD_INSTRUCTION(r1, r2, r3) \
+ int r1 = AS(RRDInstruction)->R1Value(); \
+ int r2 = AS(RRDInstruction)->R2Value(); \
+ int r3 = AS(RRDInstruction)->R3Value(); \
+ int length = 4;
+
+#define DECODE_RRF_E_INSTRUCTION(r1, r2, m3, m4) \
+ int r1 = AS(RRFInstruction)->R1Value(); \
+ int r2 = AS(RRFInstruction)->R2Value(); \
+ int m3 = AS(RRFInstruction)->M3Value(); \
+ int m4 = AS(RRFInstruction)->M4Value(); \
+ int length = 4;
+
+#define DECODE_RRF_A_INSTRUCTION(r1, r2, r3) \
+ int r1 = AS(RRFInstruction)->R1Value(); \
+ int r2 = AS(RRFInstruction)->R2Value(); \
+ int r3 = AS(RRFInstruction)->R3Value(); \
+ int length = 4;
+
#define DECODE_RR_INSTRUCTION(r1, r2) \
int r1 = AS(RRInstruction)->R1Value(); \
int r2 = AS(RRInstruction)->R2Value(); \
@@ -5994,6 +6043,13 @@
int16_t i2 = AS(RIInstruction)->I2Value(); \
int length = 4;
+#define DECODE_RXE_INSTRUCTION(r1, b2, x2, d2) \
+ int r1 = AS(RXEInstruction)->R1Value(); \
+ int b2 = AS(RXEInstruction)->B2Value(); \
+ int x2 = AS(RXEInstruction)->X2Value(); \
+ int d2 = AS(RXEInstruction)->D2Value(); \
+ int length = 6;
+
#define GET_ADDRESS(index_reg, base_reg, offset) \
(((index_reg) == 0) ? 0 : get_register(index_reg)) + \
(((base_reg) == 0) ? 0 : get_register(base_reg)) + offset
@@ -6334,11 +6390,23 @@
return length;
}
-EVALUATE(SPM) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SPM) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(BALR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(BALR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(BCTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(BCTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
EVALUATE(BCR) {
DCHECK_OPCODE(BCR);
@@ -6357,11 +6425,23 @@
return length;
}
-EVALUATE(SVC) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SVC) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(BSM) { return DecodeInstructionOriginal(instr); }
+EVALUATE(BSM) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(BASSM) { return DecodeInstructionOriginal(instr); }
+EVALUATE(BASSM) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
EVALUATE(BASR) {
DCHECK_OPCODE(BASR);
@@ -6382,11 +6462,23 @@
return length;
}
-EVALUATE(MVCL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MVCL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CLCL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CLCL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LPR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LPR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
EVALUATE(LNR) {
DCHECK_OPCODE(LNR);
@@ -6560,9 +6652,17 @@
return length;
}
-EVALUATE(CDR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CDR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LER) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LER) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
EVALUATE(STH) {
DCHECK_OPCODE(STH);
@@ -6598,7 +6698,11 @@
return length;
}
-EVALUATE(IC_z) { return DecodeInstructionOriginal(instr); }
+EVALUATE(IC_z) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
EVALUATE(EX) {
DCHECK_OPCODE(EX);
@@ -6622,11 +6726,23 @@
return length;
}
-EVALUATE(BAL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(BAL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(BCT) { return DecodeInstructionOriginal(instr); }
+EVALUATE(BCT) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(BC) { return DecodeInstructionOriginal(instr); }
+EVALUATE(BC) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
EVALUATE(LH) {
DCHECK_OPCODE(LH);
@@ -6642,7 +6758,11 @@
return length;
}
-EVALUATE(CH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
EVALUATE(AH) {
DCHECK_OPCODE(AH);
@@ -6695,13 +6815,29 @@
return length;
}
-EVALUATE(BAS) { return DecodeInstructionOriginal(instr); }
+EVALUATE(BAS) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CVD) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CVD) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CVB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CVB) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LAE) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LAE) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
EVALUATE(N) {
DCHECK_OPCODE(N);
@@ -6808,13 +6944,29 @@
return length;
}
-EVALUATE(M) { return DecodeInstructionOriginal(instr); }
+EVALUATE(M) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(D) { return DecodeInstructionOriginal(instr); }
+EVALUATE(D) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(AL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(AL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
EVALUATE(STD) {
DCHECK_OPCODE(STD);
@@ -6838,7 +6990,11 @@
return length;
}
-EVALUATE(CD) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CD) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
EVALUATE(STE) {
DCHECK_OPCODE(STE);
@@ -6873,9 +7029,17 @@
return length;
}
-EVALUATE(BRXH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(BRXH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(BRXLE) { return DecodeInstructionOriginal(instr); }
+EVALUATE(BRXLE) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
EVALUATE(BXH) {
DCHECK_OPCODE(BXH);
@@ -6905,7 +7069,11 @@
return length;
}
-EVALUATE(BXLE) { return DecodeInstructionOriginal(instr); }
+EVALUATE(BXLE) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
EVALUATE(SRL) {
DCHECK_OPCODE(SRL);
@@ -7018,7 +7186,11 @@
return length;
}
-EVALUATE(SLDA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SLDA) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
EVALUATE(STM) {
DCHECK_OPCODE(STM);
@@ -7061,11 +7233,23 @@
return length;
}
-EVALUATE(MVI) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MVI) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(TS) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TS) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(NI) { return DecodeInstructionOriginal(instr); }
+EVALUATE(NI) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
EVALUATE(CLI) {
DCHECK_OPCODE(CLI);
@@ -7078,9 +7262,17 @@
return length;
}
-EVALUATE(OI) { return DecodeInstructionOriginal(instr); }
+EVALUATE(OI) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(XI) { return DecodeInstructionOriginal(instr); }
+EVALUATE(XI) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
EVALUATE(LM) {
DCHECK_OPCODE(LM);
@@ -7102,25 +7294,65 @@
return length;
}
-EVALUATE(MVCLE) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MVCLE) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CLCLE) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CLCLE) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(MC) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MC) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CDS) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CDS) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(STCM) { return DecodeInstructionOriginal(instr); }
+EVALUATE(STCM) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(ICM) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ICM) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(BPRP) { return DecodeInstructionOriginal(instr); }
+EVALUATE(BPRP) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(BPP) { return DecodeInstructionOriginal(instr); }
+EVALUATE(BPP) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(TRTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TRTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(MVN) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MVN) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
EVALUATE(MVC) {
DCHECK_OPCODE(MVC);
@@ -7143,73 +7375,209 @@
return length;
}
-EVALUATE(MVZ) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MVZ) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(NC) { return DecodeInstructionOriginal(instr); }
+EVALUATE(NC) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CLC) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CLC) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(OC) { return DecodeInstructionOriginal(instr); }
+EVALUATE(OC) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(XC) { return DecodeInstructionOriginal(instr); }
+EVALUATE(XC) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(MVCP) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MVCP) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(TR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(TRT) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TRT) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(ED) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ED) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(EDMK) { return DecodeInstructionOriginal(instr); }
+EVALUATE(EDMK) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(PKU) { return DecodeInstructionOriginal(instr); }
+EVALUATE(PKU) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(UNPKU) { return DecodeInstructionOriginal(instr); }
+EVALUATE(UNPKU) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(MVCIN) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MVCIN) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(PKA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(PKA) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(UNPKA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(UNPKA) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(PLO) { return DecodeInstructionOriginal(instr); }
+EVALUATE(PLO) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LMD) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LMD) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SRP) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SRP) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(MVO) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MVO) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(PACK) { return DecodeInstructionOriginal(instr); }
+EVALUATE(PACK) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(UNPK) { return DecodeInstructionOriginal(instr); }
+EVALUATE(UNPK) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(ZAP) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ZAP) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(AP) { return DecodeInstructionOriginal(instr); }
+EVALUATE(AP) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SP) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SP) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(MP) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MP) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(DP) { return DecodeInstructionOriginal(instr); }
+EVALUATE(DP) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(UPT) { return DecodeInstructionOriginal(instr); }
+EVALUATE(UPT) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(PFPO) { return DecodeInstructionOriginal(instr); }
+EVALUATE(PFPO) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(IIHH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(IIHH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(IIHL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(IIHL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(IILH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(IILH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(IILL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(IILL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(NIHH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(NIHH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(NIHL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(NIHL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
EVALUATE(NILH) {
DCHECK_OPCODE(NILH);
@@ -7233,9 +7601,17 @@
return length;
}
-EVALUATE(OIHH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(OIHH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(OIHL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(OIHL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
EVALUATE(OILH) {
DCHECK_OPCODE(OILH);
@@ -7258,15 +7634,35 @@
return length;
}
-EVALUATE(LLIHH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LLIHH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LLIHL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LLIHL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LLILH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LLILH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LLILL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LLILL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(TMLH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TMLH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
EVALUATE(TMLL) {
DCHECK_OPCODE(TMLL);
@@ -7326,9 +7722,17 @@
return length;
}
-EVALUATE(TMHH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TMHH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(TMHL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TMHL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
EVALUATE(BRAS) {
DCHECK_OPCODE(BRAS);
@@ -7437,7 +7841,11 @@
return length;
}
-EVALUATE(LGFI) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LGFI) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
EVALUATE(BRASL) {
DCHECK_OPCODE(BRASL);
@@ -7668,93 +8076,269 @@
return length;
}
-EVALUATE(LLHRL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LLHRL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LGHRL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LGHRL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LHRL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LHRL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LLGHRL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LLGHRL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(STHRL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(STHRL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LGRL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LGRL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(STGRL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(STGRL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LGFRL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LGFRL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LRL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LRL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LLGFRL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LLGFRL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(STRL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(STRL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(EXRL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(EXRL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(PFDRL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(PFDRL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CGHRL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CGHRL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CHRL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CHRL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CGRL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CGRL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CGFRL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CGFRL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(ECTG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ECTG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CSST) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CSST) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LPD) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LPD) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LPDG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LPDG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(BRCTH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(BRCTH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(AIH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(AIH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(ALSIH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ALSIH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(ALSIHN) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ALSIHN) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CIH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CIH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(STCK) { return DecodeInstructionOriginal(instr); }
+EVALUATE(STCK) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CFC) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CFC) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(IPM) { return DecodeInstructionOriginal(instr); }
+EVALUATE(IPM) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(HSCH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(HSCH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(MSCH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MSCH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SSCH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SSCH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(STSCH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(STSCH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(TSCH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TSCH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(TPI) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TPI) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SAL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SAL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(RSCH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(RSCH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(STCRW) { return DecodeInstructionOriginal(instr); }
+EVALUATE(STCRW) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(STCPS) { return DecodeInstructionOriginal(instr); }
+EVALUATE(STCPS) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(RCHP) { return DecodeInstructionOriginal(instr); }
+EVALUATE(RCHP) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SCHM) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SCHM) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CKSM) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CKSM) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SAR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SAR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(EAR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(EAR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
EVALUATE(MSR) {
DCHECK_OPCODE(MSR);
@@ -7765,49 +8349,144 @@
return length;
}
-EVALUATE(MVST) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MVST) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CUSE) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CUSE) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SRST) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SRST) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(XSCH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(XSCH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(STCKE) { return DecodeInstructionOriginal(instr); }
+EVALUATE(STCKE) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(STCKF) { return DecodeInstructionOriginal(instr); }
+EVALUATE(STCKF) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SRNM) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SRNM) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(STFPC) { return DecodeInstructionOriginal(instr); }
+EVALUATE(STFPC) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LFPC) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LFPC) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(TRE) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TRE) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CUUTF) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CUUTF) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CUTFU) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CUTFU) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(STFLE) { return DecodeInstructionOriginal(instr); }
+EVALUATE(STFLE) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SRNMB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SRNMB) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SRNMT) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SRNMT) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LFAS) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LFAS) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(PPA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(PPA) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(ETND) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ETND) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(TEND) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TEND) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(NIAI) { return DecodeInstructionOriginal(instr); }
+EVALUATE(NIAI) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(TABORT) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TABORT) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(TRAP4) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TRAP4) {
+ DCHECK_OPCODE(TRAP4);
+ int length = 4;
+ // whack the space of the caller allocated stack
+ int64_t sp_addr = get_register(sp);
+ for (int i = 0; i < kCalleeRegisterSaveAreaSize / kPointerSize; ++i) {
+ // we dont want to whack the RA (r14)
+ if (i != 14) (reinterpret_cast<intptr_t*>(sp_addr))[i] = 0xdeadbabe;
+ }
+ SoftwareInterrupt(instr);
+ return length;
+}
EVALUATE(LPEBR) {
DCHECK_OPCODE(LPEBR);
@@ -7827,7 +8506,11 @@
return length;
}
-EVALUATE(LNEBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LNEBR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
EVALUATE(LTEBR) {
DCHECK_OPCODE(LTEBR);
@@ -7839,7 +8522,11 @@
return length;
}
-EVALUATE(LCEBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LCEBR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
EVALUATE(LDEBR) {
DCHECK_OPCODE(LDEBR);
@@ -7850,13 +8537,29 @@
return length;
}
-EVALUATE(LXDBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LXDBR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LXEBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LXEBR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(MXDBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MXDBR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(KEBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(KEBR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
EVALUATE(CEBR) {
DCHECK_OPCODE(CEBR);
@@ -7896,7 +8599,11 @@
return length;
}
-EVALUATE(MDEBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MDEBR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
EVALUATE(DEBR) {
DCHECK_OPCODE(DEBR);
@@ -7910,9 +8617,17 @@
return length;
}
-EVALUATE(MAEBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MAEBR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(MSEBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MSEBR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
EVALUATE(LPDBR) {
DCHECK_OPCODE(LPDBR);
@@ -7931,7 +8646,11 @@
return length;
}
-EVALUATE(LNDBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LNDBR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
EVALUATE(LTDBR) {
DCHECK_OPCODE(LTDBR);
@@ -7961,875 +8680,3890 @@
return length;
}
-EVALUATE(SQEBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SQEBR) {
+ DCHECK_OPCODE(SQEBR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ float fr1_val = get_float32_from_d_register(r1);
+ float fr2_val = get_float32_from_d_register(r2);
+ fr1_val = std::sqrt(fr2_val);
+ set_d_register_from_float32(r1, fr1_val);
+ return length;
+}
-EVALUATE(SQDBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SQDBR) {
+ DCHECK_OPCODE(SQDBR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ double r1_val = get_double_from_d_register(r1);
+ double r2_val = get_double_from_d_register(r2);
+ r1_val = std::sqrt(r2_val);
+ set_d_register_from_double(r1, r1_val);
+ return length;
+}
-EVALUATE(SQXBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SQXBR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(MEEBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MEEBR) {
+ DCHECK_OPCODE(MEEBR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ float fr1_val = get_float32_from_d_register(r1);
+ float fr2_val = get_float32_from_d_register(r2);
+ fr1_val *= fr2_val;
+ set_d_register_from_float32(r1, fr1_val);
+ SetS390ConditionCode<float>(fr1_val, 0);
+ return length;
+}
-EVALUATE(KDBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(KDBR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CDBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CDBR) {
+ DCHECK_OPCODE(CDBR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ double r1_val = get_double_from_d_register(r1);
+ double r2_val = get_double_from_d_register(r2);
+ if (isNaN(r1_val) || isNaN(r2_val)) {
+ condition_reg_ = CC_OF;
+ } else {
+ SetS390ConditionCode<double>(r1_val, r2_val);
+ }
+ return length;
+}
-EVALUATE(ADBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ADBR) {
+ DCHECK_OPCODE(ADBR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ double r1_val = get_double_from_d_register(r1);
+ double r2_val = get_double_from_d_register(r2);
+ r1_val += r2_val;
+ set_d_register_from_double(r1, r1_val);
+ SetS390ConditionCode<double>(r1_val, 0);
+ return length;
+}
-EVALUATE(SDBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SDBR) {
+ DCHECK_OPCODE(SDBR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ double r1_val = get_double_from_d_register(r1);
+ double r2_val = get_double_from_d_register(r2);
+ r1_val -= r2_val;
+ set_d_register_from_double(r1, r1_val);
+ SetS390ConditionCode<double>(r1_val, 0);
+ return length;
+}
-EVALUATE(MDBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MDBR) {
+ DCHECK_OPCODE(MDBR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ double r1_val = get_double_from_d_register(r1);
+ double r2_val = get_double_from_d_register(r2);
+ r1_val *= r2_val;
+ set_d_register_from_double(r1, r1_val);
+ SetS390ConditionCode<double>(r1_val, 0);
+ return length;
+}
-EVALUATE(DDBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(DDBR) {
+ DCHECK_OPCODE(DDBR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ double r1_val = get_double_from_d_register(r1);
+ double r2_val = get_double_from_d_register(r2);
+ r1_val /= r2_val;
+ set_d_register_from_double(r1, r1_val);
+ SetS390ConditionCode<double>(r1_val, 0);
+ return length;
+}
-EVALUATE(MADBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MADBR) {
+ DCHECK_OPCODE(MADBR);
+ DECODE_RRD_INSTRUCTION(r1, r2, r3);
+ double r1_val = get_double_from_d_register(r1);
+ double r2_val = get_double_from_d_register(r2);
+ double r3_val = get_double_from_d_register(r3);
+ r1_val += r2_val * r3_val;
+ set_d_register_from_double(r1, r1_val);
+ SetS390ConditionCode<double>(r1_val, 0);
+ return length;
+}
-EVALUATE(MSDBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MSDBR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LPXBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LPXBR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LNXBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LNXBR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LTXBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LTXBR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LCXBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LCXBR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LEDBRA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LEDBRA) {
+ DCHECK_OPCODE(LEDBRA);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ double r2_val = get_double_from_d_register(r2);
+ set_d_register_from_float32(r1, static_cast<float>(r2_val));
+ return length;
+}
-EVALUATE(LDXBRA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LDXBRA) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LEXBRA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LEXBRA) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(FIXBRA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(FIXBRA) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(KXBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(KXBR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CXBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CXBR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(AXBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(AXBR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SXBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SXBR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(MXBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MXBR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(DXBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(DXBR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(TBEDR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TBEDR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(TBDR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TBDR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(DIEBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(DIEBR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(FIEBRA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(FIEBRA) {
+ DCHECK_OPCODE(FIEBRA);
+ DECODE_RRF_E_INSTRUCTION(r1, r2, m3, m4);
+ float r2_val = get_float32_from_d_register(r2);
+ CHECK(m4 == 0);
+ switch (m3) {
+ case Assembler::FIDBRA_ROUND_TO_NEAREST_AWAY_FROM_0:
+ set_d_register_from_float32(r1, round(r2_val));
+ break;
+ case Assembler::FIDBRA_ROUND_TOWARD_0:
+ set_d_register_from_float32(r1, trunc(r2_val));
+ break;
+ case Assembler::FIDBRA_ROUND_TOWARD_POS_INF:
+ set_d_register_from_float32(r1, std::ceil(r2_val));
+ break;
+ case Assembler::FIDBRA_ROUND_TOWARD_NEG_INF:
+ set_d_register_from_float32(r1, std::floor(r2_val));
+ break;
+ default:
+ UNIMPLEMENTED();
+ break;
+ }
+ return length;
+}
-EVALUATE(THDER) { return DecodeInstructionOriginal(instr); }
+EVALUATE(THDER) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(THDR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(THDR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(DIDBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(DIDBR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(FIDBRA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(FIDBRA) {
+ DCHECK_OPCODE(FIDBRA);
+ DECODE_RRF_E_INSTRUCTION(r1, r2, m3, m4);
+ double r2_val = get_double_from_d_register(r2);
+ CHECK(m4 == 0);
+ switch (m3) {
+ case Assembler::FIDBRA_ROUND_TO_NEAREST_AWAY_FROM_0:
+ set_d_register_from_double(r1, round(r2_val));
+ break;
+ case Assembler::FIDBRA_ROUND_TOWARD_0:
+ set_d_register_from_double(r1, trunc(r2_val));
+ break;
+ case Assembler::FIDBRA_ROUND_TOWARD_POS_INF:
+ set_d_register_from_double(r1, std::ceil(r2_val));
+ break;
+ case Assembler::FIDBRA_ROUND_TOWARD_NEG_INF:
+ set_d_register_from_double(r1, std::floor(r2_val));
+ break;
+ default:
+ UNIMPLEMENTED();
+ break;
+ }
+ return length;
+}
-EVALUATE(LXR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LXR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LPDFR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LPDFR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LNDFR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LNDFR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LCDFR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LCDFR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LZER) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LZER) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LZDR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LZDR) {
+ DCHECK_OPCODE(LZDR);
+ DECODE_RRE_INSTRUCTION_NO_R2(r1);
+ set_d_register_from_double(r1, 0.0);
+ return length;
+}
-EVALUATE(LZXR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LZXR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SFPC) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SFPC) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SFASR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SFASR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(EFPC) { return DecodeInstructionOriginal(instr); }
+EVALUATE(EFPC) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CELFBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CELFBR) {
+ DCHECK_OPCODE(CELFBR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ uint32_t r2_val = get_low_register<uint32_t>(r2);
+ float r1_val = static_cast<float>(r2_val);
+ set_d_register_from_float32(r1, r1_val);
+ return length;
+}
-EVALUATE(CDLFBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CDLFBR) {
+ DCHECK_OPCODE(CDLFBR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ uint32_t r2_val = get_low_register<uint32_t>(r2);
+ double r1_val = static_cast<double>(r2_val);
+ set_d_register_from_double(r1, r1_val);
+ return length;
+}
-EVALUATE(CXLFBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CXLFBR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CEFBRA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CEFBRA) {
+ DCHECK_OPCODE(CEFBRA);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ int32_t fr2_val = get_low_register<int32_t>(r2);
+ float fr1_val = static_cast<float>(fr2_val);
+ set_d_register_from_float32(r1, fr1_val);
+ return length;
+}
-EVALUATE(CDFBRA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CDFBRA) {
+ DCHECK_OPCODE(CDFBRA);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ int32_t r2_val = get_low_register<int32_t>(r2);
+ double r1_val = static_cast<double>(r2_val);
+ set_d_register_from_double(r1, r1_val);
+ return length;
+}
-EVALUATE(CXFBRA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CXFBRA) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CFEBRA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CFEBRA) {
+ DCHECK_OPCODE(CFEBRA);
+ DECODE_RRE_INSTRUCTION_M3(r1, r2, mask_val);
+ float r2_fval = get_float32_from_d_register(r2);
+ int32_t r1_val = 0;
-EVALUATE(CFDBRA) { return DecodeInstructionOriginal(instr); }
+ SetS390RoundConditionCode(r2_fval, INT32_MAX, INT32_MIN);
-EVALUATE(CFXBRA) { return DecodeInstructionOriginal(instr); }
+ switch (mask_val) {
+ case CURRENT_ROUNDING_MODE:
+ case ROUND_TO_PREPARE_FOR_SHORTER_PRECISION: {
+ r1_val = static_cast<int32_t>(r2_fval);
+ break;
+ }
+ case ROUND_TO_NEAREST_WITH_TIES_AWAY_FROM_0: {
+ float ceil_val = std::ceil(r2_fval);
+ float floor_val = std::floor(r2_fval);
+ float sub_val1 = std::fabs(r2_fval - floor_val);
+ float sub_val2 = std::fabs(r2_fval - ceil_val);
+ if (sub_val1 > sub_val2) {
+ r1_val = static_cast<int32_t>(ceil_val);
+ } else if (sub_val1 < sub_val2) {
+ r1_val = static_cast<int32_t>(floor_val);
+ } else { // round away from zero:
+ if (r2_fval > 0.0) {
+ r1_val = static_cast<int32_t>(ceil_val);
+ } else {
+ r1_val = static_cast<int32_t>(floor_val);
+ }
+ }
+ break;
+ }
+ case ROUND_TO_NEAREST_WITH_TIES_TO_EVEN: {
+ float ceil_val = std::ceil(r2_fval);
+ float floor_val = std::floor(r2_fval);
+ float sub_val1 = std::fabs(r2_fval - floor_val);
+ float sub_val2 = std::fabs(r2_fval - ceil_val);
+ if (sub_val1 > sub_val2) {
+ r1_val = static_cast<int32_t>(ceil_val);
+ } else if (sub_val1 < sub_val2) {
+ r1_val = static_cast<int32_t>(floor_val);
+ } else { // check which one is even:
+ int32_t c_v = static_cast<int32_t>(ceil_val);
+ int32_t f_v = static_cast<int32_t>(floor_val);
+ if (f_v % 2 == 0)
+ r1_val = f_v;
+ else
+ r1_val = c_v;
+ }
+ break;
+ }
+ case ROUND_TOWARD_0: {
+ // check for overflow, cast r2_fval to 64bit integer
+ // then check value within the range of INT_MIN and INT_MAX
+ // and set condition code accordingly
+ int64_t temp = static_cast<int64_t>(r2_fval);
+ if (temp < INT_MIN || temp > INT_MAX) {
+ condition_reg_ = CC_OF;
+ }
+ r1_val = static_cast<int32_t>(r2_fval);
+ break;
+ }
+ case ROUND_TOWARD_PLUS_INFINITE: {
+ r1_val = static_cast<int32_t>(std::ceil(r2_fval));
+ break;
+ }
+ case ROUND_TOWARD_MINUS_INFINITE: {
+ // check for overflow, cast r2_fval to 64bit integer
+ // then check value within the range of INT_MIN and INT_MAX
+ // and set condition code accordingly
+ int64_t temp = static_cast<int64_t>(std::floor(r2_fval));
+ if (temp < INT_MIN || temp > INT_MAX) {
+ condition_reg_ = CC_OF;
+ }
+ r1_val = static_cast<int32_t>(std::floor(r2_fval));
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+ set_low_register(r1, r1_val);
+ return length;
+}
-EVALUATE(CLFEBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CFDBRA) {
+ DCHECK_OPCODE(CFDBRA);
+ DECODE_RRE_INSTRUCTION_M3(r1, r2, mask_val);
+ double r2_val = get_double_from_d_register(r2);
+ int32_t r1_val = 0;
-EVALUATE(CLFDBR) { return DecodeInstructionOriginal(instr); }
+ SetS390RoundConditionCode(r2_val, INT32_MAX, INT32_MIN);
-EVALUATE(CLFXBR) { return DecodeInstructionOriginal(instr); }
+ switch (mask_val) {
+ case CURRENT_ROUNDING_MODE:
+ case ROUND_TO_PREPARE_FOR_SHORTER_PRECISION: {
+ r1_val = static_cast<int32_t>(r2_val);
+ break;
+ }
+ case ROUND_TO_NEAREST_WITH_TIES_AWAY_FROM_0: {
+ double ceil_val = std::ceil(r2_val);
+ double floor_val = std::floor(r2_val);
+ double sub_val1 = std::fabs(r2_val - floor_val);
+ double sub_val2 = std::fabs(r2_val - ceil_val);
+ if (sub_val1 > sub_val2) {
+ r1_val = static_cast<int32_t>(ceil_val);
+ } else if (sub_val1 < sub_val2) {
+ r1_val = static_cast<int32_t>(floor_val);
+ } else { // round away from zero:
+ if (r2_val > 0.0) {
+ r1_val = static_cast<int32_t>(ceil_val);
+ } else {
+ r1_val = static_cast<int32_t>(floor_val);
+ }
+ }
+ break;
+ }
+ case ROUND_TO_NEAREST_WITH_TIES_TO_EVEN: {
+ double ceil_val = std::ceil(r2_val);
+ double floor_val = std::floor(r2_val);
+ double sub_val1 = std::fabs(r2_val - floor_val);
+ double sub_val2 = std::fabs(r2_val - ceil_val);
+ if (sub_val1 > sub_val2) {
+ r1_val = static_cast<int32_t>(ceil_val);
+ } else if (sub_val1 < sub_val2) {
+ r1_val = static_cast<int32_t>(floor_val);
+ } else { // check which one is even:
+ int32_t c_v = static_cast<int32_t>(ceil_val);
+ int32_t f_v = static_cast<int32_t>(floor_val);
+ if (f_v % 2 == 0)
+ r1_val = f_v;
+ else
+ r1_val = c_v;
+ }
+ break;
+ }
+ case ROUND_TOWARD_0: {
+ // check for overflow, cast r2_val to 64bit integer
+ // then check value within the range of INT_MIN and INT_MAX
+ // and set condition code accordingly
+ int64_t temp = static_cast<int64_t>(r2_val);
+ if (temp < INT_MIN || temp > INT_MAX) {
+ condition_reg_ = CC_OF;
+ }
+ r1_val = static_cast<int32_t>(r2_val);
+ break;
+ }
+ case ROUND_TOWARD_PLUS_INFINITE: {
+ r1_val = static_cast<int32_t>(std::ceil(r2_val));
+ break;
+ }
+ case ROUND_TOWARD_MINUS_INFINITE: {
+ // check for overflow, cast r2_val to 64bit integer
+ // then check value within the range of INT_MIN and INT_MAX
+ // and set condition code accordingly
+ int64_t temp = static_cast<int64_t>(std::floor(r2_val));
+ if (temp < INT_MIN || temp > INT_MAX) {
+ condition_reg_ = CC_OF;
+ }
+ r1_val = static_cast<int32_t>(std::floor(r2_val));
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+ set_low_register(r1, r1_val);
+ return length;
+}
-EVALUATE(CELGBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CFXBRA) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CDLGBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CLFEBR) {
+ DCHECK_OPCODE(CLFEBR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ float r2_val = get_float32_from_d_register(r2);
+ uint32_t r1_val = static_cast<uint32_t>(r2_val);
+ set_low_register(r1, r1_val);
+ SetS390ConvertConditionCode<double>(r2_val, r1_val, UINT32_MAX);
+ return length;
+}
-EVALUATE(CXLGBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CLFDBR) {
+ DCHECK_OPCODE(CLFDBR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ double r2_val = get_double_from_d_register(r2);
+ uint32_t r1_val = static_cast<uint32_t>(r2_val);
+ set_low_register(r1, r1_val);
+ SetS390ConvertConditionCode<double>(r2_val, r1_val, UINT32_MAX);
+ return length;
+}
-EVALUATE(CEGBRA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CLFXBR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CDGBRA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CELGBR) {
+ DCHECK_OPCODE(CELGBR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ uint64_t r2_val = get_register(r2);
+ float r1_val = static_cast<float>(r2_val);
+ set_d_register_from_float32(r1, r1_val);
+ return length;
+}
-EVALUATE(CXGBRA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CDLGBR) {
+ DCHECK_OPCODE(CDLGBR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ uint64_t r2_val = get_register(r2);
+ double r1_val = static_cast<double>(r2_val);
+ set_d_register_from_double(r1, r1_val);
+ return length;
+}
-EVALUATE(CGEBRA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CXLGBR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CGDBRA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CEGBRA) {
+ DCHECK_OPCODE(CEGBRA);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ int64_t fr2_val = get_register(r2);
+ float fr1_val = static_cast<float>(fr2_val);
+ set_d_register_from_float32(r1, fr1_val);
+ return length;
+}
-EVALUATE(CGXBRA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CDGBRA) {
+ DCHECK_OPCODE(CDGBRA);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ int64_t r2_val = get_register(r2);
+ double r1_val = static_cast<double>(r2_val);
+ set_d_register_from_double(r1, r1_val);
+ return length;
+}
-EVALUATE(CLGEBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CXGBRA) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CLGDBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CGEBRA) {
+ DCHECK_OPCODE(CGEBRA);
+ DECODE_RRE_INSTRUCTION_M3(r1, r2, mask_val);
+ float r2_fval = get_float32_from_d_register(r2);
+ int64_t r1_val = 0;
-EVALUATE(CFER) { return DecodeInstructionOriginal(instr); }
+ SetS390RoundConditionCode(r2_fval, INT64_MAX, INT64_MIN);
-EVALUATE(CFDR) { return DecodeInstructionOriginal(instr); }
+ switch (mask_val) {
+ case CURRENT_ROUNDING_MODE:
+ case ROUND_TO_NEAREST_WITH_TIES_AWAY_FROM_0:
+ case ROUND_TO_PREPARE_FOR_SHORTER_PRECISION: {
+ UNIMPLEMENTED();
+ break;
+ }
+ case ROUND_TO_NEAREST_WITH_TIES_TO_EVEN: {
+ float ceil_val = std::ceil(r2_fval);
+ float floor_val = std::floor(r2_fval);
+ if (std::abs(r2_fval - floor_val) > std::abs(r2_fval - ceil_val)) {
+ r1_val = static_cast<int64_t>(ceil_val);
+ } else if (std::abs(r2_fval - floor_val) < std::abs(r2_fval - ceil_val)) {
+ r1_val = static_cast<int64_t>(floor_val);
+ } else { // check which one is even:
+ int64_t c_v = static_cast<int64_t>(ceil_val);
+ int64_t f_v = static_cast<int64_t>(floor_val);
+ if (f_v % 2 == 0)
+ r1_val = f_v;
+ else
+ r1_val = c_v;
+ }
+ break;
+ }
+ case ROUND_TOWARD_0: {
+ r1_val = static_cast<int64_t>(r2_fval);
+ break;
+ }
+ case ROUND_TOWARD_PLUS_INFINITE: {
+ r1_val = static_cast<int64_t>(std::ceil(r2_fval));
+ break;
+ }
+ case ROUND_TOWARD_MINUS_INFINITE: {
+ r1_val = static_cast<int64_t>(std::floor(r2_fval));
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+ set_register(r1, r1_val);
+ return length;
+}
-EVALUATE(CFXR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CGDBRA) {
+ DCHECK_OPCODE(CGDBRA);
+ DECODE_RRE_INSTRUCTION_M3(r1, r2, mask_val);
+ double r2_val = get_double_from_d_register(r2);
+ int64_t r1_val = 0;
-EVALUATE(LDGR) { return DecodeInstructionOriginal(instr); }
+ SetS390RoundConditionCode(r2_val, INT64_MAX, INT64_MIN);
-EVALUATE(CGER) { return DecodeInstructionOriginal(instr); }
+ switch (mask_val) {
+ case CURRENT_ROUNDING_MODE:
+ case ROUND_TO_NEAREST_WITH_TIES_AWAY_FROM_0:
+ case ROUND_TO_PREPARE_FOR_SHORTER_PRECISION: {
+ UNIMPLEMENTED();
+ break;
+ }
+ case ROUND_TO_NEAREST_WITH_TIES_TO_EVEN: {
+ double ceil_val = std::ceil(r2_val);
+ double floor_val = std::floor(r2_val);
+ if (std::abs(r2_val - floor_val) > std::abs(r2_val - ceil_val)) {
+ r1_val = static_cast<int64_t>(ceil_val);
+ } else if (std::abs(r2_val - floor_val) < std::abs(r2_val - ceil_val)) {
+ r1_val = static_cast<int64_t>(floor_val);
+ } else { // check which one is even:
+ int64_t c_v = static_cast<int64_t>(ceil_val);
+ int64_t f_v = static_cast<int64_t>(floor_val);
+ if (f_v % 2 == 0)
+ r1_val = f_v;
+ else
+ r1_val = c_v;
+ }
+ break;
+ }
+ case ROUND_TOWARD_0: {
+ r1_val = static_cast<int64_t>(r2_val);
+ break;
+ }
+ case ROUND_TOWARD_PLUS_INFINITE: {
+ r1_val = static_cast<int64_t>(std::ceil(r2_val));
+ break;
+ }
+ case ROUND_TOWARD_MINUS_INFINITE: {
+ r1_val = static_cast<int64_t>(std::floor(r2_val));
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+ set_register(r1, r1_val);
+ return length;
+}
-EVALUATE(CGDR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CGXBRA) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CGXR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CLGEBR) {
+ DCHECK_OPCODE(CLGEBR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ float r2_val = get_float32_from_d_register(r2);
+ uint64_t r1_val = static_cast<uint64_t>(r2_val);
+ set_register(r1, r1_val);
+ SetS390ConvertConditionCode<double>(r2_val, r1_val, UINT64_MAX);
+ return length;
+}
-EVALUATE(LGDR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CLGDBR) {
+ DCHECK_OPCODE(CLGDBR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ double r2_val = get_double_from_d_register(r2);
+ uint64_t r1_val = static_cast<uint64_t>(r2_val);
+ set_register(r1, r1_val);
+ SetS390ConvertConditionCode<double>(r2_val, r1_val, UINT64_MAX);
+ return length;
+}
-EVALUATE(MDTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CFER) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(MDTRA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CFDR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(DDTRA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CFXR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(ADTRA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LDGR) {
+ DCHECK_OPCODE(LDGR);
+ // Load FPR from GPR (L <- 64)
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ uint64_t int_val = get_register(r2);
+ // double double_val = bit_cast<double, uint64_t>(int_val);
+ // set_d_register_from_double(rreInst->R1Value(), double_val);
+ set_d_register(r1, int_val);
+ return length;
+}
-EVALUATE(SDTRA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CGER) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LDETR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CGDR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LEDTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CGXR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LTDTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LGDR) {
+ DCHECK_OPCODE(LGDR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ // Load GPR from FPR (64 <- L)
+ int64_t double_val = get_d_register(r2);
+ set_register(r1, double_val);
+ return length;
+}
-EVALUATE(FIDTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MDTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(MXTRA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MDTRA) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(DXTRA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(DDTRA) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(AXTRA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ADTRA) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SXTRA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SDTRA) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LXDTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LDETR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LDXTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LEDTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LTXTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LTDTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(FIXTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(FIDTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(KDTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MXTRA) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CGDTRA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(DXTRA) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CUDTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(AXTRA) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CDTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SXTRA) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(EEDTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LXDTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(ESDTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LDXTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(KXTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LTXTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CGXTRA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(FIXTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CUXTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(KDTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CSXTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CGDTRA) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CXTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CUDTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(EEXTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CDTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(ESXTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(EEDTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CDGTRA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ESDTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CDUTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(KXTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CDSTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CGXTRA) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CEDTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CUXTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(QADTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CSXTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(IEDTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CXTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(RRDTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(EEXTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CXGTRA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ESXTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CXUTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CDGTRA) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CXSTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CDUTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CEXTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CDSTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(QAXTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CEDTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(IEXTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(QADTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(RRXTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(IEDTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LPGR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(RRDTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LNGR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CXGTRA) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LTGR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CXUTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LCGR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CXSTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SGR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CEXTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(ALGR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(QAXTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SLGR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(IEXTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(MSGR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(RRXTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(DSGR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LPGR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LRVGR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LNGR) {
+ DCHECK_OPCODE(LNGR);
+ // Load Negative (64)
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ int64_t r2_val = get_register(r2);
+ r2_val = (r2_val >= 0) ? -r2_val : r2_val; // If pos, then negate it.
+ set_register(r1, r2_val);
+ condition_reg_ = (r2_val == 0) ? CC_EQ : CC_LT; // CC0 - result is zero
+ // CC1 - result is negative
+ return length;
+}
-EVALUATE(LPGFR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LTGR) {
+ DCHECK_OPCODE(LTGR);
+ // Load Register (64)
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ int64_t r2_val = get_register(r2);
+ SetS390ConditionCode<int64_t>(r2_val, 0);
+ set_register(r1, get_register(r2));
+ return length;
+}
-EVALUATE(LNGFR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LCGR) {
+ DCHECK_OPCODE(LCGR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ int64_t r2_val = get_register(r2);
+ r2_val = ~r2_val;
+ r2_val = r2_val + 1;
+ set_register(r1, r2_val);
+ SetS390ConditionCode<int64_t>(r2_val, 0);
+ // if the input is INT_MIN, loading its compliment would be overflowing
+ if (r2_val < 0 && (r2_val + 1) > 0) {
+ SetS390OverflowCode(true);
+ }
+ return length;
+}
-EVALUATE(LTGFR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SGR) {
+ DCHECK_OPCODE(SGR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ int64_t r1_val = get_register(r1);
+ int64_t r2_val = get_register(r2);
+ bool isOF = false;
+ isOF = CheckOverflowForIntSub(r1_val, r2_val, int64_t);
+ r1_val -= r2_val;
+ SetS390ConditionCode<int64_t>(r1_val, 0);
+ SetS390OverflowCode(isOF);
+ set_register(r1, r1_val);
+ return length;
+}
-EVALUATE(LCGFR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ALGR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LLGFR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SLGR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LLGTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MSGR) {
+ DCHECK_OPCODE(MSGR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ int64_t r1_val = get_register(r1);
+ int64_t r2_val = get_register(r2);
+ set_register(r1, r1_val * r2_val);
+ return length;
+}
-EVALUATE(AGFR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(DSGR) {
+ DCHECK_OPCODE(DSGR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
-EVALUATE(SGFR) { return DecodeInstructionOriginal(instr); }
+ DCHECK(r1 % 2 == 0);
-EVALUATE(ALGFR) { return DecodeInstructionOriginal(instr); }
+ int64_t dividend = get_register(r1 + 1);
+ int64_t divisor = get_register(r2);
+ set_register(r1, dividend % divisor);
+ set_register(r1 + 1, dividend / divisor);
+ return length;
+}
-EVALUATE(SLGFR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LRVGR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(MSGFR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LPGFR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(DSGFR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LNGFR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(KMAC) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LTGFR) {
+ DCHECK_OPCODE(LTGFR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ // Load and Test Register (64 <- 32) (Sign Extends 32-bit val)
+ // Load Register (64 <- 32) (Sign Extends 32-bit val)
+ int32_t r2_val = get_low_register<int32_t>(r2);
+ int64_t result = static_cast<int64_t>(r2_val);
+ set_register(r1, result);
+ SetS390ConditionCode<int64_t>(result, 0);
+ return length;
+}
-EVALUATE(LRVR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LCGFR) {
+ DCHECK_OPCODE(LCGFR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ // Load and Test Register (64 <- 32) (Sign Extends 32-bit val)
+ // Load Register (64 <- 32) (Sign Extends 32-bit val)
+ int32_t r2_val = get_low_register<int32_t>(r2);
+ int64_t result = static_cast<int64_t>(r2_val);
+ set_register(r1, result);
+ return length;
+}
-EVALUATE(CGR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LLGFR) {
+ DCHECK_OPCODE(LLGFR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ int32_t r2_val = get_low_register<int32_t>(r2);
+ uint64_t r2_finalval = (static_cast<uint64_t>(r2_val) & 0x00000000ffffffff);
+ set_register(r1, r2_finalval);
+ return length;
+}
-EVALUATE(CLGR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LLGTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(KMF) { return DecodeInstructionOriginal(instr); }
+EVALUATE(AGFR) {
+ DCHECK_OPCODE(AGFR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ // Add Register (64 <- 32) (Sign Extends 32-bit val)
+ int64_t r1_val = get_register(r1);
+ int64_t r2_val = static_cast<int64_t>(get_low_register<int32_t>(r2));
+ bool isOF = CheckOverflowForIntAdd(r1_val, r2_val, int64_t);
+ r1_val += r2_val;
+ SetS390ConditionCode<int64_t>(r1_val, 0);
+ SetS390OverflowCode(isOF);
+ set_register(r1, r1_val);
+ return length;
+}
-EVALUATE(KMO) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SGFR) {
+ DCHECK_OPCODE(SGFR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ // Sub Reg (64 <- 32)
+ int64_t r1_val = get_register(r1);
+ int64_t r2_val = static_cast<int64_t>(get_low_register<int32_t>(r2));
+ bool isOF = false;
+ isOF = CheckOverflowForIntSub(r1_val, r2_val, int64_t);
+ r1_val -= r2_val;
+ SetS390ConditionCode<int64_t>(r1_val, 0);
+ SetS390OverflowCode(isOF);
+ set_register(r1, r1_val);
+ return length;
+}
-EVALUATE(PCC) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ALGFR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(KMCTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SLGFR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(KM) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MSGFR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(KMC) { return DecodeInstructionOriginal(instr); }
+EVALUATE(DSGFR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CGFR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(KMAC) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(KIMD) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LRVR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(KLMD) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CGR) {
+ DCHECK_OPCODE(CGR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ // Compare (64)
+ int64_t r1_val = get_register(r1);
+ int64_t r2_val = get_register(r2);
+ SetS390ConditionCode<int64_t>(r1_val, r2_val);
+ return length;
+}
-EVALUATE(CFDTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CLGR) {
+ DCHECK_OPCODE(CLGR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ // Compare Logical (64)
+ uint64_t r1_val = static_cast<uint64_t>(get_register(r1));
+ uint64_t r2_val = static_cast<uint64_t>(get_register(r2));
+ SetS390ConditionCode<uint64_t>(r1_val, r2_val);
+ return length;
+}
-EVALUATE(CLGDTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(KMF) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CLFDTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(KMO) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(BCTGR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(PCC) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CFXTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(KMCTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CLFXTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(KM) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CDFTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(KMC) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CDLGTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CGFR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CDLFTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(KIMD) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CXFTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(KLMD) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CXLGTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CFDTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CXLFTR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CLGDTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CGRT) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CLFDTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(NGR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(BCTGR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(OGR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CFXTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(XGR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CLFXTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(FLOGR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CDFTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LLGCR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CDLGTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LLGHR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CDLFTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(MLGR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CXFTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(DLGR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CXLGTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(ALCGR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CXLFTR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SLBGR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CGRT) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(EPSW) { return DecodeInstructionOriginal(instr); }
+EVALUATE(NGR) {
+ DCHECK_OPCODE(NGR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ int64_t r1_val = get_register(r1);
+ int64_t r2_val = get_register(r2);
+ r1_val &= r2_val;
+ SetS390BitWiseConditionCode<uint64_t>(r1_val);
+ set_register(r1, r1_val);
+ return length;
+}
-EVALUATE(TRTT) { return DecodeInstructionOriginal(instr); }
+EVALUATE(OGR) {
+ DCHECK_OPCODE(OGR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ int64_t r1_val = get_register(r1);
+ int64_t r2_val = get_register(r2);
+ r1_val |= r2_val;
+ SetS390BitWiseConditionCode<uint64_t>(r1_val);
+ set_register(r1, r1_val);
+ return length;
+}
-EVALUATE(TRTO) { return DecodeInstructionOriginal(instr); }
+EVALUATE(XGR) {
+ DCHECK_OPCODE(XGR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ int64_t r1_val = get_register(r1);
+ int64_t r2_val = get_register(r2);
+ r1_val ^= r2_val;
+ SetS390BitWiseConditionCode<uint64_t>(r1_val);
+ set_register(r1, r1_val);
+ return length;
+}
-EVALUATE(TROT) { return DecodeInstructionOriginal(instr); }
+EVALUATE(FLOGR) {
+ DCHECK_OPCODE(FLOGR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
-EVALUATE(TROO) { return DecodeInstructionOriginal(instr); }
+ DCHECK(r1 % 2 == 0);
-EVALUATE(LLCR) { return DecodeInstructionOriginal(instr); }
+ int64_t r2_val = get_register(r2);
-EVALUATE(LLHR) { return DecodeInstructionOriginal(instr); }
+ int i = 0;
+ for (; i < 64; i++) {
+ if (r2_val < 0) break;
+ r2_val <<= 1;
+ }
-EVALUATE(MLR) { return DecodeInstructionOriginal(instr); }
+ r2_val = get_register(r2);
-EVALUATE(DLR) { return DecodeInstructionOriginal(instr); }
+ int64_t mask = ~(1 << (63 - i));
+ set_register(r1, i);
+ set_register(r1 + 1, r2_val & mask);
+ return length;
+}
-EVALUATE(ALCR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LLGCR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SLBR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LLGHR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CU14) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MLGR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CU24) { return DecodeInstructionOriginal(instr); }
+EVALUATE(DLGR) {
+ DCHECK_OPCODE(DLGR);
+#ifdef V8_TARGET_ARCH_S390X
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ uint64_t r1_val = get_register(r1);
+ uint64_t r2_val = get_register(r2);
+ DCHECK(r1 % 2 == 0);
+ unsigned __int128 dividend = static_cast<unsigned __int128>(r1_val) << 64;
+ dividend += get_register(r1 + 1);
+ uint64_t remainder = dividend % r2_val;
+ uint64_t quotient = dividend / r2_val;
+ r1_val = remainder;
+ set_register(r1, remainder);
+ set_register(r1 + 1, quotient);
+ return length;
+#else
+ UNREACHABLE();
+#endif
+}
-EVALUATE(CU41) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ALCGR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CU42) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SLBGR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(TRTRE) { return DecodeInstructionOriginal(instr); }
+EVALUATE(EPSW) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SRSTU) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TRTT) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(TRTE) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TRTO) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(AHHHR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TROT) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SHHHR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TROO) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(ALHHHR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LLCR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SLHHHR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LLHR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CHHR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MLR) {
+ DCHECK_OPCODE(MLR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ DCHECK(r1 % 2 == 0);
+
+ uint32_t r1_val = get_low_register<uint32_t>(r1 + 1);
+ uint32_t r2_val = get_low_register<uint32_t>(r2);
+ uint64_t product =
+ static_cast<uint64_t>(r1_val) * static_cast<uint64_t>(r2_val);
+ int32_t high_bits = product >> 32;
+ int32_t low_bits = product & 0x00000000FFFFFFFF;
+ set_low_register(r1, high_bits);
+ set_low_register(r1 + 1, low_bits);
+ return length;
+}
+
+EVALUATE(DLR) {
+ DCHECK_OPCODE(DLR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ uint32_t r1_val = get_low_register<uint32_t>(r1);
+ uint32_t r2_val = get_low_register<uint32_t>(r2);
+ DCHECK(r1 % 2 == 0);
+ uint64_t dividend = static_cast<uint64_t>(r1_val) << 32;
+ dividend += get_low_register<uint32_t>(r1 + 1);
+ uint32_t remainder = dividend % r2_val;
+ uint32_t quotient = dividend / r2_val;
+ r1_val = remainder;
+ set_low_register(r1, remainder);
+ set_low_register(r1 + 1, quotient);
+ return length;
+}
+
+EVALUATE(ALCR) {
+ DCHECK_OPCODE(ALCR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ uint32_t r1_val = get_low_register<uint32_t>(r1);
+ uint32_t r2_val = get_low_register<uint32_t>(r2);
+ uint32_t alu_out = 0;
+ bool isOF = false;
+
+ alu_out = r1_val + r2_val;
+ bool isOF_original = CheckOverflowForUIntAdd(r1_val, r2_val);
+ if (TestConditionCode((Condition)2) || TestConditionCode((Condition)3)) {
+ alu_out = alu_out + 1;
+ isOF = isOF_original || CheckOverflowForUIntAdd(alu_out, 1);
+ } else {
+ isOF = isOF_original;
+ }
+ set_low_register(r1, alu_out);
+ SetS390ConditionCodeCarry<uint32_t>(alu_out, isOF);
+ return length;
+}
+
+EVALUATE(SLBR) {
+ DCHECK_OPCODE(SLBR);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ uint32_t r1_val = get_low_register<uint32_t>(r1);
+ uint32_t r2_val = get_low_register<uint32_t>(r2);
+ uint32_t alu_out = 0;
+ bool isOF = false;
+
+ alu_out = r1_val - r2_val;
+ bool isOF_original = CheckOverflowForUIntSub(r1_val, r2_val);
+ if (TestConditionCode((Condition)2) || TestConditionCode((Condition)3)) {
+ alu_out = alu_out - 1;
+ isOF = isOF_original || CheckOverflowForUIntSub(alu_out, 1);
+ } else {
+ isOF = isOF_original;
+ }
+ set_low_register(r1, alu_out);
+ SetS390ConditionCodeCarry<uint32_t>(alu_out, isOF);
+ return length;
+}
+
+EVALUATE(CU14) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
+
+EVALUATE(CU24) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
+
+EVALUATE(CU41) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
+
+EVALUATE(CU42) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
+
+EVALUATE(TRTRE) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
+
+EVALUATE(SRSTU) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
+
+EVALUATE(TRTE) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
+
+EVALUATE(AHHHR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
+
+EVALUATE(SHHHR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
+
+EVALUATE(ALHHHR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
+
+EVALUATE(SLHHHR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
+
+EVALUATE(CHHR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
+
+EVALUATE(AHHLR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
+
+EVALUATE(SHHLR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
+
+EVALUATE(ALHHLR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
+
+EVALUATE(SLHHLR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
+
+EVALUATE(CHLR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
+
+EVALUATE(POPCNT_Z) {
+ DCHECK_OPCODE(POPCNT_Z);
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ int64_t r2_val = get_register(r2);
+ int64_t r1_val = 0;
+
+ uint8_t* r2_val_ptr = reinterpret_cast<uint8_t*>(&r2_val);
+ uint8_t* r1_val_ptr = reinterpret_cast<uint8_t*>(&r1_val);
+ for (int i = 0; i < 8; i++) {
+ uint32_t x = static_cast<uint32_t>(r2_val_ptr[i]);
+#if defined(__GNUC__)
+ r1_val_ptr[i] = __builtin_popcount(x);
+#else
+#error unsupport __builtin_popcount
+#endif
+ }
+ set_register(r1, static_cast<uint64_t>(r1_val));
+ return length;
+}
+
+EVALUATE(LOCGR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
+
+EVALUATE(NGRK) {
+ DCHECK_OPCODE(NGRK);
+ DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
+ // 64-bit Non-clobbering arithmetics / bitwise ops.
+ int64_t r2_val = get_register(r2);
+ int64_t r3_val = get_register(r3);
+ uint64_t bitwise_result = 0;
+ bitwise_result = r2_val & r3_val;
+ SetS390BitWiseConditionCode<uint64_t>(bitwise_result);
+ set_register(r1, bitwise_result);
+ return length;
+}
+
+EVALUATE(OGRK) {
+ DCHECK_OPCODE(OGRK);
+ DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
+ // 64-bit Non-clobbering arithmetics / bitwise ops.
+ int64_t r2_val = get_register(r2);
+ int64_t r3_val = get_register(r3);
+ uint64_t bitwise_result = 0;
+ bitwise_result = r2_val | r3_val;
+ SetS390BitWiseConditionCode<uint64_t>(bitwise_result);
+ set_register(r1, bitwise_result);
+ return length;
+}
+
+EVALUATE(XGRK) {
+ DCHECK_OPCODE(XGRK);
+ DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
+ // 64-bit Non-clobbering arithmetics / bitwise ops.
+ int64_t r2_val = get_register(r2);
+ int64_t r3_val = get_register(r3);
+ uint64_t bitwise_result = 0;
+ bitwise_result = r2_val ^ r3_val;
+ SetS390BitWiseConditionCode<uint64_t>(bitwise_result);
+ set_register(r1, bitwise_result);
+ return length;
+}
+
+EVALUATE(AGRK) {
+ DCHECK_OPCODE(AGRK);
+ DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
+ // 64-bit Non-clobbering arithmetics / bitwise ops.
+ int64_t r2_val = get_register(r2);
+ int64_t r3_val = get_register(r3);
+ bool isOF = CheckOverflowForIntAdd(r2_val, r3_val, int64_t);
+ SetS390ConditionCode<int64_t>(r2_val + r3_val, 0);
+ SetS390OverflowCode(isOF);
+ set_register(r1, r2_val + r3_val);
+ return length;
+}
+
+EVALUATE(SGRK) {
+ DCHECK_OPCODE(SGRK);
+ DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
+ // 64-bit Non-clobbering arithmetics / bitwise ops.
+ int64_t r2_val = get_register(r2);
+ int64_t r3_val = get_register(r3);
+ bool isOF = CheckOverflowForIntSub(r2_val, r3_val, int64_t);
+ SetS390ConditionCode<int64_t>(r2_val - r3_val, 0);
+ SetS390OverflowCode(isOF);
+ set_register(r1, r2_val - r3_val);
+ return length;
+}
+
+EVALUATE(ALGRK) {
+ DCHECK_OPCODE(ALGRK);
+ DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
+ // 64-bit Non-clobbering unsigned arithmetics
+ uint64_t r2_val = get_register(r2);
+ uint64_t r3_val = get_register(r3);
+ bool isOF = CheckOverflowForUIntAdd(r2_val, r3_val);
+ SetS390ConditionCode<uint64_t>(r2_val + r3_val, 0);
+ SetS390OverflowCode(isOF);
+ set_register(r1, r2_val + r3_val);
+ return length;
+}
+
+EVALUATE(SLGRK) {
+ DCHECK_OPCODE(SLGRK);
+ DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
+ // 64-bit Non-clobbering unsigned arithmetics
+ uint64_t r2_val = get_register(r2);
+ uint64_t r3_val = get_register(r3);
+ bool isOF = CheckOverflowForUIntSub(r2_val, r3_val);
+ SetS390ConditionCode<uint64_t>(r2_val - r3_val, 0);
+ SetS390OverflowCode(isOF);
+ set_register(r1, r2_val - r3_val);
+ return length;
+}
+
+EVALUATE(LOCR) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
+
+EVALUATE(NRK) {
+ DCHECK_OPCODE(NRK);
+ DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
+ // 32-bit Non-clobbering arithmetics / bitwise ops
+ int32_t r2_val = get_low_register<int32_t>(r2);
+ int32_t r3_val = get_low_register<int32_t>(r3);
+ // Assume bitwise operation here
+ uint32_t bitwise_result = 0;
+ bitwise_result = r2_val & r3_val;
+ SetS390BitWiseConditionCode<uint32_t>(bitwise_result);
+ set_low_register(r1, bitwise_result);
+ return length;
+}
+
+EVALUATE(ORK) {
+ DCHECK_OPCODE(ORK);
+ DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
+ // 32-bit Non-clobbering arithmetics / bitwise ops
+ int32_t r2_val = get_low_register<int32_t>(r2);
+ int32_t r3_val = get_low_register<int32_t>(r3);
+ // Assume bitwise operation here
+ uint32_t bitwise_result = 0;
+ bitwise_result = r2_val | r3_val;
+ SetS390BitWiseConditionCode<uint32_t>(bitwise_result);
+ set_low_register(r1, bitwise_result);
+ return length;
+}
+
+EVALUATE(XRK) {
+ DCHECK_OPCODE(XRK);
+ DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
+ // 32-bit Non-clobbering arithmetics / bitwise ops
+ int32_t r2_val = get_low_register<int32_t>(r2);
+ int32_t r3_val = get_low_register<int32_t>(r3);
+ // Assume bitwise operation here
+ uint32_t bitwise_result = 0;
+ bitwise_result = r2_val ^ r3_val;
+ SetS390BitWiseConditionCode<uint32_t>(bitwise_result);
+ set_low_register(r1, bitwise_result);
+ return length;
+}
-EVALUATE(AHHLR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ARK) {
+ DCHECK_OPCODE(ARK);
+ DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
+ // 32-bit Non-clobbering arithmetics / bitwise ops
+ int32_t r2_val = get_low_register<int32_t>(r2);
+ int32_t r3_val = get_low_register<int32_t>(r3);
+ bool isOF = CheckOverflowForIntAdd(r2_val, r3_val, int32_t);
+ SetS390ConditionCode<int32_t>(r2_val + r3_val, 0);
+ SetS390OverflowCode(isOF);
+ set_low_register(r1, r2_val + r3_val);
+ return length;
+}
-EVALUATE(SHHLR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SRK) {
+ DCHECK_OPCODE(SRK);
+ DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
+ // 32-bit Non-clobbering arithmetics / bitwise ops
+ int32_t r2_val = get_low_register<int32_t>(r2);
+ int32_t r3_val = get_low_register<int32_t>(r3);
+ bool isOF = CheckOverflowForIntSub(r2_val, r3_val, int32_t);
+ SetS390ConditionCode<int32_t>(r2_val - r3_val, 0);
+ SetS390OverflowCode(isOF);
+ set_low_register(r1, r2_val - r3_val);
+ return length;
+}
-EVALUATE(ALHHLR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ALRK) {
+ DCHECK_OPCODE(ALRK);
+ DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
+ // 32-bit Non-clobbering unsigned arithmetics
+ uint32_t r2_val = get_low_register<uint32_t>(r2);
+ uint32_t r3_val = get_low_register<uint32_t>(r3);
+ bool isOF = CheckOverflowForUIntAdd(r2_val, r3_val);
+ SetS390ConditionCode<uint32_t>(r2_val + r3_val, 0);
+ SetS390OverflowCode(isOF);
+ set_low_register(r1, r2_val + r3_val);
+ return length;
+}
-EVALUATE(SLHHLR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SLRK) {
+ DCHECK_OPCODE(SLRK);
+ DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
+ // 32-bit Non-clobbering unsigned arithmetics
+ uint32_t r2_val = get_low_register<uint32_t>(r2);
+ uint32_t r3_val = get_low_register<uint32_t>(r3);
+ bool isOF = CheckOverflowForUIntSub(r2_val, r3_val);
+ SetS390ConditionCode<uint32_t>(r2_val - r3_val, 0);
+ SetS390OverflowCode(isOF);
+ set_low_register(r1, r2_val - r3_val);
+ return length;
+}
-EVALUATE(CHLR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LTG) {
+ DCHECK_OPCODE(LTG);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ intptr_t addr = x2_val + b2_val + d2;
+ int64_t value = ReadDW(addr);
+ set_register(r1, value);
+ SetS390ConditionCode<int64_t>(value, 0);
+ return length;
+}
-EVALUATE(POPCNT_Z) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CVBY) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LOCGR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(AG) {
+ DCHECK_OPCODE(AG);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int64_t alu_out = get_register(r1);
+ int64_t mem_val = ReadDW(b2_val + x2_val + d2);
+ alu_out += mem_val;
+ SetS390ConditionCode<int32_t>(alu_out, 0);
+ set_register(r1, alu_out);
+ return length;
+}
-EVALUATE(NGRK) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SG) {
+ DCHECK_OPCODE(SG);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int64_t alu_out = get_register(r1);
+ int64_t mem_val = ReadDW(b2_val + x2_val + d2);
+ alu_out -= mem_val;
+ SetS390ConditionCode<int32_t>(alu_out, 0);
+ set_register(r1, alu_out);
+ return length;
+}
-EVALUATE(OGRK) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ALG) {
+ DCHECK_OPCODE(ALG);
+#ifndef V8_TARGET_ARCH_S390X
+ DCHECK(false);
+#endif
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ uint64_t r1_val = get_register(r1);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ intptr_t d2_val = d2;
+ uint64_t alu_out = r1_val;
+ uint64_t mem_val = static_cast<uint64_t>(ReadDW(b2_val + d2_val + x2_val));
+ alu_out += mem_val;
+ SetS390ConditionCode<uint64_t>(alu_out, 0);
+ set_register(r1, alu_out);
+ return length;
+}
-EVALUATE(XGRK) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SLG) {
+ DCHECK_OPCODE(SLG);
+#ifndef V8_TARGET_ARCH_S390X
+ DCHECK(false);
+#endif
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ uint64_t r1_val = get_register(r1);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ intptr_t d2_val = d2;
+ uint64_t alu_out = r1_val;
+ uint64_t mem_val = static_cast<uint64_t>(ReadDW(b2_val + d2_val + x2_val));
+ alu_out -= mem_val;
+ SetS390ConditionCode<uint64_t>(alu_out, 0);
+ set_register(r1, alu_out);
+ return length;
+}
-EVALUATE(AGRK) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MSG) {
+ DCHECK_OPCODE(MSG);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ intptr_t d2_val = d2;
+ int64_t mem_val = ReadDW(b2_val + d2_val + x2_val);
+ int64_t r1_val = get_register(r1);
+ set_register(r1, mem_val * r1_val);
+ return length;
+}
-EVALUATE(SGRK) { return DecodeInstructionOriginal(instr); }
+EVALUATE(DSG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(ALGRK) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CVBG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SLGRK) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LRVG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LOCR) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LT) {
+ DCHECK_OPCODE(LT);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ intptr_t addr = x2_val + b2_val + d2;
+ int32_t value = ReadW(addr, instr);
+ set_low_register(r1, value);
+ SetS390ConditionCode<int32_t>(value, 0);
+ return length;
+}
-EVALUATE(NRK) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LGH) {
+ DCHECK_OPCODE(LGH);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ // Miscellaneous Loads and Stores
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ intptr_t addr = x2_val + b2_val + d2;
+ int64_t mem_val = static_cast<int64_t>(ReadH(addr, instr));
+ set_register(r1, mem_val);
+ return length;
+}
-EVALUATE(ORK) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LLGF) {
+ DCHECK_OPCODE(LLGF);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ // Miscellaneous Loads and Stores
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ intptr_t addr = x2_val + b2_val + d2;
+ uint64_t mem_val = static_cast<uint64_t>(ReadWU(addr, instr));
+ set_register(r1, mem_val);
+ return length;
+}
-EVALUATE(XRK) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LLGT) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(ARK) { return DecodeInstructionOriginal(instr); }
+EVALUATE(AGF) {
+ DCHECK_OPCODE(AGF);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ uint64_t r1_val = get_register(r1);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ intptr_t d2_val = d2;
+ uint64_t alu_out = r1_val;
+ uint32_t mem_val = ReadW(b2_val + d2_val + x2_val, instr);
+ alu_out += mem_val;
+ SetS390ConditionCode<int64_t>(alu_out, 0);
+ set_register(r1, alu_out);
+ return length;
+}
-EVALUATE(SRK) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SGF) {
+ DCHECK_OPCODE(SGF);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ uint64_t r1_val = get_register(r1);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ intptr_t d2_val = d2;
+ uint64_t alu_out = r1_val;
+ uint32_t mem_val = ReadW(b2_val + d2_val + x2_val, instr);
+ alu_out -= mem_val;
+ SetS390ConditionCode<int64_t>(alu_out, 0);
+ set_register(r1, alu_out);
+ return length;
+}
-EVALUATE(ALRK) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ALGF) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SLRK) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SLGF) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LTG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MSGF) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CVBY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(DSGF) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(AG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LRV) {
+ DCHECK_OPCODE(LRV);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ intptr_t mem_addr = b2_val + x2_val + d2;
+ int32_t mem_val = ReadW(mem_addr, instr);
+ set_low_register(r1, ByteReverse(mem_val));
+ return length;
+}
-EVALUATE(SG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LRVH) {
+ DCHECK_OPCODE(LRVH);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ int32_t r1_val = get_low_register<int32_t>(r1);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ intptr_t mem_addr = b2_val + x2_val + d2;
+ int16_t mem_val = ReadH(mem_addr, instr);
+ int32_t result = ByteReverse(mem_val) & 0x0000ffff;
+ result |= r1_val & 0xffff0000;
+ set_low_register(r1, result);
+ return length;
+}
-EVALUATE(ALG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CG) {
+ DCHECK_OPCODE(CG);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int64_t alu_out = get_register(r1);
+ int64_t mem_val = ReadDW(b2_val + x2_val + d2);
+ SetS390ConditionCode<int64_t>(alu_out, mem_val);
+ set_register(r1, alu_out);
+ return length;
+}
-EVALUATE(SLG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CLG) {
+ DCHECK_OPCODE(CLG);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int64_t alu_out = get_register(r1);
+ int64_t mem_val = ReadDW(b2_val + x2_val + d2);
+ SetS390ConditionCode<uint64_t>(alu_out, mem_val);
+ set_register(r1, alu_out);
+ return length;
+}
-EVALUATE(MSG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(NTSTG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(DSG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CVDY) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CVBG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CVDG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LRVG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(STRVG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LT) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CGF) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LGH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CLGF) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LLGF) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LTGF) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LLGT) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CGH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(AGF) { return DecodeInstructionOriginal(instr); }
+EVALUATE(PFD) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SGF) { return DecodeInstructionOriginal(instr); }
+EVALUATE(STRV) {
+ DCHECK_OPCODE(STRV);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ int32_t r1_val = get_low_register<int32_t>(r1);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ intptr_t mem_addr = b2_val + x2_val + d2;
+ WriteW(mem_addr, ByteReverse(r1_val), instr);
+ return length;
+}
-EVALUATE(ALGF) { return DecodeInstructionOriginal(instr); }
+EVALUATE(STRVH) {
+ DCHECK_OPCODE(STRVH);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ int32_t r1_val = get_low_register<int32_t>(r1);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ intptr_t mem_addr = b2_val + x2_val + d2;
+ int16_t result = static_cast<int16_t>(r1_val >> 16);
+ WriteH(mem_addr, ByteReverse(result), instr);
+ return length;
+}
-EVALUATE(SLGF) { return DecodeInstructionOriginal(instr); }
+EVALUATE(BCTG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(MSGF) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MSY) {
+ DCHECK_OPCODE(MSY);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ intptr_t d2_val = d2;
+ int32_t mem_val = ReadW(b2_val + d2_val + x2_val, instr);
+ int32_t r1_val = get_low_register<int32_t>(r1);
+ set_low_register(r1, mem_val * r1_val);
+ return length;
+}
-EVALUATE(DSGF) { return DecodeInstructionOriginal(instr); }
+EVALUATE(NY) {
+ DCHECK_OPCODE(NY);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int32_t alu_out = get_low_register<int32_t>(r1);
+ int32_t mem_val = ReadW(b2_val + x2_val + d2, instr);
+ alu_out &= mem_val;
+ SetS390BitWiseConditionCode<uint32_t>(alu_out);
+ set_low_register(r1, alu_out);
+ return length;
+}
-EVALUATE(LRV) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CLY) {
+ DCHECK_OPCODE(CLY);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ uint32_t alu_out = get_low_register<uint32_t>(r1);
+ uint32_t mem_val = ReadWU(b2_val + x2_val + d2, instr);
+ SetS390ConditionCode<uint32_t>(alu_out, mem_val);
+ return length;
+}
-EVALUATE(LRVH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(OY) {
+ DCHECK_OPCODE(OY);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int32_t alu_out = get_low_register<int32_t>(r1);
+ int32_t mem_val = ReadW(b2_val + x2_val + d2, instr);
+ alu_out |= mem_val;
+ SetS390BitWiseConditionCode<uint32_t>(alu_out);
+ set_low_register(r1, alu_out);
+ return length;
+}
-EVALUATE(CG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(XY) {
+ DCHECK_OPCODE(XY);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int32_t alu_out = get_low_register<int32_t>(r1);
+ int32_t mem_val = ReadW(b2_val + x2_val + d2, instr);
+ alu_out ^= mem_val;
+ SetS390BitWiseConditionCode<uint32_t>(alu_out);
+ set_low_register(r1, alu_out);
+ return length;
+}
-EVALUATE(CLG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CY) {
+ DCHECK_OPCODE(CY);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int32_t alu_out = get_low_register<int32_t>(r1);
+ int32_t mem_val = ReadW(b2_val + x2_val + d2, instr);
+ SetS390ConditionCode<int32_t>(alu_out, mem_val);
+ return length;
+}
-EVALUATE(NTSTG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(AY) {
+ DCHECK_OPCODE(AY);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int32_t alu_out = get_low_register<int32_t>(r1);
+ int32_t mem_val = ReadW(b2_val + x2_val + d2, instr);
+ bool isOF = false;
+ isOF = CheckOverflowForIntAdd(alu_out, mem_val, int32_t);
+ alu_out += mem_val;
+ SetS390ConditionCode<int32_t>(alu_out, 0);
+ SetS390OverflowCode(isOF);
+ set_low_register(r1, alu_out);
+ return length;
+}
-EVALUATE(CVDY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SY) {
+ DCHECK_OPCODE(SY);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int32_t alu_out = get_low_register<int32_t>(r1);
+ int32_t mem_val = ReadW(b2_val + x2_val + d2, instr);
+ bool isOF = false;
+ isOF = CheckOverflowForIntSub(alu_out, mem_val, int32_t);
+ alu_out -= mem_val;
+ SetS390ConditionCode<int32_t>(alu_out, 0);
+ SetS390OverflowCode(isOF);
+ set_low_register(r1, alu_out);
+ return length;
+}
-EVALUATE(CVDG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MFY) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(STRVG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ALY) {
+ DCHECK_OPCODE(ALY);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ uint32_t alu_out = get_low_register<uint32_t>(r1);
+ uint32_t mem_val = ReadWU(b2_val + x2_val + d2, instr);
+ alu_out += mem_val;
+ set_low_register(r1, alu_out);
+ SetS390ConditionCode<uint32_t>(alu_out, 0);
+ return length;
+}
-EVALUATE(CGF) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SLY) {
+ DCHECK_OPCODE(SLY);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ uint32_t alu_out = get_low_register<uint32_t>(r1);
+ uint32_t mem_val = ReadWU(b2_val + x2_val + d2, instr);
+ alu_out -= mem_val;
+ set_low_register(r1, alu_out);
+ SetS390ConditionCode<uint32_t>(alu_out, 0);
+ return length;
+}
-EVALUATE(CLGF) { return DecodeInstructionOriginal(instr); }
+EVALUATE(STHY) {
+ DCHECK_OPCODE(STHY);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ // Miscellaneous Loads and Stores
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ intptr_t addr = x2_val + b2_val + d2;
+ uint16_t value = get_low_register<uint32_t>(r1);
+ WriteH(addr, value, instr);
+ return length;
+}
-EVALUATE(LTGF) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LAY) {
+ DCHECK_OPCODE(LAY);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ // Load Address
+ int rb = b2;
+ int rx = x2;
+ int offset = d2;
+ int64_t rb_val = (rb == 0) ? 0 : get_register(rb);
+ int64_t rx_val = (rx == 0) ? 0 : get_register(rx);
+ set_register(r1, rx_val + rb_val + offset);
+ return length;
+}
-EVALUATE(CGH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(STCY) {
+ DCHECK_OPCODE(STCY);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ // Miscellaneous Loads and Stores
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ intptr_t addr = x2_val + b2_val + d2;
+ uint8_t value = get_low_register<uint32_t>(r1);
+ WriteB(addr, value);
+ return length;
+}
-EVALUATE(PFD) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ICY) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(STRV) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LAEY) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(STRVH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LB) {
+ DCHECK_OPCODE(LB);
+ // Miscellaneous Loads and Stores
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ intptr_t addr = x2_val + b2_val + d2;
+ int32_t mem_val = ReadB(addr);
+ set_low_register(r1, mem_val);
+ return length;
+}
-EVALUATE(BCTG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LGB) {
+ DCHECK_OPCODE(LGB);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ // Miscellaneous Loads and Stores
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ intptr_t addr = x2_val + b2_val + d2;
+ int64_t mem_val = ReadB(addr);
+ set_register(r1, mem_val);
+ return length;
+}
-EVALUATE(MSY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LHY) {
+ DCHECK_OPCODE(LHY);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ // Miscellaneous Loads and Stores
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ intptr_t addr = x2_val + b2_val + d2;
+ int32_t result = static_cast<int32_t>(ReadH(addr, instr));
+ set_low_register(r1, result);
+ return length;
+}
-EVALUATE(NY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CHY) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CLY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(AHY) {
+ DCHECK_OPCODE(AHY);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ int32_t r1_val = get_low_register<int32_t>(r1);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ intptr_t d2_val = d2;
+ int32_t mem_val =
+ static_cast<int32_t>(ReadH(b2_val + d2_val + x2_val, instr));
+ int32_t alu_out = 0;
+ bool isOF = false;
+ alu_out = r1_val + mem_val;
+ isOF = CheckOverflowForIntAdd(r1_val, mem_val, int32_t);
+ set_low_register(r1, alu_out);
+ SetS390ConditionCode<int32_t>(alu_out, 0);
+ SetS390OverflowCode(isOF);
+ return length;
+}
-EVALUATE(OY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SHY) {
+ DCHECK_OPCODE(SHY);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ int32_t r1_val = get_low_register<int32_t>(r1);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ intptr_t d2_val = d2;
+ int32_t mem_val =
+ static_cast<int32_t>(ReadH(b2_val + d2_val + x2_val, instr));
+ int32_t alu_out = 0;
+ bool isOF = false;
+ alu_out = r1_val - mem_val;
+ isOF = CheckOverflowForIntSub(r1_val, mem_val, int64_t);
+ set_low_register(r1, alu_out);
+ SetS390ConditionCode<int32_t>(alu_out, 0);
+ SetS390OverflowCode(isOF);
+ return length;
+}
-EVALUATE(XY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MHY) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(NG) {
+ DCHECK_OPCODE(NG);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int64_t alu_out = get_register(r1);
+ int64_t mem_val = ReadDW(b2_val + x2_val + d2);
+ alu_out &= mem_val;
+ SetS390BitWiseConditionCode<uint32_t>(alu_out);
+ set_register(r1, alu_out);
+ return length;
+}
-EVALUATE(AY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(OG) {
+ DCHECK_OPCODE(OG);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int64_t alu_out = get_register(r1);
+ int64_t mem_val = ReadDW(b2_val + x2_val + d2);
+ alu_out |= mem_val;
+ SetS390BitWiseConditionCode<uint32_t>(alu_out);
+ set_register(r1, alu_out);
+ return length;
+}
-EVALUATE(SY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(XG) {
+ DCHECK_OPCODE(XG);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int64_t alu_out = get_register(r1);
+ int64_t mem_val = ReadDW(b2_val + x2_val + d2);
+ alu_out ^= mem_val;
+ SetS390BitWiseConditionCode<uint32_t>(alu_out);
+ set_register(r1, alu_out);
+ return length;
+}
-EVALUATE(MFY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LGAT) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(ALY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MLG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SLY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(DLG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(STHY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ALCG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LAY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SLBG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(STCY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(STPQ) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(ICY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LPQ) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LAEY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LLGH) {
+ DCHECK_OPCODE(LLGH);
+ // Load Logical Halfword
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ intptr_t d2_val = d2;
+ uint16_t mem_val = ReadHU(b2_val + d2_val + x2_val, instr);
+ set_register(r1, mem_val);
+ return length;
+}
-EVALUATE(LB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LLH) {
+ DCHECK_OPCODE(LLH);
+ // Load Logical Halfword
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ intptr_t d2_val = d2;
+ uint16_t mem_val = ReadHU(b2_val + d2_val + x2_val, instr);
+ set_low_register(r1, mem_val);
+ return length;
+}
-EVALUATE(LGB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ML) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LHY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(DL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CHY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ALC) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(AHY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SLB) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SHY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LLGTAT) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(MHY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LLGFAT) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(NG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LAT) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(OG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LBH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(XG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LLCH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LGAT) { return DecodeInstructionOriginal(instr); }
+EVALUATE(STCH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(MLG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LHH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(DLG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LLHH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(ALCG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(STHH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SLBG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LFHAT) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(STPQ) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LFH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LPQ) { return DecodeInstructionOriginal(instr); }
+EVALUATE(STFH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LLGH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CHF) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LLH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MVCDK) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(ML) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MVHHI) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(DL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MVGHI) {
+ DCHECK_OPCODE(MVGHI);
+ // Move Integer (64)
+ DECODE_SIL_INSTRUCTION(b1, d1, i2);
+ int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
+ intptr_t src_addr = b1_val + d1;
+ WriteDW(src_addr, i2);
+ return length;
+}
-EVALUATE(ALC) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MVHI) {
+ DCHECK_OPCODE(MVHI);
+ // Move Integer (32)
+ DECODE_SIL_INSTRUCTION(b1, d1, i2);
+ int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
+ intptr_t src_addr = b1_val + d1;
+ WriteW(src_addr, i2, instr);
+ return length;
+}
-EVALUATE(SLB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CHHSI) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LLGTAT) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CGHSI) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LLGFAT) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CHSI) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LAT) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CLFHSI) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LBH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TBEGIN) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LLCH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TBEGINC) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(STCH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LMG) {
+ DCHECK_OPCODE(LMG);
+ // Store Multiple 64-bits.
+ DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
+ int rb = b2;
+ int offset = d2;
-EVALUATE(LHH) { return DecodeInstructionOriginal(instr); }
+ // Regs roll around if r3 is less than r1.
+ // Artifically increase r3 by 16 so we can calculate
+ // the number of regs stored properly.
+ if (r3 < r1) r3 += 16;
-EVALUATE(LLHH) { return DecodeInstructionOriginal(instr); }
+ int64_t rb_val = (rb == 0) ? 0 : get_register(rb);
-EVALUATE(STHH) { return DecodeInstructionOriginal(instr); }
+ // Store each register in ascending order.
+ for (int i = 0; i <= r3 - r1; i++) {
+ int64_t value = ReadDW(rb_val + offset + 8 * i);
+ set_register((r1 + i) % 16, value);
+ }
+ return length;
+}
-EVALUATE(LFHAT) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SRAG) {
+ DCHECK_OPCODE(SRAG);
+ // 64-bit non-clobbering shift-left/right arithmetic
+ DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
+ // only takes rightmost 6 bits
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int shiftBits = (b2_val + d2) & 0x3F;
+ int64_t r3_val = get_register(r3);
+ intptr_t alu_out = 0;
+ bool isOF = false;
+ alu_out = r3_val >> shiftBits;
+ set_register(r1, alu_out);
+ SetS390ConditionCode<intptr_t>(alu_out, 0);
+ SetS390OverflowCode(isOF);
+ return length;
+}
-EVALUATE(LFH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SLAG) {
+ DCHECK_OPCODE(SLAG);
+ // 64-bit non-clobbering shift-left/right arithmetic
+ DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
+ // only takes rightmost 6 bits
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int shiftBits = (b2_val + d2) & 0x3F;
+ int64_t r3_val = get_register(r3);
+ intptr_t alu_out = 0;
+ bool isOF = false;
+ isOF = CheckOverflowForShiftLeft(r3_val, shiftBits);
+ alu_out = r3_val << shiftBits;
+ set_register(r1, alu_out);
+ SetS390ConditionCode<intptr_t>(alu_out, 0);
+ SetS390OverflowCode(isOF);
+ return length;
+}
-EVALUATE(STFH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SRLG) {
+ DCHECK_OPCODE(SRLG);
+ // For SLLG/SRLG, the 64-bit third operand is shifted the number
+ // of bits specified by the second-operand address, and the result is
+ // placed at the first-operand location. Except for when the R1 and R3
+ // fields designate the same register, the third operand remains
+ // unchanged in general register R3.
+ DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
+ // only takes rightmost 6 bits
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int shiftBits = (b2_val + d2) & 0x3F;
+ // unsigned
+ uint64_t r3_val = get_register(r3);
+ uint64_t alu_out = 0;
+ alu_out = r3_val >> shiftBits;
+ set_register(r1, alu_out);
+ return length;
+}
-EVALUATE(CHF) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SLLG) {
+ DCHECK_OPCODE(SLLG);
+ // For SLLG/SRLG, the 64-bit third operand is shifted the number
+ // of bits specified by the second-operand address, and the result is
+ // placed at the first-operand location. Except for when the R1 and R3
+ // fields designate the same register, the third operand remains
+ // unchanged in general register R3.
+ DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
+ // only takes rightmost 6 bits
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int shiftBits = (b2_val + d2) & 0x3F;
+ // unsigned
+ uint64_t r3_val = get_register(r3);
+ uint64_t alu_out = 0;
+ alu_out = r3_val << shiftBits;
+ set_register(r1, alu_out);
+ return length;
+}
-EVALUATE(MVCDK) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CSY) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(MVHHI) { return DecodeInstructionOriginal(instr); }
+EVALUATE(RLLG) {
+ DCHECK_OPCODE(RLLG);
+ // For SLLG/SRLG, the 64-bit third operand is shifted the number
+ // of bits specified by the second-operand address, and the result is
+ // placed at the first-operand location. Except for when the R1 and R3
+ // fields designate the same register, the third operand remains
+ // unchanged in general register R3.
+ DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
+ // only takes rightmost 6 bits
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int shiftBits = (b2_val + d2) & 0x3F;
+ // unsigned
+ uint64_t r3_val = get_register(r3);
+ uint64_t alu_out = 0;
+ uint64_t rotateBits = r3_val >> (64 - shiftBits);
+ alu_out = (r3_val << shiftBits) | (rotateBits);
+ set_register(r1, alu_out);
+ return length;
+}
-EVALUATE(MVGHI) { return DecodeInstructionOriginal(instr); }
+EVALUATE(STMG) {
+ DCHECK_OPCODE(STMG);
+ DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
+ int rb = b2;
+ int offset = d2;
-EVALUATE(MVHI) { return DecodeInstructionOriginal(instr); }
+ // Regs roll around if r3 is less than r1.
+ // Artifically increase r3 by 16 so we can calculate
+ // the number of regs stored properly.
+ if (r3 < r1) r3 += 16;
-EVALUATE(CHHSI) { return DecodeInstructionOriginal(instr); }
+ int64_t rb_val = (rb == 0) ? 0 : get_register(rb);
-EVALUATE(CGHSI) { return DecodeInstructionOriginal(instr); }
+ // Store each register in ascending order.
+ for (int i = 0; i <= r3 - r1; i++) {
+ int64_t value = get_register((r1 + i) % 16);
+ WriteDW(rb_val + offset + 8 * i, value);
+ }
+ return length;
+}
-EVALUATE(CHSI) { return DecodeInstructionOriginal(instr); }
+EVALUATE(STMH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CLFHSI) { return DecodeInstructionOriginal(instr); }
+EVALUATE(STCMH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(TBEGIN) { return DecodeInstructionOriginal(instr); }
+EVALUATE(STCMY) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(TBEGINC) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CDSY) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LMG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CDSG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SRAG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(BXHG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SLAG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(BXLEG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SRLG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ECAG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SLLG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TMY) {
+ DCHECK_OPCODE(TMY);
+ // Test Under Mask (Mem - Imm) (8)
+ DECODE_SIY_INSTRUCTION(b1, d1, i2);
+ int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
+ intptr_t d1_val = d1;
+ intptr_t addr = b1_val + d1_val;
+ uint8_t mem_val = ReadB(addr);
+ uint8_t imm_val = i2;
+ uint8_t selected_bits = mem_val & imm_val;
+ // CC0: Selected bits are zero
+ // CC1: Selected bits mixed zeros and ones
+ // CC3: Selected bits all ones
+ if (0 == selected_bits) {
+ condition_reg_ = CC_EQ; // CC0
+ } else if (selected_bits == imm_val) {
+ condition_reg_ = 0x1; // CC3
+ } else {
+ condition_reg_ = 0x4; // CC1
+ }
+ return length;
+}
-EVALUATE(CSY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MVIY) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(RLLG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(NIY) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(STMG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CLIY) {
+ DCHECK_OPCODE(CLIY);
+ DECODE_SIY_INSTRUCTION(b1, d1, i2);
+ // Compare Immediate (Mem - Imm) (8)
+ int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
+ intptr_t d1_val = d1;
+ intptr_t addr = b1_val + d1_val;
+ uint8_t mem_val = ReadB(addr);
+ uint8_t imm_val = i2;
+ SetS390ConditionCode<uint8_t>(mem_val, imm_val);
+ return length;
+}
-EVALUATE(STMH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(OIY) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(STCMH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(XIY) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(STCMY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ASI) {
+ DCHECK_OPCODE(ASI);
+ // TODO(bcleung): Change all fooInstr->I2Value() to template functions.
+ // The below static cast to 8 bit and then to 32 bit is necessary
+ // because siyInstr->I2Value() returns a uint8_t, which a direct
+ // cast to int32_t could incorrectly interpret.
+ DECODE_SIY_INSTRUCTION(b1, d1, i2_unsigned);
+ int8_t i2_8bit = static_cast<int8_t>(i2_unsigned);
+ int32_t i2 = static_cast<int32_t>(i2_8bit);
+ intptr_t b1_val = (b1 == 0) ? 0 : get_register(b1);
-EVALUATE(CDSY) { return DecodeInstructionOriginal(instr); }
+ int d1_val = d1;
+ intptr_t addr = b1_val + d1_val;
-EVALUATE(CDSG) { return DecodeInstructionOriginal(instr); }
+ int32_t mem_val = ReadW(addr, instr);
+ bool isOF = CheckOverflowForIntAdd(mem_val, i2, int32_t);
+ int32_t alu_out = mem_val + i2;
+ SetS390ConditionCode<int32_t>(alu_out, 0);
+ SetS390OverflowCode(isOF);
+ WriteW(addr, alu_out, instr);
+ return length;
+}
-EVALUATE(BXHG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ALSI) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(BXLEG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(AGSI) {
+ DCHECK_OPCODE(AGSI);
+ // TODO(bcleung): Change all fooInstr->I2Value() to template functions.
+ // The below static cast to 8 bit and then to 32 bit is necessary
+ // because siyInstr->I2Value() returns a uint8_t, which a direct
+ // cast to int32_t could incorrectly interpret.
+ DECODE_SIY_INSTRUCTION(b1, d1, i2_unsigned);
+ int8_t i2_8bit = static_cast<int8_t>(i2_unsigned);
+ int64_t i2 = static_cast<int64_t>(i2_8bit);
+ intptr_t b1_val = (b1 == 0) ? 0 : get_register(b1);
-EVALUATE(ECAG) { return DecodeInstructionOriginal(instr); }
+ int d1_val = d1;
+ intptr_t addr = b1_val + d1_val;
-EVALUATE(TMY) { return DecodeInstructionOriginal(instr); }
+ int64_t mem_val = ReadDW(addr);
+ int isOF = CheckOverflowForIntAdd(mem_val, i2, int64_t);
+ int64_t alu_out = mem_val + i2;
+ SetS390ConditionCode<uint64_t>(alu_out, 0);
+ SetS390OverflowCode(isOF);
+ WriteDW(addr, alu_out);
+ return length;
+}
-EVALUATE(MVIY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ALGSI) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(NIY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ICMH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CLIY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ICMY) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(OIY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MVCLU) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(XIY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CLCLU) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(ASI) { return DecodeInstructionOriginal(instr); }
+EVALUATE(STMY) {
+ DCHECK_OPCODE(STMY);
+ DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
+ // Load/Store Multiple (32)
+ int offset = d2;
-EVALUATE(ALSI) { return DecodeInstructionOriginal(instr); }
+ // Regs roll around if r3 is less than r1.
+ // Artifically increase r3 by 16 so we can calculate
+ // the number of regs stored properly.
+ if (r3 < r1) r3 += 16;
-EVALUATE(AGSI) { return DecodeInstructionOriginal(instr); }
+ int32_t b2_val = (b2 == 0) ? 0 : get_low_register<int32_t>(b2);
-EVALUATE(ALGSI) { return DecodeInstructionOriginal(instr); }
+ // Store each register in ascending order.
+ for (int i = 0; i <= r3 - r1; i++) {
+ int32_t value = get_low_register<int32_t>((r1 + i) % 16);
+ WriteW(b2_val + offset + 4 * i, value, instr);
+ }
+ return length;
+}
-EVALUATE(ICMH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LMH) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(ICMY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LMY) {
+ DCHECK_OPCODE(LMY);
+ DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
+ // Load/Store Multiple (32)
+ int offset = d2;
-EVALUATE(MVCLU) { return DecodeInstructionOriginal(instr); }
+ // Regs roll around if r3 is less than r1.
+ // Artifically increase r3 by 16 so we can calculate
+ // the number of regs stored properly.
+ if (r3 < r1) r3 += 16;
-EVALUATE(CLCLU) { return DecodeInstructionOriginal(instr); }
+ int32_t b2_val = (b2 == 0) ? 0 : get_low_register<int32_t>(b2);
-EVALUATE(STMY) { return DecodeInstructionOriginal(instr); }
+ // Store each register in ascending order.
+ for (int i = 0; i <= r3 - r1; i++) {
+ int32_t value = ReadW(b2_val + offset + 4 * i, instr);
+ set_low_register((r1 + i) % 16, value);
+ }
+ return length;
+}
-EVALUATE(LMH) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TP) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LMY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SRAK) {
+ DCHECK_OPCODE(SRAK);
+ DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
+ // 32-bit non-clobbering shift-left/right arithmetic
+ // only takes rightmost 6 bits
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int shiftBits = (b2_val + d2) & 0x3F;
+ int32_t r3_val = get_low_register<int32_t>(r3);
+ int32_t alu_out = 0;
+ bool isOF = false;
+ alu_out = r3_val >> shiftBits;
+ set_low_register(r1, alu_out);
+ SetS390ConditionCode<int32_t>(alu_out, 0);
+ SetS390OverflowCode(isOF);
+ return length;
+}
-EVALUATE(TP) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SLAK) {
+ DCHECK_OPCODE(SLAK);
+ DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
+ // 32-bit non-clobbering shift-left/right arithmetic
+ // only takes rightmost 6 bits
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int shiftBits = (b2_val + d2) & 0x3F;
+ int32_t r3_val = get_low_register<int32_t>(r3);
+ int32_t alu_out = 0;
+ bool isOF = false;
+ isOF = CheckOverflowForShiftLeft(r3_val, shiftBits);
+ alu_out = r3_val << shiftBits;
+ set_low_register(r1, alu_out);
+ SetS390ConditionCode<int32_t>(alu_out, 0);
+ SetS390OverflowCode(isOF);
+ return length;
+}
-EVALUATE(SRAK) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SRLK) {
+ DCHECK_OPCODE(SRLK);
+ // For SLLK/SRLL, the 32-bit third operand is shifted the number
+ // of bits specified by the second-operand address, and the result is
+ // placed at the first-operand location. Except for when the R1 and R3
+ // fields designate the same register, the third operand remains
+ // unchanged in general register R3.
+ DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
+ // only takes rightmost 6 bits
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int shiftBits = (b2_val + d2) & 0x3F;
+ // unsigned
+ uint32_t r3_val = get_low_register<uint32_t>(r3);
+ uint32_t alu_out = 0;
+ alu_out = r3_val >> shiftBits;
+ set_low_register(r1, alu_out);
+ return length;
+}
-EVALUATE(SLAK) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SLLK) {
+ DCHECK_OPCODE(SLLK);
+ // For SLLK/SRLL, the 32-bit third operand is shifted the number
+ // of bits specified by the second-operand address, and the result is
+ // placed at the first-operand location. Except for when the R1 and R3
+ // fields designate the same register, the third operand remains
+ // unchanged in general register R3.
+ DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
+ // only takes rightmost 6 bits
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int shiftBits = (b2_val + d2) & 0x3F;
+ // unsigned
+ uint32_t r3_val = get_low_register<uint32_t>(r3);
+ uint32_t alu_out = 0;
+ alu_out = r3_val << shiftBits;
+ set_low_register(r1, alu_out);
+ return length;
+}
-EVALUATE(SRLK) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LOCG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SLLK) { return DecodeInstructionOriginal(instr); }
+EVALUATE(STOCG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LOCG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LANG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(STOCG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LAOG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LANG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LAXG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LAOG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LAAG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LAXG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LAALG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LAAG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LOC) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LAALG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(STOC) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LOC) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LAN) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(STOC) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LAO) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LAN) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LAX) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LAO) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LAA) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LAX) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LAAL) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LAA) { return DecodeInstructionOriginal(instr); }
+EVALUATE(BRXHG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LAAL) { return DecodeInstructionOriginal(instr); }
+EVALUATE(BRXLG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(BRXHG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(RISBLG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(BRXLG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(RNSBG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(RISBLG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ROSBG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(RNSBG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(RXSBG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(ROSBG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(RISBGN) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(RXSBG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(RISBHG) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(RISBGN) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CGRJ) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(RISBHG) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CGIT) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CGRJ) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CIT) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CGIT) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CLFIT) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CIT) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CGIJ) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CLFIT) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CIJ) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CGIJ) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ALHSIK) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CIJ) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ALGHSIK) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(ALHSIK) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CGRB) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(ALGHSIK) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CGIB) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CGRB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CIB) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CGIB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LDEB) {
+ DCHECK_OPCODE(LDEB);
+ // Load Float
+ DECODE_RXE_INSTRUCTION(r1, b2, x2, d2);
+ int rb = b2;
+ int rx = x2;
+ int offset = d2;
+ int64_t rb_val = (rb == 0) ? 0 : get_register(rb);
+ int64_t rx_val = (rx == 0) ? 0 : get_register(rx);
+ double ret =
+ static_cast<double>(*reinterpret_cast<float*>(rx_val + rb_val + offset));
+ set_d_register_from_double(r1, ret);
+ return length;
+}
-EVALUATE(CIB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LXDB) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LDEB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LXEB) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LXDB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MXDB) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LXEB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(KEB) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(MXDB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CEB) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(KEB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(AEB) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CEB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SEB) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(AEB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MDEB) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SEB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(DEB) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(MDEB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MAEB) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(DEB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MSEB) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(MAEB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TCEB) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(MSEB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TCDB) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(TCEB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TCXB) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(TCDB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SQEB) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(TCXB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SQDB) {
+ DCHECK_OPCODE(SQDB);
+ DECODE_RXE_INSTRUCTION(r1, b2, x2, d2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ intptr_t d2_val = d2;
+ double r1_val = get_double_from_d_register(r1);
+ double dbl_val = ReadDouble(b2_val + x2_val + d2_val);
+ r1_val = std::sqrt(dbl_val);
+ set_d_register_from_double(r1, r1_val);
+ return length;
+}
-EVALUATE(SQEB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MEEB) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SQDB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(KDB) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(MEEB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CDB) {
+ DCHECK_OPCODE(CDB);
-EVALUATE(KDB) { return DecodeInstructionOriginal(instr); }
+ DECODE_RXE_INSTRUCTION(r1, b2, x2, d2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ intptr_t d2_val = d2;
+ double r1_val = get_double_from_d_register(r1);
+ double dbl_val = ReadDouble(b2_val + x2_val + d2_val);
+ SetS390ConditionCode<double>(r1_val, dbl_val);
+ return length;
+}
-EVALUATE(CDB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(ADB) {
+ DCHECK_OPCODE(ADB);
-EVALUATE(ADB) { return DecodeInstructionOriginal(instr); }
+ DECODE_RXE_INSTRUCTION(r1, b2, x2, d2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ intptr_t d2_val = d2;
+ double r1_val = get_double_from_d_register(r1);
+ double dbl_val = ReadDouble(b2_val + x2_val + d2_val);
+ r1_val += dbl_val;
+ set_d_register_from_double(r1, r1_val);
+ SetS390ConditionCode<double>(r1_val, 0);
+ return length;
+}
-EVALUATE(SDB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SDB) {
+ DCHECK_OPCODE(SDB);
+ DECODE_RXE_INSTRUCTION(r1, b2, x2, d2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ intptr_t d2_val = d2;
+ double r1_val = get_double_from_d_register(r1);
+ double dbl_val = ReadDouble(b2_val + x2_val + d2_val);
+ r1_val -= dbl_val;
+ set_d_register_from_double(r1, r1_val);
+ SetS390ConditionCode<double>(r1_val, 0);
+ return length;
+}
-EVALUATE(MDB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MDB) {
+ DCHECK_OPCODE(MDB);
+ DECODE_RXE_INSTRUCTION(r1, b2, x2, d2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ intptr_t d2_val = d2;
+ double r1_val = get_double_from_d_register(r1);
+ double dbl_val = ReadDouble(b2_val + x2_val + d2_val);
+ r1_val *= dbl_val;
+ set_d_register_from_double(r1, r1_val);
+ SetS390ConditionCode<double>(r1_val, 0);
+ return length;
+}
-EVALUATE(DDB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(DDB) {
+ DCHECK_OPCODE(DDB);
+ DECODE_RXE_INSTRUCTION(r1, b2, x2, d2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ intptr_t d2_val = d2;
+ double r1_val = get_double_from_d_register(r1);
+ double dbl_val = ReadDouble(b2_val + x2_val + d2_val);
+ r1_val /= dbl_val;
+ set_d_register_from_double(r1, r1_val);
+ SetS390ConditionCode<double>(r1_val, 0);
+ return length;
+}
-EVALUATE(MADB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MADB) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(MSDB) { return DecodeInstructionOriginal(instr); }
+EVALUATE(MSDB) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SLDT) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SLDT) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SRDT) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SRDT) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SLXT) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SLXT) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(SRXT) { return DecodeInstructionOriginal(instr); }
+EVALUATE(SRXT) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(TDCET) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TDCET) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(TDGET) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TDGET) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(TDCDT) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TDCDT) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(TDGDT) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TDGDT) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(TDCXT) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TDCXT) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(TDGXT) { return DecodeInstructionOriginal(instr); }
+EVALUATE(TDGXT) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(LEY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LEY) {
+ DCHECK_OPCODE(LEY);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ // Miscellaneous Loads and Stores
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ intptr_t addr = x2_val + b2_val + d2;
+ float float_val = *reinterpret_cast<float*>(addr);
+ set_d_register_from_float32(r1, float_val);
+ return length;
+}
-EVALUATE(LDY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(LDY) {
+ DCHECK_OPCODE(LDY);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ // Miscellaneous Loads and Stores
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ intptr_t addr = x2_val + b2_val + d2;
+ uint64_t dbl_val = *reinterpret_cast<uint64_t*>(addr);
+ set_d_register(r1, dbl_val);
+ return length;
+}
-EVALUATE(STEY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(STEY) {
+ DCHECK_OPCODE(STEY);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ // Miscellaneous Loads and Stores
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ intptr_t addr = x2_val + b2_val + d2;
+ int64_t frs_val = get_d_register(r1) >> 32;
+ WriteW(addr, static_cast<int32_t>(frs_val), instr);
+ return length;
+}
-EVALUATE(STDY) { return DecodeInstructionOriginal(instr); }
+EVALUATE(STDY) {
+ DCHECK_OPCODE(STDY);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ // Miscellaneous Loads and Stores
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
+ intptr_t addr = x2_val + b2_val + d2;
+ int64_t frs_val = get_d_register(r1);
+ WriteDW(addr, frs_val);
+ return length;
+}
-EVALUATE(CZDT) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CZDT) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CZXT) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CZXT) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CDZT) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CDZT) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
-EVALUATE(CXZT) { return DecodeInstructionOriginal(instr); }
+EVALUATE(CXZT) {
+ UNIMPLEMENTED();
+ USE(instr);
+ return 0;
+}
#undef EVALUATE