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