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