OLD | NEW |
1 //===- subzero/src/IceInstX8632.cpp - X86-32 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 |
11 /// This file defines X8632 specific data related to X8632 Instructions and | 11 /// This file defines X8664 specific data related to X8664 Instructions and |
12 /// Instruction traits. These are declared in the IceTargetLoweringX8632Traits.h | 12 /// Instruction traits. These are declared in the IceTargetLoweringX8664Traits.h |
13 /// header file. | 13 /// header file. |
14 /// | 14 /// |
15 /// This file also defines X8632 operand specific methods (dump and emit.) | 15 /// This file also defines X8664 operand specific methods (dump and emit.) |
16 /// | 16 /// |
17 //===----------------------------------------------------------------------===// | 17 //===----------------------------------------------------------------------===// |
18 #include "IceInstX8632.h" | 18 #include "IceInstX8664.h" |
19 | 19 |
20 #include "IceAssemblerX8632.h" | 20 #include "IceAssemblerX8664.h" |
21 #include "IceCfg.h" | 21 #include "IceCfg.h" |
22 #include "IceCfgNode.h" | 22 #include "IceCfgNode.h" |
23 #include "IceConditionCodesX8632.h" | 23 #include "IceConditionCodesX8664.h" |
24 #include "IceInst.h" | 24 #include "IceInst.h" |
25 #include "IceRegistersX8632.h" | 25 #include "IceRegistersX8664.h" |
26 #include "IceTargetLoweringX8632.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<TargetX8632>::InstBrAttributesType | 33 const MachineTraits<TargetX8664>::InstBrAttributesType |
34 MachineTraits<TargetX8632>::InstBrAttributes[] = { | 34 MachineTraits<TargetX8664>::InstBrAttributes[] = { |
35 #define X(tag, encode, opp, dump, emit) \ | 35 #define X(tag, encode, opp, dump, emit) \ |
36 { X8632::Traits::Cond::opp, dump, emit } \ | 36 { X8664::Traits::Cond::opp, dump, emit } \ |
37 , | 37 , |
38 ICEINSTX8632BR_TABLE | 38 ICEINSTX8664BR_TABLE |
39 #undef X | 39 #undef X |
40 }; | 40 }; |
41 | 41 |
42 const MachineTraits<TargetX8632>::InstCmppsAttributesType | 42 const MachineTraits<TargetX8664>::InstCmppsAttributesType |
43 MachineTraits<TargetX8632>::InstCmppsAttributes[] = { | 43 MachineTraits<TargetX8664>::InstCmppsAttributes[] = { |
44 #define X(tag, emit) \ | 44 #define X(tag, emit) \ |
45 { emit } \ | 45 { emit } \ |
46 , | 46 , |
47 ICEINSTX8632CMPPS_TABLE | 47 ICEINSTX8664CMPPS_TABLE |
48 #undef X | 48 #undef X |
49 }; | 49 }; |
50 | 50 |
51 const MachineTraits<TargetX8632>::TypeAttributesType | 51 const MachineTraits<TargetX8664>::TypeAttributesType |
52 MachineTraits<TargetX8632>::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 } \ |
55 , | 55 , |
56 ICETYPEX8632_TABLE | 56 ICETYPEX8664_TABLE |
57 #undef X | 57 #undef X |
58 }; | 58 }; |
59 | 59 |
60 const char *MachineTraits<TargetX8632>::InstSegmentRegNames[] = { | 60 void MachineTraits<TargetX8664>::X86Operand::dump(const Cfg *, |
61 #define X(val, name, prefix) name, | |
62 SEG_REGX8632_TABLE | |
63 #undef X | |
64 }; | |
65 | |
66 uint8_t MachineTraits<TargetX8632>::InstSegmentPrefixes[] = { | |
67 #define X(val, name, prefix) prefix, | |
68 SEG_REGX8632_TABLE | |
69 #undef X | |
70 }; | |
71 | |
72 void MachineTraits<TargetX8632>::X86Operand::dump(const Cfg *, | |
73 Ostream &Str) const { | 61 Ostream &Str) const { |
74 if (BuildDefs::dump()) | 62 if (BuildDefs::dump()) |
75 Str << "<OperandX8632>"; | 63 Str << "<OperandX8664>"; |
76 } | 64 } |
77 | 65 |
78 MachineTraits<TargetX8632>::X86OperandMem::X86OperandMem( | 66 MachineTraits<TargetX8664>::X86OperandMem::X86OperandMem(Cfg *Func, Type Ty, |
79 Cfg *Func, Type Ty, Variable *Base, Constant *Offset, Variable *Index, | 67 Variable *Base, |
80 uint16_t Shift, SegmentRegisters SegmentReg) | 68 Constant *Offset, |
| 69 Variable *Index, |
| 70 uint16_t Shift) |
81 : X86Operand(kMem, Ty), Base(Base), Offset(Offset), Index(Index), | 71 : X86Operand(kMem, Ty), Base(Base), Offset(Offset), Index(Index), |
82 Shift(Shift), SegmentReg(SegmentReg), Randomized(false) { | 72 Shift(Shift), Randomized(false) { |
83 assert(Shift <= 3); | 73 assert(Shift <= 3); |
84 Vars = nullptr; | 74 Vars = nullptr; |
85 NumVars = 0; | 75 NumVars = 0; |
86 if (Base) | 76 if (Base) |
87 ++NumVars; | 77 ++NumVars; |
88 if (Index) | 78 if (Index) |
89 ++NumVars; | 79 ++NumVars; |
90 if (NumVars) { | 80 if (NumVars) { |
91 Vars = Func->allocateArrayOf<Variable *>(NumVars); | 81 Vars = Func->allocateArrayOf<Variable *>(NumVars); |
92 SizeT I = 0; | 82 SizeT I = 0; |
93 if (Base) | 83 if (Base) |
94 Vars[I++] = Base; | 84 Vars[I++] = Base; |
95 if (Index) | 85 if (Index) |
96 Vars[I++] = Index; | 86 Vars[I++] = Index; |
97 assert(I == NumVars); | 87 assert(I == NumVars); |
98 } | 88 } |
99 } | 89 } |
100 | 90 |
101 void MachineTraits<TargetX8632>::X86OperandMem::emit(const Cfg *Func) const { | 91 void MachineTraits<TargetX8664>::X86OperandMem::emit(const Cfg *Func) const { |
102 if (!BuildDefs::dump()) | 92 if (!BuildDefs::dump()) |
103 return; | 93 return; |
104 Ostream &Str = Func->getContext()->getStrEmit(); | 94 Ostream &Str = Func->getContext()->getStrEmit(); |
105 if (SegmentReg != DefaultSegment) { | |
106 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); | |
107 Str << "%" << X8632::Traits::InstSegmentRegNames[SegmentReg] << ":"; | |
108 } | |
109 // Emit as Offset(Base,Index,1<<Shift). | 95 // Emit as Offset(Base,Index,1<<Shift). |
110 // Offset is emitted without the leading '$'. | 96 // Offset is emitted without the leading '$'. |
111 // Omit the (Base,Index,1<<Shift) part if Base==nullptr. | 97 // Omit the (Base,Index,1<<Shift) part if Base==nullptr. |
112 if (!Offset) { | 98 if (!Offset) { |
113 // No offset, emit nothing. | 99 // No offset, emit nothing. |
114 } else if (const auto CI = llvm::dyn_cast<ConstantInteger32>(Offset)) { | 100 } else if (const auto CI = llvm::dyn_cast<ConstantInteger32>(Offset)) { |
115 if (Base == nullptr || CI->getValue()) | 101 if (Base == nullptr || CI->getValue()) |
116 // Emit a non-zero offset without a leading '$'. | 102 // Emit a non-zero offset without a leading '$'. |
117 Str << CI->getValue(); | 103 Str << CI->getValue(); |
118 } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Offset)) { | 104 } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Offset)) { |
119 CR->emitWithoutPrefix(Func->getTarget()); | 105 CR->emitWithoutPrefix(Func->getTarget()); |
120 } else { | 106 } else { |
121 llvm_unreachable("Invalid offset type for x86 mem operand"); | 107 llvm_unreachable("Invalid offset type for x86 mem operand"); |
122 } | 108 } |
123 | 109 |
124 if (Base) { | 110 if (Base) { |
125 Str << "("; | 111 Str << "("; |
126 Base->emit(Func); | 112 Base->emit(Func); |
127 if (Index) { | 113 if (Index) { |
128 Str << ","; | 114 Str << ","; |
129 Index->emit(Func); | 115 Index->emit(Func); |
130 if (Shift) | 116 if (Shift) |
131 Str << "," << (1u << Shift); | 117 Str << "," << (1u << Shift); |
132 } | 118 } |
133 Str << ")"; | 119 Str << ")"; |
134 } | 120 } |
135 } | 121 } |
136 | 122 |
137 void MachineTraits<TargetX8632>::X86OperandMem::dump(const Cfg *Func, | 123 void MachineTraits<TargetX8664>::X86OperandMem::dump(const Cfg *Func, |
138 Ostream &Str) const { | 124 Ostream &Str) const { |
139 if (!BuildDefs::dump()) | 125 if (!BuildDefs::dump()) |
140 return; | 126 return; |
141 if (SegmentReg != DefaultSegment) { | |
142 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); | |
143 Str << X8632::Traits::InstSegmentRegNames[SegmentReg] << ":"; | |
144 } | |
145 bool Dumped = false; | 127 bool Dumped = false; |
146 Str << "["; | 128 Str << "["; |
147 if (Base) { | 129 if (Base) { |
148 if (Func) | 130 if (Func) |
149 Base->dump(Func); | 131 Base->dump(Func); |
150 else | 132 else |
151 Base->dump(Str); | 133 Base->dump(Str); |
152 Dumped = true; | 134 Dumped = true; |
153 } | 135 } |
154 if (Index) { | 136 if (Index) { |
(...skipping 24 matching lines...) Expand all Loading... |
179 Str << "+"; | 161 Str << "+"; |
180 Offset->dump(Func, Str); | 162 Offset->dump(Func, Str); |
181 } | 163 } |
182 } else { | 164 } else { |
183 // There is only the offset. | 165 // There is only the offset. |
184 Offset->dump(Func, Str); | 166 Offset->dump(Func, Str); |
185 } | 167 } |
186 Str << "]"; | 168 Str << "]"; |
187 } | 169 } |
188 | 170 |
189 void MachineTraits<TargetX8632>::X86OperandMem::emitSegmentOverride( | 171 MachineTraits<TargetX8664>::Address |
190 MachineTraits<TargetX8632>::Assembler *Asm) const { | 172 MachineTraits<TargetX8664>::X86OperandMem::toAsmAddress( |
191 if (SegmentReg != DefaultSegment) { | 173 MachineTraits<TargetX8664>::Assembler *Asm) const { |
192 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); | |
193 Asm->emitSegmentOverride(X8632::Traits::InstSegmentPrefixes[SegmentReg]); | |
194 } | |
195 } | |
196 | |
197 MachineTraits<TargetX8632>::Address | |
198 MachineTraits<TargetX8632>::X86OperandMem::toAsmAddress( | |
199 MachineTraits<TargetX8632>::Assembler *Asm) const { | |
200 int32_t Disp = 0; | 174 int32_t Disp = 0; |
201 AssemblerFixup *Fixup = nullptr; | 175 AssemblerFixup *Fixup = nullptr; |
202 // Determine the offset (is it relocatable?) | 176 // Determine the offset (is it relocatable?) |
203 if (getOffset()) { | 177 if (getOffset()) { |
204 if (const auto CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) { | 178 if (const auto CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) { |
205 Disp = static_cast<int32_t>(CI->getValue()); | 179 Disp = static_cast<int32_t>(CI->getValue()); |
206 } else if (const auto CR = | 180 } else if (const auto CR = |
207 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { | 181 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { |
208 Disp = CR->getOffset(); | 182 Disp = CR->getOffset(); |
209 Fixup = Asm->createFixup(llvm::ELF::R_386_32, CR); | 183 Fixup = Asm->createFixup(llvm::ELF::R_386_32, CR); |
210 } else { | 184 } else { |
211 llvm_unreachable("Unexpected offset type"); | 185 llvm_unreachable("Unexpected offset type"); |
212 } | 186 } |
213 } | 187 } |
214 | 188 |
215 // Now convert to the various possible forms. | 189 // Now convert to the various possible forms. |
216 if (getBase() && getIndex()) { | 190 if (getBase() && getIndex()) { |
217 return X8632::Traits::Address( | 191 return X8664::Traits::Address( |
218 RegX8632::getEncodedGPR(getBase()->getRegNum()), | 192 RegX8664::getEncodedGPR(getBase()->getRegNum()), |
219 RegX8632::getEncodedGPR(getIndex()->getRegNum()), | 193 RegX8664::getEncodedGPR(getIndex()->getRegNum()), |
220 X8632::Traits::ScaleFactor(getShift()), Disp); | 194 X8664::Traits::ScaleFactor(getShift()), Disp); |
221 } else if (getBase()) { | 195 } else if (getBase()) { |
222 return X8632::Traits::Address( | 196 return X8664::Traits::Address( |
223 RegX8632::getEncodedGPR(getBase()->getRegNum()), Disp); | 197 RegX8664::getEncodedGPR(getBase()->getRegNum()), Disp); |
224 } else if (getIndex()) { | 198 } else if (getIndex()) { |
225 return X8632::Traits::Address( | 199 return X8664::Traits::Address( |
226 RegX8632::getEncodedGPR(getIndex()->getRegNum()), | 200 RegX8664::getEncodedGPR(getIndex()->getRegNum()), |
227 X8632::Traits::ScaleFactor(getShift()), Disp); | 201 X8664::Traits::ScaleFactor(getShift()), Disp); |
228 } else if (Fixup) { | 202 } else if (Fixup) { |
229 return X8632::Traits::Address::Absolute(Disp, Fixup); | 203 return X8664::Traits::Address::Absolute(Disp, Fixup); |
230 } else { | 204 } else { |
231 return X8632::Traits::Address::Absolute(Disp); | 205 return X8664::Traits::Address::Absolute(Disp); |
232 } | 206 } |
233 } | 207 } |
234 | 208 |
235 MachineTraits<TargetX8632>::Address | 209 MachineTraits<TargetX8664>::Address |
236 MachineTraits<TargetX8632>::VariableSplit::toAsmAddress(const Cfg *Func) const { | 210 MachineTraits<TargetX8664>::VariableSplit::toAsmAddress(const Cfg *Func) const { |
237 assert(!Var->hasReg()); | 211 assert(!Var->hasReg()); |
238 const ::Ice::TargetLowering *Target = Func->getTarget(); | 212 const ::Ice::TargetLowering *Target = Func->getTarget(); |
239 int32_t Offset = | 213 int32_t Offset = |
240 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); | 214 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); |
241 return X8632::Traits::Address( | 215 return X8664::Traits::Address( |
242 RegX8632::getEncodedGPR(Target->getFrameOrStackReg()), Offset); | 216 RegX8664::getEncodedGPR(Target->getFrameOrStackReg()), Offset); |
243 } | 217 } |
244 | 218 |
245 void MachineTraits<TargetX8632>::VariableSplit::emit(const Cfg *Func) const { | 219 void MachineTraits<TargetX8664>::VariableSplit::emit(const Cfg *Func) const { |
246 if (!BuildDefs::dump()) | 220 if (!BuildDefs::dump()) |
247 return; | 221 return; |
248 Ostream &Str = Func->getContext()->getStrEmit(); | 222 Ostream &Str = Func->getContext()->getStrEmit(); |
249 assert(!Var->hasReg()); | 223 assert(!Var->hasReg()); |
250 // The following is copied/adapted from TargetX8632::emitVariable(). | 224 // The following is copied/adapted from TargetX8664::emitVariable(). |
251 const ::Ice::TargetLowering *Target = Func->getTarget(); | 225 const ::Ice::TargetLowering *Target = Func->getTarget(); |
252 const Type Ty = IceType_i32; | 226 const Type Ty = IceType_i32; |
253 int32_t Offset = | 227 int32_t Offset = |
254 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); | 228 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); |
255 if (Offset) | 229 if (Offset) |
256 Str << Offset; | 230 Str << Offset; |
257 Str << "(%" << Target->getRegName(Target->getFrameOrStackReg(), Ty) << ")"; | 231 Str << "(%" << Target->getRegName(Target->getFrameOrStackReg(), Ty) << ")"; |
258 } | 232 } |
259 | 233 |
260 void MachineTraits<TargetX8632>::VariableSplit::dump(const Cfg *Func, | 234 void MachineTraits<TargetX8664>::VariableSplit::dump(const Cfg *Func, |
261 Ostream &Str) const { | 235 Ostream &Str) const { |
262 if (!BuildDefs::dump()) | 236 if (!BuildDefs::dump()) |
263 return; | 237 return; |
264 switch (Part) { | 238 switch (Part) { |
265 case Low: | 239 case Low: |
266 Str << "low"; | 240 Str << "low"; |
267 break; | 241 break; |
268 case High: | 242 case High: |
269 Str << "high"; | 243 Str << "high"; |
270 break; | 244 break; |
271 } | 245 } |
272 Str << "("; | 246 Str << "("; |
273 if (Func) | 247 if (Func) |
274 Var->dump(Func); | 248 Var->dump(Func); |
275 else | 249 else |
276 Var->dump(Str); | 250 Var->dump(Str); |
277 Str << ")"; | 251 Str << ")"; |
278 } | 252 } |
279 | 253 |
280 } // namespace X86Internal | 254 } // namespace X86Internal |
281 } // end of namespace Ice | 255 } // end of namespace Ice |
282 | 256 |
283 X86INSTS_DEFINE_STATIC_DATA(TargetX8632); | 257 X86INSTS_DEFINE_STATIC_DATA(TargetX8664); |
OLD | NEW |