| OLD | NEW |
| 1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// | 1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// |
| 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 implements the InstX8632 and OperandX8632 classes, | 10 // This file implements the InstX8632 and OperandX8632 classes, |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 } | 82 } |
| 83 | 83 |
| 84 const char *InstX8632::getFldString(Type Ty) { | 84 const char *InstX8632::getFldString(Type Ty) { |
| 85 return TypeX8632Attributes[Ty].FldString; | 85 return TypeX8632Attributes[Ty].FldString; |
| 86 } | 86 } |
| 87 | 87 |
| 88 CondX86::BrCond InstX8632::getOppositeCondition(CondX86::BrCond Cond) { | 88 CondX86::BrCond InstX8632::getOppositeCondition(CondX86::BrCond Cond) { |
| 89 return InstX8632BrAttributes[Cond].Opposite; | 89 return InstX8632BrAttributes[Cond].Opposite; |
| 90 } | 90 } |
| 91 | 91 |
| 92 OperandX8632Mem::OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base, | 92 OperandX8632Mem::OperandX8632Mem(Cfg *Func, Type Ty, Variable *MyBase, |
| 93 Constant *Offset, Variable *Index, | 93 Constant *MyOffset, Variable *MyIndex, |
| 94 uint16_t Shift, SegmentRegisters SegmentReg) | 94 uint16_t MyShift, |
| 95 : OperandX8632(kMem, Ty), Base(Base), Offset(Offset), Index(Index), | 95 SegmentRegisters MySegmentReg) |
| 96 Shift(Shift), SegmentReg(SegmentReg), Randomized(false) { | 96 : OperandX8632(kMem, Ty), Base(MyBase), Offset(MyOffset), Index(MyIndex), |
| 97 Shift(MyShift), SegmentReg(MySegmentReg), Randomized(false) { |
| 97 assert(Shift <= 3); | 98 assert(Shift <= 3); |
| 98 Vars = nullptr; | 99 Vars = nullptr; |
| 99 NumVars = 0; | 100 NumVars = 0; |
| 100 if (Base) | 101 if (Base) |
| 101 ++NumVars; | 102 ++NumVars; |
| 102 if (Index) | 103 if (Index) |
| 103 ++NumVars; | 104 ++NumVars; |
| 104 if (NumVars) { | 105 if (NumVars) { |
| 105 Vars = Func->allocateArrayOf<Variable *>(NumVars); | 106 Vars = Func->allocateArrayOf<Variable *>(NumVars); |
| 106 SizeT I = 0; | 107 SizeT I = 0; |
| 107 if (Base) | 108 if (Base) |
| 108 Vars[I++] = Base; | 109 Vars[I++] = Base; |
| 109 if (Index) | 110 if (Index) |
| 110 Vars[I++] = Index; | 111 Vars[I++] = Index; |
| 111 assert(I == NumVars); | 112 assert(I == NumVars); |
| 112 } | 113 } |
| 113 } | 114 } |
| 114 | 115 |
| 115 InstX8632FakeRMW::InstX8632FakeRMW(Cfg *Func, Operand *Data, Operand *Addr, | 116 InstX8632FakeRMW::InstX8632FakeRMW(Cfg *Func, Operand *Data, Operand *Addr, |
| 116 InstArithmetic::OpKind Op, Variable *Beacon) | 117 InstArithmetic::OpKind MyOp, |
| 117 : InstX8632(Func, InstX8632::FakeRMW, 3, nullptr), Op(Op) { | 118 Variable *Beacon) |
| 119 : InstX8632(Func, InstX8632::FakeRMW, 3, nullptr), Op(MyOp) { |
| 118 addSource(Data); | 120 addSource(Data); |
| 119 addSource(Addr); | 121 addSource(Addr); |
| 120 addSource(Beacon); | 122 addSource(Beacon); |
| 121 } | 123 } |
| 122 | 124 |
| 123 InstX8632AdjustStack::InstX8632AdjustStack(Cfg *Func, SizeT Amount, | 125 InstX8632AdjustStack::InstX8632AdjustStack(Cfg *Func, SizeT MyAmount, |
| 124 Variable *Esp) | 126 Variable *Esp) |
| 125 : InstX8632(Func, InstX8632::Adjuststack, 1, Esp), Amount(Amount) { | 127 : InstX8632(Func, InstX8632::Adjuststack, 1, Esp), Amount(MyAmount) { |
| 126 addSource(Esp); | 128 addSource(Esp); |
| 127 } | 129 } |
| 128 | 130 |
| 129 InstX8632Mul::InstX8632Mul(Cfg *Func, Variable *Dest, Variable *Source1, | 131 InstX8632Mul::InstX8632Mul(Cfg *Func, Variable *Dest, Variable *Source1, |
| 130 Operand *Source2) | 132 Operand *Source2) |
| 131 : InstX8632(Func, InstX8632::Mul, 2, Dest) { | 133 : InstX8632(Func, InstX8632::Mul, 2, Dest) { |
| 132 addSource(Source1); | 134 addSource(Source1); |
| 133 addSource(Source2); | 135 addSource(Source2); |
| 134 } | 136 } |
| 135 | 137 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 150 } | 152 } |
| 151 | 153 |
| 152 InstX8632Label::InstX8632Label(Cfg *Func, TargetX8632 *Target) | 154 InstX8632Label::InstX8632Label(Cfg *Func, TargetX8632 *Target) |
| 153 : InstX8632(Func, InstX8632::Label, 0, nullptr), | 155 : InstX8632(Func, InstX8632::Label, 0, nullptr), |
| 154 Number(Target->makeNextLabelNumber()) {} | 156 Number(Target->makeNextLabelNumber()) {} |
| 155 | 157 |
| 156 IceString InstX8632Label::getName(const Cfg *Func) const { | 158 IceString InstX8632Label::getName(const Cfg *Func) const { |
| 157 return ".L" + Func->getFunctionName() + "$local$__" + std::to_string(Number); | 159 return ".L" + Func->getFunctionName() + "$local$__" + std::to_string(Number); |
| 158 } | 160 } |
| 159 | 161 |
| 160 InstX8632Br::InstX8632Br(Cfg *Func, const CfgNode *TargetTrue, | 162 InstX8632Br::InstX8632Br(Cfg *Func, const CfgNode *MyTargetTrue, |
| 161 const CfgNode *TargetFalse, | 163 const CfgNode *MyTargetFalse, |
| 162 const InstX8632Label *Label, CondX86::BrCond Condition) | 164 const InstX8632Label *MyLabel, |
| 163 : InstX8632(Func, InstX8632::Br, 0, nullptr), Condition(Condition), | 165 CondX86::BrCond MyCondition) |
| 164 TargetTrue(TargetTrue), TargetFalse(TargetFalse), Label(Label) {} | 166 : InstX8632(Func, InstX8632::Br, 0, nullptr), Condition(MyCondition), |
| 167 TargetTrue(MyTargetTrue), TargetFalse(MyTargetFalse), Label(MyLabel) {} |
| 165 | 168 |
| 166 bool InstX8632Br::optimizeBranch(const CfgNode *NextNode) { | 169 bool InstX8632Br::optimizeBranch(const CfgNode *NextNode) { |
| 167 // If there is no next block, then there can be no fallthrough to | 170 // If there is no next block, then there can be no fallthrough to |
| 168 // optimize. | 171 // optimize. |
| 169 if (NextNode == nullptr) | 172 if (NextNode == nullptr) |
| 170 return false; | 173 return false; |
| 171 // Intra-block conditional branches can't be optimized. | 174 // Intra-block conditional branches can't be optimized. |
| 172 if (Label) | 175 if (Label) |
| 173 return false; | 176 return false; |
| 174 // If there is no fallthrough node, such as a non-default case label | 177 // If there is no fallthrough node, such as a non-default case label |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 addSource(Target); | 221 addSource(Target); |
| 219 } | 222 } |
| 220 | 223 |
| 221 InstX8632Call::InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget) | 224 InstX8632Call::InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget) |
| 222 : InstX8632(Func, InstX8632::Call, 1, Dest) { | 225 : InstX8632(Func, InstX8632::Call, 1, Dest) { |
| 223 HasSideEffects = true; | 226 HasSideEffects = true; |
| 224 addSource(CallTarget); | 227 addSource(CallTarget); |
| 225 } | 228 } |
| 226 | 229 |
| 227 InstX8632Cmov::InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source, | 230 InstX8632Cmov::InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source, |
| 228 CondX86::BrCond Condition) | 231 CondX86::BrCond MyCondition) |
| 229 : InstX8632(Func, InstX8632::Cmov, 2, Dest), Condition(Condition) { | 232 : InstX8632(Func, InstX8632::Cmov, 2, Dest), Condition(MyCondition) { |
| 230 // The final result is either the original Dest, or Source, so mark | 233 // The final result is either the original Dest, or Source, so mark |
| 231 // both as sources. | 234 // both as sources. |
| 232 addSource(Dest); | 235 addSource(Dest); |
| 233 addSource(Source); | 236 addSource(Source); |
| 234 } | 237 } |
| 235 | 238 |
| 236 InstX8632Cmpps::InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source, | 239 InstX8632Cmpps::InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source, |
| 237 CondX86::CmppsCond Condition) | 240 CondX86::CmppsCond MyCondition) |
| 238 : InstX8632(Func, InstX8632::Cmpps, 2, Dest), Condition(Condition) { | 241 : InstX8632(Func, InstX8632::Cmpps, 2, Dest), Condition(MyCondition) { |
| 239 addSource(Dest); | 242 addSource(Dest); |
| 240 addSource(Source); | 243 addSource(Source); |
| 241 } | 244 } |
| 242 | 245 |
| 243 InstX8632Cmpxchg::InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr, | 246 InstX8632Cmpxchg::InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr, |
| 244 Variable *Eax, Variable *Desired, | 247 Variable *Eax, Variable *Desired, |
| 245 bool Locked) | 248 bool Locked) |
| 246 : InstX8632Lockable(Func, InstX8632::Cmpxchg, 3, | 249 : InstX8632Lockable(Func, InstX8632::Cmpxchg, 3, |
| 247 llvm::dyn_cast<Variable>(DestOrAddr), Locked) { | 250 llvm::dyn_cast<Variable>(DestOrAddr), Locked) { |
| 248 assert(Eax->getRegNum() == RegX8632::Reg_eax); | 251 assert(Eax->getRegNum() == RegX8632::Reg_eax); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 261 assert(Ecx->getRegNum() == RegX8632::Reg_ecx); | 264 assert(Ecx->getRegNum() == RegX8632::Reg_ecx); |
| 262 assert(Ebx->getRegNum() == RegX8632::Reg_ebx); | 265 assert(Ebx->getRegNum() == RegX8632::Reg_ebx); |
| 263 addSource(Addr); | 266 addSource(Addr); |
| 264 addSource(Edx); | 267 addSource(Edx); |
| 265 addSource(Eax); | 268 addSource(Eax); |
| 266 addSource(Ecx); | 269 addSource(Ecx); |
| 267 addSource(Ebx); | 270 addSource(Ebx); |
| 268 } | 271 } |
| 269 | 272 |
| 270 InstX8632Cvt::InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source, | 273 InstX8632Cvt::InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source, |
| 271 CvtVariant Variant) | 274 CvtVariant MyVariant) |
| 272 : InstX8632(Func, InstX8632::Cvt, 1, Dest), Variant(Variant) { | 275 : InstX8632(Func, InstX8632::Cvt, 1, Dest), Variant(MyVariant) { |
| 273 addSource(Source); | 276 addSource(Source); |
| 274 } | 277 } |
| 275 | 278 |
| 276 InstX8632Icmp::InstX8632Icmp(Cfg *Func, Operand *Src0, Operand *Src1) | 279 InstX8632Icmp::InstX8632Icmp(Cfg *Func, Operand *Src0, Operand *Src1) |
| 277 : InstX8632(Func, InstX8632::Icmp, 2, nullptr) { | 280 : InstX8632(Func, InstX8632::Icmp, 2, nullptr) { |
| 278 addSource(Src0); | 281 addSource(Src0); |
| 279 addSource(Src1); | 282 addSource(Src1); |
| 280 } | 283 } |
| 281 | 284 |
| 282 InstX8632Ucomiss::InstX8632Ucomiss(Cfg *Func, Operand *Src0, Operand *Src1) | 285 InstX8632Ucomiss::InstX8632Ucomiss(Cfg *Func, Operand *Src0, Operand *Src1) |
| (...skipping 29 matching lines...) Expand all Loading... |
| 312 addSource(Mem); | 315 addSource(Mem); |
| 313 } | 316 } |
| 314 | 317 |
| 315 InstX8632StoreQ::InstX8632StoreQ(Cfg *Func, Variable *Value, | 318 InstX8632StoreQ::InstX8632StoreQ(Cfg *Func, Variable *Value, |
| 316 OperandX8632Mem *Mem) | 319 OperandX8632Mem *Mem) |
| 317 : InstX8632(Func, InstX8632::StoreQ, 2, nullptr) { | 320 : InstX8632(Func, InstX8632::StoreQ, 2, nullptr) { |
| 318 addSource(Value); | 321 addSource(Value); |
| 319 addSource(Mem); | 322 addSource(Mem); |
| 320 } | 323 } |
| 321 | 324 |
| 322 InstX8632Nop::InstX8632Nop(Cfg *Func, InstX8632Nop::NopVariant Variant) | 325 InstX8632Nop::InstX8632Nop(Cfg *Func, InstX8632Nop::NopVariant MyVariant) |
| 323 : InstX8632(Func, InstX8632::Nop, 0, nullptr), Variant(Variant) {} | 326 : InstX8632(Func, InstX8632::Nop, 0, nullptr), Variant(MyVariant) {} |
| 324 | 327 |
| 325 InstX8632Fld::InstX8632Fld(Cfg *Func, Operand *Src) | 328 InstX8632Fld::InstX8632Fld(Cfg *Func, Operand *Src) |
| 326 : InstX8632(Func, InstX8632::Fld, 1, nullptr) { | 329 : InstX8632(Func, InstX8632::Fld, 1, nullptr) { |
| 327 addSource(Src); | 330 addSource(Src); |
| 328 } | 331 } |
| 329 | 332 |
| 330 InstX8632Fstp::InstX8632Fstp(Cfg *Func, Variable *Dest) | 333 InstX8632Fstp::InstX8632Fstp(Cfg *Func, Variable *Dest) |
| 331 : InstX8632(Func, InstX8632::Fstp, 0, Dest) {} | 334 : InstX8632(Func, InstX8632::Fstp, 0, Dest) {} |
| 332 | 335 |
| 333 InstX8632Pop::InstX8632Pop(Cfg *Func, Variable *Dest) | 336 InstX8632Pop::InstX8632Pop(Cfg *Func, Variable *Dest) |
| (...skipping 1058 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1392 template <> void InstX8632Imul::emitIAS(const Cfg *Func) const { | 1395 template <> void InstX8632Imul::emitIAS(const Cfg *Func) const { |
| 1393 assert(getSrcSize() == 2); | 1396 assert(getSrcSize() == 2); |
| 1394 const Variable *Var = getDest(); | 1397 const Variable *Var = getDest(); |
| 1395 Type Ty = Var->getType(); | 1398 Type Ty = Var->getType(); |
| 1396 const Operand *Src = getSrc(1); | 1399 const Operand *Src = getSrc(1); |
| 1397 if (isByteSizedArithType(Ty)) { | 1400 if (isByteSizedArithType(Ty)) { |
| 1398 // The 8-bit version of imul only allows the form "imul r/m8". | 1401 // The 8-bit version of imul only allows the form "imul r/m8". |
| 1399 const auto Src0Var = llvm::dyn_cast<Variable>(getSrc(0)); | 1402 const auto Src0Var = llvm::dyn_cast<Variable>(getSrc(0)); |
| 1400 (void)Src0Var; | 1403 (void)Src0Var; |
| 1401 assert(Src0Var && Src0Var->getRegNum() == RegX8632::Reg_eax); | 1404 assert(Src0Var && Src0Var->getRegNum() == RegX8632::Reg_eax); |
| 1402 const X8632::AssemblerX8632::GPREmitterOneOp Emitter = { | 1405 const X8632::AssemblerX8632::GPREmitterOneOp MyEmitter = { |
| 1403 &X8632::AssemblerX8632::imul, &X8632::AssemblerX8632::imul}; | 1406 &X8632::AssemblerX8632::imul, &X8632::AssemblerX8632::imul}; |
| 1404 emitIASOpTyGPR(Func, Ty, getSrc(1), Emitter); | 1407 emitIASOpTyGPR(Func, Ty, getSrc(1), MyEmitter); |
| 1405 } else { | 1408 } else { |
| 1406 // We only use imul as a two-address instruction even though | 1409 // We only use imul as a two-address instruction even though |
| 1407 // there is a 3 operand version when one of the operands is a constant. | 1410 // there is a 3 operand version when one of the operands is a constant. |
| 1408 assert(Var == getSrc(0)); | 1411 assert(Var == getSrc(0)); |
| 1409 const X8632::AssemblerX8632::GPREmitterRegOp Emitter = { | 1412 const X8632::AssemblerX8632::GPREmitterRegOp MyEmitter = { |
| 1410 &X8632::AssemblerX8632::imul, &X8632::AssemblerX8632::imul, | 1413 &X8632::AssemblerX8632::imul, &X8632::AssemblerX8632::imul, |
| 1411 &X8632::AssemblerX8632::imul}; | 1414 &X8632::AssemblerX8632::imul}; |
| 1412 emitIASRegOpTyGPR(Func, Ty, Var, Src, Emitter); | 1415 emitIASRegOpTyGPR(Func, Ty, Var, Src, MyEmitter); |
| 1413 } | 1416 } |
| 1414 } | 1417 } |
| 1415 | 1418 |
| 1416 template <> void InstX8632Insertps::emitIAS(const Cfg *Func) const { | 1419 template <> void InstX8632Insertps::emitIAS(const Cfg *Func) const { |
| 1417 assert(getSrcSize() == 3); | 1420 assert(getSrcSize() == 3); |
| 1418 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 1421 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
| 1419 TargetX8632::SSE4_1); | 1422 TargetX8632::SSE4_1); |
| 1420 const Variable *Dest = getDest(); | 1423 const Variable *Dest = getDest(); |
| 1421 assert(Dest == getSrc(0)); | 1424 assert(Dest == getSrc(0)); |
| 1422 Type Ty = Dest->getType(); | 1425 Type Ty = Dest->getType(); |
| (...skipping 1630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3053 } | 3056 } |
| 3054 Str << "("; | 3057 Str << "("; |
| 3055 if (Func) | 3058 if (Func) |
| 3056 Var->dump(Func); | 3059 Var->dump(Func); |
| 3057 else | 3060 else |
| 3058 Var->dump(Str); | 3061 Var->dump(Str); |
| 3059 Str << ")"; | 3062 Str << ")"; |
| 3060 } | 3063 } |
| 3061 | 3064 |
| 3062 } // end of namespace Ice | 3065 } // end of namespace Ice |
| OLD | NEW |