[llvm] r181718 - [mips] Add option -mno-ldc1-sdc1.

Akira Hatanaka ahatanaka at mips.com
Mon May 13 11:23:35 PDT 2013


Author: ahatanak
Date: Mon May 13 13:23:35 2013
New Revision: 181718

URL: http://llvm.org/viewvc/llvm-project?rev=181718&view=rev
Log:
[mips] Add option -mno-ldc1-sdc1.

This option is used when the user wants to avoid emitting double precision FP
loads and stores. Double precision FP loads and stores are expanded to single
precision instructions after register allocation.

Added:
    llvm/trunk/test/CodeGen/Mips/mno-ldc1-sdc1.ll
Modified:
    llvm/trunk/lib/Target/Mips/MipsInstrFPU.td
    llvm/trunk/lib/Target/Mips/MipsSEInstrInfo.cpp
    llvm/trunk/lib/Target/Mips/MipsSEInstrInfo.h

Modified: llvm/trunk/lib/Target/Mips/MipsInstrFPU.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrFPU.td?rev=181718&r1=181717&r2=181718&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsInstrFPU.td (original)
+++ llvm/trunk/lib/Target/Mips/MipsInstrFPU.td Mon May 13 13:23:35 2013
@@ -154,6 +154,7 @@ class LW_FT<string opstr, RegisterClass
   InstSE<(outs RC:$rt), (ins MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"),
          [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI> {
   let DecoderMethod = "DecodeFMem";
+  let mayLoad = 1;
 }
 
 class SW_FT<string opstr, RegisterClass RC, InstrItinClass Itin,
@@ -161,6 +162,7 @@ class SW_FT<string opstr, RegisterClass
   InstSE<(outs), (ins RC:$rt, MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"),
          [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI> {
   let DecoderMethod = "DecodeFMem";
+  let mayStore = 1;
 }
 
 class MADDS_FT<string opstr, RegisterClass RC, InstrItinClass Itin,
@@ -314,8 +316,12 @@ let Predicates = [NotN64, HasMips64, Has
 }
 
 let Predicates = [NotN64, NotMips64, HasStdEnc] in {
-  def LDC1 : LW_FT<"ldc1", AFGR64, IILoad, mem, load>, LW_FM<0x35>;
-  def SDC1 : SW_FT<"sdc1", AFGR64, IIStore, mem, store>, LW_FM<0x3d>;
+  let isPseudo = 1, isCodeGenOnly = 1 in {
+    def PseudoLDC1 : LW_FT<"", AFGR64, IILoad, mem, load>;
+    def PseudoSDC1 : SW_FT<"", AFGR64, IIStore, mem, store>;
+  }
+  def LDC1 : LW_FT<"ldc1", AFGR64, IILoad, mem>, LW_FM<0x35>;
+  def SDC1 : SW_FT<"sdc1", AFGR64, IIStore, mem>, LW_FM<0x3d>;
 }
 
 // Indexed loads and stores.
@@ -523,7 +529,7 @@ let AddedComplexity = 40 in {
   }
 
   let Predicates = [NotN64, NotMips64, HasStdEnc] in {
-    def : LoadRegImmPat<LDC1, f64, load>;
-    def : StoreRegImmPat<SDC1, f64>;
+    def : LoadRegImmPat<PseudoLDC1, f64, load>;
+    def : StoreRegImmPat<PseudoSDC1, f64>;
   }
 }

Modified: llvm/trunk/lib/Target/Mips/MipsSEInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsSEInstrInfo.cpp?rev=181718&r1=181717&r2=181718&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsSEInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsSEInstrInfo.cpp Mon May 13 13:23:35 2013
@@ -18,11 +18,17 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/Support/CommandLine.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/TargetRegistry.h"
 
 using namespace llvm;
 
+static cl::opt<bool> NoDPLoadStore("mno-ldc1-sdc1", cl::init(false),
+                                   cl::desc("Expand double precision loads and "
+                                            "stores to their single precision "
+                                            "counterparts."));
+
 MipsSEInstrInfo::MipsSEInstrInfo(MipsTargetMachine &tm)
   : MipsInstrInfo(tm,
                   tm.getRelocationModel() == Reloc::PIC_ ? Mips::B : Mips::J),
@@ -253,6 +259,12 @@ bool MipsSEInstrInfo::expandPostRAPseudo
   case Mips::ExtractElementF64:
     expandExtractElementF64(MBB, MI);
     break;
+  case Mips::PseudoLDC1:
+    expandDPLoadStore(MBB, MI, Mips::LDC1, Mips::LWC1);
+    break;
+  case Mips::PseudoSDC1:
+    expandDPLoadStore(MBB, MI, Mips::SDC1, Mips::SWC1);
+    break;
   case Mips::MIPSeh_return32:
   case Mips::MIPSeh_return64:
     expandEhReturn(MBB, MI);
@@ -393,6 +405,56 @@ void MipsSEInstrInfo::expandBuildPairF64
     .addReg(HiReg);
 }
 
+/// Add 4 to the displacement of operand MO.
+static void fixDisp(MachineOperand &MO) {
+  switch (MO.getType()) {
+  default:
+    llvm_unreachable("Unhandled operand type.");
+  case MachineOperand::MO_Immediate:
+    MO.setImm(MO.getImm() + 4);
+    break;
+  case MachineOperand::MO_GlobalAddress:
+  case MachineOperand::MO_ConstantPoolIndex:
+  case MachineOperand::MO_BlockAddress:
+  case MachineOperand::MO_TargetIndex:
+  case MachineOperand::MO_ExternalSymbol:
+    MO.setOffset(MO.getOffset() + 4);
+    break;
+  }
+}
+
+void MipsSEInstrInfo::expandDPLoadStore(MachineBasicBlock &MBB,
+                                        MachineBasicBlock::iterator I,
+                                        unsigned OpcD, unsigned OpcS) const {
+  // If NoDPLoadStore is false, just change the opcode.
+  if (!NoDPLoadStore) {
+    genInstrWithNewOpc(OpcD, I);
+    return;
+  }
+
+  // Expand a double precision FP load or store to two single precision
+  // instructions.
+
+  const TargetRegisterInfo &TRI = getRegisterInfo();
+  const MachineOperand &ValReg = I->getOperand(0);
+  unsigned LoReg = TRI.getSubReg(ValReg.getReg(), Mips::sub_fpeven);
+  unsigned HiReg = TRI.getSubReg(ValReg.getReg(), Mips::sub_fpodd);
+
+  if (!TM.getSubtarget<MipsSubtarget>().isLittle())
+    std::swap(LoReg, HiReg);
+
+  // Create an instruction which loads from or stores to the lower memory
+  // address.
+  MachineInstrBuilder MIB = genInstrWithNewOpc(OpcS, I);
+  MIB->getOperand(0).setReg(LoReg);
+
+  // Create an instruction which loads from or stores to the higher memory
+  // address.
+  MIB = genInstrWithNewOpc(OpcS, I);
+  MIB->getOperand(0).setReg(HiReg);
+  fixDisp(MIB->getOperand(2));
+}
+
 void MipsSEInstrInfo::expandEhReturn(MachineBasicBlock &MBB,
                                      MachineBasicBlock::iterator I) const {
   // This pseudo instruction is generated as part of the lowering of

Modified: llvm/trunk/lib/Target/Mips/MipsSEInstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsSEInstrInfo.h?rev=181718&r1=181717&r2=181718&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsSEInstrInfo.h (original)
+++ llvm/trunk/lib/Target/Mips/MipsSEInstrInfo.h Mon May 13 13:23:35 2013
@@ -87,6 +87,9 @@ private:
                                MachineBasicBlock::iterator I) const;
   void expandBuildPairF64(MachineBasicBlock &MBB,
                           MachineBasicBlock::iterator I) const;
+  void expandDPLoadStore(MachineBasicBlock &MBB,
+                         MachineBasicBlock::iterator I, unsigned OpcD,
+                         unsigned OpcS) const;
   void expandEhReturn(MachineBasicBlock &MBB,
                       MachineBasicBlock::iterator I) const;
 };

Added: llvm/trunk/test/CodeGen/Mips/mno-ldc1-sdc1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/mno-ldc1-sdc1.ll?rev=181718&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/mno-ldc1-sdc1.ll (added)
+++ llvm/trunk/test/CodeGen/Mips/mno-ldc1-sdc1.ll Mon May 13 13:23:35 2013
@@ -0,0 +1,45 @@
+; RUN: llc -march=mipsel -relocation-model=pic -mno-ldc1-sdc1 < %s | \
+; RUN: FileCheck %s -check-prefix=LE-PIC
+; RUN: llc -march=mipsel -relocation-model=static -mno-ldc1-sdc1 < %s | \
+; RUN: FileCheck %s -check-prefix=LE-STATIC
+; RUN: llc -march=mips -relocation-model=pic -mno-ldc1-sdc1 < %s | \
+; RUN: FileCheck %s -check-prefix=BE-PIC
+; RUN: llc -march=mipsel < %s | FileCheck %s -check-prefix=CHECK-LDC1-SDC1
+
+ at g0 = common global double 0.000000e+00, align 8
+
+; LE-PIC: test_ldc1:
+; LE-PIC: lwc1 $f0, 0(${{[0-9]+}})
+; LE-PIC: lwc1 $f1, 4(${{[0-9]+}})
+; LE-STATIC: test_ldc1:
+; LE-STATIC: lwc1 $f0, %lo(g0)(${{[0-9]+}})
+; LE-STATIC: lwc1 $f1, %lo(g0+4)(${{[0-9]+}})
+; BE-PIC: test_ldc1:
+; BE-PIC: lwc1 $f1, 0(${{[0-9]+}})
+; BE-PIC: lwc1 $f0, 4(${{[0-9]+}})
+; CHECK-LDC1-SDC1: test_ldc1:
+; CHECK-LDC1-SDC1: ldc1 $f{{[0-9]+}}
+
+define double @test_ldc1() {
+entry:
+  %0 = load double* @g0, align 8
+  ret double %0
+}
+
+; LE-PIC: test_sdc1:
+; LE-PIC: swc1 $f12, 0(${{[0-9]+}})
+; LE-PIC: swc1 $f13, 4(${{[0-9]+}})
+; LE-STATIC: test_sdc1:
+; LE-STATIC: swc1 $f12, %lo(g0)(${{[0-9]+}})
+; LE-STATIC: swc1 $f13, %lo(g0+4)(${{[0-9]+}})
+; BE-PIC: test_sdc1:
+; BE-PIC: swc1 $f13, 0(${{[0-9]+}})
+; BE-PIC: swc1 $f12, 4(${{[0-9]+}})
+; CHECK-LDC1-SDC1: test_sdc1:
+; CHECK-LDC1-SDC1: sdc1 $f{{[0-9]+}}
+
+define void @test_sdc1(double %a) {
+entry:
+  store double %a, double* @g0, align 8
+  ret void
+}





More information about the llvm-commits mailing list