blob: f6311584c6efd71f23ca9e0eebf569aeb54f9a36 [file] [log] [blame]
//===- subzero/src/IceIntrinsics.h - List of Ice Intrinsics -----*- C++ -*-===//
//
// The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares the kinds of intrinsics supported by PNaCl.
//
//===----------------------------------------------------------------------===//
#ifndef SUBZERO_SRC_ICEINTRINSICS_H
#define SUBZERO_SRC_ICEINTRINSICS_H
#include "IceDefs.h"
#include "IceTypes.h"
namespace Ice {
class InstCall;
static const size_t kMaxIntrinsicParameters = 6;
class Intrinsics {
Intrinsics(const Intrinsics &) = delete;
Intrinsics &operator=(const Intrinsics &) = delete;
public:
Intrinsics();
~Intrinsics();
// Some intrinsics allow overloading by type. This enum collapses all
// overloads into a single ID, but the type can still be recovered by the
// type of the intrinsic function call's return value and parameters.
enum IntrinsicID {
UnknownIntrinsic = 0,
// Arbitrary (alphabetical) order.
AtomicCmpxchg,
AtomicFence,
AtomicFenceAll,
AtomicIsLockFree,
AtomicLoad,
AtomicRMW,
AtomicStore,
Bswap,
Ctlz,
Ctpop,
Cttz,
Longjmp,
Memcpy,
Memmove,
Memset,
NaClReadTP,
Setjmp,
Sqrt,
Stacksave,
Stackrestore,
Trap
};
/// Operations that can be represented by the AtomicRMW
/// intrinsic.
///
/// Do not reorder these values: their order offers forward
/// compatibility of bitcode targeted to PNaCl.
enum AtomicRMWOperation {
AtomicInvalid = 0, // Invalid, keep first.
AtomicAdd,
AtomicSub,
AtomicOr,
AtomicAnd,
AtomicXor,
AtomicExchange,
AtomicNum // Invalid, keep last.
};
/// Memory orderings supported by PNaCl IR.
///
/// Do not reorder these values: their order offers forward
/// compatibility of bitcode targeted to PNaCl.
enum MemoryOrder {
MemoryOrderInvalid = 0, // Invalid, keep first.
MemoryOrderRelaxed,
MemoryOrderConsume,
MemoryOrderAcquire,
MemoryOrderRelease,
MemoryOrderAcquireRelease,
MemoryOrderSequentiallyConsistent,
MemoryOrderNum // Invalid, keep last.
};
static bool VerifyMemoryOrder(uint64_t Order);
enum SideEffects {
SideEffects_F=0,
SideEffects_T=1
};
enum ReturnsTwice {
ReturnsTwice_F=0,
ReturnsTwice_T=1
};
// Basic attributes related to each intrinsic, that are relevant to
// code generation. Perhaps the attributes representation can be shared
// with general function calls, but PNaCl currently strips all
// attributes from functions.
struct IntrinsicInfo {
enum IntrinsicID ID : 30;
enum SideEffects HasSideEffects : 1;
enum ReturnsTwice ReturnsTwice : 1;
};
// The types of validation values for FullIntrinsicInfo.validateCall.
enum ValidateCallValue {
IsValidCall, // Valid use of instrinsic call.
BadReturnType, // Return type invalid for intrinsic.
WrongNumOfArgs, // Wrong number of arguments for intrinsic.
WrongCallArgType, // Argument of wrong type.
};
// The complete set of information about an intrinsic.
struct FullIntrinsicInfo {
struct IntrinsicInfo Info; // Information that CodeGen would care about.
// Sanity check during parsing.
Type Signature[kMaxIntrinsicParameters];
uint8_t NumTypes;
// Validates that type signature of call matches intrinsic.
// If WrongArgumentType is returned, ArgIndex is set to corresponding
// argument index.
ValidateCallValue validateCall(const Ice::InstCall *Call,
SizeT &ArgIndex) const;
// Returns the return type of the intrinsic.
Type getReturnType() const {
assert(NumTypes > 1);
return Signature[0];
}
// Returns number of arguments expected.
SizeT getNumArgs() const {
assert(NumTypes > 1);
return NumTypes - 1;
}
// Returns type of Index-th argument.
Type getArgType(SizeT Index) const;
};
// Find the information about a given intrinsic, based on function name.
// The function name is expected to have the common "llvm." prefix
// stripped. If found, returns a reference to a FullIntrinsicInfo entry
// (valid for the lifetime of the map). Otherwise returns null.
const FullIntrinsicInfo *find(const IceString &Name) const;
private:
// TODO(jvoung): May want to switch to something like LLVM's StringMap.
typedef std::map<IceString, FullIntrinsicInfo> IntrinsicMap;
IntrinsicMap Map;
};
} // end of namespace Ice
#endif // SUBZERO_SRC_ICEINTRINSICS_H