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 3801 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3812 int64_t value = get_register((r1 + i) % 16); | 3812 int64_t value = get_register((r1 + i) % 16); |
3813 WriteDW(rb_val + offset + 8 * i, value); | 3813 WriteDW(rb_val + offset + 8 * i, value); |
3814 } else { | 3814 } else { |
3815 DCHECK(false); | 3815 DCHECK(false); |
3816 } | 3816 } |
3817 } | 3817 } |
3818 break; | 3818 break; |
3819 } | 3819 } |
3820 case SLLK: | 3820 case SLLK: |
3821 case RLL: | 3821 case RLL: |
3822 case SRLK: { | 3822 case SRLK: |
3823 // For SLLK/SRLL, the 32-bit third operand is shifted the number | |
3824 // of bits specified by the second-operand address, and the result is | |
3825 // placed at the first-operand location. Except for when the R1 and R3 | |
3826 // fields designate the same register, the third operand remains | |
3827 // unchanged in general register R3. | |
3828 int r1 = rsyInstr->R1Value(); | |
3829 int r3 = rsyInstr->R3Value(); | |
3830 int b2 = rsyInstr->B2Value(); | |
3831 intptr_t d2 = rsyInstr->D2Value(); | |
3832 // only takes rightmost 6 bits | |
3833 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); | |
3834 int shiftBits = (b2_val + d2) & 0x3F; | |
3835 // unsigned | |
3836 uint32_t r3_val = get_low_register<uint32_t>(r3); | |
3837 uint32_t alu_out = 0; | |
3838 if (SLLK == op) { | |
3839 alu_out = r3_val << shiftBits; | |
3840 } else if (SRLK == op) { | |
3841 alu_out = r3_val >> shiftBits; | |
3842 } else if (RLL == op) { | |
3843 uint32_t rotateBits = r3_val >> (32 - shiftBits); | |
3844 alu_out = (r3_val << shiftBits) | (rotateBits); | |
3845 } else { | |
3846 UNREACHABLE(); | |
3847 } | |
3848 set_low_register(r1, alu_out); | |
3849 break; | |
3850 } | |
3851 case SLLG: | 3823 case SLLG: |
| 3824 case RLLG: |
3852 case SRLG: { | 3825 case SRLG: { |
3853 // For SLLG/SRLG, the 64-bit third operand is shifted the number | 3826 DecodeSixByteBitShift(instr); |
3854 // of bits specified by the second-operand address, and the result is | |
3855 // placed at the first-operand location. Except for when the R1 and R3 | |
3856 // fields designate the same register, the third operand remains | |
3857 // unchanged in general register R3. | |
3858 int r1 = rsyInstr->R1Value(); | |
3859 int r3 = rsyInstr->R3Value(); | |
3860 int b2 = rsyInstr->B2Value(); | |
3861 intptr_t d2 = rsyInstr->D2Value(); | |
3862 // only takes rightmost 6 bits | |
3863 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); | |
3864 int shiftBits = (b2_val + d2) & 0x3F; | |
3865 // unsigned | |
3866 uint64_t r3_val = get_register(r3); | |
3867 uint64_t alu_out = 0; | |
3868 if (op == SLLG) { | |
3869 alu_out = r3_val << shiftBits; | |
3870 } else if (op == SRLG) { | |
3871 alu_out = r3_val >> shiftBits; | |
3872 } else { | |
3873 UNREACHABLE(); | |
3874 } | |
3875 set_register(r1, alu_out); | |
3876 break; | 3827 break; |
3877 } | 3828 } |
3878 case SLAK: | 3829 case SLAK: |
3879 case SRAK: { | 3830 case SRAK: { |
3880 // 32-bit non-clobbering shift-left/right arithmetic | 3831 // 32-bit non-clobbering shift-left/right arithmetic |
3881 int r1 = rsyInstr->R1Value(); | 3832 int r1 = rsyInstr->R1Value(); |
3882 int r3 = rsyInstr->R3Value(); | 3833 int r3 = rsyInstr->R3Value(); |
3883 int b2 = rsyInstr->B2Value(); | 3834 int b2 = rsyInstr->B2Value(); |
3884 intptr_t d2 = rsyInstr->D2Value(); | 3835 intptr_t d2 = rsyInstr->D2Value(); |
3885 // only takes rightmost 6 bits | 3836 // only takes rightmost 6 bits |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4189 SetS390ConditionCode<int64_t>(selected_val, 0); | 4140 SetS390ConditionCode<int64_t>(selected_val, 0); |
4190 set_register(r1, selected_val); | 4141 set_register(r1, selected_val); |
4191 break; | 4142 break; |
4192 } | 4143 } |
4193 default: | 4144 default: |
4194 return DecodeSixByteArithmetic(instr); | 4145 return DecodeSixByteArithmetic(instr); |
4195 } | 4146 } |
4196 return true; | 4147 return true; |
4197 } | 4148 } |
4198 | 4149 |
| 4150 void Simulator::DecodeSixByteBitShift(Instruction* instr) { |
| 4151 Opcode op = instr->S390OpcodeValue(); |
| 4152 |
| 4153 // Pre-cast instruction to various types |
| 4154 |
| 4155 RSYInstruction* rsyInstr = reinterpret_cast<RSYInstruction*>(instr); |
| 4156 |
| 4157 switch (op) { |
| 4158 case SLLK: |
| 4159 case RLL: |
| 4160 case SRLK: { |
| 4161 // For SLLK/SRLL, the 32-bit third operand is shifted the number |
| 4162 // of bits specified by the second-operand address, and the result is |
| 4163 // placed at the first-operand location. Except for when the R1 and R3 |
| 4164 // fields designate the same register, the third operand remains |
| 4165 // unchanged in general register R3. |
| 4166 int r1 = rsyInstr->R1Value(); |
| 4167 int r3 = rsyInstr->R3Value(); |
| 4168 int b2 = rsyInstr->B2Value(); |
| 4169 intptr_t d2 = rsyInstr->D2Value(); |
| 4170 // only takes rightmost 6 bits |
| 4171 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
| 4172 int shiftBits = (b2_val + d2) & 0x3F; |
| 4173 // unsigned |
| 4174 uint32_t r3_val = get_low_register<uint32_t>(r3); |
| 4175 uint32_t alu_out = 0; |
| 4176 if (SLLK == op) { |
| 4177 alu_out = r3_val << shiftBits; |
| 4178 } else if (SRLK == op) { |
| 4179 alu_out = r3_val >> shiftBits; |
| 4180 } else if (RLL == op) { |
| 4181 uint32_t rotateBits = r3_val >> (32 - shiftBits); |
| 4182 alu_out = (r3_val << shiftBits) | (rotateBits); |
| 4183 } else { |
| 4184 UNREACHABLE(); |
| 4185 } |
| 4186 set_low_register(r1, alu_out); |
| 4187 break; |
| 4188 } |
| 4189 case SLLG: |
| 4190 case RLLG: |
| 4191 case SRLG: { |
| 4192 // For SLLG/SRLG, the 64-bit third operand is shifted the number |
| 4193 // of bits specified by the second-operand address, and the result is |
| 4194 // placed at the first-operand location. Except for when the R1 and R3 |
| 4195 // fields designate the same register, the third operand remains |
| 4196 // unchanged in general register R3. |
| 4197 int r1 = rsyInstr->R1Value(); |
| 4198 int r3 = rsyInstr->R3Value(); |
| 4199 int b2 = rsyInstr->B2Value(); |
| 4200 intptr_t d2 = rsyInstr->D2Value(); |
| 4201 // only takes rightmost 6 bits |
| 4202 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
| 4203 int shiftBits = (b2_val + d2) & 0x3F; |
| 4204 // unsigned |
| 4205 uint64_t r3_val = get_register(r3); |
| 4206 uint64_t alu_out = 0; |
| 4207 if (op == SLLG) { |
| 4208 alu_out = r3_val << shiftBits; |
| 4209 } else if (op == SRLG) { |
| 4210 alu_out = r3_val >> shiftBits; |
| 4211 } else if (op == RLLG) { |
| 4212 uint64_t rotateBits = r3_val >> (64 - shiftBits); |
| 4213 alu_out = (r3_val << shiftBits) | (rotateBits); |
| 4214 } else { |
| 4215 UNREACHABLE(); |
| 4216 } |
| 4217 set_register(r1, alu_out); |
| 4218 break; |
| 4219 } |
| 4220 default: |
| 4221 UNREACHABLE(); |
| 4222 } |
| 4223 } |
| 4224 |
4199 /** | 4225 /** |
4200 * Decodes and simulates six byte arithmetic instructions | 4226 * Decodes and simulates six byte arithmetic instructions |
4201 */ | 4227 */ |
4202 bool Simulator::DecodeSixByteArithmetic(Instruction* instr) { | 4228 bool Simulator::DecodeSixByteArithmetic(Instruction* instr) { |
4203 Opcode op = instr->S390OpcodeValue(); | 4229 Opcode op = instr->S390OpcodeValue(); |
4204 | 4230 |
4205 // Pre-cast instruction to various types | 4231 // Pre-cast instruction to various types |
4206 SIYInstruction* siyInstr = reinterpret_cast<SIYInstruction*>(instr); | 4232 SIYInstruction* siyInstr = reinterpret_cast<SIYInstruction*>(instr); |
4207 | 4233 |
4208 switch (op) { | 4234 switch (op) { |
(...skipping 773 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4982 uintptr_t address = *stack_slot; | 5008 uintptr_t address = *stack_slot; |
4983 set_register(sp, current_sp + sizeof(uintptr_t)); | 5009 set_register(sp, current_sp + sizeof(uintptr_t)); |
4984 return address; | 5010 return address; |
4985 } | 5011 } |
4986 | 5012 |
4987 } // namespace internal | 5013 } // namespace internal |
4988 } // namespace v8 | 5014 } // namespace v8 |
4989 | 5015 |
4990 #endif // USE_SIMULATOR | 5016 #endif // USE_SIMULATOR |
4991 #endif // V8_TARGET_ARCH_S390 | 5017 #endif // V8_TARGET_ARCH_S390 |
OLD | NEW |