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