| OLD | NEW |
| 1 //===- subzero/src/IceTargetLoweringX8632.h - x86-32 lowering ---*- C++ -*-===// | 1 //===- subzero/src/IceTargetLoweringX8632.h - x86-32 lowering ---*- 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 // This file declares the TargetLoweringX8632 class, which | 10 // This file declares the TargetLoweringX8632 class, which |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 virtual void lowerLoad(const InstLoad *Inst); | 87 virtual void lowerLoad(const InstLoad *Inst); |
| 88 virtual void lowerPhi(const InstPhi *Inst); | 88 virtual void lowerPhi(const InstPhi *Inst); |
| 89 virtual void lowerRet(const InstRet *Inst); | 89 virtual void lowerRet(const InstRet *Inst); |
| 90 virtual void lowerSelect(const InstSelect *Inst); | 90 virtual void lowerSelect(const InstSelect *Inst); |
| 91 virtual void lowerStore(const InstStore *Inst); | 91 virtual void lowerStore(const InstStore *Inst); |
| 92 virtual void lowerSwitch(const InstSwitch *Inst); | 92 virtual void lowerSwitch(const InstSwitch *Inst); |
| 93 virtual void lowerUnreachable(const InstUnreachable *Inst); | 93 virtual void lowerUnreachable(const InstUnreachable *Inst); |
| 94 virtual void doAddressOptLoad(); | 94 virtual void doAddressOptLoad(); |
| 95 virtual void doAddressOptStore(); | 95 virtual void doAddressOptStore(); |
| 96 | 96 |
| 97 void lowerAtomicRMW(Variable *Dest, uint32_t Operation, Operand *Ptr, |
| 98 Operand *Val); |
| 99 |
| 97 // Operand legalization helpers. To deal with address mode | 100 // Operand legalization helpers. To deal with address mode |
| 98 // constraints, the helpers will create a new Operand and emit | 101 // constraints, the helpers will create a new Operand and emit |
| 99 // instructions that guarantee that the Operand kind is one of those | 102 // instructions that guarantee that the Operand kind is one of those |
| 100 // indicated by the LegalMask (a bitmask of allowed kinds). If the | 103 // indicated by the LegalMask (a bitmask of allowed kinds). If the |
| 101 // input Operand is known to already meet the constraints, it may be | 104 // input Operand is known to already meet the constraints, it may be |
| 102 // simply returned as the result, without creating any new | 105 // simply returned as the result, without creating any new |
| 103 // instructions or operands. | 106 // instructions or operands. |
| 104 enum OperandLegalization { | 107 enum OperandLegalization { |
| 105 Legal_None = 0, | 108 Legal_None = 0, |
| 106 Legal_Reg = 1 << 0, // physical register, not stack location | 109 Legal_Reg = 1 << 0, // physical register, not stack location |
| 107 Legal_Imm = 1 << 1, | 110 Legal_Imm = 1 << 1, |
| 108 Legal_Mem = 1 << 2, // includes [eax+4*ecx] as well as [esp+12] | 111 Legal_Mem = 1 << 2, // includes [eax+4*ecx] as well as [esp+12] |
| 109 Legal_All = ~Legal_None | 112 Legal_All = ~Legal_None |
| 110 }; | 113 }; |
| 111 typedef uint32_t LegalMask; | 114 typedef uint32_t LegalMask; |
| 112 Operand *legalize(Operand *From, LegalMask Allowed = Legal_All, | 115 Operand *legalize(Operand *From, LegalMask Allowed = Legal_All, |
| 113 bool AllowOverlap = false, | 116 bool AllowOverlap = false, |
| 114 int32_t RegNum = Variable::NoRegister); | 117 int32_t RegNum = Variable::NoRegister); |
| 115 Variable *legalizeToVar(Operand *From, bool AllowOverlap = false, | 118 Variable *legalizeToVar(Operand *From, bool AllowOverlap = false, |
| 116 int32_t RegNum = Variable::NoRegister); | 119 int32_t RegNum = Variable::NoRegister); |
| 120 // Turn a pointer operand into a memory operand that can be |
| 121 // used by a real load/store operation. Legalizes the operand as well. |
| 122 // This is a nop if the operand is already a legal memory operand. |
| 123 OperandX8632Mem *FormMemoryOperand(Operand *Ptr, Type Ty); |
| 117 | 124 |
| 118 Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister); | 125 Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister); |
| 119 InstCall *makeHelperCall(const IceString &Name, Variable *Dest, | 126 InstCall *makeHelperCall(const IceString &Name, Variable *Dest, |
| 120 SizeT MaxSrcs) { | 127 SizeT MaxSrcs) { |
| 121 bool SuppressMangling = true; | 128 bool SuppressMangling = true; |
| 122 Type Ty = Dest ? Dest->getType() : IceType_void; | 129 Type Ty = Dest ? Dest->getType() : IceType_void; |
| 123 Constant *CallTarget = Ctx->getConstantSym(Ty, 0, Name, SuppressMangling); | 130 Constant *CallTarget = Ctx->getConstantSym(Ty, 0, Name, SuppressMangling); |
| 124 InstCall *Call = InstCall::create(Func, MaxSrcs, Dest, CallTarget); | 131 InstCall *Call = InstCall::create(Func, MaxSrcs, Dest, CallTarget); |
| 125 return Call; | 132 return Call; |
| 126 } | 133 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 void _fld(Operand *Src0) { Context.insert(InstX8632Fld::create(Func, Src0)); } | 180 void _fld(Operand *Src0) { Context.insert(InstX8632Fld::create(Func, Src0)); } |
| 174 void _fstp(Variable *Dest) { | 181 void _fstp(Variable *Dest) { |
| 175 Context.insert(InstX8632Fstp::create(Func, Dest)); | 182 Context.insert(InstX8632Fstp::create(Func, Dest)); |
| 176 } | 183 } |
| 177 void _idiv(Variable *Dest, Operand *Src0, Operand *Src1) { | 184 void _idiv(Variable *Dest, Operand *Src0, Operand *Src1) { |
| 178 Context.insert(InstX8632Idiv::create(Func, Dest, Src0, Src1)); | 185 Context.insert(InstX8632Idiv::create(Func, Dest, Src0, Src1)); |
| 179 } | 186 } |
| 180 void _imul(Variable *Dest, Operand *Src0) { | 187 void _imul(Variable *Dest, Operand *Src0) { |
| 181 Context.insert(InstX8632Imul::create(Func, Dest, Src0)); | 188 Context.insert(InstX8632Imul::create(Func, Dest, Src0)); |
| 182 } | 189 } |
| 190 void _mfence() { Context.insert(InstX8632Mfence::create(Func)); } |
| 183 // If Dest=NULL is passed in, then a new variable is created, marked | 191 // If Dest=NULL is passed in, then a new variable is created, marked |
| 184 // as infinite register allocation weight, and returned through the | 192 // as infinite register allocation weight, and returned through the |
| 185 // in/out Dest argument. | 193 // in/out Dest argument. |
| 186 void _mov(Variable *&Dest, Operand *Src0, | 194 void _mov(Variable *&Dest, Operand *Src0, |
| 187 int32_t RegNum = Variable::NoRegister) { | 195 int32_t RegNum = Variable::NoRegister) { |
| 188 if (Dest == NULL) { | 196 if (Dest == NULL) { |
| 189 Dest = legalizeToVar(Src0, false, RegNum); | 197 Dest = legalizeToVar(Src0, false, RegNum); |
| 190 } else { | 198 } else { |
| 191 Context.insert(InstX8632Mov::create(Func, Dest, Src0)); | 199 Context.insert(InstX8632Mov::create(Func, Dest, Src0)); |
| 192 } | 200 } |
| 193 } | 201 } |
| 202 void _movq(Variable *Dest, Operand *Src0) { |
| 203 Context.insert(InstX8632Movq::create(Func, Dest, Src0)); |
| 204 } |
| 194 void _movsx(Variable *Dest, Operand *Src0) { | 205 void _movsx(Variable *Dest, Operand *Src0) { |
| 195 Context.insert(InstX8632Movsx::create(Func, Dest, Src0)); | 206 Context.insert(InstX8632Movsx::create(Func, Dest, Src0)); |
| 196 } | 207 } |
| 197 void _movzx(Variable *Dest, Operand *Src0) { | 208 void _movzx(Variable *Dest, Operand *Src0) { |
| 198 Context.insert(InstX8632Movzx::create(Func, Dest, Src0)); | 209 Context.insert(InstX8632Movzx::create(Func, Dest, Src0)); |
| 199 } | 210 } |
| 200 void _mul(Variable *Dest, Variable *Src0, Operand *Src1) { | 211 void _mul(Variable *Dest, Variable *Src0, Operand *Src1) { |
| 201 Context.insert(InstX8632Mul::create(Func, Dest, Src0, Src1)); | 212 Context.insert(InstX8632Mul::create(Func, Dest, Src0, Src1)); |
| 202 } | 213 } |
| 203 void _mulss(Variable *Dest, Operand *Src0) { | 214 void _mulss(Variable *Dest, Operand *Src0) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 229 } | 240 } |
| 230 void _shr(Variable *Dest, Operand *Src0) { | 241 void _shr(Variable *Dest, Operand *Src0) { |
| 231 Context.insert(InstX8632Shr::create(Func, Dest, Src0)); | 242 Context.insert(InstX8632Shr::create(Func, Dest, Src0)); |
| 232 } | 243 } |
| 233 void _shrd(Variable *Dest, Variable *Src0, Variable *Src1) { | 244 void _shrd(Variable *Dest, Variable *Src0, Variable *Src1) { |
| 234 Context.insert(InstX8632Shrd::create(Func, Dest, Src0, Src1)); | 245 Context.insert(InstX8632Shrd::create(Func, Dest, Src0, Src1)); |
| 235 } | 246 } |
| 236 void _store(Operand *Value, OperandX8632 *Mem) { | 247 void _store(Operand *Value, OperandX8632 *Mem) { |
| 237 Context.insert(InstX8632Store::create(Func, Value, Mem)); | 248 Context.insert(InstX8632Store::create(Func, Value, Mem)); |
| 238 } | 249 } |
| 250 void _storeq(Operand *Value, OperandX8632 *Mem) { |
| 251 Context.insert(InstX8632StoreQ::create(Func, Value, Mem)); |
| 252 } |
| 239 void _sub(Variable *Dest, Operand *Src0) { | 253 void _sub(Variable *Dest, Operand *Src0) { |
| 240 Context.insert(InstX8632Sub::create(Func, Dest, Src0)); | 254 Context.insert(InstX8632Sub::create(Func, Dest, Src0)); |
| 241 } | 255 } |
| 242 void _subss(Variable *Dest, Operand *Src0) { | 256 void _subss(Variable *Dest, Operand *Src0) { |
| 243 Context.insert(InstX8632Subss::create(Func, Dest, Src0)); | 257 Context.insert(InstX8632Subss::create(Func, Dest, Src0)); |
| 244 } | 258 } |
| 245 void _test(Operand *Src0, Operand *Src1) { | 259 void _test(Operand *Src0, Operand *Src1) { |
| 246 Context.insert(InstX8632Test::create(Func, Src0, Src1)); | 260 Context.insert(InstX8632Test::create(Func, Src0, Src1)); |
| 247 } | 261 } |
| 248 void _ucomiss(Operand *Src0, Operand *Src1) { | 262 void _ucomiss(Operand *Src0, Operand *Src1) { |
| 249 Context.insert(InstX8632Ucomiss::create(Func, Src0, Src1)); | 263 Context.insert(InstX8632Ucomiss::create(Func, Src0, Src1)); |
| 250 } | 264 } |
| 251 void _ud2() { Context.insert(InstX8632UD2::create(Func)); } | 265 void _ud2() { Context.insert(InstX8632UD2::create(Func)); } |
| 266 void _xadd(Operand *Dest, Variable *Src, bool Locked) { |
| 267 Context.insert(InstX8632Xadd::create(Func, Dest, Src, Locked)); |
| 268 // The xadd exchanges Dest and Src (modifying Src). |
| 269 // Model that update with a FakeDef. |
| 270 Context.insert(InstFakeDef::create(Func, Src)); |
| 271 } |
| 252 void _xor(Variable *Dest, Operand *Src0) { | 272 void _xor(Variable *Dest, Operand *Src0) { |
| 253 Context.insert(InstX8632Xor::create(Func, Dest, Src0)); | 273 Context.insert(InstX8632Xor::create(Func, Dest, Src0)); |
| 254 } | 274 } |
| 255 | 275 |
| 256 bool IsEbpBasedFrame; | 276 bool IsEbpBasedFrame; |
| 257 size_t FrameSizeLocals; | 277 size_t FrameSizeLocals; |
| 258 size_t LocalsSizeBytes; | 278 size_t LocalsSizeBytes; |
| 259 llvm::SmallBitVector TypeToRegisterSet[IceType_NUM]; | 279 llvm::SmallBitVector TypeToRegisterSet[IceType_NUM]; |
| 260 llvm::SmallBitVector ScratchRegs; | 280 llvm::SmallBitVector ScratchRegs; |
| 261 llvm::SmallBitVector RegsUsed; | 281 llvm::SmallBitVector RegsUsed; |
| 262 SizeT NextLabelNumber; | 282 SizeT NextLabelNumber; |
| 263 bool ComputedLiveRanges; | 283 bool ComputedLiveRanges; |
| 264 VarList PhysicalRegisters; | 284 VarList PhysicalRegisters; |
| 265 static IceString RegNames[]; | 285 static IceString RegNames[]; |
| 266 | 286 |
| 267 private: | 287 private: |
| 268 TargetX8632(const TargetX8632 &) LLVM_DELETED_FUNCTION; | 288 TargetX8632(const TargetX8632 &) LLVM_DELETED_FUNCTION; |
| 269 TargetX8632 &operator=(const TargetX8632 &) LLVM_DELETED_FUNCTION; | 289 TargetX8632 &operator=(const TargetX8632 &) LLVM_DELETED_FUNCTION; |
| 270 virtual ~TargetX8632() {} | 290 virtual ~TargetX8632() {} |
| 271 template <typename T> void emitConstantPool() const; | 291 template <typename T> void emitConstantPool() const; |
| 272 }; | 292 }; |
| 273 | 293 |
| 274 template <> void ConstantFloat::emit(GlobalContext *Ctx) const; | 294 template <> void ConstantFloat::emit(GlobalContext *Ctx) const; |
| 275 template <> void ConstantDouble::emit(GlobalContext *Ctx) const; | 295 template <> void ConstantDouble::emit(GlobalContext *Ctx) const; |
| 276 | 296 |
| 277 } // end of namespace Ice | 297 } // end of namespace Ice |
| 278 | 298 |
| 279 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8632_H | 299 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8632_H |
| OLD | NEW |