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