OLD | NEW |
1 //===- subzero/src/IceInstARM32.cpp - ARM32 instruction implementation ----===// | 1 //===- subzero/src/IceInstARM32.cpp - ARM32 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 // This file implements the InstARM32 and OperandARM32 classes, | 10 // This file implements the InstARM32 and OperandARM32 classes, |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 return TypeARM32Attributes[Ty].WidthString; | 53 return TypeARM32Attributes[Ty].WidthString; |
54 } | 54 } |
55 | 55 |
56 void emitTwoAddr(const char *Opcode, const Inst *Inst, const Cfg *Func) { | 56 void emitTwoAddr(const char *Opcode, const Inst *Inst, const Cfg *Func) { |
57 if (!ALLOW_DUMP) | 57 if (!ALLOW_DUMP) |
58 return; | 58 return; |
59 Ostream &Str = Func->getContext()->getStrEmit(); | 59 Ostream &Str = Func->getContext()->getStrEmit(); |
60 assert(Inst->getSrcSize() == 2); | 60 assert(Inst->getSrcSize() == 2); |
61 Variable *Dest = Inst->getDest(); | 61 Variable *Dest = Inst->getDest(); |
62 assert(Dest == Inst->getSrc(0)); | 62 assert(Dest == Inst->getSrc(0)); |
63 Operand *Src1 = Inst->getSrc(1); | |
64 Str << "\t" << Opcode << "\t"; | 63 Str << "\t" << Opcode << "\t"; |
65 Dest->emit(Func); | 64 Dest->emit(Func); |
66 Str << ", "; | 65 Str << ", "; |
67 Src1->emit(Func); | 66 Inst->getSrc(1)->emit(Func); |
| 67 } |
| 68 |
| 69 void emitThreeAddr(const char *Opcode, const Inst *Inst, const Cfg *Func, |
| 70 bool SetFlags) { |
| 71 if (!ALLOW_DUMP) |
| 72 return; |
| 73 Ostream &Str = Func->getContext()->getStrEmit(); |
| 74 assert(Inst->getSrcSize() == 2); |
| 75 Str << "\t" << Opcode << (SetFlags ? "s" : "") << "\t"; |
| 76 Inst->getDest()->emit(Func); |
| 77 Str << ", "; |
| 78 Inst->getSrc(0)->emit(Func); |
| 79 Str << ", "; |
| 80 Inst->getSrc(1)->emit(Func); |
68 } | 81 } |
69 | 82 |
70 OperandARM32Mem::OperandARM32Mem(Cfg * /* Func */, Type Ty, Variable *Base, | 83 OperandARM32Mem::OperandARM32Mem(Cfg * /* Func */, Type Ty, Variable *Base, |
71 ConstantInteger32 *ImmOffset, AddrMode Mode) | 84 ConstantInteger32 *ImmOffset, AddrMode Mode) |
72 : OperandARM32(kMem, Ty), Base(Base), ImmOffset(ImmOffset), Index(nullptr), | 85 : OperandARM32(kMem, Ty), Base(Base), ImmOffset(ImmOffset), Index(nullptr), |
73 ShiftOp(kNoShift), ShiftAmt(0), Mode(Mode) { | 86 ShiftOp(kNoShift), ShiftAmt(0), Mode(Mode) { |
74 // The Neg modes are only needed for Reg +/- Reg. | 87 // The Neg modes are only needed for Reg +/- Reg. |
75 assert(!isNegAddrMode()); | 88 assert(!isNegAddrMode()); |
76 NumVars = 1; | 89 NumVars = 1; |
77 Vars = &this->Base; | 90 Vars = &this->Base; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 Vars[0] = Reg; | 152 Vars[0] = Reg; |
140 if (ShiftVar) | 153 if (ShiftVar) |
141 Vars[1] = ShiftVar; | 154 Vars[1] = ShiftVar; |
142 } | 155 } |
143 | 156 |
144 InstARM32Ldr::InstARM32Ldr(Cfg *Func, Variable *Dest, OperandARM32Mem *Mem) | 157 InstARM32Ldr::InstARM32Ldr(Cfg *Func, Variable *Dest, OperandARM32Mem *Mem) |
145 : InstARM32(Func, InstARM32::Ldr, 1, Dest) { | 158 : InstARM32(Func, InstARM32::Ldr, 1, Dest) { |
146 addSource(Mem); | 159 addSource(Mem); |
147 } | 160 } |
148 | 161 |
| 162 InstARM32Mla::InstARM32Mla(Cfg *Func, Variable *Dest, Variable *Src0, |
| 163 Variable *Src1, Variable *Acc) |
| 164 : InstARM32(Func, InstARM32::Mla, 3, Dest) { |
| 165 addSource(Src0); |
| 166 addSource(Src1); |
| 167 addSource(Acc); |
| 168 } |
| 169 |
149 InstARM32Ret::InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source) | 170 InstARM32Ret::InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source) |
150 : InstARM32(Func, InstARM32::Ret, Source ? 2 : 1, nullptr) { | 171 : InstARM32(Func, InstARM32::Ret, Source ? 2 : 1, nullptr) { |
151 addSource(LR); | 172 addSource(LR); |
152 if (Source) | 173 if (Source) |
153 addSource(Source); | 174 addSource(Source); |
154 } | 175 } |
155 | 176 |
| 177 InstARM32Umull::InstARM32Umull(Cfg *Func, Variable *DestLo, Variable *DestHi, |
| 178 Variable *Src0, Variable *Src1) |
| 179 : InstARM32(Func, InstARM32::Umull, 2, DestLo), |
| 180 // DestHi is expected to have a FakeDef inserted by the lowering code. |
| 181 DestHi(DestHi) { |
| 182 addSource(Src0); |
| 183 addSource(Src1); |
| 184 } |
| 185 |
156 // ======================== Dump routines ======================== // | 186 // ======================== Dump routines ======================== // |
157 | 187 |
158 // Two-addr ops | 188 // Two-addr ops |
159 template <> const char *InstARM32Movt::Opcode = "movt"; | 189 template <> const char *InstARM32Movt::Opcode = "movt"; |
160 // Unary ops | 190 // Unary ops |
161 template <> const char *InstARM32Movw::Opcode = "movw"; | 191 template <> const char *InstARM32Movw::Opcode = "movw"; |
162 template <> const char *InstARM32Mvn::Opcode = "mvn"; | 192 template <> const char *InstARM32Mvn::Opcode = "mvn"; |
163 // Mov-like ops | 193 // Mov-like ops |
164 template <> const char *InstARM32Mov::Opcode = "mov"; | 194 template <> const char *InstARM32Mov::Opcode = "mov"; |
| 195 // Three-addr ops |
| 196 template <> const char *InstARM32Adc::Opcode = "adc"; |
| 197 template <> const char *InstARM32Add::Opcode = "add"; |
| 198 template <> const char *InstARM32And::Opcode = "and"; |
| 199 template <> const char *InstARM32Eor::Opcode = "eor"; |
| 200 template <> const char *InstARM32Mul::Opcode = "mul"; |
| 201 template <> const char *InstARM32Orr::Opcode = "orr"; |
| 202 template <> const char *InstARM32Sbc::Opcode = "sbc"; |
| 203 template <> const char *InstARM32Sub::Opcode = "sub"; |
165 | 204 |
166 void InstARM32::dump(const Cfg *Func) const { | 205 void InstARM32::dump(const Cfg *Func) const { |
167 if (!ALLOW_DUMP) | 206 if (!ALLOW_DUMP) |
168 return; | 207 return; |
169 Ostream &Str = Func->getContext()->getStrDump(); | 208 Ostream &Str = Func->getContext()->getStrDump(); |
170 Str << "[ARM32] "; | 209 Str << "[ARM32] "; |
171 Inst::dump(Func); | 210 Inst::dump(Func); |
172 } | 211 } |
173 | 212 |
174 template <> void InstARM32Mov::emit(const Cfg *Func) const { | 213 template <> void InstARM32Mov::emit(const Cfg *Func) const { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 assert(getDest()->hasReg()); | 249 assert(getDest()->hasReg()); |
211 Type Ty = getSrc(0)->getType(); | 250 Type Ty = getSrc(0)->getType(); |
212 Str << "\t" | 251 Str << "\t" |
213 << "ldr" << getWidthString(Ty) << "\t"; | 252 << "ldr" << getWidthString(Ty) << "\t"; |
214 getDest()->emit(Func); | 253 getDest()->emit(Func); |
215 Str << ", "; | 254 Str << ", "; |
216 getSrc(0)->emit(Func); | 255 getSrc(0)->emit(Func); |
217 } | 256 } |
218 | 257 |
219 void InstARM32Ldr::emitIAS(const Cfg *Func) const { | 258 void InstARM32Ldr::emitIAS(const Cfg *Func) const { |
220 assert(getSrcSize() == 2); | 259 assert(getSrcSize() == 1); |
221 (void)Func; | 260 (void)Func; |
222 llvm_unreachable("Not yet implemented"); | 261 llvm_unreachable("Not yet implemented"); |
223 } | 262 } |
224 | 263 |
225 void InstARM32Ldr::dump(const Cfg *Func) const { | 264 void InstARM32Ldr::dump(const Cfg *Func) const { |
226 if (!ALLOW_DUMP) | 265 if (!ALLOW_DUMP) |
227 return; | 266 return; |
228 Ostream &Str = Func->getContext()->getStrDump(); | 267 Ostream &Str = Func->getContext()->getStrDump(); |
229 dumpDest(Func); | 268 dumpDest(Func); |
230 Str << "ldr." << getSrc(0)->getType() << " "; | 269 Str << " = ldr." << getSrc(0)->getType() << " "; |
231 dumpSources(Func); | 270 dumpSources(Func); |
232 } | 271 } |
233 | 272 |
| 273 void InstARM32Mla::emit(const Cfg *Func) const { |
| 274 if (!ALLOW_DUMP) |
| 275 return; |
| 276 Ostream &Str = Func->getContext()->getStrEmit(); |
| 277 assert(getSrcSize() == 3); |
| 278 assert(getDest()->hasReg()); |
| 279 Str << "\t" |
| 280 << "mla" |
| 281 << "\t"; |
| 282 getDest()->emit(Func); |
| 283 Str << ", "; |
| 284 getSrc(0)->emit(Func); |
| 285 Str << ", "; |
| 286 getSrc(1)->emit(Func); |
| 287 Str << ", "; |
| 288 getSrc(2)->emit(Func); |
| 289 } |
| 290 |
| 291 void InstARM32Mla::emitIAS(const Cfg *Func) const { |
| 292 assert(getSrcSize() == 3); |
| 293 (void)Func; |
| 294 llvm_unreachable("Not yet implemented"); |
| 295 } |
| 296 |
| 297 void InstARM32Mla::dump(const Cfg *Func) const { |
| 298 if (!ALLOW_DUMP) |
| 299 return; |
| 300 Ostream &Str = Func->getContext()->getStrDump(); |
| 301 dumpDest(Func); |
| 302 Str << " = mla." << getSrc(0)->getType() << " "; |
| 303 dumpSources(Func); |
| 304 } |
| 305 |
234 template <> void InstARM32Movw::emit(const Cfg *Func) const { | 306 template <> void InstARM32Movw::emit(const Cfg *Func) const { |
235 if (!ALLOW_DUMP) | 307 if (!ALLOW_DUMP) |
236 return; | 308 return; |
237 Ostream &Str = Func->getContext()->getStrEmit(); | 309 Ostream &Str = Func->getContext()->getStrEmit(); |
238 assert(getSrcSize() == 1); | 310 assert(getSrcSize() == 1); |
239 Str << "\t" << Opcode << "\t"; | 311 Str << "\t" << Opcode << "\t"; |
240 getDest()->emit(Func); | 312 getDest()->emit(Func); |
241 Str << ", "; | 313 Str << ", "; |
242 Constant *Src0 = llvm::cast<Constant>(getSrc(0)); | 314 Constant *Src0 = llvm::cast<Constant>(getSrc(0)); |
243 if (auto CR = llvm::dyn_cast<ConstantRelocatable>(Src0)) { | 315 if (auto CR = llvm::dyn_cast<ConstantRelocatable>(Src0)) { |
(...skipping 23 matching lines...) Expand all Loading... |
267 } | 339 } |
268 | 340 |
269 void InstARM32Ret::emit(const Cfg *Func) const { | 341 void InstARM32Ret::emit(const Cfg *Func) const { |
270 if (!ALLOW_DUMP) | 342 if (!ALLOW_DUMP) |
271 return; | 343 return; |
272 assert(getSrcSize() > 0); | 344 assert(getSrcSize() > 0); |
273 Variable *LR = llvm::cast<Variable>(getSrc(0)); | 345 Variable *LR = llvm::cast<Variable>(getSrc(0)); |
274 assert(LR->hasReg()); | 346 assert(LR->hasReg()); |
275 assert(LR->getRegNum() == RegARM32::Reg_lr); | 347 assert(LR->getRegNum() == RegARM32::Reg_lr); |
276 Ostream &Str = Func->getContext()->getStrEmit(); | 348 Ostream &Str = Func->getContext()->getStrEmit(); |
277 Str << "\tbx\t"; | 349 Str << "\t" |
| 350 << "bx" |
| 351 << "\t"; |
278 LR->emit(Func); | 352 LR->emit(Func); |
279 } | 353 } |
280 | 354 |
281 void InstARM32Ret::emitIAS(const Cfg *Func) const { | 355 void InstARM32Ret::emitIAS(const Cfg *Func) const { |
282 (void)Func; | 356 (void)Func; |
283 llvm_unreachable("Not yet implemented"); | 357 llvm_unreachable("Not yet implemented"); |
284 } | 358 } |
285 | 359 |
286 void InstARM32Ret::dump(const Cfg *Func) const { | 360 void InstARM32Ret::dump(const Cfg *Func) const { |
287 if (!ALLOW_DUMP) | 361 if (!ALLOW_DUMP) |
288 return; | 362 return; |
289 Ostream &Str = Func->getContext()->getStrDump(); | 363 Ostream &Str = Func->getContext()->getStrDump(); |
290 Type Ty = (getSrcSize() == 1 ? IceType_void : getSrc(0)->getType()); | 364 Type Ty = (getSrcSize() == 1 ? IceType_void : getSrc(0)->getType()); |
291 Str << "ret." << Ty << " "; | 365 Str << "ret." << Ty << " "; |
292 dumpSources(Func); | 366 dumpSources(Func); |
293 } | 367 } |
294 | 368 |
| 369 void InstARM32Umull::emit(const Cfg *Func) const { |
| 370 if (!ALLOW_DUMP) |
| 371 return; |
| 372 Ostream &Str = Func->getContext()->getStrEmit(); |
| 373 assert(getSrcSize() == 2); |
| 374 assert(getDest()->hasReg()); |
| 375 Str << "\t" |
| 376 << "umull" |
| 377 << "\t"; |
| 378 getDest()->emit(Func); |
| 379 Str << ", "; |
| 380 DestHi->emit(Func); |
| 381 Str << ", "; |
| 382 getSrc(0)->emit(Func); |
| 383 Str << ", "; |
| 384 getSrc(1)->emit(Func); |
| 385 } |
| 386 |
| 387 void InstARM32Umull::emitIAS(const Cfg *Func) const { |
| 388 assert(getSrcSize() == 2); |
| 389 (void)Func; |
| 390 llvm_unreachable("Not yet implemented"); |
| 391 } |
| 392 |
| 393 void InstARM32Umull::dump(const Cfg *Func) const { |
| 394 if (!ALLOW_DUMP) |
| 395 return; |
| 396 Ostream &Str = Func->getContext()->getStrDump(); |
| 397 dumpDest(Func); |
| 398 Str << " = umull." << getSrc(0)->getType() << " "; |
| 399 dumpSources(Func); |
| 400 } |
| 401 |
295 void OperandARM32Mem::emit(const Cfg *Func) const { | 402 void OperandARM32Mem::emit(const Cfg *Func) const { |
296 if (!ALLOW_DUMP) | 403 if (!ALLOW_DUMP) |
297 return; | 404 return; |
298 Ostream &Str = Func->getContext()->getStrEmit(); | 405 Ostream &Str = Func->getContext()->getStrEmit(); |
299 Str << "["; | 406 Str << "["; |
300 getBase()->emit(Func); | 407 getBase()->emit(Func); |
301 switch (getAddrMode()) { | 408 switch (getAddrMode()) { |
302 case PostIndex: | 409 case PostIndex: |
303 case NegPostIndex: | 410 case NegPostIndex: |
304 Str << "], "; | 411 Str << "], "; |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
401 if (getShiftOp() != kNoShift) { | 508 if (getShiftOp() != kNoShift) { |
402 Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " "; | 509 Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " "; |
403 if (Func) | 510 if (Func) |
404 getShiftAmt()->dump(Func); | 511 getShiftAmt()->dump(Func); |
405 else | 512 else |
406 getShiftAmt()->dump(Str); | 513 getShiftAmt()->dump(Str); |
407 } | 514 } |
408 } | 515 } |
409 | 516 |
410 } // end of namespace Ice | 517 } // end of namespace Ice |
OLD | NEW |