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