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