| 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 |
| 144 void InstARM32Pred::emitCmpLike(const char *Opcode, const InstARM32Pred *Inst, |
| 145 const Cfg *Func) { |
| 146 if (!BuildDefs::dump()) |
| 147 return; |
| 148 Ostream &Str = Func->getContext()->getStrEmit(); |
| 149 assert(Inst->getSrcSize() == 2); |
| 150 Str << "\t" << Opcode << Inst->getPredicate() << "\t"; |
| 151 Inst->getSrc(0)->emit(Func); |
| 152 Str << ", "; |
| 153 Inst->getSrc(1)->emit(Func); |
| 154 } |
| 155 |
| 128 OperandARM32Mem::OperandARM32Mem(Cfg * /* Func */, Type Ty, Variable *Base, | 156 OperandARM32Mem::OperandARM32Mem(Cfg * /* Func */, Type Ty, Variable *Base, |
| 129 ConstantInteger32 *ImmOffset, AddrMode Mode) | 157 ConstantInteger32 *ImmOffset, AddrMode Mode) |
| 130 : OperandARM32(kMem, Ty), Base(Base), ImmOffset(ImmOffset), Index(nullptr), | 158 : OperandARM32(kMem, Ty), Base(Base), ImmOffset(ImmOffset), Index(nullptr), |
| 131 ShiftOp(kNoShift), ShiftAmt(0), Mode(Mode) { | 159 ShiftOp(kNoShift), ShiftAmt(0), Mode(Mode) { |
| 132 // The Neg modes are only needed for Reg +/- Reg. | 160 // The Neg modes are only needed for Reg +/- Reg. |
| 133 assert(!isNegAddrMode()); | 161 assert(!isNegAddrMode()); |
| 134 NumVars = 1; | 162 NumVars = 1; |
| 135 Vars = &this->Base; | 163 Vars = &this->Base; |
| 136 } | 164 } |
| 137 | 165 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 } | 228 } |
| 201 | 229 |
| 202 InstARM32AdjustStack::InstARM32AdjustStack(Cfg *Func, Variable *SP, | 230 InstARM32AdjustStack::InstARM32AdjustStack(Cfg *Func, Variable *SP, |
| 203 SizeT Amount, Operand *SrcAmount) | 231 SizeT Amount, Operand *SrcAmount) |
| 204 : InstARM32(Func, InstARM32::Adjuststack, 2, SP), Amount(Amount) { | 232 : InstARM32(Func, InstARM32::Adjuststack, 2, SP), Amount(Amount) { |
| 205 addSource(SP); | 233 addSource(SP); |
| 206 addSource(SrcAmount); | 234 addSource(SrcAmount); |
| 207 } | 235 } |
| 208 | 236 |
| 209 InstARM32Br::InstARM32Br(Cfg *Func, const CfgNode *TargetTrue, | 237 InstARM32Br::InstARM32Br(Cfg *Func, const CfgNode *TargetTrue, |
| 210 const CfgNode *TargetFalse, CondARM32::Cond Pred) | 238 const CfgNode *TargetFalse, |
| 239 const InstARM32Label *Label, CondARM32::Cond Pred) |
| 211 : InstARM32Pred(Func, InstARM32::Br, 0, nullptr, Pred), | 240 : InstARM32Pred(Func, InstARM32::Br, 0, nullptr, Pred), |
| 212 TargetTrue(TargetTrue), TargetFalse(TargetFalse) {} | 241 TargetTrue(TargetTrue), TargetFalse(TargetFalse), Label(Label) {} |
| 213 | 242 |
| 214 bool InstARM32Br::optimizeBranch(const CfgNode *NextNode) { | 243 bool InstARM32Br::optimizeBranch(const CfgNode *NextNode) { |
| 215 // If there is no next block, then there can be no fallthrough to | 244 // If there is no next block, then there can be no fallthrough to |
| 216 // optimize. | 245 // optimize. |
| 217 if (NextNode == nullptr) | 246 if (NextNode == nullptr) |
| 218 return false; | 247 return false; |
| 248 // Intra-block conditional branches can't be optimized. |
| 249 if (Label) |
| 250 return false; |
| 219 // If there is no fallthrough node, such as a non-default case label | 251 // If there is no fallthrough node, such as a non-default case label |
| 220 // for a switch instruction, then there is no opportunity to | 252 // for a switch instruction, then there is no opportunity to |
| 221 // optimize. | 253 // optimize. |
| 222 if (getTargetFalse() == nullptr) | 254 if (getTargetFalse() == nullptr) |
| 223 return false; | 255 return false; |
| 224 | 256 |
| 225 // Unconditional branch to the next node can be removed. | 257 // Unconditional branch to the next node can be removed. |
| 226 if (isUnconditionalBranch() && getTargetFalse() == NextNode) { | 258 if (isUnconditionalBranch() && getTargetFalse() == NextNode) { |
| 227 assert(getTargetTrue() == nullptr); | 259 assert(getTargetTrue() == nullptr); |
| 228 setDeleted(); | 260 setDeleted(); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 257 } | 289 } |
| 258 return false; | 290 return false; |
| 259 } | 291 } |
| 260 | 292 |
| 261 InstARM32Call::InstARM32Call(Cfg *Func, Variable *Dest, Operand *CallTarget) | 293 InstARM32Call::InstARM32Call(Cfg *Func, Variable *Dest, Operand *CallTarget) |
| 262 : InstARM32(Func, InstARM32::Call, 1, Dest) { | 294 : InstARM32(Func, InstARM32::Call, 1, Dest) { |
| 263 HasSideEffects = true; | 295 HasSideEffects = true; |
| 264 addSource(CallTarget); | 296 addSource(CallTarget); |
| 265 } | 297 } |
| 266 | 298 |
| 267 InstARM32Cmp::InstARM32Cmp(Cfg *Func, Variable *Src1, Operand *Src2, | 299 InstARM32Label::InstARM32Label(Cfg *Func, TargetARM32 *Target) |
| 268 CondARM32::Cond Predicate) | 300 : InstARM32(Func, InstARM32::Label, 0, nullptr), |
| 269 : InstARM32Pred(Func, InstARM32::Cmp, 2, nullptr, Predicate) { | 301 Number(Target->makeNextLabelNumber()) {} |
| 270 addSource(Src1); | 302 |
| 271 addSource(Src2); | 303 IceString InstARM32Label::getName(const Cfg *Func) const { |
| 304 return ".L" + Func->getFunctionName() + "$local$__" + std::to_string(Number); |
| 272 } | 305 } |
| 273 | 306 |
| 274 InstARM32Ldr::InstARM32Ldr(Cfg *Func, Variable *Dest, OperandARM32Mem *Mem, | 307 InstARM32Ldr::InstARM32Ldr(Cfg *Func, Variable *Dest, OperandARM32Mem *Mem, |
| 275 CondARM32::Cond Predicate) | 308 CondARM32::Cond Predicate) |
| 276 : InstARM32Pred(Func, InstARM32::Ldr, 1, Dest, Predicate) { | 309 : InstARM32Pred(Func, InstARM32::Ldr, 1, Dest, Predicate) { |
| 277 addSource(Mem); | 310 addSource(Mem); |
| 278 } | 311 } |
| 279 | 312 |
| 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) | 313 InstARM32Pop::InstARM32Pop(Cfg *Func, const VarList &Dests) |
| 290 : InstARM32(Func, InstARM32::Pop, 0, nullptr), Dests(Dests) { | 314 : InstARM32(Func, InstARM32::Pop, 0, nullptr), Dests(Dests) { |
| 291 // Track modifications to Dests separately via FakeDefs. | 315 // Track modifications to Dests separately via FakeDefs. |
| 292 // Also, a pop instruction affects the stack pointer and so it should not | 316 // 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 | 317 // be allowed to be automatically dead-code eliminated. This is automatic |
| 294 // since we leave the Dest as nullptr. | 318 // since we leave the Dest as nullptr. |
| 295 } | 319 } |
| 296 | 320 |
| 297 InstARM32Push::InstARM32Push(Cfg *Func, const VarList &Srcs) | 321 InstARM32Push::InstARM32Push(Cfg *Func, const VarList &Srcs) |
| 298 : InstARM32(Func, InstARM32::Push, Srcs.size(), nullptr) { | 322 : InstARM32(Func, InstARM32::Push, Srcs.size(), nullptr) { |
| 299 for (Variable *Source : Srcs) | 323 for (Variable *Source : Srcs) |
| 300 addSource(Source); | 324 addSource(Source); |
| 301 } | 325 } |
| 302 | 326 |
| 303 InstARM32Ret::InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source) | 327 InstARM32Ret::InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source) |
| 304 : InstARM32(Func, InstARM32::Ret, Source ? 2 : 1, nullptr) { | 328 : InstARM32(Func, InstARM32::Ret, Source ? 2 : 1, nullptr) { |
| 305 addSource(LR); | 329 addSource(LR); |
| 306 if (Source) | 330 if (Source) |
| 307 addSource(Source); | 331 addSource(Source); |
| 308 } | 332 } |
| 309 | 333 |
| 310 InstARM32Str::InstARM32Str(Cfg *Func, Variable *Value, OperandARM32Mem *Mem, | 334 InstARM32Str::InstARM32Str(Cfg *Func, Variable *Value, OperandARM32Mem *Mem, |
| 311 CondARM32::Cond Predicate) | 335 CondARM32::Cond Predicate) |
| 312 : InstARM32Pred(Func, InstARM32::Str, 2, nullptr, Predicate) { | 336 : InstARM32Pred(Func, InstARM32::Str, 2, nullptr, Predicate) { |
| 313 addSource(Value); | 337 addSource(Value); |
| 314 addSource(Mem); | 338 addSource(Mem); |
| 315 } | 339 } |
| 316 | 340 |
| 341 InstARM32Trap::InstARM32Trap(Cfg *Func) |
| 342 : InstARM32(Func, InstARM32::Trap, 0, nullptr) {} |
| 343 |
| 317 InstARM32Umull::InstARM32Umull(Cfg *Func, Variable *DestLo, Variable *DestHi, | 344 InstARM32Umull::InstARM32Umull(Cfg *Func, Variable *DestLo, Variable *DestHi, |
| 318 Variable *Src0, Variable *Src1, | 345 Variable *Src0, Variable *Src1, |
| 319 CondARM32::Cond Predicate) | 346 CondARM32::Cond Predicate) |
| 320 : InstARM32Pred(Func, InstARM32::Umull, 2, DestLo, Predicate), | 347 : InstARM32Pred(Func, InstARM32::Umull, 2, DestLo, Predicate), |
| 321 // DestHi is expected to have a FakeDef inserted by the lowering code. | 348 // DestHi is expected to have a FakeDef inserted by the lowering code. |
| 322 DestHi(DestHi) { | 349 DestHi(DestHi) { |
| 323 addSource(Src0); | 350 addSource(Src0); |
| 324 addSource(Src1); | 351 addSource(Src1); |
| 325 } | 352 } |
| 326 | 353 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 341 template <> const char *InstARM32And::Opcode = "and"; | 368 template <> const char *InstARM32And::Opcode = "and"; |
| 342 template <> const char *InstARM32Asr::Opcode = "asr"; | 369 template <> const char *InstARM32Asr::Opcode = "asr"; |
| 343 template <> const char *InstARM32Bic::Opcode = "bic"; | 370 template <> const char *InstARM32Bic::Opcode = "bic"; |
| 344 template <> const char *InstARM32Eor::Opcode = "eor"; | 371 template <> const char *InstARM32Eor::Opcode = "eor"; |
| 345 template <> const char *InstARM32Lsl::Opcode = "lsl"; | 372 template <> const char *InstARM32Lsl::Opcode = "lsl"; |
| 346 template <> const char *InstARM32Lsr::Opcode = "lsr"; | 373 template <> const char *InstARM32Lsr::Opcode = "lsr"; |
| 347 template <> const char *InstARM32Mul::Opcode = "mul"; | 374 template <> const char *InstARM32Mul::Opcode = "mul"; |
| 348 template <> const char *InstARM32Orr::Opcode = "orr"; | 375 template <> const char *InstARM32Orr::Opcode = "orr"; |
| 349 template <> const char *InstARM32Rsb::Opcode = "rsb"; | 376 template <> const char *InstARM32Rsb::Opcode = "rsb"; |
| 350 template <> const char *InstARM32Sbc::Opcode = "sbc"; | 377 template <> const char *InstARM32Sbc::Opcode = "sbc"; |
| 378 template <> const char *InstARM32Sdiv::Opcode = "sdiv"; |
| 351 template <> const char *InstARM32Sub::Opcode = "sub"; | 379 template <> const char *InstARM32Sub::Opcode = "sub"; |
| 380 template <> const char *InstARM32Udiv::Opcode = "udiv"; |
| 381 // Four-addr ops |
| 382 template <> const char *InstARM32Mla::Opcode = "mla"; |
| 383 template <> const char *InstARM32Mls::Opcode = "mls"; |
| 384 // Cmp-like ops |
| 385 template <> const char *InstARM32Cmp::Opcode = "cmp"; |
| 386 template <> const char *InstARM32Tst::Opcode = "tst"; |
| 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 26 matching lines...) Expand all Loading... |
| 472 return; | 516 return; |
| 473 Ostream &Str = Func->getContext()->getStrDump(); | 517 Ostream &Str = Func->getContext()->getStrDump(); |
| 474 if (getDest()) { | 518 if (getDest()) { |
| 475 dumpDest(Func); | 519 dumpDest(Func); |
| 476 Str << " = "; | 520 Str << " = "; |
| 477 } | 521 } |
| 478 Str << "call "; | 522 Str << "call "; |
| 479 getCallTarget()->dump(Func); | 523 getCallTarget()->dump(Func); |
| 480 } | 524 } |
| 481 | 525 |
| 482 void InstARM32Cmp::emit(const Cfg *Func) const { | 526 void InstARM32Label::emit(const Cfg *Func) const { |
| 483 if (!BuildDefs::dump()) | 527 if (!BuildDefs::dump()) |
| 484 return; | 528 return; |
| 485 Ostream &Str = Func->getContext()->getStrEmit(); | 529 Ostream &Str = Func->getContext()->getStrEmit(); |
| 486 assert(getSrcSize() == 2); | 530 Str << getName(Func) << ":"; |
| 487 Str << "\t" | |
| 488 << "cmp" << getPredicate() << "\t"; | |
| 489 getSrc(0)->emit(Func); | |
| 490 Str << ", "; | |
| 491 getSrc(1)->emit(Func); | |
| 492 } | 531 } |
| 493 | 532 |
| 494 void InstARM32Cmp::emitIAS(const Cfg *Func) const { | 533 void InstARM32Label::emitIAS(const Cfg *Func) const { |
| 495 assert(getSrcSize() == 2); | |
| 496 (void)Func; | 534 (void)Func; |
| 497 llvm_unreachable("Not yet implemented"); | 535 llvm_unreachable("Not yet implemented"); |
| 498 } | 536 } |
| 499 | 537 |
| 500 void InstARM32Cmp::dump(const Cfg *Func) const { | 538 void InstARM32Label::dump(const Cfg *Func) const { |
| 501 if (!BuildDefs::dump()) | 539 if (!BuildDefs::dump()) |
| 502 return; | 540 return; |
| 503 Ostream &Str = Func->getContext()->getStrDump(); | 541 Ostream &Str = Func->getContext()->getStrDump(); |
| 504 dumpOpcodePred(Str, "cmp", getSrc(0)->getType()); | 542 Str << getName(Func) << ":"; |
| 505 dumpSources(Func); | |
| 506 } | 543 } |
| 507 | 544 |
| 508 void InstARM32Ldr::emit(const Cfg *Func) const { | 545 void InstARM32Ldr::emit(const Cfg *Func) const { |
| 509 if (!BuildDefs::dump()) | 546 if (!BuildDefs::dump()) |
| 510 return; | 547 return; |
| 511 Ostream &Str = Func->getContext()->getStrEmit(); | 548 Ostream &Str = Func->getContext()->getStrEmit(); |
| 512 assert(getSrcSize() == 1); | 549 assert(getSrcSize() == 1); |
| 513 assert(getDest()->hasReg()); | 550 assert(getDest()->hasReg()); |
| 514 Type Ty = getSrc(0)->getType(); | 551 Type Ty = getSrc(0)->getType(); |
| 515 Str << "\t" | 552 Str << "\t" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 529 if (!BuildDefs::dump()) | 566 if (!BuildDefs::dump()) |
| 530 return; | 567 return; |
| 531 Ostream &Str = Func->getContext()->getStrDump(); | 568 Ostream &Str = Func->getContext()->getStrDump(); |
| 532 dumpDest(Func); | 569 dumpDest(Func); |
| 533 Str << " = "; | 570 Str << " = "; |
| 534 dumpOpcodePred(Str, "ldr", getDest()->getType()); | 571 dumpOpcodePred(Str, "ldr", getDest()->getType()); |
| 535 Str << " "; | 572 Str << " "; |
| 536 dumpSources(Func); | 573 dumpSources(Func); |
| 537 } | 574 } |
| 538 | 575 |
| 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 | |
| 573 template <> void InstARM32Movw::emit(const Cfg *Func) const { | 576 template <> void InstARM32Movw::emit(const Cfg *Func) const { |
| 574 if (!BuildDefs::dump()) | 577 if (!BuildDefs::dump()) |
| 575 return; | 578 return; |
| 576 Ostream &Str = Func->getContext()->getStrEmit(); | 579 Ostream &Str = Func->getContext()->getStrEmit(); |
| 577 assert(getSrcSize() == 1); | 580 assert(getSrcSize() == 1); |
| 578 Str << "\t" << Opcode << getPredicate() << "\t"; | 581 Str << "\t" << Opcode << getPredicate() << "\t"; |
| 579 getDest()->emit(Func); | 582 getDest()->emit(Func); |
| 580 Str << ", "; | 583 Str << ", "; |
| 581 Constant *Src0 = llvm::cast<Constant>(getSrc(0)); | 584 Constant *Src0 = llvm::cast<Constant>(getSrc(0)); |
| 582 if (auto CR = llvm::dyn_cast<ConstantRelocatable>(Src0)) { | 585 if (auto CR = llvm::dyn_cast<ConstantRelocatable>(Src0)) { |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 750 return; | 753 return; |
| 751 Ostream &Str = Func->getContext()->getStrDump(); | 754 Ostream &Str = Func->getContext()->getStrDump(); |
| 752 Type Ty = getSrc(0)->getType(); | 755 Type Ty = getSrc(0)->getType(); |
| 753 dumpOpcodePred(Str, "str", Ty); | 756 dumpOpcodePred(Str, "str", Ty); |
| 754 Str << " "; | 757 Str << " "; |
| 755 getSrc(1)->dump(Func); | 758 getSrc(1)->dump(Func); |
| 756 Str << ", "; | 759 Str << ", "; |
| 757 getSrc(0)->dump(Func); | 760 getSrc(0)->dump(Func); |
| 758 } | 761 } |
| 759 | 762 |
| 763 void InstARM32Trap::emit(const Cfg *Func) const { |
| 764 if (!BuildDefs::dump()) |
| 765 return; |
| 766 Ostream &Str = Func->getContext()->getStrEmit(); |
| 767 assert(getSrcSize() == 0); |
| 768 // There isn't a mnemonic for the special NaCl Trap encoding, so dump |
| 769 // the raw bytes. |
| 770 Str << "\t.long 0x"; |
| 771 ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
| 772 for (uint8_t I : Asm->getNonExecBundlePadding()) { |
| 773 Str.write_hex(I); |
| 774 } |
| 775 } |
| 776 |
| 777 void InstARM32Trap::emitIAS(const Cfg *Func) const { |
| 778 assert(getSrcSize() == 0); |
| 779 (void)Func; |
| 780 llvm_unreachable("Not yet implemented"); |
| 781 } |
| 782 |
| 783 void InstARM32Trap::dump(const Cfg *Func) const { |
| 784 if (!BuildDefs::dump()) |
| 785 return; |
| 786 Ostream &Str = Func->getContext()->getStrDump(); |
| 787 Str << "trap"; |
| 788 } |
| 789 |
| 760 void InstARM32Umull::emit(const Cfg *Func) const { | 790 void InstARM32Umull::emit(const Cfg *Func) const { |
| 761 if (!BuildDefs::dump()) | 791 if (!BuildDefs::dump()) |
| 762 return; | 792 return; |
| 763 Ostream &Str = Func->getContext()->getStrEmit(); | 793 Ostream &Str = Func->getContext()->getStrEmit(); |
| 764 assert(getSrcSize() == 2); | 794 assert(getSrcSize() == 2); |
| 765 assert(getDest()->hasReg()); | 795 assert(getDest()->hasReg()); |
| 766 Str << "\t" | 796 Str << "\t" |
| 767 << "umull" << getPredicate() << "\t"; | 797 << "umull" << getPredicate() << "\t"; |
| 768 getDest()->emit(Func); | 798 getDest()->emit(Func); |
| 769 Str << ", "; | 799 Str << ", "; |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 900 if (getShiftOp() != kNoShift) { | 930 if (getShiftOp() != kNoShift) { |
| 901 Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " "; | 931 Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " "; |
| 902 if (Func) | 932 if (Func) |
| 903 getShiftAmt()->dump(Func); | 933 getShiftAmt()->dump(Func); |
| 904 else | 934 else |
| 905 getShiftAmt()->dump(Str); | 935 getShiftAmt()->dump(Str); |
| 906 } | 936 } |
| 907 } | 937 } |
| 908 | 938 |
| 909 } // end of namespace Ice | 939 } // end of namespace Ice |
| OLD | NEW |