| 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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 | 60 |
| 61 void TargetX8664Traits::X86Operand::dump(const Cfg *, Ostream &Str) const { | 61 void TargetX8664Traits::X86Operand::dump(const Cfg *, Ostream &Str) const { |
| 62 if (BuildDefs::dump()) | 62 if (BuildDefs::dump()) |
| 63 Str << "<OperandX8664>"; | 63 Str << "<OperandX8664>"; |
| 64 } | 64 } |
| 65 | 65 |
| 66 TargetX8664Traits::X86OperandMem::X86OperandMem(Cfg *Func, Type Ty, | 66 TargetX8664Traits::X86OperandMem::X86OperandMem(Cfg *Func, Type Ty, |
| 67 Variable *Base, | 67 Variable *Base, |
| 68 Constant *Offset, | 68 Constant *Offset, |
| 69 Variable *Index, uint16_t Shift, | 69 Variable *Index, uint16_t Shift, |
| 70 bool IsPIC) | 70 bool IsRebased) |
| 71 : X86Operand(kMem, Ty), Base(Base), Offset(Offset), Index(Index), | 71 : X86Operand(kMem, Ty), Base(Base), Offset(Offset), Index(Index), |
| 72 Shift(Shift), IsPIC(IsPIC) { | 72 Shift(Shift), IsRebased(IsRebased) { |
| 73 assert(Shift <= 3); | 73 assert(Shift <= 3); |
| 74 Vars = nullptr; | 74 Vars = nullptr; |
| 75 NumVars = 0; | 75 NumVars = 0; |
| 76 if (Base) | 76 if (Base) |
| 77 ++NumVars; | 77 ++NumVars; |
| 78 if (Index) | 78 if (Index) |
| 79 ++NumVars; | 79 ++NumVars; |
| 80 if (NumVars) { | 80 if (NumVars) { |
| 81 Vars = Func->allocateArrayOf<Variable *>(NumVars); | 81 Vars = Func->allocateArrayOf<Variable *>(NumVars); |
| 82 SizeT I = 0; | 82 SizeT I = 0; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 103 } | 103 } |
| 104 } // end of anonymous namespace | 104 } // end of anonymous namespace |
| 105 | 105 |
| 106 void TargetX8664Traits::X86OperandMem::emit(const Cfg *Func) const { | 106 void TargetX8664Traits::X86OperandMem::emit(const Cfg *Func) const { |
| 107 if (!BuildDefs::dump()) | 107 if (!BuildDefs::dump()) |
| 108 return; | 108 return; |
| 109 const auto *Target = | 109 const auto *Target = |
| 110 static_cast<const ::Ice::X8664::TargetX8664 *>(Func->getTarget()); | 110 static_cast<const ::Ice::X8664::TargetX8664 *>(Func->getTarget()); |
| 111 // If the base is rematerializable, we need to replace it with the correct | 111 // If the base is rematerializable, we need to replace it with the correct |
| 112 // physical register (stack or base pointer), and update the Offset. | 112 // physical register (stack or base pointer), and update the Offset. |
| 113 const bool NeedSandboxing = Target->needSandboxing(); |
| 113 int32_t Disp = 0; | 114 int32_t Disp = 0; |
| 114 if (getBase() && getBase()->isRematerializable()) { | 115 if (getBase() && getBase()->isRematerializable()) { |
| 115 Disp += getRematerializableOffset(getBase(), Target); | 116 Disp += getRematerializableOffset(getBase(), Target); |
| 116 } | 117 } |
| 117 // The index should never be rematerializable. But if we ever allow it, then | 118 // The index should never be rematerializable. But if we ever allow it, then |
| 118 // we should make sure the rematerialization offset is shifted by the Shift | 119 // we should make sure the rematerialization offset is shifted by the Shift |
| 119 // value. | 120 // value. |
| 120 if (getIndex()) | 121 if (getIndex()) |
| 121 assert(!getIndex()->isRematerializable()); | 122 assert(!getIndex()->isRematerializable()); |
| 122 Ostream &Str = Func->getContext()->getStrEmit(); | 123 Ostream &Str = Func->getContext()->getStrEmit(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 133 } else if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(Offset)) { | 134 } else if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(Offset)) { |
| 134 // TODO(sehr): ConstantRelocatable still needs updating for | 135 // TODO(sehr): ConstantRelocatable still needs updating for |
| 135 // rematerializable base/index and Disp. | 136 // rematerializable base/index and Disp. |
| 136 assert(Disp == 0); | 137 assert(Disp == 0); |
| 137 const bool UseNonsfi = Func->getContext()->getFlags().getUseNonsfi(); | 138 const bool UseNonsfi = Func->getContext()->getFlags().getUseNonsfi(); |
| 138 CR->emitWithoutPrefix(Func->getTarget(), UseNonsfi ? "@GOTOFF" : ""); | 139 CR->emitWithoutPrefix(Func->getTarget(), UseNonsfi ? "@GOTOFF" : ""); |
| 139 } else { | 140 } else { |
| 140 llvm_unreachable("Invalid offset type for x86 mem operand"); | 141 llvm_unreachable("Invalid offset type for x86 mem operand"); |
| 141 } | 142 } |
| 142 | 143 |
| 143 if (Base || Index) { | 144 if (Base == nullptr && Index == nullptr) { |
| 144 Str << "("; | 145 return; |
| 145 if (Base) { | 146 } |
| 146 const Variable *Base32 = Base; | 147 |
| 147 if (Base->getType() != IceType_i32) { | 148 Str << "("; |
| 149 if (Base != nullptr) { |
| 150 const Variable *B = Base; |
| 151 if (!NeedSandboxing) { |
| 152 // TODO(jpp): stop abusing the operand's type to identify LEAs. |
| 153 const Type MemType = getType(); |
| 154 if (Base->getType() != IceType_i32 && MemType != IceType_void) { |
| 148 // X86-64 is ILP32, but %rsp and %rbp are accessed as 64-bit registers. | 155 // X86-64 is ILP32, but %rsp and %rbp are accessed as 64-bit registers. |
| 149 // For filetype=asm, they need to be emitted as their 32-bit sibilings. | 156 // For filetype=asm, they need to be emitted as their 32-bit sibilings. |
| 150 assert(Base->getType() == IceType_i64); | 157 assert(Base->getType() == IceType_i64); |
| 151 assert(Base->getRegNum() == RegX8664::Encoded_Reg_rsp || | 158 assert(Base->getRegNum() == RegX8664::Encoded_Reg_rsp || |
| 152 Base->getRegNum() == RegX8664::Encoded_Reg_rbp); | 159 Base->getRegNum() == RegX8664::Encoded_Reg_rbp || |
| 153 Base32 = Base->asType(IceType_i32, X8664::Traits::getGprForType( | 160 getType() == IceType_void); |
| 154 IceType_i32, Base->getRegNum())); | 161 B = B->asType(IceType_i32, X8664::Traits::getGprForType( |
| 162 IceType_i32, Base->getRegNum())); |
| 155 } | 163 } |
| 156 Base32->emit(Func); | |
| 157 } | 164 } |
| 158 if (Index) { | 165 |
| 159 assert(Index->getType() == IceType_i32); | 166 B->emit(Func); |
| 160 Str << ","; | |
| 161 Index->emit(Func); | |
| 162 if (Shift) | |
| 163 Str << "," << (1u << Shift); | |
| 164 } | |
| 165 Str << ")"; | |
| 166 } | 167 } |
| 168 |
| 169 if (Index != nullptr) { |
| 170 Variable *I = Index; |
| 171 Str << ","; |
| 172 I->emit(Func); |
| 173 if (Shift) |
| 174 Str << "," << (1u << Shift); |
| 175 } |
| 176 |
| 177 Str << ")"; |
| 167 } | 178 } |
| 168 | 179 |
| 169 void TargetX8664Traits::X86OperandMem::dump(const Cfg *Func, | 180 void TargetX8664Traits::X86OperandMem::dump(const Cfg *Func, |
| 170 Ostream &Str) const { | 181 Ostream &Str) const { |
| 171 if (!BuildDefs::dump()) | 182 if (!BuildDefs::dump()) |
| 172 return; | 183 return; |
| 173 bool Dumped = false; | 184 bool Dumped = false; |
| 174 Str << "["; | 185 Str << "["; |
| 175 int32_t Disp = 0; | 186 int32_t Disp = 0; |
| 176 const auto *Target = | 187 const auto *Target = |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 } | 232 } |
| 222 } else { | 233 } else { |
| 223 // There is only the offset. | 234 // There is only the offset. |
| 224 Offset->dump(Func, Str); | 235 Offset->dump(Func, Str); |
| 225 } | 236 } |
| 226 Str << "]"; | 237 Str << "]"; |
| 227 } | 238 } |
| 228 | 239 |
| 229 TargetX8664Traits::Address TargetX8664Traits::X86OperandMem::toAsmAddress( | 240 TargetX8664Traits::Address TargetX8664Traits::X86OperandMem::toAsmAddress( |
| 230 TargetX8664Traits::Assembler *Asm, | 241 TargetX8664Traits::Assembler *Asm, |
| 231 const Ice::TargetLowering *TargetLowering) const { | 242 const Ice::TargetLowering *TargetLowering, bool IsLeaAddr) const { |
| 243 (void)IsLeaAddr; |
| 232 const auto *Target = | 244 const auto *Target = |
| 233 static_cast<const ::Ice::X8664::TargetX8664 *>(TargetLowering); | 245 static_cast<const ::Ice::X8664::TargetX8664 *>(TargetLowering); |
| 234 int32_t Disp = 0; | 246 int32_t Disp = 0; |
| 235 if (getBase() && getBase()->isRematerializable()) { | 247 if (getBase() && getBase()->isRematerializable()) { |
| 236 Disp += getRematerializableOffset(getBase(), Target); | 248 Disp += getRematerializableOffset(getBase(), Target); |
| 237 } | 249 } |
| 238 if (getIndex()) | 250 if (getIndex() != nullptr) { |
| 239 assert(!getIndex()->isRematerializable()); | 251 assert(!getIndex()->isRematerializable()); |
| 252 } |
| 253 |
| 240 AssemblerFixup *Fixup = nullptr; | 254 AssemblerFixup *Fixup = nullptr; |
| 241 // Determine the offset (is it relocatable?) | 255 // Determine the offset (is it relocatable?) |
| 242 if (getOffset() != nullptr) { | 256 if (getOffset() != nullptr) { |
| 243 if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) { | 257 if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) { |
| 244 Disp += static_cast<int32_t>(CI->getValue()); | 258 Disp += static_cast<int32_t>(CI->getValue()); |
| 245 } else if (const auto CR = | 259 } else if (const auto CR = |
| 246 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { | 260 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { |
| 247 Disp = CR->getOffset(); | 261 Disp = CR->getOffset(); |
| 248 Fixup = Asm->createFixup(FK_Abs, CR); | 262 Fixup = Asm->createFixup(FK_Abs, CR); |
| 249 } else { | 263 } else { |
| 250 llvm_unreachable("Unexpected offset type"); | 264 llvm_unreachable("Unexpected offset type"); |
| 251 } | 265 } |
| 252 } | 266 } |
| 253 | 267 |
| 254 // Now convert to the various possible forms. | 268 // Now convert to the various possible forms. |
| 255 if (getBase() && getIndex()) { | 269 if (getBase() && getIndex()) { |
| 270 const bool NeedSandboxing = Target->needSandboxing(); |
| 271 (void)NeedSandboxing; |
| 272 assert(!NeedSandboxing || IsLeaAddr || |
| 273 (getBase()->getRegNum() == Traits::RegisterSet::Reg_r15)); |
| 256 return X8664::Traits::Address(getEncodedGPR(getBase()->getRegNum()), | 274 return X8664::Traits::Address(getEncodedGPR(getBase()->getRegNum()), |
| 257 getEncodedGPR(getIndex()->getRegNum()), | 275 getEncodedGPR(getIndex()->getRegNum()), |
| 258 X8664::Traits::ScaleFactor(getShift()), Disp, | 276 X8664::Traits::ScaleFactor(getShift()), Disp, |
| 259 Fixup); | 277 Fixup); |
| 260 } else if (getBase()) { | 278 } |
| 279 |
| 280 if (getBase()) { |
| 261 return X8664::Traits::Address(getEncodedGPR(getBase()->getRegNum()), Disp, | 281 return X8664::Traits::Address(getEncodedGPR(getBase()->getRegNum()), Disp, |
| 262 Fixup); | 282 Fixup); |
| 263 } else if (getIndex()) { | 283 } |
| 284 |
| 285 if (getIndex()) { |
| 264 return X8664::Traits::Address(getEncodedGPR(getIndex()->getRegNum()), | 286 return X8664::Traits::Address(getEncodedGPR(getIndex()->getRegNum()), |
| 265 X8664::Traits::ScaleFactor(getShift()), Disp, | 287 X8664::Traits::ScaleFactor(getShift()), Disp, |
| 266 Fixup); | 288 Fixup); |
| 267 } else { | |
| 268 return X8664::Traits::Address(Disp, Fixup); | |
| 269 } | 289 } |
| 290 |
| 291 return X8664::Traits::Address(Disp, Fixup); |
| 270 } | 292 } |
| 271 | 293 |
| 272 TargetX8664Traits::Address | 294 TargetX8664Traits::Address |
| 273 TargetX8664Traits::VariableSplit::toAsmAddress(const Cfg *Func) const { | 295 TargetX8664Traits::VariableSplit::toAsmAddress(const Cfg *Func) const { |
| 274 assert(!Var->hasReg()); | 296 assert(!Var->hasReg()); |
| 275 const ::Ice::TargetLowering *Target = Func->getTarget(); | 297 const ::Ice::TargetLowering *Target = Func->getTarget(); |
| 276 int32_t Offset = Var->getStackOffset() + getOffset(); | 298 int32_t Offset = Var->getStackOffset() + getOffset(); |
| 277 return X8664::Traits::Address(getEncodedGPR(Target->getFrameOrStackReg()), | 299 return X8664::Traits::Address(getEncodedGPR(Target->getFrameOrStackReg()), |
| 278 Offset, AssemblerFixup::NoFixup); | 300 Offset, AssemblerFixup::NoFixup); |
| 279 } | 301 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 309 Var->dump(Func); | 331 Var->dump(Func); |
| 310 else | 332 else |
| 311 Var->dump(Str); | 333 Var->dump(Str); |
| 312 Str << ")"; | 334 Str << ")"; |
| 313 } | 335 } |
| 314 | 336 |
| 315 } // namespace X8664 | 337 } // namespace X8664 |
| 316 } // end of namespace Ice | 338 } // end of namespace Ice |
| 317 | 339 |
| 318 X86INSTS_DEFINE_STATIC_DATA(X8664, X8664::Traits) | 340 X86INSTS_DEFINE_STATIC_DATA(X8664, X8664::Traits) |
| OLD | NEW |