OLD | NEW |
1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// | 1 //===- subzero/src/IceInstX8632.cpp - X86-32 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 InstX8632 and OperandX8632 classes, | 10 // This file implements the InstX8632 and OperandX8632 classes, |
11 // primarily the constructors and the dump()/emit() methods. | 11 // primarily the constructors and the dump()/emit() methods. |
12 // | 12 // |
13 //===----------------------------------------------------------------------===// | 13 //===----------------------------------------------------------------------===// |
14 | 14 |
| 15 #include "assembler_ia32.h" |
15 #include "IceCfg.h" | 16 #include "IceCfg.h" |
16 #include "IceCfgNode.h" | 17 #include "IceCfgNode.h" |
17 #include "IceInst.h" | 18 #include "IceInst.h" |
18 #include "IceInstX8632.h" | 19 #include "IceInstX8632.h" |
19 #include "IceTargetLoweringX8632.h" | 20 #include "IceTargetLoweringX8632.h" |
20 #include "IceOperand.h" | 21 #include "IceOperand.h" |
21 | 22 |
22 namespace Ice { | 23 namespace Ice { |
23 | 24 |
24 namespace { | 25 namespace { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 ICETYPEX8632_TABLE | 57 ICETYPEX8632_TABLE |
57 #undef X | 58 #undef X |
58 }; | 59 }; |
59 | 60 |
60 const char *InstX8632SegmentRegNames[] = { | 61 const char *InstX8632SegmentRegNames[] = { |
61 #define X(val, name) name, | 62 #define X(val, name) name, |
62 SEG_REGX8632_TABLE | 63 SEG_REGX8632_TABLE |
63 #undef X | 64 #undef X |
64 }; | 65 }; |
65 | 66 |
| 67 x86::Condition convertToAsmCondition(InstX8632::BrCond Cond) { |
| 68 return x86::Condition(Cond); |
| 69 } |
| 70 |
| 71 x86::Register convertToAsmGPR(int32_t RegNum) { |
| 72 assert(TargetX8632::Reg_eax <= RegNum && RegNum <= TargetX8632::Reg_edi); |
| 73 // TODO(jvoung): do some sort of cross-check that the numbers are the same. |
| 74 return x86::Register(RegNum); |
| 75 } |
| 76 |
| 77 x86::ByteRegister convertToAsmByteRegister(int32_t RegNum) { |
| 78 if (RegNum == TargetX8632::Reg_ah) { |
| 79 return x86::AH; |
| 80 } |
| 81 // TODO(jvoung): do some sort of cross-check that the numbers are the same. |
| 82 assert(TargetX8632::Reg_eax <= RegNum && RegNum <= TargetX8632::Reg_ebx); |
| 83 return x86::ByteRegister(RegNum); |
| 84 } |
| 85 |
| 86 x86::XmmRegister convertToAsmXMMReg(int32_t RegNum) { |
| 87 assert(TargetX8632::Reg_xmm0 <= RegNum && RegNum <= TargetX8632::Reg_xmm7); |
| 88 // TODO(jvoung): do some sort of cross-check that the numbers are the same. |
| 89 return x86::XmmRegister(RegNum - TargetX8632::Reg_xmm0); |
| 90 } |
| 91 |
| 92 // Convert a float or double immediate to an Address Operand. |
| 93 // Modifies SymbolicOffset to contain the symbol. |
| 94 x86::Address convertImmToAsmAddress(const Constant *Imm, |
| 95 IceString &SymbolicOffset) { |
| 96 std::string Buffer; |
| 97 llvm::raw_string_ostream StrBuf(Buffer); |
| 98 Type Ty = Imm->getType(); |
| 99 assert(llvm::isa<ConstantFloat>(Imm) || llvm::isa<ConstantDouble>(Imm)); |
| 100 StrBuf << "L$" << Ty << "$" << Imm->getPoolEntryID(); |
| 101 SymbolicOffset = StrBuf.str(); |
| 102 return x86::Address::Absolute(0); |
| 103 } |
| 104 |
66 } // end of anonymous namespace | 105 } // end of anonymous namespace |
67 | 106 |
68 const char *InstX8632::getWidthString(Type Ty) { | 107 const char *InstX8632::getWidthString(Type Ty) { |
69 return TypeX8632Attributes[Ty].WidthString; | 108 return TypeX8632Attributes[Ty].WidthString; |
70 } | 109 } |
71 | 110 |
72 OperandX8632Mem::OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base, | 111 OperandX8632Mem::OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base, |
73 Constant *Offset, Variable *Index, | 112 Constant *Offset, Variable *Index, |
74 uint16_t Shift, SegmentRegisters SegmentReg) | 113 uint16_t Shift, SegmentRegisters SegmentReg) |
75 : OperandX8632(kMem, Ty), Base(Base), Offset(Offset), Index(Index), | 114 : OperandX8632(kMem, Ty), Base(Base), Offset(Offset), Index(Index), |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 } | 316 } |
278 | 317 |
279 InstX8632Xchg::InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source) | 318 InstX8632Xchg::InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source) |
280 : InstX8632(Func, InstX8632::Xchg, 2, llvm::dyn_cast<Variable>(Dest)) { | 319 : InstX8632(Func, InstX8632::Xchg, 2, llvm::dyn_cast<Variable>(Dest)) { |
281 addSource(Dest); | 320 addSource(Dest); |
282 addSource(Source); | 321 addSource(Source); |
283 } | 322 } |
284 | 323 |
285 // ======================== Dump routines ======================== // | 324 // ======================== Dump routines ======================== // |
286 | 325 |
| 326 namespace { |
| 327 |
| 328 void emitIASBytes(Ostream &Str, const x86::AssemblerX86 *Asm, |
| 329 intptr_t StartPosition) { |
| 330 intptr_t EndPosition = Asm->GetPosition(); |
| 331 for (intptr_t i = 0; i < EndPosition - StartPosition; ++i) { |
| 332 Str << "\t.byte " |
| 333 << static_cast<uint32_t>(Asm->LoadBuffer(StartPosition + i)) << "\n"; |
| 334 } |
| 335 } |
| 336 |
| 337 void emitIASBytesRelocatable(Ostream &Str, const x86::AssemblerX86 *Asm, |
| 338 intptr_t StartPosition, |
| 339 const IceString &SymbolicOffset) { |
| 340 const intptr_t OffsetSize = 4; |
| 341 intptr_t EndPosition = Asm->GetPosition() - OffsetSize; |
| 342 for (intptr_t i = 0; i < EndPosition - StartPosition; ++i) { |
| 343 Str << "\t.byte " |
| 344 << static_cast<uint32_t>(Asm->LoadBuffer(StartPosition + i)) << "\n"; |
| 345 } |
| 346 Str << "\t.long " << SymbolicOffset << "\n"; |
| 347 } |
| 348 |
| 349 void emitIASDestSrcXMM(const Cfg *Func, const Variable *Dest, |
| 350 const Operand *Src, |
| 351 x86::AssemblerX86::EmitXmmXmm EmitXmmXmm, |
| 352 x86::AssemblerX86::EmitXmmAddr EmitXmmAddr) { |
| 353 Ostream &Str = Func->getContext()->getStrEmit(); |
| 354 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 355 intptr_t StartPosition = Asm->GetPosition(); |
| 356 assert(Dest->hasReg()); |
| 357 x86::XmmRegister DestReg = convertToAsmXMMReg(Dest->getRegNum()); |
| 358 IceString SymbolicOffset = ""; |
| 359 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 360 if (SrcVar->hasReg()) { |
| 361 x86::XmmRegister SrcReg = convertToAsmXMMReg(SrcVar->getRegNum()); |
| 362 (Asm->*EmitXmmXmm)(DestReg, SrcReg); |
| 363 } else { |
| 364 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) |
| 365 ->stackVarToAsmOperand(SrcVar); |
| 366 (Asm->*EmitXmmAddr)(DestReg, SrcStackAddr); |
| 367 } |
| 368 } else if (const OperandX8632Mem *Mem = |
| 369 llvm::dyn_cast<OperandX8632Mem>(Src)) { |
| 370 x86::Address SrcAddr = Mem->convertToAsmAddress(SymbolicOffset); |
| 371 (Asm->*EmitXmmAddr)(DestReg, SrcAddr); |
| 372 } else if (const Constant *Imm = llvm::dyn_cast<Constant>(Src)) { |
| 373 (Asm->*EmitXmmAddr)(DestReg, convertImmToAsmAddress(Imm, SymbolicOffset)); |
| 374 } else { |
| 375 llvm_unreachable("Unexpected operand type"); |
| 376 } |
| 377 // TODO(jvoung): Record the buffer position containing the relocation, |
| 378 // instead of just assuming it's the last 4 bytes. |
| 379 if (!SymbolicOffset.empty()) { |
| 380 emitIASBytesRelocatable(Str, Asm, StartPosition, SymbolicOffset); |
| 381 } else { |
| 382 emitIASBytes(Str, Asm, StartPosition); |
| 383 } |
| 384 } |
| 385 |
| 386 } // end of anonymous namespace |
| 387 |
287 void InstX8632::dump(const Cfg *Func) const { | 388 void InstX8632::dump(const Cfg *Func) const { |
288 Ostream &Str = Func->getContext()->getStrDump(); | 389 Ostream &Str = Func->getContext()->getStrDump(); |
289 Str << "[X8632] "; | 390 Str << "[X8632] "; |
290 Inst::dump(Func); | 391 Inst::dump(Func); |
291 } | 392 } |
292 | 393 |
| 394 void InstX8632::emitIAS(const Cfg *Func) const { emit(Func); } |
| 395 |
293 void InstX8632Label::emit(const Cfg *Func) const { | 396 void InstX8632Label::emit(const Cfg *Func) const { |
294 Ostream &Str = Func->getContext()->getStrEmit(); | 397 Ostream &Str = Func->getContext()->getStrEmit(); |
295 Str << getName(Func) << ":\n"; | 398 Str << getName(Func) << ":\n"; |
296 } | 399 } |
297 | 400 |
298 void InstX8632Label::dump(const Cfg *Func) const { | 401 void InstX8632Label::dump(const Cfg *Func) const { |
299 Ostream &Str = Func->getContext()->getStrDump(); | 402 Ostream &Str = Func->getContext()->getStrDump(); |
300 Str << getName(Func) << ":"; | 403 Str << getName(Func) << ":"; |
301 } | 404 } |
302 | 405 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 | 450 |
348 void InstX8632Call::emit(const Cfg *Func) const { | 451 void InstX8632Call::emit(const Cfg *Func) const { |
349 Ostream &Str = Func->getContext()->getStrEmit(); | 452 Ostream &Str = Func->getContext()->getStrEmit(); |
350 assert(getSrcSize() == 1); | 453 assert(getSrcSize() == 1); |
351 Str << "\tcall\t"; | 454 Str << "\tcall\t"; |
352 getCallTarget()->emit(Func); | 455 getCallTarget()->emit(Func); |
353 Str << "\n"; | 456 Str << "\n"; |
354 Func->getTarget()->resetStackAdjustment(); | 457 Func->getTarget()->resetStackAdjustment(); |
355 } | 458 } |
356 | 459 |
| 460 void InstX8632Call::emitIAS(const Cfg *Func) const { |
| 461 Ostream &Str = Func->getContext()->getStrEmit(); |
| 462 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 463 intptr_t StartPosition = Asm->GetPosition(); |
| 464 Operand *Target = getCallTarget(); |
| 465 IceString SymbolicOffset = ""; |
| 466 if (Variable *Var = llvm::dyn_cast<Variable>(Target)) { |
| 467 if (Var->hasReg()) { |
| 468 Asm->call(convertToAsmGPR(Var->getRegNum())); |
| 469 } else { |
| 470 Asm->call(static_cast<TargetX8632 *>(Func->getTarget()) |
| 471 ->stackVarToAsmOperand(Var)); |
| 472 } |
| 473 } else if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Target)) { |
| 474 Asm->call(Mem->convertToAsmAddress(SymbolicOffset)); |
| 475 } else if (ConstantRelocatable *CR = |
| 476 llvm::dyn_cast<ConstantRelocatable>(Target)) { |
| 477 assert(CR->getOffset() == 0 && "We only support calling a function"); |
| 478 SymbolicOffset = CR->getName(); |
| 479 Asm->call(CR); |
| 480 } |
| 481 if (!SymbolicOffset.empty()) { |
| 482 // TODO(jvoung): This .byte and .long hack doesn't work, since we need |
| 483 // a pc-rel relocation, and we also need the section contents to be |
| 484 // -4 instead of 0. |
| 485 // |
| 486 // Still, we have at least filled the assembler buffer so that the |
| 487 // instruction sizes/positions are correct for jumps. |
| 488 // |
| 489 // For now, fall back to the regular .s emission. |
| 490 emit(Func); |
| 491 } else { |
| 492 emitIASBytes(Str, Asm, StartPosition); |
| 493 } |
| 494 Func->getTarget()->resetStackAdjustment(); |
| 495 } |
| 496 |
357 void InstX8632Call::dump(const Cfg *Func) const { | 497 void InstX8632Call::dump(const Cfg *Func) const { |
358 Ostream &Str = Func->getContext()->getStrDump(); | 498 Ostream &Str = Func->getContext()->getStrDump(); |
359 if (getDest()) { | 499 if (getDest()) { |
360 dumpDest(Func); | 500 dumpDest(Func); |
361 Str << " = "; | 501 Str << " = "; |
362 } | 502 } |
363 Str << "call "; | 503 Str << "call "; |
364 getCallTarget()->dump(Func); | 504 getCallTarget()->dump(Func); |
365 } | 505 } |
366 | 506 |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
470 assert(getSrcSize() == 1); | 610 assert(getSrcSize() == 1); |
471 Type Ty = getSrc(0)->getType(); | 611 Type Ty = getSrc(0)->getType(); |
472 assert(Ty == IceType_f32 || Ty == IceType_f64); | 612 assert(Ty == IceType_f32 || Ty == IceType_f64); |
473 Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t"; | 613 Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t"; |
474 getDest()->emit(Func); | 614 getDest()->emit(Func); |
475 Str << ", "; | 615 Str << ", "; |
476 getSrc(0)->emit(Func); | 616 getSrc(0)->emit(Func); |
477 Str << "\n"; | 617 Str << "\n"; |
478 } | 618 } |
479 | 619 |
| 620 template <> void InstX8632Sqrtss::emitIAS(const Cfg *Func) const { |
| 621 assert(getDest()->hasReg()); |
| 622 assert(getSrcSize() == 1); |
| 623 const Operand *Src = getSrc(0); |
| 624 Type Ty = getSrc(0)->getType(); |
| 625 assert(Ty == IceType_f32 || Ty == IceType_f64); |
| 626 if (Ty == IceType_f64) { |
| 627 emitIASDestSrcXMM(Func, getDest(), Src, &x86::AssemblerX86::sqrtsd, |
| 628 &x86::AssemblerX86::sqrtsd); |
| 629 } else { |
| 630 emitIASDestSrcXMM(Func, getDest(), Src, &x86::AssemblerX86::sqrtss, |
| 631 &x86::AssemblerX86::sqrtss); |
| 632 } |
| 633 } |
| 634 |
| 635 template <> void InstX8632Addps::emitIAS(const Cfg *Func) const { |
| 636 assert(getSrcSize() == 2); |
| 637 emitIASDestSrcXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::addps, |
| 638 &x86::AssemblerX86::addps); |
| 639 } |
| 640 |
480 template <> void InstX8632Addss::emit(const Cfg *Func) const { | 641 template <> void InstX8632Addss::emit(const Cfg *Func) const { |
481 char buf[30]; | 642 char buf[30]; |
482 snprintf(buf, llvm::array_lengthof(buf), "add%s", | 643 snprintf(buf, llvm::array_lengthof(buf), "add%s", |
483 TypeX8632Attributes[getDest()->getType()].SdSsString); | 644 TypeX8632Attributes[getDest()->getType()].SdSsString); |
484 emitTwoAddress(buf, this, Func); | 645 emitTwoAddress(buf, this, Func); |
485 } | 646 } |
486 | 647 |
| 648 template <> void InstX8632Addss::emitIAS(const Cfg *Func) const { |
| 649 Type Ty = getDest()->getType(); |
| 650 assert(getSrcSize() == 2); |
| 651 if (Ty == IceType_f64) { |
| 652 emitIASDestSrcXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::addsd, |
| 653 &x86::AssemblerX86::addsd); |
| 654 } else { |
| 655 emitIASDestSrcXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::addss, |
| 656 &x86::AssemblerX86::addss); |
| 657 } |
| 658 } |
| 659 |
487 template <> void InstX8632Padd::emit(const Cfg *Func) const { | 660 template <> void InstX8632Padd::emit(const Cfg *Func) const { |
488 char buf[30]; | 661 char buf[30]; |
489 snprintf(buf, llvm::array_lengthof(buf), "padd%s", | 662 snprintf(buf, llvm::array_lengthof(buf), "padd%s", |
490 TypeX8632Attributes[getDest()->getType()].PackString); | 663 TypeX8632Attributes[getDest()->getType()].PackString); |
491 emitTwoAddress(buf, this, Func); | 664 emitTwoAddress(buf, this, Func); |
492 } | 665 } |
493 | 666 |
494 template <> void InstX8632Pmull::emit(const Cfg *Func) const { | 667 template <> void InstX8632Pmull::emit(const Cfg *Func) const { |
495 char buf[30]; | 668 char buf[30]; |
496 bool TypesAreValid = getDest()->getType() == IceType_v4i32 || | 669 bool TypesAreValid = getDest()->getType() == IceType_v4i32 || |
497 getDest()->getType() == IceType_v8i16; | 670 getDest()->getType() == IceType_v8i16; |
498 bool InstructionSetIsValid = | 671 bool InstructionSetIsValid = |
499 getDest()->getType() == IceType_v8i16 || | 672 getDest()->getType() == IceType_v8i16 || |
500 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 673 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
501 TargetX8632::SSE4_1; | 674 TargetX8632::SSE4_1; |
502 (void)TypesAreValid; | 675 (void)TypesAreValid; |
503 (void)InstructionSetIsValid; | 676 (void)InstructionSetIsValid; |
504 assert(TypesAreValid); | 677 assert(TypesAreValid); |
505 assert(InstructionSetIsValid); | 678 assert(InstructionSetIsValid); |
506 snprintf(buf, llvm::array_lengthof(buf), "pmull%s", | 679 snprintf(buf, llvm::array_lengthof(buf), "pmull%s", |
507 TypeX8632Attributes[getDest()->getType()].PackString); | 680 TypeX8632Attributes[getDest()->getType()].PackString); |
508 emitTwoAddress(buf, this, Func); | 681 emitTwoAddress(buf, this, Func); |
509 } | 682 } |
510 | 683 |
| 684 template <> void InstX8632Subps::emitIAS(const Cfg *Func) const { |
| 685 assert(getSrcSize() == 2); |
| 686 emitIASDestSrcXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::subps, |
| 687 &x86::AssemblerX86::subps); |
| 688 } |
| 689 |
511 template <> void InstX8632Subss::emit(const Cfg *Func) const { | 690 template <> void InstX8632Subss::emit(const Cfg *Func) const { |
512 char buf[30]; | 691 char buf[30]; |
513 snprintf(buf, llvm::array_lengthof(buf), "sub%s", | 692 snprintf(buf, llvm::array_lengthof(buf), "sub%s", |
514 TypeX8632Attributes[getDest()->getType()].SdSsString); | 693 TypeX8632Attributes[getDest()->getType()].SdSsString); |
515 emitTwoAddress(buf, this, Func); | 694 emitTwoAddress(buf, this, Func); |
516 } | 695 } |
517 | 696 |
| 697 template <> void InstX8632Subss::emitIAS(const Cfg *Func) const { |
| 698 Type Ty = getDest()->getType(); |
| 699 assert(getSrcSize() == 2); |
| 700 if (Ty == IceType_f64) { |
| 701 emitIASDestSrcXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::subsd, |
| 702 &x86::AssemblerX86::subsd); |
| 703 } else { |
| 704 emitIASDestSrcXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::subss, |
| 705 &x86::AssemblerX86::subss); |
| 706 } |
| 707 } |
| 708 |
518 template <> void InstX8632Psub::emit(const Cfg *Func) const { | 709 template <> void InstX8632Psub::emit(const Cfg *Func) const { |
519 char buf[30]; | 710 char buf[30]; |
520 snprintf(buf, llvm::array_lengthof(buf), "psub%s", | 711 snprintf(buf, llvm::array_lengthof(buf), "psub%s", |
521 TypeX8632Attributes[getDest()->getType()].PackString); | 712 TypeX8632Attributes[getDest()->getType()].PackString); |
522 emitTwoAddress(buf, this, Func); | 713 emitTwoAddress(buf, this, Func); |
523 } | 714 } |
524 | 715 |
| 716 template <> void InstX8632Mulps::emitIAS(const Cfg *Func) const { |
| 717 assert(getSrcSize() == 2); |
| 718 emitIASDestSrcXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::mulps, |
| 719 &x86::AssemblerX86::mulps); |
| 720 } |
| 721 |
525 template <> void InstX8632Mulss::emit(const Cfg *Func) const { | 722 template <> void InstX8632Mulss::emit(const Cfg *Func) const { |
526 char buf[30]; | 723 char buf[30]; |
527 snprintf(buf, llvm::array_lengthof(buf), "mul%s", | 724 snprintf(buf, llvm::array_lengthof(buf), "mul%s", |
528 TypeX8632Attributes[getDest()->getType()].SdSsString); | 725 TypeX8632Attributes[getDest()->getType()].SdSsString); |
529 emitTwoAddress(buf, this, Func); | 726 emitTwoAddress(buf, this, Func); |
530 } | 727 } |
531 | 728 |
| 729 template <> void InstX8632Mulss::emitIAS(const Cfg *Func) const { |
| 730 Type Ty = getDest()->getType(); |
| 731 assert(getSrcSize() == 2); |
| 732 if (Ty == IceType_f64) { |
| 733 emitIASDestSrcXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::mulsd, |
| 734 &x86::AssemblerX86::mulsd); |
| 735 } else { |
| 736 emitIASDestSrcXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::mulss, |
| 737 &x86::AssemblerX86::mulss); |
| 738 } |
| 739 } |
| 740 |
532 template <> void InstX8632Pmuludq::emit(const Cfg *Func) const { | 741 template <> void InstX8632Pmuludq::emit(const Cfg *Func) const { |
533 assert(getSrc(0)->getType() == IceType_v4i32 && | 742 assert(getSrc(0)->getType() == IceType_v4i32 && |
534 getSrc(1)->getType() == IceType_v4i32); | 743 getSrc(1)->getType() == IceType_v4i32); |
535 emitTwoAddress(Opcode, this, Func); | 744 emitTwoAddress(Opcode, this, Func); |
536 } | 745 } |
537 | 746 |
| 747 template <> void InstX8632Divps::emitIAS(const Cfg *Func) const { |
| 748 assert(getSrcSize() == 2); |
| 749 emitIASDestSrcXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::divps, |
| 750 &x86::AssemblerX86::divps); |
| 751 } |
| 752 |
538 template <> void InstX8632Divss::emit(const Cfg *Func) const { | 753 template <> void InstX8632Divss::emit(const Cfg *Func) const { |
539 char buf[30]; | 754 char buf[30]; |
540 snprintf(buf, llvm::array_lengthof(buf), "div%s", | 755 snprintf(buf, llvm::array_lengthof(buf), "div%s", |
541 TypeX8632Attributes[getDest()->getType()].SdSsString); | 756 TypeX8632Attributes[getDest()->getType()].SdSsString); |
542 emitTwoAddress(buf, this, Func); | 757 emitTwoAddress(buf, this, Func); |
543 } | 758 } |
544 | 759 |
| 760 template <> void InstX8632Divss::emitIAS(const Cfg *Func) const { |
| 761 Type Ty = getDest()->getType(); |
| 762 assert(getSrcSize() == 2); |
| 763 if (Ty == IceType_f64) { |
| 764 emitIASDestSrcXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::divsd, |
| 765 &x86::AssemblerX86::divsd); |
| 766 } else { |
| 767 emitIASDestSrcXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::divss, |
| 768 &x86::AssemblerX86::divss); |
| 769 } |
| 770 } |
| 771 |
545 template <> void InstX8632Div::emit(const Cfg *Func) const { | 772 template <> void InstX8632Div::emit(const Cfg *Func) const { |
546 Ostream &Str = Func->getContext()->getStrEmit(); | 773 Ostream &Str = Func->getContext()->getStrEmit(); |
547 assert(getSrcSize() == 3); | 774 assert(getSrcSize() == 3); |
548 Str << "\t" << Opcode << "\t"; | 775 Str << "\t" << Opcode << "\t"; |
549 getSrc(1)->emit(Func); | 776 getSrc(1)->emit(Func); |
550 Str << "\n"; | 777 Str << "\n"; |
551 } | 778 } |
552 | 779 |
553 template <> void InstX8632Idiv::emit(const Cfg *Func) const { | 780 template <> void InstX8632Idiv::emit(const Cfg *Func) const { |
554 Ostream &Str = Func->getContext()->getStrEmit(); | 781 Ostream &Str = Func->getContext()->getStrEmit(); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
632 assert(getDest()->getRegNum() == TargetX8632::Reg_edx); | 859 assert(getDest()->getRegNum() == TargetX8632::Reg_edx); |
633 Str << "\tcwd\n"; | 860 Str << "\tcwd\n"; |
634 break; | 861 break; |
635 case IceType_i32: | 862 case IceType_i32: |
636 assert(getDest()->getRegNum() == TargetX8632::Reg_edx); | 863 assert(getDest()->getRegNum() == TargetX8632::Reg_edx); |
637 Str << "\tcdq\n"; | 864 Str << "\tcdq\n"; |
638 break; | 865 break; |
639 } | 866 } |
640 } | 867 } |
641 | 868 |
| 869 template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const { |
| 870 Ostream &Str = Func->getContext()->getStrEmit(); |
| 871 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 872 intptr_t StartPosition = Asm->GetPosition(); |
| 873 assert(getSrcSize() == 1); |
| 874 Operand *Src0 = getSrc(0); |
| 875 assert(llvm::isa<Variable>(Src0)); |
| 876 assert(llvm::cast<Variable>(Src0)->getRegNum() == TargetX8632::Reg_eax); |
| 877 switch (Src0->getType()) { |
| 878 default: |
| 879 llvm_unreachable("unexpected source type!"); |
| 880 break; |
| 881 case IceType_i8: |
| 882 assert(getDest()->getRegNum() == TargetX8632::Reg_eax); |
| 883 Asm->cbw(); |
| 884 break; |
| 885 case IceType_i16: |
| 886 assert(getDest()->getRegNum() == TargetX8632::Reg_edx); |
| 887 Asm->cwd(); |
| 888 break; |
| 889 case IceType_i32: |
| 890 assert(getDest()->getRegNum() == TargetX8632::Reg_edx); |
| 891 Asm->cdq(); |
| 892 break; |
| 893 } |
| 894 emitIASBytes(Str, Asm, StartPosition); |
| 895 } |
| 896 |
642 void InstX8632Mul::emit(const Cfg *Func) const { | 897 void InstX8632Mul::emit(const Cfg *Func) const { |
643 Ostream &Str = Func->getContext()->getStrEmit(); | 898 Ostream &Str = Func->getContext()->getStrEmit(); |
644 assert(getSrcSize() == 2); | 899 assert(getSrcSize() == 2); |
645 assert(llvm::isa<Variable>(getSrc(0))); | 900 assert(llvm::isa<Variable>(getSrc(0))); |
646 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == | 901 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == |
647 TargetX8632::Reg_eax); | 902 TargetX8632::Reg_eax); |
648 assert(getDest()->getRegNum() == TargetX8632::Reg_eax); // TODO: allow edx? | 903 assert(getDest()->getRegNum() == TargetX8632::Reg_eax); // TODO: allow edx? |
649 Str << "\tmul\t"; | 904 Str << "\tmul\t"; |
650 getSrc(1)->emit(Func); | 905 getSrc(1)->emit(Func); |
651 Str << "\n"; | 906 Str << "\n"; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
715 Str << "\t"; | 970 Str << "\t"; |
716 assert(Condition != Br_None); | 971 assert(Condition != Br_None); |
717 assert(getDest()->hasReg()); | 972 assert(getDest()->hasReg()); |
718 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "\t"; | 973 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "\t"; |
719 getDest()->emit(Func); | 974 getDest()->emit(Func); |
720 Str << ", "; | 975 Str << ", "; |
721 getSrc(1)->emit(Func); | 976 getSrc(1)->emit(Func); |
722 Str << "\n"; | 977 Str << "\n"; |
723 } | 978 } |
724 | 979 |
| 980 void InstX8632Cmov::emitIAS(const Cfg *Func) const { |
| 981 Ostream &Str = Func->getContext()->getStrEmit(); |
| 982 assert(Condition != Br_None); |
| 983 assert(getDest()->hasReg()); |
| 984 assert(getSrcSize() == 2); |
| 985 const Variable *Src = llvm::cast<Variable>(getSrc(1)); |
| 986 // Only need the 32-bit register form right now. |
| 987 assert(Src->hasReg()); |
| 988 assert(Src->getType() == IceType_i32); |
| 989 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 990 intptr_t StartPosition = Asm->GetPosition(); |
| 991 Asm->cmov(convertToAsmCondition(Condition), |
| 992 convertToAsmGPR(getDest()->getRegNum()), |
| 993 convertToAsmGPR(Src->getRegNum())); |
| 994 emitIASBytes(Str, Asm, StartPosition); |
| 995 } |
| 996 |
725 void InstX8632Cmov::dump(const Cfg *Func) const { | 997 void InstX8632Cmov::dump(const Cfg *Func) const { |
726 Ostream &Str = Func->getContext()->getStrDump(); | 998 Ostream &Str = Func->getContext()->getStrDump(); |
727 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "."; | 999 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "."; |
728 Str << getDest()->getType() << " "; | 1000 Str << getDest()->getType() << " "; |
729 dumpDest(Func); | 1001 dumpDest(Func); |
730 Str << ", "; | 1002 Str << ", "; |
731 dumpSources(Func); | 1003 dumpSources(Func); |
732 } | 1004 } |
733 | 1005 |
734 void InstX8632Cmpps::emit(const Cfg *Func) const { | 1006 void InstX8632Cmpps::emit(const Cfg *Func) const { |
735 Ostream &Str = Func->getContext()->getStrEmit(); | 1007 Ostream &Str = Func->getContext()->getStrEmit(); |
736 assert(getSrcSize() == 2); | 1008 assert(getSrcSize() == 2); |
737 assert(Condition < Cmpps_Invalid); | 1009 assert(Condition < Cmpps_Invalid); |
738 Str << "\t"; | 1010 Str << "\t"; |
739 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" | 1011 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" |
740 << "\t"; | 1012 << "\t"; |
741 getDest()->emit(Func); | 1013 getDest()->emit(Func); |
742 Str << ", "; | 1014 Str << ", "; |
743 getSrc(1)->emit(Func); | 1015 getSrc(1)->emit(Func); |
744 Str << "\n"; | 1016 Str << "\n"; |
745 } | 1017 } |
746 | 1018 |
| 1019 void InstX8632Cmpps::emitIAS(const Cfg *Func) const { |
| 1020 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1021 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1022 intptr_t StartPosition = Asm->GetPosition(); |
| 1023 assert(getSrcSize() == 2); |
| 1024 assert(Condition < Cmpps_Invalid); |
| 1025 // Assuming there isn't any load folding for cmpps, and vector constants |
| 1026 // are not allowed in PNaCl. |
| 1027 assert(llvm::isa<Variable>(getSrc(1))); |
| 1028 const Variable *SrcVar = llvm::cast<Variable>(getSrc(1)); |
| 1029 if (SrcVar->hasReg()) { |
| 1030 Asm->cmpps(convertToAsmXMMReg(getDest()->getRegNum()), |
| 1031 convertToAsmXMMReg(SrcVar->getRegNum()), Condition); |
| 1032 } else { |
| 1033 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) |
| 1034 ->stackVarToAsmOperand(SrcVar); |
| 1035 Asm->cmpps(convertToAsmXMMReg(getDest()->getRegNum()), SrcStackAddr, |
| 1036 Condition); |
| 1037 } |
| 1038 emitIASBytes(Str, Asm, StartPosition); |
| 1039 } |
| 1040 |
747 void InstX8632Cmpps::dump(const Cfg *Func) const { | 1041 void InstX8632Cmpps::dump(const Cfg *Func) const { |
748 Ostream &Str = Func->getContext()->getStrDump(); | 1042 Ostream &Str = Func->getContext()->getStrDump(); |
749 assert(Condition < Cmpps_Invalid); | 1043 assert(Condition < Cmpps_Invalid); |
750 dumpDest(Func); | 1044 dumpDest(Func); |
751 Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" | 1045 Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" |
752 << "\t"; | 1046 << "\t"; |
753 dumpSources(Func); | 1047 dumpSources(Func); |
754 } | 1048 } |
755 | 1049 |
756 void InstX8632Cmpxchg::emit(const Cfg *Func) const { | 1050 void InstX8632Cmpxchg::emit(const Cfg *Func) const { |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
990 // value between a vector and a scalar (which movss is used for). | 1284 // value between a vector and a scalar (which movss is used for). |
991 // Clean this up. | 1285 // Clean this up. |
992 assert(Func->getTarget()->typeWidthInBytesOnStack(getDest()->getType()) == | 1286 assert(Func->getTarget()->typeWidthInBytesOnStack(getDest()->getType()) == |
993 Func->getTarget()->typeWidthInBytesOnStack(Src->getType())); | 1287 Func->getTarget()->typeWidthInBytesOnStack(Src->getType())); |
994 getDest()->asType(Src->getType()).emit(Func); | 1288 getDest()->asType(Src->getType()).emit(Func); |
995 Str << ", "; | 1289 Str << ", "; |
996 Src->emit(Func); | 1290 Src->emit(Func); |
997 Str << "\n"; | 1291 Str << "\n"; |
998 } | 1292 } |
999 | 1293 |
| 1294 template <> void InstX8632Mov::emitIAS(const Cfg *Func) const { |
| 1295 // Could be movss/sd, or movb/movw/movl. |
| 1296 emit(Func); |
| 1297 } |
| 1298 |
1000 template <> void InstX8632Movp::emit(const Cfg *Func) const { | 1299 template <> void InstX8632Movp::emit(const Cfg *Func) const { |
1001 // TODO(wala,stichnot): movups works with all vector operands, but | 1300 // TODO(wala,stichnot): movups works with all vector operands, but |
1002 // there exist other instructions (movaps, movdqa, movdqu) that may | 1301 // there exist other instructions (movaps, movdqa, movdqu) that may |
1003 // perform better, depending on the data type and alignment of the | 1302 // perform better, depending on the data type and alignment of the |
1004 // operands. | 1303 // operands. |
1005 Ostream &Str = Func->getContext()->getStrEmit(); | 1304 Ostream &Str = Func->getContext()->getStrEmit(); |
1006 assert(getSrcSize() == 1); | 1305 assert(getSrcSize() == 1); |
1007 Str << "\tmovups\t"; | 1306 Str << "\tmovups\t"; |
1008 getDest()->emit(Func); | 1307 getDest()->emit(Func); |
1009 Str << ", "; | 1308 Str << ", "; |
1010 getSrc(0)->emit(Func); | 1309 getSrc(0)->emit(Func); |
1011 Str << "\n"; | 1310 Str << "\n"; |
1012 } | 1311 } |
1013 | 1312 |
1014 template <> void InstX8632Movq::emit(const Cfg *Func) const { | 1313 template <> void InstX8632Movq::emit(const Cfg *Func) const { |
1015 Ostream &Str = Func->getContext()->getStrEmit(); | 1314 Ostream &Str = Func->getContext()->getStrEmit(); |
1016 assert(getSrcSize() == 1); | 1315 assert(getSrcSize() == 1); |
1017 assert(getDest()->getType() == IceType_i64 || | 1316 assert(getDest()->getType() == IceType_i64 || |
1018 getDest()->getType() == IceType_f64); | 1317 getDest()->getType() == IceType_f64); |
1019 Str << "\tmovq\t"; | 1318 Str << "\tmovq\t"; |
1020 getDest()->emit(Func); | 1319 getDest()->emit(Func); |
1021 Str << ", "; | 1320 Str << ", "; |
1022 getSrc(0)->emit(Func); | 1321 getSrc(0)->emit(Func); |
1023 Str << "\n"; | 1322 Str << "\n"; |
1024 } | 1323 } |
1025 | 1324 |
| 1325 static void emitIASSignZeroExt(const Cfg *Func, const Variable *Dest, |
| 1326 const Operand *Src0, |
| 1327 x86::AssemblerX86::EmitRegByteR EmitByte, |
| 1328 x86::AssemblerX86::EmitRegReg EmitWord, |
| 1329 x86::AssemblerX86::EmitRegAddr EmitAddress) { |
| 1330 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1331 assert(Dest->hasReg()); |
| 1332 x86::Register DestReg = convertToAsmGPR(Dest->getRegNum()); |
| 1333 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1334 intptr_t StartPosition = Asm->GetPosition(); |
| 1335 IceString SymbolicOffset = ""; |
| 1336 Type SrcType = Src0->getType(); |
| 1337 // Source is ByteReg, WordReg, or stack slot, or other memory operand. |
| 1338 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src0)) { |
| 1339 if (SrcVar->hasReg()) { |
| 1340 if (SrcType == IceType_i8 || SrcType == IceType_i1) { |
| 1341 (Asm->*EmitByte)(DestReg, |
| 1342 convertToAsmByteRegister(SrcVar->getRegNum())); |
| 1343 } else { |
| 1344 assert(SrcType == IceType_i16); |
| 1345 (Asm->*EmitWord)(DestReg, convertToAsmGPR(SrcVar->getRegNum())); |
| 1346 } |
| 1347 } else { |
| 1348 x86::Address StackAddr = static_cast<TargetX8632 *>(Func->getTarget()) |
| 1349 ->stackVarToAsmOperand(SrcVar); |
| 1350 (Asm->*EmitAddress)(DestReg, StackAddr); |
| 1351 } |
| 1352 } else if (const OperandX8632Mem *Mem = |
| 1353 llvm::dyn_cast<OperandX8632Mem>(Src0)) { |
| 1354 x86::Address SrcAddr = Mem->convertToAsmAddress(SymbolicOffset); |
| 1355 (Asm->*EmitAddress)(DestReg, SrcAddr); |
| 1356 } else { |
| 1357 llvm_unreachable("Unexpected operand type for Movzx"); |
| 1358 } |
| 1359 |
| 1360 if (!SymbolicOffset.empty()) { |
| 1361 emitIASBytesRelocatable(Str, Func->getAssembler<x86::AssemblerX86>(), |
| 1362 StartPosition, SymbolicOffset); |
| 1363 } else { |
| 1364 emitIASBytes(Str, Func->getAssembler<x86::AssemblerX86>(), StartPosition); |
| 1365 } |
| 1366 } |
| 1367 |
1026 void InstX8632Movsx::emit(const Cfg *Func) const { | 1368 void InstX8632Movsx::emit(const Cfg *Func) const { |
1027 Ostream &Str = Func->getContext()->getStrEmit(); | 1369 Ostream &Str = Func->getContext()->getStrEmit(); |
1028 assert(getSrcSize() == 1); | 1370 assert(getSrcSize() == 1); |
1029 Str << "\tmovsx\t"; | 1371 Str << "\tmovsx\t"; |
1030 getDest()->emit(Func); | 1372 getDest()->emit(Func); |
1031 Str << ", "; | 1373 Str << ", "; |
1032 getSrc(0)->emit(Func); | 1374 getSrc(0)->emit(Func); |
1033 Str << "\n"; | 1375 Str << "\n"; |
1034 } | 1376 } |
1035 | 1377 |
| 1378 void InstX8632Movsx::emitIAS(const Cfg *Func) const { |
| 1379 assert(getSrcSize() == 1); |
| 1380 const Operand *Src0 = getSrc(0); |
| 1381 Type SrcType = Src0->getType(); |
| 1382 if (SrcType == IceType_i8 || SrcType == IceType_i1) { |
| 1383 emitIASSignZeroExt(Func, getDest(), Src0, &x86::AssemblerX86::movsxb, |
| 1384 &x86::AssemblerX86::movsxw, &x86::AssemblerX86::movsxb); |
| 1385 } else { |
| 1386 assert(SrcType == IceType_i16); |
| 1387 emitIASSignZeroExt(Func, getDest(), Src0, &x86::AssemblerX86::movsxb, |
| 1388 &x86::AssemblerX86::movsxw, &x86::AssemblerX86::movsxw); |
| 1389 } |
| 1390 } |
| 1391 |
1036 void InstX8632Movsx::dump(const Cfg *Func) const { | 1392 void InstX8632Movsx::dump(const Cfg *Func) const { |
1037 Ostream &Str = Func->getContext()->getStrDump(); | 1393 Ostream &Str = Func->getContext()->getStrDump(); |
1038 Str << "movsx." << getDest()->getType() << "." << getSrc(0)->getType(); | 1394 Str << "movsx." << getDest()->getType() << "." << getSrc(0)->getType(); |
1039 Str << " "; | 1395 Str << " "; |
1040 dumpDest(Func); | 1396 dumpDest(Func); |
1041 Str << ", "; | 1397 Str << ", "; |
1042 dumpSources(Func); | 1398 dumpSources(Func); |
1043 } | 1399 } |
1044 | 1400 |
1045 void InstX8632Movzx::emit(const Cfg *Func) const { | 1401 void InstX8632Movzx::emit(const Cfg *Func) const { |
1046 Ostream &Str = Func->getContext()->getStrEmit(); | 1402 Ostream &Str = Func->getContext()->getStrEmit(); |
1047 assert(getSrcSize() == 1); | 1403 assert(getSrcSize() == 1); |
1048 Str << "\tmovzx\t"; | 1404 Str << "\tmovzx\t"; |
1049 getDest()->emit(Func); | 1405 getDest()->emit(Func); |
1050 Str << ", "; | 1406 Str << ", "; |
1051 getSrc(0)->emit(Func); | 1407 getSrc(0)->emit(Func); |
1052 Str << "\n"; | 1408 Str << "\n"; |
1053 } | 1409 } |
1054 | 1410 |
| 1411 void InstX8632Movzx::emitIAS(const Cfg *Func) const { |
| 1412 assert(getSrcSize() == 1); |
| 1413 const Operand *Src0 = getSrc(0); |
| 1414 Type SrcType = Src0->getType(); |
| 1415 if (SrcType == IceType_i8 || SrcType == IceType_i1) { |
| 1416 emitIASSignZeroExt(Func, getDest(), Src0, &x86::AssemblerX86::movzxb, |
| 1417 &x86::AssemblerX86::movzxw, &x86::AssemblerX86::movzxb); |
| 1418 } else { |
| 1419 assert(SrcType == IceType_i16); |
| 1420 emitIASSignZeroExt(Func, getDest(), Src0, &x86::AssemblerX86::movzxb, |
| 1421 &x86::AssemblerX86::movzxw, &x86::AssemblerX86::movzxw); |
| 1422 } |
| 1423 } |
| 1424 |
1055 void InstX8632Movzx::dump(const Cfg *Func) const { | 1425 void InstX8632Movzx::dump(const Cfg *Func) const { |
1056 Ostream &Str = Func->getContext()->getStrDump(); | 1426 Ostream &Str = Func->getContext()->getStrDump(); |
1057 Str << "movzx." << getDest()->getType() << "." << getSrc(0)->getType(); | 1427 Str << "movzx." << getDest()->getType() << "." << getSrc(0)->getType(); |
1058 Str << " "; | 1428 Str << " "; |
1059 dumpDest(Func); | 1429 dumpDest(Func); |
1060 Str << ", "; | 1430 Str << ", "; |
1061 dumpSources(Func); | 1431 dumpSources(Func); |
1062 } | 1432 } |
1063 | 1433 |
1064 void InstX8632Nop::emit(const Cfg *Func) const { | 1434 void InstX8632Nop::emit(const Cfg *Func) const { |
1065 Ostream &Str = Func->getContext()->getStrEmit(); | 1435 Ostream &Str = Func->getContext()->getStrEmit(); |
1066 // TODO: Emit the right code for each variant. | 1436 // TODO: Emit the right code for each variant. |
1067 Str << "\tnop\t# variant = " << Variant << "\n"; | 1437 Str << "\tnop\t# variant = " << Variant << "\n"; |
1068 } | 1438 } |
1069 | 1439 |
| 1440 void InstX8632Nop::emitIAS(const Cfg *Func) const { |
| 1441 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1442 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1443 intptr_t StartPosition = Asm->GetPosition(); |
| 1444 // TODO: Emit the right code for the variant. |
| 1445 Asm->nop(); |
| 1446 emitIASBytes(Str, Asm, StartPosition); |
| 1447 } |
| 1448 |
1070 void InstX8632Nop::dump(const Cfg *Func) const { | 1449 void InstX8632Nop::dump(const Cfg *Func) const { |
1071 Ostream &Str = Func->getContext()->getStrDump(); | 1450 Ostream &Str = Func->getContext()->getStrDump(); |
1072 Str << "nop (variant = " << Variant << ")"; | 1451 Str << "nop (variant = " << Variant << ")"; |
1073 } | 1452 } |
1074 | 1453 |
1075 void InstX8632Fld::emit(const Cfg *Func) const { | 1454 void InstX8632Fld::emit(const Cfg *Func) const { |
1076 Ostream &Str = Func->getContext()->getStrEmit(); | 1455 Ostream &Str = Func->getContext()->getStrEmit(); |
1077 assert(getSrcSize() == 1); | 1456 assert(getSrcSize() == 1); |
1078 Type Ty = getSrc(0)->getType(); | 1457 Type Ty = getSrc(0)->getType(); |
1079 Variable *Var = llvm::dyn_cast<Variable>(getSrc(0)); | 1458 Variable *Var = llvm::dyn_cast<Variable>(getSrc(0)); |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1194 Src1->emit(Func); | 1573 Src1->emit(Func); |
1195 } | 1574 } |
1196 Str << ", "; | 1575 Str << ", "; |
1197 getSrc(2)->emit(Func); | 1576 getSrc(2)->emit(Func); |
1198 Str << "\n"; | 1577 Str << "\n"; |
1199 } | 1578 } |
1200 | 1579 |
1201 void InstX8632Pop::emit(const Cfg *Func) const { | 1580 void InstX8632Pop::emit(const Cfg *Func) const { |
1202 Ostream &Str = Func->getContext()->getStrEmit(); | 1581 Ostream &Str = Func->getContext()->getStrEmit(); |
1203 assert(getSrcSize() == 0); | 1582 assert(getSrcSize() == 0); |
| 1583 assert(getDest()->getType() == IceType_i32); |
1204 Str << "\tpop\t"; | 1584 Str << "\tpop\t"; |
1205 getDest()->emit(Func); | 1585 getDest()->emit(Func); |
1206 Str << "\n"; | 1586 Str << "\n"; |
1207 } | 1587 } |
1208 | 1588 |
| 1589 void InstX8632Pop::emitIAS(const Cfg *Func) const { |
| 1590 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1591 assert(getSrcSize() == 0); |
| 1592 assert(getDest()->getType() == IceType_i32); |
| 1593 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1594 intptr_t StartPosition = Asm->GetPosition(); |
| 1595 if (getDest()->hasReg()) { |
| 1596 Asm->popl(convertToAsmGPR(getDest()->getRegNum())); |
| 1597 } else { |
| 1598 Asm->popl(static_cast<TargetX8632 *>(Func->getTarget()) |
| 1599 ->stackVarToAsmOperand(getDest())); |
| 1600 } |
| 1601 emitIASBytes(Str, Asm, StartPosition); |
| 1602 } |
| 1603 |
1209 void InstX8632Pop::dump(const Cfg *Func) const { | 1604 void InstX8632Pop::dump(const Cfg *Func) const { |
1210 Ostream &Str = Func->getContext()->getStrDump(); | 1605 Ostream &Str = Func->getContext()->getStrDump(); |
1211 dumpDest(Func); | 1606 dumpDest(Func); |
1212 Str << " = pop." << getDest()->getType() << " "; | 1607 Str << " = pop." << getDest()->getType() << " "; |
1213 } | 1608 } |
1214 | 1609 |
1215 void InstX8632AdjustStack::emit(const Cfg *Func) const { | 1610 void InstX8632AdjustStack::emit(const Cfg *Func) const { |
1216 Ostream &Str = Func->getContext()->getStrEmit(); | 1611 Ostream &Str = Func->getContext()->getStrEmit(); |
1217 Str << "\tsub\tesp, " << Amount << "\n"; | 1612 Str << "\tsub\tesp, " << Amount << "\n"; |
1218 Func->getTarget()->updateStackAdjustment(Amount); | 1613 Func->getTarget()->updateStackAdjustment(Amount); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1283 snprintf(buf, llvm::array_lengthof(buf), "psra%s", | 1678 snprintf(buf, llvm::array_lengthof(buf), "psra%s", |
1284 TypeX8632Attributes[getDest()->getType()].PackString); | 1679 TypeX8632Attributes[getDest()->getType()].PackString); |
1285 emitTwoAddress(buf, this, Func); | 1680 emitTwoAddress(buf, this, Func); |
1286 } | 1681 } |
1287 | 1682 |
1288 void InstX8632Ret::emit(const Cfg *Func) const { | 1683 void InstX8632Ret::emit(const Cfg *Func) const { |
1289 Ostream &Str = Func->getContext()->getStrEmit(); | 1684 Ostream &Str = Func->getContext()->getStrEmit(); |
1290 Str << "\tret\n"; | 1685 Str << "\tret\n"; |
1291 } | 1686 } |
1292 | 1687 |
| 1688 void InstX8632Ret::emitIAS(const Cfg *Func) const { |
| 1689 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1690 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1691 intptr_t StartPosition = Asm->GetPosition(); |
| 1692 Asm->ret(); |
| 1693 emitIASBytes(Str, Asm, StartPosition); |
| 1694 } |
| 1695 |
1293 void InstX8632Ret::dump(const Cfg *Func) const { | 1696 void InstX8632Ret::dump(const Cfg *Func) const { |
1294 Ostream &Str = Func->getContext()->getStrDump(); | 1697 Ostream &Str = Func->getContext()->getStrDump(); |
1295 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); | 1698 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); |
1296 Str << "ret." << Ty << " "; | 1699 Str << "ret." << Ty << " "; |
1297 dumpSources(Func); | 1700 dumpSources(Func); |
1298 } | 1701 } |
1299 | 1702 |
1300 void InstX8632Xadd::emit(const Cfg *Func) const { | 1703 void InstX8632Xadd::emit(const Cfg *Func) const { |
1301 Ostream &Str = Func->getContext()->getStrEmit(); | 1704 Ostream &Str = Func->getContext()->getStrEmit(); |
1302 if (Locked) { | 1705 if (Locked) { |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1419 Str << "+"; | 1822 Str << "+"; |
1420 Offset->dump(Func); | 1823 Offset->dump(Func); |
1421 } | 1824 } |
1422 } else { | 1825 } else { |
1423 // There is only the offset. | 1826 // There is only the offset. |
1424 Offset->dump(Func); | 1827 Offset->dump(Func); |
1425 } | 1828 } |
1426 Str << "]"; | 1829 Str << "]"; |
1427 } | 1830 } |
1428 | 1831 |
| 1832 x86::Address |
| 1833 OperandX8632Mem::convertToAsmAddress(IceString &SymbolicOffset) const { |
| 1834 int32_t Disp = 0; |
| 1835 // Determine the offset (is it relocatable?) |
| 1836 if (ConstantInteger *CI = llvm::dyn_cast<ConstantInteger>(getOffset())) { |
| 1837 // Should there be a subclass of ConstantInteger that is just int32_t? |
| 1838 assert(Utils::IsInt<int64_t>(32, CI->getValue())); |
| 1839 Disp = static_cast<int32_t>(CI->getValue()); |
| 1840 } else if (ConstantRelocatable *CR = |
| 1841 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { |
| 1842 SymbolicOffset = CR->getName(); |
| 1843 assert(CR->getOffset() == 0 && "Not yet handling Reloc + offset"); |
| 1844 } |
| 1845 |
| 1846 // Now convert to the various possible forms. |
| 1847 if (getBase() && getIndex()) { |
| 1848 return x86::Address(convertToAsmGPR(getBase()->getRegNum()), |
| 1849 convertToAsmGPR(getIndex()->getRegNum()), |
| 1850 x86::ScaleFactor(getShift()), Disp); |
| 1851 } else if (getBase()) { |
| 1852 return x86::Address(convertToAsmGPR(getBase()->getRegNum()), Disp); |
| 1853 } else if (getIndex()) { |
| 1854 return x86::Address(convertToAsmGPR(getIndex()->getRegNum()), |
| 1855 x86::ScaleFactor(getShift()), Disp); |
| 1856 } else { |
| 1857 assert(!SymbolicOffset.empty() && Disp == 0 && |
| 1858 "Remaining case is symbolic offset..."); |
| 1859 return x86::Address::Absolute(Disp); |
| 1860 } |
| 1861 } |
| 1862 |
1429 void VariableSplit::emit(const Cfg *Func) const { | 1863 void VariableSplit::emit(const Cfg *Func) const { |
1430 Ostream &Str = Func->getContext()->getStrEmit(); | 1864 Ostream &Str = Func->getContext()->getStrEmit(); |
1431 assert(Var->getLocalUseNode() == NULL || | 1865 assert(Var->getLocalUseNode() == NULL || |
1432 Var->getLocalUseNode() == Func->getCurrentNode()); | 1866 Var->getLocalUseNode() == Func->getCurrentNode()); |
1433 assert(!Var->hasReg()); | 1867 assert(!Var->hasReg()); |
1434 // The following is copied/adapted from TargetX8632::emitVariable(). | 1868 // The following is copied/adapted from TargetX8632::emitVariable(). |
1435 const TargetLowering *Target = Func->getTarget(); | 1869 const TargetLowering *Target = Func->getTarget(); |
1436 const Type Ty = IceType_i32; | 1870 const Type Ty = IceType_i32; |
1437 Str << TypeX8632Attributes[Ty].WidthString << " [" | 1871 Str << TypeX8632Attributes[Ty].WidthString << " [" |
1438 << Target->getRegName(Target->getFrameOrStackReg(), Ty); | 1872 << Target->getRegName(Target->getFrameOrStackReg(), Ty); |
(...skipping 20 matching lines...) Expand all Loading... |
1459 default: | 1893 default: |
1460 Str << "???"; | 1894 Str << "???"; |
1461 break; | 1895 break; |
1462 } | 1896 } |
1463 Str << "("; | 1897 Str << "("; |
1464 Var->dump(Func); | 1898 Var->dump(Func); |
1465 Str << ")"; | 1899 Str << ")"; |
1466 } | 1900 } |
1467 | 1901 |
1468 } // end of namespace Ice | 1902 } // end of namespace Ice |
OLD | NEW |