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