| 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 && !Index) { | 
| 144     Str << "("; | 145     return; | 
| 145     if (Base) { | 146   } | 
| 146       const Variable *Base32 = Base; | 147 | 
|  | 148   Str << "("; | 
|  | 149   if (Base != nullptr) { | 
|  | 150     const Variable *B = Base; | 
|  | 151     if (!NeedSandboxing) { | 
| 147       if (Base->getType() != IceType_i32) { | 152       if (Base->getType() != IceType_i32) { | 
| 148         // X86-64 is ILP32, but %rsp and %rbp are accessed as 64-bit registers. | 153         // 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. | 154         // For filetype=asm, they need to be emitted as their 32-bit sibilings. | 
| 150         assert(Base->getType() == IceType_i64); | 155         assert(Base->getType() == IceType_i64); | 
| 151         assert(Base->getRegNum() == RegX8664::Encoded_Reg_rsp || | 156         assert(Base->getRegNum() == RegX8664::Encoded_Reg_rsp || | 
| 152                Base->getRegNum() == RegX8664::Encoded_Reg_rbp); | 157                Base->getRegNum() == RegX8664::Encoded_Reg_rbp); | 
| 153         Base32 = Base->asType(IceType_i32, X8664::Traits::getGprForType( | 158         B = B->asType(IceType_i32, X8664::Traits::getGprForType( | 
| 154                                                IceType_i32, Base->getRegNum())); | 159                                        IceType_i32, Base->getRegNum())); | 
| 155       } | 160       } | 
| 156       Base32->emit(Func); |  | 
| 157     } | 161     } | 
| 158     if (Index) { | 162 | 
| 159       assert(Index->getType() == IceType_i32); | 163     B->emit(Func); | 
| 160       Str << ","; |  | 
| 161       Index->emit(Func); |  | 
| 162       if (Shift) |  | 
| 163         Str << "," << (1u << Shift); |  | 
| 164     } |  | 
| 165     Str << ")"; |  | 
| 166   } | 164   } | 
|  | 165 | 
|  | 166   if (Index != nullptr) { | 
|  | 167     Variable *I = Index; | 
|  | 168     Str << ","; | 
|  | 169     I->emit(Func); | 
|  | 170     if (Shift) | 
|  | 171       Str << "," << (1u << Shift); | 
|  | 172   } | 
|  | 173 | 
|  | 174   Str << ")"; | 
| 167 } | 175 } | 
| 168 | 176 | 
| 169 void TargetX8664Traits::X86OperandMem::dump(const Cfg *Func, | 177 void TargetX8664Traits::X86OperandMem::dump(const Cfg *Func, | 
| 170                                             Ostream &Str) const { | 178                                             Ostream &Str) const { | 
| 171   if (!BuildDefs::dump()) | 179   if (!BuildDefs::dump()) | 
| 172     return; | 180     return; | 
| 173   bool Dumped = false; | 181   bool Dumped = false; | 
| 174   Str << "["; | 182   Str << "["; | 
| 175   int32_t Disp = 0; | 183   int32_t Disp = 0; | 
| 176   const auto *Target = | 184   const auto *Target = | 
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 221     } | 229     } | 
| 222   } else { | 230   } else { | 
| 223     // There is only the offset. | 231     // There is only the offset. | 
| 224     Offset->dump(Func, Str); | 232     Offset->dump(Func, Str); | 
| 225   } | 233   } | 
| 226   Str << "]"; | 234   Str << "]"; | 
| 227 } | 235 } | 
| 228 | 236 | 
| 229 TargetX8664Traits::Address TargetX8664Traits::X86OperandMem::toAsmAddress( | 237 TargetX8664Traits::Address TargetX8664Traits::X86OperandMem::toAsmAddress( | 
| 230     TargetX8664Traits::Assembler *Asm, | 238     TargetX8664Traits::Assembler *Asm, | 
| 231     const Ice::TargetLowering *TargetLowering) const { | 239     const Ice::TargetLowering *TargetLowering, bool LeaAddr) const { | 
|  | 240   (void)LeaAddr; | 
| 232   const auto *Target = | 241   const auto *Target = | 
| 233       static_cast<const ::Ice::X8664::TargetX8664 *>(TargetLowering); | 242       static_cast<const ::Ice::X8664::TargetX8664 *>(TargetLowering); | 
|  | 243   const bool NeedSandboxing = Target->needSandboxing(); | 
|  | 244   (void)NeedSandboxing; | 
| 234   int32_t Disp = 0; | 245   int32_t Disp = 0; | 
| 235   if (getBase() && getBase()->isRematerializable()) { | 246   if (getBase() && getBase()->isRematerializable()) { | 
| 236     Disp += getRematerializableOffset(getBase(), Target); | 247     Disp += getRematerializableOffset(getBase(), Target); | 
| 237   } | 248   } | 
| 238   if (getIndex()) | 249   if (getIndex() != nullptr) { | 
| 239     assert(!getIndex()->isRematerializable()); | 250     assert(!getIndex()->isRematerializable()); | 
|  | 251   } | 
|  | 252 | 
| 240   AssemblerFixup *Fixup = nullptr; | 253   AssemblerFixup *Fixup = nullptr; | 
| 241   // Determine the offset (is it relocatable?) | 254   // Determine the offset (is it relocatable?) | 
| 242   if (getOffset() != nullptr) { | 255   if (getOffset() != nullptr) { | 
| 243     if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) { | 256     if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) { | 
| 244       Disp += static_cast<int32_t>(CI->getValue()); | 257       Disp += static_cast<int32_t>(CI->getValue()); | 
| 245     } else if (const auto CR = | 258     } else if (const auto CR = | 
| 246                    llvm::dyn_cast<ConstantRelocatable>(getOffset())) { | 259                    llvm::dyn_cast<ConstantRelocatable>(getOffset())) { | 
| 247       Disp = CR->getOffset(); | 260       Disp = CR->getOffset(); | 
| 248       Fixup = Asm->createFixup(FK_Abs, CR); | 261       Fixup = Asm->createFixup(FK_Abs, CR); | 
| 249     } else { | 262     } else { | 
| 250       llvm_unreachable("Unexpected offset type"); | 263       llvm_unreachable("Unexpected offset type"); | 
| 251     } | 264     } | 
| 252   } | 265   } | 
| 253 | 266 | 
| 254   // Now convert to the various possible forms. | 267   // Now convert to the various possible forms. | 
| 255   if (getBase() && getIndex()) { | 268   if (getBase() && getIndex()) { | 
|  | 269     assert(!NeedSandboxing || LeaAddr || | 
|  | 270            (getBase()->getRegNum() == Traits::RegisterSet::Reg_r15)); | 
| 256     return X8664::Traits::Address(getEncodedGPR(getBase()->getRegNum()), | 271     return X8664::Traits::Address(getEncodedGPR(getBase()->getRegNum()), | 
| 257                                   getEncodedGPR(getIndex()->getRegNum()), | 272                                   getEncodedGPR(getIndex()->getRegNum()), | 
| 258                                   X8664::Traits::ScaleFactor(getShift()), Disp, | 273                                   X8664::Traits::ScaleFactor(getShift()), Disp, | 
| 259                                   Fixup); | 274                                   Fixup); | 
| 260   } else if (getBase()) { | 275   } | 
|  | 276 | 
|  | 277   if (getBase()) { | 
| 261     return X8664::Traits::Address(getEncodedGPR(getBase()->getRegNum()), Disp, | 278     return X8664::Traits::Address(getEncodedGPR(getBase()->getRegNum()), Disp, | 
| 262                                   Fixup); | 279                                   Fixup); | 
| 263   } else if (getIndex()) { | 280   } | 
|  | 281 | 
|  | 282   if (getIndex()) { | 
| 264     return X8664::Traits::Address(getEncodedGPR(getIndex()->getRegNum()), | 283     return X8664::Traits::Address(getEncodedGPR(getIndex()->getRegNum()), | 
| 265                                   X8664::Traits::ScaleFactor(getShift()), Disp, | 284                                   X8664::Traits::ScaleFactor(getShift()), Disp, | 
| 266                                   Fixup); | 285                                   Fixup); | 
| 267   } else { |  | 
| 268     return X8664::Traits::Address(Disp, Fixup); |  | 
| 269   } | 286   } | 
|  | 287 | 
|  | 288   return X8664::Traits::Address(Disp, Fixup); | 
| 270 } | 289 } | 
| 271 | 290 | 
| 272 TargetX8664Traits::Address | 291 TargetX8664Traits::Address | 
| 273 TargetX8664Traits::VariableSplit::toAsmAddress(const Cfg *Func) const { | 292 TargetX8664Traits::VariableSplit::toAsmAddress(const Cfg *Func) const { | 
| 274   assert(!Var->hasReg()); | 293   assert(!Var->hasReg()); | 
| 275   const ::Ice::TargetLowering *Target = Func->getTarget(); | 294   const ::Ice::TargetLowering *Target = Func->getTarget(); | 
| 276   int32_t Offset = Var->getStackOffset() + getOffset(); | 295   int32_t Offset = Var->getStackOffset() + getOffset(); | 
| 277   return X8664::Traits::Address(getEncodedGPR(Target->getFrameOrStackReg()), | 296   return X8664::Traits::Address(getEncodedGPR(Target->getFrameOrStackReg()), | 
| 278                                 Offset, AssemblerFixup::NoFixup); | 297                                 Offset, AssemblerFixup::NoFixup); | 
| 279 } | 298 } | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
| 309     Var->dump(Func); | 328     Var->dump(Func); | 
| 310   else | 329   else | 
| 311     Var->dump(Str); | 330     Var->dump(Str); | 
| 312   Str << ")"; | 331   Str << ")"; | 
| 313 } | 332 } | 
| 314 | 333 | 
| 315 } // namespace X8664 | 334 } // namespace X8664 | 
| 316 } // end of namespace Ice | 335 } // end of namespace Ice | 
| 317 | 336 | 
| 318 X86INSTS_DEFINE_STATIC_DATA(X8664, X8664::Traits) | 337 X86INSTS_DEFINE_STATIC_DATA(X8664, X8664::Traits) | 
| OLD | NEW | 
|---|