| 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/arm64/frames-arm64.h" | 7 #include "src/arm64/frames-arm64.h" |
| 8 #include "src/arm64/macro-assembler-arm64.h" | 8 #include "src/arm64/macro-assembler-arm64.h" |
| 9 #include "src/ast/scopes.h" | 9 #include "src/ast/scopes.h" |
| 10 #include "src/compiler/code-generator-impl.h" | 10 #include "src/compiler/code-generator-impl.h" |
| (...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 870 case kArm64CompareAndBranch32: | 870 case kArm64CompareAndBranch32: |
| 871 // Pseudo instruction turned into cbz/cbnz in AssembleArchBranch. | 871 // Pseudo instruction turned into cbz/cbnz in AssembleArchBranch. |
| 872 break; | 872 break; |
| 873 case kArm64ClaimForCallArguments: { | 873 case kArm64ClaimForCallArguments: { |
| 874 __ Claim(i.InputInt32(0)); | 874 __ Claim(i.InputInt32(0)); |
| 875 frame_access_state()->IncreaseSPDelta(i.InputInt32(0)); | 875 frame_access_state()->IncreaseSPDelta(i.InputInt32(0)); |
| 876 break; | 876 break; |
| 877 } | 877 } |
| 878 case kArm64Poke: { | 878 case kArm64Poke: { |
| 879 Operand operand(i.InputInt32(1) * kPointerSize); | 879 Operand operand(i.InputInt32(1) * kPointerSize); |
| 880 __ Poke(i.InputRegister(0), operand); | 880 if (instr->InputAt(0)->IsDoubleRegister()) { |
| 881 __ Poke(i.InputFloat64Register(0), operand); |
| 882 } else { |
| 883 __ Poke(i.InputRegister(0), operand); |
| 884 } |
| 881 break; | 885 break; |
| 882 } | 886 } |
| 883 case kArm64PokePair: { | 887 case kArm64PokePair: { |
| 884 int slot = i.InputInt32(2) - 1; | 888 int slot = i.InputInt32(2) - 1; |
| 885 __ PokePair(i.InputRegister(1), i.InputRegister(0), slot * kPointerSize); | 889 if (instr->InputAt(0)->IsDoubleRegister()) { |
| 890 __ PokePair(i.InputFloat64Register(1), i.InputFloat64Register(0), |
| 891 slot * kPointerSize); |
| 892 } else { |
| 893 __ PokePair(i.InputRegister(1), i.InputRegister(0), |
| 894 slot * kPointerSize); |
| 895 } |
| 886 break; | 896 break; |
| 887 } | 897 } |
| 888 case kArm64Clz: | 898 case kArm64Clz: |
| 889 __ Clz(i.OutputRegister64(), i.InputRegister64(0)); | 899 __ Clz(i.OutputRegister64(), i.InputRegister64(0)); |
| 890 break; | 900 break; |
| 891 case kArm64Clz32: | 901 case kArm64Clz32: |
| 892 __ Clz(i.OutputRegister32(), i.InputRegister32(0)); | 902 __ Clz(i.OutputRegister32(), i.InputRegister32(0)); |
| 893 break; | 903 break; |
| 894 case kArm64Cmp: | 904 case kArm64Cmp: |
| 895 __ Cmp(i.InputOrZeroRegister64(0), i.InputOperand(1)); | 905 __ Cmp(i.InputOrZeroRegister64(0), i.InputOperand(1)); |
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1285 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 1295 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
| 1286 if (descriptor->IsCFunctionCall()) { | 1296 if (descriptor->IsCFunctionCall()) { |
| 1287 __ SetStackPointer(csp); | 1297 __ SetStackPointer(csp); |
| 1288 __ Push(lr, fp); | 1298 __ Push(lr, fp); |
| 1289 __ Mov(fp, csp); | 1299 __ Mov(fp, csp); |
| 1290 } else if (descriptor->IsJSFunctionCall()) { | 1300 } else if (descriptor->IsJSFunctionCall()) { |
| 1291 CompilationInfo* info = this->info(); | 1301 CompilationInfo* info = this->info(); |
| 1292 __ SetStackPointer(jssp); | 1302 __ SetStackPointer(jssp); |
| 1293 __ Prologue(info->IsCodePreAgingActive()); | 1303 __ Prologue(info->IsCodePreAgingActive()); |
| 1294 } else if (frame()->needs_frame()) { | 1304 } else if (frame()->needs_frame()) { |
| 1295 __ SetStackPointer(jssp); | 1305 if (descriptor->UseNativeStack()) { |
| 1306 __ SetStackPointer(csp); |
| 1307 } else { |
| 1308 __ SetStackPointer(jssp); |
| 1309 } |
| 1296 __ StubPrologue(); | 1310 __ StubPrologue(); |
| 1297 } else { | 1311 } else { |
| 1312 if (descriptor->UseNativeStack()) { |
| 1313 __ SetStackPointer(csp); |
| 1314 } else { |
| 1315 __ SetStackPointer(jssp); |
| 1316 } |
| 1298 frame()->SetElidedFrameSizeInSlots(0); | 1317 frame()->SetElidedFrameSizeInSlots(0); |
| 1299 } | 1318 } |
| 1300 frame_access_state()->SetFrameAccessToDefault(); | 1319 frame_access_state()->SetFrameAccessToDefault(); |
| 1301 | 1320 |
| 1302 int stack_shrink_slots = frame()->GetSpillSlotCount(); | 1321 int stack_shrink_slots = frame()->GetSpillSlotCount(); |
| 1303 if (info()->is_osr()) { | 1322 if (info()->is_osr()) { |
| 1304 // TurboFan OSR-compiled functions cannot be entered directly. | 1323 // TurboFan OSR-compiled functions cannot be entered directly. |
| 1305 __ Abort(kShouldNotDirectlyEnterOsrFunction); | 1324 __ Abort(kShouldNotDirectlyEnterOsrFunction); |
| 1306 | 1325 |
| 1307 // Unoptimized code jumps directly to this entrypoint while the unoptimized | 1326 // Unoptimized code jumps directly to this entrypoint while the unoptimized |
| 1308 // frame is still on the stack. Optimized code uses OSR values directly from | 1327 // frame is still on the stack. Optimized code uses OSR values directly from |
| 1309 // the unoptimized frame. Thus, all that needs to be done is to allocate the | 1328 // the unoptimized frame. Thus, all that needs to be done is to allocate the |
| 1310 // remaining stack slots. | 1329 // remaining stack slots. |
| 1311 if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); | 1330 if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); |
| 1312 osr_pc_offset_ = __ pc_offset(); | 1331 osr_pc_offset_ = __ pc_offset(); |
| 1313 // TODO(titzer): cannot address target function == local #-1 | 1332 // TODO(titzer): cannot address target function == local #-1 |
| 1314 __ ldr(x1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 1333 __ ldr(x1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 1315 stack_shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots(); | 1334 stack_shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots(); |
| 1316 } | 1335 } |
| 1317 | 1336 |
| 1318 if (csp.Is(masm()->StackPointer())) { | 1337 // If frame()->needs_frame() is false, then |
| 1338 // frame()->AlignSavedCalleeRegisterSlots() is guaranteed to return 0. |
| 1339 if (csp.Is(masm()->StackPointer()) && frame()->needs_frame()) { |
| 1319 // The system stack pointer requires 16-byte alignment at function call | 1340 // The system stack pointer requires 16-byte alignment at function call |
| 1320 // boundaries. | 1341 // boundaries. |
| 1342 |
| 1321 stack_shrink_slots += frame()->AlignSavedCalleeRegisterSlots(); | 1343 stack_shrink_slots += frame()->AlignSavedCalleeRegisterSlots(); |
| 1322 } | 1344 } |
| 1323 __ Claim(stack_shrink_slots); | 1345 __ Claim(stack_shrink_slots); |
| 1324 | 1346 |
| 1325 // Save FP registers. | 1347 // Save FP registers. |
| 1326 CPURegList saves_fp = CPURegList(CPURegister::kFPRegister, kDRegSizeInBits, | 1348 CPURegList saves_fp = CPURegList(CPURegister::kFPRegister, kDRegSizeInBits, |
| 1327 descriptor->CalleeSavedFPRegisters()); | 1349 descriptor->CalleeSavedFPRegisters()); |
| 1328 int saved_count = saves_fp.Count(); | 1350 int saved_count = saves_fp.Count(); |
| 1329 if (saved_count != 0) { | 1351 if (saved_count != 0) { |
| 1330 DCHECK(saves_fp.list() == CPURegList::GetCalleeSavedFP().list()); | 1352 DCHECK(saves_fp.list() == CPURegList::GetCalleeSavedFP().list()); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1367 if (descriptor->IsCFunctionCall()) { | 1389 if (descriptor->IsCFunctionCall()) { |
| 1368 __ Mov(csp, fp); | 1390 __ Mov(csp, fp); |
| 1369 __ Pop(fp, lr); | 1391 __ Pop(fp, lr); |
| 1370 } else if (frame()->needs_frame()) { | 1392 } else if (frame()->needs_frame()) { |
| 1371 // Canonicalize JSFunction return sites for now. | 1393 // Canonicalize JSFunction return sites for now. |
| 1372 if (return_label_.is_bound()) { | 1394 if (return_label_.is_bound()) { |
| 1373 __ B(&return_label_); | 1395 __ B(&return_label_); |
| 1374 return; | 1396 return; |
| 1375 } else { | 1397 } else { |
| 1376 __ Bind(&return_label_); | 1398 __ Bind(&return_label_); |
| 1377 __ Mov(jssp, fp); | 1399 if (descriptor->UseNativeStack()) { |
| 1400 __ Mov(csp, fp); |
| 1401 } else { |
| 1402 __ Mov(jssp, fp); |
| 1403 } |
| 1378 __ Pop(fp, lr); | 1404 __ Pop(fp, lr); |
| 1379 } | 1405 } |
| 1406 } else if (descriptor->UseNativeStack()) { |
| 1407 pop_count += (pop_count & 1); |
| 1380 } | 1408 } |
| 1381 __ Drop(pop_count); | 1409 __ Drop(pop_count); |
| 1382 __ Ret(); | 1410 __ Ret(); |
| 1383 } | 1411 } |
| 1384 | 1412 |
| 1385 | 1413 |
| 1386 void CodeGenerator::AssembleMove(InstructionOperand* source, | 1414 void CodeGenerator::AssembleMove(InstructionOperand* source, |
| 1387 InstructionOperand* destination) { | 1415 InstructionOperand* destination) { |
| 1388 Arm64OperandConverter g(this, NULL); | 1416 Arm64OperandConverter g(this, NULL); |
| 1389 // Dispatch on the source and destination operand kinds. Not all | 1417 // Dispatch on the source and destination operand kinds. Not all |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1565 padding_size -= kInstructionSize; | 1593 padding_size -= kInstructionSize; |
| 1566 } | 1594 } |
| 1567 } | 1595 } |
| 1568 } | 1596 } |
| 1569 | 1597 |
| 1570 #undef __ | 1598 #undef __ |
| 1571 | 1599 |
| 1572 } // namespace compiler | 1600 } // namespace compiler |
| 1573 } // namespace internal | 1601 } // namespace internal |
| 1574 } // namespace v8 | 1602 } // namespace v8 |
| OLD | NEW |