//===---- Mips16HardFloat.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 defines a pass needed for Mips16 Hard Float
//
//===----------------------------------------------------------------------===//

#include "Mips16HardFloat.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <string>

#define DEBUG_TYPE "mips16-hard-float"

static void inlineAsmOut
  (LLVMContext &C, StringRef AsmString, BasicBlock *BB ) {
  std::vector<llvm::Type *> AsmArgTypes;
  std::vector<llvm::Value*> AsmArgs;
  llvm::FunctionType *AsmFTy =
    llvm::FunctionType::get(Type::getVoidTy(C),
                            AsmArgTypes, false);
  llvm::InlineAsm *IA =
    llvm::InlineAsm::get(AsmFTy, AsmString, "", true,
                         /* IsAlignStack */ false,
                         llvm::InlineAsm::AD_ATT);
  CallInst::Create(IA, AsmArgs, "", BB);
}

namespace {

class InlineAsmHelper {
  LLVMContext &C;
  BasicBlock *BB;
public:
  InlineAsmHelper(LLVMContext &C_, BasicBlock *BB_) :
    C(C_), BB(BB_) {
  }

  void Out(StringRef AsmString) {
    inlineAsmOut(C, AsmString, BB);
  }

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

//
// Determine which FP return type this function has
//
static FPReturnVariant whichFPReturnVariant(Type *T) {
  switch (T->getTypeID()) {
  case Type::FloatTyID:
    return FRet;
  case Type::DoubleTyID:
    return DRet;
  case Type::StructTyID:
    if (T->getStructNumElements() != 2)
      break;
    if ((T->getContainedType(0)->isFloatTy()) &&
        (T->getContainedType(1)->isFloatTy()))
      return CFRet;
    if ((T->getContainedType(0)->isDoubleTy()) &&
        (T->getContainedType(1)->isDoubleTy()))
      return CDRet;
    break;
  default:
    break;
  }
  return 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
};

// which floating point parameter signature variant we are dealing with
//
typedef Type::TypeID TypeID;
const Type::TypeID FloatTyID = Type::FloatTyID;
const Type::TypeID DoubleTyID = Type::DoubleTyID;

static FPParamVariant whichFPParamVariantNeeded(Function &F) {
  switch (F.arg_size()) {
  case 0:
    return NoSig;
  case 1:{
    TypeID ArgTypeID = F.getFunctionType()->getParamType(0)->getTypeID();
    switch (ArgTypeID) {
    case FloatTyID:
      return FSig;
    case DoubleTyID:
      return DSig;
    default:
      return NoSig;
    }
  }
  default: {
    TypeID ArgTypeID0 = F.getFunctionType()->getParamType(0)->getTypeID();
    TypeID ArgTypeID1 = F.getFunctionType()->getParamType(1)->getTypeID();
    switch(ArgTypeID0) {
    case FloatTyID: {
      switch (ArgTypeID1) {
      case FloatTyID:
        return FFSig;
      case DoubleTyID:
        return FDSig;
      default:
        return FSig;
      }
    }
    case DoubleTyID: {
      switch (ArgTypeID1) {
      case FloatTyID:
        return DFSig;
      case DoubleTyID:
        return DDSig;
      default:
        return DSig;
      }
    }
    default:
      return NoSig;
    }
  }
  }
  llvm_unreachable("can't get here");
}

// 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) {
  if (F.arg_size() >=1) {
    Type *ArgType = F.getFunctionType()->getParamType(0);
    switch (ArgType->getTypeID()) {
      case Type::FloatTyID:
      case Type::DoubleTyID:
        return true;
      default:
        break;
    }
  }
  return false;
}

static bool needsFPReturnHelper(Function &F) {
  Type* RetType = F.getReturnType();
  return whichFPReturnVariant(RetType) != NoFPRet;
}

static bool needsFPReturnHelper(const FunctionType &FT) {
  Type* RetType = FT.getReturnType();
  return whichFPReturnVariant(RetType) != NoFPRet;
}

static bool needsFPHelperFromSig(Function &F) {
  return needsFPStubFromParams(F) || needsFPReturnHelper(F);
}

//
// We swap between FP and Integer registers to allow Mips16 and Mips32 to
// interoperate
//

static void swapFPIntParams
  (FPParamVariant PV, Module *M, InlineAsmHelper &IAH,
   bool LE, bool ToFP) {
  //LLVMContext &Context = M->getContext();
  std::string MI = ToFP? "mtc1 ": "mfc1 ";
  switch (PV) {
  case FSig:
    IAH.Out(MI + "$$4,$$f12");
    break;
  case FFSig:
    IAH.Out(MI +"$$4,$$f12");
    IAH.Out(MI + "$$5,$$f14");
    break;
  case FDSig:
    IAH.Out(MI + "$$4,$$f12");
    if (LE) {
      IAH.Out(MI + "$$6,$$f14");
      IAH.Out(MI + "$$7,$$f15");
    } else {
      IAH.Out(MI + "$$7,$$f14");
      IAH.Out(MI + "$$6,$$f15");
    }
    break;
  case DSig:
    if (LE) {
      IAH.Out(MI + "$$4,$$f12");
      IAH.Out(MI + "$$5,$$f13");
    } else {
      IAH.Out(MI + "$$5,$$f12");
      IAH.Out(MI + "$$4,$$f13");
    }
    break;
  case DDSig:
    if (LE) {
      IAH.Out(MI + "$$4,$$f12");
      IAH.Out(MI + "$$5,$$f13");
      IAH.Out(MI + "$$6,$$f14");
      IAH.Out(MI + "$$7,$$f15");
    } else {
      IAH.Out(MI + "$$5,$$f12");
      IAH.Out(MI + "$$4,$$f13");
      IAH.Out(MI + "$$7,$$f14");
      IAH.Out(MI + "$$6,$$f15");
    }
    break;
  case DFSig:
    if (LE) {
      IAH.Out(MI + "$$4,$$f12");
      IAH.Out(MI + "$$5,$$f13");
    } else {
      IAH.Out(MI + "$$5,$$f12");
      IAH.Out(MI + "$$4,$$f13");
    }
    IAH.Out(MI + "$$6,$$f14");
    break;
  case NoSig:
    return;
  }
}
//
// 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) {
  // for now we only need them for static relocation
  if (TM.getRelocationModel() == Reloc::PIC_)
    return;
  LLVMContext &Context = M->getContext();
  bool LE = TM.isLittleEndian();
  std::string Name = F.getName();
  std::string SectionName = ".mips16.call.fp." + Name;
  std::string StubName = "__call_stub_fp_" + Name;
  //
  // see if we already have the stub
  //
  Function *FStub = M->getFunction(StubName);
  if (FStub && !FStub->isDeclaration()) return;
  FStub = Function::Create(F.getFunctionType(),
                           Function::InternalLinkage, StubName, M);
  FStub->addFnAttr("mips16_fp_stub");
  FStub->addFnAttr(llvm::Attribute::Naked);
  FStub->addFnAttr(llvm::Attribute::NoInline);
  FStub->addFnAttr(llvm::Attribute::NoUnwind);
  FStub->addFnAttr("nomips16");
  FStub->setSection(SectionName);
  BasicBlock *BB = BasicBlock::Create(Context, "entry", FStub);
  InlineAsmHelper IAH(Context, BB);
  IAH.Out(".set reorder");
  FPReturnVariant RV = whichFPReturnVariant(FStub->getReturnType());
  FPParamVariant PV = whichFPParamVariantNeeded(F);
  swapFPIntParams(PV, M, IAH, LE, true);
  if (RV != NoFPRet) {
    IAH.Out("move $$18, $$31");
    IAH.Out("jal " + Name);
  } else {
    IAH.Out("lui  $$25,%hi(" + Name + ")");
    IAH.Out("addiu  $$25,$$25,%lo(" + Name + ")" );
  }
  switch (RV) {
  case FRet:
    IAH.Out("mfc1 $$2,$$f0");
    break;
  case DRet:
    if (LE) {
      IAH.Out("mfc1 $$2,$$f0");
      IAH.Out("mfc1 $$3,$$f1");
    } else {
      IAH.Out("mfc1 $$3,$$f0");
      IAH.Out("mfc1 $$2,$$f1");
    }
    break;
  case CFRet:
    if (LE) {
    IAH.Out("mfc1 $$2,$$f0");
    IAH.Out("mfc1 $$3,$$f2");
    } else {
      IAH.Out("mfc1 $$3,$$f0");
      IAH.Out("mfc1 $$3,$$f2");
    }
    break;
  case CDRet:
    if (LE) {
      IAH.Out("mfc1 $$4,$$f2");
      IAH.Out("mfc1 $$5,$$f3");
      IAH.Out("mfc1 $$2,$$f0");
      IAH.Out("mfc1 $$3,$$f1");

    } else {
      IAH.Out("mfc1 $$5,$$f2");
      IAH.Out("mfc1 $$4,$$f3");
      IAH.Out("mfc1 $$3,$$f0");
      IAH.Out("mfc1 $$2,$$f1");
    }
    break;
  case NoFPRet:
    break;
  }
  if (RV != NoFPRet)
    IAH.Out("jr $$18");
  else
    IAH.Out("jr $$25");
  new UnreachableInst(Context, BB);
}

//
// Functions that are llvm intrinsics and don't need helpers.
//
static const char *IntrinsicInline[] =
  {"fabs",
   "fabsf",
   "llvm.ceil.f32", "llvm.ceil.f64",
   "llvm.copysign.f32", "llvm.copysign.f64",
   "llvm.cos.f32", "llvm.cos.f64",
   "llvm.exp.f32", "llvm.exp.f64",
   "llvm.exp2.f32", "llvm.exp2.f64",
   "llvm.fabs.f32", "llvm.fabs.f64",
   "llvm.floor.f32", "llvm.floor.f64",
   "llvm.fma.f32", "llvm.fma.f64",
   "llvm.log.f32", "llvm.log.f64",
   "llvm.log10.f32", "llvm.log10.f64",
   "llvm.nearbyint.f32", "llvm.nearbyint.f64",
   "llvm.pow.f32", "llvm.pow.f64",
   "llvm.powi.f32", "llvm.powi.f64",
   "llvm.rint.f32", "llvm.rint.f64",
   "llvm.round.f32", "llvm.round.f64",
   "llvm.sin.f32", "llvm.sin.f64",
   "llvm.sqrt.f32", "llvm.sqrt.f64",
   "llvm.trunc.f32", "llvm.trunc.f64",
  };

static bool isIntrinsicInline(Function *F) {
  return std::binary_search(std::begin(IntrinsicInline),
                            std::end(IntrinsicInline), F->getName());
}
//
// Returns of float, double and complex need to be handled with a helper
// function.
//
static bool fixupFPReturnAndCall(Function &F, Module *M,
                                 const MipsTargetMachine &TM) {
  bool Modified = false;
  LLVMContext &C = M->getContext();
  Type *MyVoid = Type::getVoidTy(C);
  for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
    for (BasicBlock::iterator I = BB->begin(), E = BB->end();
         I != E; ++I) {
      Instruction &Inst = *I;
      if (const ReturnInst *RI = dyn_cast<ReturnInst>(I)) {
        Value *RVal = RI->getReturnValue();
        if (!RVal) continue;
        //
        // If there is a return value and it needs a helper function,
        // figure out which one and add a call before the actual
        // return to this helper. The purpose of the helper is to move
        // floating point values from their soft float return mapping to
        // where they would have been mapped to in floating point registers.
        //
        Type *T = RVal->getType();
        FPReturnVariant RV = whichFPReturnVariant(T);
        if (RV == NoFPRet) continue;
        static const char* Helper[NoFPRet] =
          {"__mips16_ret_sf", "__mips16_ret_df", "__mips16_ret_sc",
           "__mips16_ret_dc"};
        const char *Name = Helper[RV];
        AttributeSet A;
        Value *Params[] = {RVal};
        Modified = true;
        //
        // These helper functions have a different calling ABI so
        // this __Mips16RetHelper indicates that so that later
        // during call setup, the proper call lowering to the helper
        // functions will take place.
        //
        A = A.addAttribute(C, AttributeSet::FunctionIndex,
                           "__Mips16RetHelper");
        A = A.addAttribute(C, AttributeSet::FunctionIndex,
                           Attribute::ReadNone);
        A = A.addAttribute(C, AttributeSet::FunctionIndex,
                           Attribute::NoInline);
        Value *F = (M->getOrInsertFunction(Name, A, MyVoid, T, nullptr));
        CallInst::Create(F, Params, "", &Inst );
      } else if (const CallInst *CI = dyn_cast<CallInst>(I)) {
          const Value* V = CI->getCalledValue();
          const Type* T = nullptr;
          if (V) T = V->getType();
          const PointerType *PFT=nullptr;
          if (T) PFT = dyn_cast<PointerType>(T);
          const FunctionType *FT=nullptr;
          if (PFT) FT = dyn_cast<FunctionType>(PFT->getElementType());
          Function *F_ =  CI->getCalledFunction();
          if (FT && needsFPReturnHelper(*FT) &&
              !(F_ && isIntrinsicInline(F_))) {
            Modified=true;
            F.addFnAttr("saveS2");
          }
          if (F_ && !isIntrinsicInline(F_)) {
          // pic mode calls are handled by already defined
          // helper functions
            if (needsFPReturnHelper(*F_)) {
              Modified=true;
              F.addFnAttr("saveS2");
            }
            if (TM.getRelocationModel() != Reloc::PIC_ ) {
              if (needsFPHelperFromSig(*F_)) {
                assureFPCallStub(*F_, M, TM);
                Modified=true;
              }
            }
          }
      }
    }
  return Modified;
}

static void createFPFnStub(Function *F, Module *M, FPParamVariant PV,
                           const MipsTargetMachine &TM) {
  bool PicMode = TM.getRelocationModel() == Reloc::PIC_;
  bool LE = TM.isLittleEndian();
  LLVMContext &Context = M->getContext();
  std::string Name = F->getName();
  std::string SectionName = ".mips16.fn." + Name;
  std::string StubName = "__fn_stub_" + Name;
  std::string LocalName = "$$__fn_local_" + Name;
  Function *FStub = Function::Create
    (F->getFunctionType(),
     Function::InternalLinkage, StubName, M);
  FStub->addFnAttr("mips16_fp_stub");
  FStub->addFnAttr(llvm::Attribute::Naked);
  FStub->addFnAttr(llvm::Attribute::NoUnwind);
  FStub->addFnAttr(llvm::Attribute::NoInline);
  FStub->addFnAttr("nomips16");
  FStub->setSection(SectionName);
  BasicBlock *BB = BasicBlock::Create(Context, "entry", FStub);
  InlineAsmHelper IAH(Context, BB);
  if (PicMode) {
    IAH.Out(".set noreorder");
    IAH.Out(".cpload  $$25");
    IAH.Out(".set reorder");
    IAH.Out(".reloc 0,R_MIPS_NONE," + Name);
    IAH.Out("la $$25," + LocalName);
  }
  else {
    IAH.Out("la $$25," + Name);
  }
  swapFPIntParams(PV, M, IAH, LE, false);
  IAH.Out("jr $$25");
  IAH.Out(LocalName + " = " + Name);
  new UnreachableInst(FStub->getContext(), BB);
}

//
// remove the use-soft-float attribute
//
static void removeUseSoftFloat(Function &F) {
  AttributeSet A;
  DEBUG(errs() << "removing -use-soft-float\n");
  A = A.addAttribute(F.getContext(), AttributeSet::FunctionIndex,
                     "use-soft-float", "false");
  F.removeAttributes(AttributeSet::FunctionIndex, A);
  if (F.hasFnAttribute("use-soft-float")) {
    DEBUG(errs() << "still has -use-soft-float\n");
  }
  F.addAttributes(AttributeSet::FunctionIndex, A);
}

namespace llvm {

//
// 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) {
  DEBUG(errs() << "Run on Module Mips16HardFloat\n");
  bool Modified = false;
  for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
    if (F->hasFnAttribute("nomips16") &&
        F->hasFnAttribute("use-soft-float")) {
      removeUseSoftFloat(*F);
      continue;
    }
    if (F->isDeclaration() || F->hasFnAttribute("mips16_fp_stub") ||
        F->hasFnAttribute("nomips16")) continue;
    Modified |= fixupFPReturnAndCall(*F, &M, TM);
    FPParamVariant V = whichFPParamVariantNeeded(*F);
    if (V != NoSig) {
      Modified = true;
      createFPFnStub(F, &M, V, TM);
    }
  }
  return Modified;
}

char Mips16HardFloat::ID = 0;

}

ModulePass *llvm::createMips16HardFloat(MipsTargetMachine &TM) {
  return new Mips16HardFloat(TM);
}

