mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-12 02:33:33 +00:00
[mips] Handle reading, writing or copying of ccond field of DSP control
register. - Define pseudo instructions which store or load ccond field of the DSP control register. - Emit the pseudos in MipsSEInstrInfo::storeRegToStack and loadRegFromStack. - Expand the pseudos before callee-scan save. - Emit instructions RDDSP or WRDSP to copy between ccond field and GPRs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180969 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
53f1b19c6e
commit
99ad6ac65e
@ -1231,10 +1231,14 @@ def PREPEND : PREPEND_ENC, PREPEND_DESC;
|
||||
}
|
||||
|
||||
// Pseudos.
|
||||
/// Pseudo instructions for loading and storing accumulator registers.
|
||||
let isPseudo = 1 in {
|
||||
// Pseudo instructions for loading and storing accumulator registers.
|
||||
defm LOAD_AC_DSP : LoadM<"load_ac_dsp", ACRegsDSP>;
|
||||
defm STORE_AC_DSP : StoreM<"store_ac_dsp", ACRegsDSP>;
|
||||
|
||||
// Pseudos for loading and storing ccond field of DSP control register.
|
||||
defm LOAD_CCOND_DSP : LoadM<"load_ccond_dsp", DSPCC>;
|
||||
defm STORE_CCOND_DSP : StoreM<"store_ccond_dsp", DSPCC>;
|
||||
}
|
||||
|
||||
// Pseudo CMP and PICK instructions.
|
||||
|
@ -40,6 +40,8 @@ public:
|
||||
|
||||
private:
|
||||
bool expandInstr(MachineBasicBlock &MBB, Iter I);
|
||||
void expandLoadCCond(MachineBasicBlock &MBB, Iter I);
|
||||
void expandStoreCCond(MachineBasicBlock &MBB, Iter I);
|
||||
void expandLoadACC(MachineBasicBlock &MBB, Iter I, unsigned RegSize);
|
||||
void expandStoreACC(MachineBasicBlock &MBB, Iter I, unsigned RegSize);
|
||||
bool expandCopy(MachineBasicBlock &MBB, Iter I);
|
||||
@ -71,6 +73,14 @@ bool ExpandPseudo::expand() {
|
||||
|
||||
bool ExpandPseudo::expandInstr(MachineBasicBlock &MBB, Iter I) {
|
||||
switch(I->getOpcode()) {
|
||||
case Mips::LOAD_CCOND_DSP:
|
||||
case Mips::LOAD_CCOND_DSP_P8:
|
||||
expandLoadCCond(MBB, I);
|
||||
break;
|
||||
case Mips::STORE_CCOND_DSP:
|
||||
case Mips::STORE_CCOND_DSP_P8:
|
||||
expandStoreCCond(MBB, I);
|
||||
break;
|
||||
case Mips::LOAD_AC64:
|
||||
case Mips::LOAD_AC64_P8:
|
||||
case Mips::LOAD_AC_DSP:
|
||||
@ -103,6 +113,36 @@ bool ExpandPseudo::expandInstr(MachineBasicBlock &MBB, Iter I) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ExpandPseudo::expandLoadCCond(MachineBasicBlock &MBB, Iter I) {
|
||||
// load $vr, FI
|
||||
// copy ccond, $vr
|
||||
|
||||
assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());
|
||||
|
||||
const TargetRegisterClass *RC = RegInfo.intRegClass(4);
|
||||
unsigned VR = MRI.createVirtualRegister(RC);
|
||||
unsigned Dst = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
|
||||
|
||||
TII.loadRegFromStack(MBB, I, VR, FI, RC, &RegInfo, 0);
|
||||
BuildMI(MBB, I, I->getDebugLoc(), TII.get(TargetOpcode::COPY), Dst)
|
||||
.addReg(VR, RegState::Kill);
|
||||
}
|
||||
|
||||
void ExpandPseudo::expandStoreCCond(MachineBasicBlock &MBB, Iter I) {
|
||||
// copy $vr, ccond
|
||||
// store $vr, FI
|
||||
|
||||
assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());
|
||||
|
||||
const TargetRegisterClass *RC = RegInfo.intRegClass(4);
|
||||
unsigned VR = MRI.createVirtualRegister(RC);
|
||||
unsigned Src = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
|
||||
|
||||
BuildMI(MBB, I, I->getDebugLoc(), TII.get(TargetOpcode::COPY), VR)
|
||||
.addReg(Src, getKillRegState(I->getOperand(0).isKill()));
|
||||
TII.storeRegToStack(MBB, I, VR, true, FI, RC, &RegInfo, 0);
|
||||
}
|
||||
|
||||
void ExpandPseudo::expandLoadACC(MachineBasicBlock &MBB, Iter I,
|
||||
unsigned RegSize) {
|
||||
// load $vr0, FI
|
||||
|
@ -103,6 +103,11 @@ void MipsSEInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
|
||||
Opc = Mips::MFHI_DSP;
|
||||
else if (Mips::LORegsDSPRegClass.contains(SrcReg))
|
||||
Opc = Mips::MFLO_DSP;
|
||||
else if (Mips::DSPCCRegClass.contains(SrcReg)) {
|
||||
BuildMI(MBB, I, DL, get(Mips::RDDSP), DestReg).addImm(1 << 4)
|
||||
.addReg(SrcReg, RegState::Implicit | getKillRegState(KillSrc));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (Mips::CPURegsRegClass.contains(SrcReg)) { // Copy from CPU Reg.
|
||||
if (Mips::CCRRegClass.contains(DestReg))
|
||||
@ -117,6 +122,12 @@ void MipsSEInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
|
||||
Opc = Mips::MTHI_DSP;
|
||||
else if (Mips::LORegsDSPRegClass.contains(DestReg))
|
||||
Opc = Mips::MTLO_DSP;
|
||||
else if (Mips::DSPCCRegClass.contains(DestReg)) {
|
||||
BuildMI(MBB, I, DL, get(Mips::WRDSP))
|
||||
.addReg(SrcReg, getKillRegState(KillSrc)).addImm(1 << 4)
|
||||
.addReg(DestReg, RegState::ImplicitDefine);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (Mips::FGR32RegClass.contains(DestReg, SrcReg))
|
||||
Opc = Mips::FMOV_S;
|
||||
@ -180,6 +191,8 @@ storeRegToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
|
||||
Opc = IsN64 ? Mips::STORE_AC_DSP_P8 : Mips::STORE_AC_DSP;
|
||||
else if (Mips::ACRegs128RegClass.hasSubClassEq(RC))
|
||||
Opc = IsN64 ? Mips::STORE_AC128_P8 : Mips::STORE_AC128;
|
||||
else if (Mips::DSPCCRegClass.hasSubClassEq(RC))
|
||||
Opc = IsN64 ? Mips::STORE_CCOND_DSP_P8 : Mips::STORE_CCOND_DSP;
|
||||
else if (Mips::FGR32RegClass.hasSubClassEq(RC))
|
||||
Opc = IsN64 ? Mips::SWC1_P8 : Mips::SWC1;
|
||||
else if (Mips::AFGR64RegClass.hasSubClassEq(RC))
|
||||
@ -211,6 +224,8 @@ loadRegFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
|
||||
Opc = IsN64 ? Mips::LOAD_AC_DSP_P8 : Mips::LOAD_AC_DSP;
|
||||
else if (Mips::ACRegs128RegClass.hasSubClassEq(RC))
|
||||
Opc = IsN64 ? Mips::LOAD_AC128_P8 : Mips::LOAD_AC128;
|
||||
else if (Mips::DSPCCRegClass.hasSubClassEq(RC))
|
||||
Opc = IsN64 ? Mips::LOAD_CCOND_DSP_P8 : Mips::LOAD_CCOND_DSP;
|
||||
else if (Mips::FGR32RegClass.hasSubClassEq(RC))
|
||||
Opc = IsN64 ? Mips::LWC1_P8 : Mips::LWC1;
|
||||
else if (Mips::AFGR64RegClass.hasSubClassEq(RC))
|
||||
|
@ -19,3 +19,23 @@ entry:
|
||||
declare i64 @llvm.mips.maddu(i64, i32, i32)
|
||||
|
||||
declare void @foo1()
|
||||
|
||||
@g4 = common global <2 x i16> zeroinitializer, align 4
|
||||
@g5 = common global <2 x i16> zeroinitializer, align 4
|
||||
@g6 = common global <2 x i16> zeroinitializer, align 4
|
||||
|
||||
define { i32 } @test_ccond_spill(i32 %a.coerce, i32 %b.coerce) {
|
||||
entry:
|
||||
%0 = bitcast i32 %a.coerce to <2 x i16>
|
||||
%1 = bitcast i32 %b.coerce to <2 x i16>
|
||||
%cmp3 = icmp slt <2 x i16> %0, %1
|
||||
%sext = sext <2 x i1> %cmp3 to <2 x i16>
|
||||
store <2 x i16> %sext, <2 x i16>* @g4, align 4
|
||||
tail call void @foo1()
|
||||
%2 = load <2 x i16>* @g5, align 4
|
||||
%3 = load <2 x i16>* @g6, align 4
|
||||
%or = select <2 x i1> %cmp3, <2 x i16> %2, <2 x i16> %3
|
||||
%4 = bitcast <2 x i16> %or to i32
|
||||
%.fca.0.insert = insertvalue { i32 } undef, i32 %4, 0
|
||||
ret { i32 } %.fca.0.insert
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user