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