OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stdarg.h> | 5 #include <stdarg.h> |
6 #include <stdlib.h> | 6 #include <stdlib.h> |
7 #include <cmath> | 7 #include <cmath> |
8 | 8 |
9 #if V8_TARGET_ARCH_S390 | 9 #if V8_TARGET_ARCH_S390 |
10 | 10 |
(...skipping 5882 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5893 return address; | 5893 return address; |
5894 } | 5894 } |
5895 | 5895 |
5896 #define EVALUATE(name) \ | 5896 #define EVALUATE(name) \ |
5897 int Simulator::Evaluate_##name(Instruction* instr) | 5897 int Simulator::Evaluate_##name(Instruction* instr) |
5898 | 5898 |
5899 #define DCHECK_OPCODE(op) DCHECK(instr->S390OpcodeValue() == op) | 5899 #define DCHECK_OPCODE(op) DCHECK(instr->S390OpcodeValue() == op) |
5900 | 5900 |
5901 #define AS(type) reinterpret_cast<type*>(instr) | 5901 #define AS(type) reinterpret_cast<type*>(instr) |
5902 | 5902 |
| 5903 #define DECODE_RIL_A_INSTRUCTION(r1, i2) \ |
| 5904 int r1 = AS(RILInstruction)->R1Value(); \ |
| 5905 uint32_t i2 = AS(RILInstruction)->I2UnsignedValue(); \ |
| 5906 int length = 6; |
| 5907 |
| 5908 #define DECODE_RIL_B_INSTRUCTION(r1, i2) \ |
| 5909 int r1 = AS(RILInstruction)->R1Value(); \ |
| 5910 int32_t i2 = AS(RILInstruction)->I2Value(); \ |
| 5911 int length = 6; |
| 5912 |
5903 #define DECODE_RIL_C_INSTRUCTION(m1, ri2) \ | 5913 #define DECODE_RIL_C_INSTRUCTION(m1, ri2) \ |
5904 Condition m1 = static_cast<Condition>(AS(RILInstruction)->R1Value()); \ | 5914 Condition m1 = static_cast<Condition>(AS(RILInstruction)->R1Value()); \ |
5905 uint64_t ri2 = AS(RILInstruction)->I2Value(); \ | 5915 uint64_t ri2 = AS(RILInstruction)->I2Value(); \ |
5906 int length = 6; | 5916 int length = 6; |
5907 | 5917 |
5908 #define DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2) \ | 5918 #define DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2) \ |
5909 int r1 = AS(RXYInstruction)->R1Value(); \ | 5919 int r1 = AS(RXYInstruction)->R1Value(); \ |
5910 int x2 = AS(RXYInstruction)->X2Value(); \ | 5920 int x2 = AS(RXYInstruction)->X2Value(); \ |
5911 int b2 = AS(RXYInstruction)->B2Value(); \ | 5921 int b2 = AS(RXYInstruction)->B2Value(); \ |
5912 int d2 = AS(RXYInstruction)->D2Value(); \ | 5922 int d2 = AS(RXYInstruction)->D2Value(); \ |
5913 int length = 6; | 5923 int length = 6; |
5914 | 5924 |
| 5925 #define DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val) \ |
| 5926 int x2 = AS(RXInstruction)->X2Value(); \ |
| 5927 int b2 = AS(RXInstruction)->B2Value(); \ |
| 5928 int r1 = AS(RXInstruction)->R1Value(); \ |
| 5929 intptr_t d2_val = AS(RXInstruction)->D2Value(); \ |
| 5930 int length = 4; |
| 5931 |
| 5932 #define DECODE_RS_A_INSTRUCTION(r1, r3, b2, d2) \ |
| 5933 int r3 = AS(RSInstruction)->R3Value(); \ |
| 5934 int b2 = AS(RSInstruction)->B2Value(); \ |
| 5935 int r1 = AS(RSInstruction)->R1Value(); \ |
| 5936 intptr_t d2 = AS(RSInstruction)->D2Value(); \ |
| 5937 int length = 4; |
| 5938 |
| 5939 #define DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2) \ |
| 5940 int b2 = AS(RSInstruction)->B2Value(); \ |
| 5941 int r1 = AS(RSInstruction)->R1Value(); \ |
| 5942 int d2 = AS(RSInstruction)->D2Value(); \ |
| 5943 int length = 4; |
| 5944 |
| 5945 #define DECODE_SI_INSTRUCTION_I_UINT8(b1, d1_val, imm_val) \ |
| 5946 int b1 = AS(SIInstruction)->B1Value(); \ |
| 5947 intptr_t d1_val = AS(SIInstruction)->D1Value(); \ |
| 5948 uint8_t imm_val = AS(SIInstruction)->I2Value(); \ |
| 5949 int length = 4; |
| 5950 |
5915 #define DECODE_RRE_INSTRUCTION(r1, r2) \ | 5951 #define DECODE_RRE_INSTRUCTION(r1, r2) \ |
5916 int r1 = AS(RREInstruction)->R1Value(); \ | 5952 int r1 = AS(RREInstruction)->R1Value(); \ |
5917 int r2 = AS(RREInstruction)->R2Value(); \ | 5953 int r2 = AS(RREInstruction)->R2Value(); \ |
5918 int length = 4; | 5954 int length = 4; |
5919 | 5955 |
5920 #define DECODE_RR_INSTRUCTION(r1, r2) \ | 5956 #define DECODE_RR_INSTRUCTION(r1, r2) \ |
5921 int r1 = AS(RRInstruction)->R1Value(); \ | 5957 int r1 = AS(RRInstruction)->R1Value(); \ |
5922 int r2 = AS(RRInstruction)->R2Value(); \ | 5958 int r2 = AS(RRInstruction)->R2Value(); \ |
5923 int length = 2; | 5959 int length = 2; |
5924 | 5960 |
(...skipping 16 matching lines...) Expand all Loading... |
5941 int r3 = AS(RSYInstruction)->R3Value(); \ | 5977 int r3 = AS(RSYInstruction)->R3Value(); \ |
5942 int b2 = AS(RSYInstruction)->B2Value(); \ | 5978 int b2 = AS(RSYInstruction)->B2Value(); \ |
5943 intptr_t d2 = AS(RSYInstruction)->D2Value(); \ | 5979 intptr_t d2 = AS(RSYInstruction)->D2Value(); \ |
5944 int length = 6; | 5980 int length = 6; |
5945 | 5981 |
5946 #define DECODE_RI_A_INSTRUCTION(instr, r1, i2) \ | 5982 #define DECODE_RI_A_INSTRUCTION(instr, r1, i2) \ |
5947 int32_t r1 = AS(RIInstruction)->R1Value(); \ | 5983 int32_t r1 = AS(RIInstruction)->R1Value(); \ |
5948 int16_t i2 = AS(RIInstruction)->I2Value(); \ | 5984 int16_t i2 = AS(RIInstruction)->I2Value(); \ |
5949 int length = 4; | 5985 int length = 4; |
5950 | 5986 |
| 5987 #define DECODE_RI_B_INSTRUCTION(instr, r1, i2) \ |
| 5988 int32_t r1 = AS(RILInstruction)->R1Value(); \ |
| 5989 int16_t i2 = AS(RILInstruction)->I2Value(); \ |
| 5990 int length = 4; |
| 5991 |
5951 #define DECODE_RI_C_INSTRUCTION(instr, m1, i2) \ | 5992 #define DECODE_RI_C_INSTRUCTION(instr, m1, i2) \ |
5952 Condition m1 = static_cast<Condition>(AS(RIInstruction)->R1Value()); \ | 5993 Condition m1 = static_cast<Condition>(AS(RIInstruction)->R1Value()); \ |
5953 int16_t i2 = AS(RIInstruction)->I2Value(); \ | 5994 int16_t i2 = AS(RIInstruction)->I2Value(); \ |
5954 int length = 4; | 5995 int length = 4; |
5955 | 5996 |
5956 #define GET_ADDRESS(index_reg, base_reg, offset) \ | 5997 #define GET_ADDRESS(index_reg, base_reg, offset) \ |
5957 (((index_reg) == 0) ? 0 : get_register(index_reg)) + \ | 5998 (((index_reg) == 0) ? 0 : get_register(index_reg)) + \ |
5958 (((base_reg) == 0) ? 0 : get_register(base_reg)) + offset | 5999 (((base_reg) == 0) ? 0 : get_register(base_reg)) + offset |
5959 | 6000 |
5960 int Simulator::Evaluate_Unknown(Instruction* instr) { | 6001 int Simulator::Evaluate_Unknown(Instruction* instr) { |
(...skipping 25 matching lines...) Expand all Loading... |
5986 bool isOF = CheckOverflowForIntAdd(r1_val, r2_val, int32_t); | 6027 bool isOF = CheckOverflowForIntAdd(r1_val, r2_val, int32_t); |
5987 r1_val += r2_val; | 6028 r1_val += r2_val; |
5988 SetS390ConditionCode<int32_t>(r1_val, 0); | 6029 SetS390ConditionCode<int32_t>(r1_val, 0); |
5989 SetS390OverflowCode(isOF); | 6030 SetS390OverflowCode(isOF); |
5990 set_low_register(r1, r1_val); | 6031 set_low_register(r1, r1_val); |
5991 return length; | 6032 return length; |
5992 } | 6033 } |
5993 | 6034 |
5994 EVALUATE(L) { | 6035 EVALUATE(L) { |
5995 DCHECK_OPCODE(L); | 6036 DCHECK_OPCODE(L); |
5996 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr); | 6037 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); |
5997 int b2 = rxinst->B2Value(); | |
5998 int x2 = rxinst->X2Value(); | |
5999 int32_t r1 = rxinst->R1Value(); | |
6000 int length = 4; | |
6001 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); | 6038 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
6002 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); | 6039 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
6003 intptr_t d2_val = rxinst->D2Value(); | |
6004 intptr_t addr = b2_val + x2_val + d2_val; | 6040 intptr_t addr = b2_val + x2_val + d2_val; |
6005 int32_t mem_val = ReadW(addr, instr); | 6041 int32_t mem_val = ReadW(addr, instr); |
6006 set_low_register(r1, mem_val); | 6042 set_low_register(r1, mem_val); |
6007 return length; | 6043 return length; |
6008 } | 6044 } |
6009 | 6045 |
6010 EVALUATE(BRC) { | 6046 EVALUATE(BRC) { |
6011 DCHECK_OPCODE(BRC); | 6047 DCHECK_OPCODE(BRC); |
6012 DECODE_RI_C_INSTRUCTION(instr, m1, i2); | 6048 DECODE_RI_C_INSTRUCTION(instr, m1, i2); |
6013 | 6049 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6049 | 6085 |
6050 if (TestConditionCode(m1)) { | 6086 if (TestConditionCode(m1)) { |
6051 intptr_t offset = 2 * ri2; | 6087 intptr_t offset = 2 * ri2; |
6052 set_pc(get_pc() + offset); | 6088 set_pc(get_pc() + offset); |
6053 } | 6089 } |
6054 return length; | 6090 return length; |
6055 } | 6091 } |
6056 | 6092 |
6057 EVALUATE(IIHF) { | 6093 EVALUATE(IIHF) { |
6058 DCHECK_OPCODE(IIHF); | 6094 DCHECK_OPCODE(IIHF); |
6059 RILInstruction* rilInstr = reinterpret_cast<RILInstruction*>(instr); | 6095 DECODE_RIL_A_INSTRUCTION(r1, imm); |
6060 int r1 = rilInstr->R1Value(); | |
6061 uint32_t imm = rilInstr->I2UnsignedValue(); | |
6062 int length = 6; | |
6063 set_high_register(r1, imm); | 6096 set_high_register(r1, imm); |
6064 return length; | 6097 return length; |
6065 } | 6098 } |
6066 | 6099 |
6067 EVALUATE(IILF) { | 6100 EVALUATE(IILF) { |
6068 DCHECK_OPCODE(IILF); | 6101 DCHECK_OPCODE(IILF); |
6069 RILInstruction* rilInstr = reinterpret_cast<RILInstruction*>(instr); | 6102 DECODE_RIL_A_INSTRUCTION(r1, imm); |
6070 int r1 = rilInstr->R1Value(); | |
6071 uint32_t imm = rilInstr->I2UnsignedValue(); | |
6072 int length = 6; | |
6073 set_low_register(r1, imm); | 6103 set_low_register(r1, imm); |
6074 return length; | 6104 return length; |
6075 } | 6105 } |
6076 | 6106 |
6077 EVALUATE(LGR) { | 6107 EVALUATE(LGR) { |
6078 DCHECK_OPCODE(LGR); | 6108 DCHECK_OPCODE(LGR); |
6079 DECODE_RRE_INSTRUCTION(r1, r2); | 6109 DECODE_RRE_INSTRUCTION(r1, r2); |
6080 set_register(r1, get_register(r2)); | 6110 set_register(r1, get_register(r2)); |
6081 return length; | 6111 return length; |
6082 } | 6112 } |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6157 DCHECK_OPCODE(LGF); | 6187 DCHECK_OPCODE(LGF); |
6158 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); | 6188 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); |
6159 intptr_t addr = GET_ADDRESS(x2, b2, d2); | 6189 intptr_t addr = GET_ADDRESS(x2, b2, d2); |
6160 int64_t mem_val = static_cast<int64_t>(ReadW(addr, instr)); | 6190 int64_t mem_val = static_cast<int64_t>(ReadW(addr, instr)); |
6161 set_register(r1, mem_val); | 6191 set_register(r1, mem_val); |
6162 return length; | 6192 return length; |
6163 } | 6193 } |
6164 | 6194 |
6165 EVALUATE(ST) { | 6195 EVALUATE(ST) { |
6166 DCHECK_OPCODE(ST); | 6196 DCHECK_OPCODE(ST); |
6167 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr); | 6197 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); |
6168 int b2 = rxinst->B2Value(); | 6198 int32_t r1_val = get_low_register<int32_t>(r1); |
6169 int x2 = rxinst->X2Value(); | |
6170 int length = 4; | |
6171 int32_t r1_val = get_low_register<int32_t>(rxinst->R1Value()); | |
6172 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); | 6199 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
6173 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); | 6200 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
6174 intptr_t d2_val = rxinst->D2Value(); | |
6175 intptr_t addr = b2_val + x2_val + d2_val; | 6201 intptr_t addr = b2_val + x2_val + d2_val; |
6176 WriteW(addr, r1_val, instr); | 6202 WriteW(addr, r1_val, instr); |
6177 return length; | 6203 return length; |
6178 } | 6204 } |
6179 | 6205 |
6180 EVALUATE(STG) { | 6206 EVALUATE(STG) { |
6181 DCHECK_OPCODE(STG); | 6207 DCHECK_OPCODE(STG); |
6182 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); | 6208 DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); |
6183 intptr_t addr = GET_ADDRESS(x2, b2, d2); | 6209 intptr_t addr = GET_ADDRESS(x2, b2, d2); |
6184 uint64_t value = get_register(r1); | 6210 uint64_t value = get_register(r1); |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6292 DECODE_RIE_D_INSTRUCTION(r1, r2, i2); | 6318 DECODE_RIE_D_INSTRUCTION(r1, r2, i2); |
6293 int64_t r2_val = get_register(r2); | 6319 int64_t r2_val = get_register(r2); |
6294 int64_t imm = static_cast<int64_t>(i2); | 6320 int64_t imm = static_cast<int64_t>(i2); |
6295 bool isOF = CheckOverflowForIntAdd(r2_val, imm, int64_t); | 6321 bool isOF = CheckOverflowForIntAdd(r2_val, imm, int64_t); |
6296 set_register(r1, r2_val + imm); | 6322 set_register(r1, r2_val + imm); |
6297 SetS390ConditionCode<int64_t>(r2_val + imm, 0); | 6323 SetS390ConditionCode<int64_t>(r2_val + imm, 0); |
6298 SetS390OverflowCode(isOF); | 6324 SetS390OverflowCode(isOF); |
6299 return length; | 6325 return length; |
6300 } | 6326 } |
6301 | 6327 |
6302 EVALUATE(BKPT) { return DecodeInstructionOriginal(instr); } | 6328 EVALUATE(BKPT) { |
| 6329 DCHECK_OPCODE(BKPT); |
| 6330 set_pc(get_pc() + 2); |
| 6331 S390Debugger dbg(this); |
| 6332 dbg.Debug(); |
| 6333 int length = 2; |
| 6334 return length; |
| 6335 } |
6303 | 6336 |
6304 EVALUATE(SPM) { return DecodeInstructionOriginal(instr); } | 6337 EVALUATE(SPM) { return DecodeInstructionOriginal(instr); } |
6305 | 6338 |
6306 EVALUATE(BALR) { return DecodeInstructionOriginal(instr); } | 6339 EVALUATE(BALR) { return DecodeInstructionOriginal(instr); } |
6307 | 6340 |
6308 EVALUATE(BCTR) { return DecodeInstructionOriginal(instr); } | 6341 EVALUATE(BCTR) { return DecodeInstructionOriginal(instr); } |
6309 | 6342 |
6310 EVALUATE(BCR) { return DecodeInstructionOriginal(instr); } | 6343 EVALUATE(BCR) { |
| 6344 DCHECK_OPCODE(BCR); |
| 6345 DECODE_RR_INSTRUCTION(r1, r2); |
| 6346 if (TestConditionCode(Condition(r1))) { |
| 6347 intptr_t r2_val = get_register(r2); |
| 6348 #if (!V8_TARGET_ARCH_S390X && V8_HOST_ARCH_S390) |
| 6349 // On 31-bit, the top most bit may be 0 or 1, but is ignored by the |
| 6350 // hardware. Cleanse the top bit before jumping to it, unless it's one |
| 6351 // of the special PCs |
| 6352 if (r2_val != bad_lr && r2_val != end_sim_pc) r2_val &= 0x7FFFFFFF; |
| 6353 #endif |
| 6354 set_pc(r2_val); |
| 6355 } |
| 6356 |
| 6357 return length; |
| 6358 } |
6311 | 6359 |
6312 EVALUATE(SVC) { return DecodeInstructionOriginal(instr); } | 6360 EVALUATE(SVC) { return DecodeInstructionOriginal(instr); } |
6313 | 6361 |
6314 EVALUATE(BSM) { return DecodeInstructionOriginal(instr); } | 6362 EVALUATE(BSM) { return DecodeInstructionOriginal(instr); } |
6315 | 6363 |
6316 EVALUATE(BASSM) { return DecodeInstructionOriginal(instr); } | 6364 EVALUATE(BASSM) { return DecodeInstructionOriginal(instr); } |
6317 | 6365 |
6318 EVALUATE(BASR) { return DecodeInstructionOriginal(instr); } | 6366 EVALUATE(BASR) { |
| 6367 DCHECK_OPCODE(BASR); |
| 6368 DECODE_RR_INSTRUCTION(r1, r2); |
| 6369 intptr_t link_addr = get_pc() + 2; |
| 6370 // If R2 is zero, the BASR does not branch. |
| 6371 int64_t r2_val = (r2 == 0) ? link_addr : get_register(r2); |
| 6372 #if (!V8_TARGET_ARCH_S390X && V8_HOST_ARCH_S390) |
| 6373 // On 31-bit, the top most bit may be 0 or 1, which can cause issues |
| 6374 // for stackwalker. The top bit should either be cleanse before being |
| 6375 // pushed onto the stack, or during stack walking when dereferenced. |
| 6376 // For simulator, we'll take the worst case scenario and always tag |
| 6377 // the high bit, to flush out more problems. |
| 6378 link_addr |= 0x80000000; |
| 6379 #endif |
| 6380 set_register(r1, link_addr); |
| 6381 set_pc(r2_val); |
| 6382 return length; |
| 6383 } |
6319 | 6384 |
6320 EVALUATE(MVCL) { return DecodeInstructionOriginal(instr); } | 6385 EVALUATE(MVCL) { return DecodeInstructionOriginal(instr); } |
6321 | 6386 |
6322 EVALUATE(CLCL) { return DecodeInstructionOriginal(instr); } | 6387 EVALUATE(CLCL) { return DecodeInstructionOriginal(instr); } |
6323 | 6388 |
6324 EVALUATE(LPR) { return DecodeInstructionOriginal(instr); } | 6389 EVALUATE(LPR) { return DecodeInstructionOriginal(instr); } |
6325 | 6390 |
6326 EVALUATE(LNR) { return DecodeInstructionOriginal(instr); } | 6391 EVALUATE(LNR) { |
6327 | 6392 DCHECK_OPCODE(LNR); |
6328 EVALUATE(LTR) { return DecodeInstructionOriginal(instr); } | 6393 // Load Negative (32) |
6329 | 6394 DECODE_RR_INSTRUCTION(r1, r2); |
6330 EVALUATE(LCR) { return DecodeInstructionOriginal(instr); } | 6395 int32_t r2_val = get_low_register<int32_t>(r2); |
6331 | 6396 r2_val = (r2_val >= 0) ? -r2_val : r2_val; // If pos, then negate it. |
6332 EVALUATE(NR) { return DecodeInstructionOriginal(instr); } | 6397 set_low_register(r1, r2_val); |
6333 | 6398 condition_reg_ = (r2_val == 0) ? CC_EQ : CC_LT; // CC0 - result is zero |
6334 EVALUATE(OR) { return DecodeInstructionOriginal(instr); } | 6399 // CC1 - result is negative |
6335 | 6400 return length; |
6336 EVALUATE(XR) { return DecodeInstructionOriginal(instr); } | 6401 } |
6337 | 6402 |
6338 EVALUATE(CR) { return DecodeInstructionOriginal(instr); } | 6403 EVALUATE(LTR) { |
6339 | 6404 DCHECK_OPCODE(LTR); |
6340 EVALUATE(SR) { return DecodeInstructionOriginal(instr); } | 6405 DECODE_RR_INSTRUCTION(r1, r2); |
6341 | 6406 int32_t r2_val = get_low_register<int32_t>(r2); |
6342 EVALUATE(MR) { return DecodeInstructionOriginal(instr); } | 6407 SetS390ConditionCode<int32_t>(r2_val, 0); |
6343 | 6408 set_low_register(r1, r2_val); |
6344 EVALUATE(DR) { return DecodeInstructionOriginal(instr); } | 6409 return length; |
6345 | 6410 } |
6346 EVALUATE(ALR) { return DecodeInstructionOriginal(instr); } | 6411 |
6347 | 6412 EVALUATE(LCR) { |
6348 EVALUATE(SLR) { return DecodeInstructionOriginal(instr); } | 6413 DCHECK_OPCODE(LCR); |
6349 | 6414 DECODE_RR_INSTRUCTION(r1, r2); |
6350 EVALUATE(LDR) { return DecodeInstructionOriginal(instr); } | 6415 int32_t r2_val = get_low_register<int32_t>(r2); |
| 6416 int32_t original_r2_val = r2_val; |
| 6417 r2_val = ~r2_val; |
| 6418 r2_val = r2_val + 1; |
| 6419 set_low_register(r1, r2_val); |
| 6420 SetS390ConditionCode<int32_t>(r2_val, 0); |
| 6421 // Checks for overflow where r2_val = -2147483648. |
| 6422 // Cannot do int comparison due to GCC 4.8 bug on x86. |
| 6423 // Detect INT_MIN alternatively, as it is the only value where both |
| 6424 // original and result are negative due to overflow. |
| 6425 if (r2_val < 0 && original_r2_val < 0) { |
| 6426 SetS390OverflowCode(true); |
| 6427 } |
| 6428 return length; |
| 6429 } |
| 6430 |
| 6431 EVALUATE(NR) { |
| 6432 DCHECK_OPCODE(NR); |
| 6433 DECODE_RR_INSTRUCTION(r1, r2); |
| 6434 int32_t r1_val = get_low_register<int32_t>(r1); |
| 6435 int32_t r2_val = get_low_register<int32_t>(r2); |
| 6436 r1_val &= r2_val; |
| 6437 SetS390BitWiseConditionCode<uint32_t>(r1_val); |
| 6438 set_low_register(r1, r1_val); |
| 6439 return length; |
| 6440 } |
| 6441 |
| 6442 EVALUATE(OR) { |
| 6443 DCHECK_OPCODE(OR); |
| 6444 DECODE_RR_INSTRUCTION(r1, r2); |
| 6445 int32_t r1_val = get_low_register<int32_t>(r1); |
| 6446 int32_t r2_val = get_low_register<int32_t>(r2); |
| 6447 r1_val |= r2_val; |
| 6448 SetS390BitWiseConditionCode<uint32_t>(r1_val); |
| 6449 set_low_register(r1, r1_val); |
| 6450 return length; |
| 6451 } |
| 6452 |
| 6453 EVALUATE(XR) { |
| 6454 DCHECK_OPCODE(XR); |
| 6455 DECODE_RR_INSTRUCTION(r1, r2); |
| 6456 int32_t r1_val = get_low_register<int32_t>(r1); |
| 6457 int32_t r2_val = get_low_register<int32_t>(r2); |
| 6458 r1_val ^= r2_val; |
| 6459 SetS390BitWiseConditionCode<uint32_t>(r1_val); |
| 6460 set_low_register(r1, r1_val); |
| 6461 return length; |
| 6462 } |
| 6463 |
| 6464 EVALUATE(CR) { |
| 6465 DCHECK_OPCODE(CR); |
| 6466 DECODE_RR_INSTRUCTION(r1, r2); |
| 6467 int32_t r1_val = get_low_register<int32_t>(r1); |
| 6468 int32_t r2_val = get_low_register<int32_t>(r2); |
| 6469 SetS390ConditionCode<int32_t>(r1_val, r2_val); |
| 6470 return length; |
| 6471 } |
| 6472 |
| 6473 EVALUATE(SR) { |
| 6474 DCHECK_OPCODE(SR); |
| 6475 DECODE_RR_INSTRUCTION(r1, r2); |
| 6476 int32_t r1_val = get_low_register<int32_t>(r1); |
| 6477 int32_t r2_val = get_low_register<int32_t>(r2); |
| 6478 bool isOF = false; |
| 6479 isOF = CheckOverflowForIntSub(r1_val, r2_val, int32_t); |
| 6480 r1_val -= r2_val; |
| 6481 SetS390ConditionCode<int32_t>(r1_val, 0); |
| 6482 SetS390OverflowCode(isOF); |
| 6483 set_low_register(r1, r1_val); |
| 6484 return length; |
| 6485 } |
| 6486 |
| 6487 EVALUATE(MR) { |
| 6488 DCHECK_OPCODE(MR); |
| 6489 DECODE_RR_INSTRUCTION(r1, r2); |
| 6490 int32_t r1_val = get_low_register<int32_t>(r1); |
| 6491 int32_t r2_val = get_low_register<int32_t>(r2); |
| 6492 DCHECK(r1 % 2 == 0); |
| 6493 r1_val = get_low_register<int32_t>(r1 + 1); |
| 6494 int64_t product = static_cast<int64_t>(r1_val) * static_cast<int64_t>(r2_val); |
| 6495 int32_t high_bits = product >> 32; |
| 6496 r1_val = high_bits; |
| 6497 int32_t low_bits = product & 0x00000000FFFFFFFF; |
| 6498 set_low_register(r1, high_bits); |
| 6499 set_low_register(r1 + 1, low_bits); |
| 6500 set_low_register(r1, r1_val); |
| 6501 return length; |
| 6502 } |
| 6503 |
| 6504 EVALUATE(DR) { |
| 6505 DCHECK_OPCODE(DR); |
| 6506 DECODE_RR_INSTRUCTION(r1, r2); |
| 6507 int32_t r1_val = get_low_register<int32_t>(r1); |
| 6508 int32_t r2_val = get_low_register<int32_t>(r2); |
| 6509 // reg-reg pair should be even-odd pair, assert r1 is an even register |
| 6510 DCHECK(r1 % 2 == 0); |
| 6511 // leftmost 32 bits of the dividend are in r1 |
| 6512 // rightmost 32 bits of the dividend are in r1+1 |
| 6513 // get the signed value from r1 |
| 6514 int64_t dividend = static_cast<int64_t>(r1_val) << 32; |
| 6515 // get unsigned value from r1+1 |
| 6516 // avoid addition with sign-extended r1+1 value |
| 6517 dividend += get_low_register<uint32_t>(r1 + 1); |
| 6518 int32_t remainder = dividend % r2_val; |
| 6519 int32_t quotient = dividend / r2_val; |
| 6520 r1_val = remainder; |
| 6521 set_low_register(r1, remainder); |
| 6522 set_low_register(r1 + 1, quotient); |
| 6523 set_low_register(r1, r1_val); |
| 6524 return length; |
| 6525 } |
| 6526 |
| 6527 EVALUATE(ALR) { |
| 6528 DCHECK_OPCODE(ALR); |
| 6529 DECODE_RR_INSTRUCTION(r1, r2); |
| 6530 uint32_t r1_val = get_low_register<uint32_t>(r1); |
| 6531 uint32_t r2_val = get_low_register<uint32_t>(r2); |
| 6532 uint32_t alu_out = 0; |
| 6533 bool isOF = false; |
| 6534 alu_out = r1_val + r2_val; |
| 6535 isOF = CheckOverflowForUIntAdd(r1_val, r2_val); |
| 6536 set_low_register(r1, alu_out); |
| 6537 SetS390ConditionCodeCarry<uint32_t>(alu_out, isOF); |
| 6538 return length; |
| 6539 } |
| 6540 |
| 6541 EVALUATE(SLR) { |
| 6542 DCHECK_OPCODE(SLR); |
| 6543 DECODE_RR_INSTRUCTION(r1, r2); |
| 6544 uint32_t r1_val = get_low_register<uint32_t>(r1); |
| 6545 uint32_t r2_val = get_low_register<uint32_t>(r2); |
| 6546 uint32_t alu_out = 0; |
| 6547 bool isOF = false; |
| 6548 alu_out = r1_val - r2_val; |
| 6549 isOF = CheckOverflowForUIntSub(r1_val, r2_val); |
| 6550 set_low_register(r1, alu_out); |
| 6551 SetS390ConditionCodeCarry<uint32_t>(alu_out, isOF); |
| 6552 return length; |
| 6553 } |
| 6554 |
| 6555 EVALUATE(LDR) { |
| 6556 DCHECK_OPCODE(LDR); |
| 6557 DECODE_RR_INSTRUCTION(r1, r2); |
| 6558 int64_t r2_val = get_d_register(r2); |
| 6559 set_d_register(r1, r2_val); |
| 6560 return length; |
| 6561 } |
6351 | 6562 |
6352 EVALUATE(CDR) { return DecodeInstructionOriginal(instr); } | 6563 EVALUATE(CDR) { return DecodeInstructionOriginal(instr); } |
6353 | 6564 |
6354 EVALUATE(LER) { return DecodeInstructionOriginal(instr); } | 6565 EVALUATE(LER) { return DecodeInstructionOriginal(instr); } |
6355 | 6566 |
6356 EVALUATE(STH) { return DecodeInstructionOriginal(instr); } | 6567 EVALUATE(STH) { |
6357 | 6568 DCHECK_OPCODE(STH); |
6358 EVALUATE(LA) { return DecodeInstructionOriginal(instr); } | 6569 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); |
6359 | 6570 int16_t r1_val = get_low_register<int32_t>(r1); |
6360 EVALUATE(STC) { return DecodeInstructionOriginal(instr); } | 6571 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
| 6572 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
| 6573 intptr_t mem_addr = b2_val + x2_val + d2_val; |
| 6574 WriteH(mem_addr, r1_val, instr); |
| 6575 |
| 6576 return length; |
| 6577 } |
| 6578 |
| 6579 EVALUATE(LA) { |
| 6580 DCHECK_OPCODE(LA); |
| 6581 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); |
| 6582 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
| 6583 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
| 6584 intptr_t addr = b2_val + x2_val + d2_val; |
| 6585 set_register(r1, addr); |
| 6586 return length; |
| 6587 } |
| 6588 |
| 6589 EVALUATE(STC) { |
| 6590 DCHECK_OPCODE(STC); |
| 6591 // Store Character/Byte |
| 6592 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); |
| 6593 uint8_t r1_val = get_low_register<int32_t>(r1); |
| 6594 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
| 6595 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
| 6596 intptr_t mem_addr = b2_val + x2_val + d2_val; |
| 6597 WriteB(mem_addr, r1_val); |
| 6598 return length; |
| 6599 } |
6361 | 6600 |
6362 EVALUATE(IC_z) { return DecodeInstructionOriginal(instr); } | 6601 EVALUATE(IC_z) { return DecodeInstructionOriginal(instr); } |
6363 | 6602 |
6364 EVALUATE(EX) { return DecodeInstructionOriginal(instr); } | 6603 EVALUATE(EX) { |
| 6604 DCHECK_OPCODE(EX); |
| 6605 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); |
| 6606 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
| 6607 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
| 6608 int32_t r1_val = get_low_register<int32_t>(r1); |
| 6609 |
| 6610 SixByteInstr the_instr = Instruction::InstructionBits( |
| 6611 reinterpret_cast<const byte*>(b2_val + x2_val + d2_val)); |
| 6612 int inst_length = Instruction::InstructionLength( |
| 6613 reinterpret_cast<const byte*>(b2_val + x2_val + d2_val)); |
| 6614 |
| 6615 char new_instr_buf[8]; |
| 6616 char* addr = reinterpret_cast<char*>(&new_instr_buf[0]); |
| 6617 the_instr |= static_cast<SixByteInstr>(r1_val & 0xff) |
| 6618 << (8 * inst_length - 16); |
| 6619 Instruction::SetInstructionBits<SixByteInstr>( |
| 6620 reinterpret_cast<byte*>(addr), static_cast<SixByteInstr>(the_instr)); |
| 6621 ExecuteInstruction(reinterpret_cast<Instruction*>(addr), false); |
| 6622 return length; |
| 6623 } |
6365 | 6624 |
6366 EVALUATE(BAL) { return DecodeInstructionOriginal(instr); } | 6625 EVALUATE(BAL) { return DecodeInstructionOriginal(instr); } |
6367 | 6626 |
6368 EVALUATE(BCT) { return DecodeInstructionOriginal(instr); } | 6627 EVALUATE(BCT) { return DecodeInstructionOriginal(instr); } |
6369 | 6628 |
6370 EVALUATE(BC) { return DecodeInstructionOriginal(instr); } | 6629 EVALUATE(BC) { return DecodeInstructionOriginal(instr); } |
6371 | 6630 |
6372 EVALUATE(LH) { return DecodeInstructionOriginal(instr); } | 6631 EVALUATE(LH) { |
| 6632 DCHECK_OPCODE(LH); |
| 6633 // Load Halfword |
| 6634 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); |
| 6635 |
| 6636 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
| 6637 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
| 6638 intptr_t mem_addr = x2_val + b2_val + d2_val; |
| 6639 |
| 6640 int32_t result = static_cast<int32_t>(ReadH(mem_addr, instr)); |
| 6641 set_low_register(r1, result); |
| 6642 return length; |
| 6643 } |
6373 | 6644 |
6374 EVALUATE(CH) { return DecodeInstructionOriginal(instr); } | 6645 EVALUATE(CH) { return DecodeInstructionOriginal(instr); } |
6375 | 6646 |
6376 EVALUATE(AH) { return DecodeInstructionOriginal(instr); } | 6647 EVALUATE(AH) { |
| 6648 DCHECK_OPCODE(AH); |
| 6649 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); |
| 6650 int32_t r1_val = get_low_register<int32_t>(r1); |
| 6651 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
| 6652 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
| 6653 intptr_t addr = b2_val + x2_val + d2_val; |
| 6654 int32_t mem_val = static_cast<int32_t>(ReadH(addr, instr)); |
| 6655 int32_t alu_out = 0; |
| 6656 bool isOF = false; |
| 6657 isOF = CheckOverflowForIntAdd(r1_val, mem_val, int32_t); |
| 6658 alu_out = r1_val + mem_val; |
| 6659 set_low_register(r1, alu_out); |
| 6660 SetS390ConditionCode<int32_t>(alu_out, 0); |
| 6661 SetS390OverflowCode(isOF); |
6377 | 6662 |
6378 EVALUATE(SH) { return DecodeInstructionOriginal(instr); } | 6663 return length; |
| 6664 } |
6379 | 6665 |
6380 EVALUATE(MH) { return DecodeInstructionOriginal(instr); } | 6666 EVALUATE(SH) { |
| 6667 DCHECK_OPCODE(SH); |
| 6668 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); |
| 6669 int32_t r1_val = get_low_register<int32_t>(r1); |
| 6670 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
| 6671 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
| 6672 intptr_t addr = b2_val + x2_val + d2_val; |
| 6673 int32_t mem_val = static_cast<int32_t>(ReadH(addr, instr)); |
| 6674 int32_t alu_out = 0; |
| 6675 bool isOF = false; |
| 6676 isOF = CheckOverflowForIntSub(r1_val, mem_val, int32_t); |
| 6677 alu_out = r1_val - mem_val; |
| 6678 SetS390ConditionCode<int32_t>(alu_out, 0); |
| 6679 SetS390OverflowCode(isOF); |
| 6680 |
| 6681 return length; |
| 6682 } |
| 6683 |
| 6684 EVALUATE(MH) { |
| 6685 DCHECK_OPCODE(MH); |
| 6686 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); |
| 6687 int32_t r1_val = get_low_register<int32_t>(r1); |
| 6688 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
| 6689 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
| 6690 intptr_t addr = b2_val + x2_val + d2_val; |
| 6691 int32_t mem_val = static_cast<int32_t>(ReadH(addr, instr)); |
| 6692 int32_t alu_out = 0; |
| 6693 alu_out = r1_val * mem_val; |
| 6694 set_low_register(r1, alu_out); |
| 6695 return length; |
| 6696 } |
6381 | 6697 |
6382 EVALUATE(BAS) { return DecodeInstructionOriginal(instr); } | 6698 EVALUATE(BAS) { return DecodeInstructionOriginal(instr); } |
6383 | 6699 |
6384 EVALUATE(CVD) { return DecodeInstructionOriginal(instr); } | 6700 EVALUATE(CVD) { return DecodeInstructionOriginal(instr); } |
6385 | 6701 |
6386 EVALUATE(CVB) { return DecodeInstructionOriginal(instr); } | 6702 EVALUATE(CVB) { return DecodeInstructionOriginal(instr); } |
6387 | 6703 |
6388 EVALUATE(LAE) { return DecodeInstructionOriginal(instr); } | 6704 EVALUATE(LAE) { return DecodeInstructionOriginal(instr); } |
6389 | 6705 |
6390 EVALUATE(N) { return DecodeInstructionOriginal(instr); } | 6706 EVALUATE(N) { |
| 6707 DCHECK_OPCODE(N); |
| 6708 // 32-bit Reg-Mem instructions |
| 6709 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); |
| 6710 int32_t r1_val = get_low_register<int32_t>(r1); |
| 6711 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
| 6712 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
| 6713 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr); |
| 6714 int32_t alu_out = 0; |
| 6715 alu_out = r1_val & mem_val; |
| 6716 SetS390BitWiseConditionCode<uint32_t>(alu_out); |
| 6717 set_low_register(r1, alu_out); |
| 6718 return length; |
| 6719 } |
6391 | 6720 |
6392 EVALUATE(CL) { return DecodeInstructionOriginal(instr); } | 6721 EVALUATE(CL) { |
| 6722 DCHECK_OPCODE(CL); |
| 6723 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); |
| 6724 int32_t r1_val = get_low_register<int32_t>(r1); |
| 6725 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
| 6726 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
| 6727 intptr_t addr = b2_val + x2_val + d2_val; |
| 6728 int32_t mem_val = ReadW(addr, instr); |
| 6729 SetS390ConditionCode<uint32_t>(r1_val, mem_val); |
| 6730 return length; |
| 6731 } |
6393 | 6732 |
6394 EVALUATE(O) { return DecodeInstructionOriginal(instr); } | 6733 EVALUATE(O) { |
| 6734 DCHECK_OPCODE(O); |
| 6735 // 32-bit Reg-Mem instructions |
| 6736 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); |
| 6737 int32_t r1_val = get_low_register<int32_t>(r1); |
| 6738 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
| 6739 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
| 6740 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr); |
| 6741 int32_t alu_out = 0; |
| 6742 alu_out = r1_val | mem_val; |
| 6743 SetS390BitWiseConditionCode<uint32_t>(alu_out); |
| 6744 set_low_register(r1, alu_out); |
| 6745 return length; |
| 6746 } |
6395 | 6747 |
6396 EVALUATE(X) { return DecodeInstructionOriginal(instr); } | 6748 EVALUATE(X) { |
| 6749 DCHECK_OPCODE(X); |
| 6750 // 32-bit Reg-Mem instructions |
| 6751 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); |
| 6752 int32_t r1_val = get_low_register<int32_t>(r1); |
| 6753 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
| 6754 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
| 6755 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr); |
| 6756 int32_t alu_out = 0; |
| 6757 alu_out = r1_val ^ mem_val; |
| 6758 SetS390BitWiseConditionCode<uint32_t>(alu_out); |
| 6759 set_low_register(r1, alu_out); |
| 6760 return length; |
| 6761 } |
6397 | 6762 |
6398 EVALUATE(C) { return DecodeInstructionOriginal(instr); } | 6763 EVALUATE(C) { |
| 6764 DCHECK_OPCODE(C); |
| 6765 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); |
| 6766 int32_t r1_val = get_low_register<int32_t>(r1); |
| 6767 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
| 6768 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
| 6769 intptr_t addr = b2_val + x2_val + d2_val; |
| 6770 int32_t mem_val = ReadW(addr, instr); |
| 6771 SetS390ConditionCode<int32_t>(r1_val, mem_val); |
| 6772 return length; |
| 6773 } |
6399 | 6774 |
6400 EVALUATE(A) { return DecodeInstructionOriginal(instr); } | 6775 EVALUATE(A) { |
| 6776 DCHECK_OPCODE(A); |
| 6777 // 32-bit Reg-Mem instructions |
| 6778 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); |
| 6779 int32_t r1_val = get_low_register<int32_t>(r1); |
| 6780 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
| 6781 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
| 6782 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr); |
| 6783 int32_t alu_out = 0; |
| 6784 bool isOF = false; |
| 6785 isOF = CheckOverflowForIntAdd(r1_val, mem_val, int32_t); |
| 6786 alu_out = r1_val + mem_val; |
| 6787 SetS390ConditionCode<int32_t>(alu_out, 0); |
| 6788 SetS390OverflowCode(isOF); |
| 6789 set_low_register(r1, alu_out); |
| 6790 return length; |
| 6791 } |
6401 | 6792 |
6402 EVALUATE(S) { return DecodeInstructionOriginal(instr); } | 6793 EVALUATE(S) { |
| 6794 DCHECK_OPCODE(S); |
| 6795 // 32-bit Reg-Mem instructions |
| 6796 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); |
| 6797 int32_t r1_val = get_low_register<int32_t>(r1); |
| 6798 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
| 6799 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
| 6800 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr); |
| 6801 int32_t alu_out = 0; |
| 6802 bool isOF = false; |
| 6803 isOF = CheckOverflowForIntSub(r1_val, mem_val, int32_t); |
| 6804 alu_out = r1_val - mem_val; |
| 6805 SetS390ConditionCode<int32_t>(alu_out, 0); |
| 6806 SetS390OverflowCode(isOF); |
| 6807 set_low_register(r1, alu_out); |
| 6808 return length; |
| 6809 } |
6403 | 6810 |
6404 EVALUATE(M) { return DecodeInstructionOriginal(instr); } | 6811 EVALUATE(M) { return DecodeInstructionOriginal(instr); } |
6405 | 6812 |
6406 EVALUATE(D) { return DecodeInstructionOriginal(instr); } | 6813 EVALUATE(D) { return DecodeInstructionOriginal(instr); } |
6407 | 6814 |
6408 EVALUATE(AL) { return DecodeInstructionOriginal(instr); } | 6815 EVALUATE(AL) { return DecodeInstructionOriginal(instr); } |
6409 | 6816 |
6410 EVALUATE(SL) { return DecodeInstructionOriginal(instr); } | 6817 EVALUATE(SL) { return DecodeInstructionOriginal(instr); } |
6411 | 6818 |
6412 EVALUATE(STD) { return DecodeInstructionOriginal(instr); } | 6819 EVALUATE(STD) { |
6413 | 6820 DCHECK_OPCODE(STD); |
6414 EVALUATE(LD) { return DecodeInstructionOriginal(instr); } | 6821 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); |
| 6822 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
| 6823 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
| 6824 intptr_t addr = b2_val + x2_val + d2_val; |
| 6825 int64_t frs_val = get_d_register(r1); |
| 6826 WriteDW(addr, frs_val); |
| 6827 return length; |
| 6828 } |
| 6829 |
| 6830 EVALUATE(LD) { |
| 6831 DCHECK_OPCODE(LD); |
| 6832 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); |
| 6833 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
| 6834 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
| 6835 intptr_t addr = b2_val + x2_val + d2_val; |
| 6836 int64_t dbl_val = *reinterpret_cast<int64_t*>(addr); |
| 6837 set_d_register(r1, dbl_val); |
| 6838 return length; |
| 6839 } |
6415 | 6840 |
6416 EVALUATE(CD) { return DecodeInstructionOriginal(instr); } | 6841 EVALUATE(CD) { return DecodeInstructionOriginal(instr); } |
6417 | 6842 |
6418 EVALUATE(STE) { return DecodeInstructionOriginal(instr); } | 6843 EVALUATE(STE) { |
6419 | 6844 DCHECK_OPCODE(STE); |
6420 EVALUATE(MS) { return DecodeInstructionOriginal(instr); } | 6845 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); |
6421 | 6846 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
6422 EVALUATE(LE) { return DecodeInstructionOriginal(instr); } | 6847 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
| 6848 intptr_t addr = b2_val + x2_val + d2_val; |
| 6849 int64_t frs_val = get_d_register(r1) >> 32; |
| 6850 WriteW(addr, static_cast<int32_t>(frs_val), instr); |
| 6851 return length; |
| 6852 } |
| 6853 |
| 6854 EVALUATE(MS) { |
| 6855 DCHECK_OPCODE(MS); |
| 6856 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); |
| 6857 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
| 6858 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
| 6859 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr); |
| 6860 int32_t r1_val = get_low_register<int32_t>(r1); |
| 6861 set_low_register(r1, r1_val * mem_val); |
| 6862 return length; |
| 6863 } |
| 6864 |
| 6865 EVALUATE(LE) { |
| 6866 DCHECK_OPCODE(LE); |
| 6867 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); |
| 6868 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
| 6869 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
| 6870 intptr_t addr = b2_val + x2_val + d2_val; |
| 6871 float float_val = *reinterpret_cast<float*>(addr); |
| 6872 set_d_register_from_float32(r1, float_val); |
| 6873 return length; |
| 6874 } |
6423 | 6875 |
6424 EVALUATE(BRXH) { return DecodeInstructionOriginal(instr); } | 6876 EVALUATE(BRXH) { return DecodeInstructionOriginal(instr); } |
6425 | 6877 |
6426 EVALUATE(BRXLE) { return DecodeInstructionOriginal(instr); } | 6878 EVALUATE(BRXLE) { return DecodeInstructionOriginal(instr); } |
6427 | 6879 |
6428 EVALUATE(BXH) { return DecodeInstructionOriginal(instr); } | 6880 EVALUATE(BXH) { |
| 6881 DCHECK_OPCODE(BXH); |
| 6882 DECODE_RS_A_INSTRUCTION(r1, r3, b2, d2); |
| 6883 |
| 6884 // r1_val is the first operand, r3_val is the increment |
| 6885 int32_t r1_val = r1 == 0 ? 0 : get_register(r1); |
| 6886 int32_t r3_val = r2 == 0 ? 0 : get_register(r3); |
| 6887 intptr_t b2_val = b2 == 0 ? 0 : get_register(b2); |
| 6888 intptr_t branch_address = b2_val + d2; |
| 6889 // increment r1_val |
| 6890 r1_val += r3_val; |
| 6891 |
| 6892 // if the increment is even, then it designates a pair of registers |
| 6893 // and the contents of the even and odd registers of the pair are used as |
| 6894 // the increment and compare value respectively. If the increment is odd, |
| 6895 // the increment itself is used as both the increment and compare value |
| 6896 int32_t compare_val = r3 % 2 == 0 ? get_register(r3 + 1) : r3_val; |
| 6897 if (r1_val > compare_val) { |
| 6898 // branch to address if r1_val is greater than compare value |
| 6899 set_pc(branch_address); |
| 6900 } |
| 6901 |
| 6902 // update contents of register in r1 with the new incremented value |
| 6903 set_register(r1, r1_val); |
| 6904 |
| 6905 return length; |
| 6906 } |
6429 | 6907 |
6430 EVALUATE(BXLE) { return DecodeInstructionOriginal(instr); } | 6908 EVALUATE(BXLE) { return DecodeInstructionOriginal(instr); } |
6431 | 6909 |
6432 EVALUATE(SRL) { return DecodeInstructionOriginal(instr); } | 6910 EVALUATE(SRL) { |
6433 | 6911 DCHECK_OPCODE(SRL); |
6434 EVALUATE(SLL) { return DecodeInstructionOriginal(instr); } | 6912 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2); |
6435 | 6913 // only takes rightmost 6bits |
6436 EVALUATE(SRA) { return DecodeInstructionOriginal(instr); } | 6914 int64_t b2_val = b2 == 0 ? 0 : get_register(b2); |
6437 | 6915 int shiftBits = (b2_val + d2) & 0x3F; |
6438 EVALUATE(SLA) { return DecodeInstructionOriginal(instr); } | 6916 uint32_t r1_val = get_low_register<uint32_t>(r1); |
6439 | 6917 uint32_t alu_out = 0; |
6440 EVALUATE(SRDL) { return DecodeInstructionOriginal(instr); } | 6918 alu_out = r1_val >> shiftBits; |
6441 | 6919 set_low_register(r1, alu_out); |
6442 EVALUATE(SLDL) { return DecodeInstructionOriginal(instr); } | 6920 return length; |
6443 | 6921 } |
6444 EVALUATE(SRDA) { return DecodeInstructionOriginal(instr); } | 6922 |
| 6923 EVALUATE(SLL) { |
| 6924 DCHECK_OPCODE(SLL); |
| 6925 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2) |
| 6926 // only takes rightmost 6bits |
| 6927 int64_t b2_val = b2 == 0 ? 0 : get_register(b2); |
| 6928 int shiftBits = (b2_val + d2) & 0x3F; |
| 6929 uint32_t r1_val = get_low_register<uint32_t>(r1); |
| 6930 uint32_t alu_out = 0; |
| 6931 alu_out = r1_val << shiftBits; |
| 6932 set_low_register(r1, alu_out); |
| 6933 return length; |
| 6934 } |
| 6935 |
| 6936 EVALUATE(SRA) { |
| 6937 DCHECK_OPCODE(SRA); |
| 6938 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2); |
| 6939 // only takes rightmost 6bits |
| 6940 int64_t b2_val = b2 == 0 ? 0 : get_register(b2); |
| 6941 int shiftBits = (b2_val + d2) & 0x3F; |
| 6942 int32_t r1_val = get_low_register<int32_t>(r1); |
| 6943 int32_t alu_out = 0; |
| 6944 bool isOF = false; |
| 6945 alu_out = r1_val >> shiftBits; |
| 6946 set_low_register(r1, alu_out); |
| 6947 SetS390ConditionCode<int32_t>(alu_out, 0); |
| 6948 SetS390OverflowCode(isOF); |
| 6949 return length; |
| 6950 } |
| 6951 |
| 6952 EVALUATE(SLA) { |
| 6953 DCHECK_OPCODE(SLA); |
| 6954 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2); |
| 6955 // only takes rightmost 6bits |
| 6956 int64_t b2_val = b2 == 0 ? 0 : get_register(b2); |
| 6957 int shiftBits = (b2_val + d2) & 0x3F; |
| 6958 int32_t r1_val = get_low_register<int32_t>(r1); |
| 6959 int32_t alu_out = 0; |
| 6960 bool isOF = false; |
| 6961 isOF = CheckOverflowForShiftLeft(r1_val, shiftBits); |
| 6962 alu_out = r1_val << shiftBits; |
| 6963 set_low_register(r1, alu_out); |
| 6964 SetS390ConditionCode<int32_t>(alu_out, 0); |
| 6965 SetS390OverflowCode(isOF); |
| 6966 return length; |
| 6967 } |
| 6968 |
| 6969 EVALUATE(SRDL) { |
| 6970 DCHECK_OPCODE(SRDL); |
| 6971 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2); |
| 6972 DCHECK(r1 % 2 == 0); // must be a reg pair |
| 6973 // only takes rightmost 6bits |
| 6974 int64_t b2_val = b2 == 0 ? 0 : get_register(b2); |
| 6975 int shiftBits = (b2_val + d2) & 0x3F; |
| 6976 uint64_t opnd1 = static_cast<uint64_t>(get_low_register<uint32_t>(r1)) << 32; |
| 6977 uint64_t opnd2 = static_cast<uint64_t>(get_low_register<uint32_t>(r1 + 1)); |
| 6978 uint64_t r1_val = opnd1 | opnd2; |
| 6979 uint64_t alu_out = r1_val >> shiftBits; |
| 6980 set_low_register(r1, alu_out >> 32); |
| 6981 set_low_register(r1 + 1, alu_out & 0x00000000FFFFFFFF); |
| 6982 SetS390ConditionCode<int32_t>(alu_out, 0); |
| 6983 return length; |
| 6984 } |
| 6985 |
| 6986 EVALUATE(SLDL) { |
| 6987 DCHECK_OPCODE(SLDL); |
| 6988 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2); |
| 6989 // only takes rightmost 6bits |
| 6990 int64_t b2_val = b2 == 0 ? 0 : get_register(b2); |
| 6991 int shiftBits = (b2_val + d2) & 0x3F; |
| 6992 |
| 6993 DCHECK(r1 % 2 == 0); |
| 6994 uint32_t r1_val = get_low_register<uint32_t>(r1); |
| 6995 uint32_t r1_next_val = get_low_register<uint32_t>(r1 + 1); |
| 6996 uint64_t alu_out = (static_cast<uint64_t>(r1_val) << 32) | |
| 6997 (static_cast<uint64_t>(r1_next_val)); |
| 6998 alu_out <<= shiftBits; |
| 6999 set_low_register(r1 + 1, static_cast<uint32_t>(alu_out)); |
| 7000 set_low_register(r1, static_cast<uint32_t>(alu_out >> 32)); |
| 7001 return length; |
| 7002 } |
| 7003 |
| 7004 EVALUATE(SRDA) { |
| 7005 DCHECK_OPCODE(SRDA); |
| 7006 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2); |
| 7007 DCHECK(r1 % 2 == 0); // must be a reg pair |
| 7008 // only takes rightmost 6bits |
| 7009 int64_t b2_val = b2 == 0 ? 0 : get_register(b2); |
| 7010 int shiftBits = (b2_val + d2) & 0x3F; |
| 7011 int64_t opnd1 = static_cast<int64_t>(get_low_register<int32_t>(r1)) << 32; |
| 7012 int64_t opnd2 = static_cast<uint64_t>(get_low_register<uint32_t>(r1 + 1)); |
| 7013 int64_t r1_val = opnd1 + opnd2; |
| 7014 int64_t alu_out = r1_val >> shiftBits; |
| 7015 set_low_register(r1, alu_out >> 32); |
| 7016 set_low_register(r1 + 1, alu_out & 0x00000000FFFFFFFF); |
| 7017 SetS390ConditionCode<int32_t>(alu_out, 0); |
| 7018 return length; |
| 7019 } |
6445 | 7020 |
6446 EVALUATE(SLDA) { return DecodeInstructionOriginal(instr); } | 7021 EVALUATE(SLDA) { return DecodeInstructionOriginal(instr); } |
6447 | 7022 |
6448 EVALUATE(STM) { return DecodeInstructionOriginal(instr); } | 7023 EVALUATE(STM) { |
6449 | 7024 DCHECK_OPCODE(STM); |
6450 EVALUATE(TM) { return DecodeInstructionOriginal(instr); } | 7025 DECODE_RS_A_INSTRUCTION(r1, r3, rb, d2); |
| 7026 // Store Multiple 32-bits. |
| 7027 int offset = d2; |
| 7028 // Regs roll around if r3 is less than r1. |
| 7029 // Artifically increase r3 by 16 so we can calculate |
| 7030 // the number of regs stored properly. |
| 7031 if (r3 < r1) r3 += 16; |
| 7032 |
| 7033 int32_t rb_val = (rb == 0) ? 0 : get_low_register<int32_t>(rb); |
| 7034 |
| 7035 // Store each register in ascending order. |
| 7036 for (int i = 0; i <= r3 - r1; i++) { |
| 7037 int32_t value = get_low_register<int32_t>((r1 + i) % 16); |
| 7038 WriteW(rb_val + offset + 4 * i, value, instr); |
| 7039 } |
| 7040 return length; |
| 7041 } |
| 7042 |
| 7043 EVALUATE(TM) { |
| 7044 DCHECK_OPCODE(TM); |
| 7045 // Test Under Mask (Mem - Imm) (8) |
| 7046 DECODE_SI_INSTRUCTION_I_UINT8(b1, d1_val, imm_val) |
| 7047 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1); |
| 7048 intptr_t addr = b1_val + d1_val; |
| 7049 uint8_t mem_val = ReadB(addr); |
| 7050 uint8_t selected_bits = mem_val & imm_val; |
| 7051 // CC0: Selected bits are zero |
| 7052 // CC1: Selected bits mixed zeros and ones |
| 7053 // CC3: Selected bits all ones |
| 7054 if (0 == selected_bits) { |
| 7055 condition_reg_ = CC_EQ; // CC0 |
| 7056 } else if (selected_bits == imm_val) { |
| 7057 condition_reg_ = 0x1; // CC3 |
| 7058 } else { |
| 7059 condition_reg_ = 0x4; // CC1 |
| 7060 } |
| 7061 return length; |
| 7062 } |
6451 | 7063 |
6452 EVALUATE(MVI) { return DecodeInstructionOriginal(instr); } | 7064 EVALUATE(MVI) { return DecodeInstructionOriginal(instr); } |
6453 | 7065 |
6454 EVALUATE(TS) { return DecodeInstructionOriginal(instr); } | 7066 EVALUATE(TS) { return DecodeInstructionOriginal(instr); } |
6455 | 7067 |
6456 EVALUATE(NI) { return DecodeInstructionOriginal(instr); } | 7068 EVALUATE(NI) { return DecodeInstructionOriginal(instr); } |
6457 | 7069 |
6458 EVALUATE(CLI) { return DecodeInstructionOriginal(instr); } | 7070 EVALUATE(CLI) { |
| 7071 DCHECK_OPCODE(CLI); |
| 7072 // Compare Immediate (Mem - Imm) (8) |
| 7073 DECODE_SI_INSTRUCTION_I_UINT8(b1, d1_val, imm_val) |
| 7074 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1); |
| 7075 intptr_t addr = b1_val + d1_val; |
| 7076 uint8_t mem_val = ReadB(addr); |
| 7077 SetS390ConditionCode<uint8_t>(mem_val, imm_val); |
| 7078 return length; |
| 7079 } |
6459 | 7080 |
6460 EVALUATE(OI) { return DecodeInstructionOriginal(instr); } | 7081 EVALUATE(OI) { return DecodeInstructionOriginal(instr); } |
6461 | 7082 |
6462 EVALUATE(XI) { return DecodeInstructionOriginal(instr); } | 7083 EVALUATE(XI) { return DecodeInstructionOriginal(instr); } |
6463 | 7084 |
6464 EVALUATE(LM) { return DecodeInstructionOriginal(instr); } | 7085 EVALUATE(LM) { |
| 7086 DCHECK_OPCODE(LM); |
| 7087 DECODE_RS_A_INSTRUCTION(r1, r3, rb, d2); |
| 7088 // Store Multiple 32-bits. |
| 7089 int offset = d2; |
| 7090 // Regs roll around if r3 is less than r1. |
| 7091 // Artifically increase r3 by 16 so we can calculate |
| 7092 // the number of regs stored properly. |
| 7093 if (r3 < r1) r3 += 16; |
| 7094 |
| 7095 int32_t rb_val = (rb == 0) ? 0 : get_low_register<int32_t>(rb); |
| 7096 |
| 7097 // Store each register in ascending order. |
| 7098 for (int i = 0; i <= r3 - r1; i++) { |
| 7099 int32_t value = ReadW(rb_val + offset + 4 * i, instr); |
| 7100 set_low_register((r1 + i) % 16, value); |
| 7101 } |
| 7102 return length; |
| 7103 } |
6465 | 7104 |
6466 EVALUATE(MVCLE) { return DecodeInstructionOriginal(instr); } | 7105 EVALUATE(MVCLE) { return DecodeInstructionOriginal(instr); } |
6467 | 7106 |
6468 EVALUATE(CLCLE) { return DecodeInstructionOriginal(instr); } | 7107 EVALUATE(CLCLE) { return DecodeInstructionOriginal(instr); } |
6469 | 7108 |
6470 EVALUATE(MC) { return DecodeInstructionOriginal(instr); } | 7109 EVALUATE(MC) { return DecodeInstructionOriginal(instr); } |
6471 | 7110 |
6472 EVALUATE(CDS) { return DecodeInstructionOriginal(instr); } | 7111 EVALUATE(CDS) { return DecodeInstructionOriginal(instr); } |
6473 | 7112 |
6474 EVALUATE(STCM) { return DecodeInstructionOriginal(instr); } | 7113 EVALUATE(STCM) { return DecodeInstructionOriginal(instr); } |
6475 | 7114 |
6476 EVALUATE(ICM) { return DecodeInstructionOriginal(instr); } | 7115 EVALUATE(ICM) { return DecodeInstructionOriginal(instr); } |
6477 | 7116 |
6478 EVALUATE(BPRP) { return DecodeInstructionOriginal(instr); } | 7117 EVALUATE(BPRP) { return DecodeInstructionOriginal(instr); } |
6479 | 7118 |
6480 EVALUATE(BPP) { return DecodeInstructionOriginal(instr); } | 7119 EVALUATE(BPP) { return DecodeInstructionOriginal(instr); } |
6481 | 7120 |
6482 EVALUATE(TRTR) { return DecodeInstructionOriginal(instr); } | 7121 EVALUATE(TRTR) { return DecodeInstructionOriginal(instr); } |
6483 | 7122 |
6484 EVALUATE(MVN) { return DecodeInstructionOriginal(instr); } | 7123 EVALUATE(MVN) { return DecodeInstructionOriginal(instr); } |
6485 | 7124 |
6486 EVALUATE(MVC) { return DecodeInstructionOriginal(instr); } | 7125 EVALUATE(MVC) { |
| 7126 DCHECK_OPCODE(MVC); |
| 7127 // Move Character |
| 7128 SSInstruction* ssInstr = reinterpret_cast<SSInstruction*>(instr); |
| 7129 int b1 = ssInstr->B1Value(); |
| 7130 intptr_t d1 = ssInstr->D1Value(); |
| 7131 int b2 = ssInstr->B2Value(); |
| 7132 intptr_t d2 = ssInstr->D2Value(); |
| 7133 int length = ssInstr->Length(); |
| 7134 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1); |
| 7135 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
| 7136 intptr_t src_addr = b2_val + d2; |
| 7137 intptr_t dst_addr = b1_val + d1; |
| 7138 // remember that the length is the actual length - 1 |
| 7139 for (int i = 0; i < length + 1; ++i) { |
| 7140 WriteB(dst_addr++, ReadB(src_addr++)); |
| 7141 } |
| 7142 length = 6; |
| 7143 return length; |
| 7144 } |
6487 | 7145 |
6488 EVALUATE(MVZ) { return DecodeInstructionOriginal(instr); } | 7146 EVALUATE(MVZ) { return DecodeInstructionOriginal(instr); } |
6489 | 7147 |
6490 EVALUATE(NC) { return DecodeInstructionOriginal(instr); } | 7148 EVALUATE(NC) { return DecodeInstructionOriginal(instr); } |
6491 | 7149 |
6492 EVALUATE(CLC) { return DecodeInstructionOriginal(instr); } | 7150 EVALUATE(CLC) { return DecodeInstructionOriginal(instr); } |
6493 | 7151 |
6494 EVALUATE(OC) { return DecodeInstructionOriginal(instr); } | 7152 EVALUATE(OC) { return DecodeInstructionOriginal(instr); } |
6495 | 7153 |
6496 EVALUATE(XC) { return DecodeInstructionOriginal(instr); } | 7154 EVALUATE(XC) { return DecodeInstructionOriginal(instr); } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6546 EVALUATE(IIHL) { return DecodeInstructionOriginal(instr); } | 7204 EVALUATE(IIHL) { return DecodeInstructionOriginal(instr); } |
6547 | 7205 |
6548 EVALUATE(IILH) { return DecodeInstructionOriginal(instr); } | 7206 EVALUATE(IILH) { return DecodeInstructionOriginal(instr); } |
6549 | 7207 |
6550 EVALUATE(IILL) { return DecodeInstructionOriginal(instr); } | 7208 EVALUATE(IILL) { return DecodeInstructionOriginal(instr); } |
6551 | 7209 |
6552 EVALUATE(NIHH) { return DecodeInstructionOriginal(instr); } | 7210 EVALUATE(NIHH) { return DecodeInstructionOriginal(instr); } |
6553 | 7211 |
6554 EVALUATE(NIHL) { return DecodeInstructionOriginal(instr); } | 7212 EVALUATE(NIHL) { return DecodeInstructionOriginal(instr); } |
6555 | 7213 |
6556 EVALUATE(NILH) { return DecodeInstructionOriginal(instr); } | 7214 EVALUATE(NILH) { |
| 7215 DCHECK_OPCODE(NILH); |
| 7216 DECODE_RI_A_INSTRUCTION(instr, r1, i); |
| 7217 int32_t r1_val = get_low_register<int32_t>(r1); |
| 7218 // CC is set based on the 16 bits that are AND'd |
| 7219 SetS390BitWiseConditionCode<uint16_t>((r1_val >> 16) & i); |
| 7220 i = (i << 16) | 0x0000FFFF; |
| 7221 set_low_register(r1, r1_val & i); |
| 7222 return length; |
| 7223 } |
6557 | 7224 |
6558 EVALUATE(NILL) { return DecodeInstructionOriginal(instr); } | 7225 EVALUATE(NILL) { |
| 7226 DCHECK_OPCODE(NILL); |
| 7227 DECODE_RI_A_INSTRUCTION(instr, r1, i); |
| 7228 int32_t r1_val = get_low_register<int32_t>(r1); |
| 7229 // CC is set based on the 16 bits that are AND'd |
| 7230 SetS390BitWiseConditionCode<uint16_t>(r1_val & i); |
| 7231 i |= 0xFFFF0000; |
| 7232 set_low_register(r1, r1_val & i); |
| 7233 return length; |
| 7234 } |
6559 | 7235 |
6560 EVALUATE(OIHH) { return DecodeInstructionOriginal(instr); } | 7236 EVALUATE(OIHH) { return DecodeInstructionOriginal(instr); } |
6561 | 7237 |
6562 EVALUATE(OIHL) { return DecodeInstructionOriginal(instr); } | 7238 EVALUATE(OIHL) { return DecodeInstructionOriginal(instr); } |
6563 | 7239 |
6564 EVALUATE(OILH) { return DecodeInstructionOriginal(instr); } | 7240 EVALUATE(OILH) { |
| 7241 DCHECK_OPCODE(OILH); |
| 7242 DECODE_RI_A_INSTRUCTION(instr, r1, i); |
| 7243 int32_t r1_val = get_low_register<int32_t>(r1); |
| 7244 // CC is set based on the 16 bits that are AND'd |
| 7245 SetS390BitWiseConditionCode<uint16_t>((r1_val >> 16) | i); |
| 7246 i = i << 16; |
| 7247 set_low_register(r1, r1_val | i); |
| 7248 return length; |
| 7249 } |
6565 | 7250 |
6566 EVALUATE(OILL) { return DecodeInstructionOriginal(instr); } | 7251 EVALUATE(OILL) { |
| 7252 DCHECK_OPCODE(OILL); |
| 7253 DECODE_RI_A_INSTRUCTION(instr, r1, i); |
| 7254 int32_t r1_val = get_low_register<int32_t>(r1); |
| 7255 // CC is set based on the 16 bits that are AND'd |
| 7256 SetS390BitWiseConditionCode<uint16_t>(r1_val | i); |
| 7257 set_low_register(r1, r1_val | i); |
| 7258 return length; |
| 7259 } |
6567 | 7260 |
6568 EVALUATE(LLIHH) { return DecodeInstructionOriginal(instr); } | 7261 EVALUATE(LLIHH) { return DecodeInstructionOriginal(instr); } |
6569 | 7262 |
6570 EVALUATE(LLIHL) { return DecodeInstructionOriginal(instr); } | 7263 EVALUATE(LLIHL) { return DecodeInstructionOriginal(instr); } |
6571 | 7264 |
6572 EVALUATE(LLILH) { return DecodeInstructionOriginal(instr); } | 7265 EVALUATE(LLILH) { return DecodeInstructionOriginal(instr); } |
6573 | 7266 |
6574 EVALUATE(LLILL) { return DecodeInstructionOriginal(instr); } | 7267 EVALUATE(LLILL) { return DecodeInstructionOriginal(instr); } |
6575 | 7268 |
6576 EVALUATE(TMLH) { return DecodeInstructionOriginal(instr); } | 7269 EVALUATE(TMLH) { return DecodeInstructionOriginal(instr); } |
6577 | 7270 |
6578 EVALUATE(TMLL) { return DecodeInstructionOriginal(instr); } | 7271 EVALUATE(TMLL) { |
| 7272 DCHECK_OPCODE(TMLL); |
| 7273 DECODE_RI_A_INSTRUCTION(instr, r1, i2); |
| 7274 int mask = i2 & 0x0000FFFF; |
| 7275 if (mask == 0) { |
| 7276 condition_reg_ = 0x0; |
| 7277 return length; |
| 7278 } |
| 7279 uint32_t r1_val = get_low_register<uint32_t>(r1); |
| 7280 r1_val = r1_val & 0x0000FFFF; // uses only the last 16bits |
| 7281 |
| 7282 // Test if all selected bits are Zero |
| 7283 bool allSelectedBitsAreZeros = true; |
| 7284 for (int i = 0; i < 15; i++) { |
| 7285 if (mask & (1 << i)) { |
| 7286 if (r1_val & (1 << i)) { |
| 7287 allSelectedBitsAreZeros = false; |
| 7288 break; |
| 7289 } |
| 7290 } |
| 7291 } |
| 7292 if (allSelectedBitsAreZeros) { |
| 7293 condition_reg_ = 0x8; |
| 7294 return length; // Done! |
| 7295 } |
| 7296 |
| 7297 // Test if all selected bits are one |
| 7298 bool allSelectedBitsAreOnes = true; |
| 7299 for (int i = 0; i < 15; i++) { |
| 7300 if (mask & (1 << i)) { |
| 7301 if (!(r1_val & (1 << i))) { |
| 7302 allSelectedBitsAreOnes = false; |
| 7303 break; |
| 7304 } |
| 7305 } |
| 7306 } |
| 7307 if (allSelectedBitsAreOnes) { |
| 7308 condition_reg_ = 0x1; |
| 7309 return length; // Done! |
| 7310 } |
| 7311 |
| 7312 // Now we know selected bits mixed zeros and ones |
| 7313 // Test if the leftmost bit is zero or one |
| 7314 for (int i = 14; i >= 0; i--) { |
| 7315 if (mask & (1 << i)) { |
| 7316 if (r1_val & (1 << i)) { |
| 7317 // leftmost bit is one |
| 7318 condition_reg_ = 0x2; |
| 7319 } else { |
| 7320 // leftmost bit is zero |
| 7321 condition_reg_ = 0x4; |
| 7322 } |
| 7323 return length; // Done! |
| 7324 } |
| 7325 } |
| 7326 return length; |
| 7327 } |
6579 | 7328 |
6580 EVALUATE(TMHH) { return DecodeInstructionOriginal(instr); } | 7329 EVALUATE(TMHH) { return DecodeInstructionOriginal(instr); } |
6581 | 7330 |
6582 EVALUATE(TMHL) { return DecodeInstructionOriginal(instr); } | 7331 EVALUATE(TMHL) { return DecodeInstructionOriginal(instr); } |
6583 | 7332 |
6584 EVALUATE(BRAS) { return DecodeInstructionOriginal(instr); } | 7333 EVALUATE(BRAS) { |
6585 | 7334 DCHECK_OPCODE(BRAS); |
6586 EVALUATE(BRCT) { return DecodeInstructionOriginal(instr); } | 7335 // Branch Relative and Save |
6587 | 7336 DECODE_RI_B_INSTRUCTION(instr, r1, d2) |
6588 EVALUATE(BRCTG) { return DecodeInstructionOriginal(instr); } | 7337 intptr_t pc = get_pc(); |
6589 | 7338 // Set PC of next instruction to register |
6590 EVALUATE(LHI) { return DecodeInstructionOriginal(instr); } | 7339 set_register(r1, pc + sizeof(FourByteInstr)); |
6591 | 7340 // Update PC to branch target |
6592 EVALUATE(LGHI) { return DecodeInstructionOriginal(instr); } | 7341 set_pc(pc + d2 * 2); |
6593 | 7342 return length; |
6594 EVALUATE(MHI) { return DecodeInstructionOriginal(instr); } | 7343 } |
6595 | 7344 |
6596 EVALUATE(MGHI) { return DecodeInstructionOriginal(instr); } | 7345 EVALUATE(BRCT) { |
6597 | 7346 DCHECK_OPCODE(BRCT); |
6598 EVALUATE(CHI) { return DecodeInstructionOriginal(instr); } | 7347 // Branch On Count (32/64). |
6599 | 7348 DECODE_RI_A_INSTRUCTION(instr, r1, i2); |
6600 EVALUATE(CGHI) { return DecodeInstructionOriginal(instr); } | 7349 int64_t value = get_low_register<int32_t>(r1); |
6601 | 7350 set_low_register(r1, --value); |
6602 EVALUATE(LARL) { return DecodeInstructionOriginal(instr); } | 7351 // Branch if value != 0 |
| 7352 if (value != 0) { |
| 7353 intptr_t offset = i2 * 2; |
| 7354 set_pc(get_pc() + offset); |
| 7355 } |
| 7356 return length; |
| 7357 } |
| 7358 |
| 7359 EVALUATE(BRCTG) { |
| 7360 DCHECK_OPCODE(BRCTG); |
| 7361 // Branch On Count (32/64). |
| 7362 DECODE_RI_A_INSTRUCTION(instr, r1, i2); |
| 7363 int64_t value = get_register(r1); |
| 7364 set_register(r1, --value); |
| 7365 // Branch if value != 0 |
| 7366 if (value != 0) { |
| 7367 intptr_t offset = i2 * 2; |
| 7368 set_pc(get_pc() + offset); |
| 7369 } |
| 7370 return length; |
| 7371 } |
| 7372 |
| 7373 EVALUATE(LHI) { |
| 7374 DCHECK_OPCODE(LHI); |
| 7375 DECODE_RI_A_INSTRUCTION(instr, r1, i); |
| 7376 set_low_register(r1, i); |
| 7377 return length; |
| 7378 } |
| 7379 |
| 7380 EVALUATE(LGHI) { |
| 7381 DCHECK_OPCODE(LGHI); |
| 7382 DECODE_RI_A_INSTRUCTION(instr, r1, i2); |
| 7383 int64_t i = static_cast<int64_t>(i2); |
| 7384 set_register(r1, i); |
| 7385 return length; |
| 7386 } |
| 7387 |
| 7388 EVALUATE(MHI) { |
| 7389 DCHECK_OPCODE(MHI); |
| 7390 DECODE_RI_A_INSTRUCTION(instr, r1, i); |
| 7391 int32_t r1_val = get_low_register<int32_t>(r1); |
| 7392 bool isOF = false; |
| 7393 isOF = CheckOverflowForMul(r1_val, i); |
| 7394 r1_val *= i; |
| 7395 set_low_register(r1, r1_val); |
| 7396 SetS390ConditionCode<int32_t>(r1_val, 0); |
| 7397 SetS390OverflowCode(isOF); |
| 7398 return length; |
| 7399 } |
| 7400 |
| 7401 EVALUATE(MGHI) { |
| 7402 DCHECK_OPCODE(MGHI); |
| 7403 DECODE_RI_A_INSTRUCTION(instr, r1, i2); |
| 7404 int64_t i = static_cast<int64_t>(i2); |
| 7405 int64_t r1_val = get_register(r1); |
| 7406 bool isOF = false; |
| 7407 isOF = CheckOverflowForMul(r1_val, i); |
| 7408 r1_val *= i; |
| 7409 set_register(r1, r1_val); |
| 7410 SetS390ConditionCode<int32_t>(r1_val, 0); |
| 7411 SetS390OverflowCode(isOF); |
| 7412 return length; |
| 7413 } |
| 7414 |
| 7415 EVALUATE(CHI) { |
| 7416 DCHECK_OPCODE(CHI); |
| 7417 DECODE_RI_A_INSTRUCTION(instr, r1, i); |
| 7418 int32_t r1_val = get_low_register<int32_t>(r1); |
| 7419 SetS390ConditionCode<int32_t>(r1_val, i); |
| 7420 return length; |
| 7421 } |
| 7422 |
| 7423 EVALUATE(CGHI) { |
| 7424 DCHECK_OPCODE(CGHI); |
| 7425 DECODE_RI_A_INSTRUCTION(instr, r1, i2); |
| 7426 int64_t i = static_cast<int64_t>(i2); |
| 7427 int64_t r1_val = get_register(r1); |
| 7428 SetS390ConditionCode<int64_t>(r1_val, i); |
| 7429 return length; |
| 7430 } |
| 7431 |
| 7432 EVALUATE(LARL) { |
| 7433 DCHECK_OPCODE(LARL); |
| 7434 DECODE_RIL_B_INSTRUCTION(r1, i2); |
| 7435 intptr_t offset = i2 * 2; |
| 7436 set_register(r1, get_pc() + offset); |
| 7437 return length; |
| 7438 } |
6603 | 7439 |
6604 EVALUATE(LGFI) { return DecodeInstructionOriginal(instr); } | 7440 EVALUATE(LGFI) { return DecodeInstructionOriginal(instr); } |
6605 | 7441 |
6606 EVALUATE(BRASL) { return DecodeInstructionOriginal(instr); } | 7442 EVALUATE(BRASL) { |
6607 | 7443 DCHECK_OPCODE(BRASL); |
6608 EVALUATE(XIHF) { return DecodeInstructionOriginal(instr); } | 7444 // Branch and Save Relative Long |
6609 | 7445 DECODE_RIL_B_INSTRUCTION(r1, i2); |
6610 EVALUATE(XILF) { return DecodeInstructionOriginal(instr); } | 7446 intptr_t d2 = i2; |
6611 | 7447 intptr_t pc = get_pc(); |
6612 EVALUATE(NIHF) { return DecodeInstructionOriginal(instr); } | 7448 set_register(r1, pc + 6); // save next instruction to register |
6613 | 7449 set_pc(pc + d2 * 2); // update register |
6614 EVALUATE(NILF) { return DecodeInstructionOriginal(instr); } | 7450 return length; |
6615 | 7451 } |
6616 EVALUATE(OIHF) { return DecodeInstructionOriginal(instr); } | 7452 |
6617 | 7453 EVALUATE(XIHF) { |
6618 EVALUATE(OILF) { return DecodeInstructionOriginal(instr); } | 7454 DCHECK_OPCODE(XIHF); |
6619 | 7455 DECODE_RIL_A_INSTRUCTION(r1, imm); |
6620 EVALUATE(LLIHF) { return DecodeInstructionOriginal(instr); } | 7456 uint32_t alu_out = 0; |
6621 | 7457 alu_out = get_high_register<uint32_t>(r1); |
6622 EVALUATE(LLILF) { return DecodeInstructionOriginal(instr); } | 7458 alu_out = alu_out ^ imm; |
6623 | 7459 set_high_register(r1, alu_out); |
6624 EVALUATE(MSGFI) { return DecodeInstructionOriginal(instr); } | 7460 SetS390BitWiseConditionCode<uint32_t>(alu_out); |
6625 | 7461 return length; |
6626 EVALUATE(MSFI) { return DecodeInstructionOriginal(instr); } | 7462 } |
6627 | 7463 |
6628 EVALUATE(SLGFI) { return DecodeInstructionOriginal(instr); } | 7464 EVALUATE(XILF) { |
6629 | 7465 DCHECK_OPCODE(XILF); |
6630 EVALUATE(SLFI) { return DecodeInstructionOriginal(instr); } | 7466 DECODE_RIL_A_INSTRUCTION(r1, imm); |
6631 | 7467 uint32_t alu_out = 0; |
6632 EVALUATE(AGFI) { return DecodeInstructionOriginal(instr); } | 7468 alu_out = get_low_register<uint32_t>(r1); |
6633 | 7469 alu_out = alu_out ^ imm; |
6634 EVALUATE(AFI) { return DecodeInstructionOriginal(instr); } | 7470 set_low_register(r1, alu_out); |
6635 | 7471 SetS390BitWiseConditionCode<uint32_t>(alu_out); |
6636 EVALUATE(ALGFI) { return DecodeInstructionOriginal(instr); } | 7472 return length; |
6637 | 7473 } |
6638 EVALUATE(ALFI) { return DecodeInstructionOriginal(instr); } | 7474 |
6639 | 7475 EVALUATE(NIHF) { |
6640 EVALUATE(CGFI) { return DecodeInstructionOriginal(instr); } | 7476 DCHECK_OPCODE(NIHF); |
6641 | 7477 // Bitwise Op on upper 32-bits |
6642 EVALUATE(CFI) { return DecodeInstructionOriginal(instr); } | 7478 DECODE_RIL_A_INSTRUCTION(r1, imm); |
6643 | 7479 uint32_t alu_out = get_high_register<uint32_t>(r1); |
6644 EVALUATE(CLGFI) { return DecodeInstructionOriginal(instr); } | 7480 alu_out &= imm; |
6645 | 7481 SetS390BitWiseConditionCode<uint32_t>(alu_out); |
6646 EVALUATE(CLFI) { return DecodeInstructionOriginal(instr); } | 7482 set_high_register(r1, alu_out); |
| 7483 return length; |
| 7484 } |
| 7485 |
| 7486 EVALUATE(NILF) { |
| 7487 DCHECK_OPCODE(NILF); |
| 7488 // Bitwise Op on lower 32-bits |
| 7489 DECODE_RIL_A_INSTRUCTION(r1, imm); |
| 7490 uint32_t alu_out = get_low_register<uint32_t>(r1); |
| 7491 alu_out &= imm; |
| 7492 SetS390BitWiseConditionCode<uint32_t>(alu_out); |
| 7493 set_low_register(r1, alu_out); |
| 7494 return length; |
| 7495 } |
| 7496 |
| 7497 EVALUATE(OIHF) { |
| 7498 DCHECK_OPCODE(OIHF); |
| 7499 // Bitwise Op on upper 32-bits |
| 7500 DECODE_RIL_B_INSTRUCTION(r1, imm); |
| 7501 uint32_t alu_out = get_high_register<uint32_t>(r1); |
| 7502 alu_out |= imm; |
| 7503 SetS390BitWiseConditionCode<uint32_t>(alu_out); |
| 7504 set_high_register(r1, alu_out); |
| 7505 return length; |
| 7506 } |
| 7507 |
| 7508 EVALUATE(OILF) { |
| 7509 DCHECK_OPCODE(OILF); |
| 7510 // Bitwise Op on lower 32-bits |
| 7511 DECODE_RIL_B_INSTRUCTION(r1, imm); |
| 7512 uint32_t alu_out = get_low_register<uint32_t>(r1); |
| 7513 alu_out |= imm; |
| 7514 SetS390BitWiseConditionCode<uint32_t>(alu_out); |
| 7515 set_low_register(r1, alu_out); |
| 7516 return length; |
| 7517 } |
| 7518 |
| 7519 EVALUATE(LLIHF) { |
| 7520 DCHECK_OPCODE(LLIHF); |
| 7521 // Load Logical Immediate into high word |
| 7522 DECODE_RIL_A_INSTRUCTION(r1, i2); |
| 7523 uint64_t imm = static_cast<uint64_t>(i2); |
| 7524 set_register(r1, imm << 32); |
| 7525 return length; |
| 7526 } |
| 7527 |
| 7528 EVALUATE(LLILF) { |
| 7529 DCHECK_OPCODE(LLILF); |
| 7530 // Load Logical into lower 32-bits (zero extend upper 32-bits) |
| 7531 DECODE_RIL_A_INSTRUCTION(r1, i2); |
| 7532 uint64_t imm = static_cast<uint64_t>(i2); |
| 7533 set_register(r1, imm); |
| 7534 return length; |
| 7535 } |
| 7536 |
| 7537 EVALUATE(MSGFI) { |
| 7538 DCHECK_OPCODE(MSGFI); |
| 7539 DECODE_RIL_B_INSTRUCTION(r1, i2); |
| 7540 int64_t alu_out = get_register(r1); |
| 7541 alu_out = alu_out * i2; |
| 7542 set_register(r1, alu_out); |
| 7543 return length; |
| 7544 } |
| 7545 |
| 7546 EVALUATE(MSFI) { |
| 7547 DCHECK_OPCODE(MSFI); |
| 7548 DECODE_RIL_B_INSTRUCTION(r1, i2); |
| 7549 int32_t alu_out = get_low_register<int32_t>(r1); |
| 7550 alu_out = alu_out * i2; |
| 7551 set_low_register(r1, alu_out); |
| 7552 return length; |
| 7553 } |
| 7554 |
| 7555 EVALUATE(SLGFI) { |
| 7556 DCHECK_OPCODE(SLGFI); |
| 7557 #ifndef V8_TARGET_ARCH_S390X |
| 7558 // should only be called on 64bit |
| 7559 DCHECK(false); |
| 7560 #endif |
| 7561 DECODE_RIL_A_INSTRUCTION(r1, i2); |
| 7562 uint64_t r1_val = (uint64_t)(get_register(r1)); |
| 7563 uint64_t alu_out; |
| 7564 alu_out = r1_val - i2; |
| 7565 set_register(r1, (intptr_t)alu_out); |
| 7566 SetS390ConditionCode<uint64_t>(alu_out, 0); |
| 7567 return length; |
| 7568 } |
| 7569 |
| 7570 EVALUATE(SLFI) { |
| 7571 DCHECK_OPCODE(SLFI); |
| 7572 DECODE_RIL_A_INSTRUCTION(r1, imm); |
| 7573 uint32_t alu_out = get_low_register<uint32_t>(r1); |
| 7574 alu_out -= imm; |
| 7575 SetS390ConditionCode<uint32_t>(alu_out, 0); |
| 7576 set_low_register(r1, alu_out); |
| 7577 return length; |
| 7578 } |
| 7579 |
| 7580 EVALUATE(AGFI) { |
| 7581 DCHECK_OPCODE(AGFI); |
| 7582 // Clobbering Add Word Immediate |
| 7583 DECODE_RIL_B_INSTRUCTION(r1, i2_val); |
| 7584 bool isOF = false; |
| 7585 // 64-bit Add (Register + 32-bit Imm) |
| 7586 int64_t r1_val = get_register(r1); |
| 7587 int64_t i2 = static_cast<int64_t>(i2_val); |
| 7588 isOF = CheckOverflowForIntAdd(r1_val, i2, int64_t); |
| 7589 int64_t alu_out = r1_val + i2; |
| 7590 set_register(r1, alu_out); |
| 7591 SetS390ConditionCode<int64_t>(alu_out, 0); |
| 7592 SetS390OverflowCode(isOF); |
| 7593 return length; |
| 7594 } |
| 7595 |
| 7596 EVALUATE(AFI) { |
| 7597 DCHECK_OPCODE(AFI); |
| 7598 // Clobbering Add Word Immediate |
| 7599 DECODE_RIL_B_INSTRUCTION(r1, i2); |
| 7600 bool isOF = false; |
| 7601 // 32-bit Add (Register + 32-bit Immediate) |
| 7602 int32_t r1_val = get_low_register<int32_t>(r1); |
| 7603 isOF = CheckOverflowForIntAdd(r1_val, i2, int32_t); |
| 7604 int32_t alu_out = r1_val + i2; |
| 7605 set_low_register(r1, alu_out); |
| 7606 SetS390ConditionCode<int32_t>(alu_out, 0); |
| 7607 SetS390OverflowCode(isOF); |
| 7608 return length; |
| 7609 } |
| 7610 |
| 7611 EVALUATE(ALGFI) { |
| 7612 DCHECK_OPCODE(ALGFI); |
| 7613 #ifndef V8_TARGET_ARCH_S390X |
| 7614 // should only be called on 64bit |
| 7615 DCHECK(false); |
| 7616 #endif |
| 7617 DECODE_RIL_A_INSTRUCTION(r1, i2); |
| 7618 uint64_t r1_val = (uint64_t)(get_register(r1)); |
| 7619 uint64_t alu_out; |
| 7620 alu_out = r1_val + i2; |
| 7621 set_register(r1, (intptr_t)alu_out); |
| 7622 SetS390ConditionCode<uint64_t>(alu_out, 0); |
| 7623 |
| 7624 return length; |
| 7625 } |
| 7626 |
| 7627 EVALUATE(ALFI) { |
| 7628 DCHECK_OPCODE(ALFI); |
| 7629 DECODE_RIL_A_INSTRUCTION(r1, imm); |
| 7630 uint32_t alu_out = get_low_register<uint32_t>(r1); |
| 7631 alu_out += imm; |
| 7632 SetS390ConditionCode<uint32_t>(alu_out, 0); |
| 7633 set_low_register(r1, alu_out); |
| 7634 return length; |
| 7635 } |
| 7636 |
| 7637 EVALUATE(CGFI) { |
| 7638 DCHECK_OPCODE(CGFI); |
| 7639 // Compare with Immediate (64) |
| 7640 DECODE_RIL_B_INSTRUCTION(r1, i2); |
| 7641 int64_t imm = static_cast<int64_t>(i2); |
| 7642 SetS390ConditionCode<int64_t>(get_register(r1), imm); |
| 7643 return length; |
| 7644 } |
| 7645 |
| 7646 EVALUATE(CFI) { |
| 7647 DCHECK_OPCODE(CFI); |
| 7648 // Compare with Immediate (32) |
| 7649 DECODE_RIL_B_INSTRUCTION(r1, imm); |
| 7650 SetS390ConditionCode<int32_t>(get_low_register<int32_t>(r1), imm); |
| 7651 return length; |
| 7652 } |
| 7653 |
| 7654 EVALUATE(CLGFI) { |
| 7655 DCHECK_OPCODE(CLGFI); |
| 7656 // Compare Logical with Immediate (64) |
| 7657 DECODE_RIL_A_INSTRUCTION(r1, i2); |
| 7658 uint64_t imm = static_cast<uint64_t>(i2); |
| 7659 SetS390ConditionCode<uint64_t>(get_register(r1), imm); |
| 7660 return length; |
| 7661 } |
| 7662 |
| 7663 EVALUATE(CLFI) { |
| 7664 DCHECK_OPCODE(CLFI); |
| 7665 // Compare Logical with Immediate (32) |
| 7666 DECODE_RIL_A_INSTRUCTION(r1, imm); |
| 7667 SetS390ConditionCode<uint32_t>(get_low_register<uint32_t>(r1), imm); |
| 7668 return length; |
| 7669 } |
6647 | 7670 |
6648 EVALUATE(LLHRL) { return DecodeInstructionOriginal(instr); } | 7671 EVALUATE(LLHRL) { return DecodeInstructionOriginal(instr); } |
6649 | 7672 |
6650 EVALUATE(LGHRL) { return DecodeInstructionOriginal(instr); } | 7673 EVALUATE(LGHRL) { return DecodeInstructionOriginal(instr); } |
6651 | 7674 |
6652 EVALUATE(LHRL) { return DecodeInstructionOriginal(instr); } | 7675 EVALUATE(LHRL) { return DecodeInstructionOriginal(instr); } |
6653 | 7676 |
6654 EVALUATE(LLGHRL) { return DecodeInstructionOriginal(instr); } | 7677 EVALUATE(LLGHRL) { return DecodeInstructionOriginal(instr); } |
6655 | 7678 |
6656 EVALUATE(STHRL) { return DecodeInstructionOriginal(instr); } | 7679 EVALUATE(STHRL) { return DecodeInstructionOriginal(instr); } |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6726 EVALUATE(RCHP) { return DecodeInstructionOriginal(instr); } | 7749 EVALUATE(RCHP) { return DecodeInstructionOriginal(instr); } |
6727 | 7750 |
6728 EVALUATE(SCHM) { return DecodeInstructionOriginal(instr); } | 7751 EVALUATE(SCHM) { return DecodeInstructionOriginal(instr); } |
6729 | 7752 |
6730 EVALUATE(CKSM) { return DecodeInstructionOriginal(instr); } | 7753 EVALUATE(CKSM) { return DecodeInstructionOriginal(instr); } |
6731 | 7754 |
6732 EVALUATE(SAR) { return DecodeInstructionOriginal(instr); } | 7755 EVALUATE(SAR) { return DecodeInstructionOriginal(instr); } |
6733 | 7756 |
6734 EVALUATE(EAR) { return DecodeInstructionOriginal(instr); } | 7757 EVALUATE(EAR) { return DecodeInstructionOriginal(instr); } |
6735 | 7758 |
6736 EVALUATE(MSR) { return DecodeInstructionOriginal(instr); } | 7759 EVALUATE(MSR) { |
| 7760 DCHECK_OPCODE(MSR); |
| 7761 DECODE_RRE_INSTRUCTION(r1, r2); |
| 7762 int32_t r1_val = get_low_register<int32_t>(r1); |
| 7763 int32_t r2_val = get_low_register<int32_t>(r2); |
| 7764 set_low_register(r1, r1_val * r2_val); |
| 7765 return length; |
| 7766 } |
6737 | 7767 |
6738 EVALUATE(MVST) { return DecodeInstructionOriginal(instr); } | 7768 EVALUATE(MVST) { return DecodeInstructionOriginal(instr); } |
6739 | 7769 |
6740 EVALUATE(CUSE) { return DecodeInstructionOriginal(instr); } | 7770 EVALUATE(CUSE) { return DecodeInstructionOriginal(instr); } |
6741 | 7771 |
6742 EVALUATE(SRST) { return DecodeInstructionOriginal(instr); } | 7772 EVALUATE(SRST) { return DecodeInstructionOriginal(instr); } |
6743 | 7773 |
6744 EVALUATE(XSCH) { return DecodeInstructionOriginal(instr); } | 7774 EVALUATE(XSCH) { return DecodeInstructionOriginal(instr); } |
6745 | 7775 |
6746 EVALUATE(STCKE) { return DecodeInstructionOriginal(instr); } | 7776 EVALUATE(STCKE) { return DecodeInstructionOriginal(instr); } |
(...skipping 25 matching lines...) Expand all Loading... |
6772 EVALUATE(ETND) { return DecodeInstructionOriginal(instr); } | 7802 EVALUATE(ETND) { return DecodeInstructionOriginal(instr); } |
6773 | 7803 |
6774 EVALUATE(TEND) { return DecodeInstructionOriginal(instr); } | 7804 EVALUATE(TEND) { return DecodeInstructionOriginal(instr); } |
6775 | 7805 |
6776 EVALUATE(NIAI) { return DecodeInstructionOriginal(instr); } | 7806 EVALUATE(NIAI) { return DecodeInstructionOriginal(instr); } |
6777 | 7807 |
6778 EVALUATE(TABORT) { return DecodeInstructionOriginal(instr); } | 7808 EVALUATE(TABORT) { return DecodeInstructionOriginal(instr); } |
6779 | 7809 |
6780 EVALUATE(TRAP4) { return DecodeInstructionOriginal(instr); } | 7810 EVALUATE(TRAP4) { return DecodeInstructionOriginal(instr); } |
6781 | 7811 |
6782 EVALUATE(LPEBR) { return DecodeInstructionOriginal(instr); } | 7812 EVALUATE(LPEBR) { |
| 7813 DCHECK_OPCODE(LPEBR); |
| 7814 DECODE_RRE_INSTRUCTION(r1, r2); |
| 7815 float fr1_val = get_float32_from_d_register(r1); |
| 7816 float fr2_val = get_float32_from_d_register(r2); |
| 7817 fr1_val = std::fabs(fr2_val); |
| 7818 set_d_register_from_float32(r1, fr1_val); |
| 7819 if (fr2_val != fr2_val) { // input is NaN |
| 7820 condition_reg_ = CC_OF; |
| 7821 } else if (fr2_val == 0) { |
| 7822 condition_reg_ = CC_EQ; |
| 7823 } else { |
| 7824 condition_reg_ = CC_GT; |
| 7825 } |
| 7826 |
| 7827 return length; |
| 7828 } |
6783 | 7829 |
6784 EVALUATE(LNEBR) { return DecodeInstructionOriginal(instr); } | 7830 EVALUATE(LNEBR) { return DecodeInstructionOriginal(instr); } |
6785 | 7831 |
6786 EVALUATE(LTEBR) { return DecodeInstructionOriginal(instr); } | 7832 EVALUATE(LTEBR) { |
| 7833 DCHECK_OPCODE(LTEBR); |
| 7834 DECODE_RRE_INSTRUCTION(r1, r2); |
| 7835 int64_t r2_val = get_d_register(r2); |
| 7836 float fr2_val = get_float32_from_d_register(r2); |
| 7837 SetS390ConditionCode<float>(fr2_val, 0.0); |
| 7838 set_d_register(r1, r2_val); |
| 7839 return length; |
| 7840 } |
6787 | 7841 |
6788 EVALUATE(LCEBR) { return DecodeInstructionOriginal(instr); } | 7842 EVALUATE(LCEBR) { return DecodeInstructionOriginal(instr); } |
6789 | 7843 |
6790 EVALUATE(LDEBR) { return DecodeInstructionOriginal(instr); } | 7844 EVALUATE(LDEBR) { |
| 7845 DCHECK_OPCODE(LDEBR); |
| 7846 DECODE_RRE_INSTRUCTION(r1, r2); |
| 7847 float fp_val = get_float32_from_d_register(r2); |
| 7848 double db_val = static_cast<double>(fp_val); |
| 7849 set_d_register_from_double(r1, db_val); |
| 7850 return length; |
| 7851 } |
6791 | 7852 |
6792 EVALUATE(LXDBR) { return DecodeInstructionOriginal(instr); } | 7853 EVALUATE(LXDBR) { return DecodeInstructionOriginal(instr); } |
6793 | 7854 |
6794 EVALUATE(LXEBR) { return DecodeInstructionOriginal(instr); } | 7855 EVALUATE(LXEBR) { return DecodeInstructionOriginal(instr); } |
6795 | 7856 |
6796 EVALUATE(MXDBR) { return DecodeInstructionOriginal(instr); } | 7857 EVALUATE(MXDBR) { return DecodeInstructionOriginal(instr); } |
6797 | 7858 |
6798 EVALUATE(KEBR) { return DecodeInstructionOriginal(instr); } | 7859 EVALUATE(KEBR) { return DecodeInstructionOriginal(instr); } |
6799 | 7860 |
6800 EVALUATE(CEBR) { return DecodeInstructionOriginal(instr); } | 7861 EVALUATE(CEBR) { |
| 7862 DCHECK_OPCODE(CEBR); |
| 7863 DECODE_RRE_INSTRUCTION(r1, r2); |
| 7864 float fr1_val = get_float32_from_d_register(r1); |
| 7865 float fr2_val = get_float32_from_d_register(r2); |
| 7866 if (isNaN(fr1_val) || isNaN(fr2_val)) { |
| 7867 condition_reg_ = CC_OF; |
| 7868 } else { |
| 7869 SetS390ConditionCode<float>(fr1_val, fr2_val); |
| 7870 } |
6801 | 7871 |
6802 EVALUATE(AEBR) { return DecodeInstructionOriginal(instr); } | 7872 return length; |
| 7873 } |
6803 | 7874 |
6804 EVALUATE(SEBR) { return DecodeInstructionOriginal(instr); } | 7875 EVALUATE(AEBR) { |
| 7876 DCHECK_OPCODE(AEBR); |
| 7877 DECODE_RRE_INSTRUCTION(r1, r2); |
| 7878 float fr1_val = get_float32_from_d_register(r1); |
| 7879 float fr2_val = get_float32_from_d_register(r2); |
| 7880 fr1_val += fr2_val; |
| 7881 set_d_register_from_float32(r1, fr1_val); |
| 7882 SetS390ConditionCode<float>(fr1_val, 0); |
| 7883 |
| 7884 return length; |
| 7885 } |
| 7886 |
| 7887 EVALUATE(SEBR) { |
| 7888 DCHECK_OPCODE(SEBR); |
| 7889 DECODE_RRE_INSTRUCTION(r1, r2); |
| 7890 float fr1_val = get_float32_from_d_register(r1); |
| 7891 float fr2_val = get_float32_from_d_register(r2); |
| 7892 fr1_val -= fr2_val; |
| 7893 set_d_register_from_float32(r1, fr1_val); |
| 7894 SetS390ConditionCode<float>(fr1_val, 0); |
| 7895 |
| 7896 return length; |
| 7897 } |
6805 | 7898 |
6806 EVALUATE(MDEBR) { return DecodeInstructionOriginal(instr); } | 7899 EVALUATE(MDEBR) { return DecodeInstructionOriginal(instr); } |
6807 | 7900 |
6808 EVALUATE(DEBR) { return DecodeInstructionOriginal(instr); } | 7901 EVALUATE(DEBR) { |
| 7902 DCHECK_OPCODE(DEBR); |
| 7903 DECODE_RRE_INSTRUCTION(r1, r2); |
| 7904 float fr1_val = get_float32_from_d_register(r1); |
| 7905 float fr2_val = get_float32_from_d_register(r2); |
| 7906 fr1_val /= fr2_val; |
| 7907 set_d_register_from_float32(r1, fr1_val); |
| 7908 SetS390ConditionCode<float>(fr1_val, 0); |
| 7909 |
| 7910 return length; |
| 7911 } |
6809 | 7912 |
6810 EVALUATE(MAEBR) { return DecodeInstructionOriginal(instr); } | 7913 EVALUATE(MAEBR) { return DecodeInstructionOriginal(instr); } |
6811 | 7914 |
6812 EVALUATE(MSEBR) { return DecodeInstructionOriginal(instr); } | 7915 EVALUATE(MSEBR) { return DecodeInstructionOriginal(instr); } |
6813 | 7916 |
6814 EVALUATE(LPDBR) { return DecodeInstructionOriginal(instr); } | 7917 EVALUATE(LPDBR) { |
| 7918 DCHECK_OPCODE(LPDBR); |
| 7919 DECODE_RRE_INSTRUCTION(r1, r2); |
| 7920 double r1_val = get_double_from_d_register(r1); |
| 7921 double r2_val = get_double_from_d_register(r2); |
| 7922 r1_val = std::fabs(r2_val); |
| 7923 set_d_register_from_double(r1, r1_val); |
| 7924 if (r2_val != r2_val) { // input is NaN |
| 7925 condition_reg_ = CC_OF; |
| 7926 } else if (r2_val == 0) { |
| 7927 condition_reg_ = CC_EQ; |
| 7928 } else { |
| 7929 condition_reg_ = CC_GT; |
| 7930 } |
| 7931 return length; |
| 7932 } |
6815 | 7933 |
6816 EVALUATE(LNDBR) { return DecodeInstructionOriginal(instr); } | 7934 EVALUATE(LNDBR) { return DecodeInstructionOriginal(instr); } |
6817 | 7935 |
6818 EVALUATE(LTDBR) { return DecodeInstructionOriginal(instr); } | 7936 EVALUATE(LTDBR) { |
| 7937 DCHECK_OPCODE(LTDBR); |
| 7938 DECODE_RRE_INSTRUCTION(r1, r2); |
| 7939 int64_t r2_val = get_d_register(r2); |
| 7940 SetS390ConditionCode<double>(bit_cast<double, int64_t>(r2_val), 0.0); |
| 7941 set_d_register(r1, r2_val); |
| 7942 return length; |
| 7943 } |
6819 | 7944 |
6820 EVALUATE(LCDBR) { return DecodeInstructionOriginal(instr); } | 7945 EVALUATE(LCDBR) { |
| 7946 DCHECK_OPCODE(LCDBR); |
| 7947 DECODE_RRE_INSTRUCTION(r1, r2); |
| 7948 double r1_val = get_double_from_d_register(r1); |
| 7949 double r2_val = get_double_from_d_register(r2); |
| 7950 r1_val = -r2_val; |
| 7951 set_d_register_from_double(r1, r1_val); |
| 7952 if (r2_val != r2_val) { // input is NaN |
| 7953 condition_reg_ = CC_OF; |
| 7954 } else if (r2_val == 0) { |
| 7955 condition_reg_ = CC_EQ; |
| 7956 } else if (r2_val < 0) { |
| 7957 condition_reg_ = CC_LT; |
| 7958 } else if (r2_val > 0) { |
| 7959 condition_reg_ = CC_GT; |
| 7960 } |
| 7961 return length; |
| 7962 } |
6821 | 7963 |
6822 EVALUATE(SQEBR) { return DecodeInstructionOriginal(instr); } | 7964 EVALUATE(SQEBR) { return DecodeInstructionOriginal(instr); } |
6823 | 7965 |
6824 EVALUATE(SQDBR) { return DecodeInstructionOriginal(instr); } | 7966 EVALUATE(SQDBR) { return DecodeInstructionOriginal(instr); } |
6825 | 7967 |
6826 EVALUATE(SQXBR) { return DecodeInstructionOriginal(instr); } | 7968 EVALUATE(SQXBR) { return DecodeInstructionOriginal(instr); } |
6827 | 7969 |
6828 EVALUATE(MEEBR) { return DecodeInstructionOriginal(instr); } | 7970 EVALUATE(MEEBR) { return DecodeInstructionOriginal(instr); } |
6829 | 7971 |
6830 EVALUATE(KDBR) { return DecodeInstructionOriginal(instr); } | 7972 EVALUATE(KDBR) { return DecodeInstructionOriginal(instr); } |
(...skipping 858 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7689 | 8831 |
7690 EVALUATE(CXZT) { return DecodeInstructionOriginal(instr); } | 8832 EVALUATE(CXZT) { return DecodeInstructionOriginal(instr); } |
7691 | 8833 |
7692 #undef EVALUATE | 8834 #undef EVALUATE |
7693 | 8835 |
7694 } // namespace internal | 8836 } // namespace internal |
7695 } // namespace v8 | 8837 } // namespace v8 |
7696 | 8838 |
7697 #endif // USE_SIMULATOR | 8839 #endif // USE_SIMULATOR |
7698 #endif // V8_TARGET_ARCH_S390 | 8840 #endif // V8_TARGET_ARCH_S390 |
OLD | NEW |