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