[llvm] [MIPS] Support MIPS I hard-float double loads/stores with LWC1/SWC1 (PR #209362)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 13 20:47:37 PDT 2026
https://github.com/yingopq created https://github.com/llvm/llvm-project/pull/209362
MIPS I lacks LDC1/SDC1. This patch implements double precision loads/stores using LWC1/SWC1 instructions.
* Add BuildPairF64_FPR and ExtractElementF64_FPR nodes
* Use them in lowerLOAD/lowerSTORE for MIPS I hard-float
* Avoid redundant mtc1/mfc1 instructions
Matches GCC behavior for MIPS I hard-float.
Fix #62190.
>From 340e373070f98e0977f761d8ecb4971568d97be9 Mon Sep 17 00:00:00 2001
From: Ying Huang <ying.huang at oss.cipunited.com>
Date: Tue, 14 Jul 2026 11:42:59 +0800
Subject: [PATCH] [MIPS] Support MIPS I hard-float double loads/stores with
LWC1/SWC1
MIPS I lacks LDC1/SDC1. This patch implements double precision loads/stores
using LWC1/SWC1 instructions.
* Add BuildPairF64_FPR and ExtractElementF64_FPR nodes
* Use them in lowerLOAD/lowerSTORE for MIPS I hard-float
* Avoid redundant mtc1/mfc1 instructions
Matches GCC behavior for MIPS I hard-float.
Fix #62190.
---
llvm/lib/Target/Mips/MipsInstrFPU.td | 28 +++++++++--
llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp | 27 ++++++++++
llvm/lib/Target/Mips/MipsSEISelLowering.cpp | 34 ++++++++-----
llvm/lib/Target/Mips/MipsSEInstrInfo.cpp | 4 ++
llvm/lib/Target/Mips/MipsScheduleGeneric.td | 3 +-
llvm/lib/Target/Mips/MipsScheduleP5600.td | 4 +-
llvm/test/CodeGen/Mips/llvm-ir/load.ll | 16 ++++--
llvm/test/CodeGen/Mips/llvm-ir/select-dbl.ll | 3 +-
.../CodeGen/Mips/mips1-load-in-delay-slot.ll | 3 +-
.../Mips/mips1-not-support-ldc1-sdc1.ll | 49 +++++++++++++++++++
10 files changed, 145 insertions(+), 26 deletions(-)
create mode 100644 llvm/test/CodeGen/Mips/mips1-not-support-ldc1-sdc1.ll
diff --git a/llvm/lib/Target/Mips/MipsInstrFPU.td b/llvm/lib/Target/Mips/MipsInstrFPU.td
index 7dcebff2406fc..37defa45161db 100644
--- a/llvm/lib/Target/Mips/MipsInstrFPU.td
+++ b/llvm/lib/Target/Mips/MipsInstrFPU.td
@@ -34,9 +34,15 @@ def SDT_MipsTruncIntFP : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisFP<1>]>;
def SDT_MipsBuildPairF64 : SDTypeProfile<1, 2, [SDTCisVT<0, f64>,
SDTCisVT<1, i32>,
SDTCisSameAs<1, 2>]>;
+def SDT_MipsBuildPairF64_FPR : SDTypeProfile<1, 2, [SDTCisVT<0, f64>,
+ SDTCisVT<1, f32>,
+ SDTCisSameAs<1, 2>]>;
def SDT_MipsExtractElementF64 : SDTypeProfile<1, 2, [SDTCisVT<0, i32>,
SDTCisVT<1, f64>,
SDTCisVT<2, i32>]>;
+def SDT_MipsExtractElementF64_FPR : SDTypeProfile<1, 2, [SDTCisVT<0, f32>,
+ SDTCisVT<1, f64>,
+ SDTCisVT<2, i32>]>;
def SDT_MipsMTC1_D64 : SDTypeProfile<1, 1, [SDTCisVT<0, f64>,
SDTCisVT<1, i32>]>;
@@ -57,8 +63,12 @@ def MipsTruncIntFP : SDNode<"MipsISD::TruncIntFP", SDT_MipsTruncIntFP>;
def MipsBuildPairF64 : SDNode<"MipsISD::BuildPairF64", SDT_MipsBuildPairF64>;
def : GINodeEquiv<G_MERGE_VALUES, MipsBuildPairF64>;
+def MipsBuildPairF64_FPR : SDNode<"MipsISD::BuildPairF64_FPR", SDT_MipsBuildPairF64_FPR>;
+def : GINodeEquiv<G_MERGE_VALUES, MipsBuildPairF64_FPR>;
def MipsExtractElementF64 : SDNode<"MipsISD::ExtractElementF64",
SDT_MipsExtractElementF64>;
+def MipsExtractElementF64_FPR : SDNode<"MipsISD::ExtractElementF64_FPR",
+ SDT_MipsExtractElementF64_FPR>;
// Node used to generate an MTC1 i32 to f64 instruction
def MipsMTC1_D64 : SDNode<"MipsISD::MTC1_D64", SDT_MipsMTC1_D64>;
@@ -836,7 +846,12 @@ class BuildPairF64Base<RegisterOperand RO> :
PseudoSE<(outs RO:$dst), (ins GPR32Opnd:$lo, GPR32Opnd:$hi),
[(set RO:$dst, (MipsBuildPairF64 GPR32Opnd:$lo, GPR32Opnd:$hi))]>;
+class BuildPairF64Base_FPR<RegisterOperand RO> :
+ PseudoSE<(outs RO:$dst), (ins FGR32Opnd:$lo, FGR32Opnd:$hi),
+ [(set RO:$dst, (MipsBuildPairF64_FPR FGR32Opnd:$lo, FGR32Opnd:$hi))]>;
+
def BuildPairF64 : BuildPairF64Base<AFGR64Opnd>, FGR_32, HARDFLOAT;
+def BuildPairF64_FPR : BuildPairF64Base_FPR<AFGR64Opnd>, FGR_32, HARDFLOAT;
def BuildPairF64_64 : BuildPairF64Base<FGR64Opnd>, FGR_64, HARDFLOAT;
// This pseudo instr gets expanded into 2 mfc1 instrs after register
@@ -849,7 +864,12 @@ class ExtractElementF64Base<RegisterOperand RO> :
PseudoSE<(outs GPR32Opnd:$dst), (ins RO:$src, i32imm:$n),
[(set GPR32Opnd:$dst, (MipsExtractElementF64 RO:$src, imm:$n))]>;
+class ExtractElementF64Base_FPR<RegisterOperand RO> :
+ PseudoSE<(outs FGR32Opnd:$dst), (ins RO:$src, i32imm:$n),
+ [(set FGR32Opnd:$dst, (MipsExtractElementF64_FPR RO:$src, imm:$n))]>;
+
def ExtractElementF64 : ExtractElementF64Base<AFGR64Opnd>, FGR_32, HARDFLOAT;
+def ExtractElementF64_FPR : ExtractElementF64Base_FPR<AFGR64Opnd>, FGR_32, HARDFLOAT;
def ExtractElementF64_64 : ExtractElementF64Base<FGR64Opnd>, FGR_64, HARDFLOAT;
def PseudoTRUNC_W_S : MipsAsmPseudoInst<(outs FGR32Opnd:$fd),
@@ -1090,10 +1110,10 @@ let AdditionalPredicates = [NotInMicroMips] in {
def : LoadRegImmPat<LWC1, f32, load>, ISA_MIPS1;
def : StoreRegImmPat<SWC1, f32>, ISA_MIPS1;
- def : LoadRegImmPat<LDC164, f64, load>, ISA_MIPS1, FGR_64;
- def : StoreRegImmPat<SDC164, f64>, ISA_MIPS1, FGR_64;
+ def : LoadRegImmPat<LDC164, f64, load>, ISA_MIPS2, FGR_64;
+ def : StoreRegImmPat<SDC164, f64>, ISA_MIPS2, FGR_64;
- def : LoadRegImmPat<LDC1, f64, load>, ISA_MIPS1, FGR_32;
- def : StoreRegImmPat<SDC1, f64>, ISA_MIPS1, FGR_32;
+ def : LoadRegImmPat<LDC1, f64, load>, ISA_MIPS2, FGR_32;
+ def : StoreRegImmPat<SDC1, f64>, ISA_MIPS2, FGR_32;
}
}
diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
index 8c60824a42a26..7276c139d27af 100644
--- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
+++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
@@ -297,6 +297,33 @@ bool MipsSEDAGToDAGISel::selectAddrFrameIndexOffset(
Offset = CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr),
ValTy);
+ if (Base.getOpcode() == ISD::ADD &&
+ (Subtarget->hasMips1() && !Subtarget->hasMips2())) {
+ // Instead of:
+ // lui $2, %hi($CPI1_0)
+ // addiu $2, $2, %lo($CPI1_0)
+ // lwc1 $f0, 4($2)
+ // Generate:
+ // lui $2, %hi($CPI1_0)
+ // lwc1 $f0, %lo($CPI1_0+4)($2)
+ if (Base.getOperand(1).getOpcode() == MipsISD::Lo ||
+ Base.getOperand(1).getOpcode() == MipsISD::GPRel) {
+ SDValue Opnd0 = Base.getOperand(1).getOperand(0);
+ if (isa<ConstantPoolSDNode>(Opnd0) ||
+ isa<GlobalAddressSDNode>(Opnd0) || isa<JumpTableSDNode>(Opnd0)) {
+ Base = Base.getOperand(0);
+ if (GlobalAddressSDNode *GA =
+ dyn_cast<GlobalAddressSDNode>(Opnd0)) {
+ const GlobalValue *GV = GA->getGlobal();
+ int64_t GAOffset = GA->getOffset();
+ Offset = CurDAG->getTargetGlobalAddress(
+ GV, SDLoc(Addr), MVT::i32, GAOffset + CN->getZExtValue(),
+ MipsII::MO_ABS_LO);
+ return true;
+ }
+ }
+ }
+ }
return true;
}
}
diff --git a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
index d5941fc8e0b33..d4cf259313a1d 100644
--- a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
@@ -248,7 +248,7 @@ MipsSETargetLowering::MipsSETargetLowering(const MipsTargetMachine &TM,
setOperationAction(ISD::BITCAST, MVT::i64, Custom);
}
- if (NoDPLoadStore) {
+ if (NoDPLoadStore || (Subtarget.hasMips1() && !Subtarget.hasMips2())) {
setOperationAction(ISD::LOAD, MVT::f64, Custom);
setOperationAction(ISD::STORE, MVT::f64, Custom);
}
@@ -1357,28 +1357,34 @@ getOpndList(SmallVectorImpl<SDValue> &Ops,
SDValue MipsSETargetLowering::lowerLOAD(SDValue Op, SelectionDAG &DAG) const {
LoadSDNode &Nd = *cast<LoadSDNode>(Op);
- if (Nd.getMemoryVT() != MVT::f64 || !NoDPLoadStore)
+ if (Nd.getMemoryVT() != MVT::f64 || (!NoDPLoadStore && Subtarget.hasMips2()))
return MipsTargetLowering::lowerLOAD(Op, DAG);
// Replace a double precision load with two i32 loads and a buildpair64.
SDLoc DL(Op);
SDValue Ptr = Nd.getBasePtr(), Chain = Nd.getChain();
EVT PtrVT = Ptr.getValueType();
+ EVT VT = Subtarget.hasMips2() ? MVT::i32 : MVT::f32;
// i32 load from lower address.
- SDValue Lo = DAG.getLoad(MVT::i32, DL, Chain, Ptr, MachinePointerInfo(),
+ SDValue Lo = DAG.getLoad(VT, DL, Chain, Ptr, MachinePointerInfo(),
Nd.getAlign(), Nd.getMemOperand()->getFlags());
// i32 load from higher address.
Ptr = DAG.getNode(ISD::ADD, DL, PtrVT, Ptr, DAG.getConstant(4, DL, PtrVT));
- SDValue Hi = DAG.getLoad(
- MVT::i32, DL, Lo.getValue(1), Ptr, MachinePointerInfo(),
- commonAlignment(Nd.getAlign(), 4), Nd.getMemOperand()->getFlags());
+ SDValue Hi = DAG.getLoad(VT, DL, Lo.getValue(1), Ptr, MachinePointerInfo(),
+ commonAlignment(Nd.getAlign(), 4),
+ Nd.getMemOperand()->getFlags());
if (!Subtarget.isLittle())
std::swap(Lo, Hi);
- SDValue BP = DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
+ SDValue BP;
+ if (Subtarget.hasMips2())
+ BP = DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
+ else
+ BP = DAG.getNode(MipsISD::BuildPairF64_FPR, DL, MVT::f64, Hi, Lo);
+
SDValue Ops[2] = {BP, Hi.getValue(1)};
return DAG.getMergeValues(Ops, DL);
}
@@ -1386,17 +1392,21 @@ SDValue MipsSETargetLowering::lowerLOAD(SDValue Op, SelectionDAG &DAG) const {
SDValue MipsSETargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const {
StoreSDNode &Nd = *cast<StoreSDNode>(Op);
- if (Nd.getMemoryVT() != MVT::f64 || !NoDPLoadStore)
+ if (Nd.getMemoryVT() != MVT::f64 || (!NoDPLoadStore && Subtarget.hasMips2()))
return MipsTargetLowering::lowerSTORE(Op, DAG);
// Replace a double precision store with two extractelement64s and i32 stores.
SDLoc DL(Op);
SDValue Val = Nd.getValue(), Ptr = Nd.getBasePtr(), Chain = Nd.getChain();
EVT PtrVT = Ptr.getValueType();
- SDValue Lo = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32,
- Val, DAG.getConstant(0, DL, MVT::i32));
- SDValue Hi = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32,
- Val, DAG.getConstant(1, DL, MVT::i32));
+ EVT VT = Subtarget.hasMips2() ? MVT::i32 : MVT::f32;
+
+ unsigned ExtractOp = Subtarget.hasMips2() ? MipsISD::ExtractElementF64
+ : MipsISD::ExtractElementF64_FPR;
+ SDValue Lo =
+ DAG.getNode(ExtractOp, DL, VT, Val, DAG.getConstant(0, DL, MVT::i32));
+ SDValue Hi =
+ DAG.getNode(ExtractOp, DL, VT, Val, DAG.getConstant(1, DL, MVT::i32));
if (!Subtarget.isLittle())
std::swap(Lo, Hi);
diff --git a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
index 6c59975a1b501..e31f5f5009200 100644
--- a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
@@ -526,9 +526,13 @@ bool MipsSEInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
case Mips::BuildPairF64:
expandBuildPairF64(MBB, MI, isMicroMips, false);
break;
+ case Mips::BuildPairF64_FPR:
+ MI.eraseFromParent();
+ return true;
case Mips::BuildPairF64_64:
expandBuildPairF64(MBB, MI, isMicroMips, true);
break;
+ case Mips::ExtractElementF64_FPR:
case Mips::ExtractElementF64:
expandExtractElementF64(MBB, MI, isMicroMips, false);
break;
diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td
index d7b9a002dbc5f..233311c97d392 100644
--- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td
+++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td
@@ -870,7 +870,8 @@ def : InstRW<[GenericWriteFPUMoveGPRFPU], (instrs BuildPairF64,
ExtractElementF64_64, CFC1, CTC1,
MFC1, MFC1_D64, MFHC1_D32,
MFHC1_D64, MTC1, MTC1_D64,
- MTHC1_D32, MTHC1_D64)>;
+ MTHC1_D32, MTHC1_D64,
+ BuildPairF64_FPR, ExtractElementF64_FPR)>;
// swc1, swxc1
def : InstRW<[GenericWriteFPUStore], (instrs SDC1, SDC164, SDXC1, SDXC164,
diff --git a/llvm/lib/Target/Mips/MipsScheduleP5600.td b/llvm/lib/Target/Mips/MipsScheduleP5600.td
index e8b646a37932c..342d2fa6fdb8b 100644
--- a/llvm/lib/Target/Mips/MipsScheduleP5600.td
+++ b/llvm/lib/Target/Mips/MipsScheduleP5600.td
@@ -563,7 +563,7 @@ def P5600WriteLoadFPU : WriteSequence<[P5600WriteLoadToOtherUnits,
// ctc1, mtc1, mthc1
def : InstRW<[P5600WriteMoveGPRToFPU], (instrs CTC1, MTC1, MTC1_D64, MTHC1_D32,
MTHC1_D64, BuildPairF64,
- BuildPairF64_64)>;
+ BuildPairF64_64, BuildPairF64_FPR)>;
// copy.[su]_[bhwd]
def : InstRW<[P5600WriteMoveFPUToGPR], (instregex "^COPY_U_[BHW]$")>;
@@ -573,7 +573,7 @@ def : InstRW<[P5600WriteMoveFPUToGPR], (instregex "^COPY_S_[BHWD]$")>;
def : InstRW<[P5600WriteMoveFPUToGPR], (instrs BC1F, BC1FL, BC1T, BC1TL, CFC1,
MFC1, MFC1_D64, MFHC1_D32, MFHC1_D64,
MOVF_I, MOVT_I, ExtractElementF64,
- ExtractElementF64_64)>;
+ ExtractElementF64_64, ExtractElementF64_FPR)>;
// swc1, swxc1, st.[bhwd]
def : InstRW<[P5600WriteStoreFPUS], (instrs SDC1, SDC164, SDXC1, SDXC164,
diff --git a/llvm/test/CodeGen/Mips/llvm-ir/load.ll b/llvm/test/CodeGen/Mips/llvm-ir/load.ll
index 834880f1ad74e..9e47978da8c37 100644
--- a/llvm/test/CodeGen/Mips/llvm-ir/load.ll
+++ b/llvm/test/CodeGen/Mips/llvm-ir/load.ll
@@ -1664,12 +1664,20 @@ define double @f9() {
; MIPS1-PSX-NEXT: lui $1, %hi(f) # <MCInst #[[#MCINST1]] LUi
; MIPS1-PSX-NEXT: # <MCOperand Reg:AT>
; MIPS1-PSX-NEXT: # <MCOperand Expr:%hi(f)>>
-; MIPS1-PSX-NEXT: jr $ra # <MCInst #[[#MCINST2]] JR
-; MIPS1-PSX-NEXT: # <MCOperand Reg:RA>>
-; MIPS1-PSX-NEXT: ldc1 $f0, %lo(f)($1) # <MCInst #[[#MCINST30:]] LDC1
-; MIPS1-PSX-NEXT: # <MCOperand Reg:D0>
+; MIPS1-PSX-NEXT: lwc1 $f0, %lo(f)($1) # <MCInst #[[#MCINST28:]] LWC1
+; MIPS1-PSX-NEXT: # <MCOperand Reg:F0>
; MIPS1-PSX-NEXT: # <MCOperand Reg:AT>
; MIPS1-PSX-NEXT: # <MCOperand Expr:%lo(f)>>
+; MIPS1-PSX-NEXT: lwc1 $f1, %lo(f+4)($1) # <MCInst #[[#MCINST28:]] LWC1
+; MIPS1-PSX-NEXT: # <MCOperand Reg:F1>
+; MIPS1-PSX-NEXT: # <MCOperand Reg:AT>
+; MIPS1-PSX-NEXT: # <MCOperand Expr:%lo(f+4)>>
+; MIPS1-PSX-NEXT: jr $ra # <MCInst [[#MCINST2]] JR
+; MIPS1-PSX-NEXT: # <MCOperand Reg:RA>>
+; MIPS1-PSX-NEXT: nop # <MCInst #[[#MCINST13]] SLL
+; MIPS1-PSX-NEXT: # <MCOperand Reg:ZERO>
+; MIPS1-PSX-NEXT: # <MCOperand Reg:ZERO>
+; MIPS1-PSX-NEXT: # <MCOperand Imm:0>>
entry:
%0 = load double, ptr @f
ret double %0
diff --git a/llvm/test/CodeGen/Mips/llvm-ir/select-dbl.ll b/llvm/test/CodeGen/Mips/llvm-ir/select-dbl.ll
index f39be636e09d4..ca91fa18ecd2c 100644
--- a/llvm/test/CodeGen/Mips/llvm-ir/select-dbl.ll
+++ b/llvm/test/CodeGen/Mips/llvm-ir/select-dbl.ll
@@ -139,7 +139,8 @@ define double @tst_select_i1_double(i1 signext %s, double %x, double %y) {
; MIPS1-PSX-NEXT: bnez $1, $BB0_2
; MIPS1-PSX-NEXT: nop
; MIPS1-PSX-NEXT: # %bb.1: # %entry
-; MIPS1-PSX-NEXT: ldc1 $f0, 16($sp)
+; MIPS1-PSX-NEXT: lwc1 $f0, 16($sp)
+; MIPS1-PSX-NEXT: lwc1 $f1, 20($sp)
; MIPS1-PSX-NEXT: jr $ra
; MIPS1-PSX-NEXT: nop
; MIPS1-PSX-NEXT: $BB0_2:
diff --git a/llvm/test/CodeGen/Mips/mips1-load-in-delay-slot.ll b/llvm/test/CodeGen/Mips/mips1-load-in-delay-slot.ll
index 4499dc6123fd1..d0cb5601cfd86 100644
--- a/llvm/test/CodeGen/Mips/mips1-load-in-delay-slot.ll
+++ b/llvm/test/CodeGen/Mips/mips1-load-in-delay-slot.ll
@@ -11,8 +11,7 @@ define internal fastcc void @test() unnamed_addr #0 {
; MIPS1-PSX-NEXT: addu $1, $2, $25
; MIPS1-PSX-NEXT: lw $2, %got(data)($1)
; MIPS1-PSX-NEXT: nop
-; MIPS1-PSX-NEXT: addiu $1, $2, %lo(data)
-; MIPS1-PSX-NEXT: lbu $1, 2($1)
+; MIPS1-PSX-NEXT: lbu $1, %lo(data+2)($2)
; MIPS1-PSX-NEXT: addiu $3, $zero, 2
; MIPS1-PSX-NEXT: bne $1, $3, $BB0_2
; MIPS1-PSX-NEXT: nop
diff --git a/llvm/test/CodeGen/Mips/mips1-not-support-ldc1-sdc1.ll b/llvm/test/CodeGen/Mips/mips1-not-support-ldc1-sdc1.ll
new file mode 100644
index 0000000000000..1942805530222
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/mips1-not-support-ldc1-sdc1.ll
@@ -0,0 +1,49 @@
+; RUN: llc -march=mipsel -mcpu=mips1 < %s | FileCheck %s -check-prefix=MIPS1-LE
+; RUN: llc -march=mips -mcpu=mips1 < %s | FileCheck %s -check-prefix=MIPS1-BE
+
+ at test = global double 1.000000e+00, align 8
+
+define double @test_lwc1() {
+; MIPS1-LE-LABEL: test_lwc1:
+; MIPS1-LE: # %bb.0: # %entry
+; MIPS1-LE-NEXT: lui $1, %hi(test)
+; MIPS1-LE-NEXT: lwc1 $f0, %lo(test)($1)
+; MIPS1-LE-NEXT: lwc1 $f1, %lo(test+4)($1)
+; MIPS1-LE-NEXT: jr $ra
+; MIPS1-LE-NEXT: nop
+
+; MIPS1-BE-LABEL: test_lwc1:
+; MIPS1-BE: # %bb.0: # %entry
+; MIPS1-BE-NEXT: lui $1, %hi(test)
+; MIPS1-BE-NEXT: lwc1 $f0, %lo(test+4)($1)
+; MIPS1-BE-NEXT: lwc1 $f1, %lo(test)($1)
+; MIPS1-BE-NEXT: jr $ra
+; MIPS1-BE-NEXT: nop
+entry:
+ %0 = load double, ptr @test, align 8
+ ret double %0
+}
+
+define void @test_swc1(double %a) #0 {
+; MIPS1-LE-LABEL: test_swc1:
+; MIPS1-LE: # %bb.0: # %entry
+; MIPS1-LE-NEXT: mfc1 $f0, $f13
+; MIPS1-LE-NEXT: lui $1, %hi(test)
+; MIPS1-LE-NEXT: swc1 $f0, %lo(test+4)($1)
+; MIPS1-LE-NEXT: mfc1 $f0, $f12
+; MIPS1-LE-NEXT: jr $ra
+; MIPS1-LE-NEXT: swc1 $f0, %lo(test)($1)
+
+; MIPS1-BE-LABEL: test_swc1:
+; MIPS1-BE: # %bb.0: # %entry
+; MIPS1-BE-NEXT: mfc1 $f0, $f12
+; MIPS1-BE-NEXT: lui $1, %hi(test)
+; MIPS1-BE-NEXT: swc1 $f0, %lo(test+4)($1)
+; MIPS1-BE-NEXT: mfc1 $f0, $f13
+; MIPS1-BE-NEXT: jr $ra
+; MIPS1-BE-NEXT: swc1 $f0, %lo(test)($1)
+entry:
+ store double %a, ptr @test, align 8
+ ret void
+}
+
More information about the llvm-commits
mailing list