Skip to content

Commit

Permalink
This patch has two main functions:
Browse files Browse the repository at this point in the history
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 brson#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
  • Loading branch information
Reed Kotler committed Feb 14, 2014
1 parent 034b8f9 commit fba2a76
Show file tree
Hide file tree
Showing 10 changed files with 567 additions and 12 deletions.
1 change: 1 addition & 0 deletions lib/Target/Mips/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ add_public_tablegen_target(MipsCommonTableGen)
add_llvm_target(MipsCodeGen
Mips16FrameLowering.cpp
Mips16HardFloat.cpp
Mips16HardFloatInfo.cpp
Mips16InstrInfo.cpp
Mips16ISelDAGToDAG.cpp
Mips16ISelLowering.cpp
Expand Down
9 changes: 5 additions & 4 deletions lib/Target/Mips/Mips16HardFloat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,8 @@ static void swapFPIntParams
// Make sure that we know we already need a stub for this function.
// Having called needsFPHelperFromSig
//
static void assureFPCallStub(Function &F, Module *M,
const MipsSubtarget &Subtarget){
static void assureFPCallStub(Function &F, Module *M,
const MipsSubtarget &Subtarget) {
// for now we only need them for static relocation
if (Subtarget.getRelocationModel() == Reloc::PIC_)
return;
Expand Down Expand Up @@ -500,8 +500,9 @@ namespace llvm {
// declared via attributes as nomips16, we must:
// 1) fixup all returns of float, double, single and double complex
// by calling a helper function before the actual return.
// 2) generate helper functions (stubs) that can be called by mips32 functions
// that will move parameters passed normally passed in floating point
// 2) generate helper functions (stubs) that can be called by mips32
// functions that will move parameters passed normally passed in
// floating point
// registers the soft float equivalents.
// 3) in the case of static relocation, generate helper functions so that
// mips16 functions can call extern functions of unknown type (mips16 or
Expand Down
50 changes: 50 additions & 0 deletions lib/Target/Mips/Mips16HardFloatInfo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//===---- Mips16HardFloatInfo.cpp for Mips16 Hard Float -----===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the Mips16 implementation of Mips16HardFloatInfo
// namespace.
//
//===----------------------------------------------------------------------===//

#include <string.h>
#include "Mips16HardFloatInfo.h"

namespace llvm {

namespace Mips16HardFloatInfo {

const FuncNameSignature PredefinedFuncs[] = {
{ "__floatdidf", { NoSig, DRet } },
{ "__floatdisf", { NoSig, FRet } },
{ "__floatundidf", { NoSig, DRet } },
{ "__fixsfdi", { FSig, NoFPRet } },
{ "__fixunsdfsi", { DSig, NoFPRet } },
{ "__fixunsdfdi", { DSig, NoFPRet } },
{ "__fixdfdi", { DSig, NoFPRet } },
{ "__fixunssfsi", { FSig, NoFPRet } },
{ "__fixunssfdi", { FSig, NoFPRet } },
{ "__floatundisf", { NoSig, FRet } },
{ 0, { NoSig, NoFPRet } }
};

// just do a search for now. there are very few of these special cases.
//
extern FuncSignature const *findFuncSignature(const char *name) {
const char *name_;
int i = 0;
while (PredefinedFuncs[i].Name) {
name_ = PredefinedFuncs[i].Name;
if (strcmp(name, name_) == 0)
return &PredefinedFuncs[i].Signature;
i++;
}
return 0;
}
}
}
50 changes: 50 additions & 0 deletions lib/Target/Mips/Mips16HardFloatInfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//===---- Mips16HardFloatInfo.h for Mips16 Hard Float --------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines some data structures relevant to the implementation of
// Mips16 hard float.
//
//
//===----------------------------------------------------------------------===//

#ifndef MIPS16HARDFLOATINFO_H
#define MIPS16HARDFLOATINFO_H

namespace llvm {

namespace Mips16HardFloatInfo {

// Return types that matter for hard float are:
// float, double, complex float, and complex double
//
enum FPReturnVariant { FRet, DRet, CFRet, CDRet, NoFPRet };

//
// Parameter type that matter are float, (float, float), (float, double),
// double, (double, double), (double, float)
//
enum FPParamVariant { FSig, FFSig, FDSig, DSig, DDSig, DFSig, NoSig };

struct FuncSignature {
FPParamVariant ParamSig;
FPReturnVariant RetSig;
};

struct FuncNameSignature {
const char *Name;
FuncSignature Signature;
};

extern const FuncNameSignature PredefinedFuncs[];

extern FuncSignature const *findFuncSignature(const char *name);
}
}

#endif
30 changes: 27 additions & 3 deletions lib/Target/Mips/Mips16ISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "mips-lower"
#include <string>
#include "Mips16ISelLowering.h"
#include "MCTargetDesc/MipsBaseInfo.h"
#include "MipsRegisterInfo.h"
#include "MipsTargetMachine.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Target/TargetInstrInfo.h"
Expand Down Expand Up @@ -445,7 +447,29 @@ getOpndList(SmallVectorImpl<SDValue> &Ops,
Find))
LookupHelper = false;
else {
Mips16IntrinsicHelperType IntrinsicFind = {S->getSymbol(), ""};
const char *Symbol = S->getSymbol();
Mips16IntrinsicHelperType IntrinsicFind = { Symbol, "" };
const Mips16HardFloatInfo::FuncSignature *Signature =
Mips16HardFloatInfo::findFuncSignature(Symbol);
if (!IsPICCall && (Signature && (FuncInfo->StubsNeeded.find(Symbol) ==
FuncInfo->StubsNeeded.end()))) {
FuncInfo->StubsNeeded[Symbol] = Signature;
//
// S2 is normally saved if the stub is for a function which
// returns a float or double value and is not otherwise. This is
// because more work is required after the function the stub
// is calling completes, and so the stub cannot directly return
// and the stub has no stack space to store the return address so
// S2 is used for that purpose.
// In order to take advantage of not saving S2, we need to also
// optimize the call in the stub and this requires some further
// functionality in MipsAsmPrinter which we don't have yet.
// So for now we always save S2. The optimization will be done
// in a follow-on patch.
//
if (Signature->RetSig != Mips16HardFloatInfo::NoFPRet || 1)
FuncInfo->setSaveS2();
}
// one more look at list of intrinsics
if (std::binary_search(Mips16IntrinsicHelper,
array_endof(Mips16IntrinsicHelper),
Expand Down Expand Up @@ -748,8 +772,8 @@ MachineBasicBlock *Mips16TargetLowering::emitFEXT_CCRX16_ins(
unsigned CC = MI->getOperand(0).getReg();
unsigned regX = MI->getOperand(1).getReg();
unsigned regY = MI->getOperand(2).getReg();
BuildMI(*BB, MI, MI->getDebugLoc(),
TII->get(SltOpc)).addReg(regX).addReg(regY);
BuildMI(*BB, MI, MI->getDebugLoc(), TII->get(SltOpc)).addReg(regX).addReg(
regY);
BuildMI(*BB, MI, MI->getDebugLoc(),
TII->get(Mips::MoveR3216), CC).addReg(Mips::T8);
MI->eraseFromParent(); // The pseudo instruction is gone now.
Expand Down
Loading

0 comments on commit fba2a76

Please sign in to comment.