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/compiler/code-generator-impl.h" | 8 #include "src/compiler/code-generator-impl.h" |
9 #include "src/compiler/gap-resolver.h" | 9 #include "src/compiler/gap-resolver.h" |
10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
11 #include "src/compiler/node-properties-inl.h" | 11 #include "src/compiler/node-properties-inl.h" |
12 #include "src/scopes.h" | 12 #include "src/scopes.h" |
13 | 13 |
14 namespace v8 { | 14 namespace v8 { |
15 namespace internal { | 15 namespace internal { |
16 namespace compiler { | 16 namespace compiler { |
17 | 17 |
18 #define __ masm()-> | 18 #define __ masm()-> |
19 | 19 |
20 | 20 |
21 #define kScratchReg r9 | 21 #define kScratchReg r9 |
22 | 22 |
23 | 23 |
24 // Adds Arm-specific methods to convert InstructionOperands. | 24 // Adds Arm-specific methods to convert InstructionOperands. |
25 class ArmOperandConverter : public InstructionOperandConverter { | 25 class ArmOperandConverter FINAL : public InstructionOperandConverter { |
titzer
2014/09/24 08:53:14
Is the final really necessary? This class is local
Benedikt Meurer
2014/09/25 06:09:31
Done.
| |
26 public: | 26 public: |
27 ArmOperandConverter(CodeGenerator* gen, Instruction* instr) | 27 ArmOperandConverter(CodeGenerator* gen, Instruction* instr) |
28 : InstructionOperandConverter(gen, instr) {} | 28 : InstructionOperandConverter(gen, instr) {} |
29 | 29 |
30 SwVfpRegister OutputFloat32Register(int index = 0) { | |
31 return ToFloat32Register(instr_->OutputAt(index)); | |
32 } | |
33 | |
34 SwVfpRegister InputFloat32Register(int index) { | |
35 return ToFloat32Register(instr_->InputAt(index)); | |
36 } | |
37 | |
38 SwVfpRegister ToFloat32Register(InstructionOperand* op) { | |
39 return ToFloat64Register(op).low(); | |
40 } | |
41 | |
42 LowDwVfpRegister OutputFloat64Register(int index = 0) { | |
43 return ToFloat64Register(instr_->OutputAt(index)); | |
44 } | |
45 | |
46 LowDwVfpRegister InputFloat64Register(int index) { | |
47 return ToFloat64Register(instr_->InputAt(index)); | |
48 } | |
49 | |
50 LowDwVfpRegister ToFloat64Register(InstructionOperand* op) { | |
51 return LowDwVfpRegister::from_code(ToDoubleRegister(op).code()); | |
52 } | |
53 | |
30 SBit OutputSBit() const { | 54 SBit OutputSBit() const { |
31 switch (instr_->flags_mode()) { | 55 switch (instr_->flags_mode()) { |
32 case kFlags_branch: | 56 case kFlags_branch: |
33 case kFlags_set: | 57 case kFlags_set: |
34 return SetCC; | 58 return SetCC; |
35 case kFlags_none: | 59 case kFlags_none: |
36 return LeaveCC; | 60 return LeaveCC; |
37 } | 61 } |
38 UNREACHABLE(); | 62 UNREACHABLE(); |
39 return LeaveCC; | 63 return LeaveCC; |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
171 break; | 195 break; |
172 case kArchNop: | 196 case kArchNop: |
173 // don't emit code for nops. | 197 // don't emit code for nops. |
174 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 198 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
175 break; | 199 break; |
176 case kArchRet: | 200 case kArchRet: |
177 AssembleReturn(); | 201 AssembleReturn(); |
178 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 202 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
179 break; | 203 break; |
180 case kArchTruncateDoubleToI: | 204 case kArchTruncateDoubleToI: |
181 __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0)); | 205 __ TruncateDoubleToI(i.OutputRegister(), i.InputFloat64Register(0)); |
182 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 206 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
183 break; | 207 break; |
184 case kArmAdd: | 208 case kArmAdd: |
185 __ add(i.OutputRegister(), i.InputRegister(0), i.InputOperand2(1), | 209 __ add(i.OutputRegister(), i.InputRegister(0), i.InputOperand2(1), |
186 i.OutputSBit()); | 210 i.OutputSBit()); |
187 break; | 211 break; |
188 case kArmAnd: | 212 case kArmAnd: |
189 __ and_(i.OutputRegister(), i.InputRegister(0), i.InputOperand2(1), | 213 __ and_(i.OutputRegister(), i.InputRegister(0), i.InputOperand2(1), |
190 i.OutputSBit()); | 214 i.OutputSBit()); |
191 break; | 215 break; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
265 break; | 289 break; |
266 case kArmTst: | 290 case kArmTst: |
267 __ tst(i.InputRegister(0), i.InputOperand2(1)); | 291 __ tst(i.InputRegister(0), i.InputOperand2(1)); |
268 DCHECK_EQ(SetCC, i.OutputSBit()); | 292 DCHECK_EQ(SetCC, i.OutputSBit()); |
269 break; | 293 break; |
270 case kArmTeq: | 294 case kArmTeq: |
271 __ teq(i.InputRegister(0), i.InputOperand2(1)); | 295 __ teq(i.InputRegister(0), i.InputOperand2(1)); |
272 DCHECK_EQ(SetCC, i.OutputSBit()); | 296 DCHECK_EQ(SetCC, i.OutputSBit()); |
273 break; | 297 break; |
274 case kArmVcmpF64: | 298 case kArmVcmpF64: |
275 __ VFPCompareAndSetFlags(i.InputDoubleRegister(0), | 299 __ VFPCompareAndSetFlags(i.InputFloat64Register(0), |
276 i.InputDoubleRegister(1)); | 300 i.InputFloat64Register(1)); |
277 DCHECK_EQ(SetCC, i.OutputSBit()); | 301 DCHECK_EQ(SetCC, i.OutputSBit()); |
278 break; | 302 break; |
279 case kArmVaddF64: | 303 case kArmVaddF64: |
280 __ vadd(i.OutputDoubleRegister(), i.InputDoubleRegister(0), | 304 __ vadd(i.OutputFloat64Register(), i.InputFloat64Register(0), |
281 i.InputDoubleRegister(1)); | 305 i.InputFloat64Register(1)); |
282 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 306 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
283 break; | 307 break; |
284 case kArmVsubF64: | 308 case kArmVsubF64: |
285 __ vsub(i.OutputDoubleRegister(), i.InputDoubleRegister(0), | 309 __ vsub(i.OutputFloat64Register(), i.InputFloat64Register(0), |
286 i.InputDoubleRegister(1)); | 310 i.InputFloat64Register(1)); |
287 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 311 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
288 break; | 312 break; |
289 case kArmVmulF64: | 313 case kArmVmulF64: |
290 __ vmul(i.OutputDoubleRegister(), i.InputDoubleRegister(0), | 314 __ vmul(i.OutputFloat64Register(), i.InputFloat64Register(0), |
291 i.InputDoubleRegister(1)); | 315 i.InputFloat64Register(1)); |
292 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 316 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
293 break; | 317 break; |
294 case kArmVmlaF64: | 318 case kArmVmlaF64: |
295 __ vmla(i.OutputDoubleRegister(), i.InputDoubleRegister(1), | 319 __ vmla(i.OutputFloat64Register(), i.InputFloat64Register(1), |
296 i.InputDoubleRegister(2)); | 320 i.InputFloat64Register(2)); |
297 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 321 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
298 break; | 322 break; |
299 case kArmVmlsF64: | 323 case kArmVmlsF64: |
300 __ vmls(i.OutputDoubleRegister(), i.InputDoubleRegister(1), | 324 __ vmls(i.OutputFloat64Register(), i.InputFloat64Register(1), |
301 i.InputDoubleRegister(2)); | 325 i.InputFloat64Register(2)); |
302 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 326 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
303 break; | 327 break; |
304 case kArmVdivF64: | 328 case kArmVdivF64: |
305 __ vdiv(i.OutputDoubleRegister(), i.InputDoubleRegister(0), | 329 __ vdiv(i.OutputFloat64Register(), i.InputFloat64Register(0), |
306 i.InputDoubleRegister(1)); | 330 i.InputFloat64Register(1)); |
307 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 331 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
308 break; | 332 break; |
309 case kArmVmodF64: { | 333 case kArmVmodF64: { |
310 // TODO(bmeurer): We should really get rid of this special instruction, | 334 // TODO(bmeurer): We should really get rid of this special instruction, |
311 // and generate a CallAddress instruction instead. | 335 // and generate a CallAddress instruction instead. |
312 FrameScope scope(masm(), StackFrame::MANUAL); | 336 FrameScope scope(masm(), StackFrame::MANUAL); |
313 __ PrepareCallCFunction(0, 2, kScratchReg); | 337 __ PrepareCallCFunction(0, 2, kScratchReg); |
314 __ MovToFloatParameters(i.InputDoubleRegister(0), | 338 __ MovToFloatParameters(i.InputFloat64Register(0), |
315 i.InputDoubleRegister(1)); | 339 i.InputFloat64Register(1)); |
316 __ CallCFunction(ExternalReference::mod_two_doubles_operation(isolate()), | 340 __ CallCFunction(ExternalReference::mod_two_doubles_operation(isolate()), |
317 0, 2); | 341 0, 2); |
318 // Move the result in the double result register. | 342 // Move the result in the double result register. |
319 __ MovFromFloatResult(i.OutputDoubleRegister()); | 343 __ MovFromFloatResult(i.OutputFloat64Register()); |
320 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 344 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
321 break; | 345 break; |
322 } | 346 } |
323 case kArmVnegF64: | 347 case kArmVnegF64: |
324 __ vneg(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | 348 __ vneg(i.OutputFloat64Register(), i.InputFloat64Register(0)); |
325 break; | 349 break; |
350 case kArmVcvtF32F64: { | |
351 __ vcvt_f32_f64(i.OutputFloat32Register(), i.InputFloat64Register(0)); | |
352 DCHECK_EQ(LeaveCC, i.OutputSBit()); | |
353 break; | |
354 } | |
355 case kArmVcvtF64F32: { | |
356 __ vcvt_f64_f32(i.OutputFloat64Register(), i.InputFloat32Register(0)); | |
357 DCHECK_EQ(LeaveCC, i.OutputSBit()); | |
358 break; | |
359 } | |
326 case kArmVcvtF64S32: { | 360 case kArmVcvtF64S32: { |
327 SwVfpRegister scratch = kScratchDoubleReg.low(); | 361 SwVfpRegister scratch = kScratchDoubleReg.low(); |
328 __ vmov(scratch, i.InputRegister(0)); | 362 __ vmov(scratch, i.InputRegister(0)); |
329 __ vcvt_f64_s32(i.OutputDoubleRegister(), scratch); | 363 __ vcvt_f64_s32(i.OutputFloat64Register(), scratch); |
330 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 364 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
331 break; | 365 break; |
332 } | 366 } |
333 case kArmVcvtF64U32: { | 367 case kArmVcvtF64U32: { |
334 SwVfpRegister scratch = kScratchDoubleReg.low(); | 368 SwVfpRegister scratch = kScratchDoubleReg.low(); |
335 __ vmov(scratch, i.InputRegister(0)); | 369 __ vmov(scratch, i.InputRegister(0)); |
336 __ vcvt_f64_u32(i.OutputDoubleRegister(), scratch); | 370 __ vcvt_f64_u32(i.OutputFloat64Register(), scratch); |
337 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 371 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
338 break; | 372 break; |
339 } | 373 } |
340 case kArmVcvtS32F64: { | 374 case kArmVcvtS32F64: { |
341 SwVfpRegister scratch = kScratchDoubleReg.low(); | 375 SwVfpRegister scratch = kScratchDoubleReg.low(); |
342 __ vcvt_s32_f64(scratch, i.InputDoubleRegister(0)); | 376 __ vcvt_s32_f64(scratch, i.InputFloat64Register(0)); |
343 __ vmov(i.OutputRegister(), scratch); | 377 __ vmov(i.OutputRegister(), scratch); |
344 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 378 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
345 break; | 379 break; |
346 } | 380 } |
347 case kArmVcvtU32F64: { | 381 case kArmVcvtU32F64: { |
348 SwVfpRegister scratch = kScratchDoubleReg.low(); | 382 SwVfpRegister scratch = kScratchDoubleReg.low(); |
349 __ vcvt_u32_f64(scratch, i.InputDoubleRegister(0)); | 383 __ vcvt_u32_f64(scratch, i.InputFloat64Register(0)); |
350 __ vmov(i.OutputRegister(), scratch); | 384 __ vmov(i.OutputRegister(), scratch); |
351 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 385 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
352 break; | 386 break; |
353 } | 387 } |
354 case kArmLdrb: | 388 case kArmLdrb: |
355 __ ldrb(i.OutputRegister(), i.InputOffset()); | 389 __ ldrb(i.OutputRegister(), i.InputOffset()); |
356 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 390 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
357 break; | 391 break; |
358 case kArmLdrsb: | 392 case kArmLdrsb: |
359 __ ldrsb(i.OutputRegister(), i.InputOffset()); | 393 __ ldrsb(i.OutputRegister(), i.InputOffset()); |
(...skipping 22 matching lines...) Expand all Loading... | |
382 case kArmLdr: | 416 case kArmLdr: |
383 __ ldr(i.OutputRegister(), i.InputOffset()); | 417 __ ldr(i.OutputRegister(), i.InputOffset()); |
384 break; | 418 break; |
385 case kArmStr: { | 419 case kArmStr: { |
386 int index = 0; | 420 int index = 0; |
387 MemOperand operand = i.InputOffset(&index); | 421 MemOperand operand = i.InputOffset(&index); |
388 __ str(i.InputRegister(index), operand); | 422 __ str(i.InputRegister(index), operand); |
389 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 423 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
390 break; | 424 break; |
391 } | 425 } |
392 case kArmVldr32: { | 426 case kArmVldrF32: { |
393 SwVfpRegister scratch = kScratchDoubleReg.low(); | 427 __ vldr(i.OutputFloat32Register(), i.InputOffset()); |
394 __ vldr(scratch, i.InputOffset()); | |
395 __ vcvt_f64_f32(i.OutputDoubleRegister(), scratch); | |
396 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 428 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
397 break; | 429 break; |
398 } | 430 } |
399 case kArmVstr32: { | 431 case kArmVstrF32: { |
400 int index = 0; | 432 int index = 0; |
401 SwVfpRegister scratch = kScratchDoubleReg.low(); | |
402 MemOperand operand = i.InputOffset(&index); | 433 MemOperand operand = i.InputOffset(&index); |
403 __ vcvt_f32_f64(scratch, i.InputDoubleRegister(index)); | 434 __ vstr(i.InputFloat32Register(index), operand); |
404 __ vstr(scratch, operand); | |
405 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 435 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
406 break; | 436 break; |
407 } | 437 } |
408 case kArmVldr64: | 438 case kArmVldrF64: |
409 __ vldr(i.OutputDoubleRegister(), i.InputOffset()); | 439 __ vldr(i.OutputFloat64Register(), i.InputOffset()); |
410 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 440 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
411 break; | 441 break; |
412 case kArmVstr64: { | 442 case kArmVstrF64: { |
413 int index = 0; | 443 int index = 0; |
414 MemOperand operand = i.InputOffset(&index); | 444 MemOperand operand = i.InputOffset(&index); |
415 __ vstr(i.InputDoubleRegister(index), operand); | 445 __ vstr(i.InputFloat64Register(index), operand); |
416 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 446 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
417 break; | 447 break; |
418 } | 448 } |
419 case kArmPush: | 449 case kArmPush: |
420 __ Push(i.InputRegister(0)); | 450 __ Push(i.InputRegister(0)); |
421 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 451 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
422 break; | 452 break; |
423 case kArmStoreWriteBarrier: { | 453 case kArmStoreWriteBarrier: { |
424 Register object = i.InputRegister(0); | 454 Register object = i.InputRegister(0); |
425 Register index = i.InputRegister(1); | 455 Register index = i.InputRegister(1); |
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
864 } | 894 } |
865 } | 895 } |
866 MarkLazyDeoptSite(); | 896 MarkLazyDeoptSite(); |
867 } | 897 } |
868 | 898 |
869 #undef __ | 899 #undef __ |
870 | 900 |
871 } // namespace compiler | 901 } // namespace compiler |
872 } // namespace internal | 902 } // namespace internal |
873 } // namespace v8 | 903 } // namespace v8 |
OLD | NEW |