mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-18 13:34:04 +00:00
Add GPRPair Register class to ARM.
Some instructions in ARM require 2 even-odd paired GPRs. This patch adds support for such register class. Patch by Weiming Zhao! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166816 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
6db893660f
commit
cd275f5687
@ -702,6 +702,8 @@ void ARMBaseInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
|
||||
Opc = ARM::VMOVD, BeginIdx = ARM::dsub_0, SubRegs = 3;
|
||||
else if (ARM::DQuadRegClass.contains(DestReg, SrcReg))
|
||||
Opc = ARM::VMOVD, BeginIdx = ARM::dsub_0, SubRegs = 4;
|
||||
else if (ARM::GPRPairRegClass.contains(DestReg, SrcReg))
|
||||
Opc = ARM::MOVr, BeginIdx = ARM::gsub_0, SubRegs = 2;
|
||||
|
||||
else if (ARM::DPairSpcRegClass.contains(DestReg, SrcReg))
|
||||
Opc = ARM::VMOVD, BeginIdx = ARM::dsub_0, SubRegs = 2, Spacing = 2;
|
||||
@ -791,6 +793,13 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
|
||||
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTRD))
|
||||
.addReg(SrcReg, getKillRegState(isKill))
|
||||
.addFrameIndex(FI).addImm(0).addMemOperand(MMO));
|
||||
} else if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
|
||||
MachineInstrBuilder MIB =
|
||||
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::STMIA))
|
||||
.addFrameIndex(FI))
|
||||
.addMemOperand(MMO);
|
||||
MIB = AddDReg(MIB, SrcReg, ARM::gsub_0, getKillRegState(isKill), TRI);
|
||||
AddDReg(MIB, SrcReg, ARM::gsub_1, 0, TRI);
|
||||
} else
|
||||
llvm_unreachable("Unknown reg class!");
|
||||
break;
|
||||
@ -938,6 +947,7 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
|
||||
DebugLoc DL;
|
||||
if (I != MBB.end()) DL = I->getDebugLoc();
|
||||
MachineFunction &MF = *MBB.getParent();
|
||||
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
|
||||
MachineFrameInfo &MFI = *MF.getFrameInfo();
|
||||
unsigned Align = MFI.getObjectAlignment(FI);
|
||||
MachineMemOperand *MMO =
|
||||
@ -963,6 +973,15 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
|
||||
if (ARM::DPRRegClass.hasSubClassEq(RC)) {
|
||||
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDRD), DestReg)
|
||||
.addFrameIndex(FI).addImm(0).addMemOperand(MMO));
|
||||
} else if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
|
||||
unsigned LdmOpc = AFI->isThumbFunction() ? ARM::t2LDMIA : ARM::LDMIA;
|
||||
MachineInstrBuilder MIB =
|
||||
AddDefaultPred(BuildMI(MBB, I, DL, get(LdmOpc))
|
||||
.addFrameIndex(FI).addImm(0).addMemOperand(MMO));
|
||||
MIB = AddDReg(MIB, DestReg, ARM::gsub_0, RegState::DefineNoRead, TRI);
|
||||
MIB = AddDReg(MIB, DestReg, ARM::gsub_1, RegState::DefineNoRead, TRI);
|
||||
if (TargetRegisterInfo::isPhysicalRegister(DestReg))
|
||||
MIB.addReg(DestReg, RegState::ImplicitDefine);
|
||||
} else
|
||||
llvm_unreachable("Unknown reg class!");
|
||||
break;
|
||||
|
@ -106,12 +106,23 @@ getReservedRegs(const MachineFunction &MF) const {
|
||||
for (unsigned i = 0; i != 16; ++i)
|
||||
Reserved.set(ARM::D16 + i);
|
||||
}
|
||||
const TargetRegisterClass *RC = &ARM::GPRPairRegClass;
|
||||
for(TargetRegisterClass::iterator I = RC->begin(), E = RC->end(); I!=E; ++I)
|
||||
for (MCSubRegIterator SI(*I, this); SI.isValid(); ++SI)
|
||||
if (Reserved.test(*SI)) Reserved.set(*I);
|
||||
|
||||
return Reserved;
|
||||
}
|
||||
|
||||
bool ARMBaseRegisterInfo::isReservedReg(const MachineFunction &MF,
|
||||
unsigned Reg) const {
|
||||
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
|
||||
const TargetRegisterClass *RC = &ARM::GPRPairRegClass;
|
||||
if (RC->contains(Reg)) {
|
||||
for (MCSubRegIterator SI(Reg, this); SI.isValid(); ++SI)
|
||||
if(isReservedReg(MF, *SI)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (Reg) {
|
||||
default: break;
|
||||
@ -147,6 +158,7 @@ ARMBaseRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC)
|
||||
case ARM::QPRRegClassID:
|
||||
case ARM::QQPRRegClassID:
|
||||
case ARM::QQQQPRRegClassID:
|
||||
case ARM::GPRPairRegClassID:
|
||||
return Super;
|
||||
}
|
||||
Super = *I++;
|
||||
|
@ -49,6 +49,9 @@ def ssub_0 : SubRegIndex;
|
||||
def ssub_1 : SubRegIndex;
|
||||
def ssub_2 : SubRegIndex<[dsub_1, ssub_0]>;
|
||||
def ssub_3 : SubRegIndex<[dsub_1, ssub_1]>;
|
||||
|
||||
def gsub_0 : SubRegIndex;
|
||||
def gsub_1 : SubRegIndex;
|
||||
// Let TableGen synthesize the remaining 12 ssub_* indices.
|
||||
// We don't need to name them.
|
||||
}
|
||||
@ -313,6 +316,17 @@ def DPair : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],
|
||||
let AltOrderSelect = [{ return 1; }];
|
||||
}
|
||||
|
||||
// Pseudo-registers representing even-odd pairs of GPRs from R1 to R13/SP.
|
||||
// These are needed by instructions (e.g. ldrexd/strexd) requiring even-odd GPRs.
|
||||
def Tuples2R : RegisterTuples<[gsub_0, gsub_1],
|
||||
[(add R0, R2, R4, R6, R8, R10, R12),
|
||||
(add R1, R3, R5, R7, R9, R11, SP)]>;
|
||||
|
||||
// Register class representing a pair of even-odd GPRs.
|
||||
def GPRPair : RegisterClass<"ARM", [untyped], 64, (add Tuples2R)> {
|
||||
let Size = 64; // 2 x 32 bits, we have no predefined type of that size.
|
||||
}
|
||||
|
||||
// Pseudo-registers representing 3 consecutive D registers.
|
||||
def Tuples3D : RegisterTuples<[dsub_0, dsub_1, dsub_2],
|
||||
[(shl DPR, 0),
|
||||
|
@ -128,9 +128,9 @@ define i32 @test10(i32 %p0) {
|
||||
|
||||
; ARMv7M: test10
|
||||
; ARMv7M: mov.w r1, #16253176
|
||||
; ARMv7M: mov.w r2, #458759
|
||||
; ARMv7M: and.w r0, r1, r0, lsr #7
|
||||
; ARMv7M: and.w r1, r2, r0, lsr #5
|
||||
; ARMv7M: mov.w r1, #458759
|
||||
; ARMv7M: and.w r1, r1, r0, lsr #5
|
||||
; ARMv7M: orrs r0, r1
|
||||
%tmp1 = lshr i32 %p0, 7 ; <i32> [#uses=1]
|
||||
%tmp2 = and i32 %tmp1, 16253176 ; <i32> [#uses=2]
|
||||
|
Loading…
x
Reference in New Issue
Block a user