| 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, |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 55 const char *WidthString; // {byte,word,dword,qword} ptr | 55 const char *WidthString; // {byte,word,dword,qword} ptr |
| 56 } TypeX8632Attributes[] = { | 56 } TypeX8632Attributes[] = { |
| 57 #define X(tag, elementty, cvt, sdss, pack, width) \ | 57 #define X(tag, elementty, cvt, sdss, pack, width) \ |
| 58 { cvt, "" sdss, pack, width } \ | 58 { cvt, "" sdss, pack, width } \ |
| 59 , | 59 , |
| 60 ICETYPEX8632_TABLE | 60 ICETYPEX8632_TABLE |
| 61 #undef X | 61 #undef X |
| 62 }; | 62 }; |
| 63 | 63 |
| 64 const char *InstX8632SegmentRegNames[] = { | 64 const char *InstX8632SegmentRegNames[] = { |
| 65 #define X(val, name) name, | 65 #define X(val, name, prefix) name, |
| 66 SEG_REGX8632_TABLE | 66 SEG_REGX8632_TABLE |
| 67 #undef X | 67 #undef X |
| 68 }; | 68 }; |
| 69 |
| 70 uint8_t InstX8632SegmentPrefixes[] = { |
| 71 #define X(val, name, prefix) prefix, |
| 72 SEG_REGX8632_TABLE |
| 73 #undef X |
| 74 }; |
| 69 | 75 |
| 70 } // end of anonymous namespace | 76 } // end of anonymous namespace |
| 71 | 77 |
| 72 const char *InstX8632::getWidthString(Type Ty) { | 78 const char *InstX8632::getWidthString(Type Ty) { |
| 73 return TypeX8632Attributes[Ty].WidthString; | 79 return TypeX8632Attributes[Ty].WidthString; |
| 74 } | 80 } |
| 75 | 81 |
| 76 OperandX8632Mem::OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base, | 82 OperandX8632Mem::OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base, |
| 77 Constant *Offset, Variable *Index, | 83 Constant *Offset, Variable *Index, |
| 78 uint16_t Shift, SegmentRegisters SegmentReg) | 84 uint16_t Shift, SegmentRegisters SegmentReg) |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 327 InstX8632Xchg::InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source) | 333 InstX8632Xchg::InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source) |
| 328 : InstX8632(Func, InstX8632::Xchg, 2, llvm::dyn_cast<Variable>(Dest)) { | 334 : InstX8632(Func, InstX8632::Xchg, 2, llvm::dyn_cast<Variable>(Dest)) { |
| 329 addSource(Dest); | 335 addSource(Dest); |
| 330 addSource(Source); | 336 addSource(Source); |
| 331 } | 337 } |
| 332 | 338 |
| 333 // ======================== Dump routines ======================== // | 339 // ======================== Dump routines ======================== // |
| 334 | 340 |
| 335 namespace { | 341 namespace { |
| 336 | 342 |
| 337 void emitIASBytes(Ostream &Str, const x86::AssemblerX86 *Asm, | 343 void emitIASBytes(const Cfg *Func, const x86::AssemblerX86 *Asm, |
| 338 intptr_t StartPosition) { | 344 intptr_t StartPosition) { |
| 345 GlobalContext *Ctx = Func->getContext(); |
| 346 Ostream &Str = Ctx->getStrEmit(); |
| 339 intptr_t EndPosition = Asm->GetPosition(); | 347 intptr_t EndPosition = Asm->GetPosition(); |
| 340 intptr_t LastFixupLoc = -1; | 348 intptr_t LastFixupLoc = -1; |
| 341 AssemblerFixup *LastFixup = NULL; | 349 AssemblerFixup *LastFixup = NULL; |
| 342 if (Asm->GetLatestFixup()) { | 350 if (Asm->GetLatestFixup()) { |
| 343 LastFixup = Asm->GetLatestFixup(); | 351 LastFixup = Asm->GetLatestFixup(); |
| 344 LastFixupLoc = LastFixup->position(); | 352 LastFixupLoc = LastFixup->position(); |
| 345 } | 353 } |
| 346 if (LastFixupLoc < StartPosition) { | 354 if (LastFixupLoc < StartPosition) { |
| 347 // The fixup doesn't apply to this current block. | 355 // The fixup doesn't apply to this current block. |
| 348 for (intptr_t i = StartPosition; i < EndPosition; ++i) { | 356 for (intptr_t i = StartPosition; i < EndPosition; ++i) { |
| 349 Str << "\t.byte 0x"; | 357 Str << "\t.byte 0x"; |
| 350 Str.write_hex(Asm->LoadBuffer<uint8_t>(i)); | 358 Str.write_hex(Asm->LoadBuffer<uint8_t>(i)); |
| 351 Str << "\n"; | 359 Str << "\n"; |
| 352 } | 360 } |
| 353 return; | 361 return; |
| 354 } | 362 } |
| 355 const intptr_t FixupSize = 4; | 363 const intptr_t FixupSize = 4; |
| 356 assert(LastFixupLoc + FixupSize <= EndPosition); | 364 assert(LastFixupLoc + FixupSize <= EndPosition); |
| 357 // The fixup does apply to this current block. | 365 // The fixup does apply to this current block. |
| 358 for (intptr_t i = StartPosition; i < LastFixupLoc; ++i) { | 366 for (intptr_t i = StartPosition; i < LastFixupLoc; ++i) { |
| 359 Str << "\t.byte 0x"; | 367 Str << "\t.byte 0x"; |
| 360 Str.write_hex(Asm->LoadBuffer<uint8_t>(i)); | 368 Str.write_hex(Asm->LoadBuffer<uint8_t>(i)); |
| 361 Str << "\n"; | 369 Str << "\n"; |
| 362 } | 370 } |
| 363 Str << "\t.long " << LastFixup->value()->getName(); | 371 Str << "\t.long "; |
| 372 const ConstantRelocatable *Reloc = LastFixup->value(); |
| 373 if (Reloc->getSuppressMangling()) |
| 374 Str << Reloc->getName(); |
| 375 else |
| 376 Str << Ctx->mangleName(Reloc->getName()); |
| 364 if (LastFixup->value()->getOffset()) { | 377 if (LastFixup->value()->getOffset()) { |
| 365 Str << " + " << LastFixup->value()->getOffset(); | 378 Str << " + " << LastFixup->value()->getOffset(); |
| 366 } | 379 } |
| 367 Str << "\n"; | 380 Str << "\n"; |
| 368 for (intptr_t i = LastFixupLoc + FixupSize; i < EndPosition; ++i) { | 381 for (intptr_t i = LastFixupLoc + FixupSize; i < EndPosition; ++i) { |
| 369 Str << "\t.byte 0x"; | 382 Str << "\t.byte 0x"; |
| 370 Str.write_hex(Asm->LoadBuffer<uint8_t>(i)); | 383 Str.write_hex(Asm->LoadBuffer<uint8_t>(i)); |
| 371 Str << "\n"; | 384 Str << "\n"; |
| 372 } | 385 } |
| 373 } | 386 } |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 476 } | 489 } |
| 477 if (!EmittedSrc1) | 490 if (!EmittedSrc1) |
| 478 Inst->getSrc(1)->emit(Func); | 491 Inst->getSrc(1)->emit(Func); |
| 479 Str << "\n"; | 492 Str << "\n"; |
| 480 } | 493 } |
| 481 | 494 |
| 482 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op, | 495 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op, |
| 483 const x86::AssemblerX86::GPREmitterOneOp &Emitter) { | 496 const x86::AssemblerX86::GPREmitterOneOp &Emitter) { |
| 484 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 497 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 485 intptr_t StartPosition = Asm->GetPosition(); | 498 intptr_t StartPosition = Asm->GetPosition(); |
| 486 if (const Variable *Var = llvm::dyn_cast<Variable>(Op)) { | 499 if (const auto Var = llvm::dyn_cast<Variable>(Op)) { |
| 487 if (Var->hasReg()) { | 500 if (Var->hasReg()) { |
| 488 // We cheat a little and use GPRRegister even for byte operations. | 501 // We cheat a little and use GPRRegister even for byte operations. |
| 489 RegX8632::GPRRegister VarReg = | 502 RegX8632::GPRRegister VarReg = |
| 490 RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()); | 503 RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()); |
| 491 (Asm->*(Emitter.Reg))(Ty, VarReg); | 504 (Asm->*(Emitter.Reg))(Ty, VarReg); |
| 492 } else { | 505 } else { |
| 493 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 506 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 494 ->stackVarToAsmOperand(Var)); | 507 ->stackVarToAsmOperand(Var)); |
| 495 (Asm->*(Emitter.Addr))(Ty, StackAddr); | 508 (Asm->*(Emitter.Addr))(Ty, StackAddr); |
| 496 } | 509 } |
| 497 } else if (const OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Op)) { | 510 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Op)) { |
| 511 Mem->emitSegmentOverride(Asm); |
| 498 (Asm->*(Emitter.Addr))(Ty, Mem->toAsmAddress(Asm)); | 512 (Asm->*(Emitter.Addr))(Ty, Mem->toAsmAddress(Asm)); |
| 499 } else { | 513 } else { |
| 500 llvm_unreachable("Unexpected operand type"); | 514 llvm_unreachable("Unexpected operand type"); |
| 501 } | 515 } |
| 502 Ostream &Str = Func->getContext()->getStrEmit(); | 516 emitIASBytes(Func, Asm, StartPosition); |
| 503 emitIASBytes(Str, Asm, StartPosition); | |
| 504 } | 517 } |
| 505 | 518 |
| 506 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Var, | 519 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Var, |
| 507 const Operand *Src, | 520 const Operand *Src, |
| 508 const x86::AssemblerX86::GPREmitterRegOp &Emitter) { | 521 const x86::AssemblerX86::GPREmitterRegOp &Emitter) { |
| 509 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 522 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 510 intptr_t StartPosition = Asm->GetPosition(); | 523 intptr_t StartPosition = Asm->GetPosition(); |
| 511 assert(Var->hasReg()); | 524 assert(Var->hasReg()); |
| 512 // We cheat a little and use GPRRegister even for byte operations. | 525 // We cheat a little and use GPRRegister even for byte operations. |
| 513 RegX8632::GPRRegister VarReg = | 526 RegX8632::GPRRegister VarReg = |
| 514 RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()); | 527 RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()); |
| 515 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { | 528 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 516 if (SrcVar->hasReg()) { | 529 if (SrcVar->hasReg()) { |
| 517 RegX8632::GPRRegister SrcReg = | 530 RegX8632::GPRRegister SrcReg = |
| 518 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()); | 531 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()); |
| 519 (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg); | 532 (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg); |
| 520 } else { | 533 } else { |
| 521 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) | 534 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) |
| 522 ->stackVarToAsmOperand(SrcVar); | 535 ->stackVarToAsmOperand(SrcVar); |
| 523 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr); | 536 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr); |
| 524 } | 537 } |
| 525 } else if (const OperandX8632Mem *Mem = | 538 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { |
| 526 llvm::dyn_cast<OperandX8632Mem>(Src)) { | 539 Mem->emitSegmentOverride(Asm); |
| 527 x86::Address SrcAddr = Mem->toAsmAddress(Asm); | 540 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); |
| 541 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
| 542 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); |
| 543 } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { |
| 544 AssemblerFixup *Fixup = x86::DisplacementRelocation::create( |
| 545 Asm, FK_Abs_4, Reloc); |
| 546 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Fixup)); |
| 547 } else if (const auto Split = llvm::dyn_cast<VariableSplit>(Src)) { |
| 548 x86::Address SrcAddr = Split->toAsmAddress(Func); |
| 528 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcAddr); | 549 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcAddr); |
| 529 } else if (const ConstantInteger32 *Imm = | |
| 530 llvm::dyn_cast<ConstantInteger32>(Src)) { | |
| 531 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); | |
| 532 } else { | 550 } else { |
| 533 llvm_unreachable("Unexpected operand type"); | 551 llvm_unreachable("Unexpected operand type"); |
| 534 } | 552 } |
| 535 Ostream &Str = Func->getContext()->getStrEmit(); | 553 emitIASBytes(Func, Asm, StartPosition); |
| 536 emitIASBytes(Str, Asm, StartPosition); | |
| 537 } | 554 } |
| 538 | 555 |
| 539 void emitIASAddrOpTyGPR(const Cfg *Func, Type Ty, const x86::Address &Addr, | 556 void emitIASAddrOpTyGPR(const Cfg *Func, Type Ty, const x86::Address &Addr, |
| 540 const Operand *Src, | 557 const Operand *Src, |
| 541 const x86::AssemblerX86::GPREmitterAddrOp &Emitter) { | 558 const x86::AssemblerX86::GPREmitterAddrOp &Emitter) { |
| 542 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 559 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 543 intptr_t StartPosition = Asm->GetPosition(); | 560 intptr_t StartPosition = Asm->GetPosition(); |
| 544 // Src can only be Reg or Immediate. | 561 // Src can only be Reg or Immediate. |
| 545 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { | 562 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 546 assert(SrcVar->hasReg()); | 563 assert(SrcVar->hasReg()); |
| 547 RegX8632::GPRRegister SrcReg = | 564 RegX8632::GPRRegister SrcReg = |
| 548 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()); | 565 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()); |
| 549 (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg); | 566 (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg); |
| 550 } else if (const ConstantInteger32 *Imm = | 567 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
| 551 llvm::dyn_cast<ConstantInteger32>(Src)) { | |
| 552 (Asm->*(Emitter.AddrImm))(Ty, Addr, x86::Immediate(Imm->getValue())); | 568 (Asm->*(Emitter.AddrImm))(Ty, Addr, x86::Immediate(Imm->getValue())); |
| 569 } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { |
| 570 AssemblerFixup *Fixup = x86::DisplacementRelocation::create( |
| 571 Asm, FK_Abs_4, Reloc); |
| 572 (Asm->*(Emitter.AddrImm))(Ty, Addr, x86::Immediate(Fixup)); |
| 553 } else { | 573 } else { |
| 554 llvm_unreachable("Unexpected operand type"); | 574 llvm_unreachable("Unexpected operand type"); |
| 555 } | 575 } |
| 556 Ostream &Str = Func->getContext()->getStrEmit(); | 576 emitIASBytes(Func, Asm, StartPosition); |
| 557 emitIASBytes(Str, Asm, StartPosition); | |
| 558 } | 577 } |
| 559 | 578 |
| 560 void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var, | 579 void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var, |
| 561 const Operand *Src, | 580 const Operand *Src, |
| 562 const x86::AssemblerX86::GPREmitterShiftOp &Emitter) { | 581 const x86::AssemblerX86::GPREmitterShiftOp &Emitter) { |
| 563 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 582 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 564 intptr_t StartPosition = Asm->GetPosition(); | 583 intptr_t StartPosition = Asm->GetPosition(); |
| 565 // Technically, the Dest Var can be mem as well, but we only use Reg. | 584 // Technically, the Dest Var can be mem as well, but we only use Reg. |
| 566 // We can extend this to check Dest if we decide to use that form. | 585 // We can extend this to check Dest if we decide to use that form. |
| 567 assert(Var->hasReg()); | 586 assert(Var->hasReg()); |
| 568 // We cheat a little and use GPRRegister even for byte operations. | 587 // We cheat a little and use GPRRegister even for byte operations. |
| 569 RegX8632::GPRRegister VarReg = | 588 RegX8632::GPRRegister VarReg = |
| 570 RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()); | 589 RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()); |
| 571 // Src must be reg == ECX or an Imm8. | 590 // Src must be reg == ECX or an Imm8. |
| 572 // This is asserted by the assembler. | 591 // This is asserted by the assembler. |
| 573 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { | 592 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 574 assert(SrcVar->hasReg()); | 593 assert(SrcVar->hasReg()); |
| 575 RegX8632::GPRRegister SrcReg = | 594 RegX8632::GPRRegister SrcReg = |
| 576 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()); | 595 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()); |
| 577 (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg); | 596 (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg); |
| 578 } else if (const ConstantInteger32 *Imm = | 597 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
| 579 llvm::dyn_cast<ConstantInteger32>(Src)) { | |
| 580 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); | 598 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); |
| 581 } else { | 599 } else { |
| 582 llvm_unreachable("Unexpected operand type"); | 600 llvm_unreachable("Unexpected operand type"); |
| 583 } | 601 } |
| 584 Ostream &Str = Func->getContext()->getStrEmit(); | 602 emitIASBytes(Func, Asm, StartPosition); |
| 585 emitIASBytes(Str, Asm, StartPosition); | |
| 586 } | 603 } |
| 587 | 604 |
| 588 void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var, | 605 void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var, |
| 589 const Operand *Src, | 606 const Operand *Src, |
| 590 const x86::AssemblerX86::XmmEmitterShiftOp &Emitter) { | 607 const x86::AssemblerX86::XmmEmitterShiftOp &Emitter) { |
| 591 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 608 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 592 intptr_t StartPosition = Asm->GetPosition(); | 609 intptr_t StartPosition = Asm->GetPosition(); |
| 593 assert(Var->hasReg()); | 610 assert(Var->hasReg()); |
| 594 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum()); | 611 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum()); |
| 595 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { | 612 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 596 if (SrcVar->hasReg()) { | 613 if (SrcVar->hasReg()) { |
| 597 RegX8632::XmmRegister SrcReg = | 614 RegX8632::XmmRegister SrcReg = |
| 598 RegX8632::getEncodedXmm(SrcVar->getRegNum()); | 615 RegX8632::getEncodedXmm(SrcVar->getRegNum()); |
| 599 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg); | 616 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg); |
| 600 } else { | 617 } else { |
| 601 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) | 618 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) |
| 602 ->stackVarToAsmOperand(SrcVar); | 619 ->stackVarToAsmOperand(SrcVar); |
| 603 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr); | 620 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr); |
| 604 } | 621 } |
| 605 } else if (const OperandX8632Mem *Mem = | 622 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { |
| 606 llvm::dyn_cast<OperandX8632Mem>(Src)) { | 623 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 607 x86::Address SrcAddr = Mem->toAsmAddress(Asm); | 624 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); |
| 608 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcAddr); | 625 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
| 609 } else if (const ConstantInteger32 *Imm = | |
| 610 llvm::dyn_cast<ConstantInteger32>(Src)) { | |
| 611 (Asm->*(Emitter.XmmImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); | 626 (Asm->*(Emitter.XmmImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); |
| 612 } else { | 627 } else { |
| 613 llvm_unreachable("Unexpected operand type"); | 628 llvm_unreachable("Unexpected operand type"); |
| 614 } | 629 } |
| 615 Ostream &Str = Func->getContext()->getStrEmit(); | 630 emitIASBytes(Func, Asm, StartPosition); |
| 616 emitIASBytes(Str, Asm, StartPosition); | |
| 617 } | 631 } |
| 618 | 632 |
| 619 void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var, | 633 void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var, |
| 620 const Operand *Src, | 634 const Operand *Src, |
| 621 const x86::AssemblerX86::XmmEmitterRegOp &Emitter) { | 635 const x86::AssemblerX86::XmmEmitterRegOp &Emitter) { |
| 622 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 636 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 623 intptr_t StartPosition = Asm->GetPosition(); | 637 intptr_t StartPosition = Asm->GetPosition(); |
| 624 assert(Var->hasReg()); | 638 assert(Var->hasReg()); |
| 625 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum()); | 639 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum()); |
| 626 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { | 640 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 627 if (SrcVar->hasReg()) { | 641 if (SrcVar->hasReg()) { |
| 628 RegX8632::XmmRegister SrcReg = | 642 RegX8632::XmmRegister SrcReg = |
| 629 RegX8632::getEncodedXmm(SrcVar->getRegNum()); | 643 RegX8632::getEncodedXmm(SrcVar->getRegNum()); |
| 630 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg); | 644 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg); |
| 631 } else { | 645 } else { |
| 632 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) | 646 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) |
| 633 ->stackVarToAsmOperand(SrcVar); | 647 ->stackVarToAsmOperand(SrcVar); |
| 634 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr); | 648 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr); |
| 635 } | 649 } |
| 636 } else if (const OperandX8632Mem *Mem = | 650 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { |
| 637 llvm::dyn_cast<OperandX8632Mem>(Src)) { | 651 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 638 x86::Address SrcAddr = Mem->toAsmAddress(Asm); | 652 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); |
| 639 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcAddr); | 653 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { |
| 640 } else if (const Constant *Imm = llvm::dyn_cast<Constant>(Src)) { | |
| 641 (Asm->*(Emitter.XmmAddr))( | 654 (Asm->*(Emitter.XmmAddr))( |
| 642 Ty, VarReg, x86::Address::ofConstPool(Func->getContext(), Asm, Imm)); | 655 Ty, VarReg, x86::Address::ofConstPool(Func->getContext(), Asm, Imm)); |
| 643 } else { | 656 } else { |
| 644 llvm_unreachable("Unexpected operand type"); | 657 llvm_unreachable("Unexpected operand type"); |
| 645 } | 658 } |
| 646 Ostream &Str = Func->getContext()->getStrEmit(); | 659 emitIASBytes(Func, Asm, StartPosition); |
| 647 emitIASBytes(Str, Asm, StartPosition); | |
| 648 } | 660 } |
| 649 | 661 |
| 650 template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(int32_t), | 662 template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(int32_t), |
| 651 SReg_t (*srcEnc)(int32_t)> | 663 SReg_t (*srcEnc)(int32_t)> |
| 652 void emitIASCastRegOp( | 664 void emitIASCastRegOp( |
| 653 const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src, | 665 const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src, |
| 654 const x86::AssemblerX86::CastEmitterRegOp<DReg_t, SReg_t> Emitter) { | 666 const x86::AssemblerX86::CastEmitterRegOp<DReg_t, SReg_t> Emitter) { |
| 655 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 667 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 656 intptr_t StartPosition = Asm->GetPosition(); | 668 intptr_t StartPosition = Asm->GetPosition(); |
| 657 assert(Dest->hasReg()); | 669 assert(Dest->hasReg()); |
| 658 DReg_t DestReg = destEnc(Dest->getRegNum()); | 670 DReg_t DestReg = destEnc(Dest->getRegNum()); |
| 659 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { | 671 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 660 if (SrcVar->hasReg()) { | 672 if (SrcVar->hasReg()) { |
| 661 SReg_t SrcReg = srcEnc(SrcVar->getRegNum()); | 673 SReg_t SrcReg = srcEnc(SrcVar->getRegNum()); |
| 662 (Asm->*(Emitter.RegReg))(DispatchTy, DestReg, SrcReg); | 674 (Asm->*(Emitter.RegReg))(DispatchTy, DestReg, SrcReg); |
| 663 } else { | 675 } else { |
| 664 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) | 676 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) |
| 665 ->stackVarToAsmOperand(SrcVar); | 677 ->stackVarToAsmOperand(SrcVar); |
| 666 (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, SrcStackAddr); | 678 (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, SrcStackAddr); |
| 667 } | 679 } |
| 668 } else if (const OperandX8632Mem *Mem = | 680 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { |
| 669 llvm::dyn_cast<OperandX8632Mem>(Src)) { | 681 Mem->emitSegmentOverride(Asm); |
| 670 x86::Address SrcAddr = Mem->toAsmAddress(Asm); | 682 (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, Mem->toAsmAddress(Asm)); |
| 671 (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, SrcAddr); | |
| 672 } else { | 683 } else { |
| 673 llvm_unreachable("Unexpected operand type"); | 684 llvm_unreachable("Unexpected operand type"); |
| 674 } | 685 } |
| 675 Ostream &Str = Func->getContext()->getStrEmit(); | 686 emitIASBytes(Func, Asm, StartPosition); |
| 676 emitIASBytes(Str, Asm, StartPosition); | |
| 677 } | 687 } |
| 678 | 688 |
| 679 void emitIASMovlikeXMM(const Cfg *Func, const Variable *Dest, | 689 void emitIASMovlikeXMM(const Cfg *Func, const Variable *Dest, |
| 680 const Operand *Src, | 690 const Operand *Src, |
| 681 const x86::AssemblerX86::XmmEmitterMovOps Emitter) { | 691 const x86::AssemblerX86::XmmEmitterMovOps Emitter) { |
| 682 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 692 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 683 intptr_t StartPosition = Asm->GetPosition(); | 693 intptr_t StartPosition = Asm->GetPosition(); |
| 684 if (Dest->hasReg()) { | 694 if (Dest->hasReg()) { |
| 685 RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum()); | 695 RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum()); |
| 686 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { | 696 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 687 if (SrcVar->hasReg()) { | 697 if (SrcVar->hasReg()) { |
| 688 (Asm->*(Emitter.XmmXmm))(DestReg, | 698 (Asm->*(Emitter.XmmXmm))(DestReg, |
| 689 RegX8632::getEncodedXmm(SrcVar->getRegNum())); | 699 RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
| 690 } else { | 700 } else { |
| 691 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 701 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 692 ->stackVarToAsmOperand(SrcVar)); | 702 ->stackVarToAsmOperand(SrcVar)); |
| 693 (Asm->*(Emitter.XmmAddr))(DestReg, StackAddr); | 703 (Asm->*(Emitter.XmmAddr))(DestReg, StackAddr); |
| 694 } | 704 } |
| 695 } else if (const OperandX8632Mem *SrcMem = | 705 } else if (const auto SrcMem = llvm::dyn_cast<OperandX8632Mem>(Src)) { |
| 696 llvm::dyn_cast<OperandX8632Mem>(Src)) { | 706 assert(SrcMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 697 (Asm->*(Emitter.XmmAddr))(DestReg, SrcMem->toAsmAddress(Asm)); | 707 (Asm->*(Emitter.XmmAddr))(DestReg, SrcMem->toAsmAddress(Asm)); |
| 698 } else { | 708 } else { |
| 699 llvm_unreachable("Unexpected operand type"); | 709 llvm_unreachable("Unexpected operand type"); |
| 700 } | 710 } |
| 701 } else { | 711 } else { |
| 702 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 712 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 703 ->stackVarToAsmOperand(Dest)); | 713 ->stackVarToAsmOperand(Dest)); |
| 704 // Src must be a register in this case. | 714 // Src must be a register in this case. |
| 705 const Variable *SrcVar = llvm::cast<Variable>(Src); | 715 const Variable *SrcVar = llvm::cast<Variable>(Src); |
| 706 assert(SrcVar->hasReg()); | 716 assert(SrcVar->hasReg()); |
| 707 (Asm->*(Emitter.AddrXmm))(StackAddr, | 717 (Asm->*(Emitter.AddrXmm))(StackAddr, |
| 708 RegX8632::getEncodedXmm(SrcVar->getRegNum())); | 718 RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
| 709 } | 719 } |
| 710 Ostream &Str = Func->getContext()->getStrEmit(); | 720 emitIASBytes(Func, Asm, StartPosition); |
| 711 emitIASBytes(Str, Asm, StartPosition); | |
| 712 } | 721 } |
| 713 | 722 |
| 714 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source) { | 723 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source) { |
| 715 const Variable *Src = llvm::dyn_cast<const Variable>(Source); | 724 const Variable *Src = llvm::dyn_cast<const Variable>(Source); |
| 716 if (Src == NULL) | 725 if (Src == NULL) |
| 717 return false; | 726 return false; |
| 718 if (Dest->hasReg() && Dest->getRegNum() == Src->getRegNum()) { | 727 if (Dest->hasReg() && Dest->getRegNum() == Src->getRegNum()) { |
| 719 // TODO: On x86-64, instructions like "mov eax, eax" are used to | 728 // TODO: On x86-64, instructions like "mov eax, eax" are used to |
| 720 // clear the upper 32 bits of rax. We need to recognize and | 729 // clear the upper 32 bits of rax. We need to recognize and |
| 721 // preserve these. | 730 // preserve these. |
| (...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1158 Str << "\tcwd\n"; | 1167 Str << "\tcwd\n"; |
| 1159 break; | 1168 break; |
| 1160 case IceType_i32: | 1169 case IceType_i32: |
| 1161 assert(getDest()->getRegNum() == RegX8632::Reg_edx); | 1170 assert(getDest()->getRegNum() == RegX8632::Reg_edx); |
| 1162 Str << "\tcdq\n"; | 1171 Str << "\tcdq\n"; |
| 1163 break; | 1172 break; |
| 1164 } | 1173 } |
| 1165 } | 1174 } |
| 1166 | 1175 |
| 1167 template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const { | 1176 template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const { |
| 1168 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 1169 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1177 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1170 intptr_t StartPosition = Asm->GetPosition(); | 1178 intptr_t StartPosition = Asm->GetPosition(); |
| 1171 assert(getSrcSize() == 1); | 1179 assert(getSrcSize() == 1); |
| 1172 Operand *Src0 = getSrc(0); | 1180 Operand *Src0 = getSrc(0); |
| 1173 assert(llvm::isa<Variable>(Src0)); | 1181 assert(llvm::isa<Variable>(Src0)); |
| 1174 assert(llvm::cast<Variable>(Src0)->getRegNum() == RegX8632::Reg_eax); | 1182 assert(llvm::cast<Variable>(Src0)->getRegNum() == RegX8632::Reg_eax); |
| 1175 switch (Src0->getType()) { | 1183 switch (Src0->getType()) { |
| 1176 default: | 1184 default: |
| 1177 llvm_unreachable("unexpected source type!"); | 1185 llvm_unreachable("unexpected source type!"); |
| 1178 break; | 1186 break; |
| 1179 case IceType_i8: | 1187 case IceType_i8: |
| 1180 assert(getDest()->getRegNum() == RegX8632::Reg_eax); | 1188 assert(getDest()->getRegNum() == RegX8632::Reg_eax); |
| 1181 Asm->cbw(); | 1189 Asm->cbw(); |
| 1182 break; | 1190 break; |
| 1183 case IceType_i16: | 1191 case IceType_i16: |
| 1184 assert(getDest()->getRegNum() == RegX8632::Reg_edx); | 1192 assert(getDest()->getRegNum() == RegX8632::Reg_edx); |
| 1185 Asm->cwd(); | 1193 Asm->cwd(); |
| 1186 break; | 1194 break; |
| 1187 case IceType_i32: | 1195 case IceType_i32: |
| 1188 assert(getDest()->getRegNum() == RegX8632::Reg_edx); | 1196 assert(getDest()->getRegNum() == RegX8632::Reg_edx); |
| 1189 Asm->cdq(); | 1197 Asm->cdq(); |
| 1190 break; | 1198 break; |
| 1191 } | 1199 } |
| 1192 emitIASBytes(Str, Asm, StartPosition); | 1200 emitIASBytes(Func, Asm, StartPosition); |
| 1193 } | 1201 } |
| 1194 | 1202 |
| 1195 void InstX8632Mul::emit(const Cfg *Func) const { | 1203 void InstX8632Mul::emit(const Cfg *Func) const { |
| 1196 Ostream &Str = Func->getContext()->getStrEmit(); | 1204 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1197 assert(getSrcSize() == 2); | 1205 assert(getSrcSize() == 2); |
| 1198 assert(llvm::isa<Variable>(getSrc(0))); | 1206 assert(llvm::isa<Variable>(getSrc(0))); |
| 1199 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); | 1207 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); |
| 1200 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? | 1208 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? |
| 1201 Str << "\tmul\t"; | 1209 Str << "\tmul\t"; |
| 1202 getSrc(1)->emit(Func); | 1210 getSrc(1)->emit(Func); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1280 assert(Condition != CondX86::Br_None); | 1288 assert(Condition != CondX86::Br_None); |
| 1281 assert(getDest()->hasReg()); | 1289 assert(getDest()->hasReg()); |
| 1282 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "\t"; | 1290 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "\t"; |
| 1283 getDest()->emit(Func); | 1291 getDest()->emit(Func); |
| 1284 Str << ", "; | 1292 Str << ", "; |
| 1285 getSrc(1)->emit(Func); | 1293 getSrc(1)->emit(Func); |
| 1286 Str << "\n"; | 1294 Str << "\n"; |
| 1287 } | 1295 } |
| 1288 | 1296 |
| 1289 void InstX8632Cmov::emitIAS(const Cfg *Func) const { | 1297 void InstX8632Cmov::emitIAS(const Cfg *Func) const { |
| 1290 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 1291 Str << "\t"; | |
| 1292 assert(Condition != CondX86::Br_None); | 1298 assert(Condition != CondX86::Br_None); |
| 1293 assert(getDest()->hasReg()); | 1299 assert(getDest()->hasReg()); |
| 1294 assert(getSrcSize() == 2); | 1300 assert(getSrcSize() == 2); |
| 1295 // Only need the reg/reg form now. | 1301 // Only need the reg/reg form now. |
| 1296 const Variable *Src = llvm::cast<Variable>(getSrc(1)); | 1302 const Variable *Src = llvm::cast<Variable>(getSrc(1)); |
| 1297 assert(Src->hasReg()); | 1303 assert(Src->hasReg()); |
| 1298 assert(Src->getType() == IceType_i32); | 1304 assert(Src->getType() == IceType_i32); |
| 1299 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1305 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1300 intptr_t StartPosition = Asm->GetPosition(); | 1306 intptr_t StartPosition = Asm->GetPosition(); |
| 1301 Asm->cmov(Condition, RegX8632::getEncodedGPR(getDest()->getRegNum()), | 1307 Asm->cmov(Condition, RegX8632::getEncodedGPR(getDest()->getRegNum()), |
| 1302 RegX8632::getEncodedGPR(Src->getRegNum())); | 1308 RegX8632::getEncodedGPR(Src->getRegNum())); |
| 1303 emitIASBytes(Str, Asm, StartPosition); | 1309 emitIASBytes(Func, Asm, StartPosition); |
| 1304 } | 1310 } |
| 1305 | 1311 |
| 1306 void InstX8632Cmov::dump(const Cfg *Func) const { | 1312 void InstX8632Cmov::dump(const Cfg *Func) const { |
| 1307 Ostream &Str = Func->getContext()->getStrDump(); | 1313 Ostream &Str = Func->getContext()->getStrDump(); |
| 1308 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "."; | 1314 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "."; |
| 1309 Str << getDest()->getType() << " "; | 1315 Str << getDest()->getType() << " "; |
| 1310 dumpDest(Func); | 1316 dumpDest(Func); |
| 1311 Str << ", "; | 1317 Str << ", "; |
| 1312 dumpSources(Func); | 1318 dumpSources(Func); |
| 1313 } | 1319 } |
| 1314 | 1320 |
| 1315 void InstX8632Cmpps::emit(const Cfg *Func) const { | 1321 void InstX8632Cmpps::emit(const Cfg *Func) const { |
| 1316 Ostream &Str = Func->getContext()->getStrEmit(); | 1322 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1317 assert(getSrcSize() == 2); | 1323 assert(getSrcSize() == 2); |
| 1318 assert(Condition < CondX86::Cmpps_Invalid); | 1324 assert(Condition < CondX86::Cmpps_Invalid); |
| 1319 Str << "\t"; | 1325 Str << "\t"; |
| 1320 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" | 1326 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" |
| 1321 << "\t"; | 1327 << "\t"; |
| 1322 getDest()->emit(Func); | 1328 getDest()->emit(Func); |
| 1323 Str << ", "; | 1329 Str << ", "; |
| 1324 getSrc(1)->emit(Func); | 1330 getSrc(1)->emit(Func); |
| 1325 Str << "\n"; | 1331 Str << "\n"; |
| 1326 } | 1332 } |
| 1327 | 1333 |
| 1328 void InstX8632Cmpps::emitIAS(const Cfg *Func) const { | 1334 void InstX8632Cmpps::emitIAS(const Cfg *Func) const { |
| 1329 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 1330 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1335 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1331 intptr_t StartPosition = Asm->GetPosition(); | 1336 intptr_t StartPosition = Asm->GetPosition(); |
| 1332 assert(getSrcSize() == 2); | 1337 assert(getSrcSize() == 2); |
| 1333 assert(Condition < CondX86::Cmpps_Invalid); | 1338 assert(Condition < CondX86::Cmpps_Invalid); |
| 1334 // Assuming there isn't any load folding for cmpps, and vector constants | 1339 // Assuming there isn't any load folding for cmpps, and vector constants |
| 1335 // are not allowed in PNaCl. | 1340 // are not allowed in PNaCl. |
| 1336 assert(llvm::isa<Variable>(getSrc(1))); | 1341 assert(llvm::isa<Variable>(getSrc(1))); |
| 1337 const Variable *SrcVar = llvm::cast<Variable>(getSrc(1)); | 1342 const Variable *SrcVar = llvm::cast<Variable>(getSrc(1)); |
| 1338 if (SrcVar->hasReg()) { | 1343 if (SrcVar->hasReg()) { |
| 1339 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), | 1344 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), |
| 1340 RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition); | 1345 RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition); |
| 1341 } else { | 1346 } else { |
| 1342 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) | 1347 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) |
| 1343 ->stackVarToAsmOperand(SrcVar); | 1348 ->stackVarToAsmOperand(SrcVar); |
| 1344 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr, | 1349 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr, |
| 1345 Condition); | 1350 Condition); |
| 1346 } | 1351 } |
| 1347 emitIASBytes(Str, Asm, StartPosition); | 1352 emitIASBytes(Func, Asm, StartPosition); |
| 1348 } | 1353 } |
| 1349 | 1354 |
| 1350 void InstX8632Cmpps::dump(const Cfg *Func) const { | 1355 void InstX8632Cmpps::dump(const Cfg *Func) const { |
| 1351 Ostream &Str = Func->getContext()->getStrDump(); | 1356 Ostream &Str = Func->getContext()->getStrDump(); |
| 1352 assert(Condition < CondX86::Cmpps_Invalid); | 1357 assert(Condition < CondX86::Cmpps_Invalid); |
| 1353 dumpDest(Func); | 1358 dumpDest(Func); |
| 1354 Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" | 1359 Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" |
| 1355 << "\t"; | 1360 << "\t"; |
| 1356 dumpSources(Func); | 1361 dumpSources(Func); |
| 1357 } | 1362 } |
| 1358 | 1363 |
| 1359 void InstX8632Cmpxchg::emit(const Cfg *Func) const { | 1364 void InstX8632Cmpxchg::emit(const Cfg *Func) const { |
| 1360 Ostream &Str = Func->getContext()->getStrEmit(); | 1365 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1361 assert(getSrcSize() == 3); | 1366 assert(getSrcSize() == 3); |
| 1362 if (Locked) { | 1367 if (Locked) { |
| 1363 Str << "\tlock"; | 1368 Str << "\tlock"; |
| 1364 } | 1369 } |
| 1365 Str << "\tcmpxchg\t"; | 1370 Str << "\tcmpxchg\t"; |
| 1366 getSrc(0)->emit(Func); | 1371 getSrc(0)->emit(Func); |
| 1367 Str << ", "; | 1372 Str << ", "; |
| 1368 getSrc(2)->emit(Func); | 1373 getSrc(2)->emit(Func); |
| 1369 Str << "\n"; | 1374 Str << "\n"; |
| 1370 } | 1375 } |
| 1371 | 1376 |
| 1372 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const { | 1377 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const { |
| 1373 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 1374 assert(getSrcSize() == 3); | 1378 assert(getSrcSize() == 3); |
| 1375 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1379 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1376 intptr_t StartPosition = Asm->GetPosition(); | 1380 intptr_t StartPosition = Asm->GetPosition(); |
| 1377 Type Ty = getSrc(0)->getType(); | 1381 Type Ty = getSrc(0)->getType(); |
| 1378 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 1382 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
| 1383 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 1379 const x86::Address Addr = Mem->toAsmAddress(Asm); | 1384 const x86::Address Addr = Mem->toAsmAddress(Asm); |
| 1380 const Variable *VarReg = llvm::cast<Variable>(getSrc(2)); | 1385 const Variable *VarReg = llvm::cast<Variable>(getSrc(2)); |
| 1381 assert(VarReg->hasReg()); | 1386 assert(VarReg->hasReg()); |
| 1382 const RegX8632::GPRRegister Reg = | 1387 const RegX8632::GPRRegister Reg = |
| 1383 RegX8632::getEncodedGPR(VarReg->getRegNum()); | 1388 RegX8632::getEncodedGPR(VarReg->getRegNum()); |
| 1384 if (Locked) { | 1389 if (Locked) { |
| 1385 Asm->LockCmpxchg(Ty, Addr, Reg); | 1390 Asm->LockCmpxchg(Ty, Addr, Reg); |
| 1386 } else { | 1391 } else { |
| 1387 Asm->cmpxchg(Ty, Addr, Reg); | 1392 Asm->cmpxchg(Ty, Addr, Reg); |
| 1388 } | 1393 } |
| 1389 emitIASBytes(Str, Asm, StartPosition); | 1394 emitIASBytes(Func, Asm, StartPosition); |
| 1390 } | 1395 } |
| 1391 | 1396 |
| 1392 void InstX8632Cmpxchg::dump(const Cfg *Func) const { | 1397 void InstX8632Cmpxchg::dump(const Cfg *Func) const { |
| 1393 Ostream &Str = Func->getContext()->getStrDump(); | 1398 Ostream &Str = Func->getContext()->getStrDump(); |
| 1394 if (Locked) { | 1399 if (Locked) { |
| 1395 Str << "lock "; | 1400 Str << "lock "; |
| 1396 } | 1401 } |
| 1397 Str << "cmpxchg." << getSrc(0)->getType() << " "; | 1402 Str << "cmpxchg." << getSrc(0)->getType() << " "; |
| 1398 dumpSources(Func); | 1403 dumpSources(Func); |
| 1399 } | 1404 } |
| 1400 | 1405 |
| 1401 void InstX8632Cmpxchg8b::emit(const Cfg *Func) const { | 1406 void InstX8632Cmpxchg8b::emit(const Cfg *Func) const { |
| 1402 Ostream &Str = Func->getContext()->getStrEmit(); | 1407 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1403 assert(getSrcSize() == 5); | 1408 assert(getSrcSize() == 5); |
| 1404 if (Locked) { | 1409 if (Locked) { |
| 1405 Str << "\tlock"; | 1410 Str << "\tlock"; |
| 1406 } | 1411 } |
| 1407 Str << "\tcmpxchg8b\t"; | 1412 Str << "\tcmpxchg8b\t"; |
| 1408 getSrc(0)->emit(Func); | 1413 getSrc(0)->emit(Func); |
| 1409 Str << "\n"; | 1414 Str << "\n"; |
| 1410 } | 1415 } |
| 1411 | 1416 |
| 1412 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const { | 1417 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const { |
| 1413 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 1414 assert(getSrcSize() == 5); | 1418 assert(getSrcSize() == 5); |
| 1415 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1419 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1416 intptr_t StartPosition = Asm->GetPosition(); | 1420 intptr_t StartPosition = Asm->GetPosition(); |
| 1417 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 1421 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
| 1422 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 1418 const x86::Address Addr = Mem->toAsmAddress(Asm); | 1423 const x86::Address Addr = Mem->toAsmAddress(Asm); |
| 1419 if (Locked) { | 1424 if (Locked) { |
| 1420 Asm->lock(); | 1425 Asm->lock(); |
| 1421 } | 1426 } |
| 1422 Asm->cmpxchg8b(Addr); | 1427 Asm->cmpxchg8b(Addr); |
| 1423 emitIASBytes(Str, Asm, StartPosition); | 1428 emitIASBytes(Func, Asm, StartPosition); |
| 1424 } | 1429 } |
| 1425 | 1430 |
| 1426 void InstX8632Cmpxchg8b::dump(const Cfg *Func) const { | 1431 void InstX8632Cmpxchg8b::dump(const Cfg *Func) const { |
| 1427 Ostream &Str = Func->getContext()->getStrDump(); | 1432 Ostream &Str = Func->getContext()->getStrDump(); |
| 1428 if (Locked) { | 1433 if (Locked) { |
| 1429 Str << "lock "; | 1434 Str << "lock "; |
| 1430 } | 1435 } |
| 1431 Str << "cmpxchg8b "; | 1436 Str << "cmpxchg8b "; |
| 1432 dumpSources(Func); | 1437 dumpSources(Func); |
| 1433 } | 1438 } |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1541 if (SrcVar0->hasReg()) { | 1546 if (SrcVar0->hasReg()) { |
| 1542 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); | 1547 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); |
| 1543 } else { | 1548 } else { |
| 1544 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 1549 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 1545 ->stackVarToAsmOperand(SrcVar0)); | 1550 ->stackVarToAsmOperand(SrcVar0)); |
| 1546 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Src1, AddrEmitter); | 1551 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Src1, AddrEmitter); |
| 1547 } | 1552 } |
| 1548 } else if (const OperandX8632Mem *SrcMem0 = | 1553 } else if (const OperandX8632Mem *SrcMem0 = |
| 1549 llvm::dyn_cast<OperandX8632Mem>(Src0)) { | 1554 llvm::dyn_cast<OperandX8632Mem>(Src0)) { |
| 1550 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1555 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1556 SrcMem0->emitSegmentOverride(Asm); |
| 1551 emitIASAddrOpTyGPR(Func, Ty, SrcMem0->toAsmAddress(Asm), Src1, AddrEmitter); | 1557 emitIASAddrOpTyGPR(Func, Ty, SrcMem0->toAsmAddress(Asm), Src1, AddrEmitter); |
| 1552 } | 1558 } |
| 1553 } | 1559 } |
| 1554 | 1560 |
| 1555 void InstX8632Icmp::dump(const Cfg *Func) const { | 1561 void InstX8632Icmp::dump(const Cfg *Func) const { |
| 1556 Ostream &Str = Func->getContext()->getStrDump(); | 1562 Ostream &Str = Func->getContext()->getStrDump(); |
| 1557 Str << "cmp." << getSrc(0)->getType() << " "; | 1563 Str << "cmp." << getSrc(0)->getType() << " "; |
| 1558 dumpSources(Func); | 1564 dumpSources(Func); |
| 1559 } | 1565 } |
| 1560 | 1566 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1591 void InstX8632UD2::emit(const Cfg *Func) const { | 1597 void InstX8632UD2::emit(const Cfg *Func) const { |
| 1592 Ostream &Str = Func->getContext()->getStrEmit(); | 1598 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1593 assert(getSrcSize() == 0); | 1599 assert(getSrcSize() == 0); |
| 1594 Str << "\tud2\n"; | 1600 Str << "\tud2\n"; |
| 1595 } | 1601 } |
| 1596 | 1602 |
| 1597 void InstX8632UD2::emitIAS(const Cfg *Func) const { | 1603 void InstX8632UD2::emitIAS(const Cfg *Func) const { |
| 1598 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1604 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1599 intptr_t StartPosition = Asm->GetPosition(); | 1605 intptr_t StartPosition = Asm->GetPosition(); |
| 1600 Asm->ud2(); | 1606 Asm->ud2(); |
| 1601 Ostream &Str = Func->getContext()->getStrEmit(); | 1607 emitIASBytes(Func, Asm, StartPosition); |
| 1602 emitIASBytes(Str, Asm, StartPosition); | |
| 1603 } | 1608 } |
| 1604 | 1609 |
| 1605 void InstX8632UD2::dump(const Cfg *Func) const { | 1610 void InstX8632UD2::dump(const Cfg *Func) const { |
| 1606 Ostream &Str = Func->getContext()->getStrDump(); | 1611 Ostream &Str = Func->getContext()->getStrDump(); |
| 1607 Str << "ud2\n"; | 1612 Str << "ud2\n"; |
| 1608 } | 1613 } |
| 1609 | 1614 |
| 1610 void InstX8632Test::emit(const Cfg *Func) const { | 1615 void InstX8632Test::emit(const Cfg *Func) const { |
| 1611 Ostream &Str = Func->getContext()->getStrEmit(); | 1616 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1612 assert(getSrcSize() == 2); | 1617 assert(getSrcSize() == 2); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1635 } else { | 1640 } else { |
| 1636 llvm_unreachable("Nothing actually generates this so it's untested"); | 1641 llvm_unreachable("Nothing actually generates this so it's untested"); |
| 1637 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 1642 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 1638 ->stackVarToAsmOperand(SrcVar0)); | 1643 ->stackVarToAsmOperand(SrcVar0)); |
| 1639 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Src1, AddrEmitter); | 1644 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Src1, AddrEmitter); |
| 1640 } | 1645 } |
| 1641 } else if (const OperandX8632Mem *SrcMem0 = | 1646 } else if (const OperandX8632Mem *SrcMem0 = |
| 1642 llvm::dyn_cast<OperandX8632Mem>(Src0)) { | 1647 llvm::dyn_cast<OperandX8632Mem>(Src0)) { |
| 1643 llvm_unreachable("Nothing actually generates this so it's untested"); | 1648 llvm_unreachable("Nothing actually generates this so it's untested"); |
| 1644 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1649 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1650 SrcMem0->emitSegmentOverride(Asm); |
| 1645 emitIASAddrOpTyGPR(Func, Ty, SrcMem0->toAsmAddress(Asm), Src1, AddrEmitter); | 1651 emitIASAddrOpTyGPR(Func, Ty, SrcMem0->toAsmAddress(Asm), Src1, AddrEmitter); |
| 1646 } | 1652 } |
| 1647 } | 1653 } |
| 1648 | 1654 |
| 1649 void InstX8632Test::dump(const Cfg *Func) const { | 1655 void InstX8632Test::dump(const Cfg *Func) const { |
| 1650 Ostream &Str = Func->getContext()->getStrDump(); | 1656 Ostream &Str = Func->getContext()->getStrDump(); |
| 1651 Str << "test." << getSrc(0)->getType() << " "; | 1657 Str << "test." << getSrc(0)->getType() << " "; |
| 1652 dumpSources(Func); | 1658 dumpSources(Func); |
| 1653 } | 1659 } |
| 1654 | 1660 |
| 1655 void InstX8632Mfence::emit(const Cfg *Func) const { | 1661 void InstX8632Mfence::emit(const Cfg *Func) const { |
| 1656 Ostream &Str = Func->getContext()->getStrEmit(); | 1662 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1657 assert(getSrcSize() == 0); | 1663 assert(getSrcSize() == 0); |
| 1658 Str << "\tmfence\n"; | 1664 Str << "\tmfence\n"; |
| 1659 } | 1665 } |
| 1660 | 1666 |
| 1661 void InstX8632Mfence::emitIAS(const Cfg *Func) const { | 1667 void InstX8632Mfence::emitIAS(const Cfg *Func) const { |
| 1662 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 1663 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1668 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1664 intptr_t StartPosition = Asm->GetPosition(); | 1669 intptr_t StartPosition = Asm->GetPosition(); |
| 1665 Asm->mfence(); | 1670 Asm->mfence(); |
| 1666 emitIASBytes(Str, Asm, StartPosition); | 1671 emitIASBytes(Func, Asm, StartPosition); |
| 1667 } | 1672 } |
| 1668 | 1673 |
| 1669 void InstX8632Mfence::dump(const Cfg *Func) const { | 1674 void InstX8632Mfence::dump(const Cfg *Func) const { |
| 1670 Ostream &Str = Func->getContext()->getStrDump(); | 1675 Ostream &Str = Func->getContext()->getStrDump(); |
| 1671 Str << "mfence\n"; | 1676 Str << "mfence\n"; |
| 1672 } | 1677 } |
| 1673 | 1678 |
| 1674 void InstX8632Store::emit(const Cfg *Func) const { | 1679 void InstX8632Store::emit(const Cfg *Func) const { |
| 1675 Ostream &Str = Func->getContext()->getStrEmit(); | 1680 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1676 assert(getSrcSize() == 2); | 1681 assert(getSrcSize() == 2); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1699 getSrc(0)->emit(Func); | 1704 getSrc(0)->emit(Func); |
| 1700 Str << "\n"; | 1705 Str << "\n"; |
| 1701 } | 1706 } |
| 1702 | 1707 |
| 1703 void InstX8632StoreP::emitIAS(const Cfg *Func) const { | 1708 void InstX8632StoreP::emitIAS(const Cfg *Func) const { |
| 1704 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1709 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1705 intptr_t StartPosition = Asm->GetPosition(); | 1710 intptr_t StartPosition = Asm->GetPosition(); |
| 1706 assert(getSrcSize() == 2); | 1711 assert(getSrcSize() == 2); |
| 1707 const Variable *Src = llvm::cast<Variable>(getSrc(0)); | 1712 const Variable *Src = llvm::cast<Variable>(getSrc(0)); |
| 1708 const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); | 1713 const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); |
| 1714 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 1709 assert(Src->hasReg()); | 1715 assert(Src->hasReg()); |
| 1710 Asm->movups(DestMem->toAsmAddress(Asm), | 1716 Asm->movups(DestMem->toAsmAddress(Asm), |
| 1711 RegX8632::getEncodedXmm(Src->getRegNum())); | 1717 RegX8632::getEncodedXmm(Src->getRegNum())); |
| 1712 Ostream &Str = Func->getContext()->getStrEmit(); | 1718 emitIASBytes(Func, Asm, StartPosition); |
| 1713 emitIASBytes(Str, Asm, StartPosition); | |
| 1714 } | 1719 } |
| 1715 | 1720 |
| 1716 void InstX8632StoreP::dump(const Cfg *Func) const { | 1721 void InstX8632StoreP::dump(const Cfg *Func) const { |
| 1717 Ostream &Str = Func->getContext()->getStrDump(); | 1722 Ostream &Str = Func->getContext()->getStrDump(); |
| 1718 Str << "storep." << getSrc(0)->getType() << " "; | 1723 Str << "storep." << getSrc(0)->getType() << " "; |
| 1719 getSrc(1)->dump(Func); | 1724 getSrc(1)->dump(Func); |
| 1720 Str << ", "; | 1725 Str << ", "; |
| 1721 getSrc(0)->dump(Func); | 1726 getSrc(0)->dump(Func); |
| 1722 } | 1727 } |
| 1723 | 1728 |
| 1724 void InstX8632StoreQ::emit(const Cfg *Func) const { | 1729 void InstX8632StoreQ::emit(const Cfg *Func) const { |
| 1725 Ostream &Str = Func->getContext()->getStrEmit(); | 1730 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1726 assert(getSrcSize() == 2); | 1731 assert(getSrcSize() == 2); |
| 1727 assert(getSrc(1)->getType() == IceType_i64 || | 1732 assert(getSrc(1)->getType() == IceType_i64 || |
| 1728 getSrc(1)->getType() == IceType_f64); | 1733 getSrc(1)->getType() == IceType_f64); |
| 1729 Str << "\tmovq\t"; | 1734 Str << "\tmovq\t"; |
| 1730 getSrc(1)->emit(Func); | 1735 getSrc(1)->emit(Func); |
| 1731 Str << ", "; | 1736 Str << ", "; |
| 1732 getSrc(0)->emit(Func); | 1737 getSrc(0)->emit(Func); |
| 1733 Str << "\n"; | 1738 Str << "\n"; |
| 1734 } | 1739 } |
| 1735 | 1740 |
| 1736 void InstX8632StoreQ::emitIAS(const Cfg *Func) const { | 1741 void InstX8632StoreQ::emitIAS(const Cfg *Func) const { |
| 1737 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1742 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1738 intptr_t StartPosition = Asm->GetPosition(); | 1743 intptr_t StartPosition = Asm->GetPosition(); |
| 1739 assert(getSrcSize() == 2); | 1744 assert(getSrcSize() == 2); |
| 1740 const Variable *Src = llvm::cast<Variable>(getSrc(0)); | 1745 const Variable *Src = llvm::cast<Variable>(getSrc(0)); |
| 1741 const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); | 1746 const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); |
| 1747 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 1742 assert(Src->hasReg()); | 1748 assert(Src->hasReg()); |
| 1743 Asm->movq(DestMem->toAsmAddress(Asm), | 1749 Asm->movq(DestMem->toAsmAddress(Asm), |
| 1744 RegX8632::getEncodedXmm(Src->getRegNum())); | 1750 RegX8632::getEncodedXmm(Src->getRegNum())); |
| 1745 Ostream &Str = Func->getContext()->getStrEmit(); | 1751 emitIASBytes(Func, Asm, StartPosition); |
| 1746 emitIASBytes(Str, Asm, StartPosition); | |
| 1747 } | 1752 } |
| 1748 | 1753 |
| 1749 void InstX8632StoreQ::dump(const Cfg *Func) const { | 1754 void InstX8632StoreQ::dump(const Cfg *Func) const { |
| 1750 Ostream &Str = Func->getContext()->getStrDump(); | 1755 Ostream &Str = Func->getContext()->getStrDump(); |
| 1751 Str << "storeq." << getSrc(0)->getType() << " "; | 1756 Str << "storeq." << getSrc(0)->getType() << " "; |
| 1752 getSrc(1)->dump(Func); | 1757 getSrc(1)->dump(Func); |
| 1753 Str << ", "; | 1758 Str << ", "; |
| 1754 getSrc(0)->dump(Func); | 1759 getSrc(0)->dump(Func); |
| 1755 } | 1760 } |
| 1756 | 1761 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1816 Str << "\n"; | 1821 Str << "\n"; |
| 1817 Str << ".intel_syntax\n"; | 1822 Str << ".intel_syntax\n"; |
| 1818 } else { | 1823 } else { |
| 1819 getDest()->asType(Src->getType()).emit(Func); | 1824 getDest()->asType(Src->getType()).emit(Func); |
| 1820 Str << ", "; | 1825 Str << ", "; |
| 1821 Src->emit(Func); | 1826 Src->emit(Func); |
| 1822 Str << "\n"; | 1827 Str << "\n"; |
| 1823 } | 1828 } |
| 1824 } | 1829 } |
| 1825 | 1830 |
| 1831 template <> void InstX8632Mov::emitIAS(const Cfg *Func) const { |
| 1832 assert(getSrcSize() == 1); |
| 1833 const Variable *Dest = getDest(); |
| 1834 const Operand *Src = getSrc(0); |
| 1835 Type DestTy = Dest->getType(); |
| 1836 Type SrcTy = Src->getType(); |
| 1837 // Mov can be used for GPRs or XMM registers. Also, the type does not |
| 1838 // necessarily match (Mov can be used for bitcasts). However, when |
| 1839 // the type does not match, one of the operands must be a register. |
| 1840 // Thus, the strategy is to find out if Src or Dest are a register, |
| 1841 // then use that register's type to decide on which emitter set to use. |
| 1842 // The emitter set will include reg-reg movs, but that case should |
| 1843 // be unused when the types don't match. |
| 1844 static const x86::AssemblerX86::XmmEmitterRegOp XmmRegEmitter = { |
| 1845 &x86::AssemblerX86::movss, &x86::AssemblerX86::movss}; |
| 1846 static const x86::AssemblerX86::GPREmitterRegOp GPRRegEmitter = { |
| 1847 &x86::AssemblerX86::mov, &x86::AssemblerX86::mov, &x86::AssemblerX86::mov}; |
| 1848 static const x86::AssemblerX86::GPREmitterAddrOp GPRAddrEmitter = { |
| 1849 &x86::AssemblerX86::mov, &x86::AssemblerX86::mov}; |
| 1850 // For an integer truncation operation, src is wider than dest. |
| 1851 // Ideally, we use a mov instruction whose data width matches the |
| 1852 // narrower dest. This is a problem if e.g. src is a register like |
| 1853 // esi or si where there is no 8-bit version of the register. To be |
| 1854 // safe, we instead widen the dest to match src. This works even |
| 1855 // for stack-allocated dest variables because typeWidthOnStack() |
| 1856 // pads to a 4-byte boundary even if only a lower portion is used. |
| 1857 // TODO: This assert disallows usages such as copying a floating point |
| 1858 // value between a vector and a scalar (which movss is used for). |
| 1859 // Clean this up. |
| 1860 assert(Func->getTarget()->typeWidthInBytesOnStack(getDest()->getType()) == |
| 1861 Func->getTarget()->typeWidthInBytesOnStack(Src->getType())); |
| 1862 if (Dest->hasReg()) { |
| 1863 if (isScalarFloatingType(DestTy)) { |
| 1864 emitIASRegOpTyXMM(Func, DestTy, Dest, Src, XmmRegEmitter); |
| 1865 return; |
| 1866 } else { |
| 1867 assert(isScalarIntegerType(DestTy)); |
| 1868 // Widen DestTy for truncation (see above note). We should only do this |
| 1869 // when both Src and Dest are integer types. |
| 1870 if (isScalarIntegerType(SrcTy)) { |
| 1871 DestTy = SrcTy; |
| 1872 } |
| 1873 emitIASRegOpTyGPR(Func, DestTy, Dest, Src, GPRRegEmitter); |
| 1874 return; |
| 1875 } |
| 1876 } else { |
| 1877 // Dest must be Stack and Src *could* be a register. Use Src's type |
| 1878 // to decide on the emitters. |
| 1879 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 1880 ->stackVarToAsmOperand(Dest)); |
| 1881 if (isScalarFloatingType(SrcTy)) { |
| 1882 // Src must be a register. |
| 1883 const Variable *SrcVar = llvm::cast<Variable>(Src); |
| 1884 assert(SrcVar->hasReg()); |
| 1885 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1886 intptr_t StartPosition = Asm->GetPosition(); |
| 1887 Asm->movss(SrcTy, StackAddr, |
| 1888 RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
| 1889 emitIASBytes(Func, Asm, StartPosition); |
| 1890 return; |
| 1891 } else { |
| 1892 // Src can be a register or immediate. |
| 1893 assert(isScalarIntegerType(SrcTy)); |
| 1894 emitIASAddrOpTyGPR(Func, SrcTy, StackAddr, Src, GPRAddrEmitter); |
| 1895 return; |
| 1896 } |
| 1897 return; |
| 1898 } |
| 1899 } |
| 1900 |
| 1826 template <> void InstX8632Movd::emitIAS(const Cfg *Func) const { | 1901 template <> void InstX8632Movd::emitIAS(const Cfg *Func) const { |
| 1827 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1902 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1828 intptr_t StartPosition = Asm->GetPosition(); | 1903 intptr_t StartPosition = Asm->GetPosition(); |
| 1829 assert(getSrcSize() == 1); | 1904 assert(getSrcSize() == 1); |
| 1830 const Variable *Dest = getDest(); | 1905 const Variable *Dest = getDest(); |
| 1831 const Variable *Src = llvm::cast<Variable>(getSrc(0)); | 1906 const Variable *Src = llvm::cast<Variable>(getSrc(0)); |
| 1832 // For insert/extract element (one of Src/Dest is an Xmm vector and | 1907 // For insert/extract element (one of Src/Dest is an Xmm vector and |
| 1833 // the other is an int type). | 1908 // the other is an int type). |
| 1834 if (Src->getType() == IceType_i32) { | 1909 if (Src->getType() == IceType_i32) { |
| 1835 assert(isVectorType(Dest->getType())); | 1910 assert(isVectorType(Dest->getType())); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1848 assert(Dest->getType() == IceType_i32); | 1923 assert(Dest->getType() == IceType_i32); |
| 1849 RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(Src->getRegNum()); | 1924 RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(Src->getRegNum()); |
| 1850 if (Dest->hasReg()) { | 1925 if (Dest->hasReg()) { |
| 1851 Asm->movd(RegX8632::getEncodedGPR(Dest->getRegNum()), SrcReg); | 1926 Asm->movd(RegX8632::getEncodedGPR(Dest->getRegNum()), SrcReg); |
| 1852 } else { | 1927 } else { |
| 1853 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 1928 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 1854 ->stackVarToAsmOperand(Dest)); | 1929 ->stackVarToAsmOperand(Dest)); |
| 1855 Asm->movd(StackAddr, SrcReg); | 1930 Asm->movd(StackAddr, SrcReg); |
| 1856 } | 1931 } |
| 1857 } | 1932 } |
| 1858 Ostream &Str = Func->getContext()->getStrEmit(); | 1933 emitIASBytes(Func, Asm, StartPosition); |
| 1859 emitIASBytes(Str, Asm, StartPosition); | |
| 1860 } | 1934 } |
| 1861 | 1935 |
| 1862 template <> void InstX8632Movp::emit(const Cfg *Func) const { | 1936 template <> void InstX8632Movp::emit(const Cfg *Func) const { |
| 1863 // TODO(wala,stichnot): movups works with all vector operands, but | 1937 // TODO(wala,stichnot): movups works with all vector operands, but |
| 1864 // there exist other instructions (movaps, movdqa, movdqu) that may | 1938 // there exist other instructions (movaps, movdqa, movdqu) that may |
| 1865 // perform better, depending on the data type and alignment of the | 1939 // perform better, depending on the data type and alignment of the |
| 1866 // operands. | 1940 // operands. |
| 1867 Ostream &Str = Func->getContext()->getStrEmit(); | 1941 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1868 assert(getSrcSize() == 1); | 1942 assert(getSrcSize() == 1); |
| 1869 Str << "\tmovups\t"; | 1943 Str << "\tmovups\t"; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1914 // where part of the Dest register is untouched. | 1988 // where part of the Dest register is untouched. |
| 1915 assert(getSrcSize() == 2); | 1989 assert(getSrcSize() == 2); |
| 1916 const Variable *Dest = getDest(); | 1990 const Variable *Dest = getDest(); |
| 1917 assert(Dest == getSrc(0)); | 1991 assert(Dest == getSrc(0)); |
| 1918 const Variable *Src = llvm::cast<Variable>(getSrc(1)); | 1992 const Variable *Src = llvm::cast<Variable>(getSrc(1)); |
| 1919 assert(Dest->hasReg() && Src->hasReg()); | 1993 assert(Dest->hasReg() && Src->hasReg()); |
| 1920 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1994 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1921 intptr_t StartPosition = Asm->GetPosition(); | 1995 intptr_t StartPosition = Asm->GetPosition(); |
| 1922 Asm->movss(IceType_f32, RegX8632::getEncodedXmm(Dest->getRegNum()), | 1996 Asm->movss(IceType_f32, RegX8632::getEncodedXmm(Dest->getRegNum()), |
| 1923 RegX8632::getEncodedXmm(Src->getRegNum())); | 1997 RegX8632::getEncodedXmm(Src->getRegNum())); |
| 1924 Ostream &Str = Func->getContext()->getStrEmit(); | 1998 emitIASBytes(Func, Asm, StartPosition); |
| 1925 emitIASBytes(Str, Asm, StartPosition); | |
| 1926 } | 1999 } |
| 1927 | 2000 |
| 1928 void InstX8632Movsx::emit(const Cfg *Func) const { | 2001 void InstX8632Movsx::emit(const Cfg *Func) const { |
| 1929 Ostream &Str = Func->getContext()->getStrEmit(); | 2002 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1930 assert(getSrcSize() == 1); | 2003 assert(getSrcSize() == 1); |
| 1931 Str << "\tmovsx\t"; | 2004 Str << "\tmovsx\t"; |
| 1932 getDest()->emit(Func); | 2005 getDest()->emit(Func); |
| 1933 Str << ", "; | 2006 Str << ", "; |
| 1934 getSrc(0)->emit(Func); | 2007 getSrc(0)->emit(Func); |
| 1935 Str << "\n"; | 2008 Str << "\n"; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1963 dumpSources(Func); | 2036 dumpSources(Func); |
| 1964 } | 2037 } |
| 1965 | 2038 |
| 1966 void InstX8632Nop::emit(const Cfg *Func) const { | 2039 void InstX8632Nop::emit(const Cfg *Func) const { |
| 1967 Ostream &Str = Func->getContext()->getStrEmit(); | 2040 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1968 // TODO: Emit the right code for each variant. | 2041 // TODO: Emit the right code for each variant. |
| 1969 Str << "\tnop\t# variant = " << Variant << "\n"; | 2042 Str << "\tnop\t# variant = " << Variant << "\n"; |
| 1970 } | 2043 } |
| 1971 | 2044 |
| 1972 void InstX8632Nop::emitIAS(const Cfg *Func) const { | 2045 void InstX8632Nop::emitIAS(const Cfg *Func) const { |
| 1973 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 1974 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2046 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1975 intptr_t StartPosition = Asm->GetPosition(); | 2047 intptr_t StartPosition = Asm->GetPosition(); |
| 1976 // TODO: Emit the right code for the variant. | 2048 // TODO: Emit the right code for the variant. |
| 1977 Asm->nop(); | 2049 Asm->nop(); |
| 1978 emitIASBytes(Str, Asm, StartPosition); | 2050 emitIASBytes(Func, Asm, StartPosition); |
| 1979 } | 2051 } |
| 1980 | 2052 |
| 1981 void InstX8632Nop::dump(const Cfg *Func) const { | 2053 void InstX8632Nop::dump(const Cfg *Func) const { |
| 1982 Ostream &Str = Func->getContext()->getStrDump(); | 2054 Ostream &Str = Func->getContext()->getStrDump(); |
| 1983 Str << "nop (variant = " << Variant << ")"; | 2055 Str << "nop (variant = " << Variant << ")"; |
| 1984 } | 2056 } |
| 1985 | 2057 |
| 1986 void InstX8632Fld::emit(const Cfg *Func) const { | 2058 void InstX8632Fld::emit(const Cfg *Func) const { |
| 1987 Ostream &Str = Func->getContext()->getStrEmit(); | 2059 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1988 assert(getSrcSize() == 1); | 2060 assert(getSrcSize() == 1); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2021 x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0); | 2093 x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0); |
| 2022 Asm->movss(Ty, StackSlot, RegX8632::getEncodedXmm(Var->getRegNum())); | 2094 Asm->movss(Ty, StackSlot, RegX8632::getEncodedXmm(Var->getRegNum())); |
| 2023 Asm->fld(Ty, StackSlot); | 2095 Asm->fld(Ty, StackSlot); |
| 2024 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); | 2096 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); |
| 2025 } else { | 2097 } else { |
| 2026 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 2098 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 2027 ->stackVarToAsmOperand(Var)); | 2099 ->stackVarToAsmOperand(Var)); |
| 2028 Asm->fld(Ty, StackAddr); | 2100 Asm->fld(Ty, StackAddr); |
| 2029 } | 2101 } |
| 2030 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { | 2102 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { |
| 2103 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 2031 Asm->fld(Ty, Mem->toAsmAddress(Asm)); | 2104 Asm->fld(Ty, Mem->toAsmAddress(Asm)); |
| 2032 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { | 2105 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { |
| 2033 Asm->fld(Ty, x86::Address::ofConstPool(Func->getContext(), Asm, Imm)); | 2106 Asm->fld(Ty, x86::Address::ofConstPool(Func->getContext(), Asm, Imm)); |
| 2034 } else { | 2107 } else { |
| 2035 llvm_unreachable("Unexpected operand type"); | 2108 llvm_unreachable("Unexpected operand type"); |
| 2036 } | 2109 } |
| 2037 Ostream &Str = Func->getContext()->getStrEmit(); | 2110 emitIASBytes(Func, Asm, StartPosition); |
| 2038 emitIASBytes(Str, Asm, StartPosition); | |
| 2039 } | 2111 } |
| 2040 | 2112 |
| 2041 void InstX8632Fld::dump(const Cfg *Func) const { | 2113 void InstX8632Fld::dump(const Cfg *Func) const { |
| 2042 Ostream &Str = Func->getContext()->getStrDump(); | 2114 Ostream &Str = Func->getContext()->getStrDump(); |
| 2043 Str << "fld." << getSrc(0)->getType() << " "; | 2115 Str << "fld." << getSrc(0)->getType() << " "; |
| 2044 dumpSources(Func); | 2116 dumpSources(Func); |
| 2045 } | 2117 } |
| 2046 | 2118 |
| 2047 void InstX8632Fstp::emit(const Cfg *Func) const { | 2119 void InstX8632Fstp::emit(const Cfg *Func) const { |
| 2048 Ostream &Str = Func->getContext()->getStrEmit(); | 2120 Ostream &Str = Func->getContext()->getStrEmit(); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 2079 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2151 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 2080 intptr_t StartPosition = Asm->GetPosition(); | 2152 intptr_t StartPosition = Asm->GetPosition(); |
| 2081 assert(getSrcSize() == 0); | 2153 assert(getSrcSize() == 0); |
| 2082 const Variable *Dest = getDest(); | 2154 const Variable *Dest = getDest(); |
| 2083 // TODO(jvoung,stichnot): Utilize this by setting Dest to NULL to | 2155 // TODO(jvoung,stichnot): Utilize this by setting Dest to NULL to |
| 2084 // "partially" delete the fstp if the Dest is unused. | 2156 // "partially" delete the fstp if the Dest is unused. |
| 2085 // Even if Dest is unused, the fstp should be kept for the SideEffects | 2157 // Even if Dest is unused, the fstp should be kept for the SideEffects |
| 2086 // of popping the stack. | 2158 // of popping the stack. |
| 2087 if (Dest == NULL) { | 2159 if (Dest == NULL) { |
| 2088 Asm->fstp(RegX8632::getEncodedSTReg(0)); | 2160 Asm->fstp(RegX8632::getEncodedSTReg(0)); |
| 2089 Ostream &Str = Func->getContext()->getStrEmit(); | 2161 emitIASBytes(Func, Asm, StartPosition); |
| 2090 emitIASBytes(Str, Asm, StartPosition); | |
| 2091 return; | 2162 return; |
| 2092 } | 2163 } |
| 2093 Type Ty = Dest->getType(); | 2164 Type Ty = Dest->getType(); |
| 2094 if (!Dest->hasReg()) { | 2165 if (!Dest->hasReg()) { |
| 2095 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 2166 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 2096 ->stackVarToAsmOperand(Dest)); | 2167 ->stackVarToAsmOperand(Dest)); |
| 2097 Asm->fstp(Ty, StackAddr); | 2168 Asm->fstp(Ty, StackAddr); |
| 2098 } else { | 2169 } else { |
| 2099 // Dest is a physical (xmm) register, so st(0) needs to go through | 2170 // Dest is a physical (xmm) register, so st(0) needs to go through |
| 2100 // memory. Hack this by creating a temporary stack slot, spilling | 2171 // memory. Hack this by creating a temporary stack slot, spilling |
| 2101 // st(0) there, loading it into the xmm register, and deallocating | 2172 // st(0) there, loading it into the xmm register, and deallocating |
| 2102 // the stack slot. | 2173 // the stack slot. |
| 2103 x86::Immediate Width(typeWidthInBytes(Ty)); | 2174 x86::Immediate Width(typeWidthInBytes(Ty)); |
| 2104 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width); | 2175 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width); |
| 2105 x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0); | 2176 x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0); |
| 2106 Asm->fstp(Ty, StackSlot); | 2177 Asm->fstp(Ty, StackSlot); |
| 2107 Asm->movss(Ty, RegX8632::getEncodedXmm(Dest->getRegNum()), StackSlot); | 2178 Asm->movss(Ty, RegX8632::getEncodedXmm(Dest->getRegNum()), StackSlot); |
| 2108 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); | 2179 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); |
| 2109 } | 2180 } |
| 2110 Ostream &Str = Func->getContext()->getStrEmit(); | 2181 emitIASBytes(Func, Asm, StartPosition); |
| 2111 emitIASBytes(Str, Asm, StartPosition); | |
| 2112 } | 2182 } |
| 2113 | 2183 |
| 2114 void InstX8632Fstp::dump(const Cfg *Func) const { | 2184 void InstX8632Fstp::dump(const Cfg *Func) const { |
| 2115 Ostream &Str = Func->getContext()->getStrDump(); | 2185 Ostream &Str = Func->getContext()->getStrDump(); |
| 2116 dumpDest(Func); | 2186 dumpDest(Func); |
| 2117 Str << " = fstp." << getDest()->getType() << ", st(0)"; | 2187 Str << " = fstp." << getDest()->getType() << ", st(0)"; |
| 2118 Str << "\n"; | 2188 Str << "\n"; |
| 2119 } | 2189 } |
| 2120 | 2190 |
| 2121 template <> void InstX8632Pcmpeq::emit(const Cfg *Func) const { | 2191 template <> void InstX8632Pcmpeq::emit(const Cfg *Func) const { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2183 | 2253 |
| 2184 void InstX8632Pop::emit(const Cfg *Func) const { | 2254 void InstX8632Pop::emit(const Cfg *Func) const { |
| 2185 Ostream &Str = Func->getContext()->getStrEmit(); | 2255 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2186 assert(getSrcSize() == 0); | 2256 assert(getSrcSize() == 0); |
| 2187 Str << "\tpop\t"; | 2257 Str << "\tpop\t"; |
| 2188 getDest()->emit(Func); | 2258 getDest()->emit(Func); |
| 2189 Str << "\n"; | 2259 Str << "\n"; |
| 2190 } | 2260 } |
| 2191 | 2261 |
| 2192 void InstX8632Pop::emitIAS(const Cfg *Func) const { | 2262 void InstX8632Pop::emitIAS(const Cfg *Func) const { |
| 2193 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 2194 assert(getSrcSize() == 0); | 2263 assert(getSrcSize() == 0); |
| 2195 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2264 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 2196 intptr_t StartPosition = Asm->GetPosition(); | 2265 intptr_t StartPosition = Asm->GetPosition(); |
| 2197 if (getDest()->hasReg()) { | 2266 if (getDest()->hasReg()) { |
| 2198 Asm->popl(RegX8632::getEncodedGPR(getDest()->getRegNum())); | 2267 Asm->popl(RegX8632::getEncodedGPR(getDest()->getRegNum())); |
| 2199 } else { | 2268 } else { |
| 2200 Asm->popl(static_cast<TargetX8632 *>(Func->getTarget()) | 2269 Asm->popl(static_cast<TargetX8632 *>(Func->getTarget()) |
| 2201 ->stackVarToAsmOperand(getDest())); | 2270 ->stackVarToAsmOperand(getDest())); |
| 2202 } | 2271 } |
| 2203 emitIASBytes(Str, Asm, StartPosition); | 2272 emitIASBytes(Func, Asm, StartPosition); |
| 2204 } | 2273 } |
| 2205 | 2274 |
| 2206 void InstX8632Pop::dump(const Cfg *Func) const { | 2275 void InstX8632Pop::dump(const Cfg *Func) const { |
| 2207 Ostream &Str = Func->getContext()->getStrDump(); | 2276 Ostream &Str = Func->getContext()->getStrDump(); |
| 2208 dumpDest(Func); | 2277 dumpDest(Func); |
| 2209 Str << " = pop." << getDest()->getType() << " "; | 2278 Str << " = pop." << getDest()->getType() << " "; |
| 2210 } | 2279 } |
| 2211 | 2280 |
| 2212 void InstX8632AdjustStack::emit(const Cfg *Func) const { | 2281 void InstX8632AdjustStack::emit(const Cfg *Func) const { |
| 2213 Ostream &Str = Func->getContext()->getStrEmit(); | 2282 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2214 Str << "\tsub\tesp, " << Amount << "\n"; | 2283 Str << "\tsub\tesp, " << Amount << "\n"; |
| 2215 Func->getTarget()->updateStackAdjustment(Amount); | 2284 Func->getTarget()->updateStackAdjustment(Amount); |
| 2216 } | 2285 } |
| 2217 | 2286 |
| 2218 void InstX8632AdjustStack::emitIAS(const Cfg *Func) const { | 2287 void InstX8632AdjustStack::emitIAS(const Cfg *Func) const { |
| 2219 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 2220 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2288 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 2221 intptr_t StartPosition = Asm->GetPosition(); | 2289 intptr_t StartPosition = Asm->GetPosition(); |
| 2222 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, x86::Immediate(Amount)); | 2290 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, x86::Immediate(Amount)); |
| 2223 emitIASBytes(Str, Asm, StartPosition); | 2291 emitIASBytes(Func, Asm, StartPosition); |
| 2224 Func->getTarget()->updateStackAdjustment(Amount); | 2292 Func->getTarget()->updateStackAdjustment(Amount); |
| 2225 } | 2293 } |
| 2226 | 2294 |
| 2227 void InstX8632AdjustStack::dump(const Cfg *Func) const { | 2295 void InstX8632AdjustStack::dump(const Cfg *Func) const { |
| 2228 Ostream &Str = Func->getContext()->getStrDump(); | 2296 Ostream &Str = Func->getContext()->getStrDump(); |
| 2229 Str << "esp = sub.i32 esp, " << Amount; | 2297 Str << "esp = sub.i32 esp, " << Amount; |
| 2230 } | 2298 } |
| 2231 | 2299 |
| 2232 void InstX8632Push::emit(const Cfg *Func) const { | 2300 void InstX8632Push::emit(const Cfg *Func) const { |
| 2233 Ostream &Str = Func->getContext()->getStrEmit(); | 2301 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2234 assert(getSrcSize() == 1); | 2302 assert(getSrcSize() == 1); |
| 2235 // Push is currently only used for saving GPRs. | 2303 // Push is currently only used for saving GPRs. |
| 2236 Variable *Var = llvm::cast<Variable>(getSrc(0)); | 2304 Variable *Var = llvm::cast<Variable>(getSrc(0)); |
| 2237 assert(Var->hasReg()); | 2305 assert(Var->hasReg()); |
| 2238 Str << "\tpush\t"; | 2306 Str << "\tpush\t"; |
| 2239 Var->emit(Func); | 2307 Var->emit(Func); |
| 2240 Str << "\n"; | 2308 Str << "\n"; |
| 2241 } | 2309 } |
| 2242 | 2310 |
| 2243 void InstX8632Push::emitIAS(const Cfg *Func) const { | 2311 void InstX8632Push::emitIAS(const Cfg *Func) const { |
| 2244 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 2245 assert(getSrcSize() == 1); | 2312 assert(getSrcSize() == 1); |
| 2246 // Push is currently only used for saving GPRs. | 2313 // Push is currently only used for saving GPRs. |
| 2247 Variable *Var = llvm::cast<Variable>(getSrc(0)); | 2314 Variable *Var = llvm::cast<Variable>(getSrc(0)); |
| 2248 assert(Var->hasReg()); | 2315 assert(Var->hasReg()); |
| 2249 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2316 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 2250 intptr_t StartPosition = Asm->GetPosition(); | 2317 intptr_t StartPosition = Asm->GetPosition(); |
| 2251 Asm->pushl(RegX8632::getEncodedGPR(Var->getRegNum())); | 2318 Asm->pushl(RegX8632::getEncodedGPR(Var->getRegNum())); |
| 2252 emitIASBytes(Str, Asm, StartPosition); | 2319 emitIASBytes(Func, Asm, StartPosition); |
| 2253 } | 2320 } |
| 2254 | 2321 |
| 2255 void InstX8632Push::dump(const Cfg *Func) const { | 2322 void InstX8632Push::dump(const Cfg *Func) const { |
| 2256 Ostream &Str = Func->getContext()->getStrDump(); | 2323 Ostream &Str = Func->getContext()->getStrDump(); |
| 2257 Str << "push." << getSrc(0)->getType() << " "; | 2324 Str << "push." << getSrc(0)->getType() << " "; |
| 2258 dumpSources(Func); | 2325 dumpSources(Func); |
| 2259 } | 2326 } |
| 2260 | 2327 |
| 2261 template <> void InstX8632Psll::emit(const Cfg *Func) const { | 2328 template <> void InstX8632Psll::emit(const Cfg *Func) const { |
| 2262 assert(getDest()->getType() == IceType_v8i16 || | 2329 assert(getDest()->getType() == IceType_v8i16 || |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2279 TypeX8632Attributes[getDest()->getType()].PackString); | 2346 TypeX8632Attributes[getDest()->getType()].PackString); |
| 2280 emitTwoAddress(buf, this, Func); | 2347 emitTwoAddress(buf, this, Func); |
| 2281 } | 2348 } |
| 2282 | 2349 |
| 2283 void InstX8632Ret::emit(const Cfg *Func) const { | 2350 void InstX8632Ret::emit(const Cfg *Func) const { |
| 2284 Ostream &Str = Func->getContext()->getStrEmit(); | 2351 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2285 Str << "\tret\n"; | 2352 Str << "\tret\n"; |
| 2286 } | 2353 } |
| 2287 | 2354 |
| 2288 void InstX8632Ret::emitIAS(const Cfg *Func) const { | 2355 void InstX8632Ret::emitIAS(const Cfg *Func) const { |
| 2289 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 2290 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2356 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 2291 intptr_t StartPosition = Asm->GetPosition(); | 2357 intptr_t StartPosition = Asm->GetPosition(); |
| 2292 Asm->ret(); | 2358 Asm->ret(); |
| 2293 emitIASBytes(Str, Asm, StartPosition); | 2359 emitIASBytes(Func, Asm, StartPosition); |
| 2294 } | 2360 } |
| 2295 | 2361 |
| 2296 void InstX8632Ret::dump(const Cfg *Func) const { | 2362 void InstX8632Ret::dump(const Cfg *Func) const { |
| 2297 Ostream &Str = Func->getContext()->getStrDump(); | 2363 Ostream &Str = Func->getContext()->getStrDump(); |
| 2298 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); | 2364 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); |
| 2299 Str << "ret." << Ty << " "; | 2365 Str << "ret." << Ty << " "; |
| 2300 dumpSources(Func); | 2366 dumpSources(Func); |
| 2301 } | 2367 } |
| 2302 | 2368 |
| 2303 void InstX8632Xadd::emit(const Cfg *Func) const { | 2369 void InstX8632Xadd::emit(const Cfg *Func) const { |
| 2304 Ostream &Str = Func->getContext()->getStrEmit(); | 2370 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2305 if (Locked) { | 2371 if (Locked) { |
| 2306 Str << "\tlock"; | 2372 Str << "\tlock"; |
| 2307 } | 2373 } |
| 2308 Str << "\txadd\t"; | 2374 Str << "\txadd\t"; |
| 2309 getSrc(0)->emit(Func); | 2375 getSrc(0)->emit(Func); |
| 2310 Str << ", "; | 2376 Str << ", "; |
| 2311 getSrc(1)->emit(Func); | 2377 getSrc(1)->emit(Func); |
| 2312 Str << "\n"; | 2378 Str << "\n"; |
| 2313 } | 2379 } |
| 2314 | 2380 |
| 2315 void InstX8632Xadd::emitIAS(const Cfg *Func) const { | 2381 void InstX8632Xadd::emitIAS(const Cfg *Func) const { |
| 2316 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 2317 assert(getSrcSize() == 2); | 2382 assert(getSrcSize() == 2); |
| 2318 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2383 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 2319 intptr_t StartPosition = Asm->GetPosition(); | 2384 intptr_t StartPosition = Asm->GetPosition(); |
| 2320 Type Ty = getSrc(0)->getType(); | 2385 Type Ty = getSrc(0)->getType(); |
| 2321 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 2386 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
| 2387 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 2322 const x86::Address Addr = Mem->toAsmAddress(Asm); | 2388 const x86::Address Addr = Mem->toAsmAddress(Asm); |
| 2323 const Variable *VarReg = llvm::cast<Variable>(getSrc(1)); | 2389 const Variable *VarReg = llvm::cast<Variable>(getSrc(1)); |
| 2324 assert(VarReg->hasReg()); | 2390 assert(VarReg->hasReg()); |
| 2325 const RegX8632::GPRRegister Reg = | 2391 const RegX8632::GPRRegister Reg = |
| 2326 RegX8632::getEncodedGPR(VarReg->getRegNum()); | 2392 RegX8632::getEncodedGPR(VarReg->getRegNum()); |
| 2327 if (Locked) { | 2393 if (Locked) { |
| 2328 Asm->lock(); | 2394 Asm->lock(); |
| 2329 } | 2395 } |
| 2330 Asm->xadd(Ty, Addr, Reg); | 2396 Asm->xadd(Ty, Addr, Reg); |
| 2331 emitIASBytes(Str, Asm, StartPosition); | 2397 emitIASBytes(Func, Asm, StartPosition); |
| 2332 } | 2398 } |
| 2333 | 2399 |
| 2334 void InstX8632Xadd::dump(const Cfg *Func) const { | 2400 void InstX8632Xadd::dump(const Cfg *Func) const { |
| 2335 Ostream &Str = Func->getContext()->getStrDump(); | 2401 Ostream &Str = Func->getContext()->getStrDump(); |
| 2336 if (Locked) { | 2402 if (Locked) { |
| 2337 Str << "lock "; | 2403 Str << "lock "; |
| 2338 } | 2404 } |
| 2339 Type Ty = getSrc(0)->getType(); | 2405 Type Ty = getSrc(0)->getType(); |
| 2340 Str << "xadd." << Ty << " "; | 2406 Str << "xadd." << Ty << " "; |
| 2341 dumpSources(Func); | 2407 dumpSources(Func); |
| 2342 } | 2408 } |
| 2343 | 2409 |
| 2344 void InstX8632Xchg::emit(const Cfg *Func) const { | 2410 void InstX8632Xchg::emit(const Cfg *Func) const { |
| 2345 Ostream &Str = Func->getContext()->getStrEmit(); | 2411 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2346 Str << "\txchg\t"; | 2412 Str << "\txchg\t"; |
| 2347 getSrc(0)->emit(Func); | 2413 getSrc(0)->emit(Func); |
| 2348 Str << ", "; | 2414 Str << ", "; |
| 2349 getSrc(1)->emit(Func); | 2415 getSrc(1)->emit(Func); |
| 2350 Str << "\n"; | 2416 Str << "\n"; |
| 2351 } | 2417 } |
| 2352 | 2418 |
| 2353 void InstX8632Xchg::emitIAS(const Cfg *Func) const { | 2419 void InstX8632Xchg::emitIAS(const Cfg *Func) const { |
| 2354 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 2355 assert(getSrcSize() == 2); | 2420 assert(getSrcSize() == 2); |
| 2356 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2421 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 2357 intptr_t StartPosition = Asm->GetPosition(); | 2422 intptr_t StartPosition = Asm->GetPosition(); |
| 2358 Type Ty = getSrc(0)->getType(); | 2423 Type Ty = getSrc(0)->getType(); |
| 2359 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 2424 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
| 2425 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 2360 const x86::Address Addr = Mem->toAsmAddress(Asm); | 2426 const x86::Address Addr = Mem->toAsmAddress(Asm); |
| 2361 const Variable *VarReg = llvm::cast<Variable>(getSrc(1)); | 2427 const Variable *VarReg = llvm::cast<Variable>(getSrc(1)); |
| 2362 assert(VarReg->hasReg()); | 2428 assert(VarReg->hasReg()); |
| 2363 const RegX8632::GPRRegister Reg = | 2429 const RegX8632::GPRRegister Reg = |
| 2364 RegX8632::getEncodedGPR(VarReg->getRegNum()); | 2430 RegX8632::getEncodedGPR(VarReg->getRegNum()); |
| 2365 Asm->xchg(Ty, Addr, Reg); | 2431 Asm->xchg(Ty, Addr, Reg); |
| 2366 emitIASBytes(Str, Asm, StartPosition); | 2432 emitIASBytes(Func, Asm, StartPosition); |
| 2367 } | 2433 } |
| 2368 | 2434 |
| 2369 void InstX8632Xchg::dump(const Cfg *Func) const { | 2435 void InstX8632Xchg::dump(const Cfg *Func) const { |
| 2370 Ostream &Str = Func->getContext()->getStrDump(); | 2436 Ostream &Str = Func->getContext()->getStrDump(); |
| 2371 Type Ty = getSrc(0)->getType(); | 2437 Type Ty = getSrc(0)->getType(); |
| 2372 Str << "xchg." << Ty << " "; | 2438 Str << "xchg." << Ty << " "; |
| 2373 dumpSources(Func); | 2439 dumpSources(Func); |
| 2374 } | 2440 } |
| 2375 | 2441 |
| 2376 void OperandX8632Mem::emit(const Cfg *Func) const { | 2442 void OperandX8632Mem::emit(const Cfg *Func) const { |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2463 Str << "+"; | 2529 Str << "+"; |
| 2464 Offset->dump(Func, Str); | 2530 Offset->dump(Func, Str); |
| 2465 } | 2531 } |
| 2466 } else { | 2532 } else { |
| 2467 // There is only the offset. | 2533 // There is only the offset. |
| 2468 Offset->dump(Func, Str); | 2534 Offset->dump(Func, Str); |
| 2469 } | 2535 } |
| 2470 Str << "]"; | 2536 Str << "]"; |
| 2471 } | 2537 } |
| 2472 | 2538 |
| 2539 void OperandX8632Mem::emitSegmentOverride(x86::AssemblerX86 *Asm) const { |
| 2540 if (SegmentReg != DefaultSegment) { |
| 2541 Asm->EmitSegmentOverride(InstX8632SegmentPrefixes[SegmentReg]); |
| 2542 } |
| 2543 } |
| 2544 |
| 2473 x86::Address OperandX8632Mem::toAsmAddress(Assembler *Asm) const { | 2545 x86::Address OperandX8632Mem::toAsmAddress(Assembler *Asm) const { |
| 2474 int32_t Disp = 0; | 2546 int32_t Disp = 0; |
| 2475 AssemblerFixup *Fixup = NULL; | 2547 AssemblerFixup *Fixup = NULL; |
| 2476 // Determine the offset (is it relocatable?) | 2548 // Determine the offset (is it relocatable?) |
| 2477 if (getOffset()) { | 2549 if (getOffset()) { |
| 2478 if (ConstantInteger32 *CI = | 2550 if (ConstantInteger32 *CI = |
| 2479 llvm::dyn_cast<ConstantInteger32>(getOffset())) { | 2551 llvm::dyn_cast<ConstantInteger32>(getOffset())) { |
| 2480 Disp = static_cast<int32_t>(CI->getValue()); | 2552 Disp = static_cast<int32_t>(CI->getValue()); |
| 2481 } else if (ConstantRelocatable *CR = | 2553 } else if (ConstantRelocatable *CR = |
| 2482 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { | 2554 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { |
| 2483 // TODO(jvoung): CR + non-zero-offset isn't really tested yet, | |
| 2484 // since the addressing mode optimization doesn't try to combine | |
| 2485 // ConstantRelocatable with something else. | |
| 2486 assert(CR->getOffset() == 0); | |
| 2487 Fixup = x86::DisplacementRelocation::create(Asm, FK_Abs_4, CR); | 2555 Fixup = x86::DisplacementRelocation::create(Asm, FK_Abs_4, CR); |
| 2488 } else { | 2556 } else { |
| 2489 llvm_unreachable("Unexpected offset type"); | 2557 llvm_unreachable("Unexpected offset type"); |
| 2490 } | 2558 } |
| 2491 } | 2559 } |
| 2492 | 2560 |
| 2493 // Now convert to the various possible forms. | 2561 // Now convert to the various possible forms. |
| 2494 if (getBase() && getIndex()) { | 2562 if (getBase() && getIndex()) { |
| 2495 return x86::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), | 2563 return x86::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), |
| 2496 RegX8632::getEncodedGPR(getIndex()->getRegNum()), | 2564 RegX8632::getEncodedGPR(getIndex()->getRegNum()), |
| 2497 x86::ScaleFactor(getShift()), Disp); | 2565 x86::ScaleFactor(getShift()), Disp); |
| 2498 } else if (getBase()) { | 2566 } else if (getBase()) { |
| 2499 return x86::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), Disp); | 2567 return x86::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), Disp); |
| 2500 } else if (getIndex()) { | 2568 } else if (getIndex()) { |
| 2501 return x86::Address(RegX8632::getEncodedGPR(getIndex()->getRegNum()), | 2569 return x86::Address(RegX8632::getEncodedGPR(getIndex()->getRegNum()), |
| 2502 x86::ScaleFactor(getShift()), Disp); | 2570 x86::ScaleFactor(getShift()), Disp); |
| 2571 } else if (Fixup) { |
| 2572 // The fixup itself has an offset, so Disp should still be 0. |
| 2573 assert(Disp == 0); |
| 2574 return x86::Address::Absolute(Fixup); |
| 2503 } else { | 2575 } else { |
| 2504 return x86::Address::Absolute(Disp, Fixup); | 2576 return x86::Address::Absolute(Disp); |
| 2505 } | 2577 } |
| 2506 } | 2578 } |
| 2507 | 2579 |
| 2580 x86::Address VariableSplit::toAsmAddress(const Cfg *Func) const { |
| 2581 assert(!Var->hasReg()); |
| 2582 const TargetLowering *Target = Func->getTarget(); |
| 2583 int32_t Offset = Var->getStackOffset() + Target->getStackAdjustment(); |
| 2584 if (Part == High) |
| 2585 Offset += 4; |
| 2586 return x86::Address(RegX8632::getEncodedGPR(Target->getFrameOrStackReg()), |
| 2587 Offset); |
| 2588 } |
| 2589 |
| 2508 void VariableSplit::emit(const Cfg *Func) const { | 2590 void VariableSplit::emit(const Cfg *Func) const { |
| 2509 Ostream &Str = Func->getContext()->getStrEmit(); | 2591 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2510 assert(!Var->hasReg()); | 2592 assert(!Var->hasReg()); |
| 2511 // The following is copied/adapted from TargetX8632::emitVariable(). | 2593 // The following is copied/adapted from TargetX8632::emitVariable(). |
| 2512 const TargetLowering *Target = Func->getTarget(); | 2594 const TargetLowering *Target = Func->getTarget(); |
| 2513 const Type Ty = IceType_i32; | 2595 const Type Ty = IceType_i32; |
| 2514 Str << TypeX8632Attributes[Ty].WidthString << " [" | 2596 Str << TypeX8632Attributes[Ty].WidthString << " [" |
| 2515 << Target->getRegName(Target->getFrameOrStackReg(), Ty); | 2597 << Target->getRegName(Target->getFrameOrStackReg(), Ty); |
| 2516 int32_t Offset = Var->getStackOffset() + Target->getStackAdjustment(); | 2598 int32_t Offset = Var->getStackOffset() + Target->getStackAdjustment(); |
| 2517 if (Part == High) | 2599 if (Part == High) |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2538 } | 2620 } |
| 2539 Str << "("; | 2621 Str << "("; |
| 2540 if (Func) | 2622 if (Func) |
| 2541 Var->dump(Func); | 2623 Var->dump(Func); |
| 2542 else | 2624 else |
| 2543 Var->dump(Str); | 2625 Var->dump(Str); |
| 2544 Str << ")"; | 2626 Str << ")"; |
| 2545 } | 2627 } |
| 2546 | 2628 |
| 2547 } // end of namespace Ice | 2629 } // end of namespace Ice |
| OLD | NEW |