blob: 434fbffcfc53e040be9dafb7e593573090c8b536 [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
Ben Murdoch61f157c2016-09-16 13:49:30 +010026const auto GetRegConfig = RegisterConfiguration::Crankshaft;
27
Ben Murdochda12d292016-06-02 14:46:10 +010028// This macro provides a platform independent use of sscanf. The reason for
29// SScanF not being implemented in a platform independent way through
30// ::v8::internal::OS in the same way as SNPrintF is that the
31// Windows C Run-Time Library does not provide vsscanf.
32#define SScanF sscanf // NOLINT
33
34// The S390Debugger class is used by the simulator while debugging simulated
35// z/Architecture code.
36class S390Debugger {
37 public:
38 explicit S390Debugger(Simulator* sim) : sim_(sim) {}
39 ~S390Debugger();
40
41 void Stop(Instruction* instr);
42 void Debug();
43
44 private:
45#if V8_TARGET_LITTLE_ENDIAN
46 static const Instr kBreakpointInstr = (0x0000FFB2); // TRAP4 0000
47 static const Instr kNopInstr = (0x00160016); // OR r0, r0 x2
48#else
49 static const Instr kBreakpointInstr = (0xB2FF0000); // TRAP4 0000
50 static const Instr kNopInstr = (0x16001600); // OR r0, r0 x2
51#endif
52
53 Simulator* sim_;
54
55 intptr_t GetRegisterValue(int regnum);
56 double GetRegisterPairDoubleValue(int regnum);
57 double GetFPDoubleRegisterValue(int regnum);
58 float GetFPFloatRegisterValue(int regnum);
59 bool GetValue(const char* desc, intptr_t* value);
60 bool GetFPDoubleValue(const char* desc, double* value);
61
62 // Set or delete a breakpoint. Returns true if successful.
63 bool SetBreakpoint(Instruction* break_pc);
64 bool DeleteBreakpoint(Instruction* break_pc);
65
66 // Undo and redo all breakpoints. This is needed to bracket disassembly and
67 // execution to skip past breakpoints when run from the debugger.
68 void UndoBreakpoints();
69 void RedoBreakpoints();
70};
71
72S390Debugger::~S390Debugger() {}
73
74#ifdef GENERATED_CODE_COVERAGE
75static FILE* coverage_log = NULL;
76
77static void InitializeCoverage() {
78 char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG");
79 if (file_name != NULL) {
80 coverage_log = fopen(file_name, "aw+");
81 }
82}
83
84void S390Debugger::Stop(Instruction* instr) {
85 // Get the stop code.
86 uint32_t code = instr->SvcValue() & kStopCodeMask;
87 // Retrieve the encoded address, which comes just after this stop.
88 char** msg_address =
89 reinterpret_cast<char**>(sim_->get_pc() + sizeof(FourByteInstr));
90 char* msg = *msg_address;
91 DCHECK(msg != NULL);
92
93 // Update this stop description.
94 if (isWatchedStop(code) && !watched_stops_[code].desc) {
95 watched_stops_[code].desc = msg;
96 }
97
98 if (strlen(msg) > 0) {
99 if (coverage_log != NULL) {
100 fprintf(coverage_log, "%s\n", msg);
101 fflush(coverage_log);
102 }
103 // Overwrite the instruction and address with nops.
104 instr->SetInstructionBits(kNopInstr);
105 reinterpret_cast<Instruction*>(msg_address)->SetInstructionBits(kNopInstr);
106 }
107 sim_->set_pc(sim_->get_pc() + sizeof(FourByteInstr) + kPointerSize);
108}
109
110#else // ndef GENERATED_CODE_COVERAGE
111
112static void InitializeCoverage() {}
113
114void S390Debugger::Stop(Instruction* instr) {
115 // Get the stop code.
116 // use of kStopCodeMask not right on PowerPC
117 uint32_t code = instr->SvcValue() & kStopCodeMask;
118 // Retrieve the encoded address, which comes just after this stop.
119 char* msg = *reinterpret_cast<char**>(sim_->get_pc() + sizeof(FourByteInstr));
120 // Update this stop description.
121 if (sim_->isWatchedStop(code) && !sim_->watched_stops_[code].desc) {
122 sim_->watched_stops_[code].desc = msg;
123 }
124 // Print the stop message and code if it is not the default code.
125 if (code != kMaxStopCode) {
126 PrintF("Simulator hit stop %u: %s\n", code, msg);
127 } else {
128 PrintF("Simulator hit %s\n", msg);
129 }
130 sim_->set_pc(sim_->get_pc() + sizeof(FourByteInstr) + kPointerSize);
131 Debug();
132}
133#endif
134
135intptr_t S390Debugger::GetRegisterValue(int regnum) {
136 return sim_->get_register(regnum);
137}
138
139double S390Debugger::GetRegisterPairDoubleValue(int regnum) {
140 return sim_->get_double_from_register_pair(regnum);
141}
142
143double S390Debugger::GetFPDoubleRegisterValue(int regnum) {
144 return sim_->get_double_from_d_register(regnum);
145}
146
147float S390Debugger::GetFPFloatRegisterValue(int regnum) {
148 return sim_->get_float32_from_d_register(regnum);
149}
150
151bool S390Debugger::GetValue(const char* desc, intptr_t* value) {
152 int regnum = Registers::Number(desc);
153 if (regnum != kNoRegister) {
154 *value = GetRegisterValue(regnum);
155 return true;
156 } else {
157 if (strncmp(desc, "0x", 2) == 0) {
158 return SScanF(desc + 2, "%" V8PRIxPTR,
159 reinterpret_cast<uintptr_t*>(value)) == 1;
160 } else {
161 return SScanF(desc, "%" V8PRIuPTR, reinterpret_cast<uintptr_t*>(value)) ==
162 1;
163 }
164 }
165 return false;
166}
167
168bool S390Debugger::GetFPDoubleValue(const char* desc, double* value) {
169 int regnum = DoubleRegisters::Number(desc);
170 if (regnum != kNoRegister) {
171 *value = sim_->get_double_from_d_register(regnum);
172 return true;
173 }
174 return false;
175}
176
177bool S390Debugger::SetBreakpoint(Instruction* break_pc) {
178 // Check if a breakpoint can be set. If not return without any side-effects.
179 if (sim_->break_pc_ != NULL) {
180 return false;
181 }
182
183 // Set the breakpoint.
184 sim_->break_pc_ = break_pc;
185 sim_->break_instr_ = break_pc->InstructionBits();
186 // Not setting the breakpoint instruction in the code itself. It will be set
187 // when the debugger shell continues.
188 return true;
189}
190
191bool S390Debugger::DeleteBreakpoint(Instruction* break_pc) {
192 if (sim_->break_pc_ != NULL) {
193 sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
194 }
195
196 sim_->break_pc_ = NULL;
197 sim_->break_instr_ = 0;
198 return true;
199}
200
201void S390Debugger::UndoBreakpoints() {
202 if (sim_->break_pc_ != NULL) {
203 sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
204 }
205}
206
207void S390Debugger::RedoBreakpoints() {
208 if (sim_->break_pc_ != NULL) {
209 sim_->break_pc_->SetInstructionBits(kBreakpointInstr);
210 }
211}
212
213void S390Debugger::Debug() {
214 intptr_t last_pc = -1;
215 bool done = false;
216
217#define COMMAND_SIZE 63
218#define ARG_SIZE 255
219
220#define STR(a) #a
221#define XSTR(a) STR(a)
222
223 char cmd[COMMAND_SIZE + 1];
224 char arg1[ARG_SIZE + 1];
225 char arg2[ARG_SIZE + 1];
226 char* argv[3] = {cmd, arg1, arg2};
227
228 // make sure to have a proper terminating character if reaching the limit
229 cmd[COMMAND_SIZE] = 0;
230 arg1[ARG_SIZE] = 0;
231 arg2[ARG_SIZE] = 0;
232
233 // Undo all set breakpoints while running in the debugger shell. This will
234 // make them invisible to all commands.
235 UndoBreakpoints();
236 // Disable tracing while simulating
237 bool trace = ::v8::internal::FLAG_trace_sim;
238 ::v8::internal::FLAG_trace_sim = false;
239
240 while (!done && !sim_->has_bad_pc()) {
241 if (last_pc != sim_->get_pc()) {
242 disasm::NameConverter converter;
243 disasm::Disassembler dasm(converter);
244 // use a reasonably large buffer
245 v8::internal::EmbeddedVector<char, 256> buffer;
246 dasm.InstructionDecode(buffer, reinterpret_cast<byte*>(sim_->get_pc()));
247 PrintF(" 0x%08" V8PRIxPTR " %s\n", sim_->get_pc(), buffer.start());
248 last_pc = sim_->get_pc();
249 }
250 char* line = ReadLine("sim> ");
251 if (line == NULL) {
252 break;
253 } else {
254 char* last_input = sim_->last_debugger_input();
255 if (strcmp(line, "\n") == 0 && last_input != NULL) {
256 line = last_input;
257 } else {
258 // Ownership is transferred to sim_;
259 sim_->set_last_debugger_input(line);
260 }
261 // Use sscanf to parse the individual parts of the command line. At the
262 // moment no command expects more than two parameters.
263 int argc = SScanF(line,
264 "%" XSTR(COMMAND_SIZE) "s "
265 "%" XSTR(ARG_SIZE) "s "
266 "%" XSTR(ARG_SIZE) "s",
267 cmd, arg1, arg2);
268 if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) {
269 intptr_t value;
270
271 // If at a breakpoint, proceed past it.
272 if ((reinterpret_cast<Instruction*>(sim_->get_pc()))
273 ->InstructionBits() == 0x7d821008) {
274 sim_->set_pc(sim_->get_pc() + sizeof(FourByteInstr));
275 } else {
276 sim_->ExecuteInstruction(
277 reinterpret_cast<Instruction*>(sim_->get_pc()));
278 }
279
Ben Murdochc5610432016-08-08 18:44:38 +0100280 if (argc == 2 && last_pc != sim_->get_pc()) {
281 disasm::NameConverter converter;
282 disasm::Disassembler dasm(converter);
283 // use a reasonably large buffer
284 v8::internal::EmbeddedVector<char, 256> buffer;
285
286 if (GetValue(arg1, &value)) {
287 // Interpret a numeric argument as the number of instructions to
288 // step past.
289 for (int i = 1; (!sim_->has_bad_pc()) && i < value; i++) {
290 dasm.InstructionDecode(buffer,
291 reinterpret_cast<byte*>(sim_->get_pc()));
292 PrintF(" 0x%08" V8PRIxPTR " %s\n", sim_->get_pc(),
293 buffer.start());
294 sim_->ExecuteInstruction(
295 reinterpret_cast<Instruction*>(sim_->get_pc()));
296 }
297 } else {
298 // Otherwise treat it as the mnemonic of the opcode to stop at.
299 char mnemonic[256];
300 while (!sim_->has_bad_pc()) {
301 dasm.InstructionDecode(buffer,
302 reinterpret_cast<byte*>(sim_->get_pc()));
303 char* mnemonicStart = buffer.start();
304 while (*mnemonicStart != 0 && *mnemonicStart != ' ')
305 mnemonicStart++;
306 SScanF(mnemonicStart, "%s", mnemonic);
307 if (!strcmp(arg1, mnemonic)) break;
308
309 PrintF(" 0x%08" V8PRIxPTR " %s\n", sim_->get_pc(),
310 buffer.start());
311 sim_->ExecuteInstruction(
312 reinterpret_cast<Instruction*>(sim_->get_pc()));
313 }
Ben Murdochda12d292016-06-02 14:46:10 +0100314 }
315 }
316 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) {
317 // If at a breakpoint, proceed past it.
318 if ((reinterpret_cast<Instruction*>(sim_->get_pc()))
319 ->InstructionBits() == 0x7d821008) {
320 sim_->set_pc(sim_->get_pc() + sizeof(FourByteInstr));
321 } else {
322 // Execute the one instruction we broke at with breakpoints disabled.
323 sim_->ExecuteInstruction(
324 reinterpret_cast<Instruction*>(sim_->get_pc()));
325 }
326 // Leave the debugger shell.
327 done = true;
328 } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) {
329 if (argc == 2 || (argc == 3 && strcmp(arg2, "fp") == 0)) {
330 intptr_t value;
331 double dvalue;
332 if (strcmp(arg1, "all") == 0) {
333 for (int i = 0; i < kNumRegisters; i++) {
334 value = GetRegisterValue(i);
335 PrintF(" %3s: %08" V8PRIxPTR,
Ben Murdoch61f157c2016-09-16 13:49:30 +0100336 GetRegConfig()->GetGeneralRegisterName(i), value);
Ben Murdochda12d292016-06-02 14:46:10 +0100337 if ((argc == 3 && strcmp(arg2, "fp") == 0) && i < 8 &&
338 (i % 2) == 0) {
339 dvalue = GetRegisterPairDoubleValue(i);
340 PrintF(" (%f)\n", dvalue);
341 } else if (i != 0 && !((i + 1) & 3)) {
342 PrintF("\n");
343 }
344 }
345 PrintF(" pc: %08" V8PRIxPTR " cr: %08x\n", sim_->special_reg_pc_,
346 sim_->condition_reg_);
347 } else if (strcmp(arg1, "alld") == 0) {
348 for (int i = 0; i < kNumRegisters; i++) {
349 value = GetRegisterValue(i);
350 PrintF(" %3s: %08" V8PRIxPTR " %11" V8PRIdPTR,
Ben Murdoch61f157c2016-09-16 13:49:30 +0100351 GetRegConfig()->GetGeneralRegisterName(i), value, value);
Ben Murdochda12d292016-06-02 14:46:10 +0100352 if ((argc == 3 && strcmp(arg2, "fp") == 0) && i < 8 &&
353 (i % 2) == 0) {
354 dvalue = GetRegisterPairDoubleValue(i);
355 PrintF(" (%f)\n", dvalue);
356 } else if (!((i + 1) % 2)) {
357 PrintF("\n");
358 }
359 }
360 PrintF(" pc: %08" V8PRIxPTR " cr: %08x\n", sim_->special_reg_pc_,
361 sim_->condition_reg_);
362 } else if (strcmp(arg1, "allf") == 0) {
363 for (int i = 0; i < DoubleRegister::kNumRegisters; i++) {
364 float fvalue = GetFPFloatRegisterValue(i);
365 uint32_t as_words = bit_cast<uint32_t>(fvalue);
366 PrintF("%3s: %f 0x%08x\n",
Ben Murdoch61f157c2016-09-16 13:49:30 +0100367 GetRegConfig()->GetDoubleRegisterName(i), fvalue,
368 as_words);
Ben Murdochda12d292016-06-02 14:46:10 +0100369 }
370 } else if (strcmp(arg1, "alld") == 0) {
371 for (int i = 0; i < DoubleRegister::kNumRegisters; i++) {
372 dvalue = GetFPDoubleRegisterValue(i);
373 uint64_t as_words = bit_cast<uint64_t>(dvalue);
374 PrintF("%3s: %f 0x%08x %08x\n",
Ben Murdoch61f157c2016-09-16 13:49:30 +0100375 GetRegConfig()->GetDoubleRegisterName(i), dvalue,
Ben Murdochda12d292016-06-02 14:46:10 +0100376 static_cast<uint32_t>(as_words >> 32),
377 static_cast<uint32_t>(as_words & 0xffffffff));
378 }
379 } else if (arg1[0] == 'r' &&
380 (arg1[1] >= '0' && arg1[1] <= '2' &&
381 (arg1[2] == '\0' || (arg1[2] >= '0' && arg1[2] <= '5' &&
382 arg1[3] == '\0')))) {
383 int regnum = strtoul(&arg1[1], 0, 10);
384 if (regnum != kNoRegister) {
385 value = GetRegisterValue(regnum);
386 PrintF("%s: 0x%08" V8PRIxPTR " %" V8PRIdPTR "\n", arg1, value,
387 value);
388 } else {
389 PrintF("%s unrecognized\n", arg1);
390 }
391 } else {
392 if (GetValue(arg1, &value)) {
393 PrintF("%s: 0x%08" V8PRIxPTR " %" V8PRIdPTR "\n", arg1, value,
394 value);
395 } else if (GetFPDoubleValue(arg1, &dvalue)) {
396 uint64_t as_words = bit_cast<uint64_t>(dvalue);
397 PrintF("%s: %f 0x%08x %08x\n", arg1, dvalue,
398 static_cast<uint32_t>(as_words >> 32),
399 static_cast<uint32_t>(as_words & 0xffffffff));
400 } else {
401 PrintF("%s unrecognized\n", arg1);
402 }
403 }
404 } else {
405 PrintF("print <register>\n");
406 }
407 } else if ((strcmp(cmd, "po") == 0) ||
408 (strcmp(cmd, "printobject") == 0)) {
409 if (argc == 2) {
410 intptr_t value;
411 OFStream os(stdout);
412 if (GetValue(arg1, &value)) {
413 Object* obj = reinterpret_cast<Object*>(value);
414 os << arg1 << ": \n";
415#ifdef DEBUG
416 obj->Print(os);
417 os << "\n";
418#else
419 os << Brief(obj) << "\n";
420#endif
421 } else {
422 os << arg1 << " unrecognized\n";
423 }
424 } else {
425 PrintF("printobject <value>\n");
426 }
427 } else if (strcmp(cmd, "setpc") == 0) {
428 intptr_t value;
429
430 if (!GetValue(arg1, &value)) {
431 PrintF("%s unrecognized\n", arg1);
432 continue;
433 }
434 sim_->set_pc(value);
435 } else if (strcmp(cmd, "stack") == 0 || strcmp(cmd, "mem") == 0) {
436 intptr_t* cur = NULL;
437 intptr_t* end = NULL;
438 int next_arg = 1;
439
440 if (strcmp(cmd, "stack") == 0) {
441 cur = reinterpret_cast<intptr_t*>(sim_->get_register(Simulator::sp));
442 } else { // "mem"
443 intptr_t value;
444 if (!GetValue(arg1, &value)) {
445 PrintF("%s unrecognized\n", arg1);
446 continue;
447 }
448 cur = reinterpret_cast<intptr_t*>(value);
449 next_arg++;
450 }
451
452 intptr_t words; // likely inaccurate variable name for 64bit
453 if (argc == next_arg) {
454 words = 10;
455 } else {
456 if (!GetValue(argv[next_arg], &words)) {
457 words = 10;
458 }
459 }
460 end = cur + words;
461
462 while (cur < end) {
463 PrintF(" 0x%08" V8PRIxPTR ": 0x%08" V8PRIxPTR " %10" V8PRIdPTR,
464 reinterpret_cast<intptr_t>(cur), *cur, *cur);
465 HeapObject* obj = reinterpret_cast<HeapObject*>(*cur);
466 intptr_t value = *cur;
467 Heap* current_heap = sim_->isolate_->heap();
468 if (((value & 1) == 0) ||
469 current_heap->ContainsSlow(obj->address())) {
470 PrintF("(smi %d)", PlatformSmiTagging::SmiToInt(obj));
471 } else if (current_heap->Contains(obj)) {
472 PrintF(" (");
473 obj->ShortPrint();
474 PrintF(")");
475 }
476 PrintF("\n");
477 cur++;
478 }
479 } else if (strcmp(cmd, "disasm") == 0 || strcmp(cmd, "di") == 0) {
480 disasm::NameConverter converter;
481 disasm::Disassembler dasm(converter);
482 // use a reasonably large buffer
483 v8::internal::EmbeddedVector<char, 256> buffer;
484
485 byte* prev = NULL;
486 byte* cur = NULL;
487 // Default number of instructions to disassemble.
488 int32_t numInstructions = 10;
489
490 if (argc == 1) {
491 cur = reinterpret_cast<byte*>(sim_->get_pc());
492 } else if (argc == 2) {
493 int regnum = Registers::Number(arg1);
494 if (regnum != kNoRegister || strncmp(arg1, "0x", 2) == 0) {
495 // The argument is an address or a register name.
496 intptr_t value;
497 if (GetValue(arg1, &value)) {
498 cur = reinterpret_cast<byte*>(value);
499 }
500 } else {
501 // The argument is the number of instructions.
502 intptr_t value;
503 if (GetValue(arg1, &value)) {
504 cur = reinterpret_cast<byte*>(sim_->get_pc());
505 // Disassemble <arg1> instructions.
506 numInstructions = static_cast<int32_t>(value);
507 }
508 }
509 } else {
510 intptr_t value1;
511 intptr_t value2;
512 if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) {
513 cur = reinterpret_cast<byte*>(value1);
514 // Disassemble <arg2> instructions.
515 numInstructions = static_cast<int32_t>(value2);
516 }
517 }
518
519 while (numInstructions > 0) {
520 prev = cur;
521 cur += dasm.InstructionDecode(buffer, cur);
522 PrintF(" 0x%08" V8PRIxPTR " %s\n", reinterpret_cast<intptr_t>(prev),
523 buffer.start());
524 numInstructions--;
525 }
526 } else if (strcmp(cmd, "gdb") == 0) {
527 PrintF("relinquishing control to gdb\n");
528 v8::base::OS::DebugBreak();
529 PrintF("regaining control from gdb\n");
530 } else if (strcmp(cmd, "break") == 0) {
531 if (argc == 2) {
532 intptr_t value;
533 if (GetValue(arg1, &value)) {
534 if (!SetBreakpoint(reinterpret_cast<Instruction*>(value))) {
535 PrintF("setting breakpoint failed\n");
536 }
537 } else {
538 PrintF("%s unrecognized\n", arg1);
539 }
540 } else {
541 PrintF("break <address>\n");
542 }
543 } else if (strcmp(cmd, "del") == 0) {
544 if (!DeleteBreakpoint(NULL)) {
545 PrintF("deleting breakpoint failed\n");
546 }
547 } else if (strcmp(cmd, "cr") == 0) {
548 PrintF("Condition reg: %08x\n", sim_->condition_reg_);
549 } else if (strcmp(cmd, "stop") == 0) {
550 intptr_t value;
551 intptr_t stop_pc =
552 sim_->get_pc() - (sizeof(FourByteInstr) + kPointerSize);
553 Instruction* stop_instr = reinterpret_cast<Instruction*>(stop_pc);
554 Instruction* msg_address =
555 reinterpret_cast<Instruction*>(stop_pc + sizeof(FourByteInstr));
556 if ((argc == 2) && (strcmp(arg1, "unstop") == 0)) {
557 // Remove the current stop.
558 if (sim_->isStopInstruction(stop_instr)) {
559 stop_instr->SetInstructionBits(kNopInstr);
560 msg_address->SetInstructionBits(kNopInstr);
561 } else {
562 PrintF("Not at debugger stop.\n");
563 }
564 } else if (argc == 3) {
565 // Print information about all/the specified breakpoint(s).
566 if (strcmp(arg1, "info") == 0) {
567 if (strcmp(arg2, "all") == 0) {
568 PrintF("Stop information:\n");
569 for (uint32_t i = 0; i < sim_->kNumOfWatchedStops; i++) {
570 sim_->PrintStopInfo(i);
571 }
572 } else if (GetValue(arg2, &value)) {
573 sim_->PrintStopInfo(value);
574 } else {
575 PrintF("Unrecognized argument.\n");
576 }
577 } else if (strcmp(arg1, "enable") == 0) {
578 // Enable all/the specified breakpoint(s).
579 if (strcmp(arg2, "all") == 0) {
580 for (uint32_t i = 0; i < sim_->kNumOfWatchedStops; i++) {
581 sim_->EnableStop(i);
582 }
583 } else if (GetValue(arg2, &value)) {
584 sim_->EnableStop(value);
585 } else {
586 PrintF("Unrecognized argument.\n");
587 }
588 } else if (strcmp(arg1, "disable") == 0) {
589 // Disable all/the specified breakpoint(s).
590 if (strcmp(arg2, "all") == 0) {
591 for (uint32_t i = 0; i < sim_->kNumOfWatchedStops; i++) {
592 sim_->DisableStop(i);
593 }
594 } else if (GetValue(arg2, &value)) {
595 sim_->DisableStop(value);
596 } else {
597 PrintF("Unrecognized argument.\n");
598 }
599 }
600 } else {
601 PrintF("Wrong usage. Use help command for more information.\n");
602 }
Ben Murdochc5610432016-08-08 18:44:38 +0100603 } else if (strcmp(cmd, "icount") == 0) {
604 PrintF("%05" PRId64 "\n", sim_->icount_);
Ben Murdochda12d292016-06-02 14:46:10 +0100605 } else if ((strcmp(cmd, "t") == 0) || strcmp(cmd, "trace") == 0) {
606 ::v8::internal::FLAG_trace_sim = !::v8::internal::FLAG_trace_sim;
607 PrintF("Trace of executed instructions is %s\n",
608 ::v8::internal::FLAG_trace_sim ? "on" : "off");
609 } else if ((strcmp(cmd, "h") == 0) || (strcmp(cmd, "help") == 0)) {
610 PrintF("cont\n");
611 PrintF(" continue execution (alias 'c')\n");
612 PrintF("stepi [num instructions]\n");
613 PrintF(" step one/num instruction(s) (alias 'si')\n");
614 PrintF("print <register>\n");
615 PrintF(" print register content (alias 'p')\n");
616 PrintF(" use register name 'all' to display all integer registers\n");
617 PrintF(
618 " use register name 'alld' to display integer registers "
619 "with decimal values\n");
620 PrintF(" use register name 'rN' to display register number 'N'\n");
621 PrintF(" add argument 'fp' to print register pair double values\n");
622 PrintF(
623 " use register name 'allf' to display floating-point "
624 "registers\n");
625 PrintF("printobject <register>\n");
626 PrintF(" print an object from a register (alias 'po')\n");
627 PrintF("cr\n");
628 PrintF(" print condition register\n");
629 PrintF("stack [<num words>]\n");
630 PrintF(" dump stack content, default dump 10 words)\n");
631 PrintF("mem <address> [<num words>]\n");
632 PrintF(" dump memory content, default dump 10 words)\n");
633 PrintF("disasm [<instructions>]\n");
634 PrintF("disasm [<address/register>]\n");
635 PrintF("disasm [[<address/register>] <instructions>]\n");
636 PrintF(" disassemble code, default is 10 instructions\n");
637 PrintF(" from pc (alias 'di')\n");
638 PrintF("gdb\n");
639 PrintF(" enter gdb\n");
640 PrintF("break <address>\n");
641 PrintF(" set a break point on the address\n");
642 PrintF("del\n");
643 PrintF(" delete the breakpoint\n");
644 PrintF("trace (alias 't')\n");
645 PrintF(" toogle the tracing of all executed statements\n");
646 PrintF("stop feature:\n");
647 PrintF(" Description:\n");
648 PrintF(" Stops are debug instructions inserted by\n");
649 PrintF(" the Assembler::stop() function.\n");
650 PrintF(" When hitting a stop, the Simulator will\n");
651 PrintF(" stop and and give control to the S390Debugger.\n");
652 PrintF(" The first %d stop codes are watched:\n",
653 Simulator::kNumOfWatchedStops);
654 PrintF(" - They can be enabled / disabled: the Simulator\n");
655 PrintF(" will / won't stop when hitting them.\n");
656 PrintF(" - The Simulator keeps track of how many times they \n");
657 PrintF(" are met. (See the info command.) Going over a\n");
658 PrintF(" disabled stop still increases its counter. \n");
659 PrintF(" Commands:\n");
660 PrintF(" stop info all/<code> : print infos about number <code>\n");
661 PrintF(" or all stop(s).\n");
662 PrintF(" stop enable/disable all/<code> : enables / disables\n");
663 PrintF(" all or number <code> stop(s)\n");
664 PrintF(" stop unstop\n");
665 PrintF(" ignore the stop instruction at the current location\n");
666 PrintF(" from now on\n");
667 } else {
668 PrintF("Unknown command: %s\n", cmd);
669 }
670 }
671 }
672
673 // Add all the breakpoints back to stop execution and enter the debugger
674 // shell when hit.
675 RedoBreakpoints();
676 // Restore tracing
677 ::v8::internal::FLAG_trace_sim = trace;
678
679#undef COMMAND_SIZE
680#undef ARG_SIZE
681
682#undef STR
683#undef XSTR
684}
685
686static bool ICacheMatch(void* one, void* two) {
687 DCHECK((reinterpret_cast<intptr_t>(one) & CachePage::kPageMask) == 0);
688 DCHECK((reinterpret_cast<intptr_t>(two) & CachePage::kPageMask) == 0);
689 return one == two;
690}
691
692static uint32_t ICacheHash(void* key) {
693 return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)) >> 2;
694}
695
696static bool AllOnOnePage(uintptr_t start, int size) {
697 intptr_t start_page = (start & ~CachePage::kPageMask);
698 intptr_t end_page = ((start + size) & ~CachePage::kPageMask);
699 return start_page == end_page;
700}
701
702void Simulator::set_last_debugger_input(char* input) {
703 DeleteArray(last_debugger_input_);
704 last_debugger_input_ = input;
705}
706
Ben Murdoch61f157c2016-09-16 13:49:30 +0100707void Simulator::FlushICache(base::HashMap* i_cache, void* start_addr,
Ben Murdochda12d292016-06-02 14:46:10 +0100708 size_t size) {
709 intptr_t start = reinterpret_cast<intptr_t>(start_addr);
710 int intra_line = (start & CachePage::kLineMask);
711 start -= intra_line;
712 size += intra_line;
713 size = ((size - 1) | CachePage::kLineMask) + 1;
714 int offset = (start & CachePage::kPageMask);
715 while (!AllOnOnePage(start, size - 1)) {
716 int bytes_to_flush = CachePage::kPageSize - offset;
717 FlushOnePage(i_cache, start, bytes_to_flush);
718 start += bytes_to_flush;
719 size -= bytes_to_flush;
720 DCHECK_EQ(0, static_cast<int>(start & CachePage::kPageMask));
721 offset = 0;
722 }
723 if (size != 0) {
724 FlushOnePage(i_cache, start, size);
725 }
726}
727
Ben Murdoch61f157c2016-09-16 13:49:30 +0100728CachePage* Simulator::GetCachePage(base::HashMap* i_cache, void* page) {
729 base::HashMap::Entry* entry = i_cache->LookupOrInsert(page, ICacheHash(page));
Ben Murdochda12d292016-06-02 14:46:10 +0100730 if (entry->value == NULL) {
731 CachePage* new_page = new CachePage();
732 entry->value = new_page;
733 }
734 return reinterpret_cast<CachePage*>(entry->value);
735}
736
737// Flush from start up to and not including start + size.
Ben Murdoch61f157c2016-09-16 13:49:30 +0100738void Simulator::FlushOnePage(base::HashMap* i_cache, intptr_t start, int size) {
Ben Murdochda12d292016-06-02 14:46:10 +0100739 DCHECK(size <= CachePage::kPageSize);
740 DCHECK(AllOnOnePage(start, size - 1));
741 DCHECK((start & CachePage::kLineMask) == 0);
742 DCHECK((size & CachePage::kLineMask) == 0);
743 void* page = reinterpret_cast<void*>(start & (~CachePage::kPageMask));
744 int offset = (start & CachePage::kPageMask);
745 CachePage* cache_page = GetCachePage(i_cache, page);
746 char* valid_bytemap = cache_page->ValidityByte(offset);
747 memset(valid_bytemap, CachePage::LINE_INVALID, size >> CachePage::kLineShift);
748}
749
Ben Murdoch61f157c2016-09-16 13:49:30 +0100750void Simulator::CheckICache(base::HashMap* i_cache, Instruction* instr) {
Ben Murdochda12d292016-06-02 14:46:10 +0100751 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) {
Ben Murdoch61f157c2016-09-16 13:49:30 +01001516 i_cache_ = new base::HashMap(&ICacheMatch);
Ben Murdochda12d292016-06-02 14:46:10 +01001517 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
Ben Murdoch61f157c2016-09-16 13:49:30 +01001657void Simulator::TearDown(base::HashMap* i_cache, Redirection* first) {
Ben Murdochda12d292016-06-02 14:46:10 +01001658 Redirection::DeleteChain(first);
1659 if (i_cache != nullptr) {
Ben Murdoch61f157c2016-09-16 13:49:30 +01001660 for (base::HashMap::Entry* entry = i_cache->Start(); entry != nullptr;
Ben Murdochda12d292016-06-02 14:46:10 +01001661 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",
Ben Murdoch61f157c2016-09-16 13:49:30 +01002031 static_cast<void*>(FUNCTION_ADDR(generic_target)), dval0,
2032 dval1);
Ben Murdochda12d292016-06-02 14:46:10 +01002033 break;
2034 case ExternalReference::BUILTIN_FP_CALL:
2035 PrintF("Call to host function at %p with arg %f",
Ben Murdoch61f157c2016-09-16 13:49:30 +01002036 static_cast<void*>(FUNCTION_ADDR(generic_target)), dval0);
Ben Murdochda12d292016-06-02 14:46:10 +01002037 break;
2038 case ExternalReference::BUILTIN_FP_INT_CALL:
2039 PrintF("Call to host function at %p with args %f, %" V8PRIdPTR,
Ben Murdoch61f157c2016-09-16 13:49:30 +01002040 static_cast<void*>(FUNCTION_ADDR(generic_target)), dval0,
2041 ival);
Ben Murdochda12d292016-06-02 14:46:10 +01002042 break;
2043 default:
2044 UNREACHABLE();
2045 break;
2046 }
2047 if (!stack_aligned) {
2048 PrintF(" with unaligned stack %08" V8PRIxPTR "\n",
2049 static_cast<intptr_t>(get_register(sp)));
2050 }
2051 PrintF("\n");
2052 }
2053 CHECK(stack_aligned);
2054 switch (redirection->type()) {
2055 case ExternalReference::BUILTIN_COMPARE_CALL: {
2056 SimulatorRuntimeCompareCall target =
2057 reinterpret_cast<SimulatorRuntimeCompareCall>(external);
2058 iresult = target(dval0, dval1);
2059 set_register(r2, iresult);
2060 break;
2061 }
2062 case ExternalReference::BUILTIN_FP_FP_CALL: {
2063 SimulatorRuntimeFPFPCall target =
2064 reinterpret_cast<SimulatorRuntimeFPFPCall>(external);
2065 dresult = target(dval0, dval1);
2066 SetFpResult(dresult);
2067 break;
2068 }
2069 case ExternalReference::BUILTIN_FP_CALL: {
2070 SimulatorRuntimeFPCall target =
2071 reinterpret_cast<SimulatorRuntimeFPCall>(external);
2072 dresult = target(dval0);
2073 SetFpResult(dresult);
2074 break;
2075 }
2076 case ExternalReference::BUILTIN_FP_INT_CALL: {
2077 SimulatorRuntimeFPIntCall target =
2078 reinterpret_cast<SimulatorRuntimeFPIntCall>(external);
2079 dresult = target(dval0, ival);
2080 SetFpResult(dresult);
2081 break;
2082 }
2083 default:
2084 UNREACHABLE();
2085 break;
2086 }
2087 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
2088 switch (redirection->type()) {
2089 case ExternalReference::BUILTIN_COMPARE_CALL:
2090 PrintF("Returned %08x\n", iresult);
2091 break;
2092 case ExternalReference::BUILTIN_FP_FP_CALL:
2093 case ExternalReference::BUILTIN_FP_CALL:
2094 case ExternalReference::BUILTIN_FP_INT_CALL:
2095 PrintF("Returned %f\n", dresult);
2096 break;
2097 default:
2098 UNREACHABLE();
2099 break;
2100 }
2101 }
2102 } else if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
2103 // See callers of MacroAssembler::CallApiFunctionAndReturn for
2104 // explanation of register usage.
2105 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
2106 PrintF("Call to host function at %p args %08" V8PRIxPTR,
2107 reinterpret_cast<void*>(external), arg[0]);
2108 if (!stack_aligned) {
2109 PrintF(" with unaligned stack %08" V8PRIxPTR "\n",
2110 static_cast<intptr_t>(get_register(sp)));
2111 }
2112 PrintF("\n");
2113 }
2114 CHECK(stack_aligned);
2115 SimulatorRuntimeDirectApiCall target =
2116 reinterpret_cast<SimulatorRuntimeDirectApiCall>(external);
2117 target(arg[0]);
2118 } else if (redirection->type() == ExternalReference::PROFILING_API_CALL) {
2119 // See callers of MacroAssembler::CallApiFunctionAndReturn for
2120 // explanation of register usage.
2121 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
2122 PrintF("Call to host function at %p args %08" V8PRIxPTR
2123 " %08" V8PRIxPTR,
2124 reinterpret_cast<void*>(external), arg[0], arg[1]);
2125 if (!stack_aligned) {
2126 PrintF(" with unaligned stack %08" V8PRIxPTR "\n",
2127 static_cast<intptr_t>(get_register(sp)));
2128 }
2129 PrintF("\n");
2130 }
2131 CHECK(stack_aligned);
2132 SimulatorRuntimeProfilingApiCall target =
2133 reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
2134 target(arg[0], Redirection::ReverseRedirection(arg[1]));
2135 } else if (redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
2136 // See callers of MacroAssembler::CallApiFunctionAndReturn for
2137 // explanation of register usage.
2138 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
2139 PrintF("Call to host function at %p args %08" V8PRIxPTR
2140 " %08" V8PRIxPTR,
2141 reinterpret_cast<void*>(external), arg[0], arg[1]);
2142 if (!stack_aligned) {
2143 PrintF(" with unaligned stack %08" V8PRIxPTR "\n",
2144 static_cast<intptr_t>(get_register(sp)));
2145 }
2146 PrintF("\n");
2147 }
2148 CHECK(stack_aligned);
2149 SimulatorRuntimeDirectGetterCall target =
2150 reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external);
2151 if (!ABI_PASSES_HANDLES_IN_REGS) {
2152 arg[0] = *(reinterpret_cast<intptr_t*>(arg[0]));
2153 }
2154 target(arg[0], arg[1]);
2155 } else if (redirection->type() ==
2156 ExternalReference::PROFILING_GETTER_CALL) {
2157 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
2158 PrintF("Call to host function at %p args %08" V8PRIxPTR
2159 " %08" V8PRIxPTR " %08" V8PRIxPTR,
2160 reinterpret_cast<void*>(external), arg[0], arg[1], arg[2]);
2161 if (!stack_aligned) {
2162 PrintF(" with unaligned stack %08" V8PRIxPTR "\n",
2163 static_cast<intptr_t>(get_register(sp)));
2164 }
2165 PrintF("\n");
2166 }
2167 CHECK(stack_aligned);
2168 SimulatorRuntimeProfilingGetterCall target =
2169 reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external);
2170 if (!ABI_PASSES_HANDLES_IN_REGS) {
2171 arg[0] = *(reinterpret_cast<intptr_t*>(arg[0]));
2172 }
2173 target(arg[0], arg[1], Redirection::ReverseRedirection(arg[2]));
2174 } else {
2175 // builtin call.
2176 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
2177 SimulatorRuntimeCall target =
2178 reinterpret_cast<SimulatorRuntimeCall>(external);
2179 PrintF(
2180 "Call to host function at %p,\n"
2181 "\t\t\t\targs %08" V8PRIxPTR ", %08" V8PRIxPTR ", %08" V8PRIxPTR
2182 ", %08" V8PRIxPTR ", %08" V8PRIxPTR ", %08" V8PRIxPTR,
Ben Murdoch61f157c2016-09-16 13:49:30 +01002183 static_cast<void*>(FUNCTION_ADDR(target)), arg[0], arg[1], arg[2],
2184 arg[3], arg[4], arg[5]);
Ben Murdochda12d292016-06-02 14:46:10 +01002185 if (!stack_aligned) {
2186 PrintF(" with unaligned stack %08" V8PRIxPTR "\n",
2187 static_cast<intptr_t>(get_register(sp)));
2188 }
2189 PrintF("\n");
2190 }
2191 CHECK(stack_aligned);
2192 if (redirection->type() == ExternalReference::BUILTIN_CALL_TRIPLE) {
2193 SimulatorRuntimeTripleCall target =
2194 reinterpret_cast<SimulatorRuntimeTripleCall>(external);
2195 ObjectTriple result =
2196 target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]);
2197 if (::v8::internal::FLAG_trace_sim) {
2198 PrintF("Returned {%08" V8PRIxPTR ", %08" V8PRIxPTR ", %08" V8PRIxPTR
2199 "}\n",
2200 reinterpret_cast<intptr_t>(result.x),
2201 reinterpret_cast<intptr_t>(result.y),
2202 reinterpret_cast<intptr_t>(result.z));
2203 }
2204 memcpy(reinterpret_cast<void*>(result_buffer), &result,
2205 sizeof(ObjectTriple));
2206 set_register(r2, result_buffer);
2207 } else {
2208 if (redirection->type() == ExternalReference::BUILTIN_CALL_PAIR) {
2209 SimulatorRuntimePairCall target =
2210 reinterpret_cast<SimulatorRuntimePairCall>(external);
2211 ObjectPair result =
2212 target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]);
2213 intptr_t x;
2214 intptr_t y;
2215 decodeObjectPair(&result, &x, &y);
2216 if (::v8::internal::FLAG_trace_sim) {
2217 PrintF("Returned {%08" V8PRIxPTR ", %08" V8PRIxPTR "}\n", x, y);
2218 }
2219 if (ABI_RETURNS_OBJECTPAIR_IN_REGS) {
2220 set_register(r2, x);
2221 set_register(r3, y);
2222 } else {
2223 memcpy(reinterpret_cast<void*>(result_buffer), &result,
2224 sizeof(ObjectPair));
2225 set_register(r2, result_buffer);
2226 }
2227 } else {
2228 DCHECK(redirection->type() == ExternalReference::BUILTIN_CALL);
2229 SimulatorRuntimeCall target =
2230 reinterpret_cast<SimulatorRuntimeCall>(external);
2231 intptr_t result =
2232 target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]);
2233 if (::v8::internal::FLAG_trace_sim) {
2234 PrintF("Returned %08" V8PRIxPTR "\n", result);
2235 }
2236 set_register(r2, result);
2237 }
2238 }
2239 // #if !V8_TARGET_ARCH_S390X
2240 // DCHECK(redirection->type() ==
2241 // ExternalReference::BUILTIN_CALL);
2242 // SimulatorRuntimeCall target =
2243 // reinterpret_cast<SimulatorRuntimeCall>(external);
2244 // int64_t result = target(arg[0], arg[1], arg[2], arg[3],
2245 // arg[4],
2246 // arg[5]);
2247 // int32_t lo_res = static_cast<int32_t>(result);
2248 // int32_t hi_res = static_cast<int32_t>(result >> 32);
2249 // #if !V8_TARGET_LITTLE_ENDIAN
2250 // if (::v8::internal::FLAG_trace_sim) {
2251 // PrintF("Returned %08x\n", hi_res);
2252 // }
2253 // set_register(r2, hi_res);
2254 // set_register(r3, lo_res);
2255 // #else
2256 // if (::v8::internal::FLAG_trace_sim) {
2257 // PrintF("Returned %08x\n", lo_res);
2258 // }
2259 // set_register(r2, lo_res);
2260 // set_register(r3, hi_res);
2261 // #endif
2262 // #else
2263 // if (redirection->type() == ExternalReference::BUILTIN_CALL) {
2264 // SimulatorRuntimeCall target =
2265 // reinterpret_cast<SimulatorRuntimeCall>(external);
2266 // intptr_t result = target(arg[0], arg[1], arg[2], arg[3],
2267 // arg[4],
2268 // arg[5]);
2269 // if (::v8::internal::FLAG_trace_sim) {
2270 // PrintF("Returned %08" V8PRIxPTR "\n", result);
2271 // }
2272 // set_register(r2, result);
2273 // } else {
2274 // DCHECK(redirection->type() ==
2275 // ExternalReference::BUILTIN_CALL_PAIR);
2276 // SimulatorRuntimePairCall target =
2277 // reinterpret_cast<SimulatorRuntimePairCall>(external);
2278 // ObjectPair result = target(arg[0], arg[1], arg[2], arg[3],
2279 // arg[4], arg[5]);
2280 // if (::v8::internal::FLAG_trace_sim) {
2281 // PrintF("Returned %08" V8PRIxPTR ", %08" V8PRIxPTR "\n",
2282 // result.x, result.y);
2283 // }
2284 // #if ABI_RETURNS_OBJECTPAIR_IN_REGS
2285 // set_register(r2, result.x);
2286 // set_register(r3, result.y);
2287 // #else
2288 // memcpy(reinterpret_cast<void *>(result_buffer), &result,
2289 // sizeof(ObjectPair));
2290 // #endif
2291 // }
2292 // #endif
2293 }
2294 int64_t saved_lr = *reinterpret_cast<intptr_t*>(
2295 get_register(sp) + kStackFrameRASlot * kPointerSize);
2296#if (!V8_TARGET_ARCH_S390X && V8_HOST_ARCH_S390)
2297 // On zLinux-31, the saved_lr might be tagged with a high bit of 1.
2298 // Cleanse it before proceeding with simulation.
2299 saved_lr &= 0x7FFFFFFF;
2300#endif
2301 set_pc(saved_lr);
2302 break;
2303 }
2304 case kBreakpoint: {
2305 S390Debugger dbg(this);
2306 dbg.Debug();
2307 break;
2308 }
2309 // stop uses all codes greater than 1 << 23.
2310 default: {
2311 if (svc >= (1 << 23)) {
2312 uint32_t code = svc & kStopCodeMask;
2313 if (isWatchedStop(code)) {
2314 IncreaseStopCounter(code);
2315 }
2316 // Stop if it is enabled, otherwise go on jumping over the stop
2317 // and the message address.
2318 if (isEnabledStop(code)) {
2319 S390Debugger dbg(this);
2320 dbg.Stop(instr);
2321 } else {
2322 set_pc(get_pc() + sizeof(FourByteInstr) + kPointerSize);
2323 }
2324 } else {
2325 // This is not a valid svc code.
2326 UNREACHABLE();
2327 break;
2328 }
2329 }
2330 }
2331}
2332
2333// Stop helper functions.
2334bool Simulator::isStopInstruction(Instruction* instr) {
2335 return (instr->Bits(27, 24) == 0xF) && (instr->SvcValue() >= kStopCode);
2336}
2337
2338bool Simulator::isWatchedStop(uint32_t code) {
2339 DCHECK(code <= kMaxStopCode);
2340 return code < kNumOfWatchedStops;
2341}
2342
2343bool Simulator::isEnabledStop(uint32_t code) {
2344 DCHECK(code <= kMaxStopCode);
2345 // Unwatched stops are always enabled.
2346 return !isWatchedStop(code) ||
2347 !(watched_stops_[code].count & kStopDisabledBit);
2348}
2349
2350void Simulator::EnableStop(uint32_t code) {
2351 DCHECK(isWatchedStop(code));
2352 if (!isEnabledStop(code)) {
2353 watched_stops_[code].count &= ~kStopDisabledBit;
2354 }
2355}
2356
2357void Simulator::DisableStop(uint32_t code) {
2358 DCHECK(isWatchedStop(code));
2359 if (isEnabledStop(code)) {
2360 watched_stops_[code].count |= kStopDisabledBit;
2361 }
2362}
2363
2364void Simulator::IncreaseStopCounter(uint32_t code) {
2365 DCHECK(code <= kMaxStopCode);
2366 DCHECK(isWatchedStop(code));
2367 if ((watched_stops_[code].count & ~(1 << 31)) == 0x7fffffff) {
2368 PrintF(
2369 "Stop counter for code %i has overflowed.\n"
2370 "Enabling this code and reseting the counter to 0.\n",
2371 code);
2372 watched_stops_[code].count = 0;
2373 EnableStop(code);
2374 } else {
2375 watched_stops_[code].count++;
2376 }
2377}
2378
2379// Print a stop status.
2380void Simulator::PrintStopInfo(uint32_t code) {
2381 DCHECK(code <= kMaxStopCode);
2382 if (!isWatchedStop(code)) {
2383 PrintF("Stop not watched.");
2384 } else {
2385 const char* state = isEnabledStop(code) ? "Enabled" : "Disabled";
2386 int32_t count = watched_stops_[code].count & ~kStopDisabledBit;
2387 // Don't print the state of unused breakpoints.
2388 if (count != 0) {
2389 if (watched_stops_[code].desc) {
2390 PrintF("stop %i - 0x%x: \t%s, \tcounter = %i, \t%s\n", code, code,
2391 state, count, watched_stops_[code].desc);
2392 } else {
2393 PrintF("stop %i - 0x%x: \t%s, \tcounter = %i\n", code, code, state,
2394 count);
2395 }
2396 }
2397 }
2398}
2399
2400// Method for checking overflow on signed addition:
2401// Test src1 and src2 have opposite sign,
2402// (1) No overflow if they have opposite sign
2403// (2) Test the result and one of the operands have opposite sign
2404// (a) No overflow if they don't have opposite sign
2405// (b) Overflow if opposite
2406#define CheckOverflowForIntAdd(src1, src2, type) \
2407 OverflowFromSigned<type>(src1 + src2, src1, src2, true);
2408
2409#define CheckOverflowForIntSub(src1, src2, type) \
2410 OverflowFromSigned<type>(src1 - src2, src1, src2, false);
2411
2412// Method for checking overflow on unsigned addtion
2413#define CheckOverflowForUIntAdd(src1, src2) \
2414 ((src1) + (src2) < (src1) || (src1) + (src2) < (src2))
2415
2416// Method for checking overflow on unsigned subtraction
2417#define CheckOverflowForUIntSub(src1, src2) ((src1) - (src2) > (src1))
2418
2419// Method for checking overflow on multiplication
2420#define CheckOverflowForMul(src1, src2) (((src1) * (src2)) / (src2) != (src1))
2421
2422// Method for checking overflow on shift right
2423#define CheckOverflowForShiftRight(src1, src2) \
2424 (((src1) >> (src2)) << (src2) != (src1))
2425
2426// Method for checking overflow on shift left
2427#define CheckOverflowForShiftLeft(src1, src2) \
2428 (((src1) << (src2)) >> (src2) != (src1))
2429
2430// S390 Decode and simulate helpers
2431bool Simulator::DecodeTwoByte(Instruction* instr) {
2432 Opcode op = instr->S390OpcodeValue();
2433
2434 switch (op) {
2435 // RR format instructions
2436 case AR:
2437 case SR:
2438 case MR:
2439 case DR:
2440 case OR:
2441 case NR:
2442 case XR: {
2443 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2444 int r1 = rrinst->R1Value();
2445 int r2 = rrinst->R2Value();
2446 int32_t r1_val = get_low_register<int32_t>(r1);
2447 int32_t r2_val = get_low_register<int32_t>(r2);
2448 bool isOF = false;
2449 switch (op) {
2450 case AR:
2451 isOF = CheckOverflowForIntAdd(r1_val, r2_val, int32_t);
2452 r1_val += r2_val;
2453 SetS390ConditionCode<int32_t>(r1_val, 0);
2454 SetS390OverflowCode(isOF);
2455 break;
2456 case SR:
2457 isOF = CheckOverflowForIntSub(r1_val, r2_val, int32_t);
2458 r1_val -= r2_val;
2459 SetS390ConditionCode<int32_t>(r1_val, 0);
2460 SetS390OverflowCode(isOF);
2461 break;
2462 case OR:
2463 r1_val |= r2_val;
2464 SetS390BitWiseConditionCode<uint32_t>(r1_val);
2465 break;
2466 case NR:
2467 r1_val &= r2_val;
2468 SetS390BitWiseConditionCode<uint32_t>(r1_val);
2469 break;
2470 case XR:
2471 r1_val ^= r2_val;
2472 SetS390BitWiseConditionCode<uint32_t>(r1_val);
2473 break;
2474 case MR: {
2475 DCHECK(r1 % 2 == 0);
2476 r1_val = get_low_register<int32_t>(r1 + 1);
2477 int64_t product =
2478 static_cast<int64_t>(r1_val) * static_cast<int64_t>(r2_val);
2479 int32_t high_bits = product >> 32;
2480 r1_val = high_bits;
2481 int32_t low_bits = product & 0x00000000FFFFFFFF;
2482 set_low_register(r1, high_bits);
2483 set_low_register(r1 + 1, low_bits);
2484 break;
2485 }
2486 case DR: {
2487 // reg-reg pair should be even-odd pair, assert r1 is an even register
2488 DCHECK(r1 % 2 == 0);
2489 // leftmost 32 bits of the dividend are in r1
2490 // rightmost 32 bits of the dividend are in r1+1
2491 // get the signed value from r1
2492 int64_t dividend = static_cast<int64_t>(r1_val) << 32;
2493 // get unsigned value from r1+1
2494 // avoid addition with sign-extended r1+1 value
2495 dividend += get_low_register<uint32_t>(r1 + 1);
2496 int32_t remainder = dividend % r2_val;
2497 int32_t quotient = dividend / r2_val;
2498 r1_val = remainder;
2499 set_low_register(r1, remainder);
2500 set_low_register(r1 + 1, quotient);
2501 break; // reg pair
2502 }
2503 default:
2504 UNREACHABLE();
2505 break;
2506 }
2507 set_low_register(r1, r1_val);
2508 break;
2509 }
2510 case LR: {
2511 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2512 int r1 = rrinst->R1Value();
2513 int r2 = rrinst->R2Value();
2514 set_low_register(r1, get_low_register<int32_t>(r2));
2515 break;
2516 }
2517 case LDR: {
2518 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2519 int r1 = rrinst->R1Value();
2520 int r2 = rrinst->R2Value();
2521 int64_t r2_val = get_d_register(r2);
2522 set_d_register(r1, r2_val);
2523 break;
2524 }
2525 case CR: {
2526 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2527 int r1 = rrinst->R1Value();
2528 int r2 = rrinst->R2Value();
2529 int32_t r1_val = get_low_register<int32_t>(r1);
2530 int32_t r2_val = get_low_register<int32_t>(r2);
2531 SetS390ConditionCode<int32_t>(r1_val, r2_val);
2532 break;
2533 }
2534 case CLR: {
2535 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2536 int r1 = rrinst->R1Value();
2537 int r2 = rrinst->R2Value();
2538 uint32_t r1_val = get_low_register<uint32_t>(r1);
2539 uint32_t r2_val = get_low_register<uint32_t>(r2);
2540 SetS390ConditionCode<uint32_t>(r1_val, r2_val);
2541 break;
2542 }
2543 case BCR: {
2544 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2545 int r1 = rrinst->R1Value();
2546 int r2 = rrinst->R2Value();
2547 if (TestConditionCode(Condition(r1))) {
2548 intptr_t r2_val = get_register(r2);
2549#if (!V8_TARGET_ARCH_S390X && V8_HOST_ARCH_S390)
2550 // On 31-bit, the top most bit may be 0 or 1, but is ignored by the
2551 // hardware. Cleanse the top bit before jumping to it, unless it's one
2552 // of the special PCs
2553 if (r2_val != bad_lr && r2_val != end_sim_pc) r2_val &= 0x7FFFFFFF;
2554#endif
2555 set_pc(r2_val);
2556 }
2557 break;
2558 }
2559 case LTR: {
2560 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2561 int r1 = rrinst->R1Value();
2562 int r2 = rrinst->R2Value();
2563 int32_t r2_val = get_low_register<int32_t>(r2);
2564 SetS390ConditionCode<int32_t>(r2_val, 0);
2565 set_low_register(r1, r2_val);
2566 break;
2567 }
2568 case ALR:
2569 case SLR: {
2570 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2571 int r1 = rrinst->R1Value();
2572 int r2 = rrinst->R2Value();
2573 uint32_t r1_val = get_low_register<uint32_t>(r1);
2574 uint32_t r2_val = get_low_register<uint32_t>(r2);
2575 uint32_t alu_out = 0;
2576 bool isOF = false;
2577 if (ALR == op) {
2578 alu_out = r1_val + r2_val;
2579 isOF = CheckOverflowForUIntAdd(r1_val, r2_val);
2580 } else if (SLR == op) {
2581 alu_out = r1_val - r2_val;
2582 isOF = CheckOverflowForUIntSub(r1_val, r2_val);
2583 } else {
2584 UNREACHABLE();
2585 }
2586 set_low_register(r1, alu_out);
2587 SetS390ConditionCodeCarry<uint32_t>(alu_out, isOF);
2588 break;
2589 }
2590 case LNR: {
2591 // Load Negative (32)
2592 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2593 int r1 = rrinst->R1Value();
2594 int r2 = rrinst->R2Value();
2595 int32_t r2_val = get_low_register<int32_t>(r2);
2596 r2_val = (r2_val >= 0) ? -r2_val : r2_val; // If pos, then negate it.
2597 set_low_register(r1, r2_val);
2598 condition_reg_ = (r2_val == 0) ? CC_EQ : CC_LT; // CC0 - result is zero
2599 // CC1 - result is negative
2600 break;
2601 }
2602 case BASR: {
2603 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2604 int r1 = rrinst->R1Value();
2605 int r2 = rrinst->R2Value();
2606 intptr_t link_addr = get_pc() + 2;
2607 // If R2 is zero, the BASR does not branch.
2608 int64_t r2_val = (r2 == 0) ? link_addr : get_register(r2);
2609#if (!V8_TARGET_ARCH_S390X && V8_HOST_ARCH_S390)
2610 // On 31-bit, the top most bit may be 0 or 1, which can cause issues
2611 // for stackwalker. The top bit should either be cleanse before being
2612 // pushed onto the stack, or during stack walking when dereferenced.
2613 // For simulator, we'll take the worst case scenario and always tag
2614 // the high bit, to flush out more problems.
2615 link_addr |= 0x80000000;
2616#endif
2617 set_register(r1, link_addr);
2618 set_pc(r2_val);
2619 break;
2620 }
2621 case LCR: {
2622 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2623 int r1 = rrinst->R1Value();
2624 int r2 = rrinst->R2Value();
2625 int32_t r2_val = get_low_register<int32_t>(r2);
2626 int32_t original_r2_val = r2_val;
2627 r2_val = ~r2_val;
2628 r2_val = r2_val + 1;
2629 set_low_register(r1, r2_val);
2630 SetS390ConditionCode<int32_t>(r2_val, 0);
2631 // Checks for overflow where r2_val = -2147483648.
2632 // Cannot do int comparison due to GCC 4.8 bug on x86.
2633 // Detect INT_MIN alternatively, as it is the only value where both
2634 // original and result are negative due to overflow.
2635 if (r2_val < 0 && original_r2_val < 0) {
2636 SetS390OverflowCode(true);
2637 }
2638 break;
2639 }
2640 case BKPT: {
2641 set_pc(get_pc() + 2);
2642 S390Debugger dbg(this);
2643 dbg.Debug();
2644 break;
2645 }
2646 default:
2647 UNREACHABLE();
2648 return false;
2649 break;
2650 }
2651 return true;
2652}
2653
2654// Decode routine for four-byte instructions
2655bool Simulator::DecodeFourByte(Instruction* instr) {
2656 Opcode op = instr->S390OpcodeValue();
2657
2658 // Pre-cast instruction to various types
2659 RREInstruction* rreInst = reinterpret_cast<RREInstruction*>(instr);
2660 SIInstruction* siInstr = reinterpret_cast<SIInstruction*>(instr);
2661
2662 switch (op) {
2663 case POPCNT_Z: {
2664 int r1 = rreInst->R1Value();
2665 int r2 = rreInst->R2Value();
2666 int64_t r2_val = get_register(r2);
2667 int64_t r1_val = 0;
2668
2669 uint8_t* r2_val_ptr = reinterpret_cast<uint8_t*>(&r2_val);
2670 uint8_t* r1_val_ptr = reinterpret_cast<uint8_t*>(&r1_val);
2671 for (int i = 0; i < 8; i++) {
2672 uint32_t x = static_cast<uint32_t>(r2_val_ptr[i]);
2673#if defined(__GNUC__)
2674 r1_val_ptr[i] = __builtin_popcount(x);
2675#else
2676#error unsupport __builtin_popcount
2677#endif
2678 }
2679
2680 set_register(r1, static_cast<uint64_t>(r1_val));
2681 break;
2682 }
2683 case LLGFR: {
2684 int r1 = rreInst->R1Value();
2685 int r2 = rreInst->R2Value();
2686 int32_t r2_val = get_low_register<int32_t>(r2);
2687 uint64_t r2_finalval =
2688 (static_cast<uint64_t>(r2_val) & 0x00000000ffffffff);
2689 set_register(r1, r2_finalval);
2690 break;
2691 }
2692 case EX: {
2693 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr);
2694 int r1 = rxinst->R1Value();
2695 int b2 = rxinst->B2Value();
2696 int x2 = rxinst->X2Value();
2697 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
2698 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
2699 intptr_t d2_val = rxinst->D2Value();
2700 int32_t r1_val = get_low_register<int32_t>(r1);
2701
2702 SixByteInstr the_instr = Instruction::InstructionBits(
2703 reinterpret_cast<const byte*>(b2_val + x2_val + d2_val));
2704 int length = Instruction::InstructionLength(
2705 reinterpret_cast<const byte*>(b2_val + x2_val + d2_val));
2706
2707 char new_instr_buf[8];
2708 char* addr = reinterpret_cast<char*>(&new_instr_buf[0]);
2709 the_instr |= static_cast<SixByteInstr>(r1_val & 0xff)
2710 << (8 * length - 16);
2711 Instruction::SetInstructionBits<SixByteInstr>(
2712 reinterpret_cast<byte*>(addr), static_cast<SixByteInstr>(the_instr));
2713 ExecuteInstruction(reinterpret_cast<Instruction*>(addr), false);
2714 break;
2715 }
2716 case LGR: {
2717 // Load Register (64)
2718 int r1 = rreInst->R1Value();
2719 int r2 = rreInst->R2Value();
2720 set_register(r1, get_register(r2));
2721 break;
2722 }
2723 case LDGR: {
2724 // Load FPR from GPR (L <- 64)
2725 uint64_t int_val = get_register(rreInst->R2Value());
2726 // double double_val = bit_cast<double, uint64_t>(int_val);
2727 // set_d_register_from_double(rreInst->R1Value(), double_val);
2728 set_d_register(rreInst->R1Value(), int_val);
2729 break;
2730 }
2731 case LGDR: {
2732 // Load GPR from FPR (64 <- L)
2733 int64_t double_val = get_d_register(rreInst->R2Value());
2734 set_register(rreInst->R1Value(), double_val);
2735 break;
2736 }
2737 case LTGR: {
2738 // Load Register (64)
2739 int r1 = rreInst->R1Value();
2740 int r2 = rreInst->R2Value();
2741 int64_t r2_val = get_register(r2);
2742 SetS390ConditionCode<int64_t>(r2_val, 0);
2743 set_register(r1, get_register(r2));
2744 break;
2745 }
2746 case LZDR: {
2747 int r1 = rreInst->R1Value();
2748 set_d_register_from_double(r1, 0.0);
2749 break;
2750 }
2751 case LTEBR: {
2752 RREInstruction* rreinst = reinterpret_cast<RREInstruction*>(instr);
2753 int r1 = rreinst->R1Value();
2754 int r2 = rreinst->R2Value();
2755 int64_t r2_val = get_d_register(r2);
2756 float fr2_val = get_float32_from_d_register(r2);
2757 SetS390ConditionCode<float>(fr2_val, 0.0);
2758 set_d_register(r1, r2_val);
2759 break;
2760 }
2761 case LTDBR: {
2762 RREInstruction* rreinst = reinterpret_cast<RREInstruction*>(instr);
2763 int r1 = rreinst->R1Value();
2764 int r2 = rreinst->R2Value();
2765 int64_t r2_val = get_d_register(r2);
2766 SetS390ConditionCode<double>(bit_cast<double, int64_t>(r2_val), 0.0);
2767 set_d_register(r1, r2_val);
2768 break;
2769 }
2770 case CGR: {
2771 // Compare (64)
2772 int64_t r1_val = get_register(rreInst->R1Value());
2773 int64_t r2_val = get_register(rreInst->R2Value());
2774 SetS390ConditionCode<int64_t>(r1_val, r2_val);
2775 break;
2776 }
2777 case CLGR: {
2778 // Compare Logical (64)
2779 uint64_t r1_val = static_cast<uint64_t>(get_register(rreInst->R1Value()));
2780 uint64_t r2_val = static_cast<uint64_t>(get_register(rreInst->R2Value()));
2781 SetS390ConditionCode<uint64_t>(r1_val, r2_val);
2782 break;
2783 }
2784 case LH: {
2785 // Load Halfword
2786 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr);
2787 int r1 = rxinst->R1Value();
2788 int x2 = rxinst->X2Value();
2789 int b2 = rxinst->B2Value();
2790
2791 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
2792 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
2793 intptr_t d2_val = rxinst->D2Value();
2794 intptr_t mem_addr = x2_val + b2_val + d2_val;
2795
2796 int32_t result = static_cast<int32_t>(ReadH(mem_addr, instr));
2797 set_low_register(r1, result);
2798 break;
2799 }
2800 case LHI: {
2801 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr);
2802 int r1 = riinst->R1Value();
2803 int i = riinst->I2Value();
2804 set_low_register(r1, i);
2805 break;
2806 }
2807 case LGHI: {
2808 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr);
2809 int r1 = riinst->R1Value();
2810 int64_t i = riinst->I2Value();
2811 set_register(r1, i);
2812 break;
2813 }
2814 case CHI: {
2815 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr);
2816 int r1 = riinst->R1Value();
2817 int16_t i = riinst->I2Value();
2818 int32_t r1_val = get_low_register<int32_t>(r1);
2819 SetS390ConditionCode<int32_t>(r1_val, i);
2820 break;
2821 }
2822 case CGHI: {
2823 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr);
2824 int r1 = riinst->R1Value();
2825 int64_t i = static_cast<int64_t>(riinst->I2Value());
2826 int64_t r1_val = get_register(r1);
2827 SetS390ConditionCode<int64_t>(r1_val, i);
2828 break;
2829 }
2830 case BRAS: {
2831 // Branch Relative and Save
2832 RILInstruction* rilInstr = reinterpret_cast<RILInstruction*>(instr);
2833 int r1 = rilInstr->R1Value();
2834 intptr_t d2 = rilInstr->I2Value();
2835 intptr_t pc = get_pc();
2836 // Set PC of next instruction to register
2837 set_register(r1, pc + sizeof(FourByteInstr));
2838 // Update PC to branch target
2839 set_pc(pc + d2 * 2);
2840 break;
2841 }
2842 case BRC: {
2843 // Branch Relative on Condition
2844 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr);
2845 int m1 = riinst->M1Value();
2846 if (TestConditionCode((Condition)m1)) {
2847 intptr_t offset = riinst->I2Value() * 2;
2848 set_pc(get_pc() + offset);
2849 }
2850 break;
2851 }
2852 case BRCT:
2853 case BRCTG: {
2854 // Branch On Count (32/64).
2855 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr);
2856 int r1 = riinst->R1Value();
2857 int64_t value =
2858 (op == BRCT) ? get_low_register<int32_t>(r1) : get_register(r1);
2859 if (BRCT == op)
2860 set_low_register(r1, --value);
2861 else
2862 set_register(r1, --value);
2863 // Branch if value != 0
2864 if (value != 0) {
2865 intptr_t offset = riinst->I2Value() * 2;
2866 set_pc(get_pc() + offset);
2867 }
2868 break;
2869 }
2870 case BXH: {
2871 RSInstruction* rsinst = reinterpret_cast<RSInstruction*>(instr);
2872 int r1 = rsinst->R1Value();
2873 int r3 = rsinst->R3Value();
2874 int b2 = rsinst->B2Value();
2875 int d2 = rsinst->D2Value();
2876
2877 // r1_val is the first operand, r3_val is the increment
2878 int32_t r1_val = r1 == 0 ? 0 : get_register(r1);
2879 int32_t r3_val = r2 == 0 ? 0 : get_register(r3);
2880 intptr_t b2_val = b2 == 0 ? 0 : get_register(b2);
2881 intptr_t branch_address = b2_val + d2;
2882 // increment r1_val
2883 r1_val += r3_val;
2884
2885 // if the increment is even, then it designates a pair of registers
2886 // and the contents of the even and odd registers of the pair are used as
2887 // the increment and compare value respectively. If the increment is odd,
2888 // the increment itself is used as both the increment and compare value
2889 int32_t compare_val = r3 % 2 == 0 ? get_register(r3 + 1) : r3_val;
2890 if (r1_val > compare_val) {
2891 // branch to address if r1_val is greater than compare value
2892 set_pc(branch_address);
2893 }
2894
2895 // update contents of register in r1 with the new incremented value
2896 set_register(r1, r1_val);
2897 break;
2898 }
2899 case IIHH:
2900 case IIHL:
2901 case IILH:
2902 case IILL: {
2903 UNIMPLEMENTED();
2904 break;
2905 }
2906 case STM:
2907 case LM: {
2908 // Store Multiple 32-bits.
2909 RSInstruction* rsinstr = reinterpret_cast<RSInstruction*>(instr);
2910 int r1 = rsinstr->R1Value();
2911 int r3 = rsinstr->R3Value();
2912 int rb = rsinstr->B2Value();
2913 int offset = rsinstr->D2Value();
2914
2915 // Regs roll around if r3 is less than r1.
2916 // Artifically increase r3 by 16 so we can calculate
2917 // the number of regs stored properly.
2918 if (r3 < r1) r3 += 16;
2919
2920 int32_t rb_val = (rb == 0) ? 0 : get_low_register<int32_t>(rb);
2921
2922 // Store each register in ascending order.
2923 for (int i = 0; i <= r3 - r1; i++) {
2924 if (op == STM) {
2925 int32_t value = get_low_register<int32_t>((r1 + i) % 16);
2926 WriteW(rb_val + offset + 4 * i, value, instr);
2927 } else if (op == LM) {
2928 int32_t value = ReadW(rb_val + offset + 4 * i, instr);
2929 set_low_register((r1 + i) % 16, value);
2930 }
2931 }
2932 break;
2933 }
2934 case SLL:
2935 case SRL: {
2936 RSInstruction* rsInstr = reinterpret_cast<RSInstruction*>(instr);
2937 int r1 = rsInstr->R1Value();
2938 int b2 = rsInstr->B2Value();
2939 intptr_t d2 = rsInstr->D2Value();
2940 // only takes rightmost 6bits
2941 int64_t b2_val = b2 == 0 ? 0 : get_register(b2);
2942 int shiftBits = (b2_val + d2) & 0x3F;
2943 uint32_t r1_val = get_low_register<uint32_t>(r1);
2944 uint32_t alu_out = 0;
2945 if (SLL == op) {
2946 alu_out = r1_val << shiftBits;
2947 } else if (SRL == op) {
2948 alu_out = r1_val >> shiftBits;
2949 } else {
2950 UNREACHABLE();
2951 }
2952 set_low_register(r1, alu_out);
2953 break;
2954 }
2955 case SLDL: {
2956 RSInstruction* rsInstr = reinterpret_cast<RSInstruction*>(instr);
2957 int r1 = rsInstr->R1Value();
2958 int b2 = rsInstr->B2Value();
2959 intptr_t d2 = rsInstr->D2Value();
2960 // only takes rightmost 6bits
2961 int64_t b2_val = b2 == 0 ? 0 : get_register(b2);
2962 int shiftBits = (b2_val + d2) & 0x3F;
2963
2964 DCHECK(r1 % 2 == 0);
2965 uint32_t r1_val = get_low_register<uint32_t>(r1);
2966 uint32_t r1_next_val = get_low_register<uint32_t>(r1 + 1);
2967 uint64_t alu_out = (static_cast<uint64_t>(r1_val) << 32) |
2968 (static_cast<uint64_t>(r1_next_val));
2969 alu_out <<= shiftBits;
2970 set_low_register(r1 + 1, static_cast<uint32_t>(alu_out));
2971 set_low_register(r1, static_cast<uint32_t>(alu_out >> 32));
2972 break;
2973 }
2974 case SLA:
2975 case SRA: {
2976 RSInstruction* rsInstr = reinterpret_cast<RSInstruction*>(instr);
2977 int r1 = rsInstr->R1Value();
2978 int b2 = rsInstr->B2Value();
2979 intptr_t d2 = rsInstr->D2Value();
2980 // only takes rightmost 6bits
2981 int64_t b2_val = b2 == 0 ? 0 : get_register(b2);
2982 int shiftBits = (b2_val + d2) & 0x3F;
2983 int32_t r1_val = get_low_register<int32_t>(r1);
2984 int32_t alu_out = 0;
2985 bool isOF = false;
2986 if (op == SLA) {
2987 isOF = CheckOverflowForShiftLeft(r1_val, shiftBits);
2988 alu_out = r1_val << shiftBits;
2989 } else if (op == SRA) {
2990 alu_out = r1_val >> shiftBits;
2991 }
2992 set_low_register(r1, alu_out);
2993 SetS390ConditionCode<int32_t>(alu_out, 0);
2994 SetS390OverflowCode(isOF);
2995 break;
2996 }
2997 case LLHR: {
2998 UNIMPLEMENTED();
2999 break;
3000 }
3001 case LLGHR: {
3002 UNIMPLEMENTED();
3003 break;
3004 }
3005 case L:
3006 case LA:
3007 case LD:
3008 case LE: {
3009 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr);
3010 int b2 = rxinst->B2Value();
3011 int x2 = rxinst->X2Value();
3012 int32_t r1 = rxinst->R1Value();
3013 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
3014 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
3015 intptr_t d2_val = rxinst->D2Value();
3016 intptr_t addr = b2_val + x2_val + d2_val;
3017 if (op == L) {
3018 int32_t mem_val = ReadW(addr, instr);
3019 set_low_register(r1, mem_val);
3020 } else if (op == LA) {
3021 set_register(r1, addr);
3022 } else if (op == LD) {
3023 int64_t dbl_val = *reinterpret_cast<int64_t*>(addr);
3024 set_d_register(r1, dbl_val);
3025 } else if (op == LE) {
3026 float float_val = *reinterpret_cast<float*>(addr);
3027 set_d_register_from_float32(r1, float_val);
3028 }
3029 break;
3030 }
3031 case C:
3032 case CL: {
3033 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr);
3034 int b2 = rxinst->B2Value();
3035 int x2 = rxinst->X2Value();
3036 int32_t r1_val = get_low_register<int32_t>(rxinst->R1Value());
3037 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
3038 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
3039 intptr_t d2_val = rxinst->D2Value();
3040 intptr_t addr = b2_val + x2_val + d2_val;
3041 int32_t mem_val = ReadW(addr, instr);
3042 if (C == op)
3043 SetS390ConditionCode<int32_t>(r1_val, mem_val);
3044 else if (CL == op)
3045 SetS390ConditionCode<uint32_t>(r1_val, mem_val);
3046 break;
3047 }
3048 case CLI: {
3049 // Compare Immediate (Mem - Imm) (8)
3050 int b1 = siInstr->B1Value();
3051 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
3052 intptr_t d1_val = siInstr->D1Value();
3053 intptr_t addr = b1_val + d1_val;
3054 uint8_t mem_val = ReadB(addr);
3055 uint8_t imm_val = siInstr->I2Value();
3056 SetS390ConditionCode<uint8_t>(mem_val, imm_val);
3057 break;
3058 }
3059 case TM: {
3060 // Test Under Mask (Mem - Imm) (8)
3061 int b1 = siInstr->B1Value();
3062 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
3063 intptr_t d1_val = siInstr->D1Value();
3064 intptr_t addr = b1_val + d1_val;
3065 uint8_t mem_val = ReadB(addr);
3066 uint8_t imm_val = siInstr->I2Value();
3067 uint8_t selected_bits = mem_val & imm_val;
3068 // CC0: Selected bits are zero
3069 // CC1: Selected bits mixed zeros and ones
3070 // CC3: Selected bits all ones
3071 if (0 == selected_bits) {
3072 condition_reg_ = CC_EQ; // CC0
3073 } else if (selected_bits == imm_val) {
3074 condition_reg_ = 0x1; // CC3
3075 } else {
3076 condition_reg_ = 0x4; // CC1
3077 }
3078 break;
3079 }
3080 case ST:
3081 case STE:
3082 case STD: {
3083 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr);
3084 int b2 = rxinst->B2Value();
3085 int x2 = rxinst->X2Value();
3086 int32_t r1_val = get_low_register<int32_t>(rxinst->R1Value());
3087 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
3088 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
3089 intptr_t d2_val = rxinst->D2Value();
3090 intptr_t addr = b2_val + x2_val + d2_val;
3091 if (op == ST) {
3092 WriteW(addr, r1_val, instr);
3093 } else if (op == STD) {
3094 int64_t frs_val = get_d_register(rxinst->R1Value());
3095 WriteDW(addr, frs_val);
3096 } else if (op == STE) {
3097 int64_t frs_val = get_d_register(rxinst->R1Value()) >> 32;
3098 WriteW(addr, static_cast<int32_t>(frs_val), instr);
3099 }
3100 break;
3101 }
3102 case LTGFR:
3103 case LGFR: {
3104 // Load and Test Register (64 <- 32) (Sign Extends 32-bit val)
3105 // Load Register (64 <- 32) (Sign Extends 32-bit val)
3106 RREInstruction* rreInstr = reinterpret_cast<RREInstruction*>(instr);
3107 int r1 = rreInstr->R1Value();
3108 int r2 = rreInstr->R2Value();
3109 int32_t r2_val = get_low_register<int32_t>(r2);
3110 int64_t result = static_cast<int64_t>(r2_val);
3111 set_register(r1, result);
3112
3113 if (LTGFR == op) SetS390ConditionCode<int64_t>(result, 0);
3114 break;
3115 }
3116 case LNGR: {
3117 // Load Negative (64)
3118 int r1 = rreInst->R1Value();
3119 int r2 = rreInst->R2Value();
3120 int64_t r2_val = get_register(r2);
3121 r2_val = (r2_val >= 0) ? -r2_val : r2_val; // If pos, then negate it.
3122 set_register(r1, r2_val);
3123 condition_reg_ = (r2_val == 0) ? CC_EQ : CC_LT; // CC0 - result is zero
3124 // CC1 - result is negative
3125 break;
3126 }
3127 case TRAP4: {
3128 // whack the space of the caller allocated stack
3129 int64_t sp_addr = get_register(sp);
3130 for (int i = 0; i < kCalleeRegisterSaveAreaSize / kPointerSize; ++i) {
3131 // we dont want to whack the RA (r14)
3132 if (i != 14) (reinterpret_cast<intptr_t*>(sp_addr))[i] = 0xdeadbabe;
3133 }
3134 SoftwareInterrupt(instr);
3135 break;
3136 }
3137 case STC: {
3138 // Store Character/Byte
3139 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr);
3140 int b2 = rxinst->B2Value();
3141 int x2 = rxinst->X2Value();
3142 uint8_t r1_val = get_low_register<int32_t>(rxinst->R1Value());
3143 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
3144 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
3145 intptr_t d2_val = rxinst->D2Value();
3146 intptr_t mem_addr = b2_val + x2_val + d2_val;
3147 WriteB(mem_addr, r1_val);
3148 break;
3149 }
3150 case STH: {
3151 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr);
3152 int b2 = rxinst->B2Value();
3153 int x2 = rxinst->X2Value();
3154 int16_t r1_val = get_low_register<int32_t>(rxinst->R1Value());
3155 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
3156 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
3157 intptr_t d2_val = rxinst->D2Value();
3158 intptr_t mem_addr = b2_val + x2_val + d2_val;
3159 WriteH(mem_addr, r1_val, instr);
3160 break;
3161 }
3162#if V8_TARGET_ARCH_S390X
3163 case LCGR: {
3164 int r1 = rreInst->R1Value();
3165 int r2 = rreInst->R2Value();
3166 int64_t r2_val = get_register(r2);
3167 r2_val = ~r2_val;
3168 r2_val = r2_val + 1;
3169 set_register(r1, r2_val);
3170 SetS390ConditionCode<int64_t>(r2_val, 0);
3171 // if the input is INT_MIN, loading its compliment would be overflowing
3172 if (r2_val < 0 && (r2_val + 1) > 0) {
3173 SetS390OverflowCode(true);
3174 }
3175 break;
3176 }
3177#endif
3178 case SRDA: {
3179 RSInstruction* rsInstr = reinterpret_cast<RSInstruction*>(instr);
3180 int r1 = rsInstr->R1Value();
3181 DCHECK(r1 % 2 == 0); // must be a reg pair
3182 int b2 = rsInstr->B2Value();
3183 intptr_t d2 = rsInstr->D2Value();
3184 // only takes rightmost 6bits
3185 int64_t b2_val = b2 == 0 ? 0 : get_register(b2);
3186 int shiftBits = (b2_val + d2) & 0x3F;
3187 int64_t opnd1 = static_cast<int64_t>(get_low_register<int32_t>(r1)) << 32;
3188 int64_t opnd2 = static_cast<uint64_t>(get_low_register<uint32_t>(r1 + 1));
3189 int64_t r1_val = opnd1 + opnd2;
3190 int64_t alu_out = r1_val >> shiftBits;
3191 set_low_register(r1, alu_out >> 32);
3192 set_low_register(r1 + 1, alu_out & 0x00000000FFFFFFFF);
3193 SetS390ConditionCode<int32_t>(alu_out, 0);
3194 break;
3195 }
3196 case SRDL: {
3197 RSInstruction* rsInstr = reinterpret_cast<RSInstruction*>(instr);
3198 int r1 = rsInstr->R1Value();
3199 DCHECK(r1 % 2 == 0); // must be a reg pair
3200 int b2 = rsInstr->B2Value();
3201 intptr_t d2 = rsInstr->D2Value();
3202 // only takes rightmost 6bits
3203 int64_t b2_val = b2 == 0 ? 0 : get_register(b2);
3204 int shiftBits = (b2_val + d2) & 0x3F;
3205 uint64_t opnd1 = static_cast<uint64_t>(get_low_register<uint32_t>(r1))
3206 << 32;
3207 uint64_t opnd2 =
3208 static_cast<uint64_t>(get_low_register<uint32_t>(r1 + 1));
3209 uint64_t r1_val = opnd1 | opnd2;
3210 uint64_t alu_out = r1_val >> shiftBits;
3211 set_low_register(r1, alu_out >> 32);
3212 set_low_register(r1 + 1, alu_out & 0x00000000FFFFFFFF);
3213 SetS390ConditionCode<int32_t>(alu_out, 0);
3214 break;
3215 }
3216 default: { return DecodeFourByteArithmetic(instr); }
3217 }
3218 return true;
3219}
3220
3221bool Simulator::DecodeFourByteArithmetic64Bit(Instruction* instr) {
3222 Opcode op = instr->S390OpcodeValue();
3223
3224 RRFInstruction* rrfInst = reinterpret_cast<RRFInstruction*>(instr);
3225 RREInstruction* rreInst = reinterpret_cast<RREInstruction*>(instr);
3226
3227 switch (op) {
3228 case AGR:
3229 case SGR:
3230 case OGR:
3231 case NGR:
3232 case XGR: {
3233 int r1 = rreInst->R1Value();
3234 int r2 = rreInst->R2Value();
3235 int64_t r1_val = get_register(r1);
3236 int64_t r2_val = get_register(r2);
3237 bool isOF = false;
3238 switch (op) {
3239 case AGR:
3240 isOF = CheckOverflowForIntAdd(r1_val, r2_val, int64_t);
3241 r1_val += r2_val;
3242 SetS390ConditionCode<int64_t>(r1_val, 0);
3243 SetS390OverflowCode(isOF);
3244 break;
3245 case SGR:
3246 isOF = CheckOverflowForIntSub(r1_val, r2_val, int64_t);
3247 r1_val -= r2_val;
3248 SetS390ConditionCode<int64_t>(r1_val, 0);
3249 SetS390OverflowCode(isOF);
3250 break;
3251 case OGR:
3252 r1_val |= r2_val;
3253 SetS390BitWiseConditionCode<uint64_t>(r1_val);
3254 break;
3255 case NGR:
3256 r1_val &= r2_val;
3257 SetS390BitWiseConditionCode<uint64_t>(r1_val);
3258 break;
3259 case XGR:
3260 r1_val ^= r2_val;
3261 SetS390BitWiseConditionCode<uint64_t>(r1_val);
3262 break;
3263 default:
3264 UNREACHABLE();
3265 break;
3266 }
3267 set_register(r1, r1_val);
3268 break;
3269 }
3270 case AGFR: {
3271 // Add Register (64 <- 32) (Sign Extends 32-bit val)
3272 int r1 = rreInst->R1Value();
3273 int r2 = rreInst->R2Value();
3274 int64_t r1_val = get_register(r1);
3275 int64_t r2_val = static_cast<int64_t>(get_low_register<int32_t>(r2));
3276 bool isOF = CheckOverflowForIntAdd(r1_val, r2_val, int64_t);
3277 r1_val += r2_val;
3278 SetS390ConditionCode<int64_t>(r1_val, 0);
3279 SetS390OverflowCode(isOF);
3280 set_register(r1, r1_val);
3281 break;
3282 }
3283 case SGFR: {
3284 // Sub Reg (64 <- 32)
3285 int r1 = rreInst->R1Value();
3286 int r2 = rreInst->R2Value();
3287 int64_t r1_val = get_register(r1);
3288 int64_t r2_val = static_cast<int64_t>(get_low_register<int32_t>(r2));
3289 bool isOF = false;
3290 isOF = CheckOverflowForIntSub(r1_val, r2_val, int64_t);
3291 r1_val -= r2_val;
3292 SetS390ConditionCode<int64_t>(r1_val, 0);
3293 SetS390OverflowCode(isOF);
3294 set_register(r1, r1_val);
3295 break;
3296 }
3297 case AGRK:
3298 case SGRK:
3299 case NGRK:
3300 case OGRK:
3301 case XGRK: {
3302 // 64-bit Non-clobbering arithmetics / bitwise ops.
3303 int r1 = rrfInst->R1Value();
3304 int r2 = rrfInst->R2Value();
3305 int r3 = rrfInst->R3Value();
3306 int64_t r2_val = get_register(r2);
3307 int64_t r3_val = get_register(r3);
3308 if (AGRK == op) {
3309 bool isOF = CheckOverflowForIntAdd(r2_val, r3_val, int64_t);
3310 SetS390ConditionCode<int64_t>(r2_val + r3_val, 0);
3311 SetS390OverflowCode(isOF);
3312 set_register(r1, r2_val + r3_val);
3313 } else if (SGRK == op) {
3314 bool isOF = CheckOverflowForIntSub(r2_val, r3_val, int64_t);
3315 SetS390ConditionCode<int64_t>(r2_val - r3_val, 0);
3316 SetS390OverflowCode(isOF);
3317 set_register(r1, r2_val - r3_val);
3318 } else {
3319 // Assume bitwise operation here
3320 uint64_t bitwise_result = 0;
3321 if (NGRK == op) {
3322 bitwise_result = r2_val & r3_val;
3323 } else if (OGRK == op) {
3324 bitwise_result = r2_val | r3_val;
3325 } else if (XGRK == op) {
3326 bitwise_result = r2_val ^ r3_val;
3327 }
3328 SetS390BitWiseConditionCode<uint64_t>(bitwise_result);
3329 set_register(r1, bitwise_result);
3330 }
3331 break;
3332 }
3333 case ALGRK:
3334 case SLGRK: {
3335 // 64-bit Non-clobbering unsigned arithmetics
3336 int r1 = rrfInst->R1Value();
3337 int r2 = rrfInst->R2Value();
3338 int r3 = rrfInst->R3Value();
3339 uint64_t r2_val = get_register(r2);
3340 uint64_t r3_val = get_register(r3);
3341 if (ALGRK == op) {
3342 bool isOF = CheckOverflowForUIntAdd(r2_val, r3_val);
3343 SetS390ConditionCode<uint64_t>(r2_val + r3_val, 0);
3344 SetS390OverflowCode(isOF);
3345 set_register(r1, r2_val + r3_val);
3346 } else if (SLGRK == op) {
3347 bool isOF = CheckOverflowForUIntSub(r2_val, r3_val);
3348 SetS390ConditionCode<uint64_t>(r2_val - r3_val, 0);
3349 SetS390OverflowCode(isOF);
3350 set_register(r1, r2_val - r3_val);
3351 }
Ben Murdochc5610432016-08-08 18:44:38 +01003352 break;
Ben Murdochda12d292016-06-02 14:46:10 +01003353 }
3354 case AGHI:
3355 case MGHI: {
3356 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr);
3357 int32_t r1 = riinst->R1Value();
3358 int64_t i = static_cast<int64_t>(riinst->I2Value());
3359 int64_t r1_val = get_register(r1);
3360 bool isOF = false;
3361 switch (op) {
3362 case AGHI:
3363 isOF = CheckOverflowForIntAdd(r1_val, i, int64_t);
3364 r1_val += i;
3365 break;
3366 case MGHI:
3367 isOF = CheckOverflowForMul(r1_val, i);
3368 r1_val *= i;
3369 break; // no overflow indication is given
3370 default:
3371 break;
3372 }
3373 set_register(r1, r1_val);
3374 SetS390ConditionCode<int32_t>(r1_val, 0);
3375 SetS390OverflowCode(isOF);
3376 break;
3377 }
3378 default:
3379 UNREACHABLE();
3380 }
3381 return true;
3382}
3383
3384/**
3385 * Decodes and simulates four byte arithmetic instructions
3386 */
3387bool Simulator::DecodeFourByteArithmetic(Instruction* instr) {
3388 Opcode op = instr->S390OpcodeValue();
3389
3390 // Pre-cast instruction to various types
3391 RRFInstruction* rrfInst = reinterpret_cast<RRFInstruction*>(instr);
3392
3393 switch (op) {
3394 case AGR:
3395 case SGR:
3396 case OGR:
3397 case NGR:
3398 case XGR:
3399 case AGFR:
3400 case SGFR: {
3401 DecodeFourByteArithmetic64Bit(instr);
3402 break;
3403 }
3404 case ARK:
3405 case SRK:
3406 case NRK:
3407 case ORK:
3408 case XRK: {
3409 // 32-bit Non-clobbering arithmetics / bitwise ops
3410 int r1 = rrfInst->R1Value();
3411 int r2 = rrfInst->R2Value();
3412 int r3 = rrfInst->R3Value();
3413 int32_t r2_val = get_low_register<int32_t>(r2);
3414 int32_t r3_val = get_low_register<int32_t>(r3);
3415 if (ARK == op) {
3416 bool isOF = CheckOverflowForIntAdd(r2_val, r3_val, int32_t);
3417 SetS390ConditionCode<int32_t>(r2_val + r3_val, 0);
3418 SetS390OverflowCode(isOF);
3419 set_low_register(r1, r2_val + r3_val);
3420 } else if (SRK == op) {
3421 bool isOF = CheckOverflowForIntSub(r2_val, r3_val, int32_t);
3422 SetS390ConditionCode<int32_t>(r2_val - r3_val, 0);
3423 SetS390OverflowCode(isOF);
3424 set_low_register(r1, r2_val - r3_val);
3425 } else {
3426 // Assume bitwise operation here
3427 uint32_t bitwise_result = 0;
3428 if (NRK == op) {
3429 bitwise_result = r2_val & r3_val;
3430 } else if (ORK == op) {
3431 bitwise_result = r2_val | r3_val;
3432 } else if (XRK == op) {
3433 bitwise_result = r2_val ^ r3_val;
3434 }
3435 SetS390BitWiseConditionCode<uint32_t>(bitwise_result);
3436 set_low_register(r1, bitwise_result);
3437 }
3438 break;
3439 }
3440 case ALRK:
3441 case SLRK: {
3442 // 32-bit Non-clobbering unsigned arithmetics
3443 int r1 = rrfInst->R1Value();
3444 int r2 = rrfInst->R2Value();
3445 int r3 = rrfInst->R3Value();
3446 uint32_t r2_val = get_low_register<uint32_t>(r2);
3447 uint32_t r3_val = get_low_register<uint32_t>(r3);
3448 if (ALRK == op) {
3449 bool isOF = CheckOverflowForUIntAdd(r2_val, r3_val);
3450 SetS390ConditionCode<uint32_t>(r2_val + r3_val, 0);
3451 SetS390OverflowCode(isOF);
3452 set_low_register(r1, r2_val + r3_val);
3453 } else if (SLRK == op) {
3454 bool isOF = CheckOverflowForUIntSub(r2_val, r3_val);
3455 SetS390ConditionCode<uint32_t>(r2_val - r3_val, 0);
3456 SetS390OverflowCode(isOF);
3457 set_low_register(r1, r2_val - r3_val);
3458 }
3459 break;
3460 }
3461 case AGRK:
3462 case SGRK:
3463 case NGRK:
3464 case OGRK:
3465 case XGRK: {
3466 DecodeFourByteArithmetic64Bit(instr);
3467 break;
3468 }
3469 case ALGRK:
3470 case SLGRK: {
3471 DecodeFourByteArithmetic64Bit(instr);
3472 break;
3473 }
3474 case AHI:
3475 case MHI: {
3476 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr);
3477 int32_t r1 = riinst->R1Value();
3478 int32_t i = riinst->I2Value();
3479 int32_t r1_val = get_low_register<int32_t>(r1);
3480 bool isOF = false;
3481 switch (op) {
3482 case AHI:
3483 isOF = CheckOverflowForIntAdd(r1_val, i, int32_t);
3484 r1_val += i;
3485 break;
3486 case MHI:
3487 isOF = CheckOverflowForMul(r1_val, i);
3488 r1_val *= i;
3489 break; // no overflow indication is given
3490 default:
3491 break;
3492 }
3493 set_low_register(r1, r1_val);
3494 SetS390ConditionCode<int32_t>(r1_val, 0);
3495 SetS390OverflowCode(isOF);
3496 break;
3497 }
3498 case AGHI:
3499 case MGHI: {
3500 DecodeFourByteArithmetic64Bit(instr);
3501 break;
3502 }
3503 case MLR: {
3504 RREInstruction* rreinst = reinterpret_cast<RREInstruction*>(instr);
3505 int r1 = rreinst->R1Value();
3506 int r2 = rreinst->R2Value();
3507 DCHECK(r1 % 2 == 0);
3508
3509 uint32_t r1_val = get_low_register<uint32_t>(r1 + 1);
3510 uint32_t r2_val = get_low_register<uint32_t>(r2);
3511 uint64_t product =
3512 static_cast<uint64_t>(r1_val) * static_cast<uint64_t>(r2_val);
3513 int32_t high_bits = product >> 32;
3514 int32_t low_bits = product & 0x00000000FFFFFFFF;
3515 set_low_register(r1, high_bits);
3516 set_low_register(r1 + 1, low_bits);
3517 break;
3518 }
3519 case DLGR: {
3520#ifdef V8_TARGET_ARCH_S390X
3521 RREInstruction* rreinst = reinterpret_cast<RREInstruction*>(instr);
3522 int r1 = rreinst->R1Value();
3523 int r2 = rreinst->R2Value();
3524 uint64_t r1_val = get_register(r1);
3525 uint64_t r2_val = get_register(r2);
3526 DCHECK(r1 % 2 == 0);
3527 unsigned __int128 dividend = static_cast<unsigned __int128>(r1_val) << 64;
3528 dividend += get_register(r1 + 1);
3529 uint64_t remainder = dividend % r2_val;
3530 uint64_t quotient = dividend / r2_val;
3531 r1_val = remainder;
3532 set_register(r1, remainder);
3533 set_register(r1 + 1, quotient);
3534#else
3535 UNREACHABLE();
3536#endif
3537 break;
3538 }
3539 case DLR: {
3540 RREInstruction* rreinst = reinterpret_cast<RREInstruction*>(instr);
3541 int r1 = rreinst->R1Value();
3542 int r2 = rreinst->R2Value();
3543 uint32_t r1_val = get_low_register<uint32_t>(r1);
3544 uint32_t r2_val = get_low_register<uint32_t>(r2);
3545 DCHECK(r1 % 2 == 0);
3546 uint64_t dividend = static_cast<uint64_t>(r1_val) << 32;
3547 dividend += get_low_register<uint32_t>(r1 + 1);
3548 uint32_t remainder = dividend % r2_val;
3549 uint32_t quotient = dividend / r2_val;
3550 r1_val = remainder;
3551 set_low_register(r1, remainder);
3552 set_low_register(r1 + 1, quotient);
3553 break;
3554 }
3555 case A:
3556 case S:
3557 case M:
3558 case D:
3559 case O:
3560 case N:
3561 case X: {
3562 // 32-bit Reg-Mem instructions
3563 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr);
3564 int b2 = rxinst->B2Value();
3565 int x2 = rxinst->X2Value();
3566 int32_t r1_val = get_low_register<int32_t>(rxinst->R1Value());
3567 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
3568 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
3569 intptr_t d2_val = rxinst->D2Value();
3570 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr);
3571 int32_t alu_out = 0;
3572 bool isOF = false;
3573 switch (op) {
3574 case A:
3575 isOF = CheckOverflowForIntAdd(r1_val, mem_val, int32_t);
3576 alu_out = r1_val + mem_val;
3577 SetS390ConditionCode<int32_t>(alu_out, 0);
3578 SetS390OverflowCode(isOF);
3579 break;
3580 case S:
3581 isOF = CheckOverflowForIntSub(r1_val, mem_val, int32_t);
3582 alu_out = r1_val - mem_val;
3583 SetS390ConditionCode<int32_t>(alu_out, 0);
3584 SetS390OverflowCode(isOF);
3585 break;
3586 case M:
3587 case D:
3588 UNIMPLEMENTED();
3589 break;
3590 case O:
3591 alu_out = r1_val | mem_val;
3592 SetS390BitWiseConditionCode<uint32_t>(alu_out);
3593 break;
3594 case N:
3595 alu_out = r1_val & mem_val;
3596 SetS390BitWiseConditionCode<uint32_t>(alu_out);
3597 break;
3598 case X:
3599 alu_out = r1_val ^ mem_val;
3600 SetS390BitWiseConditionCode<uint32_t>(alu_out);
3601 break;
3602 default:
3603 UNREACHABLE();
3604 break;
3605 }
3606 set_low_register(r1, alu_out);
3607 break;
3608 }
3609 case OILL:
3610 case OIHL: {
3611 RIInstruction* riInst = reinterpret_cast<RIInstruction*>(instr);
3612 int r1 = riInst->R1Value();
3613 int i = riInst->I2Value();
3614 int32_t r1_val = get_low_register<int32_t>(r1);
3615 if (OILL == op) {
3616 // CC is set based on the 16 bits that are AND'd
3617 SetS390BitWiseConditionCode<uint16_t>(r1_val | i);
3618 } else if (OILH == op) {
3619 // CC is set based on the 16 bits that are AND'd
3620 SetS390BitWiseConditionCode<uint16_t>((r1_val >> 16) | i);
3621 i = i << 16;
3622 } else {
3623 UNIMPLEMENTED();
3624 }
3625 set_low_register(r1, r1_val | i);
3626 break;
3627 }
3628 case NILL:
3629 case NILH: {
3630 RIInstruction* riInst = reinterpret_cast<RIInstruction*>(instr);
3631 int r1 = riInst->R1Value();
3632 int i = riInst->I2Value();
3633 int32_t r1_val = get_low_register<int32_t>(r1);
3634 if (NILL == op) {
3635 // CC is set based on the 16 bits that are AND'd
3636 SetS390BitWiseConditionCode<uint16_t>(r1_val & i);
3637 i |= 0xFFFF0000;
3638 } else if (NILH == op) {
3639 // CC is set based on the 16 bits that are AND'd
3640 SetS390BitWiseConditionCode<uint16_t>((r1_val >> 16) & i);
3641 i = (i << 16) | 0x0000FFFF;
3642 } else {
3643 UNIMPLEMENTED();
3644 }
3645 set_low_register(r1, r1_val & i);
3646 break;
3647 }
3648 case AH:
3649 case SH:
3650 case MH: {
3651 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr);
3652 int b2 = rxinst->B2Value();
3653 int x2 = rxinst->X2Value();
3654 int32_t r1_val = get_low_register<int32_t>(rxinst->R1Value());
3655 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
3656 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
3657 intptr_t d2_val = rxinst->D2Value();
3658 intptr_t addr = b2_val + x2_val + d2_val;
3659 int32_t mem_val = static_cast<int32_t>(ReadH(addr, instr));
3660 int32_t alu_out = 0;
3661 bool isOF = false;
3662 if (AH == op) {
3663 isOF = CheckOverflowForIntAdd(r1_val, mem_val, int32_t);
3664 alu_out = r1_val + mem_val;
3665 } else if (SH == op) {
3666 isOF = CheckOverflowForIntSub(r1_val, mem_val, int32_t);
3667 alu_out = r1_val - mem_val;
3668 } else if (MH == op) {
3669 alu_out = r1_val * mem_val;
3670 } else {
3671 UNREACHABLE();
3672 }
3673 set_low_register(r1, alu_out);
3674 if (MH != op) { // MH does not change condition code
3675 SetS390ConditionCode<int32_t>(alu_out, 0);
3676 SetS390OverflowCode(isOF);
3677 }
3678 break;
3679 }
3680 case DSGR: {
3681 RREInstruction* rreInst = reinterpret_cast<RREInstruction*>(instr);
3682 int r1 = rreInst->R1Value();
3683 int r2 = rreInst->R2Value();
3684
3685 DCHECK(r1 % 2 == 0);
3686
3687 int64_t dividend = get_register(r1 + 1);
3688 int64_t divisor = get_register(r2);
3689 set_register(r1, dividend % divisor);
3690 set_register(r1 + 1, dividend / divisor);
3691
3692 break;
3693 }
3694 case FLOGR: {
3695 RREInstruction* rreInst = reinterpret_cast<RREInstruction*>(instr);
3696 int r1 = rreInst->R1Value();
3697 int r2 = rreInst->R2Value();
3698
3699 DCHECK(r1 % 2 == 0);
3700
3701 int64_t r2_val = get_register(r2);
3702
3703 int i = 0;
3704 for (; i < 64; i++) {
3705 if (r2_val < 0) break;
3706 r2_val <<= 1;
3707 }
3708
3709 r2_val = get_register(r2);
3710
3711 int64_t mask = ~(1 << (63 - i));
3712 set_register(r1, i);
3713 set_register(r1 + 1, r2_val & mask);
3714
3715 break;
3716 }
3717 case MSR:
3718 case MSGR: { // they do not set overflow code
3719 RREInstruction* rreInst = reinterpret_cast<RREInstruction*>(instr);
3720 int r1 = rreInst->R1Value();
3721 int r2 = rreInst->R2Value();
3722 if (op == MSR) {
3723 int32_t r1_val = get_low_register<int32_t>(r1);
3724 int32_t r2_val = get_low_register<int32_t>(r2);
3725 set_low_register(r1, r1_val * r2_val);
3726 } else if (op == MSGR) {
3727 int64_t r1_val = get_register(r1);
3728 int64_t r2_val = get_register(r2);
3729 set_register(r1, r1_val * r2_val);
3730 } else {
3731 UNREACHABLE();
3732 }
3733 break;
3734 }
3735 case MS: {
3736 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr);
3737 int r1 = rxinst->R1Value();
3738 int b2 = rxinst->B2Value();
3739 int x2 = rxinst->X2Value();
3740 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
3741 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
3742 intptr_t d2_val = rxinst->D2Value();
3743 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr);
3744 int32_t r1_val = get_low_register<int32_t>(r1);
3745 set_low_register(r1, r1_val * mem_val);
3746 break;
3747 }
3748 case LGBR:
3749 case LBR: {
3750 RREInstruction* rrinst = reinterpret_cast<RREInstruction*>(instr);
3751 int r1 = rrinst->R1Value();
3752 int r2 = rrinst->R2Value();
Ben Murdochc5610432016-08-08 18:44:38 +01003753 if (op == LGBR) {
Ben Murdochda12d292016-06-02 14:46:10 +01003754 int64_t r2_val = get_low_register<int64_t>(r2);
3755 r2_val <<= 56;
3756 r2_val >>= 56;
3757 set_register(r1, r2_val);
Ben Murdochc5610432016-08-08 18:44:38 +01003758 } else if (op == LBR) {
Ben Murdochda12d292016-06-02 14:46:10 +01003759 int32_t r2_val = get_low_register<int32_t>(r2);
3760 r2_val <<= 24;
3761 r2_val >>= 24;
3762 set_low_register(r1, r2_val);
Ben Murdochc5610432016-08-08 18:44:38 +01003763 } else {
3764 UNREACHABLE();
3765 }
Ben Murdochda12d292016-06-02 14:46:10 +01003766 break;
3767 }
3768 case LGHR:
3769 case LHR: {
3770 RREInstruction* rrinst = reinterpret_cast<RREInstruction*>(instr);
3771 int r1 = rrinst->R1Value();
3772 int r2 = rrinst->R2Value();
Ben Murdochc5610432016-08-08 18:44:38 +01003773 if (op == LGHR) {
Ben Murdochda12d292016-06-02 14:46:10 +01003774 int64_t r2_val = get_low_register<int64_t>(r2);
3775 r2_val <<= 48;
3776 r2_val >>= 48;
3777 set_register(r1, r2_val);
Ben Murdochc5610432016-08-08 18:44:38 +01003778 } else if (op == LHR) {
Ben Murdochda12d292016-06-02 14:46:10 +01003779 int32_t r2_val = get_low_register<int32_t>(r2);
3780 r2_val <<= 16;
3781 r2_val >>= 16;
3782 set_low_register(r1, r2_val);
Ben Murdochc5610432016-08-08 18:44:38 +01003783 } else {
3784 UNREACHABLE();
3785 }
Ben Murdochda12d292016-06-02 14:46:10 +01003786 break;
3787 }
3788 case ALCR: {
3789 RREInstruction* rrinst = reinterpret_cast<RREInstruction*>(instr);
3790 int r1 = rrinst->R1Value();
3791 int r2 = rrinst->R2Value();
3792 uint32_t r1_val = get_low_register<uint32_t>(r1);
3793 uint32_t r2_val = get_low_register<uint32_t>(r2);
3794 uint32_t alu_out = 0;
3795 bool isOF = false;
3796
3797 alu_out = r1_val + r2_val;
3798 bool isOF_original = CheckOverflowForUIntAdd(r1_val, r2_val);
3799 if (TestConditionCode((Condition)2) || TestConditionCode((Condition)3)) {
3800 alu_out = alu_out + 1;
3801 isOF = isOF_original || CheckOverflowForUIntAdd(alu_out, 1);
3802 } else {
3803 isOF = isOF_original;
3804 }
3805 set_low_register(r1, alu_out);
3806 SetS390ConditionCodeCarry<uint32_t>(alu_out, isOF);
3807 break;
3808 }
3809 case SLBR: {
3810 RREInstruction* rrinst = reinterpret_cast<RREInstruction*>(instr);
3811 int r1 = rrinst->R1Value();
3812 int r2 = rrinst->R2Value();
3813 uint32_t r1_val = get_low_register<uint32_t>(r1);
3814 uint32_t r2_val = get_low_register<uint32_t>(r2);
3815 uint32_t alu_out = 0;
3816 bool isOF = false;
3817
3818 alu_out = r1_val - r2_val;
3819 bool isOF_original = CheckOverflowForUIntSub(r1_val, r2_val);
3820 if (TestConditionCode((Condition)2) || TestConditionCode((Condition)3)) {
3821 alu_out = alu_out - 1;
3822 isOF = isOF_original || CheckOverflowForUIntSub(alu_out, 1);
3823 } else {
3824 isOF = isOF_original;
3825 }
3826 set_low_register(r1, alu_out);
3827 SetS390ConditionCodeCarry<uint32_t>(alu_out, isOF);
3828 break;
3829 }
3830 default: { return DecodeFourByteFloatingPoint(instr); }
3831 }
3832 return true;
3833}
3834
3835void Simulator::DecodeFourByteFloatingPointIntConversion(Instruction* instr) {
3836 Opcode op = instr->S390OpcodeValue();
3837 switch (op) {
3838 case CDLFBR:
3839 case CDLGBR:
3840 case CELGBR:
3841 case CLFDBR:
3842 case CLGDBR:
3843 case CELFBR:
3844 case CLGEBR:
3845 case CLFEBR: {
3846 RREInstruction* rreInstr = reinterpret_cast<RREInstruction*>(instr);
3847 int r1 = rreInstr->R1Value();
3848 int r2 = rreInstr->R2Value();
3849 if (op == CDLFBR) {
3850 uint32_t r2_val = get_low_register<uint32_t>(r2);
3851 double r1_val = static_cast<double>(r2_val);
3852 set_d_register_from_double(r1, r1_val);
3853 } else if (op == CELFBR) {
3854 uint32_t r2_val = get_low_register<uint32_t>(r2);
3855 float r1_val = static_cast<float>(r2_val);
3856 set_d_register_from_float32(r1, r1_val);
3857 } else if (op == CDLGBR) {
3858 uint64_t r2_val = get_register(r2);
3859 double r1_val = static_cast<double>(r2_val);
3860 set_d_register_from_double(r1, r1_val);
3861 } else if (op == CELGBR) {
3862 uint64_t r2_val = get_register(r2);
3863 float r1_val = static_cast<float>(r2_val);
3864 set_d_register_from_float32(r1, r1_val);
3865 } else if (op == CLFDBR) {
3866 double r2_val = get_double_from_d_register(r2);
3867 uint32_t r1_val = static_cast<uint32_t>(r2_val);
3868 set_low_register(r1, r1_val);
3869 SetS390ConvertConditionCode<double>(r2_val, r1_val, UINT32_MAX);
3870 } else if (op == CLFEBR) {
3871 float r2_val = get_float32_from_d_register(r2);
3872 uint32_t r1_val = static_cast<uint32_t>(r2_val);
3873 set_low_register(r1, r1_val);
3874 SetS390ConvertConditionCode<double>(r2_val, r1_val, UINT32_MAX);
3875 } else if (op == CLGDBR) {
3876 double r2_val = get_double_from_d_register(r2);
3877 uint64_t r1_val = static_cast<uint64_t>(r2_val);
3878 set_register(r1, r1_val);
3879 SetS390ConvertConditionCode<double>(r2_val, r1_val, UINT64_MAX);
3880 } else if (op == CLGEBR) {
3881 float r2_val = get_float32_from_d_register(r2);
3882 uint64_t r1_val = static_cast<uint64_t>(r2_val);
3883 set_register(r1, r1_val);
3884 SetS390ConvertConditionCode<double>(r2_val, r1_val, UINT64_MAX);
3885 }
3886 break;
3887 }
3888 default:
3889 UNREACHABLE();
3890 }
3891}
3892
3893void Simulator::DecodeFourByteFloatingPointRound(Instruction* instr) {
3894 Opcode op = instr->S390OpcodeValue();
3895 RREInstruction* rreInstr = reinterpret_cast<RREInstruction*>(instr);
3896 int r1 = rreInstr->R1Value();
3897 int r2 = rreInstr->R2Value();
3898 double r2_val = get_double_from_d_register(r2);
3899 float r2_fval = get_float32_from_d_register(r2);
3900
3901 switch (op) {
3902 case CFDBR: {
3903 int mask_val = rreInstr->M3Value();
3904 int32_t r1_val = 0;
3905
3906 SetS390RoundConditionCode(r2_val, INT32_MAX, INT32_MIN);
3907
3908 switch (mask_val) {
3909 case CURRENT_ROUNDING_MODE:
3910 case ROUND_TO_PREPARE_FOR_SHORTER_PRECISION: {
3911 r1_val = static_cast<int32_t>(r2_val);
3912 break;
3913 }
3914 case ROUND_TO_NEAREST_WITH_TIES_AWAY_FROM_0: {
3915 double ceil_val = std::ceil(r2_val);
3916 double floor_val = std::floor(r2_val);
3917 double sub_val1 = std::fabs(r2_val - floor_val);
3918 double sub_val2 = std::fabs(r2_val - ceil_val);
3919 if (sub_val1 > sub_val2) {
3920 r1_val = static_cast<int32_t>(ceil_val);
3921 } else if (sub_val1 < sub_val2) {
3922 r1_val = static_cast<int32_t>(floor_val);
3923 } else { // round away from zero:
3924 if (r2_val > 0.0) {
3925 r1_val = static_cast<int32_t>(ceil_val);
3926 } else {
3927 r1_val = static_cast<int32_t>(floor_val);
3928 }
3929 }
3930 break;
3931 }
3932 case ROUND_TO_NEAREST_WITH_TIES_TO_EVEN: {
3933 double ceil_val = std::ceil(r2_val);
3934 double floor_val = std::floor(r2_val);
3935 double sub_val1 = std::fabs(r2_val - floor_val);
3936 double sub_val2 = std::fabs(r2_val - ceil_val);
3937 if (sub_val1 > sub_val2) {
3938 r1_val = static_cast<int32_t>(ceil_val);
3939 } else if (sub_val1 < sub_val2) {
3940 r1_val = static_cast<int32_t>(floor_val);
3941 } else { // check which one is even:
3942 int32_t c_v = static_cast<int32_t>(ceil_val);
3943 int32_t f_v = static_cast<int32_t>(floor_val);
3944 if (f_v % 2 == 0)
3945 r1_val = f_v;
3946 else
3947 r1_val = c_v;
3948 }
3949 break;
3950 }
3951 case ROUND_TOWARD_0: {
3952 // check for overflow, cast r2_val to 64bit integer
3953 // then check value within the range of INT_MIN and INT_MAX
3954 // and set condition code accordingly
3955 int64_t temp = static_cast<int64_t>(r2_val);
3956 if (temp < INT_MIN || temp > INT_MAX) {
3957 condition_reg_ = CC_OF;
3958 }
3959 r1_val = static_cast<int32_t>(r2_val);
3960 break;
3961 }
3962 case ROUND_TOWARD_PLUS_INFINITE: {
3963 r1_val = static_cast<int32_t>(std::ceil(r2_val));
3964 break;
3965 }
3966 case ROUND_TOWARD_MINUS_INFINITE: {
3967 // check for overflow, cast r2_val to 64bit integer
3968 // then check value within the range of INT_MIN and INT_MAX
3969 // and set condition code accordingly
3970 int64_t temp = static_cast<int64_t>(std::floor(r2_val));
3971 if (temp < INT_MIN || temp > INT_MAX) {
3972 condition_reg_ = CC_OF;
3973 }
3974 r1_val = static_cast<int32_t>(std::floor(r2_val));
3975 break;
3976 }
3977 default:
3978 UNREACHABLE();
3979 }
3980 set_low_register(r1, r1_val);
3981 break;
3982 }
3983 case CGDBR: {
3984 int mask_val = rreInstr->M3Value();
3985 int64_t r1_val = 0;
3986
3987 SetS390RoundConditionCode(r2_val, INT64_MAX, INT64_MIN);
3988
3989 switch (mask_val) {
3990 case CURRENT_ROUNDING_MODE:
3991 case ROUND_TO_NEAREST_WITH_TIES_AWAY_FROM_0:
3992 case ROUND_TO_PREPARE_FOR_SHORTER_PRECISION: {
3993 UNIMPLEMENTED();
3994 break;
3995 }
3996 case ROUND_TO_NEAREST_WITH_TIES_TO_EVEN: {
3997 double ceil_val = std::ceil(r2_val);
3998 double floor_val = std::floor(r2_val);
3999 if (std::abs(r2_val - floor_val) > std::abs(r2_val - ceil_val)) {
4000 r1_val = static_cast<int64_t>(ceil_val);
4001 } else if (std::abs(r2_val - floor_val) <
4002 std::abs(r2_val - ceil_val)) {
4003 r1_val = static_cast<int64_t>(floor_val);
4004 } else { // check which one is even:
4005 int64_t c_v = static_cast<int64_t>(ceil_val);
4006 int64_t f_v = static_cast<int64_t>(floor_val);
4007 if (f_v % 2 == 0)
4008 r1_val = f_v;
4009 else
4010 r1_val = c_v;
4011 }
4012 break;
4013 }
4014 case ROUND_TOWARD_0: {
4015 r1_val = static_cast<int64_t>(r2_val);
4016 break;
4017 }
4018 case ROUND_TOWARD_PLUS_INFINITE: {
4019 r1_val = static_cast<int64_t>(std::ceil(r2_val));
4020 break;
4021 }
4022 case ROUND_TOWARD_MINUS_INFINITE: {
4023 r1_val = static_cast<int64_t>(std::floor(r2_val));
4024 break;
4025 }
4026 default:
4027 UNREACHABLE();
4028 }
4029 set_register(r1, r1_val);
4030 break;
4031 }
4032 case CGEBR: {
4033 int mask_val = rreInstr->M3Value();
4034 int64_t r1_val = 0;
4035
4036 SetS390RoundConditionCode(r2_fval, INT64_MAX, INT64_MIN);
4037
4038 switch (mask_val) {
4039 case CURRENT_ROUNDING_MODE:
4040 case ROUND_TO_NEAREST_WITH_TIES_AWAY_FROM_0:
4041 case ROUND_TO_PREPARE_FOR_SHORTER_PRECISION: {
4042 UNIMPLEMENTED();
4043 break;
4044 }
4045 case ROUND_TO_NEAREST_WITH_TIES_TO_EVEN: {
4046 float ceil_val = std::ceil(r2_fval);
4047 float floor_val = std::floor(r2_fval);
4048 if (std::abs(r2_fval - floor_val) > std::abs(r2_fval - ceil_val)) {
4049 r1_val = static_cast<int64_t>(ceil_val);
4050 } else if (std::abs(r2_fval - floor_val) <
4051 std::abs(r2_fval - ceil_val)) {
4052 r1_val = static_cast<int64_t>(floor_val);
4053 } else { // check which one is even:
4054 int64_t c_v = static_cast<int64_t>(ceil_val);
4055 int64_t f_v = static_cast<int64_t>(floor_val);
4056 if (f_v % 2 == 0)
4057 r1_val = f_v;
4058 else
4059 r1_val = c_v;
4060 }
4061 break;
4062 }
4063 case ROUND_TOWARD_0: {
4064 r1_val = static_cast<int64_t>(r2_fval);
4065 break;
4066 }
4067 case ROUND_TOWARD_PLUS_INFINITE: {
4068 r1_val = static_cast<int64_t>(std::ceil(r2_fval));
4069 break;
4070 }
4071 case ROUND_TOWARD_MINUS_INFINITE: {
4072 r1_val = static_cast<int64_t>(std::floor(r2_fval));
4073 break;
4074 }
4075 default:
4076 UNREACHABLE();
4077 }
4078 set_register(r1, r1_val);
4079 break;
4080 }
4081 case CFEBR: {
4082 int mask_val = rreInstr->M3Value();
4083 int32_t r1_val = 0;
4084
4085 SetS390RoundConditionCode(r2_fval, INT32_MAX, INT32_MIN);
4086
4087 switch (mask_val) {
4088 case CURRENT_ROUNDING_MODE:
4089 case ROUND_TO_PREPARE_FOR_SHORTER_PRECISION: {
4090 r1_val = static_cast<int32_t>(r2_fval);
4091 break;
4092 }
4093 case ROUND_TO_NEAREST_WITH_TIES_AWAY_FROM_0: {
4094 float ceil_val = std::ceil(r2_fval);
4095 float floor_val = std::floor(r2_fval);
4096 float sub_val1 = std::fabs(r2_fval - floor_val);
4097 float sub_val2 = std::fabs(r2_fval - ceil_val);
4098 if (sub_val1 > sub_val2) {
4099 r1_val = static_cast<int32_t>(ceil_val);
4100 } else if (sub_val1 < sub_val2) {
4101 r1_val = static_cast<int32_t>(floor_val);
4102 } else { // round away from zero:
4103 if (r2_fval > 0.0) {
4104 r1_val = static_cast<int32_t>(ceil_val);
4105 } else {
4106 r1_val = static_cast<int32_t>(floor_val);
4107 }
4108 }
4109 break;
4110 }
4111 case ROUND_TO_NEAREST_WITH_TIES_TO_EVEN: {
4112 float ceil_val = std::ceil(r2_fval);
4113 float floor_val = std::floor(r2_fval);
4114 float sub_val1 = std::fabs(r2_fval - floor_val);
4115 float sub_val2 = std::fabs(r2_fval - ceil_val);
4116 if (sub_val1 > sub_val2) {
4117 r1_val = static_cast<int32_t>(ceil_val);
4118 } else if (sub_val1 < sub_val2) {
4119 r1_val = static_cast<int32_t>(floor_val);
4120 } else { // check which one is even:
4121 int32_t c_v = static_cast<int32_t>(ceil_val);
4122 int32_t f_v = static_cast<int32_t>(floor_val);
4123 if (f_v % 2 == 0)
4124 r1_val = f_v;
4125 else
4126 r1_val = c_v;
4127 }
4128 break;
4129 }
4130 case ROUND_TOWARD_0: {
4131 // check for overflow, cast r2_fval to 64bit integer
4132 // then check value within the range of INT_MIN and INT_MAX
4133 // and set condition code accordingly
4134 int64_t temp = static_cast<int64_t>(r2_fval);
4135 if (temp < INT_MIN || temp > INT_MAX) {
4136 condition_reg_ = CC_OF;
4137 }
4138 r1_val = static_cast<int32_t>(r2_fval);
4139 break;
4140 }
4141 case ROUND_TOWARD_PLUS_INFINITE: {
4142 r1_val = static_cast<int32_t>(std::ceil(r2_fval));
4143 break;
4144 }
4145 case ROUND_TOWARD_MINUS_INFINITE: {
4146 // check for overflow, cast r2_fval to 64bit integer
4147 // then check value within the range of INT_MIN and INT_MAX
4148 // and set condition code accordingly
4149 int64_t temp = static_cast<int64_t>(std::floor(r2_fval));
4150 if (temp < INT_MIN || temp > INT_MAX) {
4151 condition_reg_ = CC_OF;
4152 }
4153 r1_val = static_cast<int32_t>(std::floor(r2_fval));
4154 break;
4155 }
4156 default:
4157 UNREACHABLE();
4158 }
4159 set_low_register(r1, r1_val);
4160
4161 break;
4162 }
4163 default:
4164 UNREACHABLE();
4165 }
4166}
4167
4168/**
4169 * Decodes and simulates four byte floating point instructions
4170 */
4171bool Simulator::DecodeFourByteFloatingPoint(Instruction* instr) {
4172 Opcode op = instr->S390OpcodeValue();
4173
4174 switch (op) {
4175 case ADBR:
4176 case AEBR:
4177 case SDBR:
4178 case SEBR:
4179 case MDBR:
4180 case MEEBR:
4181 case MADBR:
4182 case DDBR:
4183 case DEBR:
4184 case CDBR:
4185 case CEBR:
4186 case CDFBR:
4187 case CDGBR:
4188 case CEGBR:
4189 case CGEBR:
4190 case CFDBR:
4191 case CGDBR:
4192 case SQDBR:
4193 case SQEBR:
4194 case CFEBR:
4195 case CEFBR:
4196 case LCDBR:
4197 case LPDBR:
4198 case LPEBR: {
4199 RREInstruction* rreInstr = reinterpret_cast<RREInstruction*>(instr);
4200 int r1 = rreInstr->R1Value();
4201 int r2 = rreInstr->R2Value();
4202 double r1_val = get_double_from_d_register(r1);
4203 double r2_val = get_double_from_d_register(r2);
4204 float fr1_val = get_float32_from_d_register(r1);
4205 float fr2_val = get_float32_from_d_register(r2);
4206 if (op == ADBR) {
4207 r1_val += r2_val;
4208 set_d_register_from_double(r1, r1_val);
4209 SetS390ConditionCode<double>(r1_val, 0);
4210 } else if (op == AEBR) {
4211 fr1_val += fr2_val;
4212 set_d_register_from_float32(r1, fr1_val);
4213 SetS390ConditionCode<float>(fr1_val, 0);
4214 } else if (op == SDBR) {
4215 r1_val -= r2_val;
4216 set_d_register_from_double(r1, r1_val);
4217 SetS390ConditionCode<double>(r1_val, 0);
4218 } else if (op == SEBR) {
4219 fr1_val -= fr2_val;
4220 set_d_register_from_float32(r1, fr1_val);
4221 SetS390ConditionCode<float>(fr1_val, 0);
4222 } else if (op == MDBR) {
4223 r1_val *= r2_val;
4224 set_d_register_from_double(r1, r1_val);
4225 SetS390ConditionCode<double>(r1_val, 0);
4226 } else if (op == MEEBR) {
4227 fr1_val *= fr2_val;
4228 set_d_register_from_float32(r1, fr1_val);
4229 SetS390ConditionCode<float>(fr1_val, 0);
4230 } else if (op == MADBR) {
4231 RRDInstruction* rrdInstr = reinterpret_cast<RRDInstruction*>(instr);
4232 int r1 = rrdInstr->R1Value();
4233 int r2 = rrdInstr->R2Value();
4234 int r3 = rrdInstr->R3Value();
4235 double r1_val = get_double_from_d_register(r1);
4236 double r2_val = get_double_from_d_register(r2);
4237 double r3_val = get_double_from_d_register(r3);
4238 r1_val += r2_val * r3_val;
4239 set_d_register_from_double(r1, r1_val);
4240 SetS390ConditionCode<double>(r1_val, 0);
4241 } else if (op == DDBR) {
4242 r1_val /= r2_val;
4243 set_d_register_from_double(r1, r1_val);
4244 SetS390ConditionCode<double>(r1_val, 0);
4245 } else if (op == DEBR) {
4246 fr1_val /= fr2_val;
4247 set_d_register_from_float32(r1, fr1_val);
4248 SetS390ConditionCode<float>(fr1_val, 0);
4249 } else if (op == CDBR) {
4250 if (isNaN(r1_val) || isNaN(r2_val)) {
4251 condition_reg_ = CC_OF;
4252 } else {
4253 SetS390ConditionCode<double>(r1_val, r2_val);
4254 }
4255 } else if (op == CEBR) {
4256 if (isNaN(fr1_val) || isNaN(fr2_val)) {
4257 condition_reg_ = CC_OF;
4258 } else {
4259 SetS390ConditionCode<float>(fr1_val, fr2_val);
4260 }
4261 } else if (op == CDGBR) {
4262 int64_t r2_val = get_register(r2);
4263 double r1_val = static_cast<double>(r2_val);
4264 set_d_register_from_double(r1, r1_val);
4265 } else if (op == CEGBR) {
4266 int64_t fr2_val = get_register(r2);
4267 float fr1_val = static_cast<float>(fr2_val);
4268 set_d_register_from_float32(r1, fr1_val);
4269 } else if (op == CDFBR) {
4270 int32_t r2_val = get_low_register<int32_t>(r2);
4271 double r1_val = static_cast<double>(r2_val);
4272 set_d_register_from_double(r1, r1_val);
4273 } else if (op == CEFBR) {
4274 int32_t fr2_val = get_low_register<int32_t>(r2);
4275 float fr1_val = static_cast<float>(fr2_val);
4276 set_d_register_from_float32(r1, fr1_val);
4277 } else if (op == CFDBR) {
4278 DecodeFourByteFloatingPointRound(instr);
4279 } else if (op == CGDBR) {
4280 DecodeFourByteFloatingPointRound(instr);
4281 } else if (op == CGEBR) {
4282 DecodeFourByteFloatingPointRound(instr);
4283 } else if (op == SQDBR) {
4284 r1_val = std::sqrt(r2_val);
4285 set_d_register_from_double(r1, r1_val);
4286 } else if (op == SQEBR) {
4287 fr1_val = std::sqrt(fr2_val);
4288 set_d_register_from_float32(r1, fr1_val);
4289 } else if (op == CFEBR) {
4290 DecodeFourByteFloatingPointRound(instr);
4291 } else if (op == LCDBR) {
4292 r1_val = -r2_val;
4293 set_d_register_from_double(r1, r1_val);
4294 if (r2_val != r2_val) { // input is NaN
4295 condition_reg_ = CC_OF;
4296 } else if (r2_val == 0) {
4297 condition_reg_ = CC_EQ;
4298 } else if (r2_val < 0) {
4299 condition_reg_ = CC_LT;
4300 } else if (r2_val > 0) {
4301 condition_reg_ = CC_GT;
4302 }
4303 } else if (op == LPDBR) {
4304 r1_val = std::fabs(r2_val);
4305 set_d_register_from_double(r1, r1_val);
4306 if (r2_val != r2_val) { // input is NaN
4307 condition_reg_ = CC_OF;
4308 } else if (r2_val == 0) {
4309 condition_reg_ = CC_EQ;
4310 } else {
4311 condition_reg_ = CC_GT;
4312 }
4313 } else if (op == LPEBR) {
4314 fr1_val = std::fabs(fr2_val);
4315 set_d_register_from_float32(r1, fr1_val);
4316 if (fr2_val != fr2_val) { // input is NaN
4317 condition_reg_ = CC_OF;
4318 } else if (fr2_val == 0) {
4319 condition_reg_ = CC_EQ;
4320 } else {
4321 condition_reg_ = CC_GT;
4322 }
4323 } else {
4324 UNREACHABLE();
4325 }
4326 break;
4327 }
4328 case CDLFBR:
4329 case CDLGBR:
4330 case CELGBR:
4331 case CLFDBR:
4332 case CELFBR:
4333 case CLGDBR:
4334 case CLGEBR:
4335 case CLFEBR: {
4336 DecodeFourByteFloatingPointIntConversion(instr);
4337 break;
4338 }
4339 case TMLL: {
4340 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr);
4341 int r1 = riinst->R1Value();
4342 int mask = riinst->I2Value() & 0x0000FFFF;
4343 if (mask == 0) {
4344 condition_reg_ = 0x0;
4345 break;
4346 }
4347 uint32_t r1_val = get_low_register<uint32_t>(r1);
4348 r1_val = r1_val & 0x0000FFFF; // uses only the last 16bits
4349
4350 // Test if all selected bits are Zero
4351 bool allSelectedBitsAreZeros = true;
4352 for (int i = 0; i < 15; i++) {
4353 if (mask & (1 << i)) {
4354 if (r1_val & (1 << i)) {
4355 allSelectedBitsAreZeros = false;
4356 break;
4357 }
4358 }
4359 }
4360 if (allSelectedBitsAreZeros) {
4361 condition_reg_ = 0x8;
4362 break; // Done!
4363 }
4364
4365 // Test if all selected bits are one
4366 bool allSelectedBitsAreOnes = true;
4367 for (int i = 0; i < 15; i++) {
4368 if (mask & (1 << i)) {
4369 if (!(r1_val & (1 << i))) {
4370 allSelectedBitsAreOnes = false;
4371 break;
4372 }
4373 }
4374 }
4375 if (allSelectedBitsAreOnes) {
4376 condition_reg_ = 0x1;
4377 break; // Done!
4378 }
4379
4380 // Now we know selected bits mixed zeros and ones
4381 // Test if the leftmost bit is zero or one
4382 for (int i = 14; i >= 0; i--) {
4383 if (mask & (1 << i)) {
4384 if (r1_val & (1 << i)) {
4385 // leftmost bit is one
4386 condition_reg_ = 0x2;
4387 } else {
4388 // leftmost bit is zero
4389 condition_reg_ = 0x4;
4390 }
4391 break; // Done!
4392 }
4393 }
4394 break;
4395 }
4396 case LEDBR: {
4397 RREInstruction* rreInst = reinterpret_cast<RREInstruction*>(instr);
4398 int r1 = rreInst->R1Value();
4399 int r2 = rreInst->R2Value();
4400 double r2_val = get_double_from_d_register(r2);
4401 set_d_register_from_float32(r1, static_cast<float>(r2_val));
4402 break;
4403 }
4404 case FIDBRA: {
4405 RRFInstruction* rrfInst = reinterpret_cast<RRFInstruction*>(instr);
4406 int r1 = rrfInst->R1Value();
4407 int r2 = rrfInst->R2Value();
4408 int m3 = rrfInst->M3Value();
4409 double r2_val = get_double_from_d_register(r2);
4410 DCHECK(rrfInst->M4Value() == 0);
4411 switch (m3) {
4412 case Assembler::FIDBRA_ROUND_TO_NEAREST_AWAY_FROM_0:
4413 set_d_register_from_double(r1, round(r2_val));
4414 break;
4415 case Assembler::FIDBRA_ROUND_TOWARD_0:
4416 set_d_register_from_double(r1, trunc(r2_val));
4417 break;
4418 case Assembler::FIDBRA_ROUND_TOWARD_POS_INF:
4419 set_d_register_from_double(r1, std::ceil(r2_val));
4420 break;
4421 case Assembler::FIDBRA_ROUND_TOWARD_NEG_INF:
4422 set_d_register_from_double(r1, std::floor(r2_val));
4423 break;
4424 default:
4425 UNIMPLEMENTED();
4426 break;
4427 }
4428 break;
4429 }
4430 case FIEBRA: {
4431 RRFInstruction* rrfInst = reinterpret_cast<RRFInstruction*>(instr);
4432 int r1 = rrfInst->R1Value();
4433 int r2 = rrfInst->R2Value();
4434 int m3 = rrfInst->M3Value();
4435 float r2_val = get_float32_from_d_register(r2);
4436 DCHECK(rrfInst->M4Value() == 0);
4437 switch (m3) {
4438 case Assembler::FIDBRA_ROUND_TO_NEAREST_AWAY_FROM_0:
4439 set_d_register_from_float32(r1, round(r2_val));
4440 break;
4441 case Assembler::FIDBRA_ROUND_TOWARD_0:
4442 set_d_register_from_float32(r1, trunc(r2_val));
4443 break;
4444 case Assembler::FIDBRA_ROUND_TOWARD_POS_INF:
4445 set_d_register_from_float32(r1, std::ceil(r2_val));
4446 break;
4447 case Assembler::FIDBRA_ROUND_TOWARD_NEG_INF:
4448 set_d_register_from_float32(r1, std::floor(r2_val));
4449 break;
4450 default:
4451 UNIMPLEMENTED();
4452 break;
4453 }
4454 break;
4455 }
4456 case MSDBR: {
4457 UNIMPLEMENTED();
4458 break;
4459 }
4460 case LDEBR: {
4461 RREInstruction* rreInstr = reinterpret_cast<RREInstruction*>(instr);
4462 int r1 = rreInstr->R1Value();
4463 int r2 = rreInstr->R2Value();
4464 float fp_val = get_float32_from_d_register(r2);
4465 double db_val = static_cast<double>(fp_val);
4466 set_d_register_from_double(r1, db_val);
4467 break;
4468 }
4469 default: {
4470 UNREACHABLE();
4471 return false;
4472 }
4473 }
4474 return true;
4475}
4476
4477// Decode routine for six-byte instructions
4478bool Simulator::DecodeSixByte(Instruction* instr) {
4479 Opcode op = instr->S390OpcodeValue();
4480
4481 // Pre-cast instruction to various types
4482 RIEInstruction* rieInstr = reinterpret_cast<RIEInstruction*>(instr);
4483 RILInstruction* rilInstr = reinterpret_cast<RILInstruction*>(instr);
4484 RSYInstruction* rsyInstr = reinterpret_cast<RSYInstruction*>(instr);
4485 RXEInstruction* rxeInstr = reinterpret_cast<RXEInstruction*>(instr);
4486 RXYInstruction* rxyInstr = reinterpret_cast<RXYInstruction*>(instr);
4487 SIYInstruction* siyInstr = reinterpret_cast<SIYInstruction*>(instr);
4488 SILInstruction* silInstr = reinterpret_cast<SILInstruction*>(instr);
4489 SSInstruction* ssInstr = reinterpret_cast<SSInstruction*>(instr);
4490
4491 switch (op) {
4492 case CLIY: {
4493 // Compare Immediate (Mem - Imm) (8)
4494 int b1 = siyInstr->B1Value();
4495 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
4496 intptr_t d1_val = siyInstr->D1Value();
4497 intptr_t addr = b1_val + d1_val;
4498 uint8_t mem_val = ReadB(addr);
4499 uint8_t imm_val = siyInstr->I2Value();
4500 SetS390ConditionCode<uint8_t>(mem_val, imm_val);
4501 break;
4502 }
4503 case TMY: {
4504 // Test Under Mask (Mem - Imm) (8)
4505 int b1 = siyInstr->B1Value();
4506 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
4507 intptr_t d1_val = siyInstr->D1Value();
4508 intptr_t addr = b1_val + d1_val;
4509 uint8_t mem_val = ReadB(addr);
4510 uint8_t imm_val = siyInstr->I2Value();
4511 uint8_t selected_bits = mem_val & imm_val;
4512 // CC0: Selected bits are zero
4513 // CC1: Selected bits mixed zeros and ones
4514 // CC3: Selected bits all ones
4515 if (0 == selected_bits) {
4516 condition_reg_ = CC_EQ; // CC0
4517 } else if (selected_bits == imm_val) {
4518 condition_reg_ = 0x1; // CC3
4519 } else {
4520 condition_reg_ = 0x4; // CC1
4521 }
4522 break;
4523 }
4524 case LDEB: {
4525 // Load Float
4526 int r1 = rxeInstr->R1Value();
4527 int rb = rxeInstr->B2Value();
4528 int rx = rxeInstr->X2Value();
4529 int offset = rxeInstr->D2Value();
4530 int64_t rb_val = (rb == 0) ? 0 : get_register(rb);
4531 int64_t rx_val = (rx == 0) ? 0 : get_register(rx);
4532 double ret = static_cast<double>(
4533 *reinterpret_cast<float*>(rx_val + rb_val + offset));
4534 set_d_register_from_double(r1, ret);
4535 break;
4536 }
4537 case LAY: {
4538 // Load Address
4539 int r1 = rxyInstr->R1Value();
4540 int rb = rxyInstr->B2Value();
4541 int rx = rxyInstr->X2Value();
4542 int offset = rxyInstr->D2Value();
4543 int64_t rb_val = (rb == 0) ? 0 : get_register(rb);
4544 int64_t rx_val = (rx == 0) ? 0 : get_register(rx);
4545 set_register(r1, rx_val + rb_val + offset);
4546 break;
4547 }
4548 case LARL: {
4549 // Load Addresss Relative Long
4550 int r1 = rilInstr->R1Value();
4551 intptr_t offset = rilInstr->I2Value() * 2;
4552 set_register(r1, get_pc() + offset);
4553 break;
4554 }
4555 case LLILF: {
4556 // Load Logical into lower 32-bits (zero extend upper 32-bits)
4557 int r1 = rilInstr->R1Value();
4558 uint64_t imm = static_cast<uint64_t>(rilInstr->I2UnsignedValue());
4559 set_register(r1, imm);
4560 break;
4561 }
4562 case LLIHF: {
4563 // Load Logical Immediate into high word
4564 int r1 = rilInstr->R1Value();
4565 uint64_t imm = static_cast<uint64_t>(rilInstr->I2UnsignedValue());
4566 set_register(r1, imm << 32);
4567 break;
4568 }
4569 case OILF:
4570 case NILF:
4571 case IILF: {
4572 // Bitwise Op on lower 32-bits
4573 int r1 = rilInstr->R1Value();
4574 uint32_t imm = rilInstr->I2UnsignedValue();
4575 uint32_t alu_out = get_low_register<uint32_t>(r1);
4576 if (NILF == op) {
4577 alu_out &= imm;
4578 SetS390BitWiseConditionCode<uint32_t>(alu_out);
4579 } else if (OILF == op) {
4580 alu_out |= imm;
4581 SetS390BitWiseConditionCode<uint32_t>(alu_out);
4582 } else if (op == IILF) {
4583 alu_out = imm;
4584 } else {
4585 DCHECK(false);
4586 }
4587 set_low_register(r1, alu_out);
4588 break;
4589 }
4590 case OIHF:
4591 case NIHF:
4592 case IIHF: {
4593 // Bitwise Op on upper 32-bits
4594 int r1 = rilInstr->R1Value();
4595 uint32_t imm = rilInstr->I2Value();
4596 uint32_t alu_out = get_high_register<uint32_t>(r1);
4597 if (op == NIHF) {
4598 alu_out &= imm;
4599 SetS390BitWiseConditionCode<uint32_t>(alu_out);
4600 } else if (op == OIHF) {
4601 alu_out |= imm;
4602 SetS390BitWiseConditionCode<uint32_t>(alu_out);
4603 } else if (op == IIHF) {
4604 alu_out = imm;
4605 } else {
4606 DCHECK(false);
4607 }
4608 set_high_register(r1, alu_out);
4609 break;
4610 }
4611 case CLFI: {
4612 // Compare Logical with Immediate (32)
4613 int r1 = rilInstr->R1Value();
4614 uint32_t imm = rilInstr->I2UnsignedValue();
4615 SetS390ConditionCode<uint32_t>(get_low_register<uint32_t>(r1), imm);
4616 break;
4617 }
4618 case CFI: {
4619 // Compare with Immediate (32)
4620 int r1 = rilInstr->R1Value();
4621 int32_t imm = rilInstr->I2Value();
4622 SetS390ConditionCode<int32_t>(get_low_register<int32_t>(r1), imm);
4623 break;
4624 }
4625 case CLGFI: {
4626 // Compare Logical with Immediate (64)
4627 int r1 = rilInstr->R1Value();
4628 uint64_t imm = static_cast<uint64_t>(rilInstr->I2UnsignedValue());
4629 SetS390ConditionCode<uint64_t>(get_register(r1), imm);
4630 break;
4631 }
4632 case CGFI: {
4633 // Compare with Immediate (64)
4634 int r1 = rilInstr->R1Value();
4635 int64_t imm = static_cast<int64_t>(rilInstr->I2Value());
4636 SetS390ConditionCode<int64_t>(get_register(r1), imm);
4637 break;
4638 }
4639 case BRASL: {
4640 // Branch and Save Relative Long
4641 int r1 = rilInstr->R1Value();
4642 intptr_t d2 = rilInstr->I2Value();
4643 intptr_t pc = get_pc();
4644 set_register(r1, pc + 6); // save next instruction to register
4645 set_pc(pc + d2 * 2); // update register
4646 break;
4647 }
4648 case BRCL: {
4649 // Branch on Condition Relative Long
4650 Condition m1 = (Condition)rilInstr->R1Value();
4651 if (TestConditionCode((Condition)m1)) {
4652 intptr_t offset = rilInstr->I2Value() * 2;
4653 set_pc(get_pc() + offset);
4654 }
4655 break;
4656 }
4657 case LMG:
4658 case STMG: {
4659 // Store Multiple 64-bits.
4660 int r1 = rsyInstr->R1Value();
4661 int r3 = rsyInstr->R3Value();
4662 int rb = rsyInstr->B2Value();
4663 int offset = rsyInstr->D2Value();
4664
4665 // Regs roll around if r3 is less than r1.
4666 // Artifically increase r3 by 16 so we can calculate
4667 // the number of regs stored properly.
4668 if (r3 < r1) r3 += 16;
4669
4670 int64_t rb_val = (rb == 0) ? 0 : get_register(rb);
4671
4672 // Store each register in ascending order.
4673 for (int i = 0; i <= r3 - r1; i++) {
4674 if (op == LMG) {
4675 int64_t value = ReadDW(rb_val + offset + 8 * i);
4676 set_register((r1 + i) % 16, value);
4677 } else if (op == STMG) {
4678 int64_t value = get_register((r1 + i) % 16);
4679 WriteDW(rb_val + offset + 8 * i, value);
4680 } else {
4681 DCHECK(false);
4682 }
4683 }
4684 break;
4685 }
4686 case SLLK:
4687 case RLL:
4688 case SRLK:
4689 case SLLG:
4690 case RLLG:
4691 case SRLG: {
4692 DecodeSixByteBitShift(instr);
4693 break;
4694 }
4695 case SLAK:
4696 case SRAK: {
4697 // 32-bit non-clobbering shift-left/right arithmetic
4698 int r1 = rsyInstr->R1Value();
4699 int r3 = rsyInstr->R3Value();
4700 int b2 = rsyInstr->B2Value();
4701 intptr_t d2 = rsyInstr->D2Value();
4702 // only takes rightmost 6 bits
4703 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
4704 int shiftBits = (b2_val + d2) & 0x3F;
4705 int32_t r3_val = get_low_register<int32_t>(r3);
4706 int32_t alu_out = 0;
4707 bool isOF = false;
4708 if (op == SLAK) {
4709 isOF = CheckOverflowForShiftLeft(r3_val, shiftBits);
4710 alu_out = r3_val << shiftBits;
4711 } else if (op == SRAK) {
4712 alu_out = r3_val >> shiftBits;
4713 }
4714 set_low_register(r1, alu_out);
4715 SetS390ConditionCode<int32_t>(alu_out, 0);
4716 SetS390OverflowCode(isOF);
4717 break;
4718 }
4719 case SLAG:
4720 case SRAG: {
4721 // 64-bit non-clobbering shift-left/right arithmetic
4722 int r1 = rsyInstr->R1Value();
4723 int r3 = rsyInstr->R3Value();
4724 int b2 = rsyInstr->B2Value();
4725 intptr_t d2 = rsyInstr->D2Value();
4726 // only takes rightmost 6 bits
4727 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
4728 int shiftBits = (b2_val + d2) & 0x3F;
4729 int64_t r3_val = get_register(r3);
4730 intptr_t alu_out = 0;
4731 bool isOF = false;
4732 if (op == SLAG) {
4733 isOF = CheckOverflowForShiftLeft(r3_val, shiftBits);
4734 alu_out = r3_val << shiftBits;
4735 } else if (op == SRAG) {
4736 alu_out = r3_val >> shiftBits;
4737 }
4738 set_register(r1, alu_out);
4739 SetS390ConditionCode<intptr_t>(alu_out, 0);
4740 SetS390OverflowCode(isOF);
4741 break;
4742 }
4743 case LMY:
4744 case STMY: {
4745 RSYInstruction* rsyInstr = reinterpret_cast<RSYInstruction*>(instr);
4746 // Load/Store Multiple (32)
4747 int r1 = rsyInstr->R1Value();
4748 int r3 = rsyInstr->R3Value();
4749 int b2 = rsyInstr->B2Value();
4750 int offset = rsyInstr->D2Value();
4751
4752 // Regs roll around if r3 is less than r1.
4753 // Artifically increase r3 by 16 so we can calculate
4754 // the number of regs stored properly.
4755 if (r3 < r1) r3 += 16;
4756
4757 int32_t b2_val = (b2 == 0) ? 0 : get_low_register<int32_t>(b2);
4758
4759 // Store each register in ascending order.
4760 for (int i = 0; i <= r3 - r1; i++) {
4761 if (op == LMY) {
4762 int32_t value = ReadW(b2_val + offset + 4 * i, instr);
4763 set_low_register((r1 + i) % 16, value);
4764 } else {
4765 int32_t value = get_low_register<int32_t>((r1 + i) % 16);
4766 WriteW(b2_val + offset + 4 * i, value, instr);
4767 }
4768 }
4769 break;
4770 }
4771 case LT:
4772 case LTG: {
4773 // Load and Test (32/64)
4774 int r1 = rxyInstr->R1Value();
4775 int x2 = rxyInstr->X2Value();
4776 int b2 = rxyInstr->B2Value();
4777 int d2 = rxyInstr->D2Value();
4778
4779 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
4780 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
4781 intptr_t addr = x2_val + b2_val + d2;
4782
4783 if (op == LT) {
4784 int32_t value = ReadW(addr, instr);
4785 set_low_register(r1, value);
4786 SetS390ConditionCode<int32_t>(value, 0);
4787 } else if (op == LTG) {
4788 int64_t value = ReadDW(addr);
4789 set_register(r1, value);
4790 SetS390ConditionCode<int64_t>(value, 0);
4791 }
4792 break;
4793 }
4794 case LY:
4795 case LB:
4796 case LGB:
4797 case LG:
4798 case LGF:
4799 case LGH:
4800 case LLGF:
4801 case STG:
4802 case STY:
4803 case STCY:
4804 case STHY:
4805 case STEY:
4806 case LDY:
4807 case LHY:
4808 case STDY:
4809 case LEY: {
4810 // Miscellaneous Loads and Stores
4811 int r1 = rxyInstr->R1Value();
4812 int x2 = rxyInstr->X2Value();
4813 int b2 = rxyInstr->B2Value();
4814 int d2 = rxyInstr->D2Value();
4815 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
4816 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
4817 intptr_t addr = x2_val + b2_val + d2;
4818 if (op == LY) {
4819 uint32_t mem_val = ReadWU(addr, instr);
4820 set_low_register(r1, mem_val);
4821 } else if (op == LB) {
4822 int32_t mem_val = ReadB(addr);
4823 set_low_register(r1, mem_val);
4824 } else if (op == LGB) {
4825 int64_t mem_val = ReadB(addr);
4826 set_register(r1, mem_val);
4827 } else if (op == LG) {
4828 int64_t mem_val = ReadDW(addr);
4829 set_register(r1, mem_val);
4830 } else if (op == LGF) {
4831 int64_t mem_val = static_cast<int64_t>(ReadW(addr, instr));
4832 set_register(r1, mem_val);
4833 } else if (op == LGH) {
4834 int64_t mem_val = static_cast<int64_t>(ReadH(addr, instr));
4835 set_register(r1, mem_val);
4836 } else if (op == LLGF) {
4837 // int r1 = rreInst->R1Value();
4838 // int r2 = rreInst->R2Value();
4839 // int32_t r2_val = get_low_register<int32_t>(r2);
4840 // uint64_t r2_finalval = (static_cast<uint64_t>(r2_val)
4841 // & 0x00000000ffffffff);
4842 // set_register(r1, r2_finalval);
4843 // break;
4844 uint64_t mem_val = static_cast<uint64_t>(ReadWU(addr, instr));
4845 set_register(r1, mem_val);
4846 } else if (op == LDY) {
4847 uint64_t dbl_val = *reinterpret_cast<uint64_t*>(addr);
4848 set_d_register(r1, dbl_val);
4849 } else if (op == STEY) {
4850 int64_t frs_val = get_d_register(r1) >> 32;
4851 WriteW(addr, static_cast<int32_t>(frs_val), instr);
4852 } else if (op == LEY) {
4853 float float_val = *reinterpret_cast<float*>(addr);
4854 set_d_register_from_float32(r1, float_val);
4855 } else if (op == STY) {
4856 uint32_t value = get_low_register<uint32_t>(r1);
4857 WriteW(addr, value, instr);
4858 } else if (op == STG) {
4859 uint64_t value = get_register(r1);
4860 WriteDW(addr, value);
4861 } else if (op == STDY) {
4862 int64_t frs_val = get_d_register(r1);
4863 WriteDW(addr, frs_val);
4864 } else if (op == STCY) {
4865 uint8_t value = get_low_register<uint32_t>(r1);
4866 WriteB(addr, value);
4867 } else if (op == STHY) {
4868 uint16_t value = get_low_register<uint32_t>(r1);
4869 WriteH(addr, value, instr);
4870 } else if (op == LHY) {
4871 int32_t result = static_cast<int32_t>(ReadH(addr, instr));
4872 set_low_register(r1, result);
4873 }
4874 break;
4875 }
4876 case MVC: {
4877 // Move Character
4878 int b1 = ssInstr->B1Value();
4879 intptr_t d1 = ssInstr->D1Value();
4880 int b2 = ssInstr->B2Value();
4881 intptr_t d2 = ssInstr->D2Value();
4882 int length = ssInstr->Length();
4883 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
4884 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
4885 intptr_t src_addr = b2_val + d2;
4886 intptr_t dst_addr = b1_val + d1;
4887 // remember that the length is the actual length - 1
4888 for (int i = 0; i < length + 1; ++i) {
4889 WriteB(dst_addr++, ReadB(src_addr++));
4890 }
4891 break;
4892 }
4893 case MVHI: {
4894 // Move Integer (32)
4895 int b1 = silInstr->B1Value();
4896 intptr_t d1 = silInstr->D1Value();
4897 int16_t i2 = silInstr->I2Value();
4898 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
4899 intptr_t src_addr = b1_val + d1;
4900 WriteW(src_addr, i2, instr);
4901 break;
4902 }
4903 case MVGHI: {
4904 // Move Integer (64)
4905 int b1 = silInstr->B1Value();
4906 intptr_t d1 = silInstr->D1Value();
4907 int16_t i2 = silInstr->I2Value();
4908 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
4909 intptr_t src_addr = b1_val + d1;
4910 WriteDW(src_addr, i2);
4911 break;
4912 }
4913 case LLH:
4914 case LLGH: {
4915 // Load Logical Halfworld
4916 int r1 = rxyInstr->R1Value();
4917 int b2 = rxyInstr->B2Value();
4918 int x2 = rxyInstr->X2Value();
4919 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
4920 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
4921 intptr_t d2_val = rxyInstr->D2Value();
4922 uint16_t mem_val = ReadHU(b2_val + d2_val + x2_val, instr);
4923 if (op == LLH) {
4924 set_low_register(r1, mem_val);
4925 } else if (op == LLGH) {
4926 set_register(r1, mem_val);
4927 } else {
4928 UNREACHABLE();
4929 }
4930 break;
4931 }
4932 case LLC:
4933 case LLGC: {
4934 // Load Logical Character - loads a byte and zero extends.
4935 int r1 = rxyInstr->R1Value();
4936 int b2 = rxyInstr->B2Value();
4937 int x2 = rxyInstr->X2Value();
4938 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
4939 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
4940 intptr_t d2_val = rxyInstr->D2Value();
4941 uint8_t mem_val = ReadBU(b2_val + d2_val + x2_val);
4942 if (op == LLC) {
4943 set_low_register(r1, static_cast<uint32_t>(mem_val));
4944 } else if (op == LLGC) {
4945 set_register(r1, static_cast<uint64_t>(mem_val));
4946 } else {
4947 UNREACHABLE();
4948 }
4949 break;
4950 }
4951 case XIHF:
4952 case XILF: {
4953 int r1 = rilInstr->R1Value();
4954 uint32_t imm = rilInstr->I2UnsignedValue();
4955 uint32_t alu_out = 0;
4956 if (op == XILF) {
4957 alu_out = get_low_register<uint32_t>(r1);
4958 alu_out = alu_out ^ imm;
4959 set_low_register(r1, alu_out);
4960 } else if (op == XIHF) {
4961 alu_out = get_high_register<uint32_t>(r1);
4962 alu_out = alu_out ^ imm;
4963 set_high_register(r1, alu_out);
4964 } else {
4965 UNREACHABLE();
4966 }
4967 SetS390BitWiseConditionCode<uint32_t>(alu_out);
4968 break;
4969 }
4970 case RISBG: {
4971 // Rotate then insert selected bits
4972 int r1 = rieInstr->R1Value();
4973 int r2 = rieInstr->R2Value();
4974 // Starting Bit Position is Bits 2-7 of I3 field
4975 uint32_t start_bit = rieInstr->I3Value() & 0x3F;
4976 // Ending Bit Position is Bits 2-7 of I4 field
4977 uint32_t end_bit = rieInstr->I4Value() & 0x3F;
4978 // Shift Amount is Bits 2-7 of I5 field
4979 uint32_t shift_amount = rieInstr->I5Value() & 0x3F;
4980 // Zero out Remaining (unslected) bits if Bit 0 of I4 is 1.
4981 bool zero_remaining = (0 != (rieInstr->I4Value() & 0x80));
4982
4983 uint64_t src_val = get_register(r2);
4984
4985 // Rotate Left by Shift Amount first
4986 uint64_t rotated_val =
4987 (src_val << shift_amount) | (src_val >> (64 - shift_amount));
4988 int32_t width = end_bit - start_bit + 1;
4989
4990 uint64_t selection_mask = 0;
4991 if (width < 64) {
4992 selection_mask = (static_cast<uint64_t>(1) << width) - 1;
4993 } else {
4994 selection_mask = static_cast<uint64_t>(static_cast<int64_t>(-1));
4995 }
4996 selection_mask = selection_mask << (63 - end_bit);
4997
4998 uint64_t selected_val = rotated_val & selection_mask;
4999
5000 if (!zero_remaining) {
5001 // Merged the unselected bits from the original value
5002 selected_val = (src_val & ~selection_mask) | selected_val;
5003 }
5004
5005 // Condition code is set by treating result as 64-bit signed int
5006 SetS390ConditionCode<int64_t>(selected_val, 0);
5007 set_register(r1, selected_val);
5008 break;
5009 }
5010 default:
5011 return DecodeSixByteArithmetic(instr);
5012 }
5013 return true;
5014}
5015
5016void Simulator::DecodeSixByteBitShift(Instruction* instr) {
5017 Opcode op = instr->S390OpcodeValue();
5018
5019 // Pre-cast instruction to various types
5020
5021 RSYInstruction* rsyInstr = reinterpret_cast<RSYInstruction*>(instr);
5022
5023 switch (op) {
5024 case SLLK:
5025 case RLL:
5026 case SRLK: {
5027 // For SLLK/SRLL, the 32-bit third operand is shifted the number
5028 // of bits specified by the second-operand address, and the result is
5029 // placed at the first-operand location. Except for when the R1 and R3
5030 // fields designate the same register, the third operand remains
5031 // unchanged in general register R3.
5032 int r1 = rsyInstr->R1Value();
5033 int r3 = rsyInstr->R3Value();
5034 int b2 = rsyInstr->B2Value();
5035 intptr_t d2 = rsyInstr->D2Value();
5036 // only takes rightmost 6 bits
5037 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
5038 int shiftBits = (b2_val + d2) & 0x3F;
5039 // unsigned
5040 uint32_t r3_val = get_low_register<uint32_t>(r3);
5041 uint32_t alu_out = 0;
5042 if (SLLK == op) {
5043 alu_out = r3_val << shiftBits;
5044 } else if (SRLK == op) {
5045 alu_out = r3_val >> shiftBits;
5046 } else if (RLL == op) {
5047 uint32_t rotateBits = r3_val >> (32 - shiftBits);
5048 alu_out = (r3_val << shiftBits) | (rotateBits);
5049 } else {
5050 UNREACHABLE();
5051 }
5052 set_low_register(r1, alu_out);
5053 break;
5054 }
5055 case SLLG:
5056 case RLLG:
5057 case SRLG: {
5058 // For SLLG/SRLG, the 64-bit third operand is shifted the number
5059 // of bits specified by the second-operand address, and the result is
5060 // placed at the first-operand location. Except for when the R1 and R3
5061 // fields designate the same register, the third operand remains
5062 // unchanged in general register R3.
5063 int r1 = rsyInstr->R1Value();
5064 int r3 = rsyInstr->R3Value();
5065 int b2 = rsyInstr->B2Value();
5066 intptr_t d2 = rsyInstr->D2Value();
5067 // only takes rightmost 6 bits
5068 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
5069 int shiftBits = (b2_val + d2) & 0x3F;
5070 // unsigned
5071 uint64_t r3_val = get_register(r3);
5072 uint64_t alu_out = 0;
5073 if (op == SLLG) {
5074 alu_out = r3_val << shiftBits;
5075 } else if (op == SRLG) {
5076 alu_out = r3_val >> shiftBits;
5077 } else if (op == RLLG) {
5078 uint64_t rotateBits = r3_val >> (64 - shiftBits);
5079 alu_out = (r3_val << shiftBits) | (rotateBits);
5080 } else {
5081 UNREACHABLE();
5082 }
5083 set_register(r1, alu_out);
5084 break;
5085 }
5086 default:
5087 UNREACHABLE();
5088 }
5089}
5090
5091/**
5092 * Decodes and simulates six byte arithmetic instructions
5093 */
5094bool Simulator::DecodeSixByteArithmetic(Instruction* instr) {
5095 Opcode op = instr->S390OpcodeValue();
5096
5097 // Pre-cast instruction to various types
5098 SIYInstruction* siyInstr = reinterpret_cast<SIYInstruction*>(instr);
5099
5100 switch (op) {
5101 case CDB:
5102 case ADB:
5103 case SDB:
5104 case MDB:
5105 case DDB:
5106 case SQDB: {
5107 RXEInstruction* rxeInstr = reinterpret_cast<RXEInstruction*>(instr);
5108 int b2 = rxeInstr->B2Value();
5109 int x2 = rxeInstr->X2Value();
5110 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
5111 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
5112 intptr_t d2_val = rxeInstr->D2Value();
5113 double r1_val = get_double_from_d_register(rxeInstr->R1Value());
5114 double dbl_val = ReadDouble(b2_val + x2_val + d2_val);
5115
5116 switch (op) {
5117 case CDB:
5118 SetS390ConditionCode<double>(r1_val, dbl_val);
5119 break;
5120 case ADB:
5121 r1_val += dbl_val;
5122 set_d_register_from_double(r1, r1_val);
5123 SetS390ConditionCode<double>(r1_val, 0);
5124 break;
5125 case SDB:
5126 r1_val -= dbl_val;
5127 set_d_register_from_double(r1, r1_val);
5128 SetS390ConditionCode<double>(r1_val, 0);
5129 break;
5130 case MDB:
5131 r1_val *= dbl_val;
5132 set_d_register_from_double(r1, r1_val);
5133 SetS390ConditionCode<double>(r1_val, 0);
5134 break;
5135 case DDB:
5136 r1_val /= dbl_val;
5137 set_d_register_from_double(r1, r1_val);
5138 SetS390ConditionCode<double>(r1_val, 0);
5139 break;
5140 case SQDB:
5141 r1_val = std::sqrt(dbl_val);
5142 set_d_register_from_double(r1, r1_val);
5143 default:
5144 UNREACHABLE();
5145 break;
5146 }
5147 break;
5148 }
5149 case LRV:
5150 case LRVH:
5151 case STRV:
5152 case STRVH: {
5153 RXYInstruction* rxyInstr = reinterpret_cast<RXYInstruction*>(instr);
5154 int r1 = rxyInstr->R1Value();
5155 int x2 = rxyInstr->X2Value();
5156 int b2 = rxyInstr->B2Value();
5157 int d2 = rxyInstr->D2Value();
5158 int32_t r1_val = get_low_register<int32_t>(r1);
5159 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
5160 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
5161 intptr_t mem_addr = b2_val + x2_val + d2;
5162
5163 if (op == LRVH) {
5164 int16_t mem_val = ReadH(mem_addr, instr);
5165 int32_t result = ByteReverse(mem_val) & 0x0000ffff;
5166 result |= r1_val & 0xffff0000;
5167 set_low_register(r1, result);
5168 } else if (op == LRV) {
5169 int32_t mem_val = ReadW(mem_addr, instr);
5170 set_low_register(r1, ByteReverse(mem_val));
5171 } else if (op == STRVH) {
5172 int16_t result = static_cast<int16_t>(r1_val >> 16);
5173 WriteH(mem_addr, ByteReverse(result), instr);
5174 } else if (op == STRV) {
5175 WriteW(mem_addr, ByteReverse(r1_val), instr);
5176 }
5177
5178 break;
5179 }
5180 case AHIK:
5181 case AGHIK: {
5182 // Non-clobbering Add Halfword Immediate
5183 RIEInstruction* rieInst = reinterpret_cast<RIEInstruction*>(instr);
5184 int r1 = rieInst->R1Value();
5185 int r2 = rieInst->R2Value();
5186 bool isOF = false;
5187 if (AHIK == op) {
5188 // 32-bit Add
5189 int32_t r2_val = get_low_register<int32_t>(r2);
5190 int32_t imm = rieInst->I6Value();
5191 isOF = CheckOverflowForIntAdd(r2_val, imm, int32_t);
5192 set_low_register(r1, r2_val + imm);
5193 SetS390ConditionCode<int32_t>(r2_val + imm, 0);
5194 } else if (AGHIK == op) {
5195 // 64-bit Add
5196 int64_t r2_val = get_register(r2);
5197 int64_t imm = static_cast<int64_t>(rieInst->I6Value());
5198 isOF = CheckOverflowForIntAdd(r2_val, imm, int64_t);
5199 set_register(r1, r2_val + imm);
5200 SetS390ConditionCode<int64_t>(r2_val + imm, 0);
5201 }
5202 SetS390OverflowCode(isOF);
5203 break;
5204 }
5205 case ALFI:
5206 case SLFI: {
5207 RILInstruction* rilInstr = reinterpret_cast<RILInstruction*>(instr);
5208 int r1 = rilInstr->R1Value();
5209 uint32_t imm = rilInstr->I2UnsignedValue();
5210 uint32_t alu_out = get_low_register<uint32_t>(r1);
5211 if (op == ALFI) {
5212 alu_out += imm;
5213 } else if (op == SLFI) {
5214 alu_out -= imm;
5215 }
5216 SetS390ConditionCode<uint32_t>(alu_out, 0);
5217 set_low_register(r1, alu_out);
5218 break;
5219 }
5220 case ML: {
5221 UNIMPLEMENTED();
5222 break;
5223 }
5224 case AY:
5225 case SY:
5226 case NY:
5227 case OY:
5228 case XY:
5229 case CY: {
5230 RXYInstruction* rxyInstr = reinterpret_cast<RXYInstruction*>(instr);
5231 int r1 = rxyInstr->R1Value();
5232 int x2 = rxyInstr->X2Value();
5233 int b2 = rxyInstr->B2Value();
5234 int d2 = rxyInstr->D2Value();
5235 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
5236 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
5237 int32_t alu_out = get_low_register<int32_t>(r1);
5238 int32_t mem_val = ReadW(b2_val + x2_val + d2, instr);
5239 bool isOF = false;
5240 if (op == AY) {
5241 isOF = CheckOverflowForIntAdd(alu_out, mem_val, int32_t);
5242 alu_out += mem_val;
5243 SetS390ConditionCode<int32_t>(alu_out, 0);
5244 SetS390OverflowCode(isOF);
5245 } else if (op == SY) {
5246 isOF = CheckOverflowForIntSub(alu_out, mem_val, int32_t);
5247 alu_out -= mem_val;
5248 SetS390ConditionCode<int32_t>(alu_out, 0);
5249 SetS390OverflowCode(isOF);
5250 } else if (op == NY) {
5251 alu_out &= mem_val;
5252 SetS390BitWiseConditionCode<uint32_t>(alu_out);
5253 } else if (op == OY) {
5254 alu_out |= mem_val;
5255 SetS390BitWiseConditionCode<uint32_t>(alu_out);
5256 } else if (op == XY) {
5257 alu_out ^= mem_val;
5258 SetS390BitWiseConditionCode<uint32_t>(alu_out);
5259 } else if (op == CY) {
5260 SetS390ConditionCode<int32_t>(alu_out, mem_val);
5261 }
5262 if (op != CY) {
5263 set_low_register(r1, alu_out);
5264 }
5265 break;
5266 }
5267 case AHY:
5268 case SHY: {
5269 RXYInstruction* rxyInstr = reinterpret_cast<RXYInstruction*>(instr);
5270 int32_t r1_val = get_low_register<int32_t>(rxyInstr->R1Value());
5271 int b2 = rxyInstr->B2Value();
5272 int x2 = rxyInstr->X2Value();
5273 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
5274 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
5275 intptr_t d2_val = rxyInstr->D2Value();
5276 int32_t mem_val =
5277 static_cast<int32_t>(ReadH(b2_val + d2_val + x2_val, instr));
5278 int32_t alu_out = 0;
5279 bool isOF = false;
5280 switch (op) {
5281 case AHY:
5282 alu_out = r1_val + mem_val;
5283 isOF = CheckOverflowForIntAdd(r1_val, mem_val, int32_t);
5284 break;
5285 case SHY:
5286 alu_out = r1_val - mem_val;
5287 isOF = CheckOverflowForIntSub(r1_val, mem_val, int64_t);
5288 break;
5289 default:
5290 UNREACHABLE();
5291 break;
5292 }
5293 set_low_register(r1, alu_out);
5294 SetS390ConditionCode<int32_t>(alu_out, 0);
5295 SetS390OverflowCode(isOF);
5296 break;
5297 }
5298 case AG:
5299 case SG:
5300 case NG:
5301 case OG:
5302 case XG:
5303 case CG:
5304 case CLG: {
5305 RXYInstruction* rxyInstr = reinterpret_cast<RXYInstruction*>(instr);
5306 int r1 = rxyInstr->R1Value();
5307 int x2 = rxyInstr->X2Value();
5308 int b2 = rxyInstr->B2Value();
5309 int d2 = rxyInstr->D2Value();
5310 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
5311 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
5312 int64_t alu_out = get_register(r1);
5313 int64_t mem_val = ReadDW(b2_val + x2_val + d2);
5314
5315 switch (op) {
5316 case AG: {
5317 alu_out += mem_val;
5318 SetS390ConditionCode<int32_t>(alu_out, 0);
5319 break;
5320 }
5321 case SG: {
5322 alu_out -= mem_val;
5323 SetS390ConditionCode<int32_t>(alu_out, 0);
5324 break;
5325 }
5326 case NG: {
5327 alu_out &= mem_val;
5328 SetS390BitWiseConditionCode<uint32_t>(alu_out);
5329 break;
5330 }
5331 case OG: {
5332 alu_out |= mem_val;
5333 SetS390BitWiseConditionCode<uint32_t>(alu_out);
5334 break;
5335 }
5336 case XG: {
5337 alu_out ^= mem_val;
5338 SetS390BitWiseConditionCode<uint32_t>(alu_out);
5339 break;
5340 }
5341 case CG: {
5342 SetS390ConditionCode<int64_t>(alu_out, mem_val);
5343 break;
5344 }
5345 case CLG: {
5346 SetS390ConditionCode<uint64_t>(alu_out, mem_val);
5347 break;
5348 }
5349 default: {
5350 DCHECK(false);
5351 break;
5352 }
5353 }
5354
5355 if (op != CG) {
5356 set_register(r1, alu_out);
5357 }
5358 break;
5359 }
5360 case ALY:
5361 case SLY:
5362 case CLY: {
5363 RXYInstruction* rxyInstr = reinterpret_cast<RXYInstruction*>(instr);
5364 int r1 = rxyInstr->R1Value();
5365 int x2 = rxyInstr->X2Value();
5366 int b2 = rxyInstr->B2Value();
5367 int d2 = rxyInstr->D2Value();
5368 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
5369 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
5370 uint32_t alu_out = get_low_register<uint32_t>(r1);
5371 uint32_t mem_val = ReadWU(b2_val + x2_val + d2, instr);
5372
5373 if (op == ALY) {
5374 alu_out += mem_val;
5375 set_low_register(r1, alu_out);
5376 SetS390ConditionCode<uint32_t>(alu_out, 0);
5377 } else if (op == SLY) {
5378 alu_out -= mem_val;
5379 set_low_register(r1, alu_out);
5380 SetS390ConditionCode<uint32_t>(alu_out, 0);
5381 } else if (op == CLY) {
5382 SetS390ConditionCode<uint32_t>(alu_out, mem_val);
5383 }
5384 break;
5385 }
5386 case AGFI:
5387 case AFI: {
5388 // Clobbering Add Word Immediate
5389 RILInstruction* rilInstr = reinterpret_cast<RILInstruction*>(instr);
5390 int32_t r1 = rilInstr->R1Value();
5391 bool isOF = false;
5392 if (AFI == op) {
5393 // 32-bit Add (Register + 32-bit Immediate)
5394 int32_t r1_val = get_low_register<int32_t>(r1);
5395 int32_t i2 = rilInstr->I2Value();
5396 isOF = CheckOverflowForIntAdd(r1_val, i2, int32_t);
5397 int32_t alu_out = r1_val + i2;
5398 set_low_register(r1, alu_out);
5399 SetS390ConditionCode<int32_t>(alu_out, 0);
5400 } else if (AGFI == op) {
5401 // 64-bit Add (Register + 32-bit Imm)
5402 int64_t r1_val = get_register(r1);
5403 int64_t i2 = static_cast<int64_t>(rilInstr->I2Value());
5404 isOF = CheckOverflowForIntAdd(r1_val, i2, int64_t);
5405 int64_t alu_out = r1_val + i2;
5406 set_register(r1, alu_out);
5407 SetS390ConditionCode<int64_t>(alu_out, 0);
5408 }
5409 SetS390OverflowCode(isOF);
5410 break;
5411 }
5412 case ASI: {
5413 // TODO(bcleung): Change all fooInstr->I2Value() to template functions.
5414 // The below static cast to 8 bit and then to 32 bit is necessary
5415 // because siyInstr->I2Value() returns a uint8_t, which a direct
5416 // cast to int32_t could incorrectly interpret.
5417 int8_t i2_8bit = static_cast<int8_t>(siyInstr->I2Value());
5418 int32_t i2 = static_cast<int32_t>(i2_8bit);
5419 int b1 = siyInstr->B1Value();
5420 intptr_t b1_val = (b1 == 0) ? 0 : get_register(b1);
5421
5422 int d1_val = siyInstr->D1Value();
5423 intptr_t addr = b1_val + d1_val;
5424
5425 int32_t mem_val = ReadW(addr, instr);
5426 bool isOF = CheckOverflowForIntAdd(mem_val, i2, int32_t);
5427 int32_t alu_out = mem_val + i2;
5428 SetS390ConditionCode<int32_t>(alu_out, 0);
5429 SetS390OverflowCode(isOF);
5430 WriteW(addr, alu_out, instr);
5431 break;
5432 }
5433 case AGSI: {
5434 // TODO(bcleung): Change all fooInstr->I2Value() to template functions.
5435 // The below static cast to 8 bit and then to 32 bit is necessary
5436 // because siyInstr->I2Value() returns a uint8_t, which a direct
5437 // cast to int32_t could incorrectly interpret.
5438 int8_t i2_8bit = static_cast<int8_t>(siyInstr->I2Value());
5439 int64_t i2 = static_cast<int64_t>(i2_8bit);
5440 int b1 = siyInstr->B1Value();
5441 intptr_t b1_val = (b1 == 0) ? 0 : get_register(b1);
5442
5443 int d1_val = siyInstr->D1Value();
5444 intptr_t addr = b1_val + d1_val;
5445
5446 int64_t mem_val = ReadDW(addr);
5447 int isOF = CheckOverflowForIntAdd(mem_val, i2, int64_t);
5448 int64_t alu_out = mem_val + i2;
5449 SetS390ConditionCode<uint64_t>(alu_out, 0);
5450 SetS390OverflowCode(isOF);
5451 WriteDW(addr, alu_out);
5452 break;
5453 }
5454 case AGF:
5455 case SGF:
5456 case ALG:
5457 case SLG: {
5458#ifndef V8_TARGET_ARCH_S390X
5459 DCHECK(false);
5460#endif
5461 RXYInstruction* rxyInstr = reinterpret_cast<RXYInstruction*>(instr);
5462 int r1 = rxyInstr->R1Value();
5463 uint64_t r1_val = get_register(rxyInstr->R1Value());
5464 int b2 = rxyInstr->B2Value();
5465 int x2 = rxyInstr->X2Value();
5466 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
5467 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
5468 intptr_t d2_val = rxyInstr->D2Value();
5469 uint64_t alu_out = r1_val;
5470 if (op == ALG) {
5471 uint64_t mem_val =
5472 static_cast<uint64_t>(ReadDW(b2_val + d2_val + x2_val));
5473 alu_out += mem_val;
5474 SetS390ConditionCode<uint64_t>(alu_out, 0);
5475 } else if (op == SLG) {
5476 uint64_t mem_val =
5477 static_cast<uint64_t>(ReadDW(b2_val + d2_val + x2_val));
5478 alu_out -= mem_val;
5479 SetS390ConditionCode<uint64_t>(alu_out, 0);
5480 } else if (op == AGF) {
5481 uint32_t mem_val = ReadW(b2_val + d2_val + x2_val, instr);
5482 alu_out += mem_val;
5483 SetS390ConditionCode<int64_t>(alu_out, 0);
5484 } else if (op == SGF) {
5485 uint32_t mem_val = ReadW(b2_val + d2_val + x2_val, instr);
5486 alu_out -= mem_val;
5487 SetS390ConditionCode<int64_t>(alu_out, 0);
5488 } else {
5489 DCHECK(false);
5490 }
5491 set_register(r1, alu_out);
5492 break;
5493 }
5494 case ALGFI:
5495 case SLGFI: {
5496#ifndef V8_TARGET_ARCH_S390X
5497 // should only be called on 64bit
5498 DCHECK(false);
5499#endif
5500 RILInstruction* rilInstr = reinterpret_cast<RILInstruction*>(instr);
5501 int r1 = rilInstr->R1Value();
5502 uint32_t i2 = rilInstr->I2UnsignedValue();
5503 uint64_t r1_val = (uint64_t)(get_register(r1));
5504 uint64_t alu_out;
5505 if (op == ALGFI)
5506 alu_out = r1_val + i2;
5507 else
5508 alu_out = r1_val - i2;
5509 set_register(r1, (intptr_t)alu_out);
5510 SetS390ConditionCode<uint64_t>(alu_out, 0);
5511 break;
5512 }
5513 case MSY:
5514 case MSG: {
5515 RXYInstruction* rxyInstr = reinterpret_cast<RXYInstruction*>(instr);
5516 int r1 = rxyInstr->R1Value();
5517 int b2 = rxyInstr->B2Value();
5518 int x2 = rxyInstr->X2Value();
5519 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
5520 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
5521 intptr_t d2_val = rxyInstr->D2Value();
5522 if (op == MSY) {
5523 int32_t mem_val = ReadW(b2_val + d2_val + x2_val, instr);
5524 int32_t r1_val = get_low_register<int32_t>(r1);
5525 set_low_register(r1, mem_val * r1_val);
5526 } else if (op == MSG) {
5527 int64_t mem_val = ReadDW(b2_val + d2_val + x2_val);
5528 int64_t r1_val = get_register(r1);
5529 set_register(r1, mem_val * r1_val);
5530 } else {
5531 UNREACHABLE();
5532 }
5533 break;
5534 }
5535 case MSFI:
5536 case MSGFI: {
5537 RILInstruction* rilinst = reinterpret_cast<RILInstruction*>(instr);
5538 int r1 = rilinst->R1Value();
5539 int32_t i2 = rilinst->I2Value();
5540 if (op == MSFI) {
5541 int32_t alu_out = get_low_register<int32_t>(r1);
5542 alu_out = alu_out * i2;
5543 set_low_register(r1, alu_out);
5544 } else if (op == MSGFI) {
5545 int64_t alu_out = get_register(r1);
5546 alu_out = alu_out * i2;
5547 set_register(r1, alu_out);
5548 } else {
5549 UNREACHABLE();
5550 }
5551 break;
5552 }
5553 default:
5554 UNREACHABLE();
5555 return false;
5556 }
5557 return true;
5558}
5559
5560int16_t Simulator::ByteReverse(int16_t hword) {
5561 return (hword << 8) | ((hword >> 8) & 0x00ff);
5562}
5563
5564int32_t Simulator::ByteReverse(int32_t word) {
5565 int32_t result = word << 24;
5566 result |= (word << 8) & 0x00ff0000;
5567 result |= (word >> 8) & 0x0000ff00;
5568 result |= (word >> 24) & 0x00000ff;
5569 return result;
5570}
5571
Ben Murdochc5610432016-08-08 18:44:38 +01005572int Simulator::DecodeInstructionOriginal(Instruction* instr) {
Ben Murdochda12d292016-06-02 14:46:10 +01005573 int instrLength = instr->InstructionLength();
Ben Murdochc5610432016-08-08 18:44:38 +01005574 bool processed = true;
Ben Murdochda12d292016-06-02 14:46:10 +01005575 if (instrLength == 2)
5576 processed = DecodeTwoByte(instr);
5577 else if (instrLength == 4)
5578 processed = DecodeFourByte(instr);
5579 else if (instrLength == 6)
5580 processed = DecodeSixByte(instr);
Ben Murdochc5610432016-08-08 18:44:38 +01005581 return instrLength;
5582}
Ben Murdochda12d292016-06-02 14:46:10 +01005583
Ben Murdochc5610432016-08-08 18:44:38 +01005584int Simulator::DecodeInstruction(Instruction* instr) {
5585 Opcode op = instr->S390OpcodeValue();
5586 DCHECK(EvalTable[op] != NULL);
5587 return (this->*EvalTable[op])(instr);
5588}
5589
5590// Executes the current instruction.
5591void Simulator::ExecuteInstruction(Instruction* instr, bool auto_incr_pc) {
5592 icount_++;
5593
5594 if (v8::internal::FLAG_check_icache) {
5595 CheckICache(isolate_->simulator_i_cache(), instr);
Ben Murdochda12d292016-06-02 14:46:10 +01005596 }
Ben Murdochc5610432016-08-08 18:44:38 +01005597
5598 pc_modified_ = false;
5599
5600 if (::v8::internal::FLAG_trace_sim) {
5601 disasm::NameConverter converter;
5602 disasm::Disassembler dasm(converter);
5603 // use a reasonably large buffer
5604 v8::internal::EmbeddedVector<char, 256> buffer;
5605 dasm.InstructionDecode(buffer, reinterpret_cast<byte*>(instr));
5606 PrintF("%05" PRId64 " %08" V8PRIxPTR " %s\n", icount_,
5607 reinterpret_cast<intptr_t>(instr), buffer.start());
5608
5609 // Flush stdout to prevent incomplete file output during abnormal exits
5610 // This is caused by the output being buffered before being written to file
5611 fflush(stdout);
5612 }
5613
5614 // Try to simulate as S390 Instruction first.
5615 int length = DecodeInstruction(instr);
5616
5617 if (!pc_modified_ && auto_incr_pc) {
5618 DCHECK(length == instr->InstructionLength());
5619 set_pc(reinterpret_cast<intptr_t>(instr) + length);
5620 }
5621 return;
Ben Murdochda12d292016-06-02 14:46:10 +01005622}
5623
5624void Simulator::DebugStart() {
5625 S390Debugger dbg(this);
5626 dbg.Debug();
5627}
5628
5629void Simulator::Execute() {
5630 // Get the PC to simulate. Cannot use the accessor here as we need the
5631 // raw PC value and not the one used as input to arithmetic instructions.
5632 intptr_t program_counter = get_pc();
5633
5634 if (::v8::internal::FLAG_stop_sim_at == 0) {
5635 // Fast version of the dispatch loop without checking whether the simulator
5636 // should be stopping at a particular executed instruction.
5637 while (program_counter != end_sim_pc) {
5638 Instruction* instr = reinterpret_cast<Instruction*>(program_counter);
Ben Murdochda12d292016-06-02 14:46:10 +01005639 ExecuteInstruction(instr);
5640 program_counter = get_pc();
5641 }
5642 } else {
5643 // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when
5644 // we reach the particular instuction count.
5645 while (program_counter != end_sim_pc) {
5646 Instruction* instr = reinterpret_cast<Instruction*>(program_counter);
Ben Murdochda12d292016-06-02 14:46:10 +01005647 if (icount_ == ::v8::internal::FLAG_stop_sim_at) {
5648 S390Debugger dbg(this);
5649 dbg.Debug();
5650 } else {
5651 ExecuteInstruction(instr);
5652 }
5653 program_counter = get_pc();
5654 }
5655 }
5656}
5657
5658void Simulator::CallInternal(byte* entry, int reg_arg_count) {
Ben Murdoch61f157c2016-09-16 13:49:30 +01005659 // Adjust JS-based stack limit to C-based stack limit.
5660 isolate_->stack_guard()->AdjustStackLimitForSimulator();
5661
Ben Murdochda12d292016-06-02 14:46:10 +01005662 // Prepare to execute the code at entry
5663 if (ABI_USES_FUNCTION_DESCRIPTORS) {
5664 // entry is the function descriptor
5665 set_pc(*(reinterpret_cast<intptr_t*>(entry)));
5666 } else {
5667 // entry is the instruction address
5668 set_pc(reinterpret_cast<intptr_t>(entry));
5669 }
5670 // Remember the values of non-volatile registers.
5671 int64_t r6_val = get_register(r6);
5672 int64_t r7_val = get_register(r7);
5673 int64_t r8_val = get_register(r8);
5674 int64_t r9_val = get_register(r9);
5675 int64_t r10_val = get_register(r10);
5676 int64_t r11_val = get_register(r11);
5677 int64_t r12_val = get_register(r12);
5678 int64_t r13_val = get_register(r13);
5679
5680 if (ABI_CALL_VIA_IP) {
5681 // Put target address in ip (for JS prologue).
5682 set_register(ip, get_pc());
5683 }
5684
5685 // Put down marker for end of simulation. The simulator will stop simulation
5686 // when the PC reaches this value. By saving the "end simulation" value into
5687 // the LR the simulation stops when returning to this call point.
5688 registers_[14] = end_sim_pc;
5689
5690 // Set up the non-volatile registers with a known value. To be able to check
5691 // that they are preserved properly across JS execution.
5692 intptr_t callee_saved_value = icount_;
5693 if (reg_arg_count < 5) {
5694 set_register(r6, callee_saved_value + 6);
5695 }
5696 set_register(r7, callee_saved_value + 7);
5697 set_register(r8, callee_saved_value + 8);
5698 set_register(r9, callee_saved_value + 9);
5699 set_register(r10, callee_saved_value + 10);
5700 set_register(r11, callee_saved_value + 11);
5701 set_register(r12, callee_saved_value + 12);
5702 set_register(r13, callee_saved_value + 13);
5703
5704 // Start the simulation
5705 Execute();
5706
5707// Check that the non-volatile registers have been preserved.
5708#ifndef V8_TARGET_ARCH_S390X
5709 if (reg_arg_count < 5) {
5710 DCHECK_EQ(callee_saved_value + 6, get_low_register<int32_t>(r6));
5711 }
5712 DCHECK_EQ(callee_saved_value + 7, get_low_register<int32_t>(r7));
5713 DCHECK_EQ(callee_saved_value + 8, get_low_register<int32_t>(r8));
5714 DCHECK_EQ(callee_saved_value + 9, get_low_register<int32_t>(r9));
5715 DCHECK_EQ(callee_saved_value + 10, get_low_register<int32_t>(r10));
5716 DCHECK_EQ(callee_saved_value + 11, get_low_register<int32_t>(r11));
5717 DCHECK_EQ(callee_saved_value + 12, get_low_register<int32_t>(r12));
5718 DCHECK_EQ(callee_saved_value + 13, get_low_register<int32_t>(r13));
5719#else
5720 if (reg_arg_count < 5) {
5721 DCHECK_EQ(callee_saved_value + 6, get_register(r6));
5722 }
5723 DCHECK_EQ(callee_saved_value + 7, get_register(r7));
5724 DCHECK_EQ(callee_saved_value + 8, get_register(r8));
5725 DCHECK_EQ(callee_saved_value + 9, get_register(r9));
5726 DCHECK_EQ(callee_saved_value + 10, get_register(r10));
5727 DCHECK_EQ(callee_saved_value + 11, get_register(r11));
5728 DCHECK_EQ(callee_saved_value + 12, get_register(r12));
5729 DCHECK_EQ(callee_saved_value + 13, get_register(r13));
5730#endif
5731
5732 // Restore non-volatile registers with the original value.
5733 set_register(r6, r6_val);
5734 set_register(r7, r7_val);
5735 set_register(r8, r8_val);
5736 set_register(r9, r9_val);
5737 set_register(r10, r10_val);
5738 set_register(r11, r11_val);
5739 set_register(r12, r12_val);
5740 set_register(r13, r13_val);
5741}
5742
5743intptr_t Simulator::Call(byte* entry, int argument_count, ...) {
Ben Murdoch61f157c2016-09-16 13:49:30 +01005744 // Adjust JS-based stack limit to C-based stack limit.
5745 isolate_->stack_guard()->AdjustStackLimitForSimulator();
5746
Ben Murdochda12d292016-06-02 14:46:10 +01005747 // Remember the values of non-volatile registers.
5748 int64_t r6_val = get_register(r6);
5749 int64_t r7_val = get_register(r7);
5750 int64_t r8_val = get_register(r8);
5751 int64_t r9_val = get_register(r9);
5752 int64_t r10_val = get_register(r10);
5753 int64_t r11_val = get_register(r11);
5754 int64_t r12_val = get_register(r12);
5755 int64_t r13_val = get_register(r13);
5756
5757 va_list parameters;
5758 va_start(parameters, argument_count);
5759 // Set up arguments
5760
5761 // First 5 arguments passed in registers r2-r6.
5762 int reg_arg_count = (argument_count > 5) ? 5 : argument_count;
5763 int stack_arg_count = argument_count - reg_arg_count;
5764 for (int i = 0; i < reg_arg_count; i++) {
5765 intptr_t value = va_arg(parameters, intptr_t);
5766 set_register(i + 2, value);
5767 }
5768
5769 // Remaining arguments passed on stack.
5770 int64_t original_stack = get_register(sp);
5771 // Compute position of stack on entry to generated code.
5772 intptr_t entry_stack =
5773 (original_stack -
5774 (kCalleeRegisterSaveAreaSize + stack_arg_count * sizeof(intptr_t)));
5775 if (base::OS::ActivationFrameAlignment() != 0) {
5776 entry_stack &= -base::OS::ActivationFrameAlignment();
5777 }
5778
5779 // Store remaining arguments on stack, from low to high memory.
5780 intptr_t* stack_argument =
5781 reinterpret_cast<intptr_t*>(entry_stack + kCalleeRegisterSaveAreaSize);
5782 for (int i = 0; i < stack_arg_count; i++) {
5783 intptr_t value = va_arg(parameters, intptr_t);
5784 stack_argument[i] = value;
5785 }
5786 va_end(parameters);
5787 set_register(sp, entry_stack);
5788
5789// Prepare to execute the code at entry
5790#if ABI_USES_FUNCTION_DESCRIPTORS
5791 // entry is the function descriptor
5792 set_pc(*(reinterpret_cast<intptr_t*>(entry)));
5793#else
5794 // entry is the instruction address
5795 set_pc(reinterpret_cast<intptr_t>(entry));
5796#endif
5797
5798 // Put target address in ip (for JS prologue).
5799 set_register(r12, get_pc());
5800
5801 // Put down marker for end of simulation. The simulator will stop simulation
5802 // when the PC reaches this value. By saving the "end simulation" value into
5803 // the LR the simulation stops when returning to this call point.
5804 registers_[14] = end_sim_pc;
5805
5806 // Set up the non-volatile registers with a known value. To be able to check
5807 // that they are preserved properly across JS execution.
5808 intptr_t callee_saved_value = icount_;
5809 if (reg_arg_count < 5) {
5810 set_register(r6, callee_saved_value + 6);
5811 }
5812 set_register(r7, callee_saved_value + 7);
5813 set_register(r8, callee_saved_value + 8);
5814 set_register(r9, callee_saved_value + 9);
5815 set_register(r10, callee_saved_value + 10);
5816 set_register(r11, callee_saved_value + 11);
5817 set_register(r12, callee_saved_value + 12);
5818 set_register(r13, callee_saved_value + 13);
5819
5820 // Start the simulation
5821 Execute();
5822
5823// Check that the non-volatile registers have been preserved.
5824#ifndef V8_TARGET_ARCH_S390X
5825 if (reg_arg_count < 5) {
5826 DCHECK_EQ(callee_saved_value + 6, get_low_register<int32_t>(r6));
5827 }
5828 DCHECK_EQ(callee_saved_value + 7, get_low_register<int32_t>(r7));
5829 DCHECK_EQ(callee_saved_value + 8, get_low_register<int32_t>(r8));
5830 DCHECK_EQ(callee_saved_value + 9, get_low_register<int32_t>(r9));
5831 DCHECK_EQ(callee_saved_value + 10, get_low_register<int32_t>(r10));
5832 DCHECK_EQ(callee_saved_value + 11, get_low_register<int32_t>(r11));
5833 DCHECK_EQ(callee_saved_value + 12, get_low_register<int32_t>(r12));
5834 DCHECK_EQ(callee_saved_value + 13, get_low_register<int32_t>(r13));
5835#else
5836 if (reg_arg_count < 5) {
5837 DCHECK_EQ(callee_saved_value + 6, get_register(r6));
5838 }
5839 DCHECK_EQ(callee_saved_value + 7, get_register(r7));
5840 DCHECK_EQ(callee_saved_value + 8, get_register(r8));
5841 DCHECK_EQ(callee_saved_value + 9, get_register(r9));
5842 DCHECK_EQ(callee_saved_value + 10, get_register(r10));
5843 DCHECK_EQ(callee_saved_value + 11, get_register(r11));
5844 DCHECK_EQ(callee_saved_value + 12, get_register(r12));
5845 DCHECK_EQ(callee_saved_value + 13, get_register(r13));
5846#endif
5847
5848 // Restore non-volatile registers with the original value.
5849 set_register(r6, r6_val);
5850 set_register(r7, r7_val);
5851 set_register(r8, r8_val);
5852 set_register(r9, r9_val);
5853 set_register(r10, r10_val);
5854 set_register(r11, r11_val);
5855 set_register(r12, r12_val);
5856 set_register(r13, r13_val);
5857// Pop stack passed arguments.
5858
5859#ifndef V8_TARGET_ARCH_S390X
5860 DCHECK_EQ(entry_stack, get_low_register<int32_t>(sp));
5861#else
5862 DCHECK_EQ(entry_stack, get_register(sp));
5863#endif
5864 set_register(sp, original_stack);
5865
5866 // Return value register
5867 intptr_t result = get_register(r2);
5868 return result;
5869}
5870
5871void Simulator::CallFP(byte* entry, double d0, double d1) {
5872 set_d_register_from_double(0, d0);
5873 set_d_register_from_double(1, d1);
5874 CallInternal(entry);
5875}
5876
5877int32_t Simulator::CallFPReturnsInt(byte* entry, double d0, double d1) {
5878 CallFP(entry, d0, d1);
5879 int32_t result = get_register(r2);
5880 return result;
5881}
5882
5883double Simulator::CallFPReturnsDouble(byte* entry, double d0, double d1) {
5884 CallFP(entry, d0, d1);
5885 return get_double_from_d_register(0);
5886}
5887
5888uintptr_t Simulator::PushAddress(uintptr_t address) {
5889 uintptr_t new_sp = get_register(sp) - sizeof(uintptr_t);
5890 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(new_sp);
5891 *stack_slot = address;
5892 set_register(sp, new_sp);
5893 return new_sp;
5894}
5895
5896uintptr_t Simulator::PopAddress() {
5897 uintptr_t current_sp = get_register(sp);
5898 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp);
5899 uintptr_t address = *stack_slot;
5900 set_register(sp, current_sp + sizeof(uintptr_t));
5901 return address;
5902}
5903
Ben Murdochc5610432016-08-08 18:44:38 +01005904#define EVALUATE(name) \
5905 int Simulator::Evaluate_##name(Instruction* instr)
5906
5907#define DCHECK_OPCODE(op) DCHECK(instr->S390OpcodeValue() == op)
5908
5909#define AS(type) reinterpret_cast<type*>(instr)
5910
5911#define DECODE_RIL_A_INSTRUCTION(r1, i2) \
5912 int r1 = AS(RILInstruction)->R1Value(); \
5913 uint32_t i2 = AS(RILInstruction)->I2UnsignedValue(); \
5914 int length = 6;
5915
5916#define DECODE_RIL_B_INSTRUCTION(r1, i2) \
5917 int r1 = AS(RILInstruction)->R1Value(); \
5918 int32_t i2 = AS(RILInstruction)->I2Value(); \
5919 int length = 6;
5920
5921#define DECODE_RIL_C_INSTRUCTION(m1, ri2) \
5922 Condition m1 = static_cast<Condition>(AS(RILInstruction)->R1Value()); \
5923 uint64_t ri2 = AS(RILInstruction)->I2Value(); \
5924 int length = 6;
5925
5926#define DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2) \
5927 int r1 = AS(RXYInstruction)->R1Value(); \
5928 int x2 = AS(RXYInstruction)->X2Value(); \
5929 int b2 = AS(RXYInstruction)->B2Value(); \
5930 int d2 = AS(RXYInstruction)->D2Value(); \
5931 int length = 6;
5932
5933#define DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val) \
5934 int x2 = AS(RXInstruction)->X2Value(); \
5935 int b2 = AS(RXInstruction)->B2Value(); \
5936 int r1 = AS(RXInstruction)->R1Value(); \
5937 intptr_t d2_val = AS(RXInstruction)->D2Value(); \
5938 int length = 4;
5939
5940#define DECODE_RS_A_INSTRUCTION(r1, r3, b2, d2) \
5941 int r3 = AS(RSInstruction)->R3Value(); \
5942 int b2 = AS(RSInstruction)->B2Value(); \
5943 int r1 = AS(RSInstruction)->R1Value(); \
5944 intptr_t d2 = AS(RSInstruction)->D2Value(); \
5945 int length = 4;
5946
5947#define DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2) \
5948 int b2 = AS(RSInstruction)->B2Value(); \
5949 int r1 = AS(RSInstruction)->R1Value(); \
5950 int d2 = AS(RSInstruction)->D2Value(); \
5951 int length = 4;
5952
5953#define DECODE_SI_INSTRUCTION_I_UINT8(b1, d1_val, imm_val) \
5954 int b1 = AS(SIInstruction)->B1Value(); \
5955 intptr_t d1_val = AS(SIInstruction)->D1Value(); \
5956 uint8_t imm_val = AS(SIInstruction)->I2Value(); \
5957 int length = 4;
5958
Ben Murdoch61f157c2016-09-16 13:49:30 +01005959#define DECODE_SIL_INSTRUCTION(b1, d1, i2) \
5960 int b1 = AS(SILInstruction)->B1Value(); \
5961 intptr_t d1 = AS(SILInstruction)->D1Value(); \
5962 int16_t i2 = AS(SILInstruction)->I2Value(); \
5963 int length = 6;
5964
5965#define DECODE_SIY_INSTRUCTION(b1, d1, i2) \
5966 int b1 = AS(SIYInstruction)->B1Value(); \
5967 intptr_t d1 = AS(SIYInstruction)->D1Value(); \
5968 uint8_t i2 = AS(SIYInstruction)->I2Value(); \
5969 int length = 6;
5970
Ben Murdochc5610432016-08-08 18:44:38 +01005971#define DECODE_RRE_INSTRUCTION(r1, r2) \
5972 int r1 = AS(RREInstruction)->R1Value(); \
5973 int r2 = AS(RREInstruction)->R2Value(); \
5974 int length = 4;
5975
Ben Murdoch61f157c2016-09-16 13:49:30 +01005976#define DECODE_RRE_INSTRUCTION_M3(r1, r2, m3) \
5977 int r1 = AS(RREInstruction)->R1Value(); \
5978 int r2 = AS(RREInstruction)->R2Value(); \
5979 int m3 = AS(RREInstruction)->M3Value(); \
5980 int length = 4;
5981
5982#define DECODE_RRE_INSTRUCTION_NO_R2(r1) \
5983 int r1 = AS(RREInstruction)->R1Value(); \
5984 int length = 4;
5985
5986#define DECODE_RRD_INSTRUCTION(r1, r2, r3) \
5987 int r1 = AS(RRDInstruction)->R1Value(); \
5988 int r2 = AS(RRDInstruction)->R2Value(); \
5989 int r3 = AS(RRDInstruction)->R3Value(); \
5990 int length = 4;
5991
5992#define DECODE_RRF_E_INSTRUCTION(r1, r2, m3, m4) \
5993 int r1 = AS(RRFInstruction)->R1Value(); \
5994 int r2 = AS(RRFInstruction)->R2Value(); \
5995 int m3 = AS(RRFInstruction)->M3Value(); \
5996 int m4 = AS(RRFInstruction)->M4Value(); \
5997 int length = 4;
5998
5999#define DECODE_RRF_A_INSTRUCTION(r1, r2, r3) \
6000 int r1 = AS(RRFInstruction)->R1Value(); \
6001 int r2 = AS(RRFInstruction)->R2Value(); \
6002 int r3 = AS(RRFInstruction)->R3Value(); \
6003 int length = 4;
6004
Ben Murdochc5610432016-08-08 18:44:38 +01006005#define DECODE_RR_INSTRUCTION(r1, r2) \
6006 int r1 = AS(RRInstruction)->R1Value(); \
6007 int r2 = AS(RRInstruction)->R2Value(); \
6008 int length = 2;
6009
6010#define DECODE_RIE_D_INSTRUCTION(r1, r2, i2) \
6011 int r1 = AS(RIEInstruction)->R1Value(); \
6012 int r2 = AS(RIEInstruction)->R2Value(); \
6013 int32_t i2 = AS(RIEInstruction)->I6Value(); \
6014 int length = 6;
6015
6016#define DECODE_RIE_F_INSTRUCTION(r1, r2, i3, i4, i5) \
6017 int r1 = AS(RIEInstruction)->R1Value(); \
6018 int r2 = AS(RIEInstruction)->R2Value(); \
6019 uint32_t i3 = AS(RIEInstruction)->I3Value(); \
6020 uint32_t i4 = AS(RIEInstruction)->I4Value(); \
6021 uint32_t i5 = AS(RIEInstruction)->I5Value(); \
6022 int length = 6;
6023
6024#define DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2) \
6025 int r1 = AS(RSYInstruction)->R1Value(); \
6026 int r3 = AS(RSYInstruction)->R3Value(); \
6027 int b2 = AS(RSYInstruction)->B2Value(); \
6028 intptr_t d2 = AS(RSYInstruction)->D2Value(); \
6029 int length = 6;
6030
6031#define DECODE_RI_A_INSTRUCTION(instr, r1, i2) \
6032 int32_t r1 = AS(RIInstruction)->R1Value(); \
6033 int16_t i2 = AS(RIInstruction)->I2Value(); \
6034 int length = 4;
6035
6036#define DECODE_RI_B_INSTRUCTION(instr, r1, i2) \
6037 int32_t r1 = AS(RILInstruction)->R1Value(); \
6038 int16_t i2 = AS(RILInstruction)->I2Value(); \
6039 int length = 4;
6040
6041#define DECODE_RI_C_INSTRUCTION(instr, m1, i2) \
6042 Condition m1 = static_cast<Condition>(AS(RIInstruction)->R1Value()); \
6043 int16_t i2 = AS(RIInstruction)->I2Value(); \
6044 int length = 4;
6045
Ben Murdoch61f157c2016-09-16 13:49:30 +01006046#define DECODE_RXE_INSTRUCTION(r1, b2, x2, d2) \
6047 int r1 = AS(RXEInstruction)->R1Value(); \
6048 int b2 = AS(RXEInstruction)->B2Value(); \
6049 int x2 = AS(RXEInstruction)->X2Value(); \
6050 int d2 = AS(RXEInstruction)->D2Value(); \
6051 int length = 6;
6052
Ben Murdochc5610432016-08-08 18:44:38 +01006053#define GET_ADDRESS(index_reg, base_reg, offset) \
6054 (((index_reg) == 0) ? 0 : get_register(index_reg)) + \
6055 (((base_reg) == 0) ? 0 : get_register(base_reg)) + offset
6056
6057int Simulator::Evaluate_Unknown(Instruction* instr) {
6058 UNREACHABLE();
6059 return 0;
6060}
6061
6062EVALUATE(CLR) {
6063 DCHECK_OPCODE(CLR);
6064 DECODE_RR_INSTRUCTION(r1, r2);
6065 uint32_t r1_val = get_low_register<uint32_t>(r1);
6066 uint32_t r2_val = get_low_register<uint32_t>(r2);
6067 SetS390ConditionCode<uint32_t>(r1_val, r2_val);
6068 return length;
6069}
6070
6071EVALUATE(LR) {
6072 DCHECK_OPCODE(LR);
6073 DECODE_RR_INSTRUCTION(r1, r2);
6074 set_low_register(r1, get_low_register<int32_t>(r2));
6075 return length;
6076}
6077
6078EVALUATE(AR) {
6079 DCHECK_OPCODE(AR);
6080 DECODE_RR_INSTRUCTION(r1, r2);
6081 int32_t r1_val = get_low_register<int32_t>(r1);
6082 int32_t r2_val = get_low_register<int32_t>(r2);
6083 bool isOF = CheckOverflowForIntAdd(r1_val, r2_val, int32_t);
6084 r1_val += r2_val;
6085 SetS390ConditionCode<int32_t>(r1_val, 0);
6086 SetS390OverflowCode(isOF);
6087 set_low_register(r1, r1_val);
6088 return length;
6089}
6090
6091EVALUATE(L) {
6092 DCHECK_OPCODE(L);
6093 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6094 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6095 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6096 intptr_t addr = b2_val + x2_val + d2_val;
6097 int32_t mem_val = ReadW(addr, instr);
6098 set_low_register(r1, mem_val);
6099 return length;
6100}
6101
6102EVALUATE(BRC) {
6103 DCHECK_OPCODE(BRC);
6104 DECODE_RI_C_INSTRUCTION(instr, m1, i2);
6105
6106 if (TestConditionCode(m1)) {
6107 intptr_t offset = 2 * i2;
6108 set_pc(get_pc() + offset);
6109 }
6110 return length;
6111}
6112
6113EVALUATE(AHI) {
6114 DCHECK_OPCODE(AHI);
6115 DECODE_RI_A_INSTRUCTION(instr, r1, i2);
6116 int32_t r1_val = get_low_register<int32_t>(r1);
6117 bool isOF = CheckOverflowForIntAdd(r1_val, i2, int32_t);
6118 r1_val += i2;
6119 set_low_register(r1, r1_val);
6120 SetS390ConditionCode<int32_t>(r1_val, 0);
6121 SetS390OverflowCode(isOF);
6122 return length;
6123}
6124
6125EVALUATE(AGHI) {
6126 DCHECK_OPCODE(AGHI);
6127 DECODE_RI_A_INSTRUCTION(instr, r1, i2);
6128 int64_t r1_val = get_register(r1);
6129 bool isOF = false;
6130 isOF = CheckOverflowForIntAdd(r1_val, i2, int64_t);
6131 r1_val += i2;
6132 set_register(r1, r1_val);
6133 SetS390ConditionCode<int64_t>(r1_val, 0);
6134 SetS390OverflowCode(isOF);
6135 return length;
6136}
6137
6138EVALUATE(BRCL) {
6139 DCHECK_OPCODE(BRCL);
6140 DECODE_RIL_C_INSTRUCTION(m1, ri2);
6141
6142 if (TestConditionCode(m1)) {
6143 intptr_t offset = 2 * ri2;
6144 set_pc(get_pc() + offset);
6145 }
6146 return length;
6147}
6148
6149EVALUATE(IIHF) {
6150 DCHECK_OPCODE(IIHF);
6151 DECODE_RIL_A_INSTRUCTION(r1, imm);
6152 set_high_register(r1, imm);
6153 return length;
6154}
6155
6156EVALUATE(IILF) {
6157 DCHECK_OPCODE(IILF);
6158 DECODE_RIL_A_INSTRUCTION(r1, imm);
6159 set_low_register(r1, imm);
6160 return length;
6161}
6162
6163EVALUATE(LGR) {
6164 DCHECK_OPCODE(LGR);
6165 DECODE_RRE_INSTRUCTION(r1, r2);
6166 set_register(r1, get_register(r2));
6167 return length;
6168}
6169
6170EVALUATE(LG) {
6171 DCHECK_OPCODE(LG);
6172 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
6173 intptr_t addr = GET_ADDRESS(x2, b2, d2);
6174 int64_t mem_val = ReadDW(addr);
6175 set_register(r1, mem_val);
6176 return length;
6177}
6178
6179EVALUATE(AGR) {
6180 DCHECK_OPCODE(AGR);
6181 DECODE_RRE_INSTRUCTION(r1, r2);
6182 int64_t r1_val = get_register(r1);
6183 int64_t r2_val = get_register(r2);
6184 bool isOF = CheckOverflowForIntAdd(r1_val, r2_val, int64_t);
6185 r1_val += r2_val;
6186 set_register(r1, r1_val);
6187 SetS390ConditionCode<int64_t>(r1_val, 0);
6188 SetS390OverflowCode(isOF);
6189 return length;
6190}
6191
6192EVALUATE(LGFR) {
6193 DCHECK_OPCODE(LGFR);
6194 DECODE_RRE_INSTRUCTION(r1, r2);
6195 int32_t r2_val = get_low_register<int32_t>(r2);
6196 int64_t result = static_cast<int64_t>(r2_val);
6197 set_register(r1, result);
6198
6199 return length;
6200}
6201
6202EVALUATE(LBR) {
6203 DCHECK_OPCODE(LBR);
6204 DECODE_RRE_INSTRUCTION(r1, r2);
6205 int32_t r2_val = get_low_register<int32_t>(r2);
6206 r2_val <<= 24;
6207 r2_val >>= 24;
6208 set_low_register(r1, r2_val);
6209 return length;
6210}
6211
6212EVALUATE(LGBR) {
6213 DCHECK_OPCODE(LGBR);
6214 DECODE_RRE_INSTRUCTION(r1, r2);
6215 int64_t r2_val = get_low_register<int64_t>(r2);
6216 r2_val <<= 56;
6217 r2_val >>= 56;
6218 set_register(r1, r2_val);
6219 return length;
6220}
6221
6222EVALUATE(LHR) {
6223 DCHECK_OPCODE(LHR);
6224 DECODE_RRE_INSTRUCTION(r1, r2);
6225 int32_t r2_val = get_low_register<int32_t>(r2);
6226 r2_val <<= 16;
6227 r2_val >>= 16;
6228 set_low_register(r1, r2_val);
6229 return length;
6230}
6231
6232EVALUATE(LGHR) {
6233 DCHECK_OPCODE(LGHR);
6234 DECODE_RRE_INSTRUCTION(r1, r2);
6235 int64_t r2_val = get_low_register<int64_t>(r2);
6236 r2_val <<= 48;
6237 r2_val >>= 48;
6238 set_register(r1, r2_val);
6239 return length;
6240}
6241
6242EVALUATE(LGF) {
6243 DCHECK_OPCODE(LGF);
6244 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
6245 intptr_t addr = GET_ADDRESS(x2, b2, d2);
6246 int64_t mem_val = static_cast<int64_t>(ReadW(addr, instr));
6247 set_register(r1, mem_val);
6248 return length;
6249}
6250
6251EVALUATE(ST) {
6252 DCHECK_OPCODE(ST);
6253 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6254 int32_t r1_val = get_low_register<int32_t>(r1);
6255 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6256 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6257 intptr_t addr = b2_val + x2_val + d2_val;
6258 WriteW(addr, r1_val, instr);
6259 return length;
6260}
6261
6262EVALUATE(STG) {
6263 DCHECK_OPCODE(STG);
6264 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
6265 intptr_t addr = GET_ADDRESS(x2, b2, d2);
6266 uint64_t value = get_register(r1);
6267 WriteDW(addr, value);
6268 return length;
6269}
6270
6271EVALUATE(STY) {
6272 DCHECK_OPCODE(STY);
6273 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
6274 intptr_t addr = GET_ADDRESS(x2, b2, d2);
6275 uint32_t value = get_low_register<uint32_t>(r1);
6276 WriteW(addr, value, instr);
6277 return length;
6278}
6279
6280EVALUATE(LY) {
6281 DCHECK_OPCODE(LY);
6282 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
6283 intptr_t addr = GET_ADDRESS(x2, b2, d2);
6284 uint32_t mem_val = ReadWU(addr, instr);
6285 set_low_register(r1, mem_val);
6286 return length;
6287}
6288
6289EVALUATE(LLGC) {
6290 DCHECK_OPCODE(LLGC);
6291 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
6292 uint8_t mem_val = ReadBU(GET_ADDRESS(x2, b2, d2));
6293 set_register(r1, static_cast<uint64_t>(mem_val));
6294 return length;
6295}
6296
6297EVALUATE(LLC) {
6298 DCHECK_OPCODE(LLC);
6299 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
6300 uint8_t mem_val = ReadBU(GET_ADDRESS(x2, b2, d2));
6301 set_low_register(r1, static_cast<uint32_t>(mem_val));
6302 return length;
6303}
6304
6305EVALUATE(RLL) {
6306 DCHECK_OPCODE(RLL);
6307 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
6308 // only takes rightmost 6 bits
6309 int shiftBits = GET_ADDRESS(0, b2, d2) & 0x3F;
6310 // unsigned
6311 uint32_t r3_val = get_low_register<uint32_t>(r3);
6312 uint32_t alu_out = 0;
6313 uint32_t rotateBits = r3_val >> (32 - shiftBits);
6314 alu_out = (r3_val << shiftBits) | (rotateBits);
6315 set_low_register(r1, alu_out);
6316 return length;
6317}
6318
6319EVALUATE(RISBG) {
6320 DCHECK_OPCODE(RISBG);
6321 DECODE_RIE_F_INSTRUCTION(r1, r2, i3, i4, i5);
6322 // Starting Bit Position is Bits 2-7 of I3 field
6323 uint32_t start_bit = i3 & 0x3F;
6324 // Ending Bit Position is Bits 2-7 of I4 field
6325 uint32_t end_bit = i4 & 0x3F;
6326 // Shift Amount is Bits 2-7 of I5 field
6327 uint32_t shift_amount = i5 & 0x3F;
6328 // Zero out Remaining (unslected) bits if Bit 0 of I4 is 1.
6329 bool zero_remaining = (0 != (i4 & 0x80));
6330
6331 uint64_t src_val = get_register(r2);
6332
6333 // Rotate Left by Shift Amount first
6334 uint64_t rotated_val =
6335 (src_val << shift_amount) | (src_val >> (64 - shift_amount));
6336 int32_t width = end_bit - start_bit + 1;
6337
6338 uint64_t selection_mask = 0;
6339 if (width < 64) {
6340 selection_mask = (static_cast<uint64_t>(1) << width) - 1;
6341 } else {
6342 selection_mask = static_cast<uint64_t>(static_cast<int64_t>(-1));
6343 }
6344 selection_mask = selection_mask << (63 - end_bit);
6345
6346 uint64_t selected_val = rotated_val & selection_mask;
6347
6348 if (!zero_remaining) {
6349 // Merged the unselected bits from the original value
6350 selected_val = (src_val & ~selection_mask) | selected_val;
6351 }
6352
6353 // Condition code is set by treating result as 64-bit signed int
6354 SetS390ConditionCode<int64_t>(selected_val, 0);
6355 set_register(r1, selected_val);
6356 return length;
6357}
6358
6359EVALUATE(AHIK) {
6360 DCHECK_OPCODE(AHIK);
6361 DECODE_RIE_D_INSTRUCTION(r1, r2, i2);
6362 int32_t r2_val = get_low_register<int32_t>(r2);
6363 int32_t imm = static_cast<int32_t>(i2);
6364 bool isOF = CheckOverflowForIntAdd(r2_val, imm, int32_t);
6365 set_low_register(r1, r2_val + imm);
6366 SetS390ConditionCode<int32_t>(r2_val + imm, 0);
6367 SetS390OverflowCode(isOF);
6368 return length;
6369}
6370
6371EVALUATE(AGHIK) {
6372 // 64-bit Add
6373 DCHECK_OPCODE(AGHIK);
6374 DECODE_RIE_D_INSTRUCTION(r1, r2, i2);
6375 int64_t r2_val = get_register(r2);
6376 int64_t imm = static_cast<int64_t>(i2);
6377 bool isOF = CheckOverflowForIntAdd(r2_val, imm, int64_t);
6378 set_register(r1, r2_val + imm);
6379 SetS390ConditionCode<int64_t>(r2_val + imm, 0);
6380 SetS390OverflowCode(isOF);
6381 return length;
6382}
6383
6384EVALUATE(BKPT) {
6385 DCHECK_OPCODE(BKPT);
6386 set_pc(get_pc() + 2);
6387 S390Debugger dbg(this);
6388 dbg.Debug();
6389 int length = 2;
6390 return length;
6391}
6392
Ben Murdoch61f157c2016-09-16 13:49:30 +01006393EVALUATE(SPM) {
6394 UNIMPLEMENTED();
6395 USE(instr);
6396 return 0;
6397}
Ben Murdochc5610432016-08-08 18:44:38 +01006398
Ben Murdoch61f157c2016-09-16 13:49:30 +01006399EVALUATE(BALR) {
6400 UNIMPLEMENTED();
6401 USE(instr);
6402 return 0;
6403}
Ben Murdochc5610432016-08-08 18:44:38 +01006404
Ben Murdoch61f157c2016-09-16 13:49:30 +01006405EVALUATE(BCTR) {
6406 UNIMPLEMENTED();
6407 USE(instr);
6408 return 0;
6409}
Ben Murdochc5610432016-08-08 18:44:38 +01006410
6411EVALUATE(BCR) {
6412 DCHECK_OPCODE(BCR);
6413 DECODE_RR_INSTRUCTION(r1, r2);
6414 if (TestConditionCode(Condition(r1))) {
6415 intptr_t r2_val = get_register(r2);
6416#if (!V8_TARGET_ARCH_S390X && V8_HOST_ARCH_S390)
6417 // On 31-bit, the top most bit may be 0 or 1, but is ignored by the
6418 // hardware. Cleanse the top bit before jumping to it, unless it's one
6419 // of the special PCs
6420 if (r2_val != bad_lr && r2_val != end_sim_pc) r2_val &= 0x7FFFFFFF;
6421#endif
6422 set_pc(r2_val);
6423 }
6424
6425 return length;
6426}
6427
Ben Murdoch61f157c2016-09-16 13:49:30 +01006428EVALUATE(SVC) {
6429 UNIMPLEMENTED();
6430 USE(instr);
6431 return 0;
6432}
Ben Murdochc5610432016-08-08 18:44:38 +01006433
Ben Murdoch61f157c2016-09-16 13:49:30 +01006434EVALUATE(BSM) {
6435 UNIMPLEMENTED();
6436 USE(instr);
6437 return 0;
6438}
Ben Murdochc5610432016-08-08 18:44:38 +01006439
Ben Murdoch61f157c2016-09-16 13:49:30 +01006440EVALUATE(BASSM) {
6441 UNIMPLEMENTED();
6442 USE(instr);
6443 return 0;
6444}
Ben Murdochc5610432016-08-08 18:44:38 +01006445
6446EVALUATE(BASR) {
6447 DCHECK_OPCODE(BASR);
6448 DECODE_RR_INSTRUCTION(r1, r2);
6449 intptr_t link_addr = get_pc() + 2;
6450 // If R2 is zero, the BASR does not branch.
6451 int64_t r2_val = (r2 == 0) ? link_addr : get_register(r2);
6452#if (!V8_TARGET_ARCH_S390X && V8_HOST_ARCH_S390)
6453 // On 31-bit, the top most bit may be 0 or 1, which can cause issues
6454 // for stackwalker. The top bit should either be cleanse before being
6455 // pushed onto the stack, or during stack walking when dereferenced.
6456 // For simulator, we'll take the worst case scenario and always tag
6457 // the high bit, to flush out more problems.
6458 link_addr |= 0x80000000;
6459#endif
6460 set_register(r1, link_addr);
6461 set_pc(r2_val);
6462 return length;
6463}
6464
Ben Murdoch61f157c2016-09-16 13:49:30 +01006465EVALUATE(MVCL) {
6466 UNIMPLEMENTED();
6467 USE(instr);
6468 return 0;
6469}
Ben Murdochc5610432016-08-08 18:44:38 +01006470
Ben Murdoch61f157c2016-09-16 13:49:30 +01006471EVALUATE(CLCL) {
6472 UNIMPLEMENTED();
6473 USE(instr);
6474 return 0;
6475}
Ben Murdochc5610432016-08-08 18:44:38 +01006476
Ben Murdoch61f157c2016-09-16 13:49:30 +01006477EVALUATE(LPR) {
6478 UNIMPLEMENTED();
6479 USE(instr);
6480 return 0;
6481}
Ben Murdochc5610432016-08-08 18:44:38 +01006482
6483EVALUATE(LNR) {
6484 DCHECK_OPCODE(LNR);
6485 // Load Negative (32)
6486 DECODE_RR_INSTRUCTION(r1, r2);
6487 int32_t r2_val = get_low_register<int32_t>(r2);
6488 r2_val = (r2_val >= 0) ? -r2_val : r2_val; // If pos, then negate it.
6489 set_low_register(r1, r2_val);
6490 condition_reg_ = (r2_val == 0) ? CC_EQ : CC_LT; // CC0 - result is zero
6491 // CC1 - result is negative
6492 return length;
6493}
6494
6495EVALUATE(LTR) {
6496 DCHECK_OPCODE(LTR);
6497 DECODE_RR_INSTRUCTION(r1, r2);
6498 int32_t r2_val = get_low_register<int32_t>(r2);
6499 SetS390ConditionCode<int32_t>(r2_val, 0);
6500 set_low_register(r1, r2_val);
6501 return length;
6502}
6503
6504EVALUATE(LCR) {
6505 DCHECK_OPCODE(LCR);
6506 DECODE_RR_INSTRUCTION(r1, r2);
6507 int32_t r2_val = get_low_register<int32_t>(r2);
6508 int32_t original_r2_val = r2_val;
6509 r2_val = ~r2_val;
6510 r2_val = r2_val + 1;
6511 set_low_register(r1, r2_val);
6512 SetS390ConditionCode<int32_t>(r2_val, 0);
6513 // Checks for overflow where r2_val = -2147483648.
6514 // Cannot do int comparison due to GCC 4.8 bug on x86.
6515 // Detect INT_MIN alternatively, as it is the only value where both
6516 // original and result are negative due to overflow.
6517 if (r2_val < 0 && original_r2_val < 0) {
6518 SetS390OverflowCode(true);
6519 }
6520 return length;
6521}
6522
6523EVALUATE(NR) {
6524 DCHECK_OPCODE(NR);
6525 DECODE_RR_INSTRUCTION(r1, r2);
6526 int32_t r1_val = get_low_register<int32_t>(r1);
6527 int32_t r2_val = get_low_register<int32_t>(r2);
6528 r1_val &= r2_val;
6529 SetS390BitWiseConditionCode<uint32_t>(r1_val);
6530 set_low_register(r1, r1_val);
6531 return length;
6532}
6533
6534EVALUATE(OR) {
6535 DCHECK_OPCODE(OR);
6536 DECODE_RR_INSTRUCTION(r1, r2);
6537 int32_t r1_val = get_low_register<int32_t>(r1);
6538 int32_t r2_val = get_low_register<int32_t>(r2);
6539 r1_val |= r2_val;
6540 SetS390BitWiseConditionCode<uint32_t>(r1_val);
6541 set_low_register(r1, r1_val);
6542 return length;
6543}
6544
6545EVALUATE(XR) {
6546 DCHECK_OPCODE(XR);
6547 DECODE_RR_INSTRUCTION(r1, r2);
6548 int32_t r1_val = get_low_register<int32_t>(r1);
6549 int32_t r2_val = get_low_register<int32_t>(r2);
6550 r1_val ^= r2_val;
6551 SetS390BitWiseConditionCode<uint32_t>(r1_val);
6552 set_low_register(r1, r1_val);
6553 return length;
6554}
6555
6556EVALUATE(CR) {
6557 DCHECK_OPCODE(CR);
6558 DECODE_RR_INSTRUCTION(r1, r2);
6559 int32_t r1_val = get_low_register<int32_t>(r1);
6560 int32_t r2_val = get_low_register<int32_t>(r2);
6561 SetS390ConditionCode<int32_t>(r1_val, r2_val);
6562 return length;
6563}
6564
6565EVALUATE(SR) {
6566 DCHECK_OPCODE(SR);
6567 DECODE_RR_INSTRUCTION(r1, r2);
6568 int32_t r1_val = get_low_register<int32_t>(r1);
6569 int32_t r2_val = get_low_register<int32_t>(r2);
6570 bool isOF = false;
6571 isOF = CheckOverflowForIntSub(r1_val, r2_val, int32_t);
6572 r1_val -= r2_val;
6573 SetS390ConditionCode<int32_t>(r1_val, 0);
6574 SetS390OverflowCode(isOF);
6575 set_low_register(r1, r1_val);
6576 return length;
6577}
6578
6579EVALUATE(MR) {
6580 DCHECK_OPCODE(MR);
6581 DECODE_RR_INSTRUCTION(r1, r2);
6582 int32_t r1_val = get_low_register<int32_t>(r1);
6583 int32_t r2_val = get_low_register<int32_t>(r2);
6584 DCHECK(r1 % 2 == 0);
6585 r1_val = get_low_register<int32_t>(r1 + 1);
6586 int64_t product = static_cast<int64_t>(r1_val) * static_cast<int64_t>(r2_val);
6587 int32_t high_bits = product >> 32;
6588 r1_val = high_bits;
6589 int32_t low_bits = product & 0x00000000FFFFFFFF;
6590 set_low_register(r1, high_bits);
6591 set_low_register(r1 + 1, low_bits);
6592 set_low_register(r1, r1_val);
6593 return length;
6594}
6595
6596EVALUATE(DR) {
6597 DCHECK_OPCODE(DR);
6598 DECODE_RR_INSTRUCTION(r1, r2);
6599 int32_t r1_val = get_low_register<int32_t>(r1);
6600 int32_t r2_val = get_low_register<int32_t>(r2);
6601 // reg-reg pair should be even-odd pair, assert r1 is an even register
6602 DCHECK(r1 % 2 == 0);
6603 // leftmost 32 bits of the dividend are in r1
6604 // rightmost 32 bits of the dividend are in r1+1
6605 // get the signed value from r1
6606 int64_t dividend = static_cast<int64_t>(r1_val) << 32;
6607 // get unsigned value from r1+1
6608 // avoid addition with sign-extended r1+1 value
6609 dividend += get_low_register<uint32_t>(r1 + 1);
6610 int32_t remainder = dividend % r2_val;
6611 int32_t quotient = dividend / r2_val;
6612 r1_val = remainder;
6613 set_low_register(r1, remainder);
6614 set_low_register(r1 + 1, quotient);
6615 set_low_register(r1, r1_val);
6616 return length;
6617}
6618
6619EVALUATE(ALR) {
6620 DCHECK_OPCODE(ALR);
6621 DECODE_RR_INSTRUCTION(r1, r2);
6622 uint32_t r1_val = get_low_register<uint32_t>(r1);
6623 uint32_t r2_val = get_low_register<uint32_t>(r2);
6624 uint32_t alu_out = 0;
6625 bool isOF = false;
6626 alu_out = r1_val + r2_val;
6627 isOF = CheckOverflowForUIntAdd(r1_val, r2_val);
6628 set_low_register(r1, alu_out);
6629 SetS390ConditionCodeCarry<uint32_t>(alu_out, isOF);
6630 return length;
6631}
6632
6633EVALUATE(SLR) {
6634 DCHECK_OPCODE(SLR);
6635 DECODE_RR_INSTRUCTION(r1, r2);
6636 uint32_t r1_val = get_low_register<uint32_t>(r1);
6637 uint32_t r2_val = get_low_register<uint32_t>(r2);
6638 uint32_t alu_out = 0;
6639 bool isOF = false;
6640 alu_out = r1_val - r2_val;
6641 isOF = CheckOverflowForUIntSub(r1_val, r2_val);
6642 set_low_register(r1, alu_out);
6643 SetS390ConditionCodeCarry<uint32_t>(alu_out, isOF);
6644 return length;
6645}
6646
6647EVALUATE(LDR) {
6648 DCHECK_OPCODE(LDR);
6649 DECODE_RR_INSTRUCTION(r1, r2);
6650 int64_t r2_val = get_d_register(r2);
6651 set_d_register(r1, r2_val);
6652 return length;
6653}
6654
Ben Murdoch61f157c2016-09-16 13:49:30 +01006655EVALUATE(CDR) {
6656 UNIMPLEMENTED();
6657 USE(instr);
6658 return 0;
6659}
Ben Murdochc5610432016-08-08 18:44:38 +01006660
Ben Murdoch61f157c2016-09-16 13:49:30 +01006661EVALUATE(LER) {
6662 UNIMPLEMENTED();
6663 USE(instr);
6664 return 0;
6665}
Ben Murdochc5610432016-08-08 18:44:38 +01006666
6667EVALUATE(STH) {
6668 DCHECK_OPCODE(STH);
6669 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6670 int16_t r1_val = get_low_register<int32_t>(r1);
6671 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6672 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6673 intptr_t mem_addr = b2_val + x2_val + d2_val;
6674 WriteH(mem_addr, r1_val, instr);
6675
6676 return length;
6677}
6678
6679EVALUATE(LA) {
6680 DCHECK_OPCODE(LA);
6681 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6682 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6683 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6684 intptr_t addr = b2_val + x2_val + d2_val;
6685 set_register(r1, addr);
6686 return length;
6687}
6688
6689EVALUATE(STC) {
6690 DCHECK_OPCODE(STC);
6691 // Store Character/Byte
6692 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6693 uint8_t r1_val = get_low_register<int32_t>(r1);
6694 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6695 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6696 intptr_t mem_addr = b2_val + x2_val + d2_val;
6697 WriteB(mem_addr, r1_val);
6698 return length;
6699}
6700
Ben Murdoch61f157c2016-09-16 13:49:30 +01006701EVALUATE(IC_z) {
6702 UNIMPLEMENTED();
6703 USE(instr);
6704 return 0;
6705}
Ben Murdochc5610432016-08-08 18:44:38 +01006706
6707EVALUATE(EX) {
6708 DCHECK_OPCODE(EX);
6709 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6710 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6711 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6712 int32_t r1_val = get_low_register<int32_t>(r1);
6713
6714 SixByteInstr the_instr = Instruction::InstructionBits(
6715 reinterpret_cast<const byte*>(b2_val + x2_val + d2_val));
6716 int inst_length = Instruction::InstructionLength(
6717 reinterpret_cast<const byte*>(b2_val + x2_val + d2_val));
6718
6719 char new_instr_buf[8];
6720 char* addr = reinterpret_cast<char*>(&new_instr_buf[0]);
6721 the_instr |= static_cast<SixByteInstr>(r1_val & 0xff)
6722 << (8 * inst_length - 16);
6723 Instruction::SetInstructionBits<SixByteInstr>(
6724 reinterpret_cast<byte*>(addr), static_cast<SixByteInstr>(the_instr));
6725 ExecuteInstruction(reinterpret_cast<Instruction*>(addr), false);
6726 return length;
6727}
6728
Ben Murdoch61f157c2016-09-16 13:49:30 +01006729EVALUATE(BAL) {
6730 UNIMPLEMENTED();
6731 USE(instr);
6732 return 0;
6733}
Ben Murdochc5610432016-08-08 18:44:38 +01006734
Ben Murdoch61f157c2016-09-16 13:49:30 +01006735EVALUATE(BCT) {
6736 UNIMPLEMENTED();
6737 USE(instr);
6738 return 0;
6739}
Ben Murdochc5610432016-08-08 18:44:38 +01006740
Ben Murdoch61f157c2016-09-16 13:49:30 +01006741EVALUATE(BC) {
6742 UNIMPLEMENTED();
6743 USE(instr);
6744 return 0;
6745}
Ben Murdochc5610432016-08-08 18:44:38 +01006746
6747EVALUATE(LH) {
6748 DCHECK_OPCODE(LH);
6749 // Load Halfword
6750 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6751
6752 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6753 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6754 intptr_t mem_addr = x2_val + b2_val + d2_val;
6755
6756 int32_t result = static_cast<int32_t>(ReadH(mem_addr, instr));
6757 set_low_register(r1, result);
6758 return length;
6759}
6760
Ben Murdoch61f157c2016-09-16 13:49:30 +01006761EVALUATE(CH) {
6762 UNIMPLEMENTED();
6763 USE(instr);
6764 return 0;
6765}
Ben Murdochc5610432016-08-08 18:44:38 +01006766
6767EVALUATE(AH) {
6768 DCHECK_OPCODE(AH);
6769 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6770 int32_t r1_val = get_low_register<int32_t>(r1);
6771 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6772 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6773 intptr_t addr = b2_val + x2_val + d2_val;
6774 int32_t mem_val = static_cast<int32_t>(ReadH(addr, instr));
6775 int32_t alu_out = 0;
6776 bool isOF = false;
6777 isOF = CheckOverflowForIntAdd(r1_val, mem_val, int32_t);
6778 alu_out = r1_val + mem_val;
6779 set_low_register(r1, alu_out);
6780 SetS390ConditionCode<int32_t>(alu_out, 0);
6781 SetS390OverflowCode(isOF);
6782
6783 return length;
6784}
6785
6786EVALUATE(SH) {
6787 DCHECK_OPCODE(SH);
6788 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6789 int32_t r1_val = get_low_register<int32_t>(r1);
6790 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6791 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6792 intptr_t addr = b2_val + x2_val + d2_val;
6793 int32_t mem_val = static_cast<int32_t>(ReadH(addr, instr));
6794 int32_t alu_out = 0;
6795 bool isOF = false;
6796 isOF = CheckOverflowForIntSub(r1_val, mem_val, int32_t);
6797 alu_out = r1_val - mem_val;
6798 SetS390ConditionCode<int32_t>(alu_out, 0);
6799 SetS390OverflowCode(isOF);
6800
6801 return length;
6802}
6803
6804EVALUATE(MH) {
6805 DCHECK_OPCODE(MH);
6806 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6807 int32_t r1_val = get_low_register<int32_t>(r1);
6808 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6809 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6810 intptr_t addr = b2_val + x2_val + d2_val;
6811 int32_t mem_val = static_cast<int32_t>(ReadH(addr, instr));
6812 int32_t alu_out = 0;
6813 alu_out = r1_val * mem_val;
6814 set_low_register(r1, alu_out);
6815 return length;
6816}
6817
Ben Murdoch61f157c2016-09-16 13:49:30 +01006818EVALUATE(BAS) {
6819 UNIMPLEMENTED();
6820 USE(instr);
6821 return 0;
6822}
Ben Murdochc5610432016-08-08 18:44:38 +01006823
Ben Murdoch61f157c2016-09-16 13:49:30 +01006824EVALUATE(CVD) {
6825 UNIMPLEMENTED();
6826 USE(instr);
6827 return 0;
6828}
Ben Murdochc5610432016-08-08 18:44:38 +01006829
Ben Murdoch61f157c2016-09-16 13:49:30 +01006830EVALUATE(CVB) {
6831 UNIMPLEMENTED();
6832 USE(instr);
6833 return 0;
6834}
Ben Murdochc5610432016-08-08 18:44:38 +01006835
Ben Murdoch61f157c2016-09-16 13:49:30 +01006836EVALUATE(LAE) {
6837 UNIMPLEMENTED();
6838 USE(instr);
6839 return 0;
6840}
Ben Murdochc5610432016-08-08 18:44:38 +01006841
6842EVALUATE(N) {
6843 DCHECK_OPCODE(N);
6844 // 32-bit Reg-Mem instructions
6845 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6846 int32_t r1_val = get_low_register<int32_t>(r1);
6847 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6848 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6849 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr);
6850 int32_t alu_out = 0;
6851 alu_out = r1_val & mem_val;
6852 SetS390BitWiseConditionCode<uint32_t>(alu_out);
6853 set_low_register(r1, alu_out);
6854 return length;
6855}
6856
6857EVALUATE(CL) {
6858 DCHECK_OPCODE(CL);
6859 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6860 int32_t r1_val = get_low_register<int32_t>(r1);
6861 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6862 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6863 intptr_t addr = b2_val + x2_val + d2_val;
6864 int32_t mem_val = ReadW(addr, instr);
6865 SetS390ConditionCode<uint32_t>(r1_val, mem_val);
6866 return length;
6867}
6868
6869EVALUATE(O) {
6870 DCHECK_OPCODE(O);
6871 // 32-bit Reg-Mem instructions
6872 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6873 int32_t r1_val = get_low_register<int32_t>(r1);
6874 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6875 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6876 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr);
6877 int32_t alu_out = 0;
6878 alu_out = r1_val | mem_val;
6879 SetS390BitWiseConditionCode<uint32_t>(alu_out);
6880 set_low_register(r1, alu_out);
6881 return length;
6882}
6883
6884EVALUATE(X) {
6885 DCHECK_OPCODE(X);
6886 // 32-bit Reg-Mem instructions
6887 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6888 int32_t r1_val = get_low_register<int32_t>(r1);
6889 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6890 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6891 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr);
6892 int32_t alu_out = 0;
6893 alu_out = r1_val ^ mem_val;
6894 SetS390BitWiseConditionCode<uint32_t>(alu_out);
6895 set_low_register(r1, alu_out);
6896 return length;
6897}
6898
6899EVALUATE(C) {
6900 DCHECK_OPCODE(C);
6901 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6902 int32_t r1_val = get_low_register<int32_t>(r1);
6903 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6904 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6905 intptr_t addr = b2_val + x2_val + d2_val;
6906 int32_t mem_val = ReadW(addr, instr);
6907 SetS390ConditionCode<int32_t>(r1_val, mem_val);
6908 return length;
6909}
6910
6911EVALUATE(A) {
6912 DCHECK_OPCODE(A);
6913 // 32-bit Reg-Mem instructions
6914 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6915 int32_t r1_val = get_low_register<int32_t>(r1);
6916 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6917 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6918 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr);
6919 int32_t alu_out = 0;
6920 bool isOF = false;
6921 isOF = CheckOverflowForIntAdd(r1_val, mem_val, int32_t);
6922 alu_out = r1_val + mem_val;
6923 SetS390ConditionCode<int32_t>(alu_out, 0);
6924 SetS390OverflowCode(isOF);
6925 set_low_register(r1, alu_out);
6926 return length;
6927}
6928
6929EVALUATE(S) {
6930 DCHECK_OPCODE(S);
6931 // 32-bit Reg-Mem instructions
6932 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6933 int32_t r1_val = get_low_register<int32_t>(r1);
6934 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6935 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6936 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr);
6937 int32_t alu_out = 0;
6938 bool isOF = false;
6939 isOF = CheckOverflowForIntSub(r1_val, mem_val, int32_t);
6940 alu_out = r1_val - mem_val;
6941 SetS390ConditionCode<int32_t>(alu_out, 0);
6942 SetS390OverflowCode(isOF);
6943 set_low_register(r1, alu_out);
6944 return length;
6945}
6946
Ben Murdoch61f157c2016-09-16 13:49:30 +01006947EVALUATE(M) {
6948 UNIMPLEMENTED();
6949 USE(instr);
6950 return 0;
6951}
Ben Murdochc5610432016-08-08 18:44:38 +01006952
Ben Murdoch61f157c2016-09-16 13:49:30 +01006953EVALUATE(D) {
6954 UNIMPLEMENTED();
6955 USE(instr);
6956 return 0;
6957}
Ben Murdochc5610432016-08-08 18:44:38 +01006958
Ben Murdoch61f157c2016-09-16 13:49:30 +01006959EVALUATE(AL) {
6960 UNIMPLEMENTED();
6961 USE(instr);
6962 return 0;
6963}
Ben Murdochc5610432016-08-08 18:44:38 +01006964
Ben Murdoch61f157c2016-09-16 13:49:30 +01006965EVALUATE(SL) {
6966 UNIMPLEMENTED();
6967 USE(instr);
6968 return 0;
6969}
Ben Murdochc5610432016-08-08 18:44:38 +01006970
6971EVALUATE(STD) {
6972 DCHECK_OPCODE(STD);
6973 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6974 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6975 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6976 intptr_t addr = b2_val + x2_val + d2_val;
6977 int64_t frs_val = get_d_register(r1);
6978 WriteDW(addr, frs_val);
6979 return length;
6980}
6981
6982EVALUATE(LD) {
6983 DCHECK_OPCODE(LD);
6984 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
6985 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
6986 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
6987 intptr_t addr = b2_val + x2_val + d2_val;
6988 int64_t dbl_val = *reinterpret_cast<int64_t*>(addr);
6989 set_d_register(r1, dbl_val);
6990 return length;
6991}
6992
Ben Murdoch61f157c2016-09-16 13:49:30 +01006993EVALUATE(CD) {
6994 UNIMPLEMENTED();
6995 USE(instr);
6996 return 0;
6997}
Ben Murdochc5610432016-08-08 18:44:38 +01006998
6999EVALUATE(STE) {
7000 DCHECK_OPCODE(STE);
7001 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
7002 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
7003 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
7004 intptr_t addr = b2_val + x2_val + d2_val;
7005 int64_t frs_val = get_d_register(r1) >> 32;
7006 WriteW(addr, static_cast<int32_t>(frs_val), instr);
7007 return length;
7008}
7009
7010EVALUATE(MS) {
7011 DCHECK_OPCODE(MS);
7012 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
7013 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
7014 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
7015 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr);
7016 int32_t r1_val = get_low_register<int32_t>(r1);
7017 set_low_register(r1, r1_val * mem_val);
7018 return length;
7019}
7020
7021EVALUATE(LE) {
7022 DCHECK_OPCODE(LE);
7023 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val);
7024 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
7025 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
7026 intptr_t addr = b2_val + x2_val + d2_val;
7027 float float_val = *reinterpret_cast<float*>(addr);
7028 set_d_register_from_float32(r1, float_val);
7029 return length;
7030}
7031
Ben Murdoch61f157c2016-09-16 13:49:30 +01007032EVALUATE(BRXH) {
7033 UNIMPLEMENTED();
7034 USE(instr);
7035 return 0;
7036}
Ben Murdochc5610432016-08-08 18:44:38 +01007037
Ben Murdoch61f157c2016-09-16 13:49:30 +01007038EVALUATE(BRXLE) {
7039 UNIMPLEMENTED();
7040 USE(instr);
7041 return 0;
7042}
Ben Murdochc5610432016-08-08 18:44:38 +01007043
7044EVALUATE(BXH) {
7045 DCHECK_OPCODE(BXH);
7046 DECODE_RS_A_INSTRUCTION(r1, r3, b2, d2);
7047
7048 // r1_val is the first operand, r3_val is the increment
7049 int32_t r1_val = r1 == 0 ? 0 : get_register(r1);
7050 int32_t r3_val = r2 == 0 ? 0 : get_register(r3);
7051 intptr_t b2_val = b2 == 0 ? 0 : get_register(b2);
7052 intptr_t branch_address = b2_val + d2;
7053 // increment r1_val
7054 r1_val += r3_val;
7055
7056 // if the increment is even, then it designates a pair of registers
7057 // and the contents of the even and odd registers of the pair are used as
7058 // the increment and compare value respectively. If the increment is odd,
7059 // the increment itself is used as both the increment and compare value
7060 int32_t compare_val = r3 % 2 == 0 ? get_register(r3 + 1) : r3_val;
7061 if (r1_val > compare_val) {
7062 // branch to address if r1_val is greater than compare value
7063 set_pc(branch_address);
7064 }
7065
7066 // update contents of register in r1 with the new incremented value
7067 set_register(r1, r1_val);
7068
7069 return length;
7070}
7071
Ben Murdoch61f157c2016-09-16 13:49:30 +01007072EVALUATE(BXLE) {
7073 UNIMPLEMENTED();
7074 USE(instr);
7075 return 0;
7076}
Ben Murdochc5610432016-08-08 18:44:38 +01007077
7078EVALUATE(SRL) {
7079 DCHECK_OPCODE(SRL);
7080 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2);
7081 // only takes rightmost 6bits
7082 int64_t b2_val = b2 == 0 ? 0 : get_register(b2);
7083 int shiftBits = (b2_val + d2) & 0x3F;
7084 uint32_t r1_val = get_low_register<uint32_t>(r1);
7085 uint32_t alu_out = 0;
7086 alu_out = r1_val >> shiftBits;
7087 set_low_register(r1, alu_out);
7088 return length;
7089}
7090
7091EVALUATE(SLL) {
7092 DCHECK_OPCODE(SLL);
7093 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2)
7094 // only takes rightmost 6bits
7095 int64_t b2_val = b2 == 0 ? 0 : get_register(b2);
7096 int shiftBits = (b2_val + d2) & 0x3F;
7097 uint32_t r1_val = get_low_register<uint32_t>(r1);
7098 uint32_t alu_out = 0;
7099 alu_out = r1_val << shiftBits;
7100 set_low_register(r1, alu_out);
7101 return length;
7102}
7103
7104EVALUATE(SRA) {
7105 DCHECK_OPCODE(SRA);
7106 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2);
7107 // only takes rightmost 6bits
7108 int64_t b2_val = b2 == 0 ? 0 : get_register(b2);
7109 int shiftBits = (b2_val + d2) & 0x3F;
7110 int32_t r1_val = get_low_register<int32_t>(r1);
7111 int32_t alu_out = 0;
7112 bool isOF = false;
7113 alu_out = r1_val >> shiftBits;
7114 set_low_register(r1, alu_out);
7115 SetS390ConditionCode<int32_t>(alu_out, 0);
7116 SetS390OverflowCode(isOF);
7117 return length;
7118}
7119
7120EVALUATE(SLA) {
7121 DCHECK_OPCODE(SLA);
7122 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2);
7123 // only takes rightmost 6bits
7124 int64_t b2_val = b2 == 0 ? 0 : get_register(b2);
7125 int shiftBits = (b2_val + d2) & 0x3F;
7126 int32_t r1_val = get_low_register<int32_t>(r1);
7127 int32_t alu_out = 0;
7128 bool isOF = false;
7129 isOF = CheckOverflowForShiftLeft(r1_val, shiftBits);
7130 alu_out = r1_val << shiftBits;
7131 set_low_register(r1, alu_out);
7132 SetS390ConditionCode<int32_t>(alu_out, 0);
7133 SetS390OverflowCode(isOF);
7134 return length;
7135}
7136
7137EVALUATE(SRDL) {
7138 DCHECK_OPCODE(SRDL);
7139 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2);
7140 DCHECK(r1 % 2 == 0); // must be a reg pair
7141 // only takes rightmost 6bits
7142 int64_t b2_val = b2 == 0 ? 0 : get_register(b2);
7143 int shiftBits = (b2_val + d2) & 0x3F;
7144 uint64_t opnd1 = static_cast<uint64_t>(get_low_register<uint32_t>(r1)) << 32;
7145 uint64_t opnd2 = static_cast<uint64_t>(get_low_register<uint32_t>(r1 + 1));
7146 uint64_t r1_val = opnd1 | opnd2;
7147 uint64_t alu_out = r1_val >> shiftBits;
7148 set_low_register(r1, alu_out >> 32);
7149 set_low_register(r1 + 1, alu_out & 0x00000000FFFFFFFF);
7150 SetS390ConditionCode<int32_t>(alu_out, 0);
7151 return length;
7152}
7153
7154EVALUATE(SLDL) {
7155 DCHECK_OPCODE(SLDL);
7156 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2);
7157 // only takes rightmost 6bits
7158 int64_t b2_val = b2 == 0 ? 0 : get_register(b2);
7159 int shiftBits = (b2_val + d2) & 0x3F;
7160
7161 DCHECK(r1 % 2 == 0);
7162 uint32_t r1_val = get_low_register<uint32_t>(r1);
7163 uint32_t r1_next_val = get_low_register<uint32_t>(r1 + 1);
7164 uint64_t alu_out = (static_cast<uint64_t>(r1_val) << 32) |
7165 (static_cast<uint64_t>(r1_next_val));
7166 alu_out <<= shiftBits;
7167 set_low_register(r1 + 1, static_cast<uint32_t>(alu_out));
7168 set_low_register(r1, static_cast<uint32_t>(alu_out >> 32));
7169 return length;
7170}
7171
7172EVALUATE(SRDA) {
7173 DCHECK_OPCODE(SRDA);
7174 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2);
7175 DCHECK(r1 % 2 == 0); // must be a reg pair
7176 // only takes rightmost 6bits
7177 int64_t b2_val = b2 == 0 ? 0 : get_register(b2);
7178 int shiftBits = (b2_val + d2) & 0x3F;
7179 int64_t opnd1 = static_cast<int64_t>(get_low_register<int32_t>(r1)) << 32;
7180 int64_t opnd2 = static_cast<uint64_t>(get_low_register<uint32_t>(r1 + 1));
7181 int64_t r1_val = opnd1 + opnd2;
7182 int64_t alu_out = r1_val >> shiftBits;
7183 set_low_register(r1, alu_out >> 32);
7184 set_low_register(r1 + 1, alu_out & 0x00000000FFFFFFFF);
7185 SetS390ConditionCode<int32_t>(alu_out, 0);
7186 return length;
7187}
7188
Ben Murdoch61f157c2016-09-16 13:49:30 +01007189EVALUATE(SLDA) {
7190 UNIMPLEMENTED();
7191 USE(instr);
7192 return 0;
7193}
Ben Murdochc5610432016-08-08 18:44:38 +01007194
7195EVALUATE(STM) {
7196 DCHECK_OPCODE(STM);
7197 DECODE_RS_A_INSTRUCTION(r1, r3, rb, d2);
7198 // Store Multiple 32-bits.
7199 int offset = d2;
7200 // Regs roll around if r3 is less than r1.
7201 // Artifically increase r3 by 16 so we can calculate
7202 // the number of regs stored properly.
7203 if (r3 < r1) r3 += 16;
7204
7205 int32_t rb_val = (rb == 0) ? 0 : get_low_register<int32_t>(rb);
7206
7207 // Store each register in ascending order.
7208 for (int i = 0; i <= r3 - r1; i++) {
7209 int32_t value = get_low_register<int32_t>((r1 + i) % 16);
7210 WriteW(rb_val + offset + 4 * i, value, instr);
7211 }
7212 return length;
7213}
7214
7215EVALUATE(TM) {
7216 DCHECK_OPCODE(TM);
7217 // Test Under Mask (Mem - Imm) (8)
7218 DECODE_SI_INSTRUCTION_I_UINT8(b1, d1_val, imm_val)
7219 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
7220 intptr_t addr = b1_val + d1_val;
7221 uint8_t mem_val = ReadB(addr);
7222 uint8_t selected_bits = mem_val & imm_val;
7223 // CC0: Selected bits are zero
7224 // CC1: Selected bits mixed zeros and ones
7225 // CC3: Selected bits all ones
7226 if (0 == selected_bits) {
7227 condition_reg_ = CC_EQ; // CC0
7228 } else if (selected_bits == imm_val) {
7229 condition_reg_ = 0x1; // CC3
7230 } else {
7231 condition_reg_ = 0x4; // CC1
7232 }
7233 return length;
7234}
7235
Ben Murdoch61f157c2016-09-16 13:49:30 +01007236EVALUATE(MVI) {
7237 UNIMPLEMENTED();
7238 USE(instr);
7239 return 0;
7240}
Ben Murdochc5610432016-08-08 18:44:38 +01007241
Ben Murdoch61f157c2016-09-16 13:49:30 +01007242EVALUATE(TS) {
7243 UNIMPLEMENTED();
7244 USE(instr);
7245 return 0;
7246}
Ben Murdochc5610432016-08-08 18:44:38 +01007247
Ben Murdoch61f157c2016-09-16 13:49:30 +01007248EVALUATE(NI) {
7249 UNIMPLEMENTED();
7250 USE(instr);
7251 return 0;
7252}
Ben Murdochc5610432016-08-08 18:44:38 +01007253
7254EVALUATE(CLI) {
7255 DCHECK_OPCODE(CLI);
7256 // Compare Immediate (Mem - Imm) (8)
7257 DECODE_SI_INSTRUCTION_I_UINT8(b1, d1_val, imm_val)
7258 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
7259 intptr_t addr = b1_val + d1_val;
7260 uint8_t mem_val = ReadB(addr);
7261 SetS390ConditionCode<uint8_t>(mem_val, imm_val);
7262 return length;
7263}
7264
Ben Murdoch61f157c2016-09-16 13:49:30 +01007265EVALUATE(OI) {
7266 UNIMPLEMENTED();
7267 USE(instr);
7268 return 0;
7269}
Ben Murdochc5610432016-08-08 18:44:38 +01007270
Ben Murdoch61f157c2016-09-16 13:49:30 +01007271EVALUATE(XI) {
7272 UNIMPLEMENTED();
7273 USE(instr);
7274 return 0;
7275}
Ben Murdochc5610432016-08-08 18:44:38 +01007276
7277EVALUATE(LM) {
7278 DCHECK_OPCODE(LM);
7279 DECODE_RS_A_INSTRUCTION(r1, r3, rb, d2);
7280 // Store Multiple 32-bits.
7281 int offset = d2;
7282 // Regs roll around if r3 is less than r1.
7283 // Artifically increase r3 by 16 so we can calculate
7284 // the number of regs stored properly.
7285 if (r3 < r1) r3 += 16;
7286
7287 int32_t rb_val = (rb == 0) ? 0 : get_low_register<int32_t>(rb);
7288
7289 // Store each register in ascending order.
7290 for (int i = 0; i <= r3 - r1; i++) {
7291 int32_t value = ReadW(rb_val + offset + 4 * i, instr);
7292 set_low_register((r1 + i) % 16, value);
7293 }
7294 return length;
7295}
7296
Ben Murdoch61f157c2016-09-16 13:49:30 +01007297EVALUATE(MVCLE) {
7298 UNIMPLEMENTED();
7299 USE(instr);
7300 return 0;
7301}
Ben Murdochc5610432016-08-08 18:44:38 +01007302
Ben Murdoch61f157c2016-09-16 13:49:30 +01007303EVALUATE(CLCLE) {
7304 UNIMPLEMENTED();
7305 USE(instr);
7306 return 0;
7307}
Ben Murdochc5610432016-08-08 18:44:38 +01007308
Ben Murdoch61f157c2016-09-16 13:49:30 +01007309EVALUATE(MC) {
7310 UNIMPLEMENTED();
7311 USE(instr);
7312 return 0;
7313}
Ben Murdochc5610432016-08-08 18:44:38 +01007314
Ben Murdoch61f157c2016-09-16 13:49:30 +01007315EVALUATE(CDS) {
7316 UNIMPLEMENTED();
7317 USE(instr);
7318 return 0;
7319}
Ben Murdochc5610432016-08-08 18:44:38 +01007320
Ben Murdoch61f157c2016-09-16 13:49:30 +01007321EVALUATE(STCM) {
7322 UNIMPLEMENTED();
7323 USE(instr);
7324 return 0;
7325}
Ben Murdochc5610432016-08-08 18:44:38 +01007326
Ben Murdoch61f157c2016-09-16 13:49:30 +01007327EVALUATE(ICM) {
7328 UNIMPLEMENTED();
7329 USE(instr);
7330 return 0;
7331}
Ben Murdochc5610432016-08-08 18:44:38 +01007332
Ben Murdoch61f157c2016-09-16 13:49:30 +01007333EVALUATE(BPRP) {
7334 UNIMPLEMENTED();
7335 USE(instr);
7336 return 0;
7337}
Ben Murdochc5610432016-08-08 18:44:38 +01007338
Ben Murdoch61f157c2016-09-16 13:49:30 +01007339EVALUATE(BPP) {
7340 UNIMPLEMENTED();
7341 USE(instr);
7342 return 0;
7343}
Ben Murdochc5610432016-08-08 18:44:38 +01007344
Ben Murdoch61f157c2016-09-16 13:49:30 +01007345EVALUATE(TRTR) {
7346 UNIMPLEMENTED();
7347 USE(instr);
7348 return 0;
7349}
Ben Murdochc5610432016-08-08 18:44:38 +01007350
Ben Murdoch61f157c2016-09-16 13:49:30 +01007351EVALUATE(MVN) {
7352 UNIMPLEMENTED();
7353 USE(instr);
7354 return 0;
7355}
Ben Murdochc5610432016-08-08 18:44:38 +01007356
7357EVALUATE(MVC) {
7358 DCHECK_OPCODE(MVC);
7359 // Move Character
7360 SSInstruction* ssInstr = reinterpret_cast<SSInstruction*>(instr);
7361 int b1 = ssInstr->B1Value();
7362 intptr_t d1 = ssInstr->D1Value();
7363 int b2 = ssInstr->B2Value();
7364 intptr_t d2 = ssInstr->D2Value();
7365 int length = ssInstr->Length();
7366 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
7367 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
7368 intptr_t src_addr = b2_val + d2;
7369 intptr_t dst_addr = b1_val + d1;
7370 // remember that the length is the actual length - 1
7371 for (int i = 0; i < length + 1; ++i) {
7372 WriteB(dst_addr++, ReadB(src_addr++));
7373 }
7374 length = 6;
7375 return length;
7376}
7377
Ben Murdoch61f157c2016-09-16 13:49:30 +01007378EVALUATE(MVZ) {
7379 UNIMPLEMENTED();
7380 USE(instr);
7381 return 0;
7382}
Ben Murdochc5610432016-08-08 18:44:38 +01007383
Ben Murdoch61f157c2016-09-16 13:49:30 +01007384EVALUATE(NC) {
7385 UNIMPLEMENTED();
7386 USE(instr);
7387 return 0;
7388}
Ben Murdochc5610432016-08-08 18:44:38 +01007389
Ben Murdoch61f157c2016-09-16 13:49:30 +01007390EVALUATE(CLC) {
7391 UNIMPLEMENTED();
7392 USE(instr);
7393 return 0;
7394}
Ben Murdochc5610432016-08-08 18:44:38 +01007395
Ben Murdoch61f157c2016-09-16 13:49:30 +01007396EVALUATE(OC) {
7397 UNIMPLEMENTED();
7398 USE(instr);
7399 return 0;
7400}
Ben Murdochc5610432016-08-08 18:44:38 +01007401
Ben Murdoch61f157c2016-09-16 13:49:30 +01007402EVALUATE(XC) {
7403 UNIMPLEMENTED();
7404 USE(instr);
7405 return 0;
7406}
Ben Murdochc5610432016-08-08 18:44:38 +01007407
Ben Murdoch61f157c2016-09-16 13:49:30 +01007408EVALUATE(MVCP) {
7409 UNIMPLEMENTED();
7410 USE(instr);
7411 return 0;
7412}
Ben Murdochc5610432016-08-08 18:44:38 +01007413
Ben Murdoch61f157c2016-09-16 13:49:30 +01007414EVALUATE(TR) {
7415 UNIMPLEMENTED();
7416 USE(instr);
7417 return 0;
7418}
Ben Murdochc5610432016-08-08 18:44:38 +01007419
Ben Murdoch61f157c2016-09-16 13:49:30 +01007420EVALUATE(TRT) {
7421 UNIMPLEMENTED();
7422 USE(instr);
7423 return 0;
7424}
Ben Murdochc5610432016-08-08 18:44:38 +01007425
Ben Murdoch61f157c2016-09-16 13:49:30 +01007426EVALUATE(ED) {
7427 UNIMPLEMENTED();
7428 USE(instr);
7429 return 0;
7430}
Ben Murdochc5610432016-08-08 18:44:38 +01007431
Ben Murdoch61f157c2016-09-16 13:49:30 +01007432EVALUATE(EDMK) {
7433 UNIMPLEMENTED();
7434 USE(instr);
7435 return 0;
7436}
Ben Murdochc5610432016-08-08 18:44:38 +01007437
Ben Murdoch61f157c2016-09-16 13:49:30 +01007438EVALUATE(PKU) {
7439 UNIMPLEMENTED();
7440 USE(instr);
7441 return 0;
7442}
Ben Murdochc5610432016-08-08 18:44:38 +01007443
Ben Murdoch61f157c2016-09-16 13:49:30 +01007444EVALUATE(UNPKU) {
7445 UNIMPLEMENTED();
7446 USE(instr);
7447 return 0;
7448}
Ben Murdochc5610432016-08-08 18:44:38 +01007449
Ben Murdoch61f157c2016-09-16 13:49:30 +01007450EVALUATE(MVCIN) {
7451 UNIMPLEMENTED();
7452 USE(instr);
7453 return 0;
7454}
Ben Murdochc5610432016-08-08 18:44:38 +01007455
Ben Murdoch61f157c2016-09-16 13:49:30 +01007456EVALUATE(PKA) {
7457 UNIMPLEMENTED();
7458 USE(instr);
7459 return 0;
7460}
Ben Murdochc5610432016-08-08 18:44:38 +01007461
Ben Murdoch61f157c2016-09-16 13:49:30 +01007462EVALUATE(UNPKA) {
7463 UNIMPLEMENTED();
7464 USE(instr);
7465 return 0;
7466}
Ben Murdochc5610432016-08-08 18:44:38 +01007467
Ben Murdoch61f157c2016-09-16 13:49:30 +01007468EVALUATE(PLO) {
7469 UNIMPLEMENTED();
7470 USE(instr);
7471 return 0;
7472}
Ben Murdochc5610432016-08-08 18:44:38 +01007473
Ben Murdoch61f157c2016-09-16 13:49:30 +01007474EVALUATE(LMD) {
7475 UNIMPLEMENTED();
7476 USE(instr);
7477 return 0;
7478}
Ben Murdochc5610432016-08-08 18:44:38 +01007479
Ben Murdoch61f157c2016-09-16 13:49:30 +01007480EVALUATE(SRP) {
7481 UNIMPLEMENTED();
7482 USE(instr);
7483 return 0;
7484}
Ben Murdochc5610432016-08-08 18:44:38 +01007485
Ben Murdoch61f157c2016-09-16 13:49:30 +01007486EVALUATE(MVO) {
7487 UNIMPLEMENTED();
7488 USE(instr);
7489 return 0;
7490}
Ben Murdochc5610432016-08-08 18:44:38 +01007491
Ben Murdoch61f157c2016-09-16 13:49:30 +01007492EVALUATE(PACK) {
7493 UNIMPLEMENTED();
7494 USE(instr);
7495 return 0;
7496}
Ben Murdochc5610432016-08-08 18:44:38 +01007497
Ben Murdoch61f157c2016-09-16 13:49:30 +01007498EVALUATE(UNPK) {
7499 UNIMPLEMENTED();
7500 USE(instr);
7501 return 0;
7502}
Ben Murdochc5610432016-08-08 18:44:38 +01007503
Ben Murdoch61f157c2016-09-16 13:49:30 +01007504EVALUATE(ZAP) {
7505 UNIMPLEMENTED();
7506 USE(instr);
7507 return 0;
7508}
Ben Murdochc5610432016-08-08 18:44:38 +01007509
Ben Murdoch61f157c2016-09-16 13:49:30 +01007510EVALUATE(AP) {
7511 UNIMPLEMENTED();
7512 USE(instr);
7513 return 0;
7514}
Ben Murdochc5610432016-08-08 18:44:38 +01007515
Ben Murdoch61f157c2016-09-16 13:49:30 +01007516EVALUATE(SP) {
7517 UNIMPLEMENTED();
7518 USE(instr);
7519 return 0;
7520}
Ben Murdochc5610432016-08-08 18:44:38 +01007521
Ben Murdoch61f157c2016-09-16 13:49:30 +01007522EVALUATE(MP) {
7523 UNIMPLEMENTED();
7524 USE(instr);
7525 return 0;
7526}
Ben Murdochc5610432016-08-08 18:44:38 +01007527
Ben Murdoch61f157c2016-09-16 13:49:30 +01007528EVALUATE(DP) {
7529 UNIMPLEMENTED();
7530 USE(instr);
7531 return 0;
7532}
Ben Murdochc5610432016-08-08 18:44:38 +01007533
Ben Murdoch61f157c2016-09-16 13:49:30 +01007534EVALUATE(UPT) {
7535 UNIMPLEMENTED();
7536 USE(instr);
7537 return 0;
7538}
Ben Murdochc5610432016-08-08 18:44:38 +01007539
Ben Murdoch61f157c2016-09-16 13:49:30 +01007540EVALUATE(PFPO) {
7541 UNIMPLEMENTED();
7542 USE(instr);
7543 return 0;
7544}
Ben Murdochc5610432016-08-08 18:44:38 +01007545
Ben Murdoch61f157c2016-09-16 13:49:30 +01007546EVALUATE(IIHH) {
7547 UNIMPLEMENTED();
7548 USE(instr);
7549 return 0;
7550}
Ben Murdochc5610432016-08-08 18:44:38 +01007551
Ben Murdoch61f157c2016-09-16 13:49:30 +01007552EVALUATE(IIHL) {
7553 UNIMPLEMENTED();
7554 USE(instr);
7555 return 0;
7556}
Ben Murdochc5610432016-08-08 18:44:38 +01007557
Ben Murdoch61f157c2016-09-16 13:49:30 +01007558EVALUATE(IILH) {
7559 UNIMPLEMENTED();
7560 USE(instr);
7561 return 0;
7562}
Ben Murdochc5610432016-08-08 18:44:38 +01007563
Ben Murdoch61f157c2016-09-16 13:49:30 +01007564EVALUATE(IILL) {
7565 UNIMPLEMENTED();
7566 USE(instr);
7567 return 0;
7568}
Ben Murdochc5610432016-08-08 18:44:38 +01007569
Ben Murdoch61f157c2016-09-16 13:49:30 +01007570EVALUATE(NIHH) {
7571 UNIMPLEMENTED();
7572 USE(instr);
7573 return 0;
7574}
Ben Murdochc5610432016-08-08 18:44:38 +01007575
Ben Murdoch61f157c2016-09-16 13:49:30 +01007576EVALUATE(NIHL) {
7577 UNIMPLEMENTED();
7578 USE(instr);
7579 return 0;
7580}
Ben Murdochc5610432016-08-08 18:44:38 +01007581
7582EVALUATE(NILH) {
7583 DCHECK_OPCODE(NILH);
7584 DECODE_RI_A_INSTRUCTION(instr, r1, i);
7585 int32_t r1_val = get_low_register<int32_t>(r1);
7586 // CC is set based on the 16 bits that are AND'd
7587 SetS390BitWiseConditionCode<uint16_t>((r1_val >> 16) & i);
7588 i = (i << 16) | 0x0000FFFF;
7589 set_low_register(r1, r1_val & i);
7590 return length;
7591}
7592
7593EVALUATE(NILL) {
7594 DCHECK_OPCODE(NILL);
7595 DECODE_RI_A_INSTRUCTION(instr, r1, i);
7596 int32_t r1_val = get_low_register<int32_t>(r1);
7597 // CC is set based on the 16 bits that are AND'd
7598 SetS390BitWiseConditionCode<uint16_t>(r1_val & i);
7599 i |= 0xFFFF0000;
7600 set_low_register(r1, r1_val & i);
7601 return length;
7602}
7603
Ben Murdoch61f157c2016-09-16 13:49:30 +01007604EVALUATE(OIHH) {
7605 UNIMPLEMENTED();
7606 USE(instr);
7607 return 0;
7608}
Ben Murdochc5610432016-08-08 18:44:38 +01007609
Ben Murdoch61f157c2016-09-16 13:49:30 +01007610EVALUATE(OIHL) {
7611 UNIMPLEMENTED();
7612 USE(instr);
7613 return 0;
7614}
Ben Murdochc5610432016-08-08 18:44:38 +01007615
7616EVALUATE(OILH) {
7617 DCHECK_OPCODE(OILH);
7618 DECODE_RI_A_INSTRUCTION(instr, r1, i);
7619 int32_t r1_val = get_low_register<int32_t>(r1);
7620 // CC is set based on the 16 bits that are AND'd
7621 SetS390BitWiseConditionCode<uint16_t>((r1_val >> 16) | i);
7622 i = i << 16;
7623 set_low_register(r1, r1_val | i);
7624 return length;
7625}
7626
7627EVALUATE(OILL) {
7628 DCHECK_OPCODE(OILL);
7629 DECODE_RI_A_INSTRUCTION(instr, r1, i);
7630 int32_t r1_val = get_low_register<int32_t>(r1);
7631 // CC is set based on the 16 bits that are AND'd
7632 SetS390BitWiseConditionCode<uint16_t>(r1_val | i);
7633 set_low_register(r1, r1_val | i);
7634 return length;
7635}
7636
Ben Murdoch61f157c2016-09-16 13:49:30 +01007637EVALUATE(LLIHH) {
7638 UNIMPLEMENTED();
7639 USE(instr);
7640 return 0;
7641}
Ben Murdochc5610432016-08-08 18:44:38 +01007642
Ben Murdoch61f157c2016-09-16 13:49:30 +01007643EVALUATE(LLIHL) {
7644 UNIMPLEMENTED();
7645 USE(instr);
7646 return 0;
7647}
Ben Murdochc5610432016-08-08 18:44:38 +01007648
Ben Murdoch61f157c2016-09-16 13:49:30 +01007649EVALUATE(LLILH) {
7650 UNIMPLEMENTED();
7651 USE(instr);
7652 return 0;
7653}
Ben Murdochc5610432016-08-08 18:44:38 +01007654
Ben Murdoch61f157c2016-09-16 13:49:30 +01007655EVALUATE(LLILL) {
7656 UNIMPLEMENTED();
7657 USE(instr);
7658 return 0;
7659}
Ben Murdochc5610432016-08-08 18:44:38 +01007660
Ben Murdoch61f157c2016-09-16 13:49:30 +01007661EVALUATE(TMLH) {
7662 UNIMPLEMENTED();
7663 USE(instr);
7664 return 0;
7665}
Ben Murdochc5610432016-08-08 18:44:38 +01007666
7667EVALUATE(TMLL) {
7668 DCHECK_OPCODE(TMLL);
7669 DECODE_RI_A_INSTRUCTION(instr, r1, i2);
7670 int mask = i2 & 0x0000FFFF;
7671 if (mask == 0) {
7672 condition_reg_ = 0x0;
7673 return length;
7674 }
7675 uint32_t r1_val = get_low_register<uint32_t>(r1);
7676 r1_val = r1_val & 0x0000FFFF; // uses only the last 16bits
7677
7678 // Test if all selected bits are Zero
7679 bool allSelectedBitsAreZeros = true;
7680 for (int i = 0; i < 15; i++) {
7681 if (mask & (1 << i)) {
7682 if (r1_val & (1 << i)) {
7683 allSelectedBitsAreZeros = false;
7684 break;
7685 }
7686 }
7687 }
7688 if (allSelectedBitsAreZeros) {
7689 condition_reg_ = 0x8;
7690 return length; // Done!
7691 }
7692
7693 // Test if all selected bits are one
7694 bool allSelectedBitsAreOnes = true;
7695 for (int i = 0; i < 15; i++) {
7696 if (mask & (1 << i)) {
7697 if (!(r1_val & (1 << i))) {
7698 allSelectedBitsAreOnes = false;
7699 break;
7700 }
7701 }
7702 }
7703 if (allSelectedBitsAreOnes) {
7704 condition_reg_ = 0x1;
7705 return length; // Done!
7706 }
7707
7708 // Now we know selected bits mixed zeros and ones
7709 // Test if the leftmost bit is zero or one
7710 for (int i = 14; i >= 0; i--) {
7711 if (mask & (1 << i)) {
7712 if (r1_val & (1 << i)) {
7713 // leftmost bit is one
7714 condition_reg_ = 0x2;
7715 } else {
7716 // leftmost bit is zero
7717 condition_reg_ = 0x4;
7718 }
7719 return length; // Done!
7720 }
7721 }
7722 return length;
7723}
7724
Ben Murdoch61f157c2016-09-16 13:49:30 +01007725EVALUATE(TMHH) {
7726 UNIMPLEMENTED();
7727 USE(instr);
7728 return 0;
7729}
Ben Murdochc5610432016-08-08 18:44:38 +01007730
Ben Murdoch61f157c2016-09-16 13:49:30 +01007731EVALUATE(TMHL) {
7732 UNIMPLEMENTED();
7733 USE(instr);
7734 return 0;
7735}
Ben Murdochc5610432016-08-08 18:44:38 +01007736
7737EVALUATE(BRAS) {
7738 DCHECK_OPCODE(BRAS);
7739 // Branch Relative and Save
7740 DECODE_RI_B_INSTRUCTION(instr, r1, d2)
7741 intptr_t pc = get_pc();
7742 // Set PC of next instruction to register
7743 set_register(r1, pc + sizeof(FourByteInstr));
7744 // Update PC to branch target
7745 set_pc(pc + d2 * 2);
7746 return length;
7747}
7748
7749EVALUATE(BRCT) {
7750 DCHECK_OPCODE(BRCT);
7751 // Branch On Count (32/64).
7752 DECODE_RI_A_INSTRUCTION(instr, r1, i2);
7753 int64_t value = get_low_register<int32_t>(r1);
7754 set_low_register(r1, --value);
7755 // Branch if value != 0
7756 if (value != 0) {
7757 intptr_t offset = i2 * 2;
7758 set_pc(get_pc() + offset);
7759 }
7760 return length;
7761}
7762
7763EVALUATE(BRCTG) {
7764 DCHECK_OPCODE(BRCTG);
7765 // Branch On Count (32/64).
7766 DECODE_RI_A_INSTRUCTION(instr, r1, i2);
7767 int64_t value = get_register(r1);
7768 set_register(r1, --value);
7769 // Branch if value != 0
7770 if (value != 0) {
7771 intptr_t offset = i2 * 2;
7772 set_pc(get_pc() + offset);
7773 }
7774 return length;
7775}
7776
7777EVALUATE(LHI) {
7778 DCHECK_OPCODE(LHI);
7779 DECODE_RI_A_INSTRUCTION(instr, r1, i);
7780 set_low_register(r1, i);
7781 return length;
7782}
7783
7784EVALUATE(LGHI) {
7785 DCHECK_OPCODE(LGHI);
7786 DECODE_RI_A_INSTRUCTION(instr, r1, i2);
7787 int64_t i = static_cast<int64_t>(i2);
7788 set_register(r1, i);
7789 return length;
7790}
7791
7792EVALUATE(MHI) {
7793 DCHECK_OPCODE(MHI);
7794 DECODE_RI_A_INSTRUCTION(instr, r1, i);
7795 int32_t r1_val = get_low_register<int32_t>(r1);
7796 bool isOF = false;
7797 isOF = CheckOverflowForMul(r1_val, i);
7798 r1_val *= i;
7799 set_low_register(r1, r1_val);
7800 SetS390ConditionCode<int32_t>(r1_val, 0);
7801 SetS390OverflowCode(isOF);
7802 return length;
7803}
7804
7805EVALUATE(MGHI) {
7806 DCHECK_OPCODE(MGHI);
7807 DECODE_RI_A_INSTRUCTION(instr, r1, i2);
7808 int64_t i = static_cast<int64_t>(i2);
7809 int64_t r1_val = get_register(r1);
7810 bool isOF = false;
7811 isOF = CheckOverflowForMul(r1_val, i);
7812 r1_val *= i;
7813 set_register(r1, r1_val);
7814 SetS390ConditionCode<int32_t>(r1_val, 0);
7815 SetS390OverflowCode(isOF);
7816 return length;
7817}
7818
7819EVALUATE(CHI) {
7820 DCHECK_OPCODE(CHI);
7821 DECODE_RI_A_INSTRUCTION(instr, r1, i);
7822 int32_t r1_val = get_low_register<int32_t>(r1);
7823 SetS390ConditionCode<int32_t>(r1_val, i);
7824 return length;
7825}
7826
7827EVALUATE(CGHI) {
7828 DCHECK_OPCODE(CGHI);
7829 DECODE_RI_A_INSTRUCTION(instr, r1, i2);
7830 int64_t i = static_cast<int64_t>(i2);
7831 int64_t r1_val = get_register(r1);
7832 SetS390ConditionCode<int64_t>(r1_val, i);
7833 return length;
7834}
7835
7836EVALUATE(LARL) {
7837 DCHECK_OPCODE(LARL);
7838 DECODE_RIL_B_INSTRUCTION(r1, i2);
7839 intptr_t offset = i2 * 2;
7840 set_register(r1, get_pc() + offset);
7841 return length;
7842}
7843
Ben Murdoch61f157c2016-09-16 13:49:30 +01007844EVALUATE(LGFI) {
7845 UNIMPLEMENTED();
7846 USE(instr);
7847 return 0;
7848}
Ben Murdochc5610432016-08-08 18:44:38 +01007849
7850EVALUATE(BRASL) {
7851 DCHECK_OPCODE(BRASL);
7852 // Branch and Save Relative Long
7853 DECODE_RIL_B_INSTRUCTION(r1, i2);
7854 intptr_t d2 = i2;
7855 intptr_t pc = get_pc();
7856 set_register(r1, pc + 6); // save next instruction to register
7857 set_pc(pc + d2 * 2); // update register
7858 return length;
7859}
7860
7861EVALUATE(XIHF) {
7862 DCHECK_OPCODE(XIHF);
7863 DECODE_RIL_A_INSTRUCTION(r1, imm);
7864 uint32_t alu_out = 0;
7865 alu_out = get_high_register<uint32_t>(r1);
7866 alu_out = alu_out ^ imm;
7867 set_high_register(r1, alu_out);
7868 SetS390BitWiseConditionCode<uint32_t>(alu_out);
7869 return length;
7870}
7871
7872EVALUATE(XILF) {
7873 DCHECK_OPCODE(XILF);
7874 DECODE_RIL_A_INSTRUCTION(r1, imm);
7875 uint32_t alu_out = 0;
7876 alu_out = get_low_register<uint32_t>(r1);
7877 alu_out = alu_out ^ imm;
7878 set_low_register(r1, alu_out);
7879 SetS390BitWiseConditionCode<uint32_t>(alu_out);
7880 return length;
7881}
7882
7883EVALUATE(NIHF) {
7884 DCHECK_OPCODE(NIHF);
7885 // Bitwise Op on upper 32-bits
7886 DECODE_RIL_A_INSTRUCTION(r1, imm);
7887 uint32_t alu_out = get_high_register<uint32_t>(r1);
7888 alu_out &= imm;
7889 SetS390BitWiseConditionCode<uint32_t>(alu_out);
7890 set_high_register(r1, alu_out);
7891 return length;
7892}
7893
7894EVALUATE(NILF) {
7895 DCHECK_OPCODE(NILF);
7896 // Bitwise Op on lower 32-bits
7897 DECODE_RIL_A_INSTRUCTION(r1, imm);
7898 uint32_t alu_out = get_low_register<uint32_t>(r1);
7899 alu_out &= imm;
7900 SetS390BitWiseConditionCode<uint32_t>(alu_out);
7901 set_low_register(r1, alu_out);
7902 return length;
7903}
7904
7905EVALUATE(OIHF) {
7906 DCHECK_OPCODE(OIHF);
7907 // Bitwise Op on upper 32-bits
7908 DECODE_RIL_B_INSTRUCTION(r1, imm);
7909 uint32_t alu_out = get_high_register<uint32_t>(r1);
7910 alu_out |= imm;
7911 SetS390BitWiseConditionCode<uint32_t>(alu_out);
7912 set_high_register(r1, alu_out);
7913 return length;
7914}
7915
7916EVALUATE(OILF) {
7917 DCHECK_OPCODE(OILF);
7918 // Bitwise Op on lower 32-bits
7919 DECODE_RIL_B_INSTRUCTION(r1, imm);
7920 uint32_t alu_out = get_low_register<uint32_t>(r1);
7921 alu_out |= imm;
7922 SetS390BitWiseConditionCode<uint32_t>(alu_out);
7923 set_low_register(r1, alu_out);
7924 return length;
7925}
7926
7927EVALUATE(LLIHF) {
7928 DCHECK_OPCODE(LLIHF);
7929 // Load Logical Immediate into high word
7930 DECODE_RIL_A_INSTRUCTION(r1, i2);
7931 uint64_t imm = static_cast<uint64_t>(i2);
7932 set_register(r1, imm << 32);
7933 return length;
7934}
7935
7936EVALUATE(LLILF) {
7937 DCHECK_OPCODE(LLILF);
7938 // Load Logical into lower 32-bits (zero extend upper 32-bits)
7939 DECODE_RIL_A_INSTRUCTION(r1, i2);
7940 uint64_t imm = static_cast<uint64_t>(i2);
7941 set_register(r1, imm);
7942 return length;
7943}
7944
7945EVALUATE(MSGFI) {
7946 DCHECK_OPCODE(MSGFI);
7947 DECODE_RIL_B_INSTRUCTION(r1, i2);
7948 int64_t alu_out = get_register(r1);
7949 alu_out = alu_out * i2;
7950 set_register(r1, alu_out);
7951 return length;
7952}
7953
7954EVALUATE(MSFI) {
7955 DCHECK_OPCODE(MSFI);
7956 DECODE_RIL_B_INSTRUCTION(r1, i2);
7957 int32_t alu_out = get_low_register<int32_t>(r1);
7958 alu_out = alu_out * i2;
7959 set_low_register(r1, alu_out);
7960 return length;
7961}
7962
7963EVALUATE(SLGFI) {
7964 DCHECK_OPCODE(SLGFI);
7965#ifndef V8_TARGET_ARCH_S390X
7966 // should only be called on 64bit
7967 DCHECK(false);
7968#endif
7969 DECODE_RIL_A_INSTRUCTION(r1, i2);
7970 uint64_t r1_val = (uint64_t)(get_register(r1));
7971 uint64_t alu_out;
7972 alu_out = r1_val - i2;
7973 set_register(r1, (intptr_t)alu_out);
7974 SetS390ConditionCode<uint64_t>(alu_out, 0);
7975 return length;
7976}
7977
7978EVALUATE(SLFI) {
7979 DCHECK_OPCODE(SLFI);
7980 DECODE_RIL_A_INSTRUCTION(r1, imm);
7981 uint32_t alu_out = get_low_register<uint32_t>(r1);
7982 alu_out -= imm;
7983 SetS390ConditionCode<uint32_t>(alu_out, 0);
7984 set_low_register(r1, alu_out);
7985 return length;
7986}
7987
7988EVALUATE(AGFI) {
7989 DCHECK_OPCODE(AGFI);
7990 // Clobbering Add Word Immediate
7991 DECODE_RIL_B_INSTRUCTION(r1, i2_val);
7992 bool isOF = false;
7993 // 64-bit Add (Register + 32-bit Imm)
7994 int64_t r1_val = get_register(r1);
7995 int64_t i2 = static_cast<int64_t>(i2_val);
7996 isOF = CheckOverflowForIntAdd(r1_val, i2, int64_t);
7997 int64_t alu_out = r1_val + i2;
7998 set_register(r1, alu_out);
7999 SetS390ConditionCode<int64_t>(alu_out, 0);
8000 SetS390OverflowCode(isOF);
8001 return length;
8002}
8003
8004EVALUATE(AFI) {
8005 DCHECK_OPCODE(AFI);
8006 // Clobbering Add Word Immediate
8007 DECODE_RIL_B_INSTRUCTION(r1, i2);
8008 bool isOF = false;
8009 // 32-bit Add (Register + 32-bit Immediate)
8010 int32_t r1_val = get_low_register<int32_t>(r1);
8011 isOF = CheckOverflowForIntAdd(r1_val, i2, int32_t);
8012 int32_t alu_out = r1_val + i2;
8013 set_low_register(r1, alu_out);
8014 SetS390ConditionCode<int32_t>(alu_out, 0);
8015 SetS390OverflowCode(isOF);
8016 return length;
8017}
8018
8019EVALUATE(ALGFI) {
8020 DCHECK_OPCODE(ALGFI);
8021#ifndef V8_TARGET_ARCH_S390X
8022 // should only be called on 64bit
8023 DCHECK(false);
8024#endif
8025 DECODE_RIL_A_INSTRUCTION(r1, i2);
8026 uint64_t r1_val = (uint64_t)(get_register(r1));
8027 uint64_t alu_out;
8028 alu_out = r1_val + i2;
8029 set_register(r1, (intptr_t)alu_out);
8030 SetS390ConditionCode<uint64_t>(alu_out, 0);
8031
8032 return length;
8033}
8034
8035EVALUATE(ALFI) {
8036 DCHECK_OPCODE(ALFI);
8037 DECODE_RIL_A_INSTRUCTION(r1, imm);
8038 uint32_t alu_out = get_low_register<uint32_t>(r1);
8039 alu_out += imm;
8040 SetS390ConditionCode<uint32_t>(alu_out, 0);
8041 set_low_register(r1, alu_out);
8042 return length;
8043}
8044
8045EVALUATE(CGFI) {
8046 DCHECK_OPCODE(CGFI);
8047 // Compare with Immediate (64)
8048 DECODE_RIL_B_INSTRUCTION(r1, i2);
8049 int64_t imm = static_cast<int64_t>(i2);
8050 SetS390ConditionCode<int64_t>(get_register(r1), imm);
8051 return length;
8052}
8053
8054EVALUATE(CFI) {
8055 DCHECK_OPCODE(CFI);
8056 // Compare with Immediate (32)
8057 DECODE_RIL_B_INSTRUCTION(r1, imm);
8058 SetS390ConditionCode<int32_t>(get_low_register<int32_t>(r1), imm);
8059 return length;
8060}
8061
8062EVALUATE(CLGFI) {
8063 DCHECK_OPCODE(CLGFI);
8064 // Compare Logical with Immediate (64)
8065 DECODE_RIL_A_INSTRUCTION(r1, i2);
8066 uint64_t imm = static_cast<uint64_t>(i2);
8067 SetS390ConditionCode<uint64_t>(get_register(r1), imm);
8068 return length;
8069}
8070
8071EVALUATE(CLFI) {
8072 DCHECK_OPCODE(CLFI);
8073 // Compare Logical with Immediate (32)
8074 DECODE_RIL_A_INSTRUCTION(r1, imm);
8075 SetS390ConditionCode<uint32_t>(get_low_register<uint32_t>(r1), imm);
8076 return length;
8077}
8078
Ben Murdoch61f157c2016-09-16 13:49:30 +01008079EVALUATE(LLHRL) {
8080 UNIMPLEMENTED();
8081 USE(instr);
8082 return 0;
8083}
Ben Murdochc5610432016-08-08 18:44:38 +01008084
Ben Murdoch61f157c2016-09-16 13:49:30 +01008085EVALUATE(LGHRL) {
8086 UNIMPLEMENTED();
8087 USE(instr);
8088 return 0;
8089}
Ben Murdochc5610432016-08-08 18:44:38 +01008090
Ben Murdoch61f157c2016-09-16 13:49:30 +01008091EVALUATE(LHRL) {
8092 UNIMPLEMENTED();
8093 USE(instr);
8094 return 0;
8095}
Ben Murdochc5610432016-08-08 18:44:38 +01008096
Ben Murdoch61f157c2016-09-16 13:49:30 +01008097EVALUATE(LLGHRL) {
8098 UNIMPLEMENTED();
8099 USE(instr);
8100 return 0;
8101}
Ben Murdochc5610432016-08-08 18:44:38 +01008102
Ben Murdoch61f157c2016-09-16 13:49:30 +01008103EVALUATE(STHRL) {
8104 UNIMPLEMENTED();
8105 USE(instr);
8106 return 0;
8107}
Ben Murdochc5610432016-08-08 18:44:38 +01008108
Ben Murdoch61f157c2016-09-16 13:49:30 +01008109EVALUATE(LGRL) {
8110 UNIMPLEMENTED();
8111 USE(instr);
8112 return 0;
8113}
Ben Murdochc5610432016-08-08 18:44:38 +01008114
Ben Murdoch61f157c2016-09-16 13:49:30 +01008115EVALUATE(STGRL) {
8116 UNIMPLEMENTED();
8117 USE(instr);
8118 return 0;
8119}
Ben Murdochc5610432016-08-08 18:44:38 +01008120
Ben Murdoch61f157c2016-09-16 13:49:30 +01008121EVALUATE(LGFRL) {
8122 UNIMPLEMENTED();
8123 USE(instr);
8124 return 0;
8125}
Ben Murdochc5610432016-08-08 18:44:38 +01008126
Ben Murdoch61f157c2016-09-16 13:49:30 +01008127EVALUATE(LRL) {
8128 UNIMPLEMENTED();
8129 USE(instr);
8130 return 0;
8131}
Ben Murdochc5610432016-08-08 18:44:38 +01008132
Ben Murdoch61f157c2016-09-16 13:49:30 +01008133EVALUATE(LLGFRL) {
8134 UNIMPLEMENTED();
8135 USE(instr);
8136 return 0;
8137}
Ben Murdochc5610432016-08-08 18:44:38 +01008138
Ben Murdoch61f157c2016-09-16 13:49:30 +01008139EVALUATE(STRL) {
8140 UNIMPLEMENTED();
8141 USE(instr);
8142 return 0;
8143}
Ben Murdochc5610432016-08-08 18:44:38 +01008144
Ben Murdoch61f157c2016-09-16 13:49:30 +01008145EVALUATE(EXRL) {
8146 UNIMPLEMENTED();
8147 USE(instr);
8148 return 0;
8149}
Ben Murdochc5610432016-08-08 18:44:38 +01008150
Ben Murdoch61f157c2016-09-16 13:49:30 +01008151EVALUATE(PFDRL) {
8152 UNIMPLEMENTED();
8153 USE(instr);
8154 return 0;
8155}
Ben Murdochc5610432016-08-08 18:44:38 +01008156
Ben Murdoch61f157c2016-09-16 13:49:30 +01008157EVALUATE(CGHRL) {
8158 UNIMPLEMENTED();
8159 USE(instr);
8160 return 0;
8161}
Ben Murdochc5610432016-08-08 18:44:38 +01008162
Ben Murdoch61f157c2016-09-16 13:49:30 +01008163EVALUATE(CHRL) {
8164 UNIMPLEMENTED();
8165 USE(instr);
8166 return 0;
8167}
Ben Murdochc5610432016-08-08 18:44:38 +01008168
Ben Murdoch61f157c2016-09-16 13:49:30 +01008169EVALUATE(CGRL) {
8170 UNIMPLEMENTED();
8171 USE(instr);
8172 return 0;
8173}
Ben Murdochc5610432016-08-08 18:44:38 +01008174
Ben Murdoch61f157c2016-09-16 13:49:30 +01008175EVALUATE(CGFRL) {
8176 UNIMPLEMENTED();
8177 USE(instr);
8178 return 0;
8179}
Ben Murdochc5610432016-08-08 18:44:38 +01008180
Ben Murdoch61f157c2016-09-16 13:49:30 +01008181EVALUATE(ECTG) {
8182 UNIMPLEMENTED();
8183 USE(instr);
8184 return 0;
8185}
Ben Murdochc5610432016-08-08 18:44:38 +01008186
Ben Murdoch61f157c2016-09-16 13:49:30 +01008187EVALUATE(CSST) {
8188 UNIMPLEMENTED();
8189 USE(instr);
8190 return 0;
8191}
Ben Murdochc5610432016-08-08 18:44:38 +01008192
Ben Murdoch61f157c2016-09-16 13:49:30 +01008193EVALUATE(LPD) {
8194 UNIMPLEMENTED();
8195 USE(instr);
8196 return 0;
8197}
Ben Murdochc5610432016-08-08 18:44:38 +01008198
Ben Murdoch61f157c2016-09-16 13:49:30 +01008199EVALUATE(LPDG) {
8200 UNIMPLEMENTED();
8201 USE(instr);
8202 return 0;
8203}
Ben Murdochc5610432016-08-08 18:44:38 +01008204
Ben Murdoch61f157c2016-09-16 13:49:30 +01008205EVALUATE(BRCTH) {
8206 UNIMPLEMENTED();
8207 USE(instr);
8208 return 0;
8209}
Ben Murdochc5610432016-08-08 18:44:38 +01008210
Ben Murdoch61f157c2016-09-16 13:49:30 +01008211EVALUATE(AIH) {
8212 UNIMPLEMENTED();
8213 USE(instr);
8214 return 0;
8215}
Ben Murdochc5610432016-08-08 18:44:38 +01008216
Ben Murdoch61f157c2016-09-16 13:49:30 +01008217EVALUATE(ALSIH) {
8218 UNIMPLEMENTED();
8219 USE(instr);
8220 return 0;
8221}
Ben Murdochc5610432016-08-08 18:44:38 +01008222
Ben Murdoch61f157c2016-09-16 13:49:30 +01008223EVALUATE(ALSIHN) {
8224 UNIMPLEMENTED();
8225 USE(instr);
8226 return 0;
8227}
Ben Murdochc5610432016-08-08 18:44:38 +01008228
Ben Murdoch61f157c2016-09-16 13:49:30 +01008229EVALUATE(CIH) {
8230 UNIMPLEMENTED();
8231 USE(instr);
8232 return 0;
8233}
Ben Murdochc5610432016-08-08 18:44:38 +01008234
Ben Murdoch61f157c2016-09-16 13:49:30 +01008235EVALUATE(STCK) {
8236 UNIMPLEMENTED();
8237 USE(instr);
8238 return 0;
8239}
Ben Murdochc5610432016-08-08 18:44:38 +01008240
Ben Murdoch61f157c2016-09-16 13:49:30 +01008241EVALUATE(CFC) {
8242 UNIMPLEMENTED();
8243 USE(instr);
8244 return 0;
8245}
Ben Murdochc5610432016-08-08 18:44:38 +01008246
Ben Murdoch61f157c2016-09-16 13:49:30 +01008247EVALUATE(IPM) {
8248 UNIMPLEMENTED();
8249 USE(instr);
8250 return 0;
8251}
Ben Murdochc5610432016-08-08 18:44:38 +01008252
Ben Murdoch61f157c2016-09-16 13:49:30 +01008253EVALUATE(HSCH) {
8254 UNIMPLEMENTED();
8255 USE(instr);
8256 return 0;
8257}
Ben Murdochc5610432016-08-08 18:44:38 +01008258
Ben Murdoch61f157c2016-09-16 13:49:30 +01008259EVALUATE(MSCH) {
8260 UNIMPLEMENTED();
8261 USE(instr);
8262 return 0;
8263}
Ben Murdochc5610432016-08-08 18:44:38 +01008264
Ben Murdoch61f157c2016-09-16 13:49:30 +01008265EVALUATE(SSCH) {
8266 UNIMPLEMENTED();
8267 USE(instr);
8268 return 0;
8269}
Ben Murdochc5610432016-08-08 18:44:38 +01008270
Ben Murdoch61f157c2016-09-16 13:49:30 +01008271EVALUATE(STSCH) {
8272 UNIMPLEMENTED();
8273 USE(instr);
8274 return 0;
8275}
Ben Murdochc5610432016-08-08 18:44:38 +01008276
Ben Murdoch61f157c2016-09-16 13:49:30 +01008277EVALUATE(TSCH) {
8278 UNIMPLEMENTED();
8279 USE(instr);
8280 return 0;
8281}
Ben Murdochc5610432016-08-08 18:44:38 +01008282
Ben Murdoch61f157c2016-09-16 13:49:30 +01008283EVALUATE(TPI) {
8284 UNIMPLEMENTED();
8285 USE(instr);
8286 return 0;
8287}
Ben Murdochc5610432016-08-08 18:44:38 +01008288
Ben Murdoch61f157c2016-09-16 13:49:30 +01008289EVALUATE(SAL) {
8290 UNIMPLEMENTED();
8291 USE(instr);
8292 return 0;
8293}
Ben Murdochc5610432016-08-08 18:44:38 +01008294
Ben Murdoch61f157c2016-09-16 13:49:30 +01008295EVALUATE(RSCH) {
8296 UNIMPLEMENTED();
8297 USE(instr);
8298 return 0;
8299}
Ben Murdochc5610432016-08-08 18:44:38 +01008300
Ben Murdoch61f157c2016-09-16 13:49:30 +01008301EVALUATE(STCRW) {
8302 UNIMPLEMENTED();
8303 USE(instr);
8304 return 0;
8305}
Ben Murdochc5610432016-08-08 18:44:38 +01008306
Ben Murdoch61f157c2016-09-16 13:49:30 +01008307EVALUATE(STCPS) {
8308 UNIMPLEMENTED();
8309 USE(instr);
8310 return 0;
8311}
Ben Murdochc5610432016-08-08 18:44:38 +01008312
Ben Murdoch61f157c2016-09-16 13:49:30 +01008313EVALUATE(RCHP) {
8314 UNIMPLEMENTED();
8315 USE(instr);
8316 return 0;
8317}
Ben Murdochc5610432016-08-08 18:44:38 +01008318
Ben Murdoch61f157c2016-09-16 13:49:30 +01008319EVALUATE(SCHM) {
8320 UNIMPLEMENTED();
8321 USE(instr);
8322 return 0;
8323}
Ben Murdochc5610432016-08-08 18:44:38 +01008324
Ben Murdoch61f157c2016-09-16 13:49:30 +01008325EVALUATE(CKSM) {
8326 UNIMPLEMENTED();
8327 USE(instr);
8328 return 0;
8329}
Ben Murdochc5610432016-08-08 18:44:38 +01008330
Ben Murdoch61f157c2016-09-16 13:49:30 +01008331EVALUATE(SAR) {
8332 UNIMPLEMENTED();
8333 USE(instr);
8334 return 0;
8335}
Ben Murdochc5610432016-08-08 18:44:38 +01008336
Ben Murdoch61f157c2016-09-16 13:49:30 +01008337EVALUATE(EAR) {
8338 UNIMPLEMENTED();
8339 USE(instr);
8340 return 0;
8341}
Ben Murdochc5610432016-08-08 18:44:38 +01008342
8343EVALUATE(MSR) {
8344 DCHECK_OPCODE(MSR);
8345 DECODE_RRE_INSTRUCTION(r1, r2);
8346 int32_t r1_val = get_low_register<int32_t>(r1);
8347 int32_t r2_val = get_low_register<int32_t>(r2);
8348 set_low_register(r1, r1_val * r2_val);
8349 return length;
8350}
8351
Ben Murdoch61f157c2016-09-16 13:49:30 +01008352EVALUATE(MVST) {
8353 UNIMPLEMENTED();
8354 USE(instr);
8355 return 0;
8356}
Ben Murdochc5610432016-08-08 18:44:38 +01008357
Ben Murdoch61f157c2016-09-16 13:49:30 +01008358EVALUATE(CUSE) {
8359 UNIMPLEMENTED();
8360 USE(instr);
8361 return 0;
8362}
Ben Murdochc5610432016-08-08 18:44:38 +01008363
Ben Murdoch61f157c2016-09-16 13:49:30 +01008364EVALUATE(SRST) {
8365 UNIMPLEMENTED();
8366 USE(instr);
8367 return 0;
8368}
Ben Murdochc5610432016-08-08 18:44:38 +01008369
Ben Murdoch61f157c2016-09-16 13:49:30 +01008370EVALUATE(XSCH) {
8371 UNIMPLEMENTED();
8372 USE(instr);
8373 return 0;
8374}
Ben Murdochc5610432016-08-08 18:44:38 +01008375
Ben Murdoch61f157c2016-09-16 13:49:30 +01008376EVALUATE(STCKE) {
8377 UNIMPLEMENTED();
8378 USE(instr);
8379 return 0;
8380}
Ben Murdochc5610432016-08-08 18:44:38 +01008381
Ben Murdoch61f157c2016-09-16 13:49:30 +01008382EVALUATE(STCKF) {
8383 UNIMPLEMENTED();
8384 USE(instr);
8385 return 0;
8386}
Ben Murdochc5610432016-08-08 18:44:38 +01008387
Ben Murdoch61f157c2016-09-16 13:49:30 +01008388EVALUATE(SRNM) {
8389 UNIMPLEMENTED();
8390 USE(instr);
8391 return 0;
8392}
Ben Murdochc5610432016-08-08 18:44:38 +01008393
Ben Murdoch61f157c2016-09-16 13:49:30 +01008394EVALUATE(STFPC) {
8395 UNIMPLEMENTED();
8396 USE(instr);
8397 return 0;
8398}
Ben Murdochc5610432016-08-08 18:44:38 +01008399
Ben Murdoch61f157c2016-09-16 13:49:30 +01008400EVALUATE(LFPC) {
8401 UNIMPLEMENTED();
8402 USE(instr);
8403 return 0;
8404}
Ben Murdochc5610432016-08-08 18:44:38 +01008405
Ben Murdoch61f157c2016-09-16 13:49:30 +01008406EVALUATE(TRE) {
8407 UNIMPLEMENTED();
8408 USE(instr);
8409 return 0;
8410}
Ben Murdochc5610432016-08-08 18:44:38 +01008411
Ben Murdoch61f157c2016-09-16 13:49:30 +01008412EVALUATE(CUUTF) {
8413 UNIMPLEMENTED();
8414 USE(instr);
8415 return 0;
8416}
Ben Murdochc5610432016-08-08 18:44:38 +01008417
Ben Murdoch61f157c2016-09-16 13:49:30 +01008418EVALUATE(CUTFU) {
8419 UNIMPLEMENTED();
8420 USE(instr);
8421 return 0;
8422}
Ben Murdochc5610432016-08-08 18:44:38 +01008423
Ben Murdoch61f157c2016-09-16 13:49:30 +01008424EVALUATE(STFLE) {
8425 UNIMPLEMENTED();
8426 USE(instr);
8427 return 0;
8428}
Ben Murdochc5610432016-08-08 18:44:38 +01008429
Ben Murdoch61f157c2016-09-16 13:49:30 +01008430EVALUATE(SRNMB) {
8431 UNIMPLEMENTED();
8432 USE(instr);
8433 return 0;
8434}
Ben Murdochc5610432016-08-08 18:44:38 +01008435
Ben Murdoch61f157c2016-09-16 13:49:30 +01008436EVALUATE(SRNMT) {
8437 UNIMPLEMENTED();
8438 USE(instr);
8439 return 0;
8440}
Ben Murdochc5610432016-08-08 18:44:38 +01008441
Ben Murdoch61f157c2016-09-16 13:49:30 +01008442EVALUATE(LFAS) {
8443 UNIMPLEMENTED();
8444 USE(instr);
8445 return 0;
8446}
Ben Murdochc5610432016-08-08 18:44:38 +01008447
Ben Murdoch61f157c2016-09-16 13:49:30 +01008448EVALUATE(PPA) {
8449 UNIMPLEMENTED();
8450 USE(instr);
8451 return 0;
8452}
Ben Murdochc5610432016-08-08 18:44:38 +01008453
Ben Murdoch61f157c2016-09-16 13:49:30 +01008454EVALUATE(ETND) {
8455 UNIMPLEMENTED();
8456 USE(instr);
8457 return 0;
8458}
Ben Murdochc5610432016-08-08 18:44:38 +01008459
Ben Murdoch61f157c2016-09-16 13:49:30 +01008460EVALUATE(TEND) {
8461 UNIMPLEMENTED();
8462 USE(instr);
8463 return 0;
8464}
Ben Murdochc5610432016-08-08 18:44:38 +01008465
Ben Murdoch61f157c2016-09-16 13:49:30 +01008466EVALUATE(NIAI) {
8467 UNIMPLEMENTED();
8468 USE(instr);
8469 return 0;
8470}
Ben Murdochc5610432016-08-08 18:44:38 +01008471
Ben Murdoch61f157c2016-09-16 13:49:30 +01008472EVALUATE(TABORT) {
8473 UNIMPLEMENTED();
8474 USE(instr);
8475 return 0;
8476}
Ben Murdochc5610432016-08-08 18:44:38 +01008477
Ben Murdoch61f157c2016-09-16 13:49:30 +01008478EVALUATE(TRAP4) {
8479 DCHECK_OPCODE(TRAP4);
8480 int length = 4;
8481 // whack the space of the caller allocated stack
8482 int64_t sp_addr = get_register(sp);
8483 for (int i = 0; i < kCalleeRegisterSaveAreaSize / kPointerSize; ++i) {
8484 // we dont want to whack the RA (r14)
8485 if (i != 14) (reinterpret_cast<intptr_t*>(sp_addr))[i] = 0xdeadbabe;
8486 }
8487 SoftwareInterrupt(instr);
8488 return length;
8489}
Ben Murdochc5610432016-08-08 18:44:38 +01008490
8491EVALUATE(LPEBR) {
8492 DCHECK_OPCODE(LPEBR);
8493 DECODE_RRE_INSTRUCTION(r1, r2);
8494 float fr1_val = get_float32_from_d_register(r1);
8495 float fr2_val = get_float32_from_d_register(r2);
8496 fr1_val = std::fabs(fr2_val);
8497 set_d_register_from_float32(r1, fr1_val);
8498 if (fr2_val != fr2_val) { // input is NaN
8499 condition_reg_ = CC_OF;
8500 } else if (fr2_val == 0) {
8501 condition_reg_ = CC_EQ;
8502 } else {
8503 condition_reg_ = CC_GT;
8504 }
8505
8506 return length;
8507}
8508
Ben Murdoch61f157c2016-09-16 13:49:30 +01008509EVALUATE(LNEBR) {
8510 UNIMPLEMENTED();
8511 USE(instr);
8512 return 0;
8513}
Ben Murdochc5610432016-08-08 18:44:38 +01008514
8515EVALUATE(LTEBR) {
8516 DCHECK_OPCODE(LTEBR);
8517 DECODE_RRE_INSTRUCTION(r1, r2);
8518 int64_t r2_val = get_d_register(r2);
8519 float fr2_val = get_float32_from_d_register(r2);
8520 SetS390ConditionCode<float>(fr2_val, 0.0);
8521 set_d_register(r1, r2_val);
8522 return length;
8523}
8524
Ben Murdoch61f157c2016-09-16 13:49:30 +01008525EVALUATE(LCEBR) {
8526 UNIMPLEMENTED();
8527 USE(instr);
8528 return 0;
8529}
Ben Murdochc5610432016-08-08 18:44:38 +01008530
8531EVALUATE(LDEBR) {
8532 DCHECK_OPCODE(LDEBR);
8533 DECODE_RRE_INSTRUCTION(r1, r2);
8534 float fp_val = get_float32_from_d_register(r2);
8535 double db_val = static_cast<double>(fp_val);
8536 set_d_register_from_double(r1, db_val);
8537 return length;
8538}
8539
Ben Murdoch61f157c2016-09-16 13:49:30 +01008540EVALUATE(LXDBR) {
8541 UNIMPLEMENTED();
8542 USE(instr);
8543 return 0;
8544}
Ben Murdochc5610432016-08-08 18:44:38 +01008545
Ben Murdoch61f157c2016-09-16 13:49:30 +01008546EVALUATE(LXEBR) {
8547 UNIMPLEMENTED();
8548 USE(instr);
8549 return 0;
8550}
Ben Murdochc5610432016-08-08 18:44:38 +01008551
Ben Murdoch61f157c2016-09-16 13:49:30 +01008552EVALUATE(MXDBR) {
8553 UNIMPLEMENTED();
8554 USE(instr);
8555 return 0;
8556}
Ben Murdochc5610432016-08-08 18:44:38 +01008557
Ben Murdoch61f157c2016-09-16 13:49:30 +01008558EVALUATE(KEBR) {
8559 UNIMPLEMENTED();
8560 USE(instr);
8561 return 0;
8562}
Ben Murdochc5610432016-08-08 18:44:38 +01008563
8564EVALUATE(CEBR) {
8565 DCHECK_OPCODE(CEBR);
8566 DECODE_RRE_INSTRUCTION(r1, r2);
8567 float fr1_val = get_float32_from_d_register(r1);
8568 float fr2_val = get_float32_from_d_register(r2);
8569 if (isNaN(fr1_val) || isNaN(fr2_val)) {
8570 condition_reg_ = CC_OF;
8571 } else {
8572 SetS390ConditionCode<float>(fr1_val, fr2_val);
8573 }
8574
8575 return length;
8576}
8577
8578EVALUATE(AEBR) {
8579 DCHECK_OPCODE(AEBR);
8580 DECODE_RRE_INSTRUCTION(r1, r2);
8581 float fr1_val = get_float32_from_d_register(r1);
8582 float fr2_val = get_float32_from_d_register(r2);
8583 fr1_val += fr2_val;
8584 set_d_register_from_float32(r1, fr1_val);
8585 SetS390ConditionCode<float>(fr1_val, 0);
8586
8587 return length;
8588}
8589
8590EVALUATE(SEBR) {
8591 DCHECK_OPCODE(SEBR);
8592 DECODE_RRE_INSTRUCTION(r1, r2);
8593 float fr1_val = get_float32_from_d_register(r1);
8594 float fr2_val = get_float32_from_d_register(r2);
8595 fr1_val -= fr2_val;
8596 set_d_register_from_float32(r1, fr1_val);
8597 SetS390ConditionCode<float>(fr1_val, 0);
8598
8599 return length;
8600}
8601
Ben Murdoch61f157c2016-09-16 13:49:30 +01008602EVALUATE(MDEBR) {
8603 UNIMPLEMENTED();
8604 USE(instr);
8605 return 0;
8606}
Ben Murdochc5610432016-08-08 18:44:38 +01008607
8608EVALUATE(DEBR) {
8609 DCHECK_OPCODE(DEBR);
8610 DECODE_RRE_INSTRUCTION(r1, r2);
8611 float fr1_val = get_float32_from_d_register(r1);
8612 float fr2_val = get_float32_from_d_register(r2);
8613 fr1_val /= fr2_val;
8614 set_d_register_from_float32(r1, fr1_val);
8615 SetS390ConditionCode<float>(fr1_val, 0);
8616
8617 return length;
8618}
8619
Ben Murdoch61f157c2016-09-16 13:49:30 +01008620EVALUATE(MAEBR) {
8621 UNIMPLEMENTED();
8622 USE(instr);
8623 return 0;
8624}
Ben Murdochc5610432016-08-08 18:44:38 +01008625
Ben Murdoch61f157c2016-09-16 13:49:30 +01008626EVALUATE(MSEBR) {
8627 UNIMPLEMENTED();
8628 USE(instr);
8629 return 0;
8630}
Ben Murdochc5610432016-08-08 18:44:38 +01008631
8632EVALUATE(LPDBR) {
8633 DCHECK_OPCODE(LPDBR);
8634 DECODE_RRE_INSTRUCTION(r1, r2);
8635 double r1_val = get_double_from_d_register(r1);
8636 double r2_val = get_double_from_d_register(r2);
8637 r1_val = std::fabs(r2_val);
8638 set_d_register_from_double(r1, r1_val);
8639 if (r2_val != r2_val) { // input is NaN
8640 condition_reg_ = CC_OF;
8641 } else if (r2_val == 0) {
8642 condition_reg_ = CC_EQ;
8643 } else {
8644 condition_reg_ = CC_GT;
8645 }
8646 return length;
8647}
8648
Ben Murdoch61f157c2016-09-16 13:49:30 +01008649EVALUATE(LNDBR) {
8650 UNIMPLEMENTED();
8651 USE(instr);
8652 return 0;
8653}
Ben Murdochc5610432016-08-08 18:44:38 +01008654
8655EVALUATE(LTDBR) {
8656 DCHECK_OPCODE(LTDBR);
8657 DECODE_RRE_INSTRUCTION(r1, r2);
8658 int64_t r2_val = get_d_register(r2);
8659 SetS390ConditionCode<double>(bit_cast<double, int64_t>(r2_val), 0.0);
8660 set_d_register(r1, r2_val);
8661 return length;
8662}
8663
8664EVALUATE(LCDBR) {
8665 DCHECK_OPCODE(LCDBR);
8666 DECODE_RRE_INSTRUCTION(r1, r2);
8667 double r1_val = get_double_from_d_register(r1);
8668 double r2_val = get_double_from_d_register(r2);
8669 r1_val = -r2_val;
8670 set_d_register_from_double(r1, r1_val);
8671 if (r2_val != r2_val) { // input is NaN
8672 condition_reg_ = CC_OF;
8673 } else if (r2_val == 0) {
8674 condition_reg_ = CC_EQ;
8675 } else if (r2_val < 0) {
8676 condition_reg_ = CC_LT;
8677 } else if (r2_val > 0) {
8678 condition_reg_ = CC_GT;
8679 }
8680 return length;
8681}
8682
Ben Murdoch61f157c2016-09-16 13:49:30 +01008683EVALUATE(SQEBR) {
8684 DCHECK_OPCODE(SQEBR);
8685 DECODE_RRE_INSTRUCTION(r1, r2);
8686 float fr1_val = get_float32_from_d_register(r1);
8687 float fr2_val = get_float32_from_d_register(r2);
8688 fr1_val = std::sqrt(fr2_val);
8689 set_d_register_from_float32(r1, fr1_val);
8690 return length;
8691}
Ben Murdochc5610432016-08-08 18:44:38 +01008692
Ben Murdoch61f157c2016-09-16 13:49:30 +01008693EVALUATE(SQDBR) {
8694 DCHECK_OPCODE(SQDBR);
8695 DECODE_RRE_INSTRUCTION(r1, r2);
8696 double r1_val = get_double_from_d_register(r1);
8697 double r2_val = get_double_from_d_register(r2);
8698 r1_val = std::sqrt(r2_val);
8699 set_d_register_from_double(r1, r1_val);
8700 return length;
8701}
Ben Murdochc5610432016-08-08 18:44:38 +01008702
Ben Murdoch61f157c2016-09-16 13:49:30 +01008703EVALUATE(SQXBR) {
8704 UNIMPLEMENTED();
8705 USE(instr);
8706 return 0;
8707}
Ben Murdochc5610432016-08-08 18:44:38 +01008708
Ben Murdoch61f157c2016-09-16 13:49:30 +01008709EVALUATE(MEEBR) {
8710 DCHECK_OPCODE(MEEBR);
8711 DECODE_RRE_INSTRUCTION(r1, r2);
8712 float fr1_val = get_float32_from_d_register(r1);
8713 float fr2_val = get_float32_from_d_register(r2);
8714 fr1_val *= fr2_val;
8715 set_d_register_from_float32(r1, fr1_val);
8716 SetS390ConditionCode<float>(fr1_val, 0);
8717 return length;
8718}
Ben Murdochc5610432016-08-08 18:44:38 +01008719
Ben Murdoch61f157c2016-09-16 13:49:30 +01008720EVALUATE(KDBR) {
8721 UNIMPLEMENTED();
8722 USE(instr);
8723 return 0;
8724}
Ben Murdochc5610432016-08-08 18:44:38 +01008725
Ben Murdoch61f157c2016-09-16 13:49:30 +01008726EVALUATE(CDBR) {
8727 DCHECK_OPCODE(CDBR);
8728 DECODE_RRE_INSTRUCTION(r1, r2);
8729 double r1_val = get_double_from_d_register(r1);
8730 double r2_val = get_double_from_d_register(r2);
8731 if (isNaN(r1_val) || isNaN(r2_val)) {
8732 condition_reg_ = CC_OF;
8733 } else {
8734 SetS390ConditionCode<double>(r1_val, r2_val);
8735 }
8736 return length;
8737}
Ben Murdochc5610432016-08-08 18:44:38 +01008738
Ben Murdoch61f157c2016-09-16 13:49:30 +01008739EVALUATE(ADBR) {
8740 DCHECK_OPCODE(ADBR);
8741 DECODE_RRE_INSTRUCTION(r1, r2);
8742 double r1_val = get_double_from_d_register(r1);
8743 double r2_val = get_double_from_d_register(r2);
8744 r1_val += r2_val;
8745 set_d_register_from_double(r1, r1_val);
8746 SetS390ConditionCode<double>(r1_val, 0);
8747 return length;
8748}
Ben Murdochc5610432016-08-08 18:44:38 +01008749
Ben Murdoch61f157c2016-09-16 13:49:30 +01008750EVALUATE(SDBR) {
8751 DCHECK_OPCODE(SDBR);
8752 DECODE_RRE_INSTRUCTION(r1, r2);
8753 double r1_val = get_double_from_d_register(r1);
8754 double r2_val = get_double_from_d_register(r2);
8755 r1_val -= r2_val;
8756 set_d_register_from_double(r1, r1_val);
8757 SetS390ConditionCode<double>(r1_val, 0);
8758 return length;
8759}
Ben Murdochc5610432016-08-08 18:44:38 +01008760
Ben Murdoch61f157c2016-09-16 13:49:30 +01008761EVALUATE(MDBR) {
8762 DCHECK_OPCODE(MDBR);
8763 DECODE_RRE_INSTRUCTION(r1, r2);
8764 double r1_val = get_double_from_d_register(r1);
8765 double r2_val = get_double_from_d_register(r2);
8766 r1_val *= r2_val;
8767 set_d_register_from_double(r1, r1_val);
8768 SetS390ConditionCode<double>(r1_val, 0);
8769 return length;
8770}
Ben Murdochc5610432016-08-08 18:44:38 +01008771
Ben Murdoch61f157c2016-09-16 13:49:30 +01008772EVALUATE(DDBR) {
8773 DCHECK_OPCODE(DDBR);
8774 DECODE_RRE_INSTRUCTION(r1, r2);
8775 double r1_val = get_double_from_d_register(r1);
8776 double r2_val = get_double_from_d_register(r2);
8777 r1_val /= r2_val;
8778 set_d_register_from_double(r1, r1_val);
8779 SetS390ConditionCode<double>(r1_val, 0);
8780 return length;
8781}
Ben Murdochc5610432016-08-08 18:44:38 +01008782
Ben Murdoch61f157c2016-09-16 13:49:30 +01008783EVALUATE(MADBR) {
8784 DCHECK_OPCODE(MADBR);
8785 DECODE_RRD_INSTRUCTION(r1, r2, r3);
8786 double r1_val = get_double_from_d_register(r1);
8787 double r2_val = get_double_from_d_register(r2);
8788 double r3_val = get_double_from_d_register(r3);
8789 r1_val += r2_val * r3_val;
8790 set_d_register_from_double(r1, r1_val);
8791 SetS390ConditionCode<double>(r1_val, 0);
8792 return length;
8793}
Ben Murdochc5610432016-08-08 18:44:38 +01008794
Ben Murdoch61f157c2016-09-16 13:49:30 +01008795EVALUATE(MSDBR) {
8796 UNIMPLEMENTED();
8797 USE(instr);
8798 return 0;
8799}
Ben Murdochc5610432016-08-08 18:44:38 +01008800
Ben Murdoch61f157c2016-09-16 13:49:30 +01008801EVALUATE(LPXBR) {
8802 UNIMPLEMENTED();
8803 USE(instr);
8804 return 0;
8805}
Ben Murdochc5610432016-08-08 18:44:38 +01008806
Ben Murdoch61f157c2016-09-16 13:49:30 +01008807EVALUATE(LNXBR) {
8808 UNIMPLEMENTED();
8809 USE(instr);
8810 return 0;
8811}
Ben Murdochc5610432016-08-08 18:44:38 +01008812
Ben Murdoch61f157c2016-09-16 13:49:30 +01008813EVALUATE(LTXBR) {
8814 UNIMPLEMENTED();
8815 USE(instr);
8816 return 0;
8817}
Ben Murdochc5610432016-08-08 18:44:38 +01008818
Ben Murdoch61f157c2016-09-16 13:49:30 +01008819EVALUATE(LCXBR) {
8820 UNIMPLEMENTED();
8821 USE(instr);
8822 return 0;
8823}
Ben Murdochc5610432016-08-08 18:44:38 +01008824
Ben Murdoch61f157c2016-09-16 13:49:30 +01008825EVALUATE(LEDBRA) {
8826 DCHECK_OPCODE(LEDBRA);
8827 DECODE_RRE_INSTRUCTION(r1, r2);
8828 double r2_val = get_double_from_d_register(r2);
8829 set_d_register_from_float32(r1, static_cast<float>(r2_val));
8830 return length;
8831}
Ben Murdochc5610432016-08-08 18:44:38 +01008832
Ben Murdoch61f157c2016-09-16 13:49:30 +01008833EVALUATE(LDXBRA) {
8834 UNIMPLEMENTED();
8835 USE(instr);
8836 return 0;
8837}
Ben Murdochc5610432016-08-08 18:44:38 +01008838
Ben Murdoch61f157c2016-09-16 13:49:30 +01008839EVALUATE(LEXBRA) {
8840 UNIMPLEMENTED();
8841 USE(instr);
8842 return 0;
8843}
Ben Murdochc5610432016-08-08 18:44:38 +01008844
Ben Murdoch61f157c2016-09-16 13:49:30 +01008845EVALUATE(FIXBRA) {
8846 UNIMPLEMENTED();
8847 USE(instr);
8848 return 0;
8849}
Ben Murdochc5610432016-08-08 18:44:38 +01008850
Ben Murdoch61f157c2016-09-16 13:49:30 +01008851EVALUATE(KXBR) {
8852 UNIMPLEMENTED();
8853 USE(instr);
8854 return 0;
8855}
Ben Murdochc5610432016-08-08 18:44:38 +01008856
Ben Murdoch61f157c2016-09-16 13:49:30 +01008857EVALUATE(CXBR) {
8858 UNIMPLEMENTED();
8859 USE(instr);
8860 return 0;
8861}
Ben Murdochc5610432016-08-08 18:44:38 +01008862
Ben Murdoch61f157c2016-09-16 13:49:30 +01008863EVALUATE(AXBR) {
8864 UNIMPLEMENTED();
8865 USE(instr);
8866 return 0;
8867}
Ben Murdochc5610432016-08-08 18:44:38 +01008868
Ben Murdoch61f157c2016-09-16 13:49:30 +01008869EVALUATE(SXBR) {
8870 UNIMPLEMENTED();
8871 USE(instr);
8872 return 0;
8873}
Ben Murdochc5610432016-08-08 18:44:38 +01008874
Ben Murdoch61f157c2016-09-16 13:49:30 +01008875EVALUATE(MXBR) {
8876 UNIMPLEMENTED();
8877 USE(instr);
8878 return 0;
8879}
Ben Murdochc5610432016-08-08 18:44:38 +01008880
Ben Murdoch61f157c2016-09-16 13:49:30 +01008881EVALUATE(DXBR) {
8882 UNIMPLEMENTED();
8883 USE(instr);
8884 return 0;
8885}
Ben Murdochc5610432016-08-08 18:44:38 +01008886
Ben Murdoch61f157c2016-09-16 13:49:30 +01008887EVALUATE(TBEDR) {
8888 UNIMPLEMENTED();
8889 USE(instr);
8890 return 0;
8891}
Ben Murdochc5610432016-08-08 18:44:38 +01008892
Ben Murdoch61f157c2016-09-16 13:49:30 +01008893EVALUATE(TBDR) {
8894 UNIMPLEMENTED();
8895 USE(instr);
8896 return 0;
8897}
Ben Murdochc5610432016-08-08 18:44:38 +01008898
Ben Murdoch61f157c2016-09-16 13:49:30 +01008899EVALUATE(DIEBR) {
8900 UNIMPLEMENTED();
8901 USE(instr);
8902 return 0;
8903}
Ben Murdochc5610432016-08-08 18:44:38 +01008904
Ben Murdoch61f157c2016-09-16 13:49:30 +01008905EVALUATE(FIEBRA) {
8906 DCHECK_OPCODE(FIEBRA);
8907 DECODE_RRF_E_INSTRUCTION(r1, r2, m3, m4);
8908 float r2_val = get_float32_from_d_register(r2);
8909 CHECK(m4 == 0);
8910 switch (m3) {
8911 case Assembler::FIDBRA_ROUND_TO_NEAREST_AWAY_FROM_0:
8912 set_d_register_from_float32(r1, round(r2_val));
8913 break;
8914 case Assembler::FIDBRA_ROUND_TOWARD_0:
8915 set_d_register_from_float32(r1, trunc(r2_val));
8916 break;
8917 case Assembler::FIDBRA_ROUND_TOWARD_POS_INF:
8918 set_d_register_from_float32(r1, std::ceil(r2_val));
8919 break;
8920 case Assembler::FIDBRA_ROUND_TOWARD_NEG_INF:
8921 set_d_register_from_float32(r1, std::floor(r2_val));
8922 break;
8923 default:
8924 UNIMPLEMENTED();
8925 break;
8926 }
8927 return length;
8928}
Ben Murdochc5610432016-08-08 18:44:38 +01008929
Ben Murdoch61f157c2016-09-16 13:49:30 +01008930EVALUATE(THDER) {
8931 UNIMPLEMENTED();
8932 USE(instr);
8933 return 0;
8934}
Ben Murdochc5610432016-08-08 18:44:38 +01008935
Ben Murdoch61f157c2016-09-16 13:49:30 +01008936EVALUATE(THDR) {
8937 UNIMPLEMENTED();
8938 USE(instr);
8939 return 0;
8940}
Ben Murdochc5610432016-08-08 18:44:38 +01008941
Ben Murdoch61f157c2016-09-16 13:49:30 +01008942EVALUATE(DIDBR) {
8943 UNIMPLEMENTED();
8944 USE(instr);
8945 return 0;
8946}
Ben Murdochc5610432016-08-08 18:44:38 +01008947
Ben Murdoch61f157c2016-09-16 13:49:30 +01008948EVALUATE(FIDBRA) {
8949 DCHECK_OPCODE(FIDBRA);
8950 DECODE_RRF_E_INSTRUCTION(r1, r2, m3, m4);
8951 double r2_val = get_double_from_d_register(r2);
8952 CHECK(m4 == 0);
8953 switch (m3) {
8954 case Assembler::FIDBRA_ROUND_TO_NEAREST_AWAY_FROM_0:
8955 set_d_register_from_double(r1, round(r2_val));
8956 break;
8957 case Assembler::FIDBRA_ROUND_TOWARD_0:
8958 set_d_register_from_double(r1, trunc(r2_val));
8959 break;
8960 case Assembler::FIDBRA_ROUND_TOWARD_POS_INF:
8961 set_d_register_from_double(r1, std::ceil(r2_val));
8962 break;
8963 case Assembler::FIDBRA_ROUND_TOWARD_NEG_INF:
8964 set_d_register_from_double(r1, std::floor(r2_val));
8965 break;
8966 default:
8967 UNIMPLEMENTED();
8968 break;
8969 }
8970 return length;
8971}
Ben Murdochc5610432016-08-08 18:44:38 +01008972
Ben Murdoch61f157c2016-09-16 13:49:30 +01008973EVALUATE(LXR) {
8974 UNIMPLEMENTED();
8975 USE(instr);
8976 return 0;
8977}
Ben Murdochc5610432016-08-08 18:44:38 +01008978
Ben Murdoch61f157c2016-09-16 13:49:30 +01008979EVALUATE(LPDFR) {
8980 UNIMPLEMENTED();
8981 USE(instr);
8982 return 0;
8983}
Ben Murdochc5610432016-08-08 18:44:38 +01008984
Ben Murdoch61f157c2016-09-16 13:49:30 +01008985EVALUATE(LNDFR) {
8986 UNIMPLEMENTED();
8987 USE(instr);
8988 return 0;
8989}
Ben Murdochc5610432016-08-08 18:44:38 +01008990
Ben Murdoch61f157c2016-09-16 13:49:30 +01008991EVALUATE(LCDFR) {
8992 UNIMPLEMENTED();
8993 USE(instr);
8994 return 0;
8995}
Ben Murdochc5610432016-08-08 18:44:38 +01008996
Ben Murdoch61f157c2016-09-16 13:49:30 +01008997EVALUATE(LZER) {
8998 UNIMPLEMENTED();
8999 USE(instr);
9000 return 0;
9001}
Ben Murdochc5610432016-08-08 18:44:38 +01009002
Ben Murdoch61f157c2016-09-16 13:49:30 +01009003EVALUATE(LZDR) {
9004 DCHECK_OPCODE(LZDR);
9005 DECODE_RRE_INSTRUCTION_NO_R2(r1);
9006 set_d_register_from_double(r1, 0.0);
9007 return length;
9008}
Ben Murdochc5610432016-08-08 18:44:38 +01009009
Ben Murdoch61f157c2016-09-16 13:49:30 +01009010EVALUATE(LZXR) {
9011 UNIMPLEMENTED();
9012 USE(instr);
9013 return 0;
9014}
Ben Murdochc5610432016-08-08 18:44:38 +01009015
Ben Murdoch61f157c2016-09-16 13:49:30 +01009016EVALUATE(SFPC) {
9017 UNIMPLEMENTED();
9018 USE(instr);
9019 return 0;
9020}
Ben Murdochc5610432016-08-08 18:44:38 +01009021
Ben Murdoch61f157c2016-09-16 13:49:30 +01009022EVALUATE(SFASR) {
9023 UNIMPLEMENTED();
9024 USE(instr);
9025 return 0;
9026}
Ben Murdochc5610432016-08-08 18:44:38 +01009027
Ben Murdoch61f157c2016-09-16 13:49:30 +01009028EVALUATE(EFPC) {
9029 UNIMPLEMENTED();
9030 USE(instr);
9031 return 0;
9032}
Ben Murdochc5610432016-08-08 18:44:38 +01009033
Ben Murdoch61f157c2016-09-16 13:49:30 +01009034EVALUATE(CELFBR) {
9035 DCHECK_OPCODE(CELFBR);
9036 DECODE_RRE_INSTRUCTION(r1, r2);
9037 uint32_t r2_val = get_low_register<uint32_t>(r2);
9038 float r1_val = static_cast<float>(r2_val);
9039 set_d_register_from_float32(r1, r1_val);
9040 return length;
9041}
Ben Murdochc5610432016-08-08 18:44:38 +01009042
Ben Murdoch61f157c2016-09-16 13:49:30 +01009043EVALUATE(CDLFBR) {
9044 DCHECK_OPCODE(CDLFBR);
9045 DECODE_RRE_INSTRUCTION(r1, r2);
9046 uint32_t r2_val = get_low_register<uint32_t>(r2);
9047 double r1_val = static_cast<double>(r2_val);
9048 set_d_register_from_double(r1, r1_val);
9049 return length;
9050}
Ben Murdochc5610432016-08-08 18:44:38 +01009051
Ben Murdoch61f157c2016-09-16 13:49:30 +01009052EVALUATE(CXLFBR) {
9053 UNIMPLEMENTED();
9054 USE(instr);
9055 return 0;
9056}
Ben Murdochc5610432016-08-08 18:44:38 +01009057
Ben Murdoch61f157c2016-09-16 13:49:30 +01009058EVALUATE(CEFBRA) {
9059 DCHECK_OPCODE(CEFBRA);
9060 DECODE_RRE_INSTRUCTION(r1, r2);
9061 int32_t fr2_val = get_low_register<int32_t>(r2);
9062 float fr1_val = static_cast<float>(fr2_val);
9063 set_d_register_from_float32(r1, fr1_val);
9064 return length;
9065}
Ben Murdochc5610432016-08-08 18:44:38 +01009066
Ben Murdoch61f157c2016-09-16 13:49:30 +01009067EVALUATE(CDFBRA) {
9068 DCHECK_OPCODE(CDFBRA);
9069 DECODE_RRE_INSTRUCTION(r1, r2);
9070 int32_t r2_val = get_low_register<int32_t>(r2);
9071 double r1_val = static_cast<double>(r2_val);
9072 set_d_register_from_double(r1, r1_val);
9073 return length;
9074}
Ben Murdochc5610432016-08-08 18:44:38 +01009075
Ben Murdoch61f157c2016-09-16 13:49:30 +01009076EVALUATE(CXFBRA) {
9077 UNIMPLEMENTED();
9078 USE(instr);
9079 return 0;
9080}
Ben Murdochc5610432016-08-08 18:44:38 +01009081
Ben Murdoch61f157c2016-09-16 13:49:30 +01009082EVALUATE(CFEBRA) {
9083 DCHECK_OPCODE(CFEBRA);
9084 DECODE_RRE_INSTRUCTION_M3(r1, r2, mask_val);
9085 float r2_fval = get_float32_from_d_register(r2);
9086 int32_t r1_val = 0;
Ben Murdochc5610432016-08-08 18:44:38 +01009087
Ben Murdoch61f157c2016-09-16 13:49:30 +01009088 SetS390RoundConditionCode(r2_fval, INT32_MAX, INT32_MIN);
Ben Murdochc5610432016-08-08 18:44:38 +01009089
Ben Murdoch61f157c2016-09-16 13:49:30 +01009090 switch (mask_val) {
9091 case CURRENT_ROUNDING_MODE:
9092 case ROUND_TO_PREPARE_FOR_SHORTER_PRECISION: {
9093 r1_val = static_cast<int32_t>(r2_fval);
9094 break;
9095 }
9096 case ROUND_TO_NEAREST_WITH_TIES_AWAY_FROM_0: {
9097 float ceil_val = std::ceil(r2_fval);
9098 float floor_val = std::floor(r2_fval);
9099 float sub_val1 = std::fabs(r2_fval - floor_val);
9100 float sub_val2 = std::fabs(r2_fval - ceil_val);
9101 if (sub_val1 > sub_val2) {
9102 r1_val = static_cast<int32_t>(ceil_val);
9103 } else if (sub_val1 < sub_val2) {
9104 r1_val = static_cast<int32_t>(floor_val);
9105 } else { // round away from zero:
9106 if (r2_fval > 0.0) {
9107 r1_val = static_cast<int32_t>(ceil_val);
9108 } else {
9109 r1_val = static_cast<int32_t>(floor_val);
9110 }
9111 }
9112 break;
9113 }
9114 case ROUND_TO_NEAREST_WITH_TIES_TO_EVEN: {
9115 float ceil_val = std::ceil(r2_fval);
9116 float floor_val = std::floor(r2_fval);
9117 float sub_val1 = std::fabs(r2_fval - floor_val);
9118 float sub_val2 = std::fabs(r2_fval - ceil_val);
9119 if (sub_val1 > sub_val2) {
9120 r1_val = static_cast<int32_t>(ceil_val);
9121 } else if (sub_val1 < sub_val2) {
9122 r1_val = static_cast<int32_t>(floor_val);
9123 } else { // check which one is even:
9124 int32_t c_v = static_cast<int32_t>(ceil_val);
9125 int32_t f_v = static_cast<int32_t>(floor_val);
9126 if (f_v % 2 == 0)
9127 r1_val = f_v;
9128 else
9129 r1_val = c_v;
9130 }
9131 break;
9132 }
9133 case ROUND_TOWARD_0: {
9134 // check for overflow, cast r2_fval to 64bit integer
9135 // then check value within the range of INT_MIN and INT_MAX
9136 // and set condition code accordingly
9137 int64_t temp = static_cast<int64_t>(r2_fval);
9138 if (temp < INT_MIN || temp > INT_MAX) {
9139 condition_reg_ = CC_OF;
9140 }
9141 r1_val = static_cast<int32_t>(r2_fval);
9142 break;
9143 }
9144 case ROUND_TOWARD_PLUS_INFINITE: {
9145 r1_val = static_cast<int32_t>(std::ceil(r2_fval));
9146 break;
9147 }
9148 case ROUND_TOWARD_MINUS_INFINITE: {
9149 // check for overflow, cast r2_fval to 64bit integer
9150 // then check value within the range of INT_MIN and INT_MAX
9151 // and set condition code accordingly
9152 int64_t temp = static_cast<int64_t>(std::floor(r2_fval));
9153 if (temp < INT_MIN || temp > INT_MAX) {
9154 condition_reg_ = CC_OF;
9155 }
9156 r1_val = static_cast<int32_t>(std::floor(r2_fval));
9157 break;
9158 }
9159 default:
9160 UNREACHABLE();
9161 }
9162 set_low_register(r1, r1_val);
9163 return length;
9164}
Ben Murdochc5610432016-08-08 18:44:38 +01009165
Ben Murdoch61f157c2016-09-16 13:49:30 +01009166EVALUATE(CFDBRA) {
9167 DCHECK_OPCODE(CFDBRA);
9168 DECODE_RRE_INSTRUCTION_M3(r1, r2, mask_val);
9169 double r2_val = get_double_from_d_register(r2);
9170 int32_t r1_val = 0;
Ben Murdochc5610432016-08-08 18:44:38 +01009171
Ben Murdoch61f157c2016-09-16 13:49:30 +01009172 SetS390RoundConditionCode(r2_val, INT32_MAX, INT32_MIN);
Ben Murdochc5610432016-08-08 18:44:38 +01009173
Ben Murdoch61f157c2016-09-16 13:49:30 +01009174 switch (mask_val) {
9175 case CURRENT_ROUNDING_MODE:
9176 case ROUND_TO_PREPARE_FOR_SHORTER_PRECISION: {
9177 r1_val = static_cast<int32_t>(r2_val);
9178 break;
9179 }
9180 case ROUND_TO_NEAREST_WITH_TIES_AWAY_FROM_0: {
9181 double ceil_val = std::ceil(r2_val);
9182 double floor_val = std::floor(r2_val);
9183 double sub_val1 = std::fabs(r2_val - floor_val);
9184 double sub_val2 = std::fabs(r2_val - ceil_val);
9185 if (sub_val1 > sub_val2) {
9186 r1_val = static_cast<int32_t>(ceil_val);
9187 } else if (sub_val1 < sub_val2) {
9188 r1_val = static_cast<int32_t>(floor_val);
9189 } else { // round away from zero:
9190 if (r2_val > 0.0) {
9191 r1_val = static_cast<int32_t>(ceil_val);
9192 } else {
9193 r1_val = static_cast<int32_t>(floor_val);
9194 }
9195 }
9196 break;
9197 }
9198 case ROUND_TO_NEAREST_WITH_TIES_TO_EVEN: {
9199 double ceil_val = std::ceil(r2_val);
9200 double floor_val = std::floor(r2_val);
9201 double sub_val1 = std::fabs(r2_val - floor_val);
9202 double sub_val2 = std::fabs(r2_val - ceil_val);
9203 if (sub_val1 > sub_val2) {
9204 r1_val = static_cast<int32_t>(ceil_val);
9205 } else if (sub_val1 < sub_val2) {
9206 r1_val = static_cast<int32_t>(floor_val);
9207 } else { // check which one is even:
9208 int32_t c_v = static_cast<int32_t>(ceil_val);
9209 int32_t f_v = static_cast<int32_t>(floor_val);
9210 if (f_v % 2 == 0)
9211 r1_val = f_v;
9212 else
9213 r1_val = c_v;
9214 }
9215 break;
9216 }
9217 case ROUND_TOWARD_0: {
9218 // check for overflow, cast r2_val to 64bit integer
9219 // then check value within the range of INT_MIN and INT_MAX
9220 // and set condition code accordingly
9221 int64_t temp = static_cast<int64_t>(r2_val);
9222 if (temp < INT_MIN || temp > INT_MAX) {
9223 condition_reg_ = CC_OF;
9224 }
9225 r1_val = static_cast<int32_t>(r2_val);
9226 break;
9227 }
9228 case ROUND_TOWARD_PLUS_INFINITE: {
9229 r1_val = static_cast<int32_t>(std::ceil(r2_val));
9230 break;
9231 }
9232 case ROUND_TOWARD_MINUS_INFINITE: {
9233 // check for overflow, cast r2_val to 64bit integer
9234 // then check value within the range of INT_MIN and INT_MAX
9235 // and set condition code accordingly
9236 int64_t temp = static_cast<int64_t>(std::floor(r2_val));
9237 if (temp < INT_MIN || temp > INT_MAX) {
9238 condition_reg_ = CC_OF;
9239 }
9240 r1_val = static_cast<int32_t>(std::floor(r2_val));
9241 break;
9242 }
9243 default:
9244 UNREACHABLE();
9245 }
9246 set_low_register(r1, r1_val);
9247 return length;
9248}
Ben Murdochc5610432016-08-08 18:44:38 +01009249
Ben Murdoch61f157c2016-09-16 13:49:30 +01009250EVALUATE(CFXBRA) {
9251 UNIMPLEMENTED();
9252 USE(instr);
9253 return 0;
9254}
Ben Murdochc5610432016-08-08 18:44:38 +01009255
Ben Murdoch61f157c2016-09-16 13:49:30 +01009256EVALUATE(CLFEBR) {
9257 DCHECK_OPCODE(CLFEBR);
9258 DECODE_RRE_INSTRUCTION(r1, r2);
9259 float r2_val = get_float32_from_d_register(r2);
9260 uint32_t r1_val = static_cast<uint32_t>(r2_val);
9261 set_low_register(r1, r1_val);
9262 SetS390ConvertConditionCode<double>(r2_val, r1_val, UINT32_MAX);
9263 return length;
9264}
Ben Murdochc5610432016-08-08 18:44:38 +01009265
Ben Murdoch61f157c2016-09-16 13:49:30 +01009266EVALUATE(CLFDBR) {
9267 DCHECK_OPCODE(CLFDBR);
9268 DECODE_RRE_INSTRUCTION(r1, r2);
9269 double r2_val = get_double_from_d_register(r2);
9270 uint32_t r1_val = static_cast<uint32_t>(r2_val);
9271 set_low_register(r1, r1_val);
9272 SetS390ConvertConditionCode<double>(r2_val, r1_val, UINT32_MAX);
9273 return length;
9274}
Ben Murdochc5610432016-08-08 18:44:38 +01009275
Ben Murdoch61f157c2016-09-16 13:49:30 +01009276EVALUATE(CLFXBR) {
9277 UNIMPLEMENTED();
9278 USE(instr);
9279 return 0;
9280}
Ben Murdochc5610432016-08-08 18:44:38 +01009281
Ben Murdoch61f157c2016-09-16 13:49:30 +01009282EVALUATE(CELGBR) {
9283 DCHECK_OPCODE(CELGBR);
9284 DECODE_RRE_INSTRUCTION(r1, r2);
9285 uint64_t r2_val = get_register(r2);
9286 float r1_val = static_cast<float>(r2_val);
9287 set_d_register_from_float32(r1, r1_val);
9288 return length;
9289}
Ben Murdochc5610432016-08-08 18:44:38 +01009290
Ben Murdoch61f157c2016-09-16 13:49:30 +01009291EVALUATE(CDLGBR) {
9292 DCHECK_OPCODE(CDLGBR);
9293 DECODE_RRE_INSTRUCTION(r1, r2);
9294 uint64_t r2_val = get_register(r2);
9295 double r1_val = static_cast<double>(r2_val);
9296 set_d_register_from_double(r1, r1_val);
9297 return length;
9298}
Ben Murdochc5610432016-08-08 18:44:38 +01009299
Ben Murdoch61f157c2016-09-16 13:49:30 +01009300EVALUATE(CXLGBR) {
9301 UNIMPLEMENTED();
9302 USE(instr);
9303 return 0;
9304}
Ben Murdochc5610432016-08-08 18:44:38 +01009305
Ben Murdoch61f157c2016-09-16 13:49:30 +01009306EVALUATE(CEGBRA) {
9307 DCHECK_OPCODE(CEGBRA);
9308 DECODE_RRE_INSTRUCTION(r1, r2);
9309 int64_t fr2_val = get_register(r2);
9310 float fr1_val = static_cast<float>(fr2_val);
9311 set_d_register_from_float32(r1, fr1_val);
9312 return length;
9313}
Ben Murdochc5610432016-08-08 18:44:38 +01009314
Ben Murdoch61f157c2016-09-16 13:49:30 +01009315EVALUATE(CDGBRA) {
9316 DCHECK_OPCODE(CDGBRA);
9317 DECODE_RRE_INSTRUCTION(r1, r2);
9318 int64_t r2_val = get_register(r2);
9319 double r1_val = static_cast<double>(r2_val);
9320 set_d_register_from_double(r1, r1_val);
9321 return length;
9322}
Ben Murdochc5610432016-08-08 18:44:38 +01009323
Ben Murdoch61f157c2016-09-16 13:49:30 +01009324EVALUATE(CXGBRA) {
9325 UNIMPLEMENTED();
9326 USE(instr);
9327 return 0;
9328}
Ben Murdochc5610432016-08-08 18:44:38 +01009329
Ben Murdoch61f157c2016-09-16 13:49:30 +01009330EVALUATE(CGEBRA) {
9331 DCHECK_OPCODE(CGEBRA);
9332 DECODE_RRE_INSTRUCTION_M3(r1, r2, mask_val);
9333 float r2_fval = get_float32_from_d_register(r2);
9334 int64_t r1_val = 0;
Ben Murdochc5610432016-08-08 18:44:38 +01009335
Ben Murdoch61f157c2016-09-16 13:49:30 +01009336 SetS390RoundConditionCode(r2_fval, INT64_MAX, INT64_MIN);
Ben Murdochc5610432016-08-08 18:44:38 +01009337
Ben Murdoch61f157c2016-09-16 13:49:30 +01009338 switch (mask_val) {
9339 case CURRENT_ROUNDING_MODE:
9340 case ROUND_TO_NEAREST_WITH_TIES_AWAY_FROM_0:
9341 case ROUND_TO_PREPARE_FOR_SHORTER_PRECISION: {
9342 UNIMPLEMENTED();
9343 break;
9344 }
9345 case ROUND_TO_NEAREST_WITH_TIES_TO_EVEN: {
9346 float ceil_val = std::ceil(r2_fval);
9347 float floor_val = std::floor(r2_fval);
9348 if (std::abs(r2_fval - floor_val) > std::abs(r2_fval - ceil_val)) {
9349 r1_val = static_cast<int64_t>(ceil_val);
9350 } else if (std::abs(r2_fval - floor_val) < std::abs(r2_fval - ceil_val)) {
9351 r1_val = static_cast<int64_t>(floor_val);
9352 } else { // check which one is even:
9353 int64_t c_v = static_cast<int64_t>(ceil_val);
9354 int64_t f_v = static_cast<int64_t>(floor_val);
9355 if (f_v % 2 == 0)
9356 r1_val = f_v;
9357 else
9358 r1_val = c_v;
9359 }
9360 break;
9361 }
9362 case ROUND_TOWARD_0: {
9363 r1_val = static_cast<int64_t>(r2_fval);
9364 break;
9365 }
9366 case ROUND_TOWARD_PLUS_INFINITE: {
9367 r1_val = static_cast<int64_t>(std::ceil(r2_fval));
9368 break;
9369 }
9370 case ROUND_TOWARD_MINUS_INFINITE: {
9371 r1_val = static_cast<int64_t>(std::floor(r2_fval));
9372 break;
9373 }
9374 default:
9375 UNREACHABLE();
9376 }
9377 set_register(r1, r1_val);
9378 return length;
9379}
Ben Murdochc5610432016-08-08 18:44:38 +01009380
Ben Murdoch61f157c2016-09-16 13:49:30 +01009381EVALUATE(CGDBRA) {
9382 DCHECK_OPCODE(CGDBRA);
9383 DECODE_RRE_INSTRUCTION_M3(r1, r2, mask_val);
9384 double r2_val = get_double_from_d_register(r2);
9385 int64_t r1_val = 0;
Ben Murdochc5610432016-08-08 18:44:38 +01009386
Ben Murdoch61f157c2016-09-16 13:49:30 +01009387 SetS390RoundConditionCode(r2_val, INT64_MAX, INT64_MIN);
Ben Murdochc5610432016-08-08 18:44:38 +01009388
Ben Murdoch61f157c2016-09-16 13:49:30 +01009389 switch (mask_val) {
9390 case CURRENT_ROUNDING_MODE:
9391 case ROUND_TO_NEAREST_WITH_TIES_AWAY_FROM_0:
9392 case ROUND_TO_PREPARE_FOR_SHORTER_PRECISION: {
9393 UNIMPLEMENTED();
9394 break;
9395 }
9396 case ROUND_TO_NEAREST_WITH_TIES_TO_EVEN: {
9397 double ceil_val = std::ceil(r2_val);
9398 double floor_val = std::floor(r2_val);
9399 if (std::abs(r2_val - floor_val) > std::abs(r2_val - ceil_val)) {
9400 r1_val = static_cast<int64_t>(ceil_val);
9401 } else if (std::abs(r2_val - floor_val) < std::abs(r2_val - ceil_val)) {
9402 r1_val = static_cast<int64_t>(floor_val);
9403 } else { // check which one is even:
9404 int64_t c_v = static_cast<int64_t>(ceil_val);
9405 int64_t f_v = static_cast<int64_t>(floor_val);
9406 if (f_v % 2 == 0)
9407 r1_val = f_v;
9408 else
9409 r1_val = c_v;
9410 }
9411 break;
9412 }
9413 case ROUND_TOWARD_0: {
9414 r1_val = static_cast<int64_t>(r2_val);
9415 break;
9416 }
9417 case ROUND_TOWARD_PLUS_INFINITE: {
9418 r1_val = static_cast<int64_t>(std::ceil(r2_val));
9419 break;
9420 }
9421 case ROUND_TOWARD_MINUS_INFINITE: {
9422 r1_val = static_cast<int64_t>(std::floor(r2_val));
9423 break;
9424 }
9425 default:
9426 UNREACHABLE();
9427 }
9428 set_register(r1, r1_val);
9429 return length;
9430}
Ben Murdochc5610432016-08-08 18:44:38 +01009431
Ben Murdoch61f157c2016-09-16 13:49:30 +01009432EVALUATE(CGXBRA) {
9433 UNIMPLEMENTED();
9434 USE(instr);
9435 return 0;
9436}
Ben Murdochc5610432016-08-08 18:44:38 +01009437
Ben Murdoch61f157c2016-09-16 13:49:30 +01009438EVALUATE(CLGEBR) {
9439 DCHECK_OPCODE(CLGEBR);
9440 DECODE_RRE_INSTRUCTION(r1, r2);
9441 float r2_val = get_float32_from_d_register(r2);
9442 uint64_t r1_val = static_cast<uint64_t>(r2_val);
9443 set_register(r1, r1_val);
9444 SetS390ConvertConditionCode<double>(r2_val, r1_val, UINT64_MAX);
9445 return length;
9446}
Ben Murdochc5610432016-08-08 18:44:38 +01009447
Ben Murdoch61f157c2016-09-16 13:49:30 +01009448EVALUATE(CLGDBR) {
9449 DCHECK_OPCODE(CLGDBR);
9450 DECODE_RRE_INSTRUCTION(r1, r2);
9451 double r2_val = get_double_from_d_register(r2);
9452 uint64_t r1_val = static_cast<uint64_t>(r2_val);
9453 set_register(r1, r1_val);
9454 SetS390ConvertConditionCode<double>(r2_val, r1_val, UINT64_MAX);
9455 return length;
9456}
Ben Murdochc5610432016-08-08 18:44:38 +01009457
Ben Murdoch61f157c2016-09-16 13:49:30 +01009458EVALUATE(CFER) {
9459 UNIMPLEMENTED();
9460 USE(instr);
9461 return 0;
9462}
Ben Murdochc5610432016-08-08 18:44:38 +01009463
Ben Murdoch61f157c2016-09-16 13:49:30 +01009464EVALUATE(CFDR) {
9465 UNIMPLEMENTED();
9466 USE(instr);
9467 return 0;
9468}
Ben Murdochc5610432016-08-08 18:44:38 +01009469
Ben Murdoch61f157c2016-09-16 13:49:30 +01009470EVALUATE(CFXR) {
9471 UNIMPLEMENTED();
9472 USE(instr);
9473 return 0;
9474}
Ben Murdochc5610432016-08-08 18:44:38 +01009475
Ben Murdoch61f157c2016-09-16 13:49:30 +01009476EVALUATE(LDGR) {
9477 DCHECK_OPCODE(LDGR);
9478 // Load FPR from GPR (L <- 64)
9479 DECODE_RRE_INSTRUCTION(r1, r2);
9480 uint64_t int_val = get_register(r2);
9481 // double double_val = bit_cast<double, uint64_t>(int_val);
9482 // set_d_register_from_double(rreInst->R1Value(), double_val);
9483 set_d_register(r1, int_val);
9484 return length;
9485}
Ben Murdochc5610432016-08-08 18:44:38 +01009486
Ben Murdoch61f157c2016-09-16 13:49:30 +01009487EVALUATE(CGER) {
9488 UNIMPLEMENTED();
9489 USE(instr);
9490 return 0;
9491}
Ben Murdochc5610432016-08-08 18:44:38 +01009492
Ben Murdoch61f157c2016-09-16 13:49:30 +01009493EVALUATE(CGDR) {
9494 UNIMPLEMENTED();
9495 USE(instr);
9496 return 0;
9497}
Ben Murdochc5610432016-08-08 18:44:38 +01009498
Ben Murdoch61f157c2016-09-16 13:49:30 +01009499EVALUATE(CGXR) {
9500 UNIMPLEMENTED();
9501 USE(instr);
9502 return 0;
9503}
Ben Murdochc5610432016-08-08 18:44:38 +01009504
Ben Murdoch61f157c2016-09-16 13:49:30 +01009505EVALUATE(LGDR) {
9506 DCHECK_OPCODE(LGDR);
9507 DECODE_RRE_INSTRUCTION(r1, r2);
9508 // Load GPR from FPR (64 <- L)
9509 int64_t double_val = get_d_register(r2);
9510 set_register(r1, double_val);
9511 return length;
9512}
Ben Murdochc5610432016-08-08 18:44:38 +01009513
Ben Murdoch61f157c2016-09-16 13:49:30 +01009514EVALUATE(MDTR) {
9515 UNIMPLEMENTED();
9516 USE(instr);
9517 return 0;
9518}
Ben Murdochc5610432016-08-08 18:44:38 +01009519
Ben Murdoch61f157c2016-09-16 13:49:30 +01009520EVALUATE(MDTRA) {
9521 UNIMPLEMENTED();
9522 USE(instr);
9523 return 0;
9524}
Ben Murdochc5610432016-08-08 18:44:38 +01009525
Ben Murdoch61f157c2016-09-16 13:49:30 +01009526EVALUATE(DDTRA) {
9527 UNIMPLEMENTED();
9528 USE(instr);
9529 return 0;
9530}
Ben Murdochc5610432016-08-08 18:44:38 +01009531
Ben Murdoch61f157c2016-09-16 13:49:30 +01009532EVALUATE(ADTRA) {
9533 UNIMPLEMENTED();
9534 USE(instr);
9535 return 0;
9536}
Ben Murdochc5610432016-08-08 18:44:38 +01009537
Ben Murdoch61f157c2016-09-16 13:49:30 +01009538EVALUATE(SDTRA) {
9539 UNIMPLEMENTED();
9540 USE(instr);
9541 return 0;
9542}
Ben Murdochc5610432016-08-08 18:44:38 +01009543
Ben Murdoch61f157c2016-09-16 13:49:30 +01009544EVALUATE(LDETR) {
9545 UNIMPLEMENTED();
9546 USE(instr);
9547 return 0;
9548}
Ben Murdochc5610432016-08-08 18:44:38 +01009549
Ben Murdoch61f157c2016-09-16 13:49:30 +01009550EVALUATE(LEDTR) {
9551 UNIMPLEMENTED();
9552 USE(instr);
9553 return 0;
9554}
Ben Murdochc5610432016-08-08 18:44:38 +01009555
Ben Murdoch61f157c2016-09-16 13:49:30 +01009556EVALUATE(LTDTR) {
9557 UNIMPLEMENTED();
9558 USE(instr);
9559 return 0;
9560}
Ben Murdochc5610432016-08-08 18:44:38 +01009561
Ben Murdoch61f157c2016-09-16 13:49:30 +01009562EVALUATE(FIDTR) {
9563 UNIMPLEMENTED();
9564 USE(instr);
9565 return 0;
9566}
Ben Murdochc5610432016-08-08 18:44:38 +01009567
Ben Murdoch61f157c2016-09-16 13:49:30 +01009568EVALUATE(MXTRA) {
9569 UNIMPLEMENTED();
9570 USE(instr);
9571 return 0;
9572}
Ben Murdochc5610432016-08-08 18:44:38 +01009573
Ben Murdoch61f157c2016-09-16 13:49:30 +01009574EVALUATE(DXTRA) {
9575 UNIMPLEMENTED();
9576 USE(instr);
9577 return 0;
9578}
Ben Murdochc5610432016-08-08 18:44:38 +01009579
Ben Murdoch61f157c2016-09-16 13:49:30 +01009580EVALUATE(AXTRA) {
9581 UNIMPLEMENTED();
9582 USE(instr);
9583 return 0;
9584}
Ben Murdochc5610432016-08-08 18:44:38 +01009585
Ben Murdoch61f157c2016-09-16 13:49:30 +01009586EVALUATE(SXTRA) {
9587 UNIMPLEMENTED();
9588 USE(instr);
9589 return 0;
9590}
Ben Murdochc5610432016-08-08 18:44:38 +01009591
Ben Murdoch61f157c2016-09-16 13:49:30 +01009592EVALUATE(LXDTR) {
9593 UNIMPLEMENTED();
9594 USE(instr);
9595 return 0;
9596}
Ben Murdochc5610432016-08-08 18:44:38 +01009597
Ben Murdoch61f157c2016-09-16 13:49:30 +01009598EVALUATE(LDXTR) {
9599 UNIMPLEMENTED();
9600 USE(instr);
9601 return 0;
9602}
Ben Murdochc5610432016-08-08 18:44:38 +01009603
Ben Murdoch61f157c2016-09-16 13:49:30 +01009604EVALUATE(LTXTR) {
9605 UNIMPLEMENTED();
9606 USE(instr);
9607 return 0;
9608}
Ben Murdochc5610432016-08-08 18:44:38 +01009609
Ben Murdoch61f157c2016-09-16 13:49:30 +01009610EVALUATE(FIXTR) {
9611 UNIMPLEMENTED();
9612 USE(instr);
9613 return 0;
9614}
Ben Murdochc5610432016-08-08 18:44:38 +01009615
Ben Murdoch61f157c2016-09-16 13:49:30 +01009616EVALUATE(KDTR) {
9617 UNIMPLEMENTED();
9618 USE(instr);
9619 return 0;
9620}
Ben Murdochc5610432016-08-08 18:44:38 +01009621
Ben Murdoch61f157c2016-09-16 13:49:30 +01009622EVALUATE(CGDTRA) {
9623 UNIMPLEMENTED();
9624 USE(instr);
9625 return 0;
9626}
Ben Murdochc5610432016-08-08 18:44:38 +01009627
Ben Murdoch61f157c2016-09-16 13:49:30 +01009628EVALUATE(CUDTR) {
9629 UNIMPLEMENTED();
9630 USE(instr);
9631 return 0;
9632}
Ben Murdochc5610432016-08-08 18:44:38 +01009633
Ben Murdoch61f157c2016-09-16 13:49:30 +01009634EVALUATE(CDTR) {
9635 UNIMPLEMENTED();
9636 USE(instr);
9637 return 0;
9638}
Ben Murdochc5610432016-08-08 18:44:38 +01009639
Ben Murdoch61f157c2016-09-16 13:49:30 +01009640EVALUATE(EEDTR) {
9641 UNIMPLEMENTED();
9642 USE(instr);
9643 return 0;
9644}
Ben Murdochc5610432016-08-08 18:44:38 +01009645
Ben Murdoch61f157c2016-09-16 13:49:30 +01009646EVALUATE(ESDTR) {
9647 UNIMPLEMENTED();
9648 USE(instr);
9649 return 0;
9650}
Ben Murdochc5610432016-08-08 18:44:38 +01009651
Ben Murdoch61f157c2016-09-16 13:49:30 +01009652EVALUATE(KXTR) {
9653 UNIMPLEMENTED();
9654 USE(instr);
9655 return 0;
9656}
Ben Murdochc5610432016-08-08 18:44:38 +01009657
Ben Murdoch61f157c2016-09-16 13:49:30 +01009658EVALUATE(CGXTRA) {
9659 UNIMPLEMENTED();
9660 USE(instr);
9661 return 0;
9662}
Ben Murdochc5610432016-08-08 18:44:38 +01009663
Ben Murdoch61f157c2016-09-16 13:49:30 +01009664EVALUATE(CUXTR) {
9665 UNIMPLEMENTED();
9666 USE(instr);
9667 return 0;
9668}
Ben Murdochc5610432016-08-08 18:44:38 +01009669
Ben Murdoch61f157c2016-09-16 13:49:30 +01009670EVALUATE(CSXTR) {
9671 UNIMPLEMENTED();
9672 USE(instr);
9673 return 0;
9674}
Ben Murdochc5610432016-08-08 18:44:38 +01009675
Ben Murdoch61f157c2016-09-16 13:49:30 +01009676EVALUATE(CXTR) {
9677 UNIMPLEMENTED();
9678 USE(instr);
9679 return 0;
9680}
Ben Murdochc5610432016-08-08 18:44:38 +01009681
Ben Murdoch61f157c2016-09-16 13:49:30 +01009682EVALUATE(EEXTR) {
9683 UNIMPLEMENTED();
9684 USE(instr);
9685 return 0;
9686}
Ben Murdochc5610432016-08-08 18:44:38 +01009687
Ben Murdoch61f157c2016-09-16 13:49:30 +01009688EVALUATE(ESXTR) {
9689 UNIMPLEMENTED();
9690 USE(instr);
9691 return 0;
9692}
Ben Murdochc5610432016-08-08 18:44:38 +01009693
Ben Murdoch61f157c2016-09-16 13:49:30 +01009694EVALUATE(CDGTRA) {
9695 UNIMPLEMENTED();
9696 USE(instr);
9697 return 0;
9698}
Ben Murdochc5610432016-08-08 18:44:38 +01009699
Ben Murdoch61f157c2016-09-16 13:49:30 +01009700EVALUATE(CDUTR) {
9701 UNIMPLEMENTED();
9702 USE(instr);
9703 return 0;
9704}
Ben Murdochc5610432016-08-08 18:44:38 +01009705
Ben Murdoch61f157c2016-09-16 13:49:30 +01009706EVALUATE(CDSTR) {
9707 UNIMPLEMENTED();
9708 USE(instr);
9709 return 0;
9710}
Ben Murdochc5610432016-08-08 18:44:38 +01009711
Ben Murdoch61f157c2016-09-16 13:49:30 +01009712EVALUATE(CEDTR) {
9713 UNIMPLEMENTED();
9714 USE(instr);
9715 return 0;
9716}
Ben Murdochc5610432016-08-08 18:44:38 +01009717
Ben Murdoch61f157c2016-09-16 13:49:30 +01009718EVALUATE(QADTR) {
9719 UNIMPLEMENTED();
9720 USE(instr);
9721 return 0;
9722}
Ben Murdochc5610432016-08-08 18:44:38 +01009723
Ben Murdoch61f157c2016-09-16 13:49:30 +01009724EVALUATE(IEDTR) {
9725 UNIMPLEMENTED();
9726 USE(instr);
9727 return 0;
9728}
Ben Murdochc5610432016-08-08 18:44:38 +01009729
Ben Murdoch61f157c2016-09-16 13:49:30 +01009730EVALUATE(RRDTR) {
9731 UNIMPLEMENTED();
9732 USE(instr);
9733 return 0;
9734}
Ben Murdochc5610432016-08-08 18:44:38 +01009735
Ben Murdoch61f157c2016-09-16 13:49:30 +01009736EVALUATE(CXGTRA) {
9737 UNIMPLEMENTED();
9738 USE(instr);
9739 return 0;
9740}
Ben Murdochc5610432016-08-08 18:44:38 +01009741
Ben Murdoch61f157c2016-09-16 13:49:30 +01009742EVALUATE(CXUTR) {
9743 UNIMPLEMENTED();
9744 USE(instr);
9745 return 0;
9746}
Ben Murdochc5610432016-08-08 18:44:38 +01009747
Ben Murdoch61f157c2016-09-16 13:49:30 +01009748EVALUATE(CXSTR) {
9749 UNIMPLEMENTED();
9750 USE(instr);
9751 return 0;
9752}
Ben Murdochc5610432016-08-08 18:44:38 +01009753
Ben Murdoch61f157c2016-09-16 13:49:30 +01009754EVALUATE(CEXTR) {
9755 UNIMPLEMENTED();
9756 USE(instr);
9757 return 0;
9758}
Ben Murdochc5610432016-08-08 18:44:38 +01009759
Ben Murdoch61f157c2016-09-16 13:49:30 +01009760EVALUATE(QAXTR) {
9761 UNIMPLEMENTED();
9762 USE(instr);
9763 return 0;
9764}
Ben Murdochc5610432016-08-08 18:44:38 +01009765
Ben Murdoch61f157c2016-09-16 13:49:30 +01009766EVALUATE(IEXTR) {
9767 UNIMPLEMENTED();
9768 USE(instr);
9769 return 0;
9770}
Ben Murdochc5610432016-08-08 18:44:38 +01009771
Ben Murdoch61f157c2016-09-16 13:49:30 +01009772EVALUATE(RRXTR) {
9773 UNIMPLEMENTED();
9774 USE(instr);
9775 return 0;
9776}
Ben Murdochc5610432016-08-08 18:44:38 +01009777
Ben Murdoch61f157c2016-09-16 13:49:30 +01009778EVALUATE(LPGR) {
9779 UNIMPLEMENTED();
9780 USE(instr);
9781 return 0;
9782}
Ben Murdochc5610432016-08-08 18:44:38 +01009783
Ben Murdoch61f157c2016-09-16 13:49:30 +01009784EVALUATE(LNGR) {
9785 DCHECK_OPCODE(LNGR);
9786 // Load Negative (64)
9787 DECODE_RRE_INSTRUCTION(r1, r2);
9788 int64_t r2_val = get_register(r2);
9789 r2_val = (r2_val >= 0) ? -r2_val : r2_val; // If pos, then negate it.
9790 set_register(r1, r2_val);
9791 condition_reg_ = (r2_val == 0) ? CC_EQ : CC_LT; // CC0 - result is zero
9792 // CC1 - result is negative
9793 return length;
9794}
Ben Murdochc5610432016-08-08 18:44:38 +01009795
Ben Murdoch61f157c2016-09-16 13:49:30 +01009796EVALUATE(LTGR) {
9797 DCHECK_OPCODE(LTGR);
9798 // Load Register (64)
9799 DECODE_RRE_INSTRUCTION(r1, r2);
9800 int64_t r2_val = get_register(r2);
9801 SetS390ConditionCode<int64_t>(r2_val, 0);
9802 set_register(r1, get_register(r2));
9803 return length;
9804}
Ben Murdochc5610432016-08-08 18:44:38 +01009805
Ben Murdoch61f157c2016-09-16 13:49:30 +01009806EVALUATE(LCGR) {
9807 DCHECK_OPCODE(LCGR);
9808 DECODE_RRE_INSTRUCTION(r1, r2);
9809 int64_t r2_val = get_register(r2);
9810 r2_val = ~r2_val;
9811 r2_val = r2_val + 1;
9812 set_register(r1, r2_val);
9813 SetS390ConditionCode<int64_t>(r2_val, 0);
9814 // if the input is INT_MIN, loading its compliment would be overflowing
9815 if (r2_val < 0 && (r2_val + 1) > 0) {
9816 SetS390OverflowCode(true);
9817 }
9818 return length;
9819}
Ben Murdochc5610432016-08-08 18:44:38 +01009820
Ben Murdoch61f157c2016-09-16 13:49:30 +01009821EVALUATE(SGR) {
9822 DCHECK_OPCODE(SGR);
9823 DECODE_RRE_INSTRUCTION(r1, r2);
9824 int64_t r1_val = get_register(r1);
9825 int64_t r2_val = get_register(r2);
9826 bool isOF = false;
9827 isOF = CheckOverflowForIntSub(r1_val, r2_val, int64_t);
9828 r1_val -= r2_val;
9829 SetS390ConditionCode<int64_t>(r1_val, 0);
9830 SetS390OverflowCode(isOF);
9831 set_register(r1, r1_val);
9832 return length;
9833}
Ben Murdochc5610432016-08-08 18:44:38 +01009834
Ben Murdoch61f157c2016-09-16 13:49:30 +01009835EVALUATE(ALGR) {
9836 UNIMPLEMENTED();
9837 USE(instr);
9838 return 0;
9839}
Ben Murdochc5610432016-08-08 18:44:38 +01009840
Ben Murdoch61f157c2016-09-16 13:49:30 +01009841EVALUATE(SLGR) {
9842 UNIMPLEMENTED();
9843 USE(instr);
9844 return 0;
9845}
Ben Murdochc5610432016-08-08 18:44:38 +01009846
Ben Murdoch61f157c2016-09-16 13:49:30 +01009847EVALUATE(MSGR) {
9848 DCHECK_OPCODE(MSGR);
9849 DECODE_RRE_INSTRUCTION(r1, r2);
9850 int64_t r1_val = get_register(r1);
9851 int64_t r2_val = get_register(r2);
9852 set_register(r1, r1_val * r2_val);
9853 return length;
9854}
Ben Murdochc5610432016-08-08 18:44:38 +01009855
Ben Murdoch61f157c2016-09-16 13:49:30 +01009856EVALUATE(DSGR) {
9857 DCHECK_OPCODE(DSGR);
9858 DECODE_RRE_INSTRUCTION(r1, r2);
Ben Murdochc5610432016-08-08 18:44:38 +01009859
Ben Murdoch61f157c2016-09-16 13:49:30 +01009860 DCHECK(r1 % 2 == 0);
Ben Murdochc5610432016-08-08 18:44:38 +01009861
Ben Murdoch61f157c2016-09-16 13:49:30 +01009862 int64_t dividend = get_register(r1 + 1);
9863 int64_t divisor = get_register(r2);
9864 set_register(r1, dividend % divisor);
9865 set_register(r1 + 1, dividend / divisor);
9866 return length;
9867}
Ben Murdochc5610432016-08-08 18:44:38 +01009868
Ben Murdoch61f157c2016-09-16 13:49:30 +01009869EVALUATE(LRVGR) {
9870 UNIMPLEMENTED();
9871 USE(instr);
9872 return 0;
9873}
Ben Murdochc5610432016-08-08 18:44:38 +01009874
Ben Murdoch61f157c2016-09-16 13:49:30 +01009875EVALUATE(LPGFR) {
9876 UNIMPLEMENTED();
9877 USE(instr);
9878 return 0;
9879}
Ben Murdochc5610432016-08-08 18:44:38 +01009880
Ben Murdoch61f157c2016-09-16 13:49:30 +01009881EVALUATE(LNGFR) {
9882 UNIMPLEMENTED();
9883 USE(instr);
9884 return 0;
9885}
Ben Murdochc5610432016-08-08 18:44:38 +01009886
Ben Murdoch61f157c2016-09-16 13:49:30 +01009887EVALUATE(LTGFR) {
9888 DCHECK_OPCODE(LTGFR);
9889 DECODE_RRE_INSTRUCTION(r1, r2);
9890 // Load and Test Register (64 <- 32) (Sign Extends 32-bit val)
9891 // Load Register (64 <- 32) (Sign Extends 32-bit val)
9892 int32_t r2_val = get_low_register<int32_t>(r2);
9893 int64_t result = static_cast<int64_t>(r2_val);
9894 set_register(r1, result);
9895 SetS390ConditionCode<int64_t>(result, 0);
9896 return length;
9897}
Ben Murdochc5610432016-08-08 18:44:38 +01009898
Ben Murdoch61f157c2016-09-16 13:49:30 +01009899EVALUATE(LCGFR) {
9900 DCHECK_OPCODE(LCGFR);
9901 DECODE_RRE_INSTRUCTION(r1, r2);
9902 // Load and Test Register (64 <- 32) (Sign Extends 32-bit val)
9903 // Load Register (64 <- 32) (Sign Extends 32-bit val)
9904 int32_t r2_val = get_low_register<int32_t>(r2);
9905 int64_t result = static_cast<int64_t>(r2_val);
9906 set_register(r1, result);
9907 return length;
9908}
Ben Murdochc5610432016-08-08 18:44:38 +01009909
Ben Murdoch61f157c2016-09-16 13:49:30 +01009910EVALUATE(LLGFR) {
9911 DCHECK_OPCODE(LLGFR);
9912 DECODE_RRE_INSTRUCTION(r1, r2);
9913 int32_t r2_val = get_low_register<int32_t>(r2);
9914 uint64_t r2_finalval = (static_cast<uint64_t>(r2_val) & 0x00000000ffffffff);
9915 set_register(r1, r2_finalval);
9916 return length;
9917}
Ben Murdochc5610432016-08-08 18:44:38 +01009918
Ben Murdoch61f157c2016-09-16 13:49:30 +01009919EVALUATE(LLGTR) {
9920 UNIMPLEMENTED();
9921 USE(instr);
9922 return 0;
9923}
Ben Murdochc5610432016-08-08 18:44:38 +01009924
Ben Murdoch61f157c2016-09-16 13:49:30 +01009925EVALUATE(AGFR) {
9926 DCHECK_OPCODE(AGFR);
9927 DECODE_RRE_INSTRUCTION(r1, r2);
9928 // Add Register (64 <- 32) (Sign Extends 32-bit val)
9929 int64_t r1_val = get_register(r1);
9930 int64_t r2_val = static_cast<int64_t>(get_low_register<int32_t>(r2));
9931 bool isOF = CheckOverflowForIntAdd(r1_val, r2_val, int64_t);
9932 r1_val += r2_val;
9933 SetS390ConditionCode<int64_t>(r1_val, 0);
9934 SetS390OverflowCode(isOF);
9935 set_register(r1, r1_val);
9936 return length;
9937}
Ben Murdochc5610432016-08-08 18:44:38 +01009938
Ben Murdoch61f157c2016-09-16 13:49:30 +01009939EVALUATE(SGFR) {
9940 DCHECK_OPCODE(SGFR);
9941 DECODE_RRE_INSTRUCTION(r1, r2);
9942 // Sub Reg (64 <- 32)
9943 int64_t r1_val = get_register(r1);
9944 int64_t r2_val = static_cast<int64_t>(get_low_register<int32_t>(r2));
9945 bool isOF = false;
9946 isOF = CheckOverflowForIntSub(r1_val, r2_val, int64_t);
9947 r1_val -= r2_val;
9948 SetS390ConditionCode<int64_t>(r1_val, 0);
9949 SetS390OverflowCode(isOF);
9950 set_register(r1, r1_val);
9951 return length;
9952}
Ben Murdochc5610432016-08-08 18:44:38 +01009953
Ben Murdoch61f157c2016-09-16 13:49:30 +01009954EVALUATE(ALGFR) {
9955 UNIMPLEMENTED();
9956 USE(instr);
9957 return 0;
9958}
Ben Murdochc5610432016-08-08 18:44:38 +01009959
Ben Murdoch61f157c2016-09-16 13:49:30 +01009960EVALUATE(SLGFR) {
9961 UNIMPLEMENTED();
9962 USE(instr);
9963 return 0;
9964}
Ben Murdochc5610432016-08-08 18:44:38 +01009965
Ben Murdoch61f157c2016-09-16 13:49:30 +01009966EVALUATE(MSGFR) {
9967 UNIMPLEMENTED();
9968 USE(instr);
9969 return 0;
9970}
Ben Murdochc5610432016-08-08 18:44:38 +01009971
Ben Murdoch61f157c2016-09-16 13:49:30 +01009972EVALUATE(DSGFR) {
9973 UNIMPLEMENTED();
9974 USE(instr);
9975 return 0;
9976}
Ben Murdochc5610432016-08-08 18:44:38 +01009977
Ben Murdoch61f157c2016-09-16 13:49:30 +01009978EVALUATE(KMAC) {
9979 UNIMPLEMENTED();
9980 USE(instr);
9981 return 0;
9982}
Ben Murdochc5610432016-08-08 18:44:38 +01009983
Ben Murdoch61f157c2016-09-16 13:49:30 +01009984EVALUATE(LRVR) {
9985 UNIMPLEMENTED();
9986 USE(instr);
9987 return 0;
9988}
Ben Murdochc5610432016-08-08 18:44:38 +01009989
Ben Murdoch61f157c2016-09-16 13:49:30 +01009990EVALUATE(CGR) {
9991 DCHECK_OPCODE(CGR);
9992 DECODE_RRE_INSTRUCTION(r1, r2);
9993 // Compare (64)
9994 int64_t r1_val = get_register(r1);
9995 int64_t r2_val = get_register(r2);
9996 SetS390ConditionCode<int64_t>(r1_val, r2_val);
9997 return length;
9998}
Ben Murdochc5610432016-08-08 18:44:38 +01009999
Ben Murdoch61f157c2016-09-16 13:49:30 +010010000EVALUATE(CLGR) {
10001 DCHECK_OPCODE(CLGR);
10002 DECODE_RRE_INSTRUCTION(r1, r2);
10003 // Compare Logical (64)
10004 uint64_t r1_val = static_cast<uint64_t>(get_register(r1));
10005 uint64_t r2_val = static_cast<uint64_t>(get_register(r2));
10006 SetS390ConditionCode<uint64_t>(r1_val, r2_val);
10007 return length;
10008}
Ben Murdochc5610432016-08-08 18:44:38 +010010009
Ben Murdoch61f157c2016-09-16 13:49:30 +010010010EVALUATE(KMF) {
10011 UNIMPLEMENTED();
10012 USE(instr);
10013 return 0;
10014}
Ben Murdochc5610432016-08-08 18:44:38 +010010015
Ben Murdoch61f157c2016-09-16 13:49:30 +010010016EVALUATE(KMO) {
10017 UNIMPLEMENTED();
10018 USE(instr);
10019 return 0;
10020}
Ben Murdochc5610432016-08-08 18:44:38 +010010021
Ben Murdoch61f157c2016-09-16 13:49:30 +010010022EVALUATE(PCC) {
10023 UNIMPLEMENTED();
10024 USE(instr);
10025 return 0;
10026}
Ben Murdochc5610432016-08-08 18:44:38 +010010027
Ben Murdoch61f157c2016-09-16 13:49:30 +010010028EVALUATE(KMCTR) {
10029 UNIMPLEMENTED();
10030 USE(instr);
10031 return 0;
10032}
Ben Murdochc5610432016-08-08 18:44:38 +010010033
Ben Murdoch61f157c2016-09-16 13:49:30 +010010034EVALUATE(KM) {
10035 UNIMPLEMENTED();
10036 USE(instr);
10037 return 0;
10038}
Ben Murdochc5610432016-08-08 18:44:38 +010010039
Ben Murdoch61f157c2016-09-16 13:49:30 +010010040EVALUATE(KMC) {
10041 UNIMPLEMENTED();
10042 USE(instr);
10043 return 0;
10044}
Ben Murdochc5610432016-08-08 18:44:38 +010010045
Ben Murdoch61f157c2016-09-16 13:49:30 +010010046EVALUATE(CGFR) {
10047 UNIMPLEMENTED();
10048 USE(instr);
10049 return 0;
10050}
Ben Murdochc5610432016-08-08 18:44:38 +010010051
Ben Murdoch61f157c2016-09-16 13:49:30 +010010052EVALUATE(KIMD) {
10053 UNIMPLEMENTED();
10054 USE(instr);
10055 return 0;
10056}
Ben Murdochc5610432016-08-08 18:44:38 +010010057
Ben Murdoch61f157c2016-09-16 13:49:30 +010010058EVALUATE(KLMD) {
10059 UNIMPLEMENTED();
10060 USE(instr);
10061 return 0;
10062}
Ben Murdochc5610432016-08-08 18:44:38 +010010063
Ben Murdoch61f157c2016-09-16 13:49:30 +010010064EVALUATE(CFDTR) {
10065 UNIMPLEMENTED();
10066 USE(instr);
10067 return 0;
10068}
Ben Murdochc5610432016-08-08 18:44:38 +010010069
Ben Murdoch61f157c2016-09-16 13:49:30 +010010070EVALUATE(CLGDTR) {
10071 UNIMPLEMENTED();
10072 USE(instr);
10073 return 0;
10074}
Ben Murdochc5610432016-08-08 18:44:38 +010010075
Ben Murdoch61f157c2016-09-16 13:49:30 +010010076EVALUATE(CLFDTR) {
10077 UNIMPLEMENTED();
10078 USE(instr);
10079 return 0;
10080}
Ben Murdochc5610432016-08-08 18:44:38 +010010081
Ben Murdoch61f157c2016-09-16 13:49:30 +010010082EVALUATE(BCTGR) {
10083 UNIMPLEMENTED();
10084 USE(instr);
10085 return 0;
10086}
Ben Murdochc5610432016-08-08 18:44:38 +010010087
Ben Murdoch61f157c2016-09-16 13:49:30 +010010088EVALUATE(CFXTR) {
10089 UNIMPLEMENTED();
10090 USE(instr);
10091 return 0;
10092}
Ben Murdochc5610432016-08-08 18:44:38 +010010093
Ben Murdoch61f157c2016-09-16 13:49:30 +010010094EVALUATE(CLFXTR) {
10095 UNIMPLEMENTED();
10096 USE(instr);
10097 return 0;
10098}
Ben Murdochc5610432016-08-08 18:44:38 +010010099
Ben Murdoch61f157c2016-09-16 13:49:30 +010010100EVALUATE(CDFTR) {
10101 UNIMPLEMENTED();
10102 USE(instr);
10103 return 0;
10104}
Ben Murdochc5610432016-08-08 18:44:38 +010010105
Ben Murdoch61f157c2016-09-16 13:49:30 +010010106EVALUATE(CDLGTR) {
10107 UNIMPLEMENTED();
10108 USE(instr);
10109 return 0;
10110}
Ben Murdochc5610432016-08-08 18:44:38 +010010111
Ben Murdoch61f157c2016-09-16 13:49:30 +010010112EVALUATE(CDLFTR) {
10113 UNIMPLEMENTED();
10114 USE(instr);
10115 return 0;
10116}
Ben Murdochc5610432016-08-08 18:44:38 +010010117
Ben Murdoch61f157c2016-09-16 13:49:30 +010010118EVALUATE(CXFTR) {
10119 UNIMPLEMENTED();
10120 USE(instr);
10121 return 0;
10122}
Ben Murdochc5610432016-08-08 18:44:38 +010010123
Ben Murdoch61f157c2016-09-16 13:49:30 +010010124EVALUATE(CXLGTR) {
10125 UNIMPLEMENTED();
10126 USE(instr);
10127 return 0;
10128}
Ben Murdochc5610432016-08-08 18:44:38 +010010129
Ben Murdoch61f157c2016-09-16 13:49:30 +010010130EVALUATE(CXLFTR) {
10131 UNIMPLEMENTED();
10132 USE(instr);
10133 return 0;
10134}
Ben Murdochc5610432016-08-08 18:44:38 +010010135
Ben Murdoch61f157c2016-09-16 13:49:30 +010010136EVALUATE(CGRT) {
10137 UNIMPLEMENTED();
10138 USE(instr);
10139 return 0;
10140}
Ben Murdochc5610432016-08-08 18:44:38 +010010141
Ben Murdoch61f157c2016-09-16 13:49:30 +010010142EVALUATE(NGR) {
10143 DCHECK_OPCODE(NGR);
10144 DECODE_RRE_INSTRUCTION(r1, r2);
10145 int64_t r1_val = get_register(r1);
10146 int64_t r2_val = get_register(r2);
10147 r1_val &= r2_val;
10148 SetS390BitWiseConditionCode<uint64_t>(r1_val);
10149 set_register(r1, r1_val);
10150 return length;
10151}
Ben Murdochc5610432016-08-08 18:44:38 +010010152
Ben Murdoch61f157c2016-09-16 13:49:30 +010010153EVALUATE(OGR) {
10154 DCHECK_OPCODE(OGR);
10155 DECODE_RRE_INSTRUCTION(r1, r2);
10156 int64_t r1_val = get_register(r1);
10157 int64_t r2_val = get_register(r2);
10158 r1_val |= r2_val;
10159 SetS390BitWiseConditionCode<uint64_t>(r1_val);
10160 set_register(r1, r1_val);
10161 return length;
10162}
Ben Murdochc5610432016-08-08 18:44:38 +010010163
Ben Murdoch61f157c2016-09-16 13:49:30 +010010164EVALUATE(XGR) {
10165 DCHECK_OPCODE(XGR);
10166 DECODE_RRE_INSTRUCTION(r1, r2);
10167 int64_t r1_val = get_register(r1);
10168 int64_t r2_val = get_register(r2);
10169 r1_val ^= r2_val;
10170 SetS390BitWiseConditionCode<uint64_t>(r1_val);
10171 set_register(r1, r1_val);
10172 return length;
10173}
Ben Murdochc5610432016-08-08 18:44:38 +010010174
Ben Murdoch61f157c2016-09-16 13:49:30 +010010175EVALUATE(FLOGR) {
10176 DCHECK_OPCODE(FLOGR);
10177 DECODE_RRE_INSTRUCTION(r1, r2);
Ben Murdochc5610432016-08-08 18:44:38 +010010178
Ben Murdoch61f157c2016-09-16 13:49:30 +010010179 DCHECK(r1 % 2 == 0);
Ben Murdochc5610432016-08-08 18:44:38 +010010180
Ben Murdoch61f157c2016-09-16 13:49:30 +010010181 int64_t r2_val = get_register(r2);
Ben Murdochc5610432016-08-08 18:44:38 +010010182
Ben Murdoch61f157c2016-09-16 13:49:30 +010010183 int i = 0;
10184 for (; i < 64; i++) {
10185 if (r2_val < 0) break;
10186 r2_val <<= 1;
10187 }
Ben Murdochc5610432016-08-08 18:44:38 +010010188
Ben Murdoch61f157c2016-09-16 13:49:30 +010010189 r2_val = get_register(r2);
Ben Murdochc5610432016-08-08 18:44:38 +010010190
Ben Murdoch61f157c2016-09-16 13:49:30 +010010191 int64_t mask = ~(1 << (63 - i));
10192 set_register(r1, i);
10193 set_register(r1 + 1, r2_val & mask);
10194 return length;
10195}
Ben Murdochc5610432016-08-08 18:44:38 +010010196
Ben Murdoch61f157c2016-09-16 13:49:30 +010010197EVALUATE(LLGCR) {
10198 UNIMPLEMENTED();
10199 USE(instr);
10200 return 0;
10201}
Ben Murdochc5610432016-08-08 18:44:38 +010010202
Ben Murdoch61f157c2016-09-16 13:49:30 +010010203EVALUATE(LLGHR) {
10204 UNIMPLEMENTED();
10205 USE(instr);
10206 return 0;
10207}
Ben Murdochc5610432016-08-08 18:44:38 +010010208
Ben Murdoch61f157c2016-09-16 13:49:30 +010010209EVALUATE(MLGR) {
10210 UNIMPLEMENTED();
10211 USE(instr);
10212 return 0;
10213}
Ben Murdochc5610432016-08-08 18:44:38 +010010214
Ben Murdoch61f157c2016-09-16 13:49:30 +010010215EVALUATE(DLGR) {
10216 DCHECK_OPCODE(DLGR);
10217#ifdef V8_TARGET_ARCH_S390X
10218 DECODE_RRE_INSTRUCTION(r1, r2);
10219 uint64_t r1_val = get_register(r1);
10220 uint64_t r2_val = get_register(r2);
10221 DCHECK(r1 % 2 == 0);
10222 unsigned __int128 dividend = static_cast<unsigned __int128>(r1_val) << 64;
10223 dividend += get_register(r1 + 1);
10224 uint64_t remainder = dividend % r2_val;
10225 uint64_t quotient = dividend / r2_val;
10226 r1_val = remainder;
10227 set_register(r1, remainder);
10228 set_register(r1 + 1, quotient);
10229 return length;
10230#else
10231 UNREACHABLE();
10232#endif
10233}
Ben Murdochc5610432016-08-08 18:44:38 +010010234
Ben Murdoch61f157c2016-09-16 13:49:30 +010010235EVALUATE(ALCGR) {
10236 UNIMPLEMENTED();
10237 USE(instr);
10238 return 0;
10239}
Ben Murdochc5610432016-08-08 18:44:38 +010010240
Ben Murdoch61f157c2016-09-16 13:49:30 +010010241EVALUATE(SLBGR) {
10242 UNIMPLEMENTED();
10243 USE(instr);
10244 return 0;
10245}
Ben Murdochc5610432016-08-08 18:44:38 +010010246
Ben Murdoch61f157c2016-09-16 13:49:30 +010010247EVALUATE(EPSW) {
10248 UNIMPLEMENTED();
10249 USE(instr);
10250 return 0;
10251}
Ben Murdochc5610432016-08-08 18:44:38 +010010252
Ben Murdoch61f157c2016-09-16 13:49:30 +010010253EVALUATE(TRTT) {
10254 UNIMPLEMENTED();
10255 USE(instr);
10256 return 0;
10257}
Ben Murdochc5610432016-08-08 18:44:38 +010010258
Ben Murdoch61f157c2016-09-16 13:49:30 +010010259EVALUATE(TRTO) {
10260 UNIMPLEMENTED();
10261 USE(instr);
10262 return 0;
10263}
Ben Murdochc5610432016-08-08 18:44:38 +010010264
Ben Murdoch61f157c2016-09-16 13:49:30 +010010265EVALUATE(TROT) {
10266 UNIMPLEMENTED();
10267 USE(instr);
10268 return 0;
10269}
Ben Murdochc5610432016-08-08 18:44:38 +010010270
Ben Murdoch61f157c2016-09-16 13:49:30 +010010271EVALUATE(TROO) {
10272 UNIMPLEMENTED();
10273 USE(instr);
10274 return 0;
10275}
Ben Murdochc5610432016-08-08 18:44:38 +010010276
Ben Murdoch61f157c2016-09-16 13:49:30 +010010277EVALUATE(LLCR) {
10278 UNIMPLEMENTED();
10279 USE(instr);
10280 return 0;
10281}
Ben Murdochc5610432016-08-08 18:44:38 +010010282
Ben Murdoch61f157c2016-09-16 13:49:30 +010010283EVALUATE(LLHR) {
10284 UNIMPLEMENTED();
10285 USE(instr);
10286 return 0;
10287}
Ben Murdochc5610432016-08-08 18:44:38 +010010288
Ben Murdoch61f157c2016-09-16 13:49:30 +010010289EVALUATE(MLR) {
10290 DCHECK_OPCODE(MLR);
10291 DECODE_RRE_INSTRUCTION(r1, r2);
10292 DCHECK(r1 % 2 == 0);
10293
10294 uint32_t r1_val = get_low_register<uint32_t>(r1 + 1);
10295 uint32_t r2_val = get_low_register<uint32_t>(r2);
10296 uint64_t product =
10297 static_cast<uint64_t>(r1_val) * static_cast<uint64_t>(r2_val);
10298 int32_t high_bits = product >> 32;
10299 int32_t low_bits = product & 0x00000000FFFFFFFF;
10300 set_low_register(r1, high_bits);
10301 set_low_register(r1 + 1, low_bits);
10302 return length;
10303}
10304
10305EVALUATE(DLR) {
10306 DCHECK_OPCODE(DLR);
10307 DECODE_RRE_INSTRUCTION(r1, r2);
10308 uint32_t r1_val = get_low_register<uint32_t>(r1);
10309 uint32_t r2_val = get_low_register<uint32_t>(r2);
10310 DCHECK(r1 % 2 == 0);
10311 uint64_t dividend = static_cast<uint64_t>(r1_val) << 32;
10312 dividend += get_low_register<uint32_t>(r1 + 1);
10313 uint32_t remainder = dividend % r2_val;
10314 uint32_t quotient = dividend / r2_val;
10315 r1_val = remainder;
10316 set_low_register(r1, remainder);
10317 set_low_register(r1 + 1, quotient);
10318 return length;
10319}
10320
10321EVALUATE(ALCR) {
10322 DCHECK_OPCODE(ALCR);
10323 DECODE_RRE_INSTRUCTION(r1, r2);
10324 uint32_t r1_val = get_low_register<uint32_t>(r1);
10325 uint32_t r2_val = get_low_register<uint32_t>(r2);
10326 uint32_t alu_out = 0;
10327 bool isOF = false;
10328
10329 alu_out = r1_val + r2_val;
10330 bool isOF_original = CheckOverflowForUIntAdd(r1_val, r2_val);
10331 if (TestConditionCode((Condition)2) || TestConditionCode((Condition)3)) {
10332 alu_out = alu_out + 1;
10333 isOF = isOF_original || CheckOverflowForUIntAdd(alu_out, 1);
10334 } else {
10335 isOF = isOF_original;
10336 }
10337 set_low_register(r1, alu_out);
10338 SetS390ConditionCodeCarry<uint32_t>(alu_out, isOF);
10339 return length;
10340}
10341
10342EVALUATE(SLBR) {
10343 DCHECK_OPCODE(SLBR);
10344 DECODE_RRE_INSTRUCTION(r1, r2);
10345 uint32_t r1_val = get_low_register<uint32_t>(r1);
10346 uint32_t r2_val = get_low_register<uint32_t>(r2);
10347 uint32_t alu_out = 0;
10348 bool isOF = false;
10349
10350 alu_out = r1_val - r2_val;
10351 bool isOF_original = CheckOverflowForUIntSub(r1_val, r2_val);
10352 if (TestConditionCode((Condition)2) || TestConditionCode((Condition)3)) {
10353 alu_out = alu_out - 1;
10354 isOF = isOF_original || CheckOverflowForUIntSub(alu_out, 1);
10355 } else {
10356 isOF = isOF_original;
10357 }
10358 set_low_register(r1, alu_out);
10359 SetS390ConditionCodeCarry<uint32_t>(alu_out, isOF);
10360 return length;
10361}
10362
10363EVALUATE(CU14) {
10364 UNIMPLEMENTED();
10365 USE(instr);
10366 return 0;
10367}
10368
10369EVALUATE(CU24) {
10370 UNIMPLEMENTED();
10371 USE(instr);
10372 return 0;
10373}
10374
10375EVALUATE(CU41) {
10376 UNIMPLEMENTED();
10377 USE(instr);
10378 return 0;
10379}
10380
10381EVALUATE(CU42) {
10382 UNIMPLEMENTED();
10383 USE(instr);
10384 return 0;
10385}
10386
10387EVALUATE(TRTRE) {
10388 UNIMPLEMENTED();
10389 USE(instr);
10390 return 0;
10391}
10392
10393EVALUATE(SRSTU) {
10394 UNIMPLEMENTED();
10395 USE(instr);
10396 return 0;
10397}
10398
10399EVALUATE(TRTE) {
10400 UNIMPLEMENTED();
10401 USE(instr);
10402 return 0;
10403}
10404
10405EVALUATE(AHHHR) {
10406 UNIMPLEMENTED();
10407 USE(instr);
10408 return 0;
10409}
10410
10411EVALUATE(SHHHR) {
10412 UNIMPLEMENTED();
10413 USE(instr);
10414 return 0;
10415}
10416
10417EVALUATE(ALHHHR) {
10418 UNIMPLEMENTED();
10419 USE(instr);
10420 return 0;
10421}
10422
10423EVALUATE(SLHHHR) {
10424 UNIMPLEMENTED();
10425 USE(instr);
10426 return 0;
10427}
10428
10429EVALUATE(CHHR) {
10430 UNIMPLEMENTED();
10431 USE(instr);
10432 return 0;
10433}
10434
10435EVALUATE(AHHLR) {
10436 UNIMPLEMENTED();
10437 USE(instr);
10438 return 0;
10439}
10440
10441EVALUATE(SHHLR) {
10442 UNIMPLEMENTED();
10443 USE(instr);
10444 return 0;
10445}
10446
10447EVALUATE(ALHHLR) {
10448 UNIMPLEMENTED();
10449 USE(instr);
10450 return 0;
10451}
10452
10453EVALUATE(SLHHLR) {
10454 UNIMPLEMENTED();
10455 USE(instr);
10456 return 0;
10457}
10458
10459EVALUATE(CHLR) {
10460 UNIMPLEMENTED();
10461 USE(instr);
10462 return 0;
10463}
10464
10465EVALUATE(POPCNT_Z) {
10466 DCHECK_OPCODE(POPCNT_Z);
10467 DECODE_RRE_INSTRUCTION(r1, r2);
10468 int64_t r2_val = get_register(r2);
10469 int64_t r1_val = 0;
10470
10471 uint8_t* r2_val_ptr = reinterpret_cast<uint8_t*>(&r2_val);
10472 uint8_t* r1_val_ptr = reinterpret_cast<uint8_t*>(&r1_val);
10473 for (int i = 0; i < 8; i++) {
10474 uint32_t x = static_cast<uint32_t>(r2_val_ptr[i]);
10475#if defined(__GNUC__)
10476 r1_val_ptr[i] = __builtin_popcount(x);
10477#else
10478#error unsupport __builtin_popcount
10479#endif
10480 }
10481 set_register(r1, static_cast<uint64_t>(r1_val));
10482 return length;
10483}
10484
10485EVALUATE(LOCGR) {
10486 UNIMPLEMENTED();
10487 USE(instr);
10488 return 0;
10489}
10490
10491EVALUATE(NGRK) {
10492 DCHECK_OPCODE(NGRK);
10493 DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
10494 // 64-bit Non-clobbering arithmetics / bitwise ops.
10495 int64_t r2_val = get_register(r2);
10496 int64_t r3_val = get_register(r3);
10497 uint64_t bitwise_result = 0;
10498 bitwise_result = r2_val & r3_val;
10499 SetS390BitWiseConditionCode<uint64_t>(bitwise_result);
10500 set_register(r1, bitwise_result);
10501 return length;
10502}
10503
10504EVALUATE(OGRK) {
10505 DCHECK_OPCODE(OGRK);
10506 DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
10507 // 64-bit Non-clobbering arithmetics / bitwise ops.
10508 int64_t r2_val = get_register(r2);
10509 int64_t r3_val = get_register(r3);
10510 uint64_t bitwise_result = 0;
10511 bitwise_result = r2_val | r3_val;
10512 SetS390BitWiseConditionCode<uint64_t>(bitwise_result);
10513 set_register(r1, bitwise_result);
10514 return length;
10515}
10516
10517EVALUATE(XGRK) {
10518 DCHECK_OPCODE(XGRK);
10519 DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
10520 // 64-bit Non-clobbering arithmetics / bitwise ops.
10521 int64_t r2_val = get_register(r2);
10522 int64_t r3_val = get_register(r3);
10523 uint64_t bitwise_result = 0;
10524 bitwise_result = r2_val ^ r3_val;
10525 SetS390BitWiseConditionCode<uint64_t>(bitwise_result);
10526 set_register(r1, bitwise_result);
10527 return length;
10528}
10529
10530EVALUATE(AGRK) {
10531 DCHECK_OPCODE(AGRK);
10532 DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
10533 // 64-bit Non-clobbering arithmetics / bitwise ops.
10534 int64_t r2_val = get_register(r2);
10535 int64_t r3_val = get_register(r3);
10536 bool isOF = CheckOverflowForIntAdd(r2_val, r3_val, int64_t);
10537 SetS390ConditionCode<int64_t>(r2_val + r3_val, 0);
10538 SetS390OverflowCode(isOF);
10539 set_register(r1, r2_val + r3_val);
10540 return length;
10541}
10542
10543EVALUATE(SGRK) {
10544 DCHECK_OPCODE(SGRK);
10545 DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
10546 // 64-bit Non-clobbering arithmetics / bitwise ops.
10547 int64_t r2_val = get_register(r2);
10548 int64_t r3_val = get_register(r3);
10549 bool isOF = CheckOverflowForIntSub(r2_val, r3_val, int64_t);
10550 SetS390ConditionCode<int64_t>(r2_val - r3_val, 0);
10551 SetS390OverflowCode(isOF);
10552 set_register(r1, r2_val - r3_val);
10553 return length;
10554}
10555
10556EVALUATE(ALGRK) {
10557 DCHECK_OPCODE(ALGRK);
10558 DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
10559 // 64-bit Non-clobbering unsigned arithmetics
10560 uint64_t r2_val = get_register(r2);
10561 uint64_t r3_val = get_register(r3);
10562 bool isOF = CheckOverflowForUIntAdd(r2_val, r3_val);
10563 SetS390ConditionCode<uint64_t>(r2_val + r3_val, 0);
10564 SetS390OverflowCode(isOF);
10565 set_register(r1, r2_val + r3_val);
10566 return length;
10567}
10568
10569EVALUATE(SLGRK) {
10570 DCHECK_OPCODE(SLGRK);
10571 DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
10572 // 64-bit Non-clobbering unsigned arithmetics
10573 uint64_t r2_val = get_register(r2);
10574 uint64_t r3_val = get_register(r3);
10575 bool isOF = CheckOverflowForUIntSub(r2_val, r3_val);
10576 SetS390ConditionCode<uint64_t>(r2_val - r3_val, 0);
10577 SetS390OverflowCode(isOF);
10578 set_register(r1, r2_val - r3_val);
10579 return length;
10580}
10581
10582EVALUATE(LOCR) {
10583 UNIMPLEMENTED();
10584 USE(instr);
10585 return 0;
10586}
10587
10588EVALUATE(NRK) {
10589 DCHECK_OPCODE(NRK);
10590 DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
10591 // 32-bit Non-clobbering arithmetics / bitwise ops
10592 int32_t r2_val = get_low_register<int32_t>(r2);
10593 int32_t r3_val = get_low_register<int32_t>(r3);
10594 // Assume bitwise operation here
10595 uint32_t bitwise_result = 0;
10596 bitwise_result = r2_val & r3_val;
10597 SetS390BitWiseConditionCode<uint32_t>(bitwise_result);
10598 set_low_register(r1, bitwise_result);
10599 return length;
10600}
10601
10602EVALUATE(ORK) {
10603 DCHECK_OPCODE(ORK);
10604 DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
10605 // 32-bit Non-clobbering arithmetics / bitwise ops
10606 int32_t r2_val = get_low_register<int32_t>(r2);
10607 int32_t r3_val = get_low_register<int32_t>(r3);
10608 // Assume bitwise operation here
10609 uint32_t bitwise_result = 0;
10610 bitwise_result = r2_val | r3_val;
10611 SetS390BitWiseConditionCode<uint32_t>(bitwise_result);
10612 set_low_register(r1, bitwise_result);
10613 return length;
10614}
10615
10616EVALUATE(XRK) {
10617 DCHECK_OPCODE(XRK);
10618 DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
10619 // 32-bit Non-clobbering arithmetics / bitwise ops
10620 int32_t r2_val = get_low_register<int32_t>(r2);
10621 int32_t r3_val = get_low_register<int32_t>(r3);
10622 // Assume bitwise operation here
10623 uint32_t bitwise_result = 0;
10624 bitwise_result = r2_val ^ r3_val;
10625 SetS390BitWiseConditionCode<uint32_t>(bitwise_result);
10626 set_low_register(r1, bitwise_result);
10627 return length;
10628}
Ben Murdochc5610432016-08-08 18:44:38 +010010629
Ben Murdoch61f157c2016-09-16 13:49:30 +010010630EVALUATE(ARK) {
10631 DCHECK_OPCODE(ARK);
10632 DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
10633 // 32-bit Non-clobbering arithmetics / bitwise ops
10634 int32_t r2_val = get_low_register<int32_t>(r2);
10635 int32_t r3_val = get_low_register<int32_t>(r3);
10636 bool isOF = CheckOverflowForIntAdd(r2_val, r3_val, int32_t);
10637 SetS390ConditionCode<int32_t>(r2_val + r3_val, 0);
10638 SetS390OverflowCode(isOF);
10639 set_low_register(r1, r2_val + r3_val);
10640 return length;
10641}
Ben Murdochc5610432016-08-08 18:44:38 +010010642
Ben Murdoch61f157c2016-09-16 13:49:30 +010010643EVALUATE(SRK) {
10644 DCHECK_OPCODE(SRK);
10645 DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
10646 // 32-bit Non-clobbering arithmetics / bitwise ops
10647 int32_t r2_val = get_low_register<int32_t>(r2);
10648 int32_t r3_val = get_low_register<int32_t>(r3);
10649 bool isOF = CheckOverflowForIntSub(r2_val, r3_val, int32_t);
10650 SetS390ConditionCode<int32_t>(r2_val - r3_val, 0);
10651 SetS390OverflowCode(isOF);
10652 set_low_register(r1, r2_val - r3_val);
10653 return length;
10654}
Ben Murdochc5610432016-08-08 18:44:38 +010010655
Ben Murdoch61f157c2016-09-16 13:49:30 +010010656EVALUATE(ALRK) {
10657 DCHECK_OPCODE(ALRK);
10658 DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
10659 // 32-bit Non-clobbering unsigned arithmetics
10660 uint32_t r2_val = get_low_register<uint32_t>(r2);
10661 uint32_t r3_val = get_low_register<uint32_t>(r3);
10662 bool isOF = CheckOverflowForUIntAdd(r2_val, r3_val);
10663 SetS390ConditionCode<uint32_t>(r2_val + r3_val, 0);
10664 SetS390OverflowCode(isOF);
10665 set_low_register(r1, r2_val + r3_val);
10666 return length;
10667}
Ben Murdochc5610432016-08-08 18:44:38 +010010668
Ben Murdoch61f157c2016-09-16 13:49:30 +010010669EVALUATE(SLRK) {
10670 DCHECK_OPCODE(SLRK);
10671 DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
10672 // 32-bit Non-clobbering unsigned arithmetics
10673 uint32_t r2_val = get_low_register<uint32_t>(r2);
10674 uint32_t r3_val = get_low_register<uint32_t>(r3);
10675 bool isOF = CheckOverflowForUIntSub(r2_val, r3_val);
10676 SetS390ConditionCode<uint32_t>(r2_val - r3_val, 0);
10677 SetS390OverflowCode(isOF);
10678 set_low_register(r1, r2_val - r3_val);
10679 return length;
10680}
Ben Murdochc5610432016-08-08 18:44:38 +010010681
Ben Murdoch61f157c2016-09-16 13:49:30 +010010682EVALUATE(LTG) {
10683 DCHECK_OPCODE(LTG);
10684 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
10685 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
10686 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
10687 intptr_t addr = x2_val + b2_val + d2;
10688 int64_t value = ReadDW(addr);
10689 set_register(r1, value);
10690 SetS390ConditionCode<int64_t>(value, 0);
10691 return length;
10692}
Ben Murdochc5610432016-08-08 18:44:38 +010010693
Ben Murdoch61f157c2016-09-16 13:49:30 +010010694EVALUATE(CVBY) {
10695 UNIMPLEMENTED();
10696 USE(instr);
10697 return 0;
10698}
Ben Murdochc5610432016-08-08 18:44:38 +010010699
Ben Murdoch61f157c2016-09-16 13:49:30 +010010700EVALUATE(AG) {
10701 DCHECK_OPCODE(AG);
10702 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
10703 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
10704 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
10705 int64_t alu_out = get_register(r1);
10706 int64_t mem_val = ReadDW(b2_val + x2_val + d2);
10707 alu_out += mem_val;
10708 SetS390ConditionCode<int32_t>(alu_out, 0);
10709 set_register(r1, alu_out);
10710 return length;
10711}
Ben Murdochc5610432016-08-08 18:44:38 +010010712
Ben Murdoch61f157c2016-09-16 13:49:30 +010010713EVALUATE(SG) {
10714 DCHECK_OPCODE(SG);
10715 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
10716 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
10717 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
10718 int64_t alu_out = get_register(r1);
10719 int64_t mem_val = ReadDW(b2_val + x2_val + d2);
10720 alu_out -= mem_val;
10721 SetS390ConditionCode<int32_t>(alu_out, 0);
10722 set_register(r1, alu_out);
10723 return length;
10724}
Ben Murdochc5610432016-08-08 18:44:38 +010010725
Ben Murdoch61f157c2016-09-16 13:49:30 +010010726EVALUATE(ALG) {
10727 DCHECK_OPCODE(ALG);
10728#ifndef V8_TARGET_ARCH_S390X
10729 DCHECK(false);
10730#endif
10731 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
10732 uint64_t r1_val = get_register(r1);
10733 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
10734 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
10735 intptr_t d2_val = d2;
10736 uint64_t alu_out = r1_val;
10737 uint64_t mem_val = static_cast<uint64_t>(ReadDW(b2_val + d2_val + x2_val));
10738 alu_out += mem_val;
10739 SetS390ConditionCode<uint64_t>(alu_out, 0);
10740 set_register(r1, alu_out);
10741 return length;
10742}
Ben Murdochc5610432016-08-08 18:44:38 +010010743
Ben Murdoch61f157c2016-09-16 13:49:30 +010010744EVALUATE(SLG) {
10745 DCHECK_OPCODE(SLG);
10746#ifndef V8_TARGET_ARCH_S390X
10747 DCHECK(false);
10748#endif
10749 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
10750 uint64_t r1_val = get_register(r1);
10751 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
10752 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
10753 intptr_t d2_val = d2;
10754 uint64_t alu_out = r1_val;
10755 uint64_t mem_val = static_cast<uint64_t>(ReadDW(b2_val + d2_val + x2_val));
10756 alu_out -= mem_val;
10757 SetS390ConditionCode<uint64_t>(alu_out, 0);
10758 set_register(r1, alu_out);
10759 return length;
10760}
Ben Murdochc5610432016-08-08 18:44:38 +010010761
Ben Murdoch61f157c2016-09-16 13:49:30 +010010762EVALUATE(MSG) {
10763 DCHECK_OPCODE(MSG);
10764 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
10765 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
10766 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
10767 intptr_t d2_val = d2;
10768 int64_t mem_val = ReadDW(b2_val + d2_val + x2_val);
10769 int64_t r1_val = get_register(r1);
10770 set_register(r1, mem_val * r1_val);
10771 return length;
10772}
Ben Murdochc5610432016-08-08 18:44:38 +010010773
Ben Murdoch61f157c2016-09-16 13:49:30 +010010774EVALUATE(DSG) {
10775 UNIMPLEMENTED();
10776 USE(instr);
10777 return 0;
10778}
Ben Murdochc5610432016-08-08 18:44:38 +010010779
Ben Murdoch61f157c2016-09-16 13:49:30 +010010780EVALUATE(CVBG) {
10781 UNIMPLEMENTED();
10782 USE(instr);
10783 return 0;
10784}
Ben Murdochc5610432016-08-08 18:44:38 +010010785
Ben Murdoch61f157c2016-09-16 13:49:30 +010010786EVALUATE(LRVG) {
10787 UNIMPLEMENTED();
10788 USE(instr);
10789 return 0;
10790}
Ben Murdochc5610432016-08-08 18:44:38 +010010791
Ben Murdoch61f157c2016-09-16 13:49:30 +010010792EVALUATE(LT) {
10793 DCHECK_OPCODE(LT);
10794 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
10795 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
10796 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
10797 intptr_t addr = x2_val + b2_val + d2;
10798 int32_t value = ReadW(addr, instr);
10799 set_low_register(r1, value);
10800 SetS390ConditionCode<int32_t>(value, 0);
10801 return length;
10802}
Ben Murdochc5610432016-08-08 18:44:38 +010010803
Ben Murdoch61f157c2016-09-16 13:49:30 +010010804EVALUATE(LGH) {
10805 DCHECK_OPCODE(LGH);
10806 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
10807 // Miscellaneous Loads and Stores
10808 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
10809 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
10810 intptr_t addr = x2_val + b2_val + d2;
10811 int64_t mem_val = static_cast<int64_t>(ReadH(addr, instr));
10812 set_register(r1, mem_val);
10813 return length;
10814}
Ben Murdochc5610432016-08-08 18:44:38 +010010815
Ben Murdoch61f157c2016-09-16 13:49:30 +010010816EVALUATE(LLGF) {
10817 DCHECK_OPCODE(LLGF);
10818 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
10819 // Miscellaneous Loads and Stores
10820 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
10821 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
10822 intptr_t addr = x2_val + b2_val + d2;
10823 uint64_t mem_val = static_cast<uint64_t>(ReadWU(addr, instr));
10824 set_register(r1, mem_val);
10825 return length;
10826}
Ben Murdochc5610432016-08-08 18:44:38 +010010827
Ben Murdoch61f157c2016-09-16 13:49:30 +010010828EVALUATE(LLGT) {
10829 UNIMPLEMENTED();
10830 USE(instr);
10831 return 0;
10832}
Ben Murdochc5610432016-08-08 18:44:38 +010010833
Ben Murdoch61f157c2016-09-16 13:49:30 +010010834EVALUATE(AGF) {
10835 DCHECK_OPCODE(AGF);
10836 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
10837 uint64_t r1_val = get_register(r1);
10838 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
10839 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
10840 intptr_t d2_val = d2;
10841 uint64_t alu_out = r1_val;
10842 uint32_t mem_val = ReadW(b2_val + d2_val + x2_val, instr);
10843 alu_out += mem_val;
10844 SetS390ConditionCode<int64_t>(alu_out, 0);
10845 set_register(r1, alu_out);
10846 return length;
10847}
Ben Murdochc5610432016-08-08 18:44:38 +010010848
Ben Murdoch61f157c2016-09-16 13:49:30 +010010849EVALUATE(SGF) {
10850 DCHECK_OPCODE(SGF);
10851 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
10852 uint64_t r1_val = get_register(r1);
10853 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
10854 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
10855 intptr_t d2_val = d2;
10856 uint64_t alu_out = r1_val;
10857 uint32_t mem_val = ReadW(b2_val + d2_val + x2_val, instr);
10858 alu_out -= mem_val;
10859 SetS390ConditionCode<int64_t>(alu_out, 0);
10860 set_register(r1, alu_out);
10861 return length;
10862}
Ben Murdochc5610432016-08-08 18:44:38 +010010863
Ben Murdoch61f157c2016-09-16 13:49:30 +010010864EVALUATE(ALGF) {
10865 UNIMPLEMENTED();
10866 USE(instr);
10867 return 0;
10868}
Ben Murdochc5610432016-08-08 18:44:38 +010010869
Ben Murdoch61f157c2016-09-16 13:49:30 +010010870EVALUATE(SLGF) {
10871 UNIMPLEMENTED();
10872 USE(instr);
10873 return 0;
10874}
Ben Murdochc5610432016-08-08 18:44:38 +010010875
Ben Murdoch61f157c2016-09-16 13:49:30 +010010876EVALUATE(MSGF) {
10877 UNIMPLEMENTED();
10878 USE(instr);
10879 return 0;
10880}
Ben Murdochc5610432016-08-08 18:44:38 +010010881
Ben Murdoch61f157c2016-09-16 13:49:30 +010010882EVALUATE(DSGF) {
10883 UNIMPLEMENTED();
10884 USE(instr);
10885 return 0;
10886}
Ben Murdochc5610432016-08-08 18:44:38 +010010887
Ben Murdoch61f157c2016-09-16 13:49:30 +010010888EVALUATE(LRV) {
10889 DCHECK_OPCODE(LRV);
10890 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
10891 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
10892 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
10893 intptr_t mem_addr = b2_val + x2_val + d2;
10894 int32_t mem_val = ReadW(mem_addr, instr);
10895 set_low_register(r1, ByteReverse(mem_val));
10896 return length;
10897}
Ben Murdochc5610432016-08-08 18:44:38 +010010898
Ben Murdoch61f157c2016-09-16 13:49:30 +010010899EVALUATE(LRVH) {
10900 DCHECK_OPCODE(LRVH);
10901 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
10902 int32_t r1_val = get_low_register<int32_t>(r1);
10903 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
10904 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
10905 intptr_t mem_addr = b2_val + x2_val + d2;
10906 int16_t mem_val = ReadH(mem_addr, instr);
10907 int32_t result = ByteReverse(mem_val) & 0x0000ffff;
10908 result |= r1_val & 0xffff0000;
10909 set_low_register(r1, result);
10910 return length;
10911}
Ben Murdochc5610432016-08-08 18:44:38 +010010912
Ben Murdoch61f157c2016-09-16 13:49:30 +010010913EVALUATE(CG) {
10914 DCHECK_OPCODE(CG);
10915 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
10916 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
10917 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
10918 int64_t alu_out = get_register(r1);
10919 int64_t mem_val = ReadDW(b2_val + x2_val + d2);
10920 SetS390ConditionCode<int64_t>(alu_out, mem_val);
10921 set_register(r1, alu_out);
10922 return length;
10923}
Ben Murdochc5610432016-08-08 18:44:38 +010010924
Ben Murdoch61f157c2016-09-16 13:49:30 +010010925EVALUATE(CLG) {
10926 DCHECK_OPCODE(CLG);
10927 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
10928 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
10929 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
10930 int64_t alu_out = get_register(r1);
10931 int64_t mem_val = ReadDW(b2_val + x2_val + d2);
10932 SetS390ConditionCode<uint64_t>(alu_out, mem_val);
10933 set_register(r1, alu_out);
10934 return length;
10935}
Ben Murdochc5610432016-08-08 18:44:38 +010010936
Ben Murdoch61f157c2016-09-16 13:49:30 +010010937EVALUATE(NTSTG) {
10938 UNIMPLEMENTED();
10939 USE(instr);
10940 return 0;
10941}
Ben Murdochc5610432016-08-08 18:44:38 +010010942
Ben Murdoch61f157c2016-09-16 13:49:30 +010010943EVALUATE(CVDY) {
10944 UNIMPLEMENTED();
10945 USE(instr);
10946 return 0;
10947}
Ben Murdochc5610432016-08-08 18:44:38 +010010948
Ben Murdoch61f157c2016-09-16 13:49:30 +010010949EVALUATE(CVDG) {
10950 UNIMPLEMENTED();
10951 USE(instr);
10952 return 0;
10953}
Ben Murdochc5610432016-08-08 18:44:38 +010010954
Ben Murdoch61f157c2016-09-16 13:49:30 +010010955EVALUATE(STRVG) {
10956 UNIMPLEMENTED();
10957 USE(instr);
10958 return 0;
10959}
Ben Murdochc5610432016-08-08 18:44:38 +010010960
Ben Murdoch61f157c2016-09-16 13:49:30 +010010961EVALUATE(CGF) {
10962 UNIMPLEMENTED();
10963 USE(instr);
10964 return 0;
10965}
Ben Murdochc5610432016-08-08 18:44:38 +010010966
Ben Murdoch61f157c2016-09-16 13:49:30 +010010967EVALUATE(CLGF) {
10968 UNIMPLEMENTED();
10969 USE(instr);
10970 return 0;
10971}
Ben Murdochc5610432016-08-08 18:44:38 +010010972
Ben Murdoch61f157c2016-09-16 13:49:30 +010010973EVALUATE(LTGF) {
10974 UNIMPLEMENTED();
10975 USE(instr);
10976 return 0;
10977}
Ben Murdochc5610432016-08-08 18:44:38 +010010978
Ben Murdoch61f157c2016-09-16 13:49:30 +010010979EVALUATE(CGH) {
10980 UNIMPLEMENTED();
10981 USE(instr);
10982 return 0;
10983}
Ben Murdochc5610432016-08-08 18:44:38 +010010984
Ben Murdoch61f157c2016-09-16 13:49:30 +010010985EVALUATE(PFD) {
10986 UNIMPLEMENTED();
10987 USE(instr);
10988 return 0;
10989}
Ben Murdochc5610432016-08-08 18:44:38 +010010990
Ben Murdoch61f157c2016-09-16 13:49:30 +010010991EVALUATE(STRV) {
10992 DCHECK_OPCODE(STRV);
10993 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
10994 int32_t r1_val = get_low_register<int32_t>(r1);
10995 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
10996 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
10997 intptr_t mem_addr = b2_val + x2_val + d2;
10998 WriteW(mem_addr, ByteReverse(r1_val), instr);
10999 return length;
11000}
Ben Murdochc5610432016-08-08 18:44:38 +010011001
Ben Murdoch61f157c2016-09-16 13:49:30 +010011002EVALUATE(STRVH) {
11003 DCHECK_OPCODE(STRVH);
11004 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11005 int32_t r1_val = get_low_register<int32_t>(r1);
11006 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11007 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11008 intptr_t mem_addr = b2_val + x2_val + d2;
11009 int16_t result = static_cast<int16_t>(r1_val >> 16);
11010 WriteH(mem_addr, ByteReverse(result), instr);
11011 return length;
11012}
Ben Murdochc5610432016-08-08 18:44:38 +010011013
Ben Murdoch61f157c2016-09-16 13:49:30 +010011014EVALUATE(BCTG) {
11015 UNIMPLEMENTED();
11016 USE(instr);
11017 return 0;
11018}
Ben Murdochc5610432016-08-08 18:44:38 +010011019
Ben Murdoch61f157c2016-09-16 13:49:30 +010011020EVALUATE(MSY) {
11021 DCHECK_OPCODE(MSY);
11022 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11023 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11024 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11025 intptr_t d2_val = d2;
11026 int32_t mem_val = ReadW(b2_val + d2_val + x2_val, instr);
11027 int32_t r1_val = get_low_register<int32_t>(r1);
11028 set_low_register(r1, mem_val * r1_val);
11029 return length;
11030}
Ben Murdochc5610432016-08-08 18:44:38 +010011031
Ben Murdoch61f157c2016-09-16 13:49:30 +010011032EVALUATE(NY) {
11033 DCHECK_OPCODE(NY);
11034 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11035 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11036 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11037 int32_t alu_out = get_low_register<int32_t>(r1);
11038 int32_t mem_val = ReadW(b2_val + x2_val + d2, instr);
11039 alu_out &= mem_val;
11040 SetS390BitWiseConditionCode<uint32_t>(alu_out);
11041 set_low_register(r1, alu_out);
11042 return length;
11043}
Ben Murdochc5610432016-08-08 18:44:38 +010011044
Ben Murdoch61f157c2016-09-16 13:49:30 +010011045EVALUATE(CLY) {
11046 DCHECK_OPCODE(CLY);
11047 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11048 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11049 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11050 uint32_t alu_out = get_low_register<uint32_t>(r1);
11051 uint32_t mem_val = ReadWU(b2_val + x2_val + d2, instr);
11052 SetS390ConditionCode<uint32_t>(alu_out, mem_val);
11053 return length;
11054}
Ben Murdochc5610432016-08-08 18:44:38 +010011055
Ben Murdoch61f157c2016-09-16 13:49:30 +010011056EVALUATE(OY) {
11057 DCHECK_OPCODE(OY);
11058 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11059 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11060 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11061 int32_t alu_out = get_low_register<int32_t>(r1);
11062 int32_t mem_val = ReadW(b2_val + x2_val + d2, instr);
11063 alu_out |= mem_val;
11064 SetS390BitWiseConditionCode<uint32_t>(alu_out);
11065 set_low_register(r1, alu_out);
11066 return length;
11067}
Ben Murdochc5610432016-08-08 18:44:38 +010011068
Ben Murdoch61f157c2016-09-16 13:49:30 +010011069EVALUATE(XY) {
11070 DCHECK_OPCODE(XY);
11071 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11072 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11073 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11074 int32_t alu_out = get_low_register<int32_t>(r1);
11075 int32_t mem_val = ReadW(b2_val + x2_val + d2, instr);
11076 alu_out ^= mem_val;
11077 SetS390BitWiseConditionCode<uint32_t>(alu_out);
11078 set_low_register(r1, alu_out);
11079 return length;
11080}
Ben Murdochc5610432016-08-08 18:44:38 +010011081
Ben Murdoch61f157c2016-09-16 13:49:30 +010011082EVALUATE(CY) {
11083 DCHECK_OPCODE(CY);
11084 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11085 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11086 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11087 int32_t alu_out = get_low_register<int32_t>(r1);
11088 int32_t mem_val = ReadW(b2_val + x2_val + d2, instr);
11089 SetS390ConditionCode<int32_t>(alu_out, mem_val);
11090 return length;
11091}
Ben Murdochc5610432016-08-08 18:44:38 +010011092
Ben Murdoch61f157c2016-09-16 13:49:30 +010011093EVALUATE(AY) {
11094 DCHECK_OPCODE(AY);
11095 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11096 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11097 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11098 int32_t alu_out = get_low_register<int32_t>(r1);
11099 int32_t mem_val = ReadW(b2_val + x2_val + d2, instr);
11100 bool isOF = false;
11101 isOF = CheckOverflowForIntAdd(alu_out, mem_val, int32_t);
11102 alu_out += mem_val;
11103 SetS390ConditionCode<int32_t>(alu_out, 0);
11104 SetS390OverflowCode(isOF);
11105 set_low_register(r1, alu_out);
11106 return length;
11107}
Ben Murdochc5610432016-08-08 18:44:38 +010011108
Ben Murdoch61f157c2016-09-16 13:49:30 +010011109EVALUATE(SY) {
11110 DCHECK_OPCODE(SY);
11111 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11112 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11113 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11114 int32_t alu_out = get_low_register<int32_t>(r1);
11115 int32_t mem_val = ReadW(b2_val + x2_val + d2, instr);
11116 bool isOF = false;
11117 isOF = CheckOverflowForIntSub(alu_out, mem_val, int32_t);
11118 alu_out -= mem_val;
11119 SetS390ConditionCode<int32_t>(alu_out, 0);
11120 SetS390OverflowCode(isOF);
11121 set_low_register(r1, alu_out);
11122 return length;
11123}
Ben Murdochc5610432016-08-08 18:44:38 +010011124
Ben Murdoch61f157c2016-09-16 13:49:30 +010011125EVALUATE(MFY) {
11126 UNIMPLEMENTED();
11127 USE(instr);
11128 return 0;
11129}
Ben Murdochc5610432016-08-08 18:44:38 +010011130
Ben Murdoch61f157c2016-09-16 13:49:30 +010011131EVALUATE(ALY) {
11132 DCHECK_OPCODE(ALY);
11133 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11134 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11135 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11136 uint32_t alu_out = get_low_register<uint32_t>(r1);
11137 uint32_t mem_val = ReadWU(b2_val + x2_val + d2, instr);
11138 alu_out += mem_val;
11139 set_low_register(r1, alu_out);
11140 SetS390ConditionCode<uint32_t>(alu_out, 0);
11141 return length;
11142}
Ben Murdochc5610432016-08-08 18:44:38 +010011143
Ben Murdoch61f157c2016-09-16 13:49:30 +010011144EVALUATE(SLY) {
11145 DCHECK_OPCODE(SLY);
11146 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11147 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11148 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11149 uint32_t alu_out = get_low_register<uint32_t>(r1);
11150 uint32_t mem_val = ReadWU(b2_val + x2_val + d2, instr);
11151 alu_out -= mem_val;
11152 set_low_register(r1, alu_out);
11153 SetS390ConditionCode<uint32_t>(alu_out, 0);
11154 return length;
11155}
Ben Murdochc5610432016-08-08 18:44:38 +010011156
Ben Murdoch61f157c2016-09-16 13:49:30 +010011157EVALUATE(STHY) {
11158 DCHECK_OPCODE(STHY);
11159 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11160 // Miscellaneous Loads and Stores
11161 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11162 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11163 intptr_t addr = x2_val + b2_val + d2;
11164 uint16_t value = get_low_register<uint32_t>(r1);
11165 WriteH(addr, value, instr);
11166 return length;
11167}
Ben Murdochc5610432016-08-08 18:44:38 +010011168
Ben Murdoch61f157c2016-09-16 13:49:30 +010011169EVALUATE(LAY) {
11170 DCHECK_OPCODE(LAY);
11171 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11172 // Load Address
11173 int rb = b2;
11174 int rx = x2;
11175 int offset = d2;
11176 int64_t rb_val = (rb == 0) ? 0 : get_register(rb);
11177 int64_t rx_val = (rx == 0) ? 0 : get_register(rx);
11178 set_register(r1, rx_val + rb_val + offset);
11179 return length;
11180}
Ben Murdochc5610432016-08-08 18:44:38 +010011181
Ben Murdoch61f157c2016-09-16 13:49:30 +010011182EVALUATE(STCY) {
11183 DCHECK_OPCODE(STCY);
11184 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11185 // Miscellaneous Loads and Stores
11186 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11187 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11188 intptr_t addr = x2_val + b2_val + d2;
11189 uint8_t value = get_low_register<uint32_t>(r1);
11190 WriteB(addr, value);
11191 return length;
11192}
Ben Murdochc5610432016-08-08 18:44:38 +010011193
Ben Murdoch61f157c2016-09-16 13:49:30 +010011194EVALUATE(ICY) {
11195 UNIMPLEMENTED();
11196 USE(instr);
11197 return 0;
11198}
Ben Murdochc5610432016-08-08 18:44:38 +010011199
Ben Murdoch61f157c2016-09-16 13:49:30 +010011200EVALUATE(LAEY) {
11201 UNIMPLEMENTED();
11202 USE(instr);
11203 return 0;
11204}
Ben Murdochc5610432016-08-08 18:44:38 +010011205
Ben Murdoch61f157c2016-09-16 13:49:30 +010011206EVALUATE(LB) {
11207 DCHECK_OPCODE(LB);
11208 // Miscellaneous Loads and Stores
11209 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11210 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11211 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11212 intptr_t addr = x2_val + b2_val + d2;
11213 int32_t mem_val = ReadB(addr);
11214 set_low_register(r1, mem_val);
11215 return length;
11216}
Ben Murdochc5610432016-08-08 18:44:38 +010011217
Ben Murdoch61f157c2016-09-16 13:49:30 +010011218EVALUATE(LGB) {
11219 DCHECK_OPCODE(LGB);
11220 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11221 // Miscellaneous Loads and Stores
11222 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11223 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11224 intptr_t addr = x2_val + b2_val + d2;
11225 int64_t mem_val = ReadB(addr);
11226 set_register(r1, mem_val);
11227 return length;
11228}
Ben Murdochc5610432016-08-08 18:44:38 +010011229
Ben Murdoch61f157c2016-09-16 13:49:30 +010011230EVALUATE(LHY) {
11231 DCHECK_OPCODE(LHY);
11232 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11233 // Miscellaneous Loads and Stores
11234 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11235 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11236 intptr_t addr = x2_val + b2_val + d2;
11237 int32_t result = static_cast<int32_t>(ReadH(addr, instr));
11238 set_low_register(r1, result);
11239 return length;
11240}
Ben Murdochc5610432016-08-08 18:44:38 +010011241
Ben Murdoch61f157c2016-09-16 13:49:30 +010011242EVALUATE(CHY) {
11243 UNIMPLEMENTED();
11244 USE(instr);
11245 return 0;
11246}
Ben Murdochc5610432016-08-08 18:44:38 +010011247
Ben Murdoch61f157c2016-09-16 13:49:30 +010011248EVALUATE(AHY) {
11249 DCHECK_OPCODE(AHY);
11250 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11251 int32_t r1_val = get_low_register<int32_t>(r1);
11252 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11253 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11254 intptr_t d2_val = d2;
11255 int32_t mem_val =
11256 static_cast<int32_t>(ReadH(b2_val + d2_val + x2_val, instr));
11257 int32_t alu_out = 0;
11258 bool isOF = false;
11259 alu_out = r1_val + mem_val;
11260 isOF = CheckOverflowForIntAdd(r1_val, mem_val, int32_t);
11261 set_low_register(r1, alu_out);
11262 SetS390ConditionCode<int32_t>(alu_out, 0);
11263 SetS390OverflowCode(isOF);
11264 return length;
11265}
Ben Murdochc5610432016-08-08 18:44:38 +010011266
Ben Murdoch61f157c2016-09-16 13:49:30 +010011267EVALUATE(SHY) {
11268 DCHECK_OPCODE(SHY);
11269 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11270 int32_t r1_val = get_low_register<int32_t>(r1);
11271 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11272 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11273 intptr_t d2_val = d2;
11274 int32_t mem_val =
11275 static_cast<int32_t>(ReadH(b2_val + d2_val + x2_val, instr));
11276 int32_t alu_out = 0;
11277 bool isOF = false;
11278 alu_out = r1_val - mem_val;
11279 isOF = CheckOverflowForIntSub(r1_val, mem_val, int64_t);
11280 set_low_register(r1, alu_out);
11281 SetS390ConditionCode<int32_t>(alu_out, 0);
11282 SetS390OverflowCode(isOF);
11283 return length;
11284}
Ben Murdochc5610432016-08-08 18:44:38 +010011285
Ben Murdoch61f157c2016-09-16 13:49:30 +010011286EVALUATE(MHY) {
11287 UNIMPLEMENTED();
11288 USE(instr);
11289 return 0;
11290}
Ben Murdochc5610432016-08-08 18:44:38 +010011291
Ben Murdoch61f157c2016-09-16 13:49:30 +010011292EVALUATE(NG) {
11293 DCHECK_OPCODE(NG);
11294 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11295 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11296 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11297 int64_t alu_out = get_register(r1);
11298 int64_t mem_val = ReadDW(b2_val + x2_val + d2);
11299 alu_out &= mem_val;
11300 SetS390BitWiseConditionCode<uint32_t>(alu_out);
11301 set_register(r1, alu_out);
11302 return length;
11303}
Ben Murdochc5610432016-08-08 18:44:38 +010011304
Ben Murdoch61f157c2016-09-16 13:49:30 +010011305EVALUATE(OG) {
11306 DCHECK_OPCODE(OG);
11307 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11308 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11309 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11310 int64_t alu_out = get_register(r1);
11311 int64_t mem_val = ReadDW(b2_val + x2_val + d2);
11312 alu_out |= mem_val;
11313 SetS390BitWiseConditionCode<uint32_t>(alu_out);
11314 set_register(r1, alu_out);
11315 return length;
11316}
Ben Murdochc5610432016-08-08 18:44:38 +010011317
Ben Murdoch61f157c2016-09-16 13:49:30 +010011318EVALUATE(XG) {
11319 DCHECK_OPCODE(XG);
11320 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11321 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11322 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11323 int64_t alu_out = get_register(r1);
11324 int64_t mem_val = ReadDW(b2_val + x2_val + d2);
11325 alu_out ^= mem_val;
11326 SetS390BitWiseConditionCode<uint32_t>(alu_out);
11327 set_register(r1, alu_out);
11328 return length;
11329}
Ben Murdochc5610432016-08-08 18:44:38 +010011330
Ben Murdoch61f157c2016-09-16 13:49:30 +010011331EVALUATE(LGAT) {
11332 UNIMPLEMENTED();
11333 USE(instr);
11334 return 0;
11335}
Ben Murdochc5610432016-08-08 18:44:38 +010011336
Ben Murdoch61f157c2016-09-16 13:49:30 +010011337EVALUATE(MLG) {
11338 UNIMPLEMENTED();
11339 USE(instr);
11340 return 0;
11341}
Ben Murdochc5610432016-08-08 18:44:38 +010011342
Ben Murdoch61f157c2016-09-16 13:49:30 +010011343EVALUATE(DLG) {
11344 UNIMPLEMENTED();
11345 USE(instr);
11346 return 0;
11347}
Ben Murdochc5610432016-08-08 18:44:38 +010011348
Ben Murdoch61f157c2016-09-16 13:49:30 +010011349EVALUATE(ALCG) {
11350 UNIMPLEMENTED();
11351 USE(instr);
11352 return 0;
11353}
Ben Murdochc5610432016-08-08 18:44:38 +010011354
Ben Murdoch61f157c2016-09-16 13:49:30 +010011355EVALUATE(SLBG) {
11356 UNIMPLEMENTED();
11357 USE(instr);
11358 return 0;
11359}
Ben Murdochc5610432016-08-08 18:44:38 +010011360
Ben Murdoch61f157c2016-09-16 13:49:30 +010011361EVALUATE(STPQ) {
11362 UNIMPLEMENTED();
11363 USE(instr);
11364 return 0;
11365}
Ben Murdochc5610432016-08-08 18:44:38 +010011366
Ben Murdoch61f157c2016-09-16 13:49:30 +010011367EVALUATE(LPQ) {
11368 UNIMPLEMENTED();
11369 USE(instr);
11370 return 0;
11371}
Ben Murdochc5610432016-08-08 18:44:38 +010011372
Ben Murdoch61f157c2016-09-16 13:49:30 +010011373EVALUATE(LLGH) {
11374 DCHECK_OPCODE(LLGH);
11375 // Load Logical Halfword
11376 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11377 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11378 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11379 intptr_t d2_val = d2;
11380 uint16_t mem_val = ReadHU(b2_val + d2_val + x2_val, instr);
11381 set_register(r1, mem_val);
11382 return length;
11383}
Ben Murdochc5610432016-08-08 18:44:38 +010011384
Ben Murdoch61f157c2016-09-16 13:49:30 +010011385EVALUATE(LLH) {
11386 DCHECK_OPCODE(LLH);
11387 // Load Logical Halfword
11388 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
11389 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11390 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
11391 intptr_t d2_val = d2;
11392 uint16_t mem_val = ReadHU(b2_val + d2_val + x2_val, instr);
11393 set_low_register(r1, mem_val);
11394 return length;
11395}
Ben Murdochc5610432016-08-08 18:44:38 +010011396
Ben Murdoch61f157c2016-09-16 13:49:30 +010011397EVALUATE(ML) {
11398 UNIMPLEMENTED();
11399 USE(instr);
11400 return 0;
11401}
Ben Murdochc5610432016-08-08 18:44:38 +010011402
Ben Murdoch61f157c2016-09-16 13:49:30 +010011403EVALUATE(DL) {
11404 UNIMPLEMENTED();
11405 USE(instr);
11406 return 0;
11407}
Ben Murdochc5610432016-08-08 18:44:38 +010011408
Ben Murdoch61f157c2016-09-16 13:49:30 +010011409EVALUATE(ALC) {
11410 UNIMPLEMENTED();
11411 USE(instr);
11412 return 0;
11413}
Ben Murdochc5610432016-08-08 18:44:38 +010011414
Ben Murdoch61f157c2016-09-16 13:49:30 +010011415EVALUATE(SLB) {
11416 UNIMPLEMENTED();
11417 USE(instr);
11418 return 0;
11419}
Ben Murdochc5610432016-08-08 18:44:38 +010011420
Ben Murdoch61f157c2016-09-16 13:49:30 +010011421EVALUATE(LLGTAT) {
11422 UNIMPLEMENTED();
11423 USE(instr);
11424 return 0;
11425}
Ben Murdochc5610432016-08-08 18:44:38 +010011426
Ben Murdoch61f157c2016-09-16 13:49:30 +010011427EVALUATE(LLGFAT) {
11428 UNIMPLEMENTED();
11429 USE(instr);
11430 return 0;
11431}
Ben Murdochc5610432016-08-08 18:44:38 +010011432
Ben Murdoch61f157c2016-09-16 13:49:30 +010011433EVALUATE(LAT) {
11434 UNIMPLEMENTED();
11435 USE(instr);
11436 return 0;
11437}
Ben Murdochc5610432016-08-08 18:44:38 +010011438
Ben Murdoch61f157c2016-09-16 13:49:30 +010011439EVALUATE(LBH) {
11440 UNIMPLEMENTED();
11441 USE(instr);
11442 return 0;
11443}
Ben Murdochc5610432016-08-08 18:44:38 +010011444
Ben Murdoch61f157c2016-09-16 13:49:30 +010011445EVALUATE(LLCH) {
11446 UNIMPLEMENTED();
11447 USE(instr);
11448 return 0;
11449}
Ben Murdochc5610432016-08-08 18:44:38 +010011450
Ben Murdoch61f157c2016-09-16 13:49:30 +010011451EVALUATE(STCH) {
11452 UNIMPLEMENTED();
11453 USE(instr);
11454 return 0;
11455}
Ben Murdochc5610432016-08-08 18:44:38 +010011456
Ben Murdoch61f157c2016-09-16 13:49:30 +010011457EVALUATE(LHH) {
11458 UNIMPLEMENTED();
11459 USE(instr);
11460 return 0;
11461}
Ben Murdochc5610432016-08-08 18:44:38 +010011462
Ben Murdoch61f157c2016-09-16 13:49:30 +010011463EVALUATE(LLHH) {
11464 UNIMPLEMENTED();
11465 USE(instr);
11466 return 0;
11467}
Ben Murdochc5610432016-08-08 18:44:38 +010011468
Ben Murdoch61f157c2016-09-16 13:49:30 +010011469EVALUATE(STHH) {
11470 UNIMPLEMENTED();
11471 USE(instr);
11472 return 0;
11473}
Ben Murdochc5610432016-08-08 18:44:38 +010011474
Ben Murdoch61f157c2016-09-16 13:49:30 +010011475EVALUATE(LFHAT) {
11476 UNIMPLEMENTED();
11477 USE(instr);
11478 return 0;
11479}
Ben Murdochc5610432016-08-08 18:44:38 +010011480
Ben Murdoch61f157c2016-09-16 13:49:30 +010011481EVALUATE(LFH) {
11482 UNIMPLEMENTED();
11483 USE(instr);
11484 return 0;
11485}
Ben Murdochc5610432016-08-08 18:44:38 +010011486
Ben Murdoch61f157c2016-09-16 13:49:30 +010011487EVALUATE(STFH) {
11488 UNIMPLEMENTED();
11489 USE(instr);
11490 return 0;
11491}
Ben Murdochc5610432016-08-08 18:44:38 +010011492
Ben Murdoch61f157c2016-09-16 13:49:30 +010011493EVALUATE(CHF) {
11494 UNIMPLEMENTED();
11495 USE(instr);
11496 return 0;
11497}
Ben Murdochc5610432016-08-08 18:44:38 +010011498
Ben Murdoch61f157c2016-09-16 13:49:30 +010011499EVALUATE(MVCDK) {
11500 UNIMPLEMENTED();
11501 USE(instr);
11502 return 0;
11503}
Ben Murdochc5610432016-08-08 18:44:38 +010011504
Ben Murdoch61f157c2016-09-16 13:49:30 +010011505EVALUATE(MVHHI) {
11506 UNIMPLEMENTED();
11507 USE(instr);
11508 return 0;
11509}
Ben Murdochc5610432016-08-08 18:44:38 +010011510
Ben Murdoch61f157c2016-09-16 13:49:30 +010011511EVALUATE(MVGHI) {
11512 DCHECK_OPCODE(MVGHI);
11513 // Move Integer (64)
11514 DECODE_SIL_INSTRUCTION(b1, d1, i2);
11515 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
11516 intptr_t src_addr = b1_val + d1;
11517 WriteDW(src_addr, i2);
11518 return length;
11519}
Ben Murdochc5610432016-08-08 18:44:38 +010011520
Ben Murdoch61f157c2016-09-16 13:49:30 +010011521EVALUATE(MVHI) {
11522 DCHECK_OPCODE(MVHI);
11523 // Move Integer (32)
11524 DECODE_SIL_INSTRUCTION(b1, d1, i2);
11525 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
11526 intptr_t src_addr = b1_val + d1;
11527 WriteW(src_addr, i2, instr);
11528 return length;
11529}
Ben Murdochc5610432016-08-08 18:44:38 +010011530
Ben Murdoch61f157c2016-09-16 13:49:30 +010011531EVALUATE(CHHSI) {
11532 UNIMPLEMENTED();
11533 USE(instr);
11534 return 0;
11535}
Ben Murdochc5610432016-08-08 18:44:38 +010011536
Ben Murdoch61f157c2016-09-16 13:49:30 +010011537EVALUATE(CGHSI) {
11538 UNIMPLEMENTED();
11539 USE(instr);
11540 return 0;
11541}
Ben Murdochc5610432016-08-08 18:44:38 +010011542
Ben Murdoch61f157c2016-09-16 13:49:30 +010011543EVALUATE(CHSI) {
11544 UNIMPLEMENTED();
11545 USE(instr);
11546 return 0;
11547}
Ben Murdochc5610432016-08-08 18:44:38 +010011548
Ben Murdoch61f157c2016-09-16 13:49:30 +010011549EVALUATE(CLFHSI) {
11550 UNIMPLEMENTED();
11551 USE(instr);
11552 return 0;
11553}
Ben Murdochc5610432016-08-08 18:44:38 +010011554
Ben Murdoch61f157c2016-09-16 13:49:30 +010011555EVALUATE(TBEGIN) {
11556 UNIMPLEMENTED();
11557 USE(instr);
11558 return 0;
11559}
Ben Murdochc5610432016-08-08 18:44:38 +010011560
Ben Murdoch61f157c2016-09-16 13:49:30 +010011561EVALUATE(TBEGINC) {
11562 UNIMPLEMENTED();
11563 USE(instr);
11564 return 0;
11565}
Ben Murdochc5610432016-08-08 18:44:38 +010011566
Ben Murdoch61f157c2016-09-16 13:49:30 +010011567EVALUATE(LMG) {
11568 DCHECK_OPCODE(LMG);
11569 // Store Multiple 64-bits.
11570 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
11571 int rb = b2;
11572 int offset = d2;
Ben Murdochc5610432016-08-08 18:44:38 +010011573
Ben Murdoch61f157c2016-09-16 13:49:30 +010011574 // Regs roll around if r3 is less than r1.
11575 // Artifically increase r3 by 16 so we can calculate
11576 // the number of regs stored properly.
11577 if (r3 < r1) r3 += 16;
Ben Murdochc5610432016-08-08 18:44:38 +010011578
Ben Murdoch61f157c2016-09-16 13:49:30 +010011579 int64_t rb_val = (rb == 0) ? 0 : get_register(rb);
Ben Murdochc5610432016-08-08 18:44:38 +010011580
Ben Murdoch61f157c2016-09-16 13:49:30 +010011581 // Store each register in ascending order.
11582 for (int i = 0; i <= r3 - r1; i++) {
11583 int64_t value = ReadDW(rb_val + offset + 8 * i);
11584 set_register((r1 + i) % 16, value);
11585 }
11586 return length;
11587}
Ben Murdochc5610432016-08-08 18:44:38 +010011588
Ben Murdoch61f157c2016-09-16 13:49:30 +010011589EVALUATE(SRAG) {
11590 DCHECK_OPCODE(SRAG);
11591 // 64-bit non-clobbering shift-left/right arithmetic
11592 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
11593 // only takes rightmost 6 bits
11594 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11595 int shiftBits = (b2_val + d2) & 0x3F;
11596 int64_t r3_val = get_register(r3);
11597 intptr_t alu_out = 0;
11598 bool isOF = false;
11599 alu_out = r3_val >> shiftBits;
11600 set_register(r1, alu_out);
11601 SetS390ConditionCode<intptr_t>(alu_out, 0);
11602 SetS390OverflowCode(isOF);
11603 return length;
11604}
Ben Murdochc5610432016-08-08 18:44:38 +010011605
Ben Murdoch61f157c2016-09-16 13:49:30 +010011606EVALUATE(SLAG) {
11607 DCHECK_OPCODE(SLAG);
11608 // 64-bit non-clobbering shift-left/right arithmetic
11609 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
11610 // only takes rightmost 6 bits
11611 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11612 int shiftBits = (b2_val + d2) & 0x3F;
11613 int64_t r3_val = get_register(r3);
11614 intptr_t alu_out = 0;
11615 bool isOF = false;
11616 isOF = CheckOverflowForShiftLeft(r3_val, shiftBits);
11617 alu_out = r3_val << shiftBits;
11618 set_register(r1, alu_out);
11619 SetS390ConditionCode<intptr_t>(alu_out, 0);
11620 SetS390OverflowCode(isOF);
11621 return length;
11622}
Ben Murdochc5610432016-08-08 18:44:38 +010011623
Ben Murdoch61f157c2016-09-16 13:49:30 +010011624EVALUATE(SRLG) {
11625 DCHECK_OPCODE(SRLG);
11626 // For SLLG/SRLG, the 64-bit third operand is shifted the number
11627 // of bits specified by the second-operand address, and the result is
11628 // placed at the first-operand location. Except for when the R1 and R3
11629 // fields designate the same register, the third operand remains
11630 // unchanged in general register R3.
11631 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
11632 // only takes rightmost 6 bits
11633 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11634 int shiftBits = (b2_val + d2) & 0x3F;
11635 // unsigned
11636 uint64_t r3_val = get_register(r3);
11637 uint64_t alu_out = 0;
11638 alu_out = r3_val >> shiftBits;
11639 set_register(r1, alu_out);
11640 return length;
11641}
Ben Murdochc5610432016-08-08 18:44:38 +010011642
Ben Murdoch61f157c2016-09-16 13:49:30 +010011643EVALUATE(SLLG) {
11644 DCHECK_OPCODE(SLLG);
11645 // For SLLG/SRLG, the 64-bit third operand is shifted the number
11646 // of bits specified by the second-operand address, and the result is
11647 // placed at the first-operand location. Except for when the R1 and R3
11648 // fields designate the same register, the third operand remains
11649 // unchanged in general register R3.
11650 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
11651 // only takes rightmost 6 bits
11652 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11653 int shiftBits = (b2_val + d2) & 0x3F;
11654 // unsigned
11655 uint64_t r3_val = get_register(r3);
11656 uint64_t alu_out = 0;
11657 alu_out = r3_val << shiftBits;
11658 set_register(r1, alu_out);
11659 return length;
11660}
Ben Murdochc5610432016-08-08 18:44:38 +010011661
Ben Murdoch61f157c2016-09-16 13:49:30 +010011662EVALUATE(CSY) {
11663 UNIMPLEMENTED();
11664 USE(instr);
11665 return 0;
11666}
Ben Murdochc5610432016-08-08 18:44:38 +010011667
Ben Murdoch61f157c2016-09-16 13:49:30 +010011668EVALUATE(RLLG) {
11669 DCHECK_OPCODE(RLLG);
11670 // For SLLG/SRLG, the 64-bit third operand is shifted the number
11671 // of bits specified by the second-operand address, and the result is
11672 // placed at the first-operand location. Except for when the R1 and R3
11673 // fields designate the same register, the third operand remains
11674 // unchanged in general register R3.
11675 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
11676 // only takes rightmost 6 bits
11677 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11678 int shiftBits = (b2_val + d2) & 0x3F;
11679 // unsigned
11680 uint64_t r3_val = get_register(r3);
11681 uint64_t alu_out = 0;
11682 uint64_t rotateBits = r3_val >> (64 - shiftBits);
11683 alu_out = (r3_val << shiftBits) | (rotateBits);
11684 set_register(r1, alu_out);
11685 return length;
11686}
Ben Murdochc5610432016-08-08 18:44:38 +010011687
Ben Murdoch61f157c2016-09-16 13:49:30 +010011688EVALUATE(STMG) {
11689 DCHECK_OPCODE(STMG);
11690 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
11691 int rb = b2;
11692 int offset = d2;
Ben Murdochc5610432016-08-08 18:44:38 +010011693
Ben Murdoch61f157c2016-09-16 13:49:30 +010011694 // Regs roll around if r3 is less than r1.
11695 // Artifically increase r3 by 16 so we can calculate
11696 // the number of regs stored properly.
11697 if (r3 < r1) r3 += 16;
Ben Murdochc5610432016-08-08 18:44:38 +010011698
Ben Murdoch61f157c2016-09-16 13:49:30 +010011699 int64_t rb_val = (rb == 0) ? 0 : get_register(rb);
Ben Murdochc5610432016-08-08 18:44:38 +010011700
Ben Murdoch61f157c2016-09-16 13:49:30 +010011701 // Store each register in ascending order.
11702 for (int i = 0; i <= r3 - r1; i++) {
11703 int64_t value = get_register((r1 + i) % 16);
11704 WriteDW(rb_val + offset + 8 * i, value);
11705 }
11706 return length;
11707}
Ben Murdochc5610432016-08-08 18:44:38 +010011708
Ben Murdoch61f157c2016-09-16 13:49:30 +010011709EVALUATE(STMH) {
11710 UNIMPLEMENTED();
11711 USE(instr);
11712 return 0;
11713}
Ben Murdochc5610432016-08-08 18:44:38 +010011714
Ben Murdoch61f157c2016-09-16 13:49:30 +010011715EVALUATE(STCMH) {
11716 UNIMPLEMENTED();
11717 USE(instr);
11718 return 0;
11719}
Ben Murdochc5610432016-08-08 18:44:38 +010011720
Ben Murdoch61f157c2016-09-16 13:49:30 +010011721EVALUATE(STCMY) {
11722 UNIMPLEMENTED();
11723 USE(instr);
11724 return 0;
11725}
Ben Murdochc5610432016-08-08 18:44:38 +010011726
Ben Murdoch61f157c2016-09-16 13:49:30 +010011727EVALUATE(CDSY) {
11728 UNIMPLEMENTED();
11729 USE(instr);
11730 return 0;
11731}
Ben Murdochc5610432016-08-08 18:44:38 +010011732
Ben Murdoch61f157c2016-09-16 13:49:30 +010011733EVALUATE(CDSG) {
11734 UNIMPLEMENTED();
11735 USE(instr);
11736 return 0;
11737}
Ben Murdochc5610432016-08-08 18:44:38 +010011738
Ben Murdoch61f157c2016-09-16 13:49:30 +010011739EVALUATE(BXHG) {
11740 UNIMPLEMENTED();
11741 USE(instr);
11742 return 0;
11743}
Ben Murdochc5610432016-08-08 18:44:38 +010011744
Ben Murdoch61f157c2016-09-16 13:49:30 +010011745EVALUATE(BXLEG) {
11746 UNIMPLEMENTED();
11747 USE(instr);
11748 return 0;
11749}
Ben Murdochc5610432016-08-08 18:44:38 +010011750
Ben Murdoch61f157c2016-09-16 13:49:30 +010011751EVALUATE(ECAG) {
11752 UNIMPLEMENTED();
11753 USE(instr);
11754 return 0;
11755}
Ben Murdochc5610432016-08-08 18:44:38 +010011756
Ben Murdoch61f157c2016-09-16 13:49:30 +010011757EVALUATE(TMY) {
11758 DCHECK_OPCODE(TMY);
11759 // Test Under Mask (Mem - Imm) (8)
11760 DECODE_SIY_INSTRUCTION(b1, d1, i2);
11761 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
11762 intptr_t d1_val = d1;
11763 intptr_t addr = b1_val + d1_val;
11764 uint8_t mem_val = ReadB(addr);
11765 uint8_t imm_val = i2;
11766 uint8_t selected_bits = mem_val & imm_val;
11767 // CC0: Selected bits are zero
11768 // CC1: Selected bits mixed zeros and ones
11769 // CC3: Selected bits all ones
11770 if (0 == selected_bits) {
11771 condition_reg_ = CC_EQ; // CC0
11772 } else if (selected_bits == imm_val) {
11773 condition_reg_ = 0x1; // CC3
11774 } else {
11775 condition_reg_ = 0x4; // CC1
11776 }
11777 return length;
11778}
Ben Murdochc5610432016-08-08 18:44:38 +010011779
Ben Murdoch61f157c2016-09-16 13:49:30 +010011780EVALUATE(MVIY) {
11781 UNIMPLEMENTED();
11782 USE(instr);
11783 return 0;
11784}
Ben Murdochc5610432016-08-08 18:44:38 +010011785
Ben Murdoch61f157c2016-09-16 13:49:30 +010011786EVALUATE(NIY) {
11787 UNIMPLEMENTED();
11788 USE(instr);
11789 return 0;
11790}
Ben Murdochc5610432016-08-08 18:44:38 +010011791
Ben Murdoch61f157c2016-09-16 13:49:30 +010011792EVALUATE(CLIY) {
11793 DCHECK_OPCODE(CLIY);
11794 DECODE_SIY_INSTRUCTION(b1, d1, i2);
11795 // Compare Immediate (Mem - Imm) (8)
11796 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
11797 intptr_t d1_val = d1;
11798 intptr_t addr = b1_val + d1_val;
11799 uint8_t mem_val = ReadB(addr);
11800 uint8_t imm_val = i2;
11801 SetS390ConditionCode<uint8_t>(mem_val, imm_val);
11802 return length;
11803}
Ben Murdochc5610432016-08-08 18:44:38 +010011804
Ben Murdoch61f157c2016-09-16 13:49:30 +010011805EVALUATE(OIY) {
11806 UNIMPLEMENTED();
11807 USE(instr);
11808 return 0;
11809}
Ben Murdochc5610432016-08-08 18:44:38 +010011810
Ben Murdoch61f157c2016-09-16 13:49:30 +010011811EVALUATE(XIY) {
11812 UNIMPLEMENTED();
11813 USE(instr);
11814 return 0;
11815}
Ben Murdochc5610432016-08-08 18:44:38 +010011816
Ben Murdoch61f157c2016-09-16 13:49:30 +010011817EVALUATE(ASI) {
11818 DCHECK_OPCODE(ASI);
11819 // TODO(bcleung): Change all fooInstr->I2Value() to template functions.
11820 // The below static cast to 8 bit and then to 32 bit is necessary
11821 // because siyInstr->I2Value() returns a uint8_t, which a direct
11822 // cast to int32_t could incorrectly interpret.
11823 DECODE_SIY_INSTRUCTION(b1, d1, i2_unsigned);
11824 int8_t i2_8bit = static_cast<int8_t>(i2_unsigned);
11825 int32_t i2 = static_cast<int32_t>(i2_8bit);
11826 intptr_t b1_val = (b1 == 0) ? 0 : get_register(b1);
Ben Murdochc5610432016-08-08 18:44:38 +010011827
Ben Murdoch61f157c2016-09-16 13:49:30 +010011828 int d1_val = d1;
11829 intptr_t addr = b1_val + d1_val;
Ben Murdochc5610432016-08-08 18:44:38 +010011830
Ben Murdoch61f157c2016-09-16 13:49:30 +010011831 int32_t mem_val = ReadW(addr, instr);
11832 bool isOF = CheckOverflowForIntAdd(mem_val, i2, int32_t);
11833 int32_t alu_out = mem_val + i2;
11834 SetS390ConditionCode<int32_t>(alu_out, 0);
11835 SetS390OverflowCode(isOF);
11836 WriteW(addr, alu_out, instr);
11837 return length;
11838}
Ben Murdochc5610432016-08-08 18:44:38 +010011839
Ben Murdoch61f157c2016-09-16 13:49:30 +010011840EVALUATE(ALSI) {
11841 UNIMPLEMENTED();
11842 USE(instr);
11843 return 0;
11844}
Ben Murdochc5610432016-08-08 18:44:38 +010011845
Ben Murdoch61f157c2016-09-16 13:49:30 +010011846EVALUATE(AGSI) {
11847 DCHECK_OPCODE(AGSI);
11848 // TODO(bcleung): Change all fooInstr->I2Value() to template functions.
11849 // The below static cast to 8 bit and then to 32 bit is necessary
11850 // because siyInstr->I2Value() returns a uint8_t, which a direct
11851 // cast to int32_t could incorrectly interpret.
11852 DECODE_SIY_INSTRUCTION(b1, d1, i2_unsigned);
11853 int8_t i2_8bit = static_cast<int8_t>(i2_unsigned);
11854 int64_t i2 = static_cast<int64_t>(i2_8bit);
11855 intptr_t b1_val = (b1 == 0) ? 0 : get_register(b1);
Ben Murdochc5610432016-08-08 18:44:38 +010011856
Ben Murdoch61f157c2016-09-16 13:49:30 +010011857 int d1_val = d1;
11858 intptr_t addr = b1_val + d1_val;
Ben Murdochc5610432016-08-08 18:44:38 +010011859
Ben Murdoch61f157c2016-09-16 13:49:30 +010011860 int64_t mem_val = ReadDW(addr);
11861 int isOF = CheckOverflowForIntAdd(mem_val, i2, int64_t);
11862 int64_t alu_out = mem_val + i2;
11863 SetS390ConditionCode<uint64_t>(alu_out, 0);
11864 SetS390OverflowCode(isOF);
11865 WriteDW(addr, alu_out);
11866 return length;
11867}
Ben Murdochc5610432016-08-08 18:44:38 +010011868
Ben Murdoch61f157c2016-09-16 13:49:30 +010011869EVALUATE(ALGSI) {
11870 UNIMPLEMENTED();
11871 USE(instr);
11872 return 0;
11873}
Ben Murdochc5610432016-08-08 18:44:38 +010011874
Ben Murdoch61f157c2016-09-16 13:49:30 +010011875EVALUATE(ICMH) {
11876 UNIMPLEMENTED();
11877 USE(instr);
11878 return 0;
11879}
Ben Murdochc5610432016-08-08 18:44:38 +010011880
Ben Murdoch61f157c2016-09-16 13:49:30 +010011881EVALUATE(ICMY) {
11882 UNIMPLEMENTED();
11883 USE(instr);
11884 return 0;
11885}
Ben Murdochc5610432016-08-08 18:44:38 +010011886
Ben Murdoch61f157c2016-09-16 13:49:30 +010011887EVALUATE(MVCLU) {
11888 UNIMPLEMENTED();
11889 USE(instr);
11890 return 0;
11891}
Ben Murdochc5610432016-08-08 18:44:38 +010011892
Ben Murdoch61f157c2016-09-16 13:49:30 +010011893EVALUATE(CLCLU) {
11894 UNIMPLEMENTED();
11895 USE(instr);
11896 return 0;
11897}
Ben Murdochc5610432016-08-08 18:44:38 +010011898
Ben Murdoch61f157c2016-09-16 13:49:30 +010011899EVALUATE(STMY) {
11900 DCHECK_OPCODE(STMY);
11901 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
11902 // Load/Store Multiple (32)
11903 int offset = d2;
Ben Murdochc5610432016-08-08 18:44:38 +010011904
Ben Murdoch61f157c2016-09-16 13:49:30 +010011905 // Regs roll around if r3 is less than r1.
11906 // Artifically increase r3 by 16 so we can calculate
11907 // the number of regs stored properly.
11908 if (r3 < r1) r3 += 16;
Ben Murdochc5610432016-08-08 18:44:38 +010011909
Ben Murdoch61f157c2016-09-16 13:49:30 +010011910 int32_t b2_val = (b2 == 0) ? 0 : get_low_register<int32_t>(b2);
Ben Murdochc5610432016-08-08 18:44:38 +010011911
Ben Murdoch61f157c2016-09-16 13:49:30 +010011912 // Store each register in ascending order.
11913 for (int i = 0; i <= r3 - r1; i++) {
11914 int32_t value = get_low_register<int32_t>((r1 + i) % 16);
11915 WriteW(b2_val + offset + 4 * i, value, instr);
11916 }
11917 return length;
11918}
Ben Murdochc5610432016-08-08 18:44:38 +010011919
Ben Murdoch61f157c2016-09-16 13:49:30 +010011920EVALUATE(LMH) {
11921 UNIMPLEMENTED();
11922 USE(instr);
11923 return 0;
11924}
Ben Murdochc5610432016-08-08 18:44:38 +010011925
Ben Murdoch61f157c2016-09-16 13:49:30 +010011926EVALUATE(LMY) {
11927 DCHECK_OPCODE(LMY);
11928 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
11929 // Load/Store Multiple (32)
11930 int offset = d2;
Ben Murdochc5610432016-08-08 18:44:38 +010011931
Ben Murdoch61f157c2016-09-16 13:49:30 +010011932 // Regs roll around if r3 is less than r1.
11933 // Artifically increase r3 by 16 so we can calculate
11934 // the number of regs stored properly.
11935 if (r3 < r1) r3 += 16;
Ben Murdochc5610432016-08-08 18:44:38 +010011936
Ben Murdoch61f157c2016-09-16 13:49:30 +010011937 int32_t b2_val = (b2 == 0) ? 0 : get_low_register<int32_t>(b2);
Ben Murdochc5610432016-08-08 18:44:38 +010011938
Ben Murdoch61f157c2016-09-16 13:49:30 +010011939 // Store each register in ascending order.
11940 for (int i = 0; i <= r3 - r1; i++) {
11941 int32_t value = ReadW(b2_val + offset + 4 * i, instr);
11942 set_low_register((r1 + i) % 16, value);
11943 }
11944 return length;
11945}
Ben Murdochc5610432016-08-08 18:44:38 +010011946
Ben Murdoch61f157c2016-09-16 13:49:30 +010011947EVALUATE(TP) {
11948 UNIMPLEMENTED();
11949 USE(instr);
11950 return 0;
11951}
Ben Murdochc5610432016-08-08 18:44:38 +010011952
Ben Murdoch61f157c2016-09-16 13:49:30 +010011953EVALUATE(SRAK) {
11954 DCHECK_OPCODE(SRAK);
11955 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
11956 // 32-bit non-clobbering shift-left/right arithmetic
11957 // only takes rightmost 6 bits
11958 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11959 int shiftBits = (b2_val + d2) & 0x3F;
11960 int32_t r3_val = get_low_register<int32_t>(r3);
11961 int32_t alu_out = 0;
11962 bool isOF = false;
11963 alu_out = r3_val >> shiftBits;
11964 set_low_register(r1, alu_out);
11965 SetS390ConditionCode<int32_t>(alu_out, 0);
11966 SetS390OverflowCode(isOF);
11967 return length;
11968}
Ben Murdochc5610432016-08-08 18:44:38 +010011969
Ben Murdoch61f157c2016-09-16 13:49:30 +010011970EVALUATE(SLAK) {
11971 DCHECK_OPCODE(SLAK);
11972 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
11973 // 32-bit non-clobbering shift-left/right arithmetic
11974 // only takes rightmost 6 bits
11975 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11976 int shiftBits = (b2_val + d2) & 0x3F;
11977 int32_t r3_val = get_low_register<int32_t>(r3);
11978 int32_t alu_out = 0;
11979 bool isOF = false;
11980 isOF = CheckOverflowForShiftLeft(r3_val, shiftBits);
11981 alu_out = r3_val << shiftBits;
11982 set_low_register(r1, alu_out);
11983 SetS390ConditionCode<int32_t>(alu_out, 0);
11984 SetS390OverflowCode(isOF);
11985 return length;
11986}
Ben Murdochc5610432016-08-08 18:44:38 +010011987
Ben Murdoch61f157c2016-09-16 13:49:30 +010011988EVALUATE(SRLK) {
11989 DCHECK_OPCODE(SRLK);
11990 // For SLLK/SRLL, the 32-bit third operand is shifted the number
11991 // of bits specified by the second-operand address, and the result is
11992 // placed at the first-operand location. Except for when the R1 and R3
11993 // fields designate the same register, the third operand remains
11994 // unchanged in general register R3.
11995 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
11996 // only takes rightmost 6 bits
11997 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
11998 int shiftBits = (b2_val + d2) & 0x3F;
11999 // unsigned
12000 uint32_t r3_val = get_low_register<uint32_t>(r3);
12001 uint32_t alu_out = 0;
12002 alu_out = r3_val >> shiftBits;
12003 set_low_register(r1, alu_out);
12004 return length;
12005}
Ben Murdochc5610432016-08-08 18:44:38 +010012006
Ben Murdoch61f157c2016-09-16 13:49:30 +010012007EVALUATE(SLLK) {
12008 DCHECK_OPCODE(SLLK);
12009 // For SLLK/SRLL, the 32-bit third operand is shifted the number
12010 // of bits specified by the second-operand address, and the result is
12011 // placed at the first-operand location. Except for when the R1 and R3
12012 // fields designate the same register, the third operand remains
12013 // unchanged in general register R3.
12014 DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
12015 // only takes rightmost 6 bits
12016 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
12017 int shiftBits = (b2_val + d2) & 0x3F;
12018 // unsigned
12019 uint32_t r3_val = get_low_register<uint32_t>(r3);
12020 uint32_t alu_out = 0;
12021 alu_out = r3_val << shiftBits;
12022 set_low_register(r1, alu_out);
12023 return length;
12024}
Ben Murdochc5610432016-08-08 18:44:38 +010012025
Ben Murdoch61f157c2016-09-16 13:49:30 +010012026EVALUATE(LOCG) {
12027 UNIMPLEMENTED();
12028 USE(instr);
12029 return 0;
12030}
Ben Murdochc5610432016-08-08 18:44:38 +010012031
Ben Murdoch61f157c2016-09-16 13:49:30 +010012032EVALUATE(STOCG) {
12033 UNIMPLEMENTED();
12034 USE(instr);
12035 return 0;
12036}
Ben Murdochc5610432016-08-08 18:44:38 +010012037
Ben Murdoch61f157c2016-09-16 13:49:30 +010012038EVALUATE(LANG) {
12039 UNIMPLEMENTED();
12040 USE(instr);
12041 return 0;
12042}
Ben Murdochc5610432016-08-08 18:44:38 +010012043
Ben Murdoch61f157c2016-09-16 13:49:30 +010012044EVALUATE(LAOG) {
12045 UNIMPLEMENTED();
12046 USE(instr);
12047 return 0;
12048}
Ben Murdochc5610432016-08-08 18:44:38 +010012049
Ben Murdoch61f157c2016-09-16 13:49:30 +010012050EVALUATE(LAXG) {
12051 UNIMPLEMENTED();
12052 USE(instr);
12053 return 0;
12054}
Ben Murdochc5610432016-08-08 18:44:38 +010012055
Ben Murdoch61f157c2016-09-16 13:49:30 +010012056EVALUATE(LAAG) {
12057 UNIMPLEMENTED();
12058 USE(instr);
12059 return 0;
12060}
Ben Murdochc5610432016-08-08 18:44:38 +010012061
Ben Murdoch61f157c2016-09-16 13:49:30 +010012062EVALUATE(LAALG) {
12063 UNIMPLEMENTED();
12064 USE(instr);
12065 return 0;
12066}
Ben Murdochc5610432016-08-08 18:44:38 +010012067
Ben Murdoch61f157c2016-09-16 13:49:30 +010012068EVALUATE(LOC) {
12069 UNIMPLEMENTED();
12070 USE(instr);
12071 return 0;
12072}
Ben Murdochc5610432016-08-08 18:44:38 +010012073
Ben Murdoch61f157c2016-09-16 13:49:30 +010012074EVALUATE(STOC) {
12075 UNIMPLEMENTED();
12076 USE(instr);
12077 return 0;
12078}
Ben Murdochc5610432016-08-08 18:44:38 +010012079
Ben Murdoch61f157c2016-09-16 13:49:30 +010012080EVALUATE(LAN) {
12081 UNIMPLEMENTED();
12082 USE(instr);
12083 return 0;
12084}
Ben Murdochc5610432016-08-08 18:44:38 +010012085
Ben Murdoch61f157c2016-09-16 13:49:30 +010012086EVALUATE(LAO) {
12087 UNIMPLEMENTED();
12088 USE(instr);
12089 return 0;
12090}
Ben Murdochc5610432016-08-08 18:44:38 +010012091
Ben Murdoch61f157c2016-09-16 13:49:30 +010012092EVALUATE(LAX) {
12093 UNIMPLEMENTED();
12094 USE(instr);
12095 return 0;
12096}
Ben Murdochc5610432016-08-08 18:44:38 +010012097
Ben Murdoch61f157c2016-09-16 13:49:30 +010012098EVALUATE(LAA) {
12099 UNIMPLEMENTED();
12100 USE(instr);
12101 return 0;
12102}
Ben Murdochc5610432016-08-08 18:44:38 +010012103
Ben Murdoch61f157c2016-09-16 13:49:30 +010012104EVALUATE(LAAL) {
12105 UNIMPLEMENTED();
12106 USE(instr);
12107 return 0;
12108}
Ben Murdochc5610432016-08-08 18:44:38 +010012109
Ben Murdoch61f157c2016-09-16 13:49:30 +010012110EVALUATE(BRXHG) {
12111 UNIMPLEMENTED();
12112 USE(instr);
12113 return 0;
12114}
Ben Murdochc5610432016-08-08 18:44:38 +010012115
Ben Murdoch61f157c2016-09-16 13:49:30 +010012116EVALUATE(BRXLG) {
12117 UNIMPLEMENTED();
12118 USE(instr);
12119 return 0;
12120}
Ben Murdochc5610432016-08-08 18:44:38 +010012121
Ben Murdoch61f157c2016-09-16 13:49:30 +010012122EVALUATE(RISBLG) {
12123 UNIMPLEMENTED();
12124 USE(instr);
12125 return 0;
12126}
Ben Murdochc5610432016-08-08 18:44:38 +010012127
Ben Murdoch61f157c2016-09-16 13:49:30 +010012128EVALUATE(RNSBG) {
12129 UNIMPLEMENTED();
12130 USE(instr);
12131 return 0;
12132}
Ben Murdochc5610432016-08-08 18:44:38 +010012133
Ben Murdoch61f157c2016-09-16 13:49:30 +010012134EVALUATE(ROSBG) {
12135 UNIMPLEMENTED();
12136 USE(instr);
12137 return 0;
12138}
Ben Murdochc5610432016-08-08 18:44:38 +010012139
Ben Murdoch61f157c2016-09-16 13:49:30 +010012140EVALUATE(RXSBG) {
12141 UNIMPLEMENTED();
12142 USE(instr);
12143 return 0;
12144}
Ben Murdochc5610432016-08-08 18:44:38 +010012145
Ben Murdoch61f157c2016-09-16 13:49:30 +010012146EVALUATE(RISBGN) {
12147 UNIMPLEMENTED();
12148 USE(instr);
12149 return 0;
12150}
Ben Murdochc5610432016-08-08 18:44:38 +010012151
Ben Murdoch61f157c2016-09-16 13:49:30 +010012152EVALUATE(RISBHG) {
12153 UNIMPLEMENTED();
12154 USE(instr);
12155 return 0;
12156}
Ben Murdochc5610432016-08-08 18:44:38 +010012157
Ben Murdoch61f157c2016-09-16 13:49:30 +010012158EVALUATE(CGRJ) {
12159 UNIMPLEMENTED();
12160 USE(instr);
12161 return 0;
12162}
Ben Murdochc5610432016-08-08 18:44:38 +010012163
Ben Murdoch61f157c2016-09-16 13:49:30 +010012164EVALUATE(CGIT) {
12165 UNIMPLEMENTED();
12166 USE(instr);
12167 return 0;
12168}
Ben Murdochc5610432016-08-08 18:44:38 +010012169
Ben Murdoch61f157c2016-09-16 13:49:30 +010012170EVALUATE(CIT) {
12171 UNIMPLEMENTED();
12172 USE(instr);
12173 return 0;
12174}
Ben Murdochc5610432016-08-08 18:44:38 +010012175
Ben Murdoch61f157c2016-09-16 13:49:30 +010012176EVALUATE(CLFIT) {
12177 UNIMPLEMENTED();
12178 USE(instr);
12179 return 0;
12180}
Ben Murdochc5610432016-08-08 18:44:38 +010012181
Ben Murdoch61f157c2016-09-16 13:49:30 +010012182EVALUATE(CGIJ) {
12183 UNIMPLEMENTED();
12184 USE(instr);
12185 return 0;
12186}
Ben Murdochc5610432016-08-08 18:44:38 +010012187
Ben Murdoch61f157c2016-09-16 13:49:30 +010012188EVALUATE(CIJ) {
12189 UNIMPLEMENTED();
12190 USE(instr);
12191 return 0;
12192}
Ben Murdochc5610432016-08-08 18:44:38 +010012193
Ben Murdoch61f157c2016-09-16 13:49:30 +010012194EVALUATE(ALHSIK) {
12195 UNIMPLEMENTED();
12196 USE(instr);
12197 return 0;
12198}
Ben Murdochc5610432016-08-08 18:44:38 +010012199
Ben Murdoch61f157c2016-09-16 13:49:30 +010012200EVALUATE(ALGHSIK) {
12201 UNIMPLEMENTED();
12202 USE(instr);
12203 return 0;
12204}
Ben Murdochc5610432016-08-08 18:44:38 +010012205
Ben Murdoch61f157c2016-09-16 13:49:30 +010012206EVALUATE(CGRB) {
12207 UNIMPLEMENTED();
12208 USE(instr);
12209 return 0;
12210}
Ben Murdochc5610432016-08-08 18:44:38 +010012211
Ben Murdoch61f157c2016-09-16 13:49:30 +010012212EVALUATE(CGIB) {
12213 UNIMPLEMENTED();
12214 USE(instr);
12215 return 0;
12216}
Ben Murdochc5610432016-08-08 18:44:38 +010012217
Ben Murdoch61f157c2016-09-16 13:49:30 +010012218EVALUATE(CIB) {
12219 UNIMPLEMENTED();
12220 USE(instr);
12221 return 0;
12222}
Ben Murdochc5610432016-08-08 18:44:38 +010012223
Ben Murdoch61f157c2016-09-16 13:49:30 +010012224EVALUATE(LDEB) {
12225 DCHECK_OPCODE(LDEB);
12226 // Load Float
12227 DECODE_RXE_INSTRUCTION(r1, b2, x2, d2);
12228 int rb = b2;
12229 int rx = x2;
12230 int offset = d2;
12231 int64_t rb_val = (rb == 0) ? 0 : get_register(rb);
12232 int64_t rx_val = (rx == 0) ? 0 : get_register(rx);
12233 double ret =
12234 static_cast<double>(*reinterpret_cast<float*>(rx_val + rb_val + offset));
12235 set_d_register_from_double(r1, ret);
12236 return length;
12237}
Ben Murdochc5610432016-08-08 18:44:38 +010012238
Ben Murdoch61f157c2016-09-16 13:49:30 +010012239EVALUATE(LXDB) {
12240 UNIMPLEMENTED();
12241 USE(instr);
12242 return 0;
12243}
Ben Murdochc5610432016-08-08 18:44:38 +010012244
Ben Murdoch61f157c2016-09-16 13:49:30 +010012245EVALUATE(LXEB) {
12246 UNIMPLEMENTED();
12247 USE(instr);
12248 return 0;
12249}
Ben Murdochc5610432016-08-08 18:44:38 +010012250
Ben Murdoch61f157c2016-09-16 13:49:30 +010012251EVALUATE(MXDB) {
12252 UNIMPLEMENTED();
12253 USE(instr);
12254 return 0;
12255}
Ben Murdochc5610432016-08-08 18:44:38 +010012256
Ben Murdoch61f157c2016-09-16 13:49:30 +010012257EVALUATE(KEB) {
12258 UNIMPLEMENTED();
12259 USE(instr);
12260 return 0;
12261}
Ben Murdochc5610432016-08-08 18:44:38 +010012262
Ben Murdoch61f157c2016-09-16 13:49:30 +010012263EVALUATE(CEB) {
12264 UNIMPLEMENTED();
12265 USE(instr);
12266 return 0;
12267}
Ben Murdochc5610432016-08-08 18:44:38 +010012268
Ben Murdoch61f157c2016-09-16 13:49:30 +010012269EVALUATE(AEB) {
12270 UNIMPLEMENTED();
12271 USE(instr);
12272 return 0;
12273}
Ben Murdochc5610432016-08-08 18:44:38 +010012274
Ben Murdoch61f157c2016-09-16 13:49:30 +010012275EVALUATE(SEB) {
12276 UNIMPLEMENTED();
12277 USE(instr);
12278 return 0;
12279}
Ben Murdochc5610432016-08-08 18:44:38 +010012280
Ben Murdoch61f157c2016-09-16 13:49:30 +010012281EVALUATE(MDEB) {
12282 UNIMPLEMENTED();
12283 USE(instr);
12284 return 0;
12285}
Ben Murdochc5610432016-08-08 18:44:38 +010012286
Ben Murdoch61f157c2016-09-16 13:49:30 +010012287EVALUATE(DEB) {
12288 UNIMPLEMENTED();
12289 USE(instr);
12290 return 0;
12291}
Ben Murdochc5610432016-08-08 18:44:38 +010012292
Ben Murdoch61f157c2016-09-16 13:49:30 +010012293EVALUATE(MAEB) {
12294 UNIMPLEMENTED();
12295 USE(instr);
12296 return 0;
12297}
Ben Murdochc5610432016-08-08 18:44:38 +010012298
Ben Murdoch61f157c2016-09-16 13:49:30 +010012299EVALUATE(MSEB) {
12300 UNIMPLEMENTED();
12301 USE(instr);
12302 return 0;
12303}
Ben Murdochc5610432016-08-08 18:44:38 +010012304
Ben Murdoch61f157c2016-09-16 13:49:30 +010012305EVALUATE(TCEB) {
12306 UNIMPLEMENTED();
12307 USE(instr);
12308 return 0;
12309}
Ben Murdochc5610432016-08-08 18:44:38 +010012310
Ben Murdoch61f157c2016-09-16 13:49:30 +010012311EVALUATE(TCDB) {
12312 UNIMPLEMENTED();
12313 USE(instr);
12314 return 0;
12315}
Ben Murdochc5610432016-08-08 18:44:38 +010012316
Ben Murdoch61f157c2016-09-16 13:49:30 +010012317EVALUATE(TCXB) {
12318 UNIMPLEMENTED();
12319 USE(instr);
12320 return 0;
12321}
Ben Murdochc5610432016-08-08 18:44:38 +010012322
Ben Murdoch61f157c2016-09-16 13:49:30 +010012323EVALUATE(SQEB) {
12324 UNIMPLEMENTED();
12325 USE(instr);
12326 return 0;
12327}
Ben Murdochc5610432016-08-08 18:44:38 +010012328
Ben Murdoch61f157c2016-09-16 13:49:30 +010012329EVALUATE(SQDB) {
12330 DCHECK_OPCODE(SQDB);
12331 DECODE_RXE_INSTRUCTION(r1, b2, x2, d2);
12332 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
12333 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
12334 intptr_t d2_val = d2;
12335 double r1_val = get_double_from_d_register(r1);
12336 double dbl_val = ReadDouble(b2_val + x2_val + d2_val);
12337 r1_val = std::sqrt(dbl_val);
12338 set_d_register_from_double(r1, r1_val);
12339 return length;
12340}
Ben Murdochc5610432016-08-08 18:44:38 +010012341
Ben Murdoch61f157c2016-09-16 13:49:30 +010012342EVALUATE(MEEB) {
12343 UNIMPLEMENTED();
12344 USE(instr);
12345 return 0;
12346}
Ben Murdochc5610432016-08-08 18:44:38 +010012347
Ben Murdoch61f157c2016-09-16 13:49:30 +010012348EVALUATE(KDB) {
12349 UNIMPLEMENTED();
12350 USE(instr);
12351 return 0;
12352}
Ben Murdochc5610432016-08-08 18:44:38 +010012353
Ben Murdoch61f157c2016-09-16 13:49:30 +010012354EVALUATE(CDB) {
12355 DCHECK_OPCODE(CDB);
Ben Murdochc5610432016-08-08 18:44:38 +010012356
Ben Murdoch61f157c2016-09-16 13:49:30 +010012357 DECODE_RXE_INSTRUCTION(r1, b2, x2, d2);
12358 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
12359 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
12360 intptr_t d2_val = d2;
12361 double r1_val = get_double_from_d_register(r1);
12362 double dbl_val = ReadDouble(b2_val + x2_val + d2_val);
12363 SetS390ConditionCode<double>(r1_val, dbl_val);
12364 return length;
12365}
Ben Murdochc5610432016-08-08 18:44:38 +010012366
Ben Murdoch61f157c2016-09-16 13:49:30 +010012367EVALUATE(ADB) {
12368 DCHECK_OPCODE(ADB);
Ben Murdochc5610432016-08-08 18:44:38 +010012369
Ben Murdoch61f157c2016-09-16 13:49:30 +010012370 DECODE_RXE_INSTRUCTION(r1, b2, x2, d2);
12371 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
12372 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
12373 intptr_t d2_val = d2;
12374 double r1_val = get_double_from_d_register(r1);
12375 double dbl_val = ReadDouble(b2_val + x2_val + d2_val);
12376 r1_val += dbl_val;
12377 set_d_register_from_double(r1, r1_val);
12378 SetS390ConditionCode<double>(r1_val, 0);
12379 return length;
12380}
Ben Murdochc5610432016-08-08 18:44:38 +010012381
Ben Murdoch61f157c2016-09-16 13:49:30 +010012382EVALUATE(SDB) {
12383 DCHECK_OPCODE(SDB);
12384 DECODE_RXE_INSTRUCTION(r1, b2, x2, d2);
12385 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
12386 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
12387 intptr_t d2_val = d2;
12388 double r1_val = get_double_from_d_register(r1);
12389 double dbl_val = ReadDouble(b2_val + x2_val + d2_val);
12390 r1_val -= dbl_val;
12391 set_d_register_from_double(r1, r1_val);
12392 SetS390ConditionCode<double>(r1_val, 0);
12393 return length;
12394}
Ben Murdochc5610432016-08-08 18:44:38 +010012395
Ben Murdoch61f157c2016-09-16 13:49:30 +010012396EVALUATE(MDB) {
12397 DCHECK_OPCODE(MDB);
12398 DECODE_RXE_INSTRUCTION(r1, b2, x2, d2);
12399 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
12400 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
12401 intptr_t d2_val = d2;
12402 double r1_val = get_double_from_d_register(r1);
12403 double dbl_val = ReadDouble(b2_val + x2_val + d2_val);
12404 r1_val *= dbl_val;
12405 set_d_register_from_double(r1, r1_val);
12406 SetS390ConditionCode<double>(r1_val, 0);
12407 return length;
12408}
Ben Murdochc5610432016-08-08 18:44:38 +010012409
Ben Murdoch61f157c2016-09-16 13:49:30 +010012410EVALUATE(DDB) {
12411 DCHECK_OPCODE(DDB);
12412 DECODE_RXE_INSTRUCTION(r1, b2, x2, d2);
12413 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
12414 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
12415 intptr_t d2_val = d2;
12416 double r1_val = get_double_from_d_register(r1);
12417 double dbl_val = ReadDouble(b2_val + x2_val + d2_val);
12418 r1_val /= dbl_val;
12419 set_d_register_from_double(r1, r1_val);
12420 SetS390ConditionCode<double>(r1_val, 0);
12421 return length;
12422}
Ben Murdochc5610432016-08-08 18:44:38 +010012423
Ben Murdoch61f157c2016-09-16 13:49:30 +010012424EVALUATE(MADB) {
12425 UNIMPLEMENTED();
12426 USE(instr);
12427 return 0;
12428}
Ben Murdochc5610432016-08-08 18:44:38 +010012429
Ben Murdoch61f157c2016-09-16 13:49:30 +010012430EVALUATE(MSDB) {
12431 UNIMPLEMENTED();
12432 USE(instr);
12433 return 0;
12434}
Ben Murdochc5610432016-08-08 18:44:38 +010012435
Ben Murdoch61f157c2016-09-16 13:49:30 +010012436EVALUATE(SLDT) {
12437 UNIMPLEMENTED();
12438 USE(instr);
12439 return 0;
12440}
Ben Murdochc5610432016-08-08 18:44:38 +010012441
Ben Murdoch61f157c2016-09-16 13:49:30 +010012442EVALUATE(SRDT) {
12443 UNIMPLEMENTED();
12444 USE(instr);
12445 return 0;
12446}
Ben Murdochc5610432016-08-08 18:44:38 +010012447
Ben Murdoch61f157c2016-09-16 13:49:30 +010012448EVALUATE(SLXT) {
12449 UNIMPLEMENTED();
12450 USE(instr);
12451 return 0;
12452}
Ben Murdochc5610432016-08-08 18:44:38 +010012453
Ben Murdoch61f157c2016-09-16 13:49:30 +010012454EVALUATE(SRXT) {
12455 UNIMPLEMENTED();
12456 USE(instr);
12457 return 0;
12458}
Ben Murdochc5610432016-08-08 18:44:38 +010012459
Ben Murdoch61f157c2016-09-16 13:49:30 +010012460EVALUATE(TDCET) {
12461 UNIMPLEMENTED();
12462 USE(instr);
12463 return 0;
12464}
Ben Murdochc5610432016-08-08 18:44:38 +010012465
Ben Murdoch61f157c2016-09-16 13:49:30 +010012466EVALUATE(TDGET) {
12467 UNIMPLEMENTED();
12468 USE(instr);
12469 return 0;
12470}
Ben Murdochc5610432016-08-08 18:44:38 +010012471
Ben Murdoch61f157c2016-09-16 13:49:30 +010012472EVALUATE(TDCDT) {
12473 UNIMPLEMENTED();
12474 USE(instr);
12475 return 0;
12476}
Ben Murdochc5610432016-08-08 18:44:38 +010012477
Ben Murdoch61f157c2016-09-16 13:49:30 +010012478EVALUATE(TDGDT) {
12479 UNIMPLEMENTED();
12480 USE(instr);
12481 return 0;
12482}
Ben Murdochc5610432016-08-08 18:44:38 +010012483
Ben Murdoch61f157c2016-09-16 13:49:30 +010012484EVALUATE(TDCXT) {
12485 UNIMPLEMENTED();
12486 USE(instr);
12487 return 0;
12488}
Ben Murdochc5610432016-08-08 18:44:38 +010012489
Ben Murdoch61f157c2016-09-16 13:49:30 +010012490EVALUATE(TDGXT) {
12491 UNIMPLEMENTED();
12492 USE(instr);
12493 return 0;
12494}
Ben Murdochc5610432016-08-08 18:44:38 +010012495
Ben Murdoch61f157c2016-09-16 13:49:30 +010012496EVALUATE(LEY) {
12497 DCHECK_OPCODE(LEY);
12498 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
12499 // Miscellaneous Loads and Stores
12500 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
12501 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
12502 intptr_t addr = x2_val + b2_val + d2;
12503 float float_val = *reinterpret_cast<float*>(addr);
12504 set_d_register_from_float32(r1, float_val);
12505 return length;
12506}
Ben Murdochc5610432016-08-08 18:44:38 +010012507
Ben Murdoch61f157c2016-09-16 13:49:30 +010012508EVALUATE(LDY) {
12509 DCHECK_OPCODE(LDY);
12510 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
12511 // Miscellaneous Loads and Stores
12512 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
12513 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
12514 intptr_t addr = x2_val + b2_val + d2;
12515 uint64_t dbl_val = *reinterpret_cast<uint64_t*>(addr);
12516 set_d_register(r1, dbl_val);
12517 return length;
12518}
Ben Murdochc5610432016-08-08 18:44:38 +010012519
Ben Murdoch61f157c2016-09-16 13:49:30 +010012520EVALUATE(STEY) {
12521 DCHECK_OPCODE(STEY);
12522 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
12523 // Miscellaneous Loads and Stores
12524 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
12525 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
12526 intptr_t addr = x2_val + b2_val + d2;
12527 int64_t frs_val = get_d_register(r1) >> 32;
12528 WriteW(addr, static_cast<int32_t>(frs_val), instr);
12529 return length;
12530}
Ben Murdochc5610432016-08-08 18:44:38 +010012531
Ben Murdoch61f157c2016-09-16 13:49:30 +010012532EVALUATE(STDY) {
12533 DCHECK_OPCODE(STDY);
12534 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
12535 // Miscellaneous Loads and Stores
12536 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
12537 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
12538 intptr_t addr = x2_val + b2_val + d2;
12539 int64_t frs_val = get_d_register(r1);
12540 WriteDW(addr, frs_val);
12541 return length;
12542}
Ben Murdochc5610432016-08-08 18:44:38 +010012543
Ben Murdoch61f157c2016-09-16 13:49:30 +010012544EVALUATE(CZDT) {
12545 UNIMPLEMENTED();
12546 USE(instr);
12547 return 0;
12548}
Ben Murdochc5610432016-08-08 18:44:38 +010012549
Ben Murdoch61f157c2016-09-16 13:49:30 +010012550EVALUATE(CZXT) {
12551 UNIMPLEMENTED();
12552 USE(instr);
12553 return 0;
12554}
Ben Murdochc5610432016-08-08 18:44:38 +010012555
Ben Murdoch61f157c2016-09-16 13:49:30 +010012556EVALUATE(CDZT) {
12557 UNIMPLEMENTED();
12558 USE(instr);
12559 return 0;
12560}
Ben Murdochc5610432016-08-08 18:44:38 +010012561
Ben Murdoch61f157c2016-09-16 13:49:30 +010012562EVALUATE(CXZT) {
12563 UNIMPLEMENTED();
12564 USE(instr);
12565 return 0;
12566}
Ben Murdochc5610432016-08-08 18:44:38 +010012567
12568#undef EVALUATE
12569
Ben Murdochda12d292016-06-02 14:46:10 +010012570} // namespace internal
12571} // namespace v8
12572
12573#endif // USE_SIMULATOR
12574#endif // V8_TARGET_ARCH_S390