//===-- PTXFPRoundingModePass.cpp - Assign rounding modes pass ------------===//
//
//                     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 machine function pass that sets appropriate FP rounding
// modes for all relevant instructions.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "ptx-fp-rounding-mode"

#include "PTX.h"
#include "PTXTargetMachine.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

// NOTE: PTXFPRoundingModePass should be executed just before emission.

namespace {
  /// PTXFPRoundingModePass - Pass to assign appropriate FP rounding modes to
  /// all FP instructions. Essentially, this pass just looks for all FP
  /// instructions that have a rounding mode set to RndDefault, and sets an
  /// appropriate rounding mode based on the target device.
  ///
  class PTXFPRoundingModePass : public MachineFunctionPass {
    private:
      static char ID;

      typedef std::pair<unsigned, unsigned> RndModeDesc;

      PTXTargetMachine& TargetMachine;
      DenseMap<unsigned, RndModeDesc> Instrs;

    public:
      PTXFPRoundingModePass(PTXTargetMachine &TM, CodeGenOpt::Level OptLevel)
        : MachineFunctionPass(ID),
          TargetMachine(TM) {
        initializeMap();
      }

      virtual bool runOnMachineFunction(MachineFunction &MF);

      virtual const char *getPassName() const {
        return "PTX FP Rounding Mode Pass";
      }

    private:

      void initializeMap();
      void processInstruction(MachineInstr &MI);
  }; // class PTXFPRoundingModePass
} // end anonymous namespace

using namespace llvm;

char PTXFPRoundingModePass::ID = 0;

bool PTXFPRoundingModePass::runOnMachineFunction(MachineFunction &MF) {
  // Look at each basic block
  for (MachineFunction::iterator bbi = MF.begin(), bbe = MF.end(); bbi != bbe;
       ++bbi) {
    MachineBasicBlock &MBB = *bbi;
    // Look at each instruction
    for (MachineBasicBlock::iterator ii = MBB.begin(), ie = MBB.end();
         ii != ie; ++ii) {
      MachineInstr &MI = *ii;
      processInstruction(MI);
    }
  }
  return false;
}

void PTXFPRoundingModePass::initializeMap() {
  using namespace PTXRoundingMode;
  const PTXSubtarget& ST = TargetMachine.getSubtarget<PTXSubtarget>();

  // Build a map of default rounding mode for all instructions that need a
  // rounding mode.
  Instrs[PTX::FADDrr32] = std::make_pair(1U, (unsigned)RndNearestEven);
  Instrs[PTX::FADDri32] = std::make_pair(1U, (unsigned)RndNearestEven);
  Instrs[PTX::FADDrr64] = std::make_pair(1U, (unsigned)RndNearestEven);
  Instrs[PTX::FADDri64] = std::make_pair(1U, (unsigned)RndNearestEven);
  Instrs[PTX::FSUBrr32] = std::make_pair(1U, (unsigned)RndNearestEven);
  Instrs[PTX::FSUBri32] = std::make_pair(1U, (unsigned)RndNearestEven);
  Instrs[PTX::FSUBrr64] = std::make_pair(1U, (unsigned)RndNearestEven);
  Instrs[PTX::FSUBri64] = std::make_pair(1U, (unsigned)RndNearestEven);
  Instrs[PTX::FMULrr32] = std::make_pair(1U, (unsigned)RndNearestEven);
  Instrs[PTX::FMULri32] = std::make_pair(1U, (unsigned)RndNearestEven);
  Instrs[PTX::FMULrr64] = std::make_pair(1U, (unsigned)RndNearestEven);
  Instrs[PTX::FMULri64] = std::make_pair(1U, (unsigned)RndNearestEven);

  Instrs[PTX::FNEGrr32] = std::make_pair(1U, (unsigned)RndNone);
  Instrs[PTX::FNEGri32] = std::make_pair(1U, (unsigned)RndNone);
  Instrs[PTX::FNEGrr64] = std::make_pair(1U, (unsigned)RndNone);
  Instrs[PTX::FNEGri64] = std::make_pair(1U, (unsigned)RndNone);

  unsigned FDivRndMode = ST.fdivNeedsRoundingMode() ? RndNearestEven : RndNone;
  Instrs[PTX::FDIVrr32] = std::make_pair(1U, FDivRndMode);
  Instrs[PTX::FDIVri32] = std::make_pair(1U, FDivRndMode);
  Instrs[PTX::FDIVrr64] = std::make_pair(1U, FDivRndMode);
  Instrs[PTX::FDIVri64] = std::make_pair(1U, FDivRndMode);

  unsigned FMADRndMode = ST.fmadNeedsRoundingMode() ? RndNearestEven : RndNone;
  Instrs[PTX::FMADrrr32] = std::make_pair(1U, FMADRndMode);
  Instrs[PTX::FMADrri32] = std::make_pair(1U, FMADRndMode);
  Instrs[PTX::FMADrii32] = std::make_pair(1U, FMADRndMode);
  Instrs[PTX::FMADrrr64] = std::make_pair(1U, FMADRndMode);
  Instrs[PTX::FMADrri64] = std::make_pair(1U, FMADRndMode);
  Instrs[PTX::FMADrii64] = std::make_pair(1U, FMADRndMode);

  Instrs[PTX::FSQRTrr32] = std::make_pair(1U, (unsigned)RndNearestEven);
  Instrs[PTX::FSQRTri32] = std::make_pair(1U, (unsigned)RndNearestEven);
  Instrs[PTX::FSQRTrr64] = std::make_pair(1U, (unsigned)RndNearestEven);
  Instrs[PTX::FSQRTri64] = std::make_pair(1U, (unsigned)RndNearestEven);

  Instrs[PTX::FSINrr32] = std::make_pair(1U, (unsigned)RndApprox);
  Instrs[PTX::FSINri32] = std::make_pair(1U, (unsigned)RndApprox);
  Instrs[PTX::FSINrr64] = std::make_pair(1U, (unsigned)RndApprox);
  Instrs[PTX::FSINri64] = std::make_pair(1U, (unsigned)RndApprox);
  Instrs[PTX::FCOSrr32] = std::make_pair(1U, (unsigned)RndApprox);
  Instrs[PTX::FCOSri32] = std::make_pair(1U, (unsigned)RndApprox);
  Instrs[PTX::FCOSrr64] = std::make_pair(1U, (unsigned)RndApprox);
  Instrs[PTX::FCOSri64] = std::make_pair(1U, (unsigned)RndApprox);

  Instrs[PTX::CVTu16f32] = std::make_pair(1U, (unsigned)RndTowardsZeroInt);
  Instrs[PTX::CVTs16f32] = std::make_pair(1U, (unsigned)RndTowardsZeroInt);
  Instrs[PTX::CVTu16f64] = std::make_pair(1U, (unsigned)RndTowardsZeroInt);
  Instrs[PTX::CVTs16f64] = std::make_pair(1U, (unsigned)RndTowardsZeroInt);
  Instrs[PTX::CVTu32f32] = std::make_pair(1U, (unsigned)RndTowardsZeroInt);
  Instrs[PTX::CVTs32f32] = std::make_pair(1U, (unsigned)RndTowardsZeroInt);
  Instrs[PTX::CVTu32f64] = std::make_pair(1U, (unsigned)RndTowardsZeroInt);
  Instrs[PTX::CVTs32f64] = std::make_pair(1U, (unsigned)RndTowardsZeroInt);
  Instrs[PTX::CVTu64f32] = std::make_pair(1U, (unsigned)RndTowardsZeroInt);
  Instrs[PTX::CVTs64f32] = std::make_pair(1U, (unsigned)RndTowardsZeroInt);
  Instrs[PTX::CVTu64f64] = std::make_pair(1U, (unsigned)RndTowardsZeroInt);
  Instrs[PTX::CVTs64f64] = std::make_pair(1U, (unsigned)RndTowardsZeroInt);

  Instrs[PTX::CVTf32u16] = std::make_pair(1U, (unsigned)RndNearestEven);
  Instrs[PTX::CVTf32s16] = std::make_pair(1U, (unsigned)RndNearestEven);
  Instrs[PTX::CVTf32u32] = std::make_pair(1U, (unsigned)RndNearestEven);
  Instrs[PTX::CVTf32s32] = std::make_pair(1U, (unsigned)RndNearestEven);
  Instrs[PTX::CVTf32u64] = std::make_pair(1U, (unsigned)RndNearestEven);
  Instrs[PTX::CVTf32s64] = std::make_pair(1U, (unsigned)RndNearestEven);
  Instrs[PTX::CVTf32f64] = std::make_pair(1U, (unsigned)RndNearestEven);
  Instrs[PTX::CVTf64u16] = std::make_pair(1U, (unsigned)RndNearestEven);
  Instrs[PTX::CVTf64s16] = std::make_pair(1U, (unsigned)RndNearestEven);
  Instrs[PTX::CVTf64u32] = std::make_pair(1U, (unsigned)RndNearestEven);
  Instrs[PTX::CVTf64s32] = std::make_pair(1U, (unsigned)RndNearestEven);
  Instrs[PTX::CVTf64u64] = std::make_pair(1U, (unsigned)RndNearestEven);
  Instrs[PTX::CVTf64s64] = std::make_pair(1U, (unsigned)RndNearestEven);
}

void PTXFPRoundingModePass::processInstruction(MachineInstr &MI) {
  // Is this an instruction that needs a rounding mode?
  if (Instrs.count(MI.getOpcode())) {
    const RndModeDesc &Desc = Instrs[MI.getOpcode()];
    // Get the rounding mode operand
    MachineOperand &Op = MI.getOperand(Desc.first);
    // Update the rounding mode if needed
    if (Op.getImm() == PTXRoundingMode::RndDefault) {
      Op.setImm(Desc.second);
    }
  }
}

FunctionPass *llvm::createPTXFPRoundingModePass(PTXTargetMachine &TM,
                                                CodeGenOpt::Level OptLevel) {
  return new PTXFPRoundingModePass(TM, OptLevel);
}

