| 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 14 matching lines...) Expand all Loading... |
| 25 #include "IceRegistersX8664.h" | 25 #include "IceRegistersX8664.h" |
| 26 #include "IceTargetLoweringX8664.h" | 26 #include "IceTargetLoweringX8664.h" |
| 27 #include "IceOperand.h" | 27 #include "IceOperand.h" |
| 28 | 28 |
| 29 namespace Ice { | 29 namespace Ice { |
| 30 | 30 |
| 31 namespace X86Internal { | 31 namespace X86Internal { |
| 32 | 32 |
| 33 const MachineTraits<TargetX8664>::InstBrAttributesType | 33 const MachineTraits<TargetX8664>::InstBrAttributesType |
| 34 MachineTraits<TargetX8664>::InstBrAttributes[] = { | 34 MachineTraits<TargetX8664>::InstBrAttributes[] = { |
| 35 #define X(tag, encode, opp, dump, emit) \ | 35 #define X(val, encode, opp, dump, emit) \ |
| 36 { X8664::Traits::Cond::opp, dump, emit } \ | 36 { X8664::Traits::Cond::opp, dump, emit } \ |
| 37 , | 37 , |
| 38 ICEINSTX8664BR_TABLE | 38 ICEINSTX8664BR_TABLE |
| 39 #undef X | 39 #undef X |
| 40 }; | 40 }; |
| 41 | 41 |
| 42 const MachineTraits<TargetX8664>::InstCmppsAttributesType | 42 const MachineTraits<TargetX8664>::InstCmppsAttributesType |
| 43 MachineTraits<TargetX8664>::InstCmppsAttributes[] = { | 43 MachineTraits<TargetX8664>::InstCmppsAttributes[] = { |
| 44 #define X(tag, emit) \ | 44 #define X(val, emit) \ |
| 45 { emit } \ | 45 { emit } \ |
| 46 , | 46 , |
| 47 ICEINSTX8664CMPPS_TABLE | 47 ICEINSTX8664CMPPS_TABLE |
| 48 #undef X | 48 #undef X |
| 49 }; | 49 }; |
| 50 | 50 |
| 51 const MachineTraits<TargetX8664>::TypeAttributesType | 51 const MachineTraits<TargetX8664>::TypeAttributesType |
| 52 MachineTraits<TargetX8664>::TypeAttributes[] = { | 52 MachineTraits<TargetX8664>::TypeAttributes[] = { |
| 53 #define X(tag, elementty, cvt, sdss, pack, width, fld) \ | 53 #define X(tag, elementty, cvt, sdss, pack, width, fld) \ |
| 54 { cvt, sdss, pack, width, fld } \ | 54 { cvt, sdss, pack, width, fld } \ |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 } | 89 } |
| 90 | 90 |
| 91 void MachineTraits<TargetX8664>::X86OperandMem::emit(const Cfg *Func) const { | 91 void MachineTraits<TargetX8664>::X86OperandMem::emit(const Cfg *Func) const { |
| 92 if (!BuildDefs::dump()) | 92 if (!BuildDefs::dump()) |
| 93 return; | 93 return; |
| 94 Ostream &Str = Func->getContext()->getStrEmit(); | 94 Ostream &Str = Func->getContext()->getStrEmit(); |
| 95 // Emit as Offset(Base,Index,1<<Shift). Offset is emitted without the leading | 95 // Emit as Offset(Base,Index,1<<Shift). Offset is emitted without the leading |
| 96 // '$'. Omit the (Base,Index,1<<Shift) part if Base==nullptr. | 96 // '$'. Omit the (Base,Index,1<<Shift) part if Base==nullptr. |
| 97 if (!Offset) { | 97 if (!Offset) { |
| 98 // No offset, emit nothing. | 98 // No offset, emit nothing. |
| 99 } else if (const auto CI = llvm::dyn_cast<ConstantInteger32>(Offset)) { | 99 } else if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(Offset)) { |
| 100 if (Base == nullptr || CI->getValue()) | 100 if (Base == nullptr || CI->getValue()) |
| 101 // Emit a non-zero offset without a leading '$'. | 101 // Emit a non-zero offset without a leading '$'. |
| 102 Str << CI->getValue(); | 102 Str << CI->getValue(); |
| 103 } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Offset)) { | 103 } else if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(Offset)) { |
| 104 CR->emitWithoutPrefix(Func->getTarget()); | 104 CR->emitWithoutPrefix(Func->getTarget()); |
| 105 } else { | 105 } else { |
| 106 llvm_unreachable("Invalid offset type for x86 mem operand"); | 106 llvm_unreachable("Invalid offset type for x86 mem operand"); |
| 107 } | 107 } |
| 108 | 108 |
| 109 if (Base || Index) { | 109 if (Base || Index) { |
| 110 Str << "("; | 110 Str << "("; |
| 111 if (Base) | 111 if (Base) |
| 112 Base->emit(Func); | 112 Base->emit(Func); |
| 113 if (Index) { | 113 if (Index) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 142 Index->dump(Func); | 142 Index->dump(Func); |
| 143 else | 143 else |
| 144 Index->dump(Str); | 144 Index->dump(Str); |
| 145 Dumped = true; | 145 Dumped = true; |
| 146 } | 146 } |
| 147 // Pretty-print the Offset. | 147 // Pretty-print the Offset. |
| 148 bool OffsetIsZero = false; | 148 bool OffsetIsZero = false; |
| 149 bool OffsetIsNegative = false; | 149 bool OffsetIsNegative = false; |
| 150 if (!Offset) { | 150 if (!Offset) { |
| 151 OffsetIsZero = true; | 151 OffsetIsZero = true; |
| 152 } else if (const auto CI = llvm::dyn_cast<ConstantInteger32>(Offset)) { | 152 } else if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(Offset)) { |
| 153 OffsetIsZero = (CI->getValue() == 0); | 153 OffsetIsZero = (CI->getValue() == 0); |
| 154 OffsetIsNegative = (static_cast<int32_t>(CI->getValue()) < 0); | 154 OffsetIsNegative = (static_cast<int32_t>(CI->getValue()) < 0); |
| 155 } else { | 155 } else { |
| 156 assert(llvm::isa<ConstantRelocatable>(Offset)); | 156 assert(llvm::isa<ConstantRelocatable>(Offset)); |
| 157 } | 157 } |
| 158 if (Dumped) { | 158 if (Dumped) { |
| 159 if (!OffsetIsZero) { // Suppress if Offset is known to be 0 | 159 if (!OffsetIsZero) { // Suppress if Offset is known to be 0 |
| 160 if (!OffsetIsNegative) // Suppress if Offset is known to be negative | 160 if (!OffsetIsNegative) // Suppress if Offset is known to be negative |
| 161 Str << "+"; | 161 Str << "+"; |
| 162 Offset->dump(Func, Str); | 162 Offset->dump(Func, Str); |
| 163 } | 163 } |
| 164 } else { | 164 } else { |
| 165 // There is only the offset. | 165 // There is only the offset. |
| 166 Offset->dump(Func, Str); | 166 Offset->dump(Func, Str); |
| 167 } | 167 } |
| 168 Str << "]"; | 168 Str << "]"; |
| 169 } | 169 } |
| 170 | 170 |
| 171 MachineTraits<TargetX8664>::Address | 171 MachineTraits<TargetX8664>::Address |
| 172 MachineTraits<TargetX8664>::X86OperandMem::toAsmAddress( | 172 MachineTraits<TargetX8664>::X86OperandMem::toAsmAddress( |
| 173 MachineTraits<TargetX8664>::Assembler *Asm) const { | 173 MachineTraits<TargetX8664>::Assembler *Asm) const { |
| 174 int32_t Disp = 0; | 174 int32_t Disp = 0; |
| 175 AssemblerFixup *Fixup = nullptr; | 175 AssemblerFixup *Fixup = nullptr; |
| 176 // Determine the offset (is it relocatable?) | 176 // Determine the offset (is it relocatable?) |
| 177 if (getOffset()) { | 177 if (getOffset()) { |
| 178 if (const auto CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) { | 178 if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) { |
| 179 Disp = static_cast<int32_t>(CI->getValue()); | 179 Disp = static_cast<int32_t>(CI->getValue()); |
| 180 } else if (const auto CR = | 180 } else if (const auto CR = |
| 181 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { | 181 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { |
| 182 Disp = CR->getOffset() - 4; | 182 Disp = CR->getOffset() - 4; |
| 183 Fixup = Asm->createFixup(PcRelFixup, CR); | 183 Fixup = Asm->createFixup(PcRelFixup, CR); |
| 184 } else { | 184 } else { |
| 185 llvm_unreachable("Unexpected offset type"); | 185 llvm_unreachable("Unexpected offset type"); |
| 186 } | 186 } |
| 187 } | 187 } |
| 188 | 188 |
| 189 // Now convert to the various possible forms. | 189 // Now convert to the various possible forms. |
| 190 if (getBase() && getIndex()) { | 190 if (getBase() && getIndex()) { |
| 191 return X8664::Traits::Address( | 191 return X8664::Traits::Address(getEncodedGPR(getBase()->getRegNum()), |
| 192 RegX8664::getEncodedGPR(getBase()->getRegNum()), | 192 getEncodedGPR(getIndex()->getRegNum()), |
| 193 RegX8664::getEncodedGPR(getIndex()->getRegNum()), | 193 X8664::Traits::ScaleFactor(getShift()), Disp, |
| 194 X8664::Traits::ScaleFactor(getShift()), Disp, Fixup); | 194 Fixup); |
| 195 } else if (getBase()) { | 195 } else if (getBase()) { |
| 196 return X8664::Traits::Address( | 196 return X8664::Traits::Address(getEncodedGPR(getBase()->getRegNum()), Disp, |
| 197 RegX8664::getEncodedGPR(getBase()->getRegNum()), Disp, Fixup); | 197 Fixup); |
| 198 } else if (getIndex()) { | 198 } else if (getIndex()) { |
| 199 return X8664::Traits::Address( | 199 return X8664::Traits::Address(getEncodedGPR(getIndex()->getRegNum()), |
| 200 RegX8664::getEncodedGPR(getIndex()->getRegNum()), | 200 X8664::Traits::ScaleFactor(getShift()), Disp, |
| 201 X8664::Traits::ScaleFactor(getShift()), Disp, Fixup); | 201 Fixup); |
| 202 } else { | 202 } else { |
| 203 return X8664::Traits::Address(Disp, Fixup); | 203 return X8664::Traits::Address(Disp, Fixup); |
| 204 } | 204 } |
| 205 } | 205 } |
| 206 | 206 |
| 207 MachineTraits<TargetX8664>::Address | 207 MachineTraits<TargetX8664>::Address |
| 208 MachineTraits<TargetX8664>::VariableSplit::toAsmAddress(const Cfg *Func) const { | 208 MachineTraits<TargetX8664>::VariableSplit::toAsmAddress(const Cfg *Func) const { |
| 209 assert(!Var->hasReg()); | 209 assert(!Var->hasReg()); |
| 210 const ::Ice::TargetLowering *Target = Func->getTarget(); | 210 const ::Ice::TargetLowering *Target = Func->getTarget(); |
| 211 int32_t Offset = | 211 int32_t Offset = |
| 212 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); | 212 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); |
| 213 return X8664::Traits::Address( | 213 return X8664::Traits::Address(getEncodedGPR(Target->getFrameOrStackReg()), |
| 214 RegX8664::getEncodedGPR(Target->getFrameOrStackReg()), Offset, | 214 Offset, AssemblerFixup::NoFixup); |
| 215 AssemblerFixup::NoFixup); | |
| 216 } | 215 } |
| 217 | 216 |
| 218 void MachineTraits<TargetX8664>::VariableSplit::emit(const Cfg *Func) const { | 217 void MachineTraits<TargetX8664>::VariableSplit::emit(const Cfg *Func) const { |
| 219 if (!BuildDefs::dump()) | 218 if (!BuildDefs::dump()) |
| 220 return; | 219 return; |
| 221 Ostream &Str = Func->getContext()->getStrEmit(); | 220 Ostream &Str = Func->getContext()->getStrEmit(); |
| 222 assert(!Var->hasReg()); | 221 assert(!Var->hasReg()); |
| 223 // The following is copied/adapted from TargetX8664::emitVariable(). | 222 // The following is copied/adapted from TargetX8664::emitVariable(). |
| 224 const ::Ice::TargetLowering *Target = Func->getTarget(); | 223 const ::Ice::TargetLowering *Target = Func->getTarget(); |
| 225 const Type Ty = IceType_i32; | 224 constexpr Type Ty = IceType_i32; |
| 226 int32_t Offset = | 225 int32_t Offset = |
| 227 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); | 226 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); |
| 228 if (Offset) | 227 if (Offset) |
| 229 Str << Offset; | 228 Str << Offset; |
| 230 Str << "(%" << Target->getRegName(Target->getFrameOrStackReg(), Ty) << ")"; | 229 Str << "(%" << Target->getRegName(Target->getFrameOrStackReg(), Ty) << ")"; |
| 231 } | 230 } |
| 232 | 231 |
| 233 void MachineTraits<TargetX8664>::VariableSplit::dump(const Cfg *Func, | 232 void MachineTraits<TargetX8664>::VariableSplit::dump(const Cfg *Func, |
| 234 Ostream &Str) const { | 233 Ostream &Str) const { |
| 235 if (!BuildDefs::dump()) | 234 if (!BuildDefs::dump()) |
| (...skipping 11 matching lines...) Expand all Loading... |
| 247 Var->dump(Func); | 246 Var->dump(Func); |
| 248 else | 247 else |
| 249 Var->dump(Str); | 248 Var->dump(Str); |
| 250 Str << ")"; | 249 Str << ")"; |
| 251 } | 250 } |
| 252 | 251 |
| 253 } // namespace X86Internal | 252 } // namespace X86Internal |
| 254 } // end of namespace Ice | 253 } // end of namespace Ice |
| 255 | 254 |
| 256 X86INSTS_DEFINE_STATIC_DATA(TargetX8664) | 255 X86INSTS_DEFINE_STATIC_DATA(TargetX8664) |
| OLD | NEW |