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