bool SelectLEAAddr(SDValue N, SDValue &Base,
SDValue &Scale, SDValue &Index, SDValue &Disp,
SDValue &Segment);
+ bool SelectLEA64_32Addr(SDValue N, SDValue &Base,
+ SDValue &Scale, SDValue &Index, SDValue &Disp,
+ SDValue &Segment);
bool SelectTLSADDRAddr(SDValue N, SDValue &Base,
SDValue &Scale, SDValue &Index, SDValue &Disp,
SDValue &Segment);
// In static codegen with small code model, we can get the address of a label
// into a register with 'movl'. TableGen has already made sure we're looking
// at a label of some kind.
- assert(N->getOpcode() == X86ISD::Wrapper && "Unexpected node type for MOV32ri64");
+ assert(N->getOpcode() == X86ISD::Wrapper &&
+ "Unexpected node type for MOV32ri64");
N = N.getOperand(0);
if (N->getOpcode() != ISD::TargetConstantPool &&
return TM.getCodeModel() == CodeModel::Small;
}
+bool X86DAGToDAGISel::SelectLEA64_32Addr(SDValue N, SDValue &Base,
+ SDValue &Scale, SDValue &Index,
+ SDValue &Disp, SDValue &Segment) {
+ if (!SelectLEAAddr(N, Base, Scale, Index, Disp, Segment))
+ return false;
+
+ SDLoc DL(N);
+ RegisterSDNode *RN = dyn_cast<RegisterSDNode>(Base);
+ if (RN && RN->getReg() == 0)
+ Base = CurDAG->getRegister(0, MVT::i64);
+ else if (Base.getValueType() == MVT::i32) {
+ // Base could already be %rip, particularly in the x32 ABI.
+ Base = SDValue(CurDAG->getMachineNode(
+ TargetOpcode::SUBREG_TO_REG, DL, MVT::i64,
+ CurDAG->getTargetConstant(0, MVT::i64),
+ Base,
+ CurDAG->getTargetConstant(X86::sub_32bit, MVT::i32)),
+ 0);
+ }
+
+ RN = dyn_cast<RegisterSDNode>(Index);
+ if (RN && RN->getReg() == 0)
+ Index = CurDAG->getRegister(0, MVT::i64);
+ else {
+ assert(Index.getValueType() == MVT::i32 &&
+ "Expect to be extending 32-bit registers for use in LEA");
+ Index = SDValue(CurDAG->getMachineNode(
+ TargetOpcode::SUBREG_TO_REG, DL, MVT::i64,
+ CurDAG->getTargetConstant(0, MVT::i64),
+ Index,
+ CurDAG->getTargetConstant(X86::sub_32bit, MVT::i32)),
+ 0);
+ }
+
+ return true;
+}
+
/// SelectLEAAddr - it calls SelectAddr and determines if the maximal addressing
/// mode it matches can be cost effectively emitted as an LEA instruction.
bool X86DAGToDAGISel::SelectLEAAddr(SDValue N,
bool isDead = MI->getOperand(0).isDead();
bool isKill = MI->getOperand(1).isKill();
- unsigned Opc = TM.getSubtarget<X86Subtarget>().is64Bit()
- ? X86::LEA64_32r : X86::LEA32r;
MachineRegisterInfo &RegInfo = MFI->getParent()->getRegInfo();
- unsigned leaInReg = RegInfo.createVirtualRegister(&X86::GR32_NOSPRegClass);
unsigned leaOutReg = RegInfo.createVirtualRegister(&X86::GR32RegClass);
+ unsigned Opc, leaInReg;
+ if (TM.getSubtarget<X86Subtarget>().is64Bit()) {
+ Opc = X86::LEA64_32r;
+ leaInReg = RegInfo.createVirtualRegister(&X86::GR64_NOSPRegClass);
+ } else {
+ Opc = X86::LEA32r;
+ leaInReg = RegInfo.createVirtualRegister(&X86::GR32_NOSPRegClass);
+ }
// Build and insert into an implicit UNDEF value. This is OK because
// well be shifting and then extracting the lower 16-bits.
// just a single insert_subreg.
addRegReg(MIB, leaInReg, true, leaInReg, false);
} else {
- leaInReg2 = RegInfo.createVirtualRegister(&X86::GR32_NOSPRegClass);
+ if (TM.getSubtarget<X86Subtarget>().is64Bit())
+ leaInReg2 = RegInfo.createVirtualRegister(&X86::GR64_NOSPRegClass);
+ else
+ leaInReg2 = RegInfo.createVirtualRegister(&X86::GR32_NOSPRegClass);
// Build and insert into an implicit UNDEF value. This is OK because
// well be shifting and then extracting the lower 16-bits.
BuildMI(*MFI, &*MIB, MI->getDebugLoc(), get(X86::IMPLICIT_DEF),leaInReg2);
if (!isTruncatedShiftCountForLEA(ShAmt)) return 0;
// LEA can't handle ESP.
- if (TargetRegisterInfo::isVirtualRegister(Src.getReg()) &&
- !MF.getRegInfo().constrainRegClass(Src.getReg(),
- &X86::GR32_NOSPRegClass))
+ bool isKill = Src.isKill();
+ unsigned SrcReg = Src.getReg();
+ if (is64Bit) {
+ unsigned NewSrc = MF.getRegInfo().createVirtualRegister(&X86::GR64_NOSPRegClass);
+ BuildMI(*MI->getParent(), MI, MI->getDebugLoc(), get(TargetOpcode::COPY))
+ .addReg(NewSrc, RegState::Define | RegState::Undef, X86::sub_32bit)
+ .addOperand(Src);
+
+ SrcReg = NewSrc;
+ isKill = true;
+ } else if (TargetRegisterInfo::isVirtualRegister(SrcReg) &&
+ !MF.getRegInfo().constrainRegClass(SrcReg,
+ &X86::GR32_NOSPRegClass)) {
return 0;
+ }
unsigned Opc = is64Bit ? X86::LEA64_32r : X86::LEA32r;
NewMI = BuildMI(MF, MI->getDebugLoc(), get(Opc))
.addOperand(Dest)
- .addReg(0).addImm(1 << ShAmt).addOperand(Src).addImm(0).addReg(0);
+ .addReg(0).addImm(1 << ShAmt)
+ .addReg(SrcReg, getKillRegState(isKill)).addImm(0).addReg(0);
break;
}
case X86::SHL16ri: {
assert(MI->getNumOperands() >= 2 && "Unknown inc instruction!");
unsigned Opc = MIOpc == X86::INC64r ? X86::LEA64r
: (is64Bit ? X86::LEA64_32r : X86::LEA32r);
- const TargetRegisterClass *RC = MIOpc == X86::INC64r ?
+ const TargetRegisterClass *RC = is64Bit ?
(const TargetRegisterClass*)&X86::GR64_NOSPRegClass :
(const TargetRegisterClass*)&X86::GR32_NOSPRegClass;
// LEA can't handle RSP.
- if (TargetRegisterInfo::isVirtualRegister(Src.getReg()) &&
- !MF.getRegInfo().constrainRegClass(Src.getReg(), RC))
+ bool isKill = Src.isKill();
+ unsigned SrcReg = Src.getReg();
+ if (Opc == X86::LEA64_32r) {
+ unsigned NewSrc = MF.getRegInfo().createVirtualRegister(&X86::GR64_NOSPRegClass);
+ BuildMI(*MI->getParent(), MI, MI->getDebugLoc(),
+ get(TargetOpcode::COPY))
+ .addReg(NewSrc, RegState::Define | RegState::Undef, X86::sub_32bit)
+ .addOperand(Src);
+
+ SrcReg = NewSrc;
+ isKill = true;
+ } else if (TargetRegisterInfo::isVirtualRegister(SrcReg) &&
+ !MF.getRegInfo().constrainRegClass(SrcReg, RC))
return 0;
NewMI = addOffset(BuildMI(MF, MI->getDebugLoc(), get(Opc))
- .addOperand(Dest).addOperand(Src), 1);
+ .addOperand(Dest).addReg(SrcReg, getKillRegState(isKill)), 1);
break;
}
case X86::INC16r:
assert(MI->getNumOperands() >= 2 && "Unknown dec instruction!");
unsigned Opc = MIOpc == X86::DEC64r ? X86::LEA64r
: (is64Bit ? X86::LEA64_32r : X86::LEA32r);
- const TargetRegisterClass *RC = MIOpc == X86::DEC64r ?
+ const TargetRegisterClass *RC = is64Bit ?
(const TargetRegisterClass*)&X86::GR64_NOSPRegClass :
(const TargetRegisterClass*)&X86::GR32_NOSPRegClass;
// LEA can't handle RSP.
- if (TargetRegisterInfo::isVirtualRegister(Src.getReg()) &&
- !MF.getRegInfo().constrainRegClass(Src.getReg(), RC))
+ bool isKill = Src.isKill();
+ unsigned SrcReg = Src.getReg();
+ if (Opc == X86::LEA64_32r) {
+ unsigned NewSrc =
+ MF.getRegInfo().createVirtualRegister(&X86::GR64_NOSPRegClass);
+ BuildMI(*MI->getParent(), MI, MI->getDebugLoc(),
+ get(TargetOpcode::COPY))
+ .addReg(NewSrc, RegState::Define | RegState::Undef, X86::sub_32bit)
+ .addOperand(Src);
+
+ SrcReg = NewSrc;
+ isKill = true;
+ } else if (TargetRegisterInfo::isVirtualRegister(SrcReg) &&
+ !MF.getRegInfo().constrainRegClass(SrcReg, RC))
return 0;
NewMI = addOffset(BuildMI(MF, MI->getDebugLoc(), get(Opc))
- .addOperand(Dest).addOperand(Src), -1);
+ .addOperand(Dest).addReg(SrcReg, getKillRegState(isKill)), -1);
break;
}
case X86::DEC16r:
RC = &X86::GR64_NOSPRegClass;
} else {
Opc = is64Bit ? X86::LEA64_32r : X86::LEA32r;
- RC = &X86::GR32_NOSPRegClass;
+ RC = is64Bit ? &X86::GR64_NOSPRegClass : &X86::GR32_NOSPRegClass;
}
-
- unsigned Src2 = MI->getOperand(2).getReg();
- bool isKill2 = MI->getOperand(2).isKill();
+ unsigned SrcReg = Src.getReg();
+ unsigned isKill = Src.isKill();
+ const MachineOperand &Src2 = MI->getOperand(2);
+ unsigned Src2Reg = Src2.getReg();
+ bool isKill2 = Src2.isKill();
// LEA can't handle RSP.
- if (TargetRegisterInfo::isVirtualRegister(Src2) &&
- !MF.getRegInfo().constrainRegClass(Src2, RC))
+ if (Opc == X86::LEA64_32r) {
+ MachineBasicBlock &MBB = *MI->getParent();
+
+ unsigned NewSrc = MF.getRegInfo().createVirtualRegister(RC);
+ BuildMI(MBB, MI, MI->getDebugLoc(), get(TargetOpcode::COPY))
+ .addReg(NewSrc, RegState::Define | RegState::Undef, X86::sub_32bit)
+ .addOperand(Src);
+ SrcReg = NewSrc;
+ isKill = true;
+
+ NewSrc = MF.getRegInfo().createVirtualRegister(RC);
+ BuildMI(MBB, MI, MI->getDebugLoc(), get(TargetOpcode::COPY))
+ .addReg(NewSrc, RegState::Define | RegState::Undef, X86::sub_32bit)
+ .addOperand(Src2);
+ Src2Reg = NewSrc;
+ isKill2 = true;
+ } else if (TargetRegisterInfo::isVirtualRegister(Src2Reg) &&
+ !MF.getRegInfo().constrainRegClass(Src2Reg, RC))
return 0;
NewMI = addRegReg(BuildMI(MF, MI->getDebugLoc(), get(Opc))
.addOperand(Dest),
- Src.getReg(), Src.isKill(), Src2, isKill2);
+ SrcReg, isKill, Src2Reg, isKill2);
// Preserve undefness of the operands.
- bool isUndef = MI->getOperand(1).isUndef();
- bool isUndef2 = MI->getOperand(2).isUndef();
- NewMI->getOperand(1).setIsUndef(isUndef);
- NewMI->getOperand(3).setIsUndef(isUndef2);
+ if (!is64Bit) {
+ bool isUndef = MI->getOperand(1).isUndef();
+ bool isUndef2 = MI->getOperand(2).isUndef();
+ NewMI->getOperand(1).setIsUndef(isUndef);
+ NewMI->getOperand(3).setIsUndef(isUndef2);
+ }
- if (LV && isKill2)
- LV->replaceKillInstruction(Src2, MI, NewMI);
+ if (LV && Src2.isKill())
+ LV->replaceKillInstruction(Src2Reg, MI, NewMI);
break;
}
case X86::ADD16rr:
case X86::ADD32ri_DB:
case X86::ADD32ri8_DB: {
assert(MI->getNumOperands() >= 3 && "Unknown add instruction!");
- unsigned Opc = is64Bit ? X86::LEA64_32r : X86::LEA32r;
- NewMI = addOffset(BuildMI(MF, MI->getDebugLoc(), get(Opc))
- .addOperand(Dest).addOperand(Src),
- MI->getOperand(2).getImm());
+ if (is64Bit) {
+ unsigned NewSrc =
+ MF.getRegInfo().createVirtualRegister(&X86::GR64_NOSPRegClass);
+ BuildMI(*MI->getParent(), MI, MI->getDebugLoc(),
+ get(TargetOpcode::COPY))
+ .addReg(NewSrc, RegState::Define | RegState::Undef, X86::sub_32bit)
+ .addOperand(Src);
+
+ NewMI = addOffset(BuildMI(MF, MI->getDebugLoc(), get(X86::LEA64_32r))
+ .addOperand(Dest)
+ .addReg(NewSrc, getKillRegState(true)),
+ MI->getOperand(2).getImm());
+ } else {
+ NewMI = addOffset(BuildMI(MF, MI->getDebugLoc(), get(X86::LEA32r))
+ .addOperand(Dest).addOperand(Src),
+ MI->getOperand(2).getImm());
+ }
+
break;
}
case X86::ADD16ri: