Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit fba2a76

Browse files
author
Reed Kotler
committed
This patch has two main functions:
1) Fix a specific bug when certain conversion functions are called in a program compiled as mips16 with hard float and the program is linked as c++. There are two libraries that are reversed in the link order with gcc/g++ and clang/clang++ for mips16 in this case and the proper stubs will then not be called. These stubs are normally handled in the Mips16HardFloat pass but in this case we don't know at that time that we need to generate the stubs. This must all be handled later in code generation and we have moved this functionality to MipsAsmPrinter. When linked as C (gcc or clang) the proper stubs are linked in from libc. 2) Set up the infrastructure to handle 90% of what is in the Mips16HardFloat pass in this new area of MipsAsmPrinter. This is a more logical place to handle this and we have known for some time that we needed to move the code later and not implement it using inline asm as we do now but it was not clear exactly where to do this and what mechanism should be used. Now it's clear to us how to do this and this patch contains the infrastructure to move most of this to MipsAsmPrinter but the actual moving will be done in a follow on patch. The same infrastructure is used to fix this current bug as described in #1. This change was requested by the list during the original putback of the Mips16HardFloat pass but was not practical for us do at that time. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@201426 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 034b8f9 commit fba2a76

10 files changed

+567
-12
lines changed

lib/Target/Mips/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ add_public_tablegen_target(MipsCommonTableGen)
1616
add_llvm_target(MipsCodeGen
1717
Mips16FrameLowering.cpp
1818
Mips16HardFloat.cpp
19+
Mips16HardFloatInfo.cpp
1920
Mips16InstrInfo.cpp
2021
Mips16ISelDAGToDAG.cpp
2122
Mips16ISelLowering.cpp

lib/Target/Mips/Mips16HardFloat.cpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,8 @@ static void swapFPIntParams
245245
// Make sure that we know we already need a stub for this function.
246246
// Having called needsFPHelperFromSig
247247
//
248-
static void assureFPCallStub(Function &F, Module *M,
249-
const MipsSubtarget &Subtarget){
248+
static void assureFPCallStub(Function &F, Module *M,
249+
const MipsSubtarget &Subtarget) {
250250
// for now we only need them for static relocation
251251
if (Subtarget.getRelocationModel() == Reloc::PIC_)
252252
return;
@@ -500,8 +500,9 @@ namespace llvm {
500500
// declared via attributes as nomips16, we must:
501501
// 1) fixup all returns of float, double, single and double complex
502502
// by calling a helper function before the actual return.
503-
// 2) generate helper functions (stubs) that can be called by mips32 functions
504-
// that will move parameters passed normally passed in floating point
503+
// 2) generate helper functions (stubs) that can be called by mips32
504+
// functions that will move parameters passed normally passed in
505+
// floating point
505506
// registers the soft float equivalents.
506507
// 3) in the case of static relocation, generate helper functions so that
507508
// mips16 functions can call extern functions of unknown type (mips16 or
+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//===---- Mips16HardFloatInfo.cpp for Mips16 Hard Float -----===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
// This file contains the Mips16 implementation of Mips16HardFloatInfo
11+
// namespace.
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
#include <string.h>
16+
#include "Mips16HardFloatInfo.h"
17+
18+
namespace llvm {
19+
20+
namespace Mips16HardFloatInfo {
21+
22+
const FuncNameSignature PredefinedFuncs[] = {
23+
{ "__floatdidf", { NoSig, DRet } },
24+
{ "__floatdisf", { NoSig, FRet } },
25+
{ "__floatundidf", { NoSig, DRet } },
26+
{ "__fixsfdi", { FSig, NoFPRet } },
27+
{ "__fixunsdfsi", { DSig, NoFPRet } },
28+
{ "__fixunsdfdi", { DSig, NoFPRet } },
29+
{ "__fixdfdi", { DSig, NoFPRet } },
30+
{ "__fixunssfsi", { FSig, NoFPRet } },
31+
{ "__fixunssfdi", { FSig, NoFPRet } },
32+
{ "__floatundisf", { NoSig, FRet } },
33+
{ 0, { NoSig, NoFPRet } }
34+
};
35+
36+
// just do a search for now. there are very few of these special cases.
37+
//
38+
extern FuncSignature const *findFuncSignature(const char *name) {
39+
const char *name_;
40+
int i = 0;
41+
while (PredefinedFuncs[i].Name) {
42+
name_ = PredefinedFuncs[i].Name;
43+
if (strcmp(name, name_) == 0)
44+
return &PredefinedFuncs[i].Signature;
45+
i++;
46+
}
47+
return 0;
48+
}
49+
}
50+
}

lib/Target/Mips/Mips16HardFloatInfo.h

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//===---- Mips16HardFloatInfo.h for Mips16 Hard Float --------===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
// This file defines some data structures relevant to the implementation of
11+
// Mips16 hard float.
12+
//
13+
//
14+
//===----------------------------------------------------------------------===//
15+
16+
#ifndef MIPS16HARDFLOATINFO_H
17+
#define MIPS16HARDFLOATINFO_H
18+
19+
namespace llvm {
20+
21+
namespace Mips16HardFloatInfo {
22+
23+
// Return types that matter for hard float are:
24+
// float, double, complex float, and complex double
25+
//
26+
enum FPReturnVariant { FRet, DRet, CFRet, CDRet, NoFPRet };
27+
28+
//
29+
// Parameter type that matter are float, (float, float), (float, double),
30+
// double, (double, double), (double, float)
31+
//
32+
enum FPParamVariant { FSig, FFSig, FDSig, DSig, DDSig, DFSig, NoSig };
33+
34+
struct FuncSignature {
35+
FPParamVariant ParamSig;
36+
FPReturnVariant RetSig;
37+
};
38+
39+
struct FuncNameSignature {
40+
const char *Name;
41+
FuncSignature Signature;
42+
};
43+
44+
extern const FuncNameSignature PredefinedFuncs[];
45+
46+
extern FuncSignature const *findFuncSignature(const char *name);
47+
}
48+
}
49+
50+
#endif

lib/Target/Mips/Mips16ISelLowering.cpp

+27-3
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@
1111
//
1212
//===----------------------------------------------------------------------===//
1313
#define DEBUG_TYPE "mips-lower"
14+
#include <string>
1415
#include "Mips16ISelLowering.h"
1516
#include "MCTargetDesc/MipsBaseInfo.h"
1617
#include "MipsRegisterInfo.h"
1718
#include "MipsTargetMachine.h"
19+
#include "llvm/ADT/StringRef.h"
1820
#include "llvm/CodeGen/MachineInstrBuilder.h"
1921
#include "llvm/Support/CommandLine.h"
2022
#include "llvm/Target/TargetInstrInfo.h"
@@ -445,7 +447,29 @@ getOpndList(SmallVectorImpl<SDValue> &Ops,
445447
Find))
446448
LookupHelper = false;
447449
else {
448-
Mips16IntrinsicHelperType IntrinsicFind = {S->getSymbol(), ""};
450+
const char *Symbol = S->getSymbol();
451+
Mips16IntrinsicHelperType IntrinsicFind = { Symbol, "" };
452+
const Mips16HardFloatInfo::FuncSignature *Signature =
453+
Mips16HardFloatInfo::findFuncSignature(Symbol);
454+
if (!IsPICCall && (Signature && (FuncInfo->StubsNeeded.find(Symbol) ==
455+
FuncInfo->StubsNeeded.end()))) {
456+
FuncInfo->StubsNeeded[Symbol] = Signature;
457+
//
458+
// S2 is normally saved if the stub is for a function which
459+
// returns a float or double value and is not otherwise. This is
460+
// because more work is required after the function the stub
461+
// is calling completes, and so the stub cannot directly return
462+
// and the stub has no stack space to store the return address so
463+
// S2 is used for that purpose.
464+
// In order to take advantage of not saving S2, we need to also
465+
// optimize the call in the stub and this requires some further
466+
// functionality in MipsAsmPrinter which we don't have yet.
467+
// So for now we always save S2. The optimization will be done
468+
// in a follow-on patch.
469+
//
470+
if (Signature->RetSig != Mips16HardFloatInfo::NoFPRet || 1)
471+
FuncInfo->setSaveS2();
472+
}
449473
// one more look at list of intrinsics
450474
if (std::binary_search(Mips16IntrinsicHelper,
451475
array_endof(Mips16IntrinsicHelper),
@@ -748,8 +772,8 @@ MachineBasicBlock *Mips16TargetLowering::emitFEXT_CCRX16_ins(
748772
unsigned CC = MI->getOperand(0).getReg();
749773
unsigned regX = MI->getOperand(1).getReg();
750774
unsigned regY = MI->getOperand(2).getReg();
751-
BuildMI(*BB, MI, MI->getDebugLoc(),
752-
TII->get(SltOpc)).addReg(regX).addReg(regY);
775+
BuildMI(*BB, MI, MI->getDebugLoc(), TII->get(SltOpc)).addReg(regX).addReg(
776+
regY);
753777
BuildMI(*BB, MI, MI->getDebugLoc(),
754778
TII->get(Mips::MoveR3216), CC).addReg(Mips::T8);
755779
MI->eraseFromParent(); // The pseudo instruction is gone now.

0 commit comments

Comments
 (0)