| 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 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 118 assert(Inst->getSrcSize() == 2); | 118 assert(Inst->getSrcSize() == 2); |
| 119 Str << "\t" << Opcode << (SetFlags ? "s" : "") << Inst->getPredicate() | 119 Str << "\t" << Opcode << (SetFlags ? "s" : "") << Inst->getPredicate() |
| 120 << "\t"; | 120 << "\t"; |
| 121 Inst->getDest()->emit(Func); | 121 Inst->getDest()->emit(Func); |
| 122 Str << ", "; | 122 Str << ", "; |
| 123 Inst->getSrc(0)->emit(Func); | 123 Inst->getSrc(0)->emit(Func); |
| 124 Str << ", "; | 124 Str << ", "; |
| 125 Inst->getSrc(1)->emit(Func); | 125 Inst->getSrc(1)->emit(Func); |
| 126 } | 126 } |
| 127 | 127 |
| 128 void InstARM32Pred::emitFourAddr(const char *Opcode, const InstARM32Pred *Inst, |
| 129 const Cfg *Func) { |
| 130 if (!BuildDefs::dump()) |
| 131 return; |
| 132 Ostream &Str = Func->getContext()->getStrEmit(); |
| 133 assert(Inst->getSrcSize() == 3); |
| 134 Str << "\t" << Opcode << Inst->getPredicate() << "\t"; |
| 135 Inst->getDest()->emit(Func); |
| 136 Str << ", "; |
| 137 Inst->getSrc(0)->emit(Func); |
| 138 Str << ", "; |
| 139 Inst->getSrc(1)->emit(Func); |
| 140 Str << ", "; |
| 141 Inst->getSrc(2)->emit(Func); |
| 142 } |
| 143 |
| 128 OperandARM32Mem::OperandARM32Mem(Cfg * /* Func */, Type Ty, Variable *Base, | 144 OperandARM32Mem::OperandARM32Mem(Cfg * /* Func */, Type Ty, Variable *Base, |
| 129 ConstantInteger32 *ImmOffset, AddrMode Mode) | 145 ConstantInteger32 *ImmOffset, AddrMode Mode) |
| 130 : OperandARM32(kMem, Ty), Base(Base), ImmOffset(ImmOffset), Index(nullptr), | 146 : OperandARM32(kMem, Ty), Base(Base), ImmOffset(ImmOffset), Index(nullptr), |
| 131 ShiftOp(kNoShift), ShiftAmt(0), Mode(Mode) { | 147 ShiftOp(kNoShift), ShiftAmt(0), Mode(Mode) { |
| 132 // The Neg modes are only needed for Reg +/- Reg. | 148 // The Neg modes are only needed for Reg +/- Reg. |
| 133 assert(!isNegAddrMode()); | 149 assert(!isNegAddrMode()); |
| 134 NumVars = 1; | 150 NumVars = 1; |
| 135 Vars = &this->Base; | 151 Vars = &this->Base; |
| 136 } | 152 } |
| 137 | 153 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 } | 216 } |
| 201 | 217 |
| 202 InstARM32AdjustStack::InstARM32AdjustStack(Cfg *Func, Variable *SP, | 218 InstARM32AdjustStack::InstARM32AdjustStack(Cfg *Func, Variable *SP, |
| 203 SizeT Amount, Operand *SrcAmount) | 219 SizeT Amount, Operand *SrcAmount) |
| 204 : InstARM32(Func, InstARM32::Adjuststack, 2, SP), Amount(Amount) { | 220 : InstARM32(Func, InstARM32::Adjuststack, 2, SP), Amount(Amount) { |
| 205 addSource(SP); | 221 addSource(SP); |
| 206 addSource(SrcAmount); | 222 addSource(SrcAmount); |
| 207 } | 223 } |
| 208 | 224 |
| 209 InstARM32Br::InstARM32Br(Cfg *Func, const CfgNode *TargetTrue, | 225 InstARM32Br::InstARM32Br(Cfg *Func, const CfgNode *TargetTrue, |
| 210 const CfgNode *TargetFalse, CondARM32::Cond Pred) | 226 const CfgNode *TargetFalse, |
| 227 const InstARM32Label *Label, CondARM32::Cond Pred) |
| 211 : InstARM32Pred(Func, InstARM32::Br, 0, nullptr, Pred), | 228 : InstARM32Pred(Func, InstARM32::Br, 0, nullptr, Pred), |
| 212 TargetTrue(TargetTrue), TargetFalse(TargetFalse) {} | 229 TargetTrue(TargetTrue), TargetFalse(TargetFalse), Label(Label) {} |
| 213 | 230 |
| 214 bool InstARM32Br::optimizeBranch(const CfgNode *NextNode) { | 231 bool InstARM32Br::optimizeBranch(const CfgNode *NextNode) { |
| 215 // If there is no next block, then there can be no fallthrough to | 232 // If there is no next block, then there can be no fallthrough to |
| 216 // optimize. | 233 // optimize. |
| 217 if (NextNode == nullptr) | 234 if (NextNode == nullptr) |
| 218 return false; | 235 return false; |
| 236 // Intra-block conditional branches can't be optimized. |
| 237 if (Label) |
| 238 return false; |
| 219 // If there is no fallthrough node, such as a non-default case label | 239 // If there is no fallthrough node, such as a non-default case label |
| 220 // for a switch instruction, then there is no opportunity to | 240 // for a switch instruction, then there is no opportunity to |
| 221 // optimize. | 241 // optimize. |
| 222 if (getTargetFalse() == nullptr) | 242 if (getTargetFalse() == nullptr) |
| 223 return false; | 243 return false; |
| 224 | 244 |
| 225 // Unconditional branch to the next node can be removed. | 245 // Unconditional branch to the next node can be removed. |
| 226 if (isUnconditionalBranch() && getTargetFalse() == NextNode) { | 246 if (isUnconditionalBranch() && getTargetFalse() == NextNode) { |
| 227 assert(getTargetTrue() == nullptr); | 247 assert(getTargetTrue() == nullptr); |
| 228 setDeleted(); | 248 setDeleted(); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 addSource(CallTarget); | 284 addSource(CallTarget); |
| 265 } | 285 } |
| 266 | 286 |
| 267 InstARM32Cmp::InstARM32Cmp(Cfg *Func, Variable *Src1, Operand *Src2, | 287 InstARM32Cmp::InstARM32Cmp(Cfg *Func, Variable *Src1, Operand *Src2, |
| 268 CondARM32::Cond Predicate) | 288 CondARM32::Cond Predicate) |
| 269 : InstARM32Pred(Func, InstARM32::Cmp, 2, nullptr, Predicate) { | 289 : InstARM32Pred(Func, InstARM32::Cmp, 2, nullptr, Predicate) { |
| 270 addSource(Src1); | 290 addSource(Src1); |
| 271 addSource(Src2); | 291 addSource(Src2); |
| 272 } | 292 } |
| 273 | 293 |
| 294 // Make this target independent? |
| 295 InstARM32Label::InstARM32Label(Cfg *Func, TargetARM32 *Target) |
| 296 : InstARM32(Func, InstARM32::Label, 0, nullptr), |
| 297 Number(Target->makeNextLabelNumber()) {} |
| 298 |
| 299 IceString InstARM32Label::getName(const Cfg *Func) const { |
| 300 return ".L" + Func->getFunctionName() + "$local$__" + std::to_string(Number); |
| 301 } |
| 302 |
| 274 InstARM32Ldr::InstARM32Ldr(Cfg *Func, Variable *Dest, OperandARM32Mem *Mem, | 303 InstARM32Ldr::InstARM32Ldr(Cfg *Func, Variable *Dest, OperandARM32Mem *Mem, |
| 275 CondARM32::Cond Predicate) | 304 CondARM32::Cond Predicate) |
| 276 : InstARM32Pred(Func, InstARM32::Ldr, 1, Dest, Predicate) { | 305 : InstARM32Pred(Func, InstARM32::Ldr, 1, Dest, Predicate) { |
| 277 addSource(Mem); | 306 addSource(Mem); |
| 278 } | 307 } |
| 279 | 308 |
| 280 InstARM32Mla::InstARM32Mla(Cfg *Func, Variable *Dest, Variable *Src0, | |
| 281 Variable *Src1, Variable *Acc, | |
| 282 CondARM32::Cond Predicate) | |
| 283 : InstARM32Pred(Func, InstARM32::Mla, 3, Dest, Predicate) { | |
| 284 addSource(Src0); | |
| 285 addSource(Src1); | |
| 286 addSource(Acc); | |
| 287 } | |
| 288 | |
| 289 InstARM32Pop::InstARM32Pop(Cfg *Func, const VarList &Dests) | 309 InstARM32Pop::InstARM32Pop(Cfg *Func, const VarList &Dests) |
| 290 : InstARM32(Func, InstARM32::Pop, 0, nullptr), Dests(Dests) { | 310 : InstARM32(Func, InstARM32::Pop, 0, nullptr), Dests(Dests) { |
| 291 // Track modifications to Dests separately via FakeDefs. | 311 // Track modifications to Dests separately via FakeDefs. |
| 292 // Also, a pop instruction affects the stack pointer and so it should not | 312 // Also, a pop instruction affects the stack pointer and so it should not |
| 293 // be allowed to be automatically dead-code eliminated. This is automatic | 313 // be allowed to be automatically dead-code eliminated. This is automatic |
| 294 // since we leave the Dest as nullptr. | 314 // since we leave the Dest as nullptr. |
| 295 } | 315 } |
| 296 | 316 |
| 297 InstARM32Push::InstARM32Push(Cfg *Func, const VarList &Srcs) | 317 InstARM32Push::InstARM32Push(Cfg *Func, const VarList &Srcs) |
| 298 : InstARM32(Func, InstARM32::Push, Srcs.size(), nullptr) { | 318 : InstARM32(Func, InstARM32::Push, Srcs.size(), nullptr) { |
| 299 for (Variable *Source : Srcs) | 319 for (Variable *Source : Srcs) |
| 300 addSource(Source); | 320 addSource(Source); |
| 301 } | 321 } |
| 302 | 322 |
| 303 InstARM32Ret::InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source) | 323 InstARM32Ret::InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source) |
| 304 : InstARM32(Func, InstARM32::Ret, Source ? 2 : 1, nullptr) { | 324 : InstARM32(Func, InstARM32::Ret, Source ? 2 : 1, nullptr) { |
| 305 addSource(LR); | 325 addSource(LR); |
| 306 if (Source) | 326 if (Source) |
| 307 addSource(Source); | 327 addSource(Source); |
| 308 } | 328 } |
| 309 | 329 |
| 310 InstARM32Str::InstARM32Str(Cfg *Func, Variable *Value, OperandARM32Mem *Mem, | 330 InstARM32Str::InstARM32Str(Cfg *Func, Variable *Value, OperandARM32Mem *Mem, |
| 311 CondARM32::Cond Predicate) | 331 CondARM32::Cond Predicate) |
| 312 : InstARM32Pred(Func, InstARM32::Str, 2, nullptr, Predicate) { | 332 : InstARM32Pred(Func, InstARM32::Str, 2, nullptr, Predicate) { |
| 313 addSource(Value); | 333 addSource(Value); |
| 314 addSource(Mem); | 334 addSource(Mem); |
| 315 } | 335 } |
| 316 | 336 |
| 337 InstARM32Trap::InstARM32Trap(Cfg *Func) |
| 338 : InstARM32(Func, InstARM32::Trap, 0, nullptr) {} |
| 339 |
| 340 InstARM32Tst::InstARM32Tst(Cfg *Func, Variable *Src0, Operand *Src1, |
| 341 CondARM32::Cond Predicate) |
| 342 : InstARM32Pred(Func, InstARM32::Tst, 2, nullptr, Predicate) { |
| 343 addSource(Src0); |
| 344 addSource(Src1); |
| 345 } |
| 346 |
| 317 InstARM32Umull::InstARM32Umull(Cfg *Func, Variable *DestLo, Variable *DestHi, | 347 InstARM32Umull::InstARM32Umull(Cfg *Func, Variable *DestLo, Variable *DestHi, |
| 318 Variable *Src0, Variable *Src1, | 348 Variable *Src0, Variable *Src1, |
| 319 CondARM32::Cond Predicate) | 349 CondARM32::Cond Predicate) |
| 320 : InstARM32Pred(Func, InstARM32::Umull, 2, DestLo, Predicate), | 350 : InstARM32Pred(Func, InstARM32::Umull, 2, DestLo, Predicate), |
| 321 // DestHi is expected to have a FakeDef inserted by the lowering code. | 351 // DestHi is expected to have a FakeDef inserted by the lowering code. |
| 322 DestHi(DestHi) { | 352 DestHi(DestHi) { |
| 323 addSource(Src0); | 353 addSource(Src0); |
| 324 addSource(Src1); | 354 addSource(Src1); |
| 325 } | 355 } |
| 326 | 356 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 341 template <> const char *InstARM32And::Opcode = "and"; | 371 template <> const char *InstARM32And::Opcode = "and"; |
| 342 template <> const char *InstARM32Asr::Opcode = "asr"; | 372 template <> const char *InstARM32Asr::Opcode = "asr"; |
| 343 template <> const char *InstARM32Bic::Opcode = "bic"; | 373 template <> const char *InstARM32Bic::Opcode = "bic"; |
| 344 template <> const char *InstARM32Eor::Opcode = "eor"; | 374 template <> const char *InstARM32Eor::Opcode = "eor"; |
| 345 template <> const char *InstARM32Lsl::Opcode = "lsl"; | 375 template <> const char *InstARM32Lsl::Opcode = "lsl"; |
| 346 template <> const char *InstARM32Lsr::Opcode = "lsr"; | 376 template <> const char *InstARM32Lsr::Opcode = "lsr"; |
| 347 template <> const char *InstARM32Mul::Opcode = "mul"; | 377 template <> const char *InstARM32Mul::Opcode = "mul"; |
| 348 template <> const char *InstARM32Orr::Opcode = "orr"; | 378 template <> const char *InstARM32Orr::Opcode = "orr"; |
| 349 template <> const char *InstARM32Rsb::Opcode = "rsb"; | 379 template <> const char *InstARM32Rsb::Opcode = "rsb"; |
| 350 template <> const char *InstARM32Sbc::Opcode = "sbc"; | 380 template <> const char *InstARM32Sbc::Opcode = "sbc"; |
| 381 template <> const char *InstARM32Sdiv::Opcode = "sdiv"; |
| 351 template <> const char *InstARM32Sub::Opcode = "sub"; | 382 template <> const char *InstARM32Sub::Opcode = "sub"; |
| 383 template <> const char *InstARM32Udiv::Opcode = "udiv"; |
| 384 // Four-addr ops |
| 385 template <> const char *InstARM32Mla::Opcode = "mla"; |
| 386 template <> const char *InstARM32Mls::Opcode = "mls"; |
| 352 | 387 |
| 353 void InstARM32::dump(const Cfg *Func) const { | 388 void InstARM32::dump(const Cfg *Func) const { |
| 354 if (!BuildDefs::dump()) | 389 if (!BuildDefs::dump()) |
| 355 return; | 390 return; |
| 356 Ostream &Str = Func->getContext()->getStrDump(); | 391 Ostream &Str = Func->getContext()->getStrDump(); |
| 357 Str << "[ARM32] "; | 392 Str << "[ARM32] "; |
| 358 Inst::dump(Func); | 393 Inst::dump(Func); |
| 359 } | 394 } |
| 360 | 395 |
| 361 template <> void InstARM32Mov::emit(const Cfg *Func) const { | 396 template <> void InstARM32Mov::emit(const Cfg *Func) const { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 395 (void)Func; | 430 (void)Func; |
| 396 llvm_unreachable("Not yet implemented"); | 431 llvm_unreachable("Not yet implemented"); |
| 397 } | 432 } |
| 398 | 433 |
| 399 void InstARM32Br::emit(const Cfg *Func) const { | 434 void InstARM32Br::emit(const Cfg *Func) const { |
| 400 if (!BuildDefs::dump()) | 435 if (!BuildDefs::dump()) |
| 401 return; | 436 return; |
| 402 Ostream &Str = Func->getContext()->getStrEmit(); | 437 Ostream &Str = Func->getContext()->getStrEmit(); |
| 403 Str << "\t" | 438 Str << "\t" |
| 404 << "b" << getPredicate() << "\t"; | 439 << "b" << getPredicate() << "\t"; |
| 405 if (isUnconditionalBranch()) { | 440 if (Label) { |
| 406 Str << getTargetFalse()->getAsmName(); | 441 Str << Label->getName(Func); |
| 407 } else { | 442 } else { |
| 408 Str << getTargetTrue()->getAsmName(); | 443 if (isUnconditionalBranch()) { |
| 409 if (getTargetFalse()) { | 444 Str << getTargetFalse()->getAsmName(); |
| 410 Str << "\n\t" | 445 } else { |
| 411 << "b" | 446 Str << getTargetTrue()->getAsmName(); |
| 412 << "\t" << getTargetFalse()->getAsmName(); | 447 if (getTargetFalse()) { |
| 448 Str << "\n\t" |
| 449 << "b" |
| 450 << "\t" << getTargetFalse()->getAsmName(); |
| 451 } |
| 413 } | 452 } |
| 414 } | 453 } |
| 415 } | 454 } |
| 416 | 455 |
| 417 void InstARM32Br::emitIAS(const Cfg *Func) const { | 456 void InstARM32Br::emitIAS(const Cfg *Func) const { |
| 418 (void)Func; | 457 (void)Func; |
| 419 llvm_unreachable("Not yet implemented"); | 458 llvm_unreachable("Not yet implemented"); |
| 420 } | 459 } |
| 421 | 460 |
| 422 void InstARM32Br::dump(const Cfg *Func) const { | 461 void InstARM32Br::dump(const Cfg *Func) const { |
| 423 if (!BuildDefs::dump()) | 462 if (!BuildDefs::dump()) |
| 424 return; | 463 return; |
| 425 Ostream &Str = Func->getContext()->getStrDump(); | 464 Ostream &Str = Func->getContext()->getStrDump(); |
| 426 Str << "br "; | 465 Str << "br "; |
| 427 | 466 |
| 428 if (getPredicate() == CondARM32::AL) { | 467 if (getPredicate() == CondARM32::AL) { |
| 429 Str << "label %" << getTargetFalse()->getName(); | 468 Str << "label %" |
| 469 << (Label ? Label->getName(Func) : getTargetFalse()->getName()); |
| 430 return; | 470 return; |
| 431 } | 471 } |
| 432 | 472 |
| 433 Str << getPredicate() << ", label %" << getTargetTrue()->getName(); | 473 if (Label) { |
| 434 if (getTargetFalse()) { | 474 Str << "label %" << Label->getName(Func); |
| 435 Str << ", label %" << getTargetFalse()->getName(); | 475 } else { |
| 476 Str << getPredicate() << ", label %" << getTargetTrue()->getName(); |
| 477 if (getTargetFalse()) { |
| 478 Str << ", label %" << getTargetFalse()->getName(); |
| 479 } |
| 436 } | 480 } |
| 437 } | 481 } |
| 438 | 482 |
| 439 void InstARM32Call::emit(const Cfg *Func) const { | 483 void InstARM32Call::emit(const Cfg *Func) const { |
| 440 if (!BuildDefs::dump()) | 484 if (!BuildDefs::dump()) |
| 441 return; | 485 return; |
| 442 Ostream &Str = Func->getContext()->getStrEmit(); | 486 Ostream &Str = Func->getContext()->getStrEmit(); |
| 443 assert(getSrcSize() == 1); | 487 assert(getSrcSize() == 1); |
| 444 if (llvm::isa<ConstantInteger32>(getCallTarget())) { | 488 if (llvm::isa<ConstantInteger32>(getCallTarget())) { |
| 445 // This shouldn't happen (typically have to copy the full 32-bits | 489 // This shouldn't happen (typically have to copy the full 32-bits |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 498 } | 542 } |
| 499 | 543 |
| 500 void InstARM32Cmp::dump(const Cfg *Func) const { | 544 void InstARM32Cmp::dump(const Cfg *Func) const { |
| 501 if (!BuildDefs::dump()) | 545 if (!BuildDefs::dump()) |
| 502 return; | 546 return; |
| 503 Ostream &Str = Func->getContext()->getStrDump(); | 547 Ostream &Str = Func->getContext()->getStrDump(); |
| 504 dumpOpcodePred(Str, "cmp", getSrc(0)->getType()); | 548 dumpOpcodePred(Str, "cmp", getSrc(0)->getType()); |
| 505 dumpSources(Func); | 549 dumpSources(Func); |
| 506 } | 550 } |
| 507 | 551 |
| 552 void InstARM32Label::emit(const Cfg *Func) const { |
| 553 if (!BuildDefs::dump()) |
| 554 return; |
| 555 Ostream &Str = Func->getContext()->getStrEmit(); |
| 556 Str << getName(Func) << ":"; |
| 557 } |
| 558 |
| 559 void InstARM32Label::emitIAS(const Cfg *Func) const { |
| 560 (void)Func; |
| 561 llvm_unreachable("Not yet implemented"); |
| 562 } |
| 563 |
| 564 void InstARM32Label::dump(const Cfg *Func) const { |
| 565 if (!BuildDefs::dump()) |
| 566 return; |
| 567 Ostream &Str = Func->getContext()->getStrDump(); |
| 568 Str << getName(Func) << ":"; |
| 569 } |
| 570 |
| 508 void InstARM32Ldr::emit(const Cfg *Func) const { | 571 void InstARM32Ldr::emit(const Cfg *Func) const { |
| 509 if (!BuildDefs::dump()) | 572 if (!BuildDefs::dump()) |
| 510 return; | 573 return; |
| 511 Ostream &Str = Func->getContext()->getStrEmit(); | 574 Ostream &Str = Func->getContext()->getStrEmit(); |
| 512 assert(getSrcSize() == 1); | 575 assert(getSrcSize() == 1); |
| 513 assert(getDest()->hasReg()); | 576 assert(getDest()->hasReg()); |
| 514 Type Ty = getSrc(0)->getType(); | 577 Type Ty = getSrc(0)->getType(); |
| 515 Str << "\t" | 578 Str << "\t" |
| 516 << "ldr" << getWidthString(Ty) << getPredicate() << "\t"; | 579 << "ldr" << getWidthString(Ty) << getPredicate() << "\t"; |
| 517 getDest()->emit(Func); | 580 getDest()->emit(Func); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 528 void InstARM32Ldr::dump(const Cfg *Func) const { | 591 void InstARM32Ldr::dump(const Cfg *Func) const { |
| 529 if (!BuildDefs::dump()) | 592 if (!BuildDefs::dump()) |
| 530 return; | 593 return; |
| 531 Ostream &Str = Func->getContext()->getStrDump(); | 594 Ostream &Str = Func->getContext()->getStrDump(); |
| 532 dumpDest(Func); | 595 dumpDest(Func); |
| 533 Str << " = "; | 596 Str << " = "; |
| 534 dumpOpcodePred(Str, "ldr", getDest()->getType()); | 597 dumpOpcodePred(Str, "ldr", getDest()->getType()); |
| 535 Str << " "; | 598 Str << " "; |
| 536 dumpSources(Func); | 599 dumpSources(Func); |
| 537 } | 600 } |
| 538 | |
| 539 void InstARM32Mla::emit(const Cfg *Func) const { | |
| 540 if (!BuildDefs::dump()) | |
| 541 return; | |
| 542 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 543 assert(getSrcSize() == 3); | |
| 544 assert(getDest()->hasReg()); | |
| 545 Str << "\t" | |
| 546 << "mla" << getPredicate() << "\t"; | |
| 547 getDest()->emit(Func); | |
| 548 Str << ", "; | |
| 549 getSrc(0)->emit(Func); | |
| 550 Str << ", "; | |
| 551 getSrc(1)->emit(Func); | |
| 552 Str << ", "; | |
| 553 getSrc(2)->emit(Func); | |
| 554 } | |
| 555 | |
| 556 void InstARM32Mla::emitIAS(const Cfg *Func) const { | |
| 557 assert(getSrcSize() == 3); | |
| 558 (void)Func; | |
| 559 llvm_unreachable("Not yet implemented"); | |
| 560 } | |
| 561 | |
| 562 void InstARM32Mla::dump(const Cfg *Func) const { | |
| 563 if (!BuildDefs::dump()) | |
| 564 return; | |
| 565 Ostream &Str = Func->getContext()->getStrDump(); | |
| 566 dumpDest(Func); | |
| 567 Str << " = "; | |
| 568 dumpOpcodePred(Str, "mla", getDest()->getType()); | |
| 569 Str << " "; | |
| 570 dumpSources(Func); | |
| 571 } | |
| 572 | 601 |
| 573 template <> void InstARM32Movw::emit(const Cfg *Func) const { | 602 template <> void InstARM32Movw::emit(const Cfg *Func) const { |
| 574 if (!BuildDefs::dump()) | 603 if (!BuildDefs::dump()) |
| 575 return; | 604 return; |
| 576 Ostream &Str = Func->getContext()->getStrEmit(); | 605 Ostream &Str = Func->getContext()->getStrEmit(); |
| 577 assert(getSrcSize() == 1); | 606 assert(getSrcSize() == 1); |
| 578 Str << "\t" << Opcode << getPredicate() << "\t"; | 607 Str << "\t" << Opcode << getPredicate() << "\t"; |
| 579 getDest()->emit(Func); | 608 getDest()->emit(Func); |
| 580 Str << ", "; | 609 Str << ", "; |
| 581 Constant *Src0 = llvm::cast<Constant>(getSrc(0)); | 610 Constant *Src0 = llvm::cast<Constant>(getSrc(0)); |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 750 return; | 779 return; |
| 751 Ostream &Str = Func->getContext()->getStrDump(); | 780 Ostream &Str = Func->getContext()->getStrDump(); |
| 752 Type Ty = getSrc(0)->getType(); | 781 Type Ty = getSrc(0)->getType(); |
| 753 dumpOpcodePred(Str, "str", Ty); | 782 dumpOpcodePred(Str, "str", Ty); |
| 754 Str << " "; | 783 Str << " "; |
| 755 getSrc(1)->dump(Func); | 784 getSrc(1)->dump(Func); |
| 756 Str << ", "; | 785 Str << ", "; |
| 757 getSrc(0)->dump(Func); | 786 getSrc(0)->dump(Func); |
| 758 } | 787 } |
| 759 | 788 |
| 789 void InstARM32Trap::emit(const Cfg *Func) const { |
| 790 if (!BuildDefs::dump()) |
| 791 return; |
| 792 Ostream &Str = Func->getContext()->getStrEmit(); |
| 793 assert(getSrcSize() == 0); |
| 794 // There isn't a mnemonic for the special NaCl Trap encoding, so dump |
| 795 // the raw bytes. |
| 796 Str << "\t.long 0x"; |
| 797 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
| 798 for (uint8_t I : Asm->getNonExecBundlePadding()) { |
| 799 Str.write_hex(I); |
| 800 } |
| 801 } |
| 802 |
| 803 void InstARM32Trap::emitIAS(const Cfg *Func) const { |
| 804 assert(getSrcSize() == 0); |
| 805 (void)Func; |
| 806 llvm_unreachable("Not yet implemented"); |
| 807 } |
| 808 |
| 809 void InstARM32Trap::dump(const Cfg *Func) const { |
| 810 if (!BuildDefs::dump()) |
| 811 return; |
| 812 Ostream &Str = Func->getContext()->getStrDump(); |
| 813 Str << "trap"; |
| 814 } |
| 815 |
| 816 void InstARM32Tst::emit(const Cfg *Func) const { |
| 817 if (!BuildDefs::dump()) |
| 818 return; |
| 819 Ostream &Str = Func->getContext()->getStrEmit(); |
| 820 assert(getSrcSize() == 2); |
| 821 Str << "\t" |
| 822 "tst" << getPredicate() << "\t"; |
| 823 getSrc(0)->emit(Func); |
| 824 Str << ", "; |
| 825 getSrc(1)->emit(Func); |
| 826 } |
| 827 |
| 828 void InstARM32Tst::emitIAS(const Cfg *Func) const { |
| 829 assert(getSrcSize() == 2); |
| 830 (void)Func; |
| 831 llvm_unreachable("Not yet implemented"); |
| 832 } |
| 833 |
| 834 void InstARM32Tst::dump(const Cfg *Func) const { |
| 835 if (!BuildDefs::dump()) |
| 836 return; |
| 837 Ostream &Str = Func->getContext()->getStrDump(); |
| 838 dumpOpcodePred(Str, "tst", getSrc(0)->getType()); |
| 839 Str << " "; |
| 840 dumpSources(Func); |
| 841 } |
| 842 |
| 760 void InstARM32Umull::emit(const Cfg *Func) const { | 843 void InstARM32Umull::emit(const Cfg *Func) const { |
| 761 if (!BuildDefs::dump()) | 844 if (!BuildDefs::dump()) |
| 762 return; | 845 return; |
| 763 Ostream &Str = Func->getContext()->getStrEmit(); | 846 Ostream &Str = Func->getContext()->getStrEmit(); |
| 764 assert(getSrcSize() == 2); | 847 assert(getSrcSize() == 2); |
| 765 assert(getDest()->hasReg()); | 848 assert(getDest()->hasReg()); |
| 766 Str << "\t" | 849 Str << "\t" |
| 767 << "umull" << getPredicate() << "\t"; | 850 << "umull" << getPredicate() << "\t"; |
| 768 getDest()->emit(Func); | 851 getDest()->emit(Func); |
| 769 Str << ", "; | 852 Str << ", "; |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 900 if (getShiftOp() != kNoShift) { | 983 if (getShiftOp() != kNoShift) { |
| 901 Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " "; | 984 Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " "; |
| 902 if (Func) | 985 if (Func) |
| 903 getShiftAmt()->dump(Func); | 986 getShiftAmt()->dump(Func); |
| 904 else | 987 else |
| 905 getShiftAmt()->dump(Str); | 988 getShiftAmt()->dump(Str); |
| 906 } | 989 } |
| 907 } | 990 } |
| 908 | 991 |
| 909 } // end of namespace Ice | 992 } // end of namespace Ice |
| OLD | NEW |