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