//===-- go-llvm-cabi-oracle.h - decls for 'CABIOracle' class -------------===//
//
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
//===----------------------------------------------------------------------===//
//
// Defines CABIOracle class. This class helps assist in the process of
// determining how values are passed to and returned from functions: whether
// in memory, directly, or via some sort of type coercion or sign extension.
//
// There are many possible complications, permutations, and oddities when
// it comes to runtime calling conventions; the code here currently supports
// only x86_64 SysV, which gets rid of many of the corner cases that can
// be found in the corresponding code in Clang.
//
//===----------------------------------------------------------------------===//

#ifndef LLVMGOFRONTEND_GO_LLVM_CABI_ORACLE_H
#define LLVMGOFRONTEND_GO_LLVM_CABI_ORACLE_H

#include "go-llvm-btype.h"

class TypeManager;
class EightByteInfo;
class ABIState;

namespace llvm {
class DataLayout;
class FunctionType;
class raw_ostream;
}

// Disposition of a specific function argument or function return value.

enum CABIParamDisp : uint8_t  {

  // Pass argument directly (not in memory).
  ParmDirect,

  // Ignore (typically for zero-sized structs)
  ParmIgnore,

  // Pass argument in memory
  ParmIndirect,

};

// Attributes on parameters. These correspond directly to the LLVM attrs
// of the same name.

enum CABIParamAttr : uint8_t  {
  AttrNone=0,
  AttrStructReturn,
  AttrByVal,
  AttrNest,
  AttrZext,
  AttrSext,
};

// Container class for storing info on how a specific parameter is
// passed to a function. A given parameter may wind up occupying
// multiple slots in the cooked (ABI-specific) signature of the LLVM
// function. For example:
//
//       type blah struct {
//          x float64
//          u,v,y,z uint8
//       }
//
//       func foo(p1 blah, p2 *int) int { ...
//         ...
//       }
//
// Here parameter p1 will be passed directly (by value in registers),
// however the signature of the function will have two params
// corresponding to the contents of "p1", e.g.
//
//      declare int @foo(double, int32, *int32)
//
// In the object below, sigOffset() returns of the index of the param
// (or first param) within the lowered fcn signature used to pass the param
// in question. For the function above, sigOffset() for "p1" would
// be 0 and for "p2" would be 2. A sigOffset value of -1 is present
// in the case of a fcn return value, or in an "empty" parm (ex: type
// of empty struct).

class CABIParamInfo {
 public:
  CABIParamInfo(const std::vector<llvm::Type *> &abiTypes,
               CABIParamDisp disp,
               CABIParamAttr attr,
               int sigOffset)
      : abiTypes_(abiTypes), disp_(disp),
        attr_(attr), sigOffset_(sigOffset) {
    assert(disp == ParmDirect);
    assert(sigOffset >= 0);
  }
  CABIParamInfo(llvm::Type *abiType,
               CABIParamDisp disp,
               CABIParamAttr attr,
               int sigOffset)
      : disp_(disp), attr_(attr), sigOffset_(sigOffset) {
    abiTypes_.push_back(abiType);
    assert(sigOffset >= -1);
  }
  CABIParamInfo(const CABIParamInfo &src)
      : abiTypes_(src.abiTypes_),
        disp_(src.disp_),
        attr_(src.attr_),
        sigOffset_(src.sigOffset_) { }

  unsigned numArgSlots() const { return abiTypes_.size(); }
  llvm::Type *abiType() const {
    assert(numArgSlots() == 1);
    return abiTypes_[0];
  }
  const std::vector<llvm::Type *> &abiTypes() const { return abiTypes_; }
  CABIParamDisp disp() const { return disp_; }
  CABIParamAttr attr() const { return attr_; }
  int sigOffset() const { return sigOffset_; }

  // Return a struct with fields corresponding to the ABI type(s)
  // for this param (may be a 1-element struct or a 2-element struct).
  llvm::Type *computeABIStructType(TypeManager *tm) const;

  void dump();
  void osdump(llvm::raw_ostream &os);

 private:
  std::vector<llvm::Type *> abiTypes_;
  CABIParamDisp disp_;
  CABIParamAttr attr_;
  unsigned sigOffset_;
};

// This class helps with determining the correct ABI-adjusted function
// signature given the high level signature of a function (argument
// types and return types), along with the disposition function args
// and returns (whether they are in memory or passed directly (and/or
// whether coercion or sext/zext is required).

class CABIOracle {
 public:

  // Given information on the param types and result type for a
  // function, create an oracle object that can answer C ABI
  // queries about the function.
  CABIOracle(const std::vector<Btype *> &fcnParamTypes,
             Btype *fcnResultType,
             bool followsCabi,
             TypeManager *typeManager);

  // This constructor draws param/result info from an existing BFunctionType
  CABIOracle(BFunctionType *ft,
             TypeManager *typeManager);

  // Returns TRUE if this cc supported, FALSE otherwise.
  bool supported() const;

  // Return the appropriate "cooked" LLVM function type for this
  // abstract function type.
  llvm::FunctionType *getFunctionTypeForABI();

  // Given the index of a parameter in the abstract function type,
  // return info on how the param is handled with respects to the ABI.
  const CABIParamInfo &paramInfo(unsigned idx);

  // Return info on transmission of return value.
  const CABIParamInfo &returnInfo();

  // Return info on the static chain parameter for the function.
  const CABIParamInfo &chainInfo();

  // Type manager used with this oracle.
  TypeManager *tm() const { return typeManager_; }

  // Various dump methods.
  void dump();
  std::string toString();
  void osdump(llvm::raw_ostream &os);

 private:
  std::vector<Btype *> fcnParamTypes_;
  Btype *fcnResultType_;
  llvm::FunctionType *fcnTypeForABI_;
  TypeManager *typeManager_;
  std::vector<CABIParamInfo> infov_;
  bool followsCabi_;

  void analyze();
  void analyzeRaw();
  CABIParamInfo analyzeABIReturn(Btype *resultType, ABIState &state);
  CABIParamInfo analyzeABIParam(Btype *pType, ABIState &state);
  bool canPassDirectly(unsigned regsInt, unsigned regsSSE, ABIState &state);
  const llvm::DataLayout *datalayout() const;
  CABIParamDisp classifyArgType(Btype *btype);
};

#endif // LLVMGOFRONTEND_GO_LLVM_CABI_ORACLE_H
