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 |