1 // Copyright 2014 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <stdarg.h> 6 #include <stdlib.h> 7 #include <cmath> 8 9 #if V8_TARGET_ARCH_S390 10 11 #include "src/assembler.h" 12 #include "src/base/bits.h" 13 #include "src/base/once.h" 14 #include "src/codegen.h" 15 #include "src/disasm.h" 16 #include "src/macro-assembler.h" 17 #include "src/ostreams.h" 18 #include "src/runtime/runtime-utils.h" 19 #include "src/s390/constants-s390.h" 20 #include "src/s390/simulator-s390.h" 21 #if defined(USE_SIMULATOR) 22 23 // Only build the simulator if not compiling for real s390 hardware. 24 namespace v8 { 25 namespace internal { 26 27 const auto GetRegConfig = RegisterConfiguration::Default; 28 29 // This macro provides a platform independent use of sscanf. The reason for 30 // SScanF not being implemented in a platform independent way through 31 // ::v8::internal::OS in the same way as SNPrintF is that the 32 // Windows C Run-Time Library does not provide vsscanf. 33 #define SScanF sscanf // NOLINT 34 35 // The S390Debugger class is used by the simulator while debugging simulated 36 // z/Architecture code. 37 class S390Debugger { 38 public: 39 explicit S390Debugger(Simulator* sim) : sim_(sim) {} 40 41 void Stop(Instruction* instr); 42 void Debug(); 43 44 private: 45 #if V8_TARGET_LITTLE_ENDIAN 46 static const Instr kBreakpointInstr = (0x0000FFB2); // TRAP4 0000 47 static const Instr kNopInstr = (0x00160016); // OR r0, r0 x2 48 #else 49 static const Instr kBreakpointInstr = (0xB2FF0000); // TRAP4 0000 50 static const Instr kNopInstr = (0x16001600); // OR r0, r0 x2 51 #endif 52 53 Simulator* sim_; 54 55 intptr_t GetRegisterValue(int regnum); 56 double GetRegisterPairDoubleValue(int regnum); 57 double GetFPDoubleRegisterValue(int regnum); 58 float GetFPFloatRegisterValue(int regnum); 59 bool GetValue(const char* desc, intptr_t* value); 60 bool GetFPDoubleValue(const char* desc, double* value); 61 62 // Set or delete a breakpoint. Returns true if successful. 63 bool SetBreakpoint(Instruction* break_pc); 64 bool DeleteBreakpoint(Instruction* break_pc); 65 66 // Undo and redo all breakpoints. This is needed to bracket disassembly and 67 // execution to skip past breakpoints when run from the debugger. 68 void UndoBreakpoints(); 69 void RedoBreakpoints(); 70 }; 71 72 void S390Debugger::Stop(Instruction* instr) { 73 // Get the stop code. 74 // use of kStopCodeMask not right on PowerPC 75 uint32_t code = instr->SvcValue() & kStopCodeMask; 76 // Retrieve the encoded address, which comes just after this stop. 77 char* msg = *reinterpret_cast<char**>(sim_->get_pc() + sizeof(FourByteInstr)); 78 // Update this stop description. 79 if (sim_->isWatchedStop(code) && !sim_->watched_stops_[code].desc) { 80 sim_->watched_stops_[code].desc = msg; 81 } 82 // Print the stop message and code if it is not the default code. 83 if (code != kMaxStopCode) { 84 PrintF("Simulator hit stop %u: %s\n", code, msg); 85 } else { 86 PrintF("Simulator hit %s\n", msg); 87 } 88 sim_->set_pc(sim_->get_pc() + sizeof(FourByteInstr) + kPointerSize); 89 Debug(); 90 } 91 92 intptr_t S390Debugger::GetRegisterValue(int regnum) { 93 return sim_->get_register(regnum); 94 } 95 96 double S390Debugger::GetRegisterPairDoubleValue(int regnum) { 97 return sim_->get_double_from_register_pair(regnum); 98 } 99 100 double S390Debugger::GetFPDoubleRegisterValue(int regnum) { 101 return sim_->get_double_from_d_register(regnum); 102 } 103 104 float S390Debugger::GetFPFloatRegisterValue(int regnum) { 105 return sim_->get_float32_from_d_register(regnum); 106 } 107 108 bool S390Debugger::GetValue(const char* desc, intptr_t* value) { 109 int regnum = Registers::Number(desc); 110 if (regnum != kNoRegister) { 111 *value = GetRegisterValue(regnum); 112 return true; 113 } else { 114 if (strncmp(desc, "0x", 2) == 0) { 115 return SScanF(desc + 2, "%" V8PRIxPTR, 116 reinterpret_cast<uintptr_t*>(value)) == 1; 117 } else { 118 return SScanF(desc, "%" V8PRIuPTR, reinterpret_cast<uintptr_t*>(value)) == 119 1; 120 } 121 } 122 return false; 123 } 124 125 bool S390Debugger::GetFPDoubleValue(const char* desc, double* value) { 126 int regnum = DoubleRegisters::Number(desc); 127 if (regnum != kNoRegister) { 128 *value = sim_->get_double_from_d_register(regnum); 129 return true; 130 } 131 return false; 132 } 133 134 bool S390Debugger::SetBreakpoint(Instruction* break_pc) { 135 // Check if a breakpoint can be set. If not return without any side-effects. 136 if (sim_->break_pc_ != nullptr) { 137 return false; 138 } 139 140 // Set the breakpoint. 141 sim_->break_pc_ = break_pc; 142 sim_->break_instr_ = break_pc->InstructionBits(); 143 // Not setting the breakpoint instruction in the code itself. It will be set 144 // when the debugger shell continues. 145 return true; 146 } 147 148 bool S390Debugger::DeleteBreakpoint(Instruction* break_pc) { 149 if (sim_->break_pc_ != nullptr) { 150 sim_->break_pc_->SetInstructionBits(sim_->break_instr_); 151 } 152 153 sim_->break_pc_ = nullptr; 154 sim_->break_instr_ = 0; 155 return true; 156 } 157 158 void S390Debugger::UndoBreakpoints() { 159 if (sim_->break_pc_ != nullptr) { 160 sim_->break_pc_->SetInstructionBits(sim_->break_instr_); 161 } 162 } 163 164 void S390Debugger::RedoBreakpoints() { 165 if (sim_->break_pc_ != nullptr) { 166 sim_->break_pc_->SetInstructionBits(kBreakpointInstr); 167 } 168 } 169 170 void S390Debugger::Debug() { 171 intptr_t last_pc = -1; 172 bool done = false; 173 174 #define COMMAND_SIZE 63 175 #define ARG_SIZE 255 176 177 #define STR(a) #a 178 #define XSTR(a) STR(a) 179 180 char cmd[COMMAND_SIZE + 1]; 181 char arg1[ARG_SIZE + 1]; 182 char arg2[ARG_SIZE + 1]; 183 char* argv[3] = {cmd, arg1, arg2}; 184 185 // make sure to have a proper terminating character if reaching the limit 186 cmd[COMMAND_SIZE] = 0; 187 arg1[ARG_SIZE] = 0; 188 arg2[ARG_SIZE] = 0; 189 190 // Undo all set breakpoints while running in the debugger shell. This will 191 // make them invisible to all commands. 192 UndoBreakpoints(); 193 // Disable tracing while simulating 194 bool trace = ::v8::internal::FLAG_trace_sim; 195 ::v8::internal::FLAG_trace_sim = false; 196 197 while (!done && !sim_->has_bad_pc()) { 198 if (last_pc != sim_->get_pc()) { 199 disasm::NameConverter converter; 200 disasm::Disassembler dasm(converter); 201 // use a reasonably large buffer 202 v8::internal::EmbeddedVector<char, 256> buffer; 203 dasm.InstructionDecode(buffer, reinterpret_cast<byte*>(sim_->get_pc())); 204 PrintF(" 0x%08" V8PRIxPTR " %s\n", sim_->get_pc(), buffer.start()); 205 last_pc = sim_->get_pc(); 206 } 207 char* line = ReadLine("sim> "); 208 if (line == nullptr) { 209 break; 210 } else { 211 char* last_input = sim_->last_debugger_input(); 212 if (strcmp(line, "\n") == 0 && last_input != nullptr) { 213 line = last_input; 214 } else { 215 // Ownership is transferred to sim_; 216 sim_->set_last_debugger_input(line); 217 } 218 // Use sscanf to parse the individual parts of the command line. At the 219 // moment no command expects more than two parameters. 220 int argc = SScanF(line, 221 "%" XSTR(COMMAND_SIZE) "s " 222 "%" XSTR(ARG_SIZE) "s " 223 "%" XSTR(ARG_SIZE) "s", 224 cmd, arg1, arg2); 225 if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) { 226 intptr_t value; 227 228 // If at a breakpoint, proceed past it. 229 if ((reinterpret_cast<Instruction*>(sim_->get_pc())) 230 ->InstructionBits() == 0x7D821008) { 231 sim_->set_pc(sim_->get_pc() + sizeof(FourByteInstr)); 232 } else { 233 sim_->ExecuteInstruction( 234 reinterpret_cast<Instruction*>(sim_->get_pc())); 235 } 236 237 if (argc == 2 && last_pc != sim_->get_pc()) { 238 disasm::NameConverter converter; 239 disasm::Disassembler dasm(converter); 240 // use a reasonably large buffer 241 v8::internal::EmbeddedVector<char, 256> buffer; 242 243 if (GetValue(arg1, &value)) { 244 // Interpret a numeric argument as the number of instructions to 245 // step past. 246 for (int i = 1; (!sim_->has_bad_pc()) && i < value; i++) { 247 dasm.InstructionDecode(buffer, 248 reinterpret_cast<byte*>(sim_->get_pc())); 249 PrintF(" 0x%08" V8PRIxPTR " %s\n", sim_->get_pc(), 250 buffer.start()); 251 sim_->ExecuteInstruction( 252 reinterpret_cast<Instruction*>(sim_->get_pc())); 253 } 254 } else { 255 // Otherwise treat it as the mnemonic of the opcode to stop at. 256 char mnemonic[256]; 257 while (!sim_->has_bad_pc()) { 258 dasm.InstructionDecode(buffer, 259 reinterpret_cast<byte*>(sim_->get_pc())); 260 char* mnemonicStart = buffer.start(); 261 while (*mnemonicStart != 0 && *mnemonicStart != ' ') 262 mnemonicStart++; 263 SScanF(mnemonicStart, "%s", mnemonic); 264 if (!strcmp(arg1, mnemonic)) break; 265 266 PrintF(" 0x%08" V8PRIxPTR " %s\n", sim_->get_pc(), 267 buffer.start()); 268 sim_->ExecuteInstruction( 269 reinterpret_cast<Instruction*>(sim_->get_pc())); 270 } 271 } 272 } 273 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) { 274 // If at a breakpoint, proceed past it. 275 if ((reinterpret_cast<Instruction*>(sim_->get_pc())) 276 ->InstructionBits() == 0x7D821008) { 277 sim_->set_pc(sim_->get_pc() + sizeof(FourByteInstr)); 278 } else { 279 // Execute the one instruction we broke at with breakpoints disabled. 280 sim_->ExecuteInstruction( 281 reinterpret_cast<Instruction*>(sim_->get_pc())); 282 } 283 // Leave the debugger shell. 284 done = true; 285 } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) { 286 if (argc == 2 || (argc == 3 && strcmp(arg2, "fp") == 0)) { 287 intptr_t value; 288 double dvalue; 289 if (strcmp(arg1, "all") == 0) { 290 for (int i = 0; i < kNumRegisters; i++) { 291 value = GetRegisterValue(i); 292 PrintF(" %3s: %08" V8PRIxPTR, 293 GetRegConfig()->GetGeneralRegisterName(i), value); 294 if ((argc == 3 && strcmp(arg2, "fp") == 0) && i < 8 && 295 (i % 2) == 0) { 296 dvalue = GetRegisterPairDoubleValue(i); 297 PrintF(" (%f)\n", dvalue); 298 } else if (i != 0 && !((i + 1) & 3)) { 299 PrintF("\n"); 300 } 301 } 302 PrintF(" pc: %08" V8PRIxPTR " cr: %08x\n", sim_->special_reg_pc_, 303 sim_->condition_reg_); 304 } else if (strcmp(arg1, "alld") == 0) { 305 for (int i = 0; i < kNumRegisters; i++) { 306 value = GetRegisterValue(i); 307 PrintF(" %3s: %08" V8PRIxPTR " %11" V8PRIdPTR, 308 GetRegConfig()->GetGeneralRegisterName(i), value, value); 309 if ((argc == 3 && strcmp(arg2, "fp") == 0) && i < 8 && 310 (i % 2) == 0) { 311 dvalue = GetRegisterPairDoubleValue(i); 312 PrintF(" (%f)\n", dvalue); 313 } else if (!((i + 1) % 2)) { 314 PrintF("\n"); 315 } 316 } 317 PrintF(" pc: %08" V8PRIxPTR " cr: %08x\n", sim_->special_reg_pc_, 318 sim_->condition_reg_); 319 } else if (strcmp(arg1, "allf") == 0) { 320 for (int i = 0; i < DoubleRegister::kNumRegisters; i++) { 321 float fvalue = GetFPFloatRegisterValue(i); 322 uint32_t as_words = bit_cast<uint32_t>(fvalue); 323 PrintF("%3s: %f 0x%08x\n", 324 GetRegConfig()->GetDoubleRegisterName(i), fvalue, 325 as_words); 326 } 327 } else if (strcmp(arg1, "alld") == 0) { 328 for (int i = 0; i < DoubleRegister::kNumRegisters; i++) { 329 dvalue = GetFPDoubleRegisterValue(i); 330 uint64_t as_words = bit_cast<uint64_t>(dvalue); 331 PrintF("%3s: %f 0x%08x %08x\n", 332 GetRegConfig()->GetDoubleRegisterName(i), dvalue, 333 static_cast<uint32_t>(as_words >> 32), 334 static_cast<uint32_t>(as_words & 0xFFFFFFFF)); 335 } 336 } else if (arg1[0] == 'r' && 337 (arg1[1] >= '0' && arg1[1] <= '2' && 338 (arg1[2] == '\0' || (arg1[2] >= '0' && arg1[2] <= '5' && 339 arg1[3] == '\0')))) { 340 int regnum = strtoul(&arg1[1], 0, 10); 341 if (regnum != kNoRegister) { 342 value = GetRegisterValue(regnum); 343 PrintF("%s: 0x%08" V8PRIxPTR " %" V8PRIdPTR "\n", arg1, value, 344 value); 345 } else { 346 PrintF("%s unrecognized\n", arg1); 347 } 348 } else { 349 if (GetValue(arg1, &value)) { 350 PrintF("%s: 0x%08" V8PRIxPTR " %" V8PRIdPTR "\n", arg1, value, 351 value); 352 } else if (GetFPDoubleValue(arg1, &dvalue)) { 353 uint64_t as_words = bit_cast<uint64_t>(dvalue); 354 PrintF("%s: %f 0x%08x %08x\n", arg1, dvalue, 355 static_cast<uint32_t>(as_words >> 32), 356 static_cast<uint32_t>(as_words & 0xFFFFFFFF)); 357 } else { 358 PrintF("%s unrecognized\n", arg1); 359 } 360 } 361 } else { 362 PrintF("print <register>\n"); 363 } 364 } else if ((strcmp(cmd, "po") == 0) || 365 (strcmp(cmd, "printobject") == 0)) { 366 if (argc == 2) { 367 intptr_t value; 368 StdoutStream os; 369 if (GetValue(arg1, &value)) { 370 Object* obj = reinterpret_cast<Object*>(value); 371 os << arg1 << ": \n"; 372 #ifdef DEBUG 373 obj->Print(os); 374 os << "\n"; 375 #else 376 os << Brief(obj) << "\n"; 377 #endif 378 } else { 379 os << arg1 << " unrecognized\n"; 380 } 381 } else { 382 PrintF("printobject <value>\n"); 383 } 384 } else if (strcmp(cmd, "setpc") == 0) { 385 intptr_t value; 386 387 if (!GetValue(arg1, &value)) { 388 PrintF("%s unrecognized\n", arg1); 389 continue; 390 } 391 sim_->set_pc(value); 392 } else if (strcmp(cmd, "stack") == 0 || strcmp(cmd, "mem") == 0) { 393 intptr_t* cur = nullptr; 394 intptr_t* end = nullptr; 395 int next_arg = 1; 396 397 if (strcmp(cmd, "stack") == 0) { 398 cur = reinterpret_cast<intptr_t*>(sim_->get_register(Simulator::sp)); 399 } else { // "mem" 400 intptr_t value; 401 if (!GetValue(arg1, &value)) { 402 PrintF("%s unrecognized\n", arg1); 403 continue; 404 } 405 cur = reinterpret_cast<intptr_t*>(value); 406 next_arg++; 407 } 408 409 intptr_t words; // likely inaccurate variable name for 64bit 410 if (argc == next_arg) { 411 words = 10; 412 } else { 413 if (!GetValue(argv[next_arg], &words)) { 414 words = 10; 415 } 416 } 417 end = cur + words; 418 419 while (cur < end) { 420 PrintF(" 0x%08" V8PRIxPTR ": 0x%08" V8PRIxPTR " %10" V8PRIdPTR, 421 reinterpret_cast<intptr_t>(cur), *cur, *cur); 422 HeapObject* obj = reinterpret_cast<HeapObject*>(*cur); 423 intptr_t value = *cur; 424 Heap* current_heap = sim_->isolate_->heap(); 425 if (((value & 1) == 0) || 426 current_heap->ContainsSlow(obj->address())) { 427 PrintF("(smi %d)", PlatformSmiTagging::SmiToInt(obj)); 428 } else if (current_heap->Contains(obj)) { 429 PrintF(" ("); 430 obj->ShortPrint(); 431 PrintF(")"); 432 } 433 PrintF("\n"); 434 cur++; 435 } 436 } else if (strcmp(cmd, "disasm") == 0 || strcmp(cmd, "di") == 0) { 437 disasm::NameConverter converter; 438 disasm::Disassembler dasm(converter); 439 // use a reasonably large buffer 440 v8::internal::EmbeddedVector<char, 256> buffer; 441 442 byte* prev = nullptr; 443 byte* cur = nullptr; 444 // Default number of instructions to disassemble. 445 int32_t numInstructions = 10; 446 447 if (argc == 1) { 448 cur = reinterpret_cast<byte*>(sim_->get_pc()); 449 } else if (argc == 2) { 450 int regnum = Registers::Number(arg1); 451 if (regnum != kNoRegister || strncmp(arg1, "0x", 2) == 0) { 452 // The argument is an address or a register name. 453 intptr_t value; 454 if (GetValue(arg1, &value)) { 455 cur = reinterpret_cast<byte*>(value); 456 } 457 } else { 458 // The argument is the number of instructions. 459 intptr_t value; 460 if (GetValue(arg1, &value)) { 461 cur = reinterpret_cast<byte*>(sim_->get_pc()); 462 // Disassemble <arg1> instructions. 463 numInstructions = static_cast<int32_t>(value); 464 } 465 } 466 } else { 467 intptr_t value1; 468 intptr_t value2; 469 if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) { 470 cur = reinterpret_cast<byte*>(value1); 471 // Disassemble <arg2> instructions. 472 numInstructions = static_cast<int32_t>(value2); 473 } 474 } 475 476 while (numInstructions > 0) { 477 prev = cur; 478 cur += dasm.InstructionDecode(buffer, cur); 479 PrintF(" 0x%08" V8PRIxPTR " %s\n", reinterpret_cast<intptr_t>(prev), 480 buffer.start()); 481 numInstructions--; 482 } 483 } else if (strcmp(cmd, "gdb") == 0) { 484 PrintF("relinquishing control to gdb\n"); 485 v8::base::OS::DebugBreak(); 486 PrintF("regaining control from gdb\n"); 487 } else if (strcmp(cmd, "break") == 0) { 488 if (argc == 2) { 489 intptr_t value; 490 if (GetValue(arg1, &value)) { 491 if (!SetBreakpoint(reinterpret_cast<Instruction*>(value))) { 492 PrintF("setting breakpoint failed\n"); 493 } 494 } else { 495 PrintF("%s unrecognized\n", arg1); 496 } 497 } else { 498 PrintF("break <address>\n"); 499 } 500 } else if (strcmp(cmd, "del") == 0) { 501 if (!DeleteBreakpoint(nullptr)) { 502 PrintF("deleting breakpoint failed\n"); 503 } 504 } else if (strcmp(cmd, "cr") == 0) { 505 PrintF("Condition reg: %08x\n", sim_->condition_reg_); 506 } else if (strcmp(cmd, "stop") == 0) { 507 intptr_t value; 508 intptr_t stop_pc = 509 sim_->get_pc() - (sizeof(FourByteInstr) + kPointerSize); 510 Instruction* stop_instr = reinterpret_cast<Instruction*>(stop_pc); 511 Instruction* msg_address = 512 reinterpret_cast<Instruction*>(stop_pc + sizeof(FourByteInstr)); 513 if ((argc == 2) && (strcmp(arg1, "unstop") == 0)) { 514 // Remove the current stop. 515 if (sim_->isStopInstruction(stop_instr)) { 516 stop_instr->SetInstructionBits(kNopInstr); 517 msg_address->SetInstructionBits(kNopInstr); 518 } else { 519 PrintF("Not at debugger stop.\n"); 520 } 521 } else if (argc == 3) { 522 // Print information about all/the specified breakpoint(s). 523 if (strcmp(arg1, "info") == 0) { 524 if (strcmp(arg2, "all") == 0) { 525 PrintF("Stop information:\n"); 526 for (uint32_t i = 0; i < sim_->kNumOfWatchedStops; i++) { 527 sim_->PrintStopInfo(i); 528 } 529 } else if (GetValue(arg2, &value)) { 530 sim_->PrintStopInfo(value); 531 } else { 532 PrintF("Unrecognized argument.\n"); 533 } 534 } else if (strcmp(arg1, "enable") == 0) { 535 // Enable all/the specified breakpoint(s). 536 if (strcmp(arg2, "all") == 0) { 537 for (uint32_t i = 0; i < sim_->kNumOfWatchedStops; i++) { 538 sim_->EnableStop(i); 539 } 540 } else if (GetValue(arg2, &value)) { 541 sim_->EnableStop(value); 542 } else { 543 PrintF("Unrecognized argument.\n"); 544 } 545 } else if (strcmp(arg1, "disable") == 0) { 546 // Disable all/the specified breakpoint(s). 547 if (strcmp(arg2, "all") == 0) { 548 for (uint32_t i = 0; i < sim_->kNumOfWatchedStops; i++) { 549 sim_->DisableStop(i); 550 } 551 } else if (GetValue(arg2, &value)) { 552 sim_->DisableStop(value); 553 } else { 554 PrintF("Unrecognized argument.\n"); 555 } 556 } 557 } else { 558 PrintF("Wrong usage. Use help command for more information.\n"); 559 } 560 } else if (strcmp(cmd, "icount") == 0) { 561 PrintF("%05" PRId64 "\n", sim_->icount_); 562 } else if ((strcmp(cmd, "t") == 0) || strcmp(cmd, "trace") == 0) { 563 ::v8::internal::FLAG_trace_sim = !::v8::internal::FLAG_trace_sim; 564 PrintF("Trace of executed instructions is %s\n", 565 ::v8::internal::FLAG_trace_sim ? "on" : "off"); 566 } else if ((strcmp(cmd, "h") == 0) || (strcmp(cmd, "help") == 0)) { 567 PrintF("cont\n"); 568 PrintF(" continue execution (alias 'c')\n"); 569 PrintF("stepi [num instructions]\n"); 570 PrintF(" step one/num instruction(s) (alias 'si')\n"); 571 PrintF("print <register>\n"); 572 PrintF(" print register content (alias 'p')\n"); 573 PrintF(" use register name 'all' to display all integer registers\n"); 574 PrintF( 575 " use register name 'alld' to display integer registers " 576 "with decimal values\n"); 577 PrintF(" use register name 'rN' to display register number 'N'\n"); 578 PrintF(" add argument 'fp' to print register pair double values\n"); 579 PrintF( 580 " use register name 'allf' to display floating-point " 581 "registers\n"); 582 PrintF("printobject <register>\n"); 583 PrintF(" print an object from a register (alias 'po')\n"); 584 PrintF("cr\n"); 585 PrintF(" print condition register\n"); 586 PrintF("stack [<num words>]\n"); 587 PrintF(" dump stack content, default dump 10 words)\n"); 588 PrintF("mem <address> [<num words>]\n"); 589 PrintF(" dump memory content, default dump 10 words)\n"); 590 PrintF("disasm [<instructions>]\n"); 591 PrintF("disasm [<address/register>]\n"); 592 PrintF("disasm [[<address/register>] <instructions>]\n"); 593 PrintF(" disassemble code, default is 10 instructions\n"); 594 PrintF(" from pc (alias 'di')\n"); 595 PrintF("gdb\n"); 596 PrintF(" enter gdb\n"); 597 PrintF("break <address>\n"); 598 PrintF(" set a break point on the address\n"); 599 PrintF("del\n"); 600 PrintF(" delete the breakpoint\n"); 601 PrintF("trace (alias 't')\n"); 602 PrintF(" toogle the tracing of all executed statements\n"); 603 PrintF("stop feature:\n"); 604 PrintF(" Description:\n"); 605 PrintF(" Stops are debug instructions inserted by\n"); 606 PrintF(" the Assembler::stop() function.\n"); 607 PrintF(" When hitting a stop, the Simulator will\n"); 608 PrintF(" stop and give control to the S390Debugger.\n"); 609 PrintF(" The first %d stop codes are watched:\n", 610 Simulator::kNumOfWatchedStops); 611 PrintF(" - They can be enabled / disabled: the Simulator\n"); 612 PrintF(" will / won't stop when hitting them.\n"); 613 PrintF(" - The Simulator keeps track of how many times they \n"); 614 PrintF(" are met. (See the info command.) Going over a\n"); 615 PrintF(" disabled stop still increases its counter. \n"); 616 PrintF(" Commands:\n"); 617 PrintF(" stop info all/<code> : print infos about number <code>\n"); 618 PrintF(" or all stop(s).\n"); 619 PrintF(" stop enable/disable all/<code> : enables / disables\n"); 620 PrintF(" all or number <code> stop(s)\n"); 621 PrintF(" stop unstop\n"); 622 PrintF(" ignore the stop instruction at the current location\n"); 623 PrintF(" from now on\n"); 624 } else { 625 PrintF("Unknown command: %s\n", cmd); 626 } 627 } 628 } 629 630 // Add all the breakpoints back to stop execution and enter the debugger 631 // shell when hit. 632 RedoBreakpoints(); 633 // Restore tracing 634 ::v8::internal::FLAG_trace_sim = trace; 635 636 #undef COMMAND_SIZE 637 #undef ARG_SIZE 638 639 #undef STR 640 #undef XSTR 641 } 642 643 bool Simulator::ICacheMatch(void* one, void* two) { 644 DCHECK_EQ(reinterpret_cast<intptr_t>(one) & CachePage::kPageMask, 0); 645 DCHECK_EQ(reinterpret_cast<intptr_t>(two) & CachePage::kPageMask, 0); 646 return one == two; 647 } 648 649 static uint32_t ICacheHash(void* key) { 650 return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)) >> 2; 651 } 652 653 static bool AllOnOnePage(uintptr_t start, int size) { 654 intptr_t start_page = (start & ~CachePage::kPageMask); 655 intptr_t end_page = ((start + size) & ~CachePage::kPageMask); 656 return start_page == end_page; 657 } 658 659 void Simulator::set_last_debugger_input(char* input) { 660 DeleteArray(last_debugger_input_); 661 last_debugger_input_ = input; 662 } 663 664 void Simulator::SetRedirectInstruction(Instruction* instruction) { 665 // we use TRAP4 here (0xBF22) 666 #if V8_TARGET_LITTLE_ENDIAN 667 instruction->SetInstructionBits(0x1000FFB2); 668 #else 669 instruction->SetInstructionBits(0xB2FF0000 | kCallRtRedirected); 670 #endif 671 } 672 673 void Simulator::FlushICache(base::CustomMatcherHashMap* i_cache, 674 void* start_addr, size_t size) { 675 intptr_t start = reinterpret_cast<intptr_t>(start_addr); 676 int intra_line = (start & CachePage::kLineMask); 677 start -= intra_line; 678 size += intra_line; 679 size = ((size - 1) | CachePage::kLineMask) + 1; 680 int offset = (start & CachePage::kPageMask); 681 while (!AllOnOnePage(start, size - 1)) { 682 int bytes_to_flush = CachePage::kPageSize - offset; 683 FlushOnePage(i_cache, start, bytes_to_flush); 684 start += bytes_to_flush; 685 size -= bytes_to_flush; 686 DCHECK_EQ(0, static_cast<int>(start & CachePage::kPageMask)); 687 offset = 0; 688 } 689 if (size != 0) { 690 FlushOnePage(i_cache, start, size); 691 } 692 } 693 694 CachePage* Simulator::GetCachePage(base::CustomMatcherHashMap* i_cache, 695 void* page) { 696 base::HashMap::Entry* entry = i_cache->LookupOrInsert(page, ICacheHash(page)); 697 if (entry->value == nullptr) { 698 CachePage* new_page = new CachePage(); 699 entry->value = new_page; 700 } 701 return reinterpret_cast<CachePage*>(entry->value); 702 } 703 704 // Flush from start up to and not including start + size. 705 void Simulator::FlushOnePage(base::CustomMatcherHashMap* i_cache, 706 intptr_t start, int size) { 707 DCHECK_LE(size, CachePage::kPageSize); 708 DCHECK(AllOnOnePage(start, size - 1)); 709 DCHECK_EQ(start & CachePage::kLineMask, 0); 710 DCHECK_EQ(size & CachePage::kLineMask, 0); 711 void* page = reinterpret_cast<void*>(start & (~CachePage::kPageMask)); 712 int offset = (start & CachePage::kPageMask); 713 CachePage* cache_page = GetCachePage(i_cache, page); 714 char* valid_bytemap = cache_page->ValidityByte(offset); 715 memset(valid_bytemap, CachePage::LINE_INVALID, size >> CachePage::kLineShift); 716 } 717 718 void Simulator::CheckICache(base::CustomMatcherHashMap* i_cache, 719 Instruction* instr) { 720 intptr_t address = reinterpret_cast<intptr_t>(instr); 721 void* page = reinterpret_cast<void*>(address & (~CachePage::kPageMask)); 722 void* line = reinterpret_cast<void*>(address & (~CachePage::kLineMask)); 723 int offset = (address & CachePage::kPageMask); 724 CachePage* cache_page = GetCachePage(i_cache, page); 725 char* cache_valid_byte = cache_page->ValidityByte(offset); 726 bool cache_hit = (*cache_valid_byte == CachePage::LINE_VALID); 727 char* cached_line = cache_page->CachedData(offset & ~CachePage::kLineMask); 728 if (cache_hit) { 729 // Check that the data in memory matches the contents of the I-cache. 730 CHECK_EQ(memcmp(reinterpret_cast<void*>(instr), 731 cache_page->CachedData(offset), sizeof(FourByteInstr)), 732 0); 733 } else { 734 // Cache miss. Load memory into the cache. 735 memcpy(cached_line, line, CachePage::kLineLength); 736 *cache_valid_byte = CachePage::LINE_VALID; 737 } 738 } 739 740 Simulator::EvaluateFuncType Simulator::EvalTable[] = {nullptr}; 741 742 void Simulator::EvalTableInit() { 743 for (int i = 0; i < MAX_NUM_OPCODES; i++) { 744 EvalTable[i] = &Simulator::Evaluate_Unknown; 745 } 746 747 #define S390_SUPPORTED_VECTOR_OPCODE_LIST(V) \ 748 V(vfs, VFS, 0xE7E2) /* type = VRR_C VECTOR FP SUBTRACT */ \ 749 V(vfa, VFA, 0xE7E3) /* type = VRR_C VECTOR FP ADD */ \ 750 V(vfd, VFD, 0xE7E5) /* type = VRR_C VECTOR FP DIVIDE */ \ 751 V(vfm, VFM, 0xE7E7) /* type = VRR_C VECTOR FP MULTIPLY */ 752 753 #define CREATE_EVALUATE_TABLE(name, op_name, op_value) \ 754 EvalTable[op_name] = &Simulator::Evaluate_##op_name; 755 S390_SUPPORTED_VECTOR_OPCODE_LIST(CREATE_EVALUATE_TABLE); 756 #undef CREATE_EVALUATE_TABLE 757 758 EvalTable[DUMY] = &Simulator::Evaluate_DUMY; 759 EvalTable[BKPT] = &Simulator::Evaluate_BKPT; 760 EvalTable[SPM] = &Simulator::Evaluate_SPM; 761 EvalTable[BALR] = &Simulator::Evaluate_BALR; 762 EvalTable[BCTR] = &Simulator::Evaluate_BCTR; 763 EvalTable[BCR] = &Simulator::Evaluate_BCR; 764 EvalTable[SVC] = &Simulator::Evaluate_SVC; 765 EvalTable[BSM] = &Simulator::Evaluate_BSM; 766 EvalTable[BASSM] = &Simulator::Evaluate_BASSM; 767 EvalTable[BASR] = &Simulator::Evaluate_BASR; 768 EvalTable[MVCL] = &Simulator::Evaluate_MVCL; 769 EvalTable[CLCL] = &Simulator::Evaluate_CLCL; 770 EvalTable[LPR] = &Simulator::Evaluate_LPR; 771 EvalTable[LNR] = &Simulator::Evaluate_LNR; 772 EvalTable[LTR] = &Simulator::Evaluate_LTR; 773 EvalTable[LCR] = &Simulator::Evaluate_LCR; 774 EvalTable[NR] = &Simulator::Evaluate_NR; 775 EvalTable[CLR] = &Simulator::Evaluate_CLR; 776 EvalTable[OR] = &Simulator::Evaluate_OR; 777 EvalTable[XR] = &Simulator::Evaluate_XR; 778 EvalTable[LR] = &Simulator::Evaluate_LR; 779 EvalTable[CR] = &Simulator::Evaluate_CR; 780 EvalTable[AR] = &Simulator::Evaluate_AR; 781 EvalTable[SR] = &Simulator::Evaluate_SR; 782 EvalTable[MR] = &Simulator::Evaluate_MR; 783 EvalTable[DR] = &Simulator::Evaluate_DR; 784 EvalTable[ALR] = &Simulator::Evaluate_ALR; 785 EvalTable[SLR] = &Simulator::Evaluate_SLR; 786 EvalTable[LDR] = &Simulator::Evaluate_LDR; 787 EvalTable[CDR] = &Simulator::Evaluate_CDR; 788 EvalTable[LER] = &Simulator::Evaluate_LER; 789 EvalTable[STH] = &Simulator::Evaluate_STH; 790 EvalTable[LA] = &Simulator::Evaluate_LA; 791 EvalTable[STC] = &Simulator::Evaluate_STC; 792 EvalTable[IC_z] = &Simulator::Evaluate_IC_z; 793 EvalTable[EX] = &Simulator::Evaluate_EX; 794 EvalTable[BAL] = &Simulator::Evaluate_BAL; 795 EvalTable[BCT] = &Simulator::Evaluate_BCT; 796 EvalTable[BC] = &Simulator::Evaluate_BC; 797 EvalTable[LH] = &Simulator::Evaluate_LH; 798 EvalTable[CH] = &Simulator::Evaluate_CH; 799 EvalTable[AH] = &Simulator::Evaluate_AH; 800 EvalTable[SH] = &Simulator::Evaluate_SH; 801 EvalTable[MH] = &Simulator::Evaluate_MH; 802 EvalTable[BAS] = &Simulator::Evaluate_BAS; 803 EvalTable[CVD] = &Simulator::Evaluate_CVD; 804 EvalTable[CVB] = &Simulator::Evaluate_CVB; 805 EvalTable[ST] = &Simulator::Evaluate_ST; 806 EvalTable[LAE] = &Simulator::Evaluate_LAE; 807 EvalTable[N] = &Simulator::Evaluate_N; 808 EvalTable[CL] = &Simulator::Evaluate_CL; 809 EvalTable[O] = &Simulator::Evaluate_O; 810 EvalTable[X] = &Simulator::Evaluate_X; 811 EvalTable[L] = &Simulator::Evaluate_L; 812 EvalTable[C] = &Simulator::Evaluate_C; 813 EvalTable[A] = &Simulator::Evaluate_A; 814 EvalTable[S] = &Simulator::Evaluate_S; 815 EvalTable[M] = &Simulator::Evaluate_M; 816 EvalTable[D] = &Simulator::Evaluate_D; 817 EvalTable[AL] = &Simulator::Evaluate_AL; 818 EvalTable[SL] = &Simulator::Evaluate_SL; 819 EvalTable[STD] = &Simulator::Evaluate_STD; 820 EvalTable[LD] = &Simulator::Evaluate_LD; 821 EvalTable[CD] = &Simulator::Evaluate_CD; 822 EvalTable[STE] = &Simulator::Evaluate_STE; 823 EvalTable[MS] = &Simulator::Evaluate_MS; 824 EvalTable[LE] = &Simulator::Evaluate_LE; 825 EvalTable[BRXH] = &Simulator::Evaluate_BRXH; 826 EvalTable[BRXLE] = &Simulator::Evaluate_BRXLE; 827 EvalTable[BXH] = &Simulator::Evaluate_BXH; 828 EvalTable[BXLE] = &Simulator::Evaluate_BXLE; 829 EvalTable[SRL] = &Simulator::Evaluate_SRL; 830 EvalTable[SLL] = &Simulator::Evaluate_SLL; 831 EvalTable[SRA] = &Simulator::Evaluate_SRA; 832 EvalTable[SLA] = &Simulator::Evaluate_SLA; 833 EvalTable[SRDL] = &Simulator::Evaluate_SRDL; 834 EvalTable[SLDL] = &Simulator::Evaluate_SLDL; 835 EvalTable[SRDA] = &Simulator::Evaluate_SRDA; 836 EvalTable[SLDA] = &Simulator::Evaluate_SLDA; 837 EvalTable[STM] = &Simulator::Evaluate_STM; 838 EvalTable[TM] = &Simulator::Evaluate_TM; 839 EvalTable[MVI] = &Simulator::Evaluate_MVI; 840 EvalTable[TS] = &Simulator::Evaluate_TS; 841 EvalTable[NI] = &Simulator::Evaluate_NI; 842 EvalTable[CLI] = &Simulator::Evaluate_CLI; 843 EvalTable[OI] = &Simulator::Evaluate_OI; 844 EvalTable[XI] = &Simulator::Evaluate_XI; 845 EvalTable[LM] = &Simulator::Evaluate_LM; 846 EvalTable[CS] = &Simulator::Evaluate_CS; 847 EvalTable[MVCLE] = &Simulator::Evaluate_MVCLE; 848 EvalTable[CLCLE] = &Simulator::Evaluate_CLCLE; 849 EvalTable[MC] = &Simulator::Evaluate_MC; 850 EvalTable[CDS] = &Simulator::Evaluate_CDS; 851 EvalTable[STCM] = &Simulator::Evaluate_STCM; 852 EvalTable[ICM] = &Simulator::Evaluate_ICM; 853 EvalTable[BPRP] = &Simulator::Evaluate_BPRP; 854 EvalTable[BPP] = &Simulator::Evaluate_BPP; 855 EvalTable[TRTR] = &Simulator::Evaluate_TRTR; 856 EvalTable[MVN] = &Simulator::Evaluate_MVN; 857 EvalTable[MVC] = &Simulator::Evaluate_MVC; 858 EvalTable[MVZ] = &Simulator::Evaluate_MVZ; 859 EvalTable[NC] = &Simulator::Evaluate_NC; 860 EvalTable[CLC] = &Simulator::Evaluate_CLC; 861 EvalTable[OC] = &Simulator::Evaluate_OC; 862 EvalTable[XC] = &Simulator::Evaluate_XC; 863 EvalTable[MVCP] = &Simulator::Evaluate_MVCP; 864 EvalTable[TR] = &Simulator::Evaluate_TR; 865 EvalTable[TRT] = &Simulator::Evaluate_TRT; 866 EvalTable[ED] = &Simulator::Evaluate_ED; 867 EvalTable[EDMK] = &Simulator::Evaluate_EDMK; 868 EvalTable[PKU] = &Simulator::Evaluate_PKU; 869 EvalTable[UNPKU] = &Simulator::Evaluate_UNPKU; 870 EvalTable[MVCIN] = &Simulator::Evaluate_MVCIN; 871 EvalTable[PKA] = &Simulator::Evaluate_PKA; 872 EvalTable[UNPKA] = &Simulator::Evaluate_UNPKA; 873 EvalTable[PLO] = &Simulator::Evaluate_PLO; 874 EvalTable[LMD] = &Simulator::Evaluate_LMD; 875 EvalTable[SRP] = &Simulator::Evaluate_SRP; 876 EvalTable[MVO] = &Simulator::Evaluate_MVO; 877 EvalTable[PACK] = &Simulator::Evaluate_PACK; 878 EvalTable[UNPK] = &Simulator::Evaluate_UNPK; 879 EvalTable[ZAP] = &Simulator::Evaluate_ZAP; 880 EvalTable[AP] = &Simulator::Evaluate_AP; 881 EvalTable[SP] = &Simulator::Evaluate_SP; 882 EvalTable[MP] = &Simulator::Evaluate_MP; 883 EvalTable[DP] = &Simulator::Evaluate_DP; 884 EvalTable[UPT] = &Simulator::Evaluate_UPT; 885 EvalTable[PFPO] = &Simulator::Evaluate_PFPO; 886 EvalTable[IIHH] = &Simulator::Evaluate_IIHH; 887 EvalTable[IIHL] = &Simulator::Evaluate_IIHL; 888 EvalTable[IILH] = &Simulator::Evaluate_IILH; 889 EvalTable[IILL] = &Simulator::Evaluate_IILL; 890 EvalTable[NIHH] = &Simulator::Evaluate_NIHH; 891 EvalTable[NIHL] = &Simulator::Evaluate_NIHL; 892 EvalTable[NILH] = &Simulator::Evaluate_NILH; 893 EvalTable[NILL] = &Simulator::Evaluate_NILL; 894 EvalTable[OIHH] = &Simulator::Evaluate_OIHH; 895 EvalTable[OIHL] = &Simulator::Evaluate_OIHL; 896 EvalTable[OILH] = &Simulator::Evaluate_OILH; 897 EvalTable[OILL] = &Simulator::Evaluate_OILL; 898 EvalTable[LLIHH] = &Simulator::Evaluate_LLIHH; 899 EvalTable[LLIHL] = &Simulator::Evaluate_LLIHL; 900 EvalTable[LLILH] = &Simulator::Evaluate_LLILH; 901 EvalTable[LLILL] = &Simulator::Evaluate_LLILL; 902 EvalTable[TMLH] = &Simulator::Evaluate_TMLH; 903 EvalTable[TMLL] = &Simulator::Evaluate_TMLL; 904 EvalTable[TMHH] = &Simulator::Evaluate_TMHH; 905 EvalTable[TMHL] = &Simulator::Evaluate_TMHL; 906 EvalTable[BRC] = &Simulator::Evaluate_BRC; 907 EvalTable[BRAS] = &Simulator::Evaluate_BRAS; 908 EvalTable[BRCT] = &Simulator::Evaluate_BRCT; 909 EvalTable[BRCTG] = &Simulator::Evaluate_BRCTG; 910 EvalTable[LHI] = &Simulator::Evaluate_LHI; 911 EvalTable[LGHI] = &Simulator::Evaluate_LGHI; 912 EvalTable[AHI] = &Simulator::Evaluate_AHI; 913 EvalTable[AGHI] = &Simulator::Evaluate_AGHI; 914 EvalTable[MHI] = &Simulator::Evaluate_MHI; 915 EvalTable[MGHI] = &Simulator::Evaluate_MGHI; 916 EvalTable[CHI] = &Simulator::Evaluate_CHI; 917 EvalTable[CGHI] = &Simulator::Evaluate_CGHI; 918 EvalTable[LARL] = &Simulator::Evaluate_LARL; 919 EvalTable[LGFI] = &Simulator::Evaluate_LGFI; 920 EvalTable[BRCL] = &Simulator::Evaluate_BRCL; 921 EvalTable[BRASL] = &Simulator::Evaluate_BRASL; 922 EvalTable[XIHF] = &Simulator::Evaluate_XIHF; 923 EvalTable[XILF] = &Simulator::Evaluate_XILF; 924 EvalTable[IIHF] = &Simulator::Evaluate_IIHF; 925 EvalTable[IILF] = &Simulator::Evaluate_IILF; 926 EvalTable[NIHF] = &Simulator::Evaluate_NIHF; 927 EvalTable[NILF] = &Simulator::Evaluate_NILF; 928 EvalTable[OIHF] = &Simulator::Evaluate_OIHF; 929 EvalTable[OILF] = &Simulator::Evaluate_OILF; 930 EvalTable[LLIHF] = &Simulator::Evaluate_LLIHF; 931 EvalTable[LLILF] = &Simulator::Evaluate_LLILF; 932 EvalTable[MSGFI] = &Simulator::Evaluate_MSGFI; 933 EvalTable[MSFI] = &Simulator::Evaluate_MSFI; 934 EvalTable[SLGFI] = &Simulator::Evaluate_SLGFI; 935 EvalTable[SLFI] = &Simulator::Evaluate_SLFI; 936 EvalTable[AGFI] = &Simulator::Evaluate_AGFI; 937 EvalTable[AFI] = &Simulator::Evaluate_AFI; 938 EvalTable[ALGFI] = &Simulator::Evaluate_ALGFI; 939 EvalTable[ALFI] = &Simulator::Evaluate_ALFI; 940 EvalTable[CGFI] = &Simulator::Evaluate_CGFI; 941 EvalTable[CFI] = &Simulator::Evaluate_CFI; 942 EvalTable[CLGFI] = &Simulator::Evaluate_CLGFI; 943 EvalTable[CLFI] = &Simulator::Evaluate_CLFI; 944 EvalTable[LLHRL] = &Simulator::Evaluate_LLHRL; 945 EvalTable[LGHRL] = &Simulator::Evaluate_LGHRL; 946 EvalTable[LHRL] = &Simulator::Evaluate_LHRL; 947 EvalTable[LLGHRL] = &Simulator::Evaluate_LLGHRL; 948 EvalTable[STHRL] = &Simulator::Evaluate_STHRL; 949 EvalTable[LGRL] = &Simulator::Evaluate_LGRL; 950 EvalTable[STGRL] = &Simulator::Evaluate_STGRL; 951 EvalTable[LGFRL] = &Simulator::Evaluate_LGFRL; 952 EvalTable[LRL] = &Simulator::Evaluate_LRL; 953 EvalTable[LLGFRL] = &Simulator::Evaluate_LLGFRL; 954 EvalTable[STRL] = &Simulator::Evaluate_STRL; 955 EvalTable[EXRL] = &Simulator::Evaluate_EXRL; 956 EvalTable[PFDRL] = &Simulator::Evaluate_PFDRL; 957 EvalTable[CGHRL] = &Simulator::Evaluate_CGHRL; 958 EvalTable[CHRL] = &Simulator::Evaluate_CHRL; 959 EvalTable[CGRL] = &Simulator::Evaluate_CGRL; 960 EvalTable[CGFRL] = &Simulator::Evaluate_CGFRL; 961 EvalTable[ECTG] = &Simulator::Evaluate_ECTG; 962 EvalTable[CSST] = &Simulator::Evaluate_CSST; 963 EvalTable[LPD] = &Simulator::Evaluate_LPD; 964 EvalTable[LPDG] = &Simulator::Evaluate_LPDG; 965 EvalTable[BRCTH] = &Simulator::Evaluate_BRCTH; 966 EvalTable[AIH] = &Simulator::Evaluate_AIH; 967 EvalTable[ALSIH] = &Simulator::Evaluate_ALSIH; 968 EvalTable[ALSIHN] = &Simulator::Evaluate_ALSIHN; 969 EvalTable[CIH] = &Simulator::Evaluate_CIH; 970 EvalTable[CLIH] = &Simulator::Evaluate_CLIH; 971 EvalTable[STCK] = &Simulator::Evaluate_STCK; 972 EvalTable[CFC] = &Simulator::Evaluate_CFC; 973 EvalTable[IPM] = &Simulator::Evaluate_IPM; 974 EvalTable[HSCH] = &Simulator::Evaluate_HSCH; 975 EvalTable[MSCH] = &Simulator::Evaluate_MSCH; 976 EvalTable[SSCH] = &Simulator::Evaluate_SSCH; 977 EvalTable[STSCH] = &Simulator::Evaluate_STSCH; 978 EvalTable[TSCH] = &Simulator::Evaluate_TSCH; 979 EvalTable[TPI] = &Simulator::Evaluate_TPI; 980 EvalTable[SAL] = &Simulator::Evaluate_SAL; 981 EvalTable[RSCH] = &Simulator::Evaluate_RSCH; 982 EvalTable[STCRW] = &Simulator::Evaluate_STCRW; 983 EvalTable[STCPS] = &Simulator::Evaluate_STCPS; 984 EvalTable[RCHP] = &Simulator::Evaluate_RCHP; 985 EvalTable[SCHM] = &Simulator::Evaluate_SCHM; 986 EvalTable[CKSM] = &Simulator::Evaluate_CKSM; 987 EvalTable[SAR] = &Simulator::Evaluate_SAR; 988 EvalTable[EAR] = &Simulator::Evaluate_EAR; 989 EvalTable[MSR] = &Simulator::Evaluate_MSR; 990 EvalTable[MSRKC] = &Simulator::Evaluate_MSRKC; 991 EvalTable[MVST] = &Simulator::Evaluate_MVST; 992 EvalTable[CUSE] = &Simulator::Evaluate_CUSE; 993 EvalTable[SRST] = &Simulator::Evaluate_SRST; 994 EvalTable[XSCH] = &Simulator::Evaluate_XSCH; 995 EvalTable[STCKE] = &Simulator::Evaluate_STCKE; 996 EvalTable[STCKF] = &Simulator::Evaluate_STCKF; 997 EvalTable[SRNM] = &Simulator::Evaluate_SRNM; 998 EvalTable[STFPC] = &Simulator::Evaluate_STFPC; 999 EvalTable[LFPC] = &Simulator::Evaluate_LFPC; 1000 EvalTable[TRE] = &Simulator::Evaluate_TRE; 1001 EvalTable[STFLE] = &Simulator::Evaluate_STFLE; 1002 EvalTable[SRNMB] = &Simulator::Evaluate_SRNMB; 1003 EvalTable[SRNMT] = &Simulator::Evaluate_SRNMT; 1004 EvalTable[LFAS] = &Simulator::Evaluate_LFAS; 1005 EvalTable[PPA] = &Simulator::Evaluate_PPA; 1006 EvalTable[ETND] = &Simulator::Evaluate_ETND; 1007 EvalTable[TEND] = &Simulator::Evaluate_TEND; 1008 EvalTable[NIAI] = &Simulator::Evaluate_NIAI; 1009 EvalTable[TABORT] = &Simulator::Evaluate_TABORT; 1010 EvalTable[TRAP4] = &Simulator::Evaluate_TRAP4; 1011 EvalTable[LPEBR] = &Simulator::Evaluate_LPEBR; 1012 EvalTable[LNEBR] = &Simulator::Evaluate_LNEBR; 1013 EvalTable[LTEBR] = &Simulator::Evaluate_LTEBR; 1014 EvalTable[LCEBR] = &Simulator::Evaluate_LCEBR; 1015 EvalTable[LDEBR] = &Simulator::Evaluate_LDEBR; 1016 EvalTable[LXDBR] = &Simulator::Evaluate_LXDBR; 1017 EvalTable[LXEBR] = &Simulator::Evaluate_LXEBR; 1018 EvalTable[MXDBR] = &Simulator::Evaluate_MXDBR; 1019 EvalTable[KEBR] = &Simulator::Evaluate_KEBR; 1020 EvalTable[CEBR] = &Simulator::Evaluate_CEBR; 1021 EvalTable[AEBR] = &Simulator::Evaluate_AEBR; 1022 EvalTable[SEBR] = &Simulator::Evaluate_SEBR; 1023 EvalTable[MDEBR] = &Simulator::Evaluate_MDEBR; 1024 EvalTable[DEBR] = &Simulator::Evaluate_DEBR; 1025 EvalTable[MAEBR] = &Simulator::Evaluate_MAEBR; 1026 EvalTable[MSEBR] = &Simulator::Evaluate_MSEBR; 1027 EvalTable[LPDBR] = &Simulator::Evaluate_LPDBR; 1028 EvalTable[LNDBR] = &Simulator::Evaluate_LNDBR; 1029 EvalTable[LTDBR] = &Simulator::Evaluate_LTDBR; 1030 EvalTable[LCDBR] = &Simulator::Evaluate_LCDBR; 1031 EvalTable[SQEBR] = &Simulator::Evaluate_SQEBR; 1032 EvalTable[SQDBR] = &Simulator::Evaluate_SQDBR; 1033 EvalTable[SQXBR] = &Simulator::Evaluate_SQXBR; 1034 EvalTable[MEEBR] = &Simulator::Evaluate_MEEBR; 1035 EvalTable[KDBR] = &Simulator::Evaluate_KDBR; 1036 EvalTable[CDBR] = &Simulator::Evaluate_CDBR; 1037 EvalTable[ADBR] = &Simulator::Evaluate_ADBR; 1038 EvalTable[SDBR] = &Simulator::Evaluate_SDBR; 1039 EvalTable[MDBR] = &Simulator::Evaluate_MDBR; 1040 EvalTable[DDBR] = &Simulator::Evaluate_DDBR; 1041 EvalTable[MADBR] = &Simulator::Evaluate_MADBR; 1042 EvalTable[MSDBR] = &Simulator::Evaluate_MSDBR; 1043 EvalTable[LPXBR] = &Simulator::Evaluate_LPXBR; 1044 EvalTable[LNXBR] = &Simulator::Evaluate_LNXBR; 1045 EvalTable[LTXBR] = &Simulator::Evaluate_LTXBR; 1046 EvalTable[LCXBR] = &Simulator::Evaluate_LCXBR; 1047 EvalTable[LEDBRA] = &Simulator::Evaluate_LEDBRA; 1048 EvalTable[LDXBRA] = &Simulator::Evaluate_LDXBRA; 1049 EvalTable[LEXBRA] = &Simulator::Evaluate_LEXBRA; 1050 EvalTable[FIXBRA] = &Simulator::Evaluate_FIXBRA; 1051 EvalTable[KXBR] = &Simulator::Evaluate_KXBR; 1052 EvalTable[CXBR] = &Simulator::Evaluate_CXBR; 1053 EvalTable[AXBR] = &Simulator::Evaluate_AXBR; 1054 EvalTable[SXBR] = &Simulator::Evaluate_SXBR; 1055 EvalTable[MXBR] = &Simulator::Evaluate_MXBR; 1056 EvalTable[DXBR] = &Simulator::Evaluate_DXBR; 1057 EvalTable[TBEDR] = &Simulator::Evaluate_TBEDR; 1058 EvalTable[TBDR] = &Simulator::Evaluate_TBDR; 1059 EvalTable[DIEBR] = &Simulator::Evaluate_DIEBR; 1060 EvalTable[FIEBRA] = &Simulator::Evaluate_FIEBRA; 1061 EvalTable[THDER] = &Simulator::Evaluate_THDER; 1062 EvalTable[THDR] = &Simulator::Evaluate_THDR; 1063 EvalTable[DIDBR] = &Simulator::Evaluate_DIDBR; 1064 EvalTable[FIDBRA] = &Simulator::Evaluate_FIDBRA; 1065 EvalTable[LXR] = &Simulator::Evaluate_LXR; 1066 EvalTable[LPDFR] = &Simulator::Evaluate_LPDFR; 1067 EvalTable[LNDFR] = &Simulator::Evaluate_LNDFR; 1068 EvalTable[LCDFR] = &Simulator::Evaluate_LCDFR; 1069 EvalTable[LZER] = &Simulator::Evaluate_LZER; 1070 EvalTable[LZDR] = &Simulator::Evaluate_LZDR; 1071 EvalTable[LZXR] = &Simulator::Evaluate_LZXR; 1072 EvalTable[SFPC] = &Simulator::Evaluate_SFPC; 1073 EvalTable[SFASR] = &Simulator::Evaluate_SFASR; 1074 EvalTable[EFPC] = &Simulator::Evaluate_EFPC; 1075 EvalTable[CELFBR] = &Simulator::Evaluate_CELFBR; 1076 EvalTable[CDLFBR] = &Simulator::Evaluate_CDLFBR; 1077 EvalTable[CXLFBR] = &Simulator::Evaluate_CXLFBR; 1078 EvalTable[CEFBRA] = &Simulator::Evaluate_CEFBRA; 1079 EvalTable[CDFBRA] = &Simulator::Evaluate_CDFBRA; 1080 EvalTable[CXFBRA] = &Simulator::Evaluate_CXFBRA; 1081 EvalTable[CFEBRA] = &Simulator::Evaluate_CFEBRA; 1082 EvalTable[CFDBRA] = &Simulator::Evaluate_CFDBRA; 1083 EvalTable[CFXBRA] = &Simulator::Evaluate_CFXBRA; 1084 EvalTable[CLFEBR] = &Simulator::Evaluate_CLFEBR; 1085 EvalTable[CLFDBR] = &Simulator::Evaluate_CLFDBR; 1086 EvalTable[CLFXBR] = &Simulator::Evaluate_CLFXBR; 1087 EvalTable[CELGBR] = &Simulator::Evaluate_CELGBR; 1088 EvalTable[CDLGBR] = &Simulator::Evaluate_CDLGBR; 1089 EvalTable[CXLGBR] = &Simulator::Evaluate_CXLGBR; 1090 EvalTable[CEGBRA] = &Simulator::Evaluate_CEGBRA; 1091 EvalTable[CDGBRA] = &Simulator::Evaluate_CDGBRA; 1092 EvalTable[CXGBRA] = &Simulator::Evaluate_CXGBRA; 1093 EvalTable[CGEBRA] = &Simulator::Evaluate_CGEBRA; 1094 EvalTable[CGDBRA] = &Simulator::Evaluate_CGDBRA; 1095 EvalTable[CGXBRA] = &Simulator::Evaluate_CGXBRA; 1096 EvalTable[CLGEBR] = &Simulator::Evaluate_CLGEBR; 1097 EvalTable[CLGDBR] = &Simulator::Evaluate_CLGDBR; 1098 EvalTable[CFER] = &Simulator::Evaluate_CFER; 1099 EvalTable[CFDR] = &Simulator::Evaluate_CFDR; 1100 EvalTable[CFXR] = &Simulator::Evaluate_CFXR; 1101 EvalTable[LDGR] = &Simulator::Evaluate_LDGR; 1102 EvalTable[CGER] = &Simulator::Evaluate_CGER; 1103 EvalTable[CGDR] = &Simulator::Evaluate_CGDR; 1104 EvalTable[CGXR] = &Simulator::Evaluate_CGXR; 1105 EvalTable[LGDR] = &Simulator::Evaluate_LGDR; 1106 EvalTable[MDTRA] = &Simulator::Evaluate_MDTRA; 1107 EvalTable[DDTRA] = &Simulator::Evaluate_DDTRA; 1108 EvalTable[ADTRA] = &Simulator::Evaluate_ADTRA; 1109 EvalTable[SDTRA] = &Simulator::Evaluate_SDTRA; 1110 EvalTable[LDETR] = &Simulator::Evaluate_LDETR; 1111 EvalTable[LEDTR] = &Simulator::Evaluate_LEDTR; 1112 EvalTable[LTDTR] = &Simulator::Evaluate_LTDTR; 1113 EvalTable[FIDTR] = &Simulator::Evaluate_FIDTR; 1114 EvalTable[MXTRA] = &Simulator::Evaluate_MXTRA; 1115 EvalTable[DXTRA] = &Simulator::Evaluate_DXTRA; 1116 EvalTable[AXTRA] = &Simulator::Evaluate_AXTRA; 1117 EvalTable[SXTRA] = &Simulator::Evaluate_SXTRA; 1118 EvalTable[LXDTR] = &Simulator::Evaluate_LXDTR; 1119 EvalTable[LDXTR] = &Simulator::Evaluate_LDXTR; 1120 EvalTable[LTXTR] = &Simulator::Evaluate_LTXTR; 1121 EvalTable[FIXTR] = &Simulator::Evaluate_FIXTR; 1122 EvalTable[KDTR] = &Simulator::Evaluate_KDTR; 1123 EvalTable[CGDTRA] = &Simulator::Evaluate_CGDTRA; 1124 EvalTable[CUDTR] = &Simulator::Evaluate_CUDTR; 1125 EvalTable[CDTR] = &Simulator::Evaluate_CDTR; 1126 EvalTable[EEDTR] = &Simulator::Evaluate_EEDTR; 1127 EvalTable[ESDTR] = &Simulator::Evaluate_ESDTR; 1128 EvalTable[KXTR] = &Simulator::Evaluate_KXTR; 1129 EvalTable[CGXTRA] = &Simulator::Evaluate_CGXTRA; 1130 EvalTable[CUXTR] = &Simulator::Evaluate_CUXTR; 1131 EvalTable[CSXTR] = &Simulator::Evaluate_CSXTR; 1132 EvalTable[CXTR] = &Simulator::Evaluate_CXTR; 1133 EvalTable[EEXTR] = &Simulator::Evaluate_EEXTR; 1134 EvalTable[ESXTR] = &Simulator::Evaluate_ESXTR; 1135 EvalTable[CDGTRA] = &Simulator::Evaluate_CDGTRA; 1136 EvalTable[CDUTR] = &Simulator::Evaluate_CDUTR; 1137 EvalTable[CDSTR] = &Simulator::Evaluate_CDSTR; 1138 EvalTable[CEDTR] = &Simulator::Evaluate_CEDTR; 1139 EvalTable[QADTR] = &Simulator::Evaluate_QADTR; 1140 EvalTable[IEDTR] = &Simulator::Evaluate_IEDTR; 1141 EvalTable[RRDTR] = &Simulator::Evaluate_RRDTR; 1142 EvalTable[CXGTRA] = &Simulator::Evaluate_CXGTRA; 1143 EvalTable[CXUTR] = &Simulator::Evaluate_CXUTR; 1144 EvalTable[CXSTR] = &Simulator::Evaluate_CXSTR; 1145 EvalTable[CEXTR] = &Simulator::Evaluate_CEXTR; 1146 EvalTable[QAXTR] = &Simulator::Evaluate_QAXTR; 1147 EvalTable[IEXTR] = &Simulator::Evaluate_IEXTR; 1148 EvalTable[RRXTR] = &Simulator::Evaluate_RRXTR; 1149 EvalTable[LPGR] = &Simulator::Evaluate_LPGR; 1150 EvalTable[LNGR] = &Simulator::Evaluate_LNGR; 1151 EvalTable[LTGR] = &Simulator::Evaluate_LTGR; 1152 EvalTable[LCGR] = &Simulator::Evaluate_LCGR; 1153 EvalTable[LGR] = &Simulator::Evaluate_LGR; 1154 EvalTable[LGBR] = &Simulator::Evaluate_LGBR; 1155 EvalTable[LGHR] = &Simulator::Evaluate_LGHR; 1156 EvalTable[AGR] = &Simulator::Evaluate_AGR; 1157 EvalTable[SGR] = &Simulator::Evaluate_SGR; 1158 EvalTable[ALGR] = &Simulator::Evaluate_ALGR; 1159 EvalTable[SLGR] = &Simulator::Evaluate_SLGR; 1160 EvalTable[MSGR] = &Simulator::Evaluate_MSGR; 1161 EvalTable[MSGRKC] = &Simulator::Evaluate_MSGRKC; 1162 EvalTable[DSGR] = &Simulator::Evaluate_DSGR; 1163 EvalTable[LRVGR] = &Simulator::Evaluate_LRVGR; 1164 EvalTable[LPGFR] = &Simulator::Evaluate_LPGFR; 1165 EvalTable[LNGFR] = &Simulator::Evaluate_LNGFR; 1166 EvalTable[LTGFR] = &Simulator::Evaluate_LTGFR; 1167 EvalTable[LCGFR] = &Simulator::Evaluate_LCGFR; 1168 EvalTable[LGFR] = &Simulator::Evaluate_LGFR; 1169 EvalTable[LLGFR] = &Simulator::Evaluate_LLGFR; 1170 EvalTable[LLGTR] = &Simulator::Evaluate_LLGTR; 1171 EvalTable[AGFR] = &Simulator::Evaluate_AGFR; 1172 EvalTable[SGFR] = &Simulator::Evaluate_SGFR; 1173 EvalTable[ALGFR] = &Simulator::Evaluate_ALGFR; 1174 EvalTable[SLGFR] = &Simulator::Evaluate_SLGFR; 1175 EvalTable[MSGFR] = &Simulator::Evaluate_MSGFR; 1176 EvalTable[DSGFR] = &Simulator::Evaluate_DSGFR; 1177 EvalTable[KMAC] = &Simulator::Evaluate_KMAC; 1178 EvalTable[LRVR] = &Simulator::Evaluate_LRVR; 1179 EvalTable[CGR] = &Simulator::Evaluate_CGR; 1180 EvalTable[CLGR] = &Simulator::Evaluate_CLGR; 1181 EvalTable[LBR] = &Simulator::Evaluate_LBR; 1182 EvalTable[LHR] = &Simulator::Evaluate_LHR; 1183 EvalTable[KMF] = &Simulator::Evaluate_KMF; 1184 EvalTable[KMO] = &Simulator::Evaluate_KMO; 1185 EvalTable[PCC] = &Simulator::Evaluate_PCC; 1186 EvalTable[KMCTR] = &Simulator::Evaluate_KMCTR; 1187 EvalTable[KM] = &Simulator::Evaluate_KM; 1188 EvalTable[KMC] = &Simulator::Evaluate_KMC; 1189 EvalTable[CGFR] = &Simulator::Evaluate_CGFR; 1190 EvalTable[KIMD] = &Simulator::Evaluate_KIMD; 1191 EvalTable[KLMD] = &Simulator::Evaluate_KLMD; 1192 EvalTable[CFDTR] = &Simulator::Evaluate_CFDTR; 1193 EvalTable[CLGDTR] = &Simulator::Evaluate_CLGDTR; 1194 EvalTable[CLFDTR] = &Simulator::Evaluate_CLFDTR; 1195 EvalTable[BCTGR] = &Simulator::Evaluate_BCTGR; 1196 EvalTable[CFXTR] = &Simulator::Evaluate_CFXTR; 1197 EvalTable[CLFXTR] = &Simulator::Evaluate_CLFXTR; 1198 EvalTable[CDFTR] = &Simulator::Evaluate_CDFTR; 1199 EvalTable[CDLGTR] = &Simulator::Evaluate_CDLGTR; 1200 EvalTable[CDLFTR] = &Simulator::Evaluate_CDLFTR; 1201 EvalTable[CXFTR] = &Simulator::Evaluate_CXFTR; 1202 EvalTable[CXLGTR] = &Simulator::Evaluate_CXLGTR; 1203 EvalTable[CXLFTR] = &Simulator::Evaluate_CXLFTR; 1204 EvalTable[CGRT] = &Simulator::Evaluate_CGRT; 1205 EvalTable[NGR] = &Simulator::Evaluate_NGR; 1206 EvalTable[OGR] = &Simulator::Evaluate_OGR; 1207 EvalTable[XGR] = &Simulator::Evaluate_XGR; 1208 EvalTable[FLOGR] = &Simulator::Evaluate_FLOGR; 1209 EvalTable[LLGCR] = &Simulator::Evaluate_LLGCR; 1210 EvalTable[LLGHR] = &Simulator::Evaluate_LLGHR; 1211 EvalTable[MLGR] = &Simulator::Evaluate_MLGR; 1212 EvalTable[DLGR] = &Simulator::Evaluate_DLGR; 1213 EvalTable[ALCGR] = &Simulator::Evaluate_ALCGR; 1214 EvalTable[SLBGR] = &Simulator::Evaluate_SLBGR; 1215 EvalTable[EPSW] = &Simulator::Evaluate_EPSW; 1216 EvalTable[TRTT] = &Simulator::Evaluate_TRTT; 1217 EvalTable[TRTO] = &Simulator::Evaluate_TRTO; 1218 EvalTable[TROT] = &Simulator::Evaluate_TROT; 1219 EvalTable[TROO] = &Simulator::Evaluate_TROO; 1220 EvalTable[LLCR] = &Simulator::Evaluate_LLCR; 1221 EvalTable[LLHR] = &Simulator::Evaluate_LLHR; 1222 EvalTable[MLR] = &Simulator::Evaluate_MLR; 1223 EvalTable[DLR] = &Simulator::Evaluate_DLR; 1224 EvalTable[ALCR] = &Simulator::Evaluate_ALCR; 1225 EvalTable[SLBR] = &Simulator::Evaluate_SLBR; 1226 EvalTable[CU14] = &Simulator::Evaluate_CU14; 1227 EvalTable[CU24] = &Simulator::Evaluate_CU24; 1228 EvalTable[CU41] = &Simulator::Evaluate_CU41; 1229 EvalTable[CU42] = &Simulator::Evaluate_CU42; 1230 EvalTable[TRTRE] = &Simulator::Evaluate_TRTRE; 1231 EvalTable[SRSTU] = &Simulator::Evaluate_SRSTU; 1232 EvalTable[TRTE] = &Simulator::Evaluate_TRTE; 1233 EvalTable[AHHHR] = &Simulator::Evaluate_AHHHR; 1234 EvalTable[SHHHR] = &Simulator::Evaluate_SHHHR; 1235 EvalTable[ALHHHR] = &Simulator::Evaluate_ALHHHR; 1236 EvalTable[SLHHHR] = &Simulator::Evaluate_SLHHHR; 1237 EvalTable[CHHR] = &Simulator::Evaluate_CHHR; 1238 EvalTable[AHHLR] = &Simulator::Evaluate_AHHLR; 1239 EvalTable[SHHLR] = &Simulator::Evaluate_SHHLR; 1240 EvalTable[ALHHLR] = &Simulator::Evaluate_ALHHLR; 1241 EvalTable[SLHHLR] = &Simulator::Evaluate_SLHHLR; 1242 EvalTable[CHLR] = &Simulator::Evaluate_CHLR; 1243 EvalTable[POPCNT_Z] = &Simulator::Evaluate_POPCNT_Z; 1244 EvalTable[LOCGR] = &Simulator::Evaluate_LOCGR; 1245 EvalTable[NGRK] = &Simulator::Evaluate_NGRK; 1246 EvalTable[OGRK] = &Simulator::Evaluate_OGRK; 1247 EvalTable[XGRK] = &Simulator::Evaluate_XGRK; 1248 EvalTable[AGRK] = &Simulator::Evaluate_AGRK; 1249 EvalTable[SGRK] = &Simulator::Evaluate_SGRK; 1250 EvalTable[ALGRK] = &Simulator::Evaluate_ALGRK; 1251 EvalTable[SLGRK] = &Simulator::Evaluate_SLGRK; 1252 EvalTable[LOCR] = &Simulator::Evaluate_LOCR; 1253 EvalTable[NRK] = &Simulator::Evaluate_NRK; 1254 EvalTable[ORK] = &Simulator::Evaluate_ORK; 1255 EvalTable[XRK] = &Simulator::Evaluate_XRK; 1256 EvalTable[ARK] = &Simulator::Evaluate_ARK; 1257 EvalTable[SRK] = &Simulator::Evaluate_SRK; 1258 EvalTable[ALRK] = &Simulator::Evaluate_ALRK; 1259 EvalTable[SLRK] = &Simulator::Evaluate_SLRK; 1260 EvalTable[LTG] = &Simulator::Evaluate_LTG; 1261 EvalTable[LG] = &Simulator::Evaluate_LG; 1262 EvalTable[CVBY] = &Simulator::Evaluate_CVBY; 1263 EvalTable[AG] = &Simulator::Evaluate_AG; 1264 EvalTable[SG] = &Simulator::Evaluate_SG; 1265 EvalTable[ALG] = &Simulator::Evaluate_ALG; 1266 EvalTable[SLG] = &Simulator::Evaluate_SLG; 1267 EvalTable[MSG] = &Simulator::Evaluate_MSG; 1268 EvalTable[DSG] = &Simulator::Evaluate_DSG; 1269 EvalTable[CVBG] = &Simulator::Evaluate_CVBG; 1270 EvalTable[LRVG] = &Simulator::Evaluate_LRVG; 1271 EvalTable[LT] = &Simulator::Evaluate_LT; 1272 EvalTable[LGF] = &Simulator::Evaluate_LGF; 1273 EvalTable[LGH] = &Simulator::Evaluate_LGH; 1274 EvalTable[LLGF] = &Simulator::Evaluate_LLGF; 1275 EvalTable[LLGT] = &Simulator::Evaluate_LLGT; 1276 EvalTable[AGF] = &Simulator::Evaluate_AGF; 1277 EvalTable[SGF] = &Simulator::Evaluate_SGF; 1278 EvalTable[ALGF] = &Simulator::Evaluate_ALGF; 1279 EvalTable[SLGF] = &Simulator::Evaluate_SLGF; 1280 EvalTable[MSGF] = &Simulator::Evaluate_MSGF; 1281 EvalTable[DSGF] = &Simulator::Evaluate_DSGF; 1282 EvalTable[LRV] = &Simulator::Evaluate_LRV; 1283 EvalTable[LRVH] = &Simulator::Evaluate_LRVH; 1284 EvalTable[CG] = &Simulator::Evaluate_CG; 1285 EvalTable[CLG] = &Simulator::Evaluate_CLG; 1286 EvalTable[STG] = &Simulator::Evaluate_STG; 1287 EvalTable[NTSTG] = &Simulator::Evaluate_NTSTG; 1288 EvalTable[CVDY] = &Simulator::Evaluate_CVDY; 1289 EvalTable[CVDG] = &Simulator::Evaluate_CVDG; 1290 EvalTable[STRVG] = &Simulator::Evaluate_STRVG; 1291 EvalTable[CGF] = &Simulator::Evaluate_CGF; 1292 EvalTable[CLGF] = &Simulator::Evaluate_CLGF; 1293 EvalTable[LTGF] = &Simulator::Evaluate_LTGF; 1294 EvalTable[CGH] = &Simulator::Evaluate_CGH; 1295 EvalTable[PFD] = &Simulator::Evaluate_PFD; 1296 EvalTable[STRV] = &Simulator::Evaluate_STRV; 1297 EvalTable[STRVH] = &Simulator::Evaluate_STRVH; 1298 EvalTable[BCTG] = &Simulator::Evaluate_BCTG; 1299 EvalTable[STY] = &Simulator::Evaluate_STY; 1300 EvalTable[MSY] = &Simulator::Evaluate_MSY; 1301 EvalTable[MSC] = &Simulator::Evaluate_MSC; 1302 EvalTable[NY] = &Simulator::Evaluate_NY; 1303 EvalTable[CLY] = &Simulator::Evaluate_CLY; 1304 EvalTable[OY] = &Simulator::Evaluate_OY; 1305 EvalTable[XY] = &Simulator::Evaluate_XY; 1306 EvalTable[LY] = &Simulator::Evaluate_LY; 1307 EvalTable[CY] = &Simulator::Evaluate_CY; 1308 EvalTable[AY] = &Simulator::Evaluate_AY; 1309 EvalTable[SY] = &Simulator::Evaluate_SY; 1310 EvalTable[MFY] = &Simulator::Evaluate_MFY; 1311 EvalTable[ALY] = &Simulator::Evaluate_ALY; 1312 EvalTable[SLY] = &Simulator::Evaluate_SLY; 1313 EvalTable[STHY] = &Simulator::Evaluate_STHY; 1314 EvalTable[LAY] = &Simulator::Evaluate_LAY; 1315 EvalTable[STCY] = &Simulator::Evaluate_STCY; 1316 EvalTable[ICY] = &Simulator::Evaluate_ICY; 1317 EvalTable[LAEY] = &Simulator::Evaluate_LAEY; 1318 EvalTable[LB] = &Simulator::Evaluate_LB; 1319 EvalTable[LGB] = &Simulator::Evaluate_LGB; 1320 EvalTable[LHY] = &Simulator::Evaluate_LHY; 1321 EvalTable[CHY] = &Simulator::Evaluate_CHY; 1322 EvalTable[AHY] = &Simulator::Evaluate_AHY; 1323 EvalTable[SHY] = &Simulator::Evaluate_SHY; 1324 EvalTable[MHY] = &Simulator::Evaluate_MHY; 1325 EvalTable[NG] = &Simulator::Evaluate_NG; 1326 EvalTable[OG] = &Simulator::Evaluate_OG; 1327 EvalTable[XG] = &Simulator::Evaluate_XG; 1328 EvalTable[LGAT] = &Simulator::Evaluate_LGAT; 1329 EvalTable[MLG] = &Simulator::Evaluate_MLG; 1330 EvalTable[DLG] = &Simulator::Evaluate_DLG; 1331 EvalTable[ALCG] = &Simulator::Evaluate_ALCG; 1332 EvalTable[SLBG] = &Simulator::Evaluate_SLBG; 1333 EvalTable[STPQ] = &Simulator::Evaluate_STPQ; 1334 EvalTable[LPQ] = &Simulator::Evaluate_LPQ; 1335 EvalTable[LLGC] = &Simulator::Evaluate_LLGC; 1336 EvalTable[LLGH] = &Simulator::Evaluate_LLGH; 1337 EvalTable[LLC] = &Simulator::Evaluate_LLC; 1338 EvalTable[LLH] = &Simulator::Evaluate_LLH; 1339 EvalTable[ML] = &Simulator::Evaluate_ML; 1340 EvalTable[DL] = &Simulator::Evaluate_DL; 1341 EvalTable[ALC] = &Simulator::Evaluate_ALC; 1342 EvalTable[SLB] = &Simulator::Evaluate_SLB; 1343 EvalTable[LLGTAT] = &Simulator::Evaluate_LLGTAT; 1344 EvalTable[LLGFAT] = &Simulator::Evaluate_LLGFAT; 1345 EvalTable[LAT] = &Simulator::Evaluate_LAT; 1346 EvalTable[LBH] = &Simulator::Evaluate_LBH; 1347 EvalTable[LLCH] = &Simulator::Evaluate_LLCH; 1348 EvalTable[STCH] = &Simulator::Evaluate_STCH; 1349 EvalTable[LHH] = &Simulator::Evaluate_LHH; 1350 EvalTable[LLHH] = &Simulator::Evaluate_LLHH; 1351 EvalTable[STHH] = &Simulator::Evaluate_STHH; 1352 EvalTable[LFHAT] = &Simulator::Evaluate_LFHAT; 1353 EvalTable[LFH] = &Simulator::Evaluate_LFH; 1354 EvalTable[STFH] = &Simulator::Evaluate_STFH; 1355 EvalTable[CHF] = &Simulator::Evaluate_CHF; 1356 EvalTable[MVCDK] = &Simulator::Evaluate_MVCDK; 1357 EvalTable[MVHHI] = &Simulator::Evaluate_MVHHI; 1358 EvalTable[MVGHI] = &Simulator::Evaluate_MVGHI; 1359 EvalTable[MVHI] = &Simulator::Evaluate_MVHI; 1360 EvalTable[CHHSI] = &Simulator::Evaluate_CHHSI; 1361 EvalTable[CGHSI] = &Simulator::Evaluate_CGHSI; 1362 EvalTable[CHSI] = &Simulator::Evaluate_CHSI; 1363 EvalTable[CLFHSI] = &Simulator::Evaluate_CLFHSI; 1364 EvalTable[TBEGIN] = &Simulator::Evaluate_TBEGIN; 1365 EvalTable[TBEGINC] = &Simulator::Evaluate_TBEGINC; 1366 EvalTable[LMG] = &Simulator::Evaluate_LMG; 1367 EvalTable[SRAG] = &Simulator::Evaluate_SRAG; 1368 EvalTable[SLAG] = &Simulator::Evaluate_SLAG; 1369 EvalTable[SRLG] = &Simulator::Evaluate_SRLG; 1370 EvalTable[SLLG] = &Simulator::Evaluate_SLLG; 1371 EvalTable[CSY] = &Simulator::Evaluate_CSY; 1372 EvalTable[RLLG] = &Simulator::Evaluate_RLLG; 1373 EvalTable[RLL] = &Simulator::Evaluate_RLL; 1374 EvalTable[STMG] = &Simulator::Evaluate_STMG; 1375 EvalTable[STMH] = &Simulator::Evaluate_STMH; 1376 EvalTable[STCMH] = &Simulator::Evaluate_STCMH; 1377 EvalTable[STCMY] = &Simulator::Evaluate_STCMY; 1378 EvalTable[CDSY] = &Simulator::Evaluate_CDSY; 1379 EvalTable[CDSG] = &Simulator::Evaluate_CDSG; 1380 EvalTable[BXHG] = &Simulator::Evaluate_BXHG; 1381 EvalTable[BXLEG] = &Simulator::Evaluate_BXLEG; 1382 EvalTable[ECAG] = &Simulator::Evaluate_ECAG; 1383 EvalTable[TMY] = &Simulator::Evaluate_TMY; 1384 EvalTable[MVIY] = &Simulator::Evaluate_MVIY; 1385 EvalTable[NIY] = &Simulator::Evaluate_NIY; 1386 EvalTable[CLIY] = &Simulator::Evaluate_CLIY; 1387 EvalTable[OIY] = &Simulator::Evaluate_OIY; 1388 EvalTable[XIY] = &Simulator::Evaluate_XIY; 1389 EvalTable[ASI] = &Simulator::Evaluate_ASI; 1390 EvalTable[ALSI] = &Simulator::Evaluate_ALSI; 1391 EvalTable[AGSI] = &Simulator::Evaluate_AGSI; 1392 EvalTable[ALGSI] = &Simulator::Evaluate_ALGSI; 1393 EvalTable[ICMH] = &Simulator::Evaluate_ICMH; 1394 EvalTable[ICMY] = &Simulator::Evaluate_ICMY; 1395 EvalTable[MVCLU] = &Simulator::Evaluate_MVCLU; 1396 EvalTable[CLCLU] = &Simulator::Evaluate_CLCLU; 1397 EvalTable[STMY] = &Simulator::Evaluate_STMY; 1398 EvalTable[LMH] = &Simulator::Evaluate_LMH; 1399 EvalTable[LMY] = &Simulator::Evaluate_LMY; 1400 EvalTable[TP] = &Simulator::Evaluate_TP; 1401 EvalTable[SRAK] = &Simulator::Evaluate_SRAK; 1402 EvalTable[SLAK] = &Simulator::Evaluate_SLAK; 1403 EvalTable[SRLK] = &Simulator::Evaluate_SRLK; 1404 EvalTable[SLLK] = &Simulator::Evaluate_SLLK; 1405 EvalTable[LOCG] = &Simulator::Evaluate_LOCG; 1406 EvalTable[STOCG] = &Simulator::Evaluate_STOCG; 1407 EvalTable[LANG] = &Simulator::Evaluate_LANG; 1408 EvalTable[LAOG] = &Simulator::Evaluate_LAOG; 1409 EvalTable[LAXG] = &Simulator::Evaluate_LAXG; 1410 EvalTable[LAAG] = &Simulator::Evaluate_LAAG; 1411 EvalTable[LAALG] = &Simulator::Evaluate_LAALG; 1412 EvalTable[LOC] = &Simulator::Evaluate_LOC; 1413 EvalTable[STOC] = &Simulator::Evaluate_STOC; 1414 EvalTable[LAN] = &Simulator::Evaluate_LAN; 1415 EvalTable[LAO] = &Simulator::Evaluate_LAO; 1416 EvalTable[LAX] = &Simulator::Evaluate_LAX; 1417 EvalTable[LAA] = &Simulator::Evaluate_LAA; 1418 EvalTable[LAAL] = &Simulator::Evaluate_LAAL; 1419 EvalTable[BRXHG] = &Simulator::Evaluate_BRXHG; 1420 EvalTable[BRXLG] = &Simulator::Evaluate_BRXLG; 1421 EvalTable[RISBLG] = &Simulator::Evaluate_RISBLG; 1422 EvalTable[RNSBG] = &Simulator::Evaluate_RNSBG; 1423 EvalTable[RISBG] = &Simulator::Evaluate_RISBG; 1424 EvalTable[ROSBG] = &Simulator::Evaluate_ROSBG; 1425 EvalTable[RXSBG] = &Simulator::Evaluate_RXSBG; 1426 EvalTable[RISBGN] = &Simulator::Evaluate_RISBGN; 1427 EvalTable[RISBHG] = &Simulator::Evaluate_RISBHG; 1428 EvalTable[CGRJ] = &Simulator::Evaluate_CGRJ; 1429 EvalTable[CGIT] = &Simulator::Evaluate_CGIT; 1430 EvalTable[CIT] = &Simulator::Evaluate_CIT; 1431 EvalTable[CLFIT] = &Simulator::Evaluate_CLFIT; 1432 EvalTable[CGIJ] = &Simulator::Evaluate_CGIJ; 1433 EvalTable[CIJ] = &Simulator::Evaluate_CIJ; 1434 EvalTable[AHIK] = &Simulator::Evaluate_AHIK; 1435 EvalTable[AGHIK] = &Simulator::Evaluate_AGHIK; 1436 EvalTable[ALHSIK] = &Simulator::Evaluate_ALHSIK; 1437 EvalTable[ALGHSIK] = &Simulator::Evaluate_ALGHSIK; 1438 EvalTable[CGRB] = &Simulator::Evaluate_CGRB; 1439 EvalTable[CGIB] = &Simulator::Evaluate_CGIB; 1440 EvalTable[CIB] = &Simulator::Evaluate_CIB; 1441 EvalTable[LDEB] = &Simulator::Evaluate_LDEB; 1442 EvalTable[LXDB] = &Simulator::Evaluate_LXDB; 1443 EvalTable[LXEB] = &Simulator::Evaluate_LXEB; 1444 EvalTable[MXDB] = &Simulator::Evaluate_MXDB; 1445 EvalTable[KEB] = &Simulator::Evaluate_KEB; 1446 EvalTable[CEB] = &Simulator::Evaluate_CEB; 1447 EvalTable[AEB] = &Simulator::Evaluate_AEB; 1448 EvalTable[SEB] = &Simulator::Evaluate_SEB; 1449 EvalTable[MDEB] = &Simulator::Evaluate_MDEB; 1450 EvalTable[DEB] = &Simulator::Evaluate_DEB; 1451 EvalTable[MAEB] = &Simulator::Evaluate_MAEB; 1452 EvalTable[MSEB] = &Simulator::Evaluate_MSEB; 1453 EvalTable[TCEB] = &Simulator::Evaluate_TCEB; 1454 EvalTable[TCDB] = &Simulator::Evaluate_TCDB; 1455 EvalTable[TCXB] = &Simulator::Evaluate_TCXB; 1456 EvalTable[SQEB] = &Simulator::Evaluate_SQEB; 1457 EvalTable[SQDB] = &Simulator::Evaluate_SQDB; 1458 EvalTable[MEEB] = &Simulator::Evaluate_MEEB; 1459 EvalTable[KDB] = &Simulator::Evaluate_KDB; 1460 EvalTable[CDB] = &Simulator::Evaluate_CDB; 1461 EvalTable[ADB] = &Simulator::Evaluate_ADB; 1462 EvalTable[SDB] = &Simulator::Evaluate_SDB; 1463 EvalTable[MDB] = &Simulator::Evaluate_MDB; 1464 EvalTable[DDB] = &Simulator::Evaluate_DDB; 1465 EvalTable[MADB] = &Simulator::Evaluate_MADB; 1466 EvalTable[MSDB] = &Simulator::Evaluate_MSDB; 1467 EvalTable[SLDT] = &Simulator::Evaluate_SLDT; 1468 EvalTable[SRDT] = &Simulator::Evaluate_SRDT; 1469 EvalTable[SLXT] = &Simulator::Evaluate_SLXT; 1470 EvalTable[SRXT] = &Simulator::Evaluate_SRXT; 1471 EvalTable[TDCET] = &Simulator::Evaluate_TDCET; 1472 EvalTable[TDGET] = &Simulator::Evaluate_TDGET; 1473 EvalTable[TDCDT] = &Simulator::Evaluate_TDCDT; 1474 EvalTable[TDGDT] = &Simulator::Evaluate_TDGDT; 1475 EvalTable[TDCXT] = &Simulator::Evaluate_TDCXT; 1476 EvalTable[TDGXT] = &Simulator::Evaluate_TDGXT; 1477 EvalTable[LEY] = &Simulator::Evaluate_LEY; 1478 EvalTable[LDY] = &Simulator::Evaluate_LDY; 1479 EvalTable[STEY] = &Simulator::Evaluate_STEY; 1480 EvalTable[STDY] = &Simulator::Evaluate_STDY; 1481 EvalTable[CZDT] = &Simulator::Evaluate_CZDT; 1482 EvalTable[CZXT] = &Simulator::Evaluate_CZXT; 1483 EvalTable[CDZT] = &Simulator::Evaluate_CDZT; 1484 EvalTable[CXZT] = &Simulator::Evaluate_CXZT; 1485 } // NOLINT 1486 1487 Simulator::Simulator(Isolate* isolate) : isolate_(isolate) { 1488 static base::OnceType once = V8_ONCE_INIT; 1489 base::CallOnce(&once, &Simulator::EvalTableInit); 1490 // Set up simulator support first. Some of this information is needed to 1491 // setup the architecture state. 1492 #if V8_TARGET_ARCH_S390X 1493 size_t stack_size = FLAG_sim_stack_size * KB; 1494 #else 1495 size_t stack_size = MB; // allocate 1MB for stack 1496 #endif 1497 stack_size += 2 * stack_protection_size_; 1498 stack_ = reinterpret_cast<char*>(malloc(stack_size)); 1499 pc_modified_ = false; 1500 icount_ = 0; 1501 break_pc_ = nullptr; 1502 break_instr_ = 0; 1503 1504 // make sure our register type can hold exactly 4/8 bytes 1505 #ifdef V8_TARGET_ARCH_S390X 1506 DCHECK_EQ(sizeof(intptr_t), 8); 1507 #else 1508 DCHECK_EQ(sizeof(intptr_t), 4); 1509 #endif 1510 // Set up architecture state. 1511 // All registers are initialized to zero to start with. 1512 for (int i = 0; i < kNumGPRs; i++) { 1513 registers_[i] = 0; 1514 } 1515 condition_reg_ = 0; 1516 special_reg_pc_ = 0; 1517 1518 // Initializing FP registers. 1519 for (int i = 0; i < kNumFPRs; i++) { 1520 fp_registers_[i] = 0.0; 1521 } 1522 1523 // The sp is initialized to point to the bottom (high address) of the 1524 // allocated stack area. To be safe in potential stack underflows we leave 1525 // some buffer below. 1526 registers_[sp] = 1527 reinterpret_cast<intptr_t>(stack_) + stack_size - stack_protection_size_; 1528 1529 last_debugger_input_ = nullptr; 1530 } 1531 1532 Simulator::~Simulator() { free(stack_); } 1533 1534 // Get the active Simulator for the current thread. 1535 Simulator* Simulator::current(Isolate* isolate) { 1536 v8::internal::Isolate::PerIsolateThreadData* isolate_data = 1537 isolate->FindOrAllocatePerThreadDataForThisThread(); 1538 DCHECK_NOT_NULL(isolate_data); 1539 1540 Simulator* sim = isolate_data->simulator(); 1541 if (sim == nullptr) { 1542 // TODO(146): delete the simulator object when a thread/isolate goes away. 1543 sim = new Simulator(isolate); 1544 isolate_data->set_simulator(sim); 1545 } 1546 return sim; 1547 } 1548 1549 // Sets the register in the architecture state. 1550 void Simulator::set_register(int reg, uint64_t value) { 1551 DCHECK((reg >= 0) && (reg < kNumGPRs)); 1552 registers_[reg] = value; 1553 } 1554 1555 // Get the register from the architecture state. 1556 uint64_t Simulator::get_register(int reg) const { 1557 DCHECK((reg >= 0) && (reg < kNumGPRs)); 1558 // Stupid code added to avoid bug in GCC. 1559 // See: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43949 1560 if (reg >= kNumGPRs) return 0; 1561 // End stupid code. 1562 return registers_[reg]; 1563 } 1564 1565 template <typename T> 1566 T Simulator::get_low_register(int reg) const { 1567 DCHECK((reg >= 0) && (reg < kNumGPRs)); 1568 // Stupid code added to avoid bug in GCC. 1569 // See: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43949 1570 if (reg >= kNumGPRs) return 0; 1571 // End stupid code. 1572 return static_cast<T>(registers_[reg] & 0xFFFFFFFF); 1573 } 1574 1575 template <typename T> 1576 T Simulator::get_high_register(int reg) const { 1577 DCHECK((reg >= 0) && (reg < kNumGPRs)); 1578 // Stupid code added to avoid bug in GCC. 1579 // See: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43949 1580 if (reg >= kNumGPRs) return 0; 1581 // End stupid code. 1582 return static_cast<T>(registers_[reg] >> 32); 1583 } 1584 1585 void Simulator::set_low_register(int reg, uint32_t value) { 1586 uint64_t shifted_val = static_cast<uint64_t>(value); 1587 uint64_t orig_val = static_cast<uint64_t>(registers_[reg]); 1588 uint64_t result = (orig_val >> 32 << 32) | shifted_val; 1589 registers_[reg] = result; 1590 } 1591 1592 void Simulator::set_high_register(int reg, uint32_t value) { 1593 uint64_t shifted_val = static_cast<uint64_t>(value) << 32; 1594 uint64_t orig_val = static_cast<uint64_t>(registers_[reg]); 1595 uint64_t result = (orig_val & 0xFFFFFFFF) | shifted_val; 1596 registers_[reg] = result; 1597 } 1598 1599 double Simulator::get_double_from_register_pair(int reg) { 1600 DCHECK((reg >= 0) && (reg < kNumGPRs) && ((reg % 2) == 0)); 1601 1602 double dm_val = 0.0; 1603 #if 0 && !V8_TARGET_ARCH_S390X // doesn't make sense in 64bit mode 1604 // Read the bits from the unsigned integer register_[] array 1605 // into the double precision floating point value and return it. 1606 char buffer[sizeof(fp_registers_[0])]; 1607 memcpy(buffer, ®isters_[reg], 2 * sizeof(registers_[0])); 1608 memcpy(&dm_val, buffer, 2 * sizeof(registers_[0])); 1609 #endif 1610 return (dm_val); 1611 } 1612 1613 // Raw access to the PC register. 1614 void Simulator::set_pc(intptr_t value) { 1615 pc_modified_ = true; 1616 special_reg_pc_ = value; 1617 } 1618 1619 bool Simulator::has_bad_pc() const { 1620 return ((special_reg_pc_ == bad_lr) || (special_reg_pc_ == end_sim_pc)); 1621 } 1622 1623 // Raw access to the PC register without the special adjustment when reading. 1624 intptr_t Simulator::get_pc() const { return special_reg_pc_; } 1625 1626 // Runtime FP routines take: 1627 // - two double arguments 1628 // - one double argument and zero or one integer arguments. 1629 // All are consructed here from d1, d2 and r2. 1630 void Simulator::GetFpArgs(double* x, double* y, intptr_t* z) { 1631 *x = get_double_from_d_register(0); 1632 *y = get_double_from_d_register(2); 1633 *z = get_register(2); 1634 } 1635 1636 // The return value is in d0. 1637 void Simulator::SetFpResult(const double& result) { 1638 set_d_register_from_double(0, result); 1639 } 1640 1641 void Simulator::TrashCallerSaveRegisters() { 1642 // We don't trash the registers with the return value. 1643 #if 0 // A good idea to trash volatile registers, needs to be done 1644 registers_[2] = 0x50BAD4U; 1645 registers_[3] = 0x50BAD4U; 1646 registers_[12] = 0x50BAD4U; 1647 #endif 1648 } 1649 1650 uint32_t Simulator::ReadWU(intptr_t addr, Instruction* instr) { 1651 uint32_t* ptr = reinterpret_cast<uint32_t*>(addr); 1652 return *ptr; 1653 } 1654 1655 int64_t Simulator::ReadW64(intptr_t addr, Instruction* instr) { 1656 int64_t* ptr = reinterpret_cast<int64_t*>(addr); 1657 return *ptr; 1658 } 1659 1660 int32_t Simulator::ReadW(intptr_t addr, Instruction* instr) { 1661 int32_t* ptr = reinterpret_cast<int32_t*>(addr); 1662 return *ptr; 1663 } 1664 1665 void Simulator::WriteW(intptr_t addr, uint32_t value, Instruction* instr) { 1666 uint32_t* ptr = reinterpret_cast<uint32_t*>(addr); 1667 *ptr = value; 1668 return; 1669 } 1670 1671 void Simulator::WriteW(intptr_t addr, int32_t value, Instruction* instr) { 1672 int32_t* ptr = reinterpret_cast<int32_t*>(addr); 1673 *ptr = value; 1674 return; 1675 } 1676 1677 uint16_t Simulator::ReadHU(intptr_t addr, Instruction* instr) { 1678 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); 1679 return *ptr; 1680 } 1681 1682 int16_t Simulator::ReadH(intptr_t addr, Instruction* instr) { 1683 int16_t* ptr = reinterpret_cast<int16_t*>(addr); 1684 return *ptr; 1685 } 1686 1687 void Simulator::WriteH(intptr_t addr, uint16_t value, Instruction* instr) { 1688 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); 1689 *ptr = value; 1690 return; 1691 } 1692 1693 void Simulator::WriteH(intptr_t addr, int16_t value, Instruction* instr) { 1694 int16_t* ptr = reinterpret_cast<int16_t*>(addr); 1695 *ptr = value; 1696 return; 1697 } 1698 1699 uint8_t Simulator::ReadBU(intptr_t addr) { 1700 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); 1701 return *ptr; 1702 } 1703 1704 int8_t Simulator::ReadB(intptr_t addr) { 1705 int8_t* ptr = reinterpret_cast<int8_t*>(addr); 1706 return *ptr; 1707 } 1708 1709 void Simulator::WriteB(intptr_t addr, uint8_t value) { 1710 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); 1711 *ptr = value; 1712 } 1713 1714 void Simulator::WriteB(intptr_t addr, int8_t value) { 1715 int8_t* ptr = reinterpret_cast<int8_t*>(addr); 1716 *ptr = value; 1717 } 1718 1719 int64_t Simulator::ReadDW(intptr_t addr) { 1720 int64_t* ptr = reinterpret_cast<int64_t*>(addr); 1721 return *ptr; 1722 } 1723 1724 void Simulator::WriteDW(intptr_t addr, int64_t value) { 1725 int64_t* ptr = reinterpret_cast<int64_t*>(addr); 1726 *ptr = value; 1727 return; 1728 } 1729 1730 /** 1731 * Reads a double value from memory at given address. 1732 */ 1733 double Simulator::ReadDouble(intptr_t addr) { 1734 double* ptr = reinterpret_cast<double*>(addr); 1735 return *ptr; 1736 } 1737 1738 float Simulator::ReadFloat(intptr_t addr) { 1739 float* ptr = reinterpret_cast<float*>(addr); 1740 return *ptr; 1741 } 1742 1743 // Returns the limit of the stack area to enable checking for stack overflows. 1744 uintptr_t Simulator::StackLimit(uintptr_t c_limit) const { 1745 // The simulator uses a separate JS stack. If we have exhausted the C stack, 1746 // we also drop down the JS limit to reflect the exhaustion on the JS stack. 1747 if (GetCurrentStackPosition() < c_limit) { 1748 return reinterpret_cast<uintptr_t>(get_sp()); 1749 } 1750 1751 // Otherwise the limit is the JS stack. Leave a safety margin to prevent 1752 // overrunning the stack when pushing values. 1753 return reinterpret_cast<uintptr_t>(stack_) + stack_protection_size_; 1754 } 1755 1756 // Unsupported instructions use Format to print an error and stop execution. 1757 void Simulator::Format(Instruction* instr, const char* format) { 1758 PrintF("Simulator found unsupported instruction:\n 0x%08" V8PRIxPTR ": %s\n", 1759 reinterpret_cast<intptr_t>(instr), format); 1760 UNIMPLEMENTED(); 1761 } 1762 1763 // Calculate C flag value for additions. 1764 bool Simulator::CarryFrom(int32_t left, int32_t right, int32_t carry) { 1765 uint32_t uleft = static_cast<uint32_t>(left); 1766 uint32_t uright = static_cast<uint32_t>(right); 1767 uint32_t urest = 0xFFFFFFFFU - uleft; 1768 1769 return (uright > urest) || 1770 (carry && (((uright + 1) > urest) || (uright > (urest - 1)))); 1771 } 1772 1773 // Calculate C flag value for subtractions. 1774 bool Simulator::BorrowFrom(int32_t left, int32_t right) { 1775 uint32_t uleft = static_cast<uint32_t>(left); 1776 uint32_t uright = static_cast<uint32_t>(right); 1777 1778 return (uright > uleft); 1779 } 1780 1781 // Calculate V flag value for additions and subtractions. 1782 template <typename T1> 1783 bool Simulator::OverflowFromSigned(T1 alu_out, T1 left, T1 right, 1784 bool addition) { 1785 bool overflow; 1786 if (addition) { 1787 // operands have the same sign 1788 overflow = ((left >= 0 && right >= 0) || (left < 0 && right < 0)) 1789 // and operands and result have different sign 1790 && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0)); 1791 } else { 1792 // operands have different signs 1793 overflow = ((left < 0 && right >= 0) || (left >= 0 && right < 0)) 1794 // and first operand and result have different signs 1795 && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0)); 1796 } 1797 return overflow; 1798 } 1799 1800 #if V8_TARGET_ARCH_S390X 1801 static void decodeObjectPair(ObjectPair* pair, intptr_t* x, intptr_t* y) { 1802 *x = reinterpret_cast<intptr_t>(pair->x); 1803 *y = reinterpret_cast<intptr_t>(pair->y); 1804 } 1805 #else 1806 static void decodeObjectPair(ObjectPair* pair, intptr_t* x, intptr_t* y) { 1807 #if V8_TARGET_BIG_ENDIAN 1808 *x = static_cast<int32_t>(*pair >> 32); 1809 *y = static_cast<int32_t>(*pair); 1810 #else 1811 *x = static_cast<int32_t>(*pair); 1812 *y = static_cast<int32_t>(*pair >> 32); 1813 #endif 1814 } 1815 #endif 1816 1817 // Calls into the V8 runtime. 1818 typedef intptr_t (*SimulatorRuntimeCall)(intptr_t arg0, intptr_t arg1, 1819 intptr_t arg2, intptr_t arg3, 1820 intptr_t arg4, intptr_t arg5, 1821 intptr_t arg6, intptr_t arg7, 1822 intptr_t arg8); 1823 typedef ObjectPair (*SimulatorRuntimePairCall)(intptr_t arg0, intptr_t arg1, 1824 intptr_t arg2, intptr_t arg3, 1825 intptr_t arg4, intptr_t arg5); 1826 1827 // These prototypes handle the four types of FP calls. 1828 typedef int (*SimulatorRuntimeCompareCall)(double darg0, double darg1); 1829 typedef double (*SimulatorRuntimeFPFPCall)(double darg0, double darg1); 1830 typedef double (*SimulatorRuntimeFPCall)(double darg0); 1831 typedef double (*SimulatorRuntimeFPIntCall)(double darg0, intptr_t arg0); 1832 1833 // This signature supports direct call in to API function native callback 1834 // (refer to InvocationCallback in v8.h). 1835 typedef void (*SimulatorRuntimeDirectApiCall)(intptr_t arg0); 1836 typedef void (*SimulatorRuntimeProfilingApiCall)(intptr_t arg0, void* arg1); 1837 1838 // This signature supports direct call to accessor getter callback. 1839 typedef void (*SimulatorRuntimeDirectGetterCall)(intptr_t arg0, intptr_t arg1); 1840 typedef void (*SimulatorRuntimeProfilingGetterCall)(intptr_t arg0, 1841 intptr_t arg1, void* arg2); 1842 1843 // Software interrupt instructions are used by the simulator to call into the 1844 // C-based V8 runtime. 1845 void Simulator::SoftwareInterrupt(Instruction* instr) { 1846 int svc = instr->SvcValue(); 1847 switch (svc) { 1848 case kCallRtRedirected: { 1849 // Check if stack is aligned. Error if not aligned is reported below to 1850 // include information on the function called. 1851 bool stack_aligned = 1852 (get_register(sp) & (::v8::internal::FLAG_sim_stack_alignment - 1)) == 1853 0; 1854 Redirection* redirection = Redirection::FromInstruction(instr); 1855 const int kArgCount = 9; 1856 const int kRegisterArgCount = 5; 1857 int arg0_regnum = 2; 1858 intptr_t result_buffer = 0; 1859 bool uses_result_buffer = 1860 redirection->type() == ExternalReference::BUILTIN_CALL_PAIR && 1861 !ABI_RETURNS_OBJECTPAIR_IN_REGS; 1862 if (uses_result_buffer) { 1863 result_buffer = get_register(r2); 1864 arg0_regnum++; 1865 } 1866 intptr_t arg[kArgCount]; 1867 // First 5 arguments in registers r2-r6. 1868 for (int i = 0; i < kRegisterArgCount; i++) { 1869 arg[i] = get_register(arg0_regnum + i); 1870 } 1871 // Remaining arguments on stack 1872 intptr_t* stack_pointer = reinterpret_cast<intptr_t*>(get_register(sp)); 1873 for (int i = kRegisterArgCount; i < kArgCount; i++) { 1874 arg[i] = stack_pointer[(kCalleeRegisterSaveAreaSize / kPointerSize) + 1875 (i - kRegisterArgCount)]; 1876 } 1877 STATIC_ASSERT(kArgCount == kRegisterArgCount + 4); 1878 STATIC_ASSERT(kMaxCParameters == 9); 1879 bool fp_call = 1880 (redirection->type() == ExternalReference::BUILTIN_FP_FP_CALL) || 1881 (redirection->type() == ExternalReference::BUILTIN_COMPARE_CALL) || 1882 (redirection->type() == ExternalReference::BUILTIN_FP_CALL) || 1883 (redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL); 1884 1885 // Place the return address on the stack, making the call GC safe. 1886 *reinterpret_cast<intptr_t*>(get_register(sp) + 1887 kStackFrameRASlot * kPointerSize) = 1888 get_register(r14); 1889 1890 intptr_t external = 1891 reinterpret_cast<intptr_t>(redirection->external_function()); 1892 if (fp_call) { 1893 double dval0, dval1; // one or two double parameters 1894 intptr_t ival; // zero or one integer parameters 1895 int iresult = 0; // integer return value 1896 double dresult = 0; // double return value 1897 GetFpArgs(&dval0, &dval1, &ival); 1898 if (::v8::internal::FLAG_trace_sim || !stack_aligned) { 1899 SimulatorRuntimeCall generic_target = 1900 reinterpret_cast<SimulatorRuntimeCall>(external); 1901 switch (redirection->type()) { 1902 case ExternalReference::BUILTIN_FP_FP_CALL: 1903 case ExternalReference::BUILTIN_COMPARE_CALL: 1904 PrintF("Call to host function at %p with args %f, %f", 1905 reinterpret_cast<void*>(FUNCTION_ADDR(generic_target)), 1906 dval0, dval1); 1907 break; 1908 case ExternalReference::BUILTIN_FP_CALL: 1909 PrintF("Call to host function at %p with arg %f", 1910 reinterpret_cast<void*>(FUNCTION_ADDR(generic_target)), 1911 dval0); 1912 break; 1913 case ExternalReference::BUILTIN_FP_INT_CALL: 1914 PrintF("Call to host function at %p with args %f, %" V8PRIdPTR, 1915 reinterpret_cast<void*>(FUNCTION_ADDR(generic_target)), 1916 dval0, ival); 1917 break; 1918 default: 1919 UNREACHABLE(); 1920 break; 1921 } 1922 if (!stack_aligned) { 1923 PrintF(" with unaligned stack %08" V8PRIxPTR "\n", 1924 static_cast<intptr_t>(get_register(sp))); 1925 } 1926 PrintF("\n"); 1927 } 1928 CHECK(stack_aligned); 1929 switch (redirection->type()) { 1930 case ExternalReference::BUILTIN_COMPARE_CALL: { 1931 SimulatorRuntimeCompareCall target = 1932 reinterpret_cast<SimulatorRuntimeCompareCall>(external); 1933 iresult = target(dval0, dval1); 1934 set_register(r2, iresult); 1935 break; 1936 } 1937 case ExternalReference::BUILTIN_FP_FP_CALL: { 1938 SimulatorRuntimeFPFPCall target = 1939 reinterpret_cast<SimulatorRuntimeFPFPCall>(external); 1940 dresult = target(dval0, dval1); 1941 SetFpResult(dresult); 1942 break; 1943 } 1944 case ExternalReference::BUILTIN_FP_CALL: { 1945 SimulatorRuntimeFPCall target = 1946 reinterpret_cast<SimulatorRuntimeFPCall>(external); 1947 dresult = target(dval0); 1948 SetFpResult(dresult); 1949 break; 1950 } 1951 case ExternalReference::BUILTIN_FP_INT_CALL: { 1952 SimulatorRuntimeFPIntCall target = 1953 reinterpret_cast<SimulatorRuntimeFPIntCall>(external); 1954 dresult = target(dval0, ival); 1955 SetFpResult(dresult); 1956 break; 1957 } 1958 default: 1959 UNREACHABLE(); 1960 break; 1961 } 1962 if (::v8::internal::FLAG_trace_sim || !stack_aligned) { 1963 switch (redirection->type()) { 1964 case ExternalReference::BUILTIN_COMPARE_CALL: 1965 PrintF("Returned %08x\n", iresult); 1966 break; 1967 case ExternalReference::BUILTIN_FP_FP_CALL: 1968 case ExternalReference::BUILTIN_FP_CALL: 1969 case ExternalReference::BUILTIN_FP_INT_CALL: 1970 PrintF("Returned %f\n", dresult); 1971 break; 1972 default: 1973 UNREACHABLE(); 1974 break; 1975 } 1976 } 1977 } else if (redirection->type() == ExternalReference::DIRECT_API_CALL) { 1978 // See callers of MacroAssembler::CallApiFunctionAndReturn for 1979 // explanation of register usage. 1980 if (::v8::internal::FLAG_trace_sim || !stack_aligned) { 1981 PrintF("Call to host function at %p args %08" V8PRIxPTR, 1982 reinterpret_cast<void*>(external), arg[0]); 1983 if (!stack_aligned) { 1984 PrintF(" with unaligned stack %08" V8PRIxPTR "\n", 1985 static_cast<intptr_t>(get_register(sp))); 1986 } 1987 PrintF("\n"); 1988 } 1989 CHECK(stack_aligned); 1990 SimulatorRuntimeDirectApiCall target = 1991 reinterpret_cast<SimulatorRuntimeDirectApiCall>(external); 1992 target(arg[0]); 1993 } else if (redirection->type() == ExternalReference::PROFILING_API_CALL) { 1994 // See callers of MacroAssembler::CallApiFunctionAndReturn for 1995 // explanation of register usage. 1996 if (::v8::internal::FLAG_trace_sim || !stack_aligned) { 1997 PrintF("Call to host function at %p args %08" V8PRIxPTR 1998 " %08" V8PRIxPTR, 1999 reinterpret_cast<void*>(external), arg[0], arg[1]); 2000 if (!stack_aligned) { 2001 PrintF(" with unaligned stack %08" V8PRIxPTR "\n", 2002 static_cast<intptr_t>(get_register(sp))); 2003 } 2004 PrintF("\n"); 2005 } 2006 CHECK(stack_aligned); 2007 SimulatorRuntimeProfilingApiCall target = 2008 reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external); 2009 target(arg[0], Redirection::ReverseRedirection(arg[1])); 2010 } else if (redirection->type() == ExternalReference::DIRECT_GETTER_CALL) { 2011 // See callers of MacroAssembler::CallApiFunctionAndReturn for 2012 // explanation of register usage. 2013 if (::v8::internal::FLAG_trace_sim || !stack_aligned) { 2014 PrintF("Call to host function at %p args %08" V8PRIxPTR 2015 " %08" V8PRIxPTR, 2016 reinterpret_cast<void*>(external), arg[0], arg[1]); 2017 if (!stack_aligned) { 2018 PrintF(" with unaligned stack %08" V8PRIxPTR "\n", 2019 static_cast<intptr_t>(get_register(sp))); 2020 } 2021 PrintF("\n"); 2022 } 2023 CHECK(stack_aligned); 2024 SimulatorRuntimeDirectGetterCall target = 2025 reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external); 2026 if (!ABI_PASSES_HANDLES_IN_REGS) { 2027 arg[0] = *(reinterpret_cast<intptr_t*>(arg[0])); 2028 } 2029 target(arg[0], arg[1]); 2030 } else if (redirection->type() == 2031 ExternalReference::PROFILING_GETTER_CALL) { 2032 if (::v8::internal::FLAG_trace_sim || !stack_aligned) { 2033 PrintF("Call to host function at %p args %08" V8PRIxPTR 2034 " %08" V8PRIxPTR " %08" V8PRIxPTR, 2035 reinterpret_cast<void*>(external), arg[0], arg[1], arg[2]); 2036 if (!stack_aligned) { 2037 PrintF(" with unaligned stack %08" V8PRIxPTR "\n", 2038 static_cast<intptr_t>(get_register(sp))); 2039 } 2040 PrintF("\n"); 2041 } 2042 CHECK(stack_aligned); 2043 SimulatorRuntimeProfilingGetterCall target = 2044 reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external); 2045 if (!ABI_PASSES_HANDLES_IN_REGS) { 2046 arg[0] = *(reinterpret_cast<intptr_t*>(arg[0])); 2047 } 2048 target(arg[0], arg[1], Redirection::ReverseRedirection(arg[2])); 2049 } else { 2050 // builtin call. 2051 if (::v8::internal::FLAG_trace_sim || !stack_aligned) { 2052 SimulatorRuntimeCall target = 2053 reinterpret_cast<SimulatorRuntimeCall>(external); 2054 PrintF( 2055 "Call to host function at %p,\n" 2056 "\t\t\t\targs %08" V8PRIxPTR ", %08" V8PRIxPTR ", %08" V8PRIxPTR 2057 ", %08" V8PRIxPTR ", %08" V8PRIxPTR ", %08" V8PRIxPTR 2058 ", %08" V8PRIxPTR ", %08" V8PRIxPTR ", %08" V8PRIxPTR, 2059 reinterpret_cast<void*>(FUNCTION_ADDR(target)), arg[0], arg[1], 2060 arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8]); 2061 if (!stack_aligned) { 2062 PrintF(" with unaligned stack %08" V8PRIxPTR "\n", 2063 static_cast<intptr_t>(get_register(sp))); 2064 } 2065 PrintF("\n"); 2066 } 2067 CHECK(stack_aligned); 2068 if (redirection->type() == ExternalReference::BUILTIN_CALL_PAIR) { 2069 SimulatorRuntimePairCall target = 2070 reinterpret_cast<SimulatorRuntimePairCall>(external); 2071 ObjectPair result = 2072 target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]); 2073 intptr_t x; 2074 intptr_t y; 2075 decodeObjectPair(&result, &x, &y); 2076 if (::v8::internal::FLAG_trace_sim) { 2077 PrintF("Returned {%08" V8PRIxPTR ", %08" V8PRIxPTR "}\n", x, y); 2078 } 2079 if (ABI_RETURNS_OBJECTPAIR_IN_REGS) { 2080 set_register(r2, x); 2081 set_register(r3, y); 2082 } else { 2083 memcpy(reinterpret_cast<void*>(result_buffer), &result, 2084 sizeof(ObjectPair)); 2085 set_register(r2, result_buffer); 2086 } 2087 } else { 2088 DCHECK(redirection->type() == ExternalReference::BUILTIN_CALL); 2089 SimulatorRuntimeCall target = 2090 reinterpret_cast<SimulatorRuntimeCall>(external); 2091 intptr_t result = target(arg[0], arg[1], arg[2], arg[3], arg[4], 2092 arg[5], arg[6], arg[7], arg[8]); 2093 if (::v8::internal::FLAG_trace_sim) { 2094 PrintF("Returned %08" V8PRIxPTR "\n", result); 2095 } 2096 set_register(r2, result); 2097 } 2098 // #if !V8_TARGET_ARCH_S390X 2099 // DCHECK(redirection->type() == 2100 // ExternalReference::BUILTIN_CALL); 2101 // SimulatorRuntimeCall target = 2102 // reinterpret_cast<SimulatorRuntimeCall>(external); 2103 // int64_t result = target(arg[0], arg[1], arg[2], arg[3], 2104 // arg[4], 2105 // arg[5]); 2106 // int32_t lo_res = static_cast<int32_t>(result); 2107 // int32_t hi_res = static_cast<int32_t>(result >> 32); 2108 // #if !V8_TARGET_LITTLE_ENDIAN 2109 // if (::v8::internal::FLAG_trace_sim) { 2110 // PrintF("Returned %08x\n", hi_res); 2111 // } 2112 // set_register(r2, hi_res); 2113 // set_register(r3, lo_res); 2114 // #else 2115 // if (::v8::internal::FLAG_trace_sim) { 2116 // PrintF("Returned %08x\n", lo_res); 2117 // } 2118 // set_register(r2, lo_res); 2119 // set_register(r3, hi_res); 2120 // #endif 2121 // #else 2122 // if (redirection->type() == ExternalReference::BUILTIN_CALL) { 2123 // SimulatorRuntimeCall target = 2124 // reinterpret_cast<SimulatorRuntimeCall>(external); 2125 // intptr_t result = target(arg[0], arg[1], arg[2], arg[3], 2126 // arg[4], 2127 // arg[5]); 2128 // if (::v8::internal::FLAG_trace_sim) { 2129 // PrintF("Returned %08" V8PRIxPTR "\n", result); 2130 // } 2131 // set_register(r2, result); 2132 // } else { 2133 // DCHECK(redirection->type() == 2134 // ExternalReference::BUILTIN_CALL_PAIR); 2135 // SimulatorRuntimePairCall target = 2136 // reinterpret_cast<SimulatorRuntimePairCall>(external); 2137 // ObjectPair result = target(arg[0], arg[1], arg[2], arg[3], 2138 // arg[4], arg[5]); 2139 // if (::v8::internal::FLAG_trace_sim) { 2140 // PrintF("Returned %08" V8PRIxPTR ", %08" V8PRIxPTR "\n", 2141 // result.x, result.y); 2142 // } 2143 // #if ABI_RETURNS_OBJECTPAIR_IN_REGS 2144 // set_register(r2, result.x); 2145 // set_register(r3, result.y); 2146 // #else 2147 // memcpy(reinterpret_cast<void *>(result_buffer), &result, 2148 // sizeof(ObjectPair)); 2149 // #endif 2150 // } 2151 // #endif 2152 } 2153 int64_t saved_lr = *reinterpret_cast<intptr_t*>( 2154 get_register(sp) + kStackFrameRASlot * kPointerSize); 2155 #if (!V8_TARGET_ARCH_S390X && V8_HOST_ARCH_S390) 2156 // On zLinux-31, the saved_lr might be tagged with a high bit of 1. 2157 // Cleanse it before proceeding with simulation. 2158 saved_lr &= 0x7FFFFFFF; 2159 #endif 2160 set_pc(saved_lr); 2161 break; 2162 } 2163 case kBreakpoint: { 2164 S390Debugger dbg(this); 2165 dbg.Debug(); 2166 break; 2167 } 2168 // stop uses all codes greater than 1 << 23. 2169 default: { 2170 if (svc >= (1 << 23)) { 2171 uint32_t code = svc & kStopCodeMask; 2172 if (isWatchedStop(code)) { 2173 IncreaseStopCounter(code); 2174 } 2175 // Stop if it is enabled, otherwise go on jumping over the stop 2176 // and the message address. 2177 if (isEnabledStop(code)) { 2178 S390Debugger dbg(this); 2179 dbg.Stop(instr); 2180 } else { 2181 set_pc(get_pc() + sizeof(FourByteInstr) + kPointerSize); 2182 } 2183 } else { 2184 // This is not a valid svc code. 2185 UNREACHABLE(); 2186 break; 2187 } 2188 } 2189 } 2190 } 2191 2192 // Stop helper functions. 2193 bool Simulator::isStopInstruction(Instruction* instr) { 2194 return (instr->Bits(27, 24) == 0xF) && (instr->SvcValue() >= kStopCode); 2195 } 2196 2197 bool Simulator::isWatchedStop(uint32_t code) { 2198 DCHECK_LE(code, kMaxStopCode); 2199 return code < kNumOfWatchedStops; 2200 } 2201 2202 bool Simulator::isEnabledStop(uint32_t code) { 2203 DCHECK_LE(code, kMaxStopCode); 2204 // Unwatched stops are always enabled. 2205 return !isWatchedStop(code) || 2206 !(watched_stops_[code].count & kStopDisabledBit); 2207 } 2208 2209 void Simulator::EnableStop(uint32_t code) { 2210 DCHECK(isWatchedStop(code)); 2211 if (!isEnabledStop(code)) { 2212 watched_stops_[code].count &= ~kStopDisabledBit; 2213 } 2214 } 2215 2216 void Simulator::DisableStop(uint32_t code) { 2217 DCHECK(isWatchedStop(code)); 2218 if (isEnabledStop(code)) { 2219 watched_stops_[code].count |= kStopDisabledBit; 2220 } 2221 } 2222 2223 void Simulator::IncreaseStopCounter(uint32_t code) { 2224 DCHECK_LE(code, kMaxStopCode); 2225 DCHECK(isWatchedStop(code)); 2226 if ((watched_stops_[code].count & ~(1 << 31)) == 0x7FFFFFFF) { 2227 PrintF( 2228 "Stop counter for code %i has overflowed.\n" 2229 "Enabling this code and reseting the counter to 0.\n", 2230 code); 2231 watched_stops_[code].count = 0; 2232 EnableStop(code); 2233 } else { 2234 watched_stops_[code].count++; 2235 } 2236 } 2237 2238 // Print a stop status. 2239 void Simulator::PrintStopInfo(uint32_t code) { 2240 DCHECK_LE(code, kMaxStopCode); 2241 if (!isWatchedStop(code)) { 2242 PrintF("Stop not watched."); 2243 } else { 2244 const char* state = isEnabledStop(code) ? "Enabled" : "Disabled"; 2245 int32_t count = watched_stops_[code].count & ~kStopDisabledBit; 2246 // Don't print the state of unused breakpoints. 2247 if (count != 0) { 2248 if (watched_stops_[code].desc) { 2249 PrintF("stop %i - 0x%x: \t%s, \tcounter = %i, \t%s\n", code, code, 2250 state, count, watched_stops_[code].desc); 2251 } else { 2252 PrintF("stop %i - 0x%x: \t%s, \tcounter = %i\n", code, code, state, 2253 count); 2254 } 2255 } 2256 } 2257 } 2258 2259 // Method for checking overflow on signed addition: 2260 // Test src1 and src2 have opposite sign, 2261 // (1) No overflow if they have opposite sign 2262 // (2) Test the result and one of the operands have opposite sign 2263 // (a) No overflow if they don't have opposite sign 2264 // (b) Overflow if opposite 2265 #define CheckOverflowForIntAdd(src1, src2, type) \ 2266 OverflowFromSigned<type>(src1 + src2, src1, src2, true); 2267 2268 #define CheckOverflowForIntSub(src1, src2, type) \ 2269 OverflowFromSigned<type>(src1 - src2, src1, src2, false); 2270 2271 // Method for checking overflow on unsigned addition 2272 #define CheckOverflowForUIntAdd(src1, src2) \ 2273 ((src1) + (src2) < (src1) || (src1) + (src2) < (src2)) 2274 2275 // Method for checking overflow on unsigned subtraction 2276 #define CheckOverflowForUIntSub(src1, src2) ((src1) - (src2) > (src1)) 2277 2278 // Method for checking overflow on multiplication 2279 #define CheckOverflowForMul(src1, src2) (((src1) * (src2)) / (src2) != (src1)) 2280 2281 // Method for checking overflow on shift right 2282 #define CheckOverflowForShiftRight(src1, src2) \ 2283 (((src1) >> (src2)) << (src2) != (src1)) 2284 2285 // Method for checking overflow on shift left 2286 #define CheckOverflowForShiftLeft(src1, src2) \ 2287 (((src1) << (src2)) >> (src2) != (src1)) 2288 2289 int16_t Simulator::ByteReverse(int16_t hword) { 2290 #if defined(__GNUC__) 2291 return __builtin_bswap16(hword); 2292 #else 2293 return (hword << 8) | ((hword >> 8) & 0x00FF); 2294 #endif 2295 } 2296 2297 int32_t Simulator::ByteReverse(int32_t word) { 2298 #if defined(__GNUC__) 2299 return __builtin_bswap32(word); 2300 #else 2301 int32_t result = word << 24; 2302 result |= (word << 8) & 0x00FF0000; 2303 result |= (word >> 8) & 0x0000FF00; 2304 result |= (word >> 24) & 0x00000FF; 2305 return result; 2306 #endif 2307 } 2308 2309 int64_t Simulator::ByteReverse(int64_t dword) { 2310 #if defined(__GNUC__) 2311 return __builtin_bswap64(dword); 2312 #else 2313 #error unsupport __builtin_bswap64 2314 #endif 2315 } 2316 2317 int Simulator::DecodeInstruction(Instruction* instr) { 2318 Opcode op = instr->S390OpcodeValue(); 2319 DCHECK_NOT_NULL(EvalTable[op]); 2320 return (this->*EvalTable[op])(instr); 2321 } 2322 2323 // Executes the current instruction. 2324 void Simulator::ExecuteInstruction(Instruction* instr, bool auto_incr_pc) { 2325 icount_++; 2326 2327 if (v8::internal::FLAG_check_icache) { 2328 CheckICache(i_cache(), instr); 2329 } 2330 2331 pc_modified_ = false; 2332 2333 if (::v8::internal::FLAG_trace_sim) { 2334 disasm::NameConverter converter; 2335 disasm::Disassembler dasm(converter); 2336 // use a reasonably large buffer 2337 v8::internal::EmbeddedVector<char, 256> buffer; 2338 dasm.InstructionDecode(buffer, reinterpret_cast<byte*>(instr)); 2339 PrintF("%05" PRId64 " %08" V8PRIxPTR " %s\n", icount_, 2340 reinterpret_cast<intptr_t>(instr), buffer.start()); 2341 2342 // Flush stdout to prevent incomplete file output during abnormal exits 2343 // This is caused by the output being buffered before being written to file 2344 fflush(stdout); 2345 } 2346 2347 // Try to simulate as S390 Instruction first. 2348 int length = DecodeInstruction(instr); 2349 2350 if (!pc_modified_ && auto_incr_pc) { 2351 DCHECK(length == instr->InstructionLength()); 2352 set_pc(reinterpret_cast<intptr_t>(instr) + length); 2353 } 2354 return; 2355 } 2356 2357 void Simulator::DebugStart() { 2358 S390Debugger dbg(this); 2359 dbg.Debug(); 2360 } 2361 2362 void Simulator::Execute() { 2363 // Get the PC to simulate. Cannot use the accessor here as we need the 2364 // raw PC value and not the one used as input to arithmetic instructions. 2365 intptr_t program_counter = get_pc(); 2366 2367 if (::v8::internal::FLAG_stop_sim_at == 0) { 2368 // Fast version of the dispatch loop without checking whether the simulator 2369 // should be stopping at a particular executed instruction. 2370 while (program_counter != end_sim_pc) { 2371 Instruction* instr = reinterpret_cast<Instruction*>(program_counter); 2372 ExecuteInstruction(instr); 2373 program_counter = get_pc(); 2374 } 2375 } else { 2376 // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when 2377 // we reach the particular instruction count. 2378 while (program_counter != end_sim_pc) { 2379 Instruction* instr = reinterpret_cast<Instruction*>(program_counter); 2380 if (icount_ == ::v8::internal::FLAG_stop_sim_at) { 2381 S390Debugger dbg(this); 2382 dbg.Debug(); 2383 } else { 2384 ExecuteInstruction(instr); 2385 } 2386 program_counter = get_pc(); 2387 } 2388 } 2389 } 2390 2391 void Simulator::CallInternal(Address entry, int reg_arg_count) { 2392 // Adjust JS-based stack limit to C-based stack limit. 2393 isolate_->stack_guard()->AdjustStackLimitForSimulator(); 2394 2395 // Prepare to execute the code at entry 2396 if (ABI_USES_FUNCTION_DESCRIPTORS) { 2397 // entry is the function descriptor 2398 set_pc(*(reinterpret_cast<intptr_t*>(entry))); 2399 } else { 2400 // entry is the instruction address 2401 set_pc(static_cast<intptr_t>(entry)); 2402 } 2403 // Remember the values of non-volatile registers. 2404 int64_t r6_val = get_register(r6); 2405 int64_t r7_val = get_register(r7); 2406 int64_t r8_val = get_register(r8); 2407 int64_t r9_val = get_register(r9); 2408 int64_t r10_val = get_register(r10); 2409 int64_t r11_val = get_register(r11); 2410 int64_t r12_val = get_register(r12); 2411 int64_t r13_val = get_register(r13); 2412 2413 if (ABI_CALL_VIA_IP) { 2414 // Put target address in ip (for JS prologue). 2415 set_register(ip, get_pc()); 2416 } 2417 2418 // Put down marker for end of simulation. The simulator will stop simulation 2419 // when the PC reaches this value. By saving the "end simulation" value into 2420 // the LR the simulation stops when returning to this call point. 2421 registers_[14] = end_sim_pc; 2422 2423 // Set up the non-volatile registers with a known value. To be able to check 2424 // that they are preserved properly across JS execution. 2425 uintptr_t callee_saved_value = icount_; 2426 if (reg_arg_count < 5) { 2427 set_register(r6, callee_saved_value + 6); 2428 } 2429 set_register(r7, callee_saved_value + 7); 2430 set_register(r8, callee_saved_value + 8); 2431 set_register(r9, callee_saved_value + 9); 2432 set_register(r10, callee_saved_value + 10); 2433 set_register(r11, callee_saved_value + 11); 2434 set_register(r12, callee_saved_value + 12); 2435 set_register(r13, callee_saved_value + 13); 2436 2437 // Start the simulation 2438 Execute(); 2439 2440 // Check that the non-volatile registers have been preserved. 2441 #ifndef V8_TARGET_ARCH_S390X 2442 if (reg_arg_count < 5) { 2443 DCHECK_EQ(callee_saved_value + 6, get_low_register<uint32_t>(r6)); 2444 } 2445 DCHECK_EQ(callee_saved_value + 7, get_low_register<uint32_t>(r7)); 2446 DCHECK_EQ(callee_saved_value + 8, get_low_register<uint32_t>(r8)); 2447 DCHECK_EQ(callee_saved_value + 9, get_low_register<uint32_t>(r9)); 2448 DCHECK_EQ(callee_saved_value + 10, get_low_register<uint32_t>(r10)); 2449 DCHECK_EQ(callee_saved_value + 11, get_low_register<uint32_t>(r11)); 2450 DCHECK_EQ(callee_saved_value + 12, get_low_register<uint32_t>(r12)); 2451 DCHECK_EQ(callee_saved_value + 13, get_low_register<uint32_t>(r13)); 2452 #else 2453 if (reg_arg_count < 5) { 2454 DCHECK_EQ(callee_saved_value + 6, get_register(r6)); 2455 } 2456 DCHECK_EQ(callee_saved_value + 7, get_register(r7)); 2457 DCHECK_EQ(callee_saved_value + 8, get_register(r8)); 2458 DCHECK_EQ(callee_saved_value + 9, get_register(r9)); 2459 DCHECK_EQ(callee_saved_value + 10, get_register(r10)); 2460 DCHECK_EQ(callee_saved_value + 11, get_register(r11)); 2461 DCHECK_EQ(callee_saved_value + 12, get_register(r12)); 2462 DCHECK_EQ(callee_saved_value + 13, get_register(r13)); 2463 #endif 2464 2465 // Restore non-volatile registers with the original value. 2466 set_register(r6, r6_val); 2467 set_register(r7, r7_val); 2468 set_register(r8, r8_val); 2469 set_register(r9, r9_val); 2470 set_register(r10, r10_val); 2471 set_register(r11, r11_val); 2472 set_register(r12, r12_val); 2473 set_register(r13, r13_val); 2474 } 2475 2476 intptr_t Simulator::CallImpl(Address entry, int argument_count, 2477 const intptr_t* arguments) { 2478 // Adjust JS-based stack limit to C-based stack limit. 2479 isolate_->stack_guard()->AdjustStackLimitForSimulator(); 2480 2481 // Remember the values of non-volatile registers. 2482 int64_t r6_val = get_register(r6); 2483 int64_t r7_val = get_register(r7); 2484 int64_t r8_val = get_register(r8); 2485 int64_t r9_val = get_register(r9); 2486 int64_t r10_val = get_register(r10); 2487 int64_t r11_val = get_register(r11); 2488 int64_t r12_val = get_register(r12); 2489 int64_t r13_val = get_register(r13); 2490 2491 // Set up arguments 2492 2493 // First 5 arguments passed in registers r2-r6. 2494 int reg_arg_count = std::min(5, argument_count); 2495 int stack_arg_count = argument_count - reg_arg_count; 2496 for (int i = 0; i < reg_arg_count; i++) { 2497 set_register(i + 2, arguments[i]); 2498 } 2499 2500 // Remaining arguments passed on stack. 2501 int64_t original_stack = get_register(sp); 2502 // Compute position of stack on entry to generated code. 2503 uintptr_t entry_stack = 2504 (original_stack - 2505 (kCalleeRegisterSaveAreaSize + stack_arg_count * sizeof(intptr_t))); 2506 if (base::OS::ActivationFrameAlignment() != 0) { 2507 entry_stack &= -base::OS::ActivationFrameAlignment(); 2508 } 2509 2510 // Store remaining arguments on stack, from low to high memory. 2511 intptr_t* stack_argument = 2512 reinterpret_cast<intptr_t*>(entry_stack + kCalleeRegisterSaveAreaSize); 2513 memcpy(stack_argument, arguments + reg_arg_count, 2514 stack_arg_count * sizeof(*arguments)); 2515 set_register(sp, entry_stack); 2516 2517 // Prepare to execute the code at entry 2518 #if ABI_USES_FUNCTION_DESCRIPTORS 2519 // entry is the function descriptor 2520 set_pc(*(reinterpret_cast<intptr_t*>(entry))); 2521 #else 2522 // entry is the instruction address 2523 set_pc(static_cast<intptr_t>(entry)); 2524 #endif 2525 2526 // Put target address in ip (for JS prologue). 2527 set_register(r12, get_pc()); 2528 2529 // Put down marker for end of simulation. The simulator will stop simulation 2530 // when the PC reaches this value. By saving the "end simulation" value into 2531 // the LR the simulation stops when returning to this call point. 2532 registers_[14] = end_sim_pc; 2533 2534 // Set up the non-volatile registers with a known value. To be able to check 2535 // that they are preserved properly across JS execution. 2536 uintptr_t callee_saved_value = icount_; 2537 if (reg_arg_count < 5) { 2538 set_register(r6, callee_saved_value + 6); 2539 } 2540 set_register(r7, callee_saved_value + 7); 2541 set_register(r8, callee_saved_value + 8); 2542 set_register(r9, callee_saved_value + 9); 2543 set_register(r10, callee_saved_value + 10); 2544 set_register(r11, callee_saved_value + 11); 2545 set_register(r12, callee_saved_value + 12); 2546 set_register(r13, callee_saved_value + 13); 2547 2548 // Start the simulation 2549 Execute(); 2550 2551 // Check that the non-volatile registers have been preserved. 2552 #ifndef V8_TARGET_ARCH_S390X 2553 if (reg_arg_count < 5) { 2554 DCHECK_EQ(callee_saved_value + 6, get_low_register<uint32_t>(r6)); 2555 } 2556 DCHECK_EQ(callee_saved_value + 7, get_low_register<uint32_t>(r7)); 2557 DCHECK_EQ(callee_saved_value + 8, get_low_register<uint32_t>(r8)); 2558 DCHECK_EQ(callee_saved_value + 9, get_low_register<uint32_t>(r9)); 2559 DCHECK_EQ(callee_saved_value + 10, get_low_register<uint32_t>(r10)); 2560 DCHECK_EQ(callee_saved_value + 11, get_low_register<uint32_t>(r11)); 2561 DCHECK_EQ(callee_saved_value + 12, get_low_register<uint32_t>(r12)); 2562 DCHECK_EQ(callee_saved_value + 13, get_low_register<uint32_t>(r13)); 2563 #else 2564 if (reg_arg_count < 5) { 2565 DCHECK_EQ(callee_saved_value + 6, get_register(r6)); 2566 } 2567 DCHECK_EQ(callee_saved_value + 7, get_register(r7)); 2568 DCHECK_EQ(callee_saved_value + 8, get_register(r8)); 2569 DCHECK_EQ(callee_saved_value + 9, get_register(r9)); 2570 DCHECK_EQ(callee_saved_value + 10, get_register(r10)); 2571 DCHECK_EQ(callee_saved_value + 11, get_register(r11)); 2572 DCHECK_EQ(callee_saved_value + 12, get_register(r12)); 2573 DCHECK_EQ(callee_saved_value + 13, get_register(r13)); 2574 #endif 2575 2576 // Restore non-volatile registers with the original value. 2577 set_register(r6, r6_val); 2578 set_register(r7, r7_val); 2579 set_register(r8, r8_val); 2580 set_register(r9, r9_val); 2581 set_register(r10, r10_val); 2582 set_register(r11, r11_val); 2583 set_register(r12, r12_val); 2584 set_register(r13, r13_val); 2585 // Pop stack passed arguments. 2586 2587 #ifndef V8_TARGET_ARCH_S390X 2588 DCHECK_EQ(entry_stack, get_low_register<uint32_t>(sp)); 2589 #else 2590 DCHECK_EQ(entry_stack, get_register(sp)); 2591 #endif 2592 set_register(sp, original_stack); 2593 2594 // Return value register 2595 return get_register(r2); 2596 } 2597 2598 void Simulator::CallFP(Address entry, double d0, double d1) { 2599 set_d_register_from_double(0, d0); 2600 set_d_register_from_double(1, d1); 2601 CallInternal(entry); 2602 } 2603 2604 int32_t Simulator::CallFPReturnsInt(Address entry, double d0, double d1) { 2605 CallFP(entry, d0, d1); 2606 int32_t result = get_register(r2); 2607 return result; 2608 } 2609 2610 double Simulator::CallFPReturnsDouble(Address entry, double d0, double d1) { 2611 CallFP(entry, d0, d1); 2612 return get_double_from_d_register(0); 2613 } 2614 2615 uintptr_t Simulator::PushAddress(uintptr_t address) { 2616 uintptr_t new_sp = get_register(sp) - sizeof(uintptr_t); 2617 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(new_sp); 2618 *stack_slot = address; 2619 set_register(sp, new_sp); 2620 return new_sp; 2621 } 2622 2623 uintptr_t Simulator::PopAddress() { 2624 uintptr_t current_sp = get_register(sp); 2625 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); 2626 uintptr_t address = *stack_slot; 2627 set_register(sp, current_sp + sizeof(uintptr_t)); 2628 return address; 2629 } 2630 2631 #define EVALUATE(name) \ 2632 int Simulator::Evaluate_##name(Instruction* instr) 2633 2634 #define DCHECK_OPCODE(op) DCHECK(instr->S390OpcodeValue() == op) 2635 2636 #define AS(type) reinterpret_cast<type*>(instr) 2637 2638 #define DECODE_RIL_A_INSTRUCTION(r1, i2) \ 2639 int r1 = AS(RILInstruction)->R1Value(); \ 2640 uint32_t i2 = AS(RILInstruction)->I2UnsignedValue(); \ 2641 int length = 6; 2642 2643 #define DECODE_RIL_B_INSTRUCTION(r1, i2) \ 2644 int r1 = AS(RILInstruction)->R1Value(); \ 2645 int32_t i2 = AS(RILInstruction)->I2Value(); \ 2646 int length = 6; 2647 2648 #define DECODE_RIL_C_INSTRUCTION(m1, ri2) \ 2649 Condition m1 = static_cast<Condition>(AS(RILInstruction)->R1Value()); \ 2650 uint64_t ri2 = AS(RILInstruction)->I2Value(); \ 2651 int length = 6; 2652 2653 #define DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2) \ 2654 int r1 = AS(RXYInstruction)->R1Value(); \ 2655 int x2 = AS(RXYInstruction)->X2Value(); \ 2656 int b2 = AS(RXYInstruction)->B2Value(); \ 2657 int d2 = AS(RXYInstruction)->D2Value(); \ 2658 int length = 6; 2659 2660 #define DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val) \ 2661 int x2 = AS(RXInstruction)->X2Value(); \ 2662 int b2 = AS(RXInstruction)->B2Value(); \ 2663 int r1 = AS(RXInstruction)->R1Value(); \ 2664 intptr_t d2_val = AS(RXInstruction)->D2Value(); \ 2665 int length = 4; 2666 2667 #define DECODE_RS_A_INSTRUCTION(r1, r3, b2, d2) \ 2668 int r3 = AS(RSInstruction)->R3Value(); \ 2669 int b2 = AS(RSInstruction)->B2Value(); \ 2670 int r1 = AS(RSInstruction)->R1Value(); \ 2671 intptr_t d2 = AS(RSInstruction)->D2Value(); \ 2672 int length = 4; 2673 2674 #define DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2) \ 2675 int b2 = AS(RSInstruction)->B2Value(); \ 2676 int r1 = AS(RSInstruction)->R1Value(); \ 2677 int d2 = AS(RSInstruction)->D2Value(); \ 2678 int length = 4; 2679 2680 #define DECODE_RSI_INSTRUCTION(r1, r3, i2) \ 2681 int r1 = AS(RSIInstruction)->R1Value(); \ 2682 int r3 = AS(RSIInstruction)->R3Value(); \ 2683 int32_t i2 = AS(RSIInstruction)->I2Value(); \ 2684 int length = 4; 2685 2686 #define DECODE_SI_INSTRUCTION_I_UINT8(b1, d1_val, imm_val) \ 2687 int b1 = AS(SIInstruction)->B1Value(); \ 2688 intptr_t d1_val = AS(SIInstruction)->D1Value(); \ 2689 uint8_t imm_val = AS(SIInstruction)->I2Value(); \ 2690 int length = 4; 2691 2692 #define DECODE_SIL_INSTRUCTION(b1, d1, i2) \ 2693 int b1 = AS(SILInstruction)->B1Value(); \ 2694 intptr_t d1 = AS(SILInstruction)->D1Value(); \ 2695 int16_t i2 = AS(SILInstruction)->I2Value(); \ 2696 int length = 6; 2697 2698 #define DECODE_SIY_INSTRUCTION(b1, d1, i2) \ 2699 int b1 = AS(SIYInstruction)->B1Value(); \ 2700 intptr_t d1 = AS(SIYInstruction)->D1Value(); \ 2701 uint8_t i2 = AS(SIYInstruction)->I2Value(); \ 2702 int length = 6; 2703 2704 #define DECODE_RRE_INSTRUCTION(r1, r2) \ 2705 int r1 = AS(RREInstruction)->R1Value(); \ 2706 int r2 = AS(RREInstruction)->R2Value(); \ 2707 int length = 4; 2708 2709 #define DECODE_RRE_INSTRUCTION_M3(r1, r2, m3) \ 2710 int r1 = AS(RREInstruction)->R1Value(); \ 2711 int r2 = AS(RREInstruction)->R2Value(); \ 2712 int m3 = AS(RREInstruction)->M3Value(); \ 2713 int length = 4; 2714 2715 #define DECODE_RRE_INSTRUCTION_NO_R2(r1) \ 2716 int r1 = AS(RREInstruction)->R1Value(); \ 2717 int length = 4; 2718 2719 #define DECODE_RRD_INSTRUCTION(r1, r2, r3) \ 2720 int r1 = AS(RRDInstruction)->R1Value(); \ 2721 int r2 = AS(RRDInstruction)->R2Value(); \ 2722 int r3 = AS(RRDInstruction)->R3Value(); \ 2723 int length = 4; 2724 2725 #define DECODE_RRF_E_INSTRUCTION(r1, r2, m3, m4) \ 2726 int r1 = AS(RRFInstruction)->R1Value(); \ 2727 int r2 = AS(RRFInstruction)->R2Value(); \ 2728 int m3 = AS(RRFInstruction)->M3Value(); \ 2729 int m4 = AS(RRFInstruction)->M4Value(); \ 2730 int length = 4; 2731 2732 #define DECODE_RRF_A_INSTRUCTION(r1, r2, r3) \ 2733 int r1 = AS(RRFInstruction)->R1Value(); \ 2734 int r2 = AS(RRFInstruction)->R2Value(); \ 2735 int r3 = AS(RRFInstruction)->R3Value(); \ 2736 int length = 4; 2737 2738 #define DECODE_RRF_C_INSTRUCTION(r1, r2, m3) \ 2739 int r1 = AS(RRFInstruction)->R1Value(); \ 2740 int r2 = AS(RRFInstruction)->R2Value(); \ 2741 Condition m3 = static_cast<Condition>(AS(RRFInstruction)->M3Value()); \ 2742 int length = 4; 2743 2744 #define DECODE_RR_INSTRUCTION(r1, r2) \ 2745 int r1 = AS(RRInstruction)->R1Value(); \ 2746 int r2 = AS(RRInstruction)->R2Value(); \ 2747 int length = 2; 2748 2749 #define DECODE_RIE_D_INSTRUCTION(r1, r2, i2) \ 2750 int r1 = AS(RIEInstruction)->R1Value(); \ 2751 int r2 = AS(RIEInstruction)->R2Value(); \ 2752 int32_t i2 = AS(RIEInstruction)->I6Value(); \ 2753 int length = 6; 2754 2755 #define DECODE_RIE_E_INSTRUCTION(r1, r2, i2) \ 2756 int r1 = AS(RIEInstruction)->R1Value(); \ 2757 int r2 = AS(RIEInstruction)->R2Value(); \ 2758 int32_t i2 = AS(RIEInstruction)->I6Value(); \ 2759 int length = 6; 2760 2761 #define DECODE_RIE_F_INSTRUCTION(r1, r2, i3, i4, i5) \ 2762 int r1 = AS(RIEInstruction)->R1Value(); \ 2763 int r2 = AS(RIEInstruction)->R2Value(); \ 2764 uint32_t i3 = AS(RIEInstruction)->I3Value(); \ 2765 uint32_t i4 = AS(RIEInstruction)->I4Value(); \ 2766 uint32_t i5 = AS(RIEInstruction)->I5Value(); \ 2767 int length = 6; 2768 2769 #define DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2) \ 2770 int r1 = AS(RSYInstruction)->R1Value(); \ 2771 int r3 = AS(RSYInstruction)->R3Value(); \ 2772 int b2 = AS(RSYInstruction)->B2Value(); \ 2773 intptr_t d2 = AS(RSYInstruction)->D2Value(); \ 2774 int length = 6; 2775 2776 #define DECODE_RI_A_INSTRUCTION(instr, r1, i2) \ 2777 int32_t r1 = AS(RIInstruction)->R1Value(); \ 2778 int16_t i2 = AS(RIInstruction)->I2Value(); \ 2779 int length = 4; 2780 2781 #define DECODE_RI_B_INSTRUCTION(instr, r1, i2) \ 2782 int32_t r1 = AS(RILInstruction)->R1Value(); \ 2783 int16_t i2 = AS(RILInstruction)->I2Value(); \ 2784 int length = 4; 2785 2786 #define DECODE_RI_C_INSTRUCTION(instr, m1, i2) \ 2787 Condition m1 = static_cast<Condition>(AS(RIInstruction)->R1Value()); \ 2788 int16_t i2 = AS(RIInstruction)->I2Value(); \ 2789 int length = 4; 2790 2791 #define DECODE_RXE_INSTRUCTION(r1, b2, x2, d2) \ 2792 int r1 = AS(RXEInstruction)->R1Value(); \ 2793 int b2 = AS(RXEInstruction)->B2Value(); \ 2794 int x2 = AS(RXEInstruction)->X2Value(); \ 2795 int d2 = AS(RXEInstruction)->D2Value(); \ 2796 int length = 6; 2797 2798 #define DECODE_VRR_C_INSTRUCTION(r1, r2, r3, m6, m5, m4) \ 2799 int r1 = AS(VRR_C_Instruction)->R1Value(); \ 2800 int r2 = AS(VRR_C_Instruction)->R2Value(); \ 2801 int r3 = AS(VRR_C_Instruction)->R3Value(); \ 2802 int m6 = AS(VRR_C_Instruction)->M6Value(); \ 2803 int m5 = AS(VRR_C_Instruction)->M5Value(); \ 2804 int m4 = AS(VRR_C_Instruction)->M4Value(); \ 2805 int length = 6; 2806 2807 #define GET_ADDRESS(index_reg, base_reg, offset) \ 2808 (((index_reg) == 0) ? 0 : get_register(index_reg)) + \ 2809 (((base_reg) == 0) ? 0 : get_register(base_reg)) + offset 2810 2811 int Simulator::Evaluate_Unknown(Instruction* instr) { 2812 UNREACHABLE(); 2813 } 2814 2815 EVALUATE(VFA) { 2816 DCHECK_OPCODE(VFA); 2817 DECODE_VRR_C_INSTRUCTION(r1, r2, r3, m6, m5, m4); 2818 USE(m6); 2819 USE(m5); 2820 USE(m4); 2821 DCHECK_EQ(m5, 8); 2822 DCHECK_EQ(m4, 3); 2823 double r2_val = get_double_from_d_register(r2); 2824 double r3_val = get_double_from_d_register(r3); 2825 double r1_val = r2_val + r3_val; 2826 set_d_register_from_double(r1, r1_val); 2827 return length; 2828 } 2829 2830 EVALUATE(VFS) { 2831 DCHECK_OPCODE(VFS); 2832 DECODE_VRR_C_INSTRUCTION(r1, r2, r3, m6, m5, m4); 2833 USE(m6); 2834 USE(m5); 2835 USE(m4); 2836 DCHECK_EQ(m5, 8); 2837 DCHECK_EQ(m4, 3); 2838 double r2_val = get_double_from_d_register(r2); 2839 double r3_val = get_double_from_d_register(r3); 2840 double r1_val = r2_val - r3_val; 2841 set_d_register_from_double(r1, r1_val); 2842 return length; 2843 } 2844 2845 EVALUATE(VFM) { 2846 DCHECK_OPCODE(VFM); 2847 DECODE_VRR_C_INSTRUCTION(r1, r2, r3, m6, m5, m4); 2848 USE(m6); 2849 USE(m5); 2850 USE(m4); 2851 DCHECK_EQ(m5, 8); 2852 DCHECK_EQ(m4, 3); 2853 double r2_val = get_double_from_d_register(r2); 2854 double r3_val = get_double_from_d_register(r3); 2855 double r1_val = r2_val * r3_val; 2856 set_d_register_from_double(r1, r1_val); 2857 return length; 2858 } 2859 2860 EVALUATE(VFD) { 2861 DCHECK_OPCODE(VFD); 2862 DECODE_VRR_C_INSTRUCTION(r1, r2, r3, m6, m5, m4); 2863 USE(m6); 2864 USE(m5); 2865 USE(m4); 2866 DCHECK_EQ(m5, 8); 2867 DCHECK_EQ(m4, 3); 2868 double r2_val = get_double_from_d_register(r2); 2869 double r3_val = get_double_from_d_register(r3); 2870 double r1_val = r2_val / r3_val; 2871 set_d_register_from_double(r1, r1_val); 2872 return length; 2873 } 2874 2875 EVALUATE(DUMY) { 2876 DCHECK_OPCODE(DUMY); 2877 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 2878 USE(r1); 2879 USE(x2); 2880 USE(b2); 2881 USE(d2); 2882 // dummy instruction does nothing. 2883 return length; 2884 } 2885 2886 EVALUATE(CLR) { 2887 DCHECK_OPCODE(CLR); 2888 DECODE_RR_INSTRUCTION(r1, r2); 2889 uint32_t r1_val = get_low_register<uint32_t>(r1); 2890 uint32_t r2_val = get_low_register<uint32_t>(r2); 2891 SetS390ConditionCode<uint32_t>(r1_val, r2_val); 2892 return length; 2893 } 2894 2895 EVALUATE(LR) { 2896 DCHECK_OPCODE(LR); 2897 DECODE_RR_INSTRUCTION(r1, r2); 2898 set_low_register(r1, get_low_register<int32_t>(r2)); 2899 return length; 2900 } 2901 2902 EVALUATE(AR) { 2903 DCHECK_OPCODE(AR); 2904 DECODE_RR_INSTRUCTION(r1, r2); 2905 int32_t r1_val = get_low_register<int32_t>(r1); 2906 int32_t r2_val = get_low_register<int32_t>(r2); 2907 bool isOF = CheckOverflowForIntAdd(r1_val, r2_val, int32_t); 2908 r1_val += r2_val; 2909 SetS390ConditionCode<int32_t>(r1_val, 0); 2910 SetS390OverflowCode(isOF); 2911 set_low_register(r1, r1_val); 2912 return length; 2913 } 2914 2915 EVALUATE(L) { 2916 DCHECK_OPCODE(L); 2917 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); 2918 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 2919 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 2920 intptr_t addr = b2_val + x2_val + d2_val; 2921 int32_t mem_val = ReadW(addr, instr); 2922 set_low_register(r1, mem_val); 2923 return length; 2924 } 2925 2926 EVALUATE(BRC) { 2927 DCHECK_OPCODE(BRC); 2928 DECODE_RI_C_INSTRUCTION(instr, m1, i2); 2929 2930 if (TestConditionCode(m1)) { 2931 intptr_t offset = 2 * i2; 2932 set_pc(get_pc() + offset); 2933 } 2934 return length; 2935 } 2936 2937 EVALUATE(AHI) { 2938 DCHECK_OPCODE(AHI); 2939 DECODE_RI_A_INSTRUCTION(instr, r1, i2); 2940 int32_t r1_val = get_low_register<int32_t>(r1); 2941 bool isOF = CheckOverflowForIntAdd(r1_val, i2, int32_t); 2942 r1_val += i2; 2943 set_low_register(r1, r1_val); 2944 SetS390ConditionCode<int32_t>(r1_val, 0); 2945 SetS390OverflowCode(isOF); 2946 return length; 2947 } 2948 2949 EVALUATE(AGHI) { 2950 DCHECK_OPCODE(AGHI); 2951 DECODE_RI_A_INSTRUCTION(instr, r1, i2); 2952 int64_t r1_val = get_register(r1); 2953 bool isOF = false; 2954 isOF = CheckOverflowForIntAdd(r1_val, i2, int64_t); 2955 r1_val += i2; 2956 set_register(r1, r1_val); 2957 SetS390ConditionCode<int64_t>(r1_val, 0); 2958 SetS390OverflowCode(isOF); 2959 return length; 2960 } 2961 2962 EVALUATE(BRCL) { 2963 DCHECK_OPCODE(BRCL); 2964 DECODE_RIL_C_INSTRUCTION(m1, ri2); 2965 2966 if (TestConditionCode(m1)) { 2967 intptr_t offset = 2 * ri2; 2968 set_pc(get_pc() + offset); 2969 } 2970 return length; 2971 } 2972 2973 EVALUATE(IIHF) { 2974 DCHECK_OPCODE(IIHF); 2975 DECODE_RIL_A_INSTRUCTION(r1, imm); 2976 set_high_register(r1, imm); 2977 return length; 2978 } 2979 2980 EVALUATE(IILF) { 2981 DCHECK_OPCODE(IILF); 2982 DECODE_RIL_A_INSTRUCTION(r1, imm); 2983 set_low_register(r1, imm); 2984 return length; 2985 } 2986 2987 EVALUATE(LGR) { 2988 DCHECK_OPCODE(LGR); 2989 DECODE_RRE_INSTRUCTION(r1, r2); 2990 set_register(r1, get_register(r2)); 2991 return length; 2992 } 2993 2994 EVALUATE(LG) { 2995 DCHECK_OPCODE(LG); 2996 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 2997 intptr_t addr = GET_ADDRESS(x2, b2, d2); 2998 int64_t mem_val = ReadDW(addr); 2999 set_register(r1, mem_val); 3000 return length; 3001 } 3002 3003 EVALUATE(AGR) { 3004 DCHECK_OPCODE(AGR); 3005 DECODE_RRE_INSTRUCTION(r1, r2); 3006 int64_t r1_val = get_register(r1); 3007 int64_t r2_val = get_register(r2); 3008 bool isOF = CheckOverflowForIntAdd(r1_val, r2_val, int64_t); 3009 r1_val += r2_val; 3010 set_register(r1, r1_val); 3011 SetS390ConditionCode<int64_t>(r1_val, 0); 3012 SetS390OverflowCode(isOF); 3013 return length; 3014 } 3015 3016 EVALUATE(LGFR) { 3017 DCHECK_OPCODE(LGFR); 3018 DECODE_RRE_INSTRUCTION(r1, r2); 3019 int32_t r2_val = get_low_register<int32_t>(r2); 3020 int64_t result = static_cast<int64_t>(r2_val); 3021 set_register(r1, result); 3022 3023 return length; 3024 } 3025 3026 EVALUATE(LBR) { 3027 DCHECK_OPCODE(LBR); 3028 DECODE_RRE_INSTRUCTION(r1, r2); 3029 int32_t r2_val = get_low_register<int32_t>(r2); 3030 r2_val <<= 24; 3031 r2_val >>= 24; 3032 set_low_register(r1, r2_val); 3033 return length; 3034 } 3035 3036 EVALUATE(LGBR) { 3037 DCHECK_OPCODE(LGBR); 3038 DECODE_RRE_INSTRUCTION(r1, r2); 3039 int64_t r2_val = get_low_register<int64_t>(r2); 3040 r2_val <<= 56; 3041 r2_val >>= 56; 3042 set_register(r1, r2_val); 3043 return length; 3044 } 3045 3046 EVALUATE(LHR) { 3047 DCHECK_OPCODE(LHR); 3048 DECODE_RRE_INSTRUCTION(r1, r2); 3049 int32_t r2_val = get_low_register<int32_t>(r2); 3050 r2_val <<= 16; 3051 r2_val >>= 16; 3052 set_low_register(r1, r2_val); 3053 return length; 3054 } 3055 3056 EVALUATE(LGHR) { 3057 DCHECK_OPCODE(LGHR); 3058 DECODE_RRE_INSTRUCTION(r1, r2); 3059 int64_t r2_val = get_low_register<int64_t>(r2); 3060 r2_val <<= 48; 3061 r2_val >>= 48; 3062 set_register(r1, r2_val); 3063 return length; 3064 } 3065 3066 EVALUATE(LGF) { 3067 DCHECK_OPCODE(LGF); 3068 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 3069 intptr_t addr = GET_ADDRESS(x2, b2, d2); 3070 int64_t mem_val = static_cast<int64_t>(ReadW(addr, instr)); 3071 set_register(r1, mem_val); 3072 return length; 3073 } 3074 3075 EVALUATE(ST) { 3076 DCHECK_OPCODE(ST); 3077 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); 3078 int32_t r1_val = get_low_register<int32_t>(r1); 3079 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 3080 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 3081 intptr_t addr = b2_val + x2_val + d2_val; 3082 WriteW(addr, r1_val, instr); 3083 return length; 3084 } 3085 3086 EVALUATE(STG) { 3087 DCHECK_OPCODE(STG); 3088 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 3089 intptr_t addr = GET_ADDRESS(x2, b2, d2); 3090 uint64_t value = get_register(r1); 3091 WriteDW(addr, value); 3092 return length; 3093 } 3094 3095 EVALUATE(STY) { 3096 DCHECK_OPCODE(STY); 3097 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 3098 intptr_t addr = GET_ADDRESS(x2, b2, d2); 3099 uint32_t value = get_low_register<uint32_t>(r1); 3100 WriteW(addr, value, instr); 3101 return length; 3102 } 3103 3104 EVALUATE(LY) { 3105 DCHECK_OPCODE(LY); 3106 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 3107 intptr_t addr = GET_ADDRESS(x2, b2, d2); 3108 uint32_t mem_val = ReadWU(addr, instr); 3109 set_low_register(r1, mem_val); 3110 return length; 3111 } 3112 3113 EVALUATE(LLGC) { 3114 DCHECK_OPCODE(LLGC); 3115 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 3116 uint8_t mem_val = ReadBU(GET_ADDRESS(x2, b2, d2)); 3117 set_register(r1, static_cast<uint64_t>(mem_val)); 3118 return length; 3119 } 3120 3121 EVALUATE(LLC) { 3122 DCHECK_OPCODE(LLC); 3123 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 3124 uint8_t mem_val = ReadBU(GET_ADDRESS(x2, b2, d2)); 3125 set_low_register(r1, static_cast<uint32_t>(mem_val)); 3126 return length; 3127 } 3128 3129 EVALUATE(RLL) { 3130 DCHECK_OPCODE(RLL); 3131 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2); 3132 // only takes rightmost 6 bits 3133 int shiftBits = GET_ADDRESS(0, b2, d2) & 0x3F; 3134 // unsigned 3135 uint32_t r3_val = get_low_register<uint32_t>(r3); 3136 uint32_t alu_out = 0; 3137 uint32_t rotateBits = r3_val >> (32 - shiftBits); 3138 alu_out = (r3_val << shiftBits) | (rotateBits); 3139 set_low_register(r1, alu_out); 3140 return length; 3141 } 3142 3143 EVALUATE(RISBG) { 3144 DCHECK_OPCODE(RISBG); 3145 DECODE_RIE_F_INSTRUCTION(r1, r2, i3, i4, i5); 3146 // Starting Bit Position is Bits 2-7 of I3 field 3147 uint32_t start_bit = i3 & 0x3F; 3148 // Ending Bit Position is Bits 2-7 of I4 field 3149 uint32_t end_bit = i4 & 0x3F; 3150 // Shift Amount is Bits 2-7 of I5 field 3151 uint32_t shift_amount = i5 & 0x3F; 3152 // Zero out Remaining (unslected) bits if Bit 0 of I4 is 1. 3153 bool zero_remaining = (0 != (i4 & 0x80)); 3154 3155 uint64_t src_val = get_register(r2); 3156 3157 // Rotate Left by Shift Amount first 3158 uint64_t rotated_val = 3159 (src_val << shift_amount) | (src_val >> (64 - shift_amount)); 3160 int32_t width = end_bit - start_bit + 1; 3161 3162 uint64_t selection_mask = 0; 3163 if (width < 64) { 3164 selection_mask = (static_cast<uint64_t>(1) << width) - 1; 3165 } else { 3166 selection_mask = static_cast<uint64_t>(static_cast<int64_t>(-1)); 3167 } 3168 selection_mask = selection_mask << (63 - end_bit); 3169 3170 uint64_t selected_val = rotated_val & selection_mask; 3171 3172 if (!zero_remaining) { 3173 // Merged the unselected bits from the original value 3174 selected_val = (get_register(r1) & ~selection_mask) | selected_val; 3175 } 3176 3177 // Condition code is set by treating result as 64-bit signed int 3178 SetS390ConditionCode<int64_t>(selected_val, 0); 3179 set_register(r1, selected_val); 3180 return length; 3181 } 3182 3183 EVALUATE(AHIK) { 3184 DCHECK_OPCODE(AHIK); 3185 DECODE_RIE_D_INSTRUCTION(r1, r2, i2); 3186 int32_t r2_val = get_low_register<int32_t>(r2); 3187 int32_t imm = static_cast<int32_t>(i2); 3188 bool isOF = CheckOverflowForIntAdd(r2_val, imm, int32_t); 3189 set_low_register(r1, r2_val + imm); 3190 SetS390ConditionCode<int32_t>(r2_val + imm, 0); 3191 SetS390OverflowCode(isOF); 3192 return length; 3193 } 3194 3195 EVALUATE(AGHIK) { 3196 // 64-bit Add 3197 DCHECK_OPCODE(AGHIK); 3198 DECODE_RIE_D_INSTRUCTION(r1, r2, i2); 3199 int64_t r2_val = get_register(r2); 3200 int64_t imm = static_cast<int64_t>(i2); 3201 bool isOF = CheckOverflowForIntAdd(r2_val, imm, int64_t); 3202 set_register(r1, r2_val + imm); 3203 SetS390ConditionCode<int64_t>(r2_val + imm, 0); 3204 SetS390OverflowCode(isOF); 3205 return length; 3206 } 3207 3208 EVALUATE(BKPT) { 3209 DCHECK_OPCODE(BKPT); 3210 set_pc(get_pc() + 2); 3211 S390Debugger dbg(this); 3212 dbg.Debug(); 3213 int length = 2; 3214 return length; 3215 } 3216 3217 EVALUATE(SPM) { 3218 UNIMPLEMENTED(); 3219 USE(instr); 3220 return 0; 3221 } 3222 3223 EVALUATE(BALR) { 3224 UNIMPLEMENTED(); 3225 USE(instr); 3226 return 0; 3227 } 3228 3229 EVALUATE(BCTR) { 3230 UNIMPLEMENTED(); 3231 USE(instr); 3232 return 0; 3233 } 3234 3235 EVALUATE(BCR) { 3236 DCHECK_OPCODE(BCR); 3237 DECODE_RR_INSTRUCTION(r1, r2); 3238 if (TestConditionCode(Condition(r1))) { 3239 intptr_t r2_val = get_register(r2); 3240 #if (!V8_TARGET_ARCH_S390X && V8_HOST_ARCH_S390) 3241 // On 31-bit, the top most bit may be 0 or 1, but is ignored by the 3242 // hardware. Cleanse the top bit before jumping to it, unless it's one 3243 // of the special PCs 3244 if (r2_val != bad_lr && r2_val != end_sim_pc) r2_val &= 0x7FFFFFFF; 3245 #endif 3246 set_pc(r2_val); 3247 } 3248 3249 return length; 3250 } 3251 3252 EVALUATE(SVC) { 3253 UNIMPLEMENTED(); 3254 USE(instr); 3255 return 0; 3256 } 3257 3258 EVALUATE(BSM) { 3259 UNIMPLEMENTED(); 3260 USE(instr); 3261 return 0; 3262 } 3263 3264 EVALUATE(BASSM) { 3265 UNIMPLEMENTED(); 3266 USE(instr); 3267 return 0; 3268 } 3269 3270 EVALUATE(BASR) { 3271 DCHECK_OPCODE(BASR); 3272 DECODE_RR_INSTRUCTION(r1, r2); 3273 intptr_t link_addr = get_pc() + 2; 3274 // If R2 is zero, the BASR does not branch. 3275 int64_t r2_val = (r2 == 0) ? link_addr : get_register(r2); 3276 #if (!V8_TARGET_ARCH_S390X && V8_HOST_ARCH_S390) 3277 // On 31-bit, the top most bit may be 0 or 1, which can cause issues 3278 // for stackwalker. The top bit should either be cleanse before being 3279 // pushed onto the stack, or during stack walking when dereferenced. 3280 // For simulator, we'll take the worst case scenario and always tag 3281 // the high bit, to flush out more problems. 3282 link_addr |= 0x80000000; 3283 #endif 3284 set_register(r1, link_addr); 3285 set_pc(r2_val); 3286 return length; 3287 } 3288 3289 EVALUATE(MVCL) { 3290 UNIMPLEMENTED(); 3291 USE(instr); 3292 return 0; 3293 } 3294 3295 EVALUATE(CLCL) { 3296 UNIMPLEMENTED(); 3297 USE(instr); 3298 return 0; 3299 } 3300 3301 EVALUATE(LPR) { 3302 DCHECK_OPCODE(LPR); 3303 // Load Positive (32) 3304 DECODE_RR_INSTRUCTION(r1, r2); 3305 int32_t r2_val = get_low_register<int32_t>(r2); 3306 // If negative, then negate it. 3307 r2_val = (r2_val < 0) ? -r2_val : r2_val; 3308 set_low_register(r1, r2_val); 3309 SetS390ConditionCode<int32_t>(r2_val, 0); 3310 if (r2_val == (static_cast<int32_t>(1) << 31)) { 3311 SetS390OverflowCode(true); 3312 } 3313 return length; 3314 } 3315 3316 EVALUATE(LNR) { 3317 DCHECK_OPCODE(LNR); 3318 // Load Negative (32) 3319 DECODE_RR_INSTRUCTION(r1, r2); 3320 int32_t r2_val = get_low_register<int32_t>(r2); 3321 r2_val = (r2_val >= 0) ? -r2_val : r2_val; // If pos, then negate it. 3322 set_low_register(r1, r2_val); 3323 condition_reg_ = (r2_val == 0) ? CC_EQ : CC_LT; // CC0 - result is zero 3324 // CC1 - result is negative 3325 return length; 3326 } 3327 3328 EVALUATE(LTR) { 3329 DCHECK_OPCODE(LTR); 3330 DECODE_RR_INSTRUCTION(r1, r2); 3331 int32_t r2_val = get_low_register<int32_t>(r2); 3332 SetS390ConditionCode<int32_t>(r2_val, 0); 3333 set_low_register(r1, r2_val); 3334 return length; 3335 } 3336 3337 EVALUATE(LCR) { 3338 DCHECK_OPCODE(LCR); 3339 DECODE_RR_INSTRUCTION(r1, r2); 3340 int32_t r2_val = get_low_register<int32_t>(r2); 3341 int32_t result = 0; 3342 bool isOF = false; 3343 isOF = __builtin_ssub_overflow(0, r2_val, &result); 3344 set_low_register(r1, result); 3345 SetS390ConditionCode<int32_t>(r2_val, 0); 3346 // Checks for overflow where r2_val = -2147483648. 3347 // Cannot do int comparison due to GCC 4.8 bug on x86. 3348 // Detect INT_MIN alternatively, as it is the only value where both 3349 // original and result are negative due to overflow. 3350 if (isOF) { 3351 SetS390OverflowCode(true); 3352 } 3353 return length; 3354 } 3355 3356 EVALUATE(NR) { 3357 DCHECK_OPCODE(NR); 3358 DECODE_RR_INSTRUCTION(r1, r2); 3359 int32_t r1_val = get_low_register<int32_t>(r1); 3360 int32_t r2_val = get_low_register<int32_t>(r2); 3361 r1_val &= r2_val; 3362 SetS390BitWiseConditionCode<uint32_t>(r1_val); 3363 set_low_register(r1, r1_val); 3364 return length; 3365 } 3366 3367 EVALUATE(OR) { 3368 DCHECK_OPCODE(OR); 3369 DECODE_RR_INSTRUCTION(r1, r2); 3370 int32_t r1_val = get_low_register<int32_t>(r1); 3371 int32_t r2_val = get_low_register<int32_t>(r2); 3372 r1_val |= r2_val; 3373 SetS390BitWiseConditionCode<uint32_t>(r1_val); 3374 set_low_register(r1, r1_val); 3375 return length; 3376 } 3377 3378 EVALUATE(XR) { 3379 DCHECK_OPCODE(XR); 3380 DECODE_RR_INSTRUCTION(r1, r2); 3381 int32_t r1_val = get_low_register<int32_t>(r1); 3382 int32_t r2_val = get_low_register<int32_t>(r2); 3383 r1_val ^= r2_val; 3384 SetS390BitWiseConditionCode<uint32_t>(r1_val); 3385 set_low_register(r1, r1_val); 3386 return length; 3387 } 3388 3389 EVALUATE(CR) { 3390 DCHECK_OPCODE(CR); 3391 DECODE_RR_INSTRUCTION(r1, r2); 3392 int32_t r1_val = get_low_register<int32_t>(r1); 3393 int32_t r2_val = get_low_register<int32_t>(r2); 3394 SetS390ConditionCode<int32_t>(r1_val, r2_val); 3395 return length; 3396 } 3397 3398 EVALUATE(SR) { 3399 DCHECK_OPCODE(SR); 3400 DECODE_RR_INSTRUCTION(r1, r2); 3401 int32_t r1_val = get_low_register<int32_t>(r1); 3402 int32_t r2_val = get_low_register<int32_t>(r2); 3403 bool isOF = false; 3404 isOF = CheckOverflowForIntSub(r1_val, r2_val, int32_t); 3405 r1_val -= r2_val; 3406 SetS390ConditionCode<int32_t>(r1_val, 0); 3407 SetS390OverflowCode(isOF); 3408 set_low_register(r1, r1_val); 3409 return length; 3410 } 3411 3412 EVALUATE(MR) { 3413 DCHECK_OPCODE(MR); 3414 DECODE_RR_INSTRUCTION(r1, r2); 3415 int32_t r1_val = get_low_register<int32_t>(r1); 3416 int32_t r2_val = get_low_register<int32_t>(r2); 3417 DCHECK_EQ(r1 % 2, 0); 3418 r1_val = get_low_register<int32_t>(r1 + 1); 3419 int64_t product = static_cast<int64_t>(r1_val) * static_cast<int64_t>(r2_val); 3420 int32_t high_bits = product >> 32; 3421 r1_val = high_bits; 3422 int32_t low_bits = product & 0x00000000FFFFFFFF; 3423 set_low_register(r1, high_bits); 3424 set_low_register(r1 + 1, low_bits); 3425 return length; 3426 } 3427 3428 EVALUATE(DR) { 3429 DCHECK_OPCODE(DR); 3430 DECODE_RR_INSTRUCTION(r1, r2); 3431 int32_t r1_val = get_low_register<int32_t>(r1); 3432 int32_t r2_val = get_low_register<int32_t>(r2); 3433 // reg-reg pair should be even-odd pair, assert r1 is an even register 3434 DCHECK_EQ(r1 % 2, 0); 3435 // leftmost 32 bits of the dividend are in r1 3436 // rightmost 32 bits of the dividend are in r1+1 3437 // get the signed value from r1 3438 int64_t dividend = static_cast<int64_t>(r1_val) << 32; 3439 // get unsigned value from r1+1 3440 // avoid addition with sign-extended r1+1 value 3441 dividend += get_low_register<uint32_t>(r1 + 1); 3442 int32_t remainder = dividend % r2_val; 3443 int32_t quotient = dividend / r2_val; 3444 r1_val = remainder; 3445 set_low_register(r1, remainder); 3446 set_low_register(r1 + 1, quotient); 3447 set_low_register(r1, r1_val); 3448 return length; 3449 } 3450 3451 EVALUATE(ALR) { 3452 DCHECK_OPCODE(ALR); 3453 DECODE_RR_INSTRUCTION(r1, r2); 3454 uint32_t r1_val = get_low_register<uint32_t>(r1); 3455 uint32_t r2_val = get_low_register<uint32_t>(r2); 3456 uint32_t alu_out = 0; 3457 bool isOF = false; 3458 alu_out = r1_val + r2_val; 3459 isOF = CheckOverflowForUIntAdd(r1_val, r2_val); 3460 set_low_register(r1, alu_out); 3461 SetS390ConditionCodeCarry<uint32_t>(alu_out, isOF); 3462 return length; 3463 } 3464 3465 EVALUATE(SLR) { 3466 DCHECK_OPCODE(SLR); 3467 DECODE_RR_INSTRUCTION(r1, r2); 3468 uint32_t r1_val = get_low_register<uint32_t>(r1); 3469 uint32_t r2_val = get_low_register<uint32_t>(r2); 3470 uint32_t alu_out = 0; 3471 bool isOF = false; 3472 alu_out = r1_val - r2_val; 3473 isOF = CheckOverflowForUIntSub(r1_val, r2_val); 3474 set_low_register(r1, alu_out); 3475 SetS390ConditionCodeCarry<uint32_t>(alu_out, isOF); 3476 return length; 3477 } 3478 3479 EVALUATE(LDR) { 3480 DCHECK_OPCODE(LDR); 3481 DECODE_RR_INSTRUCTION(r1, r2); 3482 int64_t r2_val = get_d_register(r2); 3483 set_d_register(r1, r2_val); 3484 return length; 3485 } 3486 3487 EVALUATE(CDR) { 3488 UNIMPLEMENTED(); 3489 USE(instr); 3490 return 0; 3491 } 3492 3493 EVALUATE(LER) { 3494 UNIMPLEMENTED(); 3495 USE(instr); 3496 return 0; 3497 } 3498 3499 EVALUATE(STH) { 3500 DCHECK_OPCODE(STH); 3501 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); 3502 int16_t r1_val = get_low_register<int32_t>(r1); 3503 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 3504 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 3505 intptr_t mem_addr = b2_val + x2_val + d2_val; 3506 WriteH(mem_addr, r1_val, instr); 3507 3508 return length; 3509 } 3510 3511 EVALUATE(LA) { 3512 DCHECK_OPCODE(LA); 3513 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); 3514 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 3515 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 3516 intptr_t addr = b2_val + x2_val + d2_val; 3517 set_register(r1, addr); 3518 return length; 3519 } 3520 3521 EVALUATE(STC) { 3522 DCHECK_OPCODE(STC); 3523 // Store Character/Byte 3524 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); 3525 uint8_t r1_val = get_low_register<int32_t>(r1); 3526 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 3527 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 3528 intptr_t mem_addr = b2_val + x2_val + d2_val; 3529 WriteB(mem_addr, r1_val); 3530 return length; 3531 } 3532 3533 EVALUATE(IC_z) { 3534 UNIMPLEMENTED(); 3535 USE(instr); 3536 return 0; 3537 } 3538 3539 EVALUATE(EX) { 3540 DCHECK_OPCODE(EX); 3541 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); 3542 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 3543 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 3544 int32_t r1_val = get_low_register<int32_t>(r1); 3545 3546 SixByteInstr the_instr = Instruction::InstructionBits( 3547 reinterpret_cast<const byte*>(b2_val + x2_val + d2_val)); 3548 int inst_length = Instruction::InstructionLength( 3549 reinterpret_cast<const byte*>(b2_val + x2_val + d2_val)); 3550 3551 char new_instr_buf[8]; 3552 char* addr = reinterpret_cast<char*>(&new_instr_buf[0]); 3553 the_instr |= static_cast<SixByteInstr>(r1_val & 0xFF) 3554 << (8 * inst_length - 16); 3555 Instruction::SetInstructionBits<SixByteInstr>( 3556 reinterpret_cast<byte*>(addr), static_cast<SixByteInstr>(the_instr)); 3557 ExecuteInstruction(reinterpret_cast<Instruction*>(addr), false); 3558 return length; 3559 } 3560 3561 EVALUATE(BAL) { 3562 UNIMPLEMENTED(); 3563 USE(instr); 3564 return 0; 3565 } 3566 3567 EVALUATE(BCT) { 3568 UNIMPLEMENTED(); 3569 USE(instr); 3570 return 0; 3571 } 3572 3573 EVALUATE(BC) { 3574 UNIMPLEMENTED(); 3575 USE(instr); 3576 return 0; 3577 } 3578 3579 EVALUATE(LH) { 3580 DCHECK_OPCODE(LH); 3581 // Load Halfword 3582 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); 3583 3584 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 3585 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 3586 intptr_t mem_addr = x2_val + b2_val + d2_val; 3587 3588 int32_t result = static_cast<int32_t>(ReadH(mem_addr, instr)); 3589 set_low_register(r1, result); 3590 return length; 3591 } 3592 3593 EVALUATE(CH) { 3594 UNIMPLEMENTED(); 3595 USE(instr); 3596 return 0; 3597 } 3598 3599 EVALUATE(AH) { 3600 DCHECK_OPCODE(AH); 3601 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); 3602 int32_t r1_val = get_low_register<int32_t>(r1); 3603 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 3604 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 3605 intptr_t addr = b2_val + x2_val + d2_val; 3606 int32_t mem_val = static_cast<int32_t>(ReadH(addr, instr)); 3607 int32_t alu_out = 0; 3608 bool isOF = false; 3609 isOF = CheckOverflowForIntAdd(r1_val, mem_val, int32_t); 3610 alu_out = r1_val + mem_val; 3611 set_low_register(r1, alu_out); 3612 SetS390ConditionCode<int32_t>(alu_out, 0); 3613 SetS390OverflowCode(isOF); 3614 3615 return length; 3616 } 3617 3618 EVALUATE(SH) { 3619 DCHECK_OPCODE(SH); 3620 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); 3621 int32_t r1_val = get_low_register<int32_t>(r1); 3622 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 3623 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 3624 intptr_t addr = b2_val + x2_val + d2_val; 3625 int32_t mem_val = static_cast<int32_t>(ReadH(addr, instr)); 3626 int32_t alu_out = 0; 3627 bool isOF = false; 3628 isOF = CheckOverflowForIntSub(r1_val, mem_val, int32_t); 3629 alu_out = r1_val - mem_val; 3630 SetS390ConditionCode<int32_t>(alu_out, 0); 3631 SetS390OverflowCode(isOF); 3632 3633 return length; 3634 } 3635 3636 EVALUATE(MH) { 3637 DCHECK_OPCODE(MH); 3638 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); 3639 int32_t r1_val = get_low_register<int32_t>(r1); 3640 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 3641 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 3642 intptr_t addr = b2_val + x2_val + d2_val; 3643 int32_t mem_val = static_cast<int32_t>(ReadH(addr, instr)); 3644 int32_t alu_out = 0; 3645 alu_out = r1_val * mem_val; 3646 set_low_register(r1, alu_out); 3647 return length; 3648 } 3649 3650 EVALUATE(BAS) { 3651 UNIMPLEMENTED(); 3652 USE(instr); 3653 return 0; 3654 } 3655 3656 EVALUATE(CVD) { 3657 UNIMPLEMENTED(); 3658 USE(instr); 3659 return 0; 3660 } 3661 3662 EVALUATE(CVB) { 3663 UNIMPLEMENTED(); 3664 USE(instr); 3665 return 0; 3666 } 3667 3668 EVALUATE(LAE) { 3669 UNIMPLEMENTED(); 3670 USE(instr); 3671 return 0; 3672 } 3673 3674 EVALUATE(N) { 3675 DCHECK_OPCODE(N); 3676 // 32-bit Reg-Mem instructions 3677 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); 3678 int32_t r1_val = get_low_register<int32_t>(r1); 3679 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 3680 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 3681 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr); 3682 int32_t alu_out = 0; 3683 alu_out = r1_val & mem_val; 3684 SetS390BitWiseConditionCode<uint32_t>(alu_out); 3685 set_low_register(r1, alu_out); 3686 return length; 3687 } 3688 3689 EVALUATE(CL) { 3690 DCHECK_OPCODE(CL); 3691 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); 3692 int32_t r1_val = get_low_register<int32_t>(r1); 3693 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 3694 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 3695 intptr_t addr = b2_val + x2_val + d2_val; 3696 int32_t mem_val = ReadW(addr, instr); 3697 SetS390ConditionCode<uint32_t>(r1_val, mem_val); 3698 return length; 3699 } 3700 3701 EVALUATE(O) { 3702 DCHECK_OPCODE(O); 3703 // 32-bit Reg-Mem instructions 3704 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); 3705 int32_t r1_val = get_low_register<int32_t>(r1); 3706 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 3707 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 3708 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr); 3709 int32_t alu_out = 0; 3710 alu_out = r1_val | mem_val; 3711 SetS390BitWiseConditionCode<uint32_t>(alu_out); 3712 set_low_register(r1, alu_out); 3713 return length; 3714 } 3715 3716 EVALUATE(X) { 3717 DCHECK_OPCODE(X); 3718 // 32-bit Reg-Mem instructions 3719 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); 3720 int32_t r1_val = get_low_register<int32_t>(r1); 3721 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 3722 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 3723 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr); 3724 int32_t alu_out = 0; 3725 alu_out = r1_val ^ mem_val; 3726 SetS390BitWiseConditionCode<uint32_t>(alu_out); 3727 set_low_register(r1, alu_out); 3728 return length; 3729 } 3730 3731 EVALUATE(C) { 3732 DCHECK_OPCODE(C); 3733 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); 3734 int32_t r1_val = get_low_register<int32_t>(r1); 3735 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 3736 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 3737 intptr_t addr = b2_val + x2_val + d2_val; 3738 int32_t mem_val = ReadW(addr, instr); 3739 SetS390ConditionCode<int32_t>(r1_val, mem_val); 3740 return length; 3741 } 3742 3743 EVALUATE(A) { 3744 DCHECK_OPCODE(A); 3745 // 32-bit Reg-Mem instructions 3746 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); 3747 int32_t r1_val = get_low_register<int32_t>(r1); 3748 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 3749 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 3750 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr); 3751 int32_t alu_out = 0; 3752 bool isOF = false; 3753 isOF = CheckOverflowForIntAdd(r1_val, mem_val, int32_t); 3754 alu_out = r1_val + mem_val; 3755 SetS390ConditionCode<int32_t>(alu_out, 0); 3756 SetS390OverflowCode(isOF); 3757 set_low_register(r1, alu_out); 3758 return length; 3759 } 3760 3761 EVALUATE(S) { 3762 DCHECK_OPCODE(S); 3763 // 32-bit Reg-Mem instructions 3764 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); 3765 int32_t r1_val = get_low_register<int32_t>(r1); 3766 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 3767 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 3768 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr); 3769 int32_t alu_out = 0; 3770 bool isOF = false; 3771 isOF = CheckOverflowForIntSub(r1_val, mem_val, int32_t); 3772 alu_out = r1_val - mem_val; 3773 SetS390ConditionCode<int32_t>(alu_out, 0); 3774 SetS390OverflowCode(isOF); 3775 set_low_register(r1, alu_out); 3776 return length; 3777 } 3778 3779 EVALUATE(M) { 3780 DCHECK_OPCODE(M); 3781 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); 3782 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 3783 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 3784 intptr_t addr = b2_val + x2_val + d2_val; 3785 DCHECK_EQ(r1 % 2, 0); 3786 int32_t mem_val = ReadW(addr, instr); 3787 int32_t r1_val = get_low_register<int32_t>(r1 + 1); 3788 int64_t product = 3789 static_cast<int64_t>(r1_val) * static_cast<int64_t>(mem_val); 3790 int32_t high_bits = product >> 32; 3791 r1_val = high_bits; 3792 int32_t low_bits = product & 0x00000000FFFFFFFF; 3793 set_low_register(r1, high_bits); 3794 set_low_register(r1 + 1, low_bits); 3795 return length; 3796 } 3797 3798 EVALUATE(D) { 3799 UNIMPLEMENTED(); 3800 USE(instr); 3801 return 0; 3802 } 3803 3804 EVALUATE(AL) { 3805 UNIMPLEMENTED(); 3806 USE(instr); 3807 return 0; 3808 } 3809 3810 EVALUATE(SL) { 3811 UNIMPLEMENTED(); 3812 USE(instr); 3813 return 0; 3814 } 3815 3816 EVALUATE(STD) { 3817 DCHECK_OPCODE(STD); 3818 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); 3819 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 3820 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 3821 intptr_t addr = b2_val + x2_val + d2_val; 3822 int64_t frs_val = get_d_register(r1); 3823 WriteDW(addr, frs_val); 3824 return length; 3825 } 3826 3827 EVALUATE(LD) { 3828 DCHECK_OPCODE(LD); 3829 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); 3830 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 3831 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 3832 intptr_t addr = b2_val + x2_val + d2_val; 3833 int64_t dbl_val = *reinterpret_cast<int64_t*>(addr); 3834 set_d_register(r1, dbl_val); 3835 return length; 3836 } 3837 3838 EVALUATE(CD) { 3839 UNIMPLEMENTED(); 3840 USE(instr); 3841 return 0; 3842 } 3843 3844 EVALUATE(STE) { 3845 DCHECK_OPCODE(STE); 3846 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); 3847 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 3848 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 3849 intptr_t addr = b2_val + x2_val + d2_val; 3850 int64_t frs_val = get_d_register(r1) >> 32; 3851 WriteW(addr, static_cast<int32_t>(frs_val), instr); 3852 return length; 3853 } 3854 3855 EVALUATE(MS) { 3856 DCHECK_OPCODE(MS); 3857 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); 3858 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 3859 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 3860 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr); 3861 int32_t r1_val = get_low_register<int32_t>(r1); 3862 set_low_register(r1, r1_val * mem_val); 3863 return length; 3864 } 3865 3866 EVALUATE(LE) { 3867 DCHECK_OPCODE(LE); 3868 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); 3869 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 3870 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 3871 intptr_t addr = b2_val + x2_val + d2_val; 3872 float float_val = *reinterpret_cast<float*>(addr); 3873 set_d_register_from_float32(r1, float_val); 3874 return length; 3875 } 3876 3877 EVALUATE(BRXH) { 3878 DCHECK_OPCODE(BRXH); 3879 DECODE_RSI_INSTRUCTION(r1, r3, i2); 3880 int32_t r1_val = (r1 == 0) ? 0 : get_low_register<int32_t>(r1); 3881 int32_t r3_val = (r3 == 0) ? 0 : get_low_register<int32_t>(r3); 3882 intptr_t branch_address = get_pc() + (2 * i2); 3883 r1_val += r3_val; 3884 int32_t compare_val = r3 % 2 == 0 ? 3885 get_low_register<int32_t>(r3 + 1) : r3_val; 3886 if (r1_val > compare_val) { 3887 set_pc(branch_address); 3888 } 3889 set_low_register(r1, r1_val); 3890 return length; 3891 } 3892 3893 EVALUATE(BRXLE) { 3894 UNIMPLEMENTED(); 3895 USE(instr); 3896 return 0; 3897 } 3898 3899 EVALUATE(BXH) { 3900 DCHECK_OPCODE(BXH); 3901 DECODE_RS_A_INSTRUCTION(r1, r3, b2, d2); 3902 3903 // r1_val is the first operand, r3_val is the increment 3904 int32_t r1_val = (r1 == 0) ? 0 : get_register(r1); 3905 int32_t r3_val = (r3 == 0) ? 0 : get_register(r3); 3906 intptr_t b2_val = (b2 == 0) ? 0 : get_register(b2); 3907 intptr_t branch_address = b2_val + d2; 3908 // increment r1_val 3909 r1_val += r3_val; 3910 3911 // if the increment is even, then it designates a pair of registers 3912 // and the contents of the even and odd registers of the pair are used as 3913 // the increment and compare value respectively. If the increment is odd, 3914 // the increment itself is used as both the increment and compare value 3915 int32_t compare_val = r3 % 2 == 0 ? get_register(r3 + 1) : r3_val; 3916 if (r1_val > compare_val) { 3917 // branch to address if r1_val is greater than compare value 3918 set_pc(branch_address); 3919 } 3920 3921 // update contents of register in r1 with the new incremented value 3922 set_register(r1, r1_val); 3923 3924 return length; 3925 } 3926 3927 EVALUATE(BXLE) { 3928 UNIMPLEMENTED(); 3929 USE(instr); 3930 return 0; 3931 } 3932 3933 EVALUATE(SRL) { 3934 DCHECK_OPCODE(SRL); 3935 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2); 3936 // only takes rightmost 6bits 3937 int64_t b2_val = b2 == 0 ? 0 : get_register(b2); 3938 int shiftBits = (b2_val + d2) & 0x3F; 3939 uint32_t r1_val = get_low_register<uint32_t>(r1); 3940 uint32_t alu_out = 0; 3941 alu_out = r1_val >> shiftBits; 3942 set_low_register(r1, alu_out); 3943 return length; 3944 } 3945 3946 EVALUATE(SLL) { 3947 DCHECK_OPCODE(SLL); 3948 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2) 3949 // only takes rightmost 6bits 3950 int64_t b2_val = b2 == 0 ? 0 : get_register(b2); 3951 int shiftBits = (b2_val + d2) & 0x3F; 3952 uint32_t r1_val = get_low_register<uint32_t>(r1); 3953 uint32_t alu_out = 0; 3954 alu_out = r1_val << shiftBits; 3955 set_low_register(r1, alu_out); 3956 return length; 3957 } 3958 3959 EVALUATE(SRA) { 3960 DCHECK_OPCODE(SRA); 3961 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2); 3962 // only takes rightmost 6bits 3963 int64_t b2_val = b2 == 0 ? 0 : get_register(b2); 3964 int shiftBits = (b2_val + d2) & 0x3F; 3965 int32_t r1_val = get_low_register<int32_t>(r1); 3966 int32_t alu_out = 0; 3967 bool isOF = false; 3968 alu_out = r1_val >> shiftBits; 3969 set_low_register(r1, alu_out); 3970 SetS390ConditionCode<int32_t>(alu_out, 0); 3971 SetS390OverflowCode(isOF); 3972 return length; 3973 } 3974 3975 EVALUATE(SLA) { 3976 DCHECK_OPCODE(SLA); 3977 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2); 3978 // only takes rightmost 6bits 3979 int64_t b2_val = b2 == 0 ? 0 : get_register(b2); 3980 int shiftBits = (b2_val + d2) & 0x3F; 3981 int32_t r1_val = get_low_register<int32_t>(r1); 3982 int32_t alu_out = 0; 3983 bool isOF = false; 3984 isOF = CheckOverflowForShiftLeft(r1_val, shiftBits); 3985 alu_out = r1_val << shiftBits; 3986 set_low_register(r1, alu_out); 3987 SetS390ConditionCode<int32_t>(alu_out, 0); 3988 SetS390OverflowCode(isOF); 3989 return length; 3990 } 3991 3992 EVALUATE(SRDL) { 3993 DCHECK_OPCODE(SRDL); 3994 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2); 3995 DCHECK_EQ(r1 % 2, 0); // must be a reg pair 3996 // only takes rightmost 6bits 3997 int64_t b2_val = b2 == 0 ? 0 : get_register(b2); 3998 int shiftBits = (b2_val + d2) & 0x3F; 3999 uint64_t opnd1 = static_cast<uint64_t>(get_low_register<uint32_t>(r1)) << 32; 4000 uint64_t opnd2 = static_cast<uint64_t>(get_low_register<uint32_t>(r1 + 1)); 4001 uint64_t r1_val = opnd1 | opnd2; 4002 uint64_t alu_out = r1_val >> shiftBits; 4003 set_low_register(r1, alu_out >> 32); 4004 set_low_register(r1 + 1, alu_out & 0x00000000FFFFFFFF); 4005 SetS390ConditionCode<int32_t>(alu_out, 0); 4006 return length; 4007 } 4008 4009 EVALUATE(SLDL) { 4010 DCHECK_OPCODE(SLDL); 4011 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2); 4012 // only takes rightmost 6bits 4013 int64_t b2_val = b2 == 0 ? 0 : get_register(b2); 4014 int shiftBits = (b2_val + d2) & 0x3F; 4015 4016 DCHECK_EQ(r1 % 2, 0); 4017 uint32_t r1_val = get_low_register<uint32_t>(r1); 4018 uint32_t r1_next_val = get_low_register<uint32_t>(r1 + 1); 4019 uint64_t alu_out = (static_cast<uint64_t>(r1_val) << 32) | 4020 (static_cast<uint64_t>(r1_next_val)); 4021 alu_out <<= shiftBits; 4022 set_low_register(r1 + 1, static_cast<uint32_t>(alu_out)); 4023 set_low_register(r1, static_cast<uint32_t>(alu_out >> 32)); 4024 return length; 4025 } 4026 4027 EVALUATE(SRDA) { 4028 DCHECK_OPCODE(SRDA); 4029 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2); 4030 DCHECK_EQ(r1 % 2, 0); // must be a reg pair 4031 // only takes rightmost 6bits 4032 int64_t b2_val = b2 == 0 ? 0 : get_register(b2); 4033 int shiftBits = (b2_val + d2) & 0x3F; 4034 int64_t opnd1 = static_cast<int64_t>(get_low_register<int32_t>(r1)) << 32; 4035 int64_t opnd2 = static_cast<uint64_t>(get_low_register<uint32_t>(r1 + 1)); 4036 int64_t r1_val = opnd1 + opnd2; 4037 int64_t alu_out = r1_val >> shiftBits; 4038 set_low_register(r1, alu_out >> 32); 4039 set_low_register(r1 + 1, alu_out & 0x00000000FFFFFFFF); 4040 SetS390ConditionCode<int32_t>(alu_out, 0); 4041 return length; 4042 } 4043 4044 EVALUATE(SLDA) { 4045 UNIMPLEMENTED(); 4046 USE(instr); 4047 return 0; 4048 } 4049 4050 EVALUATE(STM) { 4051 DCHECK_OPCODE(STM); 4052 DECODE_RS_A_INSTRUCTION(r1, r3, rb, d2); 4053 // Store Multiple 32-bits. 4054 int offset = d2; 4055 // Regs roll around if r3 is less than r1. 4056 // Artificially increase r3 by 16 so we can calculate 4057 // the number of regs stored properly. 4058 if (r3 < r1) r3 += 16; 4059 4060 int32_t rb_val = (rb == 0) ? 0 : get_low_register<int32_t>(rb); 4061 4062 // Store each register in ascending order. 4063 for (int i = 0; i <= r3 - r1; i++) { 4064 int32_t value = get_low_register<int32_t>((r1 + i) % 16); 4065 WriteW(rb_val + offset + 4 * i, value, instr); 4066 } 4067 return length; 4068 } 4069 4070 EVALUATE(TM) { 4071 DCHECK_OPCODE(TM); 4072 // Test Under Mask (Mem - Imm) (8) 4073 DECODE_SI_INSTRUCTION_I_UINT8(b1, d1_val, imm_val) 4074 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1); 4075 intptr_t addr = b1_val + d1_val; 4076 uint8_t mem_val = ReadB(addr); 4077 uint8_t selected_bits = mem_val & imm_val; 4078 // CC0: Selected bits are zero 4079 // CC1: Selected bits mixed zeros and ones 4080 // CC3: Selected bits all ones 4081 if (0 == selected_bits) { 4082 condition_reg_ = CC_EQ; // CC0 4083 } else if (selected_bits == imm_val) { 4084 condition_reg_ = 0x1; // CC3 4085 } else { 4086 condition_reg_ = 0x4; // CC1 4087 } 4088 return length; 4089 } 4090 4091 EVALUATE(MVI) { 4092 UNIMPLEMENTED(); 4093 USE(instr); 4094 return 0; 4095 } 4096 4097 EVALUATE(TS) { 4098 UNIMPLEMENTED(); 4099 USE(instr); 4100 return 0; 4101 } 4102 4103 EVALUATE(NI) { 4104 UNIMPLEMENTED(); 4105 USE(instr); 4106 return 0; 4107 } 4108 4109 EVALUATE(CLI) { 4110 DCHECK_OPCODE(CLI); 4111 // Compare Immediate (Mem - Imm) (8) 4112 DECODE_SI_INSTRUCTION_I_UINT8(b1, d1_val, imm_val) 4113 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1); 4114 intptr_t addr = b1_val + d1_val; 4115 uint8_t mem_val = ReadB(addr); 4116 SetS390ConditionCode<uint8_t>(mem_val, imm_val); 4117 return length; 4118 } 4119 4120 EVALUATE(OI) { 4121 UNIMPLEMENTED(); 4122 USE(instr); 4123 return 0; 4124 } 4125 4126 EVALUATE(XI) { 4127 UNIMPLEMENTED(); 4128 USE(instr); 4129 return 0; 4130 } 4131 4132 EVALUATE(LM) { 4133 DCHECK_OPCODE(LM); 4134 DECODE_RS_A_INSTRUCTION(r1, r3, rb, d2); 4135 // Store Multiple 32-bits. 4136 int offset = d2; 4137 // Regs roll around if r3 is less than r1. 4138 // Artificially increase r3 by 16 so we can calculate 4139 // the number of regs stored properly. 4140 if (r3 < r1) r3 += 16; 4141 4142 int32_t rb_val = (rb == 0) ? 0 : get_low_register<int32_t>(rb); 4143 4144 // Store each register in ascending order. 4145 for (int i = 0; i <= r3 - r1; i++) { 4146 int32_t value = ReadW(rb_val + offset + 4 * i, instr); 4147 set_low_register((r1 + i) % 16, value); 4148 } 4149 return length; 4150 } 4151 4152 EVALUATE(MVCLE) { 4153 UNIMPLEMENTED(); 4154 USE(instr); 4155 return 0; 4156 } 4157 4158 EVALUATE(CLCLE) { 4159 UNIMPLEMENTED(); 4160 USE(instr); 4161 return 0; 4162 } 4163 4164 EVALUATE(MC) { 4165 UNIMPLEMENTED(); 4166 USE(instr); 4167 return 0; 4168 } 4169 4170 EVALUATE(CDS) { 4171 UNIMPLEMENTED(); 4172 USE(instr); 4173 return 0; 4174 } 4175 4176 EVALUATE(STCM) { 4177 UNIMPLEMENTED(); 4178 USE(instr); 4179 return 0; 4180 } 4181 4182 EVALUATE(ICM) { 4183 UNIMPLEMENTED(); 4184 USE(instr); 4185 return 0; 4186 } 4187 4188 EVALUATE(BPRP) { 4189 UNIMPLEMENTED(); 4190 USE(instr); 4191 return 0; 4192 } 4193 4194 EVALUATE(BPP) { 4195 UNIMPLEMENTED(); 4196 USE(instr); 4197 return 0; 4198 } 4199 4200 EVALUATE(TRTR) { 4201 UNIMPLEMENTED(); 4202 USE(instr); 4203 return 0; 4204 } 4205 4206 EVALUATE(MVN) { 4207 UNIMPLEMENTED(); 4208 USE(instr); 4209 return 0; 4210 } 4211 4212 EVALUATE(MVC) { 4213 DCHECK_OPCODE(MVC); 4214 // Move Character 4215 SSInstruction* ssInstr = reinterpret_cast<SSInstruction*>(instr); 4216 int b1 = ssInstr->B1Value(); 4217 intptr_t d1 = ssInstr->D1Value(); 4218 int b2 = ssInstr->B2Value(); 4219 intptr_t d2 = ssInstr->D2Value(); 4220 int length = ssInstr->Length(); 4221 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1); 4222 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 4223 intptr_t src_addr = b2_val + d2; 4224 intptr_t dst_addr = b1_val + d1; 4225 // remember that the length is the actual length - 1 4226 for (int i = 0; i < length + 1; ++i) { 4227 WriteB(dst_addr++, ReadB(src_addr++)); 4228 } 4229 length = 6; 4230 return length; 4231 } 4232 4233 EVALUATE(MVZ) { 4234 UNIMPLEMENTED(); 4235 USE(instr); 4236 return 0; 4237 } 4238 4239 EVALUATE(NC) { 4240 UNIMPLEMENTED(); 4241 USE(instr); 4242 return 0; 4243 } 4244 4245 EVALUATE(CLC) { 4246 UNIMPLEMENTED(); 4247 USE(instr); 4248 return 0; 4249 } 4250 4251 EVALUATE(OC) { 4252 UNIMPLEMENTED(); 4253 USE(instr); 4254 return 0; 4255 } 4256 4257 EVALUATE(XC) { 4258 UNIMPLEMENTED(); 4259 USE(instr); 4260 return 0; 4261 } 4262 4263 EVALUATE(MVCP) { 4264 UNIMPLEMENTED(); 4265 USE(instr); 4266 return 0; 4267 } 4268 4269 EVALUATE(TR) { 4270 UNIMPLEMENTED(); 4271 USE(instr); 4272 return 0; 4273 } 4274 4275 EVALUATE(TRT) { 4276 UNIMPLEMENTED(); 4277 USE(instr); 4278 return 0; 4279 } 4280 4281 EVALUATE(ED) { 4282 UNIMPLEMENTED(); 4283 USE(instr); 4284 return 0; 4285 } 4286 4287 EVALUATE(EDMK) { 4288 UNIMPLEMENTED(); 4289 USE(instr); 4290 return 0; 4291 } 4292 4293 EVALUATE(PKU) { 4294 UNIMPLEMENTED(); 4295 USE(instr); 4296 return 0; 4297 } 4298 4299 EVALUATE(UNPKU) { 4300 UNIMPLEMENTED(); 4301 USE(instr); 4302 return 0; 4303 } 4304 4305 EVALUATE(MVCIN) { 4306 UNIMPLEMENTED(); 4307 USE(instr); 4308 return 0; 4309 } 4310 4311 EVALUATE(PKA) { 4312 UNIMPLEMENTED(); 4313 USE(instr); 4314 return 0; 4315 } 4316 4317 EVALUATE(UNPKA) { 4318 UNIMPLEMENTED(); 4319 USE(instr); 4320 return 0; 4321 } 4322 4323 EVALUATE(PLO) { 4324 UNIMPLEMENTED(); 4325 USE(instr); 4326 return 0; 4327 } 4328 4329 EVALUATE(LMD) { 4330 UNIMPLEMENTED(); 4331 USE(instr); 4332 return 0; 4333 } 4334 4335 EVALUATE(SRP) { 4336 UNIMPLEMENTED(); 4337 USE(instr); 4338 return 0; 4339 } 4340 4341 EVALUATE(MVO) { 4342 UNIMPLEMENTED(); 4343 USE(instr); 4344 return 0; 4345 } 4346 4347 EVALUATE(PACK) { 4348 UNIMPLEMENTED(); 4349 USE(instr); 4350 return 0; 4351 } 4352 4353 EVALUATE(UNPK) { 4354 UNIMPLEMENTED(); 4355 USE(instr); 4356 return 0; 4357 } 4358 4359 EVALUATE(ZAP) { 4360 UNIMPLEMENTED(); 4361 USE(instr); 4362 return 0; 4363 } 4364 4365 EVALUATE(AP) { 4366 UNIMPLEMENTED(); 4367 USE(instr); 4368 return 0; 4369 } 4370 4371 EVALUATE(SP) { 4372 UNIMPLEMENTED(); 4373 USE(instr); 4374 return 0; 4375 } 4376 4377 EVALUATE(MP) { 4378 UNIMPLEMENTED(); 4379 USE(instr); 4380 return 0; 4381 } 4382 4383 EVALUATE(DP) { 4384 UNIMPLEMENTED(); 4385 USE(instr); 4386 return 0; 4387 } 4388 4389 EVALUATE(UPT) { 4390 UNIMPLEMENTED(); 4391 USE(instr); 4392 return 0; 4393 } 4394 4395 EVALUATE(PFPO) { 4396 UNIMPLEMENTED(); 4397 USE(instr); 4398 return 0; 4399 } 4400 4401 EVALUATE(IIHH) { 4402 UNIMPLEMENTED(); 4403 USE(instr); 4404 return 0; 4405 } 4406 4407 EVALUATE(IIHL) { 4408 UNIMPLEMENTED(); 4409 USE(instr); 4410 return 0; 4411 } 4412 4413 EVALUATE(IILH) { 4414 UNIMPLEMENTED(); 4415 USE(instr); 4416 return 0; 4417 } 4418 4419 EVALUATE(IILL) { 4420 UNIMPLEMENTED(); 4421 USE(instr); 4422 return 0; 4423 } 4424 4425 EVALUATE(NIHH) { 4426 UNIMPLEMENTED(); 4427 USE(instr); 4428 return 0; 4429 } 4430 4431 EVALUATE(NIHL) { 4432 UNIMPLEMENTED(); 4433 USE(instr); 4434 return 0; 4435 } 4436 4437 EVALUATE(NILH) { 4438 DCHECK_OPCODE(NILH); 4439 DECODE_RI_A_INSTRUCTION(instr, r1, i); 4440 int32_t r1_val = get_low_register<int32_t>(r1); 4441 // CC is set based on the 16 bits that are AND'd 4442 SetS390BitWiseConditionCode<uint16_t>((r1_val >> 16) & i); 4443 i = (i << 16) | 0x0000FFFF; 4444 set_low_register(r1, r1_val & i); 4445 return length; 4446 } 4447 4448 EVALUATE(NILL) { 4449 DCHECK_OPCODE(NILL); 4450 DECODE_RI_A_INSTRUCTION(instr, r1, i); 4451 int32_t r1_val = get_low_register<int32_t>(r1); 4452 // CC is set based on the 16 bits that are AND'd 4453 SetS390BitWiseConditionCode<uint16_t>(r1_val & i); 4454 i |= 0xFFFF0000; 4455 set_low_register(r1, r1_val & i); 4456 return length; 4457 } 4458 4459 EVALUATE(OIHH) { 4460 UNIMPLEMENTED(); 4461 USE(instr); 4462 return 0; 4463 } 4464 4465 EVALUATE(OIHL) { 4466 UNIMPLEMENTED(); 4467 USE(instr); 4468 return 0; 4469 } 4470 4471 EVALUATE(OILH) { 4472 DCHECK_OPCODE(OILH); 4473 DECODE_RI_A_INSTRUCTION(instr, r1, i); 4474 int32_t r1_val = get_low_register<int32_t>(r1); 4475 // CC is set based on the 16 bits that are AND'd 4476 SetS390BitWiseConditionCode<uint16_t>((r1_val >> 16) | i); 4477 i = i << 16; 4478 set_low_register(r1, r1_val | i); 4479 return length; 4480 } 4481 4482 EVALUATE(OILL) { 4483 DCHECK_OPCODE(OILL); 4484 DECODE_RI_A_INSTRUCTION(instr, r1, i); 4485 int32_t r1_val = get_low_register<int32_t>(r1); 4486 // CC is set based on the 16 bits that are AND'd 4487 SetS390BitWiseConditionCode<uint16_t>(r1_val | i); 4488 set_low_register(r1, r1_val | i); 4489 return length; 4490 } 4491 4492 EVALUATE(LLIHH) { 4493 UNIMPLEMENTED(); 4494 USE(instr); 4495 return 0; 4496 } 4497 4498 EVALUATE(LLIHL) { 4499 UNIMPLEMENTED(); 4500 USE(instr); 4501 return 0; 4502 } 4503 4504 EVALUATE(LLILH) { 4505 UNIMPLEMENTED(); 4506 USE(instr); 4507 return 0; 4508 } 4509 4510 EVALUATE(LLILL) { 4511 UNIMPLEMENTED(); 4512 USE(instr); 4513 return 0; 4514 } 4515 4516 EVALUATE(TMLH) { 4517 UNIMPLEMENTED(); 4518 USE(instr); 4519 return 0; 4520 } 4521 4522 EVALUATE(TMLL) { 4523 DCHECK_OPCODE(TMLL); 4524 DECODE_RI_A_INSTRUCTION(instr, r1, i2); 4525 uint32_t mask = i2 & 0x0000FFFF; 4526 uint32_t r1_val = get_low_register<uint32_t>(r1); 4527 r1_val = r1_val & 0x0000FFFF; // uses only the last 16bits 4528 4529 // Test if all selected bits are zeros or mask is zero 4530 if (0 == (mask & r1_val)) { 4531 condition_reg_ = 0x8; 4532 return length; // Done! 4533 } 4534 4535 DCHECK_NE(mask, 0); 4536 // Test if all selected bits are one 4537 if (mask == (mask & r1_val)) { 4538 condition_reg_ = 0x1; 4539 return length; // Done! 4540 } 4541 4542 // Now we know selected bits mixed zeros and ones 4543 // Test if the leftmost bit is zero or one 4544 #if defined(__GNUC__) 4545 int leadingZeros = __builtin_clz(mask); 4546 mask = 0x80000000u >> leadingZeros; 4547 if (mask & r1_val) { 4548 // leftmost bit is one 4549 condition_reg_ = 0x2; 4550 } else { 4551 // leftmost bit is zero 4552 condition_reg_ = 0x4; 4553 } 4554 return length; // Done! 4555 #else 4556 for (int i = 15; i >= 0; i--) { 4557 if (mask & (1 << i)) { 4558 if (r1_val & (1 << i)) { 4559 // leftmost bit is one 4560 condition_reg_ = 0x2; 4561 } else { 4562 // leftmost bit is zero 4563 condition_reg_ = 0x4; 4564 } 4565 return length; // Done! 4566 } 4567 } 4568 #endif 4569 UNREACHABLE(); 4570 } 4571 4572 EVALUATE(TMHH) { 4573 UNIMPLEMENTED(); 4574 USE(instr); 4575 return 0; 4576 } 4577 4578 EVALUATE(TMHL) { 4579 UNIMPLEMENTED(); 4580 USE(instr); 4581 return 0; 4582 } 4583 4584 EVALUATE(BRAS) { 4585 DCHECK_OPCODE(BRAS); 4586 // Branch Relative and Save 4587 DECODE_RI_B_INSTRUCTION(instr, r1, d2) 4588 intptr_t pc = get_pc(); 4589 // Set PC of next instruction to register 4590 set_register(r1, pc + sizeof(FourByteInstr)); 4591 // Update PC to branch target 4592 set_pc(pc + d2 * 2); 4593 return length; 4594 } 4595 4596 EVALUATE(BRCT) { 4597 DCHECK_OPCODE(BRCT); 4598 // Branch On Count (32/64). 4599 DECODE_RI_A_INSTRUCTION(instr, r1, i2); 4600 int64_t value = get_low_register<int32_t>(r1); 4601 set_low_register(r1, --value); 4602 // Branch if value != 0 4603 if (value != 0) { 4604 intptr_t offset = i2 * 2; 4605 set_pc(get_pc() + offset); 4606 } 4607 return length; 4608 } 4609 4610 EVALUATE(BRCTG) { 4611 DCHECK_OPCODE(BRCTG); 4612 // Branch On Count (32/64). 4613 DECODE_RI_A_INSTRUCTION(instr, r1, i2); 4614 int64_t value = get_register(r1); 4615 set_register(r1, --value); 4616 // Branch if value != 0 4617 if (value != 0) { 4618 intptr_t offset = i2 * 2; 4619 set_pc(get_pc() + offset); 4620 } 4621 return length; 4622 } 4623 4624 EVALUATE(LHI) { 4625 DCHECK_OPCODE(LHI); 4626 DECODE_RI_A_INSTRUCTION(instr, r1, i); 4627 set_low_register(r1, i); 4628 return length; 4629 } 4630 4631 EVALUATE(LGHI) { 4632 DCHECK_OPCODE(LGHI); 4633 DECODE_RI_A_INSTRUCTION(instr, r1, i2); 4634 int64_t i = static_cast<int64_t>(i2); 4635 set_register(r1, i); 4636 return length; 4637 } 4638 4639 EVALUATE(MHI) { 4640 DCHECK_OPCODE(MHI); 4641 DECODE_RI_A_INSTRUCTION(instr, r1, i); 4642 int32_t r1_val = get_low_register<int32_t>(r1); 4643 bool isOF = false; 4644 isOF = CheckOverflowForMul(r1_val, i); 4645 r1_val *= i; 4646 set_low_register(r1, r1_val); 4647 SetS390ConditionCode<int32_t>(r1_val, 0); 4648 SetS390OverflowCode(isOF); 4649 return length; 4650 } 4651 4652 EVALUATE(MGHI) { 4653 DCHECK_OPCODE(MGHI); 4654 DECODE_RI_A_INSTRUCTION(instr, r1, i2); 4655 int64_t i = static_cast<int64_t>(i2); 4656 int64_t r1_val = get_register(r1); 4657 bool isOF = false; 4658 isOF = CheckOverflowForMul(r1_val, i); 4659 r1_val *= i; 4660 set_register(r1, r1_val); 4661 SetS390ConditionCode<int32_t>(r1_val, 0); 4662 SetS390OverflowCode(isOF); 4663 return length; 4664 } 4665 4666 EVALUATE(CHI) { 4667 DCHECK_OPCODE(CHI); 4668 DECODE_RI_A_INSTRUCTION(instr, r1, i); 4669 int32_t r1_val = get_low_register<int32_t>(r1); 4670 SetS390ConditionCode<int32_t>(r1_val, i); 4671 return length; 4672 } 4673 4674 EVALUATE(CGHI) { 4675 DCHECK_OPCODE(CGHI); 4676 DECODE_RI_A_INSTRUCTION(instr, r1, i2); 4677 int64_t i = static_cast<int64_t>(i2); 4678 int64_t r1_val = get_register(r1); 4679 SetS390ConditionCode<int64_t>(r1_val, i); 4680 return length; 4681 } 4682 4683 EVALUATE(LARL) { 4684 DCHECK_OPCODE(LARL); 4685 DECODE_RIL_B_INSTRUCTION(r1, i2); 4686 intptr_t offset = i2 * 2; 4687 set_register(r1, get_pc() + offset); 4688 return length; 4689 } 4690 4691 EVALUATE(LGFI) { 4692 DCHECK_OPCODE(LGFI); 4693 DECODE_RIL_A_INSTRUCTION(r1, imm); 4694 set_register(r1, static_cast<int64_t>(static_cast<int32_t>(imm))); 4695 return length; 4696 } 4697 4698 EVALUATE(BRASL) { 4699 DCHECK_OPCODE(BRASL); 4700 // Branch and Save Relative Long 4701 DECODE_RIL_B_INSTRUCTION(r1, i2); 4702 intptr_t d2 = i2; 4703 intptr_t pc = get_pc(); 4704 set_register(r1, pc + 6); // save next instruction to register 4705 set_pc(pc + d2 * 2); // update register 4706 return length; 4707 } 4708 4709 EVALUATE(XIHF) { 4710 DCHECK_OPCODE(XIHF); 4711 DECODE_RIL_A_INSTRUCTION(r1, imm); 4712 uint32_t alu_out = 0; 4713 alu_out = get_high_register<uint32_t>(r1); 4714 alu_out = alu_out ^ imm; 4715 set_high_register(r1, alu_out); 4716 SetS390BitWiseConditionCode<uint32_t>(alu_out); 4717 return length; 4718 } 4719 4720 EVALUATE(XILF) { 4721 DCHECK_OPCODE(XILF); 4722 DECODE_RIL_A_INSTRUCTION(r1, imm); 4723 uint32_t alu_out = 0; 4724 alu_out = get_low_register<uint32_t>(r1); 4725 alu_out = alu_out ^ imm; 4726 set_low_register(r1, alu_out); 4727 SetS390BitWiseConditionCode<uint32_t>(alu_out); 4728 return length; 4729 } 4730 4731 EVALUATE(NIHF) { 4732 DCHECK_OPCODE(NIHF); 4733 // Bitwise Op on upper 32-bits 4734 DECODE_RIL_A_INSTRUCTION(r1, imm); 4735 uint32_t alu_out = get_high_register<uint32_t>(r1); 4736 alu_out &= imm; 4737 SetS390BitWiseConditionCode<uint32_t>(alu_out); 4738 set_high_register(r1, alu_out); 4739 return length; 4740 } 4741 4742 EVALUATE(NILF) { 4743 DCHECK_OPCODE(NILF); 4744 // Bitwise Op on lower 32-bits 4745 DECODE_RIL_A_INSTRUCTION(r1, imm); 4746 uint32_t alu_out = get_low_register<uint32_t>(r1); 4747 alu_out &= imm; 4748 SetS390BitWiseConditionCode<uint32_t>(alu_out); 4749 set_low_register(r1, alu_out); 4750 return length; 4751 } 4752 4753 EVALUATE(OIHF) { 4754 DCHECK_OPCODE(OIHF); 4755 // Bitwise Op on upper 32-bits 4756 DECODE_RIL_B_INSTRUCTION(r1, imm); 4757 uint32_t alu_out = get_high_register<uint32_t>(r1); 4758 alu_out |= imm; 4759 SetS390BitWiseConditionCode<uint32_t>(alu_out); 4760 set_high_register(r1, alu_out); 4761 return length; 4762 } 4763 4764 EVALUATE(OILF) { 4765 DCHECK_OPCODE(OILF); 4766 // Bitwise Op on lower 32-bits 4767 DECODE_RIL_B_INSTRUCTION(r1, imm); 4768 uint32_t alu_out = get_low_register<uint32_t>(r1); 4769 alu_out |= imm; 4770 SetS390BitWiseConditionCode<uint32_t>(alu_out); 4771 set_low_register(r1, alu_out); 4772 return length; 4773 } 4774 4775 EVALUATE(LLIHF) { 4776 DCHECK_OPCODE(LLIHF); 4777 // Load Logical Immediate into high word 4778 DECODE_RIL_A_INSTRUCTION(r1, i2); 4779 uint64_t imm = static_cast<uint64_t>(i2); 4780 set_register(r1, imm << 32); 4781 return length; 4782 } 4783 4784 EVALUATE(LLILF) { 4785 DCHECK_OPCODE(LLILF); 4786 // Load Logical into lower 32-bits (zero extend upper 32-bits) 4787 DECODE_RIL_A_INSTRUCTION(r1, i2); 4788 uint64_t imm = static_cast<uint64_t>(i2); 4789 set_register(r1, imm); 4790 return length; 4791 } 4792 4793 EVALUATE(MSGFI) { 4794 DCHECK_OPCODE(MSGFI); 4795 DECODE_RIL_B_INSTRUCTION(r1, i2); 4796 int64_t alu_out = get_register(r1); 4797 alu_out = alu_out * i2; 4798 set_register(r1, alu_out); 4799 return length; 4800 } 4801 4802 EVALUATE(MSFI) { 4803 DCHECK_OPCODE(MSFI); 4804 DECODE_RIL_B_INSTRUCTION(r1, i2); 4805 int32_t alu_out = get_low_register<int32_t>(r1); 4806 alu_out = alu_out * i2; 4807 set_low_register(r1, alu_out); 4808 return length; 4809 } 4810 4811 EVALUATE(SLGFI) { 4812 DCHECK_OPCODE(SLGFI); 4813 #ifndef V8_TARGET_ARCH_S390X 4814 // should only be called on 64bit 4815 DCHECK(false); 4816 #endif 4817 DECODE_RIL_A_INSTRUCTION(r1, i2); 4818 uint64_t r1_val = (uint64_t)(get_register(r1)); 4819 uint64_t alu_out; 4820 alu_out = r1_val - i2; 4821 set_register(r1, (intptr_t)alu_out); 4822 SetS390ConditionCode<uint64_t>(alu_out, 0); 4823 return length; 4824 } 4825 4826 EVALUATE(SLFI) { 4827 DCHECK_OPCODE(SLFI); 4828 DECODE_RIL_A_INSTRUCTION(r1, imm); 4829 uint32_t alu_out = get_low_register<uint32_t>(r1); 4830 alu_out -= imm; 4831 SetS390ConditionCode<uint32_t>(alu_out, 0); 4832 set_low_register(r1, alu_out); 4833 return length; 4834 } 4835 4836 EVALUATE(AGFI) { 4837 DCHECK_OPCODE(AGFI); 4838 // Clobbering Add Word Immediate 4839 DECODE_RIL_B_INSTRUCTION(r1, i2_val); 4840 bool isOF = false; 4841 // 64-bit Add (Register + 32-bit Imm) 4842 int64_t r1_val = get_register(r1); 4843 int64_t i2 = static_cast<int64_t>(i2_val); 4844 isOF = CheckOverflowForIntAdd(r1_val, i2, int64_t); 4845 int64_t alu_out = r1_val + i2; 4846 set_register(r1, alu_out); 4847 SetS390ConditionCode<int64_t>(alu_out, 0); 4848 SetS390OverflowCode(isOF); 4849 return length; 4850 } 4851 4852 EVALUATE(AFI) { 4853 DCHECK_OPCODE(AFI); 4854 // Clobbering Add Word Immediate 4855 DECODE_RIL_B_INSTRUCTION(r1, i2); 4856 bool isOF = false; 4857 // 32-bit Add (Register + 32-bit Immediate) 4858 int32_t r1_val = get_low_register<int32_t>(r1); 4859 isOF = CheckOverflowForIntAdd(r1_val, i2, int32_t); 4860 int32_t alu_out = r1_val + i2; 4861 set_low_register(r1, alu_out); 4862 SetS390ConditionCode<int32_t>(alu_out, 0); 4863 SetS390OverflowCode(isOF); 4864 return length; 4865 } 4866 4867 EVALUATE(ALGFI) { 4868 DCHECK_OPCODE(ALGFI); 4869 #ifndef V8_TARGET_ARCH_S390X 4870 // should only be called on 64bit 4871 DCHECK(false); 4872 #endif 4873 DECODE_RIL_A_INSTRUCTION(r1, i2); 4874 uint64_t r1_val = (uint64_t)(get_register(r1)); 4875 uint64_t alu_out; 4876 alu_out = r1_val + i2; 4877 set_register(r1, (intptr_t)alu_out); 4878 SetS390ConditionCode<uint64_t>(alu_out, 0); 4879 4880 return length; 4881 } 4882 4883 EVALUATE(ALFI) { 4884 DCHECK_OPCODE(ALFI); 4885 DECODE_RIL_A_INSTRUCTION(r1, imm); 4886 uint32_t alu_out = get_low_register<uint32_t>(r1); 4887 alu_out += imm; 4888 SetS390ConditionCode<uint32_t>(alu_out, 0); 4889 set_low_register(r1, alu_out); 4890 return length; 4891 } 4892 4893 EVALUATE(CGFI) { 4894 DCHECK_OPCODE(CGFI); 4895 // Compare with Immediate (64) 4896 DECODE_RIL_B_INSTRUCTION(r1, i2); 4897 int64_t imm = static_cast<int64_t>(i2); 4898 SetS390ConditionCode<int64_t>(get_register(r1), imm); 4899 return length; 4900 } 4901 4902 EVALUATE(CFI) { 4903 DCHECK_OPCODE(CFI); 4904 // Compare with Immediate (32) 4905 DECODE_RIL_B_INSTRUCTION(r1, imm); 4906 SetS390ConditionCode<int32_t>(get_low_register<int32_t>(r1), imm); 4907 return length; 4908 } 4909 4910 EVALUATE(CLGFI) { 4911 DCHECK_OPCODE(CLGFI); 4912 // Compare Logical with Immediate (64) 4913 DECODE_RIL_A_INSTRUCTION(r1, i2); 4914 uint64_t imm = static_cast<uint64_t>(i2); 4915 SetS390ConditionCode<uint64_t>(get_register(r1), imm); 4916 return length; 4917 } 4918 4919 EVALUATE(CLFI) { 4920 DCHECK_OPCODE(CLFI); 4921 // Compare Logical with Immediate (32) 4922 DECODE_RIL_A_INSTRUCTION(r1, imm); 4923 SetS390ConditionCode<uint32_t>(get_low_register<uint32_t>(r1), imm); 4924 return length; 4925 } 4926 4927 EVALUATE(LLHRL) { 4928 UNIMPLEMENTED(); 4929 USE(instr); 4930 return 0; 4931 } 4932 4933 EVALUATE(LGHRL) { 4934 UNIMPLEMENTED(); 4935 USE(instr); 4936 return 0; 4937 } 4938 4939 EVALUATE(LHRL) { 4940 UNIMPLEMENTED(); 4941 USE(instr); 4942 return 0; 4943 } 4944 4945 EVALUATE(LLGHRL) { 4946 UNIMPLEMENTED(); 4947 USE(instr); 4948 return 0; 4949 } 4950 4951 EVALUATE(STHRL) { 4952 UNIMPLEMENTED(); 4953 USE(instr); 4954 return 0; 4955 } 4956 4957 EVALUATE(LGRL) { 4958 UNIMPLEMENTED(); 4959 USE(instr); 4960 return 0; 4961 } 4962 4963 EVALUATE(STGRL) { 4964 UNIMPLEMENTED(); 4965 USE(instr); 4966 return 0; 4967 } 4968 4969 EVALUATE(LGFRL) { 4970 UNIMPLEMENTED(); 4971 USE(instr); 4972 return 0; 4973 } 4974 4975 EVALUATE(LRL) { 4976 UNIMPLEMENTED(); 4977 USE(instr); 4978 return 0; 4979 } 4980 4981 EVALUATE(LLGFRL) { 4982 UNIMPLEMENTED(); 4983 USE(instr); 4984 return 0; 4985 } 4986 4987 EVALUATE(STRL) { 4988 UNIMPLEMENTED(); 4989 USE(instr); 4990 return 0; 4991 } 4992 4993 EVALUATE(EXRL) { 4994 UNIMPLEMENTED(); 4995 USE(instr); 4996 return 0; 4997 } 4998 4999 EVALUATE(PFDRL) { 5000 UNIMPLEMENTED(); 5001 USE(instr); 5002 return 0; 5003 } 5004 5005 EVALUATE(CGHRL) { 5006 UNIMPLEMENTED(); 5007 USE(instr); 5008 return 0; 5009 } 5010 5011 EVALUATE(CHRL) { 5012 UNIMPLEMENTED(); 5013 USE(instr); 5014 return 0; 5015 } 5016 5017 EVALUATE(CGRL) { 5018 UNIMPLEMENTED(); 5019 USE(instr); 5020 return 0; 5021 } 5022 5023 EVALUATE(CGFRL) { 5024 UNIMPLEMENTED(); 5025 USE(instr); 5026 return 0; 5027 } 5028 5029 EVALUATE(ECTG) { 5030 UNIMPLEMENTED(); 5031 USE(instr); 5032 return 0; 5033 } 5034 5035 EVALUATE(CSST) { 5036 UNIMPLEMENTED(); 5037 USE(instr); 5038 return 0; 5039 } 5040 5041 EVALUATE(LPD) { 5042 UNIMPLEMENTED(); 5043 USE(instr); 5044 return 0; 5045 } 5046 5047 EVALUATE(LPDG) { 5048 UNIMPLEMENTED(); 5049 USE(instr); 5050 return 0; 5051 } 5052 5053 EVALUATE(BRCTH) { 5054 UNIMPLEMENTED(); 5055 USE(instr); 5056 return 0; 5057 } 5058 5059 EVALUATE(AIH) { 5060 DCHECK_OPCODE(AIH); 5061 DECODE_RIL_A_INSTRUCTION(r1, i2); 5062 int32_t r1_val = get_high_register<int32_t>(r1); 5063 bool isOF = CheckOverflowForIntAdd(r1_val, static_cast<int32_t>(i2), int32_t); 5064 r1_val += static_cast<int32_t>(i2); 5065 set_high_register(r1, r1_val); 5066 SetS390ConditionCode<int32_t>(r1_val, 0); 5067 SetS390OverflowCode(isOF); 5068 return length; 5069 } 5070 5071 EVALUATE(ALSIH) { 5072 UNIMPLEMENTED(); 5073 USE(instr); 5074 return 0; 5075 } 5076 5077 EVALUATE(ALSIHN) { 5078 UNIMPLEMENTED(); 5079 USE(instr); 5080 return 0; 5081 } 5082 5083 EVALUATE(CIH) { 5084 DCHECK_OPCODE(CIH); 5085 DECODE_RIL_A_INSTRUCTION(r1, imm); 5086 int32_t r1_val = get_high_register<int32_t>(r1); 5087 SetS390ConditionCode<int32_t>(r1_val, static_cast<int32_t>(imm)); 5088 return length; 5089 } 5090 5091 EVALUATE(CLIH) { 5092 DCHECK_OPCODE(CLIH); 5093 // Compare Logical with Immediate (32) 5094 DECODE_RIL_A_INSTRUCTION(r1, imm); 5095 SetS390ConditionCode<uint32_t>(get_high_register<uint32_t>(r1), imm); 5096 return length; 5097 } 5098 5099 EVALUATE(STCK) { 5100 UNIMPLEMENTED(); 5101 USE(instr); 5102 return 0; 5103 } 5104 5105 EVALUATE(CFC) { 5106 UNIMPLEMENTED(); 5107 USE(instr); 5108 return 0; 5109 } 5110 5111 EVALUATE(IPM) { 5112 UNIMPLEMENTED(); 5113 USE(instr); 5114 return 0; 5115 } 5116 5117 EVALUATE(HSCH) { 5118 UNIMPLEMENTED(); 5119 USE(instr); 5120 return 0; 5121 } 5122 5123 EVALUATE(MSCH) { 5124 UNIMPLEMENTED(); 5125 USE(instr); 5126 return 0; 5127 } 5128 5129 EVALUATE(SSCH) { 5130 UNIMPLEMENTED(); 5131 USE(instr); 5132 return 0; 5133 } 5134 5135 EVALUATE(STSCH) { 5136 UNIMPLEMENTED(); 5137 USE(instr); 5138 return 0; 5139 } 5140 5141 EVALUATE(TSCH) { 5142 UNIMPLEMENTED(); 5143 USE(instr); 5144 return 0; 5145 } 5146 5147 EVALUATE(TPI) { 5148 UNIMPLEMENTED(); 5149 USE(instr); 5150 return 0; 5151 } 5152 5153 EVALUATE(SAL) { 5154 UNIMPLEMENTED(); 5155 USE(instr); 5156 return 0; 5157 } 5158 5159 EVALUATE(RSCH) { 5160 UNIMPLEMENTED(); 5161 USE(instr); 5162 return 0; 5163 } 5164 5165 EVALUATE(STCRW) { 5166 UNIMPLEMENTED(); 5167 USE(instr); 5168 return 0; 5169 } 5170 5171 EVALUATE(STCPS) { 5172 UNIMPLEMENTED(); 5173 USE(instr); 5174 return 0; 5175 } 5176 5177 EVALUATE(RCHP) { 5178 UNIMPLEMENTED(); 5179 USE(instr); 5180 return 0; 5181 } 5182 5183 EVALUATE(SCHM) { 5184 UNIMPLEMENTED(); 5185 USE(instr); 5186 return 0; 5187 } 5188 5189 EVALUATE(CKSM) { 5190 UNIMPLEMENTED(); 5191 USE(instr); 5192 return 0; 5193 } 5194 5195 EVALUATE(SAR) { 5196 UNIMPLEMENTED(); 5197 USE(instr); 5198 return 0; 5199 } 5200 5201 EVALUATE(EAR) { 5202 UNIMPLEMENTED(); 5203 USE(instr); 5204 return 0; 5205 } 5206 5207 EVALUATE(MSR) { 5208 DCHECK_OPCODE(MSR); 5209 DECODE_RRE_INSTRUCTION(r1, r2); 5210 int32_t r1_val = get_low_register<int32_t>(r1); 5211 int32_t r2_val = get_low_register<int32_t>(r2); 5212 set_low_register(r1, r1_val * r2_val); 5213 return length; 5214 } 5215 5216 EVALUATE(MSRKC) { 5217 DCHECK_OPCODE(MSRKC); 5218 DECODE_RRF_A_INSTRUCTION(r1, r2, r3); 5219 int32_t r2_val = get_low_register<int32_t>(r2); 5220 int32_t r3_val = get_low_register<int32_t>(r3); 5221 int64_t result64 = 5222 static_cast<int64_t>(r2_val) * static_cast<int64_t>(r3_val); 5223 int32_t result32 = static_cast<int32_t>(result64); 5224 bool isOF = (static_cast<int64_t>(result32) != result64); 5225 SetS390ConditionCode<int32_t>(result32, 0); 5226 SetS390OverflowCode(isOF); 5227 set_low_register(r1, result32); 5228 return length; 5229 } 5230 5231 EVALUATE(MVST) { 5232 UNIMPLEMENTED(); 5233 USE(instr); 5234 return 0; 5235 } 5236 5237 EVALUATE(CUSE) { 5238 UNIMPLEMENTED(); 5239 USE(instr); 5240 return 0; 5241 } 5242 5243 EVALUATE(SRST) { 5244 UNIMPLEMENTED(); 5245 USE(instr); 5246 return 0; 5247 } 5248 5249 EVALUATE(XSCH) { 5250 UNIMPLEMENTED(); 5251 USE(instr); 5252 return 0; 5253 } 5254 5255 EVALUATE(STCKE) { 5256 UNIMPLEMENTED(); 5257 USE(instr); 5258 return 0; 5259 } 5260 5261 EVALUATE(STCKF) { 5262 UNIMPLEMENTED(); 5263 USE(instr); 5264 return 0; 5265 } 5266 5267 EVALUATE(SRNM) { 5268 UNIMPLEMENTED(); 5269 USE(instr); 5270 return 0; 5271 } 5272 5273 EVALUATE(STFPC) { 5274 UNIMPLEMENTED(); 5275 USE(instr); 5276 return 0; 5277 } 5278 5279 EVALUATE(LFPC) { 5280 UNIMPLEMENTED(); 5281 USE(instr); 5282 return 0; 5283 } 5284 5285 EVALUATE(TRE) { 5286 UNIMPLEMENTED(); 5287 USE(instr); 5288 return 0; 5289 } 5290 5291 EVALUATE(STFLE) { 5292 UNIMPLEMENTED(); 5293 USE(instr); 5294 return 0; 5295 } 5296 5297 EVALUATE(SRNMB) { 5298 UNIMPLEMENTED(); 5299 USE(instr); 5300 return 0; 5301 } 5302 5303 EVALUATE(SRNMT) { 5304 UNIMPLEMENTED(); 5305 USE(instr); 5306 return 0; 5307 } 5308 5309 EVALUATE(LFAS) { 5310 UNIMPLEMENTED(); 5311 USE(instr); 5312 return 0; 5313 } 5314 5315 EVALUATE(PPA) { 5316 UNIMPLEMENTED(); 5317 USE(instr); 5318 return 0; 5319 } 5320 5321 EVALUATE(ETND) { 5322 UNIMPLEMENTED(); 5323 USE(instr); 5324 return 0; 5325 } 5326 5327 EVALUATE(TEND) { 5328 UNIMPLEMENTED(); 5329 USE(instr); 5330 return 0; 5331 } 5332 5333 EVALUATE(NIAI) { 5334 UNIMPLEMENTED(); 5335 USE(instr); 5336 return 0; 5337 } 5338 5339 EVALUATE(TABORT) { 5340 UNIMPLEMENTED(); 5341 USE(instr); 5342 return 0; 5343 } 5344 5345 EVALUATE(TRAP4) { 5346 DCHECK_OPCODE(TRAP4); 5347 int length = 4; 5348 // whack the space of the caller allocated stack 5349 int64_t sp_addr = get_register(sp); 5350 for (int i = 0; i < kCalleeRegisterSaveAreaSize / kPointerSize; ++i) { 5351 // we dont want to whack the RA (r14) 5352 if (i != 14) (reinterpret_cast<intptr_t*>(sp_addr))[i] = 0xDEADBABE; 5353 } 5354 SoftwareInterrupt(instr); 5355 return length; 5356 } 5357 5358 EVALUATE(LPEBR) { 5359 DCHECK_OPCODE(LPEBR); 5360 DECODE_RRE_INSTRUCTION(r1, r2); 5361 float fr1_val = get_float32_from_d_register(r1); 5362 float fr2_val = get_float32_from_d_register(r2); 5363 fr1_val = std::fabs(fr2_val); 5364 set_d_register_from_float32(r1, fr1_val); 5365 if (fr2_val != fr2_val) { // input is NaN 5366 condition_reg_ = CC_OF; 5367 } else if (fr2_val == 0) { 5368 condition_reg_ = CC_EQ; 5369 } else { 5370 condition_reg_ = CC_GT; 5371 } 5372 5373 return length; 5374 } 5375 5376 EVALUATE(LNEBR) { 5377 UNIMPLEMENTED(); 5378 USE(instr); 5379 return 0; 5380 } 5381 5382 EVALUATE(LTEBR) { 5383 DCHECK_OPCODE(LTEBR); 5384 DECODE_RRE_INSTRUCTION(r1, r2); 5385 int64_t r2_val = get_d_register(r2); 5386 float fr2_val = get_float32_from_d_register(r2); 5387 SetS390ConditionCode<float>(fr2_val, 0.0); 5388 set_d_register(r1, r2_val); 5389 return length; 5390 } 5391 5392 EVALUATE(LCEBR) { 5393 DCHECK_OPCODE(LCEBR); 5394 DECODE_RRE_INSTRUCTION(r1, r2); 5395 float fr1_val = get_float32_from_d_register(r1); 5396 float fr2_val = get_float32_from_d_register(r2); 5397 fr1_val = -fr2_val; 5398 set_d_register_from_float32(r1, fr1_val); 5399 if (fr2_val != fr2_val) { // input is NaN 5400 condition_reg_ = CC_OF; 5401 } else if (fr2_val == 0) { 5402 condition_reg_ = CC_EQ; 5403 } else if (fr2_val < 0) { 5404 condition_reg_ = CC_LT; 5405 } else if (fr2_val > 0) { 5406 condition_reg_ = CC_GT; 5407 } 5408 return length; 5409 } 5410 5411 EVALUATE(LDEBR) { 5412 DCHECK_OPCODE(LDEBR); 5413 DECODE_RRE_INSTRUCTION(r1, r2); 5414 float fp_val = get_float32_from_d_register(r2); 5415 double db_val = static_cast<double>(fp_val); 5416 set_d_register_from_double(r1, db_val); 5417 return length; 5418 } 5419 5420 EVALUATE(LXDBR) { 5421 UNIMPLEMENTED(); 5422 USE(instr); 5423 return 0; 5424 } 5425 5426 EVALUATE(LXEBR) { 5427 UNIMPLEMENTED(); 5428 USE(instr); 5429 return 0; 5430 } 5431 5432 EVALUATE(MXDBR) { 5433 UNIMPLEMENTED(); 5434 USE(instr); 5435 return 0; 5436 } 5437 5438 EVALUATE(KEBR) { 5439 UNIMPLEMENTED(); 5440 USE(instr); 5441 return 0; 5442 } 5443 5444 EVALUATE(CEBR) { 5445 DCHECK_OPCODE(CEBR); 5446 DECODE_RRE_INSTRUCTION(r1, r2); 5447 float fr1_val = get_float32_from_d_register(r1); 5448 float fr2_val = get_float32_from_d_register(r2); 5449 if (isNaN(fr1_val) || isNaN(fr2_val)) { 5450 condition_reg_ = CC_OF; 5451 } else { 5452 SetS390ConditionCode<float>(fr1_val, fr2_val); 5453 } 5454 5455 return length; 5456 } 5457 5458 EVALUATE(AEBR) { 5459 DCHECK_OPCODE(AEBR); 5460 DECODE_RRE_INSTRUCTION(r1, r2); 5461 float fr1_val = get_float32_from_d_register(r1); 5462 float fr2_val = get_float32_from_d_register(r2); 5463 fr1_val += fr2_val; 5464 set_d_register_from_float32(r1, fr1_val); 5465 SetS390ConditionCode<float>(fr1_val, 0); 5466 5467 return length; 5468 } 5469 5470 EVALUATE(SEBR) { 5471 DCHECK_OPCODE(SEBR); 5472 DECODE_RRE_INSTRUCTION(r1, r2); 5473 float fr1_val = get_float32_from_d_register(r1); 5474 float fr2_val = get_float32_from_d_register(r2); 5475 fr1_val -= fr2_val; 5476 set_d_register_from_float32(r1, fr1_val); 5477 SetS390ConditionCode<float>(fr1_val, 0); 5478 5479 return length; 5480 } 5481 5482 EVALUATE(MDEBR) { 5483 UNIMPLEMENTED(); 5484 USE(instr); 5485 return 0; 5486 } 5487 5488 EVALUATE(DEBR) { 5489 DCHECK_OPCODE(DEBR); 5490 DECODE_RRE_INSTRUCTION(r1, r2); 5491 float fr1_val = get_float32_from_d_register(r1); 5492 float fr2_val = get_float32_from_d_register(r2); 5493 fr1_val /= fr2_val; 5494 set_d_register_from_float32(r1, fr1_val); 5495 return length; 5496 } 5497 5498 EVALUATE(MAEBR) { 5499 UNIMPLEMENTED(); 5500 USE(instr); 5501 return 0; 5502 } 5503 5504 EVALUATE(MSEBR) { 5505 UNIMPLEMENTED(); 5506 USE(instr); 5507 return 0; 5508 } 5509 5510 EVALUATE(LPDBR) { 5511 DCHECK_OPCODE(LPDBR); 5512 DECODE_RRE_INSTRUCTION(r1, r2); 5513 double r1_val = get_double_from_d_register(r1); 5514 double r2_val = get_double_from_d_register(r2); 5515 r1_val = std::fabs(r2_val); 5516 set_d_register_from_double(r1, r1_val); 5517 if (r2_val != r2_val) { // input is NaN 5518 condition_reg_ = CC_OF; 5519 } else if (r2_val == 0) { 5520 condition_reg_ = CC_EQ; 5521 } else { 5522 condition_reg_ = CC_GT; 5523 } 5524 return length; 5525 } 5526 5527 EVALUATE(LNDBR) { 5528 UNIMPLEMENTED(); 5529 USE(instr); 5530 return 0; 5531 } 5532 5533 EVALUATE(LTDBR) { 5534 DCHECK_OPCODE(LTDBR); 5535 DECODE_RRE_INSTRUCTION(r1, r2); 5536 int64_t r2_val = get_d_register(r2); 5537 SetS390ConditionCode<double>(bit_cast<double, int64_t>(r2_val), 0.0); 5538 set_d_register(r1, r2_val); 5539 return length; 5540 } 5541 5542 EVALUATE(LCDBR) { 5543 DCHECK_OPCODE(LCDBR); 5544 DECODE_RRE_INSTRUCTION(r1, r2); 5545 double r1_val = get_double_from_d_register(r1); 5546 double r2_val = get_double_from_d_register(r2); 5547 r1_val = -r2_val; 5548 set_d_register_from_double(r1, r1_val); 5549 if (r2_val != r2_val) { // input is NaN 5550 condition_reg_ = CC_OF; 5551 } else if (r2_val == 0) { 5552 condition_reg_ = CC_EQ; 5553 } else if (r2_val < 0) { 5554 condition_reg_ = CC_LT; 5555 } else if (r2_val > 0) { 5556 condition_reg_ = CC_GT; 5557 } 5558 return length; 5559 } 5560 5561 EVALUATE(SQEBR) { 5562 DCHECK_OPCODE(SQEBR); 5563 DECODE_RRE_INSTRUCTION(r1, r2); 5564 float fr1_val = get_float32_from_d_register(r1); 5565 float fr2_val = get_float32_from_d_register(r2); 5566 fr1_val = std::sqrt(fr2_val); 5567 set_d_register_from_float32(r1, fr1_val); 5568 return length; 5569 } 5570 5571 EVALUATE(SQDBR) { 5572 DCHECK_OPCODE(SQDBR); 5573 DECODE_RRE_INSTRUCTION(r1, r2); 5574 double r1_val = get_double_from_d_register(r1); 5575 double r2_val = get_double_from_d_register(r2); 5576 r1_val = std::sqrt(r2_val); 5577 set_d_register_from_double(r1, r1_val); 5578 return length; 5579 } 5580 5581 EVALUATE(SQXBR) { 5582 UNIMPLEMENTED(); 5583 USE(instr); 5584 return 0; 5585 } 5586 5587 EVALUATE(MEEBR) { 5588 DCHECK_OPCODE(MEEBR); 5589 DECODE_RRE_INSTRUCTION(r1, r2); 5590 float fr1_val = get_float32_from_d_register(r1); 5591 float fr2_val = get_float32_from_d_register(r2); 5592 fr1_val *= fr2_val; 5593 set_d_register_from_float32(r1, fr1_val); 5594 return length; 5595 } 5596 5597 EVALUATE(KDBR) { 5598 UNIMPLEMENTED(); 5599 USE(instr); 5600 return 0; 5601 } 5602 5603 EVALUATE(CDBR) { 5604 DCHECK_OPCODE(CDBR); 5605 DECODE_RRE_INSTRUCTION(r1, r2); 5606 double r1_val = get_double_from_d_register(r1); 5607 double r2_val = get_double_from_d_register(r2); 5608 if (isNaN(r1_val) || isNaN(r2_val)) { 5609 condition_reg_ = CC_OF; 5610 } else { 5611 SetS390ConditionCode<double>(r1_val, r2_val); 5612 } 5613 return length; 5614 } 5615 5616 EVALUATE(ADBR) { 5617 DCHECK_OPCODE(ADBR); 5618 DECODE_RRE_INSTRUCTION(r1, r2); 5619 double r1_val = get_double_from_d_register(r1); 5620 double r2_val = get_double_from_d_register(r2); 5621 r1_val += r2_val; 5622 set_d_register_from_double(r1, r1_val); 5623 SetS390ConditionCode<double>(r1_val, 0); 5624 return length; 5625 } 5626 5627 EVALUATE(SDBR) { 5628 DCHECK_OPCODE(SDBR); 5629 DECODE_RRE_INSTRUCTION(r1, r2); 5630 double r1_val = get_double_from_d_register(r1); 5631 double r2_val = get_double_from_d_register(r2); 5632 r1_val -= r2_val; 5633 set_d_register_from_double(r1, r1_val); 5634 SetS390ConditionCode<double>(r1_val, 0); 5635 return length; 5636 } 5637 5638 EVALUATE(MDBR) { 5639 DCHECK_OPCODE(MDBR); 5640 DECODE_RRE_INSTRUCTION(r1, r2); 5641 double r1_val = get_double_from_d_register(r1); 5642 double r2_val = get_double_from_d_register(r2); 5643 r1_val *= r2_val; 5644 set_d_register_from_double(r1, r1_val); 5645 return length; 5646 } 5647 5648 EVALUATE(DDBR) { 5649 DCHECK_OPCODE(DDBR); 5650 DECODE_RRE_INSTRUCTION(r1, r2); 5651 double r1_val = get_double_from_d_register(r1); 5652 double r2_val = get_double_from_d_register(r2); 5653 r1_val /= r2_val; 5654 set_d_register_from_double(r1, r1_val); 5655 return length; 5656 } 5657 5658 EVALUATE(MADBR) { 5659 DCHECK_OPCODE(MADBR); 5660 DECODE_RRD_INSTRUCTION(r1, r2, r3); 5661 double r1_val = get_double_from_d_register(r1); 5662 double r2_val = get_double_from_d_register(r2); 5663 double r3_val = get_double_from_d_register(r3); 5664 r1_val += r2_val * r3_val; 5665 set_d_register_from_double(r1, r1_val); 5666 SetS390ConditionCode<double>(r1_val, 0); 5667 return length; 5668 } 5669 5670 EVALUATE(MSDBR) { 5671 UNIMPLEMENTED(); 5672 USE(instr); 5673 return 0; 5674 } 5675 5676 EVALUATE(LPXBR) { 5677 UNIMPLEMENTED(); 5678 USE(instr); 5679 return 0; 5680 } 5681 5682 EVALUATE(LNXBR) { 5683 UNIMPLEMENTED(); 5684 USE(instr); 5685 return 0; 5686 } 5687 5688 EVALUATE(LTXBR) { 5689 UNIMPLEMENTED(); 5690 USE(instr); 5691 return 0; 5692 } 5693 5694 EVALUATE(LCXBR) { 5695 UNIMPLEMENTED(); 5696 USE(instr); 5697 return 0; 5698 } 5699 5700 EVALUATE(LEDBRA) { 5701 DCHECK_OPCODE(LEDBRA); 5702 DECODE_RRE_INSTRUCTION(r1, r2); 5703 double r2_val = get_double_from_d_register(r2); 5704 set_d_register_from_float32(r1, static_cast<float>(r2_val)); 5705 return length; 5706 } 5707 5708 EVALUATE(LDXBRA) { 5709 UNIMPLEMENTED(); 5710 USE(instr); 5711 return 0; 5712 } 5713 5714 EVALUATE(LEXBRA) { 5715 UNIMPLEMENTED(); 5716 USE(instr); 5717 return 0; 5718 } 5719 5720 EVALUATE(FIXBRA) { 5721 UNIMPLEMENTED(); 5722 USE(instr); 5723 return 0; 5724 } 5725 5726 EVALUATE(KXBR) { 5727 UNIMPLEMENTED(); 5728 USE(instr); 5729 return 0; 5730 } 5731 5732 EVALUATE(CXBR) { 5733 UNIMPLEMENTED(); 5734 USE(instr); 5735 return 0; 5736 } 5737 5738 EVALUATE(AXBR) { 5739 UNIMPLEMENTED(); 5740 USE(instr); 5741 return 0; 5742 } 5743 5744 EVALUATE(SXBR) { 5745 UNIMPLEMENTED(); 5746 USE(instr); 5747 return 0; 5748 } 5749 5750 EVALUATE(MXBR) { 5751 UNIMPLEMENTED(); 5752 USE(instr); 5753 return 0; 5754 } 5755 5756 EVALUATE(DXBR) { 5757 UNIMPLEMENTED(); 5758 USE(instr); 5759 return 0; 5760 } 5761 5762 EVALUATE(TBEDR) { 5763 UNIMPLEMENTED(); 5764 USE(instr); 5765 return 0; 5766 } 5767 5768 EVALUATE(TBDR) { 5769 UNIMPLEMENTED(); 5770 USE(instr); 5771 return 0; 5772 } 5773 5774 EVALUATE(DIEBR) { 5775 UNIMPLEMENTED(); 5776 USE(instr); 5777 return 0; 5778 } 5779 5780 EVALUATE(FIEBRA) { 5781 DCHECK_OPCODE(FIEBRA); 5782 DECODE_RRF_E_INSTRUCTION(r1, r2, m3, m4); 5783 float r2_val = get_float32_from_d_register(r2); 5784 CHECK_EQ(m4, 0); 5785 switch (m3) { 5786 case Assembler::FIDBRA_ROUND_TO_NEAREST_AWAY_FROM_0: 5787 set_d_register_from_float32(r1, round(r2_val)); 5788 break; 5789 case Assembler::FIDBRA_ROUND_TOWARD_0: 5790 set_d_register_from_float32(r1, trunc(r2_val)); 5791 break; 5792 case Assembler::FIDBRA_ROUND_TOWARD_POS_INF: 5793 set_d_register_from_float32(r1, std::ceil(r2_val)); 5794 break; 5795 case Assembler::FIDBRA_ROUND_TOWARD_NEG_INF: 5796 set_d_register_from_float32(r1, std::floor(r2_val)); 5797 break; 5798 default: 5799 UNIMPLEMENTED(); 5800 break; 5801 } 5802 return length; 5803 } 5804 5805 EVALUATE(THDER) { 5806 UNIMPLEMENTED(); 5807 USE(instr); 5808 return 0; 5809 } 5810 5811 EVALUATE(THDR) { 5812 UNIMPLEMENTED(); 5813 USE(instr); 5814 return 0; 5815 } 5816 5817 EVALUATE(DIDBR) { 5818 UNIMPLEMENTED(); 5819 USE(instr); 5820 return 0; 5821 } 5822 5823 EVALUATE(FIDBRA) { 5824 DCHECK_OPCODE(FIDBRA); 5825 DECODE_RRF_E_INSTRUCTION(r1, r2, m3, m4); 5826 double r2_val = get_double_from_d_register(r2); 5827 CHECK_EQ(m4, 0); 5828 switch (m3) { 5829 case Assembler::FIDBRA_ROUND_TO_NEAREST_AWAY_FROM_0: 5830 set_d_register_from_double(r1, round(r2_val)); 5831 break; 5832 case Assembler::FIDBRA_ROUND_TOWARD_0: 5833 set_d_register_from_double(r1, trunc(r2_val)); 5834 break; 5835 case Assembler::FIDBRA_ROUND_TOWARD_POS_INF: 5836 set_d_register_from_double(r1, std::ceil(r2_val)); 5837 break; 5838 case Assembler::FIDBRA_ROUND_TOWARD_NEG_INF: 5839 set_d_register_from_double(r1, std::floor(r2_val)); 5840 break; 5841 default: 5842 UNIMPLEMENTED(); 5843 break; 5844 } 5845 return length; 5846 } 5847 5848 EVALUATE(LXR) { 5849 UNIMPLEMENTED(); 5850 USE(instr); 5851 return 0; 5852 } 5853 5854 EVALUATE(LPDFR) { 5855 UNIMPLEMENTED(); 5856 USE(instr); 5857 return 0; 5858 } 5859 5860 EVALUATE(LNDFR) { 5861 UNIMPLEMENTED(); 5862 USE(instr); 5863 return 0; 5864 } 5865 5866 EVALUATE(LCDFR) { 5867 UNIMPLEMENTED(); 5868 USE(instr); 5869 return 0; 5870 } 5871 5872 EVALUATE(LZER) { 5873 UNIMPLEMENTED(); 5874 USE(instr); 5875 return 0; 5876 } 5877 5878 EVALUATE(LZDR) { 5879 DCHECK_OPCODE(LZDR); 5880 DECODE_RRE_INSTRUCTION_NO_R2(r1); 5881 set_d_register_from_double(r1, 0.0); 5882 return length; 5883 } 5884 5885 EVALUATE(LZXR) { 5886 UNIMPLEMENTED(); 5887 USE(instr); 5888 return 0; 5889 } 5890 5891 EVALUATE(SFPC) { 5892 UNIMPLEMENTED(); 5893 USE(instr); 5894 return 0; 5895 } 5896 5897 EVALUATE(SFASR) { 5898 UNIMPLEMENTED(); 5899 USE(instr); 5900 return 0; 5901 } 5902 5903 EVALUATE(EFPC) { 5904 UNIMPLEMENTED(); 5905 USE(instr); 5906 return 0; 5907 } 5908 5909 EVALUATE(CELFBR) { 5910 DCHECK_OPCODE(CELFBR); 5911 DECODE_RRE_INSTRUCTION(r1, r2); 5912 uint32_t r2_val = get_low_register<uint32_t>(r2); 5913 float r1_val = static_cast<float>(r2_val); 5914 set_d_register_from_float32(r1, r1_val); 5915 return length; 5916 } 5917 5918 EVALUATE(CDLFBR) { 5919 DCHECK_OPCODE(CDLFBR); 5920 DECODE_RRE_INSTRUCTION(r1, r2); 5921 uint32_t r2_val = get_low_register<uint32_t>(r2); 5922 double r1_val = static_cast<double>(r2_val); 5923 set_d_register_from_double(r1, r1_val); 5924 return length; 5925 } 5926 5927 EVALUATE(CXLFBR) { 5928 UNIMPLEMENTED(); 5929 USE(instr); 5930 return 0; 5931 } 5932 5933 EVALUATE(CEFBRA) { 5934 DCHECK_OPCODE(CEFBRA); 5935 DECODE_RRE_INSTRUCTION(r1, r2); 5936 int32_t fr2_val = get_low_register<int32_t>(r2); 5937 float fr1_val = static_cast<float>(fr2_val); 5938 set_d_register_from_float32(r1, fr1_val); 5939 return length; 5940 } 5941 5942 EVALUATE(CDFBRA) { 5943 DCHECK_OPCODE(CDFBRA); 5944 DECODE_RRE_INSTRUCTION(r1, r2); 5945 int32_t r2_val = get_low_register<int32_t>(r2); 5946 double r1_val = static_cast<double>(r2_val); 5947 set_d_register_from_double(r1, r1_val); 5948 return length; 5949 } 5950 5951 EVALUATE(CXFBRA) { 5952 UNIMPLEMENTED(); 5953 USE(instr); 5954 return 0; 5955 } 5956 5957 EVALUATE(CFEBRA) { 5958 DCHECK_OPCODE(CFEBRA); 5959 DECODE_RRE_INSTRUCTION_M3(r1, r2, mask_val); 5960 float r2_fval = get_float32_from_d_register(r2); 5961 int32_t r1_val = 0; 5962 5963 SetS390RoundConditionCode(r2_fval, INT32_MAX, INT32_MIN); 5964 5965 switch (mask_val) { 5966 case CURRENT_ROUNDING_MODE: 5967 case ROUND_TO_PREPARE_FOR_SHORTER_PRECISION: { 5968 r1_val = static_cast<int32_t>(r2_fval); 5969 break; 5970 } 5971 case ROUND_TO_NEAREST_WITH_TIES_AWAY_FROM_0: { 5972 float ceil_val = std::ceil(r2_fval); 5973 float floor_val = std::floor(r2_fval); 5974 float sub_val1 = std::fabs(r2_fval - floor_val); 5975 float sub_val2 = std::fabs(r2_fval - ceil_val); 5976 if (sub_val1 > sub_val2) { 5977 r1_val = static_cast<int32_t>(ceil_val); 5978 } else if (sub_val1 < sub_val2) { 5979 r1_val = static_cast<int32_t>(floor_val); 5980 } else { // round away from zero: 5981 if (r2_fval > 0.0) { 5982 r1_val = static_cast<int32_t>(ceil_val); 5983 } else { 5984 r1_val = static_cast<int32_t>(floor_val); 5985 } 5986 } 5987 break; 5988 } 5989 case ROUND_TO_NEAREST_WITH_TIES_TO_EVEN: { 5990 float ceil_val = std::ceil(r2_fval); 5991 float floor_val = std::floor(r2_fval); 5992 float sub_val1 = std::fabs(r2_fval - floor_val); 5993 float sub_val2 = std::fabs(r2_fval - ceil_val); 5994 if (sub_val1 > sub_val2) { 5995 r1_val = static_cast<int32_t>(ceil_val); 5996 } else if (sub_val1 < sub_val2) { 5997 r1_val = static_cast<int32_t>(floor_val); 5998 } else { // check which one is even: 5999 int32_t c_v = static_cast<int32_t>(ceil_val); 6000 int32_t f_v = static_cast<int32_t>(floor_val); 6001 if (f_v % 2 == 0) 6002 r1_val = f_v; 6003 else 6004 r1_val = c_v; 6005 } 6006 break; 6007 } 6008 case ROUND_TOWARD_0: { 6009 // check for overflow, cast r2_fval to 64bit integer 6010 // then check value within the range of INT_MIN and INT_MAX 6011 // and set condition code accordingly 6012 int64_t temp = static_cast<int64_t>(r2_fval); 6013 if (temp < INT_MIN || temp > INT_MAX) { 6014 condition_reg_ = CC_OF; 6015 } 6016 r1_val = static_cast<int32_t>(r2_fval); 6017 break; 6018 } 6019 case ROUND_TOWARD_PLUS_INFINITE: { 6020 r1_val = static_cast<int32_t>(std::ceil(r2_fval)); 6021 break; 6022 } 6023 case ROUND_TOWARD_MINUS_INFINITE: { 6024 // check for overflow, cast r2_fval to 64bit integer 6025 // then check value within the range of INT_MIN and INT_MAX 6026 // and set condition code accordingly 6027 int64_t temp = static_cast<int64_t>(std::floor(r2_fval)); 6028 if (temp < INT_MIN || temp > INT_MAX) { 6029 condition_reg_ = CC_OF; 6030 } 6031 r1_val = static_cast<int32_t>(std::floor(r2_fval)); 6032 break; 6033 } 6034 default: 6035 UNREACHABLE(); 6036 } 6037 set_low_register(r1, r1_val); 6038 return length; 6039 } 6040 6041 EVALUATE(CFDBRA) { 6042 DCHECK_OPCODE(CFDBRA); 6043 DECODE_RRE_INSTRUCTION_M3(r1, r2, mask_val); 6044 double r2_val = get_double_from_d_register(r2); 6045 int32_t r1_val = 0; 6046 6047 SetS390RoundConditionCode(r2_val, INT32_MAX, INT32_MIN); 6048 6049 switch (mask_val) { 6050 case CURRENT_ROUNDING_MODE: 6051 case ROUND_TO_PREPARE_FOR_SHORTER_PRECISION: { 6052 r1_val = static_cast<int32_t>(r2_val); 6053 break; 6054 } 6055 case ROUND_TO_NEAREST_WITH_TIES_AWAY_FROM_0: { 6056 double ceil_val = std::ceil(r2_val); 6057 double floor_val = std::floor(r2_val); 6058 double sub_val1 = std::fabs(r2_val - floor_val); 6059 double sub_val2 = std::fabs(r2_val - ceil_val); 6060 if (sub_val1 > sub_val2) { 6061 r1_val = static_cast<int32_t>(ceil_val); 6062 } else if (sub_val1 < sub_val2) { 6063 r1_val = static_cast<int32_t>(floor_val); 6064 } else { // round away from zero: 6065 if (r2_val > 0.0) { 6066 r1_val = static_cast<int32_t>(ceil_val); 6067 } else { 6068 r1_val = static_cast<int32_t>(floor_val); 6069 } 6070 } 6071 break; 6072 } 6073 case ROUND_TO_NEAREST_WITH_TIES_TO_EVEN: { 6074 double ceil_val = std::ceil(r2_val); 6075 double floor_val = std::floor(r2_val); 6076 double sub_val1 = std::fabs(r2_val - floor_val); 6077 double sub_val2 = std::fabs(r2_val - ceil_val); 6078 if (sub_val1 > sub_val2) { 6079 r1_val = static_cast<int32_t>(ceil_val); 6080 } else if (sub_val1 < sub_val2) { 6081 r1_val = static_cast<int32_t>(floor_val); 6082 } else { // check which one is even: 6083 int32_t c_v = static_cast<int32_t>(ceil_val); 6084 int32_t f_v = static_cast<int32_t>(floor_val); 6085 if (f_v % 2 == 0) 6086 r1_val = f_v; 6087 else 6088 r1_val = c_v; 6089 } 6090 break; 6091 } 6092 case ROUND_TOWARD_0: { 6093 // check for overflow, cast r2_val to 64bit integer 6094 // then check value within the range of INT_MIN and INT_MAX 6095 // and set condition code accordingly 6096 int64_t temp = static_cast<int64_t>(r2_val); 6097 if (temp < INT_MIN || temp > INT_MAX) { 6098 condition_reg_ = CC_OF; 6099 } 6100 r1_val = static_cast<int32_t>(r2_val); 6101 break; 6102 } 6103 case ROUND_TOWARD_PLUS_INFINITE: { 6104 r1_val = static_cast<int32_t>(std::ceil(r2_val)); 6105 break; 6106 } 6107 case ROUND_TOWARD_MINUS_INFINITE: { 6108 // check for overflow, cast r2_val to 64bit integer 6109 // then check value within the range of INT_MIN and INT_MAX 6110 // and set condition code accordingly 6111 int64_t temp = static_cast<int64_t>(std::floor(r2_val)); 6112 if (temp < INT_MIN || temp > INT_MAX) { 6113 condition_reg_ = CC_OF; 6114 } 6115 r1_val = static_cast<int32_t>(std::floor(r2_val)); 6116 break; 6117 } 6118 default: 6119 UNREACHABLE(); 6120 } 6121 set_low_register(r1, r1_val); 6122 return length; 6123 } 6124 6125 EVALUATE(CFXBRA) { 6126 UNIMPLEMENTED(); 6127 USE(instr); 6128 return 0; 6129 } 6130 6131 EVALUATE(CLFEBR) { 6132 DCHECK_OPCODE(CLFEBR); 6133 DECODE_RRE_INSTRUCTION(r1, r2); 6134 float r2_val = get_float32_from_d_register(r2); 6135 uint32_t r1_val = static_cast<uint32_t>(r2_val); 6136 set_low_register(r1, r1_val); 6137 SetS390ConvertConditionCode<double>(r2_val, r1_val, UINT32_MAX); 6138 return length; 6139 } 6140 6141 EVALUATE(CLFDBR) { 6142 DCHECK_OPCODE(CLFDBR); 6143 DECODE_RRE_INSTRUCTION(r1, r2); 6144 double a = get_double_from_d_register(r2); 6145 double n = std::round(a); 6146 uint32_t r1_val = static_cast<uint32_t>(n); 6147 set_low_register(r1, r1_val); 6148 if (std::isfinite(a) && a < 0.0) { 6149 DCHECK(n <= 0.0 && std::isfinite(n)); 6150 condition_reg_ = (n < 0.0) ? 0x1 : 0x4; 6151 } else if (a == 0.0) { 6152 condition_reg_ = 0x8; 6153 } else if (std::isfinite(a) && a > 0.0) { 6154 DCHECK(n >= 0.0 && std::isfinite(n)); 6155 condition_reg_ = (n <= static_cast<double>(UINT32_MAX)) ? 0x2 : 0x1; 6156 } else { 6157 condition_reg_ = 0x1; 6158 } 6159 return length; 6160 } 6161 6162 EVALUATE(CLFXBR) { 6163 UNIMPLEMENTED(); 6164 USE(instr); 6165 return 0; 6166 } 6167 6168 EVALUATE(CELGBR) { 6169 DCHECK_OPCODE(CELGBR); 6170 DECODE_RRE_INSTRUCTION(r1, r2); 6171 uint64_t r2_val = get_register(r2); 6172 float r1_val = static_cast<float>(r2_val); 6173 set_d_register_from_float32(r1, r1_val); 6174 return length; 6175 } 6176 6177 EVALUATE(CDLGBR) { 6178 DCHECK_OPCODE(CDLGBR); 6179 DECODE_RRE_INSTRUCTION(r1, r2); 6180 uint64_t r2_val = get_register(r2); 6181 double r1_val = static_cast<double>(r2_val); 6182 set_d_register_from_double(r1, r1_val); 6183 return length; 6184 } 6185 6186 EVALUATE(CXLGBR) { 6187 UNIMPLEMENTED(); 6188 USE(instr); 6189 return 0; 6190 } 6191 6192 EVALUATE(CEGBRA) { 6193 DCHECK_OPCODE(CEGBRA); 6194 DECODE_RRE_INSTRUCTION(r1, r2); 6195 int64_t fr2_val = get_register(r2); 6196 float fr1_val = static_cast<float>(fr2_val); 6197 set_d_register_from_float32(r1, fr1_val); 6198 return length; 6199 } 6200 6201 EVALUATE(CDGBRA) { 6202 DCHECK_OPCODE(CDGBRA); 6203 DECODE_RRE_INSTRUCTION(r1, r2); 6204 int64_t r2_val = get_register(r2); 6205 double r1_val = static_cast<double>(r2_val); 6206 set_d_register_from_double(r1, r1_val); 6207 return length; 6208 } 6209 6210 EVALUATE(CXGBRA) { 6211 UNIMPLEMENTED(); 6212 USE(instr); 6213 return 0; 6214 } 6215 6216 EVALUATE(CGEBRA) { 6217 DCHECK_OPCODE(CGEBRA); 6218 DECODE_RRE_INSTRUCTION_M3(r1, r2, mask_val); 6219 float r2_fval = get_float32_from_d_register(r2); 6220 int64_t r1_val = 0; 6221 6222 SetS390RoundConditionCode(r2_fval, INT64_MAX, INT64_MIN); 6223 6224 switch (mask_val) { 6225 case CURRENT_ROUNDING_MODE: 6226 case ROUND_TO_NEAREST_WITH_TIES_AWAY_FROM_0: 6227 case ROUND_TO_PREPARE_FOR_SHORTER_PRECISION: { 6228 UNIMPLEMENTED(); 6229 break; 6230 } 6231 case ROUND_TO_NEAREST_WITH_TIES_TO_EVEN: { 6232 float ceil_val = std::ceil(r2_fval); 6233 float floor_val = std::floor(r2_fval); 6234 if (std::abs(r2_fval - floor_val) > std::abs(r2_fval - ceil_val)) { 6235 r1_val = static_cast<int64_t>(ceil_val); 6236 } else if (std::abs(r2_fval - floor_val) < std::abs(r2_fval - ceil_val)) { 6237 r1_val = static_cast<int64_t>(floor_val); 6238 } else { // check which one is even: 6239 int64_t c_v = static_cast<int64_t>(ceil_val); 6240 int64_t f_v = static_cast<int64_t>(floor_val); 6241 if (f_v % 2 == 0) 6242 r1_val = f_v; 6243 else 6244 r1_val = c_v; 6245 } 6246 break; 6247 } 6248 case ROUND_TOWARD_0: { 6249 r1_val = static_cast<int64_t>(r2_fval); 6250 break; 6251 } 6252 case ROUND_TOWARD_PLUS_INFINITE: { 6253 r1_val = static_cast<int64_t>(std::ceil(r2_fval)); 6254 break; 6255 } 6256 case ROUND_TOWARD_MINUS_INFINITE: { 6257 r1_val = static_cast<int64_t>(std::floor(r2_fval)); 6258 break; 6259 } 6260 default: 6261 UNREACHABLE(); 6262 } 6263 set_register(r1, r1_val); 6264 return length; 6265 } 6266 6267 EVALUATE(CGDBRA) { 6268 DCHECK_OPCODE(CGDBRA); 6269 DECODE_RRE_INSTRUCTION_M3(r1, r2, mask_val); 6270 double r2_val = get_double_from_d_register(r2); 6271 int64_t r1_val = 0; 6272 6273 SetS390RoundConditionCode(r2_val, INT64_MAX, INT64_MIN); 6274 6275 switch (mask_val) { 6276 case CURRENT_ROUNDING_MODE: 6277 case ROUND_TO_NEAREST_WITH_TIES_AWAY_FROM_0: 6278 case ROUND_TO_PREPARE_FOR_SHORTER_PRECISION: { 6279 UNIMPLEMENTED(); 6280 break; 6281 } 6282 case ROUND_TO_NEAREST_WITH_TIES_TO_EVEN: { 6283 double ceil_val = std::ceil(r2_val); 6284 double floor_val = std::floor(r2_val); 6285 if (std::abs(r2_val - floor_val) > std::abs(r2_val - ceil_val)) { 6286 r1_val = static_cast<int64_t>(ceil_val); 6287 } else if (std::abs(r2_val - floor_val) < std::abs(r2_val - ceil_val)) { 6288 r1_val = static_cast<int64_t>(floor_val); 6289 } else { // check which one is even: 6290 int64_t c_v = static_cast<int64_t>(ceil_val); 6291 int64_t f_v = static_cast<int64_t>(floor_val); 6292 if (f_v % 2 == 0) 6293 r1_val = f_v; 6294 else 6295 r1_val = c_v; 6296 } 6297 break; 6298 } 6299 case ROUND_TOWARD_0: { 6300 r1_val = static_cast<int64_t>(r2_val); 6301 break; 6302 } 6303 case ROUND_TOWARD_PLUS_INFINITE: { 6304 r1_val = static_cast<int64_t>(std::ceil(r2_val)); 6305 break; 6306 } 6307 case ROUND_TOWARD_MINUS_INFINITE: { 6308 r1_val = static_cast<int64_t>(std::floor(r2_val)); 6309 break; 6310 } 6311 default: 6312 UNREACHABLE(); 6313 } 6314 set_register(r1, r1_val); 6315 return length; 6316 } 6317 6318 EVALUATE(CGXBRA) { 6319 UNIMPLEMENTED(); 6320 USE(instr); 6321 return 0; 6322 } 6323 6324 EVALUATE(CLGEBR) { 6325 DCHECK_OPCODE(CLGEBR); 6326 DECODE_RRE_INSTRUCTION(r1, r2); 6327 float r2_val = get_float32_from_d_register(r2); 6328 uint64_t r1_val = static_cast<uint64_t>(r2_val); 6329 set_register(r1, r1_val); 6330 SetS390ConvertConditionCode<double>(r2_val, r1_val, UINT64_MAX); 6331 return length; 6332 } 6333 6334 EVALUATE(CLGDBR) { 6335 DCHECK_OPCODE(CLGDBR); 6336 DECODE_RRE_INSTRUCTION(r1, r2); 6337 double r2_val = get_double_from_d_register(r2); 6338 uint64_t r1_val = static_cast<uint64_t>(r2_val); 6339 set_register(r1, r1_val); 6340 SetS390ConvertConditionCode<double>(r2_val, r1_val, UINT64_MAX); 6341 return length; 6342 } 6343 6344 EVALUATE(CFER) { 6345 UNIMPLEMENTED(); 6346 USE(instr); 6347 return 0; 6348 } 6349 6350 EVALUATE(CFDR) { 6351 UNIMPLEMENTED(); 6352 USE(instr); 6353 return 0; 6354 } 6355 6356 EVALUATE(CFXR) { 6357 UNIMPLEMENTED(); 6358 USE(instr); 6359 return 0; 6360 } 6361 6362 EVALUATE(LDGR) { 6363 DCHECK_OPCODE(LDGR); 6364 // Load FPR from GPR (L <- 64) 6365 DECODE_RRE_INSTRUCTION(r1, r2); 6366 uint64_t int_val = get_register(r2); 6367 // double double_val = bit_cast<double, uint64_t>(int_val); 6368 // set_d_register_from_double(rreInst->R1Value(), double_val); 6369 set_d_register(r1, int_val); 6370 return length; 6371 } 6372 6373 EVALUATE(CGER) { 6374 UNIMPLEMENTED(); 6375 USE(instr); 6376 return 0; 6377 } 6378 6379 EVALUATE(CGDR) { 6380 UNIMPLEMENTED(); 6381 USE(instr); 6382 return 0; 6383 } 6384 6385 EVALUATE(CGXR) { 6386 UNIMPLEMENTED(); 6387 USE(instr); 6388 return 0; 6389 } 6390 6391 EVALUATE(LGDR) { 6392 DCHECK_OPCODE(LGDR); 6393 DECODE_RRE_INSTRUCTION(r1, r2); 6394 // Load GPR from FPR (64 <- L) 6395 int64_t double_val = get_d_register(r2); 6396 set_register(r1, double_val); 6397 return length; 6398 } 6399 6400 EVALUATE(MDTRA) { 6401 UNIMPLEMENTED(); 6402 USE(instr); 6403 return 0; 6404 } 6405 6406 EVALUATE(DDTRA) { 6407 UNIMPLEMENTED(); 6408 USE(instr); 6409 return 0; 6410 } 6411 6412 EVALUATE(ADTRA) { 6413 UNIMPLEMENTED(); 6414 USE(instr); 6415 return 0; 6416 } 6417 6418 EVALUATE(SDTRA) { 6419 UNIMPLEMENTED(); 6420 USE(instr); 6421 return 0; 6422 } 6423 6424 EVALUATE(LDETR) { 6425 UNIMPLEMENTED(); 6426 USE(instr); 6427 return 0; 6428 } 6429 6430 EVALUATE(LEDTR) { 6431 UNIMPLEMENTED(); 6432 USE(instr); 6433 return 0; 6434 } 6435 6436 EVALUATE(LTDTR) { 6437 UNIMPLEMENTED(); 6438 USE(instr); 6439 return 0; 6440 } 6441 6442 EVALUATE(FIDTR) { 6443 UNIMPLEMENTED(); 6444 USE(instr); 6445 return 0; 6446 } 6447 6448 EVALUATE(MXTRA) { 6449 UNIMPLEMENTED(); 6450 USE(instr); 6451 return 0; 6452 } 6453 6454 EVALUATE(DXTRA) { 6455 UNIMPLEMENTED(); 6456 USE(instr); 6457 return 0; 6458 } 6459 6460 EVALUATE(AXTRA) { 6461 UNIMPLEMENTED(); 6462 USE(instr); 6463 return 0; 6464 } 6465 6466 EVALUATE(SXTRA) { 6467 UNIMPLEMENTED(); 6468 USE(instr); 6469 return 0; 6470 } 6471 6472 EVALUATE(LXDTR) { 6473 UNIMPLEMENTED(); 6474 USE(instr); 6475 return 0; 6476 } 6477 6478 EVALUATE(LDXTR) { 6479 UNIMPLEMENTED(); 6480 USE(instr); 6481 return 0; 6482 } 6483 6484 EVALUATE(LTXTR) { 6485 UNIMPLEMENTED(); 6486 USE(instr); 6487 return 0; 6488 } 6489 6490 EVALUATE(FIXTR) { 6491 UNIMPLEMENTED(); 6492 USE(instr); 6493 return 0; 6494 } 6495 6496 EVALUATE(KDTR) { 6497 UNIMPLEMENTED(); 6498 USE(instr); 6499 return 0; 6500 } 6501 6502 EVALUATE(CGDTRA) { 6503 UNIMPLEMENTED(); 6504 USE(instr); 6505 return 0; 6506 } 6507 6508 EVALUATE(CUDTR) { 6509 UNIMPLEMENTED(); 6510 USE(instr); 6511 return 0; 6512 } 6513 6514 EVALUATE(CDTR) { 6515 UNIMPLEMENTED(); 6516 USE(instr); 6517 return 0; 6518 } 6519 6520 EVALUATE(EEDTR) { 6521 UNIMPLEMENTED(); 6522 USE(instr); 6523 return 0; 6524 } 6525 6526 EVALUATE(ESDTR) { 6527 UNIMPLEMENTED(); 6528 USE(instr); 6529 return 0; 6530 } 6531 6532 EVALUATE(KXTR) { 6533 UNIMPLEMENTED(); 6534 USE(instr); 6535 return 0; 6536 } 6537 6538 EVALUATE(CGXTRA) { 6539 UNIMPLEMENTED(); 6540 USE(instr); 6541 return 0; 6542 } 6543 6544 EVALUATE(CUXTR) { 6545 UNIMPLEMENTED(); 6546 USE(instr); 6547 return 0; 6548 } 6549 6550 EVALUATE(CSXTR) { 6551 UNIMPLEMENTED(); 6552 USE(instr); 6553 return 0; 6554 } 6555 6556 EVALUATE(CXTR) { 6557 UNIMPLEMENTED(); 6558 USE(instr); 6559 return 0; 6560 } 6561 6562 EVALUATE(EEXTR) { 6563 UNIMPLEMENTED(); 6564 USE(instr); 6565 return 0; 6566 } 6567 6568 EVALUATE(ESXTR) { 6569 UNIMPLEMENTED(); 6570 USE(instr); 6571 return 0; 6572 } 6573 6574 EVALUATE(CDGTRA) { 6575 UNIMPLEMENTED(); 6576 USE(instr); 6577 return 0; 6578 } 6579 6580 EVALUATE(CDUTR) { 6581 UNIMPLEMENTED(); 6582 USE(instr); 6583 return 0; 6584 } 6585 6586 EVALUATE(CDSTR) { 6587 UNIMPLEMENTED(); 6588 USE(instr); 6589 return 0; 6590 } 6591 6592 EVALUATE(CEDTR) { 6593 UNIMPLEMENTED(); 6594 USE(instr); 6595 return 0; 6596 } 6597 6598 EVALUATE(QADTR) { 6599 UNIMPLEMENTED(); 6600 USE(instr); 6601 return 0; 6602 } 6603 6604 EVALUATE(IEDTR) { 6605 UNIMPLEMENTED(); 6606 USE(instr); 6607 return 0; 6608 } 6609 6610 EVALUATE(RRDTR) { 6611 UNIMPLEMENTED(); 6612 USE(instr); 6613 return 0; 6614 } 6615 6616 EVALUATE(CXGTRA) { 6617 UNIMPLEMENTED(); 6618 USE(instr); 6619 return 0; 6620 } 6621 6622 EVALUATE(CXUTR) { 6623 UNIMPLEMENTED(); 6624 USE(instr); 6625 return 0; 6626 } 6627 6628 EVALUATE(CXSTR) { 6629 UNIMPLEMENTED(); 6630 USE(instr); 6631 return 0; 6632 } 6633 6634 EVALUATE(CEXTR) { 6635 UNIMPLEMENTED(); 6636 USE(instr); 6637 return 0; 6638 } 6639 6640 EVALUATE(QAXTR) { 6641 UNIMPLEMENTED(); 6642 USE(instr); 6643 return 0; 6644 } 6645 6646 EVALUATE(IEXTR) { 6647 UNIMPLEMENTED(); 6648 USE(instr); 6649 return 0; 6650 } 6651 6652 EVALUATE(RRXTR) { 6653 UNIMPLEMENTED(); 6654 USE(instr); 6655 return 0; 6656 } 6657 6658 EVALUATE(LPGR) { 6659 DCHECK_OPCODE(LPGR); 6660 // Load Positive (32) 6661 DECODE_RRE_INSTRUCTION(r1, r2); 6662 int64_t r2_val = get_register(r2); 6663 r2_val = (r2_val < 0) ? -r2_val : r2_val; // If negative, then negate it. 6664 set_register(r1, r2_val); 6665 SetS390ConditionCode<int64_t>(r2_val, 0); 6666 if (r2_val == (static_cast<int64_t>(1) << 63)) { 6667 SetS390OverflowCode(true); 6668 } 6669 return length; 6670 } 6671 6672 EVALUATE(LNGR) { 6673 DCHECK_OPCODE(LNGR); 6674 // Load Negative (64) 6675 DECODE_RRE_INSTRUCTION(r1, r2); 6676 int64_t r2_val = get_register(r2); 6677 r2_val = (r2_val >= 0) ? -r2_val : r2_val; // If pos, then negate it. 6678 set_register(r1, r2_val); 6679 condition_reg_ = (r2_val == 0) ? CC_EQ : CC_LT; // CC0 - result is zero 6680 // CC1 - result is negative 6681 return length; 6682 } 6683 6684 EVALUATE(LTGR) { 6685 DCHECK_OPCODE(LTGR); 6686 // Load Register (64) 6687 DECODE_RRE_INSTRUCTION(r1, r2); 6688 int64_t r2_val = get_register(r2); 6689 SetS390ConditionCode<int64_t>(r2_val, 0); 6690 set_register(r1, get_register(r2)); 6691 return length; 6692 } 6693 6694 EVALUATE(LCGR) { 6695 DCHECK_OPCODE(LCGR); 6696 DECODE_RRE_INSTRUCTION(r1, r2); 6697 int64_t r2_val = get_register(r2); 6698 int64_t result = 0; 6699 bool isOF = false; 6700 #ifdef V8_TARGET_ARCH_S390X 6701 isOF = __builtin_ssubl_overflow(0L, r2_val, &result); 6702 #else 6703 isOF = __builtin_ssubll_overflow(0L, r2_val, &result); 6704 #endif 6705 set_register(r1, result); 6706 SetS390ConditionCode<int64_t>(result, 0); 6707 if (isOF) { 6708 SetS390OverflowCode(true); 6709 } 6710 return length; 6711 } 6712 6713 EVALUATE(SGR) { 6714 DCHECK_OPCODE(SGR); 6715 DECODE_RRE_INSTRUCTION(r1, r2); 6716 int64_t r1_val = get_register(r1); 6717 int64_t r2_val = get_register(r2); 6718 bool isOF = false; 6719 isOF = CheckOverflowForIntSub(r1_val, r2_val, int64_t); 6720 r1_val -= r2_val; 6721 SetS390ConditionCode<int64_t>(r1_val, 0); 6722 SetS390OverflowCode(isOF); 6723 set_register(r1, r1_val); 6724 return length; 6725 } 6726 6727 EVALUATE(ALGR) { 6728 UNIMPLEMENTED(); 6729 USE(instr); 6730 return 0; 6731 } 6732 6733 EVALUATE(SLGR) { 6734 UNIMPLEMENTED(); 6735 USE(instr); 6736 return 0; 6737 } 6738 6739 EVALUATE(MSGR) { 6740 DCHECK_OPCODE(MSGR); 6741 DECODE_RRE_INSTRUCTION(r1, r2); 6742 int64_t r1_val = get_register(r1); 6743 int64_t r2_val = get_register(r2); 6744 set_register(r1, r1_val * r2_val); 6745 return length; 6746 } 6747 6748 EVALUATE(MSGRKC) { 6749 DCHECK_OPCODE(MSGRKC); 6750 DECODE_RRF_A_INSTRUCTION(r1, r2, r3); 6751 int64_t r2_val = get_register(r2); 6752 int64_t r3_val = get_register(r3); 6753 volatile int64_t result64 = r2_val * r3_val; 6754 bool isOF = ((r2_val == -1 && result64 == (static_cast<int64_t>(1L) << 63)) || 6755 (r2_val != 0 && result64 / r2_val != r3_val)); 6756 SetS390ConditionCode<int64_t>(result64, 0); 6757 SetS390OverflowCode(isOF); 6758 set_register(r1, result64); 6759 return length; 6760 } 6761 6762 EVALUATE(DSGR) { 6763 DCHECK_OPCODE(DSGR); 6764 DECODE_RRE_INSTRUCTION(r1, r2); 6765 6766 DCHECK_EQ(r1 % 2, 0); 6767 6768 int64_t dividend = get_register(r1 + 1); 6769 int64_t divisor = get_register(r2); 6770 set_register(r1, dividend % divisor); 6771 set_register(r1 + 1, dividend / divisor); 6772 return length; 6773 } 6774 6775 EVALUATE(LRVGR) { 6776 DCHECK_OPCODE(LRVGR); 6777 DECODE_RRE_INSTRUCTION(r1, r2); 6778 int64_t r2_val = get_register(r2); 6779 int64_t r1_val = ByteReverse(r2_val); 6780 6781 set_register(r1, r1_val); 6782 return length; 6783 } 6784 6785 EVALUATE(LPGFR) { 6786 DCHECK_OPCODE(LPGFR); 6787 // Load Positive (32) 6788 DECODE_RRE_INSTRUCTION(r1, r2); 6789 int32_t r2_val = get_low_register<int32_t>(r2); 6790 // If negative, then negate it. 6791 int64_t r1_val = static_cast<int64_t>((r2_val < 0) ? -r2_val : r2_val); 6792 set_register(r1, r1_val); 6793 SetS390ConditionCode<int64_t>(r1_val, 0); 6794 return length; 6795 } 6796 6797 EVALUATE(LNGFR) { 6798 UNIMPLEMENTED(); 6799 USE(instr); 6800 return 0; 6801 } 6802 6803 EVALUATE(LTGFR) { 6804 DCHECK_OPCODE(LTGFR); 6805 DECODE_RRE_INSTRUCTION(r1, r2); 6806 // Load and Test Register (64 <- 32) (Sign Extends 32-bit val) 6807 // Load Register (64 <- 32) (Sign Extends 32-bit val) 6808 int32_t r2_val = get_low_register<int32_t>(r2); 6809 int64_t result = static_cast<int64_t>(r2_val); 6810 set_register(r1, result); 6811 SetS390ConditionCode<int64_t>(result, 0); 6812 return length; 6813 } 6814 6815 EVALUATE(LCGFR) { 6816 DCHECK_OPCODE(LCGFR); 6817 DECODE_RRE_INSTRUCTION(r1, r2); 6818 // Load and Test Register (64 <- 32) (Sign Extends 32-bit val) 6819 // Load Register (64 <- 32) (Sign Extends 32-bit val) 6820 int32_t r2_val = get_low_register<int32_t>(r2); 6821 int64_t result = static_cast<int64_t>(r2_val); 6822 set_register(r1, result); 6823 return length; 6824 } 6825 6826 EVALUATE(LLGFR) { 6827 DCHECK_OPCODE(LLGFR); 6828 DECODE_RRE_INSTRUCTION(r1, r2); 6829 int32_t r2_val = get_low_register<int32_t>(r2); 6830 uint64_t r2_finalval = (static_cast<uint64_t>(r2_val) & 0x00000000FFFFFFFF); 6831 set_register(r1, r2_finalval); 6832 return length; 6833 } 6834 6835 EVALUATE(LLGTR) { 6836 UNIMPLEMENTED(); 6837 USE(instr); 6838 return 0; 6839 } 6840 6841 EVALUATE(AGFR) { 6842 DCHECK_OPCODE(AGFR); 6843 DECODE_RRE_INSTRUCTION(r1, r2); 6844 // Add Register (64 <- 32) (Sign Extends 32-bit val) 6845 int64_t r1_val = get_register(r1); 6846 int64_t r2_val = static_cast<int64_t>(get_low_register<int32_t>(r2)); 6847 bool isOF = CheckOverflowForIntAdd(r1_val, r2_val, int64_t); 6848 r1_val += r2_val; 6849 SetS390ConditionCode<int64_t>(r1_val, 0); 6850 SetS390OverflowCode(isOF); 6851 set_register(r1, r1_val); 6852 return length; 6853 } 6854 6855 EVALUATE(SGFR) { 6856 DCHECK_OPCODE(SGFR); 6857 DECODE_RRE_INSTRUCTION(r1, r2); 6858 // Sub Reg (64 <- 32) 6859 int64_t r1_val = get_register(r1); 6860 int64_t r2_val = static_cast<int64_t>(get_low_register<int32_t>(r2)); 6861 bool isOF = false; 6862 isOF = CheckOverflowForIntSub(r1_val, r2_val, int64_t); 6863 r1_val -= r2_val; 6864 SetS390ConditionCode<int64_t>(r1_val, 0); 6865 SetS390OverflowCode(isOF); 6866 set_register(r1, r1_val); 6867 return length; 6868 } 6869 6870 EVALUATE(ALGFR) { 6871 UNIMPLEMENTED(); 6872 USE(instr); 6873 return 0; 6874 } 6875 6876 EVALUATE(SLGFR) { 6877 UNIMPLEMENTED(); 6878 USE(instr); 6879 return 0; 6880 } 6881 6882 EVALUATE(MSGFR) { 6883 DCHECK_OPCODE(MSGFR); 6884 DECODE_RRE_INSTRUCTION(r1, r2); 6885 int64_t r1_val = get_register(r1); 6886 int64_t r2_val = static_cast<int64_t>(get_low_register<int32_t>(r2)); 6887 int64_t product = r1_val * r2_val; 6888 set_register(r1, product); 6889 return length; 6890 } 6891 6892 EVALUATE(DSGFR) { 6893 DCHECK_OPCODE(DSGFR); 6894 DECODE_RRE_INSTRUCTION(r1, r2); 6895 DCHECK_EQ(r1 % 2, 0); 6896 int64_t r1_val = get_register(r1 + 1); 6897 int64_t r2_val = static_cast<int64_t>(get_low_register<int32_t>(r2)); 6898 int64_t quotient = r1_val / r2_val; 6899 int64_t remainder = r1_val % r2_val; 6900 set_register(r1, remainder); 6901 set_register(r1 + 1, quotient); 6902 return length; 6903 } 6904 6905 EVALUATE(KMAC) { 6906 UNIMPLEMENTED(); 6907 USE(instr); 6908 return 0; 6909 } 6910 6911 EVALUATE(LRVR) { 6912 DCHECK_OPCODE(LRVR); 6913 DECODE_RRE_INSTRUCTION(r1, r2); 6914 int32_t r2_val = get_low_register<int32_t>(r2); 6915 int32_t r1_val = ByteReverse(r2_val); 6916 6917 set_low_register(r1, r1_val); 6918 return length; 6919 } 6920 6921 EVALUATE(CGR) { 6922 DCHECK_OPCODE(CGR); 6923 DECODE_RRE_INSTRUCTION(r1, r2); 6924 // Compare (64) 6925 int64_t r1_val = get_register(r1); 6926 int64_t r2_val = get_register(r2); 6927 SetS390ConditionCode<int64_t>(r1_val, r2_val); 6928 return length; 6929 } 6930 6931 EVALUATE(CLGR) { 6932 DCHECK_OPCODE(CLGR); 6933 DECODE_RRE_INSTRUCTION(r1, r2); 6934 // Compare Logical (64) 6935 uint64_t r1_val = static_cast<uint64_t>(get_register(r1)); 6936 uint64_t r2_val = static_cast<uint64_t>(get_register(r2)); 6937 SetS390ConditionCode<uint64_t>(r1_val, r2_val); 6938 return length; 6939 } 6940 6941 EVALUATE(KMF) { 6942 UNIMPLEMENTED(); 6943 USE(instr); 6944 return 0; 6945 } 6946 6947 EVALUATE(KMO) { 6948 UNIMPLEMENTED(); 6949 USE(instr); 6950 return 0; 6951 } 6952 6953 EVALUATE(PCC) { 6954 UNIMPLEMENTED(); 6955 USE(instr); 6956 return 0; 6957 } 6958 6959 EVALUATE(KMCTR) { 6960 UNIMPLEMENTED(); 6961 USE(instr); 6962 return 0; 6963 } 6964 6965 EVALUATE(KM) { 6966 UNIMPLEMENTED(); 6967 USE(instr); 6968 return 0; 6969 } 6970 6971 EVALUATE(KMC) { 6972 UNIMPLEMENTED(); 6973 USE(instr); 6974 return 0; 6975 } 6976 6977 EVALUATE(CGFR) { 6978 DCHECK_OPCODE(CGFR); 6979 DECODE_RRE_INSTRUCTION(r1, r2); 6980 // Compare (64) 6981 int64_t r1_val = get_register(r1); 6982 int64_t r2_val = static_cast<int64_t>(get_low_register<int32_t>(r2)); 6983 SetS390ConditionCode<int64_t>(r1_val, r2_val); 6984 return length; 6985 } 6986 6987 EVALUATE(KIMD) { 6988 UNIMPLEMENTED(); 6989 USE(instr); 6990 return 0; 6991 } 6992 6993 EVALUATE(KLMD) { 6994 UNIMPLEMENTED(); 6995 USE(instr); 6996 return 0; 6997 } 6998 6999 EVALUATE(CFDTR) { 7000 UNIMPLEMENTED(); 7001 USE(instr); 7002 return 0; 7003 } 7004 7005 EVALUATE(CLGDTR) { 7006 UNIMPLEMENTED(); 7007 USE(instr); 7008 return 0; 7009 } 7010 7011 EVALUATE(CLFDTR) { 7012 UNIMPLEMENTED(); 7013 USE(instr); 7014 return 0; 7015 } 7016 7017 EVALUATE(BCTGR) { 7018 UNIMPLEMENTED(); 7019 USE(instr); 7020 return 0; 7021 } 7022 7023 EVALUATE(CFXTR) { 7024 UNIMPLEMENTED(); 7025 USE(instr); 7026 return 0; 7027 } 7028 7029 EVALUATE(CLFXTR) { 7030 UNIMPLEMENTED(); 7031 USE(instr); 7032 return 0; 7033 } 7034 7035 EVALUATE(CDFTR) { 7036 UNIMPLEMENTED(); 7037 USE(instr); 7038 return 0; 7039 } 7040 7041 EVALUATE(CDLGTR) { 7042 UNIMPLEMENTED(); 7043 USE(instr); 7044 return 0; 7045 } 7046 7047 EVALUATE(CDLFTR) { 7048 UNIMPLEMENTED(); 7049 USE(instr); 7050 return 0; 7051 } 7052 7053 EVALUATE(CXFTR) { 7054 UNIMPLEMENTED(); 7055 USE(instr); 7056 return 0; 7057 } 7058 7059 EVALUATE(CXLGTR) { 7060 UNIMPLEMENTED(); 7061 USE(instr); 7062 return 0; 7063 } 7064 7065 EVALUATE(CXLFTR) { 7066 UNIMPLEMENTED(); 7067 USE(instr); 7068 return 0; 7069 } 7070 7071 EVALUATE(CGRT) { 7072 UNIMPLEMENTED(); 7073 USE(instr); 7074 return 0; 7075 } 7076 7077 EVALUATE(NGR) { 7078 DCHECK_OPCODE(NGR); 7079 DECODE_RRE_INSTRUCTION(r1, r2); 7080 int64_t r1_val = get_register(r1); 7081 int64_t r2_val = get_register(r2); 7082 r1_val &= r2_val; 7083 SetS390BitWiseConditionCode<uint64_t>(r1_val); 7084 set_register(r1, r1_val); 7085 return length; 7086 } 7087 7088 EVALUATE(OGR) { 7089 DCHECK_OPCODE(OGR); 7090 DECODE_RRE_INSTRUCTION(r1, r2); 7091 int64_t r1_val = get_register(r1); 7092 int64_t r2_val = get_register(r2); 7093 r1_val |= r2_val; 7094 SetS390BitWiseConditionCode<uint64_t>(r1_val); 7095 set_register(r1, r1_val); 7096 return length; 7097 } 7098 7099 EVALUATE(XGR) { 7100 DCHECK_OPCODE(XGR); 7101 DECODE_RRE_INSTRUCTION(r1, r2); 7102 int64_t r1_val = get_register(r1); 7103 int64_t r2_val = get_register(r2); 7104 r1_val ^= r2_val; 7105 SetS390BitWiseConditionCode<uint64_t>(r1_val); 7106 set_register(r1, r1_val); 7107 return length; 7108 } 7109 7110 EVALUATE(FLOGR) { 7111 DCHECK_OPCODE(FLOGR); 7112 DECODE_RRE_INSTRUCTION(r1, r2); 7113 7114 DCHECK_EQ(r1 % 2, 0); 7115 7116 int64_t r2_val = get_register(r2); 7117 7118 int i = 0; 7119 for (; i < 64; i++) { 7120 if (r2_val < 0) break; 7121 r2_val <<= 1; 7122 } 7123 7124 r2_val = get_register(r2); 7125 7126 int64_t mask = ~(1 << (63 - i)); 7127 set_register(r1, i); 7128 set_register(r1 + 1, r2_val & mask); 7129 return length; 7130 } 7131 7132 EVALUATE(LLGCR) { 7133 DCHECK_OPCODE(LLGCR); 7134 DECODE_RRE_INSTRUCTION(r1, r2); 7135 uint64_t r2_val = get_low_register<uint64_t>(r2); 7136 r2_val <<= 56; 7137 r2_val >>= 56; 7138 set_register(r1, r2_val); 7139 return length; 7140 } 7141 7142 EVALUATE(LLGHR) { 7143 DCHECK_OPCODE(LLGHR); 7144 DECODE_RRE_INSTRUCTION(r1, r2); 7145 uint64_t r2_val = get_low_register<uint64_t>(r2); 7146 r2_val <<= 48; 7147 r2_val >>= 48; 7148 set_register(r1, r2_val); 7149 return length; 7150 } 7151 7152 EVALUATE(MLGR) { 7153 UNIMPLEMENTED(); 7154 USE(instr); 7155 return 0; 7156 } 7157 7158 EVALUATE(DLGR) { 7159 DCHECK_OPCODE(DLGR); 7160 #ifdef V8_TARGET_ARCH_S390X 7161 DECODE_RRE_INSTRUCTION(r1, r2); 7162 uint64_t r1_val = get_register(r1); 7163 uint64_t r2_val = get_register(r2); 7164 DCHECK_EQ(r1 % 2, 0); 7165 unsigned __int128 dividend = static_cast<unsigned __int128>(r1_val) << 64; 7166 dividend += get_register(r1 + 1); 7167 uint64_t remainder = dividend % r2_val; 7168 uint64_t quotient = dividend / r2_val; 7169 set_register(r1, remainder); 7170 set_register(r1 + 1, quotient); 7171 return length; 7172 #else 7173 // 32 bit arch doesn't support __int128 type 7174 USE(instr); 7175 UNREACHABLE(); 7176 #endif 7177 } 7178 7179 EVALUATE(ALCGR) { 7180 UNIMPLEMENTED(); 7181 USE(instr); 7182 return 0; 7183 } 7184 7185 EVALUATE(SLBGR) { 7186 UNIMPLEMENTED(); 7187 USE(instr); 7188 return 0; 7189 } 7190 7191 EVALUATE(EPSW) { 7192 UNIMPLEMENTED(); 7193 USE(instr); 7194 return 0; 7195 } 7196 7197 EVALUATE(TRTT) { 7198 UNIMPLEMENTED(); 7199 USE(instr); 7200 return 0; 7201 } 7202 7203 EVALUATE(TRTO) { 7204 UNIMPLEMENTED(); 7205 USE(instr); 7206 return 0; 7207 } 7208 7209 EVALUATE(TROT) { 7210 UNIMPLEMENTED(); 7211 USE(instr); 7212 return 0; 7213 } 7214 7215 EVALUATE(TROO) { 7216 UNIMPLEMENTED(); 7217 USE(instr); 7218 return 0; 7219 } 7220 7221 EVALUATE(LLCR) { 7222 DCHECK_OPCODE(LLCR); 7223 DECODE_RRE_INSTRUCTION(r1, r2); 7224 uint32_t r2_val = get_low_register<uint32_t>(r2); 7225 r2_val <<= 24; 7226 r2_val >>= 24; 7227 set_low_register(r1, r2_val); 7228 return length; 7229 } 7230 7231 EVALUATE(LLHR) { 7232 DCHECK_OPCODE(LLHR); 7233 DECODE_RRE_INSTRUCTION(r1, r2); 7234 uint32_t r2_val = get_low_register<uint32_t>(r2); 7235 r2_val <<= 16; 7236 r2_val >>= 16; 7237 set_low_register(r1, r2_val); 7238 return length; 7239 } 7240 7241 EVALUATE(MLR) { 7242 DCHECK_OPCODE(MLR); 7243 DECODE_RRE_INSTRUCTION(r1, r2); 7244 DCHECK_EQ(r1 % 2, 0); 7245 7246 uint32_t r1_val = get_low_register<uint32_t>(r1 + 1); 7247 uint32_t r2_val = get_low_register<uint32_t>(r2); 7248 uint64_t product = 7249 static_cast<uint64_t>(r1_val) * static_cast<uint64_t>(r2_val); 7250 int32_t high_bits = product >> 32; 7251 int32_t low_bits = product & 0x00000000FFFFFFFF; 7252 set_low_register(r1, high_bits); 7253 set_low_register(r1 + 1, low_bits); 7254 return length; 7255 } 7256 7257 EVALUATE(DLR) { 7258 DCHECK_OPCODE(DLR); 7259 DECODE_RRE_INSTRUCTION(r1, r2); 7260 uint32_t r1_val = get_low_register<uint32_t>(r1); 7261 uint32_t r2_val = get_low_register<uint32_t>(r2); 7262 DCHECK_EQ(r1 % 2, 0); 7263 uint64_t dividend = static_cast<uint64_t>(r1_val) << 32; 7264 dividend += get_low_register<uint32_t>(r1 + 1); 7265 uint32_t remainder = dividend % r2_val; 7266 uint32_t quotient = dividend / r2_val; 7267 r1_val = remainder; 7268 set_low_register(r1, remainder); 7269 set_low_register(r1 + 1, quotient); 7270 return length; 7271 } 7272 7273 EVALUATE(ALCR) { 7274 DCHECK_OPCODE(ALCR); 7275 DECODE_RRE_INSTRUCTION(r1, r2); 7276 uint32_t r1_val = get_low_register<uint32_t>(r1); 7277 uint32_t r2_val = get_low_register<uint32_t>(r2); 7278 uint32_t alu_out = 0; 7279 bool isOF = false; 7280 7281 alu_out = r1_val + r2_val; 7282 bool isOF_original = CheckOverflowForUIntAdd(r1_val, r2_val); 7283 if (TestConditionCode((Condition)2) || TestConditionCode((Condition)3)) { 7284 alu_out = alu_out + 1; 7285 isOF = isOF_original || CheckOverflowForUIntAdd(alu_out, 1); 7286 } else { 7287 isOF = isOF_original; 7288 } 7289 set_low_register(r1, alu_out); 7290 SetS390ConditionCodeCarry<uint32_t>(alu_out, isOF); 7291 return length; 7292 } 7293 7294 EVALUATE(SLBR) { 7295 DCHECK_OPCODE(SLBR); 7296 DECODE_RRE_INSTRUCTION(r1, r2); 7297 uint32_t r1_val = get_low_register<uint32_t>(r1); 7298 uint32_t r2_val = get_low_register<uint32_t>(r2); 7299 uint32_t alu_out = 0; 7300 bool isOF = false; 7301 7302 alu_out = r1_val - r2_val; 7303 bool isOF_original = CheckOverflowForUIntSub(r1_val, r2_val); 7304 if (TestConditionCode((Condition)2) || TestConditionCode((Condition)3)) { 7305 alu_out = alu_out - 1; 7306 isOF = isOF_original || CheckOverflowForUIntSub(alu_out, 1); 7307 } else { 7308 isOF = isOF_original; 7309 } 7310 set_low_register(r1, alu_out); 7311 SetS390ConditionCodeCarry<uint32_t>(alu_out, isOF); 7312 return length; 7313 } 7314 7315 EVALUATE(CU14) { 7316 UNIMPLEMENTED(); 7317 USE(instr); 7318 return 0; 7319 } 7320 7321 EVALUATE(CU24) { 7322 UNIMPLEMENTED(); 7323 USE(instr); 7324 return 0; 7325 } 7326 7327 EVALUATE(CU41) { 7328 UNIMPLEMENTED(); 7329 USE(instr); 7330 return 0; 7331 } 7332 7333 EVALUATE(CU42) { 7334 UNIMPLEMENTED(); 7335 USE(instr); 7336 return 0; 7337 } 7338 7339 EVALUATE(TRTRE) { 7340 UNIMPLEMENTED(); 7341 USE(instr); 7342 return 0; 7343 } 7344 7345 EVALUATE(SRSTU) { 7346 UNIMPLEMENTED(); 7347 USE(instr); 7348 return 0; 7349 } 7350 7351 EVALUATE(TRTE) { 7352 UNIMPLEMENTED(); 7353 USE(instr); 7354 return 0; 7355 } 7356 7357 EVALUATE(AHHHR) { 7358 UNIMPLEMENTED(); 7359 USE(instr); 7360 return 0; 7361 } 7362 7363 EVALUATE(SHHHR) { 7364 UNIMPLEMENTED(); 7365 USE(instr); 7366 return 0; 7367 } 7368 7369 EVALUATE(ALHHHR) { 7370 UNIMPLEMENTED(); 7371 USE(instr); 7372 return 0; 7373 } 7374 7375 EVALUATE(SLHHHR) { 7376 UNIMPLEMENTED(); 7377 USE(instr); 7378 return 0; 7379 } 7380 7381 EVALUATE(CHHR) { 7382 UNIMPLEMENTED(); 7383 USE(instr); 7384 return 0; 7385 } 7386 7387 EVALUATE(AHHLR) { 7388 UNIMPLEMENTED(); 7389 USE(instr); 7390 return 0; 7391 } 7392 7393 EVALUATE(SHHLR) { 7394 UNIMPLEMENTED(); 7395 USE(instr); 7396 return 0; 7397 } 7398 7399 EVALUATE(ALHHLR) { 7400 UNIMPLEMENTED(); 7401 USE(instr); 7402 return 0; 7403 } 7404 7405 EVALUATE(SLHHLR) { 7406 UNIMPLEMENTED(); 7407 USE(instr); 7408 return 0; 7409 } 7410 7411 EVALUATE(CHLR) { 7412 UNIMPLEMENTED(); 7413 USE(instr); 7414 return 0; 7415 } 7416 7417 EVALUATE(POPCNT_Z) { 7418 DCHECK_OPCODE(POPCNT_Z); 7419 DECODE_RRE_INSTRUCTION(r1, r2); 7420 int64_t r2_val = get_register(r2); 7421 int64_t r1_val = 0; 7422 7423 uint8_t* r2_val_ptr = reinterpret_cast<uint8_t*>(&r2_val); 7424 uint8_t* r1_val_ptr = reinterpret_cast<uint8_t*>(&r1_val); 7425 for (int i = 0; i < 8; i++) { 7426 uint32_t x = static_cast<uint32_t>(r2_val_ptr[i]); 7427 #if defined(__GNUC__) 7428 r1_val_ptr[i] = __builtin_popcount(x); 7429 #else 7430 #error unsupport __builtin_popcount 7431 #endif 7432 } 7433 set_register(r1, static_cast<uint64_t>(r1_val)); 7434 return length; 7435 } 7436 7437 EVALUATE(LOCGR) { 7438 DCHECK_OPCODE(LOCGR); 7439 DECODE_RRF_C_INSTRUCTION(r1, r2, m3); 7440 if (TestConditionCode(m3)) { 7441 set_register(r1, get_register(r2)); 7442 } 7443 return length; 7444 } 7445 7446 EVALUATE(NGRK) { 7447 DCHECK_OPCODE(NGRK); 7448 DECODE_RRF_A_INSTRUCTION(r1, r2, r3); 7449 // 64-bit Non-clobbering arithmetics / bitwise ops. 7450 int64_t r2_val = get_register(r2); 7451 int64_t r3_val = get_register(r3); 7452 uint64_t bitwise_result = 0; 7453 bitwise_result = r2_val & r3_val; 7454 SetS390BitWiseConditionCode<uint64_t>(bitwise_result); 7455 set_register(r1, bitwise_result); 7456 return length; 7457 } 7458 7459 EVALUATE(OGRK) { 7460 DCHECK_OPCODE(OGRK); 7461 DECODE_RRF_A_INSTRUCTION(r1, r2, r3); 7462 // 64-bit Non-clobbering arithmetics / bitwise ops. 7463 int64_t r2_val = get_register(r2); 7464 int64_t r3_val = get_register(r3); 7465 uint64_t bitwise_result = 0; 7466 bitwise_result = r2_val | r3_val; 7467 SetS390BitWiseConditionCode<uint64_t>(bitwise_result); 7468 set_register(r1, bitwise_result); 7469 return length; 7470 } 7471 7472 EVALUATE(XGRK) { 7473 DCHECK_OPCODE(XGRK); 7474 DECODE_RRF_A_INSTRUCTION(r1, r2, r3); 7475 // 64-bit Non-clobbering arithmetics / bitwise ops. 7476 int64_t r2_val = get_register(r2); 7477 int64_t r3_val = get_register(r3); 7478 uint64_t bitwise_result = 0; 7479 bitwise_result = r2_val ^ r3_val; 7480 SetS390BitWiseConditionCode<uint64_t>(bitwise_result); 7481 set_register(r1, bitwise_result); 7482 return length; 7483 } 7484 7485 EVALUATE(AGRK) { 7486 DCHECK_OPCODE(AGRK); 7487 DECODE_RRF_A_INSTRUCTION(r1, r2, r3); 7488 // 64-bit Non-clobbering arithmetics / bitwise ops. 7489 int64_t r2_val = get_register(r2); 7490 int64_t r3_val = get_register(r3); 7491 bool isOF = CheckOverflowForIntAdd(r2_val, r3_val, int64_t); 7492 SetS390ConditionCode<int64_t>(r2_val + r3_val, 0); 7493 SetS390OverflowCode(isOF); 7494 set_register(r1, r2_val + r3_val); 7495 return length; 7496 } 7497 7498 EVALUATE(SGRK) { 7499 DCHECK_OPCODE(SGRK); 7500 DECODE_RRF_A_INSTRUCTION(r1, r2, r3); 7501 // 64-bit Non-clobbering arithmetics / bitwise ops. 7502 int64_t r2_val = get_register(r2); 7503 int64_t r3_val = get_register(r3); 7504 bool isOF = CheckOverflowForIntSub(r2_val, r3_val, int64_t); 7505 SetS390ConditionCode<int64_t>(r2_val - r3_val, 0); 7506 SetS390OverflowCode(isOF); 7507 set_register(r1, r2_val - r3_val); 7508 return length; 7509 } 7510 7511 EVALUATE(ALGRK) { 7512 DCHECK_OPCODE(ALGRK); 7513 DECODE_RRF_A_INSTRUCTION(r1, r2, r3); 7514 // 64-bit Non-clobbering unsigned arithmetics 7515 uint64_t r2_val = get_register(r2); 7516 uint64_t r3_val = get_register(r3); 7517 bool isOF = CheckOverflowForUIntAdd(r2_val, r3_val); 7518 SetS390ConditionCode<uint64_t>(r2_val + r3_val, 0); 7519 SetS390OverflowCode(isOF); 7520 set_register(r1, r2_val + r3_val); 7521 return length; 7522 } 7523 7524 EVALUATE(SLGRK) { 7525 DCHECK_OPCODE(SLGRK); 7526 DECODE_RRF_A_INSTRUCTION(r1, r2, r3); 7527 // 64-bit Non-clobbering unsigned arithmetics 7528 uint64_t r2_val = get_register(r2); 7529 uint64_t r3_val = get_register(r3); 7530 bool isOF = CheckOverflowForUIntSub(r2_val, r3_val); 7531 SetS390ConditionCode<uint64_t>(r2_val - r3_val, 0); 7532 SetS390OverflowCode(isOF); 7533 set_register(r1, r2_val - r3_val); 7534 return length; 7535 } 7536 7537 EVALUATE(LOCR) { 7538 DCHECK_OPCODE(LOCR); 7539 DECODE_RRF_C_INSTRUCTION(r1, r2, m3); 7540 if (TestConditionCode(m3)) { 7541 set_low_register(r1, get_low_register<int32_t>(r2)); 7542 } 7543 return length; 7544 } 7545 7546 EVALUATE(NRK) { 7547 DCHECK_OPCODE(NRK); 7548 DECODE_RRF_A_INSTRUCTION(r1, r2, r3); 7549 // 32-bit Non-clobbering arithmetics / bitwise ops 7550 int32_t r2_val = get_low_register<int32_t>(r2); 7551 int32_t r3_val = get_low_register<int32_t>(r3); 7552 // Assume bitwise operation here 7553 uint32_t bitwise_result = 0; 7554 bitwise_result = r2_val & r3_val; 7555 SetS390BitWiseConditionCode<uint32_t>(bitwise_result); 7556 set_low_register(r1, bitwise_result); 7557 return length; 7558 } 7559 7560 EVALUATE(ORK) { 7561 DCHECK_OPCODE(ORK); 7562 DECODE_RRF_A_INSTRUCTION(r1, r2, r3); 7563 // 32-bit Non-clobbering arithmetics / bitwise ops 7564 int32_t r2_val = get_low_register<int32_t>(r2); 7565 int32_t r3_val = get_low_register<int32_t>(r3); 7566 // Assume bitwise operation here 7567 uint32_t bitwise_result = 0; 7568 bitwise_result = r2_val | r3_val; 7569 SetS390BitWiseConditionCode<uint32_t>(bitwise_result); 7570 set_low_register(r1, bitwise_result); 7571 return length; 7572 } 7573 7574 EVALUATE(XRK) { 7575 DCHECK_OPCODE(XRK); 7576 DECODE_RRF_A_INSTRUCTION(r1, r2, r3); 7577 // 32-bit Non-clobbering arithmetics / bitwise ops 7578 int32_t r2_val = get_low_register<int32_t>(r2); 7579 int32_t r3_val = get_low_register<int32_t>(r3); 7580 // Assume bitwise operation here 7581 uint32_t bitwise_result = 0; 7582 bitwise_result = r2_val ^ r3_val; 7583 SetS390BitWiseConditionCode<uint32_t>(bitwise_result); 7584 set_low_register(r1, bitwise_result); 7585 return length; 7586 } 7587 7588 EVALUATE(ARK) { 7589 DCHECK_OPCODE(ARK); 7590 DECODE_RRF_A_INSTRUCTION(r1, r2, r3); 7591 // 32-bit Non-clobbering arithmetics / bitwise ops 7592 int32_t r2_val = get_low_register<int32_t>(r2); 7593 int32_t r3_val = get_low_register<int32_t>(r3); 7594 bool isOF = CheckOverflowForIntAdd(r2_val, r3_val, int32_t); 7595 SetS390ConditionCode<int32_t>(r2_val + r3_val, 0); 7596 SetS390OverflowCode(isOF); 7597 set_low_register(r1, r2_val + r3_val); 7598 return length; 7599 } 7600 7601 EVALUATE(SRK) { 7602 DCHECK_OPCODE(SRK); 7603 DECODE_RRF_A_INSTRUCTION(r1, r2, r3); 7604 // 32-bit Non-clobbering arithmetics / bitwise ops 7605 int32_t r2_val = get_low_register<int32_t>(r2); 7606 int32_t r3_val = get_low_register<int32_t>(r3); 7607 bool isOF = CheckOverflowForIntSub(r2_val, r3_val, int32_t); 7608 SetS390ConditionCode<int32_t>(r2_val - r3_val, 0); 7609 SetS390OverflowCode(isOF); 7610 set_low_register(r1, r2_val - r3_val); 7611 return length; 7612 } 7613 7614 EVALUATE(ALRK) { 7615 DCHECK_OPCODE(ALRK); 7616 DECODE_RRF_A_INSTRUCTION(r1, r2, r3); 7617 // 32-bit Non-clobbering unsigned arithmetics 7618 uint32_t r2_val = get_low_register<uint32_t>(r2); 7619 uint32_t r3_val = get_low_register<uint32_t>(r3); 7620 bool isOF = CheckOverflowForUIntAdd(r2_val, r3_val); 7621 SetS390ConditionCode<uint32_t>(r2_val + r3_val, 0); 7622 SetS390OverflowCode(isOF); 7623 set_low_register(r1, r2_val + r3_val); 7624 return length; 7625 } 7626 7627 EVALUATE(SLRK) { 7628 DCHECK_OPCODE(SLRK); 7629 DECODE_RRF_A_INSTRUCTION(r1, r2, r3); 7630 // 32-bit Non-clobbering unsigned arithmetics 7631 uint32_t r2_val = get_low_register<uint32_t>(r2); 7632 uint32_t r3_val = get_low_register<uint32_t>(r3); 7633 bool isOF = CheckOverflowForUIntSub(r2_val, r3_val); 7634 SetS390ConditionCode<uint32_t>(r2_val - r3_val, 0); 7635 SetS390OverflowCode(isOF); 7636 set_low_register(r1, r2_val - r3_val); 7637 return length; 7638 } 7639 7640 EVALUATE(LTG) { 7641 DCHECK_OPCODE(LTG); 7642 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 7643 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 7644 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 7645 intptr_t addr = x2_val + b2_val + d2; 7646 int64_t value = ReadDW(addr); 7647 set_register(r1, value); 7648 SetS390ConditionCode<int64_t>(value, 0); 7649 return length; 7650 } 7651 7652 EVALUATE(CVBY) { 7653 UNIMPLEMENTED(); 7654 USE(instr); 7655 return 0; 7656 } 7657 7658 EVALUATE(AG) { 7659 DCHECK_OPCODE(AG); 7660 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 7661 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 7662 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 7663 int64_t alu_out = get_register(r1); 7664 int64_t mem_val = ReadDW(b2_val + x2_val + d2); 7665 bool isOF = CheckOverflowForIntAdd(alu_out, mem_val, int64_t); 7666 alu_out += mem_val; 7667 SetS390ConditionCode<int64_t>(alu_out, 0); 7668 SetS390OverflowCode(isOF); 7669 set_register(r1, alu_out); 7670 return length; 7671 } 7672 7673 EVALUATE(SG) { 7674 DCHECK_OPCODE(SG); 7675 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 7676 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 7677 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 7678 int64_t alu_out = get_register(r1); 7679 int64_t mem_val = ReadDW(b2_val + x2_val + d2); 7680 bool isOF = CheckOverflowForIntSub(alu_out, mem_val, int64_t); 7681 alu_out -= mem_val; 7682 SetS390ConditionCode<int32_t>(alu_out, 0); 7683 SetS390OverflowCode(isOF); 7684 set_register(r1, alu_out); 7685 return length; 7686 } 7687 7688 EVALUATE(ALG) { 7689 DCHECK_OPCODE(ALG); 7690 #ifndef V8_TARGET_ARCH_S390X 7691 DCHECK(false); 7692 #endif 7693 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 7694 uint64_t r1_val = get_register(r1); 7695 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 7696 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 7697 intptr_t d2_val = d2; 7698 uint64_t alu_out = r1_val; 7699 uint64_t mem_val = static_cast<uint64_t>(ReadDW(b2_val + d2_val + x2_val)); 7700 alu_out += mem_val; 7701 SetS390ConditionCode<uint64_t>(alu_out, 0); 7702 set_register(r1, alu_out); 7703 return length; 7704 } 7705 7706 EVALUATE(SLG) { 7707 DCHECK_OPCODE(SLG); 7708 #ifndef V8_TARGET_ARCH_S390X 7709 DCHECK(false); 7710 #endif 7711 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 7712 uint64_t r1_val = get_register(r1); 7713 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 7714 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 7715 intptr_t d2_val = d2; 7716 uint64_t alu_out = r1_val; 7717 uint64_t mem_val = static_cast<uint64_t>(ReadDW(b2_val + d2_val + x2_val)); 7718 alu_out -= mem_val; 7719 SetS390ConditionCode<uint64_t>(alu_out, 0); 7720 set_register(r1, alu_out); 7721 return length; 7722 } 7723 7724 EVALUATE(MSG) { 7725 DCHECK_OPCODE(MSG); 7726 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 7727 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 7728 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 7729 intptr_t d2_val = d2; 7730 int64_t mem_val = ReadDW(b2_val + d2_val + x2_val); 7731 int64_t r1_val = get_register(r1); 7732 set_register(r1, mem_val * r1_val); 7733 return length; 7734 } 7735 7736 EVALUATE(DSG) { 7737 DCHECK_OPCODE(DSG); 7738 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 7739 DCHECK_EQ(r1 % 2, 0); 7740 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 7741 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 7742 intptr_t d2_val = d2; 7743 int64_t mem_val = ReadDW(b2_val + d2_val + x2_val); 7744 int64_t r1_val = get_register(r1 + 1); 7745 int64_t quotient = r1_val / mem_val; 7746 int64_t remainder = r1_val % mem_val; 7747 set_register(r1, remainder); 7748 set_register(r1 + 1, quotient); 7749 return length; 7750 } 7751 7752 EVALUATE(CVBG) { 7753 UNIMPLEMENTED(); 7754 USE(instr); 7755 return 0; 7756 } 7757 7758 EVALUATE(LT) { 7759 DCHECK_OPCODE(LT); 7760 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 7761 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 7762 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 7763 intptr_t addr = x2_val + b2_val + d2; 7764 int32_t value = ReadW(addr, instr); 7765 set_low_register(r1, value); 7766 SetS390ConditionCode<int32_t>(value, 0); 7767 return length; 7768 } 7769 7770 EVALUATE(LGH) { 7771 DCHECK_OPCODE(LGH); 7772 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 7773 // Miscellaneous Loads and Stores 7774 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 7775 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 7776 intptr_t addr = x2_val + b2_val + d2; 7777 int64_t mem_val = static_cast<int64_t>(ReadH(addr, instr)); 7778 set_register(r1, mem_val); 7779 return length; 7780 } 7781 7782 EVALUATE(LLGF) { 7783 DCHECK_OPCODE(LLGF); 7784 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 7785 // Miscellaneous Loads and Stores 7786 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 7787 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 7788 intptr_t addr = x2_val + b2_val + d2; 7789 uint64_t mem_val = static_cast<uint64_t>(ReadWU(addr, instr)); 7790 set_register(r1, mem_val); 7791 return length; 7792 } 7793 7794 EVALUATE(LLGT) { 7795 UNIMPLEMENTED(); 7796 USE(instr); 7797 return 0; 7798 } 7799 7800 EVALUATE(AGF) { 7801 DCHECK_OPCODE(AGF); 7802 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 7803 uint64_t r1_val = get_register(r1); 7804 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 7805 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 7806 intptr_t d2_val = d2; 7807 uint64_t alu_out = r1_val; 7808 uint32_t mem_val = ReadW(b2_val + d2_val + x2_val, instr); 7809 alu_out += mem_val; 7810 SetS390ConditionCode<int64_t>(alu_out, 0); 7811 set_register(r1, alu_out); 7812 return length; 7813 } 7814 7815 EVALUATE(SGF) { 7816 DCHECK_OPCODE(SGF); 7817 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 7818 uint64_t r1_val = get_register(r1); 7819 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 7820 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 7821 intptr_t d2_val = d2; 7822 uint64_t alu_out = r1_val; 7823 uint32_t mem_val = ReadW(b2_val + d2_val + x2_val, instr); 7824 alu_out -= mem_val; 7825 SetS390ConditionCode<int64_t>(alu_out, 0); 7826 set_register(r1, alu_out); 7827 return length; 7828 } 7829 7830 EVALUATE(ALGF) { 7831 UNIMPLEMENTED(); 7832 USE(instr); 7833 return 0; 7834 } 7835 7836 EVALUATE(SLGF) { 7837 UNIMPLEMENTED(); 7838 USE(instr); 7839 return 0; 7840 } 7841 7842 EVALUATE(MSGF) { 7843 DCHECK_OPCODE(MSGF); 7844 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 7845 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 7846 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 7847 intptr_t d2_val = d2; 7848 int64_t mem_val = 7849 static_cast<int64_t>(ReadW(b2_val + d2_val + x2_val, instr)); 7850 int64_t r1_val = get_register(r1); 7851 int64_t product = r1_val * mem_val; 7852 set_register(r1, product); 7853 return length; 7854 } 7855 7856 EVALUATE(DSGF) { 7857 DCHECK_OPCODE(DSGF); 7858 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 7859 DCHECK_EQ(r1 % 2, 0); 7860 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 7861 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 7862 intptr_t d2_val = d2; 7863 int64_t mem_val = 7864 static_cast<int64_t>(ReadW(b2_val + d2_val + x2_val, instr)); 7865 int64_t r1_val = get_register(r1 + 1); 7866 int64_t quotient = r1_val / mem_val; 7867 int64_t remainder = r1_val % mem_val; 7868 set_register(r1, remainder); 7869 set_register(r1 + 1, quotient); 7870 return length; 7871 } 7872 7873 EVALUATE(LRVG) { 7874 DCHECK_OPCODE(LRVG); 7875 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 7876 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 7877 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 7878 intptr_t mem_addr = b2_val + x2_val + d2; 7879 int64_t mem_val = ReadW64(mem_addr, instr); 7880 set_register(r1, ByteReverse(mem_val)); 7881 return length; 7882 } 7883 7884 EVALUATE(LRV) { 7885 DCHECK_OPCODE(LRV); 7886 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 7887 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 7888 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 7889 intptr_t mem_addr = b2_val + x2_val + d2; 7890 int32_t mem_val = ReadW(mem_addr, instr); 7891 set_low_register(r1, ByteReverse(mem_val)); 7892 return length; 7893 } 7894 7895 EVALUATE(LRVH) { 7896 DCHECK_OPCODE(LRVH); 7897 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 7898 int32_t r1_val = get_low_register<int32_t>(r1); 7899 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 7900 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 7901 intptr_t mem_addr = b2_val + x2_val + d2; 7902 int16_t mem_val = ReadH(mem_addr, instr); 7903 int32_t result = ByteReverse(mem_val) & 0x0000FFFF; 7904 result |= r1_val & 0xFFFF0000; 7905 set_low_register(r1, result); 7906 return length; 7907 } 7908 7909 EVALUATE(CG) { 7910 DCHECK_OPCODE(CG); 7911 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 7912 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 7913 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 7914 int64_t alu_out = get_register(r1); 7915 int64_t mem_val = ReadDW(b2_val + x2_val + d2); 7916 SetS390ConditionCode<int64_t>(alu_out, mem_val); 7917 set_register(r1, alu_out); 7918 return length; 7919 } 7920 7921 EVALUATE(CLG) { 7922 DCHECK_OPCODE(CLG); 7923 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 7924 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 7925 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 7926 int64_t alu_out = get_register(r1); 7927 int64_t mem_val = ReadDW(b2_val + x2_val + d2); 7928 SetS390ConditionCode<uint64_t>(alu_out, mem_val); 7929 set_register(r1, alu_out); 7930 return length; 7931 } 7932 7933 EVALUATE(NTSTG) { 7934 UNIMPLEMENTED(); 7935 USE(instr); 7936 return 0; 7937 } 7938 7939 EVALUATE(CVDY) { 7940 UNIMPLEMENTED(); 7941 USE(instr); 7942 return 0; 7943 } 7944 7945 EVALUATE(CVDG) { 7946 UNIMPLEMENTED(); 7947 USE(instr); 7948 return 0; 7949 } 7950 7951 EVALUATE(CGF) { 7952 UNIMPLEMENTED(); 7953 USE(instr); 7954 return 0; 7955 } 7956 7957 EVALUATE(CLGF) { 7958 UNIMPLEMENTED(); 7959 USE(instr); 7960 return 0; 7961 } 7962 7963 EVALUATE(LTGF) { 7964 UNIMPLEMENTED(); 7965 USE(instr); 7966 return 0; 7967 } 7968 7969 EVALUATE(CGH) { 7970 UNIMPLEMENTED(); 7971 USE(instr); 7972 return 0; 7973 } 7974 7975 EVALUATE(PFD) { 7976 DCHECK_OPCODE(PFD); 7977 USE(instr); 7978 return 6; 7979 } 7980 7981 EVALUATE(STRV) { 7982 DCHECK_OPCODE(STRV); 7983 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 7984 int32_t r1_val = get_low_register<int32_t>(r1); 7985 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 7986 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 7987 intptr_t mem_addr = b2_val + x2_val + d2; 7988 WriteW(mem_addr, ByteReverse(r1_val), instr); 7989 return length; 7990 } 7991 7992 EVALUATE(STRVG) { 7993 DCHECK_OPCODE(STRVG); 7994 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 7995 int64_t r1_val = get_register(r1); 7996 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 7997 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 7998 intptr_t mem_addr = b2_val + x2_val + d2; 7999 WriteDW(mem_addr, ByteReverse(r1_val)); 8000 return length; 8001 } 8002 8003 EVALUATE(STRVH) { 8004 DCHECK_OPCODE(STRVH); 8005 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 8006 int32_t r1_val = get_low_register<int32_t>(r1); 8007 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 8008 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8009 intptr_t mem_addr = b2_val + x2_val + d2; 8010 int16_t result = static_cast<int16_t>(r1_val >> 16); 8011 WriteH(mem_addr, ByteReverse(result), instr); 8012 return length; 8013 } 8014 8015 EVALUATE(BCTG) { 8016 UNIMPLEMENTED(); 8017 USE(instr); 8018 return 0; 8019 } 8020 8021 EVALUATE(MSY) { 8022 DCHECK_OPCODE(MSY); 8023 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 8024 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8025 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 8026 intptr_t d2_val = d2; 8027 int32_t mem_val = ReadW(b2_val + d2_val + x2_val, instr); 8028 int32_t r1_val = get_low_register<int32_t>(r1); 8029 set_low_register(r1, mem_val * r1_val); 8030 return length; 8031 } 8032 8033 EVALUATE(MSC) { 8034 DCHECK_OPCODE(MSC); 8035 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 8036 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8037 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 8038 intptr_t d2_val = d2; 8039 int32_t mem_val = ReadW(b2_val + d2_val + x2_val, instr); 8040 int32_t r1_val = get_low_register<int32_t>(r1); 8041 int64_t result64 = 8042 static_cast<int64_t>(r1_val) * static_cast<int64_t>(mem_val); 8043 int32_t result32 = static_cast<int32_t>(result64); 8044 bool isOF = (static_cast<int64_t>(result32) != result64); 8045 SetS390ConditionCode<int32_t>(result32, 0); 8046 SetS390OverflowCode(isOF); 8047 set_low_register(r1, result32); 8048 set_low_register(r1, mem_val * r1_val); 8049 return length; 8050 } 8051 8052 EVALUATE(NY) { 8053 DCHECK_OPCODE(NY); 8054 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 8055 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 8056 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8057 int32_t alu_out = get_low_register<int32_t>(r1); 8058 int32_t mem_val = ReadW(b2_val + x2_val + d2, instr); 8059 alu_out &= mem_val; 8060 SetS390BitWiseConditionCode<uint32_t>(alu_out); 8061 set_low_register(r1, alu_out); 8062 return length; 8063 } 8064 8065 EVALUATE(CLY) { 8066 DCHECK_OPCODE(CLY); 8067 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 8068 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 8069 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8070 uint32_t alu_out = get_low_register<uint32_t>(r1); 8071 uint32_t mem_val = ReadWU(b2_val + x2_val + d2, instr); 8072 SetS390ConditionCode<uint32_t>(alu_out, mem_val); 8073 return length; 8074 } 8075 8076 EVALUATE(OY) { 8077 DCHECK_OPCODE(OY); 8078 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 8079 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 8080 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8081 int32_t alu_out = get_low_register<int32_t>(r1); 8082 int32_t mem_val = ReadW(b2_val + x2_val + d2, instr); 8083 alu_out |= mem_val; 8084 SetS390BitWiseConditionCode<uint32_t>(alu_out); 8085 set_low_register(r1, alu_out); 8086 return length; 8087 } 8088 8089 EVALUATE(XY) { 8090 DCHECK_OPCODE(XY); 8091 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 8092 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 8093 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8094 int32_t alu_out = get_low_register<int32_t>(r1); 8095 int32_t mem_val = ReadW(b2_val + x2_val + d2, instr); 8096 alu_out ^= mem_val; 8097 SetS390BitWiseConditionCode<uint32_t>(alu_out); 8098 set_low_register(r1, alu_out); 8099 return length; 8100 } 8101 8102 EVALUATE(CY) { 8103 DCHECK_OPCODE(CY); 8104 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 8105 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 8106 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8107 int32_t alu_out = get_low_register<int32_t>(r1); 8108 int32_t mem_val = ReadW(b2_val + x2_val + d2, instr); 8109 SetS390ConditionCode<int32_t>(alu_out, mem_val); 8110 return length; 8111 } 8112 8113 EVALUATE(AY) { 8114 DCHECK_OPCODE(AY); 8115 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 8116 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 8117 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8118 int32_t alu_out = get_low_register<int32_t>(r1); 8119 int32_t mem_val = ReadW(b2_val + x2_val + d2, instr); 8120 bool isOF = false; 8121 isOF = CheckOverflowForIntAdd(alu_out, mem_val, int32_t); 8122 alu_out += mem_val; 8123 SetS390ConditionCode<int32_t>(alu_out, 0); 8124 SetS390OverflowCode(isOF); 8125 set_low_register(r1, alu_out); 8126 return length; 8127 } 8128 8129 EVALUATE(SY) { 8130 DCHECK_OPCODE(SY); 8131 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 8132 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 8133 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8134 int32_t alu_out = get_low_register<int32_t>(r1); 8135 int32_t mem_val = ReadW(b2_val + x2_val + d2, instr); 8136 bool isOF = false; 8137 isOF = CheckOverflowForIntSub(alu_out, mem_val, int32_t); 8138 alu_out -= mem_val; 8139 SetS390ConditionCode<int32_t>(alu_out, 0); 8140 SetS390OverflowCode(isOF); 8141 set_low_register(r1, alu_out); 8142 return length; 8143 } 8144 8145 EVALUATE(MFY) { 8146 DCHECK_OPCODE(MFY); 8147 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 8148 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 8149 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8150 DCHECK_EQ(r1 % 2, 0); 8151 int32_t mem_val = ReadW(b2_val + x2_val + d2, instr); 8152 int32_t r1_val = get_low_register<int32_t>(r1 + 1); 8153 int64_t product = 8154 static_cast<int64_t>(r1_val) * static_cast<int64_t>(mem_val); 8155 int32_t high_bits = product >> 32; 8156 r1_val = high_bits; 8157 int32_t low_bits = product & 0x00000000FFFFFFFF; 8158 set_low_register(r1, high_bits); 8159 set_low_register(r1 + 1, low_bits); 8160 return length; 8161 } 8162 8163 EVALUATE(ALY) { 8164 DCHECK_OPCODE(ALY); 8165 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 8166 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 8167 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8168 uint32_t alu_out = get_low_register<uint32_t>(r1); 8169 uint32_t mem_val = ReadWU(b2_val + x2_val + d2, instr); 8170 alu_out += mem_val; 8171 set_low_register(r1, alu_out); 8172 SetS390ConditionCode<uint32_t>(alu_out, 0); 8173 return length; 8174 } 8175 8176 EVALUATE(SLY) { 8177 DCHECK_OPCODE(SLY); 8178 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 8179 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 8180 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8181 uint32_t alu_out = get_low_register<uint32_t>(r1); 8182 uint32_t mem_val = ReadWU(b2_val + x2_val + d2, instr); 8183 alu_out -= mem_val; 8184 set_low_register(r1, alu_out); 8185 SetS390ConditionCode<uint32_t>(alu_out, 0); 8186 return length; 8187 } 8188 8189 EVALUATE(STHY) { 8190 DCHECK_OPCODE(STHY); 8191 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 8192 // Miscellaneous Loads and Stores 8193 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 8194 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8195 intptr_t addr = x2_val + b2_val + d2; 8196 uint16_t value = get_low_register<uint32_t>(r1); 8197 WriteH(addr, value, instr); 8198 return length; 8199 } 8200 8201 EVALUATE(LAY) { 8202 DCHECK_OPCODE(LAY); 8203 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 8204 // Load Address 8205 int rb = b2; 8206 int rx = x2; 8207 int offset = d2; 8208 int64_t rb_val = (rb == 0) ? 0 : get_register(rb); 8209 int64_t rx_val = (rx == 0) ? 0 : get_register(rx); 8210 set_register(r1, rx_val + rb_val + offset); 8211 return length; 8212 } 8213 8214 EVALUATE(STCY) { 8215 DCHECK_OPCODE(STCY); 8216 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 8217 // Miscellaneous Loads and Stores 8218 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 8219 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8220 intptr_t addr = x2_val + b2_val + d2; 8221 uint8_t value = get_low_register<uint32_t>(r1); 8222 WriteB(addr, value); 8223 return length; 8224 } 8225 8226 EVALUATE(ICY) { 8227 UNIMPLEMENTED(); 8228 USE(instr); 8229 return 0; 8230 } 8231 8232 EVALUATE(LAEY) { 8233 UNIMPLEMENTED(); 8234 USE(instr); 8235 return 0; 8236 } 8237 8238 EVALUATE(LB) { 8239 DCHECK_OPCODE(LB); 8240 // Miscellaneous Loads and Stores 8241 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 8242 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 8243 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8244 intptr_t addr = x2_val + b2_val + d2; 8245 int32_t mem_val = ReadB(addr); 8246 set_low_register(r1, mem_val); 8247 return length; 8248 } 8249 8250 EVALUATE(LGB) { 8251 DCHECK_OPCODE(LGB); 8252 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 8253 // Miscellaneous Loads and Stores 8254 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 8255 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8256 intptr_t addr = x2_val + b2_val + d2; 8257 int64_t mem_val = ReadB(addr); 8258 set_register(r1, mem_val); 8259 return length; 8260 } 8261 8262 EVALUATE(LHY) { 8263 DCHECK_OPCODE(LHY); 8264 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 8265 // Miscellaneous Loads and Stores 8266 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 8267 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8268 intptr_t addr = x2_val + b2_val + d2; 8269 int32_t result = static_cast<int32_t>(ReadH(addr, instr)); 8270 set_low_register(r1, result); 8271 return length; 8272 } 8273 8274 EVALUATE(CHY) { 8275 UNIMPLEMENTED(); 8276 USE(instr); 8277 return 0; 8278 } 8279 8280 EVALUATE(AHY) { 8281 DCHECK_OPCODE(AHY); 8282 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 8283 int32_t r1_val = get_low_register<int32_t>(r1); 8284 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8285 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 8286 intptr_t d2_val = d2; 8287 int32_t mem_val = 8288 static_cast<int32_t>(ReadH(b2_val + d2_val + x2_val, instr)); 8289 int32_t alu_out = 0; 8290 bool isOF = false; 8291 alu_out = r1_val + mem_val; 8292 isOF = CheckOverflowForIntAdd(r1_val, mem_val, int32_t); 8293 set_low_register(r1, alu_out); 8294 SetS390ConditionCode<int32_t>(alu_out, 0); 8295 SetS390OverflowCode(isOF); 8296 return length; 8297 } 8298 8299 EVALUATE(SHY) { 8300 DCHECK_OPCODE(SHY); 8301 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 8302 int32_t r1_val = get_low_register<int32_t>(r1); 8303 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8304 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 8305 intptr_t d2_val = d2; 8306 int32_t mem_val = 8307 static_cast<int32_t>(ReadH(b2_val + d2_val + x2_val, instr)); 8308 int32_t alu_out = 0; 8309 bool isOF = false; 8310 alu_out = r1_val - mem_val; 8311 isOF = CheckOverflowForIntSub(r1_val, mem_val, int64_t); 8312 set_low_register(r1, alu_out); 8313 SetS390ConditionCode<int32_t>(alu_out, 0); 8314 SetS390OverflowCode(isOF); 8315 return length; 8316 } 8317 8318 EVALUATE(MHY) { 8319 UNIMPLEMENTED(); 8320 USE(instr); 8321 return 0; 8322 } 8323 8324 EVALUATE(NG) { 8325 DCHECK_OPCODE(NG); 8326 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 8327 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 8328 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8329 int64_t alu_out = get_register(r1); 8330 int64_t mem_val = ReadDW(b2_val + x2_val + d2); 8331 alu_out &= mem_val; 8332 SetS390BitWiseConditionCode<uint32_t>(alu_out); 8333 set_register(r1, alu_out); 8334 return length; 8335 } 8336 8337 EVALUATE(OG) { 8338 DCHECK_OPCODE(OG); 8339 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 8340 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 8341 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8342 int64_t alu_out = get_register(r1); 8343 int64_t mem_val = ReadDW(b2_val + x2_val + d2); 8344 alu_out |= mem_val; 8345 SetS390BitWiseConditionCode<uint32_t>(alu_out); 8346 set_register(r1, alu_out); 8347 return length; 8348 } 8349 8350 EVALUATE(XG) { 8351 DCHECK_OPCODE(XG); 8352 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 8353 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 8354 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8355 int64_t alu_out = get_register(r1); 8356 int64_t mem_val = ReadDW(b2_val + x2_val + d2); 8357 alu_out ^= mem_val; 8358 SetS390BitWiseConditionCode<uint32_t>(alu_out); 8359 set_register(r1, alu_out); 8360 return length; 8361 } 8362 8363 EVALUATE(LGAT) { 8364 UNIMPLEMENTED(); 8365 USE(instr); 8366 return 0; 8367 } 8368 8369 EVALUATE(MLG) { 8370 UNIMPLEMENTED(); 8371 USE(instr); 8372 return 0; 8373 } 8374 8375 EVALUATE(DLG) { 8376 DCHECK_OPCODE(DLG); 8377 #ifdef V8_TARGET_ARCH_S390X 8378 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 8379 uint64_t r1_val = get_register(r1); 8380 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 8381 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8382 DCHECK_EQ(r1 % 2, 0); 8383 unsigned __int128 dividend = static_cast<unsigned __int128>(r1_val) << 64; 8384 dividend += get_register(r1 + 1); 8385 int64_t mem_val = ReadDW(b2_val + x2_val + d2); 8386 uint64_t remainder = dividend % mem_val; 8387 uint64_t quotient = dividend / mem_val; 8388 set_register(r1, remainder); 8389 set_register(r1 + 1, quotient); 8390 return length; 8391 #else 8392 // 32 bit arch doesn't support __int128 type 8393 USE(instr); 8394 UNREACHABLE(); 8395 #endif 8396 } 8397 8398 EVALUATE(ALCG) { 8399 UNIMPLEMENTED(); 8400 USE(instr); 8401 return 0; 8402 } 8403 8404 EVALUATE(SLBG) { 8405 UNIMPLEMENTED(); 8406 USE(instr); 8407 return 0; 8408 } 8409 8410 EVALUATE(STPQ) { 8411 UNIMPLEMENTED(); 8412 USE(instr); 8413 return 0; 8414 } 8415 8416 EVALUATE(LPQ) { 8417 UNIMPLEMENTED(); 8418 USE(instr); 8419 return 0; 8420 } 8421 8422 EVALUATE(LLGH) { 8423 DCHECK_OPCODE(LLGH); 8424 // Load Logical Halfword 8425 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 8426 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8427 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 8428 intptr_t d2_val = d2; 8429 uint16_t mem_val = ReadHU(b2_val + d2_val + x2_val, instr); 8430 set_register(r1, mem_val); 8431 return length; 8432 } 8433 8434 EVALUATE(LLH) { 8435 DCHECK_OPCODE(LLH); 8436 // Load Logical Halfword 8437 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 8438 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8439 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 8440 intptr_t d2_val = d2; 8441 uint16_t mem_val = ReadHU(b2_val + d2_val + x2_val, instr); 8442 set_low_register(r1, mem_val); 8443 return length; 8444 } 8445 8446 EVALUATE(ML) { 8447 DCHECK_OPCODE(ML); 8448 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 8449 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 8450 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8451 DCHECK_EQ(r1 % 2, 0); 8452 uint32_t mem_val = ReadWU(b2_val + x2_val + d2, instr); 8453 uint32_t r1_val = get_low_register<uint32_t>(r1 + 1); 8454 uint64_t product = 8455 static_cast<uint64_t>(r1_val) * static_cast<uint64_t>(mem_val); 8456 uint32_t high_bits = product >> 32; 8457 r1_val = high_bits; 8458 uint32_t low_bits = product & 0x00000000FFFFFFFF; 8459 set_low_register(r1, high_bits); 8460 set_low_register(r1 + 1, low_bits); 8461 return length; 8462 } 8463 8464 EVALUATE(DL) { 8465 DCHECK_OPCODE(DL); 8466 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 8467 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 8468 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8469 DCHECK_EQ(r1 % 2, 0); 8470 uint32_t mem_val = ReadWU(b2_val + x2_val + d2, instr); 8471 uint32_t r1_val = get_low_register<uint32_t>(r1 + 1); 8472 uint64_t quotient = 8473 static_cast<uint64_t>(r1_val) / static_cast<uint64_t>(mem_val); 8474 uint64_t remainder = 8475 static_cast<uint64_t>(r1_val) % static_cast<uint64_t>(mem_val); 8476 set_low_register(r1, remainder); 8477 set_low_register(r1 + 1, quotient); 8478 return length; 8479 } 8480 8481 EVALUATE(ALC) { 8482 UNIMPLEMENTED(); 8483 USE(instr); 8484 return 0; 8485 } 8486 8487 EVALUATE(SLB) { 8488 UNIMPLEMENTED(); 8489 USE(instr); 8490 return 0; 8491 } 8492 8493 EVALUATE(LLGTAT) { 8494 UNIMPLEMENTED(); 8495 USE(instr); 8496 return 0; 8497 } 8498 8499 EVALUATE(LLGFAT) { 8500 UNIMPLEMENTED(); 8501 USE(instr); 8502 return 0; 8503 } 8504 8505 EVALUATE(LAT) { 8506 UNIMPLEMENTED(); 8507 USE(instr); 8508 return 0; 8509 } 8510 8511 EVALUATE(LBH) { 8512 UNIMPLEMENTED(); 8513 USE(instr); 8514 return 0; 8515 } 8516 8517 EVALUATE(LLCH) { 8518 UNIMPLEMENTED(); 8519 USE(instr); 8520 return 0; 8521 } 8522 8523 EVALUATE(STCH) { 8524 UNIMPLEMENTED(); 8525 USE(instr); 8526 return 0; 8527 } 8528 8529 EVALUATE(LHH) { 8530 UNIMPLEMENTED(); 8531 USE(instr); 8532 return 0; 8533 } 8534 8535 EVALUATE(LLHH) { 8536 UNIMPLEMENTED(); 8537 USE(instr); 8538 return 0; 8539 } 8540 8541 EVALUATE(STHH) { 8542 UNIMPLEMENTED(); 8543 USE(instr); 8544 return 0; 8545 } 8546 8547 EVALUATE(LFHAT) { 8548 UNIMPLEMENTED(); 8549 USE(instr); 8550 return 0; 8551 } 8552 8553 EVALUATE(LFH) { 8554 UNIMPLEMENTED(); 8555 USE(instr); 8556 return 0; 8557 } 8558 8559 EVALUATE(STFH) { 8560 UNIMPLEMENTED(); 8561 USE(instr); 8562 return 0; 8563 } 8564 8565 EVALUATE(CHF) { 8566 UNIMPLEMENTED(); 8567 USE(instr); 8568 return 0; 8569 } 8570 8571 EVALUATE(MVCDK) { 8572 UNIMPLEMENTED(); 8573 USE(instr); 8574 return 0; 8575 } 8576 8577 EVALUATE(MVHHI) { 8578 UNIMPLEMENTED(); 8579 USE(instr); 8580 return 0; 8581 } 8582 8583 EVALUATE(MVGHI) { 8584 DCHECK_OPCODE(MVGHI); 8585 // Move Integer (64) 8586 DECODE_SIL_INSTRUCTION(b1, d1, i2); 8587 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1); 8588 intptr_t src_addr = b1_val + d1; 8589 WriteDW(src_addr, i2); 8590 return length; 8591 } 8592 8593 EVALUATE(MVHI) { 8594 DCHECK_OPCODE(MVHI); 8595 // Move Integer (32) 8596 DECODE_SIL_INSTRUCTION(b1, d1, i2); 8597 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1); 8598 intptr_t src_addr = b1_val + d1; 8599 WriteW(src_addr, i2, instr); 8600 return length; 8601 } 8602 8603 EVALUATE(CHHSI) { 8604 UNIMPLEMENTED(); 8605 USE(instr); 8606 return 0; 8607 } 8608 8609 EVALUATE(CGHSI) { 8610 UNIMPLEMENTED(); 8611 USE(instr); 8612 return 0; 8613 } 8614 8615 EVALUATE(CHSI) { 8616 UNIMPLEMENTED(); 8617 USE(instr); 8618 return 0; 8619 } 8620 8621 EVALUATE(CLFHSI) { 8622 UNIMPLEMENTED(); 8623 USE(instr); 8624 return 0; 8625 } 8626 8627 EVALUATE(TBEGIN) { 8628 UNIMPLEMENTED(); 8629 USE(instr); 8630 return 0; 8631 } 8632 8633 EVALUATE(TBEGINC) { 8634 UNIMPLEMENTED(); 8635 USE(instr); 8636 return 0; 8637 } 8638 8639 EVALUATE(LMG) { 8640 DCHECK_OPCODE(LMG); 8641 // Store Multiple 64-bits. 8642 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2); 8643 int rb = b2; 8644 int offset = d2; 8645 8646 // Regs roll around if r3 is less than r1. 8647 // Artificially increase r3 by 16 so we can calculate 8648 // the number of regs stored properly. 8649 if (r3 < r1) r3 += 16; 8650 8651 int64_t rb_val = (rb == 0) ? 0 : get_register(rb); 8652 8653 // Store each register in ascending order. 8654 for (int i = 0; i <= r3 - r1; i++) { 8655 int64_t value = ReadDW(rb_val + offset + 8 * i); 8656 set_register((r1 + i) % 16, value); 8657 } 8658 return length; 8659 } 8660 8661 EVALUATE(SRAG) { 8662 DCHECK_OPCODE(SRAG); 8663 // 64-bit non-clobbering shift-left/right arithmetic 8664 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2); 8665 // only takes rightmost 6 bits 8666 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8667 int shiftBits = (b2_val + d2) & 0x3F; 8668 int64_t r3_val = get_register(r3); 8669 intptr_t alu_out = 0; 8670 bool isOF = false; 8671 alu_out = r3_val >> shiftBits; 8672 set_register(r1, alu_out); 8673 SetS390ConditionCode<intptr_t>(alu_out, 0); 8674 SetS390OverflowCode(isOF); 8675 return length; 8676 } 8677 8678 EVALUATE(SLAG) { 8679 DCHECK_OPCODE(SLAG); 8680 // 64-bit non-clobbering shift-left/right arithmetic 8681 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2); 8682 // only takes rightmost 6 bits 8683 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8684 int shiftBits = (b2_val + d2) & 0x3F; 8685 int64_t r3_val = get_register(r3); 8686 intptr_t alu_out = 0; 8687 bool isOF = false; 8688 isOF = CheckOverflowForShiftLeft(r3_val, shiftBits); 8689 alu_out = r3_val << shiftBits; 8690 set_register(r1, alu_out); 8691 SetS390ConditionCode<intptr_t>(alu_out, 0); 8692 SetS390OverflowCode(isOF); 8693 return length; 8694 } 8695 8696 EVALUATE(SRLG) { 8697 DCHECK_OPCODE(SRLG); 8698 // For SLLG/SRLG, the 64-bit third operand is shifted the number 8699 // of bits specified by the second-operand address, and the result is 8700 // placed at the first-operand location. Except for when the R1 and R3 8701 // fields designate the same register, the third operand remains 8702 // unchanged in general register R3. 8703 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2); 8704 // only takes rightmost 6 bits 8705 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8706 int shiftBits = (b2_val + d2) & 0x3F; 8707 // unsigned 8708 uint64_t r3_val = get_register(r3); 8709 uint64_t alu_out = 0; 8710 alu_out = r3_val >> shiftBits; 8711 set_register(r1, alu_out); 8712 return length; 8713 } 8714 8715 EVALUATE(SLLG) { 8716 DCHECK_OPCODE(SLLG); 8717 // For SLLG/SRLG, the 64-bit third operand is shifted the number 8718 // of bits specified by the second-operand address, and the result is 8719 // placed at the first-operand location. Except for when the R1 and R3 8720 // fields designate the same register, the third operand remains 8721 // unchanged in general register R3. 8722 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2); 8723 // only takes rightmost 6 bits 8724 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8725 int shiftBits = (b2_val + d2) & 0x3F; 8726 // unsigned 8727 uint64_t r3_val = get_register(r3); 8728 uint64_t alu_out = 0; 8729 alu_out = r3_val << shiftBits; 8730 set_register(r1, alu_out); 8731 return length; 8732 } 8733 8734 EVALUATE(CS) { 8735 DCHECK_OPCODE(CS); 8736 DECODE_RS_A_INSTRUCTION(r1, r3, rb, d2); 8737 int32_t offset = d2; 8738 int64_t rb_val = (rb == 0) ? 0 : get_register(rb); 8739 intptr_t target_addr = static_cast<intptr_t>(rb_val) + offset; 8740 8741 int32_t r1_val = get_low_register<int32_t>(r1); 8742 int32_t r3_val = get_low_register<int32_t>(r3); 8743 8744 DCHECK_EQ(target_addr & 0x3, 0); 8745 bool is_success = __atomic_compare_exchange_n( 8746 reinterpret_cast<int32_t*>(target_addr), &r1_val, r3_val, true, 8747 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); 8748 if (!is_success) { 8749 set_low_register(r1, r1_val); 8750 condition_reg_ = 0x4; 8751 } else { 8752 condition_reg_ = 0x8; 8753 } 8754 return length; 8755 } 8756 8757 EVALUATE(CSY) { 8758 DCHECK_OPCODE(CSY); 8759 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2); 8760 int32_t offset = d2; 8761 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8762 intptr_t target_addr = static_cast<intptr_t>(b2_val) + offset; 8763 8764 int32_t r1_val = get_low_register<int32_t>(r1); 8765 int32_t r3_val = get_low_register<int32_t>(r3); 8766 8767 DCHECK_EQ(target_addr & 0x3, 0); 8768 bool is_success = __atomic_compare_exchange_n( 8769 reinterpret_cast<int32_t*>(target_addr), &r1_val, r3_val, true, 8770 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); 8771 if (!is_success) { 8772 set_low_register(r1, r1_val); 8773 condition_reg_ = 0x4; 8774 } else { 8775 condition_reg_ = 0x8; 8776 } 8777 return length; 8778 } 8779 8780 EVALUATE(CSG) { 8781 UNIMPLEMENTED(); 8782 USE(instr); 8783 return 0; 8784 } 8785 8786 EVALUATE(RLLG) { 8787 DCHECK_OPCODE(RLLG); 8788 // For SLLG/SRLG, the 64-bit third operand is shifted the number 8789 // of bits specified by the second-operand address, and the result is 8790 // placed at the first-operand location. Except for when the R1 and R3 8791 // fields designate the same register, the third operand remains 8792 // unchanged in general register R3. 8793 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2); 8794 // only takes rightmost 6 bits 8795 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 8796 int shiftBits = (b2_val + d2) & 0x3F; 8797 // unsigned 8798 uint64_t r3_val = get_register(r3); 8799 uint64_t alu_out = 0; 8800 uint64_t rotateBits = r3_val >> (64 - shiftBits); 8801 alu_out = (r3_val << shiftBits) | (rotateBits); 8802 set_register(r1, alu_out); 8803 return length; 8804 } 8805 8806 EVALUATE(STMG) { 8807 DCHECK_OPCODE(STMG); 8808 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2); 8809 int rb = b2; 8810 int offset = d2; 8811 8812 // Regs roll around if r3 is less than r1. 8813 // Artificially increase r3 by 16 so we can calculate 8814 // the number of regs stored properly. 8815 if (r3 < r1) r3 += 16; 8816 8817 int64_t rb_val = (rb == 0) ? 0 : get_register(rb); 8818 8819 // Store each register in ascending order. 8820 for (int i = 0; i <= r3 - r1; i++) { 8821 int64_t value = get_register((r1 + i) % 16); 8822 WriteDW(rb_val + offset + 8 * i, value); 8823 } 8824 return length; 8825 } 8826 8827 EVALUATE(STMH) { 8828 UNIMPLEMENTED(); 8829 USE(instr); 8830 return 0; 8831 } 8832 8833 EVALUATE(STCMH) { 8834 UNIMPLEMENTED(); 8835 USE(instr); 8836 return 0; 8837 } 8838 8839 EVALUATE(STCMY) { 8840 UNIMPLEMENTED(); 8841 USE(instr); 8842 return 0; 8843 } 8844 8845 EVALUATE(CDSY) { 8846 UNIMPLEMENTED(); 8847 USE(instr); 8848 return 0; 8849 } 8850 8851 EVALUATE(CDSG) { 8852 UNIMPLEMENTED(); 8853 USE(instr); 8854 return 0; 8855 } 8856 8857 EVALUATE(BXHG) { 8858 UNIMPLEMENTED(); 8859 USE(instr); 8860 return 0; 8861 } 8862 8863 EVALUATE(BXLEG) { 8864 UNIMPLEMENTED(); 8865 USE(instr); 8866 return 0; 8867 } 8868 8869 EVALUATE(ECAG) { 8870 UNIMPLEMENTED(); 8871 USE(instr); 8872 return 0; 8873 } 8874 8875 EVALUATE(TMY) { 8876 DCHECK_OPCODE(TMY); 8877 // Test Under Mask (Mem - Imm) (8) 8878 DECODE_SIY_INSTRUCTION(b1, d1, i2); 8879 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1); 8880 intptr_t d1_val = d1; 8881 intptr_t addr = b1_val + d1_val; 8882 uint8_t mem_val = ReadB(addr); 8883 uint8_t imm_val = i2; 8884 uint8_t selected_bits = mem_val & imm_val; 8885 // CC0: Selected bits are zero 8886 // CC1: Selected bits mixed zeros and ones 8887 // CC3: Selected bits all ones 8888 if (0 == selected_bits) { 8889 condition_reg_ = CC_EQ; // CC0 8890 } else if (selected_bits == imm_val) { 8891 condition_reg_ = 0x1; // CC3 8892 } else { 8893 condition_reg_ = 0x4; // CC1 8894 } 8895 return length; 8896 } 8897 8898 EVALUATE(MVIY) { 8899 UNIMPLEMENTED(); 8900 USE(instr); 8901 return 0; 8902 } 8903 8904 EVALUATE(NIY) { 8905 UNIMPLEMENTED(); 8906 USE(instr); 8907 return 0; 8908 } 8909 8910 EVALUATE(CLIY) { 8911 DCHECK_OPCODE(CLIY); 8912 DECODE_SIY_INSTRUCTION(b1, d1, i2); 8913 // Compare Immediate (Mem - Imm) (8) 8914 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1); 8915 intptr_t d1_val = d1; 8916 intptr_t addr = b1_val + d1_val; 8917 uint8_t mem_val = ReadB(addr); 8918 uint8_t imm_val = i2; 8919 SetS390ConditionCode<uint8_t>(mem_val, imm_val); 8920 return length; 8921 } 8922 8923 EVALUATE(OIY) { 8924 UNIMPLEMENTED(); 8925 USE(instr); 8926 return 0; 8927 } 8928 8929 EVALUATE(XIY) { 8930 UNIMPLEMENTED(); 8931 USE(instr); 8932 return 0; 8933 } 8934 8935 EVALUATE(ASI) { 8936 DCHECK_OPCODE(ASI); 8937 // TODO(bcleung): Change all fooInstr->I2Value() to template functions. 8938 // The below static cast to 8 bit and then to 32 bit is necessary 8939 // because siyInstr->I2Value() returns a uint8_t, which a direct 8940 // cast to int32_t could incorrectly interpret. 8941 DECODE_SIY_INSTRUCTION(b1, d1, i2_unsigned); 8942 int8_t i2_8bit = static_cast<int8_t>(i2_unsigned); 8943 int32_t i2 = static_cast<int32_t>(i2_8bit); 8944 intptr_t b1_val = (b1 == 0) ? 0 : get_register(b1); 8945 8946 int d1_val = d1; 8947 intptr_t addr = b1_val + d1_val; 8948 8949 int32_t mem_val = ReadW(addr, instr); 8950 bool isOF = CheckOverflowForIntAdd(mem_val, i2, int32_t); 8951 int32_t alu_out = mem_val + i2; 8952 SetS390ConditionCode<int32_t>(alu_out, 0); 8953 SetS390OverflowCode(isOF); 8954 WriteW(addr, alu_out, instr); 8955 return length; 8956 } 8957 8958 EVALUATE(ALSI) { 8959 UNIMPLEMENTED(); 8960 USE(instr); 8961 return 0; 8962 } 8963 8964 EVALUATE(AGSI) { 8965 DCHECK_OPCODE(AGSI); 8966 // TODO(bcleung): Change all fooInstr->I2Value() to template functions. 8967 // The below static cast to 8 bit and then to 32 bit is necessary 8968 // because siyInstr->I2Value() returns a uint8_t, which a direct 8969 // cast to int32_t could incorrectly interpret. 8970 DECODE_SIY_INSTRUCTION(b1, d1, i2_unsigned); 8971 int8_t i2_8bit = static_cast<int8_t>(i2_unsigned); 8972 int64_t i2 = static_cast<int64_t>(i2_8bit); 8973 intptr_t b1_val = (b1 == 0) ? 0 : get_register(b1); 8974 8975 int d1_val = d1; 8976 intptr_t addr = b1_val + d1_val; 8977 8978 int64_t mem_val = ReadDW(addr); 8979 int isOF = CheckOverflowForIntAdd(mem_val, i2, int64_t); 8980 int64_t alu_out = mem_val + i2; 8981 SetS390ConditionCode<uint64_t>(alu_out, 0); 8982 SetS390OverflowCode(isOF); 8983 WriteDW(addr, alu_out); 8984 return length; 8985 } 8986 8987 EVALUATE(ALGSI) { 8988 UNIMPLEMENTED(); 8989 USE(instr); 8990 return 0; 8991 } 8992 8993 EVALUATE(ICMH) { 8994 UNIMPLEMENTED(); 8995 USE(instr); 8996 return 0; 8997 } 8998 8999 EVALUATE(ICMY) { 9000 UNIMPLEMENTED(); 9001 USE(instr); 9002 return 0; 9003 } 9004 9005 EVALUATE(MVCLU) { 9006 UNIMPLEMENTED(); 9007 USE(instr); 9008 return 0; 9009 } 9010 9011 EVALUATE(CLCLU) { 9012 UNIMPLEMENTED(); 9013 USE(instr); 9014 return 0; 9015 } 9016 9017 EVALUATE(STMY) { 9018 DCHECK_OPCODE(STMY); 9019 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2); 9020 // Load/Store Multiple (32) 9021 int offset = d2; 9022 9023 // Regs roll around if r3 is less than r1. 9024 // Artificially increase r3 by 16 so we can calculate 9025 // the number of regs stored properly. 9026 if (r3 < r1) r3 += 16; 9027 9028 int32_t b2_val = (b2 == 0) ? 0 : get_low_register<int32_t>(b2); 9029 9030 // Store each register in ascending order. 9031 for (int i = 0; i <= r3 - r1; i++) { 9032 int32_t value = get_low_register<int32_t>((r1 + i) % 16); 9033 WriteW(b2_val + offset + 4 * i, value, instr); 9034 } 9035 return length; 9036 } 9037 9038 EVALUATE(LMH) { 9039 UNIMPLEMENTED(); 9040 USE(instr); 9041 return 0; 9042 } 9043 9044 EVALUATE(LMY) { 9045 DCHECK_OPCODE(LMY); 9046 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2); 9047 // Load/Store Multiple (32) 9048 int offset = d2; 9049 9050 // Regs roll around if r3 is less than r1. 9051 // Artificially increase r3 by 16 so we can calculate 9052 // the number of regs stored properly. 9053 if (r3 < r1) r3 += 16; 9054 9055 int32_t b2_val = (b2 == 0) ? 0 : get_low_register<int32_t>(b2); 9056 9057 // Store each register in ascending order. 9058 for (int i = 0; i <= r3 - r1; i++) { 9059 int32_t value = ReadW(b2_val + offset + 4 * i, instr); 9060 set_low_register((r1 + i) % 16, value); 9061 } 9062 return length; 9063 } 9064 9065 EVALUATE(TP) { 9066 UNIMPLEMENTED(); 9067 USE(instr); 9068 return 0; 9069 } 9070 9071 EVALUATE(SRAK) { 9072 DCHECK_OPCODE(SRAK); 9073 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2); 9074 // 32-bit non-clobbering shift-left/right arithmetic 9075 // only takes rightmost 6 bits 9076 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 9077 int shiftBits = (b2_val + d2) & 0x3F; 9078 int32_t r3_val = get_low_register<int32_t>(r3); 9079 int32_t alu_out = 0; 9080 bool isOF = false; 9081 alu_out = r3_val >> shiftBits; 9082 set_low_register(r1, alu_out); 9083 SetS390ConditionCode<int32_t>(alu_out, 0); 9084 SetS390OverflowCode(isOF); 9085 return length; 9086 } 9087 9088 EVALUATE(SLAK) { 9089 DCHECK_OPCODE(SLAK); 9090 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2); 9091 // 32-bit non-clobbering shift-left/right arithmetic 9092 // only takes rightmost 6 bits 9093 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 9094 int shiftBits = (b2_val + d2) & 0x3F; 9095 int32_t r3_val = get_low_register<int32_t>(r3); 9096 int32_t alu_out = 0; 9097 bool isOF = false; 9098 isOF = CheckOverflowForShiftLeft(r3_val, shiftBits); 9099 alu_out = r3_val << shiftBits; 9100 set_low_register(r1, alu_out); 9101 SetS390ConditionCode<int32_t>(alu_out, 0); 9102 SetS390OverflowCode(isOF); 9103 return length; 9104 } 9105 9106 EVALUATE(SRLK) { 9107 DCHECK_OPCODE(SRLK); 9108 // For SLLK/SRLL, the 32-bit third operand is shifted the number 9109 // of bits specified by the second-operand address, and the result is 9110 // placed at the first-operand location. Except for when the R1 and R3 9111 // fields designate the same register, the third operand remains 9112 // unchanged in general register R3. 9113 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2); 9114 // only takes rightmost 6 bits 9115 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 9116 int shiftBits = (b2_val + d2) & 0x3F; 9117 // unsigned 9118 uint32_t r3_val = get_low_register<uint32_t>(r3); 9119 uint32_t alu_out = 0; 9120 alu_out = r3_val >> shiftBits; 9121 set_low_register(r1, alu_out); 9122 return length; 9123 } 9124 9125 EVALUATE(SLLK) { 9126 DCHECK_OPCODE(SLLK); 9127 // For SLLK/SRLL, the 32-bit third operand is shifted the number 9128 // of bits specified by the second-operand address, and the result is 9129 // placed at the first-operand location. Except for when the R1 and R3 9130 // fields designate the same register, the third operand remains 9131 // unchanged in general register R3. 9132 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2); 9133 // only takes rightmost 6 bits 9134 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 9135 int shiftBits = (b2_val + d2) & 0x3F; 9136 // unsigned 9137 uint32_t r3_val = get_low_register<uint32_t>(r3); 9138 uint32_t alu_out = 0; 9139 alu_out = r3_val << shiftBits; 9140 set_low_register(r1, alu_out); 9141 return length; 9142 } 9143 9144 EVALUATE(LOCG) { 9145 UNIMPLEMENTED(); 9146 USE(instr); 9147 return 0; 9148 } 9149 9150 EVALUATE(STOCG) { 9151 UNIMPLEMENTED(); 9152 USE(instr); 9153 return 0; 9154 } 9155 9156 EVALUATE(LANG) { 9157 UNIMPLEMENTED(); 9158 USE(instr); 9159 return 0; 9160 } 9161 9162 EVALUATE(LAOG) { 9163 UNIMPLEMENTED(); 9164 USE(instr); 9165 return 0; 9166 } 9167 9168 EVALUATE(LAXG) { 9169 UNIMPLEMENTED(); 9170 USE(instr); 9171 return 0; 9172 } 9173 9174 EVALUATE(LAAG) { 9175 UNIMPLEMENTED(); 9176 USE(instr); 9177 return 0; 9178 } 9179 9180 EVALUATE(LAALG) { 9181 UNIMPLEMENTED(); 9182 USE(instr); 9183 return 0; 9184 } 9185 9186 EVALUATE(LOC) { 9187 UNIMPLEMENTED(); 9188 USE(instr); 9189 return 0; 9190 } 9191 9192 EVALUATE(STOC) { 9193 UNIMPLEMENTED(); 9194 USE(instr); 9195 return 0; 9196 } 9197 9198 #define ATOMIC_LOAD_AND_UPDATE_WORD32(op) \ 9199 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2); \ 9200 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); \ 9201 intptr_t addr = static_cast<intptr_t>(b2_val) + d2; \ 9202 int32_t r3_val = get_low_register<int32_t>(r3); \ 9203 DCHECK_EQ(addr & 0x3, 0); \ 9204 int32_t r1_val = op(reinterpret_cast<int32_t*>(addr), \ 9205 r3_val, __ATOMIC_SEQ_CST); \ 9206 set_low_register(r1, r1_val); 9207 9208 EVALUATE(LAN) { 9209 DCHECK_OPCODE(LAN); 9210 ATOMIC_LOAD_AND_UPDATE_WORD32(__atomic_fetch_and); 9211 return length; 9212 } 9213 9214 EVALUATE(LAO) { 9215 DCHECK_OPCODE(LAO); 9216 ATOMIC_LOAD_AND_UPDATE_WORD32(__atomic_fetch_or); 9217 return length; 9218 } 9219 9220 EVALUATE(LAX) { 9221 DCHECK_OPCODE(LAX); 9222 ATOMIC_LOAD_AND_UPDATE_WORD32(__atomic_fetch_xor); 9223 return length; 9224 } 9225 9226 EVALUATE(LAA) { 9227 DCHECK_OPCODE(LAA); 9228 ATOMIC_LOAD_AND_UPDATE_WORD32(__atomic_fetch_add); 9229 return length; 9230 } 9231 9232 EVALUATE(LAAL) { 9233 UNIMPLEMENTED(); 9234 USE(instr); 9235 return 0; 9236 } 9237 9238 #undef ATOMIC_LOAD_AND_UPDATE_WORD32 9239 9240 EVALUATE(BRXHG) { 9241 DCHECK_OPCODE(BRXHG); 9242 DECODE_RIE_E_INSTRUCTION(r1, r3, i2); 9243 int64_t r1_val = (r1 == 0) ? 0 : get_register(r1); 9244 int64_t r3_val = (r3 == 0) ? 0 : get_register(r3); 9245 intptr_t branch_address = get_pc() + (2 * i2); 9246 r1_val += r3_val; 9247 int64_t compare_val = r3 % 2 == 0 ? get_register(r3 + 1) : r3_val; 9248 if (r1_val > compare_val) { 9249 set_pc(branch_address); 9250 } 9251 set_register(r1, r1_val); 9252 return length; 9253 } 9254 9255 EVALUATE(BRXLG) { 9256 UNIMPLEMENTED(); 9257 USE(instr); 9258 return 0; 9259 } 9260 9261 EVALUATE(RISBLG) { 9262 UNIMPLEMENTED(); 9263 USE(instr); 9264 return 0; 9265 } 9266 9267 EVALUATE(RNSBG) { 9268 UNIMPLEMENTED(); 9269 USE(instr); 9270 return 0; 9271 } 9272 9273 EVALUATE(ROSBG) { 9274 UNIMPLEMENTED(); 9275 USE(instr); 9276 return 0; 9277 } 9278 9279 EVALUATE(RXSBG) { 9280 UNIMPLEMENTED(); 9281 USE(instr); 9282 return 0; 9283 } 9284 9285 EVALUATE(RISBGN) { 9286 UNIMPLEMENTED(); 9287 USE(instr); 9288 return 0; 9289 } 9290 9291 EVALUATE(RISBHG) { 9292 UNIMPLEMENTED(); 9293 USE(instr); 9294 return 0; 9295 } 9296 9297 EVALUATE(CGRJ) { 9298 UNIMPLEMENTED(); 9299 USE(instr); 9300 return 0; 9301 } 9302 9303 EVALUATE(CGIT) { 9304 UNIMPLEMENTED(); 9305 USE(instr); 9306 return 0; 9307 } 9308 9309 EVALUATE(CIT) { 9310 UNIMPLEMENTED(); 9311 USE(instr); 9312 return 0; 9313 } 9314 9315 EVALUATE(CLFIT) { 9316 UNIMPLEMENTED(); 9317 USE(instr); 9318 return 0; 9319 } 9320 9321 EVALUATE(CGIJ) { 9322 UNIMPLEMENTED(); 9323 USE(instr); 9324 return 0; 9325 } 9326 9327 EVALUATE(CIJ) { 9328 UNIMPLEMENTED(); 9329 USE(instr); 9330 return 0; 9331 } 9332 9333 EVALUATE(ALHSIK) { 9334 UNIMPLEMENTED(); 9335 USE(instr); 9336 return 0; 9337 } 9338 9339 EVALUATE(ALGHSIK) { 9340 UNIMPLEMENTED(); 9341 USE(instr); 9342 return 0; 9343 } 9344 9345 EVALUATE(CGRB) { 9346 UNIMPLEMENTED(); 9347 USE(instr); 9348 return 0; 9349 } 9350 9351 EVALUATE(CGIB) { 9352 UNIMPLEMENTED(); 9353 USE(instr); 9354 return 0; 9355 } 9356 9357 EVALUATE(CIB) { 9358 UNIMPLEMENTED(); 9359 USE(instr); 9360 return 0; 9361 } 9362 9363 EVALUATE(LDEB) { 9364 DCHECK_OPCODE(LDEB); 9365 DECODE_RXE_INSTRUCTION(r1, b2, x2, d2); 9366 int rb = b2; 9367 int rx = x2; 9368 int offset = d2; 9369 int64_t rb_val = (rb == 0) ? 0 : get_register(rb); 9370 int64_t rx_val = (rx == 0) ? 0 : get_register(rx); 9371 float fval = ReadFloat(rx_val + rb_val + offset); 9372 set_d_register_from_double(r1, static_cast<double>(fval)); 9373 return length; 9374 } 9375 9376 EVALUATE(LXDB) { 9377 UNIMPLEMENTED(); 9378 USE(instr); 9379 return 0; 9380 } 9381 9382 EVALUATE(LXEB) { 9383 UNIMPLEMENTED(); 9384 USE(instr); 9385 return 0; 9386 } 9387 9388 EVALUATE(MXDB) { 9389 UNIMPLEMENTED(); 9390 USE(instr); 9391 return 0; 9392 } 9393 9394 EVALUATE(KEB) { 9395 UNIMPLEMENTED(); 9396 USE(instr); 9397 return 0; 9398 } 9399 9400 EVALUATE(CEB) { 9401 DCHECK_OPCODE(CEB); 9402 9403 DECODE_RXE_INSTRUCTION(r1, b2, x2, d2); 9404 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 9405 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 9406 intptr_t d2_val = d2; 9407 float r1_val = get_float32_from_d_register(r1); 9408 float fval = ReadFloat(b2_val + x2_val + d2_val); 9409 SetS390ConditionCode<float>(r1_val, fval); 9410 return length; 9411 } 9412 9413 EVALUATE(AEB) { 9414 DCHECK_OPCODE(AEB); 9415 DECODE_RXE_INSTRUCTION(r1, b2, x2, d2); 9416 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 9417 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 9418 intptr_t d2_val = d2; 9419 float r1_val = get_float32_from_d_register(r1); 9420 float fval = ReadFloat(b2_val + x2_val + d2_val); 9421 r1_val += fval; 9422 set_d_register_from_float32(r1, r1_val); 9423 SetS390ConditionCode<float>(r1_val, 0); 9424 return length; 9425 } 9426 9427 EVALUATE(SEB) { 9428 DCHECK_OPCODE(SEB); 9429 DECODE_RXE_INSTRUCTION(r1, b2, x2, d2); 9430 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 9431 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 9432 intptr_t d2_val = d2; 9433 float r1_val = get_float32_from_d_register(r1); 9434 float fval = ReadFloat(b2_val + x2_val + d2_val); 9435 r1_val -= fval; 9436 set_d_register_from_float32(r1, r1_val); 9437 SetS390ConditionCode<float>(r1_val, 0); 9438 return length; 9439 } 9440 9441 EVALUATE(MDEB) { 9442 UNIMPLEMENTED(); 9443 USE(instr); 9444 return 0; 9445 } 9446 9447 EVALUATE(DEB) { 9448 DCHECK_OPCODE(DEB); 9449 DECODE_RXE_INSTRUCTION(r1, b2, x2, d2); 9450 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 9451 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 9452 intptr_t d2_val = d2; 9453 float r1_val = get_float32_from_d_register(r1); 9454 float fval = ReadFloat(b2_val + x2_val + d2_val); 9455 r1_val /= fval; 9456 set_d_register_from_float32(r1, r1_val); 9457 return length; 9458 } 9459 9460 EVALUATE(MAEB) { 9461 UNIMPLEMENTED(); 9462 USE(instr); 9463 return 0; 9464 } 9465 9466 EVALUATE(MSEB) { 9467 UNIMPLEMENTED(); 9468 USE(instr); 9469 return 0; 9470 } 9471 9472 EVALUATE(TCEB) { 9473 UNIMPLEMENTED(); 9474 USE(instr); 9475 return 0; 9476 } 9477 9478 EVALUATE(TCDB) { 9479 UNIMPLEMENTED(); 9480 USE(instr); 9481 return 0; 9482 } 9483 9484 EVALUATE(TCXB) { 9485 UNIMPLEMENTED(); 9486 USE(instr); 9487 return 0; 9488 } 9489 9490 EVALUATE(SQEB) { 9491 UNIMPLEMENTED(); 9492 USE(instr); 9493 return 0; 9494 } 9495 9496 EVALUATE(SQDB) { 9497 DCHECK_OPCODE(SQDB); 9498 DECODE_RXE_INSTRUCTION(r1, b2, x2, d2); 9499 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 9500 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 9501 intptr_t d2_val = d2; 9502 double r1_val = get_double_from_d_register(r1); 9503 double dbl_val = ReadDouble(b2_val + x2_val + d2_val); 9504 r1_val = std::sqrt(dbl_val); 9505 set_d_register_from_double(r1, r1_val); 9506 return length; 9507 } 9508 9509 EVALUATE(MEEB) { 9510 DCHECK_OPCODE(MEEB); 9511 DECODE_RXE_INSTRUCTION(r1, b2, x2, d2); 9512 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 9513 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 9514 intptr_t d2_val = d2; 9515 float r1_val = get_float32_from_d_register(r1); 9516 float fval = ReadFloat(b2_val + x2_val + d2_val); 9517 r1_val *= fval; 9518 set_d_register_from_float32(r1, r1_val); 9519 return length; 9520 } 9521 9522 EVALUATE(KDB) { 9523 UNIMPLEMENTED(); 9524 USE(instr); 9525 return 0; 9526 } 9527 9528 EVALUATE(CDB) { 9529 DCHECK_OPCODE(CDB); 9530 9531 DECODE_RXE_INSTRUCTION(r1, b2, x2, d2); 9532 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 9533 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 9534 intptr_t d2_val = d2; 9535 double r1_val = get_double_from_d_register(r1); 9536 double dbl_val = ReadDouble(b2_val + x2_val + d2_val); 9537 SetS390ConditionCode<double>(r1_val, dbl_val); 9538 return length; 9539 } 9540 9541 EVALUATE(ADB) { 9542 DCHECK_OPCODE(ADB); 9543 9544 DECODE_RXE_INSTRUCTION(r1, b2, x2, d2); 9545 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 9546 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 9547 intptr_t d2_val = d2; 9548 double r1_val = get_double_from_d_register(r1); 9549 double dbl_val = ReadDouble(b2_val + x2_val + d2_val); 9550 r1_val += dbl_val; 9551 set_d_register_from_double(r1, r1_val); 9552 SetS390ConditionCode<double>(r1_val, 0); 9553 return length; 9554 } 9555 9556 EVALUATE(SDB) { 9557 DCHECK_OPCODE(SDB); 9558 DECODE_RXE_INSTRUCTION(r1, b2, x2, d2); 9559 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 9560 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 9561 intptr_t d2_val = d2; 9562 double r1_val = get_double_from_d_register(r1); 9563 double dbl_val = ReadDouble(b2_val + x2_val + d2_val); 9564 r1_val -= dbl_val; 9565 set_d_register_from_double(r1, r1_val); 9566 SetS390ConditionCode<double>(r1_val, 0); 9567 return length; 9568 } 9569 9570 EVALUATE(MDB) { 9571 DCHECK_OPCODE(MDB); 9572 DECODE_RXE_INSTRUCTION(r1, b2, x2, d2); 9573 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 9574 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 9575 intptr_t d2_val = d2; 9576 double r1_val = get_double_from_d_register(r1); 9577 double dbl_val = ReadDouble(b2_val + x2_val + d2_val); 9578 r1_val *= dbl_val; 9579 set_d_register_from_double(r1, r1_val); 9580 return length; 9581 } 9582 9583 EVALUATE(DDB) { 9584 DCHECK_OPCODE(DDB); 9585 DECODE_RXE_INSTRUCTION(r1, b2, x2, d2); 9586 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 9587 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 9588 intptr_t d2_val = d2; 9589 double r1_val = get_double_from_d_register(r1); 9590 double dbl_val = ReadDouble(b2_val + x2_val + d2_val); 9591 r1_val /= dbl_val; 9592 set_d_register_from_double(r1, r1_val); 9593 return length; 9594 } 9595 9596 EVALUATE(MADB) { 9597 UNIMPLEMENTED(); 9598 USE(instr); 9599 return 0; 9600 } 9601 9602 EVALUATE(MSDB) { 9603 UNIMPLEMENTED(); 9604 USE(instr); 9605 return 0; 9606 } 9607 9608 EVALUATE(SLDT) { 9609 UNIMPLEMENTED(); 9610 USE(instr); 9611 return 0; 9612 } 9613 9614 EVALUATE(SRDT) { 9615 UNIMPLEMENTED(); 9616 USE(instr); 9617 return 0; 9618 } 9619 9620 EVALUATE(SLXT) { 9621 UNIMPLEMENTED(); 9622 USE(instr); 9623 return 0; 9624 } 9625 9626 EVALUATE(SRXT) { 9627 UNIMPLEMENTED(); 9628 USE(instr); 9629 return 0; 9630 } 9631 9632 EVALUATE(TDCET) { 9633 UNIMPLEMENTED(); 9634 USE(instr); 9635 return 0; 9636 } 9637 9638 EVALUATE(TDGET) { 9639 UNIMPLEMENTED(); 9640 USE(instr); 9641 return 0; 9642 } 9643 9644 EVALUATE(TDCDT) { 9645 UNIMPLEMENTED(); 9646 USE(instr); 9647 return 0; 9648 } 9649 9650 EVALUATE(TDGDT) { 9651 UNIMPLEMENTED(); 9652 USE(instr); 9653 return 0; 9654 } 9655 9656 EVALUATE(TDCXT) { 9657 UNIMPLEMENTED(); 9658 USE(instr); 9659 return 0; 9660 } 9661 9662 EVALUATE(TDGXT) { 9663 UNIMPLEMENTED(); 9664 USE(instr); 9665 return 0; 9666 } 9667 9668 EVALUATE(LEY) { 9669 DCHECK_OPCODE(LEY); 9670 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 9671 // Miscellaneous Loads and Stores 9672 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 9673 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 9674 intptr_t addr = x2_val + b2_val + d2; 9675 float float_val = *reinterpret_cast<float*>(addr); 9676 set_d_register_from_float32(r1, float_val); 9677 return length; 9678 } 9679 9680 EVALUATE(LDY) { 9681 DCHECK_OPCODE(LDY); 9682 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 9683 // Miscellaneous Loads and Stores 9684 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 9685 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 9686 intptr_t addr = x2_val + b2_val + d2; 9687 uint64_t dbl_val = *reinterpret_cast<uint64_t*>(addr); 9688 set_d_register(r1, dbl_val); 9689 return length; 9690 } 9691 9692 EVALUATE(STEY) { 9693 DCHECK_OPCODE(STEY); 9694 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 9695 // Miscellaneous Loads and Stores 9696 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 9697 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 9698 intptr_t addr = x2_val + b2_val + d2; 9699 int64_t frs_val = get_d_register(r1) >> 32; 9700 WriteW(addr, static_cast<int32_t>(frs_val), instr); 9701 return length; 9702 } 9703 9704 EVALUATE(STDY) { 9705 DCHECK_OPCODE(STDY); 9706 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); 9707 // Miscellaneous Loads and Stores 9708 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); 9709 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); 9710 intptr_t addr = x2_val + b2_val + d2; 9711 int64_t frs_val = get_d_register(r1); 9712 WriteDW(addr, frs_val); 9713 return length; 9714 } 9715 9716 EVALUATE(CZDT) { 9717 UNIMPLEMENTED(); 9718 USE(instr); 9719 return 0; 9720 } 9721 9722 EVALUATE(CZXT) { 9723 UNIMPLEMENTED(); 9724 USE(instr); 9725 return 0; 9726 } 9727 9728 EVALUATE(CDZT) { 9729 UNIMPLEMENTED(); 9730 USE(instr); 9731 return 0; 9732 } 9733 9734 EVALUATE(CXZT) { 9735 UNIMPLEMENTED(); 9736 USE(instr); 9737 return 0; 9738 } 9739 9740 #undef EVALUATE 9741 9742 } // namespace internal 9743 } // namespace v8 9744 9745 #endif // USE_SIMULATOR 9746 #endif // V8_TARGET_ARCH_S390 9747