| OLD | NEW |
| 1 //===- subzero/src/IceInstX8664.cpp - X86-64 instruction implementation ---===// | 1 //===- subzero/src/IceInstX8664.cpp - X86-64 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 /// \file | 10 /// \file |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 #include "IceCfg.h" | 22 #include "IceCfg.h" |
| 23 #include "IceCfgNode.h" | 23 #include "IceCfgNode.h" |
| 24 #include "IceConditionCodesX8664.h" | 24 #include "IceConditionCodesX8664.h" |
| 25 #include "IceInst.h" | 25 #include "IceInst.h" |
| 26 #include "IceRegistersX8664.h" | 26 #include "IceRegistersX8664.h" |
| 27 #include "IceTargetLoweringX8664.h" | 27 #include "IceTargetLoweringX8664.h" |
| 28 #include "IceOperand.h" | 28 #include "IceOperand.h" |
| 29 | 29 |
| 30 namespace Ice { | 30 namespace Ice { |
| 31 | 31 |
| 32 namespace X86Internal { | 32 namespace X8664 { |
| 33 | 33 |
| 34 const MachineTraits<TargetX8664>::InstBrAttributesType | 34 const TargetX8664Traits::InstBrAttributesType |
| 35 MachineTraits<TargetX8664>::InstBrAttributes[] = { | 35 TargetX8664Traits::InstBrAttributes[] = { |
| 36 #define X(val, encode, opp, dump, emit) \ | 36 #define X(val, encode, opp, dump, emit) \ |
| 37 { X8664::Traits::Cond::opp, dump, emit } \ | 37 { X8664::Traits::Cond::opp, dump, emit } \ |
| 38 , | 38 , |
| 39 ICEINSTX8664BR_TABLE | 39 ICEINSTX8664BR_TABLE |
| 40 #undef X | 40 #undef X |
| 41 }; | 41 }; |
| 42 | 42 |
| 43 const MachineTraits<TargetX8664>::InstCmppsAttributesType | 43 const TargetX8664Traits::InstCmppsAttributesType |
| 44 MachineTraits<TargetX8664>::InstCmppsAttributes[] = { | 44 TargetX8664Traits::InstCmppsAttributes[] = { |
| 45 #define X(val, emit) \ | 45 #define X(val, emit) \ |
| 46 { emit } \ | 46 { emit } \ |
| 47 , | 47 , |
| 48 ICEINSTX8664CMPPS_TABLE | 48 ICEINSTX8664CMPPS_TABLE |
| 49 #undef X | 49 #undef X |
| 50 }; | 50 }; |
| 51 | 51 |
| 52 const MachineTraits<TargetX8664>::TypeAttributesType | 52 const TargetX8664Traits::TypeAttributesType |
| 53 MachineTraits<TargetX8664>::TypeAttributes[] = { | 53 TargetX8664Traits::TypeAttributes[] = { |
| 54 #define X(tag, elementty, cvt, sdss, pdps, spsd, pack, width, fld) \ | 54 #define X(tag, elementty, cvt, sdss, pdps, spsd, pack, width, fld) \ |
| 55 { cvt, sdss, pdps, spsd, pack, width, fld } \ | 55 { cvt, sdss, pdps, spsd, pack, width, fld } \ |
| 56 , | 56 , |
| 57 ICETYPEX8664_TABLE | 57 ICETYPEX8664_TABLE |
| 58 #undef X | 58 #undef X |
| 59 }; | 59 }; |
| 60 | 60 |
| 61 void MachineTraits<TargetX8664>::X86Operand::dump(const Cfg *, | 61 void TargetX8664Traits::X86Operand::dump(const Cfg *, Ostream &Str) const { |
| 62 Ostream &Str) const { | |
| 63 if (BuildDefs::dump()) | 62 if (BuildDefs::dump()) |
| 64 Str << "<OperandX8664>"; | 63 Str << "<OperandX8664>"; |
| 65 } | 64 } |
| 66 | 65 |
| 67 MachineTraits<TargetX8664>::X86OperandMem::X86OperandMem(Cfg *Func, Type Ty, | 66 TargetX8664Traits::X86OperandMem::X86OperandMem(Cfg *Func, Type Ty, |
| 68 Variable *Base, | 67 Variable *Base, |
| 69 Constant *Offset, | 68 Constant *Offset, |
| 70 Variable *Index, | 69 Variable *Index, uint16_t Shift) |
| 71 uint16_t Shift) | |
| 72 : X86Operand(kMem, Ty), Base(Base), Offset(Offset), Index(Index), | 70 : X86Operand(kMem, Ty), Base(Base), Offset(Offset), Index(Index), |
| 73 Shift(Shift) { | 71 Shift(Shift) { |
| 74 assert(Shift <= 3); | 72 assert(Shift <= 3); |
| 75 Vars = nullptr; | 73 Vars = nullptr; |
| 76 NumVars = 0; | 74 NumVars = 0; |
| 77 if (Base) | 75 if (Base) |
| 78 ++NumVars; | 76 ++NumVars; |
| 79 if (Index) | 77 if (Index) |
| 80 ++NumVars; | 78 ++NumVars; |
| 81 if (NumVars) { | 79 if (NumVars) { |
| 82 Vars = Func->allocateArrayOf<Variable *>(NumVars); | 80 Vars = Func->allocateArrayOf<Variable *>(NumVars); |
| 83 SizeT I = 0; | 81 SizeT I = 0; |
| 84 if (Base) | 82 if (Base) |
| 85 Vars[I++] = Base; | 83 Vars[I++] = Base; |
| 86 if (Index) | 84 if (Index) |
| 87 Vars[I++] = Index; | 85 Vars[I++] = Index; |
| 88 assert(I == NumVars); | 86 assert(I == NumVars); |
| 89 } | 87 } |
| 90 } | 88 } |
| 91 | 89 |
| 92 namespace { | 90 namespace { |
| 93 static int32_t getRematerializableOffset(Variable *Var, | 91 static int32_t |
| 94 const Ice::TargetX8664 *Target) { | 92 getRematerializableOffset(Variable *Var, |
| 93 const ::Ice::X8664::TargetX8664 *Target) { |
| 95 int32_t Disp = Var->getStackOffset(); | 94 int32_t Disp = Var->getStackOffset(); |
| 96 SizeT RegNum = static_cast<SizeT>(Var->getRegNum()); | 95 SizeT RegNum = static_cast<SizeT>(Var->getRegNum()); |
| 97 if (RegNum == Target->getFrameReg()) { | 96 if (RegNum == Target->getFrameReg()) { |
| 98 Disp += Target->getFrameFixedAllocaOffset(); | 97 Disp += Target->getFrameFixedAllocaOffset(); |
| 99 } else if (RegNum != Target->getStackReg()) { | 98 } else if (RegNum != Target->getStackReg()) { |
| 100 llvm::report_fatal_error("Unexpected rematerializable register type"); | 99 llvm::report_fatal_error("Unexpected rematerializable register type"); |
| 101 } | 100 } |
| 102 return Disp; | 101 return Disp; |
| 103 } | 102 } |
| 104 } // end of anonymous namespace | 103 } // end of anonymous namespace |
| 105 | 104 |
| 106 void MachineTraits<TargetX8664>::X86OperandMem::emit(const Cfg *Func) const { | 105 void TargetX8664Traits::X86OperandMem::emit(const Cfg *Func) const { |
| 107 if (!BuildDefs::dump()) | 106 if (!BuildDefs::dump()) |
| 108 return; | 107 return; |
| 109 const auto *Target = static_cast<const Ice::TargetX8664 *>(Func->getTarget()); | 108 const auto *Target = |
| 109 static_cast<const ::Ice::X8664::TargetX8664 *>(Func->getTarget()); |
| 110 // If the base is rematerializable, we need to replace it with the correct | 110 // If the base is rematerializable, we need to replace it with the correct |
| 111 // physical register (stack or base pointer), and update the Offset. | 111 // physical register (stack or base pointer), and update the Offset. |
| 112 int32_t Disp = 0; | 112 int32_t Disp = 0; |
| 113 if (getBase() && getBase()->isRematerializable()) { | 113 if (getBase() && getBase()->isRematerializable()) { |
| 114 Disp += getRematerializableOffset(getBase(), Target); | 114 Disp += getRematerializableOffset(getBase(), Target); |
| 115 } | 115 } |
| 116 // The index should never be rematerializable. But if we ever allow it, then | 116 // The index should never be rematerializable. But if we ever allow it, then |
| 117 // we should make sure the rematerialization offset is shifted by the Shift | 117 // we should make sure the rematerialization offset is shifted by the Shift |
| 118 // value. | 118 // value. |
| 119 if (getIndex()) | 119 if (getIndex()) |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 assert(Index->getType() == IceType_i32); | 157 assert(Index->getType() == IceType_i32); |
| 158 Str << ","; | 158 Str << ","; |
| 159 Index->emit(Func); | 159 Index->emit(Func); |
| 160 if (Shift) | 160 if (Shift) |
| 161 Str << "," << (1u << Shift); | 161 Str << "," << (1u << Shift); |
| 162 } | 162 } |
| 163 Str << ")"; | 163 Str << ")"; |
| 164 } | 164 } |
| 165 } | 165 } |
| 166 | 166 |
| 167 void MachineTraits<TargetX8664>::X86OperandMem::dump(const Cfg *Func, | 167 void TargetX8664Traits::X86OperandMem::dump(const Cfg *Func, |
| 168 Ostream &Str) const { | 168 Ostream &Str) const { |
| 169 if (!BuildDefs::dump()) | 169 if (!BuildDefs::dump()) |
| 170 return; | 170 return; |
| 171 bool Dumped = false; | 171 bool Dumped = false; |
| 172 Str << "["; | 172 Str << "["; |
| 173 int32_t Disp = 0; | 173 int32_t Disp = 0; |
| 174 const auto *Target = static_cast<const Ice::TargetX8664 *>(Func->getTarget()); | 174 const auto *Target = |
| 175 static_cast<const ::Ice::X8664::TargetX8664 *>(Func->getTarget()); |
| 175 if (getBase() && getBase()->isRematerializable()) { | 176 if (getBase() && getBase()->isRematerializable()) { |
| 176 Disp += getRematerializableOffset(getBase(), Target); | 177 Disp += getRematerializableOffset(getBase(), Target); |
| 177 } | 178 } |
| 178 if (Base) { | 179 if (Base) { |
| 179 if (Func) | 180 if (Func) |
| 180 Base->dump(Func); | 181 Base->dump(Func); |
| 181 else | 182 else |
| 182 Base->dump(Str); | 183 Base->dump(Str); |
| 183 Dumped = true; | 184 Dumped = true; |
| 184 } | 185 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 Str << "+"; | 217 Str << "+"; |
| 217 Offset->dump(Func, Str); | 218 Offset->dump(Func, Str); |
| 218 } | 219 } |
| 219 } else { | 220 } else { |
| 220 // There is only the offset. | 221 // There is only the offset. |
| 221 Offset->dump(Func, Str); | 222 Offset->dump(Func, Str); |
| 222 } | 223 } |
| 223 Str << "]"; | 224 Str << "]"; |
| 224 } | 225 } |
| 225 | 226 |
| 226 MachineTraits<TargetX8664>::Address | 227 TargetX8664Traits::Address TargetX8664Traits::X86OperandMem::toAsmAddress( |
| 227 MachineTraits<TargetX8664>::X86OperandMem::toAsmAddress( | 228 TargetX8664Traits::Assembler *Asm, |
| 228 MachineTraits<TargetX8664>::Assembler *Asm, | |
| 229 const Ice::TargetLowering *TargetLowering) const { | 229 const Ice::TargetLowering *TargetLowering) const { |
| 230 const auto *Target = static_cast<const Ice::TargetX8664 *>(TargetLowering); | 230 const auto *Target = |
| 231 static_cast<const ::Ice::X8664::TargetX8664 *>(TargetLowering); |
| 231 int32_t Disp = 0; | 232 int32_t Disp = 0; |
| 232 if (getBase() && getBase()->isRematerializable()) { | 233 if (getBase() && getBase()->isRematerializable()) { |
| 233 Disp += getRematerializableOffset(getBase(), Target); | 234 Disp += getRematerializableOffset(getBase(), Target); |
| 234 } | 235 } |
| 235 if (getIndex()) | 236 if (getIndex()) |
| 236 assert(!getIndex()->isRematerializable()); | 237 assert(!getIndex()->isRematerializable()); |
| 237 AssemblerFixup *Fixup = nullptr; | 238 AssemblerFixup *Fixup = nullptr; |
| 238 // Determine the offset (is it relocatable?) | 239 // Determine the offset (is it relocatable?) |
| 239 if (getOffset() != nullptr) { | 240 if (getOffset() != nullptr) { |
| 240 if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) { | 241 if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 259 Fixup); | 260 Fixup); |
| 260 } else if (getIndex()) { | 261 } else if (getIndex()) { |
| 261 return X8664::Traits::Address(getEncodedGPR(getIndex()->getRegNum()), | 262 return X8664::Traits::Address(getEncodedGPR(getIndex()->getRegNum()), |
| 262 X8664::Traits::ScaleFactor(getShift()), Disp, | 263 X8664::Traits::ScaleFactor(getShift()), Disp, |
| 263 Fixup); | 264 Fixup); |
| 264 } else { | 265 } else { |
| 265 return X8664::Traits::Address(Disp, Fixup); | 266 return X8664::Traits::Address(Disp, Fixup); |
| 266 } | 267 } |
| 267 } | 268 } |
| 268 | 269 |
| 269 MachineTraits<TargetX8664>::Address | 270 TargetX8664Traits::Address |
| 270 MachineTraits<TargetX8664>::VariableSplit::toAsmAddress(const Cfg *Func) const { | 271 TargetX8664Traits::VariableSplit::toAsmAddress(const Cfg *Func) const { |
| 271 assert(!Var->hasReg()); | 272 assert(!Var->hasReg()); |
| 272 const ::Ice::TargetLowering *Target = Func->getTarget(); | 273 const ::Ice::TargetLowering *Target = Func->getTarget(); |
| 273 int32_t Offset = Var->getStackOffset() + getOffset(); | 274 int32_t Offset = Var->getStackOffset() + getOffset(); |
| 274 return X8664::Traits::Address(getEncodedGPR(Target->getFrameOrStackReg()), | 275 return X8664::Traits::Address(getEncodedGPR(Target->getFrameOrStackReg()), |
| 275 Offset, AssemblerFixup::NoFixup); | 276 Offset, AssemblerFixup::NoFixup); |
| 276 } | 277 } |
| 277 | 278 |
| 278 void MachineTraits<TargetX8664>::VariableSplit::emit(const Cfg *Func) const { | 279 void TargetX8664Traits::VariableSplit::emit(const Cfg *Func) const { |
| 279 if (!BuildDefs::dump()) | 280 if (!BuildDefs::dump()) |
| 280 return; | 281 return; |
| 281 Ostream &Str = Func->getContext()->getStrEmit(); | 282 Ostream &Str = Func->getContext()->getStrEmit(); |
| 282 assert(!Var->hasReg()); | 283 assert(!Var->hasReg()); |
| 283 // The following is copied/adapted from TargetX8664::emitVariable(). | 284 // The following is copied/adapted from TargetX8664::emitVariable(). |
| 284 const ::Ice::TargetLowering *Target = Func->getTarget(); | 285 const ::Ice::TargetLowering *Target = Func->getTarget(); |
| 285 constexpr Type Ty = IceType_i32; | 286 constexpr Type Ty = IceType_i32; |
| 286 int32_t Offset = Var->getStackOffset() + getOffset(); | 287 int32_t Offset = Var->getStackOffset() + getOffset(); |
| 287 if (Offset) | 288 if (Offset) |
| 288 Str << Offset; | 289 Str << Offset; |
| 289 Str << "(%" << Target->getRegName(Target->getFrameOrStackReg(), Ty) << ")"; | 290 Str << "(%" << Target->getRegName(Target->getFrameOrStackReg(), Ty) << ")"; |
| 290 } | 291 } |
| 291 | 292 |
| 292 void MachineTraits<TargetX8664>::VariableSplit::dump(const Cfg *Func, | 293 void TargetX8664Traits::VariableSplit::dump(const Cfg *Func, |
| 293 Ostream &Str) const { | 294 Ostream &Str) const { |
| 294 if (!BuildDefs::dump()) | 295 if (!BuildDefs::dump()) |
| 295 return; | 296 return; |
| 296 switch (Part) { | 297 switch (Part) { |
| 297 case Low: | 298 case Low: |
| 298 Str << "low"; | 299 Str << "low"; |
| 299 break; | 300 break; |
| 300 case High: | 301 case High: |
| 301 Str << "high"; | 302 Str << "high"; |
| 302 break; | 303 break; |
| 303 } | 304 } |
| 304 Str << "("; | 305 Str << "("; |
| 305 if (Func) | 306 if (Func) |
| 306 Var->dump(Func); | 307 Var->dump(Func); |
| 307 else | 308 else |
| 308 Var->dump(Str); | 309 Var->dump(Str); |
| 309 Str << ")"; | 310 Str << ")"; |
| 310 } | 311 } |
| 311 | 312 |
| 312 } // namespace X86Internal | 313 } // namespace X8664 |
| 313 } // end of namespace Ice | 314 } // end of namespace Ice |
| 314 | 315 |
| 315 X86INSTS_DEFINE_STATIC_DATA(TargetX8664) | 316 X86INSTS_DEFINE_STATIC_DATA(X8664, X8664::Traits) |
| OLD | NEW |