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, &registers_[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