| 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 | 69 |
| 70 uint8_t InstX8632SegmentPrefixes[] = { |
| 71 #define X(val, name, prefix) prefix, |
| 72 SEG_REGX8632_TABLE |
| 73 #undef X |
| 74 }; |
| 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) |
| 79 : OperandX8632(kMem, Ty), Base(Base), Offset(Offset), Index(Index), | 85 : OperandX8632(kMem, Ty), Base(Base), Offset(Offset), Index(Index), |
| (...skipping 247 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 = |
| 545 x86::DisplacementRelocation::create(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 = |
| 571 x86::DisplacementRelocation::create(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 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1184 Str << "\tcwd\n"; | 1193 Str << "\tcwd\n"; |
| 1185 break; | 1194 break; |
| 1186 case IceType_i32: | 1195 case IceType_i32: |
| 1187 assert(getDest()->getRegNum() == RegX8632::Reg_edx); | 1196 assert(getDest()->getRegNum() == RegX8632::Reg_edx); |
| 1188 Str << "\tcdq\n"; | 1197 Str << "\tcdq\n"; |
| 1189 break; | 1198 break; |
| 1190 } | 1199 } |
| 1191 } | 1200 } |
| 1192 | 1201 |
| 1193 template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const { | 1202 template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const { |
| 1194 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 1195 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1203 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1196 intptr_t StartPosition = Asm->GetPosition(); | 1204 intptr_t StartPosition = Asm->GetPosition(); |
| 1197 assert(getSrcSize() == 1); | 1205 assert(getSrcSize() == 1); |
| 1198 Operand *Src0 = getSrc(0); | 1206 Operand *Src0 = getSrc(0); |
| 1199 assert(llvm::isa<Variable>(Src0)); | 1207 assert(llvm::isa<Variable>(Src0)); |
| 1200 assert(llvm::cast<Variable>(Src0)->getRegNum() == RegX8632::Reg_eax); | 1208 assert(llvm::cast<Variable>(Src0)->getRegNum() == RegX8632::Reg_eax); |
| 1201 switch (Src0->getType()) { | 1209 switch (Src0->getType()) { |
| 1202 default: | 1210 default: |
| 1203 llvm_unreachable("unexpected source type!"); | 1211 llvm_unreachable("unexpected source type!"); |
| 1204 break; | 1212 break; |
| 1205 case IceType_i8: | 1213 case IceType_i8: |
| 1206 assert(getDest()->getRegNum() == RegX8632::Reg_eax); | 1214 assert(getDest()->getRegNum() == RegX8632::Reg_eax); |
| 1207 Asm->cbw(); | 1215 Asm->cbw(); |
| 1208 break; | 1216 break; |
| 1209 case IceType_i16: | 1217 case IceType_i16: |
| 1210 assert(getDest()->getRegNum() == RegX8632::Reg_edx); | 1218 assert(getDest()->getRegNum() == RegX8632::Reg_edx); |
| 1211 Asm->cwd(); | 1219 Asm->cwd(); |
| 1212 break; | 1220 break; |
| 1213 case IceType_i32: | 1221 case IceType_i32: |
| 1214 assert(getDest()->getRegNum() == RegX8632::Reg_edx); | 1222 assert(getDest()->getRegNum() == RegX8632::Reg_edx); |
| 1215 Asm->cdq(); | 1223 Asm->cdq(); |
| 1216 break; | 1224 break; |
| 1217 } | 1225 } |
| 1218 emitIASBytes(Str, Asm, StartPosition); | 1226 emitIASBytes(Func, Asm, StartPosition); |
| 1219 } | 1227 } |
| 1220 | 1228 |
| 1221 void InstX8632Mul::emit(const Cfg *Func) const { | 1229 void InstX8632Mul::emit(const Cfg *Func) const { |
| 1222 Ostream &Str = Func->getContext()->getStrEmit(); | 1230 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1223 assert(getSrcSize() == 2); | 1231 assert(getSrcSize() == 2); |
| 1224 assert(llvm::isa<Variable>(getSrc(0))); | 1232 assert(llvm::isa<Variable>(getSrc(0))); |
| 1225 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); | 1233 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); |
| 1226 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? | 1234 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? |
| 1227 Str << "\tmul\t"; | 1235 Str << "\tmul\t"; |
| 1228 getSrc(1)->emit(Func); | 1236 getSrc(1)->emit(Func); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1306 assert(Condition != CondX86::Br_None); | 1314 assert(Condition != CondX86::Br_None); |
| 1307 assert(getDest()->hasReg()); | 1315 assert(getDest()->hasReg()); |
| 1308 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "\t"; | 1316 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "\t"; |
| 1309 getDest()->emit(Func); | 1317 getDest()->emit(Func); |
| 1310 Str << ", "; | 1318 Str << ", "; |
| 1311 getSrc(1)->emit(Func); | 1319 getSrc(1)->emit(Func); |
| 1312 Str << "\n"; | 1320 Str << "\n"; |
| 1313 } | 1321 } |
| 1314 | 1322 |
| 1315 void InstX8632Cmov::emitIAS(const Cfg *Func) const { | 1323 void InstX8632Cmov::emitIAS(const Cfg *Func) const { |
| 1316 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 1317 Str << "\t"; | |
| 1318 assert(Condition != CondX86::Br_None); | 1324 assert(Condition != CondX86::Br_None); |
| 1319 assert(getDest()->hasReg()); | 1325 assert(getDest()->hasReg()); |
| 1320 assert(getSrcSize() == 2); | 1326 assert(getSrcSize() == 2); |
| 1321 // Only need the reg/reg form now. | 1327 // Only need the reg/reg form now. |
| 1322 const Variable *Src = llvm::cast<Variable>(getSrc(1)); | 1328 const Variable *Src = llvm::cast<Variable>(getSrc(1)); |
| 1323 assert(Src->hasReg()); | 1329 assert(Src->hasReg()); |
| 1324 assert(Src->getType() == IceType_i32); | 1330 assert(Src->getType() == IceType_i32); |
| 1325 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1331 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1326 intptr_t StartPosition = Asm->GetPosition(); | 1332 intptr_t StartPosition = Asm->GetPosition(); |
| 1327 Asm->cmov(Condition, RegX8632::getEncodedGPR(getDest()->getRegNum()), | 1333 Asm->cmov(Condition, RegX8632::getEncodedGPR(getDest()->getRegNum()), |
| 1328 RegX8632::getEncodedGPR(Src->getRegNum())); | 1334 RegX8632::getEncodedGPR(Src->getRegNum())); |
| 1329 emitIASBytes(Str, Asm, StartPosition); | 1335 emitIASBytes(Func, Asm, StartPosition); |
| 1330 } | 1336 } |
| 1331 | 1337 |
| 1332 void InstX8632Cmov::dump(const Cfg *Func) const { | 1338 void InstX8632Cmov::dump(const Cfg *Func) const { |
| 1333 Ostream &Str = Func->getContext()->getStrDump(); | 1339 Ostream &Str = Func->getContext()->getStrDump(); |
| 1334 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "."; | 1340 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "."; |
| 1335 Str << getDest()->getType() << " "; | 1341 Str << getDest()->getType() << " "; |
| 1336 dumpDest(Func); | 1342 dumpDest(Func); |
| 1337 Str << ", "; | 1343 Str << ", "; |
| 1338 dumpSources(Func); | 1344 dumpSources(Func); |
| 1339 } | 1345 } |
| 1340 | 1346 |
| 1341 void InstX8632Cmpps::emit(const Cfg *Func) const { | 1347 void InstX8632Cmpps::emit(const Cfg *Func) const { |
| 1342 Ostream &Str = Func->getContext()->getStrEmit(); | 1348 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1343 assert(getSrcSize() == 2); | 1349 assert(getSrcSize() == 2); |
| 1344 assert(Condition < CondX86::Cmpps_Invalid); | 1350 assert(Condition < CondX86::Cmpps_Invalid); |
| 1345 Str << "\t"; | 1351 Str << "\t"; |
| 1346 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" | 1352 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" |
| 1347 << "\t"; | 1353 << "\t"; |
| 1348 getDest()->emit(Func); | 1354 getDest()->emit(Func); |
| 1349 Str << ", "; | 1355 Str << ", "; |
| 1350 getSrc(1)->emit(Func); | 1356 getSrc(1)->emit(Func); |
| 1351 Str << "\n"; | 1357 Str << "\n"; |
| 1352 } | 1358 } |
| 1353 | 1359 |
| 1354 void InstX8632Cmpps::emitIAS(const Cfg *Func) const { | 1360 void InstX8632Cmpps::emitIAS(const Cfg *Func) const { |
| 1355 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 1356 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1361 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1357 intptr_t StartPosition = Asm->GetPosition(); | 1362 intptr_t StartPosition = Asm->GetPosition(); |
| 1358 assert(getSrcSize() == 2); | 1363 assert(getSrcSize() == 2); |
| 1359 assert(Condition < CondX86::Cmpps_Invalid); | 1364 assert(Condition < CondX86::Cmpps_Invalid); |
| 1360 // Assuming there isn't any load folding for cmpps, and vector constants | 1365 // Assuming there isn't any load folding for cmpps, and vector constants |
| 1361 // are not allowed in PNaCl. | 1366 // are not allowed in PNaCl. |
| 1362 assert(llvm::isa<Variable>(getSrc(1))); | 1367 assert(llvm::isa<Variable>(getSrc(1))); |
| 1363 const Variable *SrcVar = llvm::cast<Variable>(getSrc(1)); | 1368 const Variable *SrcVar = llvm::cast<Variable>(getSrc(1)); |
| 1364 if (SrcVar->hasReg()) { | 1369 if (SrcVar->hasReg()) { |
| 1365 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), | 1370 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), |
| 1366 RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition); | 1371 RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition); |
| 1367 } else { | 1372 } else { |
| 1368 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) | 1373 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) |
| 1369 ->stackVarToAsmOperand(SrcVar); | 1374 ->stackVarToAsmOperand(SrcVar); |
| 1370 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr, | 1375 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr, |
| 1371 Condition); | 1376 Condition); |
| 1372 } | 1377 } |
| 1373 emitIASBytes(Str, Asm, StartPosition); | 1378 emitIASBytes(Func, Asm, StartPosition); |
| 1374 } | 1379 } |
| 1375 | 1380 |
| 1376 void InstX8632Cmpps::dump(const Cfg *Func) const { | 1381 void InstX8632Cmpps::dump(const Cfg *Func) const { |
| 1377 Ostream &Str = Func->getContext()->getStrDump(); | 1382 Ostream &Str = Func->getContext()->getStrDump(); |
| 1378 assert(Condition < CondX86::Cmpps_Invalid); | 1383 assert(Condition < CondX86::Cmpps_Invalid); |
| 1379 dumpDest(Func); | 1384 dumpDest(Func); |
| 1380 Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" | 1385 Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" |
| 1381 << "\t"; | 1386 << "\t"; |
| 1382 dumpSources(Func); | 1387 dumpSources(Func); |
| 1383 } | 1388 } |
| 1384 | 1389 |
| 1385 void InstX8632Cmpxchg::emit(const Cfg *Func) const { | 1390 void InstX8632Cmpxchg::emit(const Cfg *Func) const { |
| 1386 Ostream &Str = Func->getContext()->getStrEmit(); | 1391 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1387 assert(getSrcSize() == 3); | 1392 assert(getSrcSize() == 3); |
| 1388 if (Locked) { | 1393 if (Locked) { |
| 1389 Str << "\tlock"; | 1394 Str << "\tlock"; |
| 1390 } | 1395 } |
| 1391 Str << "\tcmpxchg\t"; | 1396 Str << "\tcmpxchg\t"; |
| 1392 getSrc(0)->emit(Func); | 1397 getSrc(0)->emit(Func); |
| 1393 Str << ", "; | 1398 Str << ", "; |
| 1394 getSrc(2)->emit(Func); | 1399 getSrc(2)->emit(Func); |
| 1395 Str << "\n"; | 1400 Str << "\n"; |
| 1396 } | 1401 } |
| 1397 | 1402 |
| 1398 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const { | 1403 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const { |
| 1399 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 1400 assert(getSrcSize() == 3); | 1404 assert(getSrcSize() == 3); |
| 1401 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1405 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1402 intptr_t StartPosition = Asm->GetPosition(); | 1406 intptr_t StartPosition = Asm->GetPosition(); |
| 1403 Type Ty = getSrc(0)->getType(); | 1407 Type Ty = getSrc(0)->getType(); |
| 1404 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 1408 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
| 1409 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 1405 const x86::Address Addr = Mem->toAsmAddress(Asm); | 1410 const x86::Address Addr = Mem->toAsmAddress(Asm); |
| 1406 const Variable *VarReg = llvm::cast<Variable>(getSrc(2)); | 1411 const Variable *VarReg = llvm::cast<Variable>(getSrc(2)); |
| 1407 assert(VarReg->hasReg()); | 1412 assert(VarReg->hasReg()); |
| 1408 const RegX8632::GPRRegister Reg = | 1413 const RegX8632::GPRRegister Reg = |
| 1409 RegX8632::getEncodedGPR(VarReg->getRegNum()); | 1414 RegX8632::getEncodedGPR(VarReg->getRegNum()); |
| 1410 if (Locked) { | 1415 if (Locked) { |
| 1411 Asm->LockCmpxchg(Ty, Addr, Reg); | 1416 Asm->LockCmpxchg(Ty, Addr, Reg); |
| 1412 } else { | 1417 } else { |
| 1413 Asm->cmpxchg(Ty, Addr, Reg); | 1418 Asm->cmpxchg(Ty, Addr, Reg); |
| 1414 } | 1419 } |
| 1415 emitIASBytes(Str, Asm, StartPosition); | 1420 emitIASBytes(Func, Asm, StartPosition); |
| 1416 } | 1421 } |
| 1417 | 1422 |
| 1418 void InstX8632Cmpxchg::dump(const Cfg *Func) const { | 1423 void InstX8632Cmpxchg::dump(const Cfg *Func) const { |
| 1419 Ostream &Str = Func->getContext()->getStrDump(); | 1424 Ostream &Str = Func->getContext()->getStrDump(); |
| 1420 if (Locked) { | 1425 if (Locked) { |
| 1421 Str << "lock "; | 1426 Str << "lock "; |
| 1422 } | 1427 } |
| 1423 Str << "cmpxchg." << getSrc(0)->getType() << " "; | 1428 Str << "cmpxchg." << getSrc(0)->getType() << " "; |
| 1424 dumpSources(Func); | 1429 dumpSources(Func); |
| 1425 } | 1430 } |
| 1426 | 1431 |
| 1427 void InstX8632Cmpxchg8b::emit(const Cfg *Func) const { | 1432 void InstX8632Cmpxchg8b::emit(const Cfg *Func) const { |
| 1428 Ostream &Str = Func->getContext()->getStrEmit(); | 1433 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1429 assert(getSrcSize() == 5); | 1434 assert(getSrcSize() == 5); |
| 1430 if (Locked) { | 1435 if (Locked) { |
| 1431 Str << "\tlock"; | 1436 Str << "\tlock"; |
| 1432 } | 1437 } |
| 1433 Str << "\tcmpxchg8b\t"; | 1438 Str << "\tcmpxchg8b\t"; |
| 1434 getSrc(0)->emit(Func); | 1439 getSrc(0)->emit(Func); |
| 1435 Str << "\n"; | 1440 Str << "\n"; |
| 1436 } | 1441 } |
| 1437 | 1442 |
| 1438 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const { | 1443 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const { |
| 1439 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 1440 assert(getSrcSize() == 5); | 1444 assert(getSrcSize() == 5); |
| 1441 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1445 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1442 intptr_t StartPosition = Asm->GetPosition(); | 1446 intptr_t StartPosition = Asm->GetPosition(); |
| 1443 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 1447 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
| 1448 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 1444 const x86::Address Addr = Mem->toAsmAddress(Asm); | 1449 const x86::Address Addr = Mem->toAsmAddress(Asm); |
| 1445 if (Locked) { | 1450 if (Locked) { |
| 1446 Asm->lock(); | 1451 Asm->lock(); |
| 1447 } | 1452 } |
| 1448 Asm->cmpxchg8b(Addr); | 1453 Asm->cmpxchg8b(Addr); |
| 1449 emitIASBytes(Str, Asm, StartPosition); | 1454 emitIASBytes(Func, Asm, StartPosition); |
| 1450 } | 1455 } |
| 1451 | 1456 |
| 1452 void InstX8632Cmpxchg8b::dump(const Cfg *Func) const { | 1457 void InstX8632Cmpxchg8b::dump(const Cfg *Func) const { |
| 1453 Ostream &Str = Func->getContext()->getStrDump(); | 1458 Ostream &Str = Func->getContext()->getStrDump(); |
| 1454 if (Locked) { | 1459 if (Locked) { |
| 1455 Str << "lock "; | 1460 Str << "lock "; |
| 1456 } | 1461 } |
| 1457 Str << "cmpxchg8b "; | 1462 Str << "cmpxchg8b "; |
| 1458 dumpSources(Func); | 1463 dumpSources(Func); |
| 1459 } | 1464 } |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1567 if (SrcVar0->hasReg()) { | 1572 if (SrcVar0->hasReg()) { |
| 1568 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); | 1573 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); |
| 1569 } else { | 1574 } else { |
| 1570 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 1575 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 1571 ->stackVarToAsmOperand(SrcVar0)); | 1576 ->stackVarToAsmOperand(SrcVar0)); |
| 1572 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Src1, AddrEmitter); | 1577 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Src1, AddrEmitter); |
| 1573 } | 1578 } |
| 1574 } else if (const OperandX8632Mem *SrcMem0 = | 1579 } else if (const OperandX8632Mem *SrcMem0 = |
| 1575 llvm::dyn_cast<OperandX8632Mem>(Src0)) { | 1580 llvm::dyn_cast<OperandX8632Mem>(Src0)) { |
| 1576 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1581 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1582 SrcMem0->emitSegmentOverride(Asm); |
| 1577 emitIASAddrOpTyGPR(Func, Ty, SrcMem0->toAsmAddress(Asm), Src1, AddrEmitter); | 1583 emitIASAddrOpTyGPR(Func, Ty, SrcMem0->toAsmAddress(Asm), Src1, AddrEmitter); |
| 1578 } | 1584 } |
| 1579 } | 1585 } |
| 1580 | 1586 |
| 1581 void InstX8632Icmp::dump(const Cfg *Func) const { | 1587 void InstX8632Icmp::dump(const Cfg *Func) const { |
| 1582 Ostream &Str = Func->getContext()->getStrDump(); | 1588 Ostream &Str = Func->getContext()->getStrDump(); |
| 1583 Str << "cmp." << getSrc(0)->getType() << " "; | 1589 Str << "cmp." << getSrc(0)->getType() << " "; |
| 1584 dumpSources(Func); | 1590 dumpSources(Func); |
| 1585 } | 1591 } |
| 1586 | 1592 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1617 void InstX8632UD2::emit(const Cfg *Func) const { | 1623 void InstX8632UD2::emit(const Cfg *Func) const { |
| 1618 Ostream &Str = Func->getContext()->getStrEmit(); | 1624 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1619 assert(getSrcSize() == 0); | 1625 assert(getSrcSize() == 0); |
| 1620 Str << "\tud2\n"; | 1626 Str << "\tud2\n"; |
| 1621 } | 1627 } |
| 1622 | 1628 |
| 1623 void InstX8632UD2::emitIAS(const Cfg *Func) const { | 1629 void InstX8632UD2::emitIAS(const Cfg *Func) const { |
| 1624 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1630 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1625 intptr_t StartPosition = Asm->GetPosition(); | 1631 intptr_t StartPosition = Asm->GetPosition(); |
| 1626 Asm->ud2(); | 1632 Asm->ud2(); |
| 1627 Ostream &Str = Func->getContext()->getStrEmit(); | 1633 emitIASBytes(Func, Asm, StartPosition); |
| 1628 emitIASBytes(Str, Asm, StartPosition); | |
| 1629 } | 1634 } |
| 1630 | 1635 |
| 1631 void InstX8632UD2::dump(const Cfg *Func) const { | 1636 void InstX8632UD2::dump(const Cfg *Func) const { |
| 1632 Ostream &Str = Func->getContext()->getStrDump(); | 1637 Ostream &Str = Func->getContext()->getStrDump(); |
| 1633 Str << "ud2\n"; | 1638 Str << "ud2\n"; |
| 1634 } | 1639 } |
| 1635 | 1640 |
| 1636 void InstX8632Test::emit(const Cfg *Func) const { | 1641 void InstX8632Test::emit(const Cfg *Func) const { |
| 1637 Ostream &Str = Func->getContext()->getStrEmit(); | 1642 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1638 assert(getSrcSize() == 2); | 1643 assert(getSrcSize() == 2); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1661 } else { | 1666 } else { |
| 1662 llvm_unreachable("Nothing actually generates this so it's untested"); | 1667 llvm_unreachable("Nothing actually generates this so it's untested"); |
| 1663 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 1668 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 1664 ->stackVarToAsmOperand(SrcVar0)); | 1669 ->stackVarToAsmOperand(SrcVar0)); |
| 1665 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Src1, AddrEmitter); | 1670 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Src1, AddrEmitter); |
| 1666 } | 1671 } |
| 1667 } else if (const OperandX8632Mem *SrcMem0 = | 1672 } else if (const OperandX8632Mem *SrcMem0 = |
| 1668 llvm::dyn_cast<OperandX8632Mem>(Src0)) { | 1673 llvm::dyn_cast<OperandX8632Mem>(Src0)) { |
| 1669 llvm_unreachable("Nothing actually generates this so it's untested"); | 1674 llvm_unreachable("Nothing actually generates this so it's untested"); |
| 1670 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1675 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1676 SrcMem0->emitSegmentOverride(Asm); |
| 1671 emitIASAddrOpTyGPR(Func, Ty, SrcMem0->toAsmAddress(Asm), Src1, AddrEmitter); | 1677 emitIASAddrOpTyGPR(Func, Ty, SrcMem0->toAsmAddress(Asm), Src1, AddrEmitter); |
| 1672 } | 1678 } |
| 1673 } | 1679 } |
| 1674 | 1680 |
| 1675 void InstX8632Test::dump(const Cfg *Func) const { | 1681 void InstX8632Test::dump(const Cfg *Func) const { |
| 1676 Ostream &Str = Func->getContext()->getStrDump(); | 1682 Ostream &Str = Func->getContext()->getStrDump(); |
| 1677 Str << "test." << getSrc(0)->getType() << " "; | 1683 Str << "test." << getSrc(0)->getType() << " "; |
| 1678 dumpSources(Func); | 1684 dumpSources(Func); |
| 1679 } | 1685 } |
| 1680 | 1686 |
| 1681 void InstX8632Mfence::emit(const Cfg *Func) const { | 1687 void InstX8632Mfence::emit(const Cfg *Func) const { |
| 1682 Ostream &Str = Func->getContext()->getStrEmit(); | 1688 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1683 assert(getSrcSize() == 0); | 1689 assert(getSrcSize() == 0); |
| 1684 Str << "\tmfence\n"; | 1690 Str << "\tmfence\n"; |
| 1685 } | 1691 } |
| 1686 | 1692 |
| 1687 void InstX8632Mfence::emitIAS(const Cfg *Func) const { | 1693 void InstX8632Mfence::emitIAS(const Cfg *Func) const { |
| 1688 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 1689 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1694 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1690 intptr_t StartPosition = Asm->GetPosition(); | 1695 intptr_t StartPosition = Asm->GetPosition(); |
| 1691 Asm->mfence(); | 1696 Asm->mfence(); |
| 1692 emitIASBytes(Str, Asm, StartPosition); | 1697 emitIASBytes(Func, Asm, StartPosition); |
| 1693 } | 1698 } |
| 1694 | 1699 |
| 1695 void InstX8632Mfence::dump(const Cfg *Func) const { | 1700 void InstX8632Mfence::dump(const Cfg *Func) const { |
| 1696 Ostream &Str = Func->getContext()->getStrDump(); | 1701 Ostream &Str = Func->getContext()->getStrDump(); |
| 1697 Str << "mfence\n"; | 1702 Str << "mfence\n"; |
| 1698 } | 1703 } |
| 1699 | 1704 |
| 1700 void InstX8632Store::emit(const Cfg *Func) const { | 1705 void InstX8632Store::emit(const Cfg *Func) const { |
| 1701 Ostream &Str = Func->getContext()->getStrEmit(); | 1706 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1702 assert(getSrcSize() == 2); | 1707 assert(getSrcSize() == 2); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1725 getSrc(0)->emit(Func); | 1730 getSrc(0)->emit(Func); |
| 1726 Str << "\n"; | 1731 Str << "\n"; |
| 1727 } | 1732 } |
| 1728 | 1733 |
| 1729 void InstX8632StoreP::emitIAS(const Cfg *Func) const { | 1734 void InstX8632StoreP::emitIAS(const Cfg *Func) const { |
| 1730 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1735 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1731 intptr_t StartPosition = Asm->GetPosition(); | 1736 intptr_t StartPosition = Asm->GetPosition(); |
| 1732 assert(getSrcSize() == 2); | 1737 assert(getSrcSize() == 2); |
| 1733 const Variable *Src = llvm::cast<Variable>(getSrc(0)); | 1738 const Variable *Src = llvm::cast<Variable>(getSrc(0)); |
| 1734 const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); | 1739 const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); |
| 1740 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 1735 assert(Src->hasReg()); | 1741 assert(Src->hasReg()); |
| 1736 Asm->movups(DestMem->toAsmAddress(Asm), | 1742 Asm->movups(DestMem->toAsmAddress(Asm), |
| 1737 RegX8632::getEncodedXmm(Src->getRegNum())); | 1743 RegX8632::getEncodedXmm(Src->getRegNum())); |
| 1738 Ostream &Str = Func->getContext()->getStrEmit(); | 1744 emitIASBytes(Func, Asm, StartPosition); |
| 1739 emitIASBytes(Str, Asm, StartPosition); | |
| 1740 } | 1745 } |
| 1741 | 1746 |
| 1742 void InstX8632StoreP::dump(const Cfg *Func) const { | 1747 void InstX8632StoreP::dump(const Cfg *Func) const { |
| 1743 Ostream &Str = Func->getContext()->getStrDump(); | 1748 Ostream &Str = Func->getContext()->getStrDump(); |
| 1744 Str << "storep." << getSrc(0)->getType() << " "; | 1749 Str << "storep." << getSrc(0)->getType() << " "; |
| 1745 getSrc(1)->dump(Func); | 1750 getSrc(1)->dump(Func); |
| 1746 Str << ", "; | 1751 Str << ", "; |
| 1747 getSrc(0)->dump(Func); | 1752 getSrc(0)->dump(Func); |
| 1748 } | 1753 } |
| 1749 | 1754 |
| 1750 void InstX8632StoreQ::emit(const Cfg *Func) const { | 1755 void InstX8632StoreQ::emit(const Cfg *Func) const { |
| 1751 Ostream &Str = Func->getContext()->getStrEmit(); | 1756 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1752 assert(getSrcSize() == 2); | 1757 assert(getSrcSize() == 2); |
| 1753 assert(getSrc(1)->getType() == IceType_i64 || | 1758 assert(getSrc(1)->getType() == IceType_i64 || |
| 1754 getSrc(1)->getType() == IceType_f64); | 1759 getSrc(1)->getType() == IceType_f64); |
| 1755 Str << "\tmovq\t"; | 1760 Str << "\tmovq\t"; |
| 1756 getSrc(1)->emit(Func); | 1761 getSrc(1)->emit(Func); |
| 1757 Str << ", "; | 1762 Str << ", "; |
| 1758 getSrc(0)->emit(Func); | 1763 getSrc(0)->emit(Func); |
| 1759 Str << "\n"; | 1764 Str << "\n"; |
| 1760 } | 1765 } |
| 1761 | 1766 |
| 1762 void InstX8632StoreQ::emitIAS(const Cfg *Func) const { | 1767 void InstX8632StoreQ::emitIAS(const Cfg *Func) const { |
| 1763 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1768 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1764 intptr_t StartPosition = Asm->GetPosition(); | 1769 intptr_t StartPosition = Asm->GetPosition(); |
| 1765 assert(getSrcSize() == 2); | 1770 assert(getSrcSize() == 2); |
| 1766 const Variable *Src = llvm::cast<Variable>(getSrc(0)); | 1771 const Variable *Src = llvm::cast<Variable>(getSrc(0)); |
| 1767 const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); | 1772 const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); |
| 1773 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 1768 assert(Src->hasReg()); | 1774 assert(Src->hasReg()); |
| 1769 Asm->movq(DestMem->toAsmAddress(Asm), | 1775 Asm->movq(DestMem->toAsmAddress(Asm), |
| 1770 RegX8632::getEncodedXmm(Src->getRegNum())); | 1776 RegX8632::getEncodedXmm(Src->getRegNum())); |
| 1771 Ostream &Str = Func->getContext()->getStrEmit(); | 1777 emitIASBytes(Func, Asm, StartPosition); |
| 1772 emitIASBytes(Str, Asm, StartPosition); | |
| 1773 } | 1778 } |
| 1774 | 1779 |
| 1775 void InstX8632StoreQ::dump(const Cfg *Func) const { | 1780 void InstX8632StoreQ::dump(const Cfg *Func) const { |
| 1776 Ostream &Str = Func->getContext()->getStrDump(); | 1781 Ostream &Str = Func->getContext()->getStrDump(); |
| 1777 Str << "storeq." << getSrc(0)->getType() << " "; | 1782 Str << "storeq." << getSrc(0)->getType() << " "; |
| 1778 getSrc(1)->dump(Func); | 1783 getSrc(1)->dump(Func); |
| 1779 Str << ", "; | 1784 Str << ", "; |
| 1780 getSrc(0)->dump(Func); | 1785 getSrc(0)->dump(Func); |
| 1781 } | 1786 } |
| 1782 | 1787 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1842 Str << "\n"; | 1847 Str << "\n"; |
| 1843 Str << ".intel_syntax\n"; | 1848 Str << ".intel_syntax\n"; |
| 1844 } else { | 1849 } else { |
| 1845 getDest()->asType(Src->getType()).emit(Func); | 1850 getDest()->asType(Src->getType()).emit(Func); |
| 1846 Str << ", "; | 1851 Str << ", "; |
| 1847 Src->emit(Func); | 1852 Src->emit(Func); |
| 1848 Str << "\n"; | 1853 Str << "\n"; |
| 1849 } | 1854 } |
| 1850 } | 1855 } |
| 1851 | 1856 |
| 1857 template <> void InstX8632Mov::emitIAS(const Cfg *Func) const { |
| 1858 assert(getSrcSize() == 1); |
| 1859 const Variable *Dest = getDest(); |
| 1860 const Operand *Src = getSrc(0); |
| 1861 Type DestTy = Dest->getType(); |
| 1862 Type SrcTy = Src->getType(); |
| 1863 // Mov can be used for GPRs or XMM registers. Also, the type does not |
| 1864 // necessarily match (Mov can be used for bitcasts). However, when |
| 1865 // the type does not match, one of the operands must be a register. |
| 1866 // Thus, the strategy is to find out if Src or Dest are a register, |
| 1867 // then use that register's type to decide on which emitter set to use. |
| 1868 // The emitter set will include reg-reg movs, but that case should |
| 1869 // be unused when the types don't match. |
| 1870 static const x86::AssemblerX86::XmmEmitterRegOp XmmRegEmitter = { |
| 1871 &x86::AssemblerX86::movss, &x86::AssemblerX86::movss}; |
| 1872 static const x86::AssemblerX86::GPREmitterRegOp GPRRegEmitter = { |
| 1873 &x86::AssemblerX86::mov, &x86::AssemblerX86::mov, |
| 1874 &x86::AssemblerX86::mov}; |
| 1875 static const x86::AssemblerX86::GPREmitterAddrOp GPRAddrEmitter = { |
| 1876 &x86::AssemblerX86::mov, &x86::AssemblerX86::mov}; |
| 1877 // For an integer truncation operation, src is wider than dest. |
| 1878 // Ideally, we use a mov instruction whose data width matches the |
| 1879 // narrower dest. This is a problem if e.g. src is a register like |
| 1880 // esi or si where there is no 8-bit version of the register. To be |
| 1881 // safe, we instead widen the dest to match src. This works even |
| 1882 // for stack-allocated dest variables because typeWidthOnStack() |
| 1883 // pads to a 4-byte boundary even if only a lower portion is used. |
| 1884 // TODO: This assert disallows usages such as copying a floating point |
| 1885 // value between a vector and a scalar (which movss is used for). |
| 1886 // Clean this up. |
| 1887 assert(Func->getTarget()->typeWidthInBytesOnStack(getDest()->getType()) == |
| 1888 Func->getTarget()->typeWidthInBytesOnStack(Src->getType())); |
| 1889 if (Dest->hasReg()) { |
| 1890 if (isScalarFloatingType(DestTy)) { |
| 1891 emitIASRegOpTyXMM(Func, DestTy, Dest, Src, XmmRegEmitter); |
| 1892 return; |
| 1893 } else { |
| 1894 assert(isScalarIntegerType(DestTy)); |
| 1895 // Widen DestTy for truncation (see above note). We should only do this |
| 1896 // when both Src and Dest are integer types. |
| 1897 if (isScalarIntegerType(SrcTy)) { |
| 1898 DestTy = SrcTy; |
| 1899 } |
| 1900 emitIASRegOpTyGPR(Func, DestTy, Dest, Src, GPRRegEmitter); |
| 1901 return; |
| 1902 } |
| 1903 } else { |
| 1904 // Dest must be Stack and Src *could* be a register. Use Src's type |
| 1905 // to decide on the emitters. |
| 1906 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 1907 ->stackVarToAsmOperand(Dest)); |
| 1908 if (isScalarFloatingType(SrcTy)) { |
| 1909 // Src must be a register. |
| 1910 const Variable *SrcVar = llvm::cast<Variable>(Src); |
| 1911 assert(SrcVar->hasReg()); |
| 1912 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1913 intptr_t StartPosition = Asm->GetPosition(); |
| 1914 Asm->movss(SrcTy, StackAddr, |
| 1915 RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
| 1916 emitIASBytes(Func, Asm, StartPosition); |
| 1917 return; |
| 1918 } else { |
| 1919 // Src can be a register or immediate. |
| 1920 assert(isScalarIntegerType(SrcTy)); |
| 1921 emitIASAddrOpTyGPR(Func, SrcTy, StackAddr, Src, GPRAddrEmitter); |
| 1922 return; |
| 1923 } |
| 1924 return; |
| 1925 } |
| 1926 } |
| 1927 |
| 1852 template <> void InstX8632Movd::emitIAS(const Cfg *Func) const { | 1928 template <> void InstX8632Movd::emitIAS(const Cfg *Func) const { |
| 1853 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1929 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1854 intptr_t StartPosition = Asm->GetPosition(); | 1930 intptr_t StartPosition = Asm->GetPosition(); |
| 1855 assert(getSrcSize() == 1); | 1931 assert(getSrcSize() == 1); |
| 1856 const Variable *Dest = getDest(); | 1932 const Variable *Dest = getDest(); |
| 1857 const Variable *Src = llvm::cast<Variable>(getSrc(0)); | 1933 const Variable *Src = llvm::cast<Variable>(getSrc(0)); |
| 1858 // For insert/extract element (one of Src/Dest is an Xmm vector and | 1934 // For insert/extract element (one of Src/Dest is an Xmm vector and |
| 1859 // the other is an int type). | 1935 // the other is an int type). |
| 1860 if (Src->getType() == IceType_i32) { | 1936 if (Src->getType() == IceType_i32) { |
| 1861 assert(isVectorType(Dest->getType())); | 1937 assert(isVectorType(Dest->getType())); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1874 assert(Dest->getType() == IceType_i32); | 1950 assert(Dest->getType() == IceType_i32); |
| 1875 RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(Src->getRegNum()); | 1951 RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(Src->getRegNum()); |
| 1876 if (Dest->hasReg()) { | 1952 if (Dest->hasReg()) { |
| 1877 Asm->movd(RegX8632::getEncodedGPR(Dest->getRegNum()), SrcReg); | 1953 Asm->movd(RegX8632::getEncodedGPR(Dest->getRegNum()), SrcReg); |
| 1878 } else { | 1954 } else { |
| 1879 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 1955 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 1880 ->stackVarToAsmOperand(Dest)); | 1956 ->stackVarToAsmOperand(Dest)); |
| 1881 Asm->movd(StackAddr, SrcReg); | 1957 Asm->movd(StackAddr, SrcReg); |
| 1882 } | 1958 } |
| 1883 } | 1959 } |
| 1884 Ostream &Str = Func->getContext()->getStrEmit(); | 1960 emitIASBytes(Func, Asm, StartPosition); |
| 1885 emitIASBytes(Str, Asm, StartPosition); | |
| 1886 } | 1961 } |
| 1887 | 1962 |
| 1888 template <> void InstX8632Movp::emit(const Cfg *Func) const { | 1963 template <> void InstX8632Movp::emit(const Cfg *Func) const { |
| 1889 // TODO(wala,stichnot): movups works with all vector operands, but | 1964 // TODO(wala,stichnot): movups works with all vector operands, but |
| 1890 // there exist other instructions (movaps, movdqa, movdqu) that may | 1965 // there exist other instructions (movaps, movdqa, movdqu) that may |
| 1891 // perform better, depending on the data type and alignment of the | 1966 // perform better, depending on the data type and alignment of the |
| 1892 // operands. | 1967 // operands. |
| 1893 Ostream &Str = Func->getContext()->getStrEmit(); | 1968 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1894 assert(getSrcSize() == 1); | 1969 assert(getSrcSize() == 1); |
| 1895 Str << "\tmovups\t"; | 1970 Str << "\tmovups\t"; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1940 // where part of the Dest register is untouched. | 2015 // where part of the Dest register is untouched. |
| 1941 assert(getSrcSize() == 2); | 2016 assert(getSrcSize() == 2); |
| 1942 const Variable *Dest = getDest(); | 2017 const Variable *Dest = getDest(); |
| 1943 assert(Dest == getSrc(0)); | 2018 assert(Dest == getSrc(0)); |
| 1944 const Variable *Src = llvm::cast<Variable>(getSrc(1)); | 2019 const Variable *Src = llvm::cast<Variable>(getSrc(1)); |
| 1945 assert(Dest->hasReg() && Src->hasReg()); | 2020 assert(Dest->hasReg() && Src->hasReg()); |
| 1946 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2021 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1947 intptr_t StartPosition = Asm->GetPosition(); | 2022 intptr_t StartPosition = Asm->GetPosition(); |
| 1948 Asm->movss(IceType_f32, RegX8632::getEncodedXmm(Dest->getRegNum()), | 2023 Asm->movss(IceType_f32, RegX8632::getEncodedXmm(Dest->getRegNum()), |
| 1949 RegX8632::getEncodedXmm(Src->getRegNum())); | 2024 RegX8632::getEncodedXmm(Src->getRegNum())); |
| 1950 Ostream &Str = Func->getContext()->getStrEmit(); | 2025 emitIASBytes(Func, Asm, StartPosition); |
| 1951 emitIASBytes(Str, Asm, StartPosition); | |
| 1952 } | 2026 } |
| 1953 | 2027 |
| 1954 void InstX8632Movsx::emit(const Cfg *Func) const { | 2028 void InstX8632Movsx::emit(const Cfg *Func) const { |
| 1955 Ostream &Str = Func->getContext()->getStrEmit(); | 2029 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1956 assert(getSrcSize() == 1); | 2030 assert(getSrcSize() == 1); |
| 1957 Str << "\tmovsx\t"; | 2031 Str << "\tmovsx\t"; |
| 1958 getDest()->emit(Func); | 2032 getDest()->emit(Func); |
| 1959 Str << ", "; | 2033 Str << ", "; |
| 1960 getSrc(0)->emit(Func); | 2034 getSrc(0)->emit(Func); |
| 1961 Str << "\n"; | 2035 Str << "\n"; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1989 dumpSources(Func); | 2063 dumpSources(Func); |
| 1990 } | 2064 } |
| 1991 | 2065 |
| 1992 void InstX8632Nop::emit(const Cfg *Func) const { | 2066 void InstX8632Nop::emit(const Cfg *Func) const { |
| 1993 Ostream &Str = Func->getContext()->getStrEmit(); | 2067 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1994 // TODO: Emit the right code for each variant. | 2068 // TODO: Emit the right code for each variant. |
| 1995 Str << "\tnop\t# variant = " << Variant << "\n"; | 2069 Str << "\tnop\t# variant = " << Variant << "\n"; |
| 1996 } | 2070 } |
| 1997 | 2071 |
| 1998 void InstX8632Nop::emitIAS(const Cfg *Func) const { | 2072 void InstX8632Nop::emitIAS(const Cfg *Func) const { |
| 1999 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 2000 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2073 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 2001 intptr_t StartPosition = Asm->GetPosition(); | 2074 intptr_t StartPosition = Asm->GetPosition(); |
| 2002 // TODO: Emit the right code for the variant. | 2075 // TODO: Emit the right code for the variant. |
| 2003 Asm->nop(); | 2076 Asm->nop(); |
| 2004 emitIASBytes(Str, Asm, StartPosition); | 2077 emitIASBytes(Func, Asm, StartPosition); |
| 2005 } | 2078 } |
| 2006 | 2079 |
| 2007 void InstX8632Nop::dump(const Cfg *Func) const { | 2080 void InstX8632Nop::dump(const Cfg *Func) const { |
| 2008 Ostream &Str = Func->getContext()->getStrDump(); | 2081 Ostream &Str = Func->getContext()->getStrDump(); |
| 2009 Str << "nop (variant = " << Variant << ")"; | 2082 Str << "nop (variant = " << Variant << ")"; |
| 2010 } | 2083 } |
| 2011 | 2084 |
| 2012 void InstX8632Fld::emit(const Cfg *Func) const { | 2085 void InstX8632Fld::emit(const Cfg *Func) const { |
| 2013 Ostream &Str = Func->getContext()->getStrEmit(); | 2086 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2014 assert(getSrcSize() == 1); | 2087 assert(getSrcSize() == 1); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2047 x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0); | 2120 x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0); |
| 2048 Asm->movss(Ty, StackSlot, RegX8632::getEncodedXmm(Var->getRegNum())); | 2121 Asm->movss(Ty, StackSlot, RegX8632::getEncodedXmm(Var->getRegNum())); |
| 2049 Asm->fld(Ty, StackSlot); | 2122 Asm->fld(Ty, StackSlot); |
| 2050 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); | 2123 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); |
| 2051 } else { | 2124 } else { |
| 2052 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 2125 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 2053 ->stackVarToAsmOperand(Var)); | 2126 ->stackVarToAsmOperand(Var)); |
| 2054 Asm->fld(Ty, StackAddr); | 2127 Asm->fld(Ty, StackAddr); |
| 2055 } | 2128 } |
| 2056 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { | 2129 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { |
| 2130 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 2057 Asm->fld(Ty, Mem->toAsmAddress(Asm)); | 2131 Asm->fld(Ty, Mem->toAsmAddress(Asm)); |
| 2058 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { | 2132 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { |
| 2059 Asm->fld(Ty, x86::Address::ofConstPool(Func->getContext(), Asm, Imm)); | 2133 Asm->fld(Ty, x86::Address::ofConstPool(Func->getContext(), Asm, Imm)); |
| 2060 } else { | 2134 } else { |
| 2061 llvm_unreachable("Unexpected operand type"); | 2135 llvm_unreachable("Unexpected operand type"); |
| 2062 } | 2136 } |
| 2063 Ostream &Str = Func->getContext()->getStrEmit(); | 2137 emitIASBytes(Func, Asm, StartPosition); |
| 2064 emitIASBytes(Str, Asm, StartPosition); | |
| 2065 } | 2138 } |
| 2066 | 2139 |
| 2067 void InstX8632Fld::dump(const Cfg *Func) const { | 2140 void InstX8632Fld::dump(const Cfg *Func) const { |
| 2068 Ostream &Str = Func->getContext()->getStrDump(); | 2141 Ostream &Str = Func->getContext()->getStrDump(); |
| 2069 Str << "fld." << getSrc(0)->getType() << " "; | 2142 Str << "fld." << getSrc(0)->getType() << " "; |
| 2070 dumpSources(Func); | 2143 dumpSources(Func); |
| 2071 } | 2144 } |
| 2072 | 2145 |
| 2073 void InstX8632Fstp::emit(const Cfg *Func) const { | 2146 void InstX8632Fstp::emit(const Cfg *Func) const { |
| 2074 Ostream &Str = Func->getContext()->getStrEmit(); | 2147 Ostream &Str = Func->getContext()->getStrEmit(); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 2105 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2178 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 2106 intptr_t StartPosition = Asm->GetPosition(); | 2179 intptr_t StartPosition = Asm->GetPosition(); |
| 2107 assert(getSrcSize() == 0); | 2180 assert(getSrcSize() == 0); |
| 2108 const Variable *Dest = getDest(); | 2181 const Variable *Dest = getDest(); |
| 2109 // TODO(jvoung,stichnot): Utilize this by setting Dest to NULL to | 2182 // TODO(jvoung,stichnot): Utilize this by setting Dest to NULL to |
| 2110 // "partially" delete the fstp if the Dest is unused. | 2183 // "partially" delete the fstp if the Dest is unused. |
| 2111 // Even if Dest is unused, the fstp should be kept for the SideEffects | 2184 // Even if Dest is unused, the fstp should be kept for the SideEffects |
| 2112 // of popping the stack. | 2185 // of popping the stack. |
| 2113 if (Dest == NULL) { | 2186 if (Dest == NULL) { |
| 2114 Asm->fstp(RegX8632::getEncodedSTReg(0)); | 2187 Asm->fstp(RegX8632::getEncodedSTReg(0)); |
| 2115 Ostream &Str = Func->getContext()->getStrEmit(); | 2188 emitIASBytes(Func, Asm, StartPosition); |
| 2116 emitIASBytes(Str, Asm, StartPosition); | |
| 2117 return; | 2189 return; |
| 2118 } | 2190 } |
| 2119 Type Ty = Dest->getType(); | 2191 Type Ty = Dest->getType(); |
| 2120 if (!Dest->hasReg()) { | 2192 if (!Dest->hasReg()) { |
| 2121 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 2193 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 2122 ->stackVarToAsmOperand(Dest)); | 2194 ->stackVarToAsmOperand(Dest)); |
| 2123 Asm->fstp(Ty, StackAddr); | 2195 Asm->fstp(Ty, StackAddr); |
| 2124 } else { | 2196 } else { |
| 2125 // Dest is a physical (xmm) register, so st(0) needs to go through | 2197 // Dest is a physical (xmm) register, so st(0) needs to go through |
| 2126 // memory. Hack this by creating a temporary stack slot, spilling | 2198 // memory. Hack this by creating a temporary stack slot, spilling |
| 2127 // st(0) there, loading it into the xmm register, and deallocating | 2199 // st(0) there, loading it into the xmm register, and deallocating |
| 2128 // the stack slot. | 2200 // the stack slot. |
| 2129 x86::Immediate Width(typeWidthInBytes(Ty)); | 2201 x86::Immediate Width(typeWidthInBytes(Ty)); |
| 2130 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width); | 2202 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width); |
| 2131 x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0); | 2203 x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0); |
| 2132 Asm->fstp(Ty, StackSlot); | 2204 Asm->fstp(Ty, StackSlot); |
| 2133 Asm->movss(Ty, RegX8632::getEncodedXmm(Dest->getRegNum()), StackSlot); | 2205 Asm->movss(Ty, RegX8632::getEncodedXmm(Dest->getRegNum()), StackSlot); |
| 2134 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); | 2206 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); |
| 2135 } | 2207 } |
| 2136 Ostream &Str = Func->getContext()->getStrEmit(); | 2208 emitIASBytes(Func, Asm, StartPosition); |
| 2137 emitIASBytes(Str, Asm, StartPosition); | |
| 2138 } | 2209 } |
| 2139 | 2210 |
| 2140 void InstX8632Fstp::dump(const Cfg *Func) const { | 2211 void InstX8632Fstp::dump(const Cfg *Func) const { |
| 2141 Ostream &Str = Func->getContext()->getStrDump(); | 2212 Ostream &Str = Func->getContext()->getStrDump(); |
| 2142 dumpDest(Func); | 2213 dumpDest(Func); |
| 2143 Str << " = fstp." << getDest()->getType() << ", st(0)"; | 2214 Str << " = fstp." << getDest()->getType() << ", st(0)"; |
| 2144 Str << "\n"; | 2215 Str << "\n"; |
| 2145 } | 2216 } |
| 2146 | 2217 |
| 2147 template <> void InstX8632Pcmpeq::emit(const Cfg *Func) const { | 2218 template <> void InstX8632Pcmpeq::emit(const Cfg *Func) const { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2209 | 2280 |
| 2210 void InstX8632Pop::emit(const Cfg *Func) const { | 2281 void InstX8632Pop::emit(const Cfg *Func) const { |
| 2211 Ostream &Str = Func->getContext()->getStrEmit(); | 2282 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2212 assert(getSrcSize() == 0); | 2283 assert(getSrcSize() == 0); |
| 2213 Str << "\tpop\t"; | 2284 Str << "\tpop\t"; |
| 2214 getDest()->emit(Func); | 2285 getDest()->emit(Func); |
| 2215 Str << "\n"; | 2286 Str << "\n"; |
| 2216 } | 2287 } |
| 2217 | 2288 |
| 2218 void InstX8632Pop::emitIAS(const Cfg *Func) const { | 2289 void InstX8632Pop::emitIAS(const Cfg *Func) const { |
| 2219 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 2220 assert(getSrcSize() == 0); | 2290 assert(getSrcSize() == 0); |
| 2221 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2291 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 2222 intptr_t StartPosition = Asm->GetPosition(); | 2292 intptr_t StartPosition = Asm->GetPosition(); |
| 2223 if (getDest()->hasReg()) { | 2293 if (getDest()->hasReg()) { |
| 2224 Asm->popl(RegX8632::getEncodedGPR(getDest()->getRegNum())); | 2294 Asm->popl(RegX8632::getEncodedGPR(getDest()->getRegNum())); |
| 2225 } else { | 2295 } else { |
| 2226 Asm->popl(static_cast<TargetX8632 *>(Func->getTarget()) | 2296 Asm->popl(static_cast<TargetX8632 *>(Func->getTarget()) |
| 2227 ->stackVarToAsmOperand(getDest())); | 2297 ->stackVarToAsmOperand(getDest())); |
| 2228 } | 2298 } |
| 2229 emitIASBytes(Str, Asm, StartPosition); | 2299 emitIASBytes(Func, Asm, StartPosition); |
| 2230 } | 2300 } |
| 2231 | 2301 |
| 2232 void InstX8632Pop::dump(const Cfg *Func) const { | 2302 void InstX8632Pop::dump(const Cfg *Func) const { |
| 2233 Ostream &Str = Func->getContext()->getStrDump(); | 2303 Ostream &Str = Func->getContext()->getStrDump(); |
| 2234 dumpDest(Func); | 2304 dumpDest(Func); |
| 2235 Str << " = pop." << getDest()->getType() << " "; | 2305 Str << " = pop." << getDest()->getType() << " "; |
| 2236 } | 2306 } |
| 2237 | 2307 |
| 2238 void InstX8632AdjustStack::emit(const Cfg *Func) const { | 2308 void InstX8632AdjustStack::emit(const Cfg *Func) const { |
| 2239 Ostream &Str = Func->getContext()->getStrEmit(); | 2309 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2240 Str << "\tsub\tesp, " << Amount << "\n"; | 2310 Str << "\tsub\tesp, " << Amount << "\n"; |
| 2241 Func->getTarget()->updateStackAdjustment(Amount); | 2311 Func->getTarget()->updateStackAdjustment(Amount); |
| 2242 } | 2312 } |
| 2243 | 2313 |
| 2244 void InstX8632AdjustStack::emitIAS(const Cfg *Func) const { | 2314 void InstX8632AdjustStack::emitIAS(const Cfg *Func) const { |
| 2245 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 2246 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2315 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 2247 intptr_t StartPosition = Asm->GetPosition(); | 2316 intptr_t StartPosition = Asm->GetPosition(); |
| 2248 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, x86::Immediate(Amount)); | 2317 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, x86::Immediate(Amount)); |
| 2249 emitIASBytes(Str, Asm, StartPosition); | 2318 emitIASBytes(Func, Asm, StartPosition); |
| 2250 Func->getTarget()->updateStackAdjustment(Amount); | 2319 Func->getTarget()->updateStackAdjustment(Amount); |
| 2251 } | 2320 } |
| 2252 | 2321 |
| 2253 void InstX8632AdjustStack::dump(const Cfg *Func) const { | 2322 void InstX8632AdjustStack::dump(const Cfg *Func) const { |
| 2254 Ostream &Str = Func->getContext()->getStrDump(); | 2323 Ostream &Str = Func->getContext()->getStrDump(); |
| 2255 Str << "esp = sub.i32 esp, " << Amount; | 2324 Str << "esp = sub.i32 esp, " << Amount; |
| 2256 } | 2325 } |
| 2257 | 2326 |
| 2258 void InstX8632Push::emit(const Cfg *Func) const { | 2327 void InstX8632Push::emit(const Cfg *Func) const { |
| 2259 Ostream &Str = Func->getContext()->getStrEmit(); | 2328 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2260 assert(getSrcSize() == 1); | 2329 assert(getSrcSize() == 1); |
| 2261 // Push is currently only used for saving GPRs. | 2330 // Push is currently only used for saving GPRs. |
| 2262 Variable *Var = llvm::cast<Variable>(getSrc(0)); | 2331 Variable *Var = llvm::cast<Variable>(getSrc(0)); |
| 2263 assert(Var->hasReg()); | 2332 assert(Var->hasReg()); |
| 2264 Str << "\tpush\t"; | 2333 Str << "\tpush\t"; |
| 2265 Var->emit(Func); | 2334 Var->emit(Func); |
| 2266 Str << "\n"; | 2335 Str << "\n"; |
| 2267 } | 2336 } |
| 2268 | 2337 |
| 2269 void InstX8632Push::emitIAS(const Cfg *Func) const { | 2338 void InstX8632Push::emitIAS(const Cfg *Func) const { |
| 2270 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 2271 assert(getSrcSize() == 1); | 2339 assert(getSrcSize() == 1); |
| 2272 // Push is currently only used for saving GPRs. | 2340 // Push is currently only used for saving GPRs. |
| 2273 Variable *Var = llvm::cast<Variable>(getSrc(0)); | 2341 Variable *Var = llvm::cast<Variable>(getSrc(0)); |
| 2274 assert(Var->hasReg()); | 2342 assert(Var->hasReg()); |
| 2275 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2343 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 2276 intptr_t StartPosition = Asm->GetPosition(); | 2344 intptr_t StartPosition = Asm->GetPosition(); |
| 2277 Asm->pushl(RegX8632::getEncodedGPR(Var->getRegNum())); | 2345 Asm->pushl(RegX8632::getEncodedGPR(Var->getRegNum())); |
| 2278 emitIASBytes(Str, Asm, StartPosition); | 2346 emitIASBytes(Func, Asm, StartPosition); |
| 2279 } | 2347 } |
| 2280 | 2348 |
| 2281 void InstX8632Push::dump(const Cfg *Func) const { | 2349 void InstX8632Push::dump(const Cfg *Func) const { |
| 2282 Ostream &Str = Func->getContext()->getStrDump(); | 2350 Ostream &Str = Func->getContext()->getStrDump(); |
| 2283 Str << "push." << getSrc(0)->getType() << " "; | 2351 Str << "push." << getSrc(0)->getType() << " "; |
| 2284 dumpSources(Func); | 2352 dumpSources(Func); |
| 2285 } | 2353 } |
| 2286 | 2354 |
| 2287 template <> void InstX8632Psll::emit(const Cfg *Func) const { | 2355 template <> void InstX8632Psll::emit(const Cfg *Func) const { |
| 2288 assert(getDest()->getType() == IceType_v8i16 || | 2356 assert(getDest()->getType() == IceType_v8i16 || |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2305 TypeX8632Attributes[getDest()->getType()].PackString); | 2373 TypeX8632Attributes[getDest()->getType()].PackString); |
| 2306 emitTwoAddress(buf, this, Func); | 2374 emitTwoAddress(buf, this, Func); |
| 2307 } | 2375 } |
| 2308 | 2376 |
| 2309 void InstX8632Ret::emit(const Cfg *Func) const { | 2377 void InstX8632Ret::emit(const Cfg *Func) const { |
| 2310 Ostream &Str = Func->getContext()->getStrEmit(); | 2378 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2311 Str << "\tret\n"; | 2379 Str << "\tret\n"; |
| 2312 } | 2380 } |
| 2313 | 2381 |
| 2314 void InstX8632Ret::emitIAS(const Cfg *Func) const { | 2382 void InstX8632Ret::emitIAS(const Cfg *Func) const { |
| 2315 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 2316 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2383 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 2317 intptr_t StartPosition = Asm->GetPosition(); | 2384 intptr_t StartPosition = Asm->GetPosition(); |
| 2318 Asm->ret(); | 2385 Asm->ret(); |
| 2319 emitIASBytes(Str, Asm, StartPosition); | 2386 emitIASBytes(Func, Asm, StartPosition); |
| 2320 } | 2387 } |
| 2321 | 2388 |
| 2322 void InstX8632Ret::dump(const Cfg *Func) const { | 2389 void InstX8632Ret::dump(const Cfg *Func) const { |
| 2323 Ostream &Str = Func->getContext()->getStrDump(); | 2390 Ostream &Str = Func->getContext()->getStrDump(); |
| 2324 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); | 2391 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); |
| 2325 Str << "ret." << Ty << " "; | 2392 Str << "ret." << Ty << " "; |
| 2326 dumpSources(Func); | 2393 dumpSources(Func); |
| 2327 } | 2394 } |
| 2328 | 2395 |
| 2329 void InstX8632Xadd::emit(const Cfg *Func) const { | 2396 void InstX8632Xadd::emit(const Cfg *Func) const { |
| 2330 Ostream &Str = Func->getContext()->getStrEmit(); | 2397 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2331 if (Locked) { | 2398 if (Locked) { |
| 2332 Str << "\tlock"; | 2399 Str << "\tlock"; |
| 2333 } | 2400 } |
| 2334 Str << "\txadd\t"; | 2401 Str << "\txadd\t"; |
| 2335 getSrc(0)->emit(Func); | 2402 getSrc(0)->emit(Func); |
| 2336 Str << ", "; | 2403 Str << ", "; |
| 2337 getSrc(1)->emit(Func); | 2404 getSrc(1)->emit(Func); |
| 2338 Str << "\n"; | 2405 Str << "\n"; |
| 2339 } | 2406 } |
| 2340 | 2407 |
| 2341 void InstX8632Xadd::emitIAS(const Cfg *Func) const { | 2408 void InstX8632Xadd::emitIAS(const Cfg *Func) const { |
| 2342 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 2343 assert(getSrcSize() == 2); | 2409 assert(getSrcSize() == 2); |
| 2344 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2410 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 2345 intptr_t StartPosition = Asm->GetPosition(); | 2411 intptr_t StartPosition = Asm->GetPosition(); |
| 2346 Type Ty = getSrc(0)->getType(); | 2412 Type Ty = getSrc(0)->getType(); |
| 2347 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 2413 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
| 2414 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 2348 const x86::Address Addr = Mem->toAsmAddress(Asm); | 2415 const x86::Address Addr = Mem->toAsmAddress(Asm); |
| 2349 const Variable *VarReg = llvm::cast<Variable>(getSrc(1)); | 2416 const Variable *VarReg = llvm::cast<Variable>(getSrc(1)); |
| 2350 assert(VarReg->hasReg()); | 2417 assert(VarReg->hasReg()); |
| 2351 const RegX8632::GPRRegister Reg = | 2418 const RegX8632::GPRRegister Reg = |
| 2352 RegX8632::getEncodedGPR(VarReg->getRegNum()); | 2419 RegX8632::getEncodedGPR(VarReg->getRegNum()); |
| 2353 if (Locked) { | 2420 if (Locked) { |
| 2354 Asm->lock(); | 2421 Asm->lock(); |
| 2355 } | 2422 } |
| 2356 Asm->xadd(Ty, Addr, Reg); | 2423 Asm->xadd(Ty, Addr, Reg); |
| 2357 emitIASBytes(Str, Asm, StartPosition); | 2424 emitIASBytes(Func, Asm, StartPosition); |
| 2358 } | 2425 } |
| 2359 | 2426 |
| 2360 void InstX8632Xadd::dump(const Cfg *Func) const { | 2427 void InstX8632Xadd::dump(const Cfg *Func) const { |
| 2361 Ostream &Str = Func->getContext()->getStrDump(); | 2428 Ostream &Str = Func->getContext()->getStrDump(); |
| 2362 if (Locked) { | 2429 if (Locked) { |
| 2363 Str << "lock "; | 2430 Str << "lock "; |
| 2364 } | 2431 } |
| 2365 Type Ty = getSrc(0)->getType(); | 2432 Type Ty = getSrc(0)->getType(); |
| 2366 Str << "xadd." << Ty << " "; | 2433 Str << "xadd." << Ty << " "; |
| 2367 dumpSources(Func); | 2434 dumpSources(Func); |
| 2368 } | 2435 } |
| 2369 | 2436 |
| 2370 void InstX8632Xchg::emit(const Cfg *Func) const { | 2437 void InstX8632Xchg::emit(const Cfg *Func) const { |
| 2371 Ostream &Str = Func->getContext()->getStrEmit(); | 2438 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2372 Str << "\txchg\t"; | 2439 Str << "\txchg\t"; |
| 2373 getSrc(0)->emit(Func); | 2440 getSrc(0)->emit(Func); |
| 2374 Str << ", "; | 2441 Str << ", "; |
| 2375 getSrc(1)->emit(Func); | 2442 getSrc(1)->emit(Func); |
| 2376 Str << "\n"; | 2443 Str << "\n"; |
| 2377 } | 2444 } |
| 2378 | 2445 |
| 2379 void InstX8632Xchg::emitIAS(const Cfg *Func) const { | 2446 void InstX8632Xchg::emitIAS(const Cfg *Func) const { |
| 2380 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 2381 assert(getSrcSize() == 2); | 2447 assert(getSrcSize() == 2); |
| 2382 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2448 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 2383 intptr_t StartPosition = Asm->GetPosition(); | 2449 intptr_t StartPosition = Asm->GetPosition(); |
| 2384 Type Ty = getSrc(0)->getType(); | 2450 Type Ty = getSrc(0)->getType(); |
| 2385 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 2451 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
| 2452 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 2386 const x86::Address Addr = Mem->toAsmAddress(Asm); | 2453 const x86::Address Addr = Mem->toAsmAddress(Asm); |
| 2387 const Variable *VarReg = llvm::cast<Variable>(getSrc(1)); | 2454 const Variable *VarReg = llvm::cast<Variable>(getSrc(1)); |
| 2388 assert(VarReg->hasReg()); | 2455 assert(VarReg->hasReg()); |
| 2389 const RegX8632::GPRRegister Reg = | 2456 const RegX8632::GPRRegister Reg = |
| 2390 RegX8632::getEncodedGPR(VarReg->getRegNum()); | 2457 RegX8632::getEncodedGPR(VarReg->getRegNum()); |
| 2391 Asm->xchg(Ty, Addr, Reg); | 2458 Asm->xchg(Ty, Addr, Reg); |
| 2392 emitIASBytes(Str, Asm, StartPosition); | 2459 emitIASBytes(Func, Asm, StartPosition); |
| 2393 } | 2460 } |
| 2394 | 2461 |
| 2395 void InstX8632Xchg::dump(const Cfg *Func) const { | 2462 void InstX8632Xchg::dump(const Cfg *Func) const { |
| 2396 Ostream &Str = Func->getContext()->getStrDump(); | 2463 Ostream &Str = Func->getContext()->getStrDump(); |
| 2397 Type Ty = getSrc(0)->getType(); | 2464 Type Ty = getSrc(0)->getType(); |
| 2398 Str << "xchg." << Ty << " "; | 2465 Str << "xchg." << Ty << " "; |
| 2399 dumpSources(Func); | 2466 dumpSources(Func); |
| 2400 } | 2467 } |
| 2401 | 2468 |
| 2402 void OperandX8632Mem::emit(const Cfg *Func) const { | 2469 void OperandX8632Mem::emit(const Cfg *Func) const { |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2489 Str << "+"; | 2556 Str << "+"; |
| 2490 Offset->dump(Func, Str); | 2557 Offset->dump(Func, Str); |
| 2491 } | 2558 } |
| 2492 } else { | 2559 } else { |
| 2493 // There is only the offset. | 2560 // There is only the offset. |
| 2494 Offset->dump(Func, Str); | 2561 Offset->dump(Func, Str); |
| 2495 } | 2562 } |
| 2496 Str << "]"; | 2563 Str << "]"; |
| 2497 } | 2564 } |
| 2498 | 2565 |
| 2566 void OperandX8632Mem::emitSegmentOverride(x86::AssemblerX86 *Asm) const { |
| 2567 if (SegmentReg != DefaultSegment) { |
| 2568 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); |
| 2569 Asm->EmitSegmentOverride(InstX8632SegmentPrefixes[SegmentReg]); |
| 2570 } |
| 2571 } |
| 2572 |
| 2499 x86::Address OperandX8632Mem::toAsmAddress(Assembler *Asm) const { | 2573 x86::Address OperandX8632Mem::toAsmAddress(Assembler *Asm) const { |
| 2500 int32_t Disp = 0; | 2574 int32_t Disp = 0; |
| 2501 AssemblerFixup *Fixup = NULL; | 2575 AssemblerFixup *Fixup = NULL; |
| 2502 // Determine the offset (is it relocatable?) | 2576 // Determine the offset (is it relocatable?) |
| 2503 if (getOffset()) { | 2577 if (getOffset()) { |
| 2504 if (ConstantInteger32 *CI = | 2578 if (ConstantInteger32 *CI = |
| 2505 llvm::dyn_cast<ConstantInteger32>(getOffset())) { | 2579 llvm::dyn_cast<ConstantInteger32>(getOffset())) { |
| 2506 Disp = static_cast<int32_t>(CI->getValue()); | 2580 Disp = static_cast<int32_t>(CI->getValue()); |
| 2507 } else if (ConstantRelocatable *CR = | 2581 } else if (ConstantRelocatable *CR = |
| 2508 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { | 2582 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { |
| 2509 // TODO(jvoung): CR + non-zero-offset isn't really tested yet, | |
| 2510 // since the addressing mode optimization doesn't try to combine | |
| 2511 // ConstantRelocatable with something else. | |
| 2512 assert(CR->getOffset() == 0); | |
| 2513 Fixup = x86::DisplacementRelocation::create(Asm, FK_Abs_4, CR); | 2583 Fixup = x86::DisplacementRelocation::create(Asm, FK_Abs_4, CR); |
| 2514 } else { | 2584 } else { |
| 2515 llvm_unreachable("Unexpected offset type"); | 2585 llvm_unreachable("Unexpected offset type"); |
| 2516 } | 2586 } |
| 2517 } | 2587 } |
| 2518 | 2588 |
| 2519 // Now convert to the various possible forms. | 2589 // Now convert to the various possible forms. |
| 2520 if (getBase() && getIndex()) { | 2590 if (getBase() && getIndex()) { |
| 2521 return x86::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), | 2591 return x86::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), |
| 2522 RegX8632::getEncodedGPR(getIndex()->getRegNum()), | 2592 RegX8632::getEncodedGPR(getIndex()->getRegNum()), |
| 2523 x86::ScaleFactor(getShift()), Disp); | 2593 x86::ScaleFactor(getShift()), Disp); |
| 2524 } else if (getBase()) { | 2594 } else if (getBase()) { |
| 2525 return x86::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), Disp); | 2595 return x86::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), Disp); |
| 2526 } else if (getIndex()) { | 2596 } else if (getIndex()) { |
| 2527 return x86::Address(RegX8632::getEncodedGPR(getIndex()->getRegNum()), | 2597 return x86::Address(RegX8632::getEncodedGPR(getIndex()->getRegNum()), |
| 2528 x86::ScaleFactor(getShift()), Disp); | 2598 x86::ScaleFactor(getShift()), Disp); |
| 2599 } else if (Fixup) { |
| 2600 // The fixup itself has an offset, so Disp should still be 0. |
| 2601 assert(Disp == 0); |
| 2602 return x86::Address::Absolute(Fixup); |
| 2529 } else { | 2603 } else { |
| 2530 return x86::Address::Absolute(Disp, Fixup); | 2604 return x86::Address::Absolute(Disp); |
| 2531 } | 2605 } |
| 2532 } | 2606 } |
| 2533 | 2607 |
| 2608 x86::Address VariableSplit::toAsmAddress(const Cfg *Func) const { |
| 2609 assert(!Var->hasReg()); |
| 2610 const TargetLowering *Target = Func->getTarget(); |
| 2611 int32_t Offset = |
| 2612 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); |
| 2613 return x86::Address(RegX8632::getEncodedGPR(Target->getFrameOrStackReg()), |
| 2614 Offset); |
| 2615 } |
| 2616 |
| 2534 void VariableSplit::emit(const Cfg *Func) const { | 2617 void VariableSplit::emit(const Cfg *Func) const { |
| 2535 Ostream &Str = Func->getContext()->getStrEmit(); | 2618 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2536 assert(!Var->hasReg()); | 2619 assert(!Var->hasReg()); |
| 2537 // The following is copied/adapted from TargetX8632::emitVariable(). | 2620 // The following is copied/adapted from TargetX8632::emitVariable(). |
| 2538 const TargetLowering *Target = Func->getTarget(); | 2621 const TargetLowering *Target = Func->getTarget(); |
| 2539 const Type Ty = IceType_i32; | 2622 const Type Ty = IceType_i32; |
| 2540 Str << TypeX8632Attributes[Ty].WidthString << " [" | 2623 Str << TypeX8632Attributes[Ty].WidthString << " [" |
| 2541 << Target->getRegName(Target->getFrameOrStackReg(), Ty); | 2624 << Target->getRegName(Target->getFrameOrStackReg(), Ty); |
| 2542 int32_t Offset = Var->getStackOffset() + Target->getStackAdjustment(); | 2625 int32_t Offset = |
| 2543 if (Part == High) | 2626 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); |
| 2544 Offset += 4; | |
| 2545 if (Offset) { | 2627 if (Offset) { |
| 2546 if (Offset > 0) | 2628 if (Offset > 0) |
| 2547 Str << "+"; | 2629 Str << "+"; |
| 2548 Str << Offset; | 2630 Str << Offset; |
| 2549 } | 2631 } |
| 2550 Str << "]"; | 2632 Str << "]"; |
| 2551 } | 2633 } |
| 2552 | 2634 |
| 2553 void VariableSplit::dump(const Cfg *Func, Ostream &Str) const { | 2635 void VariableSplit::dump(const Cfg *Func, Ostream &Str) const { |
| 2554 switch (Part) { | 2636 switch (Part) { |
| 2555 case Low: | 2637 case Low: |
| 2556 Str << "low"; | 2638 Str << "low"; |
| 2557 break; | 2639 break; |
| 2558 case High: | 2640 case High: |
| 2559 Str << "high"; | 2641 Str << "high"; |
| 2560 break; | 2642 break; |
| 2561 default: | 2643 default: |
| 2562 Str << "???"; | 2644 Str << "???"; |
| 2563 break; | 2645 break; |
| 2564 } | 2646 } |
| 2565 Str << "("; | 2647 Str << "("; |
| 2566 if (Func) | 2648 if (Func) |
| 2567 Var->dump(Func); | 2649 Var->dump(Func); |
| 2568 else | 2650 else |
| 2569 Var->dump(Str); | 2651 Var->dump(Str); |
| 2570 Str << ")"; | 2652 Str << ")"; |
| 2571 } | 2653 } |
| 2572 | 2654 |
| 2573 } // end of namespace Ice | 2655 } // end of namespace Ice |
| OLD | NEW |