| 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/compilation-info.h" | 8 #include "src/compilation-info.h" |
| 9 #include "src/compiler/code-generator-impl.h" | 9 #include "src/compiler/code-generator-impl.h" |
| 10 #include "src/compiler/gap-resolver.h" | 10 #include "src/compiler/gap-resolver.h" |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 MemOperand ToMemOperand(InstructionOperand* op) const { | 129 MemOperand ToMemOperand(InstructionOperand* op) const { |
| 130 DCHECK_NOT_NULL(op); | 130 DCHECK_NOT_NULL(op); |
| 131 DCHECK(op->IsStackSlot() || op->IsFPStackSlot()); | 131 DCHECK(op->IsStackSlot() || op->IsFPStackSlot()); |
| 132 return SlotToMemOperand(AllocatedOperand::cast(op)->index()); | 132 return SlotToMemOperand(AllocatedOperand::cast(op)->index()); |
| 133 } | 133 } |
| 134 | 134 |
| 135 MemOperand SlotToMemOperand(int slot) const { | 135 MemOperand SlotToMemOperand(int slot) const { |
| 136 FrameOffset offset = frame_access_state()->GetFrameOffset(slot); | 136 FrameOffset offset = frame_access_state()->GetFrameOffset(slot); |
| 137 return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset()); | 137 return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset()); |
| 138 } | 138 } |
| 139 | |
| 140 FloatRegister InputFloat32Register(size_t index) { | |
| 141 return ToFloat32Register(instr_->InputAt(index)); | |
| 142 } | |
| 143 | |
| 144 FloatRegister OutputFloat32Register() { | |
| 145 return ToFloat32Register(instr_->Output()); | |
| 146 } | |
| 147 | |
| 148 FloatRegister ToFloat32Register(InstructionOperand* op) { | |
| 149 return LowDwVfpRegister::from_code(ToDoubleRegister(op).code()).low(); | |
| 150 } | |
| 151 }; | 139 }; |
| 152 | 140 |
| 153 namespace { | 141 namespace { |
| 154 | 142 |
| 155 class OutOfLineLoadFloat32 final : public OutOfLineCode { | 143 class OutOfLineLoadFloat final : public OutOfLineCode { |
| 156 public: | 144 public: |
| 157 OutOfLineLoadFloat32(CodeGenerator* gen, SwVfpRegister result) | 145 OutOfLineLoadFloat(CodeGenerator* gen, SwVfpRegister result) |
| 158 : OutOfLineCode(gen), result_(result) {} | 146 : OutOfLineCode(gen), result_(result) {} |
| 159 | 147 |
| 160 void Generate() final { | 148 void Generate() final { |
| 161 // Compute sqrtf(-1.0f), which results in a quiet single-precision NaN. | 149 // Compute sqrtf(-1.0f), which results in a quiet single-precision NaN. |
| 162 __ vmov(result_, -1.0f); | 150 __ vmov(result_, -1.0f); |
| 163 __ vsqrt(result_, result_); | 151 __ vsqrt(result_, result_); |
| 164 } | 152 } |
| 165 | 153 |
| 166 private: | 154 private: |
| 167 SwVfpRegister const result_; | 155 SwVfpRegister const result_; |
| (...skipping 938 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1106 if (instr->InputAt(2)->IsImmediate()) { | 1094 if (instr->InputAt(2)->IsImmediate()) { |
| 1107 __ AsrPair(i.OutputRegister(0), i.OutputRegister(1), i.InputRegister(0), | 1095 __ AsrPair(i.OutputRegister(0), i.OutputRegister(1), i.InputRegister(0), |
| 1108 i.InputRegister(1), i.InputInt32(2)); | 1096 i.InputRegister(1), i.InputInt32(2)); |
| 1109 } else { | 1097 } else { |
| 1110 __ AsrPair(i.OutputRegister(0), i.OutputRegister(1), i.InputRegister(0), | 1098 __ AsrPair(i.OutputRegister(0), i.OutputRegister(1), i.InputRegister(0), |
| 1111 i.InputRegister(1), kScratchReg, i.InputRegister(2)); | 1099 i.InputRegister(1), kScratchReg, i.InputRegister(2)); |
| 1112 } | 1100 } |
| 1113 break; | 1101 break; |
| 1114 case kArmVcmpF32: | 1102 case kArmVcmpF32: |
| 1115 if (instr->InputAt(1)->IsFPRegister()) { | 1103 if (instr->InputAt(1)->IsFPRegister()) { |
| 1116 __ VFPCompareAndSetFlags(i.InputFloat32Register(0), | 1104 __ VFPCompareAndSetFlags(i.InputFloatRegister(0), |
| 1117 i.InputFloat32Register(1)); | 1105 i.InputFloatRegister(1)); |
| 1118 } else { | 1106 } else { |
| 1119 DCHECK(instr->InputAt(1)->IsImmediate()); | 1107 DCHECK(instr->InputAt(1)->IsImmediate()); |
| 1120 // 0.0 is the only immediate supported by vcmp instructions. | 1108 // 0.0 is the only immediate supported by vcmp instructions. |
| 1121 DCHECK(i.InputFloat32(1) == 0.0f); | 1109 DCHECK(i.InputFloat32(1) == 0.0f); |
| 1122 __ VFPCompareAndSetFlags(i.InputFloat32Register(0), i.InputFloat32(1)); | 1110 __ VFPCompareAndSetFlags(i.InputFloatRegister(0), i.InputFloat32(1)); |
| 1123 } | 1111 } |
| 1124 DCHECK_EQ(SetCC, i.OutputSBit()); | 1112 DCHECK_EQ(SetCC, i.OutputSBit()); |
| 1125 break; | 1113 break; |
| 1126 case kArmVaddF32: | 1114 case kArmVaddF32: |
| 1127 __ vadd(i.OutputFloat32Register(), i.InputFloat32Register(0), | 1115 __ vadd(i.OutputFloatRegister(), i.InputFloatRegister(0), |
| 1128 i.InputFloat32Register(1)); | 1116 i.InputFloatRegister(1)); |
| 1129 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1117 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 1130 break; | 1118 break; |
| 1131 case kArmVsubF32: | 1119 case kArmVsubF32: |
| 1132 __ vsub(i.OutputFloat32Register(), i.InputFloat32Register(0), | 1120 __ vsub(i.OutputFloatRegister(), i.InputFloatRegister(0), |
| 1133 i.InputFloat32Register(1)); | 1121 i.InputFloatRegister(1)); |
| 1134 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1122 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 1135 break; | 1123 break; |
| 1136 case kArmVmulF32: | 1124 case kArmVmulF32: |
| 1137 __ vmul(i.OutputFloat32Register(), i.InputFloat32Register(0), | 1125 __ vmul(i.OutputFloatRegister(), i.InputFloatRegister(0), |
| 1138 i.InputFloat32Register(1)); | 1126 i.InputFloatRegister(1)); |
| 1139 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1127 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 1140 break; | 1128 break; |
| 1141 case kArmVmlaF32: | 1129 case kArmVmlaF32: |
| 1142 __ vmla(i.OutputFloat32Register(), i.InputFloat32Register(1), | 1130 __ vmla(i.OutputFloatRegister(), i.InputFloatRegister(1), |
| 1143 i.InputFloat32Register(2)); | 1131 i.InputFloatRegister(2)); |
| 1144 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1132 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 1145 break; | 1133 break; |
| 1146 case kArmVmlsF32: | 1134 case kArmVmlsF32: |
| 1147 __ vmls(i.OutputFloat32Register(), i.InputFloat32Register(1), | 1135 __ vmls(i.OutputFloatRegister(), i.InputFloatRegister(1), |
| 1148 i.InputFloat32Register(2)); | 1136 i.InputFloatRegister(2)); |
| 1149 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1137 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 1150 break; | 1138 break; |
| 1151 case kArmVdivF32: | 1139 case kArmVdivF32: |
| 1152 __ vdiv(i.OutputFloat32Register(), i.InputFloat32Register(0), | 1140 __ vdiv(i.OutputFloatRegister(), i.InputFloatRegister(0), |
| 1153 i.InputFloat32Register(1)); | 1141 i.InputFloatRegister(1)); |
| 1154 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1142 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 1155 break; | 1143 break; |
| 1156 case kArmVsqrtF32: | 1144 case kArmVsqrtF32: |
| 1157 __ vsqrt(i.OutputFloat32Register(), i.InputFloat32Register(0)); | 1145 __ vsqrt(i.OutputFloatRegister(), i.InputFloatRegister(0)); |
| 1158 break; | 1146 break; |
| 1159 case kArmVabsF32: | 1147 case kArmVabsF32: |
| 1160 __ vabs(i.OutputFloat32Register(), i.InputFloat32Register(0)); | 1148 __ vabs(i.OutputFloatRegister(), i.InputFloatRegister(0)); |
| 1161 break; | 1149 break; |
| 1162 case kArmVnegF32: | 1150 case kArmVnegF32: |
| 1163 __ vneg(i.OutputFloat32Register(), i.InputFloat32Register(0)); | 1151 __ vneg(i.OutputFloatRegister(), i.InputFloatRegister(0)); |
| 1164 break; | 1152 break; |
| 1165 case kArmVcmpF64: | 1153 case kArmVcmpF64: |
| 1166 if (instr->InputAt(1)->IsFPRegister()) { | 1154 if (instr->InputAt(1)->IsFPRegister()) { |
| 1167 __ VFPCompareAndSetFlags(i.InputDoubleRegister(0), | 1155 __ VFPCompareAndSetFlags(i.InputDoubleRegister(0), |
| 1168 i.InputDoubleRegister(1)); | 1156 i.InputDoubleRegister(1)); |
| 1169 } else { | 1157 } else { |
| 1170 DCHECK(instr->InputAt(1)->IsImmediate()); | 1158 DCHECK(instr->InputAt(1)->IsImmediate()); |
| 1171 // 0.0 is the only immediate supported by vcmp instructions. | 1159 // 0.0 is the only immediate supported by vcmp instructions. |
| 1172 DCHECK(i.InputDouble(1) == 0.0); | 1160 DCHECK(i.InputDouble(1) == 0.0); |
| 1173 __ VFPCompareAndSetFlags(i.InputDoubleRegister(0), i.InputDouble(1)); | 1161 __ VFPCompareAndSetFlags(i.InputDoubleRegister(0), i.InputDouble(1)); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1222 __ vsqrt(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | 1210 __ vsqrt(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
| 1223 break; | 1211 break; |
| 1224 case kArmVabsF64: | 1212 case kArmVabsF64: |
| 1225 __ vabs(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | 1213 __ vabs(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
| 1226 break; | 1214 break; |
| 1227 case kArmVnegF64: | 1215 case kArmVnegF64: |
| 1228 __ vneg(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | 1216 __ vneg(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
| 1229 break; | 1217 break; |
| 1230 case kArmVrintmF32: { | 1218 case kArmVrintmF32: { |
| 1231 CpuFeatureScope scope(masm(), ARMv8); | 1219 CpuFeatureScope scope(masm(), ARMv8); |
| 1232 __ vrintm(i.OutputFloat32Register(), i.InputFloat32Register(0)); | 1220 __ vrintm(i.OutputFloatRegister(), i.InputFloatRegister(0)); |
| 1233 break; | 1221 break; |
| 1234 } | 1222 } |
| 1235 case kArmVrintmF64: { | 1223 case kArmVrintmF64: { |
| 1236 CpuFeatureScope scope(masm(), ARMv8); | 1224 CpuFeatureScope scope(masm(), ARMv8); |
| 1237 __ vrintm(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | 1225 __ vrintm(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
| 1238 break; | 1226 break; |
| 1239 } | 1227 } |
| 1240 case kArmVrintpF32: { | 1228 case kArmVrintpF32: { |
| 1241 CpuFeatureScope scope(masm(), ARMv8); | 1229 CpuFeatureScope scope(masm(), ARMv8); |
| 1242 __ vrintp(i.OutputFloat32Register(), i.InputFloat32Register(0)); | 1230 __ vrintp(i.OutputFloatRegister(), i.InputFloatRegister(0)); |
| 1243 break; | 1231 break; |
| 1244 } | 1232 } |
| 1245 case kArmVrintpF64: { | 1233 case kArmVrintpF64: { |
| 1246 CpuFeatureScope scope(masm(), ARMv8); | 1234 CpuFeatureScope scope(masm(), ARMv8); |
| 1247 __ vrintp(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | 1235 __ vrintp(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
| 1248 break; | 1236 break; |
| 1249 } | 1237 } |
| 1250 case kArmVrintzF32: { | 1238 case kArmVrintzF32: { |
| 1251 CpuFeatureScope scope(masm(), ARMv8); | 1239 CpuFeatureScope scope(masm(), ARMv8); |
| 1252 __ vrintz(i.OutputFloat32Register(), i.InputFloat32Register(0)); | 1240 __ vrintz(i.OutputFloatRegister(), i.InputFloatRegister(0)); |
| 1253 break; | 1241 break; |
| 1254 } | 1242 } |
| 1255 case kArmVrintzF64: { | 1243 case kArmVrintzF64: { |
| 1256 CpuFeatureScope scope(masm(), ARMv8); | 1244 CpuFeatureScope scope(masm(), ARMv8); |
| 1257 __ vrintz(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | 1245 __ vrintz(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
| 1258 break; | 1246 break; |
| 1259 } | 1247 } |
| 1260 case kArmVrintaF64: { | 1248 case kArmVrintaF64: { |
| 1261 CpuFeatureScope scope(masm(), ARMv8); | 1249 CpuFeatureScope scope(masm(), ARMv8); |
| 1262 __ vrinta(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | 1250 __ vrinta(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
| 1263 break; | 1251 break; |
| 1264 } | 1252 } |
| 1265 case kArmVrintnF32: { | 1253 case kArmVrintnF32: { |
| 1266 CpuFeatureScope scope(masm(), ARMv8); | 1254 CpuFeatureScope scope(masm(), ARMv8); |
| 1267 __ vrintn(i.OutputFloat32Register(), i.InputFloat32Register(0)); | 1255 __ vrintn(i.OutputFloatRegister(), i.InputFloatRegister(0)); |
| 1268 break; | 1256 break; |
| 1269 } | 1257 } |
| 1270 case kArmVrintnF64: { | 1258 case kArmVrintnF64: { |
| 1271 CpuFeatureScope scope(masm(), ARMv8); | 1259 CpuFeatureScope scope(masm(), ARMv8); |
| 1272 __ vrintn(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | 1260 __ vrintn(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
| 1273 break; | 1261 break; |
| 1274 } | 1262 } |
| 1275 case kArmVcvtF32F64: { | 1263 case kArmVcvtF32F64: { |
| 1276 __ vcvt_f32_f64(i.OutputFloat32Register(), i.InputDoubleRegister(0)); | 1264 __ vcvt_f32_f64(i.OutputFloatRegister(), i.InputDoubleRegister(0)); |
| 1277 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1265 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 1278 break; | 1266 break; |
| 1279 } | 1267 } |
| 1280 case kArmVcvtF64F32: { | 1268 case kArmVcvtF64F32: { |
| 1281 __ vcvt_f64_f32(i.OutputDoubleRegister(), i.InputFloat32Register(0)); | 1269 __ vcvt_f64_f32(i.OutputDoubleRegister(), i.InputFloatRegister(0)); |
| 1282 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1270 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 1283 break; | 1271 break; |
| 1284 } | 1272 } |
| 1285 case kArmVcvtF32S32: { | 1273 case kArmVcvtF32S32: { |
| 1286 SwVfpRegister scratch = kScratchDoubleReg.low(); | 1274 SwVfpRegister scratch = kScratchDoubleReg.low(); |
| 1287 __ vmov(scratch, i.InputRegister(0)); | 1275 __ vmov(scratch, i.InputRegister(0)); |
| 1288 __ vcvt_f32_s32(i.OutputFloat32Register(), scratch); | 1276 __ vcvt_f32_s32(i.OutputFloatRegister(), scratch); |
| 1289 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1277 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 1290 break; | 1278 break; |
| 1291 } | 1279 } |
| 1292 case kArmVcvtF32U32: { | 1280 case kArmVcvtF32U32: { |
| 1293 SwVfpRegister scratch = kScratchDoubleReg.low(); | 1281 SwVfpRegister scratch = kScratchDoubleReg.low(); |
| 1294 __ vmov(scratch, i.InputRegister(0)); | 1282 __ vmov(scratch, i.InputRegister(0)); |
| 1295 __ vcvt_f32_u32(i.OutputFloat32Register(), scratch); | 1283 __ vcvt_f32_u32(i.OutputFloatRegister(), scratch); |
| 1296 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1284 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 1297 break; | 1285 break; |
| 1298 } | 1286 } |
| 1299 case kArmVcvtF64S32: { | 1287 case kArmVcvtF64S32: { |
| 1300 SwVfpRegister scratch = kScratchDoubleReg.low(); | 1288 SwVfpRegister scratch = kScratchDoubleReg.low(); |
| 1301 __ vmov(scratch, i.InputRegister(0)); | 1289 __ vmov(scratch, i.InputRegister(0)); |
| 1302 __ vcvt_f64_s32(i.OutputDoubleRegister(), scratch); | 1290 __ vcvt_f64_s32(i.OutputDoubleRegister(), scratch); |
| 1303 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1291 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 1304 break; | 1292 break; |
| 1305 } | 1293 } |
| 1306 case kArmVcvtF64U32: { | 1294 case kArmVcvtF64U32: { |
| 1307 SwVfpRegister scratch = kScratchDoubleReg.low(); | 1295 SwVfpRegister scratch = kScratchDoubleReg.low(); |
| 1308 __ vmov(scratch, i.InputRegister(0)); | 1296 __ vmov(scratch, i.InputRegister(0)); |
| 1309 __ vcvt_f64_u32(i.OutputDoubleRegister(), scratch); | 1297 __ vcvt_f64_u32(i.OutputDoubleRegister(), scratch); |
| 1310 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1298 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 1311 break; | 1299 break; |
| 1312 } | 1300 } |
| 1313 case kArmVcvtS32F32: { | 1301 case kArmVcvtS32F32: { |
| 1314 SwVfpRegister scratch = kScratchDoubleReg.low(); | 1302 SwVfpRegister scratch = kScratchDoubleReg.low(); |
| 1315 __ vcvt_s32_f32(scratch, i.InputFloat32Register(0)); | 1303 __ vcvt_s32_f32(scratch, i.InputFloatRegister(0)); |
| 1316 __ vmov(i.OutputRegister(), scratch); | 1304 __ vmov(i.OutputRegister(), scratch); |
| 1317 // Avoid INT32_MAX as an overflow indicator and use INT32_MIN instead, | 1305 // Avoid INT32_MAX as an overflow indicator and use INT32_MIN instead, |
| 1318 // because INT32_MIN allows easier out-of-bounds detection. | 1306 // because INT32_MIN allows easier out-of-bounds detection. |
| 1319 __ cmn(i.OutputRegister(), Operand(1)); | 1307 __ cmn(i.OutputRegister(), Operand(1)); |
| 1320 __ mov(i.OutputRegister(), Operand(INT32_MIN), SBit::LeaveCC, vs); | 1308 __ mov(i.OutputRegister(), Operand(INT32_MIN), SBit::LeaveCC, vs); |
| 1321 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1309 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 1322 break; | 1310 break; |
| 1323 } | 1311 } |
| 1324 case kArmVcvtU32F32: { | 1312 case kArmVcvtU32F32: { |
| 1325 SwVfpRegister scratch = kScratchDoubleReg.low(); | 1313 SwVfpRegister scratch = kScratchDoubleReg.low(); |
| 1326 __ vcvt_u32_f32(scratch, i.InputFloat32Register(0)); | 1314 __ vcvt_u32_f32(scratch, i.InputFloatRegister(0)); |
| 1327 __ vmov(i.OutputRegister(), scratch); | 1315 __ vmov(i.OutputRegister(), scratch); |
| 1328 // Avoid UINT32_MAX as an overflow indicator and use 0 instead, | 1316 // Avoid UINT32_MAX as an overflow indicator and use 0 instead, |
| 1329 // because 0 allows easier out-of-bounds detection. | 1317 // because 0 allows easier out-of-bounds detection. |
| 1330 __ cmn(i.OutputRegister(), Operand(1)); | 1318 __ cmn(i.OutputRegister(), Operand(1)); |
| 1331 __ adc(i.OutputRegister(), i.OutputRegister(), Operand::Zero()); | 1319 __ adc(i.OutputRegister(), i.OutputRegister(), Operand::Zero()); |
| 1332 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1320 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 1333 break; | 1321 break; |
| 1334 } | 1322 } |
| 1335 case kArmVcvtS32F64: { | 1323 case kArmVcvtS32F64: { |
| 1336 SwVfpRegister scratch = kScratchDoubleReg.low(); | 1324 SwVfpRegister scratch = kScratchDoubleReg.low(); |
| 1337 __ vcvt_s32_f64(scratch, i.InputDoubleRegister(0)); | 1325 __ vcvt_s32_f64(scratch, i.InputDoubleRegister(0)); |
| 1338 __ vmov(i.OutputRegister(), scratch); | 1326 __ vmov(i.OutputRegister(), scratch); |
| 1339 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1327 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 1340 break; | 1328 break; |
| 1341 } | 1329 } |
| 1342 case kArmVcvtU32F64: { | 1330 case kArmVcvtU32F64: { |
| 1343 SwVfpRegister scratch = kScratchDoubleReg.low(); | 1331 SwVfpRegister scratch = kScratchDoubleReg.low(); |
| 1344 __ vcvt_u32_f64(scratch, i.InputDoubleRegister(0)); | 1332 __ vcvt_u32_f64(scratch, i.InputDoubleRegister(0)); |
| 1345 __ vmov(i.OutputRegister(), scratch); | 1333 __ vmov(i.OutputRegister(), scratch); |
| 1346 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1334 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 1347 break; | 1335 break; |
| 1348 } | 1336 } |
| 1349 case kArmVmovU32F32: | 1337 case kArmVmovU32F32: |
| 1350 __ vmov(i.OutputRegister(), i.InputFloat32Register(0)); | 1338 __ vmov(i.OutputRegister(), i.InputFloatRegister(0)); |
| 1351 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1339 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 1352 break; | 1340 break; |
| 1353 case kArmVmovF32U32: | 1341 case kArmVmovF32U32: |
| 1354 __ vmov(i.OutputFloat32Register(), i.InputRegister(0)); | 1342 __ vmov(i.OutputFloatRegister(), i.InputRegister(0)); |
| 1355 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1343 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 1356 break; | 1344 break; |
| 1357 case kArmVmovLowU32F64: | 1345 case kArmVmovLowU32F64: |
| 1358 __ VmovLow(i.OutputRegister(), i.InputDoubleRegister(0)); | 1346 __ VmovLow(i.OutputRegister(), i.InputDoubleRegister(0)); |
| 1359 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1347 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 1360 break; | 1348 break; |
| 1361 case kArmVmovLowF64U32: | 1349 case kArmVmovLowF64U32: |
| 1362 __ VmovLow(i.OutputDoubleRegister(), i.InputRegister(1)); | 1350 __ VmovLow(i.OutputDoubleRegister(), i.InputRegister(1)); |
| 1363 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1351 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 1364 break; | 1352 break; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1402 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1390 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 1403 break; | 1391 break; |
| 1404 case kArmLdr: | 1392 case kArmLdr: |
| 1405 __ ldr(i.OutputRegister(), i.InputOffset()); | 1393 __ ldr(i.OutputRegister(), i.InputOffset()); |
| 1406 break; | 1394 break; |
| 1407 case kArmStr: | 1395 case kArmStr: |
| 1408 __ str(i.InputRegister(0), i.InputOffset(1)); | 1396 __ str(i.InputRegister(0), i.InputOffset(1)); |
| 1409 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1397 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 1410 break; | 1398 break; |
| 1411 case kArmVldrF32: { | 1399 case kArmVldrF32: { |
| 1412 __ vldr(i.OutputFloat32Register(), i.InputOffset()); | 1400 __ vldr(i.OutputFloatRegister(), i.InputOffset()); |
| 1413 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1401 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 1414 break; | 1402 break; |
| 1415 } | 1403 } |
| 1416 case kArmVstrF32: | 1404 case kArmVstrF32: |
| 1417 __ vstr(i.InputFloat32Register(0), i.InputOffset(1)); | 1405 __ vstr(i.InputFloatRegister(0), i.InputOffset(1)); |
| 1418 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1406 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 1419 break; | 1407 break; |
| 1420 case kArmVldrF64: | 1408 case kArmVldrF64: |
| 1421 __ vldr(i.OutputDoubleRegister(), i.InputOffset()); | 1409 __ vldr(i.OutputDoubleRegister(), i.InputOffset()); |
| 1422 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1410 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 1423 break; | 1411 break; |
| 1424 case kArmVstrF64: | 1412 case kArmVstrF64: |
| 1425 __ vstr(i.InputDoubleRegister(0), i.InputOffset(1)); | 1413 __ vstr(i.InputDoubleRegister(0), i.InputOffset(1)); |
| 1426 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1414 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 1427 break; | 1415 break; |
| 1428 case kArmFloat32Max: { | 1416 case kArmFloat32Max: { |
| 1429 SwVfpRegister result = i.OutputFloat32Register(); | 1417 SwVfpRegister result = i.OutputFloatRegister(); |
| 1430 SwVfpRegister left = i.InputFloat32Register(0); | 1418 SwVfpRegister left = i.InputFloatRegister(0); |
| 1431 SwVfpRegister right = i.InputFloat32Register(1); | 1419 SwVfpRegister right = i.InputFloatRegister(1); |
| 1432 if (left.is(right)) { | 1420 if (left.is(right)) { |
| 1433 __ Move(result, left); | 1421 __ Move(result, left); |
| 1434 } else { | 1422 } else { |
| 1435 auto ool = new (zone()) OutOfLineFloat32Max(this, result, left, right); | 1423 auto ool = new (zone()) OutOfLineFloat32Max(this, result, left, right); |
| 1436 __ FloatMax(result, left, right, ool->entry()); | 1424 __ FloatMax(result, left, right, ool->entry()); |
| 1437 __ bind(ool->exit()); | 1425 __ bind(ool->exit()); |
| 1438 } | 1426 } |
| 1439 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1427 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 1440 break; | 1428 break; |
| 1441 } | 1429 } |
| 1442 case kArmFloat64Max: { | 1430 case kArmFloat64Max: { |
| 1443 DwVfpRegister result = i.OutputDoubleRegister(); | 1431 DwVfpRegister result = i.OutputDoubleRegister(); |
| 1444 DwVfpRegister left = i.InputDoubleRegister(0); | 1432 DwVfpRegister left = i.InputDoubleRegister(0); |
| 1445 DwVfpRegister right = i.InputDoubleRegister(1); | 1433 DwVfpRegister right = i.InputDoubleRegister(1); |
| 1446 if (left.is(right)) { | 1434 if (left.is(right)) { |
| 1447 __ Move(result, left); | 1435 __ Move(result, left); |
| 1448 } else { | 1436 } else { |
| 1449 auto ool = new (zone()) OutOfLineFloat64Max(this, result, left, right); | 1437 auto ool = new (zone()) OutOfLineFloat64Max(this, result, left, right); |
| 1450 __ FloatMax(result, left, right, ool->entry()); | 1438 __ FloatMax(result, left, right, ool->entry()); |
| 1451 __ bind(ool->exit()); | 1439 __ bind(ool->exit()); |
| 1452 } | 1440 } |
| 1453 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1441 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 1454 break; | 1442 break; |
| 1455 } | 1443 } |
| 1456 case kArmFloat32Min: { | 1444 case kArmFloat32Min: { |
| 1457 SwVfpRegister result = i.OutputFloat32Register(); | 1445 SwVfpRegister result = i.OutputFloatRegister(); |
| 1458 SwVfpRegister left = i.InputFloat32Register(0); | 1446 SwVfpRegister left = i.InputFloatRegister(0); |
| 1459 SwVfpRegister right = i.InputFloat32Register(1); | 1447 SwVfpRegister right = i.InputFloatRegister(1); |
| 1460 if (left.is(right)) { | 1448 if (left.is(right)) { |
| 1461 __ Move(result, left); | 1449 __ Move(result, left); |
| 1462 } else { | 1450 } else { |
| 1463 auto ool = new (zone()) OutOfLineFloat32Min(this, result, left, right); | 1451 auto ool = new (zone()) OutOfLineFloat32Min(this, result, left, right); |
| 1464 __ FloatMin(result, left, right, ool->entry()); | 1452 __ FloatMin(result, left, right, ool->entry()); |
| 1465 __ bind(ool->exit()); | 1453 __ bind(ool->exit()); |
| 1466 } | 1454 } |
| 1467 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1455 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 1468 break; | 1456 break; |
| 1469 } | 1457 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1488 break; | 1476 break; |
| 1489 } | 1477 } |
| 1490 case kArmPush: | 1478 case kArmPush: |
| 1491 if (instr->InputAt(0)->IsFPRegister()) { | 1479 if (instr->InputAt(0)->IsFPRegister()) { |
| 1492 LocationOperand* op = LocationOperand::cast(instr->InputAt(0)); | 1480 LocationOperand* op = LocationOperand::cast(instr->InputAt(0)); |
| 1493 if (op->representation() == MachineRepresentation::kFloat64) { | 1481 if (op->representation() == MachineRepresentation::kFloat64) { |
| 1494 __ vpush(i.InputDoubleRegister(0)); | 1482 __ vpush(i.InputDoubleRegister(0)); |
| 1495 frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize); | 1483 frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize); |
| 1496 } else { | 1484 } else { |
| 1497 DCHECK_EQ(MachineRepresentation::kFloat32, op->representation()); | 1485 DCHECK_EQ(MachineRepresentation::kFloat32, op->representation()); |
| 1498 __ vpush(i.InputFloat32Register(0)); | 1486 __ vpush(i.InputFloatRegister(0)); |
| 1499 frame_access_state()->IncreaseSPDelta(1); | 1487 frame_access_state()->IncreaseSPDelta(1); |
| 1500 } | 1488 } |
| 1501 } else { | 1489 } else { |
| 1502 __ push(i.InputRegister(0)); | 1490 __ push(i.InputRegister(0)); |
| 1503 frame_access_state()->IncreaseSPDelta(1); | 1491 frame_access_state()->IncreaseSPDelta(1); |
| 1504 } | 1492 } |
| 1505 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1493 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 1506 break; | 1494 break; |
| 1507 case kArmPoke: { | 1495 case kArmPoke: { |
| 1508 int const slot = MiscField::decode(instr->opcode()); | 1496 int const slot = MiscField::decode(instr->opcode()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1519 case kCheckedLoadInt16: | 1507 case kCheckedLoadInt16: |
| 1520 ASSEMBLE_CHECKED_LOAD_INTEGER(ldrsh); | 1508 ASSEMBLE_CHECKED_LOAD_INTEGER(ldrsh); |
| 1521 break; | 1509 break; |
| 1522 case kCheckedLoadUint16: | 1510 case kCheckedLoadUint16: |
| 1523 ASSEMBLE_CHECKED_LOAD_INTEGER(ldrh); | 1511 ASSEMBLE_CHECKED_LOAD_INTEGER(ldrh); |
| 1524 break; | 1512 break; |
| 1525 case kCheckedLoadWord32: | 1513 case kCheckedLoadWord32: |
| 1526 ASSEMBLE_CHECKED_LOAD_INTEGER(ldr); | 1514 ASSEMBLE_CHECKED_LOAD_INTEGER(ldr); |
| 1527 break; | 1515 break; |
| 1528 case kCheckedLoadFloat32: | 1516 case kCheckedLoadFloat32: |
| 1529 ASSEMBLE_CHECKED_LOAD_FP(Float32); | 1517 ASSEMBLE_CHECKED_LOAD_FP(Float); |
| 1530 break; | 1518 break; |
| 1531 case kCheckedLoadFloat64: | 1519 case kCheckedLoadFloat64: |
| 1532 ASSEMBLE_CHECKED_LOAD_FP(Double); | 1520 ASSEMBLE_CHECKED_LOAD_FP(Double); |
| 1533 break; | 1521 break; |
| 1534 case kCheckedStoreWord8: | 1522 case kCheckedStoreWord8: |
| 1535 ASSEMBLE_CHECKED_STORE_INTEGER(strb); | 1523 ASSEMBLE_CHECKED_STORE_INTEGER(strb); |
| 1536 break; | 1524 break; |
| 1537 case kCheckedStoreWord16: | 1525 case kCheckedStoreWord16: |
| 1538 ASSEMBLE_CHECKED_STORE_INTEGER(strh); | 1526 ASSEMBLE_CHECKED_STORE_INTEGER(strh); |
| 1539 break; | 1527 break; |
| 1540 case kCheckedStoreWord32: | 1528 case kCheckedStoreWord32: |
| 1541 ASSEMBLE_CHECKED_STORE_INTEGER(str); | 1529 ASSEMBLE_CHECKED_STORE_INTEGER(str); |
| 1542 break; | 1530 break; |
| 1543 case kCheckedStoreFloat32: | 1531 case kCheckedStoreFloat32: |
| 1544 ASSEMBLE_CHECKED_STORE_FP(Float32); | 1532 ASSEMBLE_CHECKED_STORE_FP(Float); |
| 1545 break; | 1533 break; |
| 1546 case kCheckedStoreFloat64: | 1534 case kCheckedStoreFloat64: |
| 1547 ASSEMBLE_CHECKED_STORE_FP(Double); | 1535 ASSEMBLE_CHECKED_STORE_FP(Double); |
| 1548 break; | 1536 break; |
| 1549 case kCheckedLoadWord64: | 1537 case kCheckedLoadWord64: |
| 1550 case kCheckedStoreWord64: | 1538 case kCheckedStoreWord64: |
| 1551 UNREACHABLE(); // currently unsupported checked int64 load/store. | 1539 UNREACHABLE(); // currently unsupported checked int64 load/store. |
| 1552 break; | 1540 break; |
| 1553 | 1541 |
| 1554 case kAtomicLoadInt8: | 1542 case kAtomicLoadInt8: |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1776 __ b(&return_label_); | 1764 __ b(&return_label_); |
| 1777 return; | 1765 return; |
| 1778 } else { | 1766 } else { |
| 1779 __ bind(&return_label_); | 1767 __ bind(&return_label_); |
| 1780 AssembleDeconstructFrame(); | 1768 AssembleDeconstructFrame(); |
| 1781 } | 1769 } |
| 1782 } | 1770 } |
| 1783 __ Ret(pop_count); | 1771 __ Ret(pop_count); |
| 1784 } | 1772 } |
| 1785 | 1773 |
| 1786 | |
| 1787 void CodeGenerator::AssembleMove(InstructionOperand* source, | 1774 void CodeGenerator::AssembleMove(InstructionOperand* source, |
| 1788 InstructionOperand* destination) { | 1775 InstructionOperand* destination) { |
| 1789 ArmOperandConverter g(this, nullptr); | 1776 ArmOperandConverter g(this, nullptr); |
| 1790 // Dispatch on the source and destination operand kinds. Not all | 1777 // Dispatch on the source and destination operand kinds. Not all |
| 1791 // combinations are possible. | 1778 // combinations are possible. |
| 1792 if (source->IsRegister()) { | 1779 if (source->IsRegister()) { |
| 1793 DCHECK(destination->IsRegister() || destination->IsStackSlot()); | 1780 DCHECK(destination->IsRegister() || destination->IsStackSlot()); |
| 1794 Register src = g.ToRegister(source); | 1781 Register src = g.ToRegister(source); |
| 1795 if (destination->IsRegister()) { | 1782 if (destination->IsRegister()) { |
| 1796 __ mov(g.ToRegister(destination), src); | 1783 __ mov(g.ToRegister(destination), src); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1845 __ Move(dst, src_object); | 1832 __ Move(dst, src_object); |
| 1846 } | 1833 } |
| 1847 break; | 1834 break; |
| 1848 } | 1835 } |
| 1849 case Constant::kRpoNumber: | 1836 case Constant::kRpoNumber: |
| 1850 UNREACHABLE(); // TODO(dcarney): loading RPO constants on arm. | 1837 UNREACHABLE(); // TODO(dcarney): loading RPO constants on arm. |
| 1851 break; | 1838 break; |
| 1852 } | 1839 } |
| 1853 if (destination->IsStackSlot()) __ str(dst, g.ToMemOperand(destination)); | 1840 if (destination->IsStackSlot()) __ str(dst, g.ToMemOperand(destination)); |
| 1854 } else if (src.type() == Constant::kFloat32) { | 1841 } else if (src.type() == Constant::kFloat32) { |
| 1855 if (destination->IsFPStackSlot()) { | 1842 if (destination->IsFloatStackSlot()) { |
| 1856 MemOperand dst = g.ToMemOperand(destination); | 1843 MemOperand dst = g.ToMemOperand(destination); |
| 1857 __ mov(ip, Operand(bit_cast<int32_t>(src.ToFloat32()))); | 1844 __ mov(ip, Operand(bit_cast<int32_t>(src.ToFloat32()))); |
| 1858 __ str(ip, dst); | 1845 __ str(ip, dst); |
| 1859 } else { | 1846 } else { |
| 1860 SwVfpRegister dst = g.ToFloat32Register(destination); | 1847 SwVfpRegister dst = g.ToFloatRegister(destination); |
| 1861 __ vmov(dst, src.ToFloat32()); | 1848 __ vmov(dst, src.ToFloat32()); |
| 1862 } | 1849 } |
| 1863 } else { | 1850 } else { |
| 1864 DCHECK_EQ(Constant::kFloat64, src.type()); | 1851 DCHECK_EQ(Constant::kFloat64, src.type()); |
| 1865 DwVfpRegister dst = destination->IsFPRegister() | 1852 DwVfpRegister dst = destination->IsFPRegister() |
| 1866 ? g.ToDoubleRegister(destination) | 1853 ? g.ToDoubleRegister(destination) |
| 1867 : kScratchDoubleReg; | 1854 : kScratchDoubleReg; |
| 1868 __ vmov(dst, src.ToFloat64(), kScratchReg); | 1855 __ vmov(dst, src.ToFloat64(), kScratchReg); |
| 1869 if (destination->IsFPStackSlot()) { | 1856 if (destination->IsDoubleStackSlot()) { |
| 1870 __ vstr(dst, g.ToMemOperand(destination)); | 1857 __ vstr(dst, g.ToMemOperand(destination)); |
| 1871 } | 1858 } |
| 1872 } | 1859 } |
| 1873 } else if (source->IsFPRegister()) { | 1860 } else if (source->IsFPRegister()) { |
| 1874 DwVfpRegister src = g.ToDoubleRegister(source); | 1861 MachineRepresentation rep = LocationOperand::cast(source)->representation(); |
| 1875 if (destination->IsFPRegister()) { | 1862 if (rep == MachineRepresentation::kFloat64) { |
| 1876 DwVfpRegister dst = g.ToDoubleRegister(destination); | 1863 DwVfpRegister src = g.ToDoubleRegister(source); |
| 1877 __ Move(dst, src); | 1864 if (destination->IsDoubleRegister()) { |
| 1865 DwVfpRegister dst = g.ToDoubleRegister(destination); |
| 1866 __ Move(dst, src); |
| 1867 } else { |
| 1868 DCHECK(destination->IsDoubleStackSlot()); |
| 1869 __ vstr(src, g.ToMemOperand(destination)); |
| 1870 } |
| 1878 } else { | 1871 } else { |
| 1879 DCHECK(destination->IsFPStackSlot()); | 1872 DCHECK_EQ(MachineRepresentation::kFloat32, rep); |
| 1880 __ vstr(src, g.ToMemOperand(destination)); | 1873 // GapResolver may give us reg codes that don't map to actual s-registers. |
| 1874 // Generate code to work around those cases. |
| 1875 int src_code = LocationOperand::cast(source)->register_code(); |
| 1876 if (destination->IsFloatRegister()) { |
| 1877 int dst_code = LocationOperand::cast(destination)->register_code(); |
| 1878 __ VmovExtended(dst_code, src_code, kScratchReg); |
| 1879 } else { |
| 1880 DCHECK(destination->IsFloatStackSlot()); |
| 1881 __ VmovExtended(g.ToMemOperand(destination), src_code, kScratchReg); |
| 1882 } |
| 1881 } | 1883 } |
| 1882 } else if (source->IsFPStackSlot()) { | 1884 } else if (source->IsFPStackSlot()) { |
| 1883 MemOperand src = g.ToMemOperand(source); | 1885 MemOperand src = g.ToMemOperand(source); |
| 1886 MachineRepresentation rep = |
| 1887 LocationOperand::cast(destination)->representation(); |
| 1884 if (destination->IsFPRegister()) { | 1888 if (destination->IsFPRegister()) { |
| 1889 if (rep == MachineRepresentation::kFloat64) { |
| 1885 __ vldr(g.ToDoubleRegister(destination), src); | 1890 __ vldr(g.ToDoubleRegister(destination), src); |
| 1891 } else { |
| 1892 DCHECK_EQ(MachineRepresentation::kFloat32, rep); |
| 1893 // GapResolver may give us reg codes that don't map to actual |
| 1894 // s-registers. Generate code to work around those cases. |
| 1895 int dst_code = LocationOperand::cast(destination)->register_code(); |
| 1896 __ VmovExtended(dst_code, src, kScratchReg); |
| 1897 } |
| 1886 } else { | 1898 } else { |
| 1887 DCHECK(destination->IsFPStackSlot()); | 1899 DCHECK(destination->IsFPStackSlot()); |
| 1900 if (rep == MachineRepresentation::kFloat64) { |
| 1888 DwVfpRegister temp = kScratchDoubleReg; | 1901 DwVfpRegister temp = kScratchDoubleReg; |
| 1889 __ vldr(temp, src); | 1902 __ vldr(temp, src); |
| 1890 __ vstr(temp, g.ToMemOperand(destination)); | 1903 __ vstr(temp, g.ToMemOperand(destination)); |
| 1904 } else { |
| 1905 DCHECK_EQ(MachineRepresentation::kFloat32, rep); |
| 1906 SwVfpRegister temp = kScratchDoubleReg.low(); |
| 1907 __ vldr(temp, src); |
| 1908 __ vstr(temp, g.ToMemOperand(destination)); |
| 1909 } |
| 1891 } | 1910 } |
| 1892 } else { | 1911 } else { |
| 1893 UNREACHABLE(); | 1912 UNREACHABLE(); |
| 1894 } | 1913 } |
| 1895 } | 1914 } |
| 1896 | 1915 |
| 1897 | 1916 |
| 1898 void CodeGenerator::AssembleSwap(InstructionOperand* source, | 1917 void CodeGenerator::AssembleSwap(InstructionOperand* source, |
| 1899 InstructionOperand* destination) { | 1918 InstructionOperand* destination) { |
| 1900 ArmOperandConverter g(this, nullptr); | 1919 ArmOperandConverter g(this, nullptr); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1920 DCHECK(destination->IsStackSlot()); | 1939 DCHECK(destination->IsStackSlot()); |
| 1921 Register temp_0 = kScratchReg; | 1940 Register temp_0 = kScratchReg; |
| 1922 SwVfpRegister temp_1 = kScratchDoubleReg.low(); | 1941 SwVfpRegister temp_1 = kScratchDoubleReg.low(); |
| 1923 MemOperand src = g.ToMemOperand(source); | 1942 MemOperand src = g.ToMemOperand(source); |
| 1924 MemOperand dst = g.ToMemOperand(destination); | 1943 MemOperand dst = g.ToMemOperand(destination); |
| 1925 __ ldr(temp_0, src); | 1944 __ ldr(temp_0, src); |
| 1926 __ vldr(temp_1, dst); | 1945 __ vldr(temp_1, dst); |
| 1927 __ str(temp_0, dst); | 1946 __ str(temp_0, dst); |
| 1928 __ vstr(temp_1, src); | 1947 __ vstr(temp_1, src); |
| 1929 } else if (source->IsFPRegister()) { | 1948 } else if (source->IsFPRegister()) { |
| 1949 MachineRepresentation rep = LocationOperand::cast(source)->representation(); |
| 1930 LowDwVfpRegister temp = kScratchDoubleReg; | 1950 LowDwVfpRegister temp = kScratchDoubleReg; |
| 1931 DwVfpRegister src = g.ToDoubleRegister(source); | 1951 if (rep == MachineRepresentation::kFloat64) { |
| 1932 if (destination->IsFPRegister()) { | 1952 DwVfpRegister src = g.ToDoubleRegister(source); |
| 1933 DwVfpRegister dst = g.ToDoubleRegister(destination); | 1953 if (destination->IsFPRegister()) { |
| 1934 __ vswp(src, dst); | 1954 DwVfpRegister dst = g.ToDoubleRegister(destination); |
| 1955 __ vswp(src, dst); |
| 1956 } else { |
| 1957 DCHECK(destination->IsFPStackSlot()); |
| 1958 MemOperand dst = g.ToMemOperand(destination); |
| 1959 __ Move(temp, src); |
| 1960 __ vldr(src, dst); |
| 1961 __ vstr(temp, dst); |
| 1962 } |
| 1935 } else { | 1963 } else { |
| 1936 DCHECK(destination->IsFPStackSlot()); | 1964 DCHECK_EQ(MachineRepresentation::kFloat32, rep); |
| 1937 MemOperand dst = g.ToMemOperand(destination); | 1965 int src_code = LocationOperand::cast(source)->register_code(); |
| 1938 __ Move(temp, src); | 1966 if (destination->IsFPRegister()) { |
| 1939 __ vldr(src, dst); | 1967 int dst_code = LocationOperand::cast(destination)->register_code(); |
| 1940 __ vstr(temp, dst); | 1968 __ VmovExtended(temp.low().code(), src_code, kScratchReg); |
| 1969 __ VmovExtended(src_code, dst_code, kScratchReg); |
| 1970 __ VmovExtended(dst_code, temp.low().code(), kScratchReg); |
| 1971 } else { |
| 1972 DCHECK(destination->IsFPStackSlot()); |
| 1973 MemOperand dst = g.ToMemOperand(destination); |
| 1974 __ VmovExtended(temp.low().code(), src_code, kScratchReg); |
| 1975 __ VmovExtended(src_code, dst, kScratchReg); |
| 1976 __ vstr(temp.low(), dst); |
| 1977 } |
| 1941 } | 1978 } |
| 1942 } else if (source->IsFPStackSlot()) { | 1979 } else if (source->IsFPStackSlot()) { |
| 1943 DCHECK(destination->IsFPStackSlot()); | 1980 DCHECK(destination->IsFPStackSlot()); |
| 1944 Register temp_0 = kScratchReg; | 1981 Register temp_0 = kScratchReg; |
| 1945 LowDwVfpRegister temp_1 = kScratchDoubleReg; | 1982 LowDwVfpRegister temp_1 = kScratchDoubleReg; |
| 1946 MemOperand src0 = g.ToMemOperand(source); | 1983 MemOperand src0 = g.ToMemOperand(source); |
| 1947 MemOperand dst0 = g.ToMemOperand(destination); | 1984 MemOperand dst0 = g.ToMemOperand(destination); |
| 1948 MemOperand src1(src0.rn(), src0.offset() + kPointerSize); | 1985 MachineRepresentation rep = LocationOperand::cast(source)->representation(); |
| 1949 MemOperand dst1(dst0.rn(), dst0.offset() + kPointerSize); | 1986 if (rep == MachineRepresentation::kFloat64) { |
| 1950 __ vldr(temp_1, dst0); // Save destination in temp_1. | 1987 MemOperand src1(src0.rn(), src0.offset() + kPointerSize); |
| 1951 __ ldr(temp_0, src0); // Then use temp_0 to copy source to destination. | 1988 MemOperand dst1(dst0.rn(), dst0.offset() + kPointerSize); |
| 1952 __ str(temp_0, dst0); | 1989 __ vldr(temp_1, dst0); // Save destination in temp_1. |
| 1953 __ ldr(temp_0, src1); | 1990 __ ldr(temp_0, src0); // Then use temp_0 to copy source to destination. |
| 1954 __ str(temp_0, dst1); | 1991 __ str(temp_0, dst0); |
| 1955 __ vstr(temp_1, src0); | 1992 __ ldr(temp_0, src1); |
| 1993 __ str(temp_0, dst1); |
| 1994 __ vstr(temp_1, src0); |
| 1995 } else { |
| 1996 DCHECK_EQ(MachineRepresentation::kFloat32, rep); |
| 1997 __ vldr(temp_1.low(), dst0); // Save destination in temp_1. |
| 1998 __ ldr(temp_0, src0); // Then use temp_0 to copy source to destination. |
| 1999 __ str(temp_0, dst0); |
| 2000 __ vstr(temp_1.low(), src0); |
| 2001 } |
| 1956 } else { | 2002 } else { |
| 1957 // No other combinations are possible. | 2003 // No other combinations are possible. |
| 1958 UNREACHABLE(); | 2004 UNREACHABLE(); |
| 1959 } | 2005 } |
| 1960 } | 2006 } |
| 1961 | 2007 |
| 1962 | |
| 1963 void CodeGenerator::AssembleJumpTable(Label** targets, size_t target_count) { | 2008 void CodeGenerator::AssembleJumpTable(Label** targets, size_t target_count) { |
| 1964 // On 32-bit ARM we emit the jump tables inline. | 2009 // On 32-bit ARM we emit the jump tables inline. |
| 1965 UNREACHABLE(); | 2010 UNREACHABLE(); |
| 1966 } | 2011 } |
| 1967 | 2012 |
| 1968 | 2013 |
| 1969 void CodeGenerator::EnsureSpaceForLazyDeopt() { | 2014 void CodeGenerator::EnsureSpaceForLazyDeopt() { |
| 1970 if (!info()->ShouldEnsureSpaceForLazyDeopt()) { | 2015 if (!info()->ShouldEnsureSpaceForLazyDeopt()) { |
| 1971 return; | 2016 return; |
| 1972 } | 2017 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1985 padding_size -= v8::internal::Assembler::kInstrSize; | 2030 padding_size -= v8::internal::Assembler::kInstrSize; |
| 1986 } | 2031 } |
| 1987 } | 2032 } |
| 1988 } | 2033 } |
| 1989 | 2034 |
| 1990 #undef __ | 2035 #undef __ |
| 1991 | 2036 |
| 1992 } // namespace compiler | 2037 } // namespace compiler |
| 1993 } // namespace internal | 2038 } // namespace internal |
| 1994 } // namespace v8 | 2039 } // namespace v8 |
| OLD | NEW |