//===- Mips16HardFloat.cpp for Mips16 Hard Float --------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file defines a pass needed for Mips16 Hard Float // //===----------------------------------------------------------------------===// #include "MipsTargetMachine.h" #include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/IR/Module.h" #include "llvm/IR/Value.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ModRef.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> #include <string> usingnamespacellvm; #define DEBUG_TYPE … namespace { class Mips16HardFloat : public ModulePass { … }; } // end anonymous namespace static void emitInlineAsm(LLVMContext &C, BasicBlock *BB, StringRef AsmText) { … } char Mips16HardFloat::ID = …; // // Return types that matter for hard float are: // float, double, complex float, and complex double // enum FPReturnVariant { … }; // // Determine which FP return type this function has // static FPReturnVariant whichFPReturnVariant(Type *T) { … } // Parameter type that matter are float, (float, float), (float, double), // double, (double, double), (double, float) enum FPParamVariant { … }; // which floating point parameter signature variant we are dealing with TypeID; const Type::TypeID FloatTyID = …; const Type::TypeID DoubleTyID = …; static FPParamVariant whichFPParamVariantNeeded(Function &F) { … } // Figure out if we need float point based on the function parameters. // We need to move variables in and/or out of floating point // registers because of the ABI static bool needsFPStubFromParams(Function &F) { … } static bool needsFPReturnHelper(Function &F) { … } static bool needsFPReturnHelper(FunctionType &FT) { … } static bool needsFPHelperFromSig(Function &F) { … } // We swap between FP and Integer registers to allow Mips16 and Mips32 to // interoperate static std::string swapFPIntParams(FPParamVariant PV, Module *M, bool LE, bool ToFP) { … } // Make sure that we know we already need a stub for this function. // Having called needsFPHelperFromSig static void assureFPCallStub(Function &F, Module *M, const MipsTargetMachine &TM) { … } // Functions that are llvm intrinsics and don't need helpers. static const char *const IntrinsicInline[] = …; static bool isIntrinsicInline(Function *F) { … } // Returns of float, double and complex need to be handled with a helper // function. static bool fixupFPReturnAndCall(Function &F, Module *M, const MipsTargetMachine &TM) { … } static void createFPFnStub(Function *F, Module *M, FPParamVariant PV, const MipsTargetMachine &TM) { … } // remove the use-soft-float attribute static void removeUseSoftFloat(Function &F) { … } // This pass only makes sense when the underlying chip has floating point but // we are compiling as mips16. // For all mips16 functions (that are not stubs we have already generated), or // 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 // 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 // mips32). // 4) TBD. For pic, calls to extern functions of unknown type are handled by // predefined helper functions in libc but this work is currently done // during call lowering but it should be moved here in the future. bool Mips16HardFloat::runOnModule(Module &M) { … } ModulePass *llvm::createMips16HardFloatPass() { … }