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