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

Side by Side Diff: src/IceInstX86BaseImpl.h

Issue 1442753008: Reserve space for scalar FP returns in the stack frame (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Add hyphen to comment Created 5 years, 1 month 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/IceInstX86BaseImpl.h - Generic X86 instructions -*- C++ -*=// 1 //===- subzero/src/IceInstX86BaseImpl.h - Generic X86 instructions -*- C++ -*=//
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 2529 matching lines...) Expand 10 before | Expand all | Expand 10 after
2540 Ostream &Str = Func->getContext()->getStrDump(); 2540 Ostream &Str = Func->getContext()->getStrDump();
2541 Str << "nop (variant = " << Variant << ")"; 2541 Str << "nop (variant = " << Variant << ")";
2542 } 2542 }
2543 2543
2544 template <class Machine> void InstX86Fld<Machine>::emit(const Cfg *Func) const { 2544 template <class Machine> void InstX86Fld<Machine>::emit(const Cfg *Func) const {
2545 if (!BuildDefs::dump()) 2545 if (!BuildDefs::dump())
2546 return; 2546 return;
2547 Ostream &Str = Func->getContext()->getStrEmit(); 2547 Ostream &Str = Func->getContext()->getStrEmit();
2548 assert(this->getSrcSize() == 1); 2548 assert(this->getSrcSize() == 1);
2549 Type Ty = this->getSrc(0)->getType(); 2549 Type Ty = this->getSrc(0)->getType();
2550 SizeT Width = typeWidthInBytes(Ty);
2551 const auto *Var = llvm::dyn_cast<Variable>(this->getSrc(0)); 2550 const auto *Var = llvm::dyn_cast<Variable>(this->getSrc(0));
2552 if (Var && Var->hasReg()) { 2551 if (Var && Var->hasReg()) {
2553 // This is a physical xmm register, so we need to spill it to a temporary 2552 // This is a physical xmm register, so we need to spill it to a temporary
2554 // stack slot. 2553 // stack slot. Function prolog emission guarantees that there is sufficient
2555 Str << "\tsubl\t$" << Width << ", %esp" 2554 // space to do this.
2556 << "\n";
2557 Str << "\tmov" 2555 Str << "\tmov"
2558 << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString << "\t"; 2556 << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString << "\t";
2559 Var->emit(Func); 2557 Var->emit(Func);
2560 Str << ", (%esp)\n"; 2558 Str << ", (%esp)\n";
2561 Str << "\tfld" << this->getFldString(Ty) << "\t" 2559 Str << "\tfld" << this->getFldString(Ty) << "\t"
2562 << "(%esp)\n"; 2560 << "(%esp)";
2563 Str << "\taddl\t$" << Width << ", %esp";
2564 return; 2561 return;
2565 } 2562 }
2566 Str << "\tfld" << this->getFldString(Ty) << "\t"; 2563 Str << "\tfld" << this->getFldString(Ty) << "\t";
2567 this->getSrc(0)->emit(Func); 2564 this->getSrc(0)->emit(Func);
2568 } 2565 }
2569 2566
2570 template <class Machine> 2567 template <class Machine>
2571 void InstX86Fld<Machine>::emitIAS(const Cfg *Func) const { 2568 void InstX86Fld<Machine>::emitIAS(const Cfg *Func) const {
2572 typename InstX86Base<Machine>::Traits::Assembler *Asm = 2569 typename InstX86Base<Machine>::Traits::Assembler *Asm =
2573 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); 2570 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
2574 assert(this->getSrcSize() == 1); 2571 assert(this->getSrcSize() == 1);
2575 const Operand *Src = this->getSrc(0); 2572 const Operand *Src = this->getSrc(0);
2576 auto *Target = InstX86Base<Machine>::getTarget(Func); 2573 auto *Target = InstX86Base<Machine>::getTarget(Func);
2577 Type Ty = Src->getType(); 2574 Type Ty = Src->getType();
2578 if (const auto *Var = llvm::dyn_cast<Variable>(Src)) { 2575 if (const auto *Var = llvm::dyn_cast<Variable>(Src)) {
2579 if (Var->hasReg()) { 2576 if (Var->hasReg()) {
2580 // This is a physical xmm register, so we need to spill it to a temporary 2577 // This is a physical xmm register, so we need to spill it to a temporary
2581 // stack slot. 2578 // stack slot. Function prolog emission guarantees that there is
2582 Immediate Width(typeWidthInBytes(Ty)); 2579 // sufficient space to do this.
2583 Asm->sub(IceType_i32,
2584 InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp,
2585 Width);
2586 typename InstX86Base<Machine>::Traits::Address StackSlot = 2580 typename InstX86Base<Machine>::Traits::Address StackSlot =
2587 typename InstX86Base<Machine>::Traits::Address( 2581 typename InstX86Base<Machine>::Traits::Address(
2588 InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp, 0, 2582 InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp, 0,
2589 AssemblerFixup::NoFixup); 2583 AssemblerFixup::NoFixup);
2590 Asm->movss(Ty, StackSlot, 2584 Asm->movss(Ty, StackSlot,
2591 InstX86Base<Machine>::Traits::getEncodedXmm(Var->getRegNum())); 2585 InstX86Base<Machine>::Traits::getEncodedXmm(Var->getRegNum()));
2592 Asm->fld(Ty, StackSlot); 2586 Asm->fld(Ty, StackSlot);
2593 Asm->add(IceType_i32,
2594 InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp,
2595 Width);
2596 } else { 2587 } else {
2597 typename InstX86Base<Machine>::Traits::Address StackAddr( 2588 typename InstX86Base<Machine>::Traits::Address StackAddr(
2598 Target->stackVarToAsmOperand(Var)); 2589 Target->stackVarToAsmOperand(Var));
2599 Asm->fld(Ty, StackAddr); 2590 Asm->fld(Ty, StackAddr);
2600 } 2591 }
2601 } else if (const auto *Mem = llvm::dyn_cast< 2592 } else if (const auto *Mem = llvm::dyn_cast<
2602 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) { 2593 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) {
2603 assert(Mem->getSegmentRegister() == 2594 assert(Mem->getSegmentRegister() ==
2604 InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment); 2595 InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
2605 Asm->fld(Ty, Mem->toAsmAddress(Asm, Target)); 2596 Asm->fld(Ty, Mem->toAsmAddress(Asm, Target));
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2639 } 2630 }
2640 // Dest is a physical (xmm) register, so st(0) needs to go through memory. 2631 // Dest is a physical (xmm) register, so st(0) needs to go through memory.
2641 // Hack this by using caller-reserved memory at the top of stack, spilling 2632 // Hack this by using caller-reserved memory at the top of stack, spilling
2642 // st(0) there, and loading it into the xmm register. 2633 // st(0) there, and loading it into the xmm register.
2643 Str << "\tfstp" << this->getFldString(Ty) << "\t" 2634 Str << "\tfstp" << this->getFldString(Ty) << "\t"
2644 << "(%esp)\n"; 2635 << "(%esp)\n";
2645 Str << "\tmov" << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString 2636 Str << "\tmov" << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString
2646 << "\t" 2637 << "\t"
2647 << "(%esp), "; 2638 << "(%esp), ";
2648 this->getDest()->emit(Func); 2639 this->getDest()->emit(Func);
2649 Str << "\n";
2650 } 2640 }
2651 2641
2652 template <class Machine> 2642 template <class Machine>
2653 void InstX86Fstp<Machine>::emitIAS(const Cfg *Func) const { 2643 void InstX86Fstp<Machine>::emitIAS(const Cfg *Func) const {
2654 typename InstX86Base<Machine>::Traits::Assembler *Asm = 2644 typename InstX86Base<Machine>::Traits::Assembler *Asm =
2655 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); 2645 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
2656 assert(this->getSrcSize() == 0); 2646 assert(this->getSrcSize() == 0);
2657 const Variable *Dest = this->getDest(); 2647 const Variable *Dest = this->getDest();
2658 // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to 2648 // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to
2659 // "partially" delete the fstp if the Dest is unused. Even if Dest is unused, 2649 // "partially" delete the fstp if the Dest is unused. Even if Dest is unused,
(...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after
3244 return; 3234 return;
3245 Ostream &Str = Func->getContext()->getStrDump(); 3235 Ostream &Str = Func->getContext()->getStrDump();
3246 Str << "IACA_END"; 3236 Str << "IACA_END";
3247 } 3237 }
3248 3238
3249 } // end of namespace X86Internal 3239 } // end of namespace X86Internal
3250 3240
3251 } // end of namespace Ice 3241 } // end of namespace Ice
3252 3242
3253 #endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H 3243 #endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H
OLDNEW
« no previous file with comments | « src/IceCfg.h ('k') | src/IceTargetLoweringX8632.cpp » ('j') | src/IceTargetLoweringX8632.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698