From b1f4f120a50c392c85c6b4388d63e36251fce279 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Tue, 20 Aug 2013 23:47:25 +0000 Subject: [PATCH] [mips] Add support for mfhc1 and mthc1. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188848 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsInstrFPU.td | 29 +++++++++++------ lib/Target/Mips/MipsSEInstrInfo.cpp | 31 ++++++++++++++----- lib/Target/Mips/MipsSEInstrInfo.h | 4 +-- .../Mips/buildpairextractelementf64.ll | 23 ++++++++++---- 4 files changed, 62 insertions(+), 25 deletions(-) diff --git a/lib/Target/Mips/MipsInstrFPU.td b/lib/Target/Mips/MipsInstrFPU.td index aef1ace461c..ccf3458e1d9 100644 --- a/lib/Target/Mips/MipsInstrFPU.td +++ b/lib/Target/Mips/MipsInstrFPU.td @@ -338,6 +338,10 @@ def MFC1 : MFC1_FT<"mfc1", GPR32Opnd, FGR32Opnd, IIFmoveC1, bitconvert>, MFC1_FM<0>; def MTC1 : MTC1_FT<"mtc1", FGR32Opnd, GPR32Opnd, IIFmoveC1, bitconvert>, 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, bitconvert>, MFC1_FM<1>; 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 // allocation. -def BuildPairF64 : - PseudoSE<(outs AFGR64Opnd:$dst), - (ins GPR32Opnd:$lo, GPR32Opnd:$hi), - [(set AFGR64Opnd:$dst, - (MipsBuildPairF64 GPR32Opnd:$lo, GPR32Opnd:$hi))]>; +class BuildPairF64Base : + PseudoSE<(outs RO:$dst), (ins GPR32Opnd:$lo, GPR32Opnd:$hi), + [(set RO:$dst, (MipsBuildPairF64 GPR32Opnd:$lo, GPR32Opnd:$hi))]>; + +def BuildPairF64 : BuildPairF64Base, + Requires<[NotFP64bit, HasStdEnc]>; +def BuildPairF64_64 : BuildPairF64Base, + Requires<[IsFP64bit, HasStdEnc]>; // This pseudo instr gets expanded into 2 mfc1 instrs after register // allocation. // if n is 0, lower part of src is extracted. // if n is 1, higher part of src is extracted. -def ExtractElementF64 : - PseudoSE<(outs GPR32Opnd:$dst), (ins AFGR64Opnd:$src, i32imm:$n), - [(set GPR32Opnd:$dst, - (MipsExtractElementF64 AFGR64Opnd:$src, imm:$n))]>; +class ExtractElementF64Base : + PseudoSE<(outs GPR32Opnd:$dst), (ins RO:$src, i32imm:$n), + [(set GPR32Opnd:$dst, (MipsExtractElementF64 RO:$src, imm:$n))]>; + +def ExtractElementF64 : ExtractElementF64Base, + Requires<[NotFP64bit, HasStdEnc]>; +def ExtractElementF64_64 : ExtractElementF64Base, + Requires<[IsFP64bit, HasStdEnc]>; //===----------------------------------------------------------------------===// // InstAliases. diff --git a/lib/Target/Mips/MipsSEInstrInfo.cpp b/lib/Target/Mips/MipsSEInstrInfo.cpp index 86431a20631..a81db7fab75 100644 --- a/lib/Target/Mips/MipsSEInstrInfo.cpp +++ b/lib/Target/Mips/MipsSEInstrInfo.cpp @@ -263,10 +263,16 @@ bool MipsSEInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { expandCvtFPInt(MBB, MI, Mips::CVT_D64_L, Mips::DMTC1, true); break; case Mips::BuildPairF64: - expandBuildPairF64(MBB, MI); + expandBuildPairF64(MBB, MI, false); + break; + case Mips::BuildPairF64_64: + expandBuildPairF64(MBB, MI, true); break; case Mips::ExtractElementF64: - expandExtractElementF64(MBB, MI); + expandExtractElementF64(MBB, MI, false); + break; + case Mips::ExtractElementF64_64: + expandExtractElementF64(MBB, MI, true); break; case Mips::PseudoLDC1: expandDPLoadStore(MBB, MI, Mips::LDC1, Mips::LWC1); @@ -419,22 +425,26 @@ void MipsSEInstrInfo::expandCvtFPInt(MachineBasicBlock &MBB, } void MipsSEInstrInfo::expandExtractElementF64(MachineBasicBlock &MBB, - MachineBasicBlock::iterator I) const { + MachineBasicBlock::iterator I, + bool FP64) const { unsigned DstReg = I->getOperand(0).getReg(); unsigned SrcReg = I->getOperand(1).getReg(); unsigned N = I->getOperand(2).getImm(); - const MCInstrDesc& Mfc1Tdd = get(Mips::MFC1); DebugLoc dl = I->getDebugLoc(); assert(N < 2 && "Invalid immediate"); unsigned SubIdx = N ? Mips::sub_hi : Mips::sub_lo; 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, - MachineBasicBlock::iterator I) const { + MachineBasicBlock::iterator I, + bool FP64) const { unsigned DstReg = I->getOperand(0).getReg(); unsigned LoReg = I->getOperand(1).getReg(), HiReg = I->getOperand(2).getReg(); const MCInstrDesc& Mtc1Tdd = get(Mips::MTC1); @@ -445,8 +455,13 @@ void MipsSEInstrInfo::expandBuildPairF64(MachineBasicBlock &MBB, // mtc1 Hi, $fp + 1 BuildMI(MBB, I, dl, Mtc1Tdd, TRI.getSubReg(DstReg, Mips::sub_lo)) .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. diff --git a/lib/Target/Mips/MipsSEInstrInfo.h b/lib/Target/Mips/MipsSEInstrInfo.h index d962ef0eb9c..6b4f89a732a 100644 --- a/lib/Target/Mips/MipsSEInstrInfo.h +++ b/lib/Target/Mips/MipsSEInstrInfo.h @@ -101,9 +101,9 @@ private: unsigned CvtOpc, unsigned MovOpc, bool IsI64) const; void expandExtractElementF64(MachineBasicBlock &MBB, - MachineBasicBlock::iterator I) const; + MachineBasicBlock::iterator I, bool FP64) const; void expandBuildPairF64(MachineBasicBlock &MBB, - MachineBasicBlock::iterator I) const; + MachineBasicBlock::iterator I, bool FP64) const; void expandDPLoadStore(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned OpcD, unsigned OpcS) const; diff --git a/test/CodeGen/Mips/buildpairextractelementf64.ll b/test/CodeGen/Mips/buildpairextractelementf64.ll index 585bc250fb8..490d4273c5b 100644 --- a/test/CodeGen/Mips/buildpairextractelementf64.ll +++ b/test/CodeGen/Mips/buildpairextractelementf64.ll @@ -1,20 +1,31 @@ -; RUN: llc < %s -march=mipsel | FileCheck %s -; RUN: llc < %s -march=mips | FileCheck %s +; RUN: llc -march=mipsel < %s | FileCheck %s -check-prefix=FP32 +; 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 +; CHECK-LABEL: f: +; FP32: mtc1 +; FP32: mtc1 +; FP64-DAG: mtc1 +; FP64-DAG: mthc1 + define double @f(i32 %a1, double %d) nounwind { entry: -; CHECK: mtc1 -; CHECK: mtc1 store i32 %a1, i32* @a, align 4 %add = fadd double %d, 2.000000e+00 ret double %add } +; CHECK-LABEL: f3: +; FP32: mfc1 +; FP32: mfc1 +; FP64-DAG: mfc1 +; FP64-DAG: mfhc1 + define void @f3(double %d, i32 %a1) nounwind { entry: -; CHECK: mfc1 -; CHECK: mfc1 tail call void @f2(i32 %a1, double %d) nounwind ret void }