Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 1 | //===- subzero/src/IceTargetLoweringX8632.h - x86-32 lowering ---*- C++ -*-===// |
| 2 | // |
| 3 | // The Subzero Code Generator |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
| 10 | // This file declares the TargetLoweringX8632 class, which |
| 11 | // implements the TargetLowering interface for the x86-32 |
| 12 | // architecture. |
| 13 | // |
| 14 | //===----------------------------------------------------------------------===// |
| 15 | |
| 16 | #ifndef SUBZERO_SRC_ICETARGETLOWERINGX8632_H |
| 17 | #define SUBZERO_SRC_ICETARGETLOWERINGX8632_H |
| 18 | |
| 19 | #include "IceDefs.h" |
| 20 | #include "IceTargetLowering.h" |
| 21 | #include "IceInstX8632.h" |
| 22 | |
| 23 | namespace Ice { |
| 24 | |
| 25 | class TargetX8632 : public TargetLowering { |
| 26 | public: |
| 27 | static TargetX8632 *create(Cfg *Func) { return new TargetX8632(Func); } |
| 28 | |
| 29 | virtual void translateOm1(); |
Jim Stichnoth | d97c7df | 2014-06-04 11:57:08 -0700 | [diff] [blame] | 30 | virtual void translateO2(); |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 31 | |
| 32 | virtual Variable *getPhysicalRegister(SizeT RegNum); |
| 33 | virtual IceString getRegName(SizeT RegNum, Type Ty) const; |
| 34 | virtual llvm::SmallBitVector getRegisterSet(RegSetMask Include, |
| 35 | RegSetMask Exclude) const; |
| 36 | virtual const llvm::SmallBitVector &getRegisterSetForType(Type Ty) const { |
| 37 | return TypeToRegisterSet[Ty]; |
| 38 | } |
| 39 | virtual bool hasFramePointer() const { return IsEbpBasedFrame; } |
| 40 | virtual SizeT getFrameOrStackReg() const { |
| 41 | return IsEbpBasedFrame ? Reg_ebp : Reg_esp; |
| 42 | } |
| 43 | virtual size_t typeWidthInBytesOnStack(Type Ty) { |
| 44 | // Round up to the next multiple of 4 bytes. In particular, i1, |
| 45 | // i8, and i16 are rounded up to 4 bytes. |
| 46 | return (typeWidthInBytes(Ty) + 3) & ~3; |
| 47 | } |
| 48 | virtual void emitVariable(const Variable *Var, const Cfg *Func) const; |
Matt Wala | 45a0623 | 2014-07-09 16:33:22 -0700 | [diff] [blame] | 49 | virtual void lowerArguments(); |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 50 | virtual void addProlog(CfgNode *Node); |
| 51 | virtual void addEpilog(CfgNode *Node); |
Jim Stichnoth | f61d5b2 | 2014-05-23 13:31:24 -0700 | [diff] [blame] | 52 | virtual void emitConstants() const; |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 53 | SizeT makeNextLabelNumber() { return NextLabelNumber++; } |
| 54 | // Ensure that a 64-bit Variable has been split into 2 32-bit |
| 55 | // Variables, creating them if necessary. This is needed for all |
| 56 | // I64 operations, and it is needed for pushing F64 arguments for |
| 57 | // function calls using the 32-bit push instruction (though the |
| 58 | // latter could be done by directly writing to the stack). |
| 59 | void split64(Variable *Var); |
Matt Wala | 45a0623 | 2014-07-09 16:33:22 -0700 | [diff] [blame] | 60 | void finishArgumentLowering(Variable *Arg, Variable *FramePtr, |
| 61 | size_t BasicFrameOffset, size_t &InArgsSizeBytes); |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 62 | Operand *loOperand(Operand *Operand); |
| 63 | Operand *hiOperand(Operand *Operand); |
| 64 | |
| 65 | enum Registers { |
| 66 | #define X(val, init, name, name16, name8, scratch, preserved, stackptr, \ |
| 67 | frameptr, isI8, isInt, isFP) \ |
| 68 | val init, |
| 69 | REGX8632_TABLE |
| 70 | #undef X |
| 71 | Reg_NUM |
| 72 | }; |
| 73 | |
Matt Wala | 0a45051 | 2014-07-30 12:44:39 -0700 | [diff] [blame] | 74 | enum X86InstructionSet { |
| 75 | // SSE2 is the PNaCl baseline instruction set. |
| 76 | SSE2, |
| 77 | SSE4_1 |
| 78 | }; |
| 79 | |
| 80 | X86InstructionSet getInstructionSet() const { return InstructionSet; } |
| 81 | |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 82 | protected: |
| 83 | TargetX8632(Cfg *Func); |
| 84 | |
| 85 | virtual void postLower(); |
| 86 | |
| 87 | virtual void lowerAlloca(const InstAlloca *Inst); |
| 88 | virtual void lowerArithmetic(const InstArithmetic *Inst); |
| 89 | virtual void lowerAssign(const InstAssign *Inst); |
| 90 | virtual void lowerBr(const InstBr *Inst); |
| 91 | virtual void lowerCall(const InstCall *Inst); |
| 92 | virtual void lowerCast(const InstCast *Inst); |
Matt Wala | 4988923 | 2014-07-18 12:45:09 -0700 | [diff] [blame] | 93 | virtual void lowerExtractElement(const InstExtractElement *Inst); |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 94 | virtual void lowerFcmp(const InstFcmp *Inst); |
| 95 | virtual void lowerIcmp(const InstIcmp *Inst); |
Jan Voung | 3bd9f1a | 2014-06-18 10:50:57 -0700 | [diff] [blame] | 96 | virtual void lowerIntrinsicCall(const InstIntrinsicCall *Inst); |
Matt Wala | 4988923 | 2014-07-18 12:45:09 -0700 | [diff] [blame] | 97 | virtual void lowerInsertElement(const InstInsertElement *Inst); |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 98 | virtual void lowerLoad(const InstLoad *Inst); |
| 99 | virtual void lowerPhi(const InstPhi *Inst); |
| 100 | virtual void lowerRet(const InstRet *Inst); |
| 101 | virtual void lowerSelect(const InstSelect *Inst); |
| 102 | virtual void lowerStore(const InstStore *Inst); |
| 103 | virtual void lowerSwitch(const InstSwitch *Inst); |
| 104 | virtual void lowerUnreachable(const InstUnreachable *Inst); |
Jim Stichnoth | d97c7df | 2014-06-04 11:57:08 -0700 | [diff] [blame] | 105 | virtual void doAddressOptLoad(); |
| 106 | virtual void doAddressOptStore(); |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 107 | |
Jan Voung | c820ddf | 2014-07-29 14:38:51 -0700 | [diff] [blame] | 108 | // Naive lowering of cmpxchg. |
Jan Voung | a3a01a2 | 2014-07-14 10:32:41 -0700 | [diff] [blame] | 109 | void lowerAtomicCmpxchg(Variable *DestPrev, Operand *Ptr, Operand *Expected, |
| 110 | Operand *Desired); |
Jan Voung | c820ddf | 2014-07-29 14:38:51 -0700 | [diff] [blame] | 111 | // Attempt a more optimized lowering of cmpxchg. Returns true if optimized. |
| 112 | bool tryOptimizedCmpxchgCmpBr(Variable *DestPrev, Operand *Ptr, |
| 113 | Operand *Expected, Operand *Desired); |
Jan Voung | 5cd240d | 2014-06-25 10:36:46 -0700 | [diff] [blame] | 114 | void lowerAtomicRMW(Variable *Dest, uint32_t Operation, Operand *Ptr, |
| 115 | Operand *Val); |
Jan Voung | e4da26f | 2014-07-15 17:52:39 -0700 | [diff] [blame] | 116 | void lowerCountZeros(bool Cttz, Type Ty, Variable *Dest, Operand *FirstVal, |
| 117 | Operand *SecondVal); |
Jan Voung | 5cd240d | 2014-06-25 10:36:46 -0700 | [diff] [blame] | 118 | |
Jan Voung | a3a01a2 | 2014-07-14 10:32:41 -0700 | [diff] [blame] | 119 | typedef void (TargetX8632::*LowerBinOp)(Variable *, Operand *); |
| 120 | void expandAtomicRMWAsCmpxchg(LowerBinOp op_lo, LowerBinOp op_hi, |
| 121 | Variable *Dest, Operand *Ptr, Operand *Val); |
| 122 | |
Matt Wala | ce0ca8f | 2014-07-24 12:34:20 -0700 | [diff] [blame] | 123 | void eliminateNextVectorSextInstruction(Variable *SignExtendedResult); |
| 124 | |
Matt Wala | afeaee4 | 2014-08-07 13:47:30 -0700 | [diff] [blame] | 125 | void scalarizeArithmetic(InstArithmetic::OpKind K, Variable *Dest, |
| 126 | Operand *Src0, Operand *Src1); |
| 127 | |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 128 | // Operand legalization helpers. To deal with address mode |
| 129 | // constraints, the helpers will create a new Operand and emit |
| 130 | // instructions that guarantee that the Operand kind is one of those |
| 131 | // indicated by the LegalMask (a bitmask of allowed kinds). If the |
| 132 | // input Operand is known to already meet the constraints, it may be |
| 133 | // simply returned as the result, without creating any new |
| 134 | // instructions or operands. |
| 135 | enum OperandLegalization { |
| 136 | Legal_None = 0, |
| 137 | Legal_Reg = 1 << 0, // physical register, not stack location |
| 138 | Legal_Imm = 1 << 1, |
| 139 | Legal_Mem = 1 << 2, // includes [eax+4*ecx] as well as [esp+12] |
Jim Stichnoth | de4ca71 | 2014-06-29 08:13:48 -0700 | [diff] [blame] | 140 | // TODO(stichnot): LEAHACK: remove Legal_Reloc once a proper |
| 141 | // emitter is used. |
| 142 | Legal_Reloc = 1 << 3, |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 143 | Legal_All = ~Legal_None |
| 144 | }; |
| 145 | typedef uint32_t LegalMask; |
Jim Stichnoth | de4ca71 | 2014-06-29 08:13:48 -0700 | [diff] [blame] | 146 | Operand *legalize(Operand *From, LegalMask Allowed = Legal_All & ~Legal_Reloc, |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 147 | bool AllowOverlap = false, |
| 148 | int32_t RegNum = Variable::NoRegister); |
| 149 | Variable *legalizeToVar(Operand *From, bool AllowOverlap = false, |
| 150 | int32_t RegNum = Variable::NoRegister); |
Jan Voung | 5cd240d | 2014-06-25 10:36:46 -0700 | [diff] [blame] | 151 | // Turn a pointer operand into a memory operand that can be |
| 152 | // used by a real load/store operation. Legalizes the operand as well. |
| 153 | // This is a nop if the operand is already a legal memory operand. |
| 154 | OperandX8632Mem *FormMemoryOperand(Operand *Ptr, Type Ty); |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 155 | |
| 156 | Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister); |
| 157 | InstCall *makeHelperCall(const IceString &Name, Variable *Dest, |
| 158 | SizeT MaxSrcs) { |
| 159 | bool SuppressMangling = true; |
Matt Wala | ad8f726 | 2014-07-14 17:37:37 -0700 | [diff] [blame] | 160 | const Type FunctionPointerType = IceType_i32; |
| 161 | Constant *CallTarget = |
| 162 | Ctx->getConstantSym(FunctionPointerType, 0, Name, SuppressMangling); |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 163 | InstCall *Call = InstCall::create(Func, MaxSrcs, Dest, CallTarget); |
| 164 | return Call; |
| 165 | } |
Jan Voung | 3bd9f1a | 2014-06-18 10:50:57 -0700 | [diff] [blame] | 166 | static Type stackSlotType(); |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 167 | |
Matt Wala | 928f129 | 2014-07-07 16:50:46 -0700 | [diff] [blame] | 168 | Variable *copyToReg(Operand *Src, int32_t RegNum = Variable::NoRegister); |
| 169 | |
Matt Wala | 83b8036 | 2014-07-16 10:21:30 -0700 | [diff] [blame] | 170 | // Returns a vector in a register with the given constant entries. |
| 171 | Variable *makeVectorOfZeros(Type Ty, int32_t RegNum = Variable::NoRegister); |
| 172 | Variable *makeVectorOfOnes(Type Ty, int32_t RegNum = Variable::NoRegister); |
Matt Wala | 9a0168a | 2014-07-23 14:56:10 -0700 | [diff] [blame] | 173 | Variable *makeVectorOfMinusOnes(Type Ty, |
| 174 | int32_t RegNum = Variable::NoRegister); |
| 175 | Variable *makeVectorOfHighOrderBits(Type Ty, |
| 176 | int32_t RegNum = Variable::NoRegister); |
Matt Wala | 83b8036 | 2014-07-16 10:21:30 -0700 | [diff] [blame] | 177 | |
Matt Wala | 4988923 | 2014-07-18 12:45:09 -0700 | [diff] [blame] | 178 | // Return a memory operand corresponding to a stack allocated Variable. |
| 179 | OperandX8632Mem *getMemoryOperandForStackSlot(Type Ty, Variable *Slot, |
| 180 | uint32_t Offset = 0); |
| 181 | |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 182 | // The following are helpers that insert lowered x86 instructions |
| 183 | // with minimal syntactic overhead, so that the lowering code can |
| 184 | // look as close to assembly as practical. |
| 185 | void _adc(Variable *Dest, Operand *Src0) { |
| 186 | Context.insert(InstX8632Adc::create(Func, Dest, Src0)); |
| 187 | } |
| 188 | void _add(Variable *Dest, Operand *Src0) { |
| 189 | Context.insert(InstX8632Add::create(Func, Dest, Src0)); |
| 190 | } |
Matt Wala | 105b704 | 2014-08-11 19:56:19 -0700 | [diff] [blame^] | 191 | void _adjust_stack(int32_t Amount) { |
| 192 | Context.insert(InstX8632AdjustStack::create(Func, Amount)); |
| 193 | } |
Matt Wala | 8d1072e | 2014-07-11 15:43:51 -0700 | [diff] [blame] | 194 | void _addps(Variable *Dest, Operand *Src0) { |
| 195 | Context.insert(InstX8632Addps::create(Func, Dest, Src0)); |
| 196 | } |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 197 | void _addss(Variable *Dest, Operand *Src0) { |
| 198 | Context.insert(InstX8632Addss::create(Func, Dest, Src0)); |
| 199 | } |
| 200 | void _and(Variable *Dest, Operand *Src0) { |
| 201 | Context.insert(InstX8632And::create(Func, Dest, Src0)); |
| 202 | } |
Matt Wala | 0a45051 | 2014-07-30 12:44:39 -0700 | [diff] [blame] | 203 | void _blendvps(Variable *Dest, Operand *Src0, Operand *Src1) { |
| 204 | Context.insert(InstX8632Blendvps::create(Func, Dest, Src0, Src1)); |
| 205 | } |
Jan Voung | e4da26f | 2014-07-15 17:52:39 -0700 | [diff] [blame] | 206 | void _br(InstX8632::BrCond Condition, CfgNode *TargetTrue, |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 207 | CfgNode *TargetFalse) { |
| 208 | Context.insert( |
| 209 | InstX8632Br::create(Func, TargetTrue, TargetFalse, Condition)); |
| 210 | } |
| 211 | void _br(CfgNode *Target) { |
| 212 | Context.insert(InstX8632Br::create(Func, Target)); |
| 213 | } |
Jan Voung | e4da26f | 2014-07-15 17:52:39 -0700 | [diff] [blame] | 214 | void _br(InstX8632::BrCond Condition, CfgNode *Target) { |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 215 | Context.insert(InstX8632Br::create(Func, Target, Condition)); |
| 216 | } |
Jan Voung | e4da26f | 2014-07-15 17:52:39 -0700 | [diff] [blame] | 217 | void _br(InstX8632::BrCond Condition, InstX8632Label *Label) { |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 218 | Context.insert(InstX8632Br::create(Func, Label, Condition)); |
| 219 | } |
Jan Voung | e4da26f | 2014-07-15 17:52:39 -0700 | [diff] [blame] | 220 | void _bsf(Variable *Dest, Operand *Src0) { |
| 221 | Context.insert(InstX8632Bsf::create(Func, Dest, Src0)); |
| 222 | } |
| 223 | void _bsr(Variable *Dest, Operand *Src0) { |
| 224 | Context.insert(InstX8632Bsr::create(Func, Dest, Src0)); |
| 225 | } |
Jan Voung | 7fa813b | 2014-07-18 13:01:08 -0700 | [diff] [blame] | 226 | void _bswap(Variable *SrcDest) { |
| 227 | Context.insert(InstX8632Bswap::create(Func, SrcDest)); |
| 228 | } |
Matt Wala | afeaee4 | 2014-08-07 13:47:30 -0700 | [diff] [blame] | 229 | void _cbwdq(Variable *Dest, Operand *Src0) { |
| 230 | Context.insert(InstX8632Cbwdq::create(Func, Dest, Src0)); |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 231 | } |
Jan Voung | e4da26f | 2014-07-15 17:52:39 -0700 | [diff] [blame] | 232 | void _cmov(Variable *Dest, Operand *Src0, InstX8632::BrCond Condition) { |
| 233 | Context.insert(InstX8632Cmov::create(Func, Dest, Src0, Condition)); |
| 234 | } |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 235 | void _cmp(Operand *Src0, Operand *Src1) { |
| 236 | Context.insert(InstX8632Icmp::create(Func, Src0, Src1)); |
| 237 | } |
Matt Wala | ce0ca8f | 2014-07-24 12:34:20 -0700 | [diff] [blame] | 238 | void _cmpps(Variable *Dest, Operand *Src0, |
| 239 | InstX8632Cmpps::CmppsCond Condition) { |
| 240 | Context.insert(InstX8632Cmpps::create(Func, Dest, Src0, Condition)); |
| 241 | } |
Jan Voung | a3a01a2 | 2014-07-14 10:32:41 -0700 | [diff] [blame] | 242 | void _cmpxchg(Operand *DestOrAddr, Variable *Eax, Variable *Desired, |
| 243 | bool Locked) { |
| 244 | Context.insert( |
| 245 | InstX8632Cmpxchg::create(Func, DestOrAddr, Eax, Desired, Locked)); |
| 246 | // Mark eax as possibly modified by cmpxchg. |
| 247 | Context.insert( |
| 248 | InstFakeDef::create(Func, Eax, llvm::dyn_cast<Variable>(DestOrAddr))); |
| 249 | } |
| 250 | void _cmpxchg8b(OperandX8632 *Addr, Variable *Edx, Variable *Eax, |
| 251 | Variable *Ecx, Variable *Ebx, bool Locked) { |
| 252 | Context.insert( |
| 253 | InstX8632Cmpxchg8b::create(Func, Addr, Edx, Eax, Ecx, Ebx, Locked)); |
| 254 | // Mark edx, and eax as possibly modified by cmpxchg8b. |
| 255 | Context.insert(InstFakeDef::create(Func, Edx)); |
| 256 | Context.insert(InstFakeDef::create(Func, Eax)); |
| 257 | } |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 258 | void _cvt(Variable *Dest, Operand *Src0) { |
| 259 | Context.insert(InstX8632Cvt::create(Func, Dest, Src0)); |
| 260 | } |
| 261 | void _div(Variable *Dest, Operand *Src0, Operand *Src1) { |
| 262 | Context.insert(InstX8632Div::create(Func, Dest, Src0, Src1)); |
| 263 | } |
Matt Wala | 8d1072e | 2014-07-11 15:43:51 -0700 | [diff] [blame] | 264 | void _divps(Variable *Dest, Operand *Src0) { |
| 265 | Context.insert(InstX8632Divps::create(Func, Dest, Src0)); |
| 266 | } |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 267 | void _divss(Variable *Dest, Operand *Src0) { |
| 268 | Context.insert(InstX8632Divss::create(Func, Dest, Src0)); |
| 269 | } |
| 270 | void _fld(Operand *Src0) { Context.insert(InstX8632Fld::create(Func, Src0)); } |
| 271 | void _fstp(Variable *Dest) { |
| 272 | Context.insert(InstX8632Fstp::create(Func, Dest)); |
| 273 | } |
| 274 | void _idiv(Variable *Dest, Operand *Src0, Operand *Src1) { |
| 275 | Context.insert(InstX8632Idiv::create(Func, Dest, Src0, Src1)); |
| 276 | } |
| 277 | void _imul(Variable *Dest, Operand *Src0) { |
| 278 | Context.insert(InstX8632Imul::create(Func, Dest, Src0)); |
| 279 | } |
Matt Wala | 0a45051 | 2014-07-30 12:44:39 -0700 | [diff] [blame] | 280 | void _insertps(Variable *Dest, Operand *Src0, Operand *Src1) { |
| 281 | Context.insert(InstX8632Insertps::create(Func, Dest, Src0, Src1)); |
| 282 | } |
Matt Wala | 4988923 | 2014-07-18 12:45:09 -0700 | [diff] [blame] | 283 | void _lea(Variable *Dest, Operand *Src0) { |
| 284 | Context.insert(InstX8632Lea::create(Func, Dest, Src0)); |
| 285 | } |
Jan Voung | 5cd240d | 2014-06-25 10:36:46 -0700 | [diff] [blame] | 286 | void _mfence() { Context.insert(InstX8632Mfence::create(Func)); } |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 287 | // If Dest=NULL is passed in, then a new variable is created, marked |
| 288 | // as infinite register allocation weight, and returned through the |
| 289 | // in/out Dest argument. |
| 290 | void _mov(Variable *&Dest, Operand *Src0, |
| 291 | int32_t RegNum = Variable::NoRegister) { |
| 292 | if (Dest == NULL) { |
| 293 | Dest = legalizeToVar(Src0, false, RegNum); |
| 294 | } else { |
| 295 | Context.insert(InstX8632Mov::create(Func, Dest, Src0)); |
| 296 | } |
| 297 | } |
Matt Wala | 4988923 | 2014-07-18 12:45:09 -0700 | [diff] [blame] | 298 | void _movd(Variable *Dest, Operand *Src0) { |
| 299 | Context.insert(InstX8632Movd::create(Func, Dest, Src0)); |
| 300 | } |
Matt Wala | 928f129 | 2014-07-07 16:50:46 -0700 | [diff] [blame] | 301 | void _movp(Variable *Dest, Operand *Src0) { |
| 302 | Context.insert(InstX8632Movp::create(Func, Dest, Src0)); |
| 303 | } |
Jan Voung | 5cd240d | 2014-06-25 10:36:46 -0700 | [diff] [blame] | 304 | void _movq(Variable *Dest, Operand *Src0) { |
| 305 | Context.insert(InstX8632Movq::create(Func, Dest, Src0)); |
| 306 | } |
Matt Wala | 4988923 | 2014-07-18 12:45:09 -0700 | [diff] [blame] | 307 | void _movss(Variable *Dest, Operand *Src0) { |
| 308 | Context.insert(InstX8632Movss::create(Func, Dest, Src0)); |
| 309 | } |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 310 | void _movsx(Variable *Dest, Operand *Src0) { |
| 311 | Context.insert(InstX8632Movsx::create(Func, Dest, Src0)); |
| 312 | } |
| 313 | void _movzx(Variable *Dest, Operand *Src0) { |
| 314 | Context.insert(InstX8632Movzx::create(Func, Dest, Src0)); |
| 315 | } |
| 316 | void _mul(Variable *Dest, Variable *Src0, Operand *Src1) { |
| 317 | Context.insert(InstX8632Mul::create(Func, Dest, Src0, Src1)); |
| 318 | } |
Matt Wala | 8d1072e | 2014-07-11 15:43:51 -0700 | [diff] [blame] | 319 | void _mulps(Variable *Dest, Operand *Src0) { |
| 320 | Context.insert(InstX8632Mulps::create(Func, Dest, Src0)); |
| 321 | } |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 322 | void _mulss(Variable *Dest, Operand *Src0) { |
| 323 | Context.insert(InstX8632Mulss::create(Func, Dest, Src0)); |
| 324 | } |
Jan Voung | a3a01a2 | 2014-07-14 10:32:41 -0700 | [diff] [blame] | 325 | void _neg(Variable *SrcDest) { |
| 326 | Context.insert(InstX8632Neg::create(Func, SrcDest)); |
| 327 | } |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 328 | void _or(Variable *Dest, Operand *Src0) { |
| 329 | Context.insert(InstX8632Or::create(Func, Dest, Src0)); |
| 330 | } |
Matt Wala | 7fa22d8 | 2014-07-17 12:41:31 -0700 | [diff] [blame] | 331 | void _padd(Variable *Dest, Operand *Src0) { |
| 332 | Context.insert(InstX8632Padd::create(Func, Dest, Src0)); |
| 333 | } |
Matt Wala | 83b8036 | 2014-07-16 10:21:30 -0700 | [diff] [blame] | 334 | void _pand(Variable *Dest, Operand *Src0) { |
| 335 | Context.insert(InstX8632Pand::create(Func, Dest, Src0)); |
| 336 | } |
Matt Wala | 9cb61e2 | 2014-07-24 09:44:42 -0700 | [diff] [blame] | 337 | void _pandn(Variable *Dest, Operand *Src0) { |
| 338 | Context.insert(InstX8632Pandn::create(Func, Dest, Src0)); |
| 339 | } |
Matt Wala | 0a45051 | 2014-07-30 12:44:39 -0700 | [diff] [blame] | 340 | void _pblendvb(Variable *Dest, Operand *Src0, Operand *Src1) { |
| 341 | Context.insert(InstX8632Pblendvb::create(Func, Dest, Src0, Src1)); |
| 342 | } |
Matt Wala | 83b8036 | 2014-07-16 10:21:30 -0700 | [diff] [blame] | 343 | void _pcmpeq(Variable *Dest, Operand *Src0) { |
| 344 | Context.insert(InstX8632Pcmpeq::create(Func, Dest, Src0)); |
| 345 | } |
| 346 | void _pcmpgt(Variable *Dest, Operand *Src0) { |
| 347 | Context.insert(InstX8632Pcmpgt::create(Func, Dest, Src0)); |
| 348 | } |
Matt Wala | 0a45051 | 2014-07-30 12:44:39 -0700 | [diff] [blame] | 349 | void _pextr(Variable *Dest, Operand *Src0, Operand *Src1) { |
| 350 | Context.insert(InstX8632Pextr::create(Func, Dest, Src0, Src1)); |
Matt Wala | 4988923 | 2014-07-18 12:45:09 -0700 | [diff] [blame] | 351 | } |
Matt Wala | 0a45051 | 2014-07-30 12:44:39 -0700 | [diff] [blame] | 352 | void _pinsr(Variable *Dest, Operand *Src0, Operand *Src1) { |
| 353 | Context.insert(InstX8632Pinsr::create(Func, Dest, Src0, Src1)); |
Matt Wala | 4988923 | 2014-07-18 12:45:09 -0700 | [diff] [blame] | 354 | } |
Matt Wala | 0a45051 | 2014-07-30 12:44:39 -0700 | [diff] [blame] | 355 | void _pmull(Variable *Dest, Operand *Src0) { |
| 356 | Context.insert(InstX8632Pmull::create(Func, Dest, Src0)); |
Matt Wala | 7fa22d8 | 2014-07-17 12:41:31 -0700 | [diff] [blame] | 357 | } |
| 358 | void _pmuludq(Variable *Dest, Operand *Src0) { |
| 359 | Context.insert(InstX8632Pmuludq::create(Func, Dest, Src0)); |
| 360 | } |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 361 | void _pop(Variable *Dest) { |
| 362 | Context.insert(InstX8632Pop::create(Func, Dest)); |
| 363 | } |
Matt Wala | 7fa22d8 | 2014-07-17 12:41:31 -0700 | [diff] [blame] | 364 | void _por(Variable *Dest, Operand *Src0) { |
| 365 | Context.insert(InstX8632Por::create(Func, Dest, Src0)); |
| 366 | } |
| 367 | void _pshufd(Variable *Dest, Operand *Src0, Operand *Src1) { |
| 368 | Context.insert(InstX8632Pshufd::create(Func, Dest, Src0, Src1)); |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 369 | } |
Matt Wala | 83b8036 | 2014-07-16 10:21:30 -0700 | [diff] [blame] | 370 | void _psll(Variable *Dest, Operand *Src0) { |
| 371 | Context.insert(InstX8632Psll::create(Func, Dest, Src0)); |
| 372 | } |
| 373 | void _psra(Variable *Dest, Operand *Src0) { |
| 374 | Context.insert(InstX8632Psra::create(Func, Dest, Src0)); |
| 375 | } |
| 376 | void _psub(Variable *Dest, Operand *Src0) { |
| 377 | Context.insert(InstX8632Psub::create(Func, Dest, Src0)); |
| 378 | } |
Matt Wala | 7fa22d8 | 2014-07-17 12:41:31 -0700 | [diff] [blame] | 379 | void _push(Operand *Src0, bool SuppressStackAdjustment = false) { |
| 380 | Context.insert(InstX8632Push::create(Func, Src0, SuppressStackAdjustment)); |
| 381 | } |
Matt Wala | 8d1072e | 2014-07-11 15:43:51 -0700 | [diff] [blame] | 382 | void _pxor(Variable *Dest, Operand *Src0) { |
| 383 | Context.insert(InstX8632Pxor::create(Func, Dest, Src0)); |
| 384 | } |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 385 | void _ret(Variable *Src0 = NULL) { |
| 386 | Context.insert(InstX8632Ret::create(Func, Src0)); |
| 387 | } |
Jan Voung | 7fa813b | 2014-07-18 13:01:08 -0700 | [diff] [blame] | 388 | void _rol(Variable *Dest, Operand *Src0) { |
| 389 | Context.insert(InstX8632Rol::create(Func, Dest, Src0)); |
| 390 | } |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 391 | void _sar(Variable *Dest, Operand *Src0) { |
| 392 | Context.insert(InstX8632Sar::create(Func, Dest, Src0)); |
| 393 | } |
| 394 | void _sbb(Variable *Dest, Operand *Src0) { |
| 395 | Context.insert(InstX8632Sbb::create(Func, Dest, Src0)); |
| 396 | } |
| 397 | void _shl(Variable *Dest, Operand *Src0) { |
| 398 | Context.insert(InstX8632Shl::create(Func, Dest, Src0)); |
| 399 | } |
| 400 | void _shld(Variable *Dest, Variable *Src0, Variable *Src1) { |
| 401 | Context.insert(InstX8632Shld::create(Func, Dest, Src0, Src1)); |
| 402 | } |
| 403 | void _shr(Variable *Dest, Operand *Src0) { |
| 404 | Context.insert(InstX8632Shr::create(Func, Dest, Src0)); |
| 405 | } |
| 406 | void _shrd(Variable *Dest, Variable *Src0, Variable *Src1) { |
| 407 | Context.insert(InstX8632Shrd::create(Func, Dest, Src0, Src1)); |
| 408 | } |
Matt Wala | 7fa22d8 | 2014-07-17 12:41:31 -0700 | [diff] [blame] | 409 | void _shufps(Variable *Dest, Operand *Src0, Operand *Src1) { |
| 410 | Context.insert(InstX8632Shufps::create(Func, Dest, Src0, Src1)); |
| 411 | } |
Jan Voung | f37fbbe | 2014-07-09 16:13:13 -0700 | [diff] [blame] | 412 | void _sqrtss(Variable *Dest, Operand *Src0) { |
| 413 | Context.insert(InstX8632Sqrtss::create(Func, Dest, Src0)); |
| 414 | } |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 415 | void _store(Operand *Value, OperandX8632 *Mem) { |
| 416 | Context.insert(InstX8632Store::create(Func, Value, Mem)); |
| 417 | } |
Matt Wala | 105b704 | 2014-08-11 19:56:19 -0700 | [diff] [blame^] | 418 | void _storep(Operand *Value, OperandX8632 *Mem) { |
| 419 | Context.insert(InstX8632StoreP::create(Func, Value, Mem)); |
| 420 | } |
Jan Voung | 5cd240d | 2014-06-25 10:36:46 -0700 | [diff] [blame] | 421 | void _storeq(Operand *Value, OperandX8632 *Mem) { |
| 422 | Context.insert(InstX8632StoreQ::create(Func, Value, Mem)); |
| 423 | } |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 424 | void _sub(Variable *Dest, Operand *Src0) { |
| 425 | Context.insert(InstX8632Sub::create(Func, Dest, Src0)); |
| 426 | } |
Matt Wala | 8d1072e | 2014-07-11 15:43:51 -0700 | [diff] [blame] | 427 | void _subps(Variable *Dest, Operand *Src0) { |
| 428 | Context.insert(InstX8632Subps::create(Func, Dest, Src0)); |
| 429 | } |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 430 | void _subss(Variable *Dest, Operand *Src0) { |
| 431 | Context.insert(InstX8632Subss::create(Func, Dest, Src0)); |
| 432 | } |
| 433 | void _test(Operand *Src0, Operand *Src1) { |
| 434 | Context.insert(InstX8632Test::create(Func, Src0, Src1)); |
| 435 | } |
| 436 | void _ucomiss(Operand *Src0, Operand *Src1) { |
| 437 | Context.insert(InstX8632Ucomiss::create(Func, Src0, Src1)); |
| 438 | } |
Jan Voung | 3bd9f1a | 2014-06-18 10:50:57 -0700 | [diff] [blame] | 439 | void _ud2() { Context.insert(InstX8632UD2::create(Func)); } |
Jan Voung | 5cd240d | 2014-06-25 10:36:46 -0700 | [diff] [blame] | 440 | void _xadd(Operand *Dest, Variable *Src, bool Locked) { |
| 441 | Context.insert(InstX8632Xadd::create(Func, Dest, Src, Locked)); |
| 442 | // The xadd exchanges Dest and Src (modifying Src). |
| 443 | // Model that update with a FakeDef. |
Jan Voung | a3a01a2 | 2014-07-14 10:32:41 -0700 | [diff] [blame] | 444 | Context.insert( |
| 445 | InstFakeDef::create(Func, Src, llvm::dyn_cast<Variable>(Dest))); |
| 446 | } |
| 447 | void _xchg(Operand *Dest, Variable *Src) { |
| 448 | Context.insert(InstX8632Xchg::create(Func, Dest, Src)); |
| 449 | // The xchg modifies Dest and Src -- model that update with a FakeDef. |
| 450 | Context.insert( |
| 451 | InstFakeDef::create(Func, Src, llvm::dyn_cast<Variable>(Dest))); |
Jan Voung | 5cd240d | 2014-06-25 10:36:46 -0700 | [diff] [blame] | 452 | } |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 453 | void _xor(Variable *Dest, Operand *Src0) { |
| 454 | Context.insert(InstX8632Xor::create(Func, Dest, Src0)); |
| 455 | } |
| 456 | |
Matt Wala | 0a45051 | 2014-07-30 12:44:39 -0700 | [diff] [blame] | 457 | const X86InstructionSet InstructionSet; |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 458 | bool IsEbpBasedFrame; |
Matt Wala | 105b704 | 2014-08-11 19:56:19 -0700 | [diff] [blame^] | 459 | bool NeedsStackAlignment; |
Jim Stichnoth | d97c7df | 2014-06-04 11:57:08 -0700 | [diff] [blame] | 460 | size_t FrameSizeLocals; |
| 461 | size_t LocalsSizeBytes; |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 462 | llvm::SmallBitVector TypeToRegisterSet[IceType_NUM]; |
| 463 | llvm::SmallBitVector ScratchRegs; |
| 464 | llvm::SmallBitVector RegsUsed; |
| 465 | SizeT NextLabelNumber; |
| 466 | bool ComputedLiveRanges; |
| 467 | VarList PhysicalRegisters; |
| 468 | static IceString RegNames[]; |
| 469 | |
| 470 | private: |
| 471 | TargetX8632(const TargetX8632 &) LLVM_DELETED_FUNCTION; |
| 472 | TargetX8632 &operator=(const TargetX8632 &) LLVM_DELETED_FUNCTION; |
| 473 | virtual ~TargetX8632() {} |
Jim Stichnoth | f61d5b2 | 2014-05-23 13:31:24 -0700 | [diff] [blame] | 474 | template <typename T> void emitConstantPool() const; |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 475 | }; |
| 476 | |
Jim Stichnoth | de4ca71 | 2014-06-29 08:13:48 -0700 | [diff] [blame] | 477 | class TargetGlobalInitX8632 : public TargetGlobalInitLowering { |
| 478 | public: |
| 479 | static TargetGlobalInitLowering *create(GlobalContext *Ctx) { |
| 480 | return new TargetGlobalInitX8632(Ctx); |
| 481 | } |
| 482 | virtual void lower(const IceString &Name, SizeT Align, bool IsInternal, |
| 483 | bool IsConst, bool IsZeroInitializer, SizeT Size, |
| 484 | const char *Data, bool DisableTranslation); |
| 485 | |
| 486 | protected: |
| 487 | TargetGlobalInitX8632(GlobalContext *Ctx); |
| 488 | |
| 489 | private: |
| 490 | TargetGlobalInitX8632(const TargetGlobalInitX8632 &) LLVM_DELETED_FUNCTION; |
| 491 | TargetGlobalInitX8632 & |
| 492 | operator=(const TargetGlobalInitX8632 &) LLVM_DELETED_FUNCTION; |
| 493 | virtual ~TargetGlobalInitX8632() {} |
| 494 | }; |
| 495 | |
Matt Wala | 928f129 | 2014-07-07 16:50:46 -0700 | [diff] [blame] | 496 | template <> void ConstantInteger::emit(GlobalContext *Ctx) const; |
Jim Stichnoth | d97c7df | 2014-06-04 11:57:08 -0700 | [diff] [blame] | 497 | template <> void ConstantFloat::emit(GlobalContext *Ctx) const; |
| 498 | template <> void ConstantDouble::emit(GlobalContext *Ctx) const; |
Jim Stichnoth | f61d5b2 | 2014-05-23 13:31:24 -0700 | [diff] [blame] | 499 | |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 500 | } // end of namespace Ice |
| 501 | |
| 502 | #endif // SUBZERO_SRC_ICETARGETLOWERINGX8632_H |