mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-31 10:34:17 +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;
|
Opc = ARM::VMOVD, BeginIdx = ARM::dsub_0, SubRegs = 3;
|
||||||
else if (ARM::DQuadRegClass.contains(DestReg, SrcReg))
|
else if (ARM::DQuadRegClass.contains(DestReg, SrcReg))
|
||||||
Opc = ARM::VMOVD, BeginIdx = ARM::dsub_0, SubRegs = 4;
|
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))
|
else if (ARM::DPairSpcRegClass.contains(DestReg, SrcReg))
|
||||||
Opc = ARM::VMOVD, BeginIdx = ARM::dsub_0, SubRegs = 2, Spacing = 2;
|
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))
|
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTRD))
|
||||||
.addReg(SrcReg, getKillRegState(isKill))
|
.addReg(SrcReg, getKillRegState(isKill))
|
||||||
.addFrameIndex(FI).addImm(0).addMemOperand(MMO));
|
.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
|
} else
|
||||||
llvm_unreachable("Unknown reg class!");
|
llvm_unreachable("Unknown reg class!");
|
||||||
break;
|
break;
|
||||||
@ -938,6 +947,7 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
|
|||||||
DebugLoc DL;
|
DebugLoc DL;
|
||||||
if (I != MBB.end()) DL = I->getDebugLoc();
|
if (I != MBB.end()) DL = I->getDebugLoc();
|
||||||
MachineFunction &MF = *MBB.getParent();
|
MachineFunction &MF = *MBB.getParent();
|
||||||
|
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
|
||||||
MachineFrameInfo &MFI = *MF.getFrameInfo();
|
MachineFrameInfo &MFI = *MF.getFrameInfo();
|
||||||
unsigned Align = MFI.getObjectAlignment(FI);
|
unsigned Align = MFI.getObjectAlignment(FI);
|
||||||
MachineMemOperand *MMO =
|
MachineMemOperand *MMO =
|
||||||
@ -963,6 +973,15 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
|
|||||||
if (ARM::DPRRegClass.hasSubClassEq(RC)) {
|
if (ARM::DPRRegClass.hasSubClassEq(RC)) {
|
||||||
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDRD), DestReg)
|
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDRD), DestReg)
|
||||||
.addFrameIndex(FI).addImm(0).addMemOperand(MMO));
|
.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
|
} else
|
||||||
llvm_unreachable("Unknown reg class!");
|
llvm_unreachable("Unknown reg class!");
|
||||||
break;
|
break;
|
||||||
|
@ -106,12 +106,23 @@ getReservedRegs(const MachineFunction &MF) const {
|
|||||||
for (unsigned i = 0; i != 16; ++i)
|
for (unsigned i = 0; i != 16; ++i)
|
||||||
Reserved.set(ARM::D16 + 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;
|
return Reserved;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ARMBaseRegisterInfo::isReservedReg(const MachineFunction &MF,
|
bool ARMBaseRegisterInfo::isReservedReg(const MachineFunction &MF,
|
||||||
unsigned Reg) const {
|
unsigned Reg) const {
|
||||||
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
|
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) {
|
switch (Reg) {
|
||||||
default: break;
|
default: break;
|
||||||
@ -147,6 +158,7 @@ ARMBaseRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC)
|
|||||||
case ARM::QPRRegClassID:
|
case ARM::QPRRegClassID:
|
||||||
case ARM::QQPRRegClassID:
|
case ARM::QQPRRegClassID:
|
||||||
case ARM::QQQQPRRegClassID:
|
case ARM::QQQQPRRegClassID:
|
||||||
|
case ARM::GPRPairRegClassID:
|
||||||
return Super;
|
return Super;
|
||||||
}
|
}
|
||||||
Super = *I++;
|
Super = *I++;
|
||||||
|
@ -49,6 +49,9 @@ def ssub_0 : SubRegIndex;
|
|||||||
def ssub_1 : SubRegIndex;
|
def ssub_1 : SubRegIndex;
|
||||||
def ssub_2 : SubRegIndex<[dsub_1, ssub_0]>;
|
def ssub_2 : SubRegIndex<[dsub_1, ssub_0]>;
|
||||||
def ssub_3 : SubRegIndex<[dsub_1, ssub_1]>;
|
def ssub_3 : SubRegIndex<[dsub_1, ssub_1]>;
|
||||||
|
|
||||||
|
def gsub_0 : SubRegIndex;
|
||||||
|
def gsub_1 : SubRegIndex;
|
||||||
// Let TableGen synthesize the remaining 12 ssub_* indices.
|
// Let TableGen synthesize the remaining 12 ssub_* indices.
|
||||||
// We don't need to name them.
|
// 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; }];
|
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.
|
// Pseudo-registers representing 3 consecutive D registers.
|
||||||
def Tuples3D : RegisterTuples<[dsub_0, dsub_1, dsub_2],
|
def Tuples3D : RegisterTuples<[dsub_0, dsub_1, dsub_2],
|
||||||
[(shl DPR, 0),
|
[(shl DPR, 0),
|
||||||
|
@ -128,9 +128,9 @@ define i32 @test10(i32 %p0) {
|
|||||||
|
|
||||||
; ARMv7M: test10
|
; ARMv7M: test10
|
||||||
; ARMv7M: mov.w r1, #16253176
|
; ARMv7M: mov.w r1, #16253176
|
||||||
; ARMv7M: mov.w r2, #458759
|
|
||||||
; ARMv7M: and.w r0, r1, r0, lsr #7
|
; 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
|
; ARMv7M: orrs r0, r1
|
||||||
%tmp1 = lshr i32 %p0, 7 ; <i32> [#uses=1]
|
%tmp1 = lshr i32 %p0, 7 ; <i32> [#uses=1]
|
||||||
%tmp2 = and i32 %tmp1, 16253176 ; <i32> [#uses=2]
|
%tmp2 = and i32 %tmp1, 16253176 ; <i32> [#uses=2]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user