mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-21 18:29:46 +00:00
Add support to 3-addressify 16-bit instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@91104 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ac94863a1c
commit
656e51454a
@ -1058,6 +1058,107 @@ static bool hasLiveCondCodeDef(MachineInstr *MI) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// convertToThreeAddressWithLEA - Helper for convertToThreeAddress when 16-bit
|
||||
/// 16-bit LEA is disabled, use 32-bit LEA to form 3-address code by promoting
|
||||
/// to a 32-bit superregister and then truncating back down to a 16-bit
|
||||
/// subregister.
|
||||
MachineInstr *
|
||||
X86InstrInfo::convertToThreeAddressWithLEA(unsigned MIOpc,
|
||||
MachineFunction::iterator &MFI,
|
||||
MachineBasicBlock::iterator &MBBI,
|
||||
LiveVariables *LV) const {
|
||||
MachineInstr *MI = MBBI;
|
||||
unsigned Dest = MI->getOperand(0).getReg();
|
||||
unsigned Src = MI->getOperand(1).getReg();
|
||||
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::GR32RegClass);
|
||||
unsigned leaOutReg = RegInfo.createVirtualRegister(&X86::GR32RegClass);
|
||||
|
||||
// Build and insert into an implicit UNDEF value. This is OK because
|
||||
// well be shifting and then extracting the lower 16-bits.
|
||||
BuildMI(*MFI, MBBI, MI->getDebugLoc(), get(X86::IMPLICIT_DEF), leaInReg);
|
||||
MachineInstr *InsMI =
|
||||
BuildMI(*MFI, MBBI, MI->getDebugLoc(), get(X86::INSERT_SUBREG),leaInReg)
|
||||
.addReg(leaInReg)
|
||||
.addReg(Src, getKillRegState(isKill))
|
||||
.addImm(X86::SUBREG_16BIT);
|
||||
|
||||
MachineInstrBuilder MIB = BuildMI(*MFI, MBBI, MI->getDebugLoc(),
|
||||
get(Opc), leaOutReg);
|
||||
switch (MIOpc) {
|
||||
default:
|
||||
llvm_unreachable(0);
|
||||
break;
|
||||
case X86::SHL16ri: {
|
||||
unsigned ShAmt = MI->getOperand(2).getImm();
|
||||
MIB.addReg(0).addImm(1 << ShAmt)
|
||||
.addReg(leaInReg, RegState::Kill).addImm(0);
|
||||
break;
|
||||
}
|
||||
case X86::INC16r:
|
||||
case X86::INC64_16r:
|
||||
addLeaRegOffset(MIB, leaInReg, true, 1);
|
||||
break;
|
||||
case X86::DEC16r:
|
||||
case X86::DEC64_16r:
|
||||
addLeaRegOffset(MIB, leaInReg, true, -1);
|
||||
break;
|
||||
case X86::ADD16ri:
|
||||
case X86::ADD16ri8:
|
||||
addLeaRegOffset(MIB, leaInReg, true, MI->getOperand(2).getImm());
|
||||
break;
|
||||
case X86::ADD16rr: {
|
||||
unsigned Src2 = MI->getOperand(2).getReg();
|
||||
bool isKill2 = MI->getOperand(2).isKill();
|
||||
unsigned leaInReg2 = 0;
|
||||
MachineInstr *InsMI2 = 0;
|
||||
if (Src == Src2) {
|
||||
// ADD16rr %reg1028<kill>, %reg1028
|
||||
// just a single insert_subreg.
|
||||
addRegReg(MIB, leaInReg, true, leaInReg, false);
|
||||
} else {
|
||||
leaInReg2 = RegInfo.createVirtualRegister(&X86::GR32RegClass);
|
||||
// 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);
|
||||
InsMI2 =
|
||||
BuildMI(*MFI, MIB, MI->getDebugLoc(), get(X86::INSERT_SUBREG),leaInReg2)
|
||||
.addReg(leaInReg2)
|
||||
.addReg(Src2, getKillRegState(isKill2))
|
||||
.addImm(X86::SUBREG_16BIT);
|
||||
addRegReg(MIB, leaInReg, true, leaInReg2, true);
|
||||
}
|
||||
if (LV && isKill2 && InsMI2)
|
||||
LV->replaceKillInstruction(Src2, MI, InsMI2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
MachineInstr *NewMI = MIB;
|
||||
MachineInstr *ExtMI =
|
||||
BuildMI(*MFI, MBBI, MI->getDebugLoc(), get(X86::EXTRACT_SUBREG))
|
||||
.addReg(Dest, RegState::Define | getDeadRegState(isDead))
|
||||
.addReg(leaOutReg, RegState::Kill)
|
||||
.addImm(X86::SUBREG_16BIT);
|
||||
|
||||
if (LV) {
|
||||
// Update live variables
|
||||
LV->getVarInfo(leaInReg).Kills.push_back(NewMI);
|
||||
LV->getVarInfo(leaOutReg).Kills.push_back(ExtMI);
|
||||
if (isKill)
|
||||
LV->replaceKillInstruction(Src, MI, InsMI);
|
||||
if (isDead)
|
||||
LV->replaceKillInstruction(Dest, MI, ExtMI);
|
||||
}
|
||||
|
||||
return ExtMI;
|
||||
}
|
||||
|
||||
/// convertToThreeAddress - This method must be implemented by targets that
|
||||
/// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target
|
||||
/// may be able to convert a two-address instruction into a true
|
||||
@ -1137,51 +1238,13 @@ X86InstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
|
||||
unsigned ShAmt = MI->getOperand(2).getImm();
|
||||
if (ShAmt == 0 || ShAmt >= 4) return 0;
|
||||
|
||||
if (DisableLEA16) {
|
||||
// If 16-bit LEA is disabled, use 32-bit LEA via subregisters.
|
||||
MachineRegisterInfo &RegInfo = MFI->getParent()->getRegInfo();
|
||||
unsigned Opc = TM.getSubtarget<X86Subtarget>().is64Bit()
|
||||
? X86::LEA64_32r : X86::LEA32r;
|
||||
unsigned leaInReg = RegInfo.createVirtualRegister(&X86::GR32RegClass);
|
||||
unsigned leaOutReg = RegInfo.createVirtualRegister(&X86::GR32RegClass);
|
||||
|
||||
// Build and insert into an implicit UNDEF value. This is OK because
|
||||
// well be shifting and then extracting the lower 16-bits.
|
||||
BuildMI(*MFI, MBBI, MI->getDebugLoc(), get(X86::IMPLICIT_DEF), leaInReg);
|
||||
MachineInstr *InsMI =
|
||||
BuildMI(*MFI, MBBI, MI->getDebugLoc(), get(X86::INSERT_SUBREG),leaInReg)
|
||||
.addReg(leaInReg)
|
||||
.addReg(Src, getKillRegState(isKill))
|
||||
.addImm(X86::SUBREG_16BIT);
|
||||
|
||||
NewMI = BuildMI(*MFI, MBBI, MI->getDebugLoc(), get(Opc), leaOutReg)
|
||||
.addReg(0).addImm(1 << ShAmt)
|
||||
.addReg(leaInReg, RegState::Kill)
|
||||
.addImm(0);
|
||||
|
||||
MachineInstr *ExtMI =
|
||||
BuildMI(*MFI, MBBI, MI->getDebugLoc(), get(X86::EXTRACT_SUBREG))
|
||||
.addReg(Dest, RegState::Define | getDeadRegState(isDead))
|
||||
.addReg(leaOutReg, RegState::Kill)
|
||||
.addImm(X86::SUBREG_16BIT);
|
||||
|
||||
if (LV) {
|
||||
// Update live variables
|
||||
LV->getVarInfo(leaInReg).Kills.push_back(NewMI);
|
||||
LV->getVarInfo(leaOutReg).Kills.push_back(ExtMI);
|
||||
if (isKill)
|
||||
LV->replaceKillInstruction(Src, MI, InsMI);
|
||||
if (isDead)
|
||||
LV->replaceKillInstruction(Dest, MI, ExtMI);
|
||||
}
|
||||
return ExtMI;
|
||||
} else {
|
||||
NewMI = BuildMI(MF, MI->getDebugLoc(), get(X86::LEA16r))
|
||||
.addReg(Dest, RegState::Define | getDeadRegState(isDead))
|
||||
.addReg(0).addImm(1 << ShAmt)
|
||||
.addReg(Src, getKillRegState(isKill))
|
||||
.addImm(0);
|
||||
}
|
||||
if (DisableLEA16)
|
||||
return convertToThreeAddressWithLEA(MIOpc, MFI, MBBI, LV);
|
||||
NewMI = BuildMI(MF, MI->getDebugLoc(), get(X86::LEA16r))
|
||||
.addReg(Dest, RegState::Define | getDeadRegState(isDead))
|
||||
.addReg(0).addImm(1 << ShAmt)
|
||||
.addReg(Src, getKillRegState(isKill))
|
||||
.addImm(0);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@ -1208,7 +1271,8 @@ X86InstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
|
||||
}
|
||||
case X86::INC16r:
|
||||
case X86::INC64_16r:
|
||||
if (DisableLEA16) return 0;
|
||||
if (DisableLEA16)
|
||||
return convertToThreeAddressWithLEA(MIOpc, MFI, MBBI, LV);
|
||||
assert(MI->getNumOperands() >= 2 && "Unknown inc instruction!");
|
||||
NewMI = addRegOffset(BuildMI(MF, MI->getDebugLoc(), get(X86::LEA16r))
|
||||
.addReg(Dest, RegState::Define |
|
||||
@ -1229,7 +1293,8 @@ X86InstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
|
||||
}
|
||||
case X86::DEC16r:
|
||||
case X86::DEC64_16r:
|
||||
if (DisableLEA16) return 0;
|
||||
if (DisableLEA16)
|
||||
return convertToThreeAddressWithLEA(MIOpc, MFI, MBBI, LV);
|
||||
assert(MI->getNumOperands() >= 2 && "Unknown dec instruction!");
|
||||
NewMI = addRegOffset(BuildMI(MF, MI->getDebugLoc(), get(X86::LEA16r))
|
||||
.addReg(Dest, RegState::Define |
|
||||
@ -1252,7 +1317,8 @@ X86InstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
|
||||
break;
|
||||
}
|
||||
case X86::ADD16rr: {
|
||||
if (DisableLEA16) return 0;
|
||||
if (DisableLEA16)
|
||||
return convertToThreeAddressWithLEA(MIOpc, MFI, MBBI, LV);
|
||||
assert(MI->getNumOperands() >= 3 && "Unknown add instruction!");
|
||||
unsigned Src2 = MI->getOperand(2).getReg();
|
||||
bool isKill2 = MI->getOperand(2).isKill();
|
||||
@ -1267,55 +1333,31 @@ X86InstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
|
||||
case X86::ADD64ri32:
|
||||
case X86::ADD64ri8:
|
||||
assert(MI->getNumOperands() >= 3 && "Unknown add instruction!");
|
||||
if (MI->getOperand(2).isImm())
|
||||
NewMI = addLeaRegOffset(BuildMI(MF, MI->getDebugLoc(), get(X86::LEA64r))
|
||||
.addReg(Dest, RegState::Define |
|
||||
getDeadRegState(isDead)),
|
||||
Src, isKill, MI->getOperand(2).getImm());
|
||||
NewMI = addLeaRegOffset(BuildMI(MF, MI->getDebugLoc(), get(X86::LEA64r))
|
||||
.addReg(Dest, RegState::Define |
|
||||
getDeadRegState(isDead)),
|
||||
Src, isKill, MI->getOperand(2).getImm());
|
||||
break;
|
||||
case X86::ADD32ri:
|
||||
case X86::ADD32ri8:
|
||||
case X86::ADD32ri8: {
|
||||
assert(MI->getNumOperands() >= 3 && "Unknown add instruction!");
|
||||
if (MI->getOperand(2).isImm()) {
|
||||
unsigned Opc = is64Bit ? X86::LEA64_32r : X86::LEA32r;
|
||||
NewMI = addLeaRegOffset(BuildMI(MF, MI->getDebugLoc(), get(Opc))
|
||||
.addReg(Dest, RegState::Define |
|
||||
getDeadRegState(isDead)),
|
||||
unsigned Opc = is64Bit ? X86::LEA64_32r : X86::LEA32r;
|
||||
NewMI = addLeaRegOffset(BuildMI(MF, MI->getDebugLoc(), get(Opc))
|
||||
.addReg(Dest, RegState::Define |
|
||||
getDeadRegState(isDead)),
|
||||
Src, isKill, MI->getOperand(2).getImm());
|
||||
}
|
||||
break;
|
||||
case X86::ADD16ri:
|
||||
case X86::ADD16ri8:
|
||||
if (DisableLEA16) return 0;
|
||||
assert(MI->getNumOperands() >= 3 && "Unknown add instruction!");
|
||||
if (MI->getOperand(2).isImm())
|
||||
NewMI = addRegOffset(BuildMI(MF, MI->getDebugLoc(), get(X86::LEA16r))
|
||||
.addReg(Dest, RegState::Define |
|
||||
getDeadRegState(isDead)),
|
||||
Src, isKill, MI->getOperand(2).getImm());
|
||||
break;
|
||||
case X86::SHL16ri:
|
||||
if (DisableLEA16) return 0;
|
||||
case X86::SHL32ri:
|
||||
case X86::SHL64ri: {
|
||||
assert(MI->getNumOperands() >= 3 && MI->getOperand(2).isImm() &&
|
||||
"Unknown shl instruction!");
|
||||
unsigned ShAmt = MI->getOperand(2).getImm();
|
||||
if (ShAmt == 1 || ShAmt == 2 || ShAmt == 3) {
|
||||
X86AddressMode AM;
|
||||
AM.Scale = 1 << ShAmt;
|
||||
AM.IndexReg = Src;
|
||||
unsigned Opc = MIOpc == X86::SHL64ri ? X86::LEA64r
|
||||
: (MIOpc == X86::SHL32ri
|
||||
? (is64Bit ? X86::LEA64_32r : X86::LEA32r) : X86::LEA16r);
|
||||
NewMI = addFullAddress(BuildMI(MF, MI->getDebugLoc(), get(Opc))
|
||||
.addReg(Dest, RegState::Define |
|
||||
getDeadRegState(isDead)), AM);
|
||||
if (isKill)
|
||||
NewMI->getOperand(3).setIsKill(true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case X86::ADD16ri:
|
||||
case X86::ADD16ri8:
|
||||
if (DisableLEA16)
|
||||
return convertToThreeAddressWithLEA(MIOpc, MFI, MBBI, LV);
|
||||
assert(MI->getNumOperands() >= 3 && "Unknown add instruction!");
|
||||
NewMI = addLeaRegOffset(BuildMI(MF, MI->getDebugLoc(), get(X86::LEA16r))
|
||||
.addReg(Dest, RegState::Define |
|
||||
getDeadRegState(isDead)),
|
||||
Src, isKill, MI->getOperand(2).getImm());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -637,6 +637,11 @@ public:
|
||||
unsigned getGlobalBaseReg(MachineFunction *MF) const;
|
||||
|
||||
private:
|
||||
MachineInstr * convertToThreeAddressWithLEA(unsigned MIOpc,
|
||||
MachineFunction::iterator &MFI,
|
||||
MachineBasicBlock::iterator &MBBI,
|
||||
LiveVariables *LV) const;
|
||||
|
||||
MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
|
||||
MachineInstr* MI,
|
||||
unsigned OpNum,
|
||||
|
Loading…
Reference in New Issue
Block a user