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 | |
Jim Stichnoth | a59ae6f | 2015-05-17 10:11:41 -0700 | [diff] [blame] | 19 | #include <unordered_map> |
| 20 | |
John Porto | aff4ccf | 2015-06-10 16:35:06 -0700 | [diff] [blame] | 21 | #include "IceAssemblerX8632.h" |
Jim Stichnoth | a18cc9c | 2014-09-30 19:10:22 -0700 | [diff] [blame] | 22 | #include "IceDefs.h" |
Jim Stichnoth | a59ae6f | 2015-05-17 10:11:41 -0700 | [diff] [blame] | 23 | #include "IceInst.h" |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 24 | #include "IceInstX8632.h" |
Jan Voung | bd385e4 | 2014-09-18 18:18:10 -0700 | [diff] [blame] | 25 | #include "IceRegistersX8632.h" |
Jim Stichnoth | a18cc9c | 2014-09-30 19:10:22 -0700 | [diff] [blame] | 26 | #include "IceTargetLowering.h" |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 27 | |
| 28 | namespace Ice { |
| 29 | |
Jim Stichnoth | a59ae6f | 2015-05-17 10:11:41 -0700 | [diff] [blame] | 30 | class BoolFoldingEntry { |
| 31 | BoolFoldingEntry(const BoolFoldingEntry &) = delete; |
| 32 | |
| 33 | public: |
| 34 | BoolFoldingEntry() |
| 35 | : Instr(nullptr), IsComplex(false), IsLiveOut(true), NumUses(0) {} |
| 36 | explicit BoolFoldingEntry(Inst *I); |
| 37 | BoolFoldingEntry &operator=(const BoolFoldingEntry &) = default; |
| 38 | // Instr is the instruction producing the i1-type variable of interest. |
| 39 | Inst *Instr; |
| 40 | // IsComplex is the cached result of BoolFolding::hasComplexLowering(Instr). |
| 41 | bool IsComplex; |
| 42 | // IsLiveOut is initialized conservatively to true, and is set to false when |
| 43 | // we encounter an instruction that ends Var's live range. We disable the |
| 44 | // folding optimization when Var is live beyond this basic block. Note that |
| 45 | // if liveness analysis is not performed (e.g. in Om1 mode), IsLiveOut will |
| 46 | // always be true and the folding optimization will never be performed. |
| 47 | bool IsLiveOut; |
| 48 | // NumUses counts the number of times Var is used as a source operand in the |
| 49 | // basic block. If IsComplex is true and there is more than one use of Var, |
| 50 | // then the folding optimization is disabled for Var. |
| 51 | uint32_t NumUses; |
| 52 | }; |
| 53 | |
| 54 | class BoolFolding { |
| 55 | public: |
| 56 | enum BoolFoldingProducerKind { |
| 57 | PK_None, |
| 58 | PK_Icmp32, |
| 59 | PK_Icmp64, |
| 60 | PK_Fcmp, |
| 61 | PK_Trunc |
| 62 | }; |
| 63 | |
| 64 | // Currently the actual enum values are not used (other than CK_None), but we |
| 65 | // go |
| 66 | // ahead and produce them anyway for symmetry with the |
| 67 | // BoolFoldingProducerKind. |
| 68 | enum BoolFoldingConsumerKind { CK_None, CK_Br, CK_Select, CK_Sext, CK_Zext }; |
| 69 | |
| 70 | private: |
| 71 | BoolFolding(const BoolFolding &) = delete; |
| 72 | BoolFolding &operator=(const BoolFolding &) = delete; |
| 73 | |
| 74 | public: |
| 75 | BoolFolding() {} |
| 76 | static BoolFoldingProducerKind getProducerKind(const Inst *Instr); |
| 77 | static BoolFoldingConsumerKind getConsumerKind(const Inst *Instr); |
| 78 | static bool hasComplexLowering(const Inst *Instr); |
| 79 | void init(CfgNode *Node); |
| 80 | const Inst *getProducerFor(const Operand *Opnd) const; |
| 81 | void dump(const Cfg *Func) const; |
| 82 | |
| 83 | private: |
| 84 | // Returns true if Producers contains a valid entry for the given VarNum. |
| 85 | bool containsValid(SizeT VarNum) const { |
| 86 | auto Element = Producers.find(VarNum); |
| 87 | return Element != Producers.end() && Element->second.Instr != nullptr; |
| 88 | } |
| 89 | void setInvalid(SizeT VarNum) { Producers[VarNum].Instr = nullptr; } |
| 90 | // Producers maps Variable::Number to a BoolFoldingEntry. |
| 91 | std::unordered_map<SizeT, BoolFoldingEntry> Producers; |
| 92 | }; |
| 93 | |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 94 | class TargetX8632 : public TargetLowering { |
Jim Stichnoth | c6ead20 | 2015-02-24 09:30:30 -0800 | [diff] [blame] | 95 | TargetX8632() = delete; |
Jim Stichnoth | 7b451a9 | 2014-10-15 14:39:23 -0700 | [diff] [blame] | 96 | TargetX8632(const TargetX8632 &) = delete; |
| 97 | TargetX8632 &operator=(const TargetX8632 &) = delete; |
| 98 | |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 99 | public: |
| 100 | static TargetX8632 *create(Cfg *Func) { return new TargetX8632(Func); } |
| 101 | |
Jim Stichnoth | b56c8f4 | 2014-09-26 09:28:46 -0700 | [diff] [blame] | 102 | void translateOm1() override; |
| 103 | void translateO2() override; |
Jim Stichnoth | 8e6bf6e | 2015-06-03 15:58:12 -0700 | [diff] [blame] | 104 | void doLoadOpt(); |
Jim Stichnoth | b56c8f4 | 2014-09-26 09:28:46 -0700 | [diff] [blame] | 105 | bool doBranchOpt(Inst *I, const CfgNode *NextNode) override; |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 106 | |
Jim Stichnoth | 3d44fe8 | 2014-11-01 10:10:18 -0700 | [diff] [blame] | 107 | SizeT getNumRegisters() const override { return RegX8632::Reg_NUM; } |
Jim Stichnoth | 98712a3 | 2014-10-24 10:59:02 -0700 | [diff] [blame] | 108 | Variable *getPhysicalRegister(SizeT RegNum, Type Ty = IceType_void) override; |
Jim Stichnoth | b56c8f4 | 2014-09-26 09:28:46 -0700 | [diff] [blame] | 109 | IceString getRegName(SizeT RegNum, Type Ty) const override; |
| 110 | llvm::SmallBitVector getRegisterSet(RegSetMask Include, |
| 111 | RegSetMask Exclude) const override; |
| 112 | const llvm::SmallBitVector &getRegisterSetForType(Type Ty) const override { |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 113 | return TypeToRegisterSet[Ty]; |
| 114 | } |
Jim Stichnoth | b56c8f4 | 2014-09-26 09:28:46 -0700 | [diff] [blame] | 115 | bool hasFramePointer() const override { return IsEbpBasedFrame; } |
| 116 | SizeT getFrameOrStackReg() const override { |
Jan Voung | bd385e4 | 2014-09-18 18:18:10 -0700 | [diff] [blame] | 117 | return IsEbpBasedFrame ? RegX8632::Reg_ebp : RegX8632::Reg_esp; |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 118 | } |
Jim Stichnoth | b56c8f4 | 2014-09-26 09:28:46 -0700 | [diff] [blame] | 119 | size_t typeWidthInBytesOnStack(Type Ty) const override { |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 120 | // Round up to the next multiple of 4 bytes. In particular, i1, |
| 121 | // i8, and i16 are rounded up to 4 bytes. |
| 122 | return (typeWidthInBytes(Ty) + 3) & ~3; |
| 123 | } |
Jan Voung | 0fa6c5a | 2015-06-01 11:04:04 -0700 | [diff] [blame] | 124 | |
Jim Stichnoth | b56c8f4 | 2014-09-26 09:28:46 -0700 | [diff] [blame] | 125 | void emitVariable(const Variable *Var) const override; |
Jan Voung | 76bb0be | 2015-05-14 09:26:19 -0700 | [diff] [blame] | 126 | |
| 127 | const char *getConstantPrefix() const final { return "$"; } |
| 128 | void emit(const ConstantUndef *C) const final; |
| 129 | void emit(const ConstantInteger32 *C) const final; |
| 130 | void emit(const ConstantInteger64 *C) const final; |
| 131 | void emit(const ConstantFloat *C) const final; |
| 132 | void emit(const ConstantDouble *C) const final; |
| 133 | |
Jim Stichnoth | b56c8f4 | 2014-09-26 09:28:46 -0700 | [diff] [blame] | 134 | void lowerArguments() override; |
Jim Stichnoth | a59ae6f | 2015-05-17 10:11:41 -0700 | [diff] [blame] | 135 | void initNodeForLowering(CfgNode *Node) override; |
Jim Stichnoth | b56c8f4 | 2014-09-26 09:28:46 -0700 | [diff] [blame] | 136 | void addProlog(CfgNode *Node) override; |
| 137 | void addEpilog(CfgNode *Node) override; |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 138 | // Ensure that a 64-bit Variable has been split into 2 32-bit |
| 139 | // Variables, creating them if necessary. This is needed for all |
| 140 | // I64 operations, and it is needed for pushing F64 arguments for |
| 141 | // function calls using the 32-bit push instruction (though the |
| 142 | // latter could be done by directly writing to the stack). |
| 143 | void split64(Variable *Var); |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 144 | Operand *loOperand(Operand *Operand); |
| 145 | Operand *hiOperand(Operand *Operand); |
Jan Voung | 0fa6c5a | 2015-06-01 11:04:04 -0700 | [diff] [blame] | 146 | void finishArgumentLowering(Variable *Arg, Variable *FramePtr, |
| 147 | size_t BasicFrameOffset, size_t &InArgsSizeBytes); |
Jan Voung | 90ccc3f | 2015-04-30 14:15:10 -0700 | [diff] [blame] | 148 | X8632::Address stackVarToAsmOperand(const Variable *Var) const; |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 149 | |
Matt Wala | 0a45051 | 2014-07-30 12:44:39 -0700 | [diff] [blame] | 150 | enum X86InstructionSet { |
Jan Voung | 1f47ad0 | 2015-03-20 15:01:26 -0700 | [diff] [blame] | 151 | Begin, |
Matt Wala | 0a45051 | 2014-07-30 12:44:39 -0700 | [diff] [blame] | 152 | // SSE2 is the PNaCl baseline instruction set. |
Jan Voung | 1f47ad0 | 2015-03-20 15:01:26 -0700 | [diff] [blame] | 153 | SSE2 = Begin, |
| 154 | SSE4_1, |
| 155 | End |
Matt Wala | 0a45051 | 2014-07-30 12:44:39 -0700 | [diff] [blame] | 156 | }; |
| 157 | |
| 158 | X86InstructionSet getInstructionSet() const { return InstructionSet; } |
| 159 | |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 160 | protected: |
Jim Stichnoth | c6ead20 | 2015-02-24 09:30:30 -0800 | [diff] [blame] | 161 | explicit TargetX8632(Cfg *Func); |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 162 | |
Jim Stichnoth | b56c8f4 | 2014-09-26 09:28:46 -0700 | [diff] [blame] | 163 | void postLower() override; |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 164 | |
Jim Stichnoth | b56c8f4 | 2014-09-26 09:28:46 -0700 | [diff] [blame] | 165 | void lowerAlloca(const InstAlloca *Inst) override; |
| 166 | void lowerArithmetic(const InstArithmetic *Inst) override; |
| 167 | void lowerAssign(const InstAssign *Inst) override; |
| 168 | void lowerBr(const InstBr *Inst) override; |
| 169 | void lowerCall(const InstCall *Inst) override; |
| 170 | void lowerCast(const InstCast *Inst) override; |
| 171 | void lowerExtractElement(const InstExtractElement *Inst) override; |
| 172 | void lowerFcmp(const InstFcmp *Inst) override; |
| 173 | void lowerIcmp(const InstIcmp *Inst) override; |
| 174 | void lowerIntrinsicCall(const InstIntrinsicCall *Inst) override; |
| 175 | void lowerInsertElement(const InstInsertElement *Inst) override; |
| 176 | void lowerLoad(const InstLoad *Inst) override; |
| 177 | void lowerPhi(const InstPhi *Inst) override; |
| 178 | void lowerRet(const InstRet *Inst) override; |
| 179 | void lowerSelect(const InstSelect *Inst) override; |
| 180 | void lowerStore(const InstStore *Inst) override; |
| 181 | void lowerSwitch(const InstSwitch *Inst) override; |
| 182 | void lowerUnreachable(const InstUnreachable *Inst) override; |
Jim Stichnoth | 336f6c4 | 2014-10-30 15:01:31 -0700 | [diff] [blame] | 183 | void prelowerPhis() override; |
| 184 | void lowerPhiAssignments(CfgNode *Node, |
| 185 | const AssignList &Assignments) override; |
Jim Stichnoth | b56c8f4 | 2014-09-26 09:28:46 -0700 | [diff] [blame] | 186 | void doAddressOptLoad() override; |
| 187 | void doAddressOptStore() override; |
| 188 | void randomlyInsertNop(float Probability) override; |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 189 | |
Jan Voung | c820ddf | 2014-07-29 14:38:51 -0700 | [diff] [blame] | 190 | // Naive lowering of cmpxchg. |
Jan Voung | a3a01a2 | 2014-07-14 10:32:41 -0700 | [diff] [blame] | 191 | void lowerAtomicCmpxchg(Variable *DestPrev, Operand *Ptr, Operand *Expected, |
| 192 | Operand *Desired); |
Jan Voung | c820ddf | 2014-07-29 14:38:51 -0700 | [diff] [blame] | 193 | // Attempt a more optimized lowering of cmpxchg. Returns true if optimized. |
| 194 | bool tryOptimizedCmpxchgCmpBr(Variable *DestPrev, Operand *Ptr, |
| 195 | Operand *Expected, Operand *Desired); |
Jan Voung | 5cd240d | 2014-06-25 10:36:46 -0700 | [diff] [blame] | 196 | void lowerAtomicRMW(Variable *Dest, uint32_t Operation, Operand *Ptr, |
| 197 | Operand *Val); |
Jan Voung | e4da26f | 2014-07-15 17:52:39 -0700 | [diff] [blame] | 198 | void lowerCountZeros(bool Cttz, Type Ty, Variable *Dest, Operand *FirstVal, |
| 199 | Operand *SecondVal); |
Jan Voung | 5cd240d | 2014-06-25 10:36:46 -0700 | [diff] [blame] | 200 | |
Jan Voung | a3a01a2 | 2014-07-14 10:32:41 -0700 | [diff] [blame] | 201 | typedef void (TargetX8632::*LowerBinOp)(Variable *, Operand *); |
| 202 | void expandAtomicRMWAsCmpxchg(LowerBinOp op_lo, LowerBinOp op_hi, |
| 203 | Variable *Dest, Operand *Ptr, Operand *Val); |
| 204 | |
Matt Wala | ce0ca8f | 2014-07-24 12:34:20 -0700 | [diff] [blame] | 205 | void eliminateNextVectorSextInstruction(Variable *SignExtendedResult); |
| 206 | |
Matt Wala | afeaee4 | 2014-08-07 13:47:30 -0700 | [diff] [blame] | 207 | void scalarizeArithmetic(InstArithmetic::OpKind K, Variable *Dest, |
| 208 | Operand *Src0, Operand *Src1); |
| 209 | |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 210 | // Operand legalization helpers. To deal with address mode |
| 211 | // constraints, the helpers will create a new Operand and emit |
| 212 | // instructions that guarantee that the Operand kind is one of those |
| 213 | // indicated by the LegalMask (a bitmask of allowed kinds). If the |
| 214 | // input Operand is known to already meet the constraints, it may be |
| 215 | // simply returned as the result, without creating any new |
| 216 | // instructions or operands. |
| 217 | enum OperandLegalization { |
| 218 | Legal_None = 0, |
| 219 | Legal_Reg = 1 << 0, // physical register, not stack location |
| 220 | Legal_Imm = 1 << 1, |
| 221 | Legal_Mem = 1 << 2, // includes [eax+4*ecx] as well as [esp+12] |
| 222 | Legal_All = ~Legal_None |
| 223 | }; |
| 224 | typedef uint32_t LegalMask; |
Jim Stichnoth | dd16507 | 2014-11-02 09:41:45 -0800 | [diff] [blame] | 225 | Operand *legalize(Operand *From, LegalMask Allowed = Legal_All, |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 226 | int32_t RegNum = Variable::NoRegister); |
Jim Stichnoth | ad40353 | 2014-09-25 12:44:17 -0700 | [diff] [blame] | 227 | Variable *legalizeToVar(Operand *From, int32_t RegNum = Variable::NoRegister); |
Jim Stichnoth | a59ae6f | 2015-05-17 10:11:41 -0700 | [diff] [blame] | 228 | // Legalize the first source operand for use in the cmp instruction. |
| 229 | Operand *legalizeSrc0ForCmp(Operand *Src0, Operand *Src1); |
Jan Voung | 5cd240d | 2014-06-25 10:36:46 -0700 | [diff] [blame] | 230 | // Turn a pointer operand into a memory operand that can be |
| 231 | // used by a real load/store operation. Legalizes the operand as well. |
| 232 | // This is a nop if the operand is already a legal memory operand. |
Jim Stichnoth | 8e6bf6e | 2015-06-03 15:58:12 -0700 | [diff] [blame] | 233 | OperandX8632Mem *formMemoryOperand(Operand *Ptr, Type Ty, |
| 234 | bool DoLegalize = true); |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 235 | |
| 236 | Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister); |
Jan Voung | 3bd9f1a | 2014-06-18 10:50:57 -0700 | [diff] [blame] | 237 | static Type stackSlotType(); |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 238 | |
Matt Wala | 928f129 | 2014-07-07 16:50:46 -0700 | [diff] [blame] | 239 | Variable *copyToReg(Operand *Src, int32_t RegNum = Variable::NoRegister); |
| 240 | |
Matt Wala | 83b8036 | 2014-07-16 10:21:30 -0700 | [diff] [blame] | 241 | // Returns a vector in a register with the given constant entries. |
| 242 | Variable *makeVectorOfZeros(Type Ty, int32_t RegNum = Variable::NoRegister); |
| 243 | Variable *makeVectorOfOnes(Type Ty, int32_t RegNum = Variable::NoRegister); |
Matt Wala | 9a0168a | 2014-07-23 14:56:10 -0700 | [diff] [blame] | 244 | Variable *makeVectorOfMinusOnes(Type Ty, |
| 245 | int32_t RegNum = Variable::NoRegister); |
| 246 | Variable *makeVectorOfHighOrderBits(Type Ty, |
| 247 | int32_t RegNum = Variable::NoRegister); |
Jim Stichnoth | 8c980d0 | 2015-03-19 13:01:50 -0700 | [diff] [blame] | 248 | Variable *makeVectorOfFabsMask(Type Ty, |
| 249 | int32_t RegNum = Variable::NoRegister); |
Matt Wala | 83b8036 | 2014-07-16 10:21:30 -0700 | [diff] [blame] | 250 | |
Matt Wala | 4988923 | 2014-07-18 12:45:09 -0700 | [diff] [blame] | 251 | // Return a memory operand corresponding to a stack allocated Variable. |
| 252 | OperandX8632Mem *getMemoryOperandForStackSlot(Type Ty, Variable *Slot, |
| 253 | uint32_t Offset = 0); |
| 254 | |
Jim Stichnoth | e6d2478 | 2014-12-19 05:42:24 -0800 | [diff] [blame] | 255 | void makeRandomRegisterPermutation( |
| 256 | llvm::SmallVectorImpl<int32_t> &Permutation, |
Jan Voung | 3ce1a99 | 2015-02-03 08:27:44 -0800 | [diff] [blame] | 257 | const llvm::SmallBitVector &ExcludeRegisters) const override; |
Jim Stichnoth | e6d2478 | 2014-12-19 05:42:24 -0800 | [diff] [blame] | 258 | |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 259 | // The following are helpers that insert lowered x86 instructions |
| 260 | // with minimal syntactic overhead, so that the lowering code can |
| 261 | // look as close to assembly as practical. |
| 262 | void _adc(Variable *Dest, Operand *Src0) { |
| 263 | Context.insert(InstX8632Adc::create(Func, Dest, Src0)); |
| 264 | } |
| 265 | void _add(Variable *Dest, Operand *Src0) { |
| 266 | Context.insert(InstX8632Add::create(Func, Dest, Src0)); |
| 267 | } |
Matt Wala | 105b704 | 2014-08-11 19:56:19 -0700 | [diff] [blame] | 268 | void _adjust_stack(int32_t Amount) { |
Jim Stichnoth | 144cdce | 2014-09-22 16:02:59 -0700 | [diff] [blame] | 269 | Context.insert(InstX8632AdjustStack::create( |
| 270 | Func, Amount, getPhysicalRegister(RegX8632::Reg_esp))); |
Matt Wala | 105b704 | 2014-08-11 19:56:19 -0700 | [diff] [blame] | 271 | } |
Matt Wala | 8d1072e | 2014-07-11 15:43:51 -0700 | [diff] [blame] | 272 | void _addps(Variable *Dest, Operand *Src0) { |
| 273 | Context.insert(InstX8632Addps::create(Func, Dest, Src0)); |
| 274 | } |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 275 | void _addss(Variable *Dest, Operand *Src0) { |
| 276 | Context.insert(InstX8632Addss::create(Func, Dest, Src0)); |
| 277 | } |
| 278 | void _and(Variable *Dest, Operand *Src0) { |
| 279 | Context.insert(InstX8632And::create(Func, Dest, Src0)); |
| 280 | } |
Matt Wala | 0a45051 | 2014-07-30 12:44:39 -0700 | [diff] [blame] | 281 | void _blendvps(Variable *Dest, Operand *Src0, Operand *Src1) { |
| 282 | Context.insert(InstX8632Blendvps::create(Func, Dest, Src0, Src1)); |
| 283 | } |
Jan Voung | bd385e4 | 2014-09-18 18:18:10 -0700 | [diff] [blame] | 284 | void _br(CondX86::BrCond Condition, CfgNode *TargetTrue, |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 285 | CfgNode *TargetFalse) { |
| 286 | Context.insert( |
| 287 | InstX8632Br::create(Func, TargetTrue, TargetFalse, Condition)); |
| 288 | } |
| 289 | void _br(CfgNode *Target) { |
| 290 | Context.insert(InstX8632Br::create(Func, Target)); |
| 291 | } |
Jan Voung | bd385e4 | 2014-09-18 18:18:10 -0700 | [diff] [blame] | 292 | void _br(CondX86::BrCond Condition, CfgNode *Target) { |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 293 | Context.insert(InstX8632Br::create(Func, Target, Condition)); |
| 294 | } |
Jan Voung | bd385e4 | 2014-09-18 18:18:10 -0700 | [diff] [blame] | 295 | void _br(CondX86::BrCond Condition, InstX8632Label *Label) { |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 296 | Context.insert(InstX8632Br::create(Func, Label, Condition)); |
| 297 | } |
Jan Voung | e4da26f | 2014-07-15 17:52:39 -0700 | [diff] [blame] | 298 | void _bsf(Variable *Dest, Operand *Src0) { |
| 299 | Context.insert(InstX8632Bsf::create(Func, Dest, Src0)); |
| 300 | } |
| 301 | void _bsr(Variable *Dest, Operand *Src0) { |
| 302 | Context.insert(InstX8632Bsr::create(Func, Dest, Src0)); |
| 303 | } |
Jan Voung | 7fa813b | 2014-07-18 13:01:08 -0700 | [diff] [blame] | 304 | void _bswap(Variable *SrcDest) { |
| 305 | Context.insert(InstX8632Bswap::create(Func, SrcDest)); |
| 306 | } |
Matt Wala | afeaee4 | 2014-08-07 13:47:30 -0700 | [diff] [blame] | 307 | void _cbwdq(Variable *Dest, Operand *Src0) { |
| 308 | Context.insert(InstX8632Cbwdq::create(Func, Dest, Src0)); |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 309 | } |
Jan Voung | bd385e4 | 2014-09-18 18:18:10 -0700 | [diff] [blame] | 310 | void _cmov(Variable *Dest, Operand *Src0, CondX86::BrCond Condition) { |
Jan Voung | e4da26f | 2014-07-15 17:52:39 -0700 | [diff] [blame] | 311 | Context.insert(InstX8632Cmov::create(Func, Dest, Src0, Condition)); |
| 312 | } |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 313 | void _cmp(Operand *Src0, Operand *Src1) { |
| 314 | Context.insert(InstX8632Icmp::create(Func, Src0, Src1)); |
| 315 | } |
Jan Voung | bd385e4 | 2014-09-18 18:18:10 -0700 | [diff] [blame] | 316 | void _cmpps(Variable *Dest, Operand *Src0, CondX86::CmppsCond Condition) { |
Matt Wala | ce0ca8f | 2014-07-24 12:34:20 -0700 | [diff] [blame] | 317 | Context.insert(InstX8632Cmpps::create(Func, Dest, Src0, Condition)); |
| 318 | } |
Jan Voung | a3a01a2 | 2014-07-14 10:32:41 -0700 | [diff] [blame] | 319 | void _cmpxchg(Operand *DestOrAddr, Variable *Eax, Variable *Desired, |
| 320 | bool Locked) { |
| 321 | Context.insert( |
| 322 | InstX8632Cmpxchg::create(Func, DestOrAddr, Eax, Desired, Locked)); |
| 323 | // Mark eax as possibly modified by cmpxchg. |
| 324 | Context.insert( |
| 325 | InstFakeDef::create(Func, Eax, llvm::dyn_cast<Variable>(DestOrAddr))); |
Jim Stichnoth | 4775255 | 2014-10-13 17:15:08 -0700 | [diff] [blame] | 326 | _set_dest_nonkillable(); |
Jim Stichnoth | 0e432ac | 2015-03-24 15:39:16 -0700 | [diff] [blame] | 327 | Context.insert(InstFakeUse::create(Func, Eax)); |
Jan Voung | a3a01a2 | 2014-07-14 10:32:41 -0700 | [diff] [blame] | 328 | } |
Jan Voung | 03532e5 | 2014-09-23 13:32:18 -0700 | [diff] [blame] | 329 | void _cmpxchg8b(OperandX8632Mem *Addr, Variable *Edx, Variable *Eax, |
Jan Voung | a3a01a2 | 2014-07-14 10:32:41 -0700 | [diff] [blame] | 330 | Variable *Ecx, Variable *Ebx, bool Locked) { |
| 331 | Context.insert( |
| 332 | InstX8632Cmpxchg8b::create(Func, Addr, Edx, Eax, Ecx, Ebx, Locked)); |
| 333 | // Mark edx, and eax as possibly modified by cmpxchg8b. |
| 334 | Context.insert(InstFakeDef::create(Func, Edx)); |
Jim Stichnoth | 4775255 | 2014-10-13 17:15:08 -0700 | [diff] [blame] | 335 | _set_dest_nonkillable(); |
Jim Stichnoth | 0e432ac | 2015-03-24 15:39:16 -0700 | [diff] [blame] | 336 | Context.insert(InstFakeUse::create(Func, Edx)); |
Jan Voung | a3a01a2 | 2014-07-14 10:32:41 -0700 | [diff] [blame] | 337 | Context.insert(InstFakeDef::create(Func, Eax)); |
Jim Stichnoth | 4775255 | 2014-10-13 17:15:08 -0700 | [diff] [blame] | 338 | _set_dest_nonkillable(); |
Jim Stichnoth | 0e432ac | 2015-03-24 15:39:16 -0700 | [diff] [blame] | 339 | Context.insert(InstFakeUse::create(Func, Eax)); |
Jan Voung | a3a01a2 | 2014-07-14 10:32:41 -0700 | [diff] [blame] | 340 | } |
Jan Voung | 699bf02 | 2014-10-08 13:52:10 -0700 | [diff] [blame] | 341 | void _cvt(Variable *Dest, Operand *Src0, InstX8632Cvt::CvtVariant Variant) { |
| 342 | Context.insert(InstX8632Cvt::create(Func, Dest, Src0, Variant)); |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 343 | } |
| 344 | void _div(Variable *Dest, Operand *Src0, Operand *Src1) { |
| 345 | Context.insert(InstX8632Div::create(Func, Dest, Src0, Src1)); |
| 346 | } |
Matt Wala | 8d1072e | 2014-07-11 15:43:51 -0700 | [diff] [blame] | 347 | void _divps(Variable *Dest, Operand *Src0) { |
| 348 | Context.insert(InstX8632Divps::create(Func, Dest, Src0)); |
| 349 | } |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 350 | void _divss(Variable *Dest, Operand *Src0) { |
| 351 | Context.insert(InstX8632Divss::create(Func, Dest, Src0)); |
| 352 | } |
| 353 | void _fld(Operand *Src0) { Context.insert(InstX8632Fld::create(Func, Src0)); } |
| 354 | void _fstp(Variable *Dest) { |
| 355 | Context.insert(InstX8632Fstp::create(Func, Dest)); |
| 356 | } |
| 357 | void _idiv(Variable *Dest, Operand *Src0, Operand *Src1) { |
| 358 | Context.insert(InstX8632Idiv::create(Func, Dest, Src0, Src1)); |
| 359 | } |
| 360 | void _imul(Variable *Dest, Operand *Src0) { |
| 361 | Context.insert(InstX8632Imul::create(Func, Dest, Src0)); |
| 362 | } |
Matt Wala | 0a45051 | 2014-07-30 12:44:39 -0700 | [diff] [blame] | 363 | void _insertps(Variable *Dest, Operand *Src0, Operand *Src1) { |
| 364 | Context.insert(InstX8632Insertps::create(Func, Dest, Src0, Src1)); |
| 365 | } |
Jim Stichnoth | 9f42d8c | 2015-02-20 09:20:14 -0800 | [diff] [blame] | 366 | void _jmp(Operand *Target) { |
| 367 | Context.insert(InstX8632Jmp::create(Func, Target)); |
| 368 | } |
Matt Wala | 4988923 | 2014-07-18 12:45:09 -0700 | [diff] [blame] | 369 | void _lea(Variable *Dest, Operand *Src0) { |
| 370 | Context.insert(InstX8632Lea::create(Func, Dest, Src0)); |
| 371 | } |
Jan Voung | 5cd240d | 2014-06-25 10:36:46 -0700 | [diff] [blame] | 372 | void _mfence() { Context.insert(InstX8632Mfence::create(Func)); } |
Jim Stichnoth | ae95320 | 2014-12-20 06:17:49 -0800 | [diff] [blame] | 373 | // If Dest=nullptr is passed in, then a new variable is created, |
| 374 | // marked as infinite register allocation weight, and returned |
| 375 | // through the in/out Dest argument. |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 376 | void _mov(Variable *&Dest, Operand *Src0, |
| 377 | int32_t RegNum = Variable::NoRegister) { |
Jim Stichnoth | ae95320 | 2014-12-20 06:17:49 -0800 | [diff] [blame] | 378 | if (Dest == nullptr) |
Jim Stichnoth | ad40353 | 2014-09-25 12:44:17 -0700 | [diff] [blame] | 379 | Dest = makeReg(Src0->getType(), RegNum); |
| 380 | Context.insert(InstX8632Mov::create(Func, Dest, Src0)); |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 381 | } |
Jim Stichnoth | 4775255 | 2014-10-13 17:15:08 -0700 | [diff] [blame] | 382 | void _mov_nonkillable(Variable *Dest, Operand *Src0) { |
| 383 | Inst *NewInst = InstX8632Mov::create(Func, Dest, Src0); |
| 384 | NewInst->setDestNonKillable(); |
| 385 | Context.insert(NewInst); |
| 386 | } |
Matt Wala | 4988923 | 2014-07-18 12:45:09 -0700 | [diff] [blame] | 387 | void _movd(Variable *Dest, Operand *Src0) { |
| 388 | Context.insert(InstX8632Movd::create(Func, Dest, Src0)); |
| 389 | } |
Matt Wala | 928f129 | 2014-07-07 16:50:46 -0700 | [diff] [blame] | 390 | void _movp(Variable *Dest, Operand *Src0) { |
| 391 | Context.insert(InstX8632Movp::create(Func, Dest, Src0)); |
| 392 | } |
Jan Voung | 5cd240d | 2014-06-25 10:36:46 -0700 | [diff] [blame] | 393 | void _movq(Variable *Dest, Operand *Src0) { |
| 394 | Context.insert(InstX8632Movq::create(Func, Dest, Src0)); |
| 395 | } |
Jan Voung | e4dc61b | 2014-10-06 08:53:52 -0700 | [diff] [blame] | 396 | void _movss(Variable *Dest, Variable *Src0) { |
| 397 | Context.insert(InstX8632MovssRegs::create(Func, Dest, Src0)); |
Matt Wala | 4988923 | 2014-07-18 12:45:09 -0700 | [diff] [blame] | 398 | } |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 399 | void _movsx(Variable *Dest, Operand *Src0) { |
| 400 | Context.insert(InstX8632Movsx::create(Func, Dest, Src0)); |
| 401 | } |
| 402 | void _movzx(Variable *Dest, Operand *Src0) { |
| 403 | Context.insert(InstX8632Movzx::create(Func, Dest, Src0)); |
| 404 | } |
| 405 | void _mul(Variable *Dest, Variable *Src0, Operand *Src1) { |
| 406 | Context.insert(InstX8632Mul::create(Func, Dest, Src0, Src1)); |
| 407 | } |
Matt Wala | 8d1072e | 2014-07-11 15:43:51 -0700 | [diff] [blame] | 408 | void _mulps(Variable *Dest, Operand *Src0) { |
| 409 | Context.insert(InstX8632Mulps::create(Func, Dest, Src0)); |
| 410 | } |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 411 | void _mulss(Variable *Dest, Operand *Src0) { |
| 412 | Context.insert(InstX8632Mulss::create(Func, Dest, Src0)); |
| 413 | } |
Jan Voung | a3a01a2 | 2014-07-14 10:32:41 -0700 | [diff] [blame] | 414 | void _neg(Variable *SrcDest) { |
| 415 | Context.insert(InstX8632Neg::create(Func, SrcDest)); |
| 416 | } |
Matt Wala | c330274 | 2014-08-15 16:21:56 -0700 | [diff] [blame] | 417 | void _nop(SizeT Variant) { |
| 418 | Context.insert(InstX8632Nop::create(Func, Variant)); |
| 419 | } |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 420 | void _or(Variable *Dest, Operand *Src0) { |
| 421 | Context.insert(InstX8632Or::create(Func, Dest, Src0)); |
| 422 | } |
Matt Wala | 7fa22d8 | 2014-07-17 12:41:31 -0700 | [diff] [blame] | 423 | void _padd(Variable *Dest, Operand *Src0) { |
| 424 | Context.insert(InstX8632Padd::create(Func, Dest, Src0)); |
| 425 | } |
Matt Wala | 83b8036 | 2014-07-16 10:21:30 -0700 | [diff] [blame] | 426 | void _pand(Variable *Dest, Operand *Src0) { |
| 427 | Context.insert(InstX8632Pand::create(Func, Dest, Src0)); |
| 428 | } |
Matt Wala | 9cb61e2 | 2014-07-24 09:44:42 -0700 | [diff] [blame] | 429 | void _pandn(Variable *Dest, Operand *Src0) { |
| 430 | Context.insert(InstX8632Pandn::create(Func, Dest, Src0)); |
| 431 | } |
Matt Wala | 0a45051 | 2014-07-30 12:44:39 -0700 | [diff] [blame] | 432 | void _pblendvb(Variable *Dest, Operand *Src0, Operand *Src1) { |
| 433 | Context.insert(InstX8632Pblendvb::create(Func, Dest, Src0, Src1)); |
| 434 | } |
Matt Wala | 83b8036 | 2014-07-16 10:21:30 -0700 | [diff] [blame] | 435 | void _pcmpeq(Variable *Dest, Operand *Src0) { |
| 436 | Context.insert(InstX8632Pcmpeq::create(Func, Dest, Src0)); |
| 437 | } |
| 438 | void _pcmpgt(Variable *Dest, Operand *Src0) { |
| 439 | Context.insert(InstX8632Pcmpgt::create(Func, Dest, Src0)); |
| 440 | } |
Matt Wala | 0a45051 | 2014-07-30 12:44:39 -0700 | [diff] [blame] | 441 | void _pextr(Variable *Dest, Operand *Src0, Operand *Src1) { |
| 442 | Context.insert(InstX8632Pextr::create(Func, Dest, Src0, Src1)); |
Matt Wala | 4988923 | 2014-07-18 12:45:09 -0700 | [diff] [blame] | 443 | } |
Matt Wala | 0a45051 | 2014-07-30 12:44:39 -0700 | [diff] [blame] | 444 | void _pinsr(Variable *Dest, Operand *Src0, Operand *Src1) { |
| 445 | Context.insert(InstX8632Pinsr::create(Func, Dest, Src0, Src1)); |
Matt Wala | 4988923 | 2014-07-18 12:45:09 -0700 | [diff] [blame] | 446 | } |
Matt Wala | 0a45051 | 2014-07-30 12:44:39 -0700 | [diff] [blame] | 447 | void _pmull(Variable *Dest, Operand *Src0) { |
| 448 | Context.insert(InstX8632Pmull::create(Func, Dest, Src0)); |
Matt Wala | 7fa22d8 | 2014-07-17 12:41:31 -0700 | [diff] [blame] | 449 | } |
| 450 | void _pmuludq(Variable *Dest, Operand *Src0) { |
| 451 | Context.insert(InstX8632Pmuludq::create(Func, Dest, Src0)); |
| 452 | } |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 453 | void _pop(Variable *Dest) { |
| 454 | Context.insert(InstX8632Pop::create(Func, Dest)); |
| 455 | } |
Matt Wala | 7fa22d8 | 2014-07-17 12:41:31 -0700 | [diff] [blame] | 456 | void _por(Variable *Dest, Operand *Src0) { |
| 457 | Context.insert(InstX8632Por::create(Func, Dest, Src0)); |
| 458 | } |
| 459 | void _pshufd(Variable *Dest, Operand *Src0, Operand *Src1) { |
| 460 | Context.insert(InstX8632Pshufd::create(Func, Dest, Src0, Src1)); |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 461 | } |
Matt Wala | 83b8036 | 2014-07-16 10:21:30 -0700 | [diff] [blame] | 462 | void _psll(Variable *Dest, Operand *Src0) { |
| 463 | Context.insert(InstX8632Psll::create(Func, Dest, Src0)); |
| 464 | } |
| 465 | void _psra(Variable *Dest, Operand *Src0) { |
| 466 | Context.insert(InstX8632Psra::create(Func, Dest, Src0)); |
| 467 | } |
Jim Stichnoth | 8c980d0 | 2015-03-19 13:01:50 -0700 | [diff] [blame] | 468 | void _psrl(Variable *Dest, Operand *Src0) { |
| 469 | Context.insert(InstX8632Psrl::create(Func, Dest, Src0)); |
| 470 | } |
Matt Wala | 83b8036 | 2014-07-16 10:21:30 -0700 | [diff] [blame] | 471 | void _psub(Variable *Dest, Operand *Src0) { |
| 472 | Context.insert(InstX8632Psub::create(Func, Dest, Src0)); |
| 473 | } |
Jan Voung | 0b9eee5 | 2014-10-07 11:20:10 -0700 | [diff] [blame] | 474 | void _push(Variable *Src0) { |
| 475 | Context.insert(InstX8632Push::create(Func, Src0)); |
Matt Wala | 7fa22d8 | 2014-07-17 12:41:31 -0700 | [diff] [blame] | 476 | } |
Matt Wala | 8d1072e | 2014-07-11 15:43:51 -0700 | [diff] [blame] | 477 | void _pxor(Variable *Dest, Operand *Src0) { |
| 478 | Context.insert(InstX8632Pxor::create(Func, Dest, Src0)); |
| 479 | } |
Jim Stichnoth | ae95320 | 2014-12-20 06:17:49 -0800 | [diff] [blame] | 480 | void _ret(Variable *Src0 = nullptr) { |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 481 | Context.insert(InstX8632Ret::create(Func, Src0)); |
| 482 | } |
Jan Voung | 7fa813b | 2014-07-18 13:01:08 -0700 | [diff] [blame] | 483 | void _rol(Variable *Dest, Operand *Src0) { |
| 484 | Context.insert(InstX8632Rol::create(Func, Dest, Src0)); |
| 485 | } |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 486 | void _sar(Variable *Dest, Operand *Src0) { |
| 487 | Context.insert(InstX8632Sar::create(Func, Dest, Src0)); |
| 488 | } |
| 489 | void _sbb(Variable *Dest, Operand *Src0) { |
| 490 | Context.insert(InstX8632Sbb::create(Func, Dest, Src0)); |
| 491 | } |
Jim Stichnoth | f48b320 | 2015-05-04 10:22:17 -0700 | [diff] [blame] | 492 | void _setcc(Variable *Dest, CondX86::BrCond Condition) { |
| 493 | Context.insert(InstX8632Setcc::create(Func, Dest, Condition)); |
| 494 | } |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 495 | void _shl(Variable *Dest, Operand *Src0) { |
| 496 | Context.insert(InstX8632Shl::create(Func, Dest, Src0)); |
| 497 | } |
| 498 | void _shld(Variable *Dest, Variable *Src0, Variable *Src1) { |
| 499 | Context.insert(InstX8632Shld::create(Func, Dest, Src0, Src1)); |
| 500 | } |
| 501 | void _shr(Variable *Dest, Operand *Src0) { |
| 502 | Context.insert(InstX8632Shr::create(Func, Dest, Src0)); |
| 503 | } |
| 504 | void _shrd(Variable *Dest, Variable *Src0, Variable *Src1) { |
| 505 | Context.insert(InstX8632Shrd::create(Func, Dest, Src0, Src1)); |
| 506 | } |
Matt Wala | 7fa22d8 | 2014-07-17 12:41:31 -0700 | [diff] [blame] | 507 | void _shufps(Variable *Dest, Operand *Src0, Operand *Src1) { |
| 508 | Context.insert(InstX8632Shufps::create(Func, Dest, Src0, Src1)); |
| 509 | } |
Jan Voung | f37fbbe | 2014-07-09 16:13:13 -0700 | [diff] [blame] | 510 | void _sqrtss(Variable *Dest, Operand *Src0) { |
| 511 | Context.insert(InstX8632Sqrtss::create(Func, Dest, Src0)); |
| 512 | } |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 513 | void _store(Operand *Value, OperandX8632 *Mem) { |
| 514 | Context.insert(InstX8632Store::create(Func, Value, Mem)); |
| 515 | } |
Jan Voung | e4dc61b | 2014-10-06 08:53:52 -0700 | [diff] [blame] | 516 | void _storep(Variable *Value, OperandX8632Mem *Mem) { |
Matt Wala | 105b704 | 2014-08-11 19:56:19 -0700 | [diff] [blame] | 517 | Context.insert(InstX8632StoreP::create(Func, Value, Mem)); |
| 518 | } |
Jan Voung | e4dc61b | 2014-10-06 08:53:52 -0700 | [diff] [blame] | 519 | void _storeq(Variable *Value, OperandX8632Mem *Mem) { |
Jan Voung | 5cd240d | 2014-06-25 10:36:46 -0700 | [diff] [blame] | 520 | Context.insert(InstX8632StoreQ::create(Func, Value, Mem)); |
| 521 | } |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 522 | void _sub(Variable *Dest, Operand *Src0) { |
| 523 | Context.insert(InstX8632Sub::create(Func, Dest, Src0)); |
| 524 | } |
Matt Wala | 8d1072e | 2014-07-11 15:43:51 -0700 | [diff] [blame] | 525 | void _subps(Variable *Dest, Operand *Src0) { |
| 526 | Context.insert(InstX8632Subps::create(Func, Dest, Src0)); |
| 527 | } |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 528 | void _subss(Variable *Dest, Operand *Src0) { |
| 529 | Context.insert(InstX8632Subss::create(Func, Dest, Src0)); |
| 530 | } |
| 531 | void _test(Operand *Src0, Operand *Src1) { |
| 532 | Context.insert(InstX8632Test::create(Func, Src0, Src1)); |
| 533 | } |
| 534 | void _ucomiss(Operand *Src0, Operand *Src1) { |
| 535 | Context.insert(InstX8632Ucomiss::create(Func, Src0, Src1)); |
| 536 | } |
Jan Voung | 3bd9f1a | 2014-06-18 10:50:57 -0700 | [diff] [blame] | 537 | void _ud2() { Context.insert(InstX8632UD2::create(Func)); } |
Jan Voung | 5cd240d | 2014-06-25 10:36:46 -0700 | [diff] [blame] | 538 | void _xadd(Operand *Dest, Variable *Src, bool Locked) { |
| 539 | Context.insert(InstX8632Xadd::create(Func, Dest, Src, Locked)); |
| 540 | // The xadd exchanges Dest and Src (modifying Src). |
Jim Stichnoth | 0e432ac | 2015-03-24 15:39:16 -0700 | [diff] [blame] | 541 | // Model that update with a FakeDef followed by a FakeUse. |
Jan Voung | a3a01a2 | 2014-07-14 10:32:41 -0700 | [diff] [blame] | 542 | Context.insert( |
| 543 | InstFakeDef::create(Func, Src, llvm::dyn_cast<Variable>(Dest))); |
Jim Stichnoth | 4775255 | 2014-10-13 17:15:08 -0700 | [diff] [blame] | 544 | _set_dest_nonkillable(); |
Jim Stichnoth | 0e432ac | 2015-03-24 15:39:16 -0700 | [diff] [blame] | 545 | Context.insert(InstFakeUse::create(Func, Src)); |
Jan Voung | a3a01a2 | 2014-07-14 10:32:41 -0700 | [diff] [blame] | 546 | } |
| 547 | void _xchg(Operand *Dest, Variable *Src) { |
| 548 | Context.insert(InstX8632Xchg::create(Func, Dest, Src)); |
Jim Stichnoth | 0e432ac | 2015-03-24 15:39:16 -0700 | [diff] [blame] | 549 | // The xchg modifies Dest and Src -- model that update with a |
| 550 | // FakeDef/FakeUse. |
Jan Voung | a3a01a2 | 2014-07-14 10:32:41 -0700 | [diff] [blame] | 551 | Context.insert( |
| 552 | InstFakeDef::create(Func, Src, llvm::dyn_cast<Variable>(Dest))); |
Jim Stichnoth | 4775255 | 2014-10-13 17:15:08 -0700 | [diff] [blame] | 553 | _set_dest_nonkillable(); |
Jim Stichnoth | 0e432ac | 2015-03-24 15:39:16 -0700 | [diff] [blame] | 554 | Context.insert(InstFakeUse::create(Func, Src)); |
Jan Voung | 5cd240d | 2014-06-25 10:36:46 -0700 | [diff] [blame] | 555 | } |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 556 | void _xor(Variable *Dest, Operand *Src0) { |
| 557 | Context.insert(InstX8632Xor::create(Func, Dest, Src0)); |
| 558 | } |
Jim Stichnoth | 4775255 | 2014-10-13 17:15:08 -0700 | [diff] [blame] | 559 | void _set_dest_nonkillable() { |
| 560 | Context.getLastInserted()->setDestNonKillable(); |
| 561 | } |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 562 | |
Jim Stichnoth | 0933c0c | 2015-06-12 10:41:16 -0700 | [diff] [blame] | 563 | bool optimizeScalarMul(Variable *Dest, Operand *Src0, int32_t Src1); |
| 564 | |
Matt Wala | 0a45051 | 2014-07-30 12:44:39 -0700 | [diff] [blame] | 565 | const X86InstructionSet InstructionSet; |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 566 | bool IsEbpBasedFrame; |
Matt Wala | 105b704 | 2014-08-11 19:56:19 -0700 | [diff] [blame] | 567 | bool NeedsStackAlignment; |
Matt Wala | d4799f4 | 2014-08-14 14:24:12 -0700 | [diff] [blame] | 568 | size_t SpillAreaSizeBytes; |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 569 | llvm::SmallBitVector TypeToRegisterSet[IceType_NUM]; |
| 570 | llvm::SmallBitVector ScratchRegs; |
| 571 | llvm::SmallBitVector RegsUsed; |
Jim Stichnoth | 336f6c4 | 2014-10-30 15:01:31 -0700 | [diff] [blame] | 572 | VarList PhysicalRegisters[IceType_NUM]; |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 573 | static IceString RegNames[]; |
| 574 | |
| 575 | private: |
Jim Stichnoth | b56c8f4 | 2014-09-26 09:28:46 -0700 | [diff] [blame] | 576 | ~TargetX8632() override {} |
Jim Stichnoth | a59ae6f | 2015-05-17 10:11:41 -0700 | [diff] [blame] | 577 | BoolFolding FoldingInfo; |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 578 | }; |
| 579 | |
John Porto | 0f86d03 | 2015-06-15 07:44:27 -0700 | [diff] [blame^] | 580 | class TargetDataX8632 final : public TargetDataLowering { |
Jan Voung | 72984d8 | 2015-01-29 14:42:38 -0800 | [diff] [blame] | 581 | TargetDataX8632() = delete; |
| 582 | TargetDataX8632(const TargetDataX8632 &) = delete; |
| 583 | TargetDataX8632 &operator=(const TargetDataX8632 &) = delete; |
Jim Stichnoth | 7b451a9 | 2014-10-15 14:39:23 -0700 | [diff] [blame] | 584 | |
Jim Stichnoth | de4ca71 | 2014-06-29 08:13:48 -0700 | [diff] [blame] | 585 | public: |
Jan Voung | fb79284 | 2015-06-11 15:27:50 -0700 | [diff] [blame] | 586 | static std::unique_ptr<TargetDataLowering> create(GlobalContext *Ctx) { |
| 587 | return std::unique_ptr<TargetDataLowering>(new TargetDataX8632(Ctx)); |
Jim Stichnoth | de4ca71 | 2014-06-29 08:13:48 -0700 | [diff] [blame] | 588 | } |
Karl Schimpf | e3f64d0 | 2014-10-07 10:38:22 -0700 | [diff] [blame] | 589 | |
John Porto | 0f86d03 | 2015-06-15 07:44:27 -0700 | [diff] [blame^] | 590 | void lowerGlobals(std::unique_ptr<VariableDeclarationList> Vars) override; |
| 591 | void lowerConstants() override; |
Jim Stichnoth | de4ca71 | 2014-06-29 08:13:48 -0700 | [diff] [blame] | 592 | |
| 593 | protected: |
Jim Stichnoth | c6ead20 | 2015-02-24 09:30:30 -0800 | [diff] [blame] | 594 | explicit TargetDataX8632(GlobalContext *Ctx); |
Jim Stichnoth | de4ca71 | 2014-06-29 08:13:48 -0700 | [diff] [blame] | 595 | |
| 596 | private: |
John Porto | 0f86d03 | 2015-06-15 07:44:27 -0700 | [diff] [blame^] | 597 | void lowerGlobal(const VariableDeclaration &Var); |
Jan Voung | 72984d8 | 2015-01-29 14:42:38 -0800 | [diff] [blame] | 598 | ~TargetDataX8632() override {} |
Jim Stichnoth | fa4efea | 2015-01-27 05:06:03 -0800 | [diff] [blame] | 599 | template <typename T> static void emitConstantPool(GlobalContext *Ctx); |
Jim Stichnoth | de4ca71 | 2014-06-29 08:13:48 -0700 | [diff] [blame] | 600 | }; |
| 601 | |
Jan Voung | fb79284 | 2015-06-11 15:27:50 -0700 | [diff] [blame] | 602 | class TargetHeaderX8632 final : public TargetHeaderLowering { |
| 603 | TargetHeaderX8632() = delete; |
| 604 | TargetHeaderX8632(const TargetHeaderX8632 &) = delete; |
| 605 | TargetHeaderX8632 &operator=(const TargetHeaderX8632 &) = delete; |
| 606 | |
| 607 | public: |
| 608 | static std::unique_ptr<TargetHeaderLowering> create(GlobalContext *Ctx) { |
| 609 | return std::unique_ptr<TargetHeaderLowering>(new TargetHeaderX8632(Ctx)); |
| 610 | } |
| 611 | |
| 612 | protected: |
| 613 | explicit TargetHeaderX8632(GlobalContext *Ctx); |
| 614 | |
| 615 | private: |
| 616 | ~TargetHeaderX8632() = default; |
| 617 | }; |
| 618 | |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 619 | } // end of namespace Ice |
| 620 | |
| 621 | #endif // SUBZERO_SRC_ICETARGETLOWERINGX8632_H |