2006-03-03 02:33:15 +00:00
|
|
|
//===- Intrinsics.td - Defines all LLVM intrinsics ---------*- tablegen -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file was developed by Chris Lattner and is distributed under the
|
|
|
|
// University of Illinois Open Source License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file defines properties of all LLVM intrinsics.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2006-03-24 18:51:56 +00:00
|
|
|
include "llvm/CodeGen/ValueTypes.td"
|
|
|
|
|
2006-03-03 02:33:15 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Properties we keep track of for intrinsics.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
class IntrinsicProperty;
|
|
|
|
|
|
|
|
// Intr*Mem - Memory properties. An intrinsic is allowed to have exactly one of
|
|
|
|
// these properties set. They are listed from the most aggressive (best to use
|
|
|
|
// if correct) to the least aggressive. If no property is set, the worst case
|
|
|
|
// is assumed (IntrWriteMem).
|
|
|
|
|
2006-04-10 22:02:59 +00:00
|
|
|
// IntrNoMem - The intrinsic does not access memory or have any other side
|
2006-03-03 02:33:15 +00:00
|
|
|
// effects. It may be CSE'd deleted if dead, etc.
|
2006-04-10 22:02:59 +00:00
|
|
|
def IntrNoMem : IntrinsicProperty;
|
2006-03-03 02:33:15 +00:00
|
|
|
|
2006-04-10 22:02:59 +00:00
|
|
|
// IntrReadArgMem - This intrinsic reads only from memory that one of its
|
2006-03-03 02:33:15 +00:00
|
|
|
// arguments points to, but may read an unspecified amount.
|
2006-04-10 22:02:59 +00:00
|
|
|
def IntrReadArgMem : IntrinsicProperty;
|
2006-03-03 02:33:15 +00:00
|
|
|
|
|
|
|
// IntrReadMem - This intrinsic reads from unspecified memory, so it cannot be
|
|
|
|
// moved across stores. However, it can be reordered otherwise and can be
|
|
|
|
// deleted if dead.
|
|
|
|
def IntrReadMem : IntrinsicProperty;
|
|
|
|
|
2006-04-10 22:02:59 +00:00
|
|
|
// IntrWriteArgMem - This intrinsic reads and writes only from memory that one
|
2006-03-03 02:33:15 +00:00
|
|
|
// of its arguments points to, but may access an unspecified amount. It has no
|
|
|
|
// other side effects. This may only be used if the intrinsic doesn't "capture"
|
|
|
|
// the argument pointer (e.g. storing it someplace).
|
2006-04-10 22:02:59 +00:00
|
|
|
def IntrWriteArgMem : IntrinsicProperty;
|
2006-03-03 02:33:15 +00:00
|
|
|
|
|
|
|
// IntrWriteMem - This intrinsic may read or modify unspecified memory or has
|
|
|
|
// other side effects. It cannot be modified by the optimizer. This is the
|
|
|
|
// default if the intrinsic has no other Intr*Mem property.
|
|
|
|
def IntrWriteMem : IntrinsicProperty;
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Types used by intrinsics.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2006-03-24 19:41:10 +00:00
|
|
|
class LLVMType<ValueType vt, string typeval> {
|
|
|
|
ValueType VT = vt;
|
2006-03-03 02:33:15 +00:00
|
|
|
string TypeVal = typeval;
|
|
|
|
}
|
|
|
|
|
For PR1064:
Implement the arbitrary bit-width integer feature. The feature allows
integers of any bitwidth (up to 64) to be defined instead of just 1, 8,
16, 32, and 64 bit integers.
This change does several things:
1. Introduces a new Derived Type, IntegerType, to represent the number of
bits in an integer. The Type classes SubclassData field is used to
store the number of bits. This allows 2^23 bits in an integer type.
2. Removes the five integer Type::TypeID values for the 1, 8, 16, 32 and
64-bit integers. These are replaced with just IntegerType which is not
a primitive any more.
3. Adjust the rest of LLVM to account for this change.
Note that while this incremental change lays the foundation for arbitrary
bit-width integers, LLVM has not yet been converted to actually deal with
them in any significant way. Most optimization passes, for example, will
still only deal with the byte-width integer types. Future increments
will rectify this situation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33113 91177308-0d34-0410-b5e6-96231b3b80d8
2007-01-12 07:05:14 +00:00
|
|
|
class LLVMIntegerType<ValueType VT, int width>
|
|
|
|
: LLVMType<VT, "Type::IntegerTyID"> {
|
|
|
|
int Width = width;
|
|
|
|
}
|
|
|
|
|
2007-02-15 02:26:10 +00:00
|
|
|
class LLVMVectorType<ValueType VT, int numelts, LLVMType elty>
|
|
|
|
: LLVMType<VT, "Type::VectorTyID">{
|
2006-03-13 22:38:32 +00:00
|
|
|
int NumElts = numelts;
|
|
|
|
LLVMType ElTy = elty;
|
|
|
|
}
|
|
|
|
|
2007-02-07 20:38:26 +00:00
|
|
|
class LLVMPointerType<LLVMType elty>
|
|
|
|
: LLVMType<iPTR, "Type::PointerTyID">{
|
|
|
|
LLVMType ElTy = elty;
|
|
|
|
}
|
|
|
|
|
|
|
|
class LLVMEmptyStructType
|
|
|
|
: LLVMType<OtherVT, "Type::StructTyID">{
|
|
|
|
}
|
|
|
|
|
2006-03-24 19:41:10 +00:00
|
|
|
def llvm_void_ty : LLVMType<isVoid, "Type::VoidTyID">;
|
2007-04-01 07:30:57 +00:00
|
|
|
def llvm_int_ty : LLVMIntegerType<iAny, 0>;
|
|
|
|
def llvm_i1_ty : LLVMIntegerType<i1 , 1>;
|
For PR1064:
Implement the arbitrary bit-width integer feature. The feature allows
integers of any bitwidth (up to 64) to be defined instead of just 1, 8,
16, 32, and 64 bit integers.
This change does several things:
1. Introduces a new Derived Type, IntegerType, to represent the number of
bits in an integer. The Type classes SubclassData field is used to
store the number of bits. This allows 2^23 bits in an integer type.
2. Removes the five integer Type::TypeID values for the 1, 8, 16, 32 and
64-bit integers. These are replaced with just IntegerType which is not
a primitive any more.
3. Adjust the rest of LLVM to account for this change.
Note that while this incremental change lays the foundation for arbitrary
bit-width integers, LLVM has not yet been converted to actually deal with
them in any significant way. Most optimization passes, for example, will
still only deal with the byte-width integer types. Future increments
will rectify this situation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33113 91177308-0d34-0410-b5e6-96231b3b80d8
2007-01-12 07:05:14 +00:00
|
|
|
def llvm_i8_ty : LLVMIntegerType<i8 , 8>;
|
|
|
|
def llvm_i16_ty : LLVMIntegerType<i16, 16>;
|
|
|
|
def llvm_i32_ty : LLVMIntegerType<i32, 32>;
|
|
|
|
def llvm_i64_ty : LLVMIntegerType<i64, 64>;
|
2006-03-24 19:41:10 +00:00
|
|
|
def llvm_float_ty : LLVMType<f32, "Type::FloatTyID">;
|
|
|
|
def llvm_double_ty : LLVMType<f64, "Type::DoubleTyID">;
|
2007-02-07 20:38:26 +00:00
|
|
|
def llvm_ptr_ty : LLVMPointerType<llvm_i8_ty>; // i8*
|
|
|
|
def llvm_ptrptr_ty : LLVMPointerType<llvm_ptr_ty>; // i8**
|
|
|
|
def llvm_empty_ty : LLVMEmptyStructType; // { }
|
|
|
|
def llvm_descriptor_ty : LLVMPointerType<llvm_empty_ty>; // { }*
|
2006-03-24 19:41:10 +00:00
|
|
|
|
2007-02-15 02:26:10 +00:00
|
|
|
def llvm_v16i8_ty : LLVMVectorType<v16i8,16, llvm_i8_ty>; // 16 x i8
|
|
|
|
def llvm_v8i16_ty : LLVMVectorType<v8i16, 8, llvm_i16_ty>; // 8 x i16
|
|
|
|
def llvm_v2i64_ty : LLVMVectorType<v2i64, 2, llvm_i64_ty>; // 2 x i64
|
|
|
|
def llvm_v2i32_ty : LLVMVectorType<v2i32, 2, llvm_i32_ty>; // 2 x i32
|
Add support for the v1i64 type. This makes better code for this:
#include <mmintrin.h>
extern __m64 C;
void baz(__v2si *A, __v2si *B)
{
*A = C;
_mm_empty();
}
We get this:
_baz:
call "L1$pb"
"L1$pb":
popl %eax
movl L_C$non_lazy_ptr-"L1$pb"(%eax), %eax
movq (%eax), %mm0
movl 4(%esp), %eax
movq %mm0, (%eax)
emms
ret
GCC gives us this:
_baz:
pushl %ebx
call L3
"L00000000001$pb":
L3:
popl %ebx
subl $8, %esp
movl L_C$non_lazy_ptr-"L00000000001$pb"(%ebx), %eax
movl (%eax), %edx
movl 4(%eax), %ecx
movl 16(%esp), %eax
movl %edx, (%eax)
movl %ecx, 4(%eax)
emms
addl $8, %esp
popl %ebx
ret
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35351 91177308-0d34-0410-b5e6-96231b3b80d8
2007-03-26 07:53:08 +00:00
|
|
|
def llvm_v1i64_ty : LLVMVectorType<v1i64, 1, llvm_i64_ty>; // 1 x i64
|
2007-02-15 02:26:10 +00:00
|
|
|
def llvm_v4i32_ty : LLVMVectorType<v4i32, 4, llvm_i32_ty>; // 4 x i32
|
|
|
|
def llvm_v4f32_ty : LLVMVectorType<v4f32, 4, llvm_float_ty>; // 4 x float
|
|
|
|
def llvm_v2f64_ty : LLVMVectorType<v2f64, 2, llvm_double_ty>;// 2 x double
|
2006-03-13 22:38:32 +00:00
|
|
|
|
2007-03-08 22:09:11 +00:00
|
|
|
// MMX Vector Types
|
|
|
|
def llvm_v8i8_ty : LLVMVectorType<v8i8, 8, llvm_i8_ty>; // 8 x i8
|
|
|
|
def llvm_v4i16_ty : LLVMVectorType<v4i16, 4, llvm_i16_ty>; // 4 x i16
|
|
|
|
|
2007-02-06 18:19:44 +00:00
|
|
|
def llvm_vararg_ty : LLVMType<isVoid, "...">; // vararg
|
2007-02-06 18:02:54 +00:00
|
|
|
|
2006-03-03 02:33:15 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Intrinsic Definitions.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
// Intrinsic class - This is used to define one LLVM intrinsic. The name of the
|
|
|
|
// intrinsic definition should start with "int_", then match the LLVM intrinsic
|
|
|
|
// name with the "llvm." prefix removed, and all "."s turned into "_"s. For
|
|
|
|
// example, llvm.bswap.i16 -> int_bswap_i16.
|
|
|
|
//
|
|
|
|
// * Types is a list containing the return type and the argument types
|
|
|
|
// expected for the intrinsic.
|
|
|
|
// * Properties can be set to describe the behavior of the intrinsic.
|
|
|
|
//
|
|
|
|
class Intrinsic<list<LLVMType> types,
|
|
|
|
list<IntrinsicProperty> properties = [],
|
|
|
|
string name = ""> {
|
|
|
|
string LLVMName = name;
|
2006-03-15 01:32:36 +00:00
|
|
|
string TargetPrefix = ""; // Set to a prefix for target-specific intrinsics.
|
2006-03-03 02:33:15 +00:00
|
|
|
list<LLVMType> Types = types;
|
|
|
|
list<IntrinsicProperty> Properties = properties;
|
|
|
|
}
|
|
|
|
|
2006-03-13 22:38:32 +00:00
|
|
|
/// GCCBuiltin - If this intrinsic exactly corresponds to a GCC builtin, this
|
|
|
|
/// specifies the name of the builtin. This provides automatic CBE and CFE
|
|
|
|
/// support.
|
|
|
|
class GCCBuiltin<string name> {
|
|
|
|
string GCCBuiltinName = name;
|
|
|
|
}
|
|
|
|
|
2006-03-03 02:33:15 +00:00
|
|
|
|
|
|
|
//===--------------- Variable Argument Handling Intrinsics ----------------===//
|
|
|
|
//
|
|
|
|
|
2007-02-07 20:38:26 +00:00
|
|
|
def int_vastart : Intrinsic<[llvm_void_ty, llvm_ptr_ty], [], "llvm.va_start">;
|
|
|
|
def int_vacopy : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ptr_ty], [],
|
2006-03-03 02:33:15 +00:00
|
|
|
"llvm.va_copy">;
|
2007-02-07 20:38:26 +00:00
|
|
|
def int_vaend : Intrinsic<[llvm_void_ty, llvm_ptr_ty], [], "llvm.va_end">;
|
2006-03-03 02:33:15 +00:00
|
|
|
|
|
|
|
//===------------------- Garbage Collection Intrinsics --------------------===//
|
|
|
|
//
|
|
|
|
def int_gcroot : Intrinsic<[llvm_void_ty, llvm_ptrptr_ty, llvm_ptr_ty]>;
|
2006-03-14 20:00:20 +00:00
|
|
|
def int_gcread : Intrinsic<[llvm_ptr_ty, llvm_ptr_ty, llvm_ptrptr_ty],
|
2006-04-10 22:02:59 +00:00
|
|
|
[IntrReadArgMem]>;
|
2006-03-14 20:00:20 +00:00
|
|
|
def int_gcwrite : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ptr_ty,
|
2006-04-10 22:02:59 +00:00
|
|
|
llvm_ptrptr_ty], [IntrWriteArgMem]>;
|
2006-03-03 02:33:15 +00:00
|
|
|
|
|
|
|
//===--------------------- Code Generator Intrinsics ----------------------===//
|
|
|
|
//
|
2006-12-31 22:24:55 +00:00
|
|
|
def int_returnaddress : Intrinsic<[llvm_ptr_ty, llvm_i32_ty], [IntrNoMem]>;
|
|
|
|
def int_frameaddress : Intrinsic<[llvm_ptr_ty, llvm_i32_ty], [IntrNoMem]>;
|
2007-01-17 23:33:20 +00:00
|
|
|
def int_stacksave : Intrinsic<[llvm_ptr_ty], [IntrReadMem]>,
|
|
|
|
GCCBuiltin<"__builtin_stack_save">;
|
|
|
|
def int_stackrestore : Intrinsic<[llvm_void_ty, llvm_ptr_ty]>,
|
|
|
|
GCCBuiltin<"__builtin_stack_restore">;
|
2006-03-03 02:33:15 +00:00
|
|
|
def int_prefetch : Intrinsic<[llvm_void_ty, llvm_ptr_ty,
|
2006-12-31 22:24:55 +00:00
|
|
|
llvm_i32_ty, llvm_i32_ty]>;
|
|
|
|
def int_pcmarker : Intrinsic<[llvm_void_ty, llvm_i32_ty]>;
|
2006-03-03 02:33:15 +00:00
|
|
|
|
2006-12-31 22:24:55 +00:00
|
|
|
def int_readcyclecounter : Intrinsic<[llvm_i64_ty]>;
|
2006-03-03 02:33:15 +00:00
|
|
|
|
|
|
|
//===------------------- Standard C Library Intrinsics --------------------===//
|
|
|
|
//
|
|
|
|
|
2006-04-10 22:02:59 +00:00
|
|
|
let Properties = [IntrWriteArgMem] in {
|
2006-03-03 02:33:15 +00:00
|
|
|
def int_memcpy_i32 : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ptr_ty,
|
2006-12-31 22:24:55 +00:00
|
|
|
llvm_i32_ty, llvm_i32_ty]>;
|
2006-03-03 02:33:15 +00:00
|
|
|
def int_memcpy_i64 : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ptr_ty,
|
2006-12-31 22:24:55 +00:00
|
|
|
llvm_i64_ty, llvm_i32_ty]>;
|
2006-03-03 02:33:15 +00:00
|
|
|
def int_memmove_i32 : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ptr_ty,
|
2006-12-31 22:24:55 +00:00
|
|
|
llvm_i32_ty, llvm_i32_ty]>;
|
2006-03-03 02:33:15 +00:00
|
|
|
def int_memmove_i64 : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ptr_ty,
|
2006-12-31 22:24:55 +00:00
|
|
|
llvm_i64_ty, llvm_i32_ty]>;
|
|
|
|
def int_memset_i32 : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_i8_ty,
|
|
|
|
llvm_i32_ty, llvm_i32_ty]>;
|
|
|
|
def int_memset_i64 : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_i8_ty,
|
|
|
|
llvm_i64_ty, llvm_i32_ty]>;
|
2006-03-03 02:33:15 +00:00
|
|
|
}
|
|
|
|
|
2006-04-10 22:02:59 +00:00
|
|
|
let Properties = [IntrNoMem] in {
|
2006-03-03 02:33:15 +00:00
|
|
|
def int_sqrt_f32 : Intrinsic<[llvm_float_ty , llvm_float_ty]>;
|
|
|
|
def int_sqrt_f64 : Intrinsic<[llvm_double_ty, llvm_double_ty]>;
|
2006-09-08 06:43:00 +00:00
|
|
|
|
2006-12-31 22:24:55 +00:00
|
|
|
def int_powi_f32 : Intrinsic<[llvm_float_ty , llvm_float_ty, llvm_i32_ty]>;
|
|
|
|
def int_powi_f64 : Intrinsic<[llvm_double_ty, llvm_double_ty, llvm_i32_ty]>;
|
2006-03-03 02:33:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// NOTE: these are internal interfaces.
|
2006-12-31 22:24:55 +00:00
|
|
|
def int_setjmp : Intrinsic<[llvm_i32_ty , llvm_ptr_ty]>;
|
|
|
|
def int_longjmp : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_i32_ty]>;
|
|
|
|
def int_sigsetjmp : Intrinsic<[llvm_i32_ty , llvm_ptr_ty, llvm_i32_ty]>;
|
|
|
|
def int_siglongjmp : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_i32_ty]>;
|
2006-03-03 02:33:15 +00:00
|
|
|
|
|
|
|
//===-------------------- Bit Manipulation Intrinsics ---------------------===//
|
|
|
|
//
|
|
|
|
|
|
|
|
// None of these intrinsics accesses memory at all.
|
2006-04-10 22:02:59 +00:00
|
|
|
let Properties = [IntrNoMem] in {
|
2007-04-04 23:48:25 +00:00
|
|
|
def int_bit_part_select :
|
|
|
|
Intrinsic<[llvm_int_ty, llvm_int_ty, llvm_i32_ty, llvm_i32_ty]>;
|
2007-04-01 07:30:57 +00:00
|
|
|
def int_bswap: Intrinsic<[llvm_int_ty, llvm_int_ty]>;
|
|
|
|
def int_ctpop: Intrinsic<[llvm_i32_ty, llvm_int_ty]>;
|
|
|
|
def int_ctlz : Intrinsic<[llvm_i32_ty, llvm_int_ty]>;
|
|
|
|
def int_cttz : Intrinsic<[llvm_i32_ty, llvm_int_ty]>;
|
2007-04-04 23:48:25 +00:00
|
|
|
}
|
2006-03-03 02:33:15 +00:00
|
|
|
|
|
|
|
//===------------------------ Debugger Intrinsics -------------------------===//
|
|
|
|
//
|
|
|
|
|
2006-03-13 13:07:37 +00:00
|
|
|
def int_dbg_stoppoint : Intrinsic<[llvm_void_ty,
|
2006-12-31 22:24:55 +00:00
|
|
|
llvm_i32_ty, llvm_i32_ty,
|
2006-03-10 04:17:06 +00:00
|
|
|
llvm_descriptor_ty]>;
|
2006-03-23 18:04:18 +00:00
|
|
|
def int_dbg_region_start : Intrinsic<[llvm_void_ty, llvm_descriptor_ty]>;
|
|
|
|
def int_dbg_region_end : Intrinsic<[llvm_void_ty, llvm_descriptor_ty]>;
|
2006-03-13 13:07:37 +00:00
|
|
|
def int_dbg_func_start : Intrinsic<[llvm_void_ty, llvm_descriptor_ty]>;
|
2007-02-07 20:38:26 +00:00
|
|
|
def int_dbg_declare : Intrinsic<[llvm_void_ty, llvm_descriptor_ty,
|
2006-03-23 18:04:18 +00:00
|
|
|
llvm_descriptor_ty]>;
|
2006-03-13 22:38:32 +00:00
|
|
|
|
2007-02-06 18:02:54 +00:00
|
|
|
//===------------------ Exception Handling Intrinsics----------------------===//
|
|
|
|
//
|
2007-03-01 20:23:39 +00:00
|
|
|
def int_eh_exception : Intrinsic<[llvm_ptr_ty]>;
|
|
|
|
def int_eh_selector : Intrinsic<[llvm_i32_ty, llvm_ptr_ty, llvm_ptr_ty,
|
|
|
|
llvm_vararg_ty]>;
|
|
|
|
def int_eh_filter : Intrinsic<[llvm_i32_ty, llvm_ptr_ty, llvm_ptr_ty,
|
|
|
|
llvm_vararg_ty]>;
|
2007-02-21 22:35:57 +00:00
|
|
|
def int_eh_typeid_for : Intrinsic<[llvm_i32_ty, llvm_ptr_ty]>;
|
2007-02-06 18:02:54 +00:00
|
|
|
|
2006-03-13 22:38:32 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Target-specific intrinsics
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2006-03-26 02:37:19 +00:00
|
|
|
include "llvm/IntrinsicsPowerPC.td"
|
|
|
|
include "llvm/IntrinsicsX86.td"
|