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 |