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) { | 109 if (Base) { |
110 Str << "("; | 110 Str << "("; |
111 Base->emit(Func); | 111 Base->emit(Func); |
112 if (Index) { | 112 if (Index) { |
113 Str << ","; | 113 Str << ","; |
(...skipping 27 matching lines...) Expand all Loading... |
141 Index->dump(Func); | 141 Index->dump(Func); |
142 else | 142 else |
143 Index->dump(Str); | 143 Index->dump(Str); |
144 Dumped = true; | 144 Dumped = true; |
145 } | 145 } |
146 // Pretty-print the Offset. | 146 // Pretty-print the Offset. |
147 bool OffsetIsZero = false; | 147 bool OffsetIsZero = false; |
148 bool OffsetIsNegative = false; | 148 bool OffsetIsNegative = false; |
149 if (!Offset) { | 149 if (!Offset) { |
150 OffsetIsZero = true; | 150 OffsetIsZero = true; |
151 } else if (const auto CI = llvm::dyn_cast<ConstantInteger32>(Offset)) { | 151 } else if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(Offset)) { |
152 OffsetIsZero = (CI->getValue() == 0); | 152 OffsetIsZero = (CI->getValue() == 0); |
153 OffsetIsNegative = (static_cast<int32_t>(CI->getValue()) < 0); | 153 OffsetIsNegative = (static_cast<int32_t>(CI->getValue()) < 0); |
154 } else { | 154 } else { |
155 assert(llvm::isa<ConstantRelocatable>(Offset)); | 155 assert(llvm::isa<ConstantRelocatable>(Offset)); |
156 } | 156 } |
157 if (Dumped) { | 157 if (Dumped) { |
158 if (!OffsetIsZero) { // Suppress if Offset is known to be 0 | 158 if (!OffsetIsZero) { // Suppress if Offset is known to be 0 |
159 if (!OffsetIsNegative) // Suppress if Offset is known to be negative | 159 if (!OffsetIsNegative) // Suppress if Offset is known to be negative |
160 Str << "+"; | 160 Str << "+"; |
161 Offset->dump(Func, Str); | 161 Offset->dump(Func, Str); |
162 } | 162 } |
163 } else { | 163 } else { |
164 // There is only the offset. | 164 // There is only the offset. |
165 Offset->dump(Func, Str); | 165 Offset->dump(Func, Str); |
166 } | 166 } |
167 Str << "]"; | 167 Str << "]"; |
168 } | 168 } |
169 | 169 |
170 MachineTraits<TargetX8664>::Address | 170 MachineTraits<TargetX8664>::Address |
171 MachineTraits<TargetX8664>::X86OperandMem::toAsmAddress( | 171 MachineTraits<TargetX8664>::X86OperandMem::toAsmAddress( |
172 MachineTraits<TargetX8664>::Assembler *Asm) const { | 172 MachineTraits<TargetX8664>::Assembler *Asm) const { |
173 int32_t Disp = 0; | 173 int32_t Disp = 0; |
174 AssemblerFixup *Fixup = nullptr; | 174 AssemblerFixup *Fixup = nullptr; |
175 // Determine the offset (is it relocatable?) | 175 // Determine the offset (is it relocatable?) |
176 if (getOffset()) { | 176 if (getOffset()) { |
177 if (const auto CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) { | 177 if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) { |
178 Disp = static_cast<int32_t>(CI->getValue()); | 178 Disp = static_cast<int32_t>(CI->getValue()); |
179 } else if (const auto CR = | 179 } else if (const auto CR = |
180 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { | 180 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { |
181 Disp = CR->getOffset() - 4; | 181 Disp = CR->getOffset() - 4; |
182 Fixup = Asm->createFixup(PcRelFixup, CR); | 182 Fixup = Asm->createFixup(PcRelFixup, CR); |
183 } else { | 183 } else { |
184 llvm_unreachable("Unexpected offset type"); | 184 llvm_unreachable("Unexpected offset type"); |
185 } | 185 } |
186 } | 186 } |
187 | 187 |
188 // Now convert to the various possible forms. | 188 // Now convert to the various possible forms. |
189 if (getBase() && getIndex()) { | 189 if (getBase() && getIndex()) { |
190 return X8664::Traits::Address( | 190 return X8664::Traits::Address(getEncodedGPR(getBase()->getRegNum()), |
191 RegX8664::getEncodedGPR(getBase()->getRegNum()), | 191 getEncodedGPR(getIndex()->getRegNum()), |
192 RegX8664::getEncodedGPR(getIndex()->getRegNum()), | 192 X8664::Traits::ScaleFactor(getShift()), Disp); |
193 X8664::Traits::ScaleFactor(getShift()), Disp); | |
194 } else if (getBase()) { | 193 } else if (getBase()) { |
195 return X8664::Traits::Address( | 194 return X8664::Traits::Address(getEncodedGPR(getBase()->getRegNum()), Disp); |
196 RegX8664::getEncodedGPR(getBase()->getRegNum()), Disp); | |
197 } else if (getIndex()) { | 195 } else if (getIndex()) { |
198 return X8664::Traits::Address( | 196 return X8664::Traits::Address(getEncodedGPR(getIndex()->getRegNum()), |
199 RegX8664::getEncodedGPR(getIndex()->getRegNum()), | 197 X8664::Traits::ScaleFactor(getShift()), Disp); |
200 X8664::Traits::ScaleFactor(getShift()), Disp); | |
201 } else if (Fixup) { | 198 } else if (Fixup) { |
202 return X8664::Traits::Address::Absolute(Disp, Fixup); | 199 return X8664::Traits::Address::Absolute(Disp, Fixup); |
203 } else { | 200 } else { |
204 return X8664::Traits::Address::Absolute(Disp); | 201 return X8664::Traits::Address::Absolute(Disp); |
205 } | 202 } |
206 } | 203 } |
207 | 204 |
208 MachineTraits<TargetX8664>::Address | 205 MachineTraits<TargetX8664>::Address |
209 MachineTraits<TargetX8664>::VariableSplit::toAsmAddress(const Cfg *Func) const { | 206 MachineTraits<TargetX8664>::VariableSplit::toAsmAddress(const Cfg *Func) const { |
210 assert(!Var->hasReg()); | 207 assert(!Var->hasReg()); |
211 const ::Ice::TargetLowering *Target = Func->getTarget(); | 208 const ::Ice::TargetLowering *Target = Func->getTarget(); |
212 int32_t Offset = | 209 int32_t Offset = |
213 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); | 210 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); |
214 return X8664::Traits::Address( | 211 return X8664::Traits::Address(getEncodedGPR(Target->getFrameOrStackReg()), |
215 RegX8664::getEncodedGPR(Target->getFrameOrStackReg()), Offset); | 212 Offset); |
216 } | 213 } |
217 | 214 |
218 void MachineTraits<TargetX8664>::VariableSplit::emit(const Cfg *Func) const { | 215 void MachineTraits<TargetX8664>::VariableSplit::emit(const Cfg *Func) const { |
219 if (!BuildDefs::dump()) | 216 if (!BuildDefs::dump()) |
220 return; | 217 return; |
221 Ostream &Str = Func->getContext()->getStrEmit(); | 218 Ostream &Str = Func->getContext()->getStrEmit(); |
222 assert(!Var->hasReg()); | 219 assert(!Var->hasReg()); |
223 // The following is copied/adapted from TargetX8664::emitVariable(). | 220 // The following is copied/adapted from TargetX8664::emitVariable(). |
224 const ::Ice::TargetLowering *Target = Func->getTarget(); | 221 const ::Ice::TargetLowering *Target = Func->getTarget(); |
225 const Type Ty = IceType_i32; | 222 constexpr Type Ty = IceType_i32; |
226 int32_t Offset = | 223 int32_t Offset = |
227 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); | 224 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); |
228 if (Offset) | 225 if (Offset) |
229 Str << Offset; | 226 Str << Offset; |
230 Str << "(%" << Target->getRegName(Target->getFrameOrStackReg(), Ty) << ")"; | 227 Str << "(%" << Target->getRegName(Target->getFrameOrStackReg(), Ty) << ")"; |
231 } | 228 } |
232 | 229 |
233 void MachineTraits<TargetX8664>::VariableSplit::dump(const Cfg *Func, | 230 void MachineTraits<TargetX8664>::VariableSplit::dump(const Cfg *Func, |
234 Ostream &Str) const { | 231 Ostream &Str) const { |
235 if (!BuildDefs::dump()) | 232 if (!BuildDefs::dump()) |
(...skipping 11 matching lines...) Expand all Loading... |
247 Var->dump(Func); | 244 Var->dump(Func); |
248 else | 245 else |
249 Var->dump(Str); | 246 Var->dump(Str); |
250 Str << ")"; | 247 Str << ")"; |
251 } | 248 } |
252 | 249 |
253 } // namespace X86Internal | 250 } // namespace X86Internal |
254 } // end of namespace Ice | 251 } // end of namespace Ice |
255 | 252 |
256 X86INSTS_DEFINE_STATIC_DATA(TargetX8664) | 253 X86INSTS_DEFINE_STATIC_DATA(TargetX8664) |
OLD | NEW |