Chromium Code Reviews| 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 |
| 6811 // M and D are unimplemented. | |
| 6404 EVALUATE(M) { return DecodeInstructionOriginal(instr); } | 6812 EVALUATE(M) { return DecodeInstructionOriginal(instr); } |
| 6405 | 6813 |
| 6406 EVALUATE(D) { return DecodeInstructionOriginal(instr); } | 6814 EVALUATE(D) { return DecodeInstructionOriginal(instr); } |
| 6407 | 6815 |
| 6408 EVALUATE(AL) { return DecodeInstructionOriginal(instr); } | 6816 EVALUATE(AL) { return DecodeInstructionOriginal(instr); } |
| 6409 | 6817 |
| 6410 EVALUATE(SL) { return DecodeInstructionOriginal(instr); } | 6818 EVALUATE(SL) { return DecodeInstructionOriginal(instr); } |
| 6411 | 6819 |
| 6412 EVALUATE(STD) { return DecodeInstructionOriginal(instr); } | 6820 EVALUATE(STD) { |
| 6413 | 6821 DCHECK_OPCODE(STD); |
| 6414 EVALUATE(LD) { return DecodeInstructionOriginal(instr); } | 6822 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); |
| 6823 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); | |
| 6824 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); | |
| 6825 intptr_t addr = b2_val + x2_val + d2_val; | |
| 6826 int64_t frs_val = get_d_register(r1); | |
| 6827 WriteDW(addr, frs_val); | |
| 6828 return length; | |
| 6829 } | |
| 6830 | |
| 6831 EVALUATE(LD) { | |
| 6832 DCHECK_OPCODE(LD); | |
| 6833 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); | |
| 6834 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); | |
| 6835 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); | |
| 6836 intptr_t addr = b2_val + x2_val + d2_val; | |
| 6837 int64_t dbl_val = *reinterpret_cast<int64_t*>(addr); | |
| 6838 set_d_register(r1, dbl_val); | |
| 6839 return length; | |
| 6840 } | |
| 6415 | 6841 |
| 6416 EVALUATE(CD) { return DecodeInstructionOriginal(instr); } | 6842 EVALUATE(CD) { return DecodeInstructionOriginal(instr); } |
| 6417 | 6843 |
| 6418 EVALUATE(STE) { return DecodeInstructionOriginal(instr); } | 6844 EVALUATE(STE) { |
| 6419 | 6845 DCHECK_OPCODE(STE); |
| 6420 EVALUATE(MS) { return DecodeInstructionOriginal(instr); } | 6846 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); |
| 6421 | 6847 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
| 6422 EVALUATE(LE) { return DecodeInstructionOriginal(instr); } | 6848 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
| 6849 intptr_t addr = b2_val + x2_val + d2_val; | |
| 6850 int64_t frs_val = get_d_register(r1) >> 32; | |
| 6851 WriteW(addr, static_cast<int32_t>(frs_val), instr); | |
| 6852 return length; | |
| 6853 } | |
| 6854 | |
| 6855 EVALUATE(MS) { | |
| 6856 DCHECK_OPCODE(MS); | |
| 6857 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); | |
| 6858 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); | |
| 6859 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); | |
| 6860 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr); | |
| 6861 int32_t r1_val = get_low_register<int32_t>(r1); | |
| 6862 set_low_register(r1, r1_val * mem_val); | |
| 6863 return length; | |
| 6864 } | |
| 6865 | |
| 6866 EVALUATE(LE) { | |
| 6867 DCHECK_OPCODE(LE); | |
| 6868 DECODE_RX_A_INSTRUCTION(x2, b2, r1, d2_val); | |
| 6869 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); | |
| 6870 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); | |
| 6871 intptr_t addr = b2_val + x2_val + d2_val; | |
| 6872 float float_val = *reinterpret_cast<float*>(addr); | |
| 6873 set_d_register_from_float32(r1, float_val); | |
| 6874 return length; | |
| 6875 } | |
| 6423 | 6876 |
| 6424 EVALUATE(BRXH) { return DecodeInstructionOriginal(instr); } | 6877 EVALUATE(BRXH) { return DecodeInstructionOriginal(instr); } |
| 6425 | 6878 |
| 6426 EVALUATE(BRXLE) { return DecodeInstructionOriginal(instr); } | 6879 EVALUATE(BRXLE) { return DecodeInstructionOriginal(instr); } |
| 6427 | 6880 |
| 6428 EVALUATE(BXH) { return DecodeInstructionOriginal(instr); } | 6881 EVALUATE(BXH) { |
| 6882 DCHECK_OPCODE(BXH); | |
| 6883 DECODE_RS_A_INSTRUCTION(r1, r3, b2, d2); | |
| 6884 | |
| 6885 // r1_val is the first operand, r3_val is the increment | |
| 6886 int32_t r1_val = r1 == 0 ? 0 : get_register(r1); | |
| 6887 int32_t r3_val = r2 == 0 ? 0 : get_register(r3); | |
| 6888 intptr_t b2_val = b2 == 0 ? 0 : get_register(b2); | |
| 6889 intptr_t branch_address = b2_val + d2; | |
| 6890 // increment r1_val | |
| 6891 r1_val += r3_val; | |
| 6892 | |
| 6893 // if the increment is even, then it designates a pair of registers | |
| 6894 // and the contents of the even and odd registers of the pair are used as | |
| 6895 // the increment and compare value respectively. If the increment is odd, | |
| 6896 // the increment itself is used as both the increment and compare value | |
| 6897 int32_t compare_val = r3 % 2 == 0 ? get_register(r3 + 1) : r3_val; | |
| 6898 if (r1_val > compare_val) { | |
| 6899 // branch to address if r1_val is greater than compare value | |
| 6900 set_pc(branch_address); | |
| 6901 } | |
| 6902 | |
| 6903 // update contents of register in r1 with the new incremented value | |
| 6904 set_register(r1, r1_val); | |
| 6905 | |
| 6906 return length; | |
| 6907 } | |
| 6429 | 6908 |
| 6430 EVALUATE(BXLE) { return DecodeInstructionOriginal(instr); } | 6909 EVALUATE(BXLE) { return DecodeInstructionOriginal(instr); } |
| 6431 | 6910 |
| 6432 EVALUATE(SRL) { return DecodeInstructionOriginal(instr); } | 6911 EVALUATE(SRL) { |
| 6433 | 6912 DCHECK_OPCODE(SRL); |
| 6434 EVALUATE(SLL) { return DecodeInstructionOriginal(instr); } | 6913 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2); |
| 6435 | 6914 // only takes rightmost 6bits |
| 6436 EVALUATE(SRA) { return DecodeInstructionOriginal(instr); } | 6915 int64_t b2_val = b2 == 0 ? 0 : get_register(b2); |
| 6437 | 6916 int shiftBits = (b2_val + d2) & 0x3F; |
| 6438 EVALUATE(SLA) { return DecodeInstructionOriginal(instr); } | 6917 uint32_t r1_val = get_low_register<uint32_t>(r1); |
| 6439 | 6918 uint32_t alu_out = 0; |
| 6440 EVALUATE(SRDL) { return DecodeInstructionOriginal(instr); } | 6919 alu_out = r1_val >> shiftBits; |
| 6441 | 6920 set_low_register(r1, alu_out); |
| 6442 EVALUATE(SLDL) { return DecodeInstructionOriginal(instr); } | 6921 return length; |
| 6443 | 6922 } |
| 6444 EVALUATE(SRDA) { return DecodeInstructionOriginal(instr); } | 6923 |
| 6924 EVALUATE(SLL) { | |
| 6925 DCHECK_OPCODE(SLL); | |
| 6926 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2) | |
| 6927 // only takes rightmost 6bits | |
| 6928 int64_t b2_val = b2 == 0 ? 0 : get_register(b2); | |
| 6929 int shiftBits = (b2_val + d2) & 0x3F; | |
| 6930 uint32_t r1_val = get_low_register<uint32_t>(r1); | |
| 6931 uint32_t alu_out = 0; | |
| 6932 alu_out = r1_val << shiftBits; | |
| 6933 set_low_register(r1, alu_out); | |
| 6934 return length; | |
| 6935 } | |
| 6936 | |
| 6937 EVALUATE(SRA) { | |
| 6938 DCHECK_OPCODE(SRA); | |
| 6939 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2); | |
| 6940 // only takes rightmost 6bits | |
| 6941 int64_t b2_val = b2 == 0 ? 0 : get_register(b2); | |
| 6942 int shiftBits = (b2_val + d2) & 0x3F; | |
| 6943 int32_t r1_val = get_low_register<int32_t>(r1); | |
| 6944 int32_t alu_out = 0; | |
| 6945 bool isOF = false; | |
| 6946 alu_out = r1_val >> shiftBits; | |
| 6947 set_low_register(r1, alu_out); | |
| 6948 SetS390ConditionCode<int32_t>(alu_out, 0); | |
| 6949 SetS390OverflowCode(isOF); | |
| 6950 return length; | |
| 6951 } | |
| 6952 | |
| 6953 EVALUATE(SLA) { | |
| 6954 DCHECK_OPCODE(SLA); | |
| 6955 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2); | |
| 6956 // only takes rightmost 6bits | |
| 6957 int64_t b2_val = b2 == 0 ? 0 : get_register(b2); | |
| 6958 int shiftBits = (b2_val + d2) & 0x3F; | |
| 6959 int32_t r1_val = get_low_register<int32_t>(r1); | |
| 6960 int32_t alu_out = 0; | |
| 6961 bool isOF = false; | |
| 6962 isOF = CheckOverflowForShiftLeft(r1_val, shiftBits); | |
| 6963 alu_out = r1_val << shiftBits; | |
| 6964 set_low_register(r1, alu_out); | |
| 6965 SetS390ConditionCode<int32_t>(alu_out, 0); | |
| 6966 SetS390OverflowCode(isOF); | |
| 6967 return length; | |
| 6968 } | |
| 6969 | |
| 6970 EVALUATE(SRDL) { | |
| 6971 DCHECK_OPCODE(SRDL); | |
| 6972 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2); | |
| 6973 DCHECK(r1 % 2 == 0); // must be a reg pair | |
| 6974 // only takes rightmost 6bits | |
| 6975 int64_t b2_val = b2 == 0 ? 0 : get_register(b2); | |
| 6976 int shiftBits = (b2_val + d2) & 0x3F; | |
| 6977 uint64_t opnd1 = static_cast<uint64_t>(get_low_register<uint32_t>(r1)) << 32; | |
| 6978 uint64_t opnd2 = static_cast<uint64_t>(get_low_register<uint32_t>(r1 + 1)); | |
| 6979 uint64_t r1_val = opnd1 | opnd2; | |
| 6980 uint64_t alu_out = r1_val >> shiftBits; | |
| 6981 set_low_register(r1, alu_out >> 32); | |
| 6982 set_low_register(r1 + 1, alu_out & 0x00000000FFFFFFFF); | |
| 6983 SetS390ConditionCode<int32_t>(alu_out, 0); | |
| 6984 return length; | |
| 6985 } | |
| 6986 | |
| 6987 EVALUATE(SLDL) { | |
| 6988 DCHECK_OPCODE(SLDL); | |
| 6989 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2); | |
| 6990 // only takes rightmost 6bits | |
| 6991 int64_t b2_val = b2 == 0 ? 0 : get_register(b2); | |
| 6992 int shiftBits = (b2_val + d2) & 0x3F; | |
| 6993 | |
| 6994 DCHECK(r1 % 2 == 0); | |
| 6995 uint32_t r1_val = get_low_register<uint32_t>(r1); | |
| 6996 uint32_t r1_next_val = get_low_register<uint32_t>(r1 + 1); | |
| 6997 uint64_t alu_out = (static_cast<uint64_t>(r1_val) << 32) | | |
| 6998 (static_cast<uint64_t>(r1_next_val)); | |
| 6999 alu_out <<= shiftBits; | |
| 7000 set_low_register(r1 + 1, static_cast<uint32_t>(alu_out)); | |
| 7001 set_low_register(r1, static_cast<uint32_t>(alu_out >> 32)); | |
| 7002 return length; | |
| 7003 } | |
| 7004 | |
| 7005 EVALUATE(SRDA) { | |
| 7006 DCHECK_OPCODE(SRDA); | |
| 7007 DECODE_RS_A_INSTRUCTION_NO_R3(r1, b2, d2); | |
| 7008 DCHECK(r1 % 2 == 0); // must be a reg pair | |
| 7009 // only takes rightmost 6bits | |
| 7010 int64_t b2_val = b2 == 0 ? 0 : get_register(b2); | |
| 7011 int shiftBits = (b2_val + d2) & 0x3F; | |
| 7012 int64_t opnd1 = static_cast<int64_t>(get_low_register<int32_t>(r1)) << 32; | |
| 7013 int64_t opnd2 = static_cast<uint64_t>(get_low_register<uint32_t>(r1 + 1)); | |
| 7014 int64_t r1_val = opnd1 + opnd2; | |
| 7015 int64_t alu_out = r1_val >> shiftBits; | |
| 7016 set_low_register(r1, alu_out >> 32); | |
| 7017 set_low_register(r1 + 1, alu_out & 0x00000000FFFFFFFF); | |
| 7018 SetS390ConditionCode<int32_t>(alu_out, 0); | |
| 7019 return length; | |
| 7020 } | |
| 6445 | 7021 |
| 6446 EVALUATE(SLDA) { return DecodeInstructionOriginal(instr); } | 7022 EVALUATE(SLDA) { return DecodeInstructionOriginal(instr); } |
| 6447 | 7023 |
| 6448 EVALUATE(STM) { return DecodeInstructionOriginal(instr); } | 7024 EVALUATE(STM) { |
| 6449 | 7025 DCHECK_OPCODE(STM); |
| 6450 EVALUATE(TM) { return DecodeInstructionOriginal(instr); } | 7026 DECODE_RS_A_INSTRUCTION(r1, r3, rb, d2); |
| 7027 // Store Multiple 32-bits. | |
| 7028 int offset = d2; | |
| 7029 // Regs roll around if r3 is less than r1. | |
| 7030 // Artifically increase r3 by 16 so we can calculate | |
| 7031 // the number of regs stored properly. | |
| 7032 if (r3 < r1) r3 += 16; | |
| 7033 | |
| 7034 int32_t rb_val = (rb == 0) ? 0 : get_low_register<int32_t>(rb); | |
| 7035 | |
| 7036 // Store each register in ascending order. | |
| 7037 for (int i = 0; i <= r3 - r1; i++) { | |
| 7038 int32_t value = get_low_register<int32_t>((r1 + i) % 16); | |
| 7039 WriteW(rb_val + offset + 4 * i, value, instr); | |
| 7040 } | |
| 7041 return length; | |
| 7042 } | |
| 7043 | |
| 7044 EVALUATE(TM) { | |
| 7045 DCHECK_OPCODE(TM); | |
| 7046 // Test Under Mask (Mem - Imm) (8) | |
| 7047 DECODE_SI_INSTRUCTION_I_UINT8(b1, d1_val, imm_val) | |
| 7048 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1); | |
| 7049 intptr_t addr = b1_val + d1_val; | |
| 7050 uint8_t mem_val = ReadB(addr); | |
| 7051 uint8_t selected_bits = mem_val & imm_val; | |
| 7052 // CC0: Selected bits are zero | |
| 7053 // CC1: Selected bits mixed zeros and ones | |
| 7054 // CC3: Selected bits all ones | |
| 7055 if (0 == selected_bits) { | |
| 7056 condition_reg_ = CC_EQ; // CC0 | |
| 7057 } else if (selected_bits == imm_val) { | |
| 7058 condition_reg_ = 0x1; // CC3 | |
| 7059 } else { | |
| 7060 condition_reg_ = 0x4; // CC1 | |
| 7061 } | |
| 7062 return length; | |
| 7063 } | |
| 6451 | 7064 |
| 6452 EVALUATE(MVI) { return DecodeInstructionOriginal(instr); } | 7065 EVALUATE(MVI) { return DecodeInstructionOriginal(instr); } |
| 6453 | 7066 |
| 6454 EVALUATE(TS) { return DecodeInstructionOriginal(instr); } | 7067 EVALUATE(TS) { return DecodeInstructionOriginal(instr); } |
| 6455 | 7068 |
| 6456 EVALUATE(NI) { return DecodeInstructionOriginal(instr); } | 7069 EVALUATE(NI) { return DecodeInstructionOriginal(instr); } |
| 6457 | 7070 |
| 6458 EVALUATE(CLI) { return DecodeInstructionOriginal(instr); } | 7071 EVALUATE(CLI) { |
| 7072 DCHECK_OPCODE(CLI); | |
| 7073 // Compare Immediate (Mem - Imm) (8) | |
| 7074 DECODE_SI_INSTRUCTION_I_UINT8(b1, d1_val, imm_val) | |
| 7075 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1); | |
| 7076 intptr_t addr = b1_val + d1_val; | |
| 7077 uint8_t mem_val = ReadB(addr); | |
| 7078 SetS390ConditionCode<uint8_t>(mem_val, imm_val); | |
| 7079 return length; | |
| 7080 } | |
| 6459 | 7081 |
| 6460 EVALUATE(OI) { return DecodeInstructionOriginal(instr); } | 7082 EVALUATE(OI) { return DecodeInstructionOriginal(instr); } |
| 6461 | 7083 |
| 6462 EVALUATE(XI) { return DecodeInstructionOriginal(instr); } | 7084 EVALUATE(XI) { return DecodeInstructionOriginal(instr); } |
| 6463 | 7085 |
| 6464 EVALUATE(LM) { return DecodeInstructionOriginal(instr); } | 7086 EVALUATE(LM) { |
| 7087 DCHECK_OPCODE(LM); | |
| 7088 DECODE_RS_A_INSTRUCTION(r1, r3, rb, d2); | |
| 7089 // Store Multiple 32-bits. | |
| 7090 int offset = d2; | |
| 7091 // Regs roll around if r3 is less than r1. | |
| 7092 // Artifically increase r3 by 16 so we can calculate | |
| 7093 // the number of regs stored properly. | |
| 7094 if (r3 < r1) r3 += 16; | |
| 7095 | |
| 7096 int32_t rb_val = (rb == 0) ? 0 : get_low_register<int32_t>(rb); | |
| 7097 | |
| 7098 // Store each register in ascending order. | |
| 7099 for (int i = 0; i <= r3 - r1; i++) { | |
| 7100 int32_t value = ReadW(rb_val + offset + 4 * i, instr); | |
| 7101 set_low_register((r1 + i) % 16, value); | |
| 7102 } | |
| 7103 return length; | |
| 7104 } | |
| 6465 | 7105 |
| 6466 EVALUATE(MVCLE) { return DecodeInstructionOriginal(instr); } | 7106 EVALUATE(MVCLE) { return DecodeInstructionOriginal(instr); } |
| 6467 | 7107 |
| 6468 EVALUATE(CLCLE) { return DecodeInstructionOriginal(instr); } | 7108 EVALUATE(CLCLE) { return DecodeInstructionOriginal(instr); } |
| 6469 | 7109 |
| 6470 EVALUATE(MC) { return DecodeInstructionOriginal(instr); } | 7110 EVALUATE(MC) { return DecodeInstructionOriginal(instr); } |
| 6471 | 7111 |
| 6472 EVALUATE(CDS) { return DecodeInstructionOriginal(instr); } | 7112 EVALUATE(CDS) { return DecodeInstructionOriginal(instr); } |
| 6473 | 7113 |
| 6474 EVALUATE(STCM) { return DecodeInstructionOriginal(instr); } | 7114 EVALUATE(STCM) { return DecodeInstructionOriginal(instr); } |
| 6475 | 7115 |
| 6476 EVALUATE(ICM) { return DecodeInstructionOriginal(instr); } | 7116 EVALUATE(ICM) { return DecodeInstructionOriginal(instr); } |
| 6477 | 7117 |
| 6478 EVALUATE(BPRP) { return DecodeInstructionOriginal(instr); } | 7118 EVALUATE(BPRP) { return DecodeInstructionOriginal(instr); } |
| 6479 | 7119 |
| 6480 EVALUATE(BPP) { return DecodeInstructionOriginal(instr); } | 7120 EVALUATE(BPP) { return DecodeInstructionOriginal(instr); } |
| 6481 | 7121 |
| 6482 EVALUATE(TRTR) { return DecodeInstructionOriginal(instr); } | 7122 EVALUATE(TRTR) { return DecodeInstructionOriginal(instr); } |
| 6483 | 7123 |
| 6484 EVALUATE(MVN) { return DecodeInstructionOriginal(instr); } | 7124 EVALUATE(MVN) { return DecodeInstructionOriginal(instr); } |
| 6485 | 7125 |
| 6486 EVALUATE(MVC) { return DecodeInstructionOriginal(instr); } | 7126 EVALUATE(MVC) { |
| 7127 DCHECK_OPCODE(MVC); | |
| 7128 // Move Character | |
| 7129 SSInstruction* ssInstr = reinterpret_cast<SSInstruction*>(instr); | |
| 7130 int b1 = ssInstr->B1Value(); | |
| 7131 intptr_t d1 = ssInstr->D1Value(); | |
| 7132 int b2 = ssInstr->B2Value(); | |
| 7133 intptr_t d2 = ssInstr->D2Value(); | |
| 7134 int length = ssInstr->Length(); | |
| 7135 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1); | |
| 7136 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); | |
| 7137 intptr_t src_addr = b2_val + d2; | |
| 7138 intptr_t dst_addr = b1_val + d1; | |
| 7139 // remember that the length is the actual length - 1 | |
| 7140 for (int i = 0; i < length + 1; ++i) { | |
| 7141 WriteB(dst_addr++, ReadB(src_addr++)); | |
| 7142 } | |
| 7143 length = 6; | |
| 7144 return length; | |
| 7145 } | |
| 6487 | 7146 |
| 6488 EVALUATE(MVZ) { return DecodeInstructionOriginal(instr); } | 7147 EVALUATE(MVZ) { return DecodeInstructionOriginal(instr); } |
| 6489 | 7148 |
| 6490 EVALUATE(NC) { return DecodeInstructionOriginal(instr); } | 7149 EVALUATE(NC) { return DecodeInstructionOriginal(instr); } |
| 6491 | 7150 |
| 6492 EVALUATE(CLC) { return DecodeInstructionOriginal(instr); } | 7151 EVALUATE(CLC) { return DecodeInstructionOriginal(instr); } |
| 6493 | 7152 |
| 6494 EVALUATE(OC) { return DecodeInstructionOriginal(instr); } | 7153 EVALUATE(OC) { return DecodeInstructionOriginal(instr); } |
| 6495 | 7154 |
| 6496 EVALUATE(XC) { return DecodeInstructionOriginal(instr); } | 7155 EVALUATE(XC) { return DecodeInstructionOriginal(instr); } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6534 EVALUATE(SP) { return DecodeInstructionOriginal(instr); } | 7193 EVALUATE(SP) { return DecodeInstructionOriginal(instr); } |
| 6535 | 7194 |
| 6536 EVALUATE(MP) { return DecodeInstructionOriginal(instr); } | 7195 EVALUATE(MP) { return DecodeInstructionOriginal(instr); } |
| 6537 | 7196 |
| 6538 EVALUATE(DP) { return DecodeInstructionOriginal(instr); } | 7197 EVALUATE(DP) { return DecodeInstructionOriginal(instr); } |
| 6539 | 7198 |
| 6540 EVALUATE(UPT) { return DecodeInstructionOriginal(instr); } | 7199 EVALUATE(UPT) { return DecodeInstructionOriginal(instr); } |
| 6541 | 7200 |
| 6542 EVALUATE(PFPO) { return DecodeInstructionOriginal(instr); } | 7201 EVALUATE(PFPO) { return DecodeInstructionOriginal(instr); } |
| 6543 | 7202 |
| 7203 // IIHH, IIHL, IILH, IILL are unimplemented | |
|
JoranSiu
2016/05/17 21:50:14
Let's add a TODO here, so we don't miss implementi
| |
| 6544 EVALUATE(IIHH) { return DecodeInstructionOriginal(instr); } | 7204 EVALUATE(IIHH) { return DecodeInstructionOriginal(instr); } |
| 6545 | 7205 |
| 6546 EVALUATE(IIHL) { return DecodeInstructionOriginal(instr); } | 7206 EVALUATE(IIHL) { return DecodeInstructionOriginal(instr); } |
| 6547 | 7207 |
| 6548 EVALUATE(IILH) { return DecodeInstructionOriginal(instr); } | 7208 EVALUATE(IILH) { return DecodeInstructionOriginal(instr); } |
| 6549 | 7209 |
| 6550 EVALUATE(IILL) { return DecodeInstructionOriginal(instr); } | 7210 EVALUATE(IILL) { return DecodeInstructionOriginal(instr); } |
| 6551 | 7211 |
| 6552 EVALUATE(NIHH) { return DecodeInstructionOriginal(instr); } | 7212 EVALUATE(NIHH) { return DecodeInstructionOriginal(instr); } |
| 6553 | 7213 |
| 6554 EVALUATE(NIHL) { return DecodeInstructionOriginal(instr); } | 7214 EVALUATE(NIHL) { return DecodeInstructionOriginal(instr); } |
| 6555 | 7215 |
| 6556 EVALUATE(NILH) { return DecodeInstructionOriginal(instr); } | 7216 EVALUATE(NILH) { |
| 7217 DCHECK_OPCODE(NILH); | |
| 7218 DECODE_RI_A_INSTRUCTION(instr, r1, i); | |
| 7219 int32_t r1_val = get_low_register<int32_t>(r1); | |
| 7220 // CC is set based on the 16 bits that are AND'd | |
| 7221 SetS390BitWiseConditionCode<uint16_t>((r1_val >> 16) & i); | |
| 7222 i = (i << 16) | 0x0000FFFF; | |
| 7223 set_low_register(r1, r1_val & i); | |
| 7224 return length; | |
| 7225 } | |
| 6557 | 7226 |
| 6558 EVALUATE(NILL) { return DecodeInstructionOriginal(instr); } | 7227 EVALUATE(NILL) { |
| 7228 DCHECK_OPCODE(NILL); | |
| 7229 DECODE_RI_A_INSTRUCTION(instr, r1, i); | |
| 7230 int32_t r1_val = get_low_register<int32_t>(r1); | |
| 7231 // CC is set based on the 16 bits that are AND'd | |
| 7232 SetS390BitWiseConditionCode<uint16_t>(r1_val & i); | |
| 7233 i |= 0xFFFF0000; | |
| 7234 set_low_register(r1, r1_val & i); | |
| 7235 return length; | |
| 7236 } | |
| 6559 | 7237 |
| 6560 EVALUATE(OIHH) { return DecodeInstructionOriginal(instr); } | 7238 EVALUATE(OIHH) { return DecodeInstructionOriginal(instr); } |
| 6561 | 7239 |
| 6562 EVALUATE(OIHL) { return DecodeInstructionOriginal(instr); } | 7240 EVALUATE(OIHL) { return DecodeInstructionOriginal(instr); } |
| 6563 | 7241 |
| 6564 EVALUATE(OILH) { return DecodeInstructionOriginal(instr); } | 7242 EVALUATE(OILH) { |
| 7243 DCHECK_OPCODE(OILH); | |
| 7244 DECODE_RI_A_INSTRUCTION(instr, r1, i); | |
| 7245 int32_t r1_val = get_low_register<int32_t>(r1); | |
| 7246 // CC is set based on the 16 bits that are AND'd | |
| 7247 SetS390BitWiseConditionCode<uint16_t>((r1_val >> 16) | i); | |
| 7248 i = i << 16; | |
| 7249 set_low_register(r1, r1_val | i); | |
| 7250 return length; | |
| 7251 } | |
| 6565 | 7252 |
| 6566 EVALUATE(OILL) { return DecodeInstructionOriginal(instr); } | 7253 EVALUATE(OILL) { |
| 7254 DCHECK_OPCODE(OILL); | |
| 7255 DECODE_RI_A_INSTRUCTION(instr, r1, i); | |
| 7256 int32_t r1_val = get_low_register<int32_t>(r1); | |
| 7257 // CC is set based on the 16 bits that are AND'd | |
| 7258 SetS390BitWiseConditionCode<uint16_t>(r1_val | i); | |
| 7259 set_low_register(r1, r1_val | i); | |
| 7260 return length; | |
| 7261 } | |
| 6567 | 7262 |
| 6568 EVALUATE(LLIHH) { return DecodeInstructionOriginal(instr); } | 7263 EVALUATE(LLIHH) { return DecodeInstructionOriginal(instr); } |
| 6569 | 7264 |
| 6570 EVALUATE(LLIHL) { return DecodeInstructionOriginal(instr); } | 7265 EVALUATE(LLIHL) { return DecodeInstructionOriginal(instr); } |
| 6571 | 7266 |
| 6572 EVALUATE(LLILH) { return DecodeInstructionOriginal(instr); } | 7267 EVALUATE(LLILH) { return DecodeInstructionOriginal(instr); } |
| 6573 | 7268 |
| 6574 EVALUATE(LLILL) { return DecodeInstructionOriginal(instr); } | 7269 EVALUATE(LLILL) { return DecodeInstructionOriginal(instr); } |
| 6575 | 7270 |
| 6576 EVALUATE(TMLH) { return DecodeInstructionOriginal(instr); } | 7271 EVALUATE(TMLH) { return DecodeInstructionOriginal(instr); } |
| 6577 | 7272 |
| 6578 EVALUATE(TMLL) { return DecodeInstructionOriginal(instr); } | 7273 EVALUATE(TMLL) { |
| 7274 DCHECK_OPCODE(TMLL); | |
| 7275 DECODE_RI_A_INSTRUCTION(instr, r1, i2); | |
| 7276 int mask = i2 & 0x0000FFFF; | |
| 7277 if (mask == 0) { | |
| 7278 condition_reg_ = 0x0; | |
| 7279 return length; | |
| 7280 } | |
| 7281 uint32_t r1_val = get_low_register<uint32_t>(r1); | |
| 7282 r1_val = r1_val & 0x0000FFFF; // uses only the last 16bits | |
| 7283 | |
| 7284 // Test if all selected bits are Zero | |
| 7285 bool allSelectedBitsAreZeros = true; | |
| 7286 for (int i = 0; i < 15; i++) { | |
| 7287 if (mask & (1 << i)) { | |
| 7288 if (r1_val & (1 << i)) { | |
| 7289 allSelectedBitsAreZeros = false; | |
| 7290 break; | |
| 7291 } | |
| 7292 } | |
| 7293 } | |
| 7294 if (allSelectedBitsAreZeros) { | |
| 7295 condition_reg_ = 0x8; | |
| 7296 return length; // Done! | |
| 7297 } | |
| 7298 | |
| 7299 // Test if all selected bits are one | |
| 7300 bool allSelectedBitsAreOnes = true; | |
| 7301 for (int i = 0; i < 15; i++) { | |
| 7302 if (mask & (1 << i)) { | |
| 7303 if (!(r1_val & (1 << i))) { | |
| 7304 allSelectedBitsAreOnes = false; | |
| 7305 break; | |
| 7306 } | |
| 7307 } | |
| 7308 } | |
| 7309 if (allSelectedBitsAreOnes) { | |
| 7310 condition_reg_ = 0x1; | |
| 7311 return length; // Done! | |
| 7312 } | |
| 7313 | |
| 7314 // Now we know selected bits mixed zeros and ones | |
| 7315 // Test if the leftmost bit is zero or one | |
| 7316 for (int i = 14; i >= 0; i--) { | |
| 7317 if (mask & (1 << i)) { | |
| 7318 if (r1_val & (1 << i)) { | |
| 7319 // leftmost bit is one | |
| 7320 condition_reg_ = 0x2; | |
| 7321 } else { | |
| 7322 // leftmost bit is zero | |
| 7323 condition_reg_ = 0x4; | |
| 7324 } | |
| 7325 return length; // Done! | |
| 7326 } | |
| 7327 } | |
| 7328 return length; | |
| 7329 } | |
| 6579 | 7330 |
| 6580 EVALUATE(TMHH) { return DecodeInstructionOriginal(instr); } | 7331 EVALUATE(TMHH) { return DecodeInstructionOriginal(instr); } |
| 6581 | 7332 |
| 6582 EVALUATE(TMHL) { return DecodeInstructionOriginal(instr); } | 7333 EVALUATE(TMHL) { return DecodeInstructionOriginal(instr); } |
| 6583 | 7334 |
| 6584 EVALUATE(BRAS) { return DecodeInstructionOriginal(instr); } | 7335 EVALUATE(BRAS) { |
| 6585 | 7336 DCHECK_OPCODE(BRAS); |
| 6586 EVALUATE(BRCT) { return DecodeInstructionOriginal(instr); } | 7337 // Branch Relative and Save |
| 6587 | 7338 DECODE_RI_B_INSTRUCTION(instr, r1, d2) |
| 6588 EVALUATE(BRCTG) { return DecodeInstructionOriginal(instr); } | 7339 intptr_t pc = get_pc(); |
| 6589 | 7340 // Set PC of next instruction to register |
| 6590 EVALUATE(LHI) { return DecodeInstructionOriginal(instr); } | 7341 set_register(r1, pc + sizeof(FourByteInstr)); |
| 6591 | 7342 // Update PC to branch target |
| 6592 EVALUATE(LGHI) { return DecodeInstructionOriginal(instr); } | 7343 set_pc(pc + d2 * 2); |
| 6593 | 7344 return length; |
| 6594 EVALUATE(MHI) { return DecodeInstructionOriginal(instr); } | 7345 } |
| 6595 | 7346 |
| 6596 EVALUATE(MGHI) { return DecodeInstructionOriginal(instr); } | 7347 EVALUATE(BRCT) { |
| 6597 | 7348 DCHECK_OPCODE(BRCT); |
| 6598 EVALUATE(CHI) { return DecodeInstructionOriginal(instr); } | 7349 // Branch On Count (32/64). |
| 6599 | 7350 DECODE_RI_A_INSTRUCTION(instr, r1, i2); |
| 6600 EVALUATE(CGHI) { return DecodeInstructionOriginal(instr); } | 7351 int64_t value = get_low_register<int32_t>(r1); |
| 6601 | 7352 set_low_register(r1, --value); |
| 6602 EVALUATE(LARL) { return DecodeInstructionOriginal(instr); } | 7353 // Branch if value != 0 |
| 7354 if (value != 0) { | |
| 7355 intptr_t offset = i2 * 2; | |
| 7356 set_pc(get_pc() + offset); | |
| 7357 } | |
| 7358 return length; | |
| 7359 } | |
| 7360 | |
| 7361 EVALUATE(BRCTG) { | |
| 7362 DCHECK_OPCODE(BRCTG); | |
| 7363 // Branch On Count (32/64). | |
| 7364 DECODE_RI_A_INSTRUCTION(instr, r1, i2); | |
| 7365 int64_t value = get_register(r1); | |
| 7366 set_register(r1, --value); | |
| 7367 // Branch if value != 0 | |
| 7368 if (value != 0) { | |
| 7369 intptr_t offset = i2 * 2; | |
| 7370 set_pc(get_pc() + offset); | |
| 7371 } | |
| 7372 return length; | |
| 7373 } | |
| 7374 | |
| 7375 EVALUATE(LHI) { | |
| 7376 DCHECK_OPCODE(LHI); | |
| 7377 DECODE_RI_A_INSTRUCTION(instr, r1, i); | |
| 7378 set_low_register(r1, i); | |
| 7379 return length; | |
| 7380 } | |
| 7381 | |
| 7382 EVALUATE(LGHI) { | |
| 7383 DCHECK_OPCODE(LGHI); | |
| 7384 DECODE_RI_A_INSTRUCTION(instr, r1, i2); | |
| 7385 int64_t i = static_cast<int64_t>(i2); | |
| 7386 set_register(r1, i); | |
| 7387 return length; | |
| 7388 } | |
| 7389 | |
| 7390 EVALUATE(MHI) { | |
| 7391 DCHECK_OPCODE(MHI); | |
| 7392 DECODE_RI_A_INSTRUCTION(instr, r1, i); | |
| 7393 int32_t r1_val = get_low_register<int32_t>(r1); | |
| 7394 bool isOF = false; | |
| 7395 isOF = CheckOverflowForMul(r1_val, i); | |
| 7396 r1_val *= i; | |
| 7397 set_low_register(r1, r1_val); | |
| 7398 SetS390ConditionCode<int32_t>(r1_val, 0); | |
| 7399 SetS390OverflowCode(isOF); | |
| 7400 return length; | |
| 7401 } | |
| 7402 | |
| 7403 EVALUATE(MGHI) { | |
| 7404 DCHECK_OPCODE(MGHI); | |
| 7405 DECODE_RI_A_INSTRUCTION(instr, r1, i2); | |
| 7406 int64_t i = static_cast<int64_t>(i2); | |
| 7407 int64_t r1_val = get_register(r1); | |
| 7408 bool isOF = false; | |
| 7409 isOF = CheckOverflowForMul(r1_val, i); | |
| 7410 r1_val *= i; | |
| 7411 set_register(r1, r1_val); | |
| 7412 SetS390ConditionCode<int32_t>(r1_val, 0); | |
| 7413 SetS390OverflowCode(isOF); | |
| 7414 return length; | |
| 7415 } | |
| 7416 | |
| 7417 EVALUATE(CHI) { | |
| 7418 DCHECK_OPCODE(CHI); | |
| 7419 DECODE_RI_A_INSTRUCTION(instr, r1, i); | |
| 7420 int32_t r1_val = get_low_register<int32_t>(r1); | |
| 7421 SetS390ConditionCode<int32_t>(r1_val, i); | |
| 7422 return length; | |
| 7423 } | |
| 7424 | |
| 7425 EVALUATE(CGHI) { | |
| 7426 DCHECK_OPCODE(CGHI); | |
| 7427 DECODE_RI_A_INSTRUCTION(instr, r1, i2); | |
| 7428 int64_t i = static_cast<int64_t>(i2); | |
| 7429 int64_t r1_val = get_register(r1); | |
| 7430 SetS390ConditionCode<int64_t>(r1_val, i); | |
| 7431 return length; | |
| 7432 } | |
| 7433 | |
| 7434 EVALUATE(LARL) { | |
| 7435 DCHECK_OPCODE(LARL); | |
| 7436 DECODE_RIL_B_INSTRUCTION(r1, i2); | |
| 7437 intptr_t offset = i2 * 2; | |
| 7438 set_register(r1, get_pc() + offset); | |
| 7439 return length; | |
| 7440 } | |
| 6603 | 7441 |
| 6604 EVALUATE(LGFI) { return DecodeInstructionOriginal(instr); } | 7442 EVALUATE(LGFI) { return DecodeInstructionOriginal(instr); } |
| 6605 | 7443 |
| 6606 EVALUATE(BRASL) { return DecodeInstructionOriginal(instr); } | 7444 EVALUATE(BRASL) { |
| 6607 | 7445 DCHECK_OPCODE(BRASL); |
| 6608 EVALUATE(XIHF) { return DecodeInstructionOriginal(instr); } | 7446 // Branch and Save Relative Long |
| 6609 | 7447 DECODE_RIL_B_INSTRUCTION(r1, i2); |
| 6610 EVALUATE(XILF) { return DecodeInstructionOriginal(instr); } | 7448 intptr_t d2 = i2; |
| 6611 | 7449 intptr_t pc = get_pc(); |
| 6612 EVALUATE(NIHF) { return DecodeInstructionOriginal(instr); } | 7450 set_register(r1, pc + 6); // save next instruction to register |
| 6613 | 7451 set_pc(pc + d2 * 2); // update register |
| 6614 EVALUATE(NILF) { return DecodeInstructionOriginal(instr); } | 7452 return length; |
| 6615 | 7453 } |
| 6616 EVALUATE(OIHF) { return DecodeInstructionOriginal(instr); } | 7454 |
| 6617 | 7455 EVALUATE(XIHF) { |
| 6618 EVALUATE(OILF) { return DecodeInstructionOriginal(instr); } | 7456 DCHECK_OPCODE(XIHF); |
| 6619 | 7457 DECODE_RIL_A_INSTRUCTION(r1, imm); |
| 6620 EVALUATE(LLIHF) { return DecodeInstructionOriginal(instr); } | 7458 uint32_t alu_out = 0; |
| 6621 | 7459 alu_out = get_high_register<uint32_t>(r1); |
| 6622 EVALUATE(LLILF) { return DecodeInstructionOriginal(instr); } | 7460 alu_out = alu_out ^ imm; |
| 6623 | 7461 set_high_register(r1, alu_out); |
| 6624 EVALUATE(MSGFI) { return DecodeInstructionOriginal(instr); } | 7462 SetS390BitWiseConditionCode<uint32_t>(alu_out); |
| 6625 | 7463 return length; |
| 6626 EVALUATE(MSFI) { return DecodeInstructionOriginal(instr); } | 7464 } |
| 6627 | 7465 |
| 6628 EVALUATE(SLGFI) { return DecodeInstructionOriginal(instr); } | 7466 EVALUATE(XILF) { |
| 6629 | 7467 DCHECK_OPCODE(XILF); |
| 6630 EVALUATE(SLFI) { return DecodeInstructionOriginal(instr); } | 7468 DECODE_RIL_A_INSTRUCTION(r1, imm); |
| 6631 | 7469 uint32_t alu_out = 0; |
| 6632 EVALUATE(AGFI) { return DecodeInstructionOriginal(instr); } | 7470 alu_out = get_low_register<uint32_t>(r1); |
| 6633 | 7471 alu_out = alu_out ^ imm; |
| 6634 EVALUATE(AFI) { return DecodeInstructionOriginal(instr); } | 7472 set_low_register(r1, alu_out); |
| 6635 | 7473 SetS390BitWiseConditionCode<uint32_t>(alu_out); |
| 6636 EVALUATE(ALGFI) { return DecodeInstructionOriginal(instr); } | 7474 return length; |
| 6637 | 7475 } |
| 6638 EVALUATE(ALFI) { return DecodeInstructionOriginal(instr); } | 7476 |
| 6639 | 7477 EVALUATE(NIHF) { |
| 6640 EVALUATE(CGFI) { return DecodeInstructionOriginal(instr); } | 7478 DCHECK_OPCODE(NIHF); |
| 6641 | 7479 // Bitwise Op on upper 32-bits |
| 6642 EVALUATE(CFI) { return DecodeInstructionOriginal(instr); } | 7480 DECODE_RIL_A_INSTRUCTION(r1, imm); |
| 6643 | 7481 uint32_t alu_out = get_high_register<uint32_t>(r1); |
| 6644 EVALUATE(CLGFI) { return DecodeInstructionOriginal(instr); } | 7482 alu_out &= imm; |
| 6645 | 7483 SetS390BitWiseConditionCode<uint32_t>(alu_out); |
| 6646 EVALUATE(CLFI) { return DecodeInstructionOriginal(instr); } | 7484 set_high_register(r1, alu_out); |
| 7485 return length; | |
| 7486 } | |
| 7487 | |
| 7488 EVALUATE(NILF) { | |
| 7489 DCHECK_OPCODE(NILF); | |
| 7490 // Bitwise Op on lower 32-bits | |
| 7491 DECODE_RIL_A_INSTRUCTION(r1, imm); | |
| 7492 uint32_t alu_out = get_low_register<uint32_t>(r1); | |
| 7493 alu_out &= imm; | |
| 7494 SetS390BitWiseConditionCode<uint32_t>(alu_out); | |
| 7495 set_low_register(r1, alu_out); | |
| 7496 return length; | |
| 7497 } | |
| 7498 | |
| 7499 EVALUATE(OIHF) { | |
| 7500 DCHECK_OPCODE(OIHF); | |
| 7501 // Bitwise Op on upper 32-bits | |
| 7502 DECODE_RIL_B_INSTRUCTION(r1, imm); | |
| 7503 uint32_t alu_out = get_high_register<uint32_t>(r1); | |
| 7504 alu_out |= imm; | |
| 7505 SetS390BitWiseConditionCode<uint32_t>(alu_out); | |
| 7506 set_high_register(r1, alu_out); | |
| 7507 return length; | |
| 7508 } | |
| 7509 | |
| 7510 EVALUATE(OILF) { | |
| 7511 DCHECK_OPCODE(OILF); | |
| 7512 // Bitwise Op on lower 32-bits | |
| 7513 DECODE_RIL_B_INSTRUCTION(r1, imm); | |
| 7514 uint32_t alu_out = get_low_register<uint32_t>(r1); | |
| 7515 alu_out |= imm; | |
| 7516 SetS390BitWiseConditionCode<uint32_t>(alu_out); | |
| 7517 set_low_register(r1, alu_out); | |
| 7518 return length; | |
| 7519 } | |
| 7520 | |
| 7521 EVALUATE(LLIHF) { | |
| 7522 DCHECK_OPCODE(LLIHF); | |
| 7523 // Load Logical Immediate into high word | |
| 7524 DECODE_RIL_A_INSTRUCTION(r1, i2); | |
| 7525 uint64_t imm = static_cast<uint64_t>(i2); | |
| 7526 set_register(r1, imm << 32); | |
| 7527 return length; | |
| 7528 } | |
| 7529 | |
| 7530 EVALUATE(LLILF) { | |
| 7531 DCHECK_OPCODE(LLILF); | |
| 7532 // Load Logical into lower 32-bits (zero extend upper 32-bits) | |
| 7533 DECODE_RIL_A_INSTRUCTION(r1, i2); | |
| 7534 uint64_t imm = static_cast<uint64_t>(i2); | |
| 7535 set_register(r1, imm); | |
| 7536 return length; | |
| 7537 } | |
| 7538 | |
| 7539 EVALUATE(MSGFI) { | |
| 7540 DCHECK_OPCODE(MSGFI); | |
| 7541 DECODE_RIL_B_INSTRUCTION(r1, i2); | |
| 7542 int64_t alu_out = get_register(r1); | |
| 7543 alu_out = alu_out * i2; | |
| 7544 set_register(r1, alu_out); | |
| 7545 return length; | |
| 7546 } | |
| 7547 | |
| 7548 EVALUATE(MSFI) { | |
| 7549 DCHECK_OPCODE(MSFI); | |
| 7550 DECODE_RIL_B_INSTRUCTION(r1, i2); | |
| 7551 int32_t alu_out = get_low_register<int32_t>(r1); | |
| 7552 alu_out = alu_out * i2; | |
| 7553 set_low_register(r1, alu_out); | |
| 7554 return length; | |
| 7555 } | |
| 7556 | |
| 7557 EVALUATE(SLGFI) { | |
| 7558 DCHECK_OPCODE(SLGFI); | |
| 7559 #ifndef V8_TARGET_ARCH_S390X | |
| 7560 // should only be called on 64bit | |
| 7561 DCHECK(false); | |
| 7562 #endif | |
| 7563 DECODE_RIL_A_INSTRUCTION(r1, i2); | |
| 7564 uint64_t r1_val = (uint64_t)(get_register(r1)); | |
| 7565 uint64_t alu_out; | |
| 7566 alu_out = r1_val - i2; | |
| 7567 set_register(r1, (intptr_t)alu_out); | |
| 7568 SetS390ConditionCode<uint64_t>(alu_out, 0); | |
| 7569 return length; | |
| 7570 } | |
| 7571 | |
| 7572 EVALUATE(SLFI) { | |
| 7573 DCHECK_OPCODE(SLFI); | |
| 7574 DECODE_RIL_A_INSTRUCTION(r1, imm); | |
| 7575 uint32_t alu_out = get_low_register<uint32_t>(r1); | |
| 7576 alu_out -= imm; | |
| 7577 SetS390ConditionCode<uint32_t>(alu_out, 0); | |
| 7578 set_low_register(r1, alu_out); | |
| 7579 return length; | |
| 7580 } | |
| 7581 | |
| 7582 EVALUATE(AGFI) { | |
| 7583 DCHECK_OPCODE(AGFI); | |
| 7584 // Clobbering Add Word Immediate | |
| 7585 DECODE_RIL_B_INSTRUCTION(r1, i2_val); | |
| 7586 bool isOF = false; | |
| 7587 // 64-bit Add (Register + 32-bit Imm) | |
| 7588 int64_t r1_val = get_register(r1); | |
| 7589 int64_t i2 = static_cast<int64_t>(i2_val); | |
| 7590 isOF = CheckOverflowForIntAdd(r1_val, i2, int64_t); | |
| 7591 int64_t alu_out = r1_val + i2; | |
| 7592 set_register(r1, alu_out); | |
| 7593 SetS390ConditionCode<int64_t>(alu_out, 0); | |
| 7594 SetS390OverflowCode(isOF); | |
| 7595 return length; | |
| 7596 } | |
| 7597 | |
| 7598 EVALUATE(AFI) { | |
| 7599 DCHECK_OPCODE(AFI); | |
| 7600 // Clobbering Add Word Immediate | |
| 7601 DECODE_RIL_B_INSTRUCTION(r1, i2); | |
| 7602 bool isOF = false; | |
| 7603 // 32-bit Add (Register + 32-bit Immediate) | |
| 7604 int32_t r1_val = get_low_register<int32_t>(r1); | |
| 7605 isOF = CheckOverflowForIntAdd(r1_val, i2, int32_t); | |
| 7606 int32_t alu_out = r1_val + i2; | |
| 7607 set_low_register(r1, alu_out); | |
| 7608 SetS390ConditionCode<int32_t>(alu_out, 0); | |
| 7609 SetS390OverflowCode(isOF); | |
| 7610 return length; | |
| 7611 } | |
| 7612 | |
| 7613 EVALUATE(ALGFI) { | |
| 7614 DCHECK_OPCODE(ALGFI); | |
| 7615 #ifndef V8_TARGET_ARCH_S390X | |
| 7616 // should only be called on 64bit | |
| 7617 DCHECK(false); | |
| 7618 #endif | |
| 7619 DECODE_RIL_A_INSTRUCTION(r1, i2); | |
| 7620 uint64_t r1_val = (uint64_t)(get_register(r1)); | |
| 7621 uint64_t alu_out; | |
| 7622 alu_out = r1_val + i2; | |
| 7623 set_register(r1, (intptr_t)alu_out); | |
| 7624 SetS390ConditionCode<uint64_t>(alu_out, 0); | |
| 7625 | |
| 7626 return length; | |
| 7627 } | |
| 7628 | |
| 7629 EVALUATE(ALFI) { | |
| 7630 DCHECK_OPCODE(ALFI); | |
| 7631 DECODE_RIL_A_INSTRUCTION(r1, imm); | |
| 7632 uint32_t alu_out = get_low_register<uint32_t>(r1); | |
| 7633 alu_out += imm; | |
| 7634 SetS390ConditionCode<uint32_t>(alu_out, 0); | |
| 7635 set_low_register(r1, alu_out); | |
| 7636 return length; | |
| 7637 } | |
| 7638 | |
| 7639 EVALUATE(CGFI) { | |
| 7640 DCHECK_OPCODE(CGFI); | |
| 7641 // Compare with Immediate (64) | |
| 7642 DECODE_RIL_B_INSTRUCTION(r1, i2); | |
| 7643 int64_t imm = static_cast<int64_t>(i2); | |
| 7644 SetS390ConditionCode<int64_t>(get_register(r1), imm); | |
| 7645 return length; | |
| 7646 } | |
| 7647 | |
| 7648 EVALUATE(CFI) { | |
| 7649 DCHECK_OPCODE(CFI); | |
| 7650 // Compare with Immediate (32) | |
| 7651 DECODE_RIL_B_INSTRUCTION(r1, imm); | |
| 7652 SetS390ConditionCode<int32_t>(get_low_register<int32_t>(r1), imm); | |
| 7653 return length; | |
| 7654 } | |
| 7655 | |
| 7656 EVALUATE(CLGFI) { | |
| 7657 DCHECK_OPCODE(CLGFI); | |
| 7658 // Compare Logical with Immediate (64) | |
| 7659 DECODE_RIL_A_INSTRUCTION(r1, i2); | |
| 7660 uint64_t imm = static_cast<uint64_t>(i2); | |
| 7661 SetS390ConditionCode<uint64_t>(get_register(r1), imm); | |
| 7662 return length; | |
| 7663 } | |
| 7664 | |
| 7665 EVALUATE(CLFI) { | |
| 7666 DCHECK_OPCODE(CLFI); | |
| 7667 // Compare Logical with Immediate (32) | |
| 7668 DECODE_RIL_A_INSTRUCTION(r1, imm); | |
| 7669 SetS390ConditionCode<uint32_t>(get_low_register<uint32_t>(r1), imm); | |
| 7670 return length; | |
| 7671 } | |
| 6647 | 7672 |
| 6648 EVALUATE(LLHRL) { return DecodeInstructionOriginal(instr); } | 7673 EVALUATE(LLHRL) { return DecodeInstructionOriginal(instr); } |
| 6649 | 7674 |
| 6650 EVALUATE(LGHRL) { return DecodeInstructionOriginal(instr); } | 7675 EVALUATE(LGHRL) { return DecodeInstructionOriginal(instr); } |
| 6651 | 7676 |
| 6652 EVALUATE(LHRL) { return DecodeInstructionOriginal(instr); } | 7677 EVALUATE(LHRL) { return DecodeInstructionOriginal(instr); } |
| 6653 | 7678 |
| 6654 EVALUATE(LLGHRL) { return DecodeInstructionOriginal(instr); } | 7679 EVALUATE(LLGHRL) { return DecodeInstructionOriginal(instr); } |
| 6655 | 7680 |
| 6656 EVALUATE(STHRL) { return DecodeInstructionOriginal(instr); } | 7681 EVALUATE(STHRL) { return DecodeInstructionOriginal(instr); } |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6726 EVALUATE(RCHP) { return DecodeInstructionOriginal(instr); } | 7751 EVALUATE(RCHP) { return DecodeInstructionOriginal(instr); } |
| 6727 | 7752 |
| 6728 EVALUATE(SCHM) { return DecodeInstructionOriginal(instr); } | 7753 EVALUATE(SCHM) { return DecodeInstructionOriginal(instr); } |
| 6729 | 7754 |
| 6730 EVALUATE(CKSM) { return DecodeInstructionOriginal(instr); } | 7755 EVALUATE(CKSM) { return DecodeInstructionOriginal(instr); } |
| 6731 | 7756 |
| 6732 EVALUATE(SAR) { return DecodeInstructionOriginal(instr); } | 7757 EVALUATE(SAR) { return DecodeInstructionOriginal(instr); } |
| 6733 | 7758 |
| 6734 EVALUATE(EAR) { return DecodeInstructionOriginal(instr); } | 7759 EVALUATE(EAR) { return DecodeInstructionOriginal(instr); } |
| 6735 | 7760 |
| 6736 EVALUATE(MSR) { return DecodeInstructionOriginal(instr); } | 7761 EVALUATE(MSR) { |
| 7762 DCHECK_OPCODE(MSR); | |
| 7763 DECODE_RRE_INSTRUCTION(r1, r2); | |
| 7764 int32_t r1_val = get_low_register<int32_t>(r1); | |
| 7765 int32_t r2_val = get_low_register<int32_t>(r2); | |
| 7766 set_low_register(r1, r1_val * r2_val); | |
| 7767 return length; | |
| 7768 } | |
| 6737 | 7769 |
| 6738 EVALUATE(MVST) { return DecodeInstructionOriginal(instr); } | 7770 EVALUATE(MVST) { return DecodeInstructionOriginal(instr); } |
| 6739 | 7771 |
| 6740 EVALUATE(CUSE) { return DecodeInstructionOriginal(instr); } | 7772 EVALUATE(CUSE) { return DecodeInstructionOriginal(instr); } |
| 6741 | 7773 |
| 6742 EVALUATE(SRST) { return DecodeInstructionOriginal(instr); } | 7774 EVALUATE(SRST) { return DecodeInstructionOriginal(instr); } |
| 6743 | 7775 |
| 6744 EVALUATE(XSCH) { return DecodeInstructionOriginal(instr); } | 7776 EVALUATE(XSCH) { return DecodeInstructionOriginal(instr); } |
| 6745 | 7777 |
| 6746 EVALUATE(STCKE) { return DecodeInstructionOriginal(instr); } | 7778 EVALUATE(STCKE) { return DecodeInstructionOriginal(instr); } |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 6772 EVALUATE(ETND) { return DecodeInstructionOriginal(instr); } | 7804 EVALUATE(ETND) { return DecodeInstructionOriginal(instr); } |
| 6773 | 7805 |
| 6774 EVALUATE(TEND) { return DecodeInstructionOriginal(instr); } | 7806 EVALUATE(TEND) { return DecodeInstructionOriginal(instr); } |
| 6775 | 7807 |
| 6776 EVALUATE(NIAI) { return DecodeInstructionOriginal(instr); } | 7808 EVALUATE(NIAI) { return DecodeInstructionOriginal(instr); } |
| 6777 | 7809 |
| 6778 EVALUATE(TABORT) { return DecodeInstructionOriginal(instr); } | 7810 EVALUATE(TABORT) { return DecodeInstructionOriginal(instr); } |
| 6779 | 7811 |
| 6780 EVALUATE(TRAP4) { return DecodeInstructionOriginal(instr); } | 7812 EVALUATE(TRAP4) { return DecodeInstructionOriginal(instr); } |
| 6781 | 7813 |
| 6782 EVALUATE(LPEBR) { return DecodeInstructionOriginal(instr); } | 7814 EVALUATE(LPEBR) { |
| 7815 DCHECK_OPCODE(LPEBR); | |
| 7816 DECODE_RRE_INSTRUCTION(r1, r2); | |
| 7817 float fr1_val = get_float32_from_d_register(r1); | |
| 7818 float fr2_val = get_float32_from_d_register(r2); | |
| 7819 fr1_val = std::fabs(fr2_val); | |
| 7820 set_d_register_from_float32(r1, fr1_val); | |
| 7821 if (fr2_val != fr2_val) { // input is NaN | |
| 7822 condition_reg_ = CC_OF; | |
| 7823 } else if (fr2_val == 0) { | |
| 7824 condition_reg_ = CC_EQ; | |
| 7825 } else { | |
| 7826 condition_reg_ = CC_GT; | |
| 7827 } | |
| 7828 | |
| 7829 return length; | |
| 7830 } | |
| 6783 | 7831 |
| 6784 EVALUATE(LNEBR) { return DecodeInstructionOriginal(instr); } | 7832 EVALUATE(LNEBR) { return DecodeInstructionOriginal(instr); } |
| 6785 | 7833 |
| 6786 EVALUATE(LTEBR) { return DecodeInstructionOriginal(instr); } | 7834 EVALUATE(LTEBR) { |
| 7835 DCHECK_OPCODE(LTEBR); | |
| 7836 DECODE_RRE_INSTRUCTION(r1, r2); | |
| 7837 int64_t r2_val = get_d_register(r2); | |
| 7838 float fr2_val = get_float32_from_d_register(r2); | |
| 7839 SetS390ConditionCode<float>(fr2_val, 0.0); | |
| 7840 set_d_register(r1, r2_val); | |
| 7841 return length; | |
| 7842 } | |
| 6787 | 7843 |
| 6788 EVALUATE(LCEBR) { return DecodeInstructionOriginal(instr); } | 7844 EVALUATE(LCEBR) { return DecodeInstructionOriginal(instr); } |
| 6789 | 7845 |
| 6790 EVALUATE(LDEBR) { return DecodeInstructionOriginal(instr); } | 7846 EVALUATE(LDEBR) { |
| 7847 DCHECK_OPCODE(LDEBR); | |
| 7848 DECODE_RRE_INSTRUCTION(r1, r2); | |
| 7849 float fp_val = get_float32_from_d_register(r2); | |
| 7850 double db_val = static_cast<double>(fp_val); | |
| 7851 set_d_register_from_double(r1, db_val); | |
| 7852 return length; | |
| 7853 } | |
| 6791 | 7854 |
| 6792 EVALUATE(LXDBR) { return DecodeInstructionOriginal(instr); } | 7855 EVALUATE(LXDBR) { return DecodeInstructionOriginal(instr); } |
| 6793 | 7856 |
| 6794 EVALUATE(LXEBR) { return DecodeInstructionOriginal(instr); } | 7857 EVALUATE(LXEBR) { return DecodeInstructionOriginal(instr); } |
| 6795 | 7858 |
| 6796 EVALUATE(MXDBR) { return DecodeInstructionOriginal(instr); } | 7859 EVALUATE(MXDBR) { return DecodeInstructionOriginal(instr); } |
| 6797 | 7860 |
| 6798 EVALUATE(KEBR) { return DecodeInstructionOriginal(instr); } | 7861 EVALUATE(KEBR) { return DecodeInstructionOriginal(instr); } |
| 6799 | 7862 |
| 6800 EVALUATE(CEBR) { return DecodeInstructionOriginal(instr); } | 7863 EVALUATE(CEBR) { |
| 7864 DCHECK_OPCODE(CEBR); | |
| 7865 DECODE_RRE_INSTRUCTION(r1, r2); | |
| 7866 float fr1_val = get_float32_from_d_register(r1); | |
| 7867 float fr2_val = get_float32_from_d_register(r2); | |
| 7868 if (isNaN(fr1_val) || isNaN(fr2_val)) { | |
| 7869 condition_reg_ = CC_OF; | |
| 7870 } else { | |
| 7871 SetS390ConditionCode<float>(fr1_val, fr2_val); | |
| 7872 } | |
| 6801 | 7873 |
| 6802 EVALUATE(AEBR) { return DecodeInstructionOriginal(instr); } | 7874 return length; |
| 7875 } | |
| 6803 | 7876 |
| 6804 EVALUATE(SEBR) { return DecodeInstructionOriginal(instr); } | 7877 EVALUATE(AEBR) { |
| 7878 DCHECK_OPCODE(AEBR); | |
| 7879 DECODE_RRE_INSTRUCTION(r1, r2); | |
| 7880 float fr1_val = get_float32_from_d_register(r1); | |
| 7881 float fr2_val = get_float32_from_d_register(r2); | |
| 7882 fr1_val += fr2_val; | |
| 7883 set_d_register_from_float32(r1, fr1_val); | |
| 7884 SetS390ConditionCode<float>(fr1_val, 0); | |
| 7885 | |
| 7886 return length; | |
| 7887 } | |
| 7888 | |
| 7889 EVALUATE(SEBR) { | |
| 7890 DCHECK_OPCODE(SEBR); | |
| 7891 DECODE_RRE_INSTRUCTION(r1, r2); | |
| 7892 float fr1_val = get_float32_from_d_register(r1); | |
| 7893 float fr2_val = get_float32_from_d_register(r2); | |
| 7894 fr1_val -= fr2_val; | |
| 7895 set_d_register_from_float32(r1, fr1_val); | |
| 7896 SetS390ConditionCode<float>(fr1_val, 0); | |
| 7897 | |
| 7898 return length; | |
| 7899 } | |
| 6805 | 7900 |
| 6806 EVALUATE(MDEBR) { return DecodeInstructionOriginal(instr); } | 7901 EVALUATE(MDEBR) { return DecodeInstructionOriginal(instr); } |
| 6807 | 7902 |
| 6808 EVALUATE(DEBR) { return DecodeInstructionOriginal(instr); } | 7903 EVALUATE(DEBR) { |
| 7904 DCHECK_OPCODE(DEBR); | |
| 7905 DECODE_RRE_INSTRUCTION(r1, r2); | |
| 7906 float fr1_val = get_float32_from_d_register(r1); | |
| 7907 float fr2_val = get_float32_from_d_register(r2); | |
| 7908 fr1_val /= fr2_val; | |
| 7909 set_d_register_from_float32(r1, fr1_val); | |
| 7910 SetS390ConditionCode<float>(fr1_val, 0); | |
| 7911 | |
| 7912 return length; | |
| 7913 } | |
| 6809 | 7914 |
| 6810 EVALUATE(MAEBR) { return DecodeInstructionOriginal(instr); } | 7915 EVALUATE(MAEBR) { return DecodeInstructionOriginal(instr); } |
| 6811 | 7916 |
| 6812 EVALUATE(MSEBR) { return DecodeInstructionOriginal(instr); } | 7917 EVALUATE(MSEBR) { return DecodeInstructionOriginal(instr); } |
| 6813 | 7918 |
| 6814 EVALUATE(LPDBR) { return DecodeInstructionOriginal(instr); } | 7919 EVALUATE(LPDBR) { |
| 7920 DCHECK_OPCODE(LPDBR); | |
| 7921 DECODE_RRE_INSTRUCTION(r1, r2); | |
| 7922 double r1_val = get_double_from_d_register(r1); | |
| 7923 double r2_val = get_double_from_d_register(r2); | |
| 7924 r1_val = std::fabs(r2_val); | |
| 7925 set_d_register_from_double(r1, r1_val); | |
| 7926 if (r2_val != r2_val) { // input is NaN | |
| 7927 condition_reg_ = CC_OF; | |
| 7928 } else if (r2_val == 0) { | |
| 7929 condition_reg_ = CC_EQ; | |
| 7930 } else { | |
| 7931 condition_reg_ = CC_GT; | |
| 7932 } | |
| 7933 return length; | |
| 7934 } | |
| 6815 | 7935 |
| 6816 EVALUATE(LNDBR) { return DecodeInstructionOriginal(instr); } | 7936 EVALUATE(LNDBR) { return DecodeInstructionOriginal(instr); } |
| 6817 | 7937 |
| 6818 EVALUATE(LTDBR) { return DecodeInstructionOriginal(instr); } | 7938 EVALUATE(LTDBR) { |
| 7939 DCHECK_OPCODE(LTDBR); | |
| 7940 DECODE_RRE_INSTRUCTION(r1, r2); | |
| 7941 int64_t r2_val = get_d_register(r2); | |
| 7942 SetS390ConditionCode<double>(bit_cast<double, int64_t>(r2_val), 0.0); | |
| 7943 set_d_register(r1, r2_val); | |
| 7944 return length; | |
| 7945 } | |
| 6819 | 7946 |
| 6820 EVALUATE(LCDBR) { return DecodeInstructionOriginal(instr); } | 7947 EVALUATE(LCDBR) { |
| 7948 DCHECK_OPCODE(LCDBR); | |
| 7949 DECODE_RRE_INSTRUCTION(r1, r2); | |
| 7950 double r1_val = get_double_from_d_register(r1); | |
| 7951 double r2_val = get_double_from_d_register(r2); | |
| 7952 r1_val = -r2_val; | |
| 7953 set_d_register_from_double(r1, r1_val); | |
| 7954 if (r2_val != r2_val) { // input is NaN | |
| 7955 condition_reg_ = CC_OF; | |
| 7956 } else if (r2_val == 0) { | |
| 7957 condition_reg_ = CC_EQ; | |
| 7958 } else if (r2_val < 0) { | |
| 7959 condition_reg_ = CC_LT; | |
| 7960 } else if (r2_val > 0) { | |
| 7961 condition_reg_ = CC_GT; | |
| 7962 } | |
| 7963 return length; | |
| 7964 } | |
| 6821 | 7965 |
| 6822 EVALUATE(SQEBR) { return DecodeInstructionOriginal(instr); } | 7966 EVALUATE(SQEBR) { return DecodeInstructionOriginal(instr); } |
| 6823 | 7967 |
| 6824 EVALUATE(SQDBR) { return DecodeInstructionOriginal(instr); } | 7968 EVALUATE(SQDBR) { return DecodeInstructionOriginal(instr); } |
| 6825 | 7969 |
| 6826 EVALUATE(SQXBR) { return DecodeInstructionOriginal(instr); } | 7970 EVALUATE(SQXBR) { return DecodeInstructionOriginal(instr); } |
| 6827 | 7971 |
| 6828 EVALUATE(MEEBR) { return DecodeInstructionOriginal(instr); } | 7972 EVALUATE(MEEBR) { return DecodeInstructionOriginal(instr); } |
| 6829 | 7973 |
| 6830 EVALUATE(KDBR) { return DecodeInstructionOriginal(instr); } | 7974 EVALUATE(KDBR) { return DecodeInstructionOriginal(instr); } |
| (...skipping 858 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7689 | 8833 |
| 7690 EVALUATE(CXZT) { return DecodeInstructionOriginal(instr); } | 8834 EVALUATE(CXZT) { return DecodeInstructionOriginal(instr); } |
| 7691 | 8835 |
| 7692 #undef EVALUATE | 8836 #undef EVALUATE |
| 7693 | 8837 |
| 7694 } // namespace internal | 8838 } // namespace internal |
| 7695 } // namespace v8 | 8839 } // namespace v8 |
| 7696 | 8840 |
| 7697 #endif // USE_SIMULATOR | 8841 #endif // USE_SIMULATOR |
| 7698 #endif // V8_TARGET_ARCH_S390 | 8842 #endif // V8_TARGET_ARCH_S390 |
| OLD | NEW |