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