1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <stdarg.h>
6 #include <stdlib.h>
7 #include <cmath>
8
9 #if V8_TARGET_ARCH_S390
10
11 #include "src/assembler.h"
12 #include "src/base/bits.h"
13 #include "src/base/once.h"
14 #include "src/codegen.h"
15 #include "src/disasm.h"
16 #include "src/runtime/runtime-utils.h"
17 #include "src/s390/constants-s390.h"
18 #include "src/s390/frames-s390.h"
19 #include "src/s390/simulator-s390.h"
20 #if defined(USE_SIMULATOR)
21
22 // Only build the simulator if not compiling for real s390 hardware.
23 namespace v8 {
24 namespace internal {
25
26 const auto GetRegConfig = RegisterConfiguration::Crankshaft;
27
28 // This macro provides a platform independent use of sscanf. The reason for
29 // SScanF not being implemented in a platform independent way through
30 // ::v8::internal::OS in the same way as SNPrintF is that the
31 // Windows C Run-Time Library does not provide vsscanf.
32 #define SScanF sscanf // NOLINT
33
34 // The S390Debugger class is used by the simulator while debugging simulated
35 // z/Architecture code.
36 class S390Debugger {
37 public:
S390Debugger(Simulator * sim)38 explicit S390Debugger(Simulator* sim) : sim_(sim) {}
39
40 void Stop(Instruction* instr);
41 void Debug();
42
43 private:
44 #if V8_TARGET_LITTLE_ENDIAN
45 static const Instr kBreakpointInstr = (0x0000FFB2); // TRAP4 0000
46 static const Instr kNopInstr = (0x00160016); // OR r0, r0 x2
47 #else
48 static const Instr kBreakpointInstr = (0xB2FF0000); // TRAP4 0000
49 static const Instr kNopInstr = (0x16001600); // OR r0, r0 x2
50 #endif
51
52 Simulator* sim_;
53
54 intptr_t GetRegisterValue(int regnum);
55 double GetRegisterPairDoubleValue(int regnum);
56 double GetFPDoubleRegisterValue(int regnum);
57 float GetFPFloatRegisterValue(int regnum);
58 bool GetValue(const char* desc, intptr_t* value);
59 bool GetFPDoubleValue(const char* desc, double* value);
60
61 // Set or delete a breakpoint. Returns true if successful.
62 bool SetBreakpoint(Instruction* break_pc);
63 bool DeleteBreakpoint(Instruction* break_pc);
64
65 // Undo and redo all breakpoints. This is needed to bracket disassembly and
66 // execution to skip past breakpoints when run from the debugger.
67 void UndoBreakpoints();
68 void RedoBreakpoints();
69 };
70
Stop(Instruction * instr)71 void S390Debugger::Stop(Instruction* instr) {
72 // Get the stop code.
73 // use of kStopCodeMask not right on PowerPC
74 uint32_t code = instr->SvcValue() & kStopCodeMask;
75 // Retrieve the encoded address, which comes just after this stop.
76 char* msg = *reinterpret_cast<char**>(sim_->get_pc() + sizeof(FourByteInstr));
77 // Update this stop description.
78 if (sim_->isWatchedStop(code) && !sim_->watched_stops_[code].desc) {
79 sim_->watched_stops_[code].desc = msg;
80 }
81 // Print the stop message and code if it is not the default code.
82 if (code != kMaxStopCode) {
83 PrintF("Simulator hit stop %u: %s\n", code, msg);
84 } else {
85 PrintF("Simulator hit %s\n", msg);
86 }
87 sim_->set_pc(sim_->get_pc() + sizeof(FourByteInstr) + kPointerSize);
88 Debug();
89 }
90
GetRegisterValue(int regnum)91 intptr_t S390Debugger::GetRegisterValue(int regnum) {
92 return sim_->get_register(regnum);
93 }
94
GetRegisterPairDoubleValue(int regnum)95 double S390Debugger::GetRegisterPairDoubleValue(int regnum) {
96 return sim_->get_double_from_register_pair(regnum);
97 }
98
GetFPDoubleRegisterValue(int regnum)99 double S390Debugger::GetFPDoubleRegisterValue(int regnum) {
100 return sim_->get_double_from_d_register(regnum);
101 }
102
GetFPFloatRegisterValue(int regnum)103 float S390Debugger::GetFPFloatRegisterValue(int regnum) {
104 return sim_->get_float32_from_d_register(regnum);
105 }
106
GetValue(const char * desc,intptr_t * value)107 bool S390Debugger::GetValue(const char* desc, intptr_t* value) {
108 int regnum = Registers::Number(desc);
109 if (regnum != kNoRegister) {
110 *value = GetRegisterValue(regnum);
111 return true;
112 } else {
113 if (strncmp(desc, "0x", 2) == 0) {
114 return SScanF(desc + 2, "%" V8PRIxPTR,
115 reinterpret_cast<uintptr_t*>(value)) == 1;
116 } else {
117 return SScanF(desc, "%" V8PRIuPTR, reinterpret_cast<uintptr_t*>(value)) ==
118 1;
119 }
120 }
121 return false;
122 }
123
GetFPDoubleValue(const char * desc,double * value)124 bool S390Debugger::GetFPDoubleValue(const char* desc, double* value) {
125 int regnum = DoubleRegisters::Number(desc);
126 if (regnum != kNoRegister) {
127 *value = sim_->get_double_from_d_register(regnum);
128 return true;
129 }
130 return false;
131 }
132
SetBreakpoint(Instruction * break_pc)133 bool S390Debugger::SetBreakpoint(Instruction* break_pc) {
134 // Check if a breakpoint can be set. If not return without any side-effects.
135 if (sim_->break_pc_ != NULL) {
136 return false;
137 }
138
139 // Set the breakpoint.
140 sim_->break_pc_ = break_pc;
141 sim_->break_instr_ = break_pc->InstructionBits();
142 // Not setting the breakpoint instruction in the code itself. It will be set
143 // when the debugger shell continues.
144 return true;
145 }
146
DeleteBreakpoint(Instruction * break_pc)147 bool S390Debugger::DeleteBreakpoint(Instruction* break_pc) {
148 if (sim_->break_pc_ != NULL) {
149 sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
150 }
151
152 sim_->break_pc_ = NULL;
153 sim_->break_instr_ = 0;
154 return true;
155 }
156
UndoBreakpoints()157 void S390Debugger::UndoBreakpoints() {
158 if (sim_->break_pc_ != NULL) {
159 sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
160 }
161 }
162
RedoBreakpoints()163 void S390Debugger::RedoBreakpoints() {
164 if (sim_->break_pc_ != NULL) {
165 sim_->break_pc_->SetInstructionBits(kBreakpointInstr);
166 }
167 }
168
Debug()169 void S390Debugger::Debug() {
170 intptr_t last_pc = -1;
171 bool done = false;
172
173 #define COMMAND_SIZE 63
174 #define ARG_SIZE 255
175
176 #define STR(a) #a
177 #define XSTR(a) STR(a)
178
179 char cmd[COMMAND_SIZE + 1];
180 char arg1[ARG_SIZE + 1];
181 char arg2[ARG_SIZE + 1];
182 char* argv[3] = {cmd, arg1, arg2};
183
184 // make sure to have a proper terminating character if reaching the limit
185 cmd[COMMAND_SIZE] = 0;
186 arg1[ARG_SIZE] = 0;
187 arg2[ARG_SIZE] = 0;
188
189 // Undo all set breakpoints while running in the debugger shell. This will
190 // make them invisible to all commands.
191 UndoBreakpoints();
192 // Disable tracing while simulating
193 bool trace = ::v8::internal::FLAG_trace_sim;
194 ::v8::internal::FLAG_trace_sim = false;
195
196 while (!done && !sim_->has_bad_pc()) {
197 if (last_pc != sim_->get_pc()) {
198 disasm::NameConverter converter;
199 disasm::Disassembler dasm(converter);
200 // use a reasonably large buffer
201 v8::internal::EmbeddedVector<char, 256> buffer;
202 dasm.InstructionDecode(buffer, reinterpret_cast<byte*>(sim_->get_pc()));
203 PrintF(" 0x%08" V8PRIxPTR " %s\n", sim_->get_pc(), buffer.start());
204 last_pc = sim_->get_pc();
205 }
206 char* line = ReadLine("sim> ");
207 if (line == NULL) {
208 break;
209 } else {
210 char* last_input = sim_->last_debugger_input();
211 if (strcmp(line, "\n") == 0 && last_input != NULL) {
212 line = last_input;
213 } else {
214 // Ownership is transferred to sim_;
215 sim_->set_last_debugger_input(line);
216 }
217 // Use sscanf to parse the individual parts of the command line. At the
218 // moment no command expects more than two parameters.
219 int argc = SScanF(line,
220 "%" XSTR(COMMAND_SIZE) "s "
221 "%" XSTR(ARG_SIZE) "s "
222 "%" XSTR(ARG_SIZE) "s",
223 cmd, arg1, arg2);
224 if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) {
225 intptr_t value;
226
227 // If at a breakpoint, proceed past it.
228 if ((reinterpret_cast<Instruction*>(sim_->get_pc()))
229 ->InstructionBits() == 0x7d821008) {
230 sim_->set_pc(sim_->get_pc() + sizeof(FourByteInstr));
231 } else {
232 sim_->ExecuteInstruction(
233 reinterpret_cast<Instruction*>(sim_->get_pc()));
234 }
235
236 if (argc == 2 && last_pc != sim_->get_pc()) {
237 disasm::NameConverter converter;
238 disasm::Disassembler dasm(converter);
239 // use a reasonably large buffer
240 v8::internal::EmbeddedVector<char, 256> buffer;
241
242 if (GetValue(arg1, &value)) {
243 // Interpret a numeric argument as the number of instructions to
244 // step past.
245 for (int i = 1; (!sim_->has_bad_pc()) && i < value; i++) {
246 dasm.InstructionDecode(buffer,
247 reinterpret_cast<byte*>(sim_->get_pc()));
248 PrintF(" 0x%08" V8PRIxPTR " %s\n", sim_->get_pc(),
249 buffer.start());
250 sim_->ExecuteInstruction(
251 reinterpret_cast<Instruction*>(sim_->get_pc()));
252 }
253 } else {
254 // Otherwise treat it as the mnemonic of the opcode to stop at.
255 char mnemonic[256];
256 while (!sim_->has_bad_pc()) {
257 dasm.InstructionDecode(buffer,
258 reinterpret_cast<byte*>(sim_->get_pc()));
259 char* mnemonicStart = buffer.start();
260 while (*mnemonicStart != 0 && *mnemonicStart != ' ')
261 mnemonicStart++;
262 SScanF(mnemonicStart, "%s", mnemonic);
263 if (!strcmp(arg1, mnemonic)) break;
264
265 PrintF(" 0x%08" V8PRIxPTR " %s\n", sim_->get_pc(),
266 buffer.start());
267 sim_->ExecuteInstruction(
268 reinterpret_cast<Instruction*>(sim_->get_pc()));
269 }
270 }
271 }
272 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) {
273 // If at a breakpoint, proceed past it.
274 if ((reinterpret_cast<Instruction*>(sim_->get_pc()))
275 ->InstructionBits() == 0x7d821008) {
276 sim_->set_pc(sim_->get_pc() + sizeof(FourByteInstr));
277 } else {
278 // Execute the one instruction we broke at with breakpoints disabled.
279 sim_->ExecuteInstruction(
280 reinterpret_cast<Instruction*>(sim_->get_pc()));
281 }
282 // Leave the debugger shell.
283 done = true;
284 } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) {
285 if (argc == 2 || (argc == 3 && strcmp(arg2, "fp") == 0)) {
286 intptr_t value;
287 double dvalue;
288 if (strcmp(arg1, "all") == 0) {
289 for (int i = 0; i < kNumRegisters; i++) {
290 value = GetRegisterValue(i);
291 PrintF(" %3s: %08" V8PRIxPTR,
292 GetRegConfig()->GetGeneralRegisterName(i), value);
293 if ((argc == 3 && strcmp(arg2, "fp") == 0) && i < 8 &&
294 (i % 2) == 0) {
295 dvalue = GetRegisterPairDoubleValue(i);
296 PrintF(" (%f)\n", dvalue);
297 } else if (i != 0 && !((i + 1) & 3)) {
298 PrintF("\n");
299 }
300 }
301 PrintF(" pc: %08" V8PRIxPTR " cr: %08x\n", sim_->special_reg_pc_,
302 sim_->condition_reg_);
303 } else if (strcmp(arg1, "alld") == 0) {
304 for (int i = 0; i < kNumRegisters; i++) {
305 value = GetRegisterValue(i);
306 PrintF(" %3s: %08" V8PRIxPTR " %11" V8PRIdPTR,
307 GetRegConfig()->GetGeneralRegisterName(i), value, value);
308 if ((argc == 3 && strcmp(arg2, "fp") == 0) && i < 8 &&
309 (i % 2) == 0) {
310 dvalue = GetRegisterPairDoubleValue(i);
311 PrintF(" (%f)\n", dvalue);
312 } else if (!((i + 1) % 2)) {
313 PrintF("\n");
314 }
315 }
316 PrintF(" pc: %08" V8PRIxPTR " cr: %08x\n", sim_->special_reg_pc_,
317 sim_->condition_reg_);
318 } else if (strcmp(arg1, "allf") == 0) {
319 for (int i = 0; i < DoubleRegister::kNumRegisters; i++) {
320 float fvalue = GetFPFloatRegisterValue(i);
321 uint32_t as_words = bit_cast<uint32_t>(fvalue);
322 PrintF("%3s: %f 0x%08x\n",
323 GetRegConfig()->GetDoubleRegisterName(i), fvalue,
324 as_words);
325 }
326 } else if (strcmp(arg1, "alld") == 0) {
327 for (int i = 0; i < DoubleRegister::kNumRegisters; i++) {
328 dvalue = GetFPDoubleRegisterValue(i);
329 uint64_t as_words = bit_cast<uint64_t>(dvalue);
330 PrintF("%3s: %f 0x%08x %08x\n",
331 GetRegConfig()->GetDoubleRegisterName(i), dvalue,
332 static_cast<uint32_t>(as_words >> 32),
333 static_cast<uint32_t>(as_words & 0xffffffff));
334 }
335 } else if (arg1[0] == 'r' &&
336 (arg1[1] >= '0' && arg1[1] <= '2' &&
337 (arg1[2] == '\0' || (arg1[2] >= '0' && arg1[2] <= '5' &&
338 arg1[3] == '\0')))) {
339 int regnum = strtoul(&arg1[1], 0, 10);
340 if (regnum != kNoRegister) {
341 value = GetRegisterValue(regnum);
342 PrintF("%s: 0x%08" V8PRIxPTR " %" V8PRIdPTR "\n", arg1, value,
343 value);
344 } else {
345 PrintF("%s unrecognized\n", arg1);
346 }
347 } else {
348 if (GetValue(arg1, &value)) {
349 PrintF("%s: 0x%08" V8PRIxPTR " %" V8PRIdPTR "\n", arg1, value,
350 value);
351 } else if (GetFPDoubleValue(arg1, &dvalue)) {
352 uint64_t as_words = bit_cast<uint64_t>(dvalue);
353 PrintF("%s: %f 0x%08x %08x\n", arg1, dvalue,
354 static_cast<uint32_t>(as_words >> 32),
355 static_cast<uint32_t>(as_words & 0xffffffff));
356 } else {
357 PrintF("%s unrecognized\n", arg1);
358 }
359 }
360 } else {
361 PrintF("print <register>\n");
362 }
363 } else if ((strcmp(cmd, "po") == 0) ||
364 (strcmp(cmd, "printobject") == 0)) {
365 if (argc == 2) {
366 intptr_t value;
367 OFStream os(stdout);
368 if (GetValue(arg1, &value)) {
369 Object* obj = reinterpret_cast<Object*>(value);
370 os << arg1 << ": \n";
371 #ifdef DEBUG
372 obj->Print(os);
373 os << "\n";
374 #else
375 os << Brief(obj) << "\n";
376 #endif
377 } else {
378 os << arg1 << " unrecognized\n";
379 }
380 } else {
381 PrintF("printobject <value>\n");
382 }
383 } else if (strcmp(cmd, "setpc") == 0) {
384 intptr_t value;
385
386 if (!GetValue(arg1, &value)) {
387 PrintF("%s unrecognized\n", arg1);
388 continue;
389 }
390 sim_->set_pc(value);
391 } else if (strcmp(cmd, "stack") == 0 || strcmp(cmd, "mem") == 0) {
392 intptr_t* cur = NULL;
393 intptr_t* end = NULL;
394 int next_arg = 1;
395
396 if (strcmp(cmd, "stack") == 0) {
397 cur = reinterpret_cast<intptr_t*>(sim_->get_register(Simulator::sp));
398 } else { // "mem"
399 intptr_t value;
400 if (!GetValue(arg1, &value)) {
401 PrintF("%s unrecognized\n", arg1);
402 continue;
403 }
404 cur = reinterpret_cast<intptr_t*>(value);
405 next_arg++;
406 }
407
408 intptr_t words; // likely inaccurate variable name for 64bit
409 if (argc == next_arg) {
410 words = 10;
411 } else {
412 if (!GetValue(argv[next_arg], &words)) {
413 words = 10;
414 }
415 }
416 end = cur + words;
417
418 while (cur < end) {
419 PrintF(" 0x%08" V8PRIxPTR ": 0x%08" V8PRIxPTR " %10" V8PRIdPTR,
420 reinterpret_cast<intptr_t>(cur), *cur, *cur);
421 HeapObject* obj = reinterpret_cast<HeapObject*>(*cur);
422 intptr_t value = *cur;
423 Heap* current_heap = sim_->isolate_->heap();
424 if (((value & 1) == 0) ||
425 current_heap->ContainsSlow(obj->address())) {
426 PrintF("(smi %d)", PlatformSmiTagging::SmiToInt(obj));
427 } else if (current_heap->Contains(obj)) {
428 PrintF(" (");
429 obj->ShortPrint();
430 PrintF(")");
431 }
432 PrintF("\n");
433 cur++;
434 }
435 } else if (strcmp(cmd, "disasm") == 0 || strcmp(cmd, "di") == 0) {
436 disasm::NameConverter converter;
437 disasm::Disassembler dasm(converter);
438 // use a reasonably large buffer
439 v8::internal::EmbeddedVector<char, 256> buffer;
440
441 byte* prev = NULL;
442 byte* cur = NULL;
443 // Default number of instructions to disassemble.
444 int32_t numInstructions = 10;
445
446 if (argc == 1) {
447 cur = reinterpret_cast<byte*>(sim_->get_pc());
448 } else if (argc == 2) {
449 int regnum = Registers::Number(arg1);
450 if (regnum != kNoRegister || strncmp(arg1, "0x", 2) == 0) {
451 // The argument is an address or a register name.
452 intptr_t value;
453 if (GetValue(arg1, &value)) {
454 cur = reinterpret_cast<byte*>(value);
455 }
456 } else {
457 // The argument is the number of instructions.
458 intptr_t value;
459 if (GetValue(arg1, &value)) {
460 cur = reinterpret_cast<byte*>(sim_->get_pc());
461 // Disassemble <arg1> instructions.
462 numInstructions = static_cast<int32_t>(value);
463 }
464 }
465 } else {
466 intptr_t value1;
467 intptr_t value2;
468 if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) {
469 cur = reinterpret_cast<byte*>(value1);
470 // Disassemble <arg2> instructions.
471 numInstructions = static_cast<int32_t>(value2);
472 }
473 }
474
475 while (numInstructions > 0) {
476 prev = cur;
477 cur += dasm.InstructionDecode(buffer, cur);
478 PrintF(" 0x%08" V8PRIxPTR " %s\n", reinterpret_cast<intptr_t>(prev),
479 buffer.start());
480 numInstructions--;
481 }
482 } else if (strcmp(cmd, "gdb") == 0) {
483 PrintF("relinquishing control to gdb\n");
484 v8::base::OS::DebugBreak();
485 PrintF("regaining control from gdb\n");
486 } else if (strcmp(cmd, "break") == 0) {
487 if (argc == 2) {
488 intptr_t value;
489 if (GetValue(arg1, &value)) {
490 if (!SetBreakpoint(reinterpret_cast<Instruction*>(value))) {
491 PrintF("setting breakpoint failed\n");
492 }
493 } else {
494 PrintF("%s unrecognized\n", arg1);
495 }
496 } else {
497 PrintF("break <address>\n");
498 }
499 } else if (strcmp(cmd, "del") == 0) {
500 if (!DeleteBreakpoint(NULL)) {
501 PrintF("deleting breakpoint failed\n");
502 }
503 } else if (strcmp(cmd, "cr") == 0) {
504 PrintF("Condition reg: %08x\n", sim_->condition_reg_);
505 } else if (strcmp(cmd, "stop") == 0) {
506 intptr_t value;
507 intptr_t stop_pc =
508 sim_->get_pc() - (sizeof(FourByteInstr) + kPointerSize);
509 Instruction* stop_instr = reinterpret_cast<Instruction*>(stop_pc);
510 Instruction* msg_address =
511 reinterpret_cast<Instruction*>(stop_pc + sizeof(FourByteInstr));
512 if ((argc == 2) && (strcmp(arg1, "unstop") == 0)) {
513 // Remove the current stop.
514 if (sim_->isStopInstruction(stop_instr)) {
515 stop_instr->SetInstructionBits(kNopInstr);
516 msg_address->SetInstructionBits(kNopInstr);
517 } else {
518 PrintF("Not at debugger stop.\n");
519 }
520 } else if (argc == 3) {
521 // Print information about all/the specified breakpoint(s).
522 if (strcmp(arg1, "info") == 0) {
523 if (strcmp(arg2, "all") == 0) {
524 PrintF("Stop information:\n");
525 for (uint32_t i = 0; i < sim_->kNumOfWatchedStops; i++) {
526 sim_->PrintStopInfo(i);
527 }
528 } else if (GetValue(arg2, &value)) {
529 sim_->PrintStopInfo(value);
530 } else {
531 PrintF("Unrecognized argument.\n");
532 }
533 } else if (strcmp(arg1, "enable") == 0) {
534 // Enable all/the specified breakpoint(s).
535 if (strcmp(arg2, "all") == 0) {
536 for (uint32_t i = 0; i < sim_->kNumOfWatchedStops; i++) {
537 sim_->EnableStop(i);
538 }
539 } else if (GetValue(arg2, &value)) {
540 sim_->EnableStop(value);
541 } else {
542 PrintF("Unrecognized argument.\n");
543 }
544 } else if (strcmp(arg1, "disable") == 0) {
545 // Disable all/the specified breakpoint(s).
546 if (strcmp(arg2, "all") == 0) {
547 for (uint32_t i = 0; i < sim_->kNumOfWatchedStops; i++) {
548 sim_->DisableStop(i);
549 }
550 } else if (GetValue(arg2, &value)) {
551 sim_->DisableStop(value);
552 } else {
553 PrintF("Unrecognized argument.\n");
554 }
555 }
556 } else {
557 PrintF("Wrong usage. Use help command for more information.\n");
558 }
559 } else if (strcmp(cmd, "icount") == 0) {
560 PrintF("%05" PRId64 "\n", sim_->icount_);
561 } else if ((strcmp(cmd, "t") == 0) || strcmp(cmd, "trace") == 0) {
562 ::v8::internal::FLAG_trace_sim = !::v8::internal::FLAG_trace_sim;
563 PrintF("Trace of executed instructions is %s\n",
564 ::v8::internal::FLAG_trace_sim ? "on" : "off");
565 } else if ((strcmp(cmd, "h") == 0) || (strcmp(cmd, "help") == 0)) {
566 PrintF("cont\n");
567 PrintF(" continue execution (alias 'c')\n");
568 PrintF("stepi [num instructions]\n");
569 PrintF(" step one/num instruction(s) (alias 'si')\n");
570 PrintF("print <register>\n");
571 PrintF(" print register content (alias 'p')\n");
572 PrintF(" use register name 'all' to display all integer registers\n");
573 PrintF(
574 " use register name 'alld' to display integer registers "
575 "with decimal values\n");
576 PrintF(" use register name 'rN' to display register number 'N'\n");
577 PrintF(" add argument 'fp' to print register pair double values\n");
578 PrintF(
579 " use register name 'allf' to display floating-point "
580 "registers\n");
581 PrintF("printobject <register>\n");
582 PrintF(" print an object from a register (alias 'po')\n");
583 PrintF("cr\n");
584 PrintF(" print condition register\n");
585 PrintF("stack [<num words>]\n");
586 PrintF(" dump stack content, default dump 10 words)\n");
587 PrintF("mem <address> [<num words>]\n");
588 PrintF(" dump memory content, default dump 10 words)\n");
589 PrintF("disasm [<instructions>]\n");
590 PrintF("disasm [<address/register>]\n");
591 PrintF("disasm [[<address/register>] <instructions>]\n");
592 PrintF(" disassemble code, default is 10 instructions\n");
593 PrintF(" from pc (alias 'di')\n");
594 PrintF("gdb\n");
595 PrintF(" enter gdb\n");
596 PrintF("break <address>\n");
597 PrintF(" set a break point on the address\n");
598 PrintF("del\n");
599 PrintF(" delete the breakpoint\n");
600 PrintF("trace (alias 't')\n");
601 PrintF(" toogle the tracing of all executed statements\n");
602 PrintF("stop feature:\n");
603 PrintF(" Description:\n");
604 PrintF(" Stops are debug instructions inserted by\n");
605 PrintF(" the Assembler::stop() function.\n");
606 PrintF(" When hitting a stop, the Simulator will\n");
607 PrintF(" stop and and give control to the S390Debugger.\n");
608 PrintF(" The first %d stop codes are watched:\n",
609 Simulator::kNumOfWatchedStops);
610 PrintF(" - They can be enabled / disabled: the Simulator\n");
611 PrintF(" will / won't stop when hitting them.\n");
612 PrintF(" - The Simulator keeps track of how many times they \n");
613 PrintF(" are met. (See the info command.) Going over a\n");
614 PrintF(" disabled stop still increases its counter. \n");
615 PrintF(" Commands:\n");
616 PrintF(" stop info all/<code> : print infos about number <code>\n");
617 PrintF(" or all stop(s).\n");
618 PrintF(" stop enable/disable all/<code> : enables / disables\n");
619 PrintF(" all or number <code> stop(s)\n");
620 PrintF(" stop unstop\n");
621 PrintF(" ignore the stop instruction at the current location\n");
622 PrintF(" from now on\n");
623 } else {
624 PrintF("Unknown command: %s\n", cmd);
625 }
626 }
627 }
628
629 // Add all the breakpoints back to stop execution and enter the debugger
630 // shell when hit.
631 RedoBreakpoints();
632 // Restore tracing
633 ::v8::internal::FLAG_trace_sim = trace;
634
635 #undef COMMAND_SIZE
636 #undef ARG_SIZE
637
638 #undef STR
639 #undef XSTR
640 }
641
ICacheMatch(void * one,void * two)642 static bool ICacheMatch(void* one, void* two) {
643 DCHECK((reinterpret_cast<intptr_t>(one) & CachePage::kPageMask) == 0);
644 DCHECK((reinterpret_cast<intptr_t>(two) & CachePage::kPageMask) == 0);
645 return one == two;
646 }
647
ICacheHash(void * key)648 static uint32_t ICacheHash(void* key) {
649 return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)) >> 2;
650 }
651
AllOnOnePage(uintptr_t start,int size)652 static bool AllOnOnePage(uintptr_t start, int size) {
653 intptr_t start_page = (start & ~CachePage::kPageMask);
654 intptr_t end_page = ((start + size) & ~CachePage::kPageMask);
655 return start_page == end_page;
656 }
657
set_last_debugger_input(char * input)658 void Simulator::set_last_debugger_input(char* input) {
659 DeleteArray(last_debugger_input_);
660 last_debugger_input_ = input;
661 }
662
FlushICache(base::CustomMatcherHashMap * i_cache,void * start_addr,size_t size)663 void Simulator::FlushICache(base::CustomMatcherHashMap* i_cache,
664 void* start_addr, size_t size) {
665 intptr_t start = reinterpret_cast<intptr_t>(start_addr);
666 int intra_line = (start & CachePage::kLineMask);
667 start -= intra_line;
668 size += intra_line;
669 size = ((size - 1) | CachePage::kLineMask) + 1;
670 int offset = (start & CachePage::kPageMask);
671 while (!AllOnOnePage(start, size - 1)) {
672 int bytes_to_flush = CachePage::kPageSize - offset;
673 FlushOnePage(i_cache, start, bytes_to_flush);
674 start += bytes_to_flush;
675 size -= bytes_to_flush;
676 DCHECK_EQ(0, static_cast<int>(start & CachePage::kPageMask));
677 offset = 0;
678 }
679 if (size != 0) {
680 FlushOnePage(i_cache, start, size);
681 }
682 }
683
GetCachePage(base::CustomMatcherHashMap * i_cache,void * page)684 CachePage* Simulator::GetCachePage(base::CustomMatcherHashMap* i_cache,
685 void* page) {
686 base::HashMap::Entry* entry = i_cache->LookupOrInsert(page, ICacheHash(page));
687 if (entry->value == NULL) {
688 CachePage* new_page = new CachePage();
689 entry->value = new_page;
690 }
691 return reinterpret_cast<CachePage*>(entry->value);
692 }
693
694 // Flush from start up to and not including start + size.
FlushOnePage(base::CustomMatcherHashMap * i_cache,intptr_t start,int size)695 void Simulator::FlushOnePage(base::CustomMatcherHashMap* i_cache,
696 intptr_t start, int size) {
697 DCHECK(size <= CachePage::kPageSize);
698 DCHECK(AllOnOnePage(start, size - 1));
699 DCHECK((start & CachePage::kLineMask) == 0);
700 DCHECK((size & CachePage::kLineMask) == 0);
701 void* page = reinterpret_cast<void*>(start & (~CachePage::kPageMask));
702 int offset = (start & CachePage::kPageMask);
703 CachePage* cache_page = GetCachePage(i_cache, page);
704 char* valid_bytemap = cache_page->ValidityByte(offset);
705 memset(valid_bytemap, CachePage::LINE_INVALID, size >> CachePage::kLineShift);
706 }
707
CheckICache(base::CustomMatcherHashMap * i_cache,Instruction * instr)708 void Simulator::CheckICache(base::CustomMatcherHashMap* i_cache,
709 Instruction* instr) {
710 intptr_t address = reinterpret_cast<intptr_t>(instr);
711 void* page = reinterpret_cast<void*>(address & (~CachePage::kPageMask));
712 void* line = reinterpret_cast<void*>(address & (~CachePage::kLineMask));
713 int offset = (address & CachePage::kPageMask);
714 CachePage* cache_page = GetCachePage(i_cache, page);
715 char* cache_valid_byte = cache_page->ValidityByte(offset);
716 bool cache_hit = (*cache_valid_byte == CachePage::LINE_VALID);
717 char* cached_line = cache_page->CachedData(offset & ~CachePage::kLineMask);
718 if (cache_hit) {
719 // Check that the data in memory matches the contents of the I-cache.
720 CHECK_EQ(memcmp(reinterpret_cast<void*>(instr),
721 cache_page->CachedData(offset), sizeof(FourByteInstr)),
722 0);
723 } else {
724 // Cache miss. Load memory into the cache.
725 memcpy(cached_line, line, CachePage::kLineLength);
726 *cache_valid_byte = CachePage::LINE_VALID;
727 }
728 }
729
Initialize(Isolate * isolate)730 void Simulator::Initialize(Isolate* isolate) {
731 if (isolate->simulator_initialized()) return;
732 isolate->set_simulator_initialized(true);
733 ::v8::internal::ExternalReference::set_redirector(isolate,
734 &RedirectExternalReference);
735 static base::OnceType once = V8_ONCE_INIT;
736 base::CallOnce(&once, &Simulator::EvalTableInit);
737 }
738
739 Simulator::EvaluateFuncType Simulator::EvalTable[] = {NULL};
740
EvalTableInit()741 void Simulator::EvalTableInit() {
742 for (int i = 0; i < MAX_NUM_OPCODES; i++) {
743 EvalTable[i] = &Simulator::Evaluate_Unknown;
744 }
745
746 #define S390_SUPPORTED_VECTOR_OPCODE_LIST(V) \
747 V(vfs, VFS, 0xE7E2) /* type = VRR_C VECTOR FP SUBTRACT */ \
748 V(vfa, VFA, 0xE7E3) /* type = VRR_C VECTOR FP ADD */ \
749 V(vfd, VFD, 0xE7E5) /* type = VRR_C VECTOR FP DIVIDE */ \
750 V(vfm, VFM, 0xE7E7) /* type = VRR_C VECTOR FP MULTIPLY */
751
752 #define CREATE_EVALUATE_TABLE(name, op_name, op_value) \
753 EvalTable[op_name] = &Simulator::Evaluate_##op_name;
754 S390_SUPPORTED_VECTOR_OPCODE_LIST(CREATE_EVALUATE_TABLE);
755 #undef CREATE_EVALUATE_TABLE
756
757 EvalTable[DUMY] = &Simulator::Evaluate_DUMY;
758 EvalTable[BKPT] = &Simulator::Evaluate_BKPT;
759 EvalTable[SPM] = &Simulator::Evaluate_SPM;
760 EvalTable[BALR] = &Simulator::Evaluate_BALR;
761 EvalTable[BCTR] = &Simulator::Evaluate_BCTR;
762 EvalTable[BCR] = &Simulator::Evaluate_BCR;
763 EvalTable[SVC] = &Simulator::Evaluate_SVC;
764 EvalTable[BSM] = &Simulator::Evaluate_BSM;
765 EvalTable[BASSM] = &Simulator::Evaluate_BASSM;
766 EvalTable[BASR] = &Simulator::Evaluate_BASR;
767 EvalTable[MVCL] = &Simulator::Evaluate_MVCL;
768 EvalTable[CLCL] = &Simulator::Evaluate_CLCL;
769 EvalTable[LPR] = &Simulator::Evaluate_LPR;
770 EvalTable[LNR] = &Simulator::Evaluate_LNR;
771 EvalTable[LTR] = &Simulator::Evaluate_LTR;
772 EvalTable[LCR] = &Simulator::Evaluate_LCR;
773 EvalTable[NR] = &Simulator::Evaluate_NR;
774 EvalTable[CLR] = &Simulator::Evaluate_CLR;
775 EvalTable[OR] = &Simulator::Evaluate_OR;
776 EvalTable[XR] = &Simulator::Evaluate_XR;
777 EvalTable[LR] = &Simulator::Evaluate_LR;
778 EvalTable[CR] = &Simulator::Evaluate_CR;
779 EvalTable[AR] = &Simulator::Evaluate_AR;
780 EvalTable[SR] = &Simulator::Evaluate_SR;
781 EvalTable[MR] = &Simulator::Evaluate_MR;
782 EvalTable[DR] = &Simulator::Evaluate_DR;
783 EvalTable[ALR] = &Simulator::Evaluate_ALR;
784 EvalTable[SLR] = &Simulator::Evaluate_SLR;
785 EvalTable[LDR] = &Simulator::Evaluate_LDR;
786 EvalTable[CDR] = &Simulator::Evaluate_CDR;
787 EvalTable[LER] = &Simulator::Evaluate_LER;
788 EvalTable[STH] = &Simulator::Evaluate_STH;
789 EvalTable[LA] = &Simulator::Evaluate_LA;
790 EvalTable[STC] = &Simulator::Evaluate_STC;
791 EvalTable[IC_z] = &Simulator::Evaluate_IC_z;
792 EvalTable[EX] = &Simulator::Evaluate_EX;
793 EvalTable[BAL] = &Simulator::Evaluate_BAL;
794 EvalTable[BCT] = &Simulator::Evaluate_BCT;
795 EvalTable[BC] = &Simulator::Evaluate_BC;
796 EvalTable[LH] = &Simulator::Evaluate_LH;
797 EvalTable[CH] = &Simulator::Evaluate_CH;
798 EvalTable[AH] = &Simulator::Evaluate_AH;
799 EvalTable[SH] = &Simulator::Evaluate_SH;
800 EvalTable[MH] = &Simulator::Evaluate_MH;
801 EvalTable[BAS] = &Simulator::Evaluate_BAS;
802 EvalTable[CVD] = &Simulator::Evaluate_CVD;
803 EvalTable[CVB] = &Simulator::Evaluate_CVB;
804 EvalTable[ST] = &Simulator::Evaluate_ST;
805 EvalTable[LAE] = &Simulator::Evaluate_LAE;
806 EvalTable[N] = &Simulator::Evaluate_N;
807 EvalTable[CL] = &Simulator::Evaluate_CL;
808 EvalTable[O] = &Simulator::Evaluate_O;
809 EvalTable[X] = &Simulator::Evaluate_X;
810 EvalTable[L] = &Simulator::Evaluate_L;
811 EvalTable[C] = &Simulator::Evaluate_C;
812 EvalTable[A] = &Simulator::Evaluate_A;
813 EvalTable[S] = &Simulator::Evaluate_S;
814 EvalTable[M] = &Simulator::Evaluate_M;
815 EvalTable[D] = &Simulator::Evaluate_D;
816 EvalTable[AL] = &Simulator::Evaluate_AL;
817 EvalTable[SL] = &Simulator::Evaluate_SL;
818 EvalTable[STD] = &Simulator::Evaluate_STD;
819 EvalTable[LD] = &Simulator::Evaluate_LD;
820 EvalTable[CD] = &Simulator::Evaluate_CD;
821 EvalTable[STE] = &Simulator::Evaluate_STE;
822 EvalTable[MS] = &Simulator::Evaluate_MS;
823 EvalTable[LE] = &Simulator::Evaluate_LE;
824 EvalTable[BRXH] = &Simulator::Evaluate_BRXH;
825 EvalTable[BRXLE] = &Simulator::Evaluate_BRXLE;
826 EvalTable[BXH] = &Simulator::Evaluate_BXH;
827 EvalTable[BXLE] = &Simulator::Evaluate_BXLE;
828 EvalTable[SRL] = &Simulator::Evaluate_SRL;
829 EvalTable[SLL] = &Simulator::Evaluate_SLL;
830 EvalTable[SRA] = &Simulator::Evaluate_SRA;
831 EvalTable[SLA] = &Simulator::Evaluate_SLA;
832 EvalTable[SRDL] = &Simulator::Evaluate_SRDL;
833 EvalTable[SLDL] = &Simulator::Evaluate_SLDL;
834 EvalTable[SRDA] = &Simulator::Evaluate_SRDA;
835 EvalTable[SLDA] = &Simulator::Evaluate_SLDA;
836 EvalTable[STM] = &Simulator::Evaluate_STM;
837 EvalTable[TM] = &Simulator::Evaluate_TM;
838 EvalTable[MVI] = &Simulator::Evaluate_MVI;
839 EvalTable[TS] = &Simulator::Evaluate_TS;
840 EvalTable[NI] = &Simulator::Evaluate_NI;
841 EvalTable[CLI] = &Simulator::Evaluate_CLI;
842 EvalTable[OI] = &Simulator::Evaluate_OI;
843 EvalTable[XI] = &Simulator::Evaluate_XI;
844 EvalTable[LM] = &Simulator::Evaluate_LM;
845 EvalTable[MVCLE] = &Simulator::Evaluate_MVCLE;
846 EvalTable[CLCLE] = &Simulator::Evaluate_CLCLE;
847 EvalTable[MC] = &Simulator::Evaluate_MC;
848 EvalTable[CDS] = &Simulator::Evaluate_CDS;
849 EvalTable[STCM] = &Simulator::Evaluate_STCM;
850 EvalTable[ICM] = &Simulator::Evaluate_ICM;
851 EvalTable[BPRP] = &Simulator::Evaluate_BPRP;
852 EvalTable[BPP] = &Simulator::Evaluate_BPP;
853 EvalTable[TRTR] = &Simulator::Evaluate_TRTR;
854 EvalTable[MVN] = &Simulator::Evaluate_MVN;
855 EvalTable[MVC] = &Simulator::Evaluate_MVC;
856 EvalTable[MVZ] = &Simulator::Evaluate_MVZ;
857 EvalTable[NC] = &Simulator::Evaluate_NC;
858 EvalTable[CLC] = &Simulator::Evaluate_CLC;
859 EvalTable[OC] = &Simulator::Evaluate_OC;
860 EvalTable[XC] = &Simulator::Evaluate_XC;
861 EvalTable[MVCP] = &Simulator::Evaluate_MVCP;
862 EvalTable[TR] = &Simulator::Evaluate_TR;
863 EvalTable[TRT] = &Simulator::Evaluate_TRT;
864 EvalTable[ED] = &Simulator::Evaluate_ED;
865 EvalTable[EDMK] = &Simulator::Evaluate_EDMK;
866 EvalTable[PKU] = &Simulator::Evaluate_PKU;
867 EvalTable[UNPKU] = &Simulator::Evaluate_UNPKU;
868 EvalTable[MVCIN] = &Simulator::Evaluate_MVCIN;
869 EvalTable[PKA] = &Simulator::Evaluate_PKA;
870 EvalTable[UNPKA] = &Simulator::Evaluate_UNPKA;
871 EvalTable[PLO] = &Simulator::Evaluate_PLO;
872 EvalTable[LMD] = &Simulator::Evaluate_LMD;
873 EvalTable[SRP] = &Simulator::Evaluate_SRP;
874 EvalTable[MVO] = &Simulator::Evaluate_MVO;
875 EvalTable[PACK] = &Simulator::Evaluate_PACK;
876 EvalTable[UNPK] = &Simulator::Evaluate_UNPK;
877 EvalTable[ZAP] = &Simulator::Evaluate_ZAP;
878 EvalTable[AP] = &Simulator::Evaluate_AP;
879 EvalTable[SP] = &Simulator::Evaluate_SP;
880 EvalTable[MP] = &Simulator::Evaluate_MP;
881 EvalTable[DP] = &Simulator::Evaluate_DP;
882 EvalTable[UPT] = &Simulator::Evaluate_UPT;
883 EvalTable[PFPO] = &Simulator::Evaluate_PFPO;
884 EvalTable[IIHH] = &Simulator::Evaluate_IIHH;
885 EvalTable[IIHL] = &Simulator::Evaluate_IIHL;
886 EvalTable[IILH] = &Simulator::Evaluate_IILH;
887 EvalTable[IILL] = &Simulator::Evaluate_IILL;
888 EvalTable[NIHH] = &Simulator::Evaluate_NIHH;
889 EvalTable[NIHL] = &Simulator::Evaluate_NIHL;
890 EvalTable[NILH] = &Simulator::Evaluate_NILH;
891 EvalTable[NILL] = &Simulator::Evaluate_NILL;
892 EvalTable[OIHH] = &Simulator::Evaluate_OIHH;
893 EvalTable[OIHL] = &Simulator::Evaluate_OIHL;
894 EvalTable[OILH] = &Simulator::Evaluate_OILH;
895 EvalTable[OILL] = &Simulator::Evaluate_OILL;
896 EvalTable[LLIHH] = &Simulator::Evaluate_LLIHH;
897 EvalTable[LLIHL] = &Simulator::Evaluate_LLIHL;
898 EvalTable[LLILH] = &Simulator::Evaluate_LLILH;
899 EvalTable[LLILL] = &Simulator::Evaluate_LLILL;
900 EvalTable[TMLH] = &Simulator::Evaluate_TMLH;
901 EvalTable[TMLL] = &Simulator::Evaluate_TMLL;
902 EvalTable[TMHH] = &Simulator::Evaluate_TMHH;
903 EvalTable[TMHL] = &Simulator::Evaluate_TMHL;
904 EvalTable[BRC] = &Simulator::Evaluate_BRC;
905 EvalTable[BRAS] = &Simulator::Evaluate_BRAS;
906 EvalTable[BRCT] = &Simulator::Evaluate_BRCT;
907 EvalTable[BRCTG] = &Simulator::Evaluate_BRCTG;
908 EvalTable[LHI] = &Simulator::Evaluate_LHI;
909 EvalTable[LGHI] = &Simulator::Evaluate_LGHI;
910 EvalTable[AHI] = &Simulator::Evaluate_AHI;
911 EvalTable[AGHI] = &Simulator::Evaluate_AGHI;
912 EvalTable[MHI] = &Simulator::Evaluate_MHI;
913 EvalTable[MGHI] = &Simulator::Evaluate_MGHI;
914 EvalTable[CHI] = &Simulator::Evaluate_CHI;
915 EvalTable[CGHI] = &Simulator::Evaluate_CGHI;
916 EvalTable[LARL] = &Simulator::Evaluate_LARL;
917 EvalTable[LGFI] = &Simulator::Evaluate_LGFI;
918 EvalTable[BRCL] = &Simulator::Evaluate_BRCL;
919 EvalTable[BRASL] = &Simulator::Evaluate_BRASL;
920 EvalTable[XIHF] = &Simulator::Evaluate_XIHF;
921 EvalTable[XILF] = &Simulator::Evaluate_XILF;
922 EvalTable[IIHF] = &Simulator::Evaluate_IIHF;
923 EvalTable[IILF] = &Simulator::Evaluate_IILF;
924 EvalTable[NIHF] = &Simulator::Evaluate_NIHF;
925 EvalTable[NILF] = &Simulator::Evaluate_NILF;
926 EvalTable[OIHF] = &Simulator::Evaluate_OIHF;
927 EvalTable[OILF] = &Simulator::Evaluate_OILF;
928 EvalTable[LLIHF] = &Simulator::Evaluate_LLIHF;
929 EvalTable[LLILF] = &Simulator::Evaluate_LLILF;
930 EvalTable[MSGFI] = &Simulator::Evaluate_MSGFI;
931 EvalTable[MSFI] = &Simulator::Evaluate_MSFI;
932 EvalTable[SLGFI] = &Simulator::Evaluate_SLGFI;
933 EvalTable[SLFI] = &Simulator::Evaluate_SLFI;
934 EvalTable[AGFI] = &Simulator::Evaluate_AGFI;
935 EvalTable[AFI] = &Simulator::Evaluate_AFI;
936 EvalTable[ALGFI] = &Simulator::Evaluate_ALGFI;
937 EvalTable[ALFI] = &Simulator::Evaluate_ALFI;
938 EvalTable[CGFI] = &Simulator::Evaluate_CGFI;
939 EvalTable[CFI] = &Simulator::Evaluate_CFI;
940 EvalTable[CLGFI] = &Simulator::Evaluate_CLGFI;
941 EvalTable[CLFI] = &Simulator::Evaluate_CLFI;
942 EvalTable[LLHRL] = &Simulator::Evaluate_LLHRL;
943 EvalTable[LGHRL] = &Simulator::Evaluate_LGHRL;
944 EvalTable[LHRL] = &Simulator::Evaluate_LHRL;
945 EvalTable[LLGHRL] = &Simulator::Evaluate_LLGHRL;
946 EvalTable[STHRL] = &Simulator::Evaluate_STHRL;
947 EvalTable[LGRL] = &Simulator::Evaluate_LGRL;
948 EvalTable[STGRL] = &Simulator::Evaluate_STGRL;
949 EvalTable[LGFRL] = &Simulator::Evaluate_LGFRL;
950 EvalTable[LRL] = &Simulator::Evaluate_LRL;
951 EvalTable[LLGFRL] = &Simulator::Evaluate_LLGFRL;
952 EvalTable[STRL] = &Simulator::Evaluate_STRL;
953 EvalTable[EXRL] = &Simulator::Evaluate_EXRL;
954 EvalTable[PFDRL] = &Simulator::Evaluate_PFDRL;
955 EvalTable[CGHRL] = &Simulator::Evaluate_CGHRL;
956 EvalTable[CHRL] = &Simulator::Evaluate_CHRL;
957 EvalTable[CGRL] = &Simulator::Evaluate_CGRL;
958 EvalTable[CGFRL] = &Simulator::Evaluate_CGFRL;
959 EvalTable[ECTG] = &Simulator::Evaluate_ECTG;
960 EvalTable[CSST] = &Simulator::Evaluate_CSST;
961 EvalTable[LPD] = &Simulator::Evaluate_LPD;
962 EvalTable[LPDG] = &Simulator::Evaluate_LPDG;
963 EvalTable[BRCTH] = &Simulator::Evaluate_BRCTH;
964 EvalTable[AIH] = &Simulator::Evaluate_AIH;
965 EvalTable[ALSIH] = &Simulator::Evaluate_ALSIH;
966 EvalTable[ALSIHN] = &Simulator::Evaluate_ALSIHN;
967 EvalTable[CIH] = &Simulator::Evaluate_CIH;
968 EvalTable[CLIH] = &Simulator::Evaluate_CLIH;
969 EvalTable[STCK] = &Simulator::Evaluate_STCK;
970 EvalTable[CFC] = &Simulator::Evaluate_CFC;
971 EvalTable[IPM] = &Simulator::Evaluate_IPM;
972 EvalTable[HSCH] = &Simulator::Evaluate_HSCH;
973 EvalTable[MSCH] = &Simulator::Evaluate_MSCH;
974 EvalTable[SSCH] = &Simulator::Evaluate_SSCH;
975 EvalTable[STSCH] = &Simulator::Evaluate_STSCH;
976 EvalTable[TSCH] = &Simulator::Evaluate_TSCH;
977 EvalTable[TPI] = &Simulator::Evaluate_TPI;
978 EvalTable[SAL] = &Simulator::Evaluate_SAL;
979 EvalTable[RSCH] = &Simulator::Evaluate_RSCH;
980 EvalTable[STCRW] = &Simulator::Evaluate_STCRW;
981 EvalTable[STCPS] = &Simulator::Evaluate_STCPS;
982 EvalTable[RCHP] = &Simulator::Evaluate_RCHP;
983 EvalTable[SCHM] = &Simulator::Evaluate_SCHM;
984 EvalTable[CKSM] = &Simulator::Evaluate_CKSM;
985 EvalTable[SAR] = &Simulator::Evaluate_SAR;
986 EvalTable[EAR] = &Simulator::Evaluate_EAR;
987 EvalTable[MSR] = &Simulator::Evaluate_MSR;
988 EvalTable[MSRKC] = &Simulator::Evaluate_MSRKC;
989 EvalTable[MVST] = &Simulator::Evaluate_MVST;
990 EvalTable[CUSE] = &Simulator::Evaluate_CUSE;
991 EvalTable[SRST] = &Simulator::Evaluate_SRST;
992 EvalTable[XSCH] = &Simulator::Evaluate_XSCH;
993 EvalTable[STCKE] = &Simulator::Evaluate_STCKE;
994 EvalTable[STCKF] = &Simulator::Evaluate_STCKF;
995 EvalTable[SRNM] = &Simulator::Evaluate_SRNM;
996 EvalTable[STFPC] = &Simulator::Evaluate_STFPC;
997 EvalTable[LFPC] = &Simulator::Evaluate_LFPC;
998 EvalTable[TRE] = &Simulator::Evaluate_TRE;
999 EvalTable[CUUTF] = &Simulator::Evaluate_CUUTF;
1000 EvalTable[CUTFU] = &Simulator::Evaluate_CUTFU;
1001 EvalTable[STFLE] = &Simulator::Evaluate_STFLE;
1002 EvalTable[SRNMB] = &Simulator::Evaluate_SRNMB;
1003 EvalTable[SRNMT] = &Simulator::Evaluate_SRNMT;
1004 EvalTable[LFAS] = &Simulator::Evaluate_LFAS;
1005 EvalTable[PPA] = &Simulator::Evaluate_PPA;
1006 EvalTable[ETND] = &Simulator::Evaluate_ETND;
1007 EvalTable[TEND] = &Simulator::Evaluate_TEND;
1008 EvalTable[NIAI] = &Simulator::Evaluate_NIAI;
1009 EvalTable[TABORT] = &Simulator::Evaluate_TABORT;
1010 EvalTable[TRAP4] = &Simulator::Evaluate_TRAP4;
1011 EvalTable[LPEBR] = &Simulator::Evaluate_LPEBR;
1012 EvalTable[LNEBR] = &Simulator::Evaluate_LNEBR;
1013 EvalTable[LTEBR] = &Simulator::Evaluate_LTEBR;
1014 EvalTable[LCEBR] = &Simulator::Evaluate_LCEBR;
1015 EvalTable[LDEBR] = &Simulator::Evaluate_LDEBR;
1016 EvalTable[LXDBR] = &Simulator::Evaluate_LXDBR;
1017 EvalTable[LXEBR] = &Simulator::Evaluate_LXEBR;
1018 EvalTable[MXDBR] = &Simulator::Evaluate_MXDBR;
1019 EvalTable[KEBR] = &Simulator::Evaluate_KEBR;
1020 EvalTable[CEBR] = &Simulator::Evaluate_CEBR;
1021 EvalTable[AEBR] = &Simulator::Evaluate_AEBR;
1022 EvalTable[SEBR] = &Simulator::Evaluate_SEBR;
1023 EvalTable[MDEBR] = &Simulator::Evaluate_MDEBR;
1024 EvalTable[DEBR] = &Simulator::Evaluate_DEBR;
1025 EvalTable[MAEBR] = &Simulator::Evaluate_MAEBR;
1026 EvalTable[MSEBR] = &Simulator::Evaluate_MSEBR;
1027 EvalTable[LPDBR] = &Simulator::Evaluate_LPDBR;
1028 EvalTable[LNDBR] = &Simulator::Evaluate_LNDBR;
1029 EvalTable[LTDBR] = &Simulator::Evaluate_LTDBR;
1030 EvalTable[LCDBR] = &Simulator::Evaluate_LCDBR;
1031 EvalTable[SQEBR] = &Simulator::Evaluate_SQEBR;
1032 EvalTable[SQDBR] = &Simulator::Evaluate_SQDBR;
1033 EvalTable[SQXBR] = &Simulator::Evaluate_SQXBR;
1034 EvalTable[MEEBR] = &Simulator::Evaluate_MEEBR;
1035 EvalTable[KDBR] = &Simulator::Evaluate_KDBR;
1036 EvalTable[CDBR] = &Simulator::Evaluate_CDBR;
1037 EvalTable[ADBR] = &Simulator::Evaluate_ADBR;
1038 EvalTable[SDBR] = &Simulator::Evaluate_SDBR;
1039 EvalTable[MDBR] = &Simulator::Evaluate_MDBR;
1040 EvalTable[DDBR] = &Simulator::Evaluate_DDBR;
1041 EvalTable[MADBR] = &Simulator::Evaluate_MADBR;
1042 EvalTable[MSDBR] = &Simulator::Evaluate_MSDBR;
1043 EvalTable[LPXBR] = &Simulator::Evaluate_LPXBR;
1044 EvalTable[LNXBR] = &Simulator::Evaluate_LNXBR;
1045 EvalTable[LTXBR] = &Simulator::Evaluate_LTXBR;
1046 EvalTable[LCXBR] = &Simulator::Evaluate_LCXBR;
1047 EvalTable[LEDBRA] = &Simulator::Evaluate_LEDBRA;
1048 EvalTable[LDXBRA] = &Simulator::Evaluate_LDXBRA;
1049 EvalTable[LEXBRA] = &Simulator::Evaluate_LEXBRA;
1050 EvalTable[FIXBRA] = &Simulator::Evaluate_FIXBRA;
1051 EvalTable[KXBR] = &Simulator::Evaluate_KXBR;
1052 EvalTable[CXBR] = &Simulator::Evaluate_CXBR;
1053 EvalTable[AXBR] = &Simulator::Evaluate_AXBR;
1054 EvalTable[SXBR] = &Simulator::Evaluate_SXBR;
1055 EvalTable[MXBR] = &Simulator::Evaluate_MXBR;
1056 EvalTable[DXBR] = &Simulator::Evaluate_DXBR;
1057 EvalTable[TBEDR] = &Simulator::Evaluate_TBEDR;
1058 EvalTable[TBDR] = &Simulator::Evaluate_TBDR;
1059 EvalTable[DIEBR] = &Simulator::Evaluate_DIEBR;
1060 EvalTable[FIEBRA] = &Simulator::Evaluate_FIEBRA;
1061 EvalTable[THDER] = &Simulator::Evaluate_THDER;
1062 EvalTable[THDR] = &Simulator::Evaluate_THDR;
1063 EvalTable[DIDBR] = &Simulator::Evaluate_DIDBR;
1064 EvalTable[FIDBRA] = &Simulator::Evaluate_FIDBRA;
1065 EvalTable[LXR] = &Simulator::Evaluate_LXR;
1066 EvalTable[LPDFR] = &Simulator::Evaluate_LPDFR;
1067 EvalTable[LNDFR] = &Simulator::Evaluate_LNDFR;
1068 EvalTable[LCDFR] = &Simulator::Evaluate_LCDFR;
1069 EvalTable[LZER] = &Simulator::Evaluate_LZER;
1070 EvalTable[LZDR] = &Simulator::Evaluate_LZDR;
1071 EvalTable[LZXR] = &Simulator::Evaluate_LZXR;
1072 EvalTable[SFPC] = &Simulator::Evaluate_SFPC;
1073 EvalTable[SFASR] = &Simulator::Evaluate_SFASR;
1074 EvalTable[EFPC] = &Simulator::Evaluate_EFPC;
1075 EvalTable[CELFBR] = &Simulator::Evaluate_CELFBR;
1076 EvalTable[CDLFBR] = &Simulator::Evaluate_CDLFBR;
1077 EvalTable[CXLFBR] = &Simulator::Evaluate_CXLFBR;
1078 EvalTable[CEFBRA] = &Simulator::Evaluate_CEFBRA;
1079 EvalTable[CDFBRA] = &Simulator::Evaluate_CDFBRA;
1080 EvalTable[CXFBRA] = &Simulator::Evaluate_CXFBRA;
1081 EvalTable[CFEBRA] = &Simulator::Evaluate_CFEBRA;
1082 EvalTable[CFDBRA] = &Simulator::Evaluate_CFDBRA;
1083 EvalTable[CFXBRA] = &Simulator::Evaluate_CFXBRA;
1084 EvalTable[CLFEBR] = &Simulator::Evaluate_CLFEBR;
1085 EvalTable[CLFDBR] = &Simulator::Evaluate_CLFDBR;
1086 EvalTable[CLFXBR] = &Simulator::Evaluate_CLFXBR;
1087 EvalTable[CELGBR] = &Simulator::Evaluate_CELGBR;
1088 EvalTable[CDLGBR] = &Simulator::Evaluate_CDLGBR;
1089 EvalTable[CXLGBR] = &Simulator::Evaluate_CXLGBR;
1090 EvalTable[CEGBRA] = &Simulator::Evaluate_CEGBRA;
1091 EvalTable[CDGBRA] = &Simulator::Evaluate_CDGBRA;
1092 EvalTable[CXGBRA] = &Simulator::Evaluate_CXGBRA;
1093 EvalTable[CGEBRA] = &Simulator::Evaluate_CGEBRA;
1094 EvalTable[CGDBRA] = &Simulator::Evaluate_CGDBRA;
1095 EvalTable[CGXBRA] = &Simulator::Evaluate_CGXBRA;
1096 EvalTable[CLGEBR] = &Simulator::Evaluate_CLGEBR;
1097 EvalTable[CLGDBR] = &Simulator::Evaluate_CLGDBR;
1098 EvalTable[CFER] = &Simulator::Evaluate_CFER;
1099 EvalTable[CFDR] = &Simulator::Evaluate_CFDR;
1100 EvalTable[CFXR] = &Simulator::Evaluate_CFXR;
1101 EvalTable[LDGR] = &Simulator::Evaluate_LDGR;
1102 EvalTable[CGER] = &Simulator::Evaluate_CGER;
1103 EvalTable[CGDR] = &Simulator::Evaluate_CGDR;
1104 EvalTable[CGXR] = &Simulator::Evaluate_CGXR;
1105 EvalTable[LGDR] = &Simulator::Evaluate_LGDR;
1106 EvalTable[MDTR] = &Simulator::Evaluate_MDTR;
1107 EvalTable[MDTRA] = &Simulator::Evaluate_MDTRA;
1108 EvalTable[DDTRA] = &Simulator::Evaluate_DDTRA;
1109 EvalTable[ADTRA] = &Simulator::Evaluate_ADTRA;
1110 EvalTable[SDTRA] = &Simulator::Evaluate_SDTRA;
1111 EvalTable[LDETR] = &Simulator::Evaluate_LDETR;
1112 EvalTable[LEDTR] = &Simulator::Evaluate_LEDTR;
1113 EvalTable[LTDTR] = &Simulator::Evaluate_LTDTR;
1114 EvalTable[FIDTR] = &Simulator::Evaluate_FIDTR;
1115 EvalTable[MXTRA] = &Simulator::Evaluate_MXTRA;
1116 EvalTable[DXTRA] = &Simulator::Evaluate_DXTRA;
1117 EvalTable[AXTRA] = &Simulator::Evaluate_AXTRA;
1118 EvalTable[SXTRA] = &Simulator::Evaluate_SXTRA;
1119 EvalTable[LXDTR] = &Simulator::Evaluate_LXDTR;
1120 EvalTable[LDXTR] = &Simulator::Evaluate_LDXTR;
1121 EvalTable[LTXTR] = &Simulator::Evaluate_LTXTR;
1122 EvalTable[FIXTR] = &Simulator::Evaluate_FIXTR;
1123 EvalTable[KDTR] = &Simulator::Evaluate_KDTR;
1124 EvalTable[CGDTRA] = &Simulator::Evaluate_CGDTRA;
1125 EvalTable[CUDTR] = &Simulator::Evaluate_CUDTR;
1126 EvalTable[CDTR] = &Simulator::Evaluate_CDTR;
1127 EvalTable[EEDTR] = &Simulator::Evaluate_EEDTR;
1128 EvalTable[ESDTR] = &Simulator::Evaluate_ESDTR;
1129 EvalTable[KXTR] = &Simulator::Evaluate_KXTR;
1130 EvalTable[CGXTRA] = &Simulator::Evaluate_CGXTRA;
1131 EvalTable[CUXTR] = &Simulator::Evaluate_CUXTR;
1132 EvalTable[CSXTR] = &Simulator::Evaluate_CSXTR;
1133 EvalTable[CXTR] = &Simulator::Evaluate_CXTR;
1134 EvalTable[EEXTR] = &Simulator::Evaluate_EEXTR;
1135 EvalTable[ESXTR] = &Simulator::Evaluate_ESXTR;
1136 EvalTable[CDGTRA] = &Simulator::Evaluate_CDGTRA;
1137 EvalTable[CDUTR] = &Simulator::Evaluate_CDUTR;
1138 EvalTable[CDSTR] = &Simulator::Evaluate_CDSTR;
1139 EvalTable[CEDTR] = &Simulator::Evaluate_CEDTR;
1140 EvalTable[QADTR] = &Simulator::Evaluate_QADTR;
1141 EvalTable[IEDTR] = &Simulator::Evaluate_IEDTR;
1142 EvalTable[RRDTR] = &Simulator::Evaluate_RRDTR;
1143 EvalTable[CXGTRA] = &Simulator::Evaluate_CXGTRA;
1144 EvalTable[CXUTR] = &Simulator::Evaluate_CXUTR;
1145 EvalTable[CXSTR] = &Simulator::Evaluate_CXSTR;
1146 EvalTable[CEXTR] = &Simulator::Evaluate_CEXTR;
1147 EvalTable[QAXTR] = &Simulator::Evaluate_QAXTR;
1148 EvalTable[IEXTR] = &Simulator::Evaluate_IEXTR;
1149 EvalTable[RRXTR] = &Simulator::Evaluate_RRXTR;
1150 EvalTable[LPGR] = &Simulator::Evaluate_LPGR;
1151 EvalTable[LNGR] = &Simulator::Evaluate_LNGR;
1152 EvalTable[LTGR] = &Simulator::Evaluate_LTGR;
1153 EvalTable[LCGR] = &Simulator::Evaluate_LCGR;
1154 EvalTable[LGR] = &Simulator::Evaluate_LGR;
1155 EvalTable[LGBR] = &Simulator::Evaluate_LGBR;
1156 EvalTable[LGHR] = &Simulator::Evaluate_LGHR;
1157 EvalTable[AGR] = &Simulator::Evaluate_AGR;
1158 EvalTable[SGR] = &Simulator::Evaluate_SGR;
1159 EvalTable[ALGR] = &Simulator::Evaluate_ALGR;
1160 EvalTable[SLGR] = &Simulator::Evaluate_SLGR;
1161 EvalTable[MSGR] = &Simulator::Evaluate_MSGR;
1162 EvalTable[MSGRKC] = &Simulator::Evaluate_MSGRKC;
1163 EvalTable[DSGR] = &Simulator::Evaluate_DSGR;
1164 EvalTable[LRVGR] = &Simulator::Evaluate_LRVGR;
1165 EvalTable[LPGFR] = &Simulator::Evaluate_LPGFR;
1166 EvalTable[LNGFR] = &Simulator::Evaluate_LNGFR;
1167 EvalTable[LTGFR] = &Simulator::Evaluate_LTGFR;
1168 EvalTable[LCGFR] = &Simulator::Evaluate_LCGFR;
1169 EvalTable[LGFR] = &Simulator::Evaluate_LGFR;
1170 EvalTable[LLGFR] = &Simulator::Evaluate_LLGFR;
1171 EvalTable[LLGTR] = &Simulator::Evaluate_LLGTR;
1172 EvalTable[AGFR] = &Simulator::Evaluate_AGFR;
1173 EvalTable[SGFR] = &Simulator::Evaluate_SGFR;
1174 EvalTable[ALGFR] = &Simulator::Evaluate_ALGFR;
1175 EvalTable[SLGFR] = &Simulator::Evaluate_SLGFR;
1176 EvalTable[MSGFR] = &Simulator::Evaluate_MSGFR;
1177 EvalTable[DSGFR] = &Simulator::Evaluate_DSGFR;
1178 EvalTable[KMAC] = &Simulator::Evaluate_KMAC;
1179 EvalTable[LRVR] = &Simulator::Evaluate_LRVR;
1180 EvalTable[CGR] = &Simulator::Evaluate_CGR;
1181 EvalTable[CLGR] = &Simulator::Evaluate_CLGR;
1182 EvalTable[LBR] = &Simulator::Evaluate_LBR;
1183 EvalTable[LHR] = &Simulator::Evaluate_LHR;
1184 EvalTable[KMF] = &Simulator::Evaluate_KMF;
1185 EvalTable[KMO] = &Simulator::Evaluate_KMO;
1186 EvalTable[PCC] = &Simulator::Evaluate_PCC;
1187 EvalTable[KMCTR] = &Simulator::Evaluate_KMCTR;
1188 EvalTable[KM] = &Simulator::Evaluate_KM;
1189 EvalTable[KMC] = &Simulator::Evaluate_KMC;
1190 EvalTable[CGFR] = &Simulator::Evaluate_CGFR;
1191 EvalTable[KIMD] = &Simulator::Evaluate_KIMD;
1192 EvalTable[KLMD] = &Simulator::Evaluate_KLMD;
1193 EvalTable[CFDTR] = &Simulator::Evaluate_CFDTR;
1194 EvalTable[CLGDTR] = &Simulator::Evaluate_CLGDTR;
1195 EvalTable[CLFDTR] = &Simulator::Evaluate_CLFDTR;
1196 EvalTable[BCTGR] = &Simulator::Evaluate_BCTGR;
1197 EvalTable[CFXTR] = &Simulator::Evaluate_CFXTR;
1198 EvalTable[CLFXTR] = &Simulator::Evaluate_CLFXTR;
1199 EvalTable[CDFTR] = &Simulator::Evaluate_CDFTR;
1200 EvalTable[CDLGTR] = &Simulator::Evaluate_CDLGTR;
1201 EvalTable[CDLFTR] = &Simulator::Evaluate_CDLFTR;
1202 EvalTable[CXFTR] = &Simulator::Evaluate_CXFTR;
1203 EvalTable[CXLGTR] = &Simulator::Evaluate_CXLGTR;
1204 EvalTable[CXLFTR] = &Simulator::Evaluate_CXLFTR;
1205 EvalTable[CGRT] = &Simulator::Evaluate_CGRT;
1206 EvalTable[NGR] = &Simulator::Evaluate_NGR;
1207 EvalTable[OGR] = &Simulator::Evaluate_OGR;
1208 EvalTable[XGR] = &Simulator::Evaluate_XGR;
1209 EvalTable[FLOGR] = &Simulator::Evaluate_FLOGR;
1210 EvalTable[LLGCR] = &Simulator::Evaluate_LLGCR;
1211 EvalTable[LLGHR] = &Simulator::Evaluate_LLGHR;
1212 EvalTable[MLGR] = &Simulator::Evaluate_MLGR;
1213 EvalTable[DLGR] = &Simulator::Evaluate_DLGR;
1214 EvalTable[ALCGR] = &Simulator::Evaluate_ALCGR;
1215 EvalTable[SLBGR] = &Simulator::Evaluate_SLBGR;
1216 EvalTable[EPSW] = &Simulator::Evaluate_EPSW;
1217 EvalTable[TRTT] = &Simulator::Evaluate_TRTT;
1218 EvalTable[TRTO] = &Simulator::Evaluate_TRTO;
1219 EvalTable[TROT] = &Simulator::Evaluate_TROT;
1220 EvalTable[TROO] = &Simulator::Evaluate_TROO;
1221 EvalTable[LLCR] = &Simulator::Evaluate_LLCR;
1222 EvalTable[LLHR] = &Simulator::Evaluate_LLHR;
1223 EvalTable[MLR] = &Simulator::Evaluate_MLR;
1224 EvalTable[DLR] = &Simulator::Evaluate_DLR;
1225 EvalTable[ALCR] = &Simulator::Evaluate_ALCR;
1226 EvalTable[SLBR] = &Simulator::Evaluate_SLBR;
1227 EvalTable[CU14] = &Simulator::Evaluate_CU14;
1228 EvalTable[CU24] = &Simulator::Evaluate_CU24;
1229 EvalTable[CU41] = &Simulator::Evaluate_CU41;
1230 EvalTable[CU42] = &Simulator::Evaluate_CU42;
1231 EvalTable[TRTRE] = &Simulator::Evaluate_TRTRE;
1232 EvalTable[SRSTU] = &Simulator::Evaluate_SRSTU;
1233 EvalTable[TRTE] = &Simulator::Evaluate_TRTE;
1234 EvalTable[AHHHR] = &Simulator::Evaluate_AHHHR;
1235 EvalTable[SHHHR] = &Simulator::Evaluate_SHHHR;
1236 EvalTable[ALHHHR] = &Simulator::Evaluate_ALHHHR;
1237 EvalTable[SLHHHR] = &Simulator::Evaluate_SLHHHR;
1238 EvalTable[CHHR] = &Simulator::Evaluate_CHHR;
1239 EvalTable[AHHLR] = &Simulator::Evaluate_AHHLR;
1240 EvalTable[SHHLR] = &Simulator::Evaluate_SHHLR;
1241 EvalTable[ALHHLR] = &Simulator::Evaluate_ALHHLR;
1242 EvalTable[SLHHLR] = &Simulator::Evaluate_SLHHLR;
1243 EvalTable[CHLR] = &Simulator::Evaluate_CHLR;
1244 EvalTable[POPCNT_Z] = &Simulator::Evaluate_POPCNT_Z;
1245 EvalTable[LOCGR] = &Simulator::Evaluate_LOCGR;
1246 EvalTable[NGRK] = &Simulator::Evaluate_NGRK;
1247 EvalTable[OGRK] = &Simulator::Evaluate_OGRK;
1248 EvalTable[XGRK] = &Simulator::Evaluate_XGRK;
1249 EvalTable[AGRK] = &Simulator::Evaluate_AGRK;
1250 EvalTable[SGRK] = &Simulator::Evaluate_SGRK;
1251 EvalTable[ALGRK] = &Simulator::Evaluate_ALGRK;
1252 EvalTable[SLGRK] = &Simulator::Evaluate_SLGRK;
1253 EvalTable[LOCR] = &Simulator::Evaluate_LOCR;
1254 EvalTable[NRK] = &Simulator::Evaluate_NRK;
1255 EvalTable[ORK] = &Simulator::Evaluate_ORK;
1256 EvalTable[XRK] = &Simulator::Evaluate_XRK;
1257 EvalTable[ARK] = &Simulator::Evaluate_ARK;
1258 EvalTable[SRK] = &Simulator::Evaluate_SRK;
1259 EvalTable[ALRK] = &Simulator::Evaluate_ALRK;
1260 EvalTable[SLRK] = &Simulator::Evaluate_SLRK;
1261 EvalTable[LTG] = &Simulator::Evaluate_LTG;
1262 EvalTable[LG] = &Simulator::Evaluate_LG;
1263 EvalTable[CVBY] = &Simulator::Evaluate_CVBY;
1264 EvalTable[AG] = &Simulator::Evaluate_AG;
1265 EvalTable[SG] = &Simulator::Evaluate_SG;
1266 EvalTable[ALG] = &Simulator::Evaluate_ALG;
1267 EvalTable[SLG] = &Simulator::Evaluate_SLG;
1268 EvalTable[MSG] = &Simulator::Evaluate_MSG;
1269 EvalTable[DSG] = &Simulator::Evaluate_DSG;
1270 EvalTable[CVBG] = &Simulator::Evaluate_CVBG;
1271 EvalTable[LRVG] = &Simulator::Evaluate_LRVG;
1272 EvalTable[LT] = &Simulator::Evaluate_LT;
1273 EvalTable[LGF] = &Simulator::Evaluate_LGF;
1274 EvalTable[LGH] = &Simulator::Evaluate_LGH;
1275 EvalTable[LLGF] = &Simulator::Evaluate_LLGF;
1276 EvalTable[LLGT] = &Simulator::Evaluate_LLGT;
1277 EvalTable[AGF] = &Simulator::Evaluate_AGF;
1278 EvalTable[SGF] = &Simulator::Evaluate_SGF;
1279 EvalTable[ALGF] = &Simulator::Evaluate_ALGF;
1280 EvalTable[SLGF] = &Simulator::Evaluate_SLGF;
1281 EvalTable[MSGF] = &Simulator::Evaluate_MSGF;
1282 EvalTable[DSGF] = &Simulator::Evaluate_DSGF;
1283 EvalTable[LRV] = &Simulator::Evaluate_LRV;
1284 EvalTable[LRVH] = &Simulator::Evaluate_LRVH;
1285 EvalTable[CG] = &Simulator::Evaluate_CG;
1286 EvalTable[CLG] = &Simulator::Evaluate_CLG;
1287 EvalTable[STG] = &Simulator::Evaluate_STG;
1288 EvalTable[NTSTG] = &Simulator::Evaluate_NTSTG;
1289 EvalTable[CVDY] = &Simulator::Evaluate_CVDY;
1290 EvalTable[CVDG] = &Simulator::Evaluate_CVDG;
1291 EvalTable[STRVG] = &Simulator::Evaluate_STRVG;
1292 EvalTable[CGF] = &Simulator::Evaluate_CGF;
1293 EvalTable[CLGF] = &Simulator::Evaluate_CLGF;
1294 EvalTable[LTGF] = &Simulator::Evaluate_LTGF;
1295 EvalTable[CGH] = &Simulator::Evaluate_CGH;
1296 EvalTable[PFD] = &Simulator::Evaluate_PFD;
1297 EvalTable[STRV] = &Simulator::Evaluate_STRV;
1298 EvalTable[STRVH] = &Simulator::Evaluate_STRVH;
1299 EvalTable[BCTG] = &Simulator::Evaluate_BCTG;
1300 EvalTable[STY] = &Simulator::Evaluate_STY;
1301 EvalTable[MSY] = &Simulator::Evaluate_MSY;
1302 EvalTable[NY] = &Simulator::Evaluate_NY;
1303 EvalTable[CLY] = &Simulator::Evaluate_CLY;
1304 EvalTable[OY] = &Simulator::Evaluate_OY;
1305 EvalTable[XY] = &Simulator::Evaluate_XY;
1306 EvalTable[LY] = &Simulator::Evaluate_LY;
1307 EvalTable[CY] = &Simulator::Evaluate_CY;
1308 EvalTable[AY] = &Simulator::Evaluate_AY;
1309 EvalTable[SY] = &Simulator::Evaluate_SY;
1310 EvalTable[MFY] = &Simulator::Evaluate_MFY;
1311 EvalTable[ALY] = &Simulator::Evaluate_ALY;
1312 EvalTable[SLY] = &Simulator::Evaluate_SLY;
1313 EvalTable[STHY] = &Simulator::Evaluate_STHY;
1314 EvalTable[LAY] = &Simulator::Evaluate_LAY;
1315 EvalTable[STCY] = &Simulator::Evaluate_STCY;
1316 EvalTable[ICY] = &Simulator::Evaluate_ICY;
1317 EvalTable[LAEY] = &Simulator::Evaluate_LAEY;
1318 EvalTable[LB] = &Simulator::Evaluate_LB;
1319 EvalTable[LGB] = &Simulator::Evaluate_LGB;
1320 EvalTable[LHY] = &Simulator::Evaluate_LHY;
1321 EvalTable[CHY] = &Simulator::Evaluate_CHY;
1322 EvalTable[AHY] = &Simulator::Evaluate_AHY;
1323 EvalTable[SHY] = &Simulator::Evaluate_SHY;
1324 EvalTable[MHY] = &Simulator::Evaluate_MHY;
1325 EvalTable[NG] = &Simulator::Evaluate_NG;
1326 EvalTable[OG] = &Simulator::Evaluate_OG;
1327 EvalTable[XG] = &Simulator::Evaluate_XG;
1328 EvalTable[LGAT] = &Simulator::Evaluate_LGAT;
1329 EvalTable[MLG] = &Simulator::Evaluate_MLG;
1330 EvalTable[DLG] = &Simulator::Evaluate_DLG;
1331 EvalTable[ALCG] = &Simulator::Evaluate_ALCG;
1332 EvalTable[SLBG] = &Simulator::Evaluate_SLBG;
1333 EvalTable[STPQ] = &Simulator::Evaluate_STPQ;
1334 EvalTable[LPQ] = &Simulator::Evaluate_LPQ;
1335 EvalTable[LLGC] = &Simulator::Evaluate_LLGC;
1336 EvalTable[LLGH] = &Simulator::Evaluate_LLGH;
1337 EvalTable[LLC] = &Simulator::Evaluate_LLC;
1338 EvalTable[LLH] = &Simulator::Evaluate_LLH;
1339 EvalTable[ML] = &Simulator::Evaluate_ML;
1340 EvalTable[DL] = &Simulator::Evaluate_DL;
1341 EvalTable[ALC] = &Simulator::Evaluate_ALC;
1342 EvalTable[SLB] = &Simulator::Evaluate_SLB;
1343 EvalTable[LLGTAT] = &Simulator::Evaluate_LLGTAT;
1344 EvalTable[LLGFAT] = &Simulator::Evaluate_LLGFAT;
1345 EvalTable[LAT] = &Simulator::Evaluate_LAT;
1346 EvalTable[LBH] = &Simulator::Evaluate_LBH;
1347 EvalTable[LLCH] = &Simulator::Evaluate_LLCH;
1348 EvalTable[STCH] = &Simulator::Evaluate_STCH;
1349 EvalTable[LHH] = &Simulator::Evaluate_LHH;
1350 EvalTable[LLHH] = &Simulator::Evaluate_LLHH;
1351 EvalTable[STHH] = &Simulator::Evaluate_STHH;
1352 EvalTable[LFHAT] = &Simulator::Evaluate_LFHAT;
1353 EvalTable[LFH] = &Simulator::Evaluate_LFH;
1354 EvalTable[STFH] = &Simulator::Evaluate_STFH;
1355 EvalTable[CHF] = &Simulator::Evaluate_CHF;
1356 EvalTable[MVCDK] = &Simulator::Evaluate_MVCDK;
1357 EvalTable[MVHHI] = &Simulator::Evaluate_MVHHI;
1358 EvalTable[MVGHI] = &Simulator::Evaluate_MVGHI;
1359 EvalTable[MVHI] = &Simulator::Evaluate_MVHI;
1360 EvalTable[CHHSI] = &Simulator::Evaluate_CHHSI;
1361 EvalTable[CGHSI] = &Simulator::Evaluate_CGHSI;
1362 EvalTable[CHSI] = &Simulator::Evaluate_CHSI;
1363 EvalTable[CLFHSI] = &Simulator::Evaluate_CLFHSI;
1364 EvalTable[TBEGIN] = &Simulator::Evaluate_TBEGIN;
1365 EvalTable[TBEGINC] = &Simulator::Evaluate_TBEGINC;
1366 EvalTable[LMG] = &Simulator::Evaluate_LMG;
1367 EvalTable[SRAG] = &Simulator::Evaluate_SRAG;
1368 EvalTable[SLAG] = &Simulator::Evaluate_SLAG;
1369 EvalTable[SRLG] = &Simulator::Evaluate_SRLG;
1370 EvalTable[SLLG] = &Simulator::Evaluate_SLLG;
1371 EvalTable[CSY] = &Simulator::Evaluate_CSY;
1372 EvalTable[RLLG] = &Simulator::Evaluate_RLLG;
1373 EvalTable[RLL] = &Simulator::Evaluate_RLL;
1374 EvalTable[STMG] = &Simulator::Evaluate_STMG;
1375 EvalTable[STMH] = &Simulator::Evaluate_STMH;
1376 EvalTable[STCMH] = &Simulator::Evaluate_STCMH;
1377 EvalTable[STCMY] = &Simulator::Evaluate_STCMY;
1378 EvalTable[CDSY] = &Simulator::Evaluate_CDSY;
1379 EvalTable[CDSG] = &Simulator::Evaluate_CDSG;
1380 EvalTable[BXHG] = &Simulator::Evaluate_BXHG;
1381 EvalTable[BXLEG] = &Simulator::Evaluate_BXLEG;
1382 EvalTable[ECAG] = &Simulator::Evaluate_ECAG;
1383 EvalTable[TMY] = &Simulator::Evaluate_TMY;
1384 EvalTable[MVIY] = &Simulator::Evaluate_MVIY;
1385 EvalTable[NIY] = &Simulator::Evaluate_NIY;
1386 EvalTable[CLIY] = &Simulator::Evaluate_CLIY;
1387 EvalTable[OIY] = &Simulator::Evaluate_OIY;
1388 EvalTable[XIY] = &Simulator::Evaluate_XIY;
1389 EvalTable[ASI] = &Simulator::Evaluate_ASI;
1390 EvalTable[ALSI] = &Simulator::Evaluate_ALSI;
1391 EvalTable[AGSI] = &Simulator::Evaluate_AGSI;
1392 EvalTable[ALGSI] = &Simulator::Evaluate_ALGSI;
1393 EvalTable[ICMH] = &Simulator::Evaluate_ICMH;
1394 EvalTable[ICMY] = &Simulator::Evaluate_ICMY;
1395 EvalTable[MVCLU] = &Simulator::Evaluate_MVCLU;
1396 EvalTable[CLCLU] = &Simulator::Evaluate_CLCLU;
1397 EvalTable[STMY] = &Simulator::Evaluate_STMY;
1398 EvalTable[LMH] = &Simulator::Evaluate_LMH;
1399 EvalTable[LMY] = &Simulator::Evaluate_LMY;
1400 EvalTable[TP] = &Simulator::Evaluate_TP;
1401 EvalTable[SRAK] = &Simulator::Evaluate_SRAK;
1402 EvalTable[SLAK] = &Simulator::Evaluate_SLAK;
1403 EvalTable[SRLK] = &Simulator::Evaluate_SRLK;
1404 EvalTable[SLLK] = &Simulator::Evaluate_SLLK;
1405 EvalTable[LOCG] = &Simulator::Evaluate_LOCG;
1406 EvalTable[STOCG] = &Simulator::Evaluate_STOCG;
1407 EvalTable[LANG] = &Simulator::Evaluate_LANG;
1408 EvalTable[LAOG] = &Simulator::Evaluate_LAOG;
1409 EvalTable[LAXG] = &Simulator::Evaluate_LAXG;
1410 EvalTable[LAAG] = &Simulator::Evaluate_LAAG;
1411 EvalTable[LAALG] = &Simulator::Evaluate_LAALG;
1412 EvalTable[LOC] = &Simulator::Evaluate_LOC;
1413 EvalTable[STOC] = &Simulator::Evaluate_STOC;
1414 EvalTable[LAN] = &Simulator::Evaluate_LAN;
1415 EvalTable[LAO] = &Simulator::Evaluate_LAO;
1416 EvalTable[LAX] = &Simulator::Evaluate_LAX;
1417 EvalTable[LAA] = &Simulator::Evaluate_LAA;
1418 EvalTable[LAAL] = &Simulator::Evaluate_LAAL;
1419 EvalTable[BRXHG] = &Simulator::Evaluate_BRXHG;
1420 EvalTable[BRXLG] = &Simulator::Evaluate_BRXLG;
1421 EvalTable[RISBLG] = &Simulator::Evaluate_RISBLG;
1422 EvalTable[RNSBG] = &Simulator::Evaluate_RNSBG;
1423 EvalTable[RISBG] = &Simulator::Evaluate_RISBG;
1424 EvalTable[ROSBG] = &Simulator::Evaluate_ROSBG;
1425 EvalTable[RXSBG] = &Simulator::Evaluate_RXSBG;
1426 EvalTable[RISBGN] = &Simulator::Evaluate_RISBGN;
1427 EvalTable[RISBHG] = &Simulator::Evaluate_RISBHG;
1428 EvalTable[CGRJ] = &Simulator::Evaluate_CGRJ;
1429 EvalTable[CGIT] = &Simulator::Evaluate_CGIT;
1430 EvalTable[CIT] = &Simulator::Evaluate_CIT;
1431 EvalTable[CLFIT] = &Simulator::Evaluate_CLFIT;
1432 EvalTable[CGIJ] = &Simulator::Evaluate_CGIJ;
1433 EvalTable[CIJ] = &Simulator::Evaluate_CIJ;
1434 EvalTable[AHIK] = &Simulator::Evaluate_AHIK;
1435 EvalTable[AGHIK] = &Simulator::Evaluate_AGHIK;
1436 EvalTable[ALHSIK] = &Simulator::Evaluate_ALHSIK;
1437 EvalTable[ALGHSIK] = &Simulator::Evaluate_ALGHSIK;
1438 EvalTable[CGRB] = &Simulator::Evaluate_CGRB;
1439 EvalTable[CGIB] = &Simulator::Evaluate_CGIB;
1440 EvalTable[CIB] = &Simulator::Evaluate_CIB;
1441 EvalTable[LDEB] = &Simulator::Evaluate_LDEB;
1442 EvalTable[LXDB] = &Simulator::Evaluate_LXDB;
1443 EvalTable[LXEB] = &Simulator::Evaluate_LXEB;
1444 EvalTable[MXDB] = &Simulator::Evaluate_MXDB;
1445 EvalTable[KEB] = &Simulator::Evaluate_KEB;
1446 EvalTable[CEB] = &Simulator::Evaluate_CEB;
1447 EvalTable[AEB] = &Simulator::Evaluate_AEB;
1448 EvalTable[SEB] = &Simulator::Evaluate_SEB;
1449 EvalTable[MDEB] = &Simulator::Evaluate_MDEB;
1450 EvalTable[DEB] = &Simulator::Evaluate_DEB;
1451 EvalTable[MAEB] = &Simulator::Evaluate_MAEB;
1452 EvalTable[MSEB] = &Simulator::Evaluate_MSEB;
1453 EvalTable[TCEB] = &Simulator::Evaluate_TCEB;
1454 EvalTable[TCDB] = &Simulator::Evaluate_TCDB;
1455 EvalTable[TCXB] = &Simulator::Evaluate_TCXB;
1456 EvalTable[SQEB] = &Simulator::Evaluate_SQEB;
1457 EvalTable[SQDB] = &Simulator::Evaluate_SQDB;
1458 EvalTable[MEEB] = &Simulator::Evaluate_MEEB;
1459 EvalTable[KDB] = &Simulator::Evaluate_KDB;
1460 EvalTable[CDB] = &Simulator::Evaluate_CDB;
1461 EvalTable[ADB] = &Simulator::Evaluate_ADB;
1462 EvalTable[SDB] = &Simulator::Evaluate_SDB;
1463 EvalTable[MDB] = &Simulator::Evaluate_MDB;
1464 EvalTable[DDB] = &Simulator::Evaluate_DDB;
1465 EvalTable[MADB] = &Simulator::Evaluate_MADB;
1466 EvalTable[MSDB] = &Simulator::Evaluate_MSDB;
1467 EvalTable[SLDT] = &Simulator::Evaluate_SLDT;
1468 EvalTable[SRDT] = &Simulator::Evaluate_SRDT;
1469 EvalTable[SLXT] = &Simulator::Evaluate_SLXT;
1470 EvalTable[SRXT] = &Simulator::Evaluate_SRXT;
1471 EvalTable[TDCET] = &Simulator::Evaluate_TDCET;
1472 EvalTable[TDGET] = &Simulator::Evaluate_TDGET;
1473 EvalTable[TDCDT] = &Simulator::Evaluate_TDCDT;
1474 EvalTable[TDGDT] = &Simulator::Evaluate_TDGDT;
1475 EvalTable[TDCXT] = &Simulator::Evaluate_TDCXT;
1476 EvalTable[TDGXT] = &Simulator::Evaluate_TDGXT;
1477 EvalTable[LEY] = &Simulator::Evaluate_LEY;
1478 EvalTable[LDY] = &Simulator::Evaluate_LDY;
1479 EvalTable[STEY] = &Simulator::Evaluate_STEY;
1480 EvalTable[STDY] = &Simulator::Evaluate_STDY;
1481 EvalTable[CZDT] = &Simulator::Evaluate_CZDT;
1482 EvalTable[CZXT] = &Simulator::Evaluate_CZXT;
1483 EvalTable[CDZT] = &Simulator::Evaluate_CDZT;
1484 EvalTable[CXZT] = &Simulator::Evaluate_CXZT;
1485 } // NOLINT
1486
Simulator(Isolate * isolate)1487 Simulator::Simulator(Isolate* isolate) : isolate_(isolate) {
1488 i_cache_ = isolate_->simulator_i_cache();
1489 if (i_cache_ == NULL) {
1490 i_cache_ = new base::CustomMatcherHashMap(&ICacheMatch);
1491 isolate_->set_simulator_i_cache(i_cache_);
1492 }
1493 Initialize(isolate);
1494 // Set up simulator support first. Some of this information is needed to
1495 // setup the architecture state.
1496 #if V8_TARGET_ARCH_S390X
1497 size_t stack_size = FLAG_sim_stack_size * KB;
1498 #else
1499 size_t stack_size = MB; // allocate 1MB for stack
1500 #endif
1501 stack_size += 2 * stack_protection_size_;
1502 stack_ = reinterpret_cast<char*>(malloc(stack_size));
1503 pc_modified_ = false;
1504 icount_ = 0;
1505 break_pc_ = NULL;
1506 break_instr_ = 0;
1507
1508 // make sure our register type can hold exactly 4/8 bytes
1509 #ifdef V8_TARGET_ARCH_S390X
1510 DCHECK(sizeof(intptr_t) == 8);
1511 #else
1512 DCHECK(sizeof(intptr_t) == 4);
1513 #endif
1514 // Set up architecture state.
1515 // All registers are initialized to zero to start with.
1516 for (int i = 0; i < kNumGPRs; i++) {
1517 registers_[i] = 0;
1518 }
1519 condition_reg_ = 0;
1520 special_reg_pc_ = 0;
1521
1522 // Initializing FP registers.
1523 for (int i = 0; i < kNumFPRs; i++) {
1524 fp_registers_[i] = 0.0;
1525 }
1526
1527 // The sp is initialized to point to the bottom (high address) of the
1528 // allocated stack area. To be safe in potential stack underflows we leave
1529 // some buffer below.
1530 registers_[sp] =
1531 reinterpret_cast<intptr_t>(stack_) + stack_size - stack_protection_size_;
1532
1533 last_debugger_input_ = NULL;
1534 }
1535
~Simulator()1536 Simulator::~Simulator() { free(stack_); }
1537
1538 // When the generated code calls an external reference we need to catch that in
1539 // the simulator. The external reference will be a function compiled for the
1540 // host architecture. We need to call that function instead of trying to
1541 // execute it with the simulator. We do that by redirecting the external
1542 // reference to a svc (Supervisor Call) instruction that is handled by
1543 // the simulator. We write the original destination of the jump just at a known
1544 // offset from the svc instruction so the simulator knows what to call.
1545 class Redirection {
1546 public:
Redirection(Isolate * isolate,void * external_function,ExternalReference::Type type)1547 Redirection(Isolate* isolate, void* external_function,
1548 ExternalReference::Type type)
1549 : external_function_(external_function),
1550 // we use TRAP4 here (0xBF22)
1551 #if V8_TARGET_LITTLE_ENDIAN
1552 swi_instruction_(0x1000FFB2),
1553 #else
1554 swi_instruction_(0xB2FF0000 | kCallRtRedirected),
1555 #endif
1556 type_(type),
1557 next_(NULL) {
1558 next_ = isolate->simulator_redirection();
1559 Simulator::current(isolate)->FlushICache(
1560 isolate->simulator_i_cache(),
1561 reinterpret_cast<void*>(&swi_instruction_), sizeof(FourByteInstr));
1562 isolate->set_simulator_redirection(this);
1563 if (ABI_USES_FUNCTION_DESCRIPTORS) {
1564 function_descriptor_[0] = reinterpret_cast<intptr_t>(&swi_instruction_);
1565 function_descriptor_[1] = 0;
1566 function_descriptor_[2] = 0;
1567 }
1568 }
1569
address()1570 void* address() {
1571 if (ABI_USES_FUNCTION_DESCRIPTORS) {
1572 return reinterpret_cast<void*>(function_descriptor_);
1573 } else {
1574 return reinterpret_cast<void*>(&swi_instruction_);
1575 }
1576 }
1577
external_function()1578 void* external_function() { return external_function_; }
type()1579 ExternalReference::Type type() { return type_; }
1580
Get(Isolate * isolate,void * external_function,ExternalReference::Type type)1581 static Redirection* Get(Isolate* isolate, void* external_function,
1582 ExternalReference::Type type) {
1583 Redirection* current = isolate->simulator_redirection();
1584 for (; current != NULL; current = current->next_) {
1585 if (current->external_function_ == external_function) {
1586 DCHECK_EQ(current->type(), type);
1587 return current;
1588 }
1589 }
1590 return new Redirection(isolate, external_function, type);
1591 }
1592
FromSwiInstruction(Instruction * swi_instruction)1593 static Redirection* FromSwiInstruction(Instruction* swi_instruction) {
1594 char* addr_of_swi = reinterpret_cast<char*>(swi_instruction);
1595 char* addr_of_redirection =
1596 addr_of_swi - offsetof(Redirection, swi_instruction_);
1597 return reinterpret_cast<Redirection*>(addr_of_redirection);
1598 }
1599
FromAddress(void * address)1600 static Redirection* FromAddress(void* address) {
1601 int delta = ABI_USES_FUNCTION_DESCRIPTORS
1602 ? offsetof(Redirection, function_descriptor_)
1603 : offsetof(Redirection, swi_instruction_);
1604 char* addr_of_redirection = reinterpret_cast<char*>(address) - delta;
1605 return reinterpret_cast<Redirection*>(addr_of_redirection);
1606 }
1607
ReverseRedirection(intptr_t reg)1608 static void* ReverseRedirection(intptr_t reg) {
1609 Redirection* redirection = FromAddress(reinterpret_cast<void*>(reg));
1610 return redirection->external_function();
1611 }
1612
DeleteChain(Redirection * redirection)1613 static void DeleteChain(Redirection* redirection) {
1614 while (redirection != nullptr) {
1615 Redirection* next = redirection->next_;
1616 delete redirection;
1617 redirection = next;
1618 }
1619 }
1620
1621 private:
1622 void* external_function_;
1623 uint32_t swi_instruction_;
1624 ExternalReference::Type type_;
1625 Redirection* next_;
1626 intptr_t function_descriptor_[3];
1627 };
1628
1629 // static
TearDown(base::CustomMatcherHashMap * i_cache,Redirection * first)1630 void Simulator::TearDown(base::CustomMatcherHashMap* i_cache,
1631 Redirection* first) {
1632 Redirection::DeleteChain(first);
1633 if (i_cache != nullptr) {
1634 for (base::HashMap::Entry* entry = i_cache->Start(); entry != nullptr;
1635 entry = i_cache->Next(entry)) {
1636 delete static_cast<CachePage*>(entry->value);
1637 }
1638 delete i_cache;
1639 }
1640 }
1641
RedirectExternalReference(Isolate * isolate,void * external_function,ExternalReference::Type type)1642 void* Simulator::RedirectExternalReference(Isolate* isolate,
1643 void* external_function,
1644 ExternalReference::Type type) {
1645 Redirection* redirection = Redirection::Get(isolate, external_function, type);
1646 return redirection->address();
1647 }
1648
1649 // Get the active Simulator for the current thread.
current(Isolate * isolate)1650 Simulator* Simulator::current(Isolate* isolate) {
1651 v8::internal::Isolate::PerIsolateThreadData* isolate_data =
1652 isolate->FindOrAllocatePerThreadDataForThisThread();
1653 DCHECK(isolate_data != NULL);
1654
1655 Simulator* sim = isolate_data->simulator();
1656 if (sim == NULL) {
1657 // TODO(146): delete the simulator object when a thread/isolate goes away.
1658 sim = new Simulator(isolate);
1659 isolate_data->set_simulator(sim);
1660 }
1661 return sim;
1662 }
1663
1664 // Sets the register in the architecture state.
set_register(int reg,uint64_t value)1665 void Simulator::set_register(int reg, uint64_t value) {
1666 DCHECK((reg >= 0) && (reg < kNumGPRs));
1667 registers_[reg] = value;
1668 }
1669
1670 // Get the register from the architecture state.
get_register(int reg) const1671 uint64_t Simulator::get_register(int reg) const {
1672 DCHECK((reg >= 0) && (reg < kNumGPRs));
1673 // Stupid code added to avoid bug in GCC.
1674 // See: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43949
1675 if (reg >= kNumGPRs) return 0;
1676 // End stupid code.
1677 return registers_[reg];
1678 }
1679
1680 template <typename T>
get_low_register(int reg) const1681 T Simulator::get_low_register(int reg) const {
1682 DCHECK((reg >= 0) && (reg < kNumGPRs));
1683 // Stupid code added to avoid bug in GCC.
1684 // See: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43949
1685 if (reg >= kNumGPRs) return 0;
1686 // End stupid code.
1687 return static_cast<T>(registers_[reg] & 0xFFFFFFFF);
1688 }
1689
1690 template <typename T>
get_high_register(int reg) const1691 T Simulator::get_high_register(int reg) const {
1692 DCHECK((reg >= 0) && (reg < kNumGPRs));
1693 // Stupid code added to avoid bug in GCC.
1694 // See: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43949
1695 if (reg >= kNumGPRs) return 0;
1696 // End stupid code.
1697 return static_cast<T>(registers_[reg] >> 32);
1698 }
1699
set_low_register(int reg,uint32_t value)1700 void Simulator::set_low_register(int reg, uint32_t value) {
1701 uint64_t shifted_val = static_cast<uint64_t>(value);
1702 uint64_t orig_val = static_cast<uint64_t>(registers_[reg]);
1703 uint64_t result = (orig_val >> 32 << 32) | shifted_val;
1704 registers_[reg] = result;
1705 }
1706
set_high_register(int reg,uint32_t value)1707 void Simulator::set_high_register(int reg, uint32_t value) {
1708 uint64_t shifted_val = static_cast<uint64_t>(value) << 32;
1709 uint64_t orig_val = static_cast<uint64_t>(registers_[reg]);
1710 uint64_t result = (orig_val & 0xFFFFFFFF) | shifted_val;
1711 registers_[reg] = result;
1712 }
1713
get_double_from_register_pair(int reg)1714 double Simulator::get_double_from_register_pair(int reg) {
1715 DCHECK((reg >= 0) && (reg < kNumGPRs) && ((reg % 2) == 0));
1716
1717 double dm_val = 0.0;
1718 #if 0 && !V8_TARGET_ARCH_S390X // doesn't make sense in 64bit mode
1719 // Read the bits from the unsigned integer register_[] array
1720 // into the double precision floating point value and return it.
1721 char buffer[sizeof(fp_registers_[0])];
1722 memcpy(buffer, ®isters_[reg], 2 * sizeof(registers_[0]));
1723 memcpy(&dm_val, buffer, 2 * sizeof(registers_[0]));
1724 #endif
1725 return (dm_val);
1726 }
1727
1728 // Raw access to the PC register.
set_pc(intptr_t value)1729 void Simulator::set_pc(intptr_t value) {
1730 pc_modified_ = true;
1731 special_reg_pc_ = value;
1732 }
1733
has_bad_pc() const1734 bool Simulator::has_bad_pc() const {
1735 return ((special_reg_pc_ == bad_lr) || (special_reg_pc_ == end_sim_pc));
1736 }
1737
1738 // Raw access to the PC register without the special adjustment when reading.
get_pc() const1739 intptr_t Simulator::get_pc() const { return special_reg_pc_; }
1740
1741 // Runtime FP routines take:
1742 // - two double arguments
1743 // - one double argument and zero or one integer arguments.
1744 // All are consructed here from d1, d2 and r2.
GetFpArgs(double * x,double * y,intptr_t * z)1745 void Simulator::GetFpArgs(double* x, double* y, intptr_t* z) {
1746 *x = get_double_from_d_register(0);
1747 *y = get_double_from_d_register(2);
1748 *z = get_register(2);
1749 }
1750
1751 // The return value is in d0.
SetFpResult(const double & result)1752 void Simulator::SetFpResult(const double& result) {
1753 set_d_register_from_double(0, result);
1754 }
1755
TrashCallerSaveRegisters()1756 void Simulator::TrashCallerSaveRegisters() {
1757 // We don't trash the registers with the return value.
1758 #if 0 // A good idea to trash volatile registers, needs to be done
1759 registers_[2] = 0x50Bad4U;
1760 registers_[3] = 0x50Bad4U;
1761 registers_[12] = 0x50Bad4U;
1762 #endif
1763 }
1764
ReadWU(intptr_t addr,Instruction * instr)1765 uint32_t Simulator::ReadWU(intptr_t addr, Instruction* instr) {
1766 uint32_t* ptr = reinterpret_cast<uint32_t*>(addr);
1767 return *ptr;
1768 }
1769
ReadW64(intptr_t addr,Instruction * instr)1770 int64_t Simulator::ReadW64(intptr_t addr, Instruction* instr) {
1771 int64_t* ptr = reinterpret_cast<int64_t*>(addr);
1772 return *ptr;
1773 }
1774
ReadW(intptr_t addr,Instruction * instr)1775 int32_t Simulator::ReadW(intptr_t addr, Instruction* instr) {
1776 int32_t* ptr = reinterpret_cast<int32_t*>(addr);
1777 return *ptr;
1778 }
1779
WriteW(intptr_t addr,uint32_t value,Instruction * instr)1780 void Simulator::WriteW(intptr_t addr, uint32_t value, Instruction* instr) {
1781 uint32_t* ptr = reinterpret_cast<uint32_t*>(addr);
1782 *ptr = value;
1783 return;
1784 }
1785
WriteW(intptr_t addr,int32_t value,Instruction * instr)1786 void Simulator::WriteW(intptr_t addr, int32_t value, Instruction* instr) {
1787 int32_t* ptr = reinterpret_cast<int32_t*>(addr);
1788 *ptr = value;
1789 return;
1790 }
1791
ReadHU(intptr_t addr,Instruction * instr)1792 uint16_t Simulator::ReadHU(intptr_t addr, Instruction* instr) {
1793 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
1794 return *ptr;
1795 }
1796
ReadH(intptr_t addr,Instruction * instr)1797 int16_t Simulator::ReadH(intptr_t addr, Instruction* instr) {
1798 int16_t* ptr = reinterpret_cast<int16_t*>(addr);
1799 return *ptr;
1800 }
1801
WriteH(intptr_t addr,uint16_t value,Instruction * instr)1802 void Simulator::WriteH(intptr_t addr, uint16_t value, Instruction* instr) {
1803 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
1804 *ptr = value;
1805 return;
1806 }
1807
WriteH(intptr_t addr,int16_t value,Instruction * instr)1808 void Simulator::WriteH(intptr_t addr, int16_t value, Instruction* instr) {
1809 int16_t* ptr = reinterpret_cast<int16_t*>(addr);
1810 *ptr = value;
1811 return;
1812 }
1813
ReadBU(intptr_t addr)1814 uint8_t Simulator::ReadBU(intptr_t addr) {
1815 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
1816 return *ptr;
1817 }
1818
ReadB(intptr_t addr)1819 int8_t Simulator::ReadB(intptr_t addr) {
1820 int8_t* ptr = reinterpret_cast<int8_t*>(addr);
1821 return *ptr;
1822 }
1823
WriteB(intptr_t addr,uint8_t value)1824 void Simulator::WriteB(intptr_t addr, uint8_t value) {
1825 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
1826 *ptr = value;
1827 }
1828
WriteB(intptr_t addr,int8_t value)1829 void Simulator::WriteB(intptr_t addr, int8_t value) {
1830 int8_t* ptr = reinterpret_cast<int8_t*>(addr);
1831 *ptr = value;
1832 }
1833
ReadDW(intptr_t addr)1834 int64_t Simulator::ReadDW(intptr_t addr) {
1835 int64_t* ptr = reinterpret_cast<int64_t*>(addr);
1836 return *ptr;
1837 }
1838
WriteDW(intptr_t addr,int64_t value)1839 void Simulator::WriteDW(intptr_t addr, int64_t value) {
1840 int64_t* ptr = reinterpret_cast<int64_t*>(addr);
1841 *ptr = value;
1842 return;
1843 }
1844
1845 /**
1846 * Reads a double value from memory at given address.
1847 */
ReadDouble(intptr_t addr)1848 double Simulator::ReadDouble(intptr_t addr) {
1849 double* ptr = reinterpret_cast<double*>(addr);
1850 return *ptr;
1851 }
1852
ReadFloat(intptr_t addr)1853 float Simulator::ReadFloat(intptr_t addr) {
1854 float* ptr = reinterpret_cast<float*>(addr);
1855 return *ptr;
1856 }
1857
1858 // Returns the limit of the stack area to enable checking for stack overflows.
StackLimit(uintptr_t c_limit) const1859 uintptr_t Simulator::StackLimit(uintptr_t c_limit) const {
1860 // The simulator uses a separate JS stack. If we have exhausted the C stack,
1861 // we also drop down the JS limit to reflect the exhaustion on the JS stack.
1862 if (GetCurrentStackPosition() < c_limit) {
1863 return reinterpret_cast<uintptr_t>(get_sp());
1864 }
1865
1866 // Otherwise the limit is the JS stack. Leave a safety margin to prevent
1867 // overrunning the stack when pushing values.
1868 return reinterpret_cast<uintptr_t>(stack_) + stack_protection_size_;
1869 }
1870
1871 // Unsupported instructions use Format to print an error and stop execution.
Format(Instruction * instr,const char * format)1872 void Simulator::Format(Instruction* instr, const char* format) {
1873 PrintF("Simulator found unsupported instruction:\n 0x%08" V8PRIxPTR ": %s\n",
1874 reinterpret_cast<intptr_t>(instr), format);
1875 UNIMPLEMENTED();
1876 }
1877
1878 // Calculate C flag value for additions.
CarryFrom(int32_t left,int32_t right,int32_t carry)1879 bool Simulator::CarryFrom(int32_t left, int32_t right, int32_t carry) {
1880 uint32_t uleft = static_cast<uint32_t>(left);
1881 uint32_t uright = static_cast<uint32_t>(right);
1882 uint32_t urest = 0xffffffffU - uleft;
1883
1884 return (uright > urest) ||
1885 (carry && (((uright + 1) > urest) || (uright > (urest - 1))));
1886 }
1887
1888 // Calculate C flag value for subtractions.
BorrowFrom(int32_t left,int32_t right)1889 bool Simulator::BorrowFrom(int32_t left, int32_t right) {
1890 uint32_t uleft = static_cast<uint32_t>(left);
1891 uint32_t uright = static_cast<uint32_t>(right);
1892
1893 return (uright > uleft);
1894 }
1895
1896 // Calculate V flag value for additions and subtractions.
1897 template <typename T1>
OverflowFromSigned(T1 alu_out,T1 left,T1 right,bool addition)1898 bool Simulator::OverflowFromSigned(T1 alu_out, T1 left, T1 right,
1899 bool addition) {
1900 bool overflow;
1901 if (addition) {
1902 // operands have the same sign
1903 overflow = ((left >= 0 && right >= 0) || (left < 0 && right < 0))
1904 // and operands and result have different sign
1905 && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
1906 } else {
1907 // operands have different signs
1908 overflow = ((left < 0 && right >= 0) || (left >= 0 && right < 0))
1909 // and first operand and result have different signs
1910 && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
1911 }
1912 return overflow;
1913 }
1914
1915 #if V8_TARGET_ARCH_S390X
decodeObjectPair(ObjectPair * pair,intptr_t * x,intptr_t * y)1916 static void decodeObjectPair(ObjectPair* pair, intptr_t* x, intptr_t* y) {
1917 *x = reinterpret_cast<intptr_t>(pair->x);
1918 *y = reinterpret_cast<intptr_t>(pair->y);
1919 }
1920 #else
decodeObjectPair(ObjectPair * pair,intptr_t * x,intptr_t * y)1921 static void decodeObjectPair(ObjectPair* pair, intptr_t* x, intptr_t* y) {
1922 #if V8_TARGET_BIG_ENDIAN
1923 *x = static_cast<int32_t>(*pair >> 32);
1924 *y = static_cast<int32_t>(*pair);
1925 #else
1926 *x = static_cast<int32_t>(*pair);
1927 *y = static_cast<int32_t>(*pair >> 32);
1928 #endif
1929 }
1930 #endif
1931
1932 // Calls into the V8 runtime.
1933 typedef intptr_t (*SimulatorRuntimeCall)(intptr_t arg0, intptr_t arg1,
1934 intptr_t arg2, intptr_t arg3,
1935 intptr_t arg4, intptr_t arg5);
1936 typedef ObjectPair (*SimulatorRuntimePairCall)(intptr_t arg0, intptr_t arg1,
1937 intptr_t arg2, intptr_t arg3,
1938 intptr_t arg4, intptr_t arg5);
1939 typedef ObjectTriple (*SimulatorRuntimeTripleCall)(intptr_t arg0, intptr_t arg1,
1940 intptr_t arg2, intptr_t arg3,
1941 intptr_t arg4,
1942 intptr_t arg5);
1943
1944 // These prototypes handle the four types of FP calls.
1945 typedef int (*SimulatorRuntimeCompareCall)(double darg0, double darg1);
1946 typedef double (*SimulatorRuntimeFPFPCall)(double darg0, double darg1);
1947 typedef double (*SimulatorRuntimeFPCall)(double darg0);
1948 typedef double (*SimulatorRuntimeFPIntCall)(double darg0, intptr_t arg0);
1949
1950 // This signature supports direct call in to API function native callback
1951 // (refer to InvocationCallback in v8.h).
1952 typedef void (*SimulatorRuntimeDirectApiCall)(intptr_t arg0);
1953 typedef void (*SimulatorRuntimeProfilingApiCall)(intptr_t arg0, void* arg1);
1954
1955 // This signature supports direct call to accessor getter callback.
1956 typedef void (*SimulatorRuntimeDirectGetterCall)(intptr_t arg0, intptr_t arg1);
1957 typedef void (*SimulatorRuntimeProfilingGetterCall)(intptr_t arg0,
1958 intptr_t arg1, void* arg2);
1959
1960 // Software interrupt instructions are used by the simulator to call into the
1961 // C-based V8 runtime.
SoftwareInterrupt(Instruction * instr)1962 void Simulator::SoftwareInterrupt(Instruction* instr) {
1963 int svc = instr->SvcValue();
1964 switch (svc) {
1965 case kCallRtRedirected: {
1966 // Check if stack is aligned. Error if not aligned is reported below to
1967 // include information on the function called.
1968 bool stack_aligned =
1969 (get_register(sp) & (::v8::internal::FLAG_sim_stack_alignment - 1)) ==
1970 0;
1971 Redirection* redirection = Redirection::FromSwiInstruction(instr);
1972 const int kArgCount = 6;
1973 int arg0_regnum = 2;
1974 intptr_t result_buffer = 0;
1975 bool uses_result_buffer =
1976 redirection->type() == ExternalReference::BUILTIN_CALL_TRIPLE ||
1977 (redirection->type() == ExternalReference::BUILTIN_CALL_PAIR &&
1978 !ABI_RETURNS_OBJECTPAIR_IN_REGS);
1979 if (uses_result_buffer) {
1980 result_buffer = get_register(r2);
1981 arg0_regnum++;
1982 }
1983 intptr_t arg[kArgCount];
1984 for (int i = 0; i < kArgCount - 1; i++) {
1985 arg[i] = get_register(arg0_regnum + i);
1986 }
1987 intptr_t* stack_pointer = reinterpret_cast<intptr_t*>(get_register(sp));
1988 arg[5] = stack_pointer[kCalleeRegisterSaveAreaSize / kPointerSize];
1989 bool fp_call =
1990 (redirection->type() == ExternalReference::BUILTIN_FP_FP_CALL) ||
1991 (redirection->type() == ExternalReference::BUILTIN_COMPARE_CALL) ||
1992 (redirection->type() == ExternalReference::BUILTIN_FP_CALL) ||
1993 (redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL);
1994
1995 // Place the return address on the stack, making the call GC safe.
1996 *reinterpret_cast<intptr_t*>(get_register(sp) +
1997 kStackFrameRASlot * kPointerSize) =
1998 get_register(r14);
1999
2000 intptr_t external =
2001 reinterpret_cast<intptr_t>(redirection->external_function());
2002 if (fp_call) {
2003 double dval0, dval1; // one or two double parameters
2004 intptr_t ival; // zero or one integer parameters
2005 int iresult = 0; // integer return value
2006 double dresult = 0; // double return value
2007 GetFpArgs(&dval0, &dval1, &ival);
2008 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
2009 SimulatorRuntimeCall generic_target =
2010 reinterpret_cast<SimulatorRuntimeCall>(external);
2011 switch (redirection->type()) {
2012 case ExternalReference::BUILTIN_FP_FP_CALL:
2013 case ExternalReference::BUILTIN_COMPARE_CALL:
2014 PrintF("Call to host function at %p with args %f, %f",
2015 static_cast<void*>(FUNCTION_ADDR(generic_target)), dval0,
2016 dval1);
2017 break;
2018 case ExternalReference::BUILTIN_FP_CALL:
2019 PrintF("Call to host function at %p with arg %f",
2020 static_cast<void*>(FUNCTION_ADDR(generic_target)), dval0);
2021 break;
2022 case ExternalReference::BUILTIN_FP_INT_CALL:
2023 PrintF("Call to host function at %p with args %f, %" V8PRIdPTR,
2024 static_cast<void*>(FUNCTION_ADDR(generic_target)), dval0,
2025 ival);
2026 break;
2027 default:
2028 UNREACHABLE();
2029 break;
2030 }
2031 if (!stack_aligned) {
2032 PrintF(" with unaligned stack %08" V8PRIxPTR "\n",
2033 static_cast<intptr_t>(get_register(sp)));
2034 }
2035 PrintF("\n");
2036 }
2037 CHECK(stack_aligned);
2038 switch (redirection->type()) {
2039 case ExternalReference::BUILTIN_COMPARE_CALL: {
2040 SimulatorRuntimeCompareCall target =
2041 reinterpret_cast<SimulatorRuntimeCompareCall>(external);
2042 iresult = target(dval0, dval1);
2043 set_register(r2, iresult);
2044 break;
2045 }
2046 case ExternalReference::BUILTIN_FP_FP_CALL: {
2047 SimulatorRuntimeFPFPCall target =
2048 reinterpret_cast<SimulatorRuntimeFPFPCall>(external);
2049 dresult = target(dval0, dval1);
2050 SetFpResult(dresult);
2051 break;
2052 }
2053 case ExternalReference::BUILTIN_FP_CALL: {
2054 SimulatorRuntimeFPCall target =
2055 reinterpret_cast<SimulatorRuntimeFPCall>(external);
2056 dresult = target(dval0);
2057 SetFpResult(dresult);
2058 break;
2059 }
2060 case ExternalReference::BUILTIN_FP_INT_CALL: {
2061 SimulatorRuntimeFPIntCall target =
2062 reinterpret_cast<SimulatorRuntimeFPIntCall>(external);
2063 dresult = target(dval0, ival);
2064 SetFpResult(dresult);
2065 break;
2066 }
2067 default:
2068 UNREACHABLE();
2069 break;
2070 }
2071 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
2072 switch (redirection->type()) {
2073 case ExternalReference::BUILTIN_COMPARE_CALL:
2074 PrintF("Returned %08x\n", iresult);
2075 break;
2076 case ExternalReference::BUILTIN_FP_FP_CALL:
2077 case ExternalReference::BUILTIN_FP_CALL:
2078 case ExternalReference::BUILTIN_FP_INT_CALL:
2079 PrintF("Returned %f\n", dresult);
2080 break;
2081 default:
2082 UNREACHABLE();
2083 break;
2084 }
2085 }
2086 } else if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
2087 // See callers of MacroAssembler::CallApiFunctionAndReturn for
2088 // explanation of register usage.
2089 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
2090 PrintF("Call to host function at %p args %08" V8PRIxPTR,
2091 reinterpret_cast<void*>(external), arg[0]);
2092 if (!stack_aligned) {
2093 PrintF(" with unaligned stack %08" V8PRIxPTR "\n",
2094 static_cast<intptr_t>(get_register(sp)));
2095 }
2096 PrintF("\n");
2097 }
2098 CHECK(stack_aligned);
2099 SimulatorRuntimeDirectApiCall target =
2100 reinterpret_cast<SimulatorRuntimeDirectApiCall>(external);
2101 target(arg[0]);
2102 } else if (redirection->type() == ExternalReference::PROFILING_API_CALL) {
2103 // See callers of MacroAssembler::CallApiFunctionAndReturn for
2104 // explanation of register usage.
2105 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
2106 PrintF("Call to host function at %p args %08" V8PRIxPTR
2107 " %08" V8PRIxPTR,
2108 reinterpret_cast<void*>(external), arg[0], arg[1]);
2109 if (!stack_aligned) {
2110 PrintF(" with unaligned stack %08" V8PRIxPTR "\n",
2111 static_cast<intptr_t>(get_register(sp)));
2112 }
2113 PrintF("\n");
2114 }
2115 CHECK(stack_aligned);
2116 SimulatorRuntimeProfilingApiCall target =
2117 reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
2118 target(arg[0], Redirection::ReverseRedirection(arg[1]));
2119 } else if (redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
2120 // See callers of MacroAssembler::CallApiFunctionAndReturn for
2121 // explanation of register usage.
2122 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
2123 PrintF("Call to host function at %p args %08" V8PRIxPTR
2124 " %08" V8PRIxPTR,
2125 reinterpret_cast<void*>(external), arg[0], arg[1]);
2126 if (!stack_aligned) {
2127 PrintF(" with unaligned stack %08" V8PRIxPTR "\n",
2128 static_cast<intptr_t>(get_register(sp)));
2129 }
2130 PrintF("\n");
2131 }
2132 CHECK(stack_aligned);
2133 SimulatorRuntimeDirectGetterCall target =
2134 reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external);
2135 if (!ABI_PASSES_HANDLES_IN_REGS) {
2136 arg[0] = *(reinterpret_cast<intptr_t*>(arg[0]));
2137 }
2138 target(arg[0], arg[1]);
2139 } else if (redirection->type() ==
2140 ExternalReference::PROFILING_GETTER_CALL) {
2141 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
2142 PrintF("Call to host function at %p args %08" V8PRIxPTR
2143 " %08" V8PRIxPTR " %08" V8PRIxPTR,
2144 reinterpret_cast<void*>(external), arg[0], arg[1], arg[2]);
2145 if (!stack_aligned) {
2146 PrintF(" with unaligned stack %08" V8PRIxPTR "\n",
2147 static_cast<intptr_t>(get_register(sp)));
2148 }
2149 PrintF("\n");
2150 }
2151 CHECK(stack_aligned);
2152 SimulatorRuntimeProfilingGetterCall target =
2153 reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external);
2154 if (!ABI_PASSES_HANDLES_IN_REGS) {
2155 arg[0] = *(reinterpret_cast<intptr_t*>(arg[0]));
2156 }
2157 target(arg[0], arg[1], Redirection::ReverseRedirection(arg[2]));
2158 } else {
2159 // builtin call.
2160 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
2161 SimulatorRuntimeCall target =
2162 reinterpret_cast<SimulatorRuntimeCall>(external);
2163 PrintF(
2164 "Call to host function at %p,\n"
2165 "\t\t\t\targs %08" V8PRIxPTR ", %08" V8PRIxPTR ", %08" V8PRIxPTR
2166 ", %08" V8PRIxPTR ", %08" V8PRIxPTR ", %08" V8PRIxPTR,
2167 static_cast<void*>(FUNCTION_ADDR(target)), arg[0], arg[1], arg[2],
2168 arg[3], arg[4], arg[5]);
2169 if (!stack_aligned) {
2170 PrintF(" with unaligned stack %08" V8PRIxPTR "\n",
2171 static_cast<intptr_t>(get_register(sp)));
2172 }
2173 PrintF("\n");
2174 }
2175 CHECK(stack_aligned);
2176 if (redirection->type() == ExternalReference::BUILTIN_CALL_TRIPLE) {
2177 SimulatorRuntimeTripleCall target =
2178 reinterpret_cast<SimulatorRuntimeTripleCall>(external);
2179 ObjectTriple result =
2180 target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]);
2181 if (::v8::internal::FLAG_trace_sim) {
2182 PrintF("Returned {%08" V8PRIxPTR ", %08" V8PRIxPTR ", %08" V8PRIxPTR
2183 "}\n",
2184 reinterpret_cast<intptr_t>(result.x),
2185 reinterpret_cast<intptr_t>(result.y),
2186 reinterpret_cast<intptr_t>(result.z));
2187 }
2188 memcpy(reinterpret_cast<void*>(result_buffer), &result,
2189 sizeof(ObjectTriple));
2190 set_register(r2, result_buffer);
2191 } else {
2192 if (redirection->type() == ExternalReference::BUILTIN_CALL_PAIR) {
2193 SimulatorRuntimePairCall target =
2194 reinterpret_cast<SimulatorRuntimePairCall>(external);
2195 ObjectPair result =
2196 target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]);
2197 intptr_t x;
2198 intptr_t y;
2199 decodeObjectPair(&result, &x, &y);
2200 if (::v8::internal::FLAG_trace_sim) {
2201 PrintF("Returned {%08" V8PRIxPTR ", %08" V8PRIxPTR "}\n", x, y);
2202 }
2203 if (ABI_RETURNS_OBJECTPAIR_IN_REGS) {
2204 set_register(r2, x);
2205 set_register(r3, y);
2206 } else {
2207 memcpy(reinterpret_cast<void*>(result_buffer), &result,
2208 sizeof(ObjectPair));
2209 set_register(r2, result_buffer);
2210 }
2211 } else {
2212 DCHECK(redirection->type() == ExternalReference::BUILTIN_CALL);
2213 SimulatorRuntimeCall target =
2214 reinterpret_cast<SimulatorRuntimeCall>(external);
2215 intptr_t result =
2216 target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]);
2217 if (::v8::internal::FLAG_trace_sim) {
2218 PrintF("Returned %08" V8PRIxPTR "\n", result);
2219 }
2220 set_register(r2, result);
2221 }
2222 }
2223 // #if !V8_TARGET_ARCH_S390X
2224 // DCHECK(redirection->type() ==
2225 // ExternalReference::BUILTIN_CALL);
2226 // SimulatorRuntimeCall target =
2227 // reinterpret_cast<SimulatorRuntimeCall>(external);
2228 // int64_t result = target(arg[0], arg[1], arg[2], arg[3],
2229 // arg[4],
2230 // arg[5]);
2231 // int32_t lo_res = static_cast<int32_t>(result);
2232 // int32_t hi_res = static_cast<int32_t>(result >> 32);
2233 // #if !V8_TARGET_LITTLE_ENDIAN
2234 // if (::v8::internal::FLAG_trace_sim) {
2235 // PrintF("Returned %08x\n", hi_res);
2236 // }
2237 // set_register(r2, hi_res);
2238 // set_register(r3, lo_res);
2239 // #else
2240 // if (::v8::internal::FLAG_trace_sim) {
2241 // PrintF("Returned %08x\n", lo_res);
2242 // }
2243 // set_register(r2, lo_res);
2244 // set_register(r3, hi_res);
2245 // #endif
2246 // #else
2247 // if (redirection->type() == ExternalReference::BUILTIN_CALL) {
2248 // SimulatorRuntimeCall target =
2249 // reinterpret_cast<SimulatorRuntimeCall>(external);
2250 // intptr_t result = target(arg[0], arg[1], arg[2], arg[3],
2251 // arg[4],
2252 // arg[5]);
2253 // if (::v8::internal::FLAG_trace_sim) {
2254 // PrintF("Returned %08" V8PRIxPTR "\n", result);
2255 // }
2256 // set_register(r2, result);
2257 // } else {
2258 // DCHECK(redirection->type() ==
2259 // ExternalReference::BUILTIN_CALL_PAIR);
2260 // SimulatorRuntimePairCall target =
2261 // reinterpret_cast<SimulatorRuntimePairCall>(external);
2262 // ObjectPair result = target(arg[0], arg[1], arg[2], arg[3],
2263 // arg[4], arg[5]);
2264 // if (::v8::internal::FLAG_trace_sim) {
2265 // PrintF("Returned %08" V8PRIxPTR ", %08" V8PRIxPTR "\n",
2266 // result.x, result.y);
2267 // }
2268 // #if ABI_RETURNS_OBJECTPAIR_IN_REGS
2269 // set_register(r2, result.x);
2270 // set_register(r3, result.y);
2271 // #else
2272 // memcpy(reinterpret_cast<void *>(result_buffer), &result,
2273 // sizeof(ObjectPair));
2274 // #endif
2275 // }
2276 // #endif
2277 }
2278 int64_t saved_lr = *reinterpret_cast<intptr_t*>(
2279 get_register(sp) + kStackFrameRASlot * kPointerSize);
2280 #if (!V8_TARGET_ARCH_S390X && V8_HOST_ARCH_S390)
2281 // On zLinux-31, the saved_lr might be tagged with a high bit of 1.
2282 // Cleanse it before proceeding with simulation.
2283 saved_lr &= 0x7FFFFFFF;
2284 #endif
2285 set_pc(saved_lr);
2286 break;
2287 }
2288 case kBreakpoint: {
2289 S390Debugger dbg(this);
2290 dbg.Debug();
2291 break;
2292 }
2293 // stop uses all codes greater than 1 << 23.
2294 default: {
2295 if (svc >= (1 << 23)) {
2296 uint32_t code = svc & kStopCodeMask;
2297 if (isWatchedStop(code)) {
2298 IncreaseStopCounter(code);
2299 }
2300 // Stop if it is enabled, otherwise go on jumping over the stop
2301 // and the message address.
2302 if (isEnabledStop(code)) {
2303 S390Debugger dbg(this);
2304 dbg.Stop(instr);
2305 } else {
2306 set_pc(get_pc() + sizeof(FourByteInstr) + kPointerSize);
2307 }
2308 } else {
2309 // This is not a valid svc code.
2310 UNREACHABLE();
2311 break;
2312 }
2313 }
2314 }
2315 }
2316
2317 // Stop helper functions.
isStopInstruction(Instruction * instr)2318 bool Simulator::isStopInstruction(Instruction* instr) {
2319 return (instr->Bits(27, 24) == 0xF) && (instr->SvcValue() >= kStopCode);
2320 }
2321
isWatchedStop(uint32_t code)2322 bool Simulator::isWatchedStop(uint32_t code) {
2323 DCHECK(code <= kMaxStopCode);
2324 return code < kNumOfWatchedStops;
2325 }
2326
isEnabledStop(uint32_t code)2327 bool Simulator::isEnabledStop(uint32_t code) {
2328 DCHECK(code <= kMaxStopCode);
2329 // Unwatched stops are always enabled.
2330 return !isWatchedStop(code) ||
2331 !(watched_stops_[code].count & kStopDisabledBit);
2332 }
2333
EnableStop(uint32_t code)2334 void Simulator::EnableStop(uint32_t code) {
2335 DCHECK(isWatchedStop(code));
2336 if (!isEnabledStop(code)) {
2337 watched_stops_[code].count &= ~kStopDisabledBit;
2338 }
2339 }
2340
DisableStop(uint32_t code)2341 void Simulator::DisableStop(uint32_t code) {
2342 DCHECK(isWatchedStop(code));
2343 if (isEnabledStop(code)) {
2344 watched_stops_[code].count |= kStopDisabledBit;
2345 }
2346 }
2347
IncreaseStopCounter(uint32_t code)2348 void Simulator::IncreaseStopCounter(uint32_t code) {
2349 DCHECK(code <= kMaxStopCode);
2350 DCHECK(isWatchedStop(code));
2351 if ((watched_stops_[code].count & ~(1 << 31)) == 0x7fffffff) {
2352 PrintF(
2353 "Stop counter for code %i has overflowed.\n"
2354 "Enabling this code and reseting the counter to 0.\n",
2355 code);
2356 watched_stops_[code].count = 0;
2357 EnableStop(code);
2358 } else {
2359 watched_stops_[code].count++;
2360 }
2361 }
2362
2363 // Print a stop status.
PrintStopInfo(uint32_t code)2364 void Simulator::PrintStopInfo(uint32_t code) {
2365 DCHECK(code <= kMaxStopCode);
2366 if (!isWatchedStop(code)) {
2367 PrintF("Stop not watched.");
2368 } else {
2369 const char* state = isEnabledStop(code) ? "Enabled" : "Disabled";
2370 int32_t count = watched_stops_[code].count & ~kStopDisabledBit;
2371 // Don't print the state of unused breakpoints.
2372 if (count != 0) {
2373 if (watched_stops_[code].desc) {
2374 PrintF("stop %i - 0x%x: \t%s, \tcounter = %i, \t%s\n", code, code,
2375 state, count, watched_stops_[code].desc);
2376 } else {
2377 PrintF("stop %i - 0x%x: \t%s, \tcounter = %i\n", code, code, state,
2378 count);
2379 }
2380 }
2381 }
2382 }
2383
2384 // Method for checking overflow on signed addition:
2385 // Test src1 and src2 have opposite sign,
2386 // (1) No overflow if they have opposite sign
2387 // (2) Test the result and one of the operands have opposite sign
2388 // (a) No overflow if they don't have opposite sign
2389 // (b) Overflow if opposite
2390 #define CheckOverflowForIntAdd(src1, src2, type) \
2391 OverflowFromSigned<type>(src1 + src2, src1, src2, true);
2392
2393 #define CheckOverflowForIntSub(src1, src2, type) \
2394 OverflowFromSigned<type>(src1 - src2, src1, src2, false);
2395
2396 // Method for checking overflow on unsigned addtion
2397 #define CheckOverflowForUIntAdd(src1, src2) \
2398 ((src1) + (src2) < (src1) || (src1) + (src2) < (src2))
2399
2400 // Method for checking overflow on unsigned subtraction
2401 #define CheckOverflowForUIntSub(src1, src2) ((src1) - (src2) > (src1))
2402
2403 // Method for checking overflow on multiplication
2404 #define CheckOverflowForMul(src1, src2) (((src1) * (src2)) / (src2) != (src1))
2405
2406 // Method for checking overflow on shift right
2407 #define CheckOverflowForShiftRight(src1, src2) \
2408 (((src1) >> (src2)) << (src2) != (src1))
2409
2410 // Method for checking overflow on shift left
2411 #define CheckOverflowForShiftLeft(src1, src2) \
2412 (((src1) << (src2)) >> (src2) != (src1))
2413
2414 // S390 Decode and simulate helpers
DecodeTwoByte(Instruction * instr)2415 bool Simulator::DecodeTwoByte(Instruction* instr) {
2416 Opcode op = instr->S390OpcodeValue();
2417
2418 switch (op) {
2419 // RR format instructions
2420 case AR:
2421 case SR:
2422 case MR:
2423 case DR:
2424 case OR:
2425 case NR:
2426 case XR: {
2427 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2428 int r1 = rrinst->R1Value();
2429 int r2 = rrinst->R2Value();
2430 int32_t r1_val = get_low_register<int32_t>(r1);
2431 int32_t r2_val = get_low_register<int32_t>(r2);
2432 bool isOF = false;
2433 switch (op) {
2434 case AR:
2435 isOF = CheckOverflowForIntAdd(r1_val, r2_val, int32_t);
2436 r1_val += r2_val;
2437 SetS390ConditionCode<int32_t>(r1_val, 0);
2438 SetS390OverflowCode(isOF);
2439 break;
2440 case SR:
2441 isOF = CheckOverflowForIntSub(r1_val, r2_val, int32_t);
2442 r1_val -= r2_val;
2443 SetS390ConditionCode<int32_t>(r1_val, 0);
2444 SetS390OverflowCode(isOF);
2445 break;
2446 case OR:
2447 r1_val |= r2_val;
2448 SetS390BitWiseConditionCode<uint32_t>(r1_val);
2449 break;
2450 case NR:
2451 r1_val &= r2_val;
2452 SetS390BitWiseConditionCode<uint32_t>(r1_val);
2453 break;
2454 case XR:
2455 r1_val ^= r2_val;
2456 SetS390BitWiseConditionCode<uint32_t>(r1_val);
2457 break;
2458 case MR: {
2459 DCHECK(r1 % 2 == 0);
2460 r1_val = get_low_register<int32_t>(r1 + 1);
2461 int64_t product =
2462 static_cast<int64_t>(r1_val) * static_cast<int64_t>(r2_val);
2463 int32_t high_bits = product >> 32;
2464 r1_val = high_bits;
2465 int32_t low_bits = product & 0x00000000FFFFFFFF;
2466 set_low_register(r1, high_bits);
2467 set_low_register(r1 + 1, low_bits);
2468 break;
2469 }
2470 case DR: {
2471 // reg-reg pair should be even-odd pair, assert r1 is an even register
2472 DCHECK(r1 % 2 == 0);
2473 // leftmost 32 bits of the dividend are in r1
2474 // rightmost 32 bits of the dividend are in r1+1
2475 // get the signed value from r1
2476 int64_t dividend = static_cast<int64_t>(r1_val) << 32;
2477 // get unsigned value from r1+1
2478 // avoid addition with sign-extended r1+1 value
2479 dividend += get_low_register<uint32_t>(r1 + 1);
2480 int32_t remainder = dividend % r2_val;
2481 int32_t quotient = dividend / r2_val;
2482 r1_val = remainder;
2483 set_low_register(r1, remainder);
2484 set_low_register(r1 + 1, quotient);
2485 break; // reg pair
2486 }
2487 default:
2488 UNREACHABLE();
2489 break;
2490 }
2491 set_low_register(r1, r1_val);
2492 break;
2493 }
2494 case LR: {
2495 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2496 int r1 = rrinst->R1Value();
2497 int r2 = rrinst->R2Value();
2498 set_low_register(r1, get_low_register<int32_t>(r2));
2499 break;
2500 }
2501 case LDR: {
2502 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2503 int r1 = rrinst->R1Value();
2504 int r2 = rrinst->R2Value();
2505 int64_t r2_val = get_d_register(r2);
2506 set_d_register(r1, r2_val);
2507 break;
2508 }
2509 case CR: {
2510 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2511 int r1 = rrinst->R1Value();
2512 int r2 = rrinst->R2Value();
2513 int32_t r1_val = get_low_register<int32_t>(r1);
2514 int32_t r2_val = get_low_register<int32_t>(r2);
2515 SetS390ConditionCode<int32_t>(r1_val, r2_val);
2516 break;
2517 }
2518 case CLR: {
2519 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2520 int r1 = rrinst->R1Value();
2521 int r2 = rrinst->R2Value();
2522 uint32_t r1_val = get_low_register<uint32_t>(r1);
2523 uint32_t r2_val = get_low_register<uint32_t>(r2);
2524 SetS390ConditionCode<uint32_t>(r1_val, r2_val);
2525 break;
2526 }
2527 case BCR: {
2528 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2529 int r1 = rrinst->R1Value();
2530 int r2 = rrinst->R2Value();
2531 if (TestConditionCode(Condition(r1))) {
2532 intptr_t r2_val = get_register(r2);
2533 #if (!V8_TARGET_ARCH_S390X && V8_HOST_ARCH_S390)
2534 // On 31-bit, the top most bit may be 0 or 1, but is ignored by the
2535 // hardware. Cleanse the top bit before jumping to it, unless it's one
2536 // of the special PCs
2537 if (r2_val != bad_lr && r2_val != end_sim_pc) r2_val &= 0x7FFFFFFF;
2538 #endif
2539 set_pc(r2_val);
2540 }
2541 break;
2542 }
2543 case LTR: {
2544 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2545 int r1 = rrinst->R1Value();
2546 int r2 = rrinst->R2Value();
2547 int32_t r2_val = get_low_register<int32_t>(r2);
2548 SetS390ConditionCode<int32_t>(r2_val, 0);
2549 set_low_register(r1, r2_val);
2550 break;
2551 }
2552 case ALR:
2553 case SLR: {
2554 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2555 int r1 = rrinst->R1Value();
2556 int r2 = rrinst->R2Value();
2557 uint32_t r1_val = get_low_register<uint32_t>(r1);
2558 uint32_t r2_val = get_low_register<uint32_t>(r2);
2559 uint32_t alu_out = 0;
2560 bool isOF = false;
2561 if (ALR == op) {
2562 alu_out = r1_val + r2_val;
2563 isOF = CheckOverflowForUIntAdd(r1_val, r2_val);
2564 } else if (SLR == op) {
2565 alu_out = r1_val - r2_val;
2566 isOF = CheckOverflowForUIntSub(r1_val, r2_val);
2567 } else {
2568 UNREACHABLE();
2569 }
2570 set_low_register(r1, alu_out);
2571 SetS390ConditionCodeCarry<uint32_t>(alu_out, isOF);
2572 break;
2573 }
2574 case LNR: {
2575 // Load Negative (32)
2576 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2577 int r1 = rrinst->R1Value();
2578 int r2 = rrinst->R2Value();
2579 int32_t r2_val = get_low_register<int32_t>(r2);
2580 r2_val = (r2_val >= 0) ? -r2_val : r2_val; // If pos, then negate it.
2581 set_low_register(r1, r2_val);
2582 condition_reg_ = (r2_val == 0) ? CC_EQ : CC_LT; // CC0 - result is zero
2583 // CC1 - result is negative
2584 break;
2585 }
2586 case BASR: {
2587 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2588 int r1 = rrinst->R1Value();
2589 int r2 = rrinst->R2Value();
2590 intptr_t link_addr = get_pc() + 2;
2591 // If R2 is zero, the BASR does not branch.
2592 int64_t r2_val = (r2 == 0) ? link_addr : get_register(r2);
2593 #if (!V8_TARGET_ARCH_S390X && V8_HOST_ARCH_S390)
2594 // On 31-bit, the top most bit may be 0 or 1, which can cause issues
2595 // for stackwalker. The top bit should either be cleanse before being
2596 // pushed onto the stack, or during stack walking when dereferenced.
2597 // For simulator, we'll take the worst case scenario and always tag
2598 // the high bit, to flush out more problems.
2599 link_addr |= 0x80000000;
2600 #endif
2601 set_register(r1, link_addr);
2602 set_pc(r2_val);
2603 break;
2604 }
2605 case LCR: {
2606 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2607 int r1 = rrinst->R1Value();
2608 int r2 = rrinst->R2Value();
2609 int32_t r2_val = get_low_register<int32_t>(r2);
2610 int32_t original_r2_val = r2_val;
2611 r2_val = ~r2_val;
2612 r2_val = r2_val + 1;
2613 set_low_register(r1, r2_val);
2614 SetS390ConditionCode<int32_t>(r2_val, 0);
2615 // Checks for overflow where r2_val = -2147483648.
2616 // Cannot do int comparison due to GCC 4.8 bug on x86.
2617 // Detect INT_MIN alternatively, as it is the only value where both
2618 // original and result are negative due to overflow.
2619 if (r2_val < 0 && original_r2_val < 0) {
2620 SetS390OverflowCode(true);
2621 }
2622 break;
2623 }
2624 case BKPT: {
2625 set_pc(get_pc() + 2);
2626 S390Debugger dbg(this);
2627 dbg.Debug();
2628 break;
2629 }
2630 default:
2631 UNREACHABLE();
2632 return false;
2633 break;
2634 }
2635 return true;
2636 }
2637
2638 // Decode routine for four-byte instructions
DecodeFourByte(Instruction * instr)2639 bool Simulator::DecodeFourByte(Instruction* instr) {
2640 Opcode op = instr->S390OpcodeValue();
2641
2642 // Pre-cast instruction to various types
2643 RREInstruction* rreInst = reinterpret_cast<RREInstruction*>(instr);
2644 SIInstruction* siInstr = reinterpret_cast<SIInstruction*>(instr);
2645
2646 switch (op) {
2647 case POPCNT_Z: {
2648 int r1 = rreInst->R1Value();
2649 int r2 = rreInst->R2Value();
2650 int64_t r2_val = get_register(r2);
2651 int64_t r1_val = 0;
2652
2653 uint8_t* r2_val_ptr = reinterpret_cast<uint8_t*>(&r2_val);
2654 uint8_t* r1_val_ptr = reinterpret_cast<uint8_t*>(&r1_val);
2655 for (int i = 0; i < 8; i++) {
2656 uint32_t x = static_cast<uint32_t>(r2_val_ptr[i]);
2657 #if defined(__GNUC__)
2658 r1_val_ptr[i] = __builtin_popcount(x);
2659 #else
2660 #error unsupport __builtin_popcount
2661 #endif
2662 }
2663
2664 set_register(r1, static_cast<uint64_t>(r1_val));
2665 break;
2666 }
2667 case LLGFR: {
2668 int r1 = rreInst->R1Value();
2669 int r2 = rreInst->R2Value();
2670 int32_t r2_val = get_low_register<int32_t>(r2);
2671 uint64_t r2_finalval =
2672 (static_cast<uint64_t>(r2_val) & 0x00000000ffffffff);
2673 set_register(r1, r2_finalval);
2674 break;
2675 }
2676 case EX: {
2677 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr);
2678 int r1 = rxinst->R1Value();
2679 int b2 = rxinst->B2Value();
2680 int x2 = rxinst->X2Value();
2681 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
2682 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
2683 intptr_t d2_val = rxinst->D2Value();
2684 int32_t r1_val = get_low_register<int32_t>(r1);
2685
2686 SixByteInstr the_instr = Instruction::InstructionBits(
2687 reinterpret_cast<const byte*>(b2_val + x2_val + d2_val));
2688 int length = Instruction::InstructionLength(
2689 reinterpret_cast<const byte*>(b2_val + x2_val + d2_val));
2690
2691 char new_instr_buf[8];
2692 char* addr = reinterpret_cast<char*>(&new_instr_buf[0]);
2693 the_instr |= static_cast<SixByteInstr>(r1_val & 0xff)
2694 << (8 * length - 16);
2695 Instruction::SetInstructionBits<SixByteInstr>(
2696 reinterpret_cast<byte*>(addr), static_cast<SixByteInstr>(the_instr));
2697 ExecuteInstruction(reinterpret_cast<Instruction*>(addr), false);
2698 break;
2699 }
2700 case LGR: {
2701 // Load Register (64)
2702 int r1 = rreInst->R1Value();
2703 int r2 = rreInst->R2Value();
2704 set_register(r1, get_register(r2));
2705 break;
2706 }
2707 case LDGR: {
2708 // Load FPR from GPR (L <- 64)
2709 uint64_t int_val = get_register(rreInst->R2Value());
2710 // double double_val = bit_cast<double, uint64_t>(int_val);
2711 // set_d_register_from_double(rreInst->R1Value(), double_val);
2712 set_d_register(rreInst->R1Value(), int_val);
2713 break;
2714 }
2715 case LGDR: {
2716 // Load GPR from FPR (64 <- L)
2717 int64_t double_val = get_d_register(rreInst->R2Value());
2718 set_register(rreInst->R1Value(), double_val);
2719 break;
2720 }
2721 case LTGR: {
2722 // Load Register (64)
2723 int r1 = rreInst->R1Value();
2724 int r2 = rreInst->R2Value();
2725 int64_t r2_val = get_register(r2);
2726 SetS390ConditionCode<int64_t>(r2_val, 0);
2727 set_register(r1, get_register(r2));
2728 break;
2729 }
2730 case LZDR: {
2731 int r1 = rreInst->R1Value();
2732 set_d_register_from_double(r1, 0.0);
2733 break;
2734 }
2735 case LTEBR: {
2736 RREInstruction* rreinst = reinterpret_cast<RREInstruction*>(instr);
2737 int r1 = rreinst->R1Value();
2738 int r2 = rreinst->R2Value();
2739 int64_t r2_val = get_d_register(r2);
2740 float fr2_val = get_float32_from_d_register(r2);
2741 SetS390ConditionCode<float>(fr2_val, 0.0);
2742 set_d_register(r1, r2_val);
2743 break;
2744 }
2745 case LTDBR: {
2746 RREInstruction* rreinst = reinterpret_cast<RREInstruction*>(instr);
2747 int r1 = rreinst->R1Value();
2748 int r2 = rreinst->R2Value();
2749 int64_t r2_val = get_d_register(r2);
2750 SetS390ConditionCode<double>(bit_cast<double, int64_t>(r2_val), 0.0);
2751 set_d_register(r1, r2_val);
2752 break;
2753 }
2754 case CGR: {
2755 // Compare (64)
2756 int64_t r1_val = get_register(rreInst->R1Value());
2757 int64_t r2_val = get_register(rreInst->R2Value());
2758 SetS390ConditionCode<int64_t>(r1_val, r2_val);
2759 break;
2760 }
2761 case CLGR: {
2762 // Compare Logical (64)
2763 uint64_t r1_val = static_cast<uint64_t>(get_register(rreInst->R1Value()));
2764 uint64_t r2_val = static_cast<uint64_t>(get_register(rreInst->R2Value()));
2765 SetS390ConditionCode<uint64_t>(r1_val, r2_val);
2766 break;
2767 }
2768 case LH: {
2769 // Load Halfword
2770 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr);
2771 int r1 = rxinst->R1Value();
2772 int x2 = rxinst->X2Value();
2773 int b2 = rxinst->B2Value();
2774
2775 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
2776 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
2777 intptr_t d2_val = rxinst->D2Value();
2778 intptr_t mem_addr = x2_val + b2_val + d2_val;
2779
2780 int32_t result = static_cast<int32_t>(ReadH(mem_addr, instr));
2781 set_low_register(r1, result);
2782 break;
2783 }
2784 case LHI: {
2785 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr);
2786 int r1 = riinst->R1Value();
2787 int i = riinst->I2Value();
2788 set_low_register(r1, i);
2789 break;
2790 }
2791 case LGHI: {
2792 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr);
2793 int r1 = riinst->R1Value();
2794 int64_t i = riinst->I2Value();
2795 set_register(r1, i);
2796 break;
2797 }
2798 case CHI: {
2799 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr);
2800 int r1 = riinst->R1Value();
2801 int16_t i = riinst->I2Value();
2802 int32_t r1_val = get_low_register<int32_t>(r1);
2803 SetS390ConditionCode<int32_t>(r1_val, i);
2804 break;
2805 }
2806 case CGHI: {
2807 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr);
2808 int r1 = riinst->R1Value();
2809 int64_t i = static_cast<int64_t>(riinst->I2Value());
2810 int64_t r1_val = get_register(r1);
2811 SetS390ConditionCode<int64_t>(r1_val, i);
2812 break;
2813 }
2814 case BRAS: {
2815 // Branch Relative and Save
2816 RILInstruction* rilInstr = reinterpret_cast<RILInstruction*>(instr);
2817 int r1 = rilInstr->R1Value();
2818 intptr_t d2 = rilInstr->I2Value();
2819 intptr_t pc = get_pc();
2820 // Set PC of next instruction to register
2821 set_register(r1, pc + sizeof(FourByteInstr));
2822 // Update PC to branch target
2823 set_pc(pc + d2 * 2);
2824 break;
2825 }
2826 case BRC: {
2827 // Branch Relative on Condition
2828 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr);
2829 int m1 = riinst->M1Value();
2830 if (TestConditionCode((Condition)m1)) {
2831 intptr_t offset = riinst->I2Value() * 2;
2832 set_pc(get_pc() + offset);
2833 }
2834 break;
2835 }
2836 case BRCT:
2837 case BRCTG: {
2838 // Branch On Count (32/64).
2839 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr);
2840 int r1 = riinst->R1Value();
2841 int64_t value =
2842 (op == BRCT) ? get_low_register<int32_t>(r1) : get_register(r1);
2843 if (BRCT == op)
2844 set_low_register(r1, --value);
2845 else
2846 set_register(r1, --value);
2847 // Branch if value != 0
2848 if (value != 0) {
2849 intptr_t offset = riinst->I2Value() * 2;
2850 set_pc(get_pc() + offset);
2851 }
2852 break;
2853 }
2854 case BXH: {
2855 RSInstruction* rsinst = reinterpret_cast<RSInstruction*>(instr);
2856 int r1 = rsinst->R1Value();
2857 int r3 = rsinst->R3Value();
2858 int b2 = rsinst->B2Value();
2859 int d2 = rsinst->D2Value();
2860
2861 // r1_val is the first operand, r3_val is the increment
2862 int32_t r1_val = r1 == 0 ? 0 : get_register(r1);
2863 int32_t r3_val = r2 == 0 ? 0 : get_register(r3);
2864 intptr_t b2_val = b2 == 0 ? 0 : get_register(b2);
2865 intptr_t branch_address = b2_val + d2;
2866 // increment r1_val
2867 r1_val += r3_val;
2868
2869 // if the increment is even, then it designates a pair of registers
2870 // and the contents of the even and odd registers of the pair are used as
2871 // the increment and compare value respectively. If the increment is odd,
2872 // the increment itself is used as both the increment and compare value
2873 int32_t compare_val = r3 % 2 == 0 ? get_register(r3 + 1) : r3_val;
2874 if (r1_val > compare_val) {
2875 // branch to address if r1_val is greater than compare value
2876 set_pc(branch_address);
2877 }
2878
2879 // update contents of register in r1 with the new incremented value
2880 set_register(r1, r1_val);
2881 break;
2882 }
2883 case IIHH:
2884 case IIHL:
2885 case IILH:
2886 case IILL: {
2887 UNIMPLEMENTED();
2888 break;
2889 }
2890 case STM:
2891 case LM: {
2892 // Store Multiple 32-bits.
2893 RSInstruction* rsinstr = reinterpret_cast<RSInstruction*>(instr);
2894 int r1 = rsinstr->R1Value();
2895 int r3 = rsinstr->R3Value();
2896 int rb = rsinstr->B2Value();
2897 int offset = rsinstr->D2Value();
2898
2899 // Regs roll around if r3 is less than r1.
2900 // Artifically increase r3 by 16 so we can calculate
2901 // the number of regs stored properly.
2902 if (r3 < r1) r3 += 16;
2903
2904 int32_t rb_val = (rb == 0) ? 0 : get_low_register<int32_t>(rb);
2905
2906 // Store each register in ascending order.
2907 for (int i = 0; i <= r3 - r1; i++) {
2908 if (op == STM) {
2909 int32_t value = get_low_register<int32_t>((r1 + i) % 16);
2910 WriteW(rb_val + offset + 4 * i, value, instr);
2911 } else if (op == LM) {
2912 int32_t value = ReadW(rb_val + offset + 4 * i, instr);
2913 set_low_register((r1 + i) % 16, value);
2914 }
2915 }
2916 break;
2917 }
2918 case SLL:
2919 case SRL: {
2920 RSInstruction* rsInstr = reinterpret_cast<RSInstruction*>(instr);
2921 int r1 = rsInstr->R1Value();
2922 int b2 = rsInstr->B2Value();
2923 intptr_t d2 = rsInstr->D2Value();
2924 // only takes rightmost 6bits
2925 int64_t b2_val = b2 == 0 ? 0 : get_register(b2);
2926 int shiftBits = (b2_val + d2) & 0x3F;
2927 uint32_t r1_val = get_low_register<uint32_t>(r1);
2928 uint32_t alu_out = 0;
2929 if (SLL == op) {
2930 alu_out = r1_val << shiftBits;
2931 } else if (SRL == op) {
2932 alu_out = r1_val >> shiftBits;
2933 } else {
2934 UNREACHABLE();
2935 }
2936 set_low_register(r1, alu_out);
2937 break;
2938 }
2939 case SLDL: {
2940 RSInstruction* rsInstr = reinterpret_cast<RSInstruction*>(instr);
2941 int r1 = rsInstr->R1Value();
2942 int b2 = rsInstr->B2Value();
2943 intptr_t d2 = rsInstr->D2Value();
2944 // only takes rightmost 6bits
2945 int64_t b2_val = b2 == 0 ? 0 : get_register(b2);
2946 int shiftBits = (b2_val + d2) & 0x3F;
2947
2948 DCHECK(r1 % 2 == 0);
2949 uint32_t r1_val = get_low_register<uint32_t>(r1);
2950 uint32_t r1_next_val = get_low_register<uint32_t>(r1 + 1);
2951 uint64_t alu_out = (static_cast<uint64_t>(r1_val) << 32) |
2952 (static_cast<uint64_t>(r1_next_val));
2953 alu_out <<= shiftBits;
2954 set_low_register(r1 + 1, static_cast<uint32_t>(alu_out));
2955 set_low_register(r1, static_cast<uint32_t>(alu_out >> 32));
2956 break;
2957 }
2958 case SLA:
2959 case SRA: {
2960 RSInstruction* rsInstr = reinterpret_cast<RSInstruction*>(instr);
2961 int r1 = rsInstr->R1Value();
2962 int b2 = rsInstr->B2Value();
2963 intptr_t d2 = rsInstr->D2Value();
2964 // only takes rightmost 6bits
2965 int64_t b2_val = b2 == 0 ? 0 : get_register(b2);
2966 int shiftBits = (b2_val + d2) & 0x3F;
2967 int32_t r1_val = get_low_register<int32_t>(r1);
2968 int32_t alu_out = 0;
2969 bool isOF = false;
2970 if (op == SLA) {
2971 isOF = CheckOverflowForShiftLeft(r1_val, shiftBits);
2972 alu_out = r1_val << shiftBits;
2973 } else if (op == SRA) {
2974 alu_out = r1_val >> shiftBits;
2975 }
2976 set_low_register(r1, alu_out);
2977 SetS390ConditionCode<int32_t>(alu_out, 0);
2978 SetS390OverflowCode(isOF);
2979 break;
2980 }
2981 case LLHR: {
2982 UNIMPLEMENTED();
2983 break;
2984 }
2985 case LLGHR: {
2986 UNIMPLEMENTED();
2987 break;
2988 }
2989 case L:
2990 case LA:
2991 case LD:
2992 case LE: {
2993 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr);
2994 int b2 = rxinst->B2Value();
2995 int x2 = rxinst->X2Value();
2996 int32_t r1 = rxinst->R1Value();
2997 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
2998 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
2999 intptr_t d2_val = rxinst->D2Value();
3000 intptr_t addr = b2_val + x2_val + d2_val;
3001 if (op == L) {
3002 int32_t mem_val = ReadW(addr, instr);
3003 set_low_register(r1, mem_val);
3004 } else if (op == LA) {
3005 set_register(r1, addr);
3006 } else if (op == LD) {
3007 int64_t dbl_val = *reinterpret_cast<int64_t*>(addr);
3008 set_d_register(r1, dbl_val);
3009 } else if (op == LE) {
3010 float float_val = *reinterpret_cast<float*>(addr);
3011 set_d_register_from_float32(r1, float_val);
3012 }
3013 break;
3014 }
3015 case C:
3016 case CL: {
3017 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr);
3018 int b2 = rxinst->B2Value();
3019 int x2 = rxinst->X2Value();
3020 int32_t r1_val = get_low_register<int32_t>(rxinst->R1Value());
3021 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
3022 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
3023 intptr_t d2_val = rxinst->D2Value();
3024 intptr_t addr = b2_val + x2_val + d2_val;
3025 int32_t mem_val = ReadW(addr, instr);
3026 if (C == op)
3027 SetS390ConditionCode<int32_t>(r1_val, mem_val);
3028 else if (CL == op)
3029 SetS390ConditionCode<uint32_t>(r1_val, mem_val);
3030 break;
3031 }
3032 case CLI: {
3033 // Compare Immediate (Mem - Imm) (8)
3034 int b1 = siInstr->B1Value();
3035 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
3036 intptr_t d1_val = siInstr->D1Value();
3037 intptr_t addr = b1_val + d1_val;
3038 uint8_t mem_val = ReadB(addr);
3039 uint8_t imm_val = siInstr->I2Value();
3040 SetS390ConditionCode<uint8_t>(mem_val, imm_val);
3041 break;
3042 }
3043 case TM: {
3044 // Test Under Mask (Mem - Imm) (8)
3045 int b1 = siInstr->B1Value();
3046 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
3047 intptr_t d1_val = siInstr->D1Value();
3048 intptr_t addr = b1_val + d1_val;
3049 uint8_t mem_val = ReadB(addr);
3050 uint8_t imm_val = siInstr->I2Value();
3051 uint8_t selected_bits = mem_val & imm_val;
3052 // CC0: Selected bits are zero
3053 // CC1: Selected bits mixed zeros and ones
3054 // CC3: Selected bits all ones
3055 if (0 == selected_bits) {
3056 condition_reg_ = CC_EQ; // CC0
3057 } else if (selected_bits == imm_val) {
3058 condition_reg_ = 0x1; // CC3
3059 } else {
3060 condition_reg_ = 0x4; // CC1
3061 }
3062 break;
3063 }
3064 case ST:
3065 case STE:
3066 case STD: {
3067 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr);
3068 int b2 = rxinst->B2Value();
3069 int x2 = rxinst->X2Value();
3070 int32_t r1_val = get_low_register<int32_t>(rxinst->R1Value());
3071 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
3072 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
3073 intptr_t d2_val = rxinst->D2Value();
3074 intptr_t addr = b2_val + x2_val + d2_val;
3075 if (op == ST) {
3076 WriteW(addr, r1_val, instr);
3077 } else if (op == STD) {
3078 int64_t frs_val = get_d_register(rxinst->R1Value());
3079 WriteDW(addr, frs_val);
3080 } else if (op == STE) {
3081 int64_t frs_val = get_d_register(rxinst->R1Value()) >> 32;
3082 WriteW(addr, static_cast<int32_t>(frs_val), instr);
3083 }
3084 break;
3085 }
3086 case LTGFR:
3087 case LGFR: {
3088 // Load and Test Register (64 <- 32) (Sign Extends 32-bit val)
3089 // Load Register (64 <- 32) (Sign Extends 32-bit val)
3090 RREInstruction* rreInstr = reinterpret_cast<RREInstruction*>(instr);
3091 int r1 = rreInstr->R1Value();
3092 int r2 = rreInstr->R2Value();
3093 int32_t r2_val = get_low_register<int32_t>(r2);
3094 int64_t result = static_cast<int64_t>(r2_val);
3095 set_register(r1, result);
3096
3097 if (LTGFR == op) SetS390ConditionCode<int64_t>(result, 0);
3098 break;
3099 }
3100 case LNGR: {
3101 // Load Negative (64)
3102 int r1 = rreInst->R1Value();
3103 int r2 = rreInst->R2Value();
3104 int64_t r2_val = get_register(r2);
3105 r2_val = (r2_val >= 0) ? -r2_val : r2_val; // If pos, then negate it.
3106 set_register(r1, r2_val);
3107 condition_reg_ = (r2_val == 0) ? CC_EQ : CC_LT; // CC0 - result is zero
3108 // CC1 - result is negative
3109 break;
3110 }
3111 case TRAP4: {
3112 // whack the space of the caller allocated stack
3113 int64_t sp_addr = get_register(sp);
3114 for (int i = 0; i < kCalleeRegisterSaveAreaSize / kPointerSize; ++i) {
3115 // we dont want to whack the RA (r14)
3116 if (i != 14) (reinterpret_cast<intptr_t*>(sp_addr))[i] = 0xdeadbabe;
3117 }
3118 SoftwareInterrupt(instr);
3119 break;
3120 }
3121 case STC: {
3122 // Store Character/Byte
3123 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr);
3124 int b2 = rxinst->B2Value();
3125 int x2 = rxinst->X2Value();
3126 uint8_t r1_val = get_low_register<int32_t>(rxinst->R1Value());
3127 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
3128 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
3129 intptr_t d2_val = rxinst->D2Value();
3130 intptr_t mem_addr = b2_val + x2_val + d2_val;
3131 WriteB(mem_addr, r1_val);
3132 break;
3133 }
3134 case STH: {
3135 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr);
3136 int b2 = rxinst->B2Value();
3137 int x2 = rxinst->X2Value();
3138 int16_t r1_val = get_low_register<int32_t>(rxinst->R1Value());
3139 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
3140 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
3141 intptr_t d2_val = rxinst->D2Value();
3142 intptr_t mem_addr = b2_val + x2_val + d2_val;
3143 WriteH(mem_addr, r1_val, instr);
3144 break;
3145 }
3146 #if V8_TARGET_ARCH_S390X
3147 case LCGR: {
3148 int r1 = rreInst->R1Value();
3149 int r2 = rreInst->R2Value();
3150 int64_t r2_val = get_register(r2);
3151 r2_val = ~r2_val;
3152 r2_val = r2_val + 1;
3153 set_register(r1, r2_val);
3154 SetS390ConditionCode<int64_t>(r2_val, 0);
3155 // if the input is INT_MIN, loading its compliment would be overflowing
3156 if (r2_val < 0 && (r2_val + 1) > 0) {
3157 SetS390OverflowCode(true);
3158 }
3159 break;
3160 }
3161 #endif
3162 case SRDA: {
3163 RSInstruction* rsInstr = reinterpret_cast<RSInstruction*>(instr);
3164 int r1 = rsInstr->R1Value();
3165 DCHECK(r1 % 2 == 0); // must be a reg pair
3166 int b2 = rsInstr->B2Value();
3167 intptr_t d2 = rsInstr->D2Value();
3168 // only takes rightmost 6bits
3169 int64_t b2_val = b2 == 0 ? 0 : get_register(b2);
3170 int shiftBits = (b2_val + d2) & 0x3F;
3171 int64_t opnd1 = static_cast<int64_t>(get_low_register<int32_t>(r1)) << 32;
3172 int64_t opnd2 = static_cast<uint64_t>(get_low_register<uint32_t>(r1 + 1));
3173 int64_t r1_val = opnd1 + opnd2;
3174 int64_t alu_out = r1_val >> shiftBits;
3175 set_low_register(r1, alu_out >> 32);
3176 set_low_register(r1 + 1, alu_out & 0x00000000FFFFFFFF);
3177 SetS390ConditionCode<int32_t>(alu_out, 0);
3178 break;
3179 }
3180 case SRDL: {
3181 RSInstruction* rsInstr = reinterpret_cast<RSInstruction*>(instr);
3182 int r1 = rsInstr->R1Value();
3183 DCHECK(r1 % 2 == 0); // must be a reg pair
3184 int b2 = rsInstr->B2Value();
3185 intptr_t d2 = rsInstr->D2Value();
3186 // only takes rightmost 6bits
3187 int64_t b2_val = b2 == 0 ? 0 : get_register(b2);
3188 int shiftBits = (b2_val + d2) & 0x3F;
3189 uint64_t opnd1 = static_cast<uint64_t>(get_low_register<uint32_t>(r1))
3190 << 32;
3191 uint64_t opnd2 =
3192 static_cast<uint64_t>(get_low_register<uint32_t>(r1 + 1));
3193 uint64_t r1_val = opnd1 | opnd2;
3194 uint64_t alu_out = r1_val >> shiftBits;
3195 set_low_register(r1, alu_out >> 32);
3196 set_low_register(r1 + 1, alu_out & 0x00000000FFFFFFFF);
3197 SetS390ConditionCode<int32_t>(alu_out, 0);
3198 break;
3199 }
3200 default: { return DecodeFourByteArithmetic(instr); }
3201 }
3202 return true;
3203 }
3204
DecodeFourByteArithmetic64Bit(Instruction * instr)3205 bool Simulator::DecodeFourByteArithmetic64Bit(Instruction* instr) {
3206 Opcode op = instr->S390OpcodeValue();
3207
3208 RRFInstruction* rrfInst = reinterpret_cast<RRFInstruction*>(instr);
3209 RREInstruction* rreInst = reinterpret_cast<RREInstruction*>(instr);
3210
3211 switch (op) {
3212 case AGR:
3213 case SGR:
3214 case OGR:
3215 case NGR:
3216 case XGR: {
3217 int r1 = rreInst->R1Value();
3218 int r2 = rreInst->R2Value();
3219 int64_t r1_val = get_register(r1);
3220 int64_t r2_val = get_register(r2);
3221 bool isOF = false;
3222 switch (op) {
3223 case AGR:
3224 isOF = CheckOverflowForIntAdd(r1_val, r2_val, int64_t);
3225 r1_val += r2_val;
3226 SetS390ConditionCode<int64_t>(r1_val, 0);
3227 SetS390OverflowCode(isOF);
3228 break;
3229 case SGR:
3230 isOF = CheckOverflowForIntSub(r1_val, r2_val, int64_t);
3231 r1_val -= r2_val;
3232 SetS390ConditionCode<int64_t>(r1_val, 0);
3233 SetS390OverflowCode(isOF);
3234 break;
3235 case OGR:
3236 r1_val |= r2_val;
3237 SetS390BitWiseConditionCode<uint64_t>(r1_val);
3238 break;
3239 case NGR:
3240 r1_val &= r2_val;
3241 SetS390BitWiseConditionCode<uint64_t>(r1_val);
3242 break;
3243 case XGR:
3244 r1_val ^= r2_val;
3245 SetS390BitWiseConditionCode<uint64_t>(r1_val);
3246 break;
3247 default:
3248 UNREACHABLE();
3249 break;
3250 }
3251 set_register(r1, r1_val);
3252 break;
3253 }
3254 case AGFR: {
3255 // Add Register (64 <- 32) (Sign Extends 32-bit val)
3256 int r1 = rreInst->R1Value();
3257 int r2 = rreInst->R2Value();
3258 int64_t r1_val = get_register(r1);
3259 int64_t r2_val = static_cast<int64_t>(get_low_register<int32_t>(r2));
3260 bool isOF = CheckOverflowForIntAdd(r1_val, r2_val, int64_t);
3261 r1_val += r2_val;
3262 SetS390ConditionCode<int64_t>(r1_val, 0);
3263 SetS390OverflowCode(isOF);
3264 set_register(r1, r1_val);
3265 break;
3266 }
3267 case SGFR: {
3268 // Sub Reg (64 <- 32)
3269 int r1 = rreInst->R1Value();
3270 int r2 = rreInst->R2Value();
3271 int64_t r1_val = get_register(r1);
3272 int64_t r2_val = static_cast<int64_t>(get_low_register<int32_t>(r2));
3273 bool isOF = false;
3274 isOF = CheckOverflowForIntSub(r1_val, r2_val, int64_t);
3275 r1_val -= r2_val;
3276 SetS390ConditionCode<int64_t>(r1_val, 0);
3277 SetS390OverflowCode(isOF);
3278 set_register(r1, r1_val);
3279 break;
3280 }
3281 case AGRK:
3282 case SGRK:
3283 case NGRK:
3284 case OGRK:
3285 case XGRK: {
3286 // 64-bit Non-clobbering arithmetics / bitwise ops.
3287 int r1 = rrfInst->R1Value();
3288 int r2 = rrfInst->R2Value();
3289 int r3 = rrfInst->R3Value();
3290 int64_t r2_val = get_register(r2);
3291 int64_t r3_val = get_register(r3);
3292 if (AGRK == op) {
3293 bool isOF = CheckOverflowForIntAdd(r2_val, r3_val, int64_t);
3294 SetS390ConditionCode<int64_t>(r2_val + r3_val, 0);
3295 SetS390OverflowCode(isOF);
3296 set_register(r1, r2_val + r3_val);
3297 } else if (SGRK == op) {
3298 bool isOF = CheckOverflowForIntSub(r2_val, r3_val, int64_t);
3299 SetS390ConditionCode<int64_t>(r2_val - r3_val, 0);
3300 SetS390OverflowCode(isOF);
3301 set_register(r1, r2_val - r3_val);
3302 } else {
3303 // Assume bitwise operation here
3304 uint64_t bitwise_result = 0;
3305 if (NGRK == op) {
3306 bitwise_result = r2_val & r3_val;
3307 } else if (OGRK == op) {
3308 bitwise_result = r2_val | r3_val;
3309 } else if (XGRK == op) {
3310 bitwise_result = r2_val ^ r3_val;
3311 }
3312 SetS390BitWiseConditionCode<uint64_t>(bitwise_result);
3313 set_register(r1, bitwise_result);
3314 }
3315 break;
3316 }
3317 case ALGRK:
3318 case SLGRK: {
3319 // 64-bit Non-clobbering unsigned arithmetics
3320 int r1 = rrfInst->R1Value();
3321 int r2 = rrfInst->R2Value();
3322 int r3 = rrfInst->R3Value();
3323 uint64_t r2_val = get_register(r2);
3324 uint64_t r3_val = get_register(r3);
3325 if (ALGRK == op) {
3326 bool isOF = CheckOverflowForUIntAdd(r2_val, r3_val);
3327 SetS390ConditionCode<uint64_t>(r2_val + r3_val, 0);
3328 SetS390OverflowCode(isOF);
3329 set_register(r1, r2_val + r3_val);
3330 } else if (SLGRK == op) {
3331 bool isOF = CheckOverflowForUIntSub(r2_val, r3_val);
3332 SetS390ConditionCode<uint64_t>(r2_val - r3_val, 0);
3333 SetS390OverflowCode(isOF);
3334 set_register(r1, r2_val - r3_val);
3335 }
3336 break;
3337 }
3338 case AGHI:
3339 case MGHI: {
3340 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr);
3341 int32_t r1 = riinst->R1Value();
3342 int64_t i = static_cast<int64_t>(riinst->I2Value());
3343 int64_t r1_val = get_register(r1);
3344 bool isOF = false;
3345 switch (op) {
3346 case AGHI:
3347 isOF = CheckOverflowForIntAdd(r1_val, i, int64_t);
3348 r1_val += i;
3349 break;
3350 case MGHI:
3351 isOF = CheckOverflowForMul(r1_val, i);
3352 r1_val *= i;
3353 break; // no overflow indication is given
3354 default:
3355 break;
3356 }
3357 set_register(r1, r1_val);
3358 SetS390ConditionCode<int32_t>(r1_val, 0);
3359 SetS390OverflowCode(isOF);
3360 break;
3361 }
3362 default:
3363 UNREACHABLE();
3364 }
3365 return true;
3366 }
3367
3368 /**
3369 * Decodes and simulates four byte arithmetic instructions
3370 */
DecodeFourByteArithmetic(Instruction * instr)3371 bool Simulator::DecodeFourByteArithmetic(Instruction* instr) {
3372 Opcode op = instr->S390OpcodeValue();
3373
3374 // Pre-cast instruction to various types
3375 RRFInstruction* rrfInst = reinterpret_cast<RRFInstruction*>(instr);
3376
3377 switch (op) {
3378 case AGR:
3379 case SGR:
3380 case OGR:
3381 case NGR:
3382 case XGR:
3383 case AGFR:
3384 case SGFR: {
3385 DecodeFourByteArithmetic64Bit(instr);
3386 break;
3387 }
3388 case ARK:
3389 case SRK:
3390 case NRK:
3391 case ORK:
3392 case XRK: {
3393 // 32-bit Non-clobbering arithmetics / bitwise ops
3394 int r1 = rrfInst->R1Value();
3395 int r2 = rrfInst->R2Value();
3396 int r3 = rrfInst->R3Value();
3397 int32_t r2_val = get_low_register<int32_t>(r2);
3398 int32_t r3_val = get_low_register<int32_t>(r3);
3399 if (ARK == op) {
3400 bool isOF = CheckOverflowForIntAdd(r2_val, r3_val, int32_t);
3401 SetS390ConditionCode<int32_t>(r2_val + r3_val, 0);
3402 SetS390OverflowCode(isOF);
3403 set_low_register(r1, r2_val + r3_val);
3404 } else if (SRK == op) {
3405 bool isOF = CheckOverflowForIntSub(r2_val, r3_val, int32_t);
3406 SetS390ConditionCode<int32_t>(r2_val - r3_val, 0);
3407 SetS390OverflowCode(isOF);
3408 set_low_register(r1, r2_val - r3_val);
3409 } else {
3410 // Assume bitwise operation here
3411 uint32_t bitwise_result = 0;
3412 if (NRK == op) {
3413 bitwise_result = r2_val & r3_val;
3414 } else if (ORK == op) {
3415 bitwise_result = r2_val | r3_val;
3416 } else if (XRK == op) {
3417 bitwise_result = r2_val ^ r3_val;
3418 }
3419 SetS390BitWiseConditionCode<uint32_t>(bitwise_result);
3420 set_low_register(r1, bitwise_result);
3421 }
3422 break;
3423 }
3424 case ALRK:
3425 case SLRK: {
3426 // 32-bit Non-clobbering unsigned arithmetics
3427 int r1 = rrfInst->R1Value();
3428 int r2 = rrfInst->R2Value();
3429 int r3 = rrfInst->R3Value();
3430 uint32_t r2_val = get_low_register<uint32_t>(r2);
3431 uint32_t r3_val = get_low_register<uint32_t>(r3);
3432 if (ALRK == op) {
3433 bool isOF = CheckOverflowForUIntAdd(r2_val, r3_val);
3434 SetS390ConditionCode<uint32_t>(r2_val + r3_val, 0);
3435 SetS390OverflowCode(isOF);
3436 set_low_register(r1, r2_val + r3_val);
3437 } else if (SLRK == op) {
3438 bool isOF = CheckOverflowForUIntSub(r2_val, r3_val);
3439 SetS390ConditionCode<uint32_t>(r2_val - r3_val, 0);
3440 SetS390OverflowCode(isOF);
3441 set_low_register(r1, r2_val - r3_val);
3442 }
3443 break;
3444 }
3445 case AGRK:
3446 case SGRK:
3447 case NGRK:
3448 case OGRK:
3449 case XGRK: {
3450 DecodeFourByteArithmetic64Bit(instr);
3451 break;
3452 }
3453 case ALGRK:
3454 case SLGRK: {
3455 DecodeFourByteArithmetic64Bit(instr);
3456 break;
3457 }
3458 case AHI:
3459 case MHI: {
3460 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr);
3461 int32_t r1 = riinst->R1Value();
3462 int32_t i = riinst->I2Value();
3463 int32_t r1_val = get_low_register<int32_t>(r1);
3464 bool isOF = false;
3465 switch (op) {
3466 case AHI:
3467 isOF = CheckOverflowForIntAdd(r1_val, i, int32_t);
3468 r1_val += i;
3469 break;
3470 case MHI:
3471 isOF = CheckOverflowForMul(r1_val, i);
3472 r1_val *= i;
3473 break; // no overflow indication is given
3474 default:
3475 break;
3476 }
3477 set_low_register(r1, r1_val);
3478 SetS390ConditionCode<int32_t>(r1_val, 0);
3479 SetS390OverflowCode(isOF);
3480 break;
3481 }
3482 case AGHI:
3483 case MGHI: {
3484 DecodeFourByteArithmetic64Bit(instr);
3485 break;
3486 }
3487 case MLR: {
3488 RREInstruction* rreinst = reinterpret_cast<RREInstruction*>(instr);
3489 int r1 = rreinst->R1Value();
3490 int r2 = rreinst->R2Value();
3491 DCHECK(r1 % 2 == 0);
3492
3493 uint32_t r1_val = get_low_register<uint32_t>(r1 + 1);
3494 uint32_t r2_val = get_low_register<uint32_t>(r2);
3495 uint64_t product =
3496 static_cast<uint64_t>(r1_val) * static_cast<uint64_t>(r2_val);
3497 int32_t high_bits = product >> 32;
3498 int32_t low_bits = product & 0x00000000FFFFFFFF;
3499 set_low_register(r1, high_bits);
3500 set_low_register(r1 + 1, low_bits);
3501 break;
3502 }
3503 case DLGR: {
3504 #ifdef V8_TARGET_ARCH_S390X
3505 RREInstruction* rreinst = reinterpret_cast<RREInstruction*>(instr);
3506 int r1 = rreinst->R1Value();
3507 int r2 = rreinst->R2Value();
3508 uint64_t r1_val = get_register(r1);
3509 uint64_t r2_val = get_register(r2);
3510 DCHECK(r1 % 2 == 0);
3511 unsigned __int128 dividend = static_cast<unsigned __int128>(r1_val) << 64;
3512 dividend += get_register(r1 + 1);
3513 uint64_t remainder = dividend % r2_val;
3514 uint64_t quotient = dividend / r2_val;
3515 r1_val = remainder;
3516 set_register(r1, remainder);
3517 set_register(r1 + 1, quotient);
3518 #else
3519 UNREACHABLE();
3520 #endif
3521 break;
3522 }
3523 case DLR: {
3524 RREInstruction* rreinst = reinterpret_cast<RREInstruction*>(instr);
3525 int r1 = rreinst->R1Value();
3526 int r2 = rreinst->R2Value();
3527 uint32_t r1_val = get_low_register<uint32_t>(r1);
3528 uint32_t r2_val = get_low_register<uint32_t>(r2);
3529 DCHECK(r1 % 2 == 0);
3530 uint64_t dividend = static_cast<uint64_t>(r1_val) << 32;
3531 dividend += get_low_register<uint32_t>(r1 + 1);
3532 uint32_t remainder = dividend % r2_val;
3533 uint32_t quotient = dividend / r2_val;
3534 r1_val = remainder;
3535 set_low_register(r1, remainder);
3536 set_low_register(r1 + 1, quotient);
3537 break;
3538 }
3539 case A:
3540 case S:
3541 case M:
3542 case D:
3543 case O:
3544 case N:
3545 case X: {
3546 // 32-bit Reg-Mem instructions
3547 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr);
3548 int b2 = rxinst->B2Value();
3549 int x2 = rxinst->X2Value();
3550 int32_t r1_val = get_low_register<int32_t>(rxinst->R1Value());
3551 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
3552 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
3553 intptr_t d2_val = rxinst->D2Value();
3554 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr);
3555 int32_t alu_out = 0;
3556 bool isOF = false;
3557 switch (op) {
3558 case A:
3559 isOF = CheckOverflowForIntAdd(r1_val, mem_val, int32_t);
3560 alu_out = r1_val + mem_val;
3561 SetS390ConditionCode<int32_t>(alu_out, 0);
3562 SetS390OverflowCode(isOF);
3563 break;
3564 case S:
3565 isOF = CheckOverflowForIntSub(r1_val, mem_val, int32_t);
3566 alu_out = r1_val - mem_val;
3567 SetS390ConditionCode<int32_t>(alu_out, 0);
3568 SetS390OverflowCode(isOF);
3569 break;
3570 case M:
3571 case D:
3572 UNIMPLEMENTED();
3573 break;
3574 case O:
3575 alu_out = r1_val | mem_val;
3576 SetS390BitWiseConditionCode<uint32_t>(alu_out);
3577 break;
3578 case N:
3579 alu_out = r1_val & mem_val;
3580 SetS390BitWiseConditionCode<uint32_t>(alu_out);
3581 break;
3582 case X:
3583 alu_out = r1_val ^ mem_val;
3584 SetS390BitWiseConditionCode<uint32_t>(alu_out);
3585 break;
3586 default:
3587 UNREACHABLE();
3588 break;
3589 }
3590 set_low_register(r1, alu_out);
3591 break;
3592 }
3593 case OILL:
3594 case OIHL: {
3595 RIInstruction* riInst = reinterpret_cast<RIInstruction*>(instr);
3596 int r1 = riInst->R1Value();
3597 int i = riInst->I2Value();
3598 int32_t r1_val = get_low_register<int32_t>(r1);
3599 if (OILL == op) {
3600 // CC is set based on the 16 bits that are AND'd
3601 SetS390BitWiseConditionCode<uint16_t>(r1_val | i);
3602 } else if (OILH == op) {
3603 // CC is set based on the 16 bits that are AND'd
3604 SetS390BitWiseConditionCode<uint16_t>((r1_val >> 16) | i);
3605 i = i << 16;
3606 } else {
3607 UNIMPLEMENTED();
3608 }
3609 set_low_register(r1, r1_val | i);
3610 break;
3611 }
3612 case NILL:
3613 case NILH: {
3614 RIInstruction* riInst = reinterpret_cast<RIInstruction*>(instr);
3615 int r1 = riInst->R1Value();
3616 int i = riInst->I2Value();
3617 int32_t r1_val = get_low_register<int32_t>(r1);
3618 if (NILL == op) {
3619 // CC is set based on the 16 bits that are AND'd
3620 SetS390BitWiseConditionCode<uint16_t>(r1_val & i);
3621 i |= 0xFFFF0000;
3622 } else if (NILH == op) {
3623 // CC is set based on the 16 bits that are AND'd
3624 SetS390BitWiseConditionCode<uint16_t>((r1_val >> 16) & i);
3625 i = (i << 16) | 0x0000FFFF;
3626 } else {
3627 UNIMPLEMENTED();
3628 }
3629 set_low_register(r1, r1_val & i);
3630 break;
3631 }
3632 case AH:
3633 case SH:
3634 case MH: {
3635 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr);
3636 int b2 = rxinst->B2Value();
3637 int x2 = rxinst->X2Value();
3638 int32_t r1_val = get_low_register<int32_t>(rxinst->R1Value());
3639 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
3640 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
3641 intptr_t d2_val = rxinst->D2Value();
3642 intptr_t addr = b2_val + x2_val + d2_val;
3643 int32_t mem_val = static_cast<int32_t>(ReadH(addr, instr));
3644 int32_t alu_out = 0;
3645 bool isOF = false;
3646 if (AH == op) {
3647 isOF = CheckOverflowForIntAdd(r1_val, mem_val, int32_t);
3648 alu_out = r1_val + mem_val;
3649 } else if (SH == op) {
3650 isOF = CheckOverflowForIntSub(r1_val, mem_val, int32_t);
3651 alu_out = r1_val - mem_val;
3652 } else if (MH == op) {
3653 alu_out = r1_val * mem_val;
3654 } else {
3655 UNREACHABLE();
3656 }
3657 set_low_register(r1, alu_out);
3658 if (MH != op) { // MH does not change condition code
3659 SetS390ConditionCode<int32_t>(alu_out, 0);
3660 SetS390OverflowCode(isOF);
3661 }
3662 break;
3663 }
3664 case DSGR: {
3665 RREInstruction* rreInst = reinterpret_cast<RREInstruction*>(instr);
3666 int r1 = rreInst->R1Value();
3667 int r2 = rreInst->R2Value();
3668
3669 DCHECK(r1 % 2 == 0);
3670
3671 int64_t dividend = get_register(r1 + 1);
3672 int64_t divisor = get_register(r2);
3673 set_register(r1, dividend % divisor);
3674 set_register(r1 + 1, dividend / divisor);
3675
3676 break;
3677 }
3678 case FLOGR: {
3679 RREInstruction* rreInst = reinterpret_cast<RREInstruction*>(instr);
3680 int r1 = rreInst->R1Value();
3681 int r2 = rreInst->R2Value();
3682
3683 DCHECK(r1 % 2 == 0);
3684
3685 int64_t r2_val = get_register(r2);
3686
3687 int i = 0;
3688 for (; i < 64; i++) {
3689 if (r2_val < 0) break;
3690 r2_val <<= 1;
3691 }
3692
3693 r2_val = get_register(r2);
3694
3695 int64_t mask = ~(1 << (63 - i));
3696 set_register(r1, i);
3697 set_register(r1 + 1, r2_val & mask);
3698
3699 break;
3700 }
3701 case MSR:
3702 case MSGR: { // they do not set overflow code
3703 RREInstruction* rreInst = reinterpret_cast<RREInstruction*>(instr);
3704 int r1 = rreInst->R1Value();
3705 int r2 = rreInst->R2Value();
3706 if (op == MSR) {
3707 int32_t r1_val = get_low_register<int32_t>(r1);
3708 int32_t r2_val = get_low_register<int32_t>(r2);
3709 set_low_register(r1, r1_val * r2_val);
3710 } else if (op == MSGR) {
3711 int64_t r1_val = get_register(r1);
3712 int64_t r2_val = get_register(r2);
3713 set_register(r1, r1_val * r2_val);
3714 } else {
3715 UNREACHABLE();
3716 }
3717 break;
3718 }
3719 case MS: {
3720 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr);
3721 int r1 = rxinst->R1Value();
3722 int b2 = rxinst->B2Value();
3723 int x2 = rxinst->X2Value();
3724 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
3725 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
3726 intptr_t d2_val = rxinst->D2Value();
3727 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr);
3728 int32_t r1_val = get_low_register<int32_t>(r1);
3729 set_low_register(r1, r1_val * mem_val);
3730 break;
3731 }
3732 case LGBR:
3733 case LBR: {
3734 RREInstruction* rrinst = reinterpret_cast<RREInstruction*>(instr);
3735 int r1 = rrinst->R1Value();
3736 int r2 = rrinst->R2Value();
3737 if (op == LGBR) {
3738 int64_t r2_val = get_low_register<int64_t>(r2);
3739 r2_val <<= 56;
3740 r2_val >>= 56;
3741 set_register(r1, r2_val);
3742 } else if (op == LBR) {
3743 int32_t r2_val = get_low_register<int32_t>(r2);
3744 r2_val <<= 24;
3745 r2_val >>= 24;
3746 set_low_register(r1, r2_val);
3747 } else {
3748 UNREACHABLE();
3749 }
3750 break;
3751 }
3752 case LGHR:
3753 case LHR: {
3754 RREInstruction* rrinst = reinterpret_cast<RREInstruction*>(instr);
3755 int r1 = rrinst->R1Value();
3756 int r2 = rrinst->R2Value();
3757 if (op == LGHR) {
3758 int64_t r2_val = get_low_register<int64_t>(r2);
3759 r2_val <<= 48;
3760 r2_val >>= 48;
3761 set_register(r1, r2_val);
3762 } else if (op == LHR) {
3763 int32_t r2_val = get_low_register<int32_t>(r2);
3764 r2_val <<= 16;
3765 r2_val >>= 16;
3766 set_low_register(r1, r2_val);
3767 } else {
3768 UNREACHABLE();
3769 }
3770 break;
3771 }
3772 case ALCR: {
3773 RREInstruction* rrinst = reinterpret_cast<RREInstruction*>(instr);
3774 int r1 = rrinst->R1Value();
3775 int r2 = rrinst->R2Value();
3776 uint32_t r1_val = get_low_register<uint32_t>(r1);
3777 uint32_t r2_val = get_low_register<uint32_t>(r2);
3778 uint32_t alu_out = 0;
3779 bool isOF = false;
3780
3781 alu_out = r1_val + r2_val;
3782 bool isOF_original = CheckOverflowForUIntAdd(r1_val, r2_val);
3783 if (TestConditionCode((Condition)2) || TestConditionCode((Condition)3)) {
3784 alu_out = alu_out + 1;
3785 isOF = isOF_original || CheckOverflowForUIntAdd(alu_out, 1);
3786 } else {
3787 isOF = isOF_original;
3788 }
3789 set_low_register(r1, alu_out);
3790 SetS390ConditionCodeCarry<uint32_t>(alu_out, isOF);
3791 break;
3792 }
3793 case SLBR: {
3794 RREInstruction* rrinst = reinterpret_cast<RREInstruction*>(instr);
3795 int r1 = rrinst->R1Value();
3796 int r2 = rrinst->R2Value();
3797 uint32_t r1_val = get_low_register<uint32_t>(r1);
3798 uint32_t r2_val = get_low_register<uint32_t>(r2);
3799 uint32_t alu_out = 0;
3800 bool isOF = false;
3801
3802 alu_out = r1_val - r2_val;
3803 bool isOF_original = CheckOverflowForUIntSub(r1_val, r2_val);
3804 if (TestConditionCode((Condition)2) || TestConditionCode((Condition)3)) {
3805 alu_out = alu_out - 1;
3806 isOF = isOF_original || CheckOverflowForUIntSub(alu_out, 1);
3807 } else {
3808 isOF = isOF_original;
3809 }
3810 set_low_register(r1, alu_out);
3811 SetS390ConditionCodeCarry<uint32_t>(alu_out, isOF);
3812 break;
3813 }
3814 default: { return DecodeFourByteFloatingPoint(instr); }
3815 }
3816 return true;
3817 }
3818
DecodeFourByteFloatingPointIntConversion(Instruction * instr)3819 void Simulator::DecodeFourByteFloatingPointIntConversion(Instruction* instr) {
3820 Opcode op = instr->S390OpcodeValue();
3821 switch (op) {
3822 case CDLFBR:
3823 case CDLGBR:
3824 case CELGBR:
3825 case CLFDBR:
3826 case CLGDBR:
3827 case CELFBR:
3828 case CLGEBR:
3829 case CLFEBR: {
3830 RREInstruction* rreInstr = reinterpret_cast<RREInstruction*>(instr);
3831 int r1 = rreInstr->R1Value();
3832 int r2 = rreInstr->R2Value();
3833 if (op == CDLFBR) {
3834 uint32_t r2_val = get_low_register<uint32_t>(r2);
3835 double r1_val = static_cast<double>(r2_val);
3836 set_d_register_from_double(r1, r1_val);
3837 } else if (op == CELFBR) {
3838 uint32_t r2_val = get_low_register<uint32_t>(r2);
3839 float r1_val = static_cast<float>(r2_val);
3840 set_d_register_from_float32(r1, r1_val);
3841 } else if (op == CDLGBR) {
3842 uint64_t r2_val = get_register(r2);
3843 double r1_val = static_cast<double>(r2_val);
3844 set_d_register_from_double(r1, r1_val);
3845 } else if (op == CELGBR) {
3846 uint64_t r2_val = get_register(r2);
3847 float r1_val = static_cast<float>(r2_val);
3848 set_d_register_from_float32(r1, r1_val);
3849 } else if (op == CLFDBR) {
3850 double r2_val = get_double_from_d_register(r2);
3851 uint32_t r1_val = static_cast<uint32_t>(r2_val);
3852 set_low_register(r1, r1_val);
3853 SetS390ConvertConditionCode<double>(r2_val, r1_val, UINT32_MAX);
3854 } else if (op == CLFEBR) {
3855 float r2_val = get_float32_from_d_register(r2);
3856 uint32_t r1_val = static_cast<uint32_t>(r2_val);
3857 set_low_register(r1, r1_val);
3858 SetS390ConvertConditionCode<double>(r2_val, r1_val, UINT32_MAX);
3859 } else if (op == CLGDBR) {
3860 double r2_val = get_double_from_d_register(r2);
3861 uint64_t r1_val = static_cast<uint64_t>(r2_val);
3862 set_register(r1, r1_val);
3863 SetS390ConvertConditionCode<double>(r2_val, r1_val, UINT64_MAX);
3864 } else if (op == CLGEBR) {
3865 float r2_val = get_float32_from_d_register(r2);
3866 uint64_t r1_val = static_cast<uint64_t>(r2_val);
3867 set_register(r1, r1_val);
3868 SetS390ConvertConditionCode<double>(r2_val, r1_val, UINT64_MAX);
3869 }
3870 break;
3871 }
3872 default:
3873 UNREACHABLE();
3874 }
3875 }
3876
DecodeFourByteFloatingPointRound(Instruction * instr)3877 void Simulator::DecodeFourByteFloatingPointRound(Instruction* instr) {
3878 Opcode op = instr->S390OpcodeValue();
3879 RREInstruction* rreInstr = reinterpret_cast<RREInstruction*>(instr);
3880 int r1 = rreInstr->R1Value();
3881 int r2 = rreInstr->R2Value();
3882 double r2_val = get_double_from_d_register(r2);
3883 float r2_fval = get_float32_from_d_register(r2);
3884
3885 switch (op) {
3886 case CFDBR: {
3887 int mask_val = rreInstr->M3Value();
3888 int32_t r1_val = 0;
3889
3890 SetS390RoundConditionCode(r2_val, INT32_MAX, INT32_MIN);
3891
3892 switch (mask_val) {
3893 case CURRENT_ROUNDING_MODE:
3894 case ROUND_TO_PREPARE_FOR_SHORTER_PRECISION: {
3895 r1_val = static_cast<int32_t>(r2_val);
3896 break;
3897 }
3898 case ROUND_TO_NEAREST_WITH_TIES_AWAY_FROM_0: {
3899 double ceil_val = std::ceil(r2_val);
3900 double floor_val = std::floor(r2_val);
3901 double sub_val1 = std::fabs(r2_val - floor_val);
3902 double sub_val2 = std::fabs(r2_val - ceil_val);
3903 if (sub_val1 > sub_val2) {
3904 r1_val = static_cast<int32_t>(ceil_val);
3905 } else if (sub_val1 < sub_val2) {
3906 r1_val = static_cast<int32_t>(floor_val);
3907 } else { // round away from zero:
3908 if (r2_val > 0.0) {
3909 r1_val = static_cast<int32_t>(ceil_val);
3910 } else {
3911 r1_val = static_cast<int32_t>(floor_val);
3912 }
3913 }
3914 break;
3915 }
3916 case ROUND_TO_NEAREST_WITH_TIES_TO_EVEN: {
3917 double ceil_val = std::ceil(r2_val);
3918 double floor_val = std::floor(r2_val);
3919 double sub_val1 = std::fabs(r2_val - floor_val);
3920 double sub_val2 = std::fabs(r2_val - ceil_val);
3921 if (sub_val1 > sub_val2) {
3922 r1_val = static_cast<int32_t>(ceil_val);
3923 } else if (sub_val1 < sub_val2) {
3924 r1_val = static_cast<int32_t>(floor_val);
3925 } else { // check which one is even:
3926 int32_t c_v = static_cast<int32_t>(ceil_val);
3927 int32_t f_v = static_cast<int32_t>(floor_val);
3928 if (f_v % 2 == 0)
3929 r1_val = f_v;
3930 else
3931 r1_val = c_v;
3932 }
3933 break;
3934 }
3935 case ROUND_TOWARD_0: {
3936 // check for overflow, cast r2_val to 64bit integer
3937 // then check value within the range of INT_MIN and INT_MAX
3938 // and set condition code accordingly
3939 int64_t temp = static_cast<int64_t>(r2_val);
3940 if (temp < INT_MIN || temp > INT_MAX) {
3941 condition_reg_ = CC_OF;
3942 }
3943 r1_val = static_cast<int32_t>(r2_val);
3944 break;
3945 }
3946 case ROUND_TOWARD_PLUS_INFINITE: {
3947 r1_val = static_cast<int32_t>(std::ceil(r2_val));
3948 break;
3949 }
3950 case ROUND_TOWARD_MINUS_INFINITE: {
3951 // check for overflow, cast r2_val to 64bit integer
3952 // then check value within the range of INT_MIN and INT_MAX
3953 // and set condition code accordingly
3954 int64_t temp = static_cast<int64_t>(std::floor(r2_val));
3955 if (temp < INT_MIN || temp > INT_MAX) {
3956 condition_reg_ = CC_OF;
3957 }
3958 r1_val = static_cast<int32_t>(std::floor(r2_val));
3959 break;
3960 }
3961 default:
3962 UNREACHABLE();
3963 }
3964 set_low_register(r1, r1_val);
3965 break;
3966 }
3967 case CGDBR: {
3968 int mask_val = rreInstr->M3Value();
3969 int64_t r1_val = 0;
3970
3971 SetS390RoundConditionCode(r2_val, INT64_MAX, INT64_MIN);
3972
3973 switch (mask_val) {
3974 case CURRENT_ROUNDING_MODE:
3975 case ROUND_TO_NEAREST_WITH_TIES_AWAY_FROM_0:
3976 case ROUND_TO_PREPARE_FOR_SHORTER_PRECISION: {
3977 UNIMPLEMENTED();
3978 break;
3979 }
3980 case ROUND_TO_NEAREST_WITH_TIES_TO_EVEN: {
3981 double ceil_val = std::ceil(r2_val);
3982 double floor_val = std::floor(r2_val);
3983 if (std::abs(r2_val - floor_val) > std::abs(r2_val - ceil_val)) {
3984 r1_val = static_cast<int64_t>(ceil_val);
3985 } else if (std::abs(r2_val - floor_val) <
3986 std::abs(r2_val - ceil_val)) {
3987 r1_val = static_cast<int64_t>(floor_val);
3988 } else { // check which one is even:
3989 int64_t c_v = static_cast<int64_t>(ceil_val);
3990 int64_t f_v = static_cast<int64_t>(floor_val);
3991 if (f_v % 2 == 0)
3992 r1_val = f_v;
3993 else
3994 r1_val = c_v;
3995 }
3996 break;
3997 }
3998 case ROUND_TOWARD_0: {
3999 r1_val = static_cast<int64_t>(r2_val);
4000 break;
4001 }
4002 case ROUND_TOWARD_PLUS_INFINITE: {
4003 r1_val = static_cast<int64_t>(std::ceil(r2_val));
4004 break;
4005 }
4006 case ROUND_TOWARD_MINUS_INFINITE: {
4007 r1_val = static_cast<int64_t>(std::floor(r2_val));
4008 break;
4009 }
4010 default:
4011 UNREACHABLE();
4012 }
4013 set_register(r1, r1_val);
4014 break;
4015 }
4016 case CGEBR: {
4017 int mask_val = rreInstr->M3Value();
4018 int64_t r1_val = 0;
4019
4020 SetS390RoundConditionCode(r2_fval, INT64_MAX, INT64_MIN);
4021
4022 switch (mask_val) {
4023 case CURRENT_ROUNDING_MODE:
4024 case ROUND_TO_NEAREST_WITH_TIES_AWAY_FROM_0:
4025 case ROUND_TO_PREPARE_FOR_SHORTER_PRECISION: {
4026 UNIMPLEMENTED();
4027 break;
4028 }
4029 case ROUND_TO_NEAREST_WITH_TIES_TO_EVEN: {
4030 float ceil_val = std::ceil(r2_fval);
4031 float floor_val = std::floor(r2_fval);
4032 if (std::abs(r2_fval - floor_val) > std::abs(r2_fval - ceil_val)) {
4033 r1_val = static_cast<int64_t>(ceil_val);
4034 } else if (std::abs(r2_fval - floor_val) <
4035 std::abs(r2_fval - ceil_val)) {
4036 r1_val = static_cast<int64_t>(floor_val);
4037 } else { // check which one is even:
4038 int64_t c_v = static_cast<int64_t>(ceil_val);
4039 int64_t f_v = static_cast<int64_t>(floor_val);
4040 if (f_v % 2 == 0)
4041 r1_val = f_v;
4042 else
4043 r1_val = c_v;
4044 }
4045 break;
4046 }
4047 case ROUND_TOWARD_0: {
4048 r1_val = static_cast<int64_t>(r2_fval);
4049 break;
4050 }
4051 case ROUND_TOWARD_PLUS_INFINITE: {
4052 r1_val = static_cast<int64_t>(std::ceil(r2_fval));
4053 break;
4054 }
4055 case ROUND_TOWARD_MINUS_INFINITE: {
4056 r1_val = static_cast<int64_t>(std::floor(r2_fval));
4057 break;
4058 }
4059 default:
4060 UNREACHABLE();
4061 }
4062 set_register(r1, r1_val);
4063 break;
4064 }
4065 case CFEBR: {
4066 int mask_val = rreInstr->M3Value();
4067 int32_t r1_val = 0;
4068
4069 SetS390RoundConditionCode(r2_fval, INT32_MAX, INT32_MIN);
4070
4071 switch (mask_val) {
4072 case CURRENT_ROUNDING_MODE:
4073 case ROUND_TO_PREPARE_FOR_SHORTER_PRECISION: {
4074 r1_val = static_cast<int32_t>(r2_fval);
4075 break;
4076 }
4077 case ROUND_TO_NEAREST_WITH_TIES_AWAY_FROM_0: {
4078 float ceil_val = std::ceil(r2_fval);
4079 float floor_val = std::floor(r2_fval);
4080 float sub_val1 = std::fabs(r2_fval - floor_val);
4081 float sub_val2 = std::fabs(r2_fval - ceil_val);
4082 if (sub_val1 > sub_val2) {
4083 r1_val = static_cast<int32_t>(ceil_val);
4084 } else if (sub_val1 < sub_val2) {
4085 r1_val = static_cast<int32_t>(floor_val);
4086 } else { // round away from zero:
4087 if (r2_fval > 0.0) {
4088 r1_val = static_cast<int32_t>(ceil_val);
4089 } else {
4090 r1_val = static_cast<int32_t>(floor_val);
4091 }
4092 }
4093 break;
4094 }
4095 case ROUND_TO_NEAREST_WITH_TIES_TO_EVEN: {
4096 float ceil_val = std::ceil(r2_fval);
4097 float floor_val = std::floor(r2_fval);
4098 float sub_val1 = std::fabs(r2_fval - floor_val);
4099 float sub_val2 = std::fabs(r2_fval - ceil_val);
4100 if (sub_val1 > sub_val2) {
4101 r1_val = static_cast<int32_t>(ceil_val);
4102 } else if (sub_val1 < sub_val2) {
4103 r1_val = static_cast<int32_t>(floor_val);
4104 } else { // check which one is even:
4105 int32_t c_v = static_cast<int32_t>(ceil_val);
4106 int32_t f_v = static_cast<int32_t>(floor_val);
4107 if (f_v % 2 == 0)
4108 r1_val = f_v;
4109 else
4110 r1_val = c_v;
4111 }
4112 break;
4113 }
4114 case ROUND_TOWARD_0: {
4115 // check for overflow, cast r2_fval to 64bit integer
4116 // then check value within the range of INT_MIN and INT_MAX
4117 // and set condition code accordingly
4118 int64_t temp = static_cast<int64_t>(r2_fval);
4119 if (temp < INT_MIN || temp > INT_MAX) {
4120 condition_reg_ = CC_OF;
4121 }
4122 r1_val = static_cast<int32_t>(r2_fval);
4123 break;
4124 }
4125 case ROUND_TOWARD_PLUS_INFINITE: {
4126 r1_val = static_cast<int32_t>(std::ceil(r2_fval));
4127 break;
4128 }
4129 case ROUND_TOWARD_MINUS_INFINITE: {
4130 // check for overflow, cast r2_fval to 64bit integer
4131 // then check value within the range of INT_MIN and INT_MAX
4132 // and set condition code accordingly
4133 int64_t temp = static_cast<int64_t>(std::floor(r2_fval));
4134 if (temp < INT_MIN || temp > INT_MAX) {
4135 condition_reg_ = CC_OF;
4136 }
4137 r1_val = static_cast<int32_t>(std::floor(r2_fval));
4138 break;
4139 }
4140 default:
4141 UNREACHABLE();
4142 }
4143 set_low_register(r1, r1_val);
4144
4145 break;
4146 }
4147 default:
4148 UNREACHABLE();
4149 }
4150 }
4151
4152 /**
4153 * Decodes and simulates four byte floating point instructions
4154 */
DecodeFourByteFloatingPoint(Instruction * instr)4155 bool Simulator::DecodeFourByteFloatingPoint(Instruction* instr) {
4156 Opcode op = instr->S390OpcodeValue();
4157
4158 switch (op) {
4159 case ADBR:
4160 case AEBR:
4161 case SDBR:
4162 case SEBR:
4163 case MDBR:
4164 case MEEBR:
4165 case MADBR:
4166 case DDBR:
4167 case DEBR:
4168 case CDBR:
4169 case CEBR:
4170 case CDFBR:
4171 case CDGBR:
4172 case CEGBR:
4173 case CGEBR:
4174 case CFDBR:
4175 case CGDBR:
4176 case SQDBR:
4177 case SQEBR:
4178 case CFEBR:
4179 case CEFBR:
4180 case LCDBR:
4181 case LCEBR:
4182 case LPDBR:
4183 case LPEBR: {
4184 RREInstruction* rreInstr = reinterpret_cast<RREInstruction*>(instr);
4185 int r1 = rreInstr->R1Value();
4186 int r2 = rreInstr->R2Value();
4187 double r1_val = get_double_from_d_register(r1);
4188 double r2_val = get_double_from_d_register(r2);
4189 float fr1_val = get_float32_from_d_register(r1);
4190 float fr2_val = get_float32_from_d_register(r2);
4191 if (op == ADBR) {
4192 r1_val += r2_val;
4193 set_d_register_from_double(r1, r1_val);
4194 SetS390ConditionCode<double>(r1_val, 0);
4195 } else if (op == AEBR) {
4196 fr1_val += fr2_val;
4197 set_d_register_from_float32(r1, fr1_val);
4198 SetS390ConditionCode<float>(fr1_val, 0);
4199 } else if (op == SDBR) {
4200 r1_val -= r2_val;
4201 set_d_register_from_double(r1, r1_val);
4202 SetS390ConditionCode<double>(r1_val, 0);
4203 } else if (op == SEBR) {
4204 fr1_val -= fr2_val;
4205 set_d_register_from_float32(r1, fr1_val);
4206 SetS390ConditionCode<float>(fr1_val, 0);
4207 } else if (op == MDBR) {
4208 r1_val *= r2_val;
4209 set_d_register_from_double(r1, r1_val);
4210 SetS390ConditionCode<double>(r1_val, 0);
4211 } else if (op == MEEBR) {
4212 fr1_val *= fr2_val;
4213 set_d_register_from_float32(r1, fr1_val);
4214 SetS390ConditionCode<float>(fr1_val, 0);
4215 } else if (op == MADBR) {
4216 RRDInstruction* rrdInstr = reinterpret_cast<RRDInstruction*>(instr);
4217 int r1 = rrdInstr->R1Value();
4218 int r2 = rrdInstr->R2Value();
4219 int r3 = rrdInstr->R3Value();
4220 double r1_val = get_double_from_d_register(r1);
4221 double r2_val = get_double_from_d_register(r2);
4222 double r3_val = get_double_from_d_register(r3);
4223 r1_val += r2_val * r3_val;
4224 set_d_register_from_double(r1, r1_val);
4225 SetS390ConditionCode<double>(r1_val, 0);
4226 } else if (op == DDBR) {
4227 r1_val /= r2_val;
4228 set_d_register_from_double(r1, r1_val);
4229 SetS390ConditionCode<double>(r1_val, 0);
4230 } else if (op == DEBR) {
4231 fr1_val /= fr2_val;
4232 set_d_register_from_float32(r1, fr1_val);
4233 SetS390ConditionCode<float>(fr1_val, 0);
4234 } else if (op == CDBR) {
4235 if (isNaN(r1_val) || isNaN(r2_val)) {
4236 condition_reg_ = CC_OF;
4237 } else {
4238 SetS390ConditionCode<double>(r1_val, r2_val);
4239 }
4240 } else if (op == CEBR) {
4241 if (isNaN(fr1_val) || isNaN(fr2_val)) {
4242 condition_reg_ = CC_OF;
4243 } else {
4244 SetS390ConditionCode<float>(fr1_val, fr2_val);
4245 }
4246 } else if (op == CDGBR) {
4247 int64_t r2_val = get_register(r2);
4248 double r1_val = static_cast<double>(r2_val);
4249 set_d_register_from_double(r1, r1_val);
4250 } else if (op == CEGBR) {
4251 int64_t fr2_val = get_register(r2);
4252 float fr1_val = static_cast<float>(fr2_val);
4253 set_d_register_from_float32(r1, fr1_val);
4254 } else if (op == CDFBR) {
4255 int32_t r2_val = get_low_register<int32_t>(r2);
4256 double r1_val = static_cast<double>(r2_val);
4257 set_d_register_from_double(r1, r1_val);
4258 } else if (op == CEFBR) {
4259 int32_t fr2_val = get_low_register<int32_t>(r2);
4260 float fr1_val = static_cast<float>(fr2_val);
4261 set_d_register_from_float32(r1, fr1_val);
4262 } else if (op == CFDBR) {
4263 DecodeFourByteFloatingPointRound(instr);
4264 } else if (op == CGDBR) {
4265 DecodeFourByteFloatingPointRound(instr);
4266 } else if (op == CGEBR) {
4267 DecodeFourByteFloatingPointRound(instr);
4268 } else if (op == SQDBR) {
4269 r1_val = std::sqrt(r2_val);
4270 set_d_register_from_double(r1, r1_val);
4271 } else if (op == SQEBR) {
4272 fr1_val = std::sqrt(fr2_val);
4273 set_d_register_from_float32(r1, fr1_val);
4274 } else if (op == CFEBR) {
4275 DecodeFourByteFloatingPointRound(instr);
4276 } else if (op == LCDBR) {
4277 r1_val = -r2_val;
4278 set_d_register_from_double(r1, r1_val);
4279 if (r2_val != r2_val) { // input is NaN
4280 condition_reg_ = CC_OF;
4281 } else if (r2_val == 0) {
4282 condition_reg_ = CC_EQ;
4283 } else if (r2_val < 0) {
4284 condition_reg_ = CC_LT;
4285 } else if (r2_val > 0) {
4286 condition_reg_ = CC_GT;
4287 }
4288 } else if (op == LCEBR) {
4289 fr1_val = -fr2_val;
4290 set_d_register_from_float32(r1, fr1_val);
4291 if (fr2_val != fr2_val) { // input is NaN
4292 condition_reg_ = CC_OF;
4293 } else if (fr2_val == 0) {
4294 condition_reg_ = CC_EQ;
4295 } else if (fr2_val < 0) {
4296 condition_reg_ = CC_LT;
4297 } else if (fr2_val > 0) {
4298 condition_reg_ = CC_GT;
4299 }
4300 } else if (op == LPDBR) {
4301 r1_val = std::fabs(r2_val);
4302 set_d_register_from_double(r1, r1_val);
4303 if (r2_val != r2_val) { // input is NaN
4304 condition_reg_ = CC_OF;
4305 } else if (r2_val == 0) {
4306 condition_reg_ = CC_EQ;
4307 } else {
4308 condition_reg_ = CC_GT;
4309 }
4310 } else if (op == LPEBR) {
4311 fr1_val = std::fabs(fr2_val);
4312 set_d_register_from_float32(r1, fr1_val);
4313 if (fr2_val != fr2_val) { // input is NaN
4314 condition_reg_ = CC_OF;
4315 } else if (fr2_val == 0) {
4316 condition_reg_ = CC_EQ;
4317 } else {
4318 condition_reg_ = CC_GT;
4319 }
4320 } else {
4321 UNREACHABLE();
4322 }
4323 break;
4324 }
4325 case CDLFBR:
4326 case CDLGBR:
4327 case CELGBR:
4328 case CLFDBR:
4329 case CELFBR:
4330 case CLGDBR:
4331 case CLGEBR:
4332 case CLFEBR: {
4333 DecodeFourByteFloatingPointIntConversion(instr);
4334 break;
4335 }
4336 case TMLL: {
4337 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr);
4338 int r1 = riinst->R1Value();
4339 int mask = riinst->I2Value() & 0x0000FFFF;
4340 if (mask == 0) {
4341 condition_reg_ = 0x0;
4342 break;
4343 }
4344 uint32_t r1_val = get_low_register<uint32_t>(r1);
4345 r1_val = r1_val & 0x0000FFFF; // uses only the last 16bits
4346
4347 // Test if all selected bits are Zero
4348 bool allSelectedBitsAreZeros = true;
4349 for (int i = 0; i < 15; i++) {
4350 if (mask & (1 << i)) {
4351 if (r1_val & (1 << i)) {
4352 allSelectedBitsAreZeros = false;
4353 break;
4354 }
4355 }
4356 }
4357 if (allSelectedBitsAreZeros) {
4358 condition_reg_ = 0x8;
4359 break; // Done!
4360 }
4361
4362 // Test if all selected bits are one
4363 bool allSelectedBitsAreOnes = true;
4364 for (int i = 0; i < 15; i++) {
4365 if (mask & (1 << i)) {
4366 if (!(r1_val & (1 << i))) {
4367 allSelectedBitsAreOnes = false;
4368 break;
4369 }
4370 }
4371 }
4372 if (allSelectedBitsAreOnes) {
4373 condition_reg_ = 0x1;
4374 break; // Done!
4375 }
4376
4377 // Now we know selected bits mixed zeros and ones
4378 // Test if the leftmost bit is zero or one
4379 for (int i = 14; i >= 0; i--) {
4380 if (mask & (1 << i)) {
4381 if (r1_val & (1 << i)) {
4382 // leftmost bit is one
4383 condition_reg_ = 0x2;
4384 } else {
4385 // leftmost bit is zero
4386 condition_reg_ = 0x4;
4387 }
4388 break; // Done!
4389 }
4390 }
4391 break;
4392 }
4393 case LEDBR: {
4394 RREInstruction* rreInst = reinterpret_cast<RREInstruction*>(instr);
4395 int r1 = rreInst->R1Value();
4396 int r2 = rreInst->R2Value();
4397 double r2_val = get_double_from_d_register(r2);
4398 set_d_register_from_float32(r1, static_cast<float>(r2_val));
4399 break;
4400 }
4401 case FIDBRA: {
4402 RRFInstruction* rrfInst = reinterpret_cast<RRFInstruction*>(instr);
4403 int r1 = rrfInst->R1Value();
4404 int r2 = rrfInst->R2Value();
4405 int m3 = rrfInst->M3Value();
4406 double r2_val = get_double_from_d_register(r2);
4407 DCHECK(rrfInst->M4Value() == 0);
4408 switch (m3) {
4409 case Assembler::FIDBRA_ROUND_TO_NEAREST_AWAY_FROM_0:
4410 set_d_register_from_double(r1, round(r2_val));
4411 break;
4412 case Assembler::FIDBRA_ROUND_TOWARD_0:
4413 set_d_register_from_double(r1, trunc(r2_val));
4414 break;
4415 case Assembler::FIDBRA_ROUND_TOWARD_POS_INF:
4416 set_d_register_from_double(r1, std::ceil(r2_val));
4417 break;
4418 case Assembler::FIDBRA_ROUND_TOWARD_NEG_INF:
4419 set_d_register_from_double(r1, std::floor(r2_val));
4420 break;
4421 default:
4422 UNIMPLEMENTED();
4423 break;
4424 }
4425 break;
4426 }
4427 case FIEBRA: {
4428 RRFInstruction* rrfInst = reinterpret_cast<RRFInstruction*>(instr);
4429 int r1 = rrfInst->R1Value();
4430 int r2 = rrfInst->R2Value();
4431 int m3 = rrfInst->M3Value();
4432 float r2_val = get_float32_from_d_register(r2);
4433 DCHECK(rrfInst->M4Value() == 0);
4434 switch (m3) {
4435 case Assembler::FIDBRA_ROUND_TO_NEAREST_AWAY_FROM_0:
4436 set_d_register_from_float32(r1, round(r2_val));
4437 break;
4438 case Assembler::FIDBRA_ROUND_TOWARD_0:
4439 set_d_register_from_float32(r1, trunc(r2_val));
4440 break;
4441 case Assembler::FIDBRA_ROUND_TOWARD_POS_INF:
4442 set_d_register_from_float32(r1, std::ceil(r2_val));
4443 break;
4444 case Assembler::FIDBRA_ROUND_TOWARD_NEG_INF:
4445 set_d_register_from_float32(r1, std::floor(r2_val));
4446 break;
4447 default:
4448 UNIMPLEMENTED();
4449 break;
4450 }
4451 break;
4452 }
4453 case MSDBR: {
4454 UNIMPLEMENTED();
4455 break;
4456 }
4457 case LDEBR: {
4458 RREInstruction* rreInstr = reinterpret_cast<RREInstruction*>(instr);
4459 int r1 = rreInstr->R1Value();
4460 int r2 = rreInstr->R2Value();
4461 float fp_val = get_float32_from_d_register(r2);
4462 double db_val = static_cast<double>(fp_val);
4463 set_d_register_from_double(r1, db_val);
4464 break;
4465 }
4466 default: {
4467 UNREACHABLE();
4468 return false;
4469 }
4470 }
4471 return true;
4472 }
4473
4474 // Decode routine for six-byte instructions
DecodeSixByte(Instruction * instr)4475 bool Simulator::DecodeSixByte(Instruction* instr) {
4476 Opcode op = instr->S390OpcodeValue();
4477
4478 // Pre-cast instruction to various types
4479 RIEInstruction* rieInstr = reinterpret_cast<RIEInstruction*>(instr);
4480 RILInstruction* rilInstr = reinterpret_cast<RILInstruction*>(instr);
4481 RSYInstruction* rsyInstr = reinterpret_cast<RSYInstruction*>(instr);
4482 RXEInstruction* rxeInstr = reinterpret_cast<RXEInstruction*>(instr);
4483 RXYInstruction* rxyInstr = reinterpret_cast<RXYInstruction*>(instr);
4484 SIYInstruction* siyInstr = reinterpret_cast<SIYInstruction*>(instr);
4485 SILInstruction* silInstr = reinterpret_cast<SILInstruction*>(instr);
4486 SSInstruction* ssInstr = reinterpret_cast<SSInstruction*>(instr);
4487
4488 switch (op) {
4489 case CLIY: {
4490 // Compare Immediate (Mem - Imm) (8)
4491 int b1 = siyInstr->B1Value();
4492 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
4493 intptr_t d1_val = siyInstr->D1Value();
4494 intptr_t addr = b1_val + d1_val;
4495 uint8_t mem_val = ReadB(addr);
4496 uint8_t imm_val = siyInstr->I2Value();
4497 SetS390ConditionCode<uint8_t>(mem_val, imm_val);
4498 break;
4499 }
4500 case TMY: {
4501 // Test Under Mask (Mem - Imm) (8)
4502 int b1 = siyInstr->B1Value();
4503 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
4504 intptr_t d1_val = siyInstr->D1Value();
4505 intptr_t addr = b1_val + d1_val;
4506 uint8_t mem_val = ReadB(addr);
4507 uint8_t imm_val = siyInstr->I2Value();
4508 uint8_t selected_bits = mem_val & imm_val;
4509 // CC0: Selected bits are zero
4510 // CC1: Selected bits mixed zeros and ones
4511 // CC3: Selected bits all ones
4512 if (0 == selected_bits) {
4513 condition_reg_ = CC_EQ; // CC0
4514 } else if (selected_bits == imm_val) {
4515 condition_reg_ = 0x1; // CC3
4516 } else {
4517 condition_reg_ = 0x4; // CC1
4518 }
4519 break;
4520 }
4521 case LDEB: {
4522 // Load Float
4523 int r1 = rxeInstr->R1Value();
4524 int rb = rxeInstr->B2Value();
4525 int rx = rxeInstr->X2Value();
4526 int offset = rxeInstr->D2Value();
4527 int64_t rb_val = (rb == 0) ? 0 : get_register(rb);
4528 int64_t rx_val = (rx == 0) ? 0 : get_register(rx);
4529 double ret = static_cast<double>(
4530 *reinterpret_cast<float*>(rx_val + rb_val + offset));
4531 set_d_register_from_double(r1, ret);
4532 break;
4533 }
4534 case LAY: {
4535 // Load Address
4536 int r1 = rxyInstr->R1Value();
4537 int rb = rxyInstr->B2Value();
4538 int rx = rxyInstr->X2Value();
4539 int offset = rxyInstr->D2Value();
4540 int64_t rb_val = (rb == 0) ? 0 : get_register(rb);
4541 int64_t rx_val = (rx == 0) ? 0 : get_register(rx);
4542 set_register(r1, rx_val + rb_val + offset);
4543 break;
4544 }
4545 case LARL: {
4546 // Load Addresss Relative Long
4547 int r1 = rilInstr->R1Value();
4548 intptr_t offset = rilInstr->I2Value() * 2;
4549 set_register(r1, get_pc() + offset);
4550 break;
4551 }
4552 case LLILF: {
4553 // Load Logical into lower 32-bits (zero extend upper 32-bits)
4554 int r1 = rilInstr->R1Value();
4555 uint64_t imm = static_cast<uint64_t>(rilInstr->I2UnsignedValue());
4556 set_register(r1, imm);
4557 break;
4558 }
4559 case LLIHF: {
4560 // Load Logical Immediate into high word
4561 int r1 = rilInstr->R1Value();
4562 uint64_t imm = static_cast<uint64_t>(rilInstr->I2UnsignedValue());
4563 set_register(r1, imm << 32);
4564 break;
4565 }
4566 case OILF:
4567 case NILF:
4568 case IILF: {
4569 // Bitwise Op on lower 32-bits
4570 int r1 = rilInstr->R1Value();
4571 uint32_t imm = rilInstr->I2UnsignedValue();
4572 uint32_t alu_out = get_low_register<uint32_t>(r1);
4573 if (NILF == op) {
4574 alu_out &= imm;
4575 SetS390BitWiseConditionCode<uint32_t>(alu_out);
4576 } else if (OILF == op) {
4577 alu_out |= imm;
4578 SetS390BitWiseConditionCode<uint32_t>(alu_out);
4579 } else if (op == IILF) {
4580 alu_out = imm;
4581 } else {
4582 DCHECK(false);
4583 }
4584 set_low_register(r1, alu_out);
4585 break;
4586 }
4587 case OIHF:
4588 case NIHF:
4589 case IIHF: {
4590 // Bitwise Op on upper 32-bits
4591 int r1 = rilInstr->R1Value();
4592 uint32_t imm = rilInstr->I2Value();
4593 uint32_t alu_out = get_high_register<uint32_t>(r1);
4594 if (op == NIHF) {
4595 alu_out &= imm;
4596 SetS390BitWiseConditionCode<uint32_t>(alu_out);
4597 } else if (op == OIHF) {
4598 alu_out |= imm;
4599 SetS390BitWiseConditionCode<uint32_t>(alu_out);
4600 } else if (op == IIHF) {
4601 alu_out = imm;
4602 } else {
4603 DCHECK(false);
4604 }
4605 set_high_register(r1, alu_out);
4606 break;
4607 }
4608 case CLFI: {
4609 // Compare Logical with Immediate (32)
4610 int r1 = rilInstr->R1Value();
4611 uint32_t imm = rilInstr->I2UnsignedValue();
4612 SetS390ConditionCode<uint32_t>(get_low_register<uint32_t>(r1), imm);
4613 break;
4614 }
4615 case CFI: {
4616 // Compare with Immediate (32)
4617 int r1 = rilInstr->R1Value();
4618 int32_t imm = rilInstr->I2Value();
4619 SetS390ConditionCode<int32_t>(get_low_register<int32_t>(r1), imm);
4620 break;
4621 }
4622 case CLGFI: {
4623 // Compare Logical with Immediate (64)
4624 int r1 = rilInstr->R1Value();
4625 uint64_t imm = static_cast<uint64_t>(rilInstr->I2UnsignedValue());
4626 SetS390ConditionCode<uint64_t>(get_register(r1), imm);
4627 break;
4628 }
4629 case CGFI: {
4630 // Compare with Immediate (64)
4631 int r1 = rilInstr->R1Value();
4632 int64_t imm = static_cast<int64_t>(rilInstr->I2Value());
4633 SetS390ConditionCode<int64_t>(get_register(r1), imm);
4634 break;
4635 }
4636 case BRASL: {
4637 // Branch and Save Relative Long
4638 int r1 = rilInstr->R1Value();
4639 intptr_t d2 = rilInstr->I2Value();
4640 intptr_t pc = get_pc();
4641 set_register(r1, pc + 6); // save next instruction to register
4642 set_pc(pc + d2 * 2); // update register
4643 break;
4644 }
4645 case BRCL: {
4646 // Branch on Condition Relative Long
4647 Condition m1 = (Condition)rilInstr->R1Value();
4648 if (TestConditionCode((Condition)m1)) {
4649 intptr_t offset = rilInstr->I2Value() * 2;
4650 set_pc(get_pc() + offset);
4651 }
4652 break;
4653 }
4654 case LMG:
4655 case STMG: {
4656 // Store Multiple 64-bits.
4657 int r1 = rsyInstr->R1Value();
4658 int r3 = rsyInstr->R3Value();
4659 int rb = rsyInstr->B2Value();
4660 int offset = rsyInstr->D2Value();
4661
4662 // Regs roll around if r3 is less than r1.
4663 // Artifically increase r3 by 16 so we can calculate
4664 // the number of regs stored properly.
4665 if (r3 < r1) r3 += 16;
4666
4667 int64_t rb_val = (rb == 0) ? 0 : get_register(rb);
4668
4669 // Store each register in ascending order.
4670 for (int i = 0; i <= r3 - r1; i++) {
4671 if (op == LMG) {
4672 int64_t value = ReadDW(rb_val + offset + 8 * i);
4673 set_register((r1 + i) % 16, value);
4674 } else if (op == STMG) {
4675 int64_t value = get_register((r1 + i) % 16);
4676 WriteDW(rb_val + offset + 8 * i, value);
4677 } else {
4678 DCHECK(false);
4679 }
4680 }
4681 break;
4682 }
4683 case SLLK:
4684 case RLL:
4685 case SRLK:
4686 case SLLG:
4687 case RLLG:
4688 case SRLG: {
4689 DecodeSixByteBitShift(instr);
4690 break;
4691 }
4692 case SLAK:
4693 case SRAK: {
4694 // 32-bit non-clobbering shift-left/right arithmetic
4695 int r1 = rsyInstr->R1Value();
4696 int r3 = rsyInstr->R3Value();
4697 int b2 = rsyInstr->B2Value();
4698 intptr_t d2 = rsyInstr->D2Value();
4699 // only takes rightmost 6 bits
4700 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
4701 int shiftBits = (b2_val + d2) & 0x3F;
4702 int32_t r3_val = get_low_register<int32_t>(r3);
4703 int32_t alu_out = 0;
4704 bool isOF = false;
4705 if (op == SLAK) {
4706 isOF = CheckOverflowForShiftLeft(r3_val, shiftBits);
4707 alu_out = r3_val << shiftBits;
4708 } else if (op == SRAK) {
4709 alu_out = r3_val >> shiftBits;
4710 }
4711 set_low_register(r1, alu_out);
4712 SetS390ConditionCode<int32_t>(alu_out, 0);
4713 SetS390OverflowCode(isOF);
4714 break;
4715 }
4716 case SLAG:
4717 case SRAG: {
4718 // 64-bit non-clobbering shift-left/right arithmetic
4719 int r1 = rsyInstr->R1Value();
4720 int r3 = rsyInstr->R3Value();
4721 int b2 = rsyInstr->B2Value();
4722 intptr_t d2 = rsyInstr->D2Value();
4723 // only takes rightmost 6 bits
4724 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
4725 int shiftBits = (b2_val + d2) & 0x3F;
4726 int64_t r3_val = get_register(r3);
4727 intptr_t alu_out = 0;
4728 bool isOF = false;
4729 if (op == SLAG) {
4730 isOF = CheckOverflowForShiftLeft(r3_val, shiftBits);
4731 alu_out = r3_val << shiftBits;
4732 } else if (op == SRAG) {
4733 alu_out = r3_val >> shiftBits;
4734 }
4735 set_register(r1, alu_out);
4736 SetS390ConditionCode<intptr_t>(alu_out, 0);
4737 SetS390OverflowCode(isOF);
4738 break;
4739 }
4740 case LMY:
4741 case STMY: {
4742 RSYInstruction* rsyInstr = reinterpret_cast<RSYInstruction*>(instr);
4743 // Load/Store Multiple (32)
4744 int r1 = rsyInstr->R1Value();
4745 int r3 = rsyInstr->R3Value();
4746 int b2 = rsyInstr->B2Value();
4747 int offset = rsyInstr->D2Value();
4748
4749 // Regs roll around if r3 is less than r1.
4750 // Artifically increase r3 by 16 so we can calculate
4751 // the number of regs stored properly.
4752 if (r3 < r1) r3 += 16;
4753
4754 int32_t b2_val = (b2 == 0) ? 0 : get_low_register<int32_t>(b2);
4755
4756 // Store each register in ascending order.
4757 for (int i = 0; i <= r3 - r1; i++) {
4758 if (op == LMY) {
4759 int32_t value = ReadW(b2_val + offset + 4 * i, instr);
4760 set_low_register((r1 + i) % 16, value);
4761 } else {
4762 int32_t value = get_low_register<int32_t>((r1 + i) % 16);
4763 WriteW(b2_val + offset + 4 * i, value, instr);
4764 }
4765 }
4766 break;
4767 }
4768 case LT:
4769 case LTG: {
4770 // Load and Test (32/64)
4771 int r1 = rxyInstr->R1Value();
4772 int x2 = rxyInstr->X2Value();
4773 int b2 = rxyInstr->B2Value();
4774 int d2 = rxyInstr->D2Value();
4775
4776 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
4777 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
4778 intptr_t addr = x2_val + b2_val + d2;
4779
4780 if (op == LT) {
4781 int32_t value = ReadW(addr, instr);
4782 set_low_register(r1, value);
4783 SetS390ConditionCode<int32_t>(value, 0);
4784 } else if (op == LTG) {
4785 int64_t value = ReadDW(addr);
4786 set_register(r1, value);
4787 SetS390ConditionCode<int64_t>(value, 0);
4788 }
4789 break;
4790 }
4791 case LY:
4792 case LB:
4793 case LGB:
4794 case LG:
4795 case LGF:
4796 case LGH:
4797 case LLGF:
4798 case STG:
4799 case STY:
4800 case STCY:
4801 case STHY:
4802 case STEY:
4803 case LDY:
4804 case LHY:
4805 case STDY:
4806 case LEY: {
4807 // Miscellaneous Loads and Stores
4808 int r1 = rxyInstr->R1Value();
4809 int x2 = rxyInstr->X2Value();
4810 int b2 = rxyInstr->B2Value();
4811 int d2 = rxyInstr->D2Value();
4812 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
4813 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
4814 intptr_t addr = x2_val + b2_val + d2;
4815 if (op == LY) {
4816 uint32_t mem_val = ReadWU(addr, instr);
4817 set_low_register(r1, mem_val);
4818 } else if (op == LB) {
4819 int32_t mem_val = ReadB(addr);
4820 set_low_register(r1, mem_val);
4821 } else if (op == LGB) {
4822 int64_t mem_val = ReadB(addr);
4823 set_register(r1, mem_val);
4824 } else if (op == LG) {
4825 int64_t mem_val = ReadDW(addr);
4826 set_register(r1, mem_val);
4827 } else if (op == LGF) {
4828 int64_t mem_val = static_cast<int64_t>(ReadW(addr, instr));
4829 set_register(r1, mem_val);
4830 } else if (op == LGH) {
4831 int64_t mem_val = static_cast<int64_t>(ReadH(addr, instr));
4832 set_register(r1, mem_val);
4833 } else if (op == LLGF) {
4834 // int r1 = rreInst->R1Value();
4835 // int r2 = rreInst->R2Value();
4836 // int32_t r2_val = get_low_register<int32_t>(r2);
4837 // uint64_t r2_finalval = (static_cast<uint64_t>(r2_val)
4838 // & 0x00000000ffffffff);
4839 // set_register(r1, r2_finalval);
4840 // break;
4841 uint64_t mem_val = static_cast<uint64_t>(ReadWU(addr, instr));
4842 set_register(r1, mem_val);
4843 } else if (op == LDY) {
4844 uint64_t dbl_val = *reinterpret_cast<uint64_t*>(addr);
4845 set_d_register(r1, dbl_val);
4846 } else if (op == STEY) {
4847 int64_t frs_val = get_d_register(r1) >> 32;
4848 WriteW(addr, static_cast<int32_t>(frs_val), instr);
4849 } else if (op == LEY) {
4850 float float_val = *reinterpret_cast<float*>(addr);
4851 set_d_register_from_float32(r1, float_val);
4852 } else if (op == STY) {
4853 uint32_t value = get_low_register<uint32_t>(r1);
4854 WriteW(addr, value, instr);
4855 } else if (op == STG) {
4856 uint64_t value = get_register(r1);
4857 WriteDW(addr, value);
4858 } else if (op == STDY) {
4859 int64_t frs_val = get_d_register(r1);
4860 WriteDW(addr, frs_val);
4861 } else if (op == STCY) {
4862 uint8_t value = get_low_register<uint32_t>(r1);
4863 WriteB(addr, value);
4864 } else if (op == STHY) {
4865 uint16_t value = get_low_register<uint32_t>(r1);
4866 WriteH(addr, value, instr);
4867 } else if (op == LHY) {
4868 int32_t result = static_cast<int32_t>(ReadH(addr, instr));
4869 set_low_register(r1, result);
4870 }
4871 break;
4872 }
4873 case MVC: {
4874 // Move Character
4875 int b1 = ssInstr->B1Value();
4876 intptr_t d1 = ssInstr->D1Value();
4877 int b2 = ssInstr->B2Value();
4878 intptr_t d2 = ssInstr->D2Value();
4879 int length = ssInstr->Length();
4880 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
4881 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
4882 intptr_t src_addr = b2_val + d2;
4883 intptr_t dst_addr = b1_val + d1;
4884 // remember that the length is the actual length - 1
4885 for (int i = 0; i < length + 1; ++i) {
4886 WriteB(dst_addr++, ReadB(src_addr++));
4887 }
4888 break;
4889 }
4890 case MVHI: {
4891 // Move Integer (32)
4892 int b1 = silInstr->B1Value();
4893 intptr_t d1 = silInstr->D1Value();
4894 int16_t i2 = silInstr->I2Value();
4895 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
4896 intptr_t src_addr = b1_val + d1;
4897 WriteW(src_addr, i2, instr);
4898 break;
4899 }
4900 case MVGHI: {
4901 // Move Integer (64)
4902 int b1 = silInstr->B1Value();
4903 intptr_t d1 = silInstr->D1Value();
4904 int16_t i2 = silInstr->I2Value();
4905 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
4906 intptr_t src_addr = b1_val + d1;
4907 WriteDW(src_addr, i2);
4908 break;
4909 }
4910 case LLH:
4911 case LLGH: {
4912 // Load Logical Halfworld
4913 int r1 = rxyInstr->R1Value();
4914 int b2 = rxyInstr->B2Value();
4915 int x2 = rxyInstr->X2Value();
4916 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
4917 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
4918 intptr_t d2_val = rxyInstr->D2Value();
4919 uint16_t mem_val = ReadHU(b2_val + d2_val + x2_val, instr);
4920 if (op == LLH) {
4921 set_low_register(r1, mem_val);
4922 } else if (op == LLGH) {
4923 set_register(r1, mem_val);
4924 } else {
4925 UNREACHABLE();
4926 }
4927 break;
4928 }
4929 case LLC:
4930 case LLGC: {
4931 // Load Logical Character - loads a byte and zero extends.
4932 int r1 = rxyInstr->R1Value();
4933 int b2 = rxyInstr->B2Value();
4934 int x2 = rxyInstr->X2Value();
4935 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
4936 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
4937 intptr_t d2_val = rxyInstr->D2Value();
4938 uint8_t mem_val = ReadBU(b2_val + d2_val + x2_val);
4939 if (op == LLC) {
4940 set_low_register(r1, static_cast<uint32_t>(mem_val));
4941 } else if (op == LLGC) {
4942 set_register(r1, static_cast<uint64_t>(mem_val));
4943 } else {
4944 UNREACHABLE();
4945 }
4946 break;
4947 }
4948 case XIHF:
4949 case XILF: {
4950 int r1 = rilInstr->R1Value();
4951 uint32_t imm = rilInstr->I2UnsignedValue();
4952 uint32_t alu_out = 0;
4953 if (op == XILF) {
4954 alu_out = get_low_register<uint32_t>(r1);
4955 alu_out = alu_out ^ imm;
4956 set_low_register(r1, alu_out);
4957 } else if (op == XIHF) {
4958 alu_out = get_high_register<uint32_t>(r1);
4959 alu_out = alu_out ^ imm;
4960 set_high_register(r1, alu_out);
4961 } else {
4962 UNREACHABLE();
4963 }
4964 SetS390BitWiseConditionCode<uint32_t>(alu_out);
4965 break;
4966 }
4967 case RISBG: {
4968 // Rotate then insert selected bits
4969 int r1 = rieInstr->R1Value();
4970 int r2 = rieInstr->R2Value();
4971 // Starting Bit Position is Bits 2-7 of I3 field
4972 uint32_t start_bit = rieInstr->I3Value() & 0x3F;
4973 // Ending Bit Position is Bits 2-7 of I4 field
4974 uint32_t end_bit = rieInstr->I4Value() & 0x3F;
4975 // Shift Amount is Bits 2-7 of I5 field
4976 uint32_t shift_amount = rieInstr->I5Value() & 0x3F;
4977 // Zero out Remaining (unslected) bits if Bit 0 of I4 is 1.
4978 bool zero_remaining = (0 != (rieInstr->I4Value() & 0x80));
4979
4980 uint64_t src_val = get_register(r2);
4981
4982 // Rotate Left by Shift Amount first
4983 uint64_t rotated_val =
4984 (src_val << shift_amount) | (src_val >> (64 - shift_amount));
4985 int32_t width = end_bit - start_bit + 1;
4986
4987 uint64_t selection_mask = 0;
4988 if (width < 64) {
4989 selection_mask = (static_cast<uint64_t>(1) << width) - 1;
4990 } else {
4991 selection_mask = static_cast<uint64_t>(static_cast<int64_t>(-1));
4992 }
4993 selection_mask = selection_mask << (63 - end_bit);
4994
4995 uint64_t selected_val = rotated_val & selection_mask;
4996
4997 if (!zero_remaining) {
4998 // Merged the unselected bits from the original value
4999 selected_val = (src_val & ~selection_mask) | selected_val;
5000 }
5001
5002 // Condition code is set by treating result as 64-bit signed int
5003 SetS390ConditionCode<int64_t>(selected_val, 0);
5004 set_register(r1, selected_val);
5005 break;
5006 }
5007 default:
5008 return DecodeSixByteArithmetic(instr);
5009 }
5010 return true;
5011 }
5012
DecodeSixByteBitShift(Instruction * instr)5013 void Simulator::DecodeSixByteBitShift(Instruction* instr) {
5014 Opcode op = instr->S390OpcodeValue();
5015
5016 // Pre-cast instruction to various types
5017
5018 RSYInstruction* rsyInstr = reinterpret_cast<RSYInstruction*>(instr);
5019
5020 switch (op) {
5021 case SLLK:
5022 case RLL:
5023 case SRLK: {
5024 // For SLLK/SRLL, the 32-bit third operand is shifted the number
5025 // of bits specified by the second-operand address, and the result is
5026 // placed at the first-operand location. Except for when the R1 and R3
5027 // fields designate the same register, the third operand remains
5028 // unchanged in general register R3.
5029 int r1 = rsyInstr->R1Value();
5030 int r3 = rsyInstr->R3Value();
5031 int b2 = rsyInstr->B2Value();
5032 intptr_t d2 = rsyInstr->D2Value();
5033 // only takes rightmost 6 bits
5034 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
5035 int shiftBits = (b2_val + d2) & 0x3F;
5036 // unsigned
5037 uint32_t r3_val = get_low_register<uint32_t>(r3);
5038 uint32_t alu_out = 0;
5039 if (SLLK == op) {
5040 alu_out = r3_val << shiftBits;
5041 } else if (SRLK == op) {
5042 alu_out = r3_val >> shiftBits;
5043 } else if (RLL == op) {
5044 uint32_t rotateBits = r3_val >> (32 - shiftBits);
5045 alu_out = (r3_val << shiftBits) | (rotateBits);
5046 } else {
5047 UNREACHABLE();
5048 }
5049 set_low_register(r1, alu_out);
5050 break;
5051 }
5052 case SLLG:
5053 case RLLG:
5054 case SRLG: {
5055 // For SLLG/SRLG, the 64-bit third operand is shifted the number
5056 // of bits specified by the second-operand address, and the result is
5057 // placed at the first-operand location. Except for when the R1 and R3
5058 // fields designate the same register, the third operand remains
5059 // unchanged in general register R3.
5060 int r1 = rsyInstr->R1Value();
5061 int r3 = rsyInstr->R3Value();
5062 int b2 = rsyInstr->B2Value();
5063 intptr_t d2 = rsyInstr->D2Value();
5064 // only takes rightmost 6 bits
5065 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
5066 int shiftBits = (b2_val + d2) & 0x3F;
5067 // unsigned
5068 uint64_t r3_val = get_register(r3);
5069 uint64_t alu_out = 0;
5070 if (op == SLLG) {
5071 alu_out = r3_val << shiftBits;
5072 } else if (op == SRLG) {
5073 alu_out = r3_val >> shiftBits;
5074 } else if (op == RLLG) {
5075 uint64_t rotateBits = r3_val >> (64 - shiftBits);
5076 alu_out = (r3_val << shiftBits) | (rotateBits);
5077 } else {
5078 UNREACHABLE();
5079 }
5080 set_register(r1, alu_out);
5081 break;
5082 }
5083 default:
5084 UNREACHABLE();
5085 }
5086 }
5087
5088 /**
5089 * Decodes and simulates six byte arithmetic instructions
5090 */
DecodeSixByteArithmetic(Instruction * instr)5091 bool Simulator::DecodeSixByteArithmetic(Instruction* instr) {
5092 Opcode op = instr->S390OpcodeValue();
5093
5094 // Pre-cast instruction to various types
5095 SIYInstruction* siyInstr = reinterpret_cast<SIYInstruction*>(instr);
5096
5097 switch (op) {
5098 case CDB:
5099 case ADB:
5100 case SDB:
5101 case MDB:
5102 case DDB:
5103 case SQDB: {
5104 RXEInstruction* rxeInstr = reinterpret_cast<RXEInstruction*>(instr);
5105 int b2 = rxeInstr->B2Value();
5106 int x2 = rxeInstr->X2Value();
5107 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
5108 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
5109 intptr_t d2_val = rxeInstr->D2Value();
5110 double r1_val = get_double_from_d_register(rxeInstr->R1Value());
5111 double dbl_val = ReadDouble(b2_val + x2_val + d2_val);
5112
5113 switch (op) {
5114 case CDB:
5115 SetS390ConditionCode<double>(r1_val, dbl_val);
5116 break;
5117 case ADB:
5118 r1_val += dbl_val;
5119 set_d_register_from_double(r1, r1_val);
5120 SetS390ConditionCode<double>(r1_val, 0);
5121 break;
5122 case SDB:
5123 r1_val -= dbl_val;
5124 set_d_register_from_double(r1, r1_val);
5125 SetS390ConditionCode<double>(r1_val, 0);
5126 break;
5127 case MDB:
5128 r1_val *= dbl_val;
5129 set_d_register_from_double(r1, r1_val);
5130 SetS390ConditionCode<double>(r1_val, 0);
5131 break;
5132 case DDB:
5133 r1_val /= dbl_val;
5134 set_d_register_from_double(r1, r1_val);
5135 SetS390ConditionCode<double>(r1_val, 0);
5136 break;
5137 case SQDB:
5138 r1_val = std::sqrt(dbl_val);
5139 set_d_register_from_double(r1, r1_val);
5140 default:
5141 UNREACHABLE();
5142 break;
5143 }
5144 break;
5145 }
5146 case LRV:
5147 case LRVH:
5148 case STRV:
5149 case STRVH: {
5150 RXYInstruction* rxyInstr = reinterpret_cast<RXYInstruction*>(instr);
5151 int r1 = rxyInstr->R1Value();
5152 int x2 = rxyInstr->X2Value();
5153 int b2 = rxyInstr->B2Value();
5154 int d2 = rxyInstr->D2Value();
5155 int32_t r1_val = get_low_register<int32_t>(r1);
5156 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
5157 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
5158 intptr_t mem_addr = b2_val + x2_val + d2;
5159
5160 if (op == LRVH) {
5161 int16_t mem_val = ReadH(mem_addr, instr);
5162 int32_t result = ByteReverse(mem_val) & 0x0000ffff;
5163 result |= r1_val & 0xffff0000;
5164 set_low_register(r1, result);
5165 } else if (op == LRV) {
5166 int32_t mem_val = ReadW(mem_addr, instr);
5167 set_low_register(r1, ByteReverse(mem_val));
5168 } else if (op == STRVH) {
5169 int16_t result = static_cast<int16_t>(r1_val >> 16);
5170 WriteH(mem_addr, ByteReverse(result), instr);
5171 } else if (op == STRV) {
5172 WriteW(mem_addr, ByteReverse(r1_val), instr);
5173 }
5174
5175 break;
5176 }
5177 case AHIK:
5178 case AGHIK: {
5179 // Non-clobbering Add Halfword Immediate
5180 RIEInstruction* rieInst = reinterpret_cast<RIEInstruction*>(instr);
5181 int r1 = rieInst->R1Value();
5182 int r2 = rieInst->R2Value();
5183 bool isOF = false;
5184 if (AHIK == op) {
5185 // 32-bit Add
5186 int32_t r2_val = get_low_register<int32_t>(r2);
5187 int32_t imm = rieInst->I6Value();
5188 isOF = CheckOverflowForIntAdd(r2_val, imm, int32_t);
5189 set_low_register(r1, r2_val + imm);
5190 SetS390ConditionCode<int32_t>(r2_val + imm, 0);
5191 } else if (AGHIK == op) {
5192 // 64-bit Add
5193 int64_t r2_val = get_register(r2);
5194 int64_t imm = static_cast<int64_t>(rieInst->I6Value());
5195 isOF = CheckOverflowForIntAdd(r2_val, imm, int64_t);
5196 set_register(r1, r2_val + imm);
5197 SetS390ConditionCode<int64_t>(r2_val + imm, 0);
5198 }
5199 SetS390OverflowCode(isOF);
5200 break;
5201 }
5202 case ALFI:
5203 case SLFI: {
5204 RILInstruction* rilInstr = reinterpret_cast<RILInstruction*>(instr);
5205 int r1 = rilInstr->R1Value();
5206 uint32_t imm = rilInstr->I2UnsignedValue();
5207 uint32_t alu_out = get_low_register<uint32_t>(r1);
5208 if (op == ALFI) {
5209 alu_out += imm;
5210 } else if (op == SLFI) {
5211 alu_out -= imm;
5212 }
5213 SetS390ConditionCode<uint32_t>(alu_out, 0);
5214 set_low_register(r1, alu_out);
5215 break;
5216 }
5217 case ML: {
5218 UNIMPLEMENTED();
5219 break;
5220 }
5221 case AY:
5222 case SY:
5223 case NY:
5224 case OY:
5225 case XY:
5226 case CY: {
5227 RXYInstruction* rxyInstr = reinterpret_cast<RXYInstruction*>(instr);
5228 int r1 = rxyInstr->R1Value();
5229 int x2 = rxyInstr->X2Value();
5230 int b2 = rxyInstr->B2Value();
5231 int d2 = rxyInstr->D2Value();
5232 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
5233 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
5234 int32_t alu_out = get_low_register<int32_t>(r1);
5235 int32_t mem_val = ReadW(b2_val + x2_val + d2, instr);
5236 bool isOF = false;
5237 if (op == AY) {
5238 isOF = CheckOverflowForIntAdd(alu_out, mem_val, int32_t);
5239 alu_out += mem_val;
5240 SetS390ConditionCode<int32_t>(alu_out, 0);
5241 SetS390OverflowCode(isOF);
5242 } else if (op == SY) {
5243 isOF = CheckOverflowForIntSub(alu_out, mem_val, int32_t);
5244 alu_out -= mem_val;
5245 SetS390ConditionCode<int32_t>(alu_out, 0);
5246 SetS390OverflowCode(isOF);
5247 } else if (op == NY) {
5248 alu_out &= mem_val;
5249 SetS390BitWiseConditionCode<uint32_t>(alu_out);
5250 } else if (op == OY) {
5251 alu_out |= mem_val;
5252 SetS390BitWiseConditionCode<uint32_t>(alu_out);
5253 } else if (op == XY) {
5254 alu_out ^= mem_val;
5255 SetS390BitWiseConditionCode<uint32_t>(alu_out);
5256 } else if (op == CY) {
5257 SetS390ConditionCode<int32_t>(alu_out, mem_val);
5258 }
5259 if (op != CY) {
5260 set_low_register(r1, alu_out);
5261 }
5262 break;
5263 }
5264 case AHY:
5265 case SHY: {
5266 RXYInstruction* rxyInstr = reinterpret_cast<RXYInstruction*>(instr);
5267 int32_t r1_val = get_low_register<int32_t>(rxyInstr->R1Value());
5268 int b2 = rxyInstr->B2Value();
5269 int x2 = rxyInstr->X2Value();
5270 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
5271 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
5272 intptr_t d2_val = rxyInstr->D2Value();
5273 int32_t mem_val =
5274 static_cast<int32_t>(ReadH(b2_val + d2_val + x2_val, instr));
5275 int32_t alu_out = 0;
5276 bool isOF = false;
5277 switch (op) {
5278 case AHY:
5279 alu_out = r1_val + mem_val;
5280 isOF = CheckOverflowForIntAdd(r1_val, mem_val, int32_t);
5281 break;
5282 case SHY:
5283 alu_out = r1_val - mem_val;
5284 isOF = CheckOverflowForIntSub(r1_val, mem_val, int64_t);
5285 break;
5286 default:
5287 UNREACHABLE();
5288 break;
5289 }
5290 set_low_register(r1, alu_out);
5291 SetS390ConditionCode<int32_t>(alu_out, 0);
5292 SetS390OverflowCode(isOF);
5293 break;
5294 }
5295 case AG:
5296 case SG:
5297 case NG:
5298 case OG:
5299 case XG:
5300 case CG:
5301 case CLG: {
5302 RXYInstruction* rxyInstr = reinterpret_cast<RXYInstruction*>(instr);
5303 int r1 = rxyInstr->R1Value();
5304 int x2 = rxyInstr->X2Value();
5305 int b2 = rxyInstr->B2Value();
5306 int d2 = rxyInstr->D2Value();
5307 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
5308 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
5309 int64_t alu_out = get_register(r1);
5310 int64_t mem_val = ReadDW(b2_val + x2_val + d2);
5311
5312 switch (op) {
5313 case AG: {
5314 alu_out += mem_val;
5315 SetS390ConditionCode<int32_t>(alu_out, 0);
5316 break;
5317 }
5318 case SG: {
5319 alu_out -= mem_val;
5320 SetS390ConditionCode<int32_t>(alu_out, 0);
5321 break;
5322 }
5323 case NG: {
5324 alu_out &= mem_val;
5325 SetS390BitWiseConditionCode<uint32_t>(alu_out);
5326 break;
5327 }
5328 case OG: {
5329 alu_out |= mem_val;
5330 SetS390BitWiseConditionCode<uint32_t>(alu_out);
5331 break;
5332 }
5333 case XG: {
5334 alu_out ^= mem_val;
5335 SetS390BitWiseConditionCode<uint32_t>(alu_out);
5336 break;
5337 }
5338 case CG: {
5339 SetS390ConditionCode<int64_t>(alu_out, mem_val);
5340 break;
5341 }
5342 case CLG: {
5343 SetS390ConditionCode<uint64_t>(alu_out, mem_val);
5344 break;
5345 }
5346 default: {
5347 DCHECK(false);
5348 break;
5349 }
5350 }
5351
5352 if (op != CG) {
5353 set_register(r1, alu_out);
5354 }
5355 break;
5356 }
5357 case ALY:
5358 case SLY:
5359 case CLY: {
5360 RXYInstruction* rxyInstr = reinterpret_cast<RXYInstruction*>(instr);
5361 int r1 = rxyInstr->R1Value();
5362 int x2 = rxyInstr->X2Value();
5363 int b2 = rxyInstr->B2Value();
5364 int d2 = rxyInstr->D2Value();
5365 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
5366 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
5367 uint32_t alu_out = get_low_register<uint32_t>(r1);
5368 uint32_t mem_val = ReadWU(b2_val + x2_val + d2, instr);
5369
5370 if (op == ALY) {
5371 alu_out += mem_val;
5372 set_low_register(r1, alu_out);
5373 SetS390ConditionCode<uint32_t>(alu_out, 0);
5374 } else if (op == SLY) {
5375 alu_out -= mem_val;
5376 set_low_register(r1, alu_out);
5377 SetS390ConditionCode<uint32_t>(alu_out, 0);
5378 } else if (op == CLY) {
5379 SetS390ConditionCode<uint32_t>(alu_out, mem_val);
5380 }
5381 break;
5382 }
5383 case AGFI:
5384 case AFI: {
5385 // Clobbering Add Word Immediate
5386 RILInstruction* rilInstr = reinterpret_cast<RILInstruction*>(instr);
5387 int32_t r1 = rilInstr->R1Value();
5388 bool isOF = false;
5389 if (AFI == op) {
5390 // 32-bit Add (Register + 32-bit Immediate)
5391 int32_t r1_val = get_low_register<int32_t>(r1);
5392 int32_t i2 = rilInstr->I2Value();
5393 isOF = CheckOverflowForIntAdd(r1_val, i2, int32_t);
5394 int32_t alu_out = r1_val + i2;
5395 set_low_register(r1, alu_out);
5396 SetS390ConditionCode<int32_t>(alu_out, 0);
5397 } else if (AGFI == op) {
5398 // 64-bit Add (Register + 32-bit Imm)
5399 int64_t r1_val = get_register(r1);
5400 int64_t i2 = static_cast<int64_t>(rilInstr->I2Value());
5401 isOF = CheckOverflowForIntAdd(r1_val, i2, int64_t);
5402 int64_t alu_out = r1_val + i2;
5403 set_register(r1, alu_out);
5404 SetS390ConditionCode<int64_t>(alu_out, 0);
5405 }
5406 SetS390OverflowCode(isOF);
5407 break;
5408 }
5409 case ASI: {
5410 // TODO(bcleung): Change all fooInstr->I2Value() to template functions.
5411 // The below static cast to 8 bit and then to 32 bit is necessary
5412 // because siyInstr->I2Value() returns a uint8_t, which a direct
5413 // cast to int32_t could incorrectly interpret.
5414 int8_t i2_8bit = static_cast<int8_t>(siyInstr->I2Value());
5415 int32_t i2 = static_cast<int32_t>(i2_8bit);
5416 int b1 = siyInstr->B1Value();
5417 intptr_t b1_val = (b1 == 0) ? 0 : get_register(b1);
5418
5419 int d1_val = siyInstr->D1Value();
5420 intptr_t addr = b1_val + d1_val;
5421
5422 int32_t mem_val = ReadW(addr, instr);
5423 bool isOF = CheckOverflowForIntAdd(mem_val, i2, int32_t);
5424 int32_t alu_out = mem_val + i2;
5425 SetS390ConditionCode<int32_t>(alu_out, 0);
5426 SetS390OverflowCode(isOF);
5427 WriteW(addr, alu_out, instr);
5428 break;
5429 }
5430 case AGSI: {
5431 // TODO(bcleung): Change all fooInstr->I2Value() to template functions.
5432 // The below static cast to 8 bit and then to 32 bit is necessary
5433 // because siyInstr->I2Value() returns a uint8_t, which a direct
5434 // cast to int32_t could incorrectly interpret.
5435 int8_t i2_8bit = static_cast<int8_t>(siyInstr->I2Value());
5436 int64_t i2 = static_cast<int64_t>(i2_8bit);
5437 int b1 = siyInstr->B1Value();
5438 intptr_t b1_val = (b1 == 0) ? 0 : get_register(b1);
5439
5440 int d1_val = siyInstr->D1Value();
5441 intptr_t addr = b1_val + d1_val;
5442
5443 int64_t mem_val = ReadDW(addr);
5444 int isOF = CheckOverflowForIntAdd(mem_val, i2, int64_t);
5445 int64_t alu_out = mem_val + i2;
5446 SetS390ConditionCode<uint64_t>(alu_out, 0);
5447 SetS390OverflowCode(isOF);
5448 WriteDW(addr, alu_out);
5449 break;
5450 }
5451 case AGF:
5452 case SGF:
5453 case ALG:
5454 case SLG: {
5455 #ifndef V8_TARGET_ARCH_S390X
5456 DCHECK(false);
5457 #endif
5458 RXYInstruction* rxyInstr = reinterpret_cast<RXYInstruction*>(instr);
5459 int r1 = rxyInstr->R1Value();
5460 uint64_t r1_val = get_register(rxyInstr->R1Value());
5461 int b2 = rxyInstr->B2Value();
5462 int x2 = rxyInstr->X2Value();
5463 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
5464 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
5465 intptr_t d2_val = rxyInstr->D2Value();
5466 uint64_t alu_out = r1_val;
5467 if (op == ALG) {
5468 uint64_t mem_val =
5469 static_cast<uint64_t>(ReadDW(b2_val + d2_val + x2_val));
5470 alu_out += mem_val;
5471 SetS390ConditionCode<uint64_t>(alu_out, 0);
5472 } else if (op == SLG) {
5473 uint64_t mem_val =
5474 static_cast<uint64_t>(ReadDW(b2_val + d2_val + x2_val));
5475 alu_out -= mem_val;
5476 SetS390ConditionCode<uint64_t>(alu_out, 0);
5477 } else if (op == AGF) {
5478 uint32_t mem_val = ReadW(b2_val + d2_val + x2_val, instr);
5479 alu_out += mem_val;
5480 SetS390ConditionCode<int64_t>(alu_out, 0);
5481 } else if (op == SGF) {
5482 uint32_t mem_val = ReadW(b2_val + d2_val + x2_val, instr);
5483 alu_out -= mem_val;
5484 SetS390ConditionCode<int64_t>(alu_out, 0);
5485 } else {
5486 DCHECK(false);
5487 }
5488 set_register(r1, alu_out);
5489 break;
5490 }
5491 case ALGFI:
5492 case SLGFI: {
5493 #ifndef V8_TARGET_ARCH_S390X
5494 // should only be called on 64bit
5495 DCHECK(false);
5496 #endif
5497 RILInstruction* rilInstr = reinterpret_cast<RILInstruction*>(instr);
5498 int r1 = rilInstr->R1Value();
5499 uint32_t i2 = rilInstr->I2UnsignedValue();
5500 uint64_t r1_val = (uint64_t)(get_register(r1));
5501 uint64_t alu_out;
5502 if (op == ALGFI)
5503 alu_out = r1_val + i2;
5504 else
5505 alu_out = r1_val - i2;
5506 set_register(r1, (intptr_t)alu_out);
5507 SetS390ConditionCode<uint64_t>(alu_out, 0);
5508 break;
5509 }
5510 case MSY:
5511 case MSG: {
5512 RXYInstruction* rxyInstr = reinterpret_cast<RXYInstruction*>(instr);
5513 int r1 = rxyInstr->R1Value();
5514 int b2 = rxyInstr->B2Value();
5515 int x2 = rxyInstr->X2Value();
5516 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
5517 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
5518 intptr_t d2_val = rxyInstr->D2Value();
5519 if (op == MSY) {
5520 int32_t mem_val = ReadW(b2_val + d2_val + x2_val, instr);
5521 int32_t r1_val = get_low_register<int32_t>(r1);
5522 set_low_register(r1, mem_val * r1_val);
5523 } else if (op == MSG) {
5524 int64_t mem_val = ReadDW(b2_val + d2_val + x2_val);
5525 int64_t r1_val = get_register(r1);
5526 set_register(r1, mem_val * r1_val);
5527 } else {
5528 UNREACHABLE();
5529 }
5530 break;
5531 }
5532 case MSFI:
5533 case MSGFI: {
5534 RILInstruction* rilinst = reinterpret_cast<RILInstruction*>(instr);
5535 int r1 = rilinst->R1Value();
5536 int32_t i2 = rilinst->I2Value();
5537 if (op == MSFI) {
5538 int32_t alu_out = get_low_register<int32_t>(r1);
5539 alu_out = alu_out * i2;
5540 set_low_register(r1, alu_out);
5541 } else if (op == MSGFI) {
5542 int64_t alu_out = get_register(r1);
5543 alu_out = alu_out * i2;
5544 set_register(r1, alu_out);
5545 } else {
5546 UNREACHABLE();
5547 }
5548 break;
5549 }
5550 default:
5551 UNREACHABLE();
5552 return false;
5553 }
5554 return true;
5555 }
5556
ByteReverse(int16_t hword)5557 int16_t Simulator::ByteReverse(int16_t hword) {
5558 #if defined(__GNUC__)
5559 return __builtin_bswap16(hword);
5560 #else
5561 return (hword << 8) | ((hword >> 8) & 0x00ff);
5562 #endif
5563 }
5564
ByteReverse(int32_t word)5565 int32_t Simulator::ByteReverse(int32_t word) {
5566 #if defined(__GNUC__)
5567 return __builtin_bswap32(word);
5568 #else
5569 int32_t result = word << 24;
5570 result |= (word << 8) & 0x00ff0000;
5571 result |= (word >> 8) & 0x0000ff00;
5572 result |= (word >> 24) & 0x00000ff;
5573 return result;
5574 #endif
5575 }
5576
ByteReverse(int64_t dword)5577 int64_t Simulator::ByteReverse(int64_t dword) {
5578 #if defined(__GNUC__)
5579 return __builtin_bswap64(dword);
5580 #else
5581 #error unsupport __builtin_bswap64
5582 #endif
5583 }
5584
DecodeInstructionOriginal(Instruction * instr)5585 int Simulator::DecodeInstructionOriginal(Instruction* instr) {
5586 int instrLength = instr->InstructionLength();
5587 bool processed = true;
5588 if (instrLength == 2)
5589 processed = DecodeTwoByte(instr);
5590 else if (instrLength == 4)
5591 processed = DecodeFourByte(instr);
5592 else if (instrLength == 6)
5593 processed = DecodeSixByte(instr);
5594 return instrLength;
5595 }
5596
DecodeInstruction(Instruction * instr)5597 int Simulator::DecodeInstruction(Instruction* instr) {
5598 Opcode op = instr->S390OpcodeValue();
5599 DCHECK(EvalTable[op] != NULL);
5600 return (this->*EvalTable[op])(instr);
5601 }
5602
5603 // Executes the current instruction.
ExecuteInstruction(Instruction * instr,bool auto_incr_pc)5604 void Simulator::ExecuteInstruction(Instruction* instr, bool auto_incr_pc) {
5605 icount_++;
5606
5607 if (v8::internal::FLAG_check_icache) {
5608 CheckICache(isolate_->simulator_i_cache(), instr);
5609 }
5610
5611 pc_modified_ = false;
5612
5613 if (::v8::internal::FLAG_trace_sim) {
5614 disasm::NameConverter converter;
5615 disasm::Disassembler dasm(converter);
5616 // use a reasonably large buffer
5617 v8::internal::EmbeddedVector<char, 256> buffer;
5618 dasm.InstructionDecode(buffer, reinterpret_cast<byte*>(instr));
5619 PrintF("%05" PRId64 " %08" V8PRIxPTR " %s\n", icount_,
5620 reinterpret_cast<intptr_t>(instr), buffer.start());
5621
5622 // Flush stdout to prevent incomplete file output during abnormal exits
5623 // This is caused by the output being buffered before being written to file
5624 fflush(stdout);
5625 }
5626
5627 // Try to simulate as S390 Instruction first.
5628 int length = DecodeInstruction(instr);
5629
5630 if (!pc_modified_ && auto_incr_pc) {
5631 DCHECK(length == instr->InstructionLength());
5632 set_pc(reinterpret_cast<intptr_t>(instr) + length);
5633 }
5634 return;
5635 }
5636
DebugStart()5637 void Simulator::DebugStart() {
5638 S390Debugger dbg(this);
5639 dbg.Debug();
5640 }
5641
Execute()5642 void Simulator::Execute() {
5643 // Get the PC to simulate. Cannot use the accessor here as we need the
5644 // raw PC value and not the one used as input to arithmetic instructions.
5645 intptr_t program_counter = get_pc();
5646
5647 if (::v8::internal::FLAG_stop_sim_at == 0) {
5648 // Fast version of the dispatch loop without checking whether the simulator
5649 // should be stopping at a particular executed instruction.
5650 while (program_counter != end_sim_pc) {
5651 Instruction* instr = reinterpret_cast<Instruction*>(program_counter);
5652 ExecuteInstruction(instr);
5653 program_counter = get_pc();
5654 }
5655 } else {
5656 // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when
5657 // we reach the particular instuction count.
5658 while (program_counter != end_sim_pc) {
5659 Instruction* instr = reinterpret_cast<Instruction*>(program_counter);
5660 if (icount_ == ::v8::internal::FLAG_stop_sim_at) {
5661 S390Debugger dbg(this);
5662 dbg.Debug();
5663 } else {
5664 ExecuteInstruction(instr);
5665 }
5666 program_counter = get_pc();
5667 }
5668 }
5669 }
5670
CallInternal(byte * entry,int reg_arg_count)5671 void Simulator::CallInternal(byte* entry, int reg_arg_count) {
5672 // Adjust JS-based stack limit to C-based stack limit.
5673 isolate_->stack_guard()->AdjustStackLimitForSimulator();
5674
5675 // Prepare to execute the code at entry
5676 if (ABI_USES_FUNCTION_DESCRIPTORS) {
5677 // entry is the function descriptor
5678 set_pc(*(reinterpret_cast<intptr_t*>(entry)));
5679 } else {
5680 // entry is the instruction address
5681 set_pc(reinterpret_cast<intptr_t>(entry));
5682 }
5683 // Remember the values of non-volatile registers.
5684 int64_t r6_val = get_register(r6);
5685 int64_t r7_val = get_register(r7);
5686 int64_t r8_val = get_register(r8);
5687 int64_t r9_val = get_register(r9);
5688 int64_t r10_val = get_register(r10);
5689 int64_t r11_val = get_register(r11);
5690 int64_t r12_val = get_register(r12);
5691 int64_t r13_val = get_register(r13);
5692
5693 if (ABI_CALL_VIA_IP) {
5694 // Put target address in ip (for JS prologue).
5695 set_register(ip, get_pc());
5696 }
5697
5698 // Put down marker for end of simulation. The simulator will stop simulation
5699 // when the PC reaches this value. By saving the "end simulation" value into
5700 // the LR the simulation stops when returning to this call point.
5701 registers_[14] = end_sim_pc;
5702
5703 // Set up the non-volatile registers with a known value. To be able to check
5704 // that they are preserved properly across JS execution.
5705 uintptr_t callee_saved_value = icount_;
5706 if (reg_arg_count < 5) {
5707 set_register(r6, callee_saved_value + 6);
5708 }
5709 set_register(r7, callee_saved_value + 7);
5710 set_register(r8, callee_saved_value + 8);
5711 set_register(r9, callee_saved_value + 9);
5712 set_register(r10, callee_saved_value + 10);
5713 set_register(r11, callee_saved_value + 11);
5714 set_register(r12, callee_saved_value + 12);
5715 set_register(r13, callee_saved_value + 13);
5716
5717 // Start the simulation
5718 Execute();
5719
5720 // Check that the non-volatile registers have been preserved.
5721 #ifndef V8_TARGET_ARCH_S390X
5722 if (reg_arg_count < 5) {
5723 DCHECK_EQ(callee_saved_value + 6, get_low_register<uint32_t>(r6));
5724 }
5725 DCHECK_EQ(callee_saved_value + 7, get_low_register<uint32_t>(r7));
5726 DCHECK_EQ(callee_saved_value + 8, get_low_register<uint32_t>(r8));
5727 DCHECK_EQ(callee_saved_value + 9, get_low_register<uint32_t>(r9));
5728 DCHECK_EQ(callee_saved_value + 10, get_low_register<uint32_t>(r10));
5729 DCHECK_EQ(callee_saved_value + 11, get_low_register<uint32_t>(r11));
5730 DCHECK_EQ(callee_saved_value + 12, get_low_register<uint32_t>(r12));
5731 DCHECK_EQ(callee_saved_value + 13, get_low_register<uint32_t>(r13));
5732 #else
5733 if (reg_arg_count < 5) {
5734 DCHECK_EQ(callee_saved_value + 6, get_register(r6));
5735 }
5736 DCHECK_EQ(callee_saved_value + 7, get_register(r7));
5737 DCHECK_EQ(callee_saved_value + 8, get_register(r8));
5738 DCHECK_EQ(callee_saved_value + 9, get_register(r9));
5739 DCHECK_EQ(callee_saved_value + 10, get_register(r10));
5740 DCHECK_EQ(callee_saved_value + 11, get_register(r11));
5741 DCHECK_EQ(callee_saved_value + 12, get_register(r12));
5742 DCHECK_EQ(callee_saved_value + 13, get_register(r13));
5743 #endif
5744
5745 // Restore non-volatile registers with the original value.
5746 set_register(r6, r6_val);
5747 set_register(r7, r7_val);
5748 set_register(r8, r8_val);
5749 set_register(r9, r9_val);
5750 set_register(r10, r10_val);
5751 set_register(r11, r11_val);
5752 set_register(r12, r12_val);
5753 set_register(r13, r13_val);
5754 }
5755
Call(byte * entry,int argument_count,...)5756 intptr_t Simulator::Call(byte* entry, int argument_count, ...) {
5757 // Adjust JS-based stack limit to C-based stack limit.
5758 isolate_->stack_guard()->AdjustStackLimitForSimulator();
5759
5760 // Remember the values of non-volatile registers.
5761 int64_t r6_val = get_register(r6);
5762 int64_t r7_val = get_register(r7);
5763 int64_t r8_val = get_register(r8);
5764 int64_t r9_val = get_register(r9);
5765 int64_t r10_val = get_register(r10);
5766 int64_t r11_val = get_register(r11);
5767 int64_t r12_val = get_register(r12);
5768 int64_t r13_val = get_register(r13);
5769
5770 va_list parameters;
5771 va_start(parameters, argument_count);
5772 // Set up arguments
5773
5774 // First 5 arguments passed in registers r2-r6.
5775 int reg_arg_count = (argument_count > 5) ? 5 : argument_count;
5776 int stack_arg_count = argument_count - reg_arg_count;
5777 for (int i = 0; i < reg_arg_count; i++) {
5778 intptr_t value = va_arg(parameters, intptr_t);
5779 set_register(i + 2, value);
5780 }
5781
5782 // Remaining arguments passed on stack.
5783 int64_t original_stack = get_register(sp);
5784 // Compute position of stack on entry to generated code.
5785 uintptr_t entry_stack =
5786 (original_stack -
5787 (kCalleeRegisterSaveAreaSize + stack_arg_count * sizeof(intptr_t)));
5788 if (base::OS::ActivationFrameAlignment() != 0) {
5789 entry_stack &= -base::OS::ActivationFrameAlignment();
5790 }
5791
5792 // Store remaining arguments on stack, from low to high memory.
5793 intptr_t* stack_argument =
5794 reinterpret_cast<intptr_t*>(entry_stack + kCalleeRegisterSaveAreaSize);
5795 for (int i = 0; i < stack_arg_count; i++) {
5796 intptr_t value = va_arg(parameters, intptr_t);
5797 stack_argument[i] = value;
5798 }
5799 va_end(parameters);
5800 set_register(sp, entry_stack);
5801
5802 // Prepare to execute the code at entry
5803 #if ABI_USES_FUNCTION_DESCRIPTORS
5804 // entry is the function descriptor
5805 set_pc(*(reinterpret_cast<intptr_t*>(entry)));
5806 #else
5807 // entry is the instruction address
5808 set_pc(reinterpret_cast<intptr_t>(entry));
5809 #endif
5810
5811 // Put target address in ip (for JS prologue).
5812 set_register(r12, get_pc());
5813
5814 // Put down marker for end of simulation. The simulator will stop simulation
5815 // when the PC reaches this value. By saving the "end simulation" value into
5816 // the LR the simulation stops when returning to this call point.
5817 registers_[14] = end_sim_pc;
5818
5819 // Set up the non-volatile registers with a known value. To be able to check
5820 // that they are preserved properly across JS execution.
5821 uintptr_t callee_saved_value = icount_;
5822 if (reg_arg_count < 5) {
5823 set_register(r6, callee_saved_value + 6);
5824 }
5825 set_register(r7, callee_saved_value + 7);
5826 set_register(r8, callee_saved_value + 8);
5827 set_register(r9, callee_saved_value + 9);
5828 set_register(r10, callee_saved_value + 10);
5829 set_register(r11, callee_saved_value + 11);
5830 set_register(r12, callee_saved_value + 12);
5831 set_register(r13, callee_saved_value + 13);
5832
5833 // Start the simulation
5834 Execute();
5835
5836 // Check that the non-volatile registers have been preserved.
5837 #ifndef V8_TARGET_ARCH_S390X
5838 if (reg_arg_count < 5) {
5839 DCHECK_EQ(callee_saved_value + 6, get_low_register<uint32_t>(r6));
5840 }
5841 DCHECK_EQ(callee_saved_value + 7, get_low_register<uint32_t>(r7));
5842 DCHECK_EQ(callee_saved_value + 8, get_low_register<uint32_t>(r8));
5843 DCHECK_EQ(callee_saved_value + 9, get_low_register<uint32_t>(r9));
5844 DCHECK_EQ(callee_saved_value + 10, get_low_register<uint32_t>(r10));
5845 DCHECK_EQ(callee_saved_value + 11, get_low_register<uint32_t>(r11));
5846 DCHECK_EQ(callee_saved_value + 12, get_low_register<uint32_t>(r12));
5847 DCHECK_EQ(callee_saved_value + 13, get_low_register<uint32_t>(r13));
5848 #else
5849 if (reg_arg_count < 5) {
5850 DCHECK_EQ(callee_saved_value + 6, get_register(r6));
5851 }
5852 DCHECK_EQ(callee_saved_value + 7, get_register(r7));
5853 DCHECK_EQ(callee_saved_value + 8, get_register(r8));
5854 DCHECK_EQ(callee_saved_value + 9, get_register(r9));
5855 DCHECK_EQ(callee_saved_value + 10, get_register(r10));
5856 DCHECK_EQ(callee_saved_value + 11, get_register(r11));
5857 DCHECK_EQ(callee_saved_value + 12, get_register(r12));
5858 DCHECK_EQ(callee_saved_value + 13, get_register(r13));
5859 #endif
5860
5861 // Restore non-volatile registers with the original value.
5862 set_register(r6, r6_val);
5863 set_register(r7, r7_val);
5864 set_register(r8, r8_val);
5865 set_register(r9, r9_val);
5866 set_register(r10, r10_val);
5867 set_register(r11, r11_val);
5868 set_register(r12, r12_val);
5869 set_register(r13, r13_val);
5870 // Pop stack passed arguments.
5871
5872 #ifndef V8_TARGET_ARCH_S390X
5873 DCHECK_EQ(entry_stack, get_low_register<uint32_t>(sp));
5874 #else
5875 DCHECK_EQ(entry_stack, get_register(sp));
5876 #endif
5877 set_register(sp, original_stack);
5878
5879 // Return value register
5880 intptr_t result = get_register(r2);
5881 return result;
5882 }
5883
CallFP(byte * entry,double d0,double d1)5884 void Simulator::CallFP(byte* entry, double d0, double d1) {
5885 set_d_register_from_double(0, d0);
5886 set_d_register_from_double(1, d1);
5887 CallInternal(entry);
5888 }
5889
CallFPReturnsInt(byte * entry,double d0,double d1)5890 int32_t Simulator::CallFPReturnsInt(byte* entry, double d0, double d1) {
5891 CallFP(entry, d0, d1);
5892 int32_t result = get_register(r2);
5893 return result;
5894 }
5895
CallFPReturnsDouble(byte * entry,double d0,double d1)5896 double Simulator::CallFPReturnsDouble(byte* entry, double d0, double d1) {
5897 CallFP(entry, d0, d1);
5898 return get_double_from_d_register(0);
5899 }
5900
PushAddress(uintptr_t address)5901 uintptr_t Simulator::PushAddress(uintptr_t address) {
5902 uintptr_t new_sp = get_register(sp) - sizeof(uintptr_t);
5903 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(new_sp);
5904 *stack_slot = address;
5905 set_register(sp, new_sp);
5906 return new_sp;
5907 }
5908
PopAddress()5909 uintptr_t Simulator::PopAddress() {
5910 uintptr_t current_sp = get_register(sp);
5911 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp);
5912 uintptr_t address = *stack_slot;
5913 set_register(sp, current_sp + sizeof(uintptr_t));
5914 return address;
5915 }
5916
5917 #define EVALUATE(name) \
5918 int Simulator::Evaluate_##name(Instruction* instr)
5919
5920 #define DCHECK_OPCODE(op) DCHECK(instr->S390OpcodeValue() == op)
5921
5922 #define AS(type) reinterpret_cast<type*>(instr)
5923
5924 #define DECODE_RIL_A_INSTRUCTION(r1, i2) \
5925 int r1 = AS(RILInstruction)->R1Value(); \
5926 uint32_t i2 = AS(RILInstruction)->I2UnsignedValue(); \
5927 int length = 6;
5928
5929 #define DECODE_RIL_B_INSTRUCTION(r1, i2) \
5930 int r1 = AS(RILInstruction)->R1Value(); \
5931 int32_t i2 = AS(RILInstruction)->I2Value(); \
5932 int length = 6;
5933
5934 #define DECODE_RIL_C_INSTRUCTION(m1, ri2) \
5935 Condition m1 = static_cast<Condition>(AS(RILInstruction)->R1Value()); \
5936 uint64_t ri2 = AS(RILInstruction)->I2Value(); \
5937 int length = 6;
5938
5939 #define DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2) \
5940 int r1 = AS(RXYInstruction)->R1Value(); \
5941 int x2 = AS(RXYInstruction)->X2Value(); \
5942 int b2 = AS(RXYInstruction)->B2Value(); \
5943 int d2 = AS(RXYInstruction)->D2Value(); \
5944 int length = 6;
5945
5946 #define DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val) \
5947 int x2 = AS(RXInstruction)->X2Value(); \
5948 int b2 = AS(RXInstruction)->B2Value(); \
5949 int r1 = AS(RXInstruction)->R1Value(); \
5950 intptr_t d2_val = AS(RXInstruction)->D2Value(); \
5951 int length = 4;
5952
5953 #define DECODE_RS_A_INSTRUCTION(r1, r3, b2, d2) \
5954 int r3 = AS(RSInstruction)->R3Value(); \
5955 int b2 = AS(RSInstruction)->B2Value(); \
5956 int r1 = AS(RSInstruction)->R1Value(); \
5957 intptr_t d2 = AS(RSInstruction)->D2Value(); \
5958 int length = 4;
5959
5960 #define DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2) \
5961 int b2 = AS(RSInstruction)->B2Value(); \
5962 int r1 = AS(RSInstruction)->R1Value(); \
5963 int d2 = AS(RSInstruction)->D2Value(); \
5964 int length = 4;
5965
5966 #define DECODE_SI_INSTRUCTION_I_UINT8(b1, d1_val, imm_val) \
5967 int b1 = AS(SIInstruction)->B1Value(); \
5968 intptr_t d1_val = AS(SIInstruction)->D1Value(); \
5969 uint8_t imm_val = AS(SIInstruction)->I2Value(); \
5970 int length = 4;
5971
5972 #define DECODE_SIL_INSTRUCTION(b1, d1, i2) \
5973 int b1 = AS(SILInstruction)->B1Value(); \
5974 intptr_t d1 = AS(SILInstruction)->D1Value(); \
5975 int16_t i2 = AS(SILInstruction)->I2Value(); \
5976 int length = 6;
5977
5978 #define DECODE_SIY_INSTRUCTION(b1, d1, i2) \
5979 int b1 = AS(SIYInstruction)->B1Value(); \
5980 intptr_t d1 = AS(SIYInstruction)->D1Value(); \
5981 uint8_t i2 = AS(SIYInstruction)->I2Value(); \
5982 int length = 6;
5983
5984 #define DECODE_RRE_INSTRUCTION(r1, r2) \
5985 int r1 = AS(RREInstruction)->R1Value(); \
5986 int r2 = AS(RREInstruction)->R2Value(); \
5987 int length = 4;
5988
5989 #define DECODE_RRE_INSTRUCTION_M3(r1, r2, m3) \
5990 int r1 = AS(RREInstruction)->R1Value(); \
5991 int r2 = AS(RREInstruction)->R2Value(); \
5992 int m3 = AS(RREInstruction)->M3Value(); \
5993 int length = 4;
5994
5995 #define DECODE_RRE_INSTRUCTION_NO_R2(r1) \
5996 int r1 = AS(RREInstruction)->R1Value(); \
5997 int length = 4;
5998
5999 #define DECODE_RRD_INSTRUCTION(r1, r2, r3) \
6000 int r1 = AS(RRDInstruction)->R1Value(); \
6001 int r2 = AS(RRDInstruction)->R2Value(); \
6002 int r3 = AS(RRDInstruction)->R3Value(); \
6003 int length = 4;
6004
6005 #define DECODE_RRF_E_INSTRUCTION(r1, r2, m3, m4) \
6006 int r1 = AS(RRFInstruction)->R1Value(); \
6007 int r2 = AS(RRFInstruction)->R2Value(); \
6008 int m3 = AS(RRFInstruction)->M3Value(); \
6009 int m4 = AS(RRFInstruction)->M4Value(); \
6010 int length = 4;
6011
6012 #define DECODE_RRF_A_INSTRUCTION(r1, r2, r3) \
6013 int r1 = AS(RRFInstruction)->R1Value(); \
6014 int r2 = AS(RRFInstruction)->R2Value(); \
6015 int r3 = AS(RRFInstruction)->R3Value(); \
6016 int length = 4;
6017
6018 #define DECODE_RRF_C_INSTRUCTION(r1, r2, m3) \
6019 int r1 = AS(RRFInstruction)->R1Value(); \
6020 int r2 = AS(RRFInstruction)->R2Value(); \
6021 Condition m3 = static_cast<Condition>(AS(RRFInstruction)->M3Value()); \
6022 int length = 4;
6023
6024 #define DECODE_RR_INSTRUCTION(r1, r2) \
6025 int r1 = AS(RRInstruction)->R1Value(); \
6026 int r2 = AS(RRInstruction)->R2Value(); \
6027 int length = 2;
6028
6029 #define DECODE_RIE_D_INSTRUCTION(r1, r2, i2) \
6030 int r1 = AS(RIEInstruction)->R1Value(); \
6031 int r2 = AS(RIEInstruction)->R2Value(); \
6032 int32_t i2 = AS(RIEInstruction)->I6Value(); \
6033 int length = 6;
6034
6035 #define DECODE_RIE_F_INSTRUCTION(r1, r2, i3, i4, i5) \
6036 int r1 = AS(RIEInstruction)->R1Value(); \
6037 int r2 = AS(RIEInstruction)->R2Value(); \
6038 uint32_t i3 = AS(RIEInstruction)->I3Value(); \
6039 uint32_t i4 = AS(RIEInstruction)->I4Value(); \
6040 uint32_t i5 = AS(RIEInstruction)->I5Value(); \
6041 int length = 6;
6042
6043 #define DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2) \
6044 int r1 = AS(RSYInstruction)->R1Value(); \
6045 int r3 = AS(RSYInstruction)->R3Value(); \
6046 int b2 = AS(RSYInstruction)->B2Value(); \
6047 intptr_t d2 = AS(RSYInstruction)->D2Value(); \
6048 int length = 6;
6049
6050 #define DECODE_RI_A_INSTRUCTION(instr, r1, i2) \
6051 int32_t r1 = AS(RIInstruction)->R1Value(); \
6052 int16_t i2 = AS(RIInstruction)->I2Value(); \
6053 int length = 4;
6054
6055 #define DECODE_RI_B_INSTRUCTION(instr, r1, i2) \
6056 int32_t r1 = AS(RILInstruction)->R1Value(); \
6057 int16_t i2 = AS(RILInstruction)->I2Value(); \
6058 int length = 4;
6059
6060 #define DECODE_RI_C_INSTRUCTION(instr, m1, i2) \
6061 Condition m1 = static_cast<Condition>(AS(RIInstruction)->R1Value()); \
6062 int16_t i2 = AS(RIInstruction)->I2Value(); \
6063 int length = 4;
6064
6065 #define DECODE_RXE_INSTRUCTION(r1, b2, x2, d2) \
6066 int r1 = AS(RXEInstruction)->R1Value(); \
6067 int b2 = AS(RXEInstruction)->B2Value(); \
6068 int x2 = AS(RXEInstruction)->X2Value(); \
6069 int d2 = AS(RXEInstruction)->D2Value(); \
6070 int length = 6;
6071
6072 #define DECODE_VRR_C_INSTRUCTION(r1, r2, r3, m6, m5, m4) \
6073 int r1 = AS(VRR_C_Instruction)->R1Value(); \
6074 int r2 = AS(VRR_C_Instruction)->R2Value(); \
6075 int r3 = AS(VRR_C_Instruction)->R3Value(); \
6076 int m6 = AS(VRR_C_Instruction)->M6Value(); \
6077 int m5 = AS(VRR_C_Instruction)->M5Value(); \
6078 int m4 = AS(VRR_C_Instruction)->M4Value(); \
6079 int length = 6;
6080
6081 #define GET_ADDRESS(index_reg, base_reg, offset) \
6082 (((index_reg) == 0) ? 0 : get_register(index_reg)) + \
6083 (((base_reg) == 0) ? 0 : get_register(base_reg)) + offset
6084
Evaluate_Unknown(Instruction * instr)6085 int Simulator::Evaluate_Unknown(Instruction* instr) {
6086 UNREACHABLE();
6087 return 0;
6088 }
6089
EVALUATE(VFA)6090 EVALUATE(VFA) {
6091 DCHECK_OPCODE(VFA);
6092 DECODE_VRR_C_INSTRUCTION(r1, r2, r3, m6, m5, m4);
6093 USE(m6);
6094 USE(m5);
6095 USE(m4);
6096 DCHECK(m5 == 8);
6097 DCHECK(m4 == 3);
6098 double r2_val = get_double_from_d_register(r2);
6099 double r3_val = get_double_from_d_register(r3);
6100 double r1_val = r2_val + r3_val;
6101 set_d_register_from_double(r1, r1_val);
6102 return length;
6103 }
6104
EVALUATE(VFS)6105 EVALUATE(VFS) {
6106 DCHECK_OPCODE(VFS);
6107 DECODE_VRR_C_INSTRUCTION(r1, r2, r3, m6, m5, m4);
6108 USE(m6);
6109 USE(m5);
6110 USE(m4);
6111 DCHECK(m5 == 8);
6112 DCHECK(m4 == 3);
6113 double r2_val = get_double_from_d_register(r2);
6114 double r3_val = get_double_from_d_register(r3);
6115 double r1_val = r2_val - r3_val;
6116 set_d_register_from_double(r1, r1_val);
6117 return length;
6118 }
6119
EVALUATE(VFM)6120 EVALUATE(VFM) {
6121 DCHECK_OPCODE(VFM);
6122 DECODE_VRR_C_INSTRUCTION(r1, r2, r3, m6, m5, m4);
6123 USE(m6);
6124 USE(m5);
6125 USE(m4);
6126 DCHECK(m5 == 8);
6127 DCHECK(m4 == 3);
6128 double r2_val = get_double_from_d_register(r2);
6129 double r3_val = get_double_from_d_register(r3);
6130 double r1_val = r2_val * r3_val;
6131 set_d_register_from_double(r1, r1_val);
6132 return length;
6133 }
6134
EVALUATE(VFD)6135 EVALUATE(VFD) {
6136 DCHECK_OPCODE(VFD);
6137 DECODE_VRR_C_INSTRUCTION(r1, r2, r3, m6, m5, m4);
6138 USE(m6);
6139 USE(m5);
6140 USE(m4);
6141 DCHECK(m5 == 8);
6142 DCHECK(m4 == 3);
6143 double r2_val = get_double_from_d_register(r2);
6144 double r3_val = get_double_from_d_register(r3);
6145 double r1_val = r2_val / r3_val;
6146 set_d_register_from_double(r1, r1_val);
6147 return length;
6148 }
6149
EVALUATE(DUMY)6150 EVALUATE(DUMY) {
6151 DCHECK_OPCODE(DUMY);
6152 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
6153 USE(r1);
6154 USE(x2);
6155 USE(b2);
6156 USE(d2);
6157 // dummy instruction does nothing.
6158 return length;
6159 }
6160
EVALUATE(CLR)6161 EVALUATE(CLR) {
6162 DCHECK_OPCODE(CLR);
6163 DECODE_RR_INSTRUCTION(r1, r2);
6164 uint32_t r1_val = get_low_register<uint32_t>(r1);
6165 uint32_t r2_val = get_low_register<uint32_t>(r2);
6166 SetS390ConditionCode<uint32_t>(r1_val, r2_val);
6167 return length;
6168 }
6169
EVALUATE(LR)6170 EVALUATE(LR) {
6171 DCHECK_OPCODE(LR);
6172 DECODE_RR_INSTRUCTION(r1, r2);
6173 set_low_register(r1, get_low_register<int32_t>(r2));
6174 return length;
6175 }
6176
EVALUATE(AR)6177 EVALUATE(AR) {
6178 DCHECK_OPCODE(AR);
6179 DECODE_RR_INSTRUCTION(r1, r2);
6180 int32_t r1_val = get_low_register<int32_t>(r1);
6181 int32_t r2_val = get_low_register<int32_t>(r2);
6182 bool isOF = CheckOverflowForIntAdd(r1_val, r2_val, int32_t);
6183 r1_val += r2_val;
6184 SetS390ConditionCode<int32_t>(r1_val, 0);
6185 SetS390OverflowCode(isOF);
6186 set_low_register(r1, r1_val);
6187 return length;
6188 }
6189
EVALUATE(L)6190 EVALUATE(L) {
6191 DCHECK_OPCODE(L);
6192 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6193 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6194 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6195 intptr_t addr = b2_val + x2_val + d2_val;
6196 int32_t mem_val = ReadW(addr, instr);
6197 set_low_register(r1, mem_val);
6198 return length;
6199 }
6200
EVALUATE(BRC)6201 EVALUATE(BRC) {
6202 DCHECK_OPCODE(BRC);
6203 DECODE_RI_C_INSTRUCTION(instr, m1, i2);
6204
6205 if (TestConditionCode(m1)) {
6206 intptr_t offset = 2 * i2;
6207 set_pc(get_pc() + offset);
6208 }
6209 return length;
6210 }
6211
EVALUATE(AHI)6212 EVALUATE(AHI) {
6213 DCHECK_OPCODE(AHI);
6214 DECODE_RI_A_INSTRUCTION(instr, r1, i2);
6215 int32_t r1_val = get_low_register<int32_t>(r1);
6216 bool isOF = CheckOverflowForIntAdd(r1_val, i2, int32_t);
6217 r1_val += i2;
6218 set_low_register(r1, r1_val);
6219 SetS390ConditionCode<int32_t>(r1_val, 0);
6220 SetS390OverflowCode(isOF);
6221 return length;
6222 }
6223
EVALUATE(AGHI)6224 EVALUATE(AGHI) {
6225 DCHECK_OPCODE(AGHI);
6226 DECODE_RI_A_INSTRUCTION(instr, r1, i2);
6227 int64_t r1_val = get_register(r1);
6228 bool isOF = false;
6229 isOF = CheckOverflowForIntAdd(r1_val, i2, int64_t);
6230 r1_val += i2;
6231 set_register(r1, r1_val);
6232 SetS390ConditionCode<int64_t>(r1_val, 0);
6233 SetS390OverflowCode(isOF);
6234 return length;
6235 }
6236
EVALUATE(BRCL)6237 EVALUATE(BRCL) {
6238 DCHECK_OPCODE(BRCL);
6239 DECODE_RIL_C_INSTRUCTION(m1, ri2);
6240
6241 if (TestConditionCode(m1)) {
6242 intptr_t offset = 2 * ri2;
6243 set_pc(get_pc() + offset);
6244 }
6245 return length;
6246 }
6247
EVALUATE(IIHF)6248 EVALUATE(IIHF) {
6249 DCHECK_OPCODE(IIHF);
6250 DECODE_RIL_A_INSTRUCTION(r1, imm);
6251 set_high_register(r1, imm);
6252 return length;
6253 }
6254
EVALUATE(IILF)6255 EVALUATE(IILF) {
6256 DCHECK_OPCODE(IILF);
6257 DECODE_RIL_A_INSTRUCTION(r1, imm);
6258 set_low_register(r1, imm);
6259 return length;
6260 }
6261
EVALUATE(LGR)6262 EVALUATE(LGR) {
6263 DCHECK_OPCODE(LGR);
6264 DECODE_RRE_INSTRUCTION(r1, r2);
6265 set_register(r1, get_register(r2));
6266 return length;
6267 }
6268
EVALUATE(LG)6269 EVALUATE(LG) {
6270 DCHECK_OPCODE(LG);
6271 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
6272 intptr_t addr = GET_ADDRESS(x2, b2, d2);
6273 int64_t mem_val = ReadDW(addr);
6274 set_register(r1, mem_val);
6275 return length;
6276 }
6277
EVALUATE(AGR)6278 EVALUATE(AGR) {
6279 DCHECK_OPCODE(AGR);
6280 DECODE_RRE_INSTRUCTION(r1, r2);
6281 int64_t r1_val = get_register(r1);
6282 int64_t r2_val = get_register(r2);
6283 bool isOF = CheckOverflowForIntAdd(r1_val, r2_val, int64_t);
6284 r1_val += r2_val;
6285 set_register(r1, r1_val);
6286 SetS390ConditionCode<int64_t>(r1_val, 0);
6287 SetS390OverflowCode(isOF);
6288 return length;
6289 }
6290
EVALUATE(LGFR)6291 EVALUATE(LGFR) {
6292 DCHECK_OPCODE(LGFR);
6293 DECODE_RRE_INSTRUCTION(r1, r2);
6294 int32_t r2_val = get_low_register<int32_t>(r2);
6295 int64_t result = static_cast<int64_t>(r2_val);
6296 set_register(r1, result);
6297
6298 return length;
6299 }
6300
EVALUATE(LBR)6301 EVALUATE(LBR) {
6302 DCHECK_OPCODE(LBR);
6303 DECODE_RRE_INSTRUCTION(r1, r2);
6304 int32_t r2_val = get_low_register<int32_t>(r2);
6305 r2_val <<= 24;
6306 r2_val >>= 24;
6307 set_low_register(r1, r2_val);
6308 return length;
6309 }
6310
EVALUATE(LGBR)6311 EVALUATE(LGBR) {
6312 DCHECK_OPCODE(LGBR);
6313 DECODE_RRE_INSTRUCTION(r1, r2);
6314 int64_t r2_val = get_low_register<int64_t>(r2);
6315 r2_val <<= 56;
6316 r2_val >>= 56;
6317 set_register(r1, r2_val);
6318 return length;
6319 }
6320
EVALUATE(LHR)6321 EVALUATE(LHR) {
6322 DCHECK_OPCODE(LHR);
6323 DECODE_RRE_INSTRUCTION(r1, r2);
6324 int32_t r2_val = get_low_register<int32_t>(r2);
6325 r2_val <<= 16;
6326 r2_val >>= 16;
6327 set_low_register(r1, r2_val);
6328 return length;
6329 }
6330
EVALUATE(LGHR)6331 EVALUATE(LGHR) {
6332 DCHECK_OPCODE(LGHR);
6333 DECODE_RRE_INSTRUCTION(r1, r2);
6334 int64_t r2_val = get_low_register<int64_t>(r2);
6335 r2_val <<= 48;
6336 r2_val >>= 48;
6337 set_register(r1, r2_val);
6338 return length;
6339 }
6340
EVALUATE(LGF)6341 EVALUATE(LGF) {
6342 DCHECK_OPCODE(LGF);
6343 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
6344 intptr_t addr = GET_ADDRESS(x2, b2, d2);
6345 int64_t mem_val = static_cast<int64_t>(ReadW(addr, instr));
6346 set_register(r1, mem_val);
6347 return length;
6348 }
6349
EVALUATE(ST)6350 EVALUATE(ST) {
6351 DCHECK_OPCODE(ST);
6352 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6353 int32_t r1_val = get_low_register<int32_t>(r1);
6354 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6355 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6356 intptr_t addr = b2_val + x2_val + d2_val;
6357 WriteW(addr, r1_val, instr);
6358 return length;
6359 }
6360
EVALUATE(STG)6361 EVALUATE(STG) {
6362 DCHECK_OPCODE(STG);
6363 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
6364 intptr_t addr = GET_ADDRESS(x2, b2, d2);
6365 uint64_t value = get_register(r1);
6366 WriteDW(addr, value);
6367 return length;
6368 }
6369
EVALUATE(STY)6370 EVALUATE(STY) {
6371 DCHECK_OPCODE(STY);
6372 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
6373 intptr_t addr = GET_ADDRESS(x2, b2, d2);
6374 uint32_t value = get_low_register<uint32_t>(r1);
6375 WriteW(addr, value, instr);
6376 return length;
6377 }
6378
EVALUATE(LY)6379 EVALUATE(LY) {
6380 DCHECK_OPCODE(LY);
6381 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
6382 intptr_t addr = GET_ADDRESS(x2, b2, d2);
6383 uint32_t mem_val = ReadWU(addr, instr);
6384 set_low_register(r1, mem_val);
6385 return length;
6386 }
6387
EVALUATE(LLGC)6388 EVALUATE(LLGC) {
6389 DCHECK_OPCODE(LLGC);
6390 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
6391 uint8_t mem_val = ReadBU(GET_ADDRESS(x2, b2, d2));
6392 set_register(r1, static_cast<uint64_t>(mem_val));
6393 return length;
6394 }
6395
EVALUATE(LLC)6396 EVALUATE(LLC) {
6397 DCHECK_OPCODE(LLC);
6398 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
6399 uint8_t mem_val = ReadBU(GET_ADDRESS(x2, b2, d2));
6400 set_low_register(r1, static_cast<uint32_t>(mem_val));
6401 return length;
6402 }
6403
EVALUATE(RLL)6404 EVALUATE(RLL) {
6405 DCHECK_OPCODE(RLL);
6406 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
6407 // only takes rightmost 6 bits
6408 int shiftBits = GET_ADDRESS(0, b2, d2) & 0x3F;
6409 // unsigned
6410 uint32_t r3_val = get_low_register<uint32_t>(r3);
6411 uint32_t alu_out = 0;
6412 uint32_t rotateBits = r3_val >> (32 - shiftBits);
6413 alu_out = (r3_val << shiftBits) | (rotateBits);
6414 set_low_register(r1, alu_out);
6415 return length;
6416 }
6417
EVALUATE(RISBG)6418 EVALUATE(RISBG) {
6419 DCHECK_OPCODE(RISBG);
6420 DECODE_RIE_F_INSTRUCTION(r1, r2, i3, i4, i5);
6421 // Starting Bit Position is Bits 2-7 of I3 field
6422 uint32_t start_bit = i3 & 0x3F;
6423 // Ending Bit Position is Bits 2-7 of I4 field
6424 uint32_t end_bit = i4 & 0x3F;
6425 // Shift Amount is Bits 2-7 of I5 field
6426 uint32_t shift_amount = i5 & 0x3F;
6427 // Zero out Remaining (unslected) bits if Bit 0 of I4 is 1.
6428 bool zero_remaining = (0 != (i4 & 0x80));
6429
6430 uint64_t src_val = get_register(r2);
6431
6432 // Rotate Left by Shift Amount first
6433 uint64_t rotated_val =
6434 (src_val << shift_amount) | (src_val >> (64 - shift_amount));
6435 int32_t width = end_bit - start_bit + 1;
6436
6437 uint64_t selection_mask = 0;
6438 if (width < 64) {
6439 selection_mask = (static_cast<uint64_t>(1) << width) - 1;
6440 } else {
6441 selection_mask = static_cast<uint64_t>(static_cast<int64_t>(-1));
6442 }
6443 selection_mask = selection_mask << (63 - end_bit);
6444
6445 uint64_t selected_val = rotated_val & selection_mask;
6446
6447 if (!zero_remaining) {
6448 // Merged the unselected bits from the original value
6449 selected_val = (src_val & ~selection_mask) | selected_val;
6450 }
6451
6452 // Condition code is set by treating result as 64-bit signed int
6453 SetS390ConditionCode<int64_t>(selected_val, 0);
6454 set_register(r1, selected_val);
6455 return length;
6456 }
6457
EVALUATE(AHIK)6458 EVALUATE(AHIK) {
6459 DCHECK_OPCODE(AHIK);
6460 DECODE_RIE_D_INSTRUCTION(r1, r2, i2);
6461 int32_t r2_val = get_low_register<int32_t>(r2);
6462 int32_t imm = static_cast<int32_t>(i2);
6463 bool isOF = CheckOverflowForIntAdd(r2_val, imm, int32_t);
6464 set_low_register(r1, r2_val + imm);
6465 SetS390ConditionCode<int32_t>(r2_val + imm, 0);
6466 SetS390OverflowCode(isOF);
6467 return length;
6468 }
6469
EVALUATE(AGHIK)6470 EVALUATE(AGHIK) {
6471 // 64-bit Add
6472 DCHECK_OPCODE(AGHIK);
6473 DECODE_RIE_D_INSTRUCTION(r1, r2, i2);
6474 int64_t r2_val = get_register(r2);
6475 int64_t imm = static_cast<int64_t>(i2);
6476 bool isOF = CheckOverflowForIntAdd(r2_val, imm, int64_t);
6477 set_register(r1, r2_val + imm);
6478 SetS390ConditionCode<int64_t>(r2_val + imm, 0);
6479 SetS390OverflowCode(isOF);
6480 return length;
6481 }
6482
EVALUATE(BKPT)6483 EVALUATE(BKPT) {
6484 DCHECK_OPCODE(BKPT);
6485 set_pc(get_pc() + 2);
6486 S390Debugger dbg(this);
6487 dbg.Debug();
6488 int length = 2;
6489 return length;
6490 }
6491
EVALUATE(SPM)6492 EVALUATE(SPM) {
6493 UNIMPLEMENTED();
6494 USE(instr);
6495 return 0;
6496 }
6497
EVALUATE(BALR)6498 EVALUATE(BALR) {
6499 UNIMPLEMENTED();
6500 USE(instr);
6501 return 0;
6502 }
6503
EVALUATE(BCTR)6504 EVALUATE(BCTR) {
6505 UNIMPLEMENTED();
6506 USE(instr);
6507 return 0;
6508 }
6509
EVALUATE(BCR)6510 EVALUATE(BCR) {
6511 DCHECK_OPCODE(BCR);
6512 DECODE_RR_INSTRUCTION(r1, r2);
6513 if (TestConditionCode(Condition(r1))) {
6514 intptr_t r2_val = get_register(r2);
6515 #if (!V8_TARGET_ARCH_S390X && V8_HOST_ARCH_S390)
6516 // On 31-bit, the top most bit may be 0 or 1, but is ignored by the
6517 // hardware. Cleanse the top bit before jumping to it, unless it's one
6518 // of the special PCs
6519 if (r2_val != bad_lr && r2_val != end_sim_pc) r2_val &= 0x7FFFFFFF;
6520 #endif
6521 set_pc(r2_val);
6522 }
6523
6524 return length;
6525 }
6526
EVALUATE(SVC)6527 EVALUATE(SVC) {
6528 UNIMPLEMENTED();
6529 USE(instr);
6530 return 0;
6531 }
6532
EVALUATE(BSM)6533 EVALUATE(BSM) {
6534 UNIMPLEMENTED();
6535 USE(instr);
6536 return 0;
6537 }
6538
EVALUATE(BASSM)6539 EVALUATE(BASSM) {
6540 UNIMPLEMENTED();
6541 USE(instr);
6542 return 0;
6543 }
6544
EVALUATE(BASR)6545 EVALUATE(BASR) {
6546 DCHECK_OPCODE(BASR);
6547 DECODE_RR_INSTRUCTION(r1, r2);
6548 intptr_t link_addr = get_pc() + 2;
6549 // If R2 is zero, the BASR does not branch.
6550 int64_t r2_val = (r2 == 0) ? link_addr : get_register(r2);
6551 #if (!V8_TARGET_ARCH_S390X && V8_HOST_ARCH_S390)
6552 // On 31-bit, the top most bit may be 0 or 1, which can cause issues
6553 // for stackwalker. The top bit should either be cleanse before being
6554 // pushed onto the stack, or during stack walking when dereferenced.
6555 // For simulator, we'll take the worst case scenario and always tag
6556 // the high bit, to flush out more problems.
6557 link_addr |= 0x80000000;
6558 #endif
6559 set_register(r1, link_addr);
6560 set_pc(r2_val);
6561 return length;
6562 }
6563
EVALUATE(MVCL)6564 EVALUATE(MVCL) {
6565 UNIMPLEMENTED();
6566 USE(instr);
6567 return 0;
6568 }
6569
EVALUATE(CLCL)6570 EVALUATE(CLCL) {
6571 UNIMPLEMENTED();
6572 USE(instr);
6573 return 0;
6574 }
6575
EVALUATE(LPR)6576 EVALUATE(LPR) {
6577 DCHECK_OPCODE(LPR);
6578 // Load Positive (32)
6579 DECODE_RR_INSTRUCTION(r1, r2);
6580 int32_t r2_val = get_low_register<int32_t>(r2);
6581 // If negative, then negate it.
6582 r2_val = (r2_val < 0) ? -r2_val : r2_val;
6583 set_low_register(r1, r2_val);
6584 SetS390ConditionCode<int32_t>(r2_val, 0);
6585 if (r2_val == (static_cast<int32_t>(1) << 31)) {
6586 SetS390OverflowCode(true);
6587 }
6588 return length;
6589 }
6590
EVALUATE(LNR)6591 EVALUATE(LNR) {
6592 DCHECK_OPCODE(LNR);
6593 // Load Negative (32)
6594 DECODE_RR_INSTRUCTION(r1, r2);
6595 int32_t r2_val = get_low_register<int32_t>(r2);
6596 r2_val = (r2_val >= 0) ? -r2_val : r2_val; // If pos, then negate it.
6597 set_low_register(r1, r2_val);
6598 condition_reg_ = (r2_val == 0) ? CC_EQ : CC_LT; // CC0 - result is zero
6599 // CC1 - result is negative
6600 return length;
6601 }
6602
EVALUATE(LTR)6603 EVALUATE(LTR) {
6604 DCHECK_OPCODE(LTR);
6605 DECODE_RR_INSTRUCTION(r1, r2);
6606 int32_t r2_val = get_low_register<int32_t>(r2);
6607 SetS390ConditionCode<int32_t>(r2_val, 0);
6608 set_low_register(r1, r2_val);
6609 return length;
6610 }
6611
EVALUATE(LCR)6612 EVALUATE(LCR) {
6613 DCHECK_OPCODE(LCR);
6614 DECODE_RR_INSTRUCTION(r1, r2);
6615 int32_t r2_val = get_low_register<int32_t>(r2);
6616 int32_t result = 0;
6617 bool isOF = false;
6618 isOF = __builtin_ssub_overflow(0, r2_val, &result);
6619 set_low_register(r1, result);
6620 SetS390ConditionCode<int32_t>(r2_val, 0);
6621 // Checks for overflow where r2_val = -2147483648.
6622 // Cannot do int comparison due to GCC 4.8 bug on x86.
6623 // Detect INT_MIN alternatively, as it is the only value where both
6624 // original and result are negative due to overflow.
6625 if (isOF) {
6626 SetS390OverflowCode(true);
6627 }
6628 return length;
6629 }
6630
EVALUATE(NR)6631 EVALUATE(NR) {
6632 DCHECK_OPCODE(NR);
6633 DECODE_RR_INSTRUCTION(r1, r2);
6634 int32_t r1_val = get_low_register<int32_t>(r1);
6635 int32_t r2_val = get_low_register<int32_t>(r2);
6636 r1_val &= r2_val;
6637 SetS390BitWiseConditionCode<uint32_t>(r1_val);
6638 set_low_register(r1, r1_val);
6639 return length;
6640 }
6641
EVALUATE(OR)6642 EVALUATE(OR) {
6643 DCHECK_OPCODE(OR);
6644 DECODE_RR_INSTRUCTION(r1, r2);
6645 int32_t r1_val = get_low_register<int32_t>(r1);
6646 int32_t r2_val = get_low_register<int32_t>(r2);
6647 r1_val |= r2_val;
6648 SetS390BitWiseConditionCode<uint32_t>(r1_val);
6649 set_low_register(r1, r1_val);
6650 return length;
6651 }
6652
EVALUATE(XR)6653 EVALUATE(XR) {
6654 DCHECK_OPCODE(XR);
6655 DECODE_RR_INSTRUCTION(r1, r2);
6656 int32_t r1_val = get_low_register<int32_t>(r1);
6657 int32_t r2_val = get_low_register<int32_t>(r2);
6658 r1_val ^= r2_val;
6659 SetS390BitWiseConditionCode<uint32_t>(r1_val);
6660 set_low_register(r1, r1_val);
6661 return length;
6662 }
6663
EVALUATE(CR)6664 EVALUATE(CR) {
6665 DCHECK_OPCODE(CR);
6666 DECODE_RR_INSTRUCTION(r1, r2);
6667 int32_t r1_val = get_low_register<int32_t>(r1);
6668 int32_t r2_val = get_low_register<int32_t>(r2);
6669 SetS390ConditionCode<int32_t>(r1_val, r2_val);
6670 return length;
6671 }
6672
EVALUATE(SR)6673 EVALUATE(SR) {
6674 DCHECK_OPCODE(SR);
6675 DECODE_RR_INSTRUCTION(r1, r2);
6676 int32_t r1_val = get_low_register<int32_t>(r1);
6677 int32_t r2_val = get_low_register<int32_t>(r2);
6678 bool isOF = false;
6679 isOF = CheckOverflowForIntSub(r1_val, r2_val, int32_t);
6680 r1_val -= r2_val;
6681 SetS390ConditionCode<int32_t>(r1_val, 0);
6682 SetS390OverflowCode(isOF);
6683 set_low_register(r1, r1_val);
6684 return length;
6685 }
6686
EVALUATE(MR)6687 EVALUATE(MR) {
6688 DCHECK_OPCODE(MR);
6689 DECODE_RR_INSTRUCTION(r1, r2);
6690 int32_t r1_val = get_low_register<int32_t>(r1);
6691 int32_t r2_val = get_low_register<int32_t>(r2);
6692 DCHECK(r1 % 2 == 0);
6693 r1_val = get_low_register<int32_t>(r1 + 1);
6694 int64_t product = static_cast<int64_t>(r1_val) * static_cast<int64_t>(r2_val);
6695 int32_t high_bits = product >> 32;
6696 r1_val = high_bits;
6697 int32_t low_bits = product & 0x00000000FFFFFFFF;
6698 set_low_register(r1, high_bits);
6699 set_low_register(r1 + 1, low_bits);
6700 return length;
6701 }
6702
EVALUATE(DR)6703 EVALUATE(DR) {
6704 DCHECK_OPCODE(DR);
6705 DECODE_RR_INSTRUCTION(r1, r2);
6706 int32_t r1_val = get_low_register<int32_t>(r1);
6707 int32_t r2_val = get_low_register<int32_t>(r2);
6708 // reg-reg pair should be even-odd pair, assert r1 is an even register
6709 DCHECK(r1 % 2 == 0);
6710 // leftmost 32 bits of the dividend are in r1
6711 // rightmost 32 bits of the dividend are in r1+1
6712 // get the signed value from r1
6713 int64_t dividend = static_cast<int64_t>(r1_val) << 32;
6714 // get unsigned value from r1+1
6715 // avoid addition with sign-extended r1+1 value
6716 dividend += get_low_register<uint32_t>(r1 + 1);
6717 int32_t remainder = dividend % r2_val;
6718 int32_t quotient = dividend / r2_val;
6719 r1_val = remainder;
6720 set_low_register(r1, remainder);
6721 set_low_register(r1 + 1, quotient);
6722 set_low_register(r1, r1_val);
6723 return length;
6724 }
6725
EVALUATE(ALR)6726 EVALUATE(ALR) {
6727 DCHECK_OPCODE(ALR);
6728 DECODE_RR_INSTRUCTION(r1, r2);
6729 uint32_t r1_val = get_low_register<uint32_t>(r1);
6730 uint32_t r2_val = get_low_register<uint32_t>(r2);
6731 uint32_t alu_out = 0;
6732 bool isOF = false;
6733 alu_out = r1_val + r2_val;
6734 isOF = CheckOverflowForUIntAdd(r1_val, r2_val);
6735 set_low_register(r1, alu_out);
6736 SetS390ConditionCodeCarry<uint32_t>(alu_out, isOF);
6737 return length;
6738 }
6739
EVALUATE(SLR)6740 EVALUATE(SLR) {
6741 DCHECK_OPCODE(SLR);
6742 DECODE_RR_INSTRUCTION(r1, r2);
6743 uint32_t r1_val = get_low_register<uint32_t>(r1);
6744 uint32_t r2_val = get_low_register<uint32_t>(r2);
6745 uint32_t alu_out = 0;
6746 bool isOF = false;
6747 alu_out = r1_val - r2_val;
6748 isOF = CheckOverflowForUIntSub(r1_val, r2_val);
6749 set_low_register(r1, alu_out);
6750 SetS390ConditionCodeCarry<uint32_t>(alu_out, isOF);
6751 return length;
6752 }
6753
EVALUATE(LDR)6754 EVALUATE(LDR) {
6755 DCHECK_OPCODE(LDR);
6756 DECODE_RR_INSTRUCTION(r1, r2);
6757 int64_t r2_val = get_d_register(r2);
6758 set_d_register(r1, r2_val);
6759 return length;
6760 }
6761
EVALUATE(CDR)6762 EVALUATE(CDR) {
6763 UNIMPLEMENTED();
6764 USE(instr);
6765 return 0;
6766 }
6767
EVALUATE(LER)6768 EVALUATE(LER) {
6769 UNIMPLEMENTED();
6770 USE(instr);
6771 return 0;
6772 }
6773
EVALUATE(STH)6774 EVALUATE(STH) {
6775 DCHECK_OPCODE(STH);
6776 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6777 int16_t r1_val = get_low_register<int32_t>(r1);
6778 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6779 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6780 intptr_t mem_addr = b2_val + x2_val + d2_val;
6781 WriteH(mem_addr, r1_val, instr);
6782
6783 return length;
6784 }
6785
EVALUATE(LA)6786 EVALUATE(LA) {
6787 DCHECK_OPCODE(LA);
6788 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6789 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6790 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6791 intptr_t addr = b2_val + x2_val + d2_val;
6792 set_register(r1, addr);
6793 return length;
6794 }
6795
EVALUATE(STC)6796 EVALUATE(STC) {
6797 DCHECK_OPCODE(STC);
6798 // Store Character/Byte
6799 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6800 uint8_t r1_val = get_low_register<int32_t>(r1);
6801 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6802 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6803 intptr_t mem_addr = b2_val + x2_val + d2_val;
6804 WriteB(mem_addr, r1_val);
6805 return length;
6806 }
6807
EVALUATE(IC_z)6808 EVALUATE(IC_z) {
6809 UNIMPLEMENTED();
6810 USE(instr);
6811 return 0;
6812 }
6813
EVALUATE(EX)6814 EVALUATE(EX) {
6815 DCHECK_OPCODE(EX);
6816 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6817 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6818 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6819 int32_t r1_val = get_low_register<int32_t>(r1);
6820
6821 SixByteInstr the_instr = Instruction::InstructionBits(
6822 reinterpret_cast<const byte*>(b2_val + x2_val + d2_val));
6823 int inst_length = Instruction::InstructionLength(
6824 reinterpret_cast<const byte*>(b2_val + x2_val + d2_val));
6825
6826 char new_instr_buf[8];
6827 char* addr = reinterpret_cast<char*>(&new_instr_buf[0]);
6828 the_instr |= static_cast<SixByteInstr>(r1_val & 0xff)
6829 << (8 * inst_length - 16);
6830 Instruction::SetInstructionBits<SixByteInstr>(
6831 reinterpret_cast<byte*>(addr), static_cast<SixByteInstr>(the_instr));
6832 ExecuteInstruction(reinterpret_cast<Instruction*>(addr), false);
6833 return length;
6834 }
6835
EVALUATE(BAL)6836 EVALUATE(BAL) {
6837 UNIMPLEMENTED();
6838 USE(instr);
6839 return 0;
6840 }
6841
EVALUATE(BCT)6842 EVALUATE(BCT) {
6843 UNIMPLEMENTED();
6844 USE(instr);
6845 return 0;
6846 }
6847
EVALUATE(BC)6848 EVALUATE(BC) {
6849 UNIMPLEMENTED();
6850 USE(instr);
6851 return 0;
6852 }
6853
EVALUATE(LH)6854 EVALUATE(LH) {
6855 DCHECK_OPCODE(LH);
6856 // Load Halfword
6857 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6858
6859 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6860 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6861 intptr_t mem_addr = x2_val + b2_val + d2_val;
6862
6863 int32_t result = static_cast<int32_t>(ReadH(mem_addr, instr));
6864 set_low_register(r1, result);
6865 return length;
6866 }
6867
EVALUATE(CH)6868 EVALUATE(CH) {
6869 UNIMPLEMENTED();
6870 USE(instr);
6871 return 0;
6872 }
6873
EVALUATE(AH)6874 EVALUATE(AH) {
6875 DCHECK_OPCODE(AH);
6876 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6877 int32_t r1_val = get_low_register<int32_t>(r1);
6878 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6879 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6880 intptr_t addr = b2_val + x2_val + d2_val;
6881 int32_t mem_val = static_cast<int32_t>(ReadH(addr, instr));
6882 int32_t alu_out = 0;
6883 bool isOF = false;
6884 isOF = CheckOverflowForIntAdd(r1_val, mem_val, int32_t);
6885 alu_out = r1_val + mem_val;
6886 set_low_register(r1, alu_out);
6887 SetS390ConditionCode<int32_t>(alu_out, 0);
6888 SetS390OverflowCode(isOF);
6889
6890 return length;
6891 }
6892
EVALUATE(SH)6893 EVALUATE(SH) {
6894 DCHECK_OPCODE(SH);
6895 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6896 int32_t r1_val = get_low_register<int32_t>(r1);
6897 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6898 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6899 intptr_t addr = b2_val + x2_val + d2_val;
6900 int32_t mem_val = static_cast<int32_t>(ReadH(addr, instr));
6901 int32_t alu_out = 0;
6902 bool isOF = false;
6903 isOF = CheckOverflowForIntSub(r1_val, mem_val, int32_t);
6904 alu_out = r1_val - mem_val;
6905 SetS390ConditionCode<int32_t>(alu_out, 0);
6906 SetS390OverflowCode(isOF);
6907
6908 return length;
6909 }
6910
EVALUATE(MH)6911 EVALUATE(MH) {
6912 DCHECK_OPCODE(MH);
6913 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6914 int32_t r1_val = get_low_register<int32_t>(r1);
6915 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6916 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6917 intptr_t addr = b2_val + x2_val + d2_val;
6918 int32_t mem_val = static_cast<int32_t>(ReadH(addr, instr));
6919 int32_t alu_out = 0;
6920 alu_out = r1_val * mem_val;
6921 set_low_register(r1, alu_out);
6922 return length;
6923 }
6924
EVALUATE(BAS)6925 EVALUATE(BAS) {
6926 UNIMPLEMENTED();
6927 USE(instr);
6928 return 0;
6929 }
6930
EVALUATE(CVD)6931 EVALUATE(CVD) {
6932 UNIMPLEMENTED();
6933 USE(instr);
6934 return 0;
6935 }
6936
EVALUATE(CVB)6937 EVALUATE(CVB) {
6938 UNIMPLEMENTED();
6939 USE(instr);
6940 return 0;
6941 }
6942
EVALUATE(LAE)6943 EVALUATE(LAE) {
6944 UNIMPLEMENTED();
6945 USE(instr);
6946 return 0;
6947 }
6948
EVALUATE(N)6949 EVALUATE(N) {
6950 DCHECK_OPCODE(N);
6951 // 32-bit Reg-Mem instructions
6952 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6953 int32_t r1_val = get_low_register<int32_t>(r1);
6954 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6955 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6956 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr);
6957 int32_t alu_out = 0;
6958 alu_out = r1_val & mem_val;
6959 SetS390BitWiseConditionCode<uint32_t>(alu_out);
6960 set_low_register(r1, alu_out);
6961 return length;
6962 }
6963
EVALUATE(CL)6964 EVALUATE(CL) {
6965 DCHECK_OPCODE(CL);
6966 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6967 int32_t r1_val = get_low_register<int32_t>(r1);
6968 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6969 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6970 intptr_t addr = b2_val + x2_val + d2_val;
6971 int32_t mem_val = ReadW(addr, instr);
6972 SetS390ConditionCode<uint32_t>(r1_val, mem_val);
6973 return length;
6974 }
6975
EVALUATE(O)6976 EVALUATE(O) {
6977 DCHECK_OPCODE(O);
6978 // 32-bit Reg-Mem instructions
6979 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6980 int32_t r1_val = get_low_register<int32_t>(r1);
6981 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6982 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6983 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr);
6984 int32_t alu_out = 0;
6985 alu_out = r1_val | mem_val;
6986 SetS390BitWiseConditionCode<uint32_t>(alu_out);
6987 set_low_register(r1, alu_out);
6988 return length;
6989 }
6990
EVALUATE(X)6991 EVALUATE(X) {
6992 DCHECK_OPCODE(X);
6993 // 32-bit Reg-Mem instructions
6994 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6995 int32_t r1_val = get_low_register<int32_t>(r1);
6996 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6997 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6998 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr);
6999 int32_t alu_out = 0;
7000 alu_out = r1_val ^ mem_val;
7001 SetS390BitWiseConditionCode<uint32_t>(alu_out);
7002 set_low_register(r1, alu_out);
7003 return length;
7004 }
7005
EVALUATE(C)7006 EVALUATE(C) {
7007 DCHECK_OPCODE(C);
7008 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
7009 int32_t r1_val = get_low_register<int32_t>(r1);
7010 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
7011 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
7012 intptr_t addr = b2_val + x2_val + d2_val;
7013 int32_t mem_val = ReadW(addr, instr);
7014 SetS390ConditionCode<int32_t>(r1_val, mem_val);
7015 return length;
7016 }
7017
EVALUATE(A)7018 EVALUATE(A) {
7019 DCHECK_OPCODE(A);
7020 // 32-bit Reg-Mem instructions
7021 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
7022 int32_t r1_val = get_low_register<int32_t>(r1);
7023 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
7024 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
7025 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr);
7026 int32_t alu_out = 0;
7027 bool isOF = false;
7028 isOF = CheckOverflowForIntAdd(r1_val, mem_val, int32_t);
7029 alu_out = r1_val + mem_val;
7030 SetS390ConditionCode<int32_t>(alu_out, 0);
7031 SetS390OverflowCode(isOF);
7032 set_low_register(r1, alu_out);
7033 return length;
7034 }
7035
EVALUATE(S)7036 EVALUATE(S) {
7037 DCHECK_OPCODE(S);
7038 // 32-bit Reg-Mem instructions
7039 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
7040 int32_t r1_val = get_low_register<int32_t>(r1);
7041 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
7042 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
7043 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr);
7044 int32_t alu_out = 0;
7045 bool isOF = false;
7046 isOF = CheckOverflowForIntSub(r1_val, mem_val, int32_t);
7047 alu_out = r1_val - mem_val;
7048 SetS390ConditionCode<int32_t>(alu_out, 0);
7049 SetS390OverflowCode(isOF);
7050 set_low_register(r1, alu_out);
7051 return length;
7052 }
7053
EVALUATE(M)7054 EVALUATE(M) {
7055 DCHECK_OPCODE(M);
7056 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
7057 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
7058 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
7059 intptr_t addr = b2_val + x2_val + d2_val;
7060 DCHECK(r1 % 2 == 0);
7061 int32_t mem_val = ReadW(addr, instr);
7062 int32_t r1_val = get_low_register<int32_t>(r1 + 1);
7063 int64_t product =
7064 static_cast<int64_t>(r1_val) * static_cast<int64_t>(mem_val);
7065 int32_t high_bits = product >> 32;
7066 r1_val = high_bits;
7067 int32_t low_bits = product & 0x00000000FFFFFFFF;
7068 set_low_register(r1, high_bits);
7069 set_low_register(r1 + 1, low_bits);
7070 return length;
7071 }
7072
EVALUATE(D)7073 EVALUATE(D) {
7074 UNIMPLEMENTED();
7075 USE(instr);
7076 return 0;
7077 }
7078
EVALUATE(AL)7079 EVALUATE(AL) {
7080 UNIMPLEMENTED();
7081 USE(instr);
7082 return 0;
7083 }
7084
EVALUATE(SL)7085 EVALUATE(SL) {
7086 UNIMPLEMENTED();
7087 USE(instr);
7088 return 0;
7089 }
7090
EVALUATE(STD)7091 EVALUATE(STD) {
7092 DCHECK_OPCODE(STD);
7093 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
7094 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
7095 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
7096 intptr_t addr = b2_val + x2_val + d2_val;
7097 int64_t frs_val = get_d_register(r1);
7098 WriteDW(addr, frs_val);
7099 return length;
7100 }
7101
EVALUATE(LD)7102 EVALUATE(LD) {
7103 DCHECK_OPCODE(LD);
7104 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
7105 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
7106 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
7107 intptr_t addr = b2_val + x2_val + d2_val;
7108 int64_t dbl_val = *reinterpret_cast<int64_t*>(addr);
7109 set_d_register(r1, dbl_val);
7110 return length;
7111 }
7112
EVALUATE(CD)7113 EVALUATE(CD) {
7114 UNIMPLEMENTED();
7115 USE(instr);
7116 return 0;
7117 }
7118
EVALUATE(STE)7119 EVALUATE(STE) {
7120 DCHECK_OPCODE(STE);
7121 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
7122 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
7123 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
7124 intptr_t addr = b2_val + x2_val + d2_val;
7125 int64_t frs_val = get_d_register(r1) >> 32;
7126 WriteW(addr, static_cast<int32_t>(frs_val), instr);
7127 return length;
7128 }
7129
EVALUATE(MS)7130 EVALUATE(MS) {
7131 DCHECK_OPCODE(MS);
7132 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
7133 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
7134 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
7135 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr);
7136 int32_t r1_val = get_low_register<int32_t>(r1);
7137 set_low_register(r1, r1_val * mem_val);
7138 return length;
7139 }
7140
EVALUATE(LE)7141 EVALUATE(LE) {
7142 DCHECK_OPCODE(LE);
7143 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
7144 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
7145 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
7146 intptr_t addr = b2_val + x2_val + d2_val;
7147 float float_val = *reinterpret_cast<float*>(addr);
7148 set_d_register_from_float32(r1, float_val);
7149 return length;
7150 }
7151
EVALUATE(BRXH)7152 EVALUATE(BRXH) {
7153 UNIMPLEMENTED();
7154 USE(instr);
7155 return 0;
7156 }
7157
EVALUATE(BRXLE)7158 EVALUATE(BRXLE) {
7159 UNIMPLEMENTED();
7160 USE(instr);
7161 return 0;
7162 }
7163
EVALUATE(BXH)7164 EVALUATE(BXH) {
7165 DCHECK_OPCODE(BXH);
7166 DECODE_RS_A_INSTRUCTION(r1, r3, b2, d2);
7167
7168 // r1_val is the first operand, r3_val is the increment
7169 int32_t r1_val = r1 == 0 ? 0 : get_register(r1);
7170 int32_t r3_val = r2 == 0 ? 0 : get_register(r3);
7171 intptr_t b2_val = b2 == 0 ? 0 : get_register(b2);
7172 intptr_t branch_address = b2_val + d2;
7173 // increment r1_val
7174 r1_val += r3_val;
7175
7176 // if the increment is even, then it designates a pair of registers
7177 // and the contents of the even and odd registers of the pair are used as
7178 // the increment and compare value respectively. If the increment is odd,
7179 // the increment itself is used as both the increment and compare value
7180 int32_t compare_val = r3 % 2 == 0 ? get_register(r3 + 1) : r3_val;
7181 if (r1_val > compare_val) {
7182 // branch to address if r1_val is greater than compare value
7183 set_pc(branch_address);
7184 }
7185
7186 // update contents of register in r1 with the new incremented value
7187 set_register(r1, r1_val);
7188
7189 return length;
7190 }
7191
EVALUATE(BXLE)7192 EVALUATE(BXLE) {
7193 UNIMPLEMENTED();
7194 USE(instr);
7195 return 0;
7196 }
7197
EVALUATE(SRL)7198 EVALUATE(SRL) {
7199 DCHECK_OPCODE(SRL);
7200 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2);
7201 // only takes rightmost 6bits
7202 int64_t b2_val = b2 == 0 ? 0 : get_register(b2);
7203 int shiftBits = (b2_val + d2) & 0x3F;
7204 uint32_t r1_val = get_low_register<uint32_t>(r1);
7205 uint32_t alu_out = 0;
7206 alu_out = r1_val >> shiftBits;
7207 set_low_register(r1, alu_out);
7208 return length;
7209 }
7210
EVALUATE(SLL)7211 EVALUATE(SLL) {
7212 DCHECK_OPCODE(SLL);
7213 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2)
7214 // only takes rightmost 6bits
7215 int64_t b2_val = b2 == 0 ? 0 : get_register(b2);
7216 int shiftBits = (b2_val + d2) & 0x3F;
7217 uint32_t r1_val = get_low_register<uint32_t>(r1);
7218 uint32_t alu_out = 0;
7219 alu_out = r1_val << shiftBits;
7220 set_low_register(r1, alu_out);
7221 return length;
7222 }
7223
EVALUATE(SRA)7224 EVALUATE(SRA) {
7225 DCHECK_OPCODE(SRA);
7226 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2);
7227 // only takes rightmost 6bits
7228 int64_t b2_val = b2 == 0 ? 0 : get_register(b2);
7229 int shiftBits = (b2_val + d2) & 0x3F;
7230 int32_t r1_val = get_low_register<int32_t>(r1);
7231 int32_t alu_out = 0;
7232 bool isOF = false;
7233 alu_out = r1_val >> shiftBits;
7234 set_low_register(r1, alu_out);
7235 SetS390ConditionCode<int32_t>(alu_out, 0);
7236 SetS390OverflowCode(isOF);
7237 return length;
7238 }
7239
EVALUATE(SLA)7240 EVALUATE(SLA) {
7241 DCHECK_OPCODE(SLA);
7242 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2);
7243 // only takes rightmost 6bits
7244 int64_t b2_val = b2 == 0 ? 0 : get_register(b2);
7245 int shiftBits = (b2_val + d2) & 0x3F;
7246 int32_t r1_val = get_low_register<int32_t>(r1);
7247 int32_t alu_out = 0;
7248 bool isOF = false;
7249 isOF = CheckOverflowForShiftLeft(r1_val, shiftBits);
7250 alu_out = r1_val << shiftBits;
7251 set_low_register(r1, alu_out);
7252 SetS390ConditionCode<int32_t>(alu_out, 0);
7253 SetS390OverflowCode(isOF);
7254 return length;
7255 }
7256
EVALUATE(SRDL)7257 EVALUATE(SRDL) {
7258 DCHECK_OPCODE(SRDL);
7259 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2);
7260 DCHECK(r1 % 2 == 0); // must be a reg pair
7261 // only takes rightmost 6bits
7262 int64_t b2_val = b2 == 0 ? 0 : get_register(b2);
7263 int shiftBits = (b2_val + d2) & 0x3F;
7264 uint64_t opnd1 = static_cast<uint64_t>(get_low_register<uint32_t>(r1)) << 32;
7265 uint64_t opnd2 = static_cast<uint64_t>(get_low_register<uint32_t>(r1 + 1));
7266 uint64_t r1_val = opnd1 | opnd2;
7267 uint64_t alu_out = r1_val >> shiftBits;
7268 set_low_register(r1, alu_out >> 32);
7269 set_low_register(r1 + 1, alu_out & 0x00000000FFFFFFFF);
7270 SetS390ConditionCode<int32_t>(alu_out, 0);
7271 return length;
7272 }
7273
EVALUATE(SLDL)7274 EVALUATE(SLDL) {
7275 DCHECK_OPCODE(SLDL);
7276 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2);
7277 // only takes rightmost 6bits
7278 int64_t b2_val = b2 == 0 ? 0 : get_register(b2);
7279 int shiftBits = (b2_val + d2) & 0x3F;
7280
7281 DCHECK(r1 % 2 == 0);
7282 uint32_t r1_val = get_low_register<uint32_t>(r1);
7283 uint32_t r1_next_val = get_low_register<uint32_t>(r1 + 1);
7284 uint64_t alu_out = (static_cast<uint64_t>(r1_val) << 32) |
7285 (static_cast<uint64_t>(r1_next_val));
7286 alu_out <<= shiftBits;
7287 set_low_register(r1 + 1, static_cast<uint32_t>(alu_out));
7288 set_low_register(r1, static_cast<uint32_t>(alu_out >> 32));
7289 return length;
7290 }
7291
EVALUATE(SRDA)7292 EVALUATE(SRDA) {
7293 DCHECK_OPCODE(SRDA);
7294 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2);
7295 DCHECK(r1 % 2 == 0); // must be a reg pair
7296 // only takes rightmost 6bits
7297 int64_t b2_val = b2 == 0 ? 0 : get_register(b2);
7298 int shiftBits = (b2_val + d2) & 0x3F;
7299 int64_t opnd1 = static_cast<int64_t>(get_low_register<int32_t>(r1)) << 32;
7300 int64_t opnd2 = static_cast<uint64_t>(get_low_register<uint32_t>(r1 + 1));
7301 int64_t r1_val = opnd1 + opnd2;
7302 int64_t alu_out = r1_val >> shiftBits;
7303 set_low_register(r1, alu_out >> 32);
7304 set_low_register(r1 + 1, alu_out & 0x00000000FFFFFFFF);
7305 SetS390ConditionCode<int32_t>(alu_out, 0);
7306 return length;
7307 }
7308
EVALUATE(SLDA)7309 EVALUATE(SLDA) {
7310 UNIMPLEMENTED();
7311 USE(instr);
7312 return 0;
7313 }
7314
EVALUATE(STM)7315 EVALUATE(STM) {
7316 DCHECK_OPCODE(STM);
7317 DECODE_RS_A_INSTRUCTION(r1, r3, rb, d2);
7318 // Store Multiple 32-bits.
7319 int offset = d2;
7320 // Regs roll around if r3 is less than r1.
7321 // Artifically increase r3 by 16 so we can calculate
7322 // the number of regs stored properly.
7323 if (r3 < r1) r3 += 16;
7324
7325 int32_t rb_val = (rb == 0) ? 0 : get_low_register<int32_t>(rb);
7326
7327 // Store each register in ascending order.
7328 for (int i = 0; i <= r3 - r1; i++) {
7329 int32_t value = get_low_register<int32_t>((r1 + i) % 16);
7330 WriteW(rb_val + offset + 4 * i, value, instr);
7331 }
7332 return length;
7333 }
7334
EVALUATE(TM)7335 EVALUATE(TM) {
7336 DCHECK_OPCODE(TM);
7337 // Test Under Mask (Mem - Imm) (8)
7338 DECODE_SI_INSTRUCTION_I_UINT8(b1, d1_val, imm_val)
7339 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
7340 intptr_t addr = b1_val + d1_val;
7341 uint8_t mem_val = ReadB(addr);
7342 uint8_t selected_bits = mem_val & imm_val;
7343 // CC0: Selected bits are zero
7344 // CC1: Selected bits mixed zeros and ones
7345 // CC3: Selected bits all ones
7346 if (0 == selected_bits) {
7347 condition_reg_ = CC_EQ; // CC0
7348 } else if (selected_bits == imm_val) {
7349 condition_reg_ = 0x1; // CC3
7350 } else {
7351 condition_reg_ = 0x4; // CC1
7352 }
7353 return length;
7354 }
7355
EVALUATE(MVI)7356 EVALUATE(MVI) {
7357 UNIMPLEMENTED();
7358 USE(instr);
7359 return 0;
7360 }
7361
EVALUATE(TS)7362 EVALUATE(TS) {
7363 UNIMPLEMENTED();
7364 USE(instr);
7365 return 0;
7366 }
7367
EVALUATE(NI)7368 EVALUATE(NI) {
7369 UNIMPLEMENTED();
7370 USE(instr);
7371 return 0;
7372 }
7373
EVALUATE(CLI)7374 EVALUATE(CLI) {
7375 DCHECK_OPCODE(CLI);
7376 // Compare Immediate (Mem - Imm) (8)
7377 DECODE_SI_INSTRUCTION_I_UINT8(b1, d1_val, imm_val)
7378 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
7379 intptr_t addr = b1_val + d1_val;
7380 uint8_t mem_val = ReadB(addr);
7381 SetS390ConditionCode<uint8_t>(mem_val, imm_val);
7382 return length;
7383 }
7384
EVALUATE(OI)7385 EVALUATE(OI) {
7386 UNIMPLEMENTED();
7387 USE(instr);
7388 return 0;
7389 }
7390
EVALUATE(XI)7391 EVALUATE(XI) {
7392 UNIMPLEMENTED();
7393 USE(instr);
7394 return 0;
7395 }
7396
EVALUATE(LM)7397 EVALUATE(LM) {
7398 DCHECK_OPCODE(LM);
7399 DECODE_RS_A_INSTRUCTION(r1, r3, rb, d2);
7400 // Store Multiple 32-bits.
7401 int offset = d2;
7402 // Regs roll around if r3 is less than r1.
7403 // Artifically increase r3 by 16 so we can calculate
7404 // the number of regs stored properly.
7405 if (r3 < r1) r3 += 16;
7406
7407 int32_t rb_val = (rb == 0) ? 0 : get_low_register<int32_t>(rb);
7408
7409 // Store each register in ascending order.
7410 for (int i = 0; i <= r3 - r1; i++) {
7411 int32_t value = ReadW(rb_val + offset + 4 * i, instr);
7412 set_low_register((r1 + i) % 16, value);
7413 }
7414 return length;
7415 }
7416
EVALUATE(MVCLE)7417 EVALUATE(MVCLE) {
7418 UNIMPLEMENTED();
7419 USE(instr);
7420 return 0;
7421 }
7422
EVALUATE(CLCLE)7423 EVALUATE(CLCLE) {
7424 UNIMPLEMENTED();
7425 USE(instr);
7426 return 0;
7427 }
7428
EVALUATE(MC)7429 EVALUATE(MC) {
7430 UNIMPLEMENTED();
7431 USE(instr);
7432 return 0;
7433 }
7434
EVALUATE(CDS)7435 EVALUATE(CDS) {
7436 UNIMPLEMENTED();
7437 USE(instr);
7438 return 0;
7439 }
7440
EVALUATE(STCM)7441 EVALUATE(STCM) {
7442 UNIMPLEMENTED();
7443 USE(instr);
7444 return 0;
7445 }
7446
EVALUATE(ICM)7447 EVALUATE(ICM) {
7448 UNIMPLEMENTED();
7449 USE(instr);
7450 return 0;
7451 }
7452
EVALUATE(BPRP)7453 EVALUATE(BPRP) {
7454 UNIMPLEMENTED();
7455 USE(instr);
7456 return 0;
7457 }
7458
EVALUATE(BPP)7459 EVALUATE(BPP) {
7460 UNIMPLEMENTED();
7461 USE(instr);
7462 return 0;
7463 }
7464
EVALUATE(TRTR)7465 EVALUATE(TRTR) {
7466 UNIMPLEMENTED();
7467 USE(instr);
7468 return 0;
7469 }
7470
EVALUATE(MVN)7471 EVALUATE(MVN) {
7472 UNIMPLEMENTED();
7473 USE(instr);
7474 return 0;
7475 }
7476
EVALUATE(MVC)7477 EVALUATE(MVC) {
7478 DCHECK_OPCODE(MVC);
7479 // Move Character
7480 SSInstruction* ssInstr = reinterpret_cast<SSInstruction*>(instr);
7481 int b1 = ssInstr->B1Value();
7482 intptr_t d1 = ssInstr->D1Value();
7483 int b2 = ssInstr->B2Value();
7484 intptr_t d2 = ssInstr->D2Value();
7485 int length = ssInstr->Length();
7486 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
7487 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
7488 intptr_t src_addr = b2_val + d2;
7489 intptr_t dst_addr = b1_val + d1;
7490 // remember that the length is the actual length - 1
7491 for (int i = 0; i < length + 1; ++i) {
7492 WriteB(dst_addr++, ReadB(src_addr++));
7493 }
7494 length = 6;
7495 return length;
7496 }
7497
EVALUATE(MVZ)7498 EVALUATE(MVZ) {
7499 UNIMPLEMENTED();
7500 USE(instr);
7501 return 0;
7502 }
7503
EVALUATE(NC)7504 EVALUATE(NC) {
7505 UNIMPLEMENTED();
7506 USE(instr);
7507 return 0;
7508 }
7509
EVALUATE(CLC)7510 EVALUATE(CLC) {
7511 UNIMPLEMENTED();
7512 USE(instr);
7513 return 0;
7514 }
7515
EVALUATE(OC)7516 EVALUATE(OC) {
7517 UNIMPLEMENTED();
7518 USE(instr);
7519 return 0;
7520 }
7521
EVALUATE(XC)7522 EVALUATE(XC) {
7523 UNIMPLEMENTED();
7524 USE(instr);
7525 return 0;
7526 }
7527
EVALUATE(MVCP)7528 EVALUATE(MVCP) {
7529 UNIMPLEMENTED();
7530 USE(instr);
7531 return 0;
7532 }
7533
EVALUATE(TR)7534 EVALUATE(TR) {
7535 UNIMPLEMENTED();
7536 USE(instr);
7537 return 0;
7538 }
7539
EVALUATE(TRT)7540 EVALUATE(TRT) {
7541 UNIMPLEMENTED();
7542 USE(instr);
7543 return 0;
7544 }
7545
EVALUATE(ED)7546 EVALUATE(ED) {
7547 UNIMPLEMENTED();
7548 USE(instr);
7549 return 0;
7550 }
7551
EVALUATE(EDMK)7552 EVALUATE(EDMK) {
7553 UNIMPLEMENTED();
7554 USE(instr);
7555 return 0;
7556 }
7557
EVALUATE(PKU)7558 EVALUATE(PKU) {
7559 UNIMPLEMENTED();
7560 USE(instr);
7561 return 0;
7562 }
7563
EVALUATE(UNPKU)7564 EVALUATE(UNPKU) {
7565 UNIMPLEMENTED();
7566 USE(instr);
7567 return 0;
7568 }
7569
EVALUATE(MVCIN)7570 EVALUATE(MVCIN) {
7571 UNIMPLEMENTED();
7572 USE(instr);
7573 return 0;
7574 }
7575
EVALUATE(PKA)7576 EVALUATE(PKA) {
7577 UNIMPLEMENTED();
7578 USE(instr);
7579 return 0;
7580 }
7581
EVALUATE(UNPKA)7582 EVALUATE(UNPKA) {
7583 UNIMPLEMENTED();
7584 USE(instr);
7585 return 0;
7586 }
7587
EVALUATE(PLO)7588 EVALUATE(PLO) {
7589 UNIMPLEMENTED();
7590 USE(instr);
7591 return 0;
7592 }
7593
EVALUATE(LMD)7594 EVALUATE(LMD) {
7595 UNIMPLEMENTED();
7596 USE(instr);
7597 return 0;
7598 }
7599
EVALUATE(SRP)7600 EVALUATE(SRP) {
7601 UNIMPLEMENTED();
7602 USE(instr);
7603 return 0;
7604 }
7605
EVALUATE(MVO)7606 EVALUATE(MVO) {
7607 UNIMPLEMENTED();
7608 USE(instr);
7609 return 0;
7610 }
7611
EVALUATE(PACK)7612 EVALUATE(PACK) {
7613 UNIMPLEMENTED();
7614 USE(instr);
7615 return 0;
7616 }
7617
EVALUATE(UNPK)7618 EVALUATE(UNPK) {
7619 UNIMPLEMENTED();
7620 USE(instr);
7621 return 0;
7622 }
7623
EVALUATE(ZAP)7624 EVALUATE(ZAP) {
7625 UNIMPLEMENTED();
7626 USE(instr);
7627 return 0;
7628 }
7629
EVALUATE(AP)7630 EVALUATE(AP) {
7631 UNIMPLEMENTED();
7632 USE(instr);
7633 return 0;
7634 }
7635
EVALUATE(SP)7636 EVALUATE(SP) {
7637 UNIMPLEMENTED();
7638 USE(instr);
7639 return 0;
7640 }
7641
EVALUATE(MP)7642 EVALUATE(MP) {
7643 UNIMPLEMENTED();
7644 USE(instr);
7645 return 0;
7646 }
7647
EVALUATE(DP)7648 EVALUATE(DP) {
7649 UNIMPLEMENTED();
7650 USE(instr);
7651 return 0;
7652 }
7653
EVALUATE(UPT)7654 EVALUATE(UPT) {
7655 UNIMPLEMENTED();
7656 USE(instr);
7657 return 0;
7658 }
7659
EVALUATE(PFPO)7660 EVALUATE(PFPO) {
7661 UNIMPLEMENTED();
7662 USE(instr);
7663 return 0;
7664 }
7665
EVALUATE(IIHH)7666 EVALUATE(IIHH) {
7667 UNIMPLEMENTED();
7668 USE(instr);
7669 return 0;
7670 }
7671
EVALUATE(IIHL)7672 EVALUATE(IIHL) {
7673 UNIMPLEMENTED();
7674 USE(instr);
7675 return 0;
7676 }
7677
EVALUATE(IILH)7678 EVALUATE(IILH) {
7679 UNIMPLEMENTED();
7680 USE(instr);
7681 return 0;
7682 }
7683
EVALUATE(IILL)7684 EVALUATE(IILL) {
7685 UNIMPLEMENTED();
7686 USE(instr);
7687 return 0;
7688 }
7689
EVALUATE(NIHH)7690 EVALUATE(NIHH) {
7691 UNIMPLEMENTED();
7692 USE(instr);
7693 return 0;
7694 }
7695
EVALUATE(NIHL)7696 EVALUATE(NIHL) {
7697 UNIMPLEMENTED();
7698 USE(instr);
7699 return 0;
7700 }
7701
EVALUATE(NILH)7702 EVALUATE(NILH) {
7703 DCHECK_OPCODE(NILH);
7704 DECODE_RI_A_INSTRUCTION(instr, r1, i);
7705 int32_t r1_val = get_low_register<int32_t>(r1);
7706 // CC is set based on the 16 bits that are AND'd
7707 SetS390BitWiseConditionCode<uint16_t>((r1_val >> 16) & i);
7708 i = (i << 16) | 0x0000FFFF;
7709 set_low_register(r1, r1_val & i);
7710 return length;
7711 }
7712
EVALUATE(NILL)7713 EVALUATE(NILL) {
7714 DCHECK_OPCODE(NILL);
7715 DECODE_RI_A_INSTRUCTION(instr, r1, i);
7716 int32_t r1_val = get_low_register<int32_t>(r1);
7717 // CC is set based on the 16 bits that are AND'd
7718 SetS390BitWiseConditionCode<uint16_t>(r1_val & i);
7719 i |= 0xFFFF0000;
7720 set_low_register(r1, r1_val & i);
7721 return length;
7722 }
7723
EVALUATE(OIHH)7724 EVALUATE(OIHH) {
7725 UNIMPLEMENTED();
7726 USE(instr);
7727 return 0;
7728 }
7729
EVALUATE(OIHL)7730 EVALUATE(OIHL) {
7731 UNIMPLEMENTED();
7732 USE(instr);
7733 return 0;
7734 }
7735
EVALUATE(OILH)7736 EVALUATE(OILH) {
7737 DCHECK_OPCODE(OILH);
7738 DECODE_RI_A_INSTRUCTION(instr, r1, i);
7739 int32_t r1_val = get_low_register<int32_t>(r1);
7740 // CC is set based on the 16 bits that are AND'd
7741 SetS390BitWiseConditionCode<uint16_t>((r1_val >> 16) | i);
7742 i = i << 16;
7743 set_low_register(r1, r1_val | i);
7744 return length;
7745 }
7746
EVALUATE(OILL)7747 EVALUATE(OILL) {
7748 DCHECK_OPCODE(OILL);
7749 DECODE_RI_A_INSTRUCTION(instr, r1, i);
7750 int32_t r1_val = get_low_register<int32_t>(r1);
7751 // CC is set based on the 16 bits that are AND'd
7752 SetS390BitWiseConditionCode<uint16_t>(r1_val | i);
7753 set_low_register(r1, r1_val | i);
7754 return length;
7755 }
7756
EVALUATE(LLIHH)7757 EVALUATE(LLIHH) {
7758 UNIMPLEMENTED();
7759 USE(instr);
7760 return 0;
7761 }
7762
EVALUATE(LLIHL)7763 EVALUATE(LLIHL) {
7764 UNIMPLEMENTED();
7765 USE(instr);
7766 return 0;
7767 }
7768
EVALUATE(LLILH)7769 EVALUATE(LLILH) {
7770 UNIMPLEMENTED();
7771 USE(instr);
7772 return 0;
7773 }
7774
EVALUATE(LLILL)7775 EVALUATE(LLILL) {
7776 UNIMPLEMENTED();
7777 USE(instr);
7778 return 0;
7779 }
7780
EVALUATE(TMLH)7781 EVALUATE(TMLH) {
7782 UNIMPLEMENTED();
7783 USE(instr);
7784 return 0;
7785 }
7786
EVALUATE(TMLL)7787 EVALUATE(TMLL) {
7788 DCHECK_OPCODE(TMLL);
7789 DECODE_RI_A_INSTRUCTION(instr, r1, i2);
7790 uint32_t mask = i2 & 0x0000FFFF;
7791 uint32_t r1_val = get_low_register<uint32_t>(r1);
7792 r1_val = r1_val & 0x0000FFFF; // uses only the last 16bits
7793
7794 // Test if all selected bits are zeros or mask is zero
7795 if (0 == (mask & r1_val)) {
7796 condition_reg_ = 0x8;
7797 return length; // Done!
7798 }
7799
7800 DCHECK(mask != 0);
7801 // Test if all selected bits are one
7802 if (mask == (mask & r1_val)) {
7803 condition_reg_ = 0x1;
7804 return length; // Done!
7805 }
7806
7807 // Now we know selected bits mixed zeros and ones
7808 // Test if the leftmost bit is zero or one
7809 #if defined(__GNUC__)
7810 int leadingZeros = __builtin_clz(mask);
7811 mask = 0x80000000u >> leadingZeros;
7812 if (mask & r1_val) {
7813 // leftmost bit is one
7814 condition_reg_ = 0x4;
7815 } else {
7816 // leftmost bit is zero
7817 condition_reg_ = 0x2;
7818 }
7819 return length; // Done!
7820 #else
7821 for (int i = 15; i >= 0; i--) {
7822 if (mask & (1 << i)) {
7823 if (r1_val & (1 << i)) {
7824 // leftmost bit is one
7825 condition_reg_ = 0x2;
7826 } else {
7827 // leftmost bit is zero
7828 condition_reg_ = 0x4;
7829 }
7830 return length; // Done!
7831 }
7832 }
7833 #endif
7834 UNREACHABLE();
7835 return length;
7836 }
7837
EVALUATE(TMHH)7838 EVALUATE(TMHH) {
7839 UNIMPLEMENTED();
7840 USE(instr);
7841 return 0;
7842 }
7843
EVALUATE(TMHL)7844 EVALUATE(TMHL) {
7845 UNIMPLEMENTED();
7846 USE(instr);
7847 return 0;
7848 }
7849
EVALUATE(BRAS)7850 EVALUATE(BRAS) {
7851 DCHECK_OPCODE(BRAS);
7852 // Branch Relative and Save
7853 DECODE_RI_B_INSTRUCTION(instr, r1, d2)
7854 intptr_t pc = get_pc();
7855 // Set PC of next instruction to register
7856 set_register(r1, pc + sizeof(FourByteInstr));
7857 // Update PC to branch target
7858 set_pc(pc + d2 * 2);
7859 return length;
7860 }
7861
EVALUATE(BRCT)7862 EVALUATE(BRCT) {
7863 DCHECK_OPCODE(BRCT);
7864 // Branch On Count (32/64).
7865 DECODE_RI_A_INSTRUCTION(instr, r1, i2);
7866 int64_t value = get_low_register<int32_t>(r1);
7867 set_low_register(r1, --value);
7868 // Branch if value != 0
7869 if (value != 0) {
7870 intptr_t offset = i2 * 2;
7871 set_pc(get_pc() + offset);
7872 }
7873 return length;
7874 }
7875
EVALUATE(BRCTG)7876 EVALUATE(BRCTG) {
7877 DCHECK_OPCODE(BRCTG);
7878 // Branch On Count (32/64).
7879 DECODE_RI_A_INSTRUCTION(instr, r1, i2);
7880 int64_t value = get_register(r1);
7881 set_register(r1, --value);
7882 // Branch if value != 0
7883 if (value != 0) {
7884 intptr_t offset = i2 * 2;
7885 set_pc(get_pc() + offset);
7886 }
7887 return length;
7888 }
7889
EVALUATE(LHI)7890 EVALUATE(LHI) {
7891 DCHECK_OPCODE(LHI);
7892 DECODE_RI_A_INSTRUCTION(instr, r1, i);
7893 set_low_register(r1, i);
7894 return length;
7895 }
7896
EVALUATE(LGHI)7897 EVALUATE(LGHI) {
7898 DCHECK_OPCODE(LGHI);
7899 DECODE_RI_A_INSTRUCTION(instr, r1, i2);
7900 int64_t i = static_cast<int64_t>(i2);
7901 set_register(r1, i);
7902 return length;
7903 }
7904
EVALUATE(MHI)7905 EVALUATE(MHI) {
7906 DCHECK_OPCODE(MHI);
7907 DECODE_RI_A_INSTRUCTION(instr, r1, i);
7908 int32_t r1_val = get_low_register<int32_t>(r1);
7909 bool isOF = false;
7910 isOF = CheckOverflowForMul(r1_val, i);
7911 r1_val *= i;
7912 set_low_register(r1, r1_val);
7913 SetS390ConditionCode<int32_t>(r1_val, 0);
7914 SetS390OverflowCode(isOF);
7915 return length;
7916 }
7917
EVALUATE(MGHI)7918 EVALUATE(MGHI) {
7919 DCHECK_OPCODE(MGHI);
7920 DECODE_RI_A_INSTRUCTION(instr, r1, i2);
7921 int64_t i = static_cast<int64_t>(i2);
7922 int64_t r1_val = get_register(r1);
7923 bool isOF = false;
7924 isOF = CheckOverflowForMul(r1_val, i);
7925 r1_val *= i;
7926 set_register(r1, r1_val);
7927 SetS390ConditionCode<int32_t>(r1_val, 0);
7928 SetS390OverflowCode(isOF);
7929 return length;
7930 }
7931
EVALUATE(CHI)7932 EVALUATE(CHI) {
7933 DCHECK_OPCODE(CHI);
7934 DECODE_RI_A_INSTRUCTION(instr, r1, i);
7935 int32_t r1_val = get_low_register<int32_t>(r1);
7936 SetS390ConditionCode<int32_t>(r1_val, i);
7937 return length;
7938 }
7939
EVALUATE(CGHI)7940 EVALUATE(CGHI) {
7941 DCHECK_OPCODE(CGHI);
7942 DECODE_RI_A_INSTRUCTION(instr, r1, i2);
7943 int64_t i = static_cast<int64_t>(i2);
7944 int64_t r1_val = get_register(r1);
7945 SetS390ConditionCode<int64_t>(r1_val, i);
7946 return length;
7947 }
7948
EVALUATE(LARL)7949 EVALUATE(LARL) {
7950 DCHECK_OPCODE(LARL);
7951 DECODE_RIL_B_INSTRUCTION(r1, i2);
7952 intptr_t offset = i2 * 2;
7953 set_register(r1, get_pc() + offset);
7954 return length;
7955 }
7956
EVALUATE(LGFI)7957 EVALUATE(LGFI) {
7958 DCHECK_OPCODE(LGFI);
7959 DECODE_RIL_A_INSTRUCTION(r1, imm);
7960 set_register(r1, static_cast<int64_t>(static_cast<int32_t>(imm)));
7961 return length;
7962 }
7963
EVALUATE(BRASL)7964 EVALUATE(BRASL) {
7965 DCHECK_OPCODE(BRASL);
7966 // Branch and Save Relative Long
7967 DECODE_RIL_B_INSTRUCTION(r1, i2);
7968 intptr_t d2 = i2;
7969 intptr_t pc = get_pc();
7970 set_register(r1, pc + 6); // save next instruction to register
7971 set_pc(pc + d2 * 2); // update register
7972 return length;
7973 }
7974
EVALUATE(XIHF)7975 EVALUATE(XIHF) {
7976 DCHECK_OPCODE(XIHF);
7977 DECODE_RIL_A_INSTRUCTION(r1, imm);
7978 uint32_t alu_out = 0;
7979 alu_out = get_high_register<uint32_t>(r1);
7980 alu_out = alu_out ^ imm;
7981 set_high_register(r1, alu_out);
7982 SetS390BitWiseConditionCode<uint32_t>(alu_out);
7983 return length;
7984 }
7985
EVALUATE(XILF)7986 EVALUATE(XILF) {
7987 DCHECK_OPCODE(XILF);
7988 DECODE_RIL_A_INSTRUCTION(r1, imm);
7989 uint32_t alu_out = 0;
7990 alu_out = get_low_register<uint32_t>(r1);
7991 alu_out = alu_out ^ imm;
7992 set_low_register(r1, alu_out);
7993 SetS390BitWiseConditionCode<uint32_t>(alu_out);
7994 return length;
7995 }
7996
EVALUATE(NIHF)7997 EVALUATE(NIHF) {
7998 DCHECK_OPCODE(NIHF);
7999 // Bitwise Op on upper 32-bits
8000 DECODE_RIL_A_INSTRUCTION(r1, imm);
8001 uint32_t alu_out = get_high_register<uint32_t>(r1);
8002 alu_out &= imm;
8003 SetS390BitWiseConditionCode<uint32_t>(alu_out);
8004 set_high_register(r1, alu_out);
8005 return length;
8006 }
8007
EVALUATE(NILF)8008 EVALUATE(NILF) {
8009 DCHECK_OPCODE(NILF);
8010 // Bitwise Op on lower 32-bits
8011 DECODE_RIL_A_INSTRUCTION(r1, imm);
8012 uint32_t alu_out = get_low_register<uint32_t>(r1);
8013 alu_out &= imm;
8014 SetS390BitWiseConditionCode<uint32_t>(alu_out);
8015 set_low_register(r1, alu_out);
8016 return length;
8017 }
8018
EVALUATE(OIHF)8019 EVALUATE(OIHF) {
8020 DCHECK_OPCODE(OIHF);
8021 // Bitwise Op on upper 32-bits
8022 DECODE_RIL_B_INSTRUCTION(r1, imm);
8023 uint32_t alu_out = get_high_register<uint32_t>(r1);
8024 alu_out |= imm;
8025 SetS390BitWiseConditionCode<uint32_t>(alu_out);
8026 set_high_register(r1, alu_out);
8027 return length;
8028 }
8029
EVALUATE(OILF)8030 EVALUATE(OILF) {
8031 DCHECK_OPCODE(OILF);
8032 // Bitwise Op on lower 32-bits
8033 DECODE_RIL_B_INSTRUCTION(r1, imm);
8034 uint32_t alu_out = get_low_register<uint32_t>(r1);
8035 alu_out |= imm;
8036 SetS390BitWiseConditionCode<uint32_t>(alu_out);
8037 set_low_register(r1, alu_out);
8038 return length;
8039 }
8040
EVALUATE(LLIHF)8041 EVALUATE(LLIHF) {
8042 DCHECK_OPCODE(LLIHF);
8043 // Load Logical Immediate into high word
8044 DECODE_RIL_A_INSTRUCTION(r1, i2);
8045 uint64_t imm = static_cast<uint64_t>(i2);
8046 set_register(r1, imm << 32);
8047 return length;
8048 }
8049
EVALUATE(LLILF)8050 EVALUATE(LLILF) {
8051 DCHECK_OPCODE(LLILF);
8052 // Load Logical into lower 32-bits (zero extend upper 32-bits)
8053 DECODE_RIL_A_INSTRUCTION(r1, i2);
8054 uint64_t imm = static_cast<uint64_t>(i2);
8055 set_register(r1, imm);
8056 return length;
8057 }
8058
EVALUATE(MSGFI)8059 EVALUATE(MSGFI) {
8060 DCHECK_OPCODE(MSGFI);
8061 DECODE_RIL_B_INSTRUCTION(r1, i2);
8062 int64_t alu_out = get_register(r1);
8063 alu_out = alu_out * i2;
8064 set_register(r1, alu_out);
8065 return length;
8066 }
8067
EVALUATE(MSFI)8068 EVALUATE(MSFI) {
8069 DCHECK_OPCODE(MSFI);
8070 DECODE_RIL_B_INSTRUCTION(r1, i2);
8071 int32_t alu_out = get_low_register<int32_t>(r1);
8072 alu_out = alu_out * i2;
8073 set_low_register(r1, alu_out);
8074 return length;
8075 }
8076
EVALUATE(SLGFI)8077 EVALUATE(SLGFI) {
8078 DCHECK_OPCODE(SLGFI);
8079 #ifndef V8_TARGET_ARCH_S390X
8080 // should only be called on 64bit
8081 DCHECK(false);
8082 #endif
8083 DECODE_RIL_A_INSTRUCTION(r1, i2);
8084 uint64_t r1_val = (uint64_t)(get_register(r1));
8085 uint64_t alu_out;
8086 alu_out = r1_val - i2;
8087 set_register(r1, (intptr_t)alu_out);
8088 SetS390ConditionCode<uint64_t>(alu_out, 0);
8089 return length;
8090 }
8091
EVALUATE(SLFI)8092 EVALUATE(SLFI) {
8093 DCHECK_OPCODE(SLFI);
8094 DECODE_RIL_A_INSTRUCTION(r1, imm);
8095 uint32_t alu_out = get_low_register<uint32_t>(r1);
8096 alu_out -= imm;
8097 SetS390ConditionCode<uint32_t>(alu_out, 0);
8098 set_low_register(r1, alu_out);
8099 return length;
8100 }
8101
EVALUATE(AGFI)8102 EVALUATE(AGFI) {
8103 DCHECK_OPCODE(AGFI);
8104 // Clobbering Add Word Immediate
8105 DECODE_RIL_B_INSTRUCTION(r1, i2_val);
8106 bool isOF = false;
8107 // 64-bit Add (Register + 32-bit Imm)
8108 int64_t r1_val = get_register(r1);
8109 int64_t i2 = static_cast<int64_t>(i2_val);
8110 isOF = CheckOverflowForIntAdd(r1_val, i2, int64_t);
8111 int64_t alu_out = r1_val + i2;
8112 set_register(r1, alu_out);
8113 SetS390ConditionCode<int64_t>(alu_out, 0);
8114 SetS390OverflowCode(isOF);
8115 return length;
8116 }
8117
EVALUATE(AFI)8118 EVALUATE(AFI) {
8119 DCHECK_OPCODE(AFI);
8120 // Clobbering Add Word Immediate
8121 DECODE_RIL_B_INSTRUCTION(r1, i2);
8122 bool isOF = false;
8123 // 32-bit Add (Register + 32-bit Immediate)
8124 int32_t r1_val = get_low_register<int32_t>(r1);
8125 isOF = CheckOverflowForIntAdd(r1_val, i2, int32_t);
8126 int32_t alu_out = r1_val + i2;
8127 set_low_register(r1, alu_out);
8128 SetS390ConditionCode<int32_t>(alu_out, 0);
8129 SetS390OverflowCode(isOF);
8130 return length;
8131 }
8132
EVALUATE(ALGFI)8133 EVALUATE(ALGFI) {
8134 DCHECK_OPCODE(ALGFI);
8135 #ifndef V8_TARGET_ARCH_S390X
8136 // should only be called on 64bit
8137 DCHECK(false);
8138 #endif
8139 DECODE_RIL_A_INSTRUCTION(r1, i2);
8140 uint64_t r1_val = (uint64_t)(get_register(r1));
8141 uint64_t alu_out;
8142 alu_out = r1_val + i2;
8143 set_register(r1, (intptr_t)alu_out);
8144 SetS390ConditionCode<uint64_t>(alu_out, 0);
8145
8146 return length;
8147 }
8148
EVALUATE(ALFI)8149 EVALUATE(ALFI) {
8150 DCHECK_OPCODE(ALFI);
8151 DECODE_RIL_A_INSTRUCTION(r1, imm);
8152 uint32_t alu_out = get_low_register<uint32_t>(r1);
8153 alu_out += imm;
8154 SetS390ConditionCode<uint32_t>(alu_out, 0);
8155 set_low_register(r1, alu_out);
8156 return length;
8157 }
8158
EVALUATE(CGFI)8159 EVALUATE(CGFI) {
8160 DCHECK_OPCODE(CGFI);
8161 // Compare with Immediate (64)
8162 DECODE_RIL_B_INSTRUCTION(r1, i2);
8163 int64_t imm = static_cast<int64_t>(i2);
8164 SetS390ConditionCode<int64_t>(get_register(r1), imm);
8165 return length;
8166 }
8167
EVALUATE(CFI)8168 EVALUATE(CFI) {
8169 DCHECK_OPCODE(CFI);
8170 // Compare with Immediate (32)
8171 DECODE_RIL_B_INSTRUCTION(r1, imm);
8172 SetS390ConditionCode<int32_t>(get_low_register<int32_t>(r1), imm);
8173 return length;
8174 }
8175
EVALUATE(CLGFI)8176 EVALUATE(CLGFI) {
8177 DCHECK_OPCODE(CLGFI);
8178 // Compare Logical with Immediate (64)
8179 DECODE_RIL_A_INSTRUCTION(r1, i2);
8180 uint64_t imm = static_cast<uint64_t>(i2);
8181 SetS390ConditionCode<uint64_t>(get_register(r1), imm);
8182 return length;
8183 }
8184
EVALUATE(CLFI)8185 EVALUATE(CLFI) {
8186 DCHECK_OPCODE(CLFI);
8187 // Compare Logical with Immediate (32)
8188 DECODE_RIL_A_INSTRUCTION(r1, imm);
8189 SetS390ConditionCode<uint32_t>(get_low_register<uint32_t>(r1), imm);
8190 return length;
8191 }
8192
EVALUATE(LLHRL)8193 EVALUATE(LLHRL) {
8194 UNIMPLEMENTED();
8195 USE(instr);
8196 return 0;
8197 }
8198
EVALUATE(LGHRL)8199 EVALUATE(LGHRL) {
8200 UNIMPLEMENTED();
8201 USE(instr);
8202 return 0;
8203 }
8204
EVALUATE(LHRL)8205 EVALUATE(LHRL) {
8206 UNIMPLEMENTED();
8207 USE(instr);
8208 return 0;
8209 }
8210
EVALUATE(LLGHRL)8211 EVALUATE(LLGHRL) {
8212 UNIMPLEMENTED();
8213 USE(instr);
8214 return 0;
8215 }
8216
EVALUATE(STHRL)8217 EVALUATE(STHRL) {
8218 UNIMPLEMENTED();
8219 USE(instr);
8220 return 0;
8221 }
8222
EVALUATE(LGRL)8223 EVALUATE(LGRL) {
8224 UNIMPLEMENTED();
8225 USE(instr);
8226 return 0;
8227 }
8228
EVALUATE(STGRL)8229 EVALUATE(STGRL) {
8230 UNIMPLEMENTED();
8231 USE(instr);
8232 return 0;
8233 }
8234
EVALUATE(LGFRL)8235 EVALUATE(LGFRL) {
8236 UNIMPLEMENTED();
8237 USE(instr);
8238 return 0;
8239 }
8240
EVALUATE(LRL)8241 EVALUATE(LRL) {
8242 UNIMPLEMENTED();
8243 USE(instr);
8244 return 0;
8245 }
8246
EVALUATE(LLGFRL)8247 EVALUATE(LLGFRL) {
8248 UNIMPLEMENTED();
8249 USE(instr);
8250 return 0;
8251 }
8252
EVALUATE(STRL)8253 EVALUATE(STRL) {
8254 UNIMPLEMENTED();
8255 USE(instr);
8256 return 0;
8257 }
8258
EVALUATE(EXRL)8259 EVALUATE(EXRL) {
8260 UNIMPLEMENTED();
8261 USE(instr);
8262 return 0;
8263 }
8264
EVALUATE(PFDRL)8265 EVALUATE(PFDRL) {
8266 UNIMPLEMENTED();
8267 USE(instr);
8268 return 0;
8269 }
8270
EVALUATE(CGHRL)8271 EVALUATE(CGHRL) {
8272 UNIMPLEMENTED();
8273 USE(instr);
8274 return 0;
8275 }
8276
EVALUATE(CHRL)8277 EVALUATE(CHRL) {
8278 UNIMPLEMENTED();
8279 USE(instr);
8280 return 0;
8281 }
8282
EVALUATE(CGRL)8283 EVALUATE(CGRL) {
8284 UNIMPLEMENTED();
8285 USE(instr);
8286 return 0;
8287 }
8288
EVALUATE(CGFRL)8289 EVALUATE(CGFRL) {
8290 UNIMPLEMENTED();
8291 USE(instr);
8292 return 0;
8293 }
8294
EVALUATE(ECTG)8295 EVALUATE(ECTG) {
8296 UNIMPLEMENTED();
8297 USE(instr);
8298 return 0;
8299 }
8300
EVALUATE(CSST)8301 EVALUATE(CSST) {
8302 UNIMPLEMENTED();
8303 USE(instr);
8304 return 0;
8305 }
8306
EVALUATE(LPD)8307 EVALUATE(LPD) {
8308 UNIMPLEMENTED();
8309 USE(instr);
8310 return 0;
8311 }
8312
EVALUATE(LPDG)8313 EVALUATE(LPDG) {
8314 UNIMPLEMENTED();
8315 USE(instr);
8316 return 0;
8317 }
8318
EVALUATE(BRCTH)8319 EVALUATE(BRCTH) {
8320 UNIMPLEMENTED();
8321 USE(instr);
8322 return 0;
8323 }
8324
EVALUATE(AIH)8325 EVALUATE(AIH) {
8326 DCHECK_OPCODE(AIH);
8327 DECODE_RIL_A_INSTRUCTION(r1, i2);
8328 int32_t r1_val = get_high_register<int32_t>(r1);
8329 bool isOF = CheckOverflowForIntAdd(r1_val, static_cast<int32_t>(i2), int32_t);
8330 r1_val += static_cast<int32_t>(i2);
8331 set_high_register(r1, r1_val);
8332 SetS390ConditionCode<int32_t>(r1_val, 0);
8333 SetS390OverflowCode(isOF);
8334 return length;
8335 }
8336
EVALUATE(ALSIH)8337 EVALUATE(ALSIH) {
8338 UNIMPLEMENTED();
8339 USE(instr);
8340 return 0;
8341 }
8342
EVALUATE(ALSIHN)8343 EVALUATE(ALSIHN) {
8344 UNIMPLEMENTED();
8345 USE(instr);
8346 return 0;
8347 }
8348
EVALUATE(CIH)8349 EVALUATE(CIH) {
8350 DCHECK_OPCODE(CIH);
8351 DECODE_RIL_A_INSTRUCTION(r1, imm);
8352 int32_t r1_val = get_high_register<int32_t>(r1);
8353 SetS390ConditionCode<int32_t>(r1_val, static_cast<int32_t>(imm));
8354 return length;
8355 }
8356
EVALUATE(CLIH)8357 EVALUATE(CLIH) {
8358 DCHECK_OPCODE(CLIH);
8359 // Compare Logical with Immediate (32)
8360 DECODE_RIL_A_INSTRUCTION(r1, imm);
8361 SetS390ConditionCode<uint32_t>(get_high_register<uint32_t>(r1), imm);
8362 return length;
8363 }
8364
EVALUATE(STCK)8365 EVALUATE(STCK) {
8366 UNIMPLEMENTED();
8367 USE(instr);
8368 return 0;
8369 }
8370
EVALUATE(CFC)8371 EVALUATE(CFC) {
8372 UNIMPLEMENTED();
8373 USE(instr);
8374 return 0;
8375 }
8376
EVALUATE(IPM)8377 EVALUATE(IPM) {
8378 UNIMPLEMENTED();
8379 USE(instr);
8380 return 0;
8381 }
8382
EVALUATE(HSCH)8383 EVALUATE(HSCH) {
8384 UNIMPLEMENTED();
8385 USE(instr);
8386 return 0;
8387 }
8388
EVALUATE(MSCH)8389 EVALUATE(MSCH) {
8390 UNIMPLEMENTED();
8391 USE(instr);
8392 return 0;
8393 }
8394
EVALUATE(SSCH)8395 EVALUATE(SSCH) {
8396 UNIMPLEMENTED();
8397 USE(instr);
8398 return 0;
8399 }
8400
EVALUATE(STSCH)8401 EVALUATE(STSCH) {
8402 UNIMPLEMENTED();
8403 USE(instr);
8404 return 0;
8405 }
8406
EVALUATE(TSCH)8407 EVALUATE(TSCH) {
8408 UNIMPLEMENTED();
8409 USE(instr);
8410 return 0;
8411 }
8412
EVALUATE(TPI)8413 EVALUATE(TPI) {
8414 UNIMPLEMENTED();
8415 USE(instr);
8416 return 0;
8417 }
8418
EVALUATE(SAL)8419 EVALUATE(SAL) {
8420 UNIMPLEMENTED();
8421 USE(instr);
8422 return 0;
8423 }
8424
EVALUATE(RSCH)8425 EVALUATE(RSCH) {
8426 UNIMPLEMENTED();
8427 USE(instr);
8428 return 0;
8429 }
8430
EVALUATE(STCRW)8431 EVALUATE(STCRW) {
8432 UNIMPLEMENTED();
8433 USE(instr);
8434 return 0;
8435 }
8436
EVALUATE(STCPS)8437 EVALUATE(STCPS) {
8438 UNIMPLEMENTED();
8439 USE(instr);
8440 return 0;
8441 }
8442
EVALUATE(RCHP)8443 EVALUATE(RCHP) {
8444 UNIMPLEMENTED();
8445 USE(instr);
8446 return 0;
8447 }
8448
EVALUATE(SCHM)8449 EVALUATE(SCHM) {
8450 UNIMPLEMENTED();
8451 USE(instr);
8452 return 0;
8453 }
8454
EVALUATE(CKSM)8455 EVALUATE(CKSM) {
8456 UNIMPLEMENTED();
8457 USE(instr);
8458 return 0;
8459 }
8460
EVALUATE(SAR)8461 EVALUATE(SAR) {
8462 UNIMPLEMENTED();
8463 USE(instr);
8464 return 0;
8465 }
8466
EVALUATE(EAR)8467 EVALUATE(EAR) {
8468 UNIMPLEMENTED();
8469 USE(instr);
8470 return 0;
8471 }
8472
EVALUATE(MSR)8473 EVALUATE(MSR) {
8474 DCHECK_OPCODE(MSR);
8475 DECODE_RRE_INSTRUCTION(r1, r2);
8476 int32_t r1_val = get_low_register<int32_t>(r1);
8477 int32_t r2_val = get_low_register<int32_t>(r2);
8478 set_low_register(r1, r1_val * r2_val);
8479 return length;
8480 }
8481
EVALUATE(MSRKC)8482 EVALUATE(MSRKC) {
8483 DCHECK_OPCODE(MSRKC);
8484 DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
8485 int32_t r2_val = get_low_register<int32_t>(r2);
8486 int32_t r3_val = get_low_register<int32_t>(r3);
8487 int64_t result64 =
8488 static_cast<int64_t>(r2_val) * static_cast<int64_t>(r3_val);
8489 int32_t result32 = static_cast<int32_t>(result64);
8490 bool isOF = (static_cast<int64_t>(result32) != result64);
8491 SetS390ConditionCode<int32_t>(result32, 0);
8492 SetS390OverflowCode(isOF);
8493 set_low_register(r1, result32);
8494 return length;
8495 }
8496
EVALUATE(MVST)8497 EVALUATE(MVST) {
8498 UNIMPLEMENTED();
8499 USE(instr);
8500 return 0;
8501 }
8502
EVALUATE(CUSE)8503 EVALUATE(CUSE) {
8504 UNIMPLEMENTED();
8505 USE(instr);
8506 return 0;
8507 }
8508
EVALUATE(SRST)8509 EVALUATE(SRST) {
8510 UNIMPLEMENTED();
8511 USE(instr);
8512 return 0;
8513 }
8514
EVALUATE(XSCH)8515 EVALUATE(XSCH) {
8516 UNIMPLEMENTED();
8517 USE(instr);
8518 return 0;
8519 }
8520
EVALUATE(STCKE)8521 EVALUATE(STCKE) {
8522 UNIMPLEMENTED();
8523 USE(instr);
8524 return 0;
8525 }
8526
EVALUATE(STCKF)8527 EVALUATE(STCKF) {
8528 UNIMPLEMENTED();
8529 USE(instr);
8530 return 0;
8531 }
8532
EVALUATE(SRNM)8533 EVALUATE(SRNM) {
8534 UNIMPLEMENTED();
8535 USE(instr);
8536 return 0;
8537 }
8538
EVALUATE(STFPC)8539 EVALUATE(STFPC) {
8540 UNIMPLEMENTED();
8541 USE(instr);
8542 return 0;
8543 }
8544
EVALUATE(LFPC)8545 EVALUATE(LFPC) {
8546 UNIMPLEMENTED();
8547 USE(instr);
8548 return 0;
8549 }
8550
EVALUATE(TRE)8551 EVALUATE(TRE) {
8552 UNIMPLEMENTED();
8553 USE(instr);
8554 return 0;
8555 }
8556
EVALUATE(CUUTF)8557 EVALUATE(CUUTF) {
8558 UNIMPLEMENTED();
8559 USE(instr);
8560 return 0;
8561 }
8562
EVALUATE(CUTFU)8563 EVALUATE(CUTFU) {
8564 UNIMPLEMENTED();
8565 USE(instr);
8566 return 0;
8567 }
8568
EVALUATE(STFLE)8569 EVALUATE(STFLE) {
8570 UNIMPLEMENTED();
8571 USE(instr);
8572 return 0;
8573 }
8574
EVALUATE(SRNMB)8575 EVALUATE(SRNMB) {
8576 UNIMPLEMENTED();
8577 USE(instr);
8578 return 0;
8579 }
8580
EVALUATE(SRNMT)8581 EVALUATE(SRNMT) {
8582 UNIMPLEMENTED();
8583 USE(instr);
8584 return 0;
8585 }
8586
EVALUATE(LFAS)8587 EVALUATE(LFAS) {
8588 UNIMPLEMENTED();
8589 USE(instr);
8590 return 0;
8591 }
8592
EVALUATE(PPA)8593 EVALUATE(PPA) {
8594 UNIMPLEMENTED();
8595 USE(instr);
8596 return 0;
8597 }
8598
EVALUATE(ETND)8599 EVALUATE(ETND) {
8600 UNIMPLEMENTED();
8601 USE(instr);
8602 return 0;
8603 }
8604
EVALUATE(TEND)8605 EVALUATE(TEND) {
8606 UNIMPLEMENTED();
8607 USE(instr);
8608 return 0;
8609 }
8610
EVALUATE(NIAI)8611 EVALUATE(NIAI) {
8612 UNIMPLEMENTED();
8613 USE(instr);
8614 return 0;
8615 }
8616
EVALUATE(TABORT)8617 EVALUATE(TABORT) {
8618 UNIMPLEMENTED();
8619 USE(instr);
8620 return 0;
8621 }
8622
EVALUATE(TRAP4)8623 EVALUATE(TRAP4) {
8624 DCHECK_OPCODE(TRAP4);
8625 int length = 4;
8626 // whack the space of the caller allocated stack
8627 int64_t sp_addr = get_register(sp);
8628 for (int i = 0; i < kCalleeRegisterSaveAreaSize / kPointerSize; ++i) {
8629 // we dont want to whack the RA (r14)
8630 if (i != 14) (reinterpret_cast<intptr_t*>(sp_addr))[i] = 0xdeadbabe;
8631 }
8632 SoftwareInterrupt(instr);
8633 return length;
8634 }
8635
EVALUATE(LPEBR)8636 EVALUATE(LPEBR) {
8637 DCHECK_OPCODE(LPEBR);
8638 DECODE_RRE_INSTRUCTION(r1, r2);
8639 float fr1_val = get_float32_from_d_register(r1);
8640 float fr2_val = get_float32_from_d_register(r2);
8641 fr1_val = std::fabs(fr2_val);
8642 set_d_register_from_float32(r1, fr1_val);
8643 if (fr2_val != fr2_val) { // input is NaN
8644 condition_reg_ = CC_OF;
8645 } else if (fr2_val == 0) {
8646 condition_reg_ = CC_EQ;
8647 } else {
8648 condition_reg_ = CC_GT;
8649 }
8650
8651 return length;
8652 }
8653
EVALUATE(LNEBR)8654 EVALUATE(LNEBR) {
8655 UNIMPLEMENTED();
8656 USE(instr);
8657 return 0;
8658 }
8659
EVALUATE(LTEBR)8660 EVALUATE(LTEBR) {
8661 DCHECK_OPCODE(LTEBR);
8662 DECODE_RRE_INSTRUCTION(r1, r2);
8663 int64_t r2_val = get_d_register(r2);
8664 float fr2_val = get_float32_from_d_register(r2);
8665 SetS390ConditionCode<float>(fr2_val, 0.0);
8666 set_d_register(r1, r2_val);
8667 return length;
8668 }
8669
EVALUATE(LCEBR)8670 EVALUATE(LCEBR) {
8671 DCHECK_OPCODE(LCEBR);
8672 DECODE_RRE_INSTRUCTION(r1, r2);
8673 float fr1_val = get_float32_from_d_register(r1);
8674 float fr2_val = get_float32_from_d_register(r2);
8675 fr1_val = -fr2_val;
8676 set_d_register_from_float32(r1, fr1_val);
8677 if (fr2_val != fr2_val) { // input is NaN
8678 condition_reg_ = CC_OF;
8679 } else if (fr2_val == 0) {
8680 condition_reg_ = CC_EQ;
8681 } else if (fr2_val < 0) {
8682 condition_reg_ = CC_LT;
8683 } else if (fr2_val > 0) {
8684 condition_reg_ = CC_GT;
8685 }
8686 return length;
8687 }
8688
EVALUATE(LDEBR)8689 EVALUATE(LDEBR) {
8690 DCHECK_OPCODE(LDEBR);
8691 DECODE_RRE_INSTRUCTION(r1, r2);
8692 float fp_val = get_float32_from_d_register(r2);
8693 double db_val = static_cast<double>(fp_val);
8694 set_d_register_from_double(r1, db_val);
8695 return length;
8696 }
8697
EVALUATE(LXDBR)8698 EVALUATE(LXDBR) {
8699 UNIMPLEMENTED();
8700 USE(instr);
8701 return 0;
8702 }
8703
EVALUATE(LXEBR)8704 EVALUATE(LXEBR) {
8705 UNIMPLEMENTED();
8706 USE(instr);
8707 return 0;
8708 }
8709
EVALUATE(MXDBR)8710 EVALUATE(MXDBR) {
8711 UNIMPLEMENTED();
8712 USE(instr);
8713 return 0;
8714 }
8715
EVALUATE(KEBR)8716 EVALUATE(KEBR) {
8717 UNIMPLEMENTED();
8718 USE(instr);
8719 return 0;
8720 }
8721
EVALUATE(CEBR)8722 EVALUATE(CEBR) {
8723 DCHECK_OPCODE(CEBR);
8724 DECODE_RRE_INSTRUCTION(r1, r2);
8725 float fr1_val = get_float32_from_d_register(r1);
8726 float fr2_val = get_float32_from_d_register(r2);
8727 if (isNaN(fr1_val) || isNaN(fr2_val)) {
8728 condition_reg_ = CC_OF;
8729 } else {
8730 SetS390ConditionCode<float>(fr1_val, fr2_val);
8731 }
8732
8733 return length;
8734 }
8735
EVALUATE(AEBR)8736 EVALUATE(AEBR) {
8737 DCHECK_OPCODE(AEBR);
8738 DECODE_RRE_INSTRUCTION(r1, r2);
8739 float fr1_val = get_float32_from_d_register(r1);
8740 float fr2_val = get_float32_from_d_register(r2);
8741 fr1_val += fr2_val;
8742 set_d_register_from_float32(r1, fr1_val);
8743 SetS390ConditionCode<float>(fr1_val, 0);
8744
8745 return length;
8746 }
8747
EVALUATE(SEBR)8748 EVALUATE(SEBR) {
8749 DCHECK_OPCODE(SEBR);
8750 DECODE_RRE_INSTRUCTION(r1, r2);
8751 float fr1_val = get_float32_from_d_register(r1);
8752 float fr2_val = get_float32_from_d_register(r2);
8753 fr1_val -= fr2_val;
8754 set_d_register_from_float32(r1, fr1_val);
8755 SetS390ConditionCode<float>(fr1_val, 0);
8756
8757 return length;
8758 }
8759
EVALUATE(MDEBR)8760 EVALUATE(MDEBR) {
8761 UNIMPLEMENTED();
8762 USE(instr);
8763 return 0;
8764 }
8765
EVALUATE(DEBR)8766 EVALUATE(DEBR) {
8767 DCHECK_OPCODE(DEBR);
8768 DECODE_RRE_INSTRUCTION(r1, r2);
8769 float fr1_val = get_float32_from_d_register(r1);
8770 float fr2_val = get_float32_from_d_register(r2);
8771 fr1_val /= fr2_val;
8772 set_d_register_from_float32(r1, fr1_val);
8773 SetS390ConditionCode<float>(fr1_val, 0);
8774
8775 return length;
8776 }
8777
EVALUATE(MAEBR)8778 EVALUATE(MAEBR) {
8779 UNIMPLEMENTED();
8780 USE(instr);
8781 return 0;
8782 }
8783
EVALUATE(MSEBR)8784 EVALUATE(MSEBR) {
8785 UNIMPLEMENTED();
8786 USE(instr);
8787 return 0;
8788 }
8789
EVALUATE(LPDBR)8790 EVALUATE(LPDBR) {
8791 DCHECK_OPCODE(LPDBR);
8792 DECODE_RRE_INSTRUCTION(r1, r2);
8793 double r1_val = get_double_from_d_register(r1);
8794 double r2_val = get_double_from_d_register(r2);
8795 r1_val = std::fabs(r2_val);
8796 set_d_register_from_double(r1, r1_val);
8797 if (r2_val != r2_val) { // input is NaN
8798 condition_reg_ = CC_OF;
8799 } else if (r2_val == 0) {
8800 condition_reg_ = CC_EQ;
8801 } else {
8802 condition_reg_ = CC_GT;
8803 }
8804 return length;
8805 }
8806
EVALUATE(LNDBR)8807 EVALUATE(LNDBR) {
8808 UNIMPLEMENTED();
8809 USE(instr);
8810 return 0;
8811 }
8812
EVALUATE(LTDBR)8813 EVALUATE(LTDBR) {
8814 DCHECK_OPCODE(LTDBR);
8815 DECODE_RRE_INSTRUCTION(r1, r2);
8816 int64_t r2_val = get_d_register(r2);
8817 SetS390ConditionCode<double>(bit_cast<double, int64_t>(r2_val), 0.0);
8818 set_d_register(r1, r2_val);
8819 return length;
8820 }
8821
EVALUATE(LCDBR)8822 EVALUATE(LCDBR) {
8823 DCHECK_OPCODE(LCDBR);
8824 DECODE_RRE_INSTRUCTION(r1, r2);
8825 double r1_val = get_double_from_d_register(r1);
8826 double r2_val = get_double_from_d_register(r2);
8827 r1_val = -r2_val;
8828 set_d_register_from_double(r1, r1_val);
8829 if (r2_val != r2_val) { // input is NaN
8830 condition_reg_ = CC_OF;
8831 } else if (r2_val == 0) {
8832 condition_reg_ = CC_EQ;
8833 } else if (r2_val < 0) {
8834 condition_reg_ = CC_LT;
8835 } else if (r2_val > 0) {
8836 condition_reg_ = CC_GT;
8837 }
8838 return length;
8839 }
8840
EVALUATE(SQEBR)8841 EVALUATE(SQEBR) {
8842 DCHECK_OPCODE(SQEBR);
8843 DECODE_RRE_INSTRUCTION(r1, r2);
8844 float fr1_val = get_float32_from_d_register(r1);
8845 float fr2_val = get_float32_from_d_register(r2);
8846 fr1_val = std::sqrt(fr2_val);
8847 set_d_register_from_float32(r1, fr1_val);
8848 return length;
8849 }
8850
EVALUATE(SQDBR)8851 EVALUATE(SQDBR) {
8852 DCHECK_OPCODE(SQDBR);
8853 DECODE_RRE_INSTRUCTION(r1, r2);
8854 double r1_val = get_double_from_d_register(r1);
8855 double r2_val = get_double_from_d_register(r2);
8856 r1_val = std::sqrt(r2_val);
8857 set_d_register_from_double(r1, r1_val);
8858 return length;
8859 }
8860
EVALUATE(SQXBR)8861 EVALUATE(SQXBR) {
8862 UNIMPLEMENTED();
8863 USE(instr);
8864 return 0;
8865 }
8866
EVALUATE(MEEBR)8867 EVALUATE(MEEBR) {
8868 DCHECK_OPCODE(MEEBR);
8869 DECODE_RRE_INSTRUCTION(r1, r2);
8870 float fr1_val = get_float32_from_d_register(r1);
8871 float fr2_val = get_float32_from_d_register(r2);
8872 fr1_val *= fr2_val;
8873 set_d_register_from_float32(r1, fr1_val);
8874 SetS390ConditionCode<float>(fr1_val, 0);
8875 return length;
8876 }
8877
EVALUATE(KDBR)8878 EVALUATE(KDBR) {
8879 UNIMPLEMENTED();
8880 USE(instr);
8881 return 0;
8882 }
8883
EVALUATE(CDBR)8884 EVALUATE(CDBR) {
8885 DCHECK_OPCODE(CDBR);
8886 DECODE_RRE_INSTRUCTION(r1, r2);
8887 double r1_val = get_double_from_d_register(r1);
8888 double r2_val = get_double_from_d_register(r2);
8889 if (isNaN(r1_val) || isNaN(r2_val)) {
8890 condition_reg_ = CC_OF;
8891 } else {
8892 SetS390ConditionCode<double>(r1_val, r2_val);
8893 }
8894 return length;
8895 }
8896
EVALUATE(ADBR)8897 EVALUATE(ADBR) {
8898 DCHECK_OPCODE(ADBR);
8899 DECODE_RRE_INSTRUCTION(r1, r2);
8900 double r1_val = get_double_from_d_register(r1);
8901 double r2_val = get_double_from_d_register(r2);
8902 r1_val += r2_val;
8903 set_d_register_from_double(r1, r1_val);
8904 SetS390ConditionCode<double>(r1_val, 0);
8905 return length;
8906 }
8907
EVALUATE(SDBR)8908 EVALUATE(SDBR) {
8909 DCHECK_OPCODE(SDBR);
8910 DECODE_RRE_INSTRUCTION(r1, r2);
8911 double r1_val = get_double_from_d_register(r1);
8912 double r2_val = get_double_from_d_register(r2);
8913 r1_val -= r2_val;
8914 set_d_register_from_double(r1, r1_val);
8915 SetS390ConditionCode<double>(r1_val, 0);
8916 return length;
8917 }
8918
EVALUATE(MDBR)8919 EVALUATE(MDBR) {
8920 DCHECK_OPCODE(MDBR);
8921 DECODE_RRE_INSTRUCTION(r1, r2);
8922 double r1_val = get_double_from_d_register(r1);
8923 double r2_val = get_double_from_d_register(r2);
8924 r1_val *= r2_val;
8925 set_d_register_from_double(r1, r1_val);
8926 SetS390ConditionCode<double>(r1_val, 0);
8927 return length;
8928 }
8929
EVALUATE(DDBR)8930 EVALUATE(DDBR) {
8931 DCHECK_OPCODE(DDBR);
8932 DECODE_RRE_INSTRUCTION(r1, r2);
8933 double r1_val = get_double_from_d_register(r1);
8934 double r2_val = get_double_from_d_register(r2);
8935 r1_val /= r2_val;
8936 set_d_register_from_double(r1, r1_val);
8937 SetS390ConditionCode<double>(r1_val, 0);
8938 return length;
8939 }
8940
EVALUATE(MADBR)8941 EVALUATE(MADBR) {
8942 DCHECK_OPCODE(MADBR);
8943 DECODE_RRD_INSTRUCTION(r1, r2, r3);
8944 double r1_val = get_double_from_d_register(r1);
8945 double r2_val = get_double_from_d_register(r2);
8946 double r3_val = get_double_from_d_register(r3);
8947 r1_val += r2_val * r3_val;
8948 set_d_register_from_double(r1, r1_val);
8949 SetS390ConditionCode<double>(r1_val, 0);
8950 return length;
8951 }
8952
EVALUATE(MSDBR)8953 EVALUATE(MSDBR) {
8954 UNIMPLEMENTED();
8955 USE(instr);
8956 return 0;
8957 }
8958
EVALUATE(LPXBR)8959 EVALUATE(LPXBR) {
8960 UNIMPLEMENTED();
8961 USE(instr);
8962 return 0;
8963 }
8964
EVALUATE(LNXBR)8965 EVALUATE(LNXBR) {
8966 UNIMPLEMENTED();
8967 USE(instr);
8968 return 0;
8969 }
8970
EVALUATE(LTXBR)8971 EVALUATE(LTXBR) {
8972 UNIMPLEMENTED();
8973 USE(instr);
8974 return 0;
8975 }
8976
EVALUATE(LCXBR)8977 EVALUATE(LCXBR) {
8978 UNIMPLEMENTED();
8979 USE(instr);
8980 return 0;
8981 }
8982
EVALUATE(LEDBRA)8983 EVALUATE(LEDBRA) {
8984 DCHECK_OPCODE(LEDBRA);
8985 DECODE_RRE_INSTRUCTION(r1, r2);
8986 double r2_val = get_double_from_d_register(r2);
8987 set_d_register_from_float32(r1, static_cast<float>(r2_val));
8988 return length;
8989 }
8990
EVALUATE(LDXBRA)8991 EVALUATE(LDXBRA) {
8992 UNIMPLEMENTED();
8993 USE(instr);
8994 return 0;
8995 }
8996
EVALUATE(LEXBRA)8997 EVALUATE(LEXBRA) {
8998 UNIMPLEMENTED();
8999 USE(instr);
9000 return 0;
9001 }
9002
EVALUATE(FIXBRA)9003 EVALUATE(FIXBRA) {
9004 UNIMPLEMENTED();
9005 USE(instr);
9006 return 0;
9007 }
9008
EVALUATE(KXBR)9009 EVALUATE(KXBR) {
9010 UNIMPLEMENTED();
9011 USE(instr);
9012 return 0;
9013 }
9014
EVALUATE(CXBR)9015 EVALUATE(CXBR) {
9016 UNIMPLEMENTED();
9017 USE(instr);
9018 return 0;
9019 }
9020
EVALUATE(AXBR)9021 EVALUATE(AXBR) {
9022 UNIMPLEMENTED();
9023 USE(instr);
9024 return 0;
9025 }
9026
EVALUATE(SXBR)9027 EVALUATE(SXBR) {
9028 UNIMPLEMENTED();
9029 USE(instr);
9030 return 0;
9031 }
9032
EVALUATE(MXBR)9033 EVALUATE(MXBR) {
9034 UNIMPLEMENTED();
9035 USE(instr);
9036 return 0;
9037 }
9038
EVALUATE(DXBR)9039 EVALUATE(DXBR) {
9040 UNIMPLEMENTED();
9041 USE(instr);
9042 return 0;
9043 }
9044
EVALUATE(TBEDR)9045 EVALUATE(TBEDR) {
9046 UNIMPLEMENTED();
9047 USE(instr);
9048 return 0;
9049 }
9050
EVALUATE(TBDR)9051 EVALUATE(TBDR) {
9052 UNIMPLEMENTED();
9053 USE(instr);
9054 return 0;
9055 }
9056
EVALUATE(DIEBR)9057 EVALUATE(DIEBR) {
9058 UNIMPLEMENTED();
9059 USE(instr);
9060 return 0;
9061 }
9062
EVALUATE(FIEBRA)9063 EVALUATE(FIEBRA) {
9064 DCHECK_OPCODE(FIEBRA);
9065 DECODE_RRF_E_INSTRUCTION(r1, r2, m3, m4);
9066 float r2_val = get_float32_from_d_register(r2);
9067 CHECK(m4 == 0);
9068 switch (m3) {
9069 case Assembler::FIDBRA_ROUND_TO_NEAREST_AWAY_FROM_0:
9070 set_d_register_from_float32(r1, round(r2_val));
9071 break;
9072 case Assembler::FIDBRA_ROUND_TOWARD_0:
9073 set_d_register_from_float32(r1, trunc(r2_val));
9074 break;
9075 case Assembler::FIDBRA_ROUND_TOWARD_POS_INF:
9076 set_d_register_from_float32(r1, std::ceil(r2_val));
9077 break;
9078 case Assembler::FIDBRA_ROUND_TOWARD_NEG_INF:
9079 set_d_register_from_float32(r1, std::floor(r2_val));
9080 break;
9081 default:
9082 UNIMPLEMENTED();
9083 break;
9084 }
9085 return length;
9086 }
9087
EVALUATE(THDER)9088 EVALUATE(THDER) {
9089 UNIMPLEMENTED();
9090 USE(instr);
9091 return 0;
9092 }
9093
EVALUATE(THDR)9094 EVALUATE(THDR) {
9095 UNIMPLEMENTED();
9096 USE(instr);
9097 return 0;
9098 }
9099
EVALUATE(DIDBR)9100 EVALUATE(DIDBR) {
9101 UNIMPLEMENTED();
9102 USE(instr);
9103 return 0;
9104 }
9105
EVALUATE(FIDBRA)9106 EVALUATE(FIDBRA) {
9107 DCHECK_OPCODE(FIDBRA);
9108 DECODE_RRF_E_INSTRUCTION(r1, r2, m3, m4);
9109 double r2_val = get_double_from_d_register(r2);
9110 CHECK(m4 == 0);
9111 switch (m3) {
9112 case Assembler::FIDBRA_ROUND_TO_NEAREST_AWAY_FROM_0:
9113 set_d_register_from_double(r1, round(r2_val));
9114 break;
9115 case Assembler::FIDBRA_ROUND_TOWARD_0:
9116 set_d_register_from_double(r1, trunc(r2_val));
9117 break;
9118 case Assembler::FIDBRA_ROUND_TOWARD_POS_INF:
9119 set_d_register_from_double(r1, std::ceil(r2_val));
9120 break;
9121 case Assembler::FIDBRA_ROUND_TOWARD_NEG_INF:
9122 set_d_register_from_double(r1, std::floor(r2_val));
9123 break;
9124 default:
9125 UNIMPLEMENTED();
9126 break;
9127 }
9128 return length;
9129 }
9130
EVALUATE(LXR)9131 EVALUATE(LXR) {
9132 UNIMPLEMENTED();
9133 USE(instr);
9134 return 0;
9135 }
9136
EVALUATE(LPDFR)9137 EVALUATE(LPDFR) {
9138 UNIMPLEMENTED();
9139 USE(instr);
9140 return 0;
9141 }
9142
EVALUATE(LNDFR)9143 EVALUATE(LNDFR) {
9144 UNIMPLEMENTED();
9145 USE(instr);
9146 return 0;
9147 }
9148
EVALUATE(LCDFR)9149 EVALUATE(LCDFR) {
9150 UNIMPLEMENTED();
9151 USE(instr);
9152 return 0;
9153 }
9154
EVALUATE(LZER)9155 EVALUATE(LZER) {
9156 UNIMPLEMENTED();
9157 USE(instr);
9158 return 0;
9159 }
9160
EVALUATE(LZDR)9161 EVALUATE(LZDR) {
9162 DCHECK_OPCODE(LZDR);
9163 DECODE_RRE_INSTRUCTION_NO_R2(r1);
9164 set_d_register_from_double(r1, 0.0);
9165 return length;
9166 }
9167
EVALUATE(LZXR)9168 EVALUATE(LZXR) {
9169 UNIMPLEMENTED();
9170 USE(instr);
9171 return 0;
9172 }
9173
EVALUATE(SFPC)9174 EVALUATE(SFPC) {
9175 UNIMPLEMENTED();
9176 USE(instr);
9177 return 0;
9178 }
9179
EVALUATE(SFASR)9180 EVALUATE(SFASR) {
9181 UNIMPLEMENTED();
9182 USE(instr);
9183 return 0;
9184 }
9185
EVALUATE(EFPC)9186 EVALUATE(EFPC) {
9187 UNIMPLEMENTED();
9188 USE(instr);
9189 return 0;
9190 }
9191
EVALUATE(CELFBR)9192 EVALUATE(CELFBR) {
9193 DCHECK_OPCODE(CELFBR);
9194 DECODE_RRE_INSTRUCTION(r1, r2);
9195 uint32_t r2_val = get_low_register<uint32_t>(r2);
9196 float r1_val = static_cast<float>(r2_val);
9197 set_d_register_from_float32(r1, r1_val);
9198 return length;
9199 }
9200
EVALUATE(CDLFBR)9201 EVALUATE(CDLFBR) {
9202 DCHECK_OPCODE(CDLFBR);
9203 DECODE_RRE_INSTRUCTION(r1, r2);
9204 uint32_t r2_val = get_low_register<uint32_t>(r2);
9205 double r1_val = static_cast<double>(r2_val);
9206 set_d_register_from_double(r1, r1_val);
9207 return length;
9208 }
9209
EVALUATE(CXLFBR)9210 EVALUATE(CXLFBR) {
9211 UNIMPLEMENTED();
9212 USE(instr);
9213 return 0;
9214 }
9215
EVALUATE(CEFBRA)9216 EVALUATE(CEFBRA) {
9217 DCHECK_OPCODE(CEFBRA);
9218 DECODE_RRE_INSTRUCTION(r1, r2);
9219 int32_t fr2_val = get_low_register<int32_t>(r2);
9220 float fr1_val = static_cast<float>(fr2_val);
9221 set_d_register_from_float32(r1, fr1_val);
9222 return length;
9223 }
9224
EVALUATE(CDFBRA)9225 EVALUATE(CDFBRA) {
9226 DCHECK_OPCODE(CDFBRA);
9227 DECODE_RRE_INSTRUCTION(r1, r2);
9228 int32_t r2_val = get_low_register<int32_t>(r2);
9229 double r1_val = static_cast<double>(r2_val);
9230 set_d_register_from_double(r1, r1_val);
9231 return length;
9232 }
9233
EVALUATE(CXFBRA)9234 EVALUATE(CXFBRA) {
9235 UNIMPLEMENTED();
9236 USE(instr);
9237 return 0;
9238 }
9239
EVALUATE(CFEBRA)9240 EVALUATE(CFEBRA) {
9241 DCHECK_OPCODE(CFEBRA);
9242 DECODE_RRE_INSTRUCTION_M3(r1, r2, mask_val);
9243 float r2_fval = get_float32_from_d_register(r2);
9244 int32_t r1_val = 0;
9245
9246 SetS390RoundConditionCode(r2_fval, INT32_MAX, INT32_MIN);
9247
9248 switch (mask_val) {
9249 case CURRENT_ROUNDING_MODE:
9250 case ROUND_TO_PREPARE_FOR_SHORTER_PRECISION: {
9251 r1_val = static_cast<int32_t>(r2_fval);
9252 break;
9253 }
9254 case ROUND_TO_NEAREST_WITH_TIES_AWAY_FROM_0: {
9255 float ceil_val = std::ceil(r2_fval);
9256 float floor_val = std::floor(r2_fval);
9257 float sub_val1 = std::fabs(r2_fval - floor_val);
9258 float sub_val2 = std::fabs(r2_fval - ceil_val);
9259 if (sub_val1 > sub_val2) {
9260 r1_val = static_cast<int32_t>(ceil_val);
9261 } else if (sub_val1 < sub_val2) {
9262 r1_val = static_cast<int32_t>(floor_val);
9263 } else { // round away from zero:
9264 if (r2_fval > 0.0) {
9265 r1_val = static_cast<int32_t>(ceil_val);
9266 } else {
9267 r1_val = static_cast<int32_t>(floor_val);
9268 }
9269 }
9270 break;
9271 }
9272 case ROUND_TO_NEAREST_WITH_TIES_TO_EVEN: {
9273 float ceil_val = std::ceil(r2_fval);
9274 float floor_val = std::floor(r2_fval);
9275 float sub_val1 = std::fabs(r2_fval - floor_val);
9276 float sub_val2 = std::fabs(r2_fval - ceil_val);
9277 if (sub_val1 > sub_val2) {
9278 r1_val = static_cast<int32_t>(ceil_val);
9279 } else if (sub_val1 < sub_val2) {
9280 r1_val = static_cast<int32_t>(floor_val);
9281 } else { // check which one is even:
9282 int32_t c_v = static_cast<int32_t>(ceil_val);
9283 int32_t f_v = static_cast<int32_t>(floor_val);
9284 if (f_v % 2 == 0)
9285 r1_val = f_v;
9286 else
9287 r1_val = c_v;
9288 }
9289 break;
9290 }
9291 case ROUND_TOWARD_0: {
9292 // check for overflow, cast r2_fval to 64bit integer
9293 // then check value within the range of INT_MIN and INT_MAX
9294 // and set condition code accordingly
9295 int64_t temp = static_cast<int64_t>(r2_fval);
9296 if (temp < INT_MIN || temp > INT_MAX) {
9297 condition_reg_ = CC_OF;
9298 }
9299 r1_val = static_cast<int32_t>(r2_fval);
9300 break;
9301 }
9302 case ROUND_TOWARD_PLUS_INFINITE: {
9303 r1_val = static_cast<int32_t>(std::ceil(r2_fval));
9304 break;
9305 }
9306 case ROUND_TOWARD_MINUS_INFINITE: {
9307 // check for overflow, cast r2_fval to 64bit integer
9308 // then check value within the range of INT_MIN and INT_MAX
9309 // and set condition code accordingly
9310 int64_t temp = static_cast<int64_t>(std::floor(r2_fval));
9311 if (temp < INT_MIN || temp > INT_MAX) {
9312 condition_reg_ = CC_OF;
9313 }
9314 r1_val = static_cast<int32_t>(std::floor(r2_fval));
9315 break;
9316 }
9317 default:
9318 UNREACHABLE();
9319 }
9320 set_low_register(r1, r1_val);
9321 return length;
9322 }
9323
EVALUATE(CFDBRA)9324 EVALUATE(CFDBRA) {
9325 DCHECK_OPCODE(CFDBRA);
9326 DECODE_RRE_INSTRUCTION_M3(r1, r2, mask_val);
9327 double r2_val = get_double_from_d_register(r2);
9328 int32_t r1_val = 0;
9329
9330 SetS390RoundConditionCode(r2_val, INT32_MAX, INT32_MIN);
9331
9332 switch (mask_val) {
9333 case CURRENT_ROUNDING_MODE:
9334 case ROUND_TO_PREPARE_FOR_SHORTER_PRECISION: {
9335 r1_val = static_cast<int32_t>(r2_val);
9336 break;
9337 }
9338 case ROUND_TO_NEAREST_WITH_TIES_AWAY_FROM_0: {
9339 double ceil_val = std::ceil(r2_val);
9340 double floor_val = std::floor(r2_val);
9341 double sub_val1 = std::fabs(r2_val - floor_val);
9342 double sub_val2 = std::fabs(r2_val - ceil_val);
9343 if (sub_val1 > sub_val2) {
9344 r1_val = static_cast<int32_t>(ceil_val);
9345 } else if (sub_val1 < sub_val2) {
9346 r1_val = static_cast<int32_t>(floor_val);
9347 } else { // round away from zero:
9348 if (r2_val > 0.0) {
9349 r1_val = static_cast<int32_t>(ceil_val);
9350 } else {
9351 r1_val = static_cast<int32_t>(floor_val);
9352 }
9353 }
9354 break;
9355 }
9356 case ROUND_TO_NEAREST_WITH_TIES_TO_EVEN: {
9357 double ceil_val = std::ceil(r2_val);
9358 double floor_val = std::floor(r2_val);
9359 double sub_val1 = std::fabs(r2_val - floor_val);
9360 double sub_val2 = std::fabs(r2_val - ceil_val);
9361 if (sub_val1 > sub_val2) {
9362 r1_val = static_cast<int32_t>(ceil_val);
9363 } else if (sub_val1 < sub_val2) {
9364 r1_val = static_cast<int32_t>(floor_val);
9365 } else { // check which one is even:
9366 int32_t c_v = static_cast<int32_t>(ceil_val);
9367 int32_t f_v = static_cast<int32_t>(floor_val);
9368 if (f_v % 2 == 0)
9369 r1_val = f_v;
9370 else
9371 r1_val = c_v;
9372 }
9373 break;
9374 }
9375 case ROUND_TOWARD_0: {
9376 // check for overflow, cast r2_val to 64bit integer
9377 // then check value within the range of INT_MIN and INT_MAX
9378 // and set condition code accordingly
9379 int64_t temp = static_cast<int64_t>(r2_val);
9380 if (temp < INT_MIN || temp > INT_MAX) {
9381 condition_reg_ = CC_OF;
9382 }
9383 r1_val = static_cast<int32_t>(r2_val);
9384 break;
9385 }
9386 case ROUND_TOWARD_PLUS_INFINITE: {
9387 r1_val = static_cast<int32_t>(std::ceil(r2_val));
9388 break;
9389 }
9390 case ROUND_TOWARD_MINUS_INFINITE: {
9391 // check for overflow, cast r2_val to 64bit integer
9392 // then check value within the range of INT_MIN and INT_MAX
9393 // and set condition code accordingly
9394 int64_t temp = static_cast<int64_t>(std::floor(r2_val));
9395 if (temp < INT_MIN || temp > INT_MAX) {
9396 condition_reg_ = CC_OF;
9397 }
9398 r1_val = static_cast<int32_t>(std::floor(r2_val));
9399 break;
9400 }
9401 default:
9402 UNREACHABLE();
9403 }
9404 set_low_register(r1, r1_val);
9405 return length;
9406 }
9407
EVALUATE(CFXBRA)9408 EVALUATE(CFXBRA) {
9409 UNIMPLEMENTED();
9410 USE(instr);
9411 return 0;
9412 }
9413
EVALUATE(CLFEBR)9414 EVALUATE(CLFEBR) {
9415 DCHECK_OPCODE(CLFEBR);
9416 DECODE_RRE_INSTRUCTION(r1, r2);
9417 float r2_val = get_float32_from_d_register(r2);
9418 uint32_t r1_val = static_cast<uint32_t>(r2_val);
9419 set_low_register(r1, r1_val);
9420 SetS390ConvertConditionCode<double>(r2_val, r1_val, UINT32_MAX);
9421 return length;
9422 }
9423
EVALUATE(CLFDBR)9424 EVALUATE(CLFDBR) {
9425 DCHECK_OPCODE(CLFDBR);
9426 DECODE_RRE_INSTRUCTION(r1, r2);
9427 double r2_val = get_double_from_d_register(r2);
9428 uint32_t r1_val = static_cast<uint32_t>(r2_val);
9429 set_low_register(r1, r1_val);
9430 SetS390ConvertConditionCode<double>(r2_val, r1_val, UINT32_MAX);
9431 return length;
9432 }
9433
EVALUATE(CLFXBR)9434 EVALUATE(CLFXBR) {
9435 UNIMPLEMENTED();
9436 USE(instr);
9437 return 0;
9438 }
9439
EVALUATE(CELGBR)9440 EVALUATE(CELGBR) {
9441 DCHECK_OPCODE(CELGBR);
9442 DECODE_RRE_INSTRUCTION(r1, r2);
9443 uint64_t r2_val = get_register(r2);
9444 float r1_val = static_cast<float>(r2_val);
9445 set_d_register_from_float32(r1, r1_val);
9446 return length;
9447 }
9448
EVALUATE(CDLGBR)9449 EVALUATE(CDLGBR) {
9450 DCHECK_OPCODE(CDLGBR);
9451 DECODE_RRE_INSTRUCTION(r1, r2);
9452 uint64_t r2_val = get_register(r2);
9453 double r1_val = static_cast<double>(r2_val);
9454 set_d_register_from_double(r1, r1_val);
9455 return length;
9456 }
9457
EVALUATE(CXLGBR)9458 EVALUATE(CXLGBR) {
9459 UNIMPLEMENTED();
9460 USE(instr);
9461 return 0;
9462 }
9463
EVALUATE(CEGBRA)9464 EVALUATE(CEGBRA) {
9465 DCHECK_OPCODE(CEGBRA);
9466 DECODE_RRE_INSTRUCTION(r1, r2);
9467 int64_t fr2_val = get_register(r2);
9468 float fr1_val = static_cast<float>(fr2_val);
9469 set_d_register_from_float32(r1, fr1_val);
9470 return length;
9471 }
9472
EVALUATE(CDGBRA)9473 EVALUATE(CDGBRA) {
9474 DCHECK_OPCODE(CDGBRA);
9475 DECODE_RRE_INSTRUCTION(r1, r2);
9476 int64_t r2_val = get_register(r2);
9477 double r1_val = static_cast<double>(r2_val);
9478 set_d_register_from_double(r1, r1_val);
9479 return length;
9480 }
9481
EVALUATE(CXGBRA)9482 EVALUATE(CXGBRA) {
9483 UNIMPLEMENTED();
9484 USE(instr);
9485 return 0;
9486 }
9487
EVALUATE(CGEBRA)9488 EVALUATE(CGEBRA) {
9489 DCHECK_OPCODE(CGEBRA);
9490 DECODE_RRE_INSTRUCTION_M3(r1, r2, mask_val);
9491 float r2_fval = get_float32_from_d_register(r2);
9492 int64_t r1_val = 0;
9493
9494 SetS390RoundConditionCode(r2_fval, INT64_MAX, INT64_MIN);
9495
9496 switch (mask_val) {
9497 case CURRENT_ROUNDING_MODE:
9498 case ROUND_TO_NEAREST_WITH_TIES_AWAY_FROM_0:
9499 case ROUND_TO_PREPARE_FOR_SHORTER_PRECISION: {
9500 UNIMPLEMENTED();
9501 break;
9502 }
9503 case ROUND_TO_NEAREST_WITH_TIES_TO_EVEN: {
9504 float ceil_val = std::ceil(r2_fval);
9505 float floor_val = std::floor(r2_fval);
9506 if (std::abs(r2_fval - floor_val) > std::abs(r2_fval - ceil_val)) {
9507 r1_val = static_cast<int64_t>(ceil_val);
9508 } else if (std::abs(r2_fval - floor_val) < std::abs(r2_fval - ceil_val)) {
9509 r1_val = static_cast<int64_t>(floor_val);
9510 } else { // check which one is even:
9511 int64_t c_v = static_cast<int64_t>(ceil_val);
9512 int64_t f_v = static_cast<int64_t>(floor_val);
9513 if (f_v % 2 == 0)
9514 r1_val = f_v;
9515 else
9516 r1_val = c_v;
9517 }
9518 break;
9519 }
9520 case ROUND_TOWARD_0: {
9521 r1_val = static_cast<int64_t>(r2_fval);
9522 break;
9523 }
9524 case ROUND_TOWARD_PLUS_INFINITE: {
9525 r1_val = static_cast<int64_t>(std::ceil(r2_fval));
9526 break;
9527 }
9528 case ROUND_TOWARD_MINUS_INFINITE: {
9529 r1_val = static_cast<int64_t>(std::floor(r2_fval));
9530 break;
9531 }
9532 default:
9533 UNREACHABLE();
9534 }
9535 set_register(r1, r1_val);
9536 return length;
9537 }
9538
EVALUATE(CGDBRA)9539 EVALUATE(CGDBRA) {
9540 DCHECK_OPCODE(CGDBRA);
9541 DECODE_RRE_INSTRUCTION_M3(r1, r2, mask_val);
9542 double r2_val = get_double_from_d_register(r2);
9543 int64_t r1_val = 0;
9544
9545 SetS390RoundConditionCode(r2_val, INT64_MAX, INT64_MIN);
9546
9547 switch (mask_val) {
9548 case CURRENT_ROUNDING_MODE:
9549 case ROUND_TO_NEAREST_WITH_TIES_AWAY_FROM_0:
9550 case ROUND_TO_PREPARE_FOR_SHORTER_PRECISION: {
9551 UNIMPLEMENTED();
9552 break;
9553 }
9554 case ROUND_TO_NEAREST_WITH_TIES_TO_EVEN: {
9555 double ceil_val = std::ceil(r2_val);
9556 double floor_val = std::floor(r2_val);
9557 if (std::abs(r2_val - floor_val) > std::abs(r2_val - ceil_val)) {
9558 r1_val = static_cast<int64_t>(ceil_val);
9559 } else if (std::abs(r2_val - floor_val) < std::abs(r2_val - ceil_val)) {
9560 r1_val = static_cast<int64_t>(floor_val);
9561 } else { // check which one is even:
9562 int64_t c_v = static_cast<int64_t>(ceil_val);
9563 int64_t f_v = static_cast<int64_t>(floor_val);
9564 if (f_v % 2 == 0)
9565 r1_val = f_v;
9566 else
9567 r1_val = c_v;
9568 }
9569 break;
9570 }
9571 case ROUND_TOWARD_0: {
9572 r1_val = static_cast<int64_t>(r2_val);
9573 break;
9574 }
9575 case ROUND_TOWARD_PLUS_INFINITE: {
9576 r1_val = static_cast<int64_t>(std::ceil(r2_val));
9577 break;
9578 }
9579 case ROUND_TOWARD_MINUS_INFINITE: {
9580 r1_val = static_cast<int64_t>(std::floor(r2_val));
9581 break;
9582 }
9583 default:
9584 UNREACHABLE();
9585 }
9586 set_register(r1, r1_val);
9587 return length;
9588 }
9589
EVALUATE(CGXBRA)9590 EVALUATE(CGXBRA) {
9591 UNIMPLEMENTED();
9592 USE(instr);
9593 return 0;
9594 }
9595
EVALUATE(CLGEBR)9596 EVALUATE(CLGEBR) {
9597 DCHECK_OPCODE(CLGEBR);
9598 DECODE_RRE_INSTRUCTION(r1, r2);
9599 float r2_val = get_float32_from_d_register(r2);
9600 uint64_t r1_val = static_cast<uint64_t>(r2_val);
9601 set_register(r1, r1_val);
9602 SetS390ConvertConditionCode<double>(r2_val, r1_val, UINT64_MAX);
9603 return length;
9604 }
9605
EVALUATE(CLGDBR)9606 EVALUATE(CLGDBR) {
9607 DCHECK_OPCODE(CLGDBR);
9608 DECODE_RRE_INSTRUCTION(r1, r2);
9609 double r2_val = get_double_from_d_register(r2);
9610 uint64_t r1_val = static_cast<uint64_t>(r2_val);
9611 set_register(r1, r1_val);
9612 SetS390ConvertConditionCode<double>(r2_val, r1_val, UINT64_MAX);
9613 return length;
9614 }
9615
EVALUATE(CFER)9616 EVALUATE(CFER) {
9617 UNIMPLEMENTED();
9618 USE(instr);
9619 return 0;
9620 }
9621
EVALUATE(CFDR)9622 EVALUATE(CFDR) {
9623 UNIMPLEMENTED();
9624 USE(instr);
9625 return 0;
9626 }
9627
EVALUATE(CFXR)9628 EVALUATE(CFXR) {
9629 UNIMPLEMENTED();
9630 USE(instr);
9631 return 0;
9632 }
9633
EVALUATE(LDGR)9634 EVALUATE(LDGR) {
9635 DCHECK_OPCODE(LDGR);
9636 // Load FPR from GPR (L <- 64)
9637 DECODE_RRE_INSTRUCTION(r1, r2);
9638 uint64_t int_val = get_register(r2);
9639 // double double_val = bit_cast<double, uint64_t>(int_val);
9640 // set_d_register_from_double(rreInst->R1Value(), double_val);
9641 set_d_register(r1, int_val);
9642 return length;
9643 }
9644
EVALUATE(CGER)9645 EVALUATE(CGER) {
9646 UNIMPLEMENTED();
9647 USE(instr);
9648 return 0;
9649 }
9650
EVALUATE(CGDR)9651 EVALUATE(CGDR) {
9652 UNIMPLEMENTED();
9653 USE(instr);
9654 return 0;
9655 }
9656
EVALUATE(CGXR)9657 EVALUATE(CGXR) {
9658 UNIMPLEMENTED();
9659 USE(instr);
9660 return 0;
9661 }
9662
EVALUATE(LGDR)9663 EVALUATE(LGDR) {
9664 DCHECK_OPCODE(LGDR);
9665 DECODE_RRE_INSTRUCTION(r1, r2);
9666 // Load GPR from FPR (64 <- L)
9667 int64_t double_val = get_d_register(r2);
9668 set_register(r1, double_val);
9669 return length;
9670 }
9671
EVALUATE(MDTR)9672 EVALUATE(MDTR) {
9673 UNIMPLEMENTED();
9674 USE(instr);
9675 return 0;
9676 }
9677
EVALUATE(MDTRA)9678 EVALUATE(MDTRA) {
9679 UNIMPLEMENTED();
9680 USE(instr);
9681 return 0;
9682 }
9683
EVALUATE(DDTRA)9684 EVALUATE(DDTRA) {
9685 UNIMPLEMENTED();
9686 USE(instr);
9687 return 0;
9688 }
9689
EVALUATE(ADTRA)9690 EVALUATE(ADTRA) {
9691 UNIMPLEMENTED();
9692 USE(instr);
9693 return 0;
9694 }
9695
EVALUATE(SDTRA)9696 EVALUATE(SDTRA) {
9697 UNIMPLEMENTED();
9698 USE(instr);
9699 return 0;
9700 }
9701
EVALUATE(LDETR)9702 EVALUATE(LDETR) {
9703 UNIMPLEMENTED();
9704 USE(instr);
9705 return 0;
9706 }
9707
EVALUATE(LEDTR)9708 EVALUATE(LEDTR) {
9709 UNIMPLEMENTED();
9710 USE(instr);
9711 return 0;
9712 }
9713
EVALUATE(LTDTR)9714 EVALUATE(LTDTR) {
9715 UNIMPLEMENTED();
9716 USE(instr);
9717 return 0;
9718 }
9719
EVALUATE(FIDTR)9720 EVALUATE(FIDTR) {
9721 UNIMPLEMENTED();
9722 USE(instr);
9723 return 0;
9724 }
9725
EVALUATE(MXTRA)9726 EVALUATE(MXTRA) {
9727 UNIMPLEMENTED();
9728 USE(instr);
9729 return 0;
9730 }
9731
EVALUATE(DXTRA)9732 EVALUATE(DXTRA) {
9733 UNIMPLEMENTED();
9734 USE(instr);
9735 return 0;
9736 }
9737
EVALUATE(AXTRA)9738 EVALUATE(AXTRA) {
9739 UNIMPLEMENTED();
9740 USE(instr);
9741 return 0;
9742 }
9743
EVALUATE(SXTRA)9744 EVALUATE(SXTRA) {
9745 UNIMPLEMENTED();
9746 USE(instr);
9747 return 0;
9748 }
9749
EVALUATE(LXDTR)9750 EVALUATE(LXDTR) {
9751 UNIMPLEMENTED();
9752 USE(instr);
9753 return 0;
9754 }
9755
EVALUATE(LDXTR)9756 EVALUATE(LDXTR) {
9757 UNIMPLEMENTED();
9758 USE(instr);
9759 return 0;
9760 }
9761
EVALUATE(LTXTR)9762 EVALUATE(LTXTR) {
9763 UNIMPLEMENTED();
9764 USE(instr);
9765 return 0;
9766 }
9767
EVALUATE(FIXTR)9768 EVALUATE(FIXTR) {
9769 UNIMPLEMENTED();
9770 USE(instr);
9771 return 0;
9772 }
9773
EVALUATE(KDTR)9774 EVALUATE(KDTR) {
9775 UNIMPLEMENTED();
9776 USE(instr);
9777 return 0;
9778 }
9779
EVALUATE(CGDTRA)9780 EVALUATE(CGDTRA) {
9781 UNIMPLEMENTED();
9782 USE(instr);
9783 return 0;
9784 }
9785
EVALUATE(CUDTR)9786 EVALUATE(CUDTR) {
9787 UNIMPLEMENTED();
9788 USE(instr);
9789 return 0;
9790 }
9791
EVALUATE(CDTR)9792 EVALUATE(CDTR) {
9793 UNIMPLEMENTED();
9794 USE(instr);
9795 return 0;
9796 }
9797
EVALUATE(EEDTR)9798 EVALUATE(EEDTR) {
9799 UNIMPLEMENTED();
9800 USE(instr);
9801 return 0;
9802 }
9803
EVALUATE(ESDTR)9804 EVALUATE(ESDTR) {
9805 UNIMPLEMENTED();
9806 USE(instr);
9807 return 0;
9808 }
9809
EVALUATE(KXTR)9810 EVALUATE(KXTR) {
9811 UNIMPLEMENTED();
9812 USE(instr);
9813 return 0;
9814 }
9815
EVALUATE(CGXTRA)9816 EVALUATE(CGXTRA) {
9817 UNIMPLEMENTED();
9818 USE(instr);
9819 return 0;
9820 }
9821
EVALUATE(CUXTR)9822 EVALUATE(CUXTR) {
9823 UNIMPLEMENTED();
9824 USE(instr);
9825 return 0;
9826 }
9827
EVALUATE(CSXTR)9828 EVALUATE(CSXTR) {
9829 UNIMPLEMENTED();
9830 USE(instr);
9831 return 0;
9832 }
9833
EVALUATE(CXTR)9834 EVALUATE(CXTR) {
9835 UNIMPLEMENTED();
9836 USE(instr);
9837 return 0;
9838 }
9839
EVALUATE(EEXTR)9840 EVALUATE(EEXTR) {
9841 UNIMPLEMENTED();
9842 USE(instr);
9843 return 0;
9844 }
9845
EVALUATE(ESXTR)9846 EVALUATE(ESXTR) {
9847 UNIMPLEMENTED();
9848 USE(instr);
9849 return 0;
9850 }
9851
EVALUATE(CDGTRA)9852 EVALUATE(CDGTRA) {
9853 UNIMPLEMENTED();
9854 USE(instr);
9855 return 0;
9856 }
9857
EVALUATE(CDUTR)9858 EVALUATE(CDUTR) {
9859 UNIMPLEMENTED();
9860 USE(instr);
9861 return 0;
9862 }
9863
EVALUATE(CDSTR)9864 EVALUATE(CDSTR) {
9865 UNIMPLEMENTED();
9866 USE(instr);
9867 return 0;
9868 }
9869
EVALUATE(CEDTR)9870 EVALUATE(CEDTR) {
9871 UNIMPLEMENTED();
9872 USE(instr);
9873 return 0;
9874 }
9875
EVALUATE(QADTR)9876 EVALUATE(QADTR) {
9877 UNIMPLEMENTED();
9878 USE(instr);
9879 return 0;
9880 }
9881
EVALUATE(IEDTR)9882 EVALUATE(IEDTR) {
9883 UNIMPLEMENTED();
9884 USE(instr);
9885 return 0;
9886 }
9887
EVALUATE(RRDTR)9888 EVALUATE(RRDTR) {
9889 UNIMPLEMENTED();
9890 USE(instr);
9891 return 0;
9892 }
9893
EVALUATE(CXGTRA)9894 EVALUATE(CXGTRA) {
9895 UNIMPLEMENTED();
9896 USE(instr);
9897 return 0;
9898 }
9899
EVALUATE(CXUTR)9900 EVALUATE(CXUTR) {
9901 UNIMPLEMENTED();
9902 USE(instr);
9903 return 0;
9904 }
9905
EVALUATE(CXSTR)9906 EVALUATE(CXSTR) {
9907 UNIMPLEMENTED();
9908 USE(instr);
9909 return 0;
9910 }
9911
EVALUATE(CEXTR)9912 EVALUATE(CEXTR) {
9913 UNIMPLEMENTED();
9914 USE(instr);
9915 return 0;
9916 }
9917
EVALUATE(QAXTR)9918 EVALUATE(QAXTR) {
9919 UNIMPLEMENTED();
9920 USE(instr);
9921 return 0;
9922 }
9923
EVALUATE(IEXTR)9924 EVALUATE(IEXTR) {
9925 UNIMPLEMENTED();
9926 USE(instr);
9927 return 0;
9928 }
9929
EVALUATE(RRXTR)9930 EVALUATE(RRXTR) {
9931 UNIMPLEMENTED();
9932 USE(instr);
9933 return 0;
9934 }
9935
EVALUATE(LPGR)9936 EVALUATE(LPGR) {
9937 DCHECK_OPCODE(LPGR);
9938 // Load Positive (32)
9939 DECODE_RRE_INSTRUCTION(r1, r2);
9940 int64_t r2_val = get_register(r2);
9941 r2_val = (r2_val < 0) ? -r2_val : r2_val; // If negative, then negate it.
9942 set_register(r1, r2_val);
9943 SetS390ConditionCode<int64_t>(r2_val, 0);
9944 if (r2_val == (static_cast<int64_t>(1) << 63)) {
9945 SetS390OverflowCode(true);
9946 }
9947 return length;
9948 }
9949
EVALUATE(LNGR)9950 EVALUATE(LNGR) {
9951 DCHECK_OPCODE(LNGR);
9952 // Load Negative (64)
9953 DECODE_RRE_INSTRUCTION(r1, r2);
9954 int64_t r2_val = get_register(r2);
9955 r2_val = (r2_val >= 0) ? -r2_val : r2_val; // If pos, then negate it.
9956 set_register(r1, r2_val);
9957 condition_reg_ = (r2_val == 0) ? CC_EQ : CC_LT; // CC0 - result is zero
9958 // CC1 - result is negative
9959 return length;
9960 }
9961
EVALUATE(LTGR)9962 EVALUATE(LTGR) {
9963 DCHECK_OPCODE(LTGR);
9964 // Load Register (64)
9965 DECODE_RRE_INSTRUCTION(r1, r2);
9966 int64_t r2_val = get_register(r2);
9967 SetS390ConditionCode<int64_t>(r2_val, 0);
9968 set_register(r1, get_register(r2));
9969 return length;
9970 }
9971
EVALUATE(LCGR)9972 EVALUATE(LCGR) {
9973 DCHECK_OPCODE(LCGR);
9974 DECODE_RRE_INSTRUCTION(r1, r2);
9975 int64_t r2_val = get_register(r2);
9976 int64_t result = 0;
9977 bool isOF = false;
9978 #ifdef V8_TARGET_ARCH_S390X
9979 isOF = __builtin_ssubl_overflow(0L, r2_val, &result);
9980 #else
9981 isOF = __builtin_ssubll_overflow(0L, r2_val, &result);
9982 #endif
9983 set_register(r1, result);
9984 SetS390ConditionCode<int64_t>(result, 0);
9985 if (isOF) {
9986 SetS390OverflowCode(true);
9987 }
9988 return length;
9989 }
9990
EVALUATE(SGR)9991 EVALUATE(SGR) {
9992 DCHECK_OPCODE(SGR);
9993 DECODE_RRE_INSTRUCTION(r1, r2);
9994 int64_t r1_val = get_register(r1);
9995 int64_t r2_val = get_register(r2);
9996 bool isOF = false;
9997 isOF = CheckOverflowForIntSub(r1_val, r2_val, int64_t);
9998 r1_val -= r2_val;
9999 SetS390ConditionCode<int64_t>(r1_val, 0);
10000 SetS390OverflowCode(isOF);
10001 set_register(r1, r1_val);
10002 return length;
10003 }
10004
EVALUATE(ALGR)10005 EVALUATE(ALGR) {
10006 UNIMPLEMENTED();
10007 USE(instr);
10008 return 0;
10009 }
10010
EVALUATE(SLGR)10011 EVALUATE(SLGR) {
10012 UNIMPLEMENTED();
10013 USE(instr);
10014 return 0;
10015 }
10016
EVALUATE(MSGR)10017 EVALUATE(MSGR) {
10018 DCHECK_OPCODE(MSGR);
10019 DECODE_RRE_INSTRUCTION(r1, r2);
10020 int64_t r1_val = get_register(r1);
10021 int64_t r2_val = get_register(r2);
10022 set_register(r1, r1_val * r2_val);
10023 return length;
10024 }
10025
EVALUATE(MSGRKC)10026 EVALUATE(MSGRKC) {
10027 DCHECK_OPCODE(MSGRKC);
10028 DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
10029 int64_t r2_val = get_register(r2);
10030 int64_t r3_val = get_register(r3);
10031 volatile int64_t result64 = r2_val * r3_val;
10032 bool isOF = ((r2_val == -1 && result64 == (static_cast<int64_t>(1L) << 63)) ||
10033 (r2_val != 0 && result64 / r2_val != r3_val));
10034 SetS390ConditionCode<int64_t>(result64, 0);
10035 SetS390OverflowCode(isOF);
10036 set_register(r1, result64);
10037 return length;
10038 }
10039
EVALUATE(DSGR)10040 EVALUATE(DSGR) {
10041 DCHECK_OPCODE(DSGR);
10042 DECODE_RRE_INSTRUCTION(r1, r2);
10043
10044 DCHECK(r1 % 2 == 0);
10045
10046 int64_t dividend = get_register(r1 + 1);
10047 int64_t divisor = get_register(r2);
10048 set_register(r1, dividend % divisor);
10049 set_register(r1 + 1, dividend / divisor);
10050 return length;
10051 }
10052
EVALUATE(LRVGR)10053 EVALUATE(LRVGR) {
10054 DCHECK_OPCODE(LRVGR);
10055 DECODE_RRE_INSTRUCTION(r1, r2);
10056 int64_t r2_val = get_register(r2);
10057 int64_t r1_val = ByteReverse(r2_val);
10058
10059 set_register(r1, r1_val);
10060 return length;
10061 }
10062
EVALUATE(LPGFR)10063 EVALUATE(LPGFR) {
10064 DCHECK_OPCODE(LPGFR);
10065 // Load Positive (32)
10066 DECODE_RRE_INSTRUCTION(r1, r2);
10067 int32_t r2_val = get_low_register<int32_t>(r2);
10068 // If negative, then negate it.
10069 int64_t r1_val = static_cast<int64_t>((r2_val < 0) ? -r2_val : r2_val);
10070 set_register(r1, r1_val);
10071 SetS390ConditionCode<int64_t>(r1_val, 0);
10072 return length;
10073 }
10074
EVALUATE(LNGFR)10075 EVALUATE(LNGFR) {
10076 UNIMPLEMENTED();
10077 USE(instr);
10078 return 0;
10079 }
10080
EVALUATE(LTGFR)10081 EVALUATE(LTGFR) {
10082 DCHECK_OPCODE(LTGFR);
10083 DECODE_RRE_INSTRUCTION(r1, r2);
10084 // Load and Test Register (64 <- 32) (Sign Extends 32-bit val)
10085 // Load Register (64 <- 32) (Sign Extends 32-bit val)
10086 int32_t r2_val = get_low_register<int32_t>(r2);
10087 int64_t result = static_cast<int64_t>(r2_val);
10088 set_register(r1, result);
10089 SetS390ConditionCode<int64_t>(result, 0);
10090 return length;
10091 }
10092
EVALUATE(LCGFR)10093 EVALUATE(LCGFR) {
10094 DCHECK_OPCODE(LCGFR);
10095 DECODE_RRE_INSTRUCTION(r1, r2);
10096 // Load and Test Register (64 <- 32) (Sign Extends 32-bit val)
10097 // Load Register (64 <- 32) (Sign Extends 32-bit val)
10098 int32_t r2_val = get_low_register<int32_t>(r2);
10099 int64_t result = static_cast<int64_t>(r2_val);
10100 set_register(r1, result);
10101 return length;
10102 }
10103
EVALUATE(LLGFR)10104 EVALUATE(LLGFR) {
10105 DCHECK_OPCODE(LLGFR);
10106 DECODE_RRE_INSTRUCTION(r1, r2);
10107 int32_t r2_val = get_low_register<int32_t>(r2);
10108 uint64_t r2_finalval = (static_cast<uint64_t>(r2_val) & 0x00000000ffffffff);
10109 set_register(r1, r2_finalval);
10110 return length;
10111 }
10112
EVALUATE(LLGTR)10113 EVALUATE(LLGTR) {
10114 UNIMPLEMENTED();
10115 USE(instr);
10116 return 0;
10117 }
10118
EVALUATE(AGFR)10119 EVALUATE(AGFR) {
10120 DCHECK_OPCODE(AGFR);
10121 DECODE_RRE_INSTRUCTION(r1, r2);
10122 // Add Register (64 <- 32) (Sign Extends 32-bit val)
10123 int64_t r1_val = get_register(r1);
10124 int64_t r2_val = static_cast<int64_t>(get_low_register<int32_t>(r2));
10125 bool isOF = CheckOverflowForIntAdd(r1_val, r2_val, int64_t);
10126 r1_val += r2_val;
10127 SetS390ConditionCode<int64_t>(r1_val, 0);
10128 SetS390OverflowCode(isOF);
10129 set_register(r1, r1_val);
10130 return length;
10131 }
10132
EVALUATE(SGFR)10133 EVALUATE(SGFR) {
10134 DCHECK_OPCODE(SGFR);
10135 DECODE_RRE_INSTRUCTION(r1, r2);
10136 // Sub Reg (64 <- 32)
10137 int64_t r1_val = get_register(r1);
10138 int64_t r2_val = static_cast<int64_t>(get_low_register<int32_t>(r2));
10139 bool isOF = false;
10140 isOF = CheckOverflowForIntSub(r1_val, r2_val, int64_t);
10141 r1_val -= r2_val;
10142 SetS390ConditionCode<int64_t>(r1_val, 0);
10143 SetS390OverflowCode(isOF);
10144 set_register(r1, r1_val);
10145 return length;
10146 }
10147
EVALUATE(ALGFR)10148 EVALUATE(ALGFR) {
10149 UNIMPLEMENTED();
10150 USE(instr);
10151 return 0;
10152 }
10153
EVALUATE(SLGFR)10154 EVALUATE(SLGFR) {
10155 UNIMPLEMENTED();
10156 USE(instr);
10157 return 0;
10158 }
10159
EVALUATE(MSGFR)10160 EVALUATE(MSGFR) {
10161 DCHECK_OPCODE(MSGFR);
10162 DECODE_RRE_INSTRUCTION(r1, r2);
10163 int64_t r1_val = get_register(r1);
10164 int64_t r2_val = static_cast<int64_t>(get_low_register<int32_t>(r2));
10165 int64_t product = r1_val * r2_val;
10166 set_register(r1, product);
10167 return length;
10168 }
10169
EVALUATE(DSGFR)10170 EVALUATE(DSGFR) {
10171 DCHECK_OPCODE(DSGFR);
10172 DECODE_RRE_INSTRUCTION(r1, r2);
10173 DCHECK(r1 % 2 == 0);
10174 int64_t r1_val = get_register(r1 + 1);
10175 int64_t r2_val = static_cast<int64_t>(get_low_register<int32_t>(r2));
10176 int64_t quotient = r1_val / r2_val;
10177 int64_t remainder = r1_val % r2_val;
10178 set_register(r1, remainder);
10179 set_register(r1 + 1, quotient);
10180 return length;
10181 }
10182
EVALUATE(KMAC)10183 EVALUATE(KMAC) {
10184 UNIMPLEMENTED();
10185 USE(instr);
10186 return 0;
10187 }
10188
EVALUATE(LRVR)10189 EVALUATE(LRVR) {
10190 DCHECK_OPCODE(LRVR);
10191 DECODE_RRE_INSTRUCTION(r1, r2);
10192 int32_t r2_val = get_low_register<int32_t>(r2);
10193 int32_t r1_val = ByteReverse(r2_val);
10194
10195 set_low_register(r1, r1_val);
10196 return length;
10197 }
10198
EVALUATE(CGR)10199 EVALUATE(CGR) {
10200 DCHECK_OPCODE(CGR);
10201 DECODE_RRE_INSTRUCTION(r1, r2);
10202 // Compare (64)
10203 int64_t r1_val = get_register(r1);
10204 int64_t r2_val = get_register(r2);
10205 SetS390ConditionCode<int64_t>(r1_val, r2_val);
10206 return length;
10207 }
10208
EVALUATE(CLGR)10209 EVALUATE(CLGR) {
10210 DCHECK_OPCODE(CLGR);
10211 DECODE_RRE_INSTRUCTION(r1, r2);
10212 // Compare Logical (64)
10213 uint64_t r1_val = static_cast<uint64_t>(get_register(r1));
10214 uint64_t r2_val = static_cast<uint64_t>(get_register(r2));
10215 SetS390ConditionCode<uint64_t>(r1_val, r2_val);
10216 return length;
10217 }
10218
EVALUATE(KMF)10219 EVALUATE(KMF) {
10220 UNIMPLEMENTED();
10221 USE(instr);
10222 return 0;
10223 }
10224
EVALUATE(KMO)10225 EVALUATE(KMO) {
10226 UNIMPLEMENTED();
10227 USE(instr);
10228 return 0;
10229 }
10230
EVALUATE(PCC)10231 EVALUATE(PCC) {
10232 UNIMPLEMENTED();
10233 USE(instr);
10234 return 0;
10235 }
10236
EVALUATE(KMCTR)10237 EVALUATE(KMCTR) {
10238 UNIMPLEMENTED();
10239 USE(instr);
10240 return 0;
10241 }
10242
EVALUATE(KM)10243 EVALUATE(KM) {
10244 UNIMPLEMENTED();
10245 USE(instr);
10246 return 0;
10247 }
10248
EVALUATE(KMC)10249 EVALUATE(KMC) {
10250 UNIMPLEMENTED();
10251 USE(instr);
10252 return 0;
10253 }
10254
EVALUATE(CGFR)10255 EVALUATE(CGFR) {
10256 DCHECK_OPCODE(CGFR);
10257 DECODE_RRE_INSTRUCTION(r1, r2);
10258 // Compare (64)
10259 int64_t r1_val = get_register(r1);
10260 int64_t r2_val = static_cast<int64_t>(get_low_register<int32_t>(r2));
10261 SetS390ConditionCode<int64_t>(r1_val, r2_val);
10262 return length;
10263 }
10264
EVALUATE(KIMD)10265 EVALUATE(KIMD) {
10266 UNIMPLEMENTED();
10267 USE(instr);
10268 return 0;
10269 }
10270
EVALUATE(KLMD)10271 EVALUATE(KLMD) {
10272 UNIMPLEMENTED();
10273 USE(instr);
10274 return 0;
10275 }
10276
EVALUATE(CFDTR)10277 EVALUATE(CFDTR) {
10278 UNIMPLEMENTED();
10279 USE(instr);
10280 return 0;
10281 }
10282
EVALUATE(CLGDTR)10283 EVALUATE(CLGDTR) {
10284 UNIMPLEMENTED();
10285 USE(instr);
10286 return 0;
10287 }
10288
EVALUATE(CLFDTR)10289 EVALUATE(CLFDTR) {
10290 UNIMPLEMENTED();
10291 USE(instr);
10292 return 0;
10293 }
10294
EVALUATE(BCTGR)10295 EVALUATE(BCTGR) {
10296 UNIMPLEMENTED();
10297 USE(instr);
10298 return 0;
10299 }
10300
EVALUATE(CFXTR)10301 EVALUATE(CFXTR) {
10302 UNIMPLEMENTED();
10303 USE(instr);
10304 return 0;
10305 }
10306
EVALUATE(CLFXTR)10307 EVALUATE(CLFXTR) {
10308 UNIMPLEMENTED();
10309 USE(instr);
10310 return 0;
10311 }
10312
EVALUATE(CDFTR)10313 EVALUATE(CDFTR) {
10314 UNIMPLEMENTED();
10315 USE(instr);
10316 return 0;
10317 }
10318
EVALUATE(CDLGTR)10319 EVALUATE(CDLGTR) {
10320 UNIMPLEMENTED();
10321 USE(instr);
10322 return 0;
10323 }
10324
EVALUATE(CDLFTR)10325 EVALUATE(CDLFTR) {
10326 UNIMPLEMENTED();
10327 USE(instr);
10328 return 0;
10329 }
10330
EVALUATE(CXFTR)10331 EVALUATE(CXFTR) {
10332 UNIMPLEMENTED();
10333 USE(instr);
10334 return 0;
10335 }
10336
EVALUATE(CXLGTR)10337 EVALUATE(CXLGTR) {
10338 UNIMPLEMENTED();
10339 USE(instr);
10340 return 0;
10341 }
10342
EVALUATE(CXLFTR)10343 EVALUATE(CXLFTR) {
10344 UNIMPLEMENTED();
10345 USE(instr);
10346 return 0;
10347 }
10348
EVALUATE(CGRT)10349 EVALUATE(CGRT) {
10350 UNIMPLEMENTED();
10351 USE(instr);
10352 return 0;
10353 }
10354
EVALUATE(NGR)10355 EVALUATE(NGR) {
10356 DCHECK_OPCODE(NGR);
10357 DECODE_RRE_INSTRUCTION(r1, r2);
10358 int64_t r1_val = get_register(r1);
10359 int64_t r2_val = get_register(r2);
10360 r1_val &= r2_val;
10361 SetS390BitWiseConditionCode<uint64_t>(r1_val);
10362 set_register(r1, r1_val);
10363 return length;
10364 }
10365
EVALUATE(OGR)10366 EVALUATE(OGR) {
10367 DCHECK_OPCODE(OGR);
10368 DECODE_RRE_INSTRUCTION(r1, r2);
10369 int64_t r1_val = get_register(r1);
10370 int64_t r2_val = get_register(r2);
10371 r1_val |= r2_val;
10372 SetS390BitWiseConditionCode<uint64_t>(r1_val);
10373 set_register(r1, r1_val);
10374 return length;
10375 }
10376
EVALUATE(XGR)10377 EVALUATE(XGR) {
10378 DCHECK_OPCODE(XGR);
10379 DECODE_RRE_INSTRUCTION(r1, r2);
10380 int64_t r1_val = get_register(r1);
10381 int64_t r2_val = get_register(r2);
10382 r1_val ^= r2_val;
10383 SetS390BitWiseConditionCode<uint64_t>(r1_val);
10384 set_register(r1, r1_val);
10385 return length;
10386 }
10387
EVALUATE(FLOGR)10388 EVALUATE(FLOGR) {
10389 DCHECK_OPCODE(FLOGR);
10390 DECODE_RRE_INSTRUCTION(r1, r2);
10391
10392 DCHECK(r1 % 2 == 0);
10393
10394 int64_t r2_val = get_register(r2);
10395
10396 int i = 0;
10397 for (; i < 64; i++) {
10398 if (r2_val < 0) break;
10399 r2_val <<= 1;
10400 }
10401
10402 r2_val = get_register(r2);
10403
10404 int64_t mask = ~(1 << (63 - i));
10405 set_register(r1, i);
10406 set_register(r1 + 1, r2_val & mask);
10407 return length;
10408 }
10409
EVALUATE(LLGCR)10410 EVALUATE(LLGCR) {
10411 DCHECK_OPCODE(LLGCR);
10412 DECODE_RRE_INSTRUCTION(r1, r2);
10413 uint64_t r2_val = get_low_register<uint64_t>(r2);
10414 r2_val <<= 56;
10415 r2_val >>= 56;
10416 set_register(r1, r2_val);
10417 return length;
10418 }
10419
EVALUATE(LLGHR)10420 EVALUATE(LLGHR) {
10421 UNIMPLEMENTED();
10422 USE(instr);
10423 return 0;
10424 }
10425
EVALUATE(MLGR)10426 EVALUATE(MLGR) {
10427 UNIMPLEMENTED();
10428 USE(instr);
10429 return 0;
10430 }
10431
EVALUATE(DLGR)10432 EVALUATE(DLGR) {
10433 DCHECK_OPCODE(DLGR);
10434 #ifdef V8_TARGET_ARCH_S390X
10435 DECODE_RRE_INSTRUCTION(r1, r2);
10436 uint64_t r1_val = get_register(r1);
10437 uint64_t r2_val = get_register(r2);
10438 DCHECK(r1 % 2 == 0);
10439 unsigned __int128 dividend = static_cast<unsigned __int128>(r1_val) << 64;
10440 dividend += get_register(r1 + 1);
10441 uint64_t remainder = dividend % r2_val;
10442 uint64_t quotient = dividend / r2_val;
10443 r1_val = remainder;
10444 set_register(r1, remainder);
10445 set_register(r1 + 1, quotient);
10446 return length;
10447 #else
10448 UNREACHABLE();
10449 #endif
10450 }
10451
EVALUATE(ALCGR)10452 EVALUATE(ALCGR) {
10453 UNIMPLEMENTED();
10454 USE(instr);
10455 return 0;
10456 }
10457
EVALUATE(SLBGR)10458 EVALUATE(SLBGR) {
10459 UNIMPLEMENTED();
10460 USE(instr);
10461 return 0;
10462 }
10463
EVALUATE(EPSW)10464 EVALUATE(EPSW) {
10465 UNIMPLEMENTED();
10466 USE(instr);
10467 return 0;
10468 }
10469
EVALUATE(TRTT)10470 EVALUATE(TRTT) {
10471 UNIMPLEMENTED();
10472 USE(instr);
10473 return 0;
10474 }
10475
EVALUATE(TRTO)10476 EVALUATE(TRTO) {
10477 UNIMPLEMENTED();
10478 USE(instr);
10479 return 0;
10480 }
10481
EVALUATE(TROT)10482 EVALUATE(TROT) {
10483 UNIMPLEMENTED();
10484 USE(instr);
10485 return 0;
10486 }
10487
EVALUATE(TROO)10488 EVALUATE(TROO) {
10489 UNIMPLEMENTED();
10490 USE(instr);
10491 return 0;
10492 }
10493
EVALUATE(LLCR)10494 EVALUATE(LLCR) {
10495 DCHECK_OPCODE(LLCR);
10496 DECODE_RRE_INSTRUCTION(r1, r2);
10497 uint32_t r2_val = get_low_register<uint32_t>(r2);
10498 r2_val <<= 24;
10499 r2_val >>= 24;
10500 set_low_register(r1, r2_val);
10501 return length;
10502 }
10503
EVALUATE(LLHR)10504 EVALUATE(LLHR) {
10505 UNIMPLEMENTED();
10506 USE(instr);
10507 return 0;
10508 }
10509
EVALUATE(MLR)10510 EVALUATE(MLR) {
10511 DCHECK_OPCODE(MLR);
10512 DECODE_RRE_INSTRUCTION(r1, r2);
10513 DCHECK(r1 % 2 == 0);
10514
10515 uint32_t r1_val = get_low_register<uint32_t>(r1 + 1);
10516 uint32_t r2_val = get_low_register<uint32_t>(r2);
10517 uint64_t product =
10518 static_cast<uint64_t>(r1_val) * static_cast<uint64_t>(r2_val);
10519 int32_t high_bits = product >> 32;
10520 int32_t low_bits = product & 0x00000000FFFFFFFF;
10521 set_low_register(r1, high_bits);
10522 set_low_register(r1 + 1, low_bits);
10523 return length;
10524 }
10525
EVALUATE(DLR)10526 EVALUATE(DLR) {
10527 DCHECK_OPCODE(DLR);
10528 DECODE_RRE_INSTRUCTION(r1, r2);
10529 uint32_t r1_val = get_low_register<uint32_t>(r1);
10530 uint32_t r2_val = get_low_register<uint32_t>(r2);
10531 DCHECK(r1 % 2 == 0);
10532 uint64_t dividend = static_cast<uint64_t>(r1_val) << 32;
10533 dividend += get_low_register<uint32_t>(r1 + 1);
10534 uint32_t remainder = dividend % r2_val;
10535 uint32_t quotient = dividend / r2_val;
10536 r1_val = remainder;
10537 set_low_register(r1, remainder);
10538 set_low_register(r1 + 1, quotient);
10539 return length;
10540 }
10541
EVALUATE(ALCR)10542 EVALUATE(ALCR) {
10543 DCHECK_OPCODE(ALCR);
10544 DECODE_RRE_INSTRUCTION(r1, r2);
10545 uint32_t r1_val = get_low_register<uint32_t>(r1);
10546 uint32_t r2_val = get_low_register<uint32_t>(r2);
10547 uint32_t alu_out = 0;
10548 bool isOF = false;
10549
10550 alu_out = r1_val + r2_val;
10551 bool isOF_original = CheckOverflowForUIntAdd(r1_val, r2_val);
10552 if (TestConditionCode((Condition)2) || TestConditionCode((Condition)3)) {
10553 alu_out = alu_out + 1;
10554 isOF = isOF_original || CheckOverflowForUIntAdd(alu_out, 1);
10555 } else {
10556 isOF = isOF_original;
10557 }
10558 set_low_register(r1, alu_out);
10559 SetS390ConditionCodeCarry<uint32_t>(alu_out, isOF);
10560 return length;
10561 }
10562
EVALUATE(SLBR)10563 EVALUATE(SLBR) {
10564 DCHECK_OPCODE(SLBR);
10565 DECODE_RRE_INSTRUCTION(r1, r2);
10566 uint32_t r1_val = get_low_register<uint32_t>(r1);
10567 uint32_t r2_val = get_low_register<uint32_t>(r2);
10568 uint32_t alu_out = 0;
10569 bool isOF = false;
10570
10571 alu_out = r1_val - r2_val;
10572 bool isOF_original = CheckOverflowForUIntSub(r1_val, r2_val);
10573 if (TestConditionCode((Condition)2) || TestConditionCode((Condition)3)) {
10574 alu_out = alu_out - 1;
10575 isOF = isOF_original || CheckOverflowForUIntSub(alu_out, 1);
10576 } else {
10577 isOF = isOF_original;
10578 }
10579 set_low_register(r1, alu_out);
10580 SetS390ConditionCodeCarry<uint32_t>(alu_out, isOF);
10581 return length;
10582 }
10583
EVALUATE(CU14)10584 EVALUATE(CU14) {
10585 UNIMPLEMENTED();
10586 USE(instr);
10587 return 0;
10588 }
10589
EVALUATE(CU24)10590 EVALUATE(CU24) {
10591 UNIMPLEMENTED();
10592 USE(instr);
10593 return 0;
10594 }
10595
EVALUATE(CU41)10596 EVALUATE(CU41) {
10597 UNIMPLEMENTED();
10598 USE(instr);
10599 return 0;
10600 }
10601
EVALUATE(CU42)10602 EVALUATE(CU42) {
10603 UNIMPLEMENTED();
10604 USE(instr);
10605 return 0;
10606 }
10607
EVALUATE(TRTRE)10608 EVALUATE(TRTRE) {
10609 UNIMPLEMENTED();
10610 USE(instr);
10611 return 0;
10612 }
10613
EVALUATE(SRSTU)10614 EVALUATE(SRSTU) {
10615 UNIMPLEMENTED();
10616 USE(instr);
10617 return 0;
10618 }
10619
EVALUATE(TRTE)10620 EVALUATE(TRTE) {
10621 UNIMPLEMENTED();
10622 USE(instr);
10623 return 0;
10624 }
10625
EVALUATE(AHHHR)10626 EVALUATE(AHHHR) {
10627 UNIMPLEMENTED();
10628 USE(instr);
10629 return 0;
10630 }
10631
EVALUATE(SHHHR)10632 EVALUATE(SHHHR) {
10633 UNIMPLEMENTED();
10634 USE(instr);
10635 return 0;
10636 }
10637
EVALUATE(ALHHHR)10638 EVALUATE(ALHHHR) {
10639 UNIMPLEMENTED();
10640 USE(instr);
10641 return 0;
10642 }
10643
EVALUATE(SLHHHR)10644 EVALUATE(SLHHHR) {
10645 UNIMPLEMENTED();
10646 USE(instr);
10647 return 0;
10648 }
10649
EVALUATE(CHHR)10650 EVALUATE(CHHR) {
10651 UNIMPLEMENTED();
10652 USE(instr);
10653 return 0;
10654 }
10655
EVALUATE(AHHLR)10656 EVALUATE(AHHLR) {
10657 UNIMPLEMENTED();
10658 USE(instr);
10659 return 0;
10660 }
10661
EVALUATE(SHHLR)10662 EVALUATE(SHHLR) {
10663 UNIMPLEMENTED();
10664 USE(instr);
10665 return 0;
10666 }
10667
EVALUATE(ALHHLR)10668 EVALUATE(ALHHLR) {
10669 UNIMPLEMENTED();
10670 USE(instr);
10671 return 0;
10672 }
10673
EVALUATE(SLHHLR)10674 EVALUATE(SLHHLR) {
10675 UNIMPLEMENTED();
10676 USE(instr);
10677 return 0;
10678 }
10679
EVALUATE(CHLR)10680 EVALUATE(CHLR) {
10681 UNIMPLEMENTED();
10682 USE(instr);
10683 return 0;
10684 }
10685
EVALUATE(POPCNT_Z)10686 EVALUATE(POPCNT_Z) {
10687 DCHECK_OPCODE(POPCNT_Z);
10688 DECODE_RRE_INSTRUCTION(r1, r2);
10689 int64_t r2_val = get_register(r2);
10690 int64_t r1_val = 0;
10691
10692 uint8_t* r2_val_ptr = reinterpret_cast<uint8_t*>(&r2_val);
10693 uint8_t* r1_val_ptr = reinterpret_cast<uint8_t*>(&r1_val);
10694 for (int i = 0; i < 8; i++) {
10695 uint32_t x = static_cast<uint32_t>(r2_val_ptr[i]);
10696 #if defined(__GNUC__)
10697 r1_val_ptr[i] = __builtin_popcount(x);
10698 #else
10699 #error unsupport __builtin_popcount
10700 #endif
10701 }
10702 set_register(r1, static_cast<uint64_t>(r1_val));
10703 return length;
10704 }
10705
EVALUATE(LOCGR)10706 EVALUATE(LOCGR) {
10707 DCHECK_OPCODE(LOCGR);
10708 DECODE_RRF_C_INSTRUCTION(r1, r2, m3);
10709 if (TestConditionCode(m3)) {
10710 set_register(r1, get_register(r2));
10711 }
10712 return length;
10713 }
10714
EVALUATE(NGRK)10715 EVALUATE(NGRK) {
10716 DCHECK_OPCODE(NGRK);
10717 DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
10718 // 64-bit Non-clobbering arithmetics / bitwise ops.
10719 int64_t r2_val = get_register(r2);
10720 int64_t r3_val = get_register(r3);
10721 uint64_t bitwise_result = 0;
10722 bitwise_result = r2_val & r3_val;
10723 SetS390BitWiseConditionCode<uint64_t>(bitwise_result);
10724 set_register(r1, bitwise_result);
10725 return length;
10726 }
10727
EVALUATE(OGRK)10728 EVALUATE(OGRK) {
10729 DCHECK_OPCODE(OGRK);
10730 DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
10731 // 64-bit Non-clobbering arithmetics / bitwise ops.
10732 int64_t r2_val = get_register(r2);
10733 int64_t r3_val = get_register(r3);
10734 uint64_t bitwise_result = 0;
10735 bitwise_result = r2_val | r3_val;
10736 SetS390BitWiseConditionCode<uint64_t>(bitwise_result);
10737 set_register(r1, bitwise_result);
10738 return length;
10739 }
10740
EVALUATE(XGRK)10741 EVALUATE(XGRK) {
10742 DCHECK_OPCODE(XGRK);
10743 DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
10744 // 64-bit Non-clobbering arithmetics / bitwise ops.
10745 int64_t r2_val = get_register(r2);
10746 int64_t r3_val = get_register(r3);
10747 uint64_t bitwise_result = 0;
10748 bitwise_result = r2_val ^ r3_val;
10749 SetS390BitWiseConditionCode<uint64_t>(bitwise_result);
10750 set_register(r1, bitwise_result);
10751 return length;
10752 }
10753
EVALUATE(AGRK)10754 EVALUATE(AGRK) {
10755 DCHECK_OPCODE(AGRK);
10756 DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
10757 // 64-bit Non-clobbering arithmetics / bitwise ops.
10758 int64_t r2_val = get_register(r2);
10759 int64_t r3_val = get_register(r3);
10760 bool isOF = CheckOverflowForIntAdd(r2_val, r3_val, int64_t);
10761 SetS390ConditionCode<int64_t>(r2_val + r3_val, 0);
10762 SetS390OverflowCode(isOF);
10763 set_register(r1, r2_val + r3_val);
10764 return length;
10765 }
10766
EVALUATE(SGRK)10767 EVALUATE(SGRK) {
10768 DCHECK_OPCODE(SGRK);
10769 DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
10770 // 64-bit Non-clobbering arithmetics / bitwise ops.
10771 int64_t r2_val = get_register(r2);
10772 int64_t r3_val = get_register(r3);
10773 bool isOF = CheckOverflowForIntSub(r2_val, r3_val, int64_t);
10774 SetS390ConditionCode<int64_t>(r2_val - r3_val, 0);
10775 SetS390OverflowCode(isOF);
10776 set_register(r1, r2_val - r3_val);
10777 return length;
10778 }
10779
EVALUATE(ALGRK)10780 EVALUATE(ALGRK) {
10781 DCHECK_OPCODE(ALGRK);
10782 DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
10783 // 64-bit Non-clobbering unsigned arithmetics
10784 uint64_t r2_val = get_register(r2);
10785 uint64_t r3_val = get_register(r3);
10786 bool isOF = CheckOverflowForUIntAdd(r2_val, r3_val);
10787 SetS390ConditionCode<uint64_t>(r2_val + r3_val, 0);
10788 SetS390OverflowCode(isOF);
10789 set_register(r1, r2_val + r3_val);
10790 return length;
10791 }
10792
EVALUATE(SLGRK)10793 EVALUATE(SLGRK) {
10794 DCHECK_OPCODE(SLGRK);
10795 DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
10796 // 64-bit Non-clobbering unsigned arithmetics
10797 uint64_t r2_val = get_register(r2);
10798 uint64_t r3_val = get_register(r3);
10799 bool isOF = CheckOverflowForUIntSub(r2_val, r3_val);
10800 SetS390ConditionCode<uint64_t>(r2_val - r3_val, 0);
10801 SetS390OverflowCode(isOF);
10802 set_register(r1, r2_val - r3_val);
10803 return length;
10804 }
10805
EVALUATE(LOCR)10806 EVALUATE(LOCR) {
10807 DCHECK_OPCODE(LOCR);
10808 DECODE_RRF_C_INSTRUCTION(r1, r2, m3);
10809 if (TestConditionCode(m3)) {
10810 set_low_register(r1, get_low_register<int32_t>(r2));
10811 }
10812 return length;
10813 }
10814
EVALUATE(NRK)10815 EVALUATE(NRK) {
10816 DCHECK_OPCODE(NRK);
10817 DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
10818 // 32-bit Non-clobbering arithmetics / bitwise ops
10819 int32_t r2_val = get_low_register<int32_t>(r2);
10820 int32_t r3_val = get_low_register<int32_t>(r3);
10821 // Assume bitwise operation here
10822 uint32_t bitwise_result = 0;
10823 bitwise_result = r2_val & r3_val;
10824 SetS390BitWiseConditionCode<uint32_t>(bitwise_result);
10825 set_low_register(r1, bitwise_result);
10826 return length;
10827 }
10828
EVALUATE(ORK)10829 EVALUATE(ORK) {
10830 DCHECK_OPCODE(ORK);
10831 DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
10832 // 32-bit Non-clobbering arithmetics / bitwise ops
10833 int32_t r2_val = get_low_register<int32_t>(r2);
10834 int32_t r3_val = get_low_register<int32_t>(r3);
10835 // Assume bitwise operation here
10836 uint32_t bitwise_result = 0;
10837 bitwise_result = r2_val | r3_val;
10838 SetS390BitWiseConditionCode<uint32_t>(bitwise_result);
10839 set_low_register(r1, bitwise_result);
10840 return length;
10841 }
10842
EVALUATE(XRK)10843 EVALUATE(XRK) {
10844 DCHECK_OPCODE(XRK);
10845 DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
10846 // 32-bit Non-clobbering arithmetics / bitwise ops
10847 int32_t r2_val = get_low_register<int32_t>(r2);
10848 int32_t r3_val = get_low_register<int32_t>(r3);
10849 // Assume bitwise operation here
10850 uint32_t bitwise_result = 0;
10851 bitwise_result = r2_val ^ r3_val;
10852 SetS390BitWiseConditionCode<uint32_t>(bitwise_result);
10853 set_low_register(r1, bitwise_result);
10854 return length;
10855 }
10856
EVALUATE(ARK)10857 EVALUATE(ARK) {
10858 DCHECK_OPCODE(ARK);
10859 DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
10860 // 32-bit Non-clobbering arithmetics / bitwise ops
10861 int32_t r2_val = get_low_register<int32_t>(r2);
10862 int32_t r3_val = get_low_register<int32_t>(r3);
10863 bool isOF = CheckOverflowForIntAdd(r2_val, r3_val, int32_t);
10864 SetS390ConditionCode<int32_t>(r2_val + r3_val, 0);
10865 SetS390OverflowCode(isOF);
10866 set_low_register(r1, r2_val + r3_val);
10867 return length;
10868 }
10869
EVALUATE(SRK)10870 EVALUATE(SRK) {
10871 DCHECK_OPCODE(SRK);
10872 DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
10873 // 32-bit Non-clobbering arithmetics / bitwise ops
10874 int32_t r2_val = get_low_register<int32_t>(r2);
10875 int32_t r3_val = get_low_register<int32_t>(r3);
10876 bool isOF = CheckOverflowForIntSub(r2_val, r3_val, int32_t);
10877 SetS390ConditionCode<int32_t>(r2_val - r3_val, 0);
10878 SetS390OverflowCode(isOF);
10879 set_low_register(r1, r2_val - r3_val);
10880 return length;
10881 }
10882
EVALUATE(ALRK)10883 EVALUATE(ALRK) {
10884 DCHECK_OPCODE(ALRK);
10885 DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
10886 // 32-bit Non-clobbering unsigned arithmetics
10887 uint32_t r2_val = get_low_register<uint32_t>(r2);
10888 uint32_t r3_val = get_low_register<uint32_t>(r3);
10889 bool isOF = CheckOverflowForUIntAdd(r2_val, r3_val);
10890 SetS390ConditionCode<uint32_t>(r2_val + r3_val, 0);
10891 SetS390OverflowCode(isOF);
10892 set_low_register(r1, r2_val + r3_val);
10893 return length;
10894 }
10895
EVALUATE(SLRK)10896 EVALUATE(SLRK) {
10897 DCHECK_OPCODE(SLRK);
10898 DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
10899 // 32-bit Non-clobbering unsigned arithmetics
10900 uint32_t r2_val = get_low_register<uint32_t>(r2);
10901 uint32_t r3_val = get_low_register<uint32_t>(r3);
10902 bool isOF = CheckOverflowForUIntSub(r2_val, r3_val);
10903 SetS390ConditionCode<uint32_t>(r2_val - r3_val, 0);
10904 SetS390OverflowCode(isOF);
10905 set_low_register(r1, r2_val - r3_val);
10906 return length;
10907 }
10908
EVALUATE(LTG)10909 EVALUATE(LTG) {
10910 DCHECK_OPCODE(LTG);
10911 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
10912 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
10913 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
10914 intptr_t addr = x2_val + b2_val + d2;
10915 int64_t value = ReadDW(addr);
10916 set_register(r1, value);
10917 SetS390ConditionCode<int64_t>(value, 0);
10918 return length;
10919 }
10920
EVALUATE(CVBY)10921 EVALUATE(CVBY) {
10922 UNIMPLEMENTED();
10923 USE(instr);
10924 return 0;
10925 }
10926
EVALUATE(AG)10927 EVALUATE(AG) {
10928 DCHECK_OPCODE(AG);
10929 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
10930 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
10931 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
10932 int64_t alu_out = get_register(r1);
10933 int64_t mem_val = ReadDW(b2_val + x2_val + d2);
10934 alu_out += mem_val;
10935 SetS390ConditionCode<int32_t>(alu_out, 0);
10936 set_register(r1, alu_out);
10937 return length;
10938 }
10939
EVALUATE(SG)10940 EVALUATE(SG) {
10941 DCHECK_OPCODE(SG);
10942 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
10943 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
10944 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
10945 int64_t alu_out = get_register(r1);
10946 int64_t mem_val = ReadDW(b2_val + x2_val + d2);
10947 alu_out -= mem_val;
10948 SetS390ConditionCode<int32_t>(alu_out, 0);
10949 set_register(r1, alu_out);
10950 return length;
10951 }
10952
EVALUATE(ALG)10953 EVALUATE(ALG) {
10954 DCHECK_OPCODE(ALG);
10955 #ifndef V8_TARGET_ARCH_S390X
10956 DCHECK(false);
10957 #endif
10958 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
10959 uint64_t r1_val = get_register(r1);
10960 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
10961 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
10962 intptr_t d2_val = d2;
10963 uint64_t alu_out = r1_val;
10964 uint64_t mem_val = static_cast<uint64_t>(ReadDW(b2_val + d2_val + x2_val));
10965 alu_out += mem_val;
10966 SetS390ConditionCode<uint64_t>(alu_out, 0);
10967 set_register(r1, alu_out);
10968 return length;
10969 }
10970
EVALUATE(SLG)10971 EVALUATE(SLG) {
10972 DCHECK_OPCODE(SLG);
10973 #ifndef V8_TARGET_ARCH_S390X
10974 DCHECK(false);
10975 #endif
10976 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
10977 uint64_t r1_val = get_register(r1);
10978 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
10979 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
10980 intptr_t d2_val = d2;
10981 uint64_t alu_out = r1_val;
10982 uint64_t mem_val = static_cast<uint64_t>(ReadDW(b2_val + d2_val + x2_val));
10983 alu_out -= mem_val;
10984 SetS390ConditionCode<uint64_t>(alu_out, 0);
10985 set_register(r1, alu_out);
10986 return length;
10987 }
10988
EVALUATE(MSG)10989 EVALUATE(MSG) {
10990 DCHECK_OPCODE(MSG);
10991 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
10992 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
10993 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
10994 intptr_t d2_val = d2;
10995 int64_t mem_val = ReadDW(b2_val + d2_val + x2_val);
10996 int64_t r1_val = get_register(r1);
10997 set_register(r1, mem_val * r1_val);
10998 return length;
10999 }
11000
EVALUATE(DSG)11001 EVALUATE(DSG) {
11002 UNIMPLEMENTED();
11003 USE(instr);
11004 return 0;
11005 }
11006
EVALUATE(CVBG)11007 EVALUATE(CVBG) {
11008 UNIMPLEMENTED();
11009 USE(instr);
11010 return 0;
11011 }
11012
EVALUATE(LT)11013 EVALUATE(LT) {
11014 DCHECK_OPCODE(LT);
11015 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11016 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11017 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11018 intptr_t addr = x2_val + b2_val + d2;
11019 int32_t value = ReadW(addr, instr);
11020 set_low_register(r1, value);
11021 SetS390ConditionCode<int32_t>(value, 0);
11022 return length;
11023 }
11024
EVALUATE(LGH)11025 EVALUATE(LGH) {
11026 DCHECK_OPCODE(LGH);
11027 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11028 // Miscellaneous Loads and Stores
11029 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11030 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11031 intptr_t addr = x2_val + b2_val + d2;
11032 int64_t mem_val = static_cast<int64_t>(ReadH(addr, instr));
11033 set_register(r1, mem_val);
11034 return length;
11035 }
11036
EVALUATE(LLGF)11037 EVALUATE(LLGF) {
11038 DCHECK_OPCODE(LLGF);
11039 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11040 // Miscellaneous Loads and Stores
11041 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11042 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11043 intptr_t addr = x2_val + b2_val + d2;
11044 uint64_t mem_val = static_cast<uint64_t>(ReadWU(addr, instr));
11045 set_register(r1, mem_val);
11046 return length;
11047 }
11048
EVALUATE(LLGT)11049 EVALUATE(LLGT) {
11050 UNIMPLEMENTED();
11051 USE(instr);
11052 return 0;
11053 }
11054
EVALUATE(AGF)11055 EVALUATE(AGF) {
11056 DCHECK_OPCODE(AGF);
11057 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11058 uint64_t r1_val = get_register(r1);
11059 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11060 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11061 intptr_t d2_val = d2;
11062 uint64_t alu_out = r1_val;
11063 uint32_t mem_val = ReadW(b2_val + d2_val + x2_val, instr);
11064 alu_out += mem_val;
11065 SetS390ConditionCode<int64_t>(alu_out, 0);
11066 set_register(r1, alu_out);
11067 return length;
11068 }
11069
EVALUATE(SGF)11070 EVALUATE(SGF) {
11071 DCHECK_OPCODE(SGF);
11072 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11073 uint64_t r1_val = get_register(r1);
11074 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11075 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11076 intptr_t d2_val = d2;
11077 uint64_t alu_out = r1_val;
11078 uint32_t mem_val = ReadW(b2_val + d2_val + x2_val, instr);
11079 alu_out -= mem_val;
11080 SetS390ConditionCode<int64_t>(alu_out, 0);
11081 set_register(r1, alu_out);
11082 return length;
11083 }
11084
EVALUATE(ALGF)11085 EVALUATE(ALGF) {
11086 UNIMPLEMENTED();
11087 USE(instr);
11088 return 0;
11089 }
11090
EVALUATE(SLGF)11091 EVALUATE(SLGF) {
11092 UNIMPLEMENTED();
11093 USE(instr);
11094 return 0;
11095 }
11096
EVALUATE(MSGF)11097 EVALUATE(MSGF) {
11098 DCHECK_OPCODE(MSGF);
11099 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11100 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11101 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11102 intptr_t d2_val = d2;
11103 int64_t mem_val =
11104 static_cast<int64_t>(ReadW(b2_val + d2_val + x2_val, instr));
11105 int64_t r1_val = get_register(r1);
11106 int64_t product = r1_val * mem_val;
11107 set_register(r1, product);
11108 return length;
11109 }
11110
EVALUATE(DSGF)11111 EVALUATE(DSGF) {
11112 DCHECK_OPCODE(DSGF);
11113 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11114 DCHECK(r1 % 2 == 0);
11115 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11116 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11117 intptr_t d2_val = d2;
11118 int64_t mem_val =
11119 static_cast<int64_t>(ReadW(b2_val + d2_val + x2_val, instr));
11120 int64_t r1_val = get_register(r1 + 1);
11121 int64_t quotient = r1_val / mem_val;
11122 int64_t remainder = r1_val % mem_val;
11123 set_register(r1, remainder);
11124 set_register(r1 + 1, quotient);
11125 return length;
11126 }
11127
EVALUATE(LRVG)11128 EVALUATE(LRVG) {
11129 DCHECK_OPCODE(LRVG);
11130 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11131 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11132 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11133 intptr_t mem_addr = b2_val + x2_val + d2;
11134 int64_t mem_val = ReadW64(mem_addr, instr);
11135 set_register(r1, ByteReverse(mem_val));
11136 return length;
11137 }
11138
EVALUATE(LRV)11139 EVALUATE(LRV) {
11140 DCHECK_OPCODE(LRV);
11141 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11142 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11143 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11144 intptr_t mem_addr = b2_val + x2_val + d2;
11145 int32_t mem_val = ReadW(mem_addr, instr);
11146 set_low_register(r1, ByteReverse(mem_val));
11147 return length;
11148 }
11149
EVALUATE(LRVH)11150 EVALUATE(LRVH) {
11151 DCHECK_OPCODE(LRVH);
11152 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11153 int32_t r1_val = get_low_register<int32_t>(r1);
11154 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11155 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11156 intptr_t mem_addr = b2_val + x2_val + d2;
11157 int16_t mem_val = ReadH(mem_addr, instr);
11158 int32_t result = ByteReverse(mem_val) & 0x0000ffff;
11159 result |= r1_val & 0xffff0000;
11160 set_low_register(r1, result);
11161 return length;
11162 }
11163
EVALUATE(CG)11164 EVALUATE(CG) {
11165 DCHECK_OPCODE(CG);
11166 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11167 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11168 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11169 int64_t alu_out = get_register(r1);
11170 int64_t mem_val = ReadDW(b2_val + x2_val + d2);
11171 SetS390ConditionCode<int64_t>(alu_out, mem_val);
11172 set_register(r1, alu_out);
11173 return length;
11174 }
11175
EVALUATE(CLG)11176 EVALUATE(CLG) {
11177 DCHECK_OPCODE(CLG);
11178 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11179 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11180 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11181 int64_t alu_out = get_register(r1);
11182 int64_t mem_val = ReadDW(b2_val + x2_val + d2);
11183 SetS390ConditionCode<uint64_t>(alu_out, mem_val);
11184 set_register(r1, alu_out);
11185 return length;
11186 }
11187
EVALUATE(NTSTG)11188 EVALUATE(NTSTG) {
11189 UNIMPLEMENTED();
11190 USE(instr);
11191 return 0;
11192 }
11193
EVALUATE(CVDY)11194 EVALUATE(CVDY) {
11195 UNIMPLEMENTED();
11196 USE(instr);
11197 return 0;
11198 }
11199
EVALUATE(CVDG)11200 EVALUATE(CVDG) {
11201 UNIMPLEMENTED();
11202 USE(instr);
11203 return 0;
11204 }
11205
EVALUATE(CGF)11206 EVALUATE(CGF) {
11207 UNIMPLEMENTED();
11208 USE(instr);
11209 return 0;
11210 }
11211
EVALUATE(CLGF)11212 EVALUATE(CLGF) {
11213 UNIMPLEMENTED();
11214 USE(instr);
11215 return 0;
11216 }
11217
EVALUATE(LTGF)11218 EVALUATE(LTGF) {
11219 UNIMPLEMENTED();
11220 USE(instr);
11221 return 0;
11222 }
11223
EVALUATE(CGH)11224 EVALUATE(CGH) {
11225 UNIMPLEMENTED();
11226 USE(instr);
11227 return 0;
11228 }
11229
EVALUATE(PFD)11230 EVALUATE(PFD) {
11231 DCHECK_OPCODE(PFD);
11232 USE(instr);
11233 return 6;
11234 }
11235
EVALUATE(STRV)11236 EVALUATE(STRV) {
11237 DCHECK_OPCODE(STRV);
11238 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11239 int32_t r1_val = get_low_register<int32_t>(r1);
11240 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11241 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11242 intptr_t mem_addr = b2_val + x2_val + d2;
11243 WriteW(mem_addr, ByteReverse(r1_val), instr);
11244 return length;
11245 }
11246
EVALUATE(STRVG)11247 EVALUATE(STRVG) {
11248 DCHECK_OPCODE(STRVG);
11249 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11250 int64_t r1_val = get_register(r1);
11251 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11252 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11253 intptr_t mem_addr = b2_val + x2_val + d2;
11254 WriteDW(mem_addr, ByteReverse(r1_val));
11255 return length;
11256 }
11257
EVALUATE(STRVH)11258 EVALUATE(STRVH) {
11259 DCHECK_OPCODE(STRVH);
11260 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11261 int32_t r1_val = get_low_register<int32_t>(r1);
11262 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11263 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11264 intptr_t mem_addr = b2_val + x2_val + d2;
11265 int16_t result = static_cast<int16_t>(r1_val >> 16);
11266 WriteH(mem_addr, ByteReverse(result), instr);
11267 return length;
11268 }
11269
EVALUATE(BCTG)11270 EVALUATE(BCTG) {
11271 UNIMPLEMENTED();
11272 USE(instr);
11273 return 0;
11274 }
11275
EVALUATE(MSY)11276 EVALUATE(MSY) {
11277 DCHECK_OPCODE(MSY);
11278 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11279 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11280 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11281 intptr_t d2_val = d2;
11282 int32_t mem_val = ReadW(b2_val + d2_val + x2_val, instr);
11283 int32_t r1_val = get_low_register<int32_t>(r1);
11284 set_low_register(r1, mem_val * r1_val);
11285 return length;
11286 }
11287
EVALUATE(NY)11288 EVALUATE(NY) {
11289 DCHECK_OPCODE(NY);
11290 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11291 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11292 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11293 int32_t alu_out = get_low_register<int32_t>(r1);
11294 int32_t mem_val = ReadW(b2_val + x2_val + d2, instr);
11295 alu_out &= mem_val;
11296 SetS390BitWiseConditionCode<uint32_t>(alu_out);
11297 set_low_register(r1, alu_out);
11298 return length;
11299 }
11300
EVALUATE(CLY)11301 EVALUATE(CLY) {
11302 DCHECK_OPCODE(CLY);
11303 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11304 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11305 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11306 uint32_t alu_out = get_low_register<uint32_t>(r1);
11307 uint32_t mem_val = ReadWU(b2_val + x2_val + d2, instr);
11308 SetS390ConditionCode<uint32_t>(alu_out, mem_val);
11309 return length;
11310 }
11311
EVALUATE(OY)11312 EVALUATE(OY) {
11313 DCHECK_OPCODE(OY);
11314 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11315 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11316 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11317 int32_t alu_out = get_low_register<int32_t>(r1);
11318 int32_t mem_val = ReadW(b2_val + x2_val + d2, instr);
11319 alu_out |= mem_val;
11320 SetS390BitWiseConditionCode<uint32_t>(alu_out);
11321 set_low_register(r1, alu_out);
11322 return length;
11323 }
11324
EVALUATE(XY)11325 EVALUATE(XY) {
11326 DCHECK_OPCODE(XY);
11327 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11328 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11329 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11330 int32_t alu_out = get_low_register<int32_t>(r1);
11331 int32_t mem_val = ReadW(b2_val + x2_val + d2, instr);
11332 alu_out ^= mem_val;
11333 SetS390BitWiseConditionCode<uint32_t>(alu_out);
11334 set_low_register(r1, alu_out);
11335 return length;
11336 }
11337
EVALUATE(CY)11338 EVALUATE(CY) {
11339 DCHECK_OPCODE(CY);
11340 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11341 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11342 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11343 int32_t alu_out = get_low_register<int32_t>(r1);
11344 int32_t mem_val = ReadW(b2_val + x2_val + d2, instr);
11345 SetS390ConditionCode<int32_t>(alu_out, mem_val);
11346 return length;
11347 }
11348
EVALUATE(AY)11349 EVALUATE(AY) {
11350 DCHECK_OPCODE(AY);
11351 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11352 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11353 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11354 int32_t alu_out = get_low_register<int32_t>(r1);
11355 int32_t mem_val = ReadW(b2_val + x2_val + d2, instr);
11356 bool isOF = false;
11357 isOF = CheckOverflowForIntAdd(alu_out, mem_val, int32_t);
11358 alu_out += mem_val;
11359 SetS390ConditionCode<int32_t>(alu_out, 0);
11360 SetS390OverflowCode(isOF);
11361 set_low_register(r1, alu_out);
11362 return length;
11363 }
11364
EVALUATE(SY)11365 EVALUATE(SY) {
11366 DCHECK_OPCODE(SY);
11367 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11368 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11369 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11370 int32_t alu_out = get_low_register<int32_t>(r1);
11371 int32_t mem_val = ReadW(b2_val + x2_val + d2, instr);
11372 bool isOF = false;
11373 isOF = CheckOverflowForIntSub(alu_out, mem_val, int32_t);
11374 alu_out -= mem_val;
11375 SetS390ConditionCode<int32_t>(alu_out, 0);
11376 SetS390OverflowCode(isOF);
11377 set_low_register(r1, alu_out);
11378 return length;
11379 }
11380
EVALUATE(MFY)11381 EVALUATE(MFY) {
11382 DCHECK_OPCODE(MFY);
11383 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11384 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11385 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11386 DCHECK(r1 % 2 == 0);
11387 int32_t mem_val = ReadW(b2_val + x2_val + d2, instr);
11388 int32_t r1_val = get_low_register<int32_t>(r1 + 1);
11389 int64_t product =
11390 static_cast<int64_t>(r1_val) * static_cast<int64_t>(mem_val);
11391 int32_t high_bits = product >> 32;
11392 r1_val = high_bits;
11393 int32_t low_bits = product & 0x00000000FFFFFFFF;
11394 set_low_register(r1, high_bits);
11395 set_low_register(r1 + 1, low_bits);
11396 return length;
11397 }
11398
EVALUATE(ALY)11399 EVALUATE(ALY) {
11400 DCHECK_OPCODE(ALY);
11401 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11402 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11403 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11404 uint32_t alu_out = get_low_register<uint32_t>(r1);
11405 uint32_t mem_val = ReadWU(b2_val + x2_val + d2, instr);
11406 alu_out += mem_val;
11407 set_low_register(r1, alu_out);
11408 SetS390ConditionCode<uint32_t>(alu_out, 0);
11409 return length;
11410 }
11411
EVALUATE(SLY)11412 EVALUATE(SLY) {
11413 DCHECK_OPCODE(SLY);
11414 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11415 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11416 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11417 uint32_t alu_out = get_low_register<uint32_t>(r1);
11418 uint32_t mem_val = ReadWU(b2_val + x2_val + d2, instr);
11419 alu_out -= mem_val;
11420 set_low_register(r1, alu_out);
11421 SetS390ConditionCode<uint32_t>(alu_out, 0);
11422 return length;
11423 }
11424
EVALUATE(STHY)11425 EVALUATE(STHY) {
11426 DCHECK_OPCODE(STHY);
11427 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11428 // Miscellaneous Loads and Stores
11429 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11430 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11431 intptr_t addr = x2_val + b2_val + d2;
11432 uint16_t value = get_low_register<uint32_t>(r1);
11433 WriteH(addr, value, instr);
11434 return length;
11435 }
11436
EVALUATE(LAY)11437 EVALUATE(LAY) {
11438 DCHECK_OPCODE(LAY);
11439 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11440 // Load Address
11441 int rb = b2;
11442 int rx = x2;
11443 int offset = d2;
11444 int64_t rb_val = (rb == 0) ? 0 : get_register(rb);
11445 int64_t rx_val = (rx == 0) ? 0 : get_register(rx);
11446 set_register(r1, rx_val + rb_val + offset);
11447 return length;
11448 }
11449
EVALUATE(STCY)11450 EVALUATE(STCY) {
11451 DCHECK_OPCODE(STCY);
11452 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11453 // Miscellaneous Loads and Stores
11454 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11455 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11456 intptr_t addr = x2_val + b2_val + d2;
11457 uint8_t value = get_low_register<uint32_t>(r1);
11458 WriteB(addr, value);
11459 return length;
11460 }
11461
EVALUATE(ICY)11462 EVALUATE(ICY) {
11463 UNIMPLEMENTED();
11464 USE(instr);
11465 return 0;
11466 }
11467
EVALUATE(LAEY)11468 EVALUATE(LAEY) {
11469 UNIMPLEMENTED();
11470 USE(instr);
11471 return 0;
11472 }
11473
EVALUATE(LB)11474 EVALUATE(LB) {
11475 DCHECK_OPCODE(LB);
11476 // Miscellaneous Loads and Stores
11477 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11478 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11479 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11480 intptr_t addr = x2_val + b2_val + d2;
11481 int32_t mem_val = ReadB(addr);
11482 set_low_register(r1, mem_val);
11483 return length;
11484 }
11485
EVALUATE(LGB)11486 EVALUATE(LGB) {
11487 DCHECK_OPCODE(LGB);
11488 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11489 // Miscellaneous Loads and Stores
11490 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11491 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11492 intptr_t addr = x2_val + b2_val + d2;
11493 int64_t mem_val = ReadB(addr);
11494 set_register(r1, mem_val);
11495 return length;
11496 }
11497
EVALUATE(LHY)11498 EVALUATE(LHY) {
11499 DCHECK_OPCODE(LHY);
11500 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11501 // Miscellaneous Loads and Stores
11502 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11503 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11504 intptr_t addr = x2_val + b2_val + d2;
11505 int32_t result = static_cast<int32_t>(ReadH(addr, instr));
11506 set_low_register(r1, result);
11507 return length;
11508 }
11509
EVALUATE(CHY)11510 EVALUATE(CHY) {
11511 UNIMPLEMENTED();
11512 USE(instr);
11513 return 0;
11514 }
11515
EVALUATE(AHY)11516 EVALUATE(AHY) {
11517 DCHECK_OPCODE(AHY);
11518 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11519 int32_t r1_val = get_low_register<int32_t>(r1);
11520 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11521 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11522 intptr_t d2_val = d2;
11523 int32_t mem_val =
11524 static_cast<int32_t>(ReadH(b2_val + d2_val + x2_val, instr));
11525 int32_t alu_out = 0;
11526 bool isOF = false;
11527 alu_out = r1_val + mem_val;
11528 isOF = CheckOverflowForIntAdd(r1_val, mem_val, int32_t);
11529 set_low_register(r1, alu_out);
11530 SetS390ConditionCode<int32_t>(alu_out, 0);
11531 SetS390OverflowCode(isOF);
11532 return length;
11533 }
11534
EVALUATE(SHY)11535 EVALUATE(SHY) {
11536 DCHECK_OPCODE(SHY);
11537 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11538 int32_t r1_val = get_low_register<int32_t>(r1);
11539 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11540 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11541 intptr_t d2_val = d2;
11542 int32_t mem_val =
11543 static_cast<int32_t>(ReadH(b2_val + d2_val + x2_val, instr));
11544 int32_t alu_out = 0;
11545 bool isOF = false;
11546 alu_out = r1_val - mem_val;
11547 isOF = CheckOverflowForIntSub(r1_val, mem_val, int64_t);
11548 set_low_register(r1, alu_out);
11549 SetS390ConditionCode<int32_t>(alu_out, 0);
11550 SetS390OverflowCode(isOF);
11551 return length;
11552 }
11553
EVALUATE(MHY)11554 EVALUATE(MHY) {
11555 UNIMPLEMENTED();
11556 USE(instr);
11557 return 0;
11558 }
11559
EVALUATE(NG)11560 EVALUATE(NG) {
11561 DCHECK_OPCODE(NG);
11562 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11563 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11564 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11565 int64_t alu_out = get_register(r1);
11566 int64_t mem_val = ReadDW(b2_val + x2_val + d2);
11567 alu_out &= mem_val;
11568 SetS390BitWiseConditionCode<uint32_t>(alu_out);
11569 set_register(r1, alu_out);
11570 return length;
11571 }
11572
EVALUATE(OG)11573 EVALUATE(OG) {
11574 DCHECK_OPCODE(OG);
11575 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11576 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11577 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11578 int64_t alu_out = get_register(r1);
11579 int64_t mem_val = ReadDW(b2_val + x2_val + d2);
11580 alu_out |= mem_val;
11581 SetS390BitWiseConditionCode<uint32_t>(alu_out);
11582 set_register(r1, alu_out);
11583 return length;
11584 }
11585
EVALUATE(XG)11586 EVALUATE(XG) {
11587 DCHECK_OPCODE(XG);
11588 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11589 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11590 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11591 int64_t alu_out = get_register(r1);
11592 int64_t mem_val = ReadDW(b2_val + x2_val + d2);
11593 alu_out ^= mem_val;
11594 SetS390BitWiseConditionCode<uint32_t>(alu_out);
11595 set_register(r1, alu_out);
11596 return length;
11597 }
11598
EVALUATE(LGAT)11599 EVALUATE(LGAT) {
11600 UNIMPLEMENTED();
11601 USE(instr);
11602 return 0;
11603 }
11604
EVALUATE(MLG)11605 EVALUATE(MLG) {
11606 UNIMPLEMENTED();
11607 USE(instr);
11608 return 0;
11609 }
11610
EVALUATE(DLG)11611 EVALUATE(DLG) {
11612 UNIMPLEMENTED();
11613 USE(instr);
11614 return 0;
11615 }
11616
EVALUATE(ALCG)11617 EVALUATE(ALCG) {
11618 UNIMPLEMENTED();
11619 USE(instr);
11620 return 0;
11621 }
11622
EVALUATE(SLBG)11623 EVALUATE(SLBG) {
11624 UNIMPLEMENTED();
11625 USE(instr);
11626 return 0;
11627 }
11628
EVALUATE(STPQ)11629 EVALUATE(STPQ) {
11630 UNIMPLEMENTED();
11631 USE(instr);
11632 return 0;
11633 }
11634
EVALUATE(LPQ)11635 EVALUATE(LPQ) {
11636 UNIMPLEMENTED();
11637 USE(instr);
11638 return 0;
11639 }
11640
EVALUATE(LLGH)11641 EVALUATE(LLGH) {
11642 DCHECK_OPCODE(LLGH);
11643 // Load Logical Halfword
11644 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11645 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11646 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11647 intptr_t d2_val = d2;
11648 uint16_t mem_val = ReadHU(b2_val + d2_val + x2_val, instr);
11649 set_register(r1, mem_val);
11650 return length;
11651 }
11652
EVALUATE(LLH)11653 EVALUATE(LLH) {
11654 DCHECK_OPCODE(LLH);
11655 // Load Logical Halfword
11656 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11657 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11658 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11659 intptr_t d2_val = d2;
11660 uint16_t mem_val = ReadHU(b2_val + d2_val + x2_val, instr);
11661 set_low_register(r1, mem_val);
11662 return length;
11663 }
11664
EVALUATE(ML)11665 EVALUATE(ML) {
11666 DCHECK_OPCODE(ML);
11667 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11668 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11669 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11670 DCHECK(r1 % 2 == 0);
11671 uint32_t mem_val = ReadWU(b2_val + x2_val + d2, instr);
11672 uint32_t r1_val = get_low_register<uint32_t>(r1 + 1);
11673 uint64_t product =
11674 static_cast<uint64_t>(r1_val) * static_cast<uint64_t>(mem_val);
11675 uint32_t high_bits = product >> 32;
11676 r1_val = high_bits;
11677 uint32_t low_bits = product & 0x00000000FFFFFFFF;
11678 set_low_register(r1, high_bits);
11679 set_low_register(r1 + 1, low_bits);
11680 return length;
11681 }
11682
EVALUATE(DL)11683 EVALUATE(DL) {
11684 DCHECK_OPCODE(DL);
11685 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11686 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11687 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11688 DCHECK(r1 % 2 == 0);
11689 uint32_t mem_val = ReadWU(b2_val + x2_val + d2, instr);
11690 uint32_t r1_val = get_low_register<uint32_t>(r1 + 1);
11691 uint64_t quotient =
11692 static_cast<uint64_t>(r1_val) / static_cast<uint64_t>(mem_val);
11693 uint64_t remainder =
11694 static_cast<uint64_t>(r1_val) % static_cast<uint64_t>(mem_val);
11695 set_low_register(r1, remainder);
11696 set_low_register(r1 + 1, quotient);
11697 return length;
11698 }
11699
EVALUATE(ALC)11700 EVALUATE(ALC) {
11701 UNIMPLEMENTED();
11702 USE(instr);
11703 return 0;
11704 }
11705
EVALUATE(SLB)11706 EVALUATE(SLB) {
11707 UNIMPLEMENTED();
11708 USE(instr);
11709 return 0;
11710 }
11711
EVALUATE(LLGTAT)11712 EVALUATE(LLGTAT) {
11713 UNIMPLEMENTED();
11714 USE(instr);
11715 return 0;
11716 }
11717
EVALUATE(LLGFAT)11718 EVALUATE(LLGFAT) {
11719 UNIMPLEMENTED();
11720 USE(instr);
11721 return 0;
11722 }
11723
EVALUATE(LAT)11724 EVALUATE(LAT) {
11725 UNIMPLEMENTED();
11726 USE(instr);
11727 return 0;
11728 }
11729
EVALUATE(LBH)11730 EVALUATE(LBH) {
11731 UNIMPLEMENTED();
11732 USE(instr);
11733 return 0;
11734 }
11735
EVALUATE(LLCH)11736 EVALUATE(LLCH) {
11737 UNIMPLEMENTED();
11738 USE(instr);
11739 return 0;
11740 }
11741
EVALUATE(STCH)11742 EVALUATE(STCH) {
11743 UNIMPLEMENTED();
11744 USE(instr);
11745 return 0;
11746 }
11747
EVALUATE(LHH)11748 EVALUATE(LHH) {
11749 UNIMPLEMENTED();
11750 USE(instr);
11751 return 0;
11752 }
11753
EVALUATE(LLHH)11754 EVALUATE(LLHH) {
11755 UNIMPLEMENTED();
11756 USE(instr);
11757 return 0;
11758 }
11759
EVALUATE(STHH)11760 EVALUATE(STHH) {
11761 UNIMPLEMENTED();
11762 USE(instr);
11763 return 0;
11764 }
11765
EVALUATE(LFHAT)11766 EVALUATE(LFHAT) {
11767 UNIMPLEMENTED();
11768 USE(instr);
11769 return 0;
11770 }
11771
EVALUATE(LFH)11772 EVALUATE(LFH) {
11773 UNIMPLEMENTED();
11774 USE(instr);
11775 return 0;
11776 }
11777
EVALUATE(STFH)11778 EVALUATE(STFH) {
11779 UNIMPLEMENTED();
11780 USE(instr);
11781 return 0;
11782 }
11783
EVALUATE(CHF)11784 EVALUATE(CHF) {
11785 UNIMPLEMENTED();
11786 USE(instr);
11787 return 0;
11788 }
11789
EVALUATE(MVCDK)11790 EVALUATE(MVCDK) {
11791 UNIMPLEMENTED();
11792 USE(instr);
11793 return 0;
11794 }
11795
EVALUATE(MVHHI)11796 EVALUATE(MVHHI) {
11797 UNIMPLEMENTED();
11798 USE(instr);
11799 return 0;
11800 }
11801
EVALUATE(MVGHI)11802 EVALUATE(MVGHI) {
11803 DCHECK_OPCODE(MVGHI);
11804 // Move Integer (64)
11805 DECODE_SIL_INSTRUCTION(b1, d1, i2);
11806 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
11807 intptr_t src_addr = b1_val + d1;
11808 WriteDW(src_addr, i2);
11809 return length;
11810 }
11811
EVALUATE(MVHI)11812 EVALUATE(MVHI) {
11813 DCHECK_OPCODE(MVHI);
11814 // Move Integer (32)
11815 DECODE_SIL_INSTRUCTION(b1, d1, i2);
11816 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
11817 intptr_t src_addr = b1_val + d1;
11818 WriteW(src_addr, i2, instr);
11819 return length;
11820 }
11821
EVALUATE(CHHSI)11822 EVALUATE(CHHSI) {
11823 UNIMPLEMENTED();
11824 USE(instr);
11825 return 0;
11826 }
11827
EVALUATE(CGHSI)11828 EVALUATE(CGHSI) {
11829 UNIMPLEMENTED();
11830 USE(instr);
11831 return 0;
11832 }
11833
EVALUATE(CHSI)11834 EVALUATE(CHSI) {
11835 UNIMPLEMENTED();
11836 USE(instr);
11837 return 0;
11838 }
11839
EVALUATE(CLFHSI)11840 EVALUATE(CLFHSI) {
11841 UNIMPLEMENTED();
11842 USE(instr);
11843 return 0;
11844 }
11845
EVALUATE(TBEGIN)11846 EVALUATE(TBEGIN) {
11847 UNIMPLEMENTED();
11848 USE(instr);
11849 return 0;
11850 }
11851
EVALUATE(TBEGINC)11852 EVALUATE(TBEGINC) {
11853 UNIMPLEMENTED();
11854 USE(instr);
11855 return 0;
11856 }
11857
EVALUATE(LMG)11858 EVALUATE(LMG) {
11859 DCHECK_OPCODE(LMG);
11860 // Store Multiple 64-bits.
11861 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
11862 int rb = b2;
11863 int offset = d2;
11864
11865 // Regs roll around if r3 is less than r1.
11866 // Artifically increase r3 by 16 so we can calculate
11867 // the number of regs stored properly.
11868 if (r3 < r1) r3 += 16;
11869
11870 int64_t rb_val = (rb == 0) ? 0 : get_register(rb);
11871
11872 // Store each register in ascending order.
11873 for (int i = 0; i <= r3 - r1; i++) {
11874 int64_t value = ReadDW(rb_val + offset + 8 * i);
11875 set_register((r1 + i) % 16, value);
11876 }
11877 return length;
11878 }
11879
EVALUATE(SRAG)11880 EVALUATE(SRAG) {
11881 DCHECK_OPCODE(SRAG);
11882 // 64-bit non-clobbering shift-left/right arithmetic
11883 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
11884 // only takes rightmost 6 bits
11885 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11886 int shiftBits = (b2_val + d2) & 0x3F;
11887 int64_t r3_val = get_register(r3);
11888 intptr_t alu_out = 0;
11889 bool isOF = false;
11890 alu_out = r3_val >> shiftBits;
11891 set_register(r1, alu_out);
11892 SetS390ConditionCode<intptr_t>(alu_out, 0);
11893 SetS390OverflowCode(isOF);
11894 return length;
11895 }
11896
EVALUATE(SLAG)11897 EVALUATE(SLAG) {
11898 DCHECK_OPCODE(SLAG);
11899 // 64-bit non-clobbering shift-left/right arithmetic
11900 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
11901 // only takes rightmost 6 bits
11902 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11903 int shiftBits = (b2_val + d2) & 0x3F;
11904 int64_t r3_val = get_register(r3);
11905 intptr_t alu_out = 0;
11906 bool isOF = false;
11907 isOF = CheckOverflowForShiftLeft(r3_val, shiftBits);
11908 alu_out = r3_val << shiftBits;
11909 set_register(r1, alu_out);
11910 SetS390ConditionCode<intptr_t>(alu_out, 0);
11911 SetS390OverflowCode(isOF);
11912 return length;
11913 }
11914
EVALUATE(SRLG)11915 EVALUATE(SRLG) {
11916 DCHECK_OPCODE(SRLG);
11917 // For SLLG/SRLG, the 64-bit third operand is shifted the number
11918 // of bits specified by the second-operand address, and the result is
11919 // placed at the first-operand location. Except for when the R1 and R3
11920 // fields designate the same register, the third operand remains
11921 // unchanged in general register R3.
11922 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
11923 // only takes rightmost 6 bits
11924 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11925 int shiftBits = (b2_val + d2) & 0x3F;
11926 // unsigned
11927 uint64_t r3_val = get_register(r3);
11928 uint64_t alu_out = 0;
11929 alu_out = r3_val >> shiftBits;
11930 set_register(r1, alu_out);
11931 return length;
11932 }
11933
EVALUATE(SLLG)11934 EVALUATE(SLLG) {
11935 DCHECK_OPCODE(SLLG);
11936 // For SLLG/SRLG, the 64-bit third operand is shifted the number
11937 // of bits specified by the second-operand address, and the result is
11938 // placed at the first-operand location. Except for when the R1 and R3
11939 // fields designate the same register, the third operand remains
11940 // unchanged in general register R3.
11941 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
11942 // only takes rightmost 6 bits
11943 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11944 int shiftBits = (b2_val + d2) & 0x3F;
11945 // unsigned
11946 uint64_t r3_val = get_register(r3);
11947 uint64_t alu_out = 0;
11948 alu_out = r3_val << shiftBits;
11949 set_register(r1, alu_out);
11950 return length;
11951 }
11952
EVALUATE(CSY)11953 EVALUATE(CSY) {
11954 UNIMPLEMENTED();
11955 USE(instr);
11956 return 0;
11957 }
11958
EVALUATE(RLLG)11959 EVALUATE(RLLG) {
11960 DCHECK_OPCODE(RLLG);
11961 // For SLLG/SRLG, the 64-bit third operand is shifted the number
11962 // of bits specified by the second-operand address, and the result is
11963 // placed at the first-operand location. Except for when the R1 and R3
11964 // fields designate the same register, the third operand remains
11965 // unchanged in general register R3.
11966 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
11967 // only takes rightmost 6 bits
11968 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11969 int shiftBits = (b2_val + d2) & 0x3F;
11970 // unsigned
11971 uint64_t r3_val = get_register(r3);
11972 uint64_t alu_out = 0;
11973 uint64_t rotateBits = r3_val >> (64 - shiftBits);
11974 alu_out = (r3_val << shiftBits) | (rotateBits);
11975 set_register(r1, alu_out);
11976 return length;
11977 }
11978
EVALUATE(STMG)11979 EVALUATE(STMG) {
11980 DCHECK_OPCODE(STMG);
11981 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
11982 int rb = b2;
11983 int offset = d2;
11984
11985 // Regs roll around if r3 is less than r1.
11986 // Artifically increase r3 by 16 so we can calculate
11987 // the number of regs stored properly.
11988 if (r3 < r1) r3 += 16;
11989
11990 int64_t rb_val = (rb == 0) ? 0 : get_register(rb);
11991
11992 // Store each register in ascending order.
11993 for (int i = 0; i <= r3 - r1; i++) {
11994 int64_t value = get_register((r1 + i) % 16);
11995 WriteDW(rb_val + offset + 8 * i, value);
11996 }
11997 return length;
11998 }
11999
EVALUATE(STMH)12000 EVALUATE(STMH) {
12001 UNIMPLEMENTED();
12002 USE(instr);
12003 return 0;
12004 }
12005
EVALUATE(STCMH)12006 EVALUATE(STCMH) {
12007 UNIMPLEMENTED();
12008 USE(instr);
12009 return 0;
12010 }
12011
EVALUATE(STCMY)12012 EVALUATE(STCMY) {
12013 UNIMPLEMENTED();
12014 USE(instr);
12015 return 0;
12016 }
12017
EVALUATE(CDSY)12018 EVALUATE(CDSY) {
12019 UNIMPLEMENTED();
12020 USE(instr);
12021 return 0;
12022 }
12023
EVALUATE(CDSG)12024 EVALUATE(CDSG) {
12025 UNIMPLEMENTED();
12026 USE(instr);
12027 return 0;
12028 }
12029
EVALUATE(BXHG)12030 EVALUATE(BXHG) {
12031 UNIMPLEMENTED();
12032 USE(instr);
12033 return 0;
12034 }
12035
EVALUATE(BXLEG)12036 EVALUATE(BXLEG) {
12037 UNIMPLEMENTED();
12038 USE(instr);
12039 return 0;
12040 }
12041
EVALUATE(ECAG)12042 EVALUATE(ECAG) {
12043 UNIMPLEMENTED();
12044 USE(instr);
12045 return 0;
12046 }
12047
EVALUATE(TMY)12048 EVALUATE(TMY) {
12049 DCHECK_OPCODE(TMY);
12050 // Test Under Mask (Mem - Imm) (8)
12051 DECODE_SIY_INSTRUCTION(b1, d1, i2);
12052 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
12053 intptr_t d1_val = d1;
12054 intptr_t addr = b1_val + d1_val;
12055 uint8_t mem_val = ReadB(addr);
12056 uint8_t imm_val = i2;
12057 uint8_t selected_bits = mem_val & imm_val;
12058 // CC0: Selected bits are zero
12059 // CC1: Selected bits mixed zeros and ones
12060 // CC3: Selected bits all ones
12061 if (0 == selected_bits) {
12062 condition_reg_ = CC_EQ; // CC0
12063 } else if (selected_bits == imm_val) {
12064 condition_reg_ = 0x1; // CC3
12065 } else {
12066 condition_reg_ = 0x4; // CC1
12067 }
12068 return length;
12069 }
12070
EVALUATE(MVIY)12071 EVALUATE(MVIY) {
12072 UNIMPLEMENTED();
12073 USE(instr);
12074 return 0;
12075 }
12076
EVALUATE(NIY)12077 EVALUATE(NIY) {
12078 UNIMPLEMENTED();
12079 USE(instr);
12080 return 0;
12081 }
12082
EVALUATE(CLIY)12083 EVALUATE(CLIY) {
12084 DCHECK_OPCODE(CLIY);
12085 DECODE_SIY_INSTRUCTION(b1, d1, i2);
12086 // Compare Immediate (Mem - Imm) (8)
12087 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
12088 intptr_t d1_val = d1;
12089 intptr_t addr = b1_val + d1_val;
12090 uint8_t mem_val = ReadB(addr);
12091 uint8_t imm_val = i2;
12092 SetS390ConditionCode<uint8_t>(mem_val, imm_val);
12093 return length;
12094 }
12095
EVALUATE(OIY)12096 EVALUATE(OIY) {
12097 UNIMPLEMENTED();
12098 USE(instr);
12099 return 0;
12100 }
12101
EVALUATE(XIY)12102 EVALUATE(XIY) {
12103 UNIMPLEMENTED();
12104 USE(instr);
12105 return 0;
12106 }
12107
EVALUATE(ASI)12108 EVALUATE(ASI) {
12109 DCHECK_OPCODE(ASI);
12110 // TODO(bcleung): Change all fooInstr->I2Value() to template functions.
12111 // The below static cast to 8 bit and then to 32 bit is necessary
12112 // because siyInstr->I2Value() returns a uint8_t, which a direct
12113 // cast to int32_t could incorrectly interpret.
12114 DECODE_SIY_INSTRUCTION(b1, d1, i2_unsigned);
12115 int8_t i2_8bit = static_cast<int8_t>(i2_unsigned);
12116 int32_t i2 = static_cast<int32_t>(i2_8bit);
12117 intptr_t b1_val = (b1 == 0) ? 0 : get_register(b1);
12118
12119 int d1_val = d1;
12120 intptr_t addr = b1_val + d1_val;
12121
12122 int32_t mem_val = ReadW(addr, instr);
12123 bool isOF = CheckOverflowForIntAdd(mem_val, i2, int32_t);
12124 int32_t alu_out = mem_val + i2;
12125 SetS390ConditionCode<int32_t>(alu_out, 0);
12126 SetS390OverflowCode(isOF);
12127 WriteW(addr, alu_out, instr);
12128 return length;
12129 }
12130
EVALUATE(ALSI)12131 EVALUATE(ALSI) {
12132 UNIMPLEMENTED();
12133 USE(instr);
12134 return 0;
12135 }
12136
EVALUATE(AGSI)12137 EVALUATE(AGSI) {
12138 DCHECK_OPCODE(AGSI);
12139 // TODO(bcleung): Change all fooInstr->I2Value() to template functions.
12140 // The below static cast to 8 bit and then to 32 bit is necessary
12141 // because siyInstr->I2Value() returns a uint8_t, which a direct
12142 // cast to int32_t could incorrectly interpret.
12143 DECODE_SIY_INSTRUCTION(b1, d1, i2_unsigned);
12144 int8_t i2_8bit = static_cast<int8_t>(i2_unsigned);
12145 int64_t i2 = static_cast<int64_t>(i2_8bit);
12146 intptr_t b1_val = (b1 == 0) ? 0 : get_register(b1);
12147
12148 int d1_val = d1;
12149 intptr_t addr = b1_val + d1_val;
12150
12151 int64_t mem_val = ReadDW(addr);
12152 int isOF = CheckOverflowForIntAdd(mem_val, i2, int64_t);
12153 int64_t alu_out = mem_val + i2;
12154 SetS390ConditionCode<uint64_t>(alu_out, 0);
12155 SetS390OverflowCode(isOF);
12156 WriteDW(addr, alu_out);
12157 return length;
12158 }
12159
EVALUATE(ALGSI)12160 EVALUATE(ALGSI) {
12161 UNIMPLEMENTED();
12162 USE(instr);
12163 return 0;
12164 }
12165
EVALUATE(ICMH)12166 EVALUATE(ICMH) {
12167 UNIMPLEMENTED();
12168 USE(instr);
12169 return 0;
12170 }
12171
EVALUATE(ICMY)12172 EVALUATE(ICMY) {
12173 UNIMPLEMENTED();
12174 USE(instr);
12175 return 0;
12176 }
12177
EVALUATE(MVCLU)12178 EVALUATE(MVCLU) {
12179 UNIMPLEMENTED();
12180 USE(instr);
12181 return 0;
12182 }
12183
EVALUATE(CLCLU)12184 EVALUATE(CLCLU) {
12185 UNIMPLEMENTED();
12186 USE(instr);
12187 return 0;
12188 }
12189
EVALUATE(STMY)12190 EVALUATE(STMY) {
12191 DCHECK_OPCODE(STMY);
12192 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
12193 // Load/Store Multiple (32)
12194 int offset = d2;
12195
12196 // Regs roll around if r3 is less than r1.
12197 // Artifically increase r3 by 16 so we can calculate
12198 // the number of regs stored properly.
12199 if (r3 < r1) r3 += 16;
12200
12201 int32_t b2_val = (b2 == 0) ? 0 : get_low_register<int32_t>(b2);
12202
12203 // Store each register in ascending order.
12204 for (int i = 0; i <= r3 - r1; i++) {
12205 int32_t value = get_low_register<int32_t>((r1 + i) % 16);
12206 WriteW(b2_val + offset + 4 * i, value, instr);
12207 }
12208 return length;
12209 }
12210
EVALUATE(LMH)12211 EVALUATE(LMH) {
12212 UNIMPLEMENTED();
12213 USE(instr);
12214 return 0;
12215 }
12216
EVALUATE(LMY)12217 EVALUATE(LMY) {
12218 DCHECK_OPCODE(LMY);
12219 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
12220 // Load/Store Multiple (32)
12221 int offset = d2;
12222
12223 // Regs roll around if r3 is less than r1.
12224 // Artifically increase r3 by 16 so we can calculate
12225 // the number of regs stored properly.
12226 if (r3 < r1) r3 += 16;
12227
12228 int32_t b2_val = (b2 == 0) ? 0 : get_low_register<int32_t>(b2);
12229
12230 // Store each register in ascending order.
12231 for (int i = 0; i <= r3 - r1; i++) {
12232 int32_t value = ReadW(b2_val + offset + 4 * i, instr);
12233 set_low_register((r1 + i) % 16, value);
12234 }
12235 return length;
12236 }
12237
EVALUATE(TP)12238 EVALUATE(TP) {
12239 UNIMPLEMENTED();
12240 USE(instr);
12241 return 0;
12242 }
12243
EVALUATE(SRAK)12244 EVALUATE(SRAK) {
12245 DCHECK_OPCODE(SRAK);
12246 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
12247 // 32-bit non-clobbering shift-left/right arithmetic
12248 // only takes rightmost 6 bits
12249 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
12250 int shiftBits = (b2_val + d2) & 0x3F;
12251 int32_t r3_val = get_low_register<int32_t>(r3);
12252 int32_t alu_out = 0;
12253 bool isOF = false;
12254 alu_out = r3_val >> shiftBits;
12255 set_low_register(r1, alu_out);
12256 SetS390ConditionCode<int32_t>(alu_out, 0);
12257 SetS390OverflowCode(isOF);
12258 return length;
12259 }
12260
EVALUATE(SLAK)12261 EVALUATE(SLAK) {
12262 DCHECK_OPCODE(SLAK);
12263 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
12264 // 32-bit non-clobbering shift-left/right arithmetic
12265 // only takes rightmost 6 bits
12266 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
12267 int shiftBits = (b2_val + d2) & 0x3F;
12268 int32_t r3_val = get_low_register<int32_t>(r3);
12269 int32_t alu_out = 0;
12270 bool isOF = false;
12271 isOF = CheckOverflowForShiftLeft(r3_val, shiftBits);
12272 alu_out = r3_val << shiftBits;
12273 set_low_register(r1, alu_out);
12274 SetS390ConditionCode<int32_t>(alu_out, 0);
12275 SetS390OverflowCode(isOF);
12276 return length;
12277 }
12278
EVALUATE(SRLK)12279 EVALUATE(SRLK) {
12280 DCHECK_OPCODE(SRLK);
12281 // For SLLK/SRLL, the 32-bit third operand is shifted the number
12282 // of bits specified by the second-operand address, and the result is
12283 // placed at the first-operand location. Except for when the R1 and R3
12284 // fields designate the same register, the third operand remains
12285 // unchanged in general register R3.
12286 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
12287 // only takes rightmost 6 bits
12288 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
12289 int shiftBits = (b2_val + d2) & 0x3F;
12290 // unsigned
12291 uint32_t r3_val = get_low_register<uint32_t>(r3);
12292 uint32_t alu_out = 0;
12293 alu_out = r3_val >> shiftBits;
12294 set_low_register(r1, alu_out);
12295 return length;
12296 }
12297
EVALUATE(SLLK)12298 EVALUATE(SLLK) {
12299 DCHECK_OPCODE(SLLK);
12300 // For SLLK/SRLL, the 32-bit third operand is shifted the number
12301 // of bits specified by the second-operand address, and the result is
12302 // placed at the first-operand location. Except for when the R1 and R3
12303 // fields designate the same register, the third operand remains
12304 // unchanged in general register R3.
12305 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
12306 // only takes rightmost 6 bits
12307 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
12308 int shiftBits = (b2_val + d2) & 0x3F;
12309 // unsigned
12310 uint32_t r3_val = get_low_register<uint32_t>(r3);
12311 uint32_t alu_out = 0;
12312 alu_out = r3_val << shiftBits;
12313 set_low_register(r1, alu_out);
12314 return length;
12315 }
12316
EVALUATE(LOCG)12317 EVALUATE(LOCG) {
12318 UNIMPLEMENTED();
12319 USE(instr);
12320 return 0;
12321 }
12322
EVALUATE(STOCG)12323 EVALUATE(STOCG) {
12324 UNIMPLEMENTED();
12325 USE(instr);
12326 return 0;
12327 }
12328
EVALUATE(LANG)12329 EVALUATE(LANG) {
12330 UNIMPLEMENTED();
12331 USE(instr);
12332 return 0;
12333 }
12334
EVALUATE(LAOG)12335 EVALUATE(LAOG) {
12336 UNIMPLEMENTED();
12337 USE(instr);
12338 return 0;
12339 }
12340
EVALUATE(LAXG)12341 EVALUATE(LAXG) {
12342 UNIMPLEMENTED();
12343 USE(instr);
12344 return 0;
12345 }
12346
EVALUATE(LAAG)12347 EVALUATE(LAAG) {
12348 UNIMPLEMENTED();
12349 USE(instr);
12350 return 0;
12351 }
12352
EVALUATE(LAALG)12353 EVALUATE(LAALG) {
12354 UNIMPLEMENTED();
12355 USE(instr);
12356 return 0;
12357 }
12358
EVALUATE(LOC)12359 EVALUATE(LOC) {
12360 UNIMPLEMENTED();
12361 USE(instr);
12362 return 0;
12363 }
12364
EVALUATE(STOC)12365 EVALUATE(STOC) {
12366 UNIMPLEMENTED();
12367 USE(instr);
12368 return 0;
12369 }
12370
EVALUATE(LAN)12371 EVALUATE(LAN) {
12372 UNIMPLEMENTED();
12373 USE(instr);
12374 return 0;
12375 }
12376
EVALUATE(LAO)12377 EVALUATE(LAO) {
12378 UNIMPLEMENTED();
12379 USE(instr);
12380 return 0;
12381 }
12382
EVALUATE(LAX)12383 EVALUATE(LAX) {
12384 UNIMPLEMENTED();
12385 USE(instr);
12386 return 0;
12387 }
12388
EVALUATE(LAA)12389 EVALUATE(LAA) {
12390 UNIMPLEMENTED();
12391 USE(instr);
12392 return 0;
12393 }
12394
EVALUATE(LAAL)12395 EVALUATE(LAAL) {
12396 UNIMPLEMENTED();
12397 USE(instr);
12398 return 0;
12399 }
12400
EVALUATE(BRXHG)12401 EVALUATE(BRXHG) {
12402 UNIMPLEMENTED();
12403 USE(instr);
12404 return 0;
12405 }
12406
EVALUATE(BRXLG)12407 EVALUATE(BRXLG) {
12408 UNIMPLEMENTED();
12409 USE(instr);
12410 return 0;
12411 }
12412
EVALUATE(RISBLG)12413 EVALUATE(RISBLG) {
12414 UNIMPLEMENTED();
12415 USE(instr);
12416 return 0;
12417 }
12418
EVALUATE(RNSBG)12419 EVALUATE(RNSBG) {
12420 UNIMPLEMENTED();
12421 USE(instr);
12422 return 0;
12423 }
12424
EVALUATE(ROSBG)12425 EVALUATE(ROSBG) {
12426 UNIMPLEMENTED();
12427 USE(instr);
12428 return 0;
12429 }
12430
EVALUATE(RXSBG)12431 EVALUATE(RXSBG) {
12432 UNIMPLEMENTED();
12433 USE(instr);
12434 return 0;
12435 }
12436
EVALUATE(RISBGN)12437 EVALUATE(RISBGN) {
12438 UNIMPLEMENTED();
12439 USE(instr);
12440 return 0;
12441 }
12442
EVALUATE(RISBHG)12443 EVALUATE(RISBHG) {
12444 UNIMPLEMENTED();
12445 USE(instr);
12446 return 0;
12447 }
12448
EVALUATE(CGRJ)12449 EVALUATE(CGRJ) {
12450 UNIMPLEMENTED();
12451 USE(instr);
12452 return 0;
12453 }
12454
EVALUATE(CGIT)12455 EVALUATE(CGIT) {
12456 UNIMPLEMENTED();
12457 USE(instr);
12458 return 0;
12459 }
12460
EVALUATE(CIT)12461 EVALUATE(CIT) {
12462 UNIMPLEMENTED();
12463 USE(instr);
12464 return 0;
12465 }
12466
EVALUATE(CLFIT)12467 EVALUATE(CLFIT) {
12468 UNIMPLEMENTED();
12469 USE(instr);
12470 return 0;
12471 }
12472
EVALUATE(CGIJ)12473 EVALUATE(CGIJ) {
12474 UNIMPLEMENTED();
12475 USE(instr);
12476 return 0;
12477 }
12478
EVALUATE(CIJ)12479 EVALUATE(CIJ) {
12480 UNIMPLEMENTED();
12481 USE(instr);
12482 return 0;
12483 }
12484
EVALUATE(ALHSIK)12485 EVALUATE(ALHSIK) {
12486 UNIMPLEMENTED();
12487 USE(instr);
12488 return 0;
12489 }
12490
EVALUATE(ALGHSIK)12491 EVALUATE(ALGHSIK) {
12492 UNIMPLEMENTED();
12493 USE(instr);
12494 return 0;
12495 }
12496
EVALUATE(CGRB)12497 EVALUATE(CGRB) {
12498 UNIMPLEMENTED();
12499 USE(instr);
12500 return 0;
12501 }
12502
EVALUATE(CGIB)12503 EVALUATE(CGIB) {
12504 UNIMPLEMENTED();
12505 USE(instr);
12506 return 0;
12507 }
12508
EVALUATE(CIB)12509 EVALUATE(CIB) {
12510 UNIMPLEMENTED();
12511 USE(instr);
12512 return 0;
12513 }
12514
EVALUATE(LDEB)12515 EVALUATE(LDEB) {
12516 DCHECK_OPCODE(LDEB);
12517 // Load Float
12518 DECODE_RXE_INSTRUCTION(r1, b2, x2, d2);
12519 int rb = b2;
12520 int rx = x2;
12521 int offset = d2;
12522 int64_t rb_val = (rb == 0) ? 0 : get_register(rb);
12523 int64_t rx_val = (rx == 0) ? 0 : get_register(rx);
12524 double ret =
12525 static_cast<double>(*reinterpret_cast<float*>(rx_val + rb_val + offset));
12526 set_d_register_from_double(r1, ret);
12527 return length;
12528 }
12529
EVALUATE(LXDB)12530 EVALUATE(LXDB) {
12531 UNIMPLEMENTED();
12532 USE(instr);
12533 return 0;
12534 }
12535
EVALUATE(LXEB)12536 EVALUATE(LXEB) {
12537 UNIMPLEMENTED();
12538 USE(instr);
12539 return 0;
12540 }
12541
EVALUATE(MXDB)12542 EVALUATE(MXDB) {
12543 UNIMPLEMENTED();
12544 USE(instr);
12545 return 0;
12546 }
12547
EVALUATE(KEB)12548 EVALUATE(KEB) {
12549 UNIMPLEMENTED();
12550 USE(instr);
12551 return 0;
12552 }
12553
EVALUATE(CEB)12554 EVALUATE(CEB) {
12555 DCHECK_OPCODE(CEB);
12556
12557 DECODE_RXE_INSTRUCTION(r1, b2, x2, d2);
12558 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
12559 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
12560 intptr_t d2_val = d2;
12561 float r1_val = get_float32_from_d_register(r1);
12562 float fval = ReadFloat(b2_val + x2_val + d2_val);
12563 SetS390ConditionCode<float>(r1_val, fval);
12564 return length;
12565 }
12566
EVALUATE(AEB)12567 EVALUATE(AEB) {
12568 UNIMPLEMENTED();
12569 USE(instr);
12570 return 0;
12571 }
12572
EVALUATE(SEB)12573 EVALUATE(SEB) {
12574 UNIMPLEMENTED();
12575 USE(instr);
12576 return 0;
12577 }
12578
EVALUATE(MDEB)12579 EVALUATE(MDEB) {
12580 UNIMPLEMENTED();
12581 USE(instr);
12582 return 0;
12583 }
12584
EVALUATE(DEB)12585 EVALUATE(DEB) {
12586 UNIMPLEMENTED();
12587 USE(instr);
12588 return 0;
12589 }
12590
EVALUATE(MAEB)12591 EVALUATE(MAEB) {
12592 UNIMPLEMENTED();
12593 USE(instr);
12594 return 0;
12595 }
12596
EVALUATE(MSEB)12597 EVALUATE(MSEB) {
12598 UNIMPLEMENTED();
12599 USE(instr);
12600 return 0;
12601 }
12602
EVALUATE(TCEB)12603 EVALUATE(TCEB) {
12604 UNIMPLEMENTED();
12605 USE(instr);
12606 return 0;
12607 }
12608
EVALUATE(TCDB)12609 EVALUATE(TCDB) {
12610 UNIMPLEMENTED();
12611 USE(instr);
12612 return 0;
12613 }
12614
EVALUATE(TCXB)12615 EVALUATE(TCXB) {
12616 UNIMPLEMENTED();
12617 USE(instr);
12618 return 0;
12619 }
12620
EVALUATE(SQEB)12621 EVALUATE(SQEB) {
12622 UNIMPLEMENTED();
12623 USE(instr);
12624 return 0;
12625 }
12626
EVALUATE(SQDB)12627 EVALUATE(SQDB) {
12628 DCHECK_OPCODE(SQDB);
12629 DECODE_RXE_INSTRUCTION(r1, b2, x2, d2);
12630 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
12631 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
12632 intptr_t d2_val = d2;
12633 double r1_val = get_double_from_d_register(r1);
12634 double dbl_val = ReadDouble(b2_val + x2_val + d2_val);
12635 r1_val = std::sqrt(dbl_val);
12636 set_d_register_from_double(r1, r1_val);
12637 return length;
12638 }
12639
EVALUATE(MEEB)12640 EVALUATE(MEEB) {
12641 UNIMPLEMENTED();
12642 USE(instr);
12643 return 0;
12644 }
12645
EVALUATE(KDB)12646 EVALUATE(KDB) {
12647 UNIMPLEMENTED();
12648 USE(instr);
12649 return 0;
12650 }
12651
EVALUATE(CDB)12652 EVALUATE(CDB) {
12653 DCHECK_OPCODE(CDB);
12654
12655 DECODE_RXE_INSTRUCTION(r1, b2, x2, d2);
12656 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
12657 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
12658 intptr_t d2_val = d2;
12659 double r1_val = get_double_from_d_register(r1);
12660 double dbl_val = ReadDouble(b2_val + x2_val + d2_val);
12661 SetS390ConditionCode<double>(r1_val, dbl_val);
12662 return length;
12663 }
12664
EVALUATE(ADB)12665 EVALUATE(ADB) {
12666 DCHECK_OPCODE(ADB);
12667
12668 DECODE_RXE_INSTRUCTION(r1, b2, x2, d2);
12669 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
12670 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
12671 intptr_t d2_val = d2;
12672 double r1_val = get_double_from_d_register(r1);
12673 double dbl_val = ReadDouble(b2_val + x2_val + d2_val);
12674 r1_val += dbl_val;
12675 set_d_register_from_double(r1, r1_val);
12676 SetS390ConditionCode<double>(r1_val, 0);
12677 return length;
12678 }
12679
EVALUATE(SDB)12680 EVALUATE(SDB) {
12681 DCHECK_OPCODE(SDB);
12682 DECODE_RXE_INSTRUCTION(r1, b2, x2, d2);
12683 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
12684 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
12685 intptr_t d2_val = d2;
12686 double r1_val = get_double_from_d_register(r1);
12687 double dbl_val = ReadDouble(b2_val + x2_val + d2_val);
12688 r1_val -= dbl_val;
12689 set_d_register_from_double(r1, r1_val);
12690 SetS390ConditionCode<double>(r1_val, 0);
12691 return length;
12692 }
12693
EVALUATE(MDB)12694 EVALUATE(MDB) {
12695 DCHECK_OPCODE(MDB);
12696 DECODE_RXE_INSTRUCTION(r1, b2, x2, d2);
12697 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
12698 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
12699 intptr_t d2_val = d2;
12700 double r1_val = get_double_from_d_register(r1);
12701 double dbl_val = ReadDouble(b2_val + x2_val + d2_val);
12702 r1_val *= dbl_val;
12703 set_d_register_from_double(r1, r1_val);
12704 SetS390ConditionCode<double>(r1_val, 0);
12705 return length;
12706 }
12707
EVALUATE(DDB)12708 EVALUATE(DDB) {
12709 DCHECK_OPCODE(DDB);
12710 DECODE_RXE_INSTRUCTION(r1, b2, x2, d2);
12711 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
12712 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
12713 intptr_t d2_val = d2;
12714 double r1_val = get_double_from_d_register(r1);
12715 double dbl_val = ReadDouble(b2_val + x2_val + d2_val);
12716 r1_val /= dbl_val;
12717 set_d_register_from_double(r1, r1_val);
12718 SetS390ConditionCode<double>(r1_val, 0);
12719 return length;
12720 }
12721
EVALUATE(MADB)12722 EVALUATE(MADB) {
12723 UNIMPLEMENTED();
12724 USE(instr);
12725 return 0;
12726 }
12727
EVALUATE(MSDB)12728 EVALUATE(MSDB) {
12729 UNIMPLEMENTED();
12730 USE(instr);
12731 return 0;
12732 }
12733
EVALUATE(SLDT)12734 EVALUATE(SLDT) {
12735 UNIMPLEMENTED();
12736 USE(instr);
12737 return 0;
12738 }
12739
EVALUATE(SRDT)12740 EVALUATE(SRDT) {
12741 UNIMPLEMENTED();
12742 USE(instr);
12743 return 0;
12744 }
12745
EVALUATE(SLXT)12746 EVALUATE(SLXT) {
12747 UNIMPLEMENTED();
12748 USE(instr);
12749 return 0;
12750 }
12751
EVALUATE(SRXT)12752 EVALUATE(SRXT) {
12753 UNIMPLEMENTED();
12754 USE(instr);
12755 return 0;
12756 }
12757
EVALUATE(TDCET)12758 EVALUATE(TDCET) {
12759 UNIMPLEMENTED();
12760 USE(instr);
12761 return 0;
12762 }
12763
EVALUATE(TDGET)12764 EVALUATE(TDGET) {
12765 UNIMPLEMENTED();
12766 USE(instr);
12767 return 0;
12768 }
12769
EVALUATE(TDCDT)12770 EVALUATE(TDCDT) {
12771 UNIMPLEMENTED();
12772 USE(instr);
12773 return 0;
12774 }
12775
EVALUATE(TDGDT)12776 EVALUATE(TDGDT) {
12777 UNIMPLEMENTED();
12778 USE(instr);
12779 return 0;
12780 }
12781
EVALUATE(TDCXT)12782 EVALUATE(TDCXT) {
12783 UNIMPLEMENTED();
12784 USE(instr);
12785 return 0;
12786 }
12787
EVALUATE(TDGXT)12788 EVALUATE(TDGXT) {
12789 UNIMPLEMENTED();
12790 USE(instr);
12791 return 0;
12792 }
12793
EVALUATE(LEY)12794 EVALUATE(LEY) {
12795 DCHECK_OPCODE(LEY);
12796 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
12797 // Miscellaneous Loads and Stores
12798 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
12799 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
12800 intptr_t addr = x2_val + b2_val + d2;
12801 float float_val = *reinterpret_cast<float*>(addr);
12802 set_d_register_from_float32(r1, float_val);
12803 return length;
12804 }
12805
EVALUATE(LDY)12806 EVALUATE(LDY) {
12807 DCHECK_OPCODE(LDY);
12808 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
12809 // Miscellaneous Loads and Stores
12810 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
12811 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
12812 intptr_t addr = x2_val + b2_val + d2;
12813 uint64_t dbl_val = *reinterpret_cast<uint64_t*>(addr);
12814 set_d_register(r1, dbl_val);
12815 return length;
12816 }
12817
EVALUATE(STEY)12818 EVALUATE(STEY) {
12819 DCHECK_OPCODE(STEY);
12820 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
12821 // Miscellaneous Loads and Stores
12822 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
12823 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
12824 intptr_t addr = x2_val + b2_val + d2;
12825 int64_t frs_val = get_d_register(r1) >> 32;
12826 WriteW(addr, static_cast<int32_t>(frs_val), instr);
12827 return length;
12828 }
12829
EVALUATE(STDY)12830 EVALUATE(STDY) {
12831 DCHECK_OPCODE(STDY);
12832 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
12833 // Miscellaneous Loads and Stores
12834 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
12835 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
12836 intptr_t addr = x2_val + b2_val + d2;
12837 int64_t frs_val = get_d_register(r1);
12838 WriteDW(addr, frs_val);
12839 return length;
12840 }
12841
EVALUATE(CZDT)12842 EVALUATE(CZDT) {
12843 UNIMPLEMENTED();
12844 USE(instr);
12845 return 0;
12846 }
12847
EVALUATE(CZXT)12848 EVALUATE(CZXT) {
12849 UNIMPLEMENTED();
12850 USE(instr);
12851 return 0;
12852 }
12853
EVALUATE(CDZT)12854 EVALUATE(CDZT) {
12855 UNIMPLEMENTED();
12856 USE(instr);
12857 return 0;
12858 }
12859
EVALUATE(CXZT)12860 EVALUATE(CXZT) {
12861 UNIMPLEMENTED();
12862 USE(instr);
12863 return 0;
12864 }
12865
12866 #undef EVALUATE
12867
12868 } // namespace internal
12869 } // namespace v8
12870
12871 #endif // USE_SIMULATOR
12872 #endif // V8_TARGET_ARCH_S390
12873