Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(636)

Side by Side Diff: src/IceTargetLoweringX8664.cpp

Issue 1537703002: Subzero. x8664. Resurrects the Target. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Addresses comments Created 4 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 //===- subzero/src/IceTargetLoweringX8664.cpp - x86-64 lowering -----------===// 1 //===- subzero/src/IceTargetLoweringX8664.cpp - x86-64 lowering -----------===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 /// 9 ///
10 /// \file 10 /// \file
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 XmmArgs.push_back(Arg); 186 XmmArgs.push_back(Arg);
187 } else if (isScalarIntegerType(Ty) && 187 } else if (isScalarIntegerType(Ty) &&
188 GprArgs.size() < Traits::X86_MAX_GPR_ARGS) { 188 GprArgs.size() < Traits::X86_MAX_GPR_ARGS) {
189 GprArgs.push_back(Arg); 189 GprArgs.push_back(Arg);
190 } else { 190 } else {
191 StackArgs.push_back(Arg); 191 StackArgs.push_back(Arg);
192 if (isVectorType(Arg->getType())) { 192 if (isVectorType(Arg->getType())) {
193 ParameterAreaSizeBytes = 193 ParameterAreaSizeBytes =
194 Traits::applyStackAlignment(ParameterAreaSizeBytes); 194 Traits::applyStackAlignment(ParameterAreaSizeBytes);
195 } 195 }
196 Variable *esp = getPhysicalRegister(Traits::RegisterSet::Reg_esp); 196 Variable *esp = getPhysicalRegister(Traits::RegisterSet::Reg_rsp);
197 Constant *Loc = Ctx->getConstantInt32(ParameterAreaSizeBytes); 197 Constant *Loc = Ctx->getConstantInt32(ParameterAreaSizeBytes);
198 StackArgLocations.push_back( 198 StackArgLocations.push_back(
199 Traits::X86OperandMem::create(Func, Ty, esp, Loc)); 199 Traits::X86OperandMem::create(Func, Ty, esp, Loc));
200 ParameterAreaSizeBytes += typeWidthInBytesOnStack(Arg->getType()); 200 ParameterAreaSizeBytes += typeWidthInBytesOnStack(Arg->getType());
201 } 201 }
202 } 202 }
203 203
204 // Adjust the parameter area so that the stack is aligned. It is assumed that 204 // Adjust the parameter area so that the stack is aligned. It is assumed that
205 // the stack is already aligned at the start of the calling sequence. 205 // the stack is already aligned at the start of the calling sequence.
206 ParameterAreaSizeBytes = Traits::applyStackAlignment(ParameterAreaSizeBytes); 206 ParameterAreaSizeBytes = Traits::applyStackAlignment(ParameterAreaSizeBytes);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 Operand *CallTarget = legalize(Instr->getCallTarget(), Legal_Reg | Legal_Imm); 269 Operand *CallTarget = legalize(Instr->getCallTarget(), Legal_Reg | Legal_Imm);
270 const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing(); 270 const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing();
271 if (NeedSandboxing) { 271 if (NeedSandboxing) {
272 llvm_unreachable("X86-64 Sandboxing codegen not implemented."); 272 llvm_unreachable("X86-64 Sandboxing codegen not implemented.");
273 } 273 }
274 auto *NewCall = Context.insert<Traits::Insts::Call>(ReturnReg, CallTarget); 274 auto *NewCall = Context.insert<Traits::Insts::Call>(ReturnReg, CallTarget);
275 if (NeedSandboxing) { 275 if (NeedSandboxing) {
276 llvm_unreachable("X86-64 Sandboxing codegen not implemented."); 276 llvm_unreachable("X86-64 Sandboxing codegen not implemented.");
277 } 277 }
278 278
279 // Add the appropriate offset to esp. The call instruction takes care of
280 // resetting the stack offset during emission.
281 if (ParameterAreaSizeBytes) {
282 Variable *Esp =
283 Func->getTarget()->getPhysicalRegister(Traits::RegisterSet::Reg_esp);
284 _add(Esp, Ctx->getConstantInt32(ParameterAreaSizeBytes));
285 }
286
287 // Insert a register-kill pseudo instruction. 279 // Insert a register-kill pseudo instruction.
288 Context.insert<InstFakeKill>(NewCall); 280 Context.insert<InstFakeKill>(NewCall);
289 281
290 // Generate a FakeUse to keep the call live if necessary. 282 // Generate a FakeUse to keep the call live if necessary.
291 if (Instr->hasSideEffects() && ReturnReg) { 283 if (Instr->hasSideEffects() && ReturnReg) {
292 Context.insert<InstFakeUse>(ReturnReg); 284 Context.insert<InstFakeUse>(ReturnReg);
293 } 285 }
294 286
295 if (!Dest) 287 if (!Dest)
296 return; 288 return;
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 // Compute the list of spilled variables and bounds for GlobalsSize, etc. 450 // Compute the list of spilled variables and bounds for GlobalsSize, etc.
459 getVarStackSlotParams(SortedSpilledVariables, RegsUsed, &GlobalsSize, 451 getVarStackSlotParams(SortedSpilledVariables, RegsUsed, &GlobalsSize,
460 &SpillAreaSizeBytes, &SpillAreaAlignmentBytes, 452 &SpillAreaSizeBytes, &SpillAreaAlignmentBytes,
461 &LocalsSlotsAlignmentBytes, TargetVarHook); 453 &LocalsSlotsAlignmentBytes, TargetVarHook);
462 uint32_t LocalsSpillAreaSize = SpillAreaSizeBytes; 454 uint32_t LocalsSpillAreaSize = SpillAreaSizeBytes;
463 SpillAreaSizeBytes += GlobalsSize; 455 SpillAreaSizeBytes += GlobalsSize;
464 456
465 // Add push instructions for preserved registers. 457 // Add push instructions for preserved registers.
466 uint32_t NumCallee = 0; 458 uint32_t NumCallee = 0;
467 size_t PreservedRegsSizeBytes = 0; 459 size_t PreservedRegsSizeBytes = 0;
460 llvm::SmallBitVector Pushed(CalleeSaves.size());
468 for (SizeT i = 0; i < CalleeSaves.size(); ++i) { 461 for (SizeT i = 0; i < CalleeSaves.size(); ++i) {
469 if (CalleeSaves[i] && RegsUsed[i]) { 462 const int32_t Canonical = Traits::getBaseReg(i);
470 ++NumCallee; 463 assert(Canonical == Traits::getBaseReg(Canonical));
471 PreservedRegsSizeBytes += typeWidthInBytes(IceType_i64); 464 if (CalleeSaves[i] && RegsUsed[i])
472 _push(getPhysicalRegister(i)); 465 Pushed[Canonical] = true;
473 } 466 }
467 for (SizeT i = 0; i < Pushed.size(); ++i) {
468 if (!Pushed[i])
469 continue;
470 assert(static_cast<int32_t>(i) == Traits::getBaseReg(i));
471 ++NumCallee;
472 PreservedRegsSizeBytes += typeWidthInBytes(IceType_i64);
473 _push(getPhysicalRegister(i, IceType_i64));
474 } 474 }
475 Ctx->statsUpdateRegistersSaved(NumCallee); 475 Ctx->statsUpdateRegistersSaved(NumCallee);
476 476
477 // Generate "push ebp; mov ebp, esp" 477 // Generate "push ebp; mov ebp, esp"
478 if (IsEbpBasedFrame) { 478 if (IsEbpBasedFrame) {
479 assert((RegsUsed & getRegisterSet(RegSet_FramePointer, RegSet_None)) 479 assert((RegsUsed & getRegisterSet(RegSet_FramePointer, RegSet_None))
480 .count() == 0); 480 .count() == 0);
481 PreservedRegsSizeBytes += typeWidthInBytes(IceType_i64); 481 PreservedRegsSizeBytes += typeWidthInBytes(IceType_i64);
482 Variable *ebp = getPhysicalRegister(Traits::RegisterSet::Reg_ebp); 482 Variable *ebp = getPhysicalRegister(Traits::RegisterSet::Reg_rbp);
483 Variable *esp = getPhysicalRegister(Traits::RegisterSet::Reg_esp); 483 Variable *esp = getPhysicalRegister(Traits::RegisterSet::Reg_rsp);
484 _push(ebp); 484 _push(ebp);
485 _mov(ebp, esp); 485 _mov(ebp, esp);
486 // Keep ebp live for late-stage liveness analysis (e.g. asm-verbose mode). 486 // Keep ebp live for late-stage liveness analysis (e.g. asm-verbose mode).
487 Context.insert<InstFakeUse>(ebp); 487 Context.insert<InstFakeUse>(ebp);
488 } 488 }
489 489
490 // Align the variables area. SpillAreaPaddingBytes is the size of the region 490 // Align the variables area. SpillAreaPaddingBytes is the size of the region
491 // after the preserved registers and before the spill areas. 491 // after the preserved registers and before the spill areas.
492 // LocalsSlotsPaddingBytes is the amount of padding between the globals and 492 // LocalsSlotsPaddingBytes is the amount of padding between the globals and
493 // locals area if they are separate. 493 // locals area if they are separate.
(...skipping 20 matching lines...) Expand all
514 } else { 514 } else {
515 SpillAreaSizeBytes += maxOutArgsSizeBytes(); 515 SpillAreaSizeBytes += maxOutArgsSizeBytes();
516 } 516 }
517 517
518 // Combine fixed allocations into SpillAreaSizeBytes if we are emitting the 518 // Combine fixed allocations into SpillAreaSizeBytes if we are emitting the
519 // fixed allocations in the prolog. 519 // fixed allocations in the prolog.
520 if (PrologEmitsFixedAllocas) 520 if (PrologEmitsFixedAllocas)
521 SpillAreaSizeBytes += FixedAllocaSizeBytes; 521 SpillAreaSizeBytes += FixedAllocaSizeBytes;
522 // Generate "sub esp, SpillAreaSizeBytes" 522 // Generate "sub esp, SpillAreaSizeBytes"
523 if (SpillAreaSizeBytes) { 523 if (SpillAreaSizeBytes) {
524 _sub(getPhysicalRegister(Traits::RegisterSet::Reg_esp), 524 _sub(getPhysicalRegister(getStackReg(), IceType_i64),
525 Ctx->getConstantInt32(SpillAreaSizeBytes)); 525 Ctx->getConstantInt32(SpillAreaSizeBytes));
526 // If the fixed allocas are aligned more than the stack frame, align the 526 // If the fixed allocas are aligned more than the stack frame, align the
527 // stack pointer accordingly. 527 // stack pointer accordingly.
528 if (PrologEmitsFixedAllocas && 528 if (PrologEmitsFixedAllocas &&
529 FixedAllocaAlignBytes > Traits::X86_STACK_ALIGNMENT_BYTES) { 529 FixedAllocaAlignBytes > Traits::X86_STACK_ALIGNMENT_BYTES) {
530 assert(IsEbpBasedFrame); 530 assert(IsEbpBasedFrame);
531 _and(getPhysicalRegister(Traits::RegisterSet::Reg_esp), 531 _and(getPhysicalRegister(Traits::RegisterSet::Reg_rsp),
532 Ctx->getConstantInt32(-FixedAllocaAlignBytes)); 532 Ctx->getConstantInt32(-FixedAllocaAlignBytes));
533 } 533 }
534 } 534 }
535 535
536 // Account for alloca instructions with known frame offsets. 536 // Account for alloca instructions with known frame offsets.
537 if (!PrologEmitsFixedAllocas) 537 if (!PrologEmitsFixedAllocas)
538 SpillAreaSizeBytes += FixedAllocaSizeBytes; 538 SpillAreaSizeBytes += FixedAllocaSizeBytes;
539 539
540 Ctx->statsUpdateFrameBytes(SpillAreaSizeBytes); 540 Ctx->statsUpdateFrameBytes(SpillAreaSizeBytes);
541 541
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 if (RI == E) 630 if (RI == E)
631 return; 631 return;
632 632
633 // Convert the reverse_iterator position into its corresponding (forward) 633 // Convert the reverse_iterator position into its corresponding (forward)
634 // iterator position. 634 // iterator position.
635 InstList::iterator InsertPoint = RI.base(); 635 InstList::iterator InsertPoint = RI.base();
636 --InsertPoint; 636 --InsertPoint;
637 Context.init(Node); 637 Context.init(Node);
638 Context.setInsertPoint(InsertPoint); 638 Context.setInsertPoint(InsertPoint);
639 639
640 Variable *esp = getPhysicalRegister(Traits::RegisterSet::Reg_esp); 640 Variable *esp = getPhysicalRegister(Traits::RegisterSet::Reg_rsp);
641 if (IsEbpBasedFrame) { 641 if (IsEbpBasedFrame) {
642 Variable *ebp = getPhysicalRegister(Traits::RegisterSet::Reg_ebp); 642 Variable *ebp = getPhysicalRegister(Traits::RegisterSet::Reg_rbp);
643 // For late-stage liveness analysis (e.g. asm-verbose mode), adding a fake 643 // For late-stage liveness analysis (e.g. asm-verbose mode), adding a fake
644 // use of esp before the assignment of esp=ebp keeps previous esp 644 // use of esp before the assignment of esp=ebp keeps previous esp
645 // adjustments from being dead-code eliminated. 645 // adjustments from being dead-code eliminated.
646 Context.insert<InstFakeUse>(esp); 646 Context.insert<InstFakeUse>(esp);
647 _mov(esp, ebp); 647 _mov(esp, ebp);
648 _pop(ebp); 648 _pop(ebp);
649 } else { 649 } else {
650 // add esp, SpillAreaSizeBytes 650 // add esp, SpillAreaSizeBytes
651 if (SpillAreaSizeBytes) 651 if (SpillAreaSizeBytes)
652 _add(esp, Ctx->getConstantInt32(SpillAreaSizeBytes)); 652 _add(esp, Ctx->getConstantInt32(SpillAreaSizeBytes));
653 } 653 }
654 654
655 // Add pop instructions for preserved registers. 655 // Add pop instructions for preserved registers.
656 llvm::SmallBitVector CalleeSaves = 656 llvm::SmallBitVector CalleeSaves =
657 getRegisterSet(RegSet_CalleeSave, RegSet_None); 657 getRegisterSet(RegSet_CalleeSave, RegSet_None);
658 for (SizeT i = 0; i < CalleeSaves.size(); ++i) { 658 llvm::SmallBitVector Popped(CalleeSaves.size());
659 SizeT j = CalleeSaves.size() - i - 1; 659 for (int32_t i = CalleeSaves.size() - 1; i >= 0; --i) {
660 if (j == Traits::RegisterSet::Reg_ebp && IsEbpBasedFrame) 660 if (i == Traits::RegisterSet::Reg_rbp && IsEbpBasedFrame)
661 continue; 661 continue;
662 if (CalleeSaves[j] && RegsUsed[j]) { 662 const SizeT Canonical = Traits::getBaseReg(i);
663 _pop(getPhysicalRegister(j)); 663 if (CalleeSaves[i] && RegsUsed[i])
664 } 664 Popped[Canonical] = true;
665 }
666 for (int32_t i = Popped.size() - 1; i >= 0; --i) {
667 if (!Popped[i])
668 continue;
669 assert(i == Traits::getBaseReg(i));
670 _pop(getPhysicalRegister(i, IceType_i64));
665 } 671 }
666 672
667 if (Ctx->getFlags().getUseSandboxing()) { 673 if (Ctx->getFlags().getUseSandboxing()) {
668 llvm_unreachable("X86-64 Sandboxing codegen not implemented."); 674 llvm_unreachable("X86-64 Sandboxing codegen not implemented.");
669 } 675 }
670 } 676 }
671 677
672 void TargetX8664::emitJumpTable(const Cfg *Func, 678 void TargetX8664::emitJumpTable(const Cfg *Func,
673 const InstJumpTable *JumpTable) const { 679 const InstJumpTable *JumpTable) const {
674 if (!BuildDefs::dump()) 680 if (!BuildDefs::dump())
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
977 // case the high-level table has extra entries. 983 // case the high-level table has extra entries.
978 #define X(tag, sizeLog2, align, elts, elty, str) \ 984 #define X(tag, sizeLog2, align, elts, elty, str) \
979 static_assert(_table1_##tag == _table2_##tag, \ 985 static_assert(_table1_##tag == _table2_##tag, \
980 "Inconsistency between ICETYPEX8664_TABLE and ICETYPE_TABLE"); 986 "Inconsistency between ICETYPEX8664_TABLE and ICETYPE_TABLE");
981 ICETYPE_TABLE 987 ICETYPE_TABLE
982 #undef X 988 #undef X
983 } // end of namespace dummy3 989 } // end of namespace dummy3
984 } // end of anonymous namespace 990 } // end of anonymous namespace
985 991
986 } // end of namespace Ice 992 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698