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 "src/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
6 | 6 |
7 #include "src/arm/macro-assembler-arm.h" | 7 #include "src/arm/macro-assembler-arm.h" |
8 #include "src/assembler-inl.h" | 8 #include "src/assembler-inl.h" |
9 #include "src/compilation-info.h" | 9 #include "src/compilation-info.h" |
10 #include "src/compiler/code-generator-impl.h" | 10 #include "src/compiler/code-generator-impl.h" |
(...skipping 1594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1605 } | 1605 } |
1606 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1606 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1607 break; | 1607 break; |
1608 case kArmPoke: { | 1608 case kArmPoke: { |
1609 int const slot = MiscField::decode(instr->opcode()); | 1609 int const slot = MiscField::decode(instr->opcode()); |
1610 __ str(i.InputRegister(0), MemOperand(sp, slot * kPointerSize)); | 1610 __ str(i.InputRegister(0), MemOperand(sp, slot * kPointerSize)); |
1611 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1611 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1612 break; | 1612 break; |
1613 } | 1613 } |
1614 case kArmF32x4Splat: { | 1614 case kArmF32x4Splat: { |
1615 __ vdup(i.OutputSimd128Register(), i.InputFloatRegister(0)); | 1615 SwVfpRegister src = i.InputFloatRegister(0); |
| 1616 DwVfpRegister src_d = DwVfpRegister::from_code(src.code() / 2); |
| 1617 int src_index = src.code() & 0x1; |
| 1618 __ vdup(Neon32, i.OutputSimd128Register(), src_d, src_index); |
1616 break; | 1619 break; |
1617 } | 1620 } |
1618 case kArmF32x4ExtractLane: { | 1621 case kArmF32x4ExtractLane: { |
1619 __ ExtractLane(i.OutputFloatRegister(), i.InputSimd128Register(0), | 1622 __ ExtractLane(i.OutputFloatRegister(), i.InputSimd128Register(0), |
1620 kScratchReg, i.InputInt8(1)); | 1623 i.InputInt8(1)); |
1621 break; | 1624 break; |
1622 } | 1625 } |
1623 case kArmF32x4ReplaceLane: { | 1626 case kArmF32x4ReplaceLane: { |
1624 __ ReplaceLane(i.OutputSimd128Register(), i.InputSimd128Register(0), | 1627 __ ReplaceLane(i.OutputSimd128Register(), i.InputSimd128Register(0), |
1625 i.InputFloatRegister(2), kScratchReg, i.InputInt8(1)); | 1628 i.InputFloatRegister(2), i.InputInt8(1)); |
1626 break; | 1629 break; |
1627 } | 1630 } |
1628 case kArmF32x4SConvertI32x4: { | 1631 case kArmF32x4SConvertI32x4: { |
1629 __ vcvt_f32_s32(i.OutputSimd128Register(), i.InputSimd128Register(0)); | 1632 __ vcvt_f32_s32(i.OutputSimd128Register(), i.InputSimd128Register(0)); |
1630 break; | 1633 break; |
1631 } | 1634 } |
1632 case kArmF32x4UConvertI32x4: { | 1635 case kArmF32x4UConvertI32x4: { |
1633 __ vcvt_f32_u32(i.OutputSimd128Register(), i.InputSimd128Register(0)); | 1636 __ vcvt_f32_u32(i.OutputSimd128Register(), i.InputSimd128Register(0)); |
1634 break; | 1637 break; |
1635 } | 1638 } |
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2212 int src0_code = src0.code() * 4; | 2215 int src0_code = src0.code() * 4; |
2213 int src1_code = src1.code() * 4; | 2216 int src1_code = src1.code() * 4; |
2214 int32_t shuffle = i.InputInt32(2); | 2217 int32_t shuffle = i.InputInt32(2); |
2215 for (int i = 0; i < 4; i++) { | 2218 for (int i = 0; i < 4; i++) { |
2216 int lane = shuffle & 0x7; | 2219 int lane = shuffle & 0x7; |
2217 int src_code = src0_code; | 2220 int src_code = src0_code; |
2218 if (lane >= 4) { | 2221 if (lane >= 4) { |
2219 src_code = src1_code; | 2222 src_code = src1_code; |
2220 lane &= 0x3; | 2223 lane &= 0x3; |
2221 } | 2224 } |
2222 __ VmovExtended(dst_code + i, src_code + lane, kScratchReg); | 2225 __ VmovExtended(dst_code + i, src_code + lane); |
2223 shuffle >>= 8; | 2226 shuffle >>= 8; |
2224 } | 2227 } |
2225 break; | 2228 break; |
2226 } | 2229 } |
2227 case kArmS32x4TransposeRight: { | 2230 case kArmS32x4TransposeRight: { |
2228 Simd128Register dst = i.OutputSimd128Register(), | 2231 Simd128Register dst = i.OutputSimd128Register(), |
2229 src1 = i.InputSimd128Register(1); | 2232 src1 = i.InputSimd128Register(1); |
2230 DCHECK(dst.is(i.InputSimd128Register(0))); | 2233 DCHECK(dst.is(i.InputSimd128Register(0))); |
2231 // src0 = [4, 5, 6, 7], src1 = [0, 1, 2, 3] (flipped from TransposeLeft). | 2234 // src0 = [4, 5, 6, 7], src1 = [0, 1, 2, 3] (flipped from TransposeLeft). |
2232 __ vmov(kScratchQuadReg, src1); | 2235 __ vmov(kScratchQuadReg, src1); |
(...skipping 798 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3031 } else { | 3034 } else { |
3032 DCHECK(destination->IsDoubleStackSlot()); | 3035 DCHECK(destination->IsDoubleStackSlot()); |
3033 __ vstr(src, g.ToMemOperand(destination)); | 3036 __ vstr(src, g.ToMemOperand(destination)); |
3034 } | 3037 } |
3035 } else if (rep == MachineRepresentation::kFloat32) { | 3038 } else if (rep == MachineRepresentation::kFloat32) { |
3036 // GapResolver may give us reg codes that don't map to actual s-registers. | 3039 // GapResolver may give us reg codes that don't map to actual s-registers. |
3037 // Generate code to work around those cases. | 3040 // Generate code to work around those cases. |
3038 int src_code = LocationOperand::cast(source)->register_code(); | 3041 int src_code = LocationOperand::cast(source)->register_code(); |
3039 if (destination->IsFloatRegister()) { | 3042 if (destination->IsFloatRegister()) { |
3040 int dst_code = LocationOperand::cast(destination)->register_code(); | 3043 int dst_code = LocationOperand::cast(destination)->register_code(); |
3041 __ VmovExtended(dst_code, src_code, kScratchReg); | 3044 __ VmovExtended(dst_code, src_code); |
3042 } else { | 3045 } else { |
3043 DCHECK(destination->IsFloatStackSlot()); | 3046 DCHECK(destination->IsFloatStackSlot()); |
3044 __ VmovExtended(g.ToMemOperand(destination), src_code, kScratchReg); | 3047 __ VmovExtended(g.ToMemOperand(destination), src_code); |
3045 } | 3048 } |
3046 } else { | 3049 } else { |
3047 DCHECK_EQ(MachineRepresentation::kSimd128, rep); | 3050 DCHECK_EQ(MachineRepresentation::kSimd128, rep); |
3048 QwNeonRegister src = g.ToSimd128Register(source); | 3051 QwNeonRegister src = g.ToSimd128Register(source); |
3049 if (destination->IsSimd128Register()) { | 3052 if (destination->IsSimd128Register()) { |
3050 QwNeonRegister dst = g.ToSimd128Register(destination); | 3053 QwNeonRegister dst = g.ToSimd128Register(destination); |
3051 __ Move(dst, src); | 3054 __ Move(dst, src); |
3052 } else { | 3055 } else { |
3053 DCHECK(destination->IsSimd128StackSlot()); | 3056 DCHECK(destination->IsSimd128StackSlot()); |
3054 MemOperand dst = g.ToMemOperand(destination); | 3057 MemOperand dst = g.ToMemOperand(destination); |
3055 __ add(kScratchReg, dst.rn(), Operand(dst.offset())); | 3058 __ add(kScratchReg, dst.rn(), Operand(dst.offset())); |
3056 __ vst1(Neon8, NeonListOperand(src.low(), 2), | 3059 __ vst1(Neon8, NeonListOperand(src.low(), 2), |
3057 NeonMemOperand(kScratchReg)); | 3060 NeonMemOperand(kScratchReg)); |
3058 } | 3061 } |
3059 } | 3062 } |
3060 } else if (source->IsFPStackSlot()) { | 3063 } else if (source->IsFPStackSlot()) { |
3061 MemOperand src = g.ToMemOperand(source); | 3064 MemOperand src = g.ToMemOperand(source); |
3062 MachineRepresentation rep = | 3065 MachineRepresentation rep = |
3063 LocationOperand::cast(destination)->representation(); | 3066 LocationOperand::cast(destination)->representation(); |
3064 if (destination->IsFPRegister()) { | 3067 if (destination->IsFPRegister()) { |
3065 if (rep == MachineRepresentation::kFloat64) { | 3068 if (rep == MachineRepresentation::kFloat64) { |
3066 __ vldr(g.ToDoubleRegister(destination), src); | 3069 __ vldr(g.ToDoubleRegister(destination), src); |
3067 } else if (rep == MachineRepresentation::kFloat32) { | 3070 } else if (rep == MachineRepresentation::kFloat32) { |
3068 // GapResolver may give us reg codes that don't map to actual | 3071 // GapResolver may give us reg codes that don't map to actual |
3069 // s-registers. Generate code to work around those cases. | 3072 // s-registers. Generate code to work around those cases. |
3070 int dst_code = LocationOperand::cast(destination)->register_code(); | 3073 int dst_code = LocationOperand::cast(destination)->register_code(); |
3071 __ VmovExtended(dst_code, src, kScratchReg); | 3074 __ VmovExtended(dst_code, src); |
3072 } else { | 3075 } else { |
3073 DCHECK_EQ(MachineRepresentation::kSimd128, rep); | 3076 DCHECK_EQ(MachineRepresentation::kSimd128, rep); |
3074 QwNeonRegister dst = g.ToSimd128Register(destination); | 3077 QwNeonRegister dst = g.ToSimd128Register(destination); |
3075 __ add(kScratchReg, src.rn(), Operand(src.offset())); | 3078 __ add(kScratchReg, src.rn(), Operand(src.offset())); |
3076 __ vld1(Neon8, NeonListOperand(dst.low(), 2), | 3079 __ vld1(Neon8, NeonListOperand(dst.low(), 2), |
3077 NeonMemOperand(kScratchReg)); | 3080 NeonMemOperand(kScratchReg)); |
3078 } | 3081 } |
3079 } else if (rep == MachineRepresentation::kFloat64) { | 3082 } else if (rep == MachineRepresentation::kFloat64) { |
3080 DCHECK(destination->IsFPStackSlot()); | 3083 DCHECK(destination->IsFPStackSlot()); |
3081 if (rep == MachineRepresentation::kFloat64) { | 3084 if (rep == MachineRepresentation::kFloat64) { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3145 DCHECK(destination->IsFPStackSlot()); | 3148 DCHECK(destination->IsFPStackSlot()); |
3146 MemOperand dst = g.ToMemOperand(destination); | 3149 MemOperand dst = g.ToMemOperand(destination); |
3147 __ Move(temp, src); | 3150 __ Move(temp, src); |
3148 __ vldr(src, dst); | 3151 __ vldr(src, dst); |
3149 __ vstr(temp, dst); | 3152 __ vstr(temp, dst); |
3150 } | 3153 } |
3151 } else if (rep == MachineRepresentation::kFloat32) { | 3154 } else if (rep == MachineRepresentation::kFloat32) { |
3152 int src_code = LocationOperand::cast(source)->register_code(); | 3155 int src_code = LocationOperand::cast(source)->register_code(); |
3153 if (destination->IsFPRegister()) { | 3156 if (destination->IsFPRegister()) { |
3154 int dst_code = LocationOperand::cast(destination)->register_code(); | 3157 int dst_code = LocationOperand::cast(destination)->register_code(); |
3155 __ VmovExtended(temp.low().code(), src_code, kScratchReg); | 3158 __ VmovExtended(temp.low().code(), src_code); |
3156 __ VmovExtended(src_code, dst_code, kScratchReg); | 3159 __ VmovExtended(src_code, dst_code); |
3157 __ VmovExtended(dst_code, temp.low().code(), kScratchReg); | 3160 __ VmovExtended(dst_code, temp.low().code()); |
3158 } else { | 3161 } else { |
3159 DCHECK(destination->IsFPStackSlot()); | 3162 DCHECK(destination->IsFPStackSlot()); |
3160 MemOperand dst = g.ToMemOperand(destination); | 3163 MemOperand dst = g.ToMemOperand(destination); |
3161 __ VmovExtended(temp.low().code(), src_code, kScratchReg); | 3164 __ VmovExtended(temp.low().code(), src_code); |
3162 __ VmovExtended(src_code, dst, kScratchReg); | 3165 __ VmovExtended(src_code, dst); |
3163 __ vstr(temp.low(), dst); | 3166 __ vstr(temp.low(), dst); |
3164 } | 3167 } |
3165 } else { | 3168 } else { |
3166 DCHECK_EQ(MachineRepresentation::kSimd128, rep); | 3169 DCHECK_EQ(MachineRepresentation::kSimd128, rep); |
3167 QwNeonRegister src = g.ToSimd128Register(source); | 3170 QwNeonRegister src = g.ToSimd128Register(source); |
3168 if (destination->IsFPRegister()) { | 3171 if (destination->IsFPRegister()) { |
3169 QwNeonRegister dst = g.ToSimd128Register(destination); | 3172 QwNeonRegister dst = g.ToSimd128Register(destination); |
3170 __ Swap(src, dst); | 3173 __ Swap(src, dst); |
3171 } else { | 3174 } else { |
3172 DCHECK(destination->IsFPStackSlot()); | 3175 DCHECK(destination->IsFPStackSlot()); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3244 padding_size -= v8::internal::Assembler::kInstrSize; | 3247 padding_size -= v8::internal::Assembler::kInstrSize; |
3245 } | 3248 } |
3246 } | 3249 } |
3247 } | 3250 } |
3248 | 3251 |
3249 #undef __ | 3252 #undef __ |
3250 | 3253 |
3251 } // namespace compiler | 3254 } // namespace compiler |
3252 } // namespace internal | 3255 } // namespace internal |
3253 } // namespace v8 | 3256 } // namespace v8 |
OLD | NEW |