mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 19:31:58 +00:00
[mips] Add support for mfhc1 and mthc1.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188848 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ad341d48f0
commit
b1f4f120a5
@ -338,6 +338,10 @@ def MFC1 : MFC1_FT<"mfc1", GPR32Opnd, FGR32Opnd, IIFmoveC1, bitconvert>,
|
|||||||
MFC1_FM<0>;
|
MFC1_FM<0>;
|
||||||
def MTC1 : MTC1_FT<"mtc1", FGR32Opnd, GPR32Opnd, IIFmoveC1, bitconvert>,
|
def MTC1 : MTC1_FT<"mtc1", FGR32Opnd, GPR32Opnd, IIFmoveC1, bitconvert>,
|
||||||
MFC1_FM<4>;
|
MFC1_FM<4>;
|
||||||
|
def MFHC1 : MFC1_FT<"mfhc1", GPR32Opnd, FGRH32Opnd, IIFmoveC1>,
|
||||||
|
MFC1_FM<3>;
|
||||||
|
def MTHC1 : MTC1_FT<"mthc1", FGRH32Opnd, GPR32Opnd, IIFmoveC1>,
|
||||||
|
MFC1_FM<7>;
|
||||||
def DMFC1 : MFC1_FT<"dmfc1", GPR64Opnd, FGR64Opnd, IIFmoveC1,
|
def DMFC1 : MFC1_FT<"dmfc1", GPR64Opnd, FGR64Opnd, IIFmoveC1,
|
||||||
bitconvert>, MFC1_FM<1>;
|
bitconvert>, MFC1_FM<1>;
|
||||||
def DMTC1 : MTC1_FT<"dmtc1", FGR64Opnd, GPR64Opnd, IIFmoveC1,
|
def DMTC1 : MTC1_FT<"dmtc1", FGR64Opnd, GPR64Opnd, IIFmoveC1,
|
||||||
@ -526,20 +530,27 @@ def FCMP_D64 : CEQS_FT<"d", FGR64, IIFcmp, MipsFPCmp>, CEQS_FM<17>,
|
|||||||
|
|
||||||
// This pseudo instr gets expanded into 2 mtc1 instrs after register
|
// This pseudo instr gets expanded into 2 mtc1 instrs after register
|
||||||
// allocation.
|
// allocation.
|
||||||
def BuildPairF64 :
|
class BuildPairF64Base<RegisterOperand RO> :
|
||||||
PseudoSE<(outs AFGR64Opnd:$dst),
|
PseudoSE<(outs RO:$dst), (ins GPR32Opnd:$lo, GPR32Opnd:$hi),
|
||||||
(ins GPR32Opnd:$lo, GPR32Opnd:$hi),
|
[(set RO:$dst, (MipsBuildPairF64 GPR32Opnd:$lo, GPR32Opnd:$hi))]>;
|
||||||
[(set AFGR64Opnd:$dst,
|
|
||||||
(MipsBuildPairF64 GPR32Opnd:$lo, GPR32Opnd:$hi))]>;
|
def BuildPairF64 : BuildPairF64Base<AFGR64Opnd>,
|
||||||
|
Requires<[NotFP64bit, HasStdEnc]>;
|
||||||
|
def BuildPairF64_64 : BuildPairF64Base<FGR64Opnd>,
|
||||||
|
Requires<[IsFP64bit, HasStdEnc]>;
|
||||||
|
|
||||||
// This pseudo instr gets expanded into 2 mfc1 instrs after register
|
// This pseudo instr gets expanded into 2 mfc1 instrs after register
|
||||||
// allocation.
|
// allocation.
|
||||||
// if n is 0, lower part of src is extracted.
|
// if n is 0, lower part of src is extracted.
|
||||||
// if n is 1, higher part of src is extracted.
|
// if n is 1, higher part of src is extracted.
|
||||||
def ExtractElementF64 :
|
class ExtractElementF64Base<RegisterOperand RO> :
|
||||||
PseudoSE<(outs GPR32Opnd:$dst), (ins AFGR64Opnd:$src, i32imm:$n),
|
PseudoSE<(outs GPR32Opnd:$dst), (ins RO:$src, i32imm:$n),
|
||||||
[(set GPR32Opnd:$dst,
|
[(set GPR32Opnd:$dst, (MipsExtractElementF64 RO:$src, imm:$n))]>;
|
||||||
(MipsExtractElementF64 AFGR64Opnd:$src, imm:$n))]>;
|
|
||||||
|
def ExtractElementF64 : ExtractElementF64Base<AFGR64Opnd>,
|
||||||
|
Requires<[NotFP64bit, HasStdEnc]>;
|
||||||
|
def ExtractElementF64_64 : ExtractElementF64Base<FGR64Opnd>,
|
||||||
|
Requires<[IsFP64bit, HasStdEnc]>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// InstAliases.
|
// InstAliases.
|
||||||
|
@ -263,10 +263,16 @@ bool MipsSEInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const {
|
|||||||
expandCvtFPInt(MBB, MI, Mips::CVT_D64_L, Mips::DMTC1, true);
|
expandCvtFPInt(MBB, MI, Mips::CVT_D64_L, Mips::DMTC1, true);
|
||||||
break;
|
break;
|
||||||
case Mips::BuildPairF64:
|
case Mips::BuildPairF64:
|
||||||
expandBuildPairF64(MBB, MI);
|
expandBuildPairF64(MBB, MI, false);
|
||||||
|
break;
|
||||||
|
case Mips::BuildPairF64_64:
|
||||||
|
expandBuildPairF64(MBB, MI, true);
|
||||||
break;
|
break;
|
||||||
case Mips::ExtractElementF64:
|
case Mips::ExtractElementF64:
|
||||||
expandExtractElementF64(MBB, MI);
|
expandExtractElementF64(MBB, MI, false);
|
||||||
|
break;
|
||||||
|
case Mips::ExtractElementF64_64:
|
||||||
|
expandExtractElementF64(MBB, MI, true);
|
||||||
break;
|
break;
|
||||||
case Mips::PseudoLDC1:
|
case Mips::PseudoLDC1:
|
||||||
expandDPLoadStore(MBB, MI, Mips::LDC1, Mips::LWC1);
|
expandDPLoadStore(MBB, MI, Mips::LDC1, Mips::LWC1);
|
||||||
@ -419,22 +425,26 @@ void MipsSEInstrInfo::expandCvtFPInt(MachineBasicBlock &MBB,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MipsSEInstrInfo::expandExtractElementF64(MachineBasicBlock &MBB,
|
void MipsSEInstrInfo::expandExtractElementF64(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator I) const {
|
MachineBasicBlock::iterator I,
|
||||||
|
bool FP64) const {
|
||||||
unsigned DstReg = I->getOperand(0).getReg();
|
unsigned DstReg = I->getOperand(0).getReg();
|
||||||
unsigned SrcReg = I->getOperand(1).getReg();
|
unsigned SrcReg = I->getOperand(1).getReg();
|
||||||
unsigned N = I->getOperand(2).getImm();
|
unsigned N = I->getOperand(2).getImm();
|
||||||
const MCInstrDesc& Mfc1Tdd = get(Mips::MFC1);
|
|
||||||
DebugLoc dl = I->getDebugLoc();
|
DebugLoc dl = I->getDebugLoc();
|
||||||
|
|
||||||
assert(N < 2 && "Invalid immediate");
|
assert(N < 2 && "Invalid immediate");
|
||||||
unsigned SubIdx = N ? Mips::sub_hi : Mips::sub_lo;
|
unsigned SubIdx = N ? Mips::sub_hi : Mips::sub_lo;
|
||||||
unsigned SubReg = getRegisterInfo().getSubReg(SrcReg, SubIdx);
|
unsigned SubReg = getRegisterInfo().getSubReg(SrcReg, SubIdx);
|
||||||
|
|
||||||
BuildMI(MBB, I, dl, Mfc1Tdd, DstReg).addReg(SubReg);
|
if (SubIdx == Mips::sub_hi && FP64)
|
||||||
|
BuildMI(MBB, I, dl, get(Mips::MFHC1), DstReg).addReg(SubReg);
|
||||||
|
else
|
||||||
|
BuildMI(MBB, I, dl, get(Mips::MFC1), DstReg).addReg(SubReg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MipsSEInstrInfo::expandBuildPairF64(MachineBasicBlock &MBB,
|
void MipsSEInstrInfo::expandBuildPairF64(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator I) const {
|
MachineBasicBlock::iterator I,
|
||||||
|
bool FP64) const {
|
||||||
unsigned DstReg = I->getOperand(0).getReg();
|
unsigned DstReg = I->getOperand(0).getReg();
|
||||||
unsigned LoReg = I->getOperand(1).getReg(), HiReg = I->getOperand(2).getReg();
|
unsigned LoReg = I->getOperand(1).getReg(), HiReg = I->getOperand(2).getReg();
|
||||||
const MCInstrDesc& Mtc1Tdd = get(Mips::MTC1);
|
const MCInstrDesc& Mtc1Tdd = get(Mips::MTC1);
|
||||||
@ -445,8 +455,13 @@ void MipsSEInstrInfo::expandBuildPairF64(MachineBasicBlock &MBB,
|
|||||||
// mtc1 Hi, $fp + 1
|
// mtc1 Hi, $fp + 1
|
||||||
BuildMI(MBB, I, dl, Mtc1Tdd, TRI.getSubReg(DstReg, Mips::sub_lo))
|
BuildMI(MBB, I, dl, Mtc1Tdd, TRI.getSubReg(DstReg, Mips::sub_lo))
|
||||||
.addReg(LoReg);
|
.addReg(LoReg);
|
||||||
BuildMI(MBB, I, dl, Mtc1Tdd, TRI.getSubReg(DstReg, Mips::sub_hi))
|
|
||||||
.addReg(HiReg);
|
if (FP64)
|
||||||
|
BuildMI(MBB, I, dl, get(Mips::MTHC1), TRI.getSubReg(DstReg, Mips::sub_hi))
|
||||||
|
.addReg(HiReg);
|
||||||
|
else
|
||||||
|
BuildMI(MBB, I, dl, Mtc1Tdd, TRI.getSubReg(DstReg, Mips::sub_hi))
|
||||||
|
.addReg(HiReg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add 4 to the displacement of operand MO.
|
/// Add 4 to the displacement of operand MO.
|
||||||
|
@ -101,9 +101,9 @@ private:
|
|||||||
unsigned CvtOpc, unsigned MovOpc, bool IsI64) const;
|
unsigned CvtOpc, unsigned MovOpc, bool IsI64) const;
|
||||||
|
|
||||||
void expandExtractElementF64(MachineBasicBlock &MBB,
|
void expandExtractElementF64(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator I) const;
|
MachineBasicBlock::iterator I, bool FP64) const;
|
||||||
void expandBuildPairF64(MachineBasicBlock &MBB,
|
void expandBuildPairF64(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator I) const;
|
MachineBasicBlock::iterator I, bool FP64) const;
|
||||||
void expandDPLoadStore(MachineBasicBlock &MBB,
|
void expandDPLoadStore(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator I, unsigned OpcD,
|
MachineBasicBlock::iterator I, unsigned OpcD,
|
||||||
unsigned OpcS) const;
|
unsigned OpcS) const;
|
||||||
|
@ -1,20 +1,31 @@
|
|||||||
; RUN: llc < %s -march=mipsel | FileCheck %s
|
; RUN: llc -march=mipsel < %s | FileCheck %s -check-prefix=FP32
|
||||||
; RUN: llc < %s -march=mips | FileCheck %s
|
; RUN: llc -march=mips < %s | FileCheck %s -check-prefix=FP32
|
||||||
|
; RUN: llc -march=mipsel -mattr=+fp64 < %s | FileCheck %s -check-prefix=FP64
|
||||||
|
; RUN: llc -march=mips -mattr=+fp64 < %s | FileCheck %s -check-prefix=FP64
|
||||||
|
|
||||||
@a = external global i32
|
@a = external global i32
|
||||||
|
|
||||||
|
; CHECK-LABEL: f:
|
||||||
|
; FP32: mtc1
|
||||||
|
; FP32: mtc1
|
||||||
|
; FP64-DAG: mtc1
|
||||||
|
; FP64-DAG: mthc1
|
||||||
|
|
||||||
define double @f(i32 %a1, double %d) nounwind {
|
define double @f(i32 %a1, double %d) nounwind {
|
||||||
entry:
|
entry:
|
||||||
; CHECK: mtc1
|
|
||||||
; CHECK: mtc1
|
|
||||||
store i32 %a1, i32* @a, align 4
|
store i32 %a1, i32* @a, align 4
|
||||||
%add = fadd double %d, 2.000000e+00
|
%add = fadd double %d, 2.000000e+00
|
||||||
ret double %add
|
ret double %add
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; CHECK-LABEL: f3:
|
||||||
|
; FP32: mfc1
|
||||||
|
; FP32: mfc1
|
||||||
|
; FP64-DAG: mfc1
|
||||||
|
; FP64-DAG: mfhc1
|
||||||
|
|
||||||
define void @f3(double %d, i32 %a1) nounwind {
|
define void @f3(double %d, i32 %a1) nounwind {
|
||||||
entry:
|
entry:
|
||||||
; CHECK: mfc1
|
|
||||||
; CHECK: mfc1
|
|
||||||
tail call void @f2(i32 %a1, double %d) nounwind
|
tail call void @f2(i32 %a1, double %d) nounwind
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user