forked from OSchip/llvm-project
Modify the intrinsics pattern to separate out the "return" types from the
"parameter" types. An intrinsic can now return a multiple return values like this: def add_with_overflow : Intrinsic<[llvm_i32_ty, llvm_i1_ty], [LLVMMatchType<0>, LLVMMatchType<0>]>; llvm-svn: 59237
This commit is contained in:
parent
b9ec8f555f
commit
9182147f17
|
@ -117,16 +117,20 @@ def llvm_vararg_ty : LLVMType<isVoid>; // this means vararg here
|
|||
// 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.
|
||||
// * RetTypes is a list containing the return types expected for the
|
||||
// intrinsic.
|
||||
// * ParamTypes is a list containing the parameter types expected for the
|
||||
// intrinsic.
|
||||
// * Properties can be set to describe the behavior of the intrinsic.
|
||||
//
|
||||
class Intrinsic<list<LLVMType> types,
|
||||
class Intrinsic<list<LLVMType> ret_types,
|
||||
list<LLVMType> param_types = [],
|
||||
list<IntrinsicProperty> properties = [],
|
||||
string name = ""> {
|
||||
string LLVMName = name;
|
||||
string TargetPrefix = ""; // Set to a prefix for target-specific intrinsics.
|
||||
list<LLVMType> Types = types;
|
||||
list<LLVMType> RetTypes = ret_types;
|
||||
list<LLVMType> ParamTypes = param_types;
|
||||
list<IntrinsicProperty> Properties = properties;
|
||||
}
|
||||
|
||||
|
@ -141,64 +145,71 @@ class GCCBuiltin<string name> {
|
|||
//===--------------- Variable Argument Handling Intrinsics ----------------===//
|
||||
//
|
||||
|
||||
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], [],
|
||||
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], [],
|
||||
"llvm.va_copy">;
|
||||
def int_vaend : Intrinsic<[llvm_void_ty, llvm_ptr_ty], [], "llvm.va_end">;
|
||||
def int_vaend : Intrinsic<[llvm_void_ty], [llvm_ptr_ty], [], "llvm.va_end">;
|
||||
|
||||
//===------------------- Garbage Collection Intrinsics --------------------===//
|
||||
//
|
||||
def int_gcroot : Intrinsic<[llvm_void_ty, llvm_ptrptr_ty, llvm_ptr_ty]>;
|
||||
def int_gcread : Intrinsic<[llvm_ptr_ty, llvm_ptr_ty, llvm_ptrptr_ty],
|
||||
def int_gcroot : Intrinsic<[llvm_void_ty], [llvm_ptrptr_ty, llvm_ptr_ty]>;
|
||||
def int_gcread : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty, llvm_ptrptr_ty],
|
||||
[IntrReadArgMem]>;
|
||||
def int_gcwrite : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ptr_ty,
|
||||
def int_gcwrite : Intrinsic<[llvm_void_ty], [llvm_ptr_ty, llvm_ptr_ty,
|
||||
llvm_ptrptr_ty], [IntrWriteArgMem]>;
|
||||
|
||||
//===--------------------- Code Generator Intrinsics ----------------------===//
|
||||
//
|
||||
def int_returnaddress : Intrinsic<[llvm_ptr_ty, llvm_i32_ty], [IntrNoMem]>;
|
||||
def int_frameaddress : Intrinsic<[llvm_ptr_ty, llvm_i32_ty], [IntrNoMem]>;
|
||||
def int_returnaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>;
|
||||
def int_frameaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>;
|
||||
|
||||
// Note: we treat stacksave/stackrestore as writemem because we don't otherwise
|
||||
// model their dependencies on allocas.
|
||||
def int_stacksave : Intrinsic<[llvm_ptr_ty]>,
|
||||
GCCBuiltin<"__builtin_stack_save">;
|
||||
def int_stackrestore : Intrinsic<[llvm_void_ty, llvm_ptr_ty]>,
|
||||
def int_stackrestore : Intrinsic<[llvm_void_ty], [llvm_ptr_ty]>,
|
||||
GCCBuiltin<"__builtin_stack_restore">;
|
||||
|
||||
// IntrWriteArgMem is more pessimistic than strictly necessary for prefetch,
|
||||
// however it does conveniently prevent the prefetch from being reordered
|
||||
// with respect to nearby accesses to the same memory.
|
||||
def int_prefetch : Intrinsic<[llvm_void_ty, llvm_ptr_ty,
|
||||
llvm_i32_ty, llvm_i32_ty],
|
||||
def int_prefetch : Intrinsic<[llvm_void_ty],
|
||||
[llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty],
|
||||
[IntrWriteArgMem]>;
|
||||
def int_pcmarker : Intrinsic<[llvm_void_ty, llvm_i32_ty]>;
|
||||
def int_pcmarker : Intrinsic<[llvm_void_ty], [llvm_i32_ty]>;
|
||||
|
||||
def int_readcyclecounter : Intrinsic<[llvm_i64_ty]>;
|
||||
|
||||
// Stack Protector Intrinsics - The stackprotector_create writes the stack guard
|
||||
// to the correct place on the stack frame. The stackprotector_check reads back
|
||||
// the stack guard that the stackprotector_create stored.
|
||||
def int_stackprotector_create : Intrinsic<[llvm_void_ty, llvm_ptr_ty,
|
||||
llvm_ptrptr_ty], [IntrWriteMem]>;
|
||||
def int_stackprotector_check : Intrinsic<[llvm_ptr_ty, llvm_ptrptr_ty],
|
||||
def int_stackprotector_create : Intrinsic<[llvm_void_ty],
|
||||
[llvm_ptr_ty, llvm_ptrptr_ty],
|
||||
[IntrWriteMem]>;
|
||||
def int_stackprotector_check : Intrinsic<[llvm_ptr_ty], [llvm_ptrptr_ty],
|
||||
[IntrReadMem]>;
|
||||
|
||||
//===------------------- Standard C Library Intrinsics --------------------===//
|
||||
//
|
||||
|
||||
let Properties = [IntrWriteArgMem] in {
|
||||
def int_memcpy_i32 : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ptr_ty,
|
||||
def int_memcpy_i32 : Intrinsic<[llvm_void_ty],
|
||||
[llvm_ptr_ty, llvm_ptr_ty,
|
||||
llvm_i32_ty, llvm_i32_ty]>;
|
||||
def int_memcpy_i64 : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ptr_ty,
|
||||
def int_memcpy_i64 : Intrinsic<[llvm_void_ty],
|
||||
[llvm_ptr_ty, llvm_ptr_ty,
|
||||
llvm_i64_ty, llvm_i32_ty]>;
|
||||
def int_memmove_i32 : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ptr_ty,
|
||||
def int_memmove_i32 : Intrinsic<[llvm_void_ty],
|
||||
[llvm_ptr_ty, llvm_ptr_ty,
|
||||
llvm_i32_ty, llvm_i32_ty]>;
|
||||
def int_memmove_i64 : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ptr_ty,
|
||||
def int_memmove_i64 : Intrinsic<[llvm_void_ty],
|
||||
[llvm_ptr_ty, llvm_ptr_ty,
|
||||
llvm_i64_ty, llvm_i32_ty]>;
|
||||
def int_memset_i32 : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_i8_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,
|
||||
def int_memset_i64 : Intrinsic<[llvm_void_ty],
|
||||
[llvm_ptr_ty, llvm_i8_ty,
|
||||
llvm_i64_ty, llvm_i32_ty]>;
|
||||
}
|
||||
|
||||
|
@ -206,156 +217,159 @@ let Properties = [IntrWriteArgMem] in {
|
|||
// rounding mode. This needs to be modelled separately; in the meantime
|
||||
// declaring them as reading memory is conservatively correct.
|
||||
let Properties = [IntrReadMem] in {
|
||||
def int_sqrt : Intrinsic<[llvm_anyfloat_ty, LLVMMatchType<0>]>;
|
||||
def int_powi : Intrinsic<[llvm_anyfloat_ty, LLVMMatchType<0>, llvm_i32_ty]>;
|
||||
def int_sin : Intrinsic<[llvm_anyfloat_ty, LLVMMatchType<0>]>;
|
||||
def int_cos : Intrinsic<[llvm_anyfloat_ty, LLVMMatchType<0>]>;
|
||||
def int_pow : Intrinsic<[llvm_anyfloat_ty,
|
||||
LLVMMatchType<0>, LLVMMatchType<0>]>;
|
||||
def int_log : Intrinsic<[llvm_anyfloat_ty, LLVMMatchType<0>]>;
|
||||
def int_log10: Intrinsic<[llvm_anyfloat_ty, LLVMMatchType<0>]>;
|
||||
def int_log2 : Intrinsic<[llvm_anyfloat_ty, LLVMMatchType<0>]>;
|
||||
def int_exp : Intrinsic<[llvm_anyfloat_ty, LLVMMatchType<0>]>;
|
||||
def int_exp2 : Intrinsic<[llvm_anyfloat_ty, LLVMMatchType<0>]>;
|
||||
def int_sqrt : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
|
||||
def int_powi : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, llvm_i32_ty]>;
|
||||
def int_sin : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
|
||||
def int_cos : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
|
||||
def int_pow : Intrinsic<[llvm_anyfloat_ty],
|
||||
[LLVMMatchType<0>, LLVMMatchType<0>]>;
|
||||
def int_log : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
|
||||
def int_log10: Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
|
||||
def int_log2 : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
|
||||
def int_exp : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
|
||||
def int_exp2 : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
|
||||
}
|
||||
|
||||
// NOTE: these are internal interfaces.
|
||||
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]>;
|
||||
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]>;
|
||||
|
||||
//===-------------------- Bit Manipulation Intrinsics ---------------------===//
|
||||
//
|
||||
|
||||
// None of these intrinsics accesses memory at all.
|
||||
let Properties = [IntrNoMem] in {
|
||||
def int_bswap: Intrinsic<[llvm_anyint_ty, LLVMMatchType<0>]>;
|
||||
def int_ctpop: Intrinsic<[llvm_anyint_ty, LLVMMatchType<0>]>;
|
||||
def int_ctlz : Intrinsic<[llvm_anyint_ty, LLVMMatchType<0>]>;
|
||||
def int_cttz : Intrinsic<[llvm_anyint_ty, LLVMMatchType<0>]>;
|
||||
def int_bswap: Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>;
|
||||
def int_ctpop: Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>;
|
||||
def int_ctlz : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>;
|
||||
def int_cttz : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>;
|
||||
def int_part_select :
|
||||
Intrinsic<[llvm_anyint_ty, LLVMMatchType<0>, llvm_i32_ty, llvm_i32_ty]>;
|
||||
Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, llvm_i32_ty, llvm_i32_ty]>;
|
||||
def int_part_set :
|
||||
Intrinsic<[llvm_anyint_ty, LLVMMatchType<0>, llvm_anyint_ty, llvm_i32_ty,
|
||||
llvm_i32_ty]>;
|
||||
Intrinsic<[llvm_anyint_ty],
|
||||
[LLVMMatchType<0>, llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>;
|
||||
}
|
||||
|
||||
//===------------------------ Debugger Intrinsics -------------------------===//
|
||||
//
|
||||
|
||||
def int_dbg_stoppoint : Intrinsic<[llvm_void_ty,
|
||||
llvm_i32_ty, llvm_i32_ty,
|
||||
def int_dbg_stoppoint : Intrinsic<[llvm_void_ty],
|
||||
[llvm_i32_ty, llvm_i32_ty,
|
||||
llvm_descriptor_ty]>;
|
||||
def int_dbg_region_start : Intrinsic<[llvm_void_ty, llvm_descriptor_ty]>;
|
||||
def int_dbg_region_end : Intrinsic<[llvm_void_ty, llvm_descriptor_ty]>;
|
||||
def int_dbg_func_start : Intrinsic<[llvm_void_ty, llvm_descriptor_ty]>;
|
||||
def int_dbg_declare : Intrinsic<[llvm_void_ty, llvm_descriptor_ty,
|
||||
llvm_descriptor_ty]>;
|
||||
def int_dbg_region_start : Intrinsic<[llvm_void_ty], [llvm_descriptor_ty]>;
|
||||
def int_dbg_region_end : Intrinsic<[llvm_void_ty], [llvm_descriptor_ty]>;
|
||||
def int_dbg_func_start : Intrinsic<[llvm_void_ty], [llvm_descriptor_ty]>;
|
||||
def int_dbg_declare : Intrinsic<[llvm_void_ty],
|
||||
[llvm_descriptor_ty, llvm_descriptor_ty]>;
|
||||
|
||||
//===------------------ Exception Handling Intrinsics----------------------===//
|
||||
//
|
||||
def int_eh_exception : Intrinsic<[llvm_ptr_ty]>;
|
||||
def int_eh_selector_i32 : Intrinsic<[llvm_i32_ty, llvm_ptr_ty, llvm_ptr_ty,
|
||||
llvm_vararg_ty]>;
|
||||
def int_eh_selector_i64 : Intrinsic<[llvm_i64_ty, llvm_ptr_ty, llvm_ptr_ty,
|
||||
llvm_vararg_ty]>;
|
||||
def int_eh_exception : Intrinsic<[llvm_ptr_ty]>;
|
||||
def int_eh_selector_i32 : Intrinsic<[llvm_i32_ty],
|
||||
[llvm_ptr_ty, llvm_ptr_ty, llvm_vararg_ty]>;
|
||||
def int_eh_selector_i64 : Intrinsic<[llvm_i64_ty],
|
||||
[llvm_ptr_ty, llvm_ptr_ty, llvm_vararg_ty]>;
|
||||
|
||||
def int_eh_typeid_for_i32 : Intrinsic<[llvm_i32_ty, llvm_ptr_ty]>;
|
||||
def int_eh_typeid_for_i64 : Intrinsic<[llvm_i64_ty, llvm_ptr_ty]>;
|
||||
def int_eh_typeid_for_i32 : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>;
|
||||
def int_eh_typeid_for_i64 : Intrinsic<[llvm_i64_ty], [llvm_ptr_ty]>;
|
||||
|
||||
def int_eh_return_i32 : Intrinsic<[llvm_void_ty, llvm_i32_ty, llvm_ptr_ty]>;
|
||||
def int_eh_return_i64 : Intrinsic<[llvm_void_ty, llvm_i64_ty, llvm_ptr_ty]>;
|
||||
def int_eh_return_i32 : Intrinsic<[llvm_void_ty], [llvm_i32_ty, llvm_ptr_ty]>;
|
||||
def int_eh_return_i64 : Intrinsic<[llvm_void_ty], [llvm_i64_ty, llvm_ptr_ty]>;
|
||||
|
||||
def int_eh_unwind_init: Intrinsic<[llvm_void_ty]>,
|
||||
GCCBuiltin<"__builtin_unwind_init">;
|
||||
|
||||
def int_eh_dwarf_cfa : Intrinsic<[llvm_ptr_ty, llvm_i32_ty]>;
|
||||
def int_eh_dwarf_cfa : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty]>;
|
||||
|
||||
//===---------------- Generic Variable Attribute Intrinsics----------------===//
|
||||
//
|
||||
def int_var_annotation : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ptr_ty,
|
||||
def int_var_annotation : Intrinsic<[llvm_void_ty],
|
||||
[llvm_ptr_ty, llvm_ptr_ty,
|
||||
llvm_ptr_ty, llvm_i32_ty],
|
||||
[], "llvm.var.annotation">;
|
||||
def int_ptr_annotation : Intrinsic<[LLVMAnyPointerType<llvm_anyint_ty>,
|
||||
LLVMMatchType<0>,
|
||||
llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty],
|
||||
[], "llvm.ptr.annotation">;
|
||||
def int_annotation : Intrinsic<[llvm_anyint_ty, LLVMMatchType<0>, llvm_ptr_ty,
|
||||
llvm_ptr_ty, llvm_i32_ty],
|
||||
[], "llvm.annotation">;
|
||||
def int_ptr_annotation : Intrinsic<[LLVMAnyPointerType<llvm_anyint_ty>],
|
||||
[LLVMMatchType<0>, llvm_ptr_ty, llvm_ptr_ty,
|
||||
llvm_i32_ty],
|
||||
[], "llvm.ptr.annotation">;
|
||||
def int_annotation : Intrinsic<[llvm_anyint_ty],
|
||||
[LLVMMatchType<0>, llvm_ptr_ty,
|
||||
llvm_ptr_ty, llvm_i32_ty],
|
||||
[], "llvm.annotation">;
|
||||
|
||||
//===------------------------ Trampoline Intrinsics -----------------------===//
|
||||
//
|
||||
def int_init_trampoline : Intrinsic<[llvm_ptr_ty, llvm_ptr_ty, llvm_ptr_ty,
|
||||
llvm_ptr_ty], []>,
|
||||
def int_init_trampoline : Intrinsic<[llvm_ptr_ty],
|
||||
[llvm_ptr_ty, llvm_ptr_ty, llvm_ptr_ty],
|
||||
[]>,
|
||||
GCCBuiltin<"__builtin_init_trampoline">;
|
||||
|
||||
//===------------------------- Atomic Intrinsics --------------------------===//
|
||||
//
|
||||
def int_memory_barrier : Intrinsic<[llvm_void_ty, llvm_i1_ty, llvm_i1_ty,
|
||||
def int_memory_barrier : Intrinsic<[llvm_void_ty], [llvm_i1_ty, llvm_i1_ty,
|
||||
llvm_i1_ty, llvm_i1_ty, llvm_i1_ty], []>,
|
||||
GCCBuiltin<"__builtin_llvm_memory_barrier">;
|
||||
|
||||
def int_atomic_cmp_swap : Intrinsic<[llvm_anyint_ty,
|
||||
LLVMAnyPointerType<LLVMMatchType<0>>,
|
||||
LLVMMatchType<0>, LLVMMatchType<0>],
|
||||
[IntrWriteArgMem]>,
|
||||
def int_atomic_cmp_swap : Intrinsic<[llvm_anyint_ty],
|
||||
[LLVMAnyPointerType<LLVMMatchType<0>>,
|
||||
LLVMMatchType<0>, LLVMMatchType<0>],
|
||||
[IntrWriteArgMem]>,
|
||||
GCCBuiltin<"__sync_val_compare_and_swap">;
|
||||
def int_atomic_load_add : Intrinsic<[llvm_anyint_ty,
|
||||
LLVMAnyPointerType<LLVMMatchType<0>>,
|
||||
LLVMMatchType<0>],
|
||||
[IntrWriteArgMem]>,
|
||||
def int_atomic_load_add : Intrinsic<[llvm_anyint_ty],
|
||||
[LLVMAnyPointerType<LLVMMatchType<0>>,
|
||||
LLVMMatchType<0>],
|
||||
[IntrWriteArgMem]>,
|
||||
GCCBuiltin<"__sync_fetch_and_add">;
|
||||
def int_atomic_swap : Intrinsic<[llvm_anyint_ty,
|
||||
LLVMAnyPointerType<LLVMMatchType<0>>,
|
||||
LLVMMatchType<0>],
|
||||
[IntrWriteArgMem]>,
|
||||
def int_atomic_swap : Intrinsic<[llvm_anyint_ty],
|
||||
[LLVMAnyPointerType<LLVMMatchType<0>>,
|
||||
LLVMMatchType<0>],
|
||||
[IntrWriteArgMem]>,
|
||||
GCCBuiltin<"__sync_lock_test_and_set">;
|
||||
def int_atomic_load_sub : Intrinsic<[llvm_anyint_ty,
|
||||
LLVMAnyPointerType<LLVMMatchType<0>>,
|
||||
LLVMMatchType<0>],
|
||||
[IntrWriteArgMem]>,
|
||||
def int_atomic_load_sub : Intrinsic<[llvm_anyint_ty],
|
||||
[LLVMAnyPointerType<LLVMMatchType<0>>,
|
||||
LLVMMatchType<0>],
|
||||
[IntrWriteArgMem]>,
|
||||
GCCBuiltin<"__sync_fetch_and_sub">;
|
||||
def int_atomic_load_and : Intrinsic<[llvm_anyint_ty,
|
||||
LLVMAnyPointerType<LLVMMatchType<0>>,
|
||||
LLVMMatchType<0>],
|
||||
[IntrWriteArgMem]>,
|
||||
def int_atomic_load_and : Intrinsic<[llvm_anyint_ty],
|
||||
[LLVMAnyPointerType<LLVMMatchType<0>>,
|
||||
LLVMMatchType<0>],
|
||||
[IntrWriteArgMem]>,
|
||||
GCCBuiltin<"__sync_fetch_and_and">;
|
||||
def int_atomic_load_or : Intrinsic<[llvm_anyint_ty,
|
||||
LLVMAnyPointerType<LLVMMatchType<0>>,
|
||||
LLVMMatchType<0>],
|
||||
[IntrWriteArgMem]>,
|
||||
def int_atomic_load_or : Intrinsic<[llvm_anyint_ty],
|
||||
[LLVMAnyPointerType<LLVMMatchType<0>>,
|
||||
LLVMMatchType<0>],
|
||||
[IntrWriteArgMem]>,
|
||||
GCCBuiltin<"__sync_fetch_and_or">;
|
||||
def int_atomic_load_xor : Intrinsic<[llvm_anyint_ty,
|
||||
LLVMAnyPointerType<LLVMMatchType<0>>,
|
||||
LLVMMatchType<0>],
|
||||
[IntrWriteArgMem]>,
|
||||
def int_atomic_load_xor : Intrinsic<[llvm_anyint_ty],
|
||||
[LLVMAnyPointerType<LLVMMatchType<0>>,
|
||||
LLVMMatchType<0>],
|
||||
[IntrWriteArgMem]>,
|
||||
GCCBuiltin<"__sync_fetch_and_xor">;
|
||||
def int_atomic_load_nand : Intrinsic<[llvm_anyint_ty,
|
||||
LLVMAnyPointerType<LLVMMatchType<0>>,
|
||||
LLVMMatchType<0>],
|
||||
[IntrWriteArgMem]>,
|
||||
def int_atomic_load_nand : Intrinsic<[llvm_anyint_ty],
|
||||
[LLVMAnyPointerType<LLVMMatchType<0>>,
|
||||
LLVMMatchType<0>],
|
||||
[IntrWriteArgMem]>,
|
||||
GCCBuiltin<"__sync_fetch_and_nand">;
|
||||
def int_atomic_load_min : Intrinsic<[llvm_anyint_ty,
|
||||
LLVMAnyPointerType<LLVMMatchType<0>>,
|
||||
LLVMMatchType<0>],
|
||||
[IntrWriteArgMem]>,
|
||||
def int_atomic_load_min : Intrinsic<[llvm_anyint_ty],
|
||||
[LLVMAnyPointerType<LLVMMatchType<0>>,
|
||||
LLVMMatchType<0>],
|
||||
[IntrWriteArgMem]>,
|
||||
GCCBuiltin<"__sync_fetch_and_min">;
|
||||
def int_atomic_load_max : Intrinsic<[llvm_anyint_ty,
|
||||
LLVMAnyPointerType<LLVMMatchType<0>>,
|
||||
LLVMMatchType<0>],
|
||||
[IntrWriteArgMem]>,
|
||||
def int_atomic_load_max : Intrinsic<[llvm_anyint_ty],
|
||||
[LLVMAnyPointerType<LLVMMatchType<0>>,
|
||||
LLVMMatchType<0>],
|
||||
[IntrWriteArgMem]>,
|
||||
GCCBuiltin<"__sync_fetch_and_max">;
|
||||
def int_atomic_load_umin : Intrinsic<[llvm_anyint_ty,
|
||||
LLVMAnyPointerType<LLVMMatchType<0>>,
|
||||
LLVMMatchType<0>],
|
||||
[IntrWriteArgMem]>,
|
||||
def int_atomic_load_umin : Intrinsic<[llvm_anyint_ty],
|
||||
[LLVMAnyPointerType<LLVMMatchType<0>>,
|
||||
LLVMMatchType<0>],
|
||||
[IntrWriteArgMem]>,
|
||||
GCCBuiltin<"__sync_fetch_and_umin">;
|
||||
def int_atomic_load_umax : Intrinsic<[llvm_anyint_ty,
|
||||
LLVMAnyPointerType<LLVMMatchType<0>>,
|
||||
LLVMMatchType<0>],
|
||||
[IntrWriteArgMem]>,
|
||||
def int_atomic_load_umax : Intrinsic<[llvm_anyint_ty],
|
||||
[LLVMAnyPointerType<LLVMMatchType<0>>,
|
||||
LLVMMatchType<0>],
|
||||
[IntrWriteArgMem]>,
|
||||
GCCBuiltin<"__sync_fetch_and_umax">;
|
||||
|
||||
//===-------------------------- Other Intrinsics --------------------------===//
|
||||
|
@ -369,24 +383,24 @@ def int_trap : Intrinsic<[llvm_void_ty]>,
|
|||
// various types with rounding and saturation. NOTE: avoid using these
|
||||
// intrinsics as they might be removed sometime in the future and
|
||||
// most targets don't support them.
|
||||
def int_convertff : Intrinsic<[llvm_anyfloat_ty, llvm_anyfloat_ty,
|
||||
llvm_i32_ty, llvm_i32_ty]>;
|
||||
def int_convertfsi : Intrinsic<[llvm_anyfloat_ty, llvm_anyint_ty,
|
||||
llvm_i32_ty, llvm_i32_ty]>;
|
||||
def int_convertfui : Intrinsic<[llvm_anyfloat_ty, llvm_anyint_ty,
|
||||
llvm_i32_ty, llvm_i32_ty]>;
|
||||
def int_convertsif : Intrinsic<[llvm_anyint_ty, llvm_anyfloat_ty,
|
||||
llvm_i32_ty, llvm_i32_ty]>;
|
||||
def int_convertuif : Intrinsic<[llvm_anyint_ty, llvm_anyfloat_ty,
|
||||
llvm_i32_ty, llvm_i32_ty]>;
|
||||
def int_convertss : Intrinsic<[llvm_anyint_ty, llvm_anyint_ty,
|
||||
llvm_i32_ty, llvm_i32_ty]>;
|
||||
def int_convertsu : Intrinsic<[llvm_anyint_ty, llvm_anyint_ty,
|
||||
llvm_i32_ty, llvm_i32_ty]>;
|
||||
def int_convertus : Intrinsic<[llvm_anyint_ty, llvm_anyint_ty,
|
||||
llvm_i32_ty, llvm_i32_ty]>;
|
||||
def int_convertuu : Intrinsic<[llvm_anyint_ty, llvm_anyint_ty,
|
||||
llvm_i32_ty, llvm_i32_ty]>;
|
||||
def int_convertff : Intrinsic<[llvm_anyfloat_ty],
|
||||
[llvm_anyfloat_ty, llvm_i32_ty, llvm_i32_ty]>;
|
||||
def int_convertfsi : Intrinsic<[llvm_anyfloat_ty],
|
||||
[llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>;
|
||||
def int_convertfui : Intrinsic<[llvm_anyfloat_ty],
|
||||
[llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>;
|
||||
def int_convertsif : Intrinsic<[llvm_anyint_ty],
|
||||
[llvm_anyfloat_ty, llvm_i32_ty, llvm_i32_ty]>;
|
||||
def int_convertuif : Intrinsic<[llvm_anyint_ty],
|
||||
[llvm_anyfloat_ty, llvm_i32_ty, llvm_i32_ty]>;
|
||||
def int_convertss : Intrinsic<[llvm_anyint_ty],
|
||||
[llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>;
|
||||
def int_convertsu : Intrinsic<[llvm_anyint_ty],
|
||||
[llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>;
|
||||
def int_convertus : Intrinsic<[llvm_anyint_ty],
|
||||
[llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>;
|
||||
def int_convertuu : Intrinsic<[llvm_anyint_ty],
|
||||
[llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Target-specific intrinsics
|
||||
|
|
|
@ -17,5 +17,5 @@
|
|||
|
||||
let TargetPrefix = "arm" in { // All intrinsics start with "llvm.arm.".
|
||||
def int_arm_thread_pointer : GCCBuiltin<"__builtin_thread_pointer">,
|
||||
Intrinsic<[llvm_ptr_ty],[IntrNoMem]>;
|
||||
Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,5 @@
|
|||
|
||||
let TargetPrefix = "alpha" in { // All intrinsics start with "llvm.alpha.".
|
||||
def int_alpha_umulh : GCCBuiltin<"__builtin_alpha_umulh">,
|
||||
Intrinsic<[llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
|
||||
|
||||
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
|
||||
}
|
||||
|
|
|
@ -25,77 +25,77 @@ def llvm_i128_ty : LLVMType<i128>;
|
|||
|
||||
class v16i8_u7imm<string builtin_suffix> :
|
||||
GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
|
||||
Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, cell_i7_ty],
|
||||
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, cell_i7_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
class v16i8_u8imm<string builtin_suffix> :
|
||||
GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
|
||||
Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
|
||||
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i8_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
class v16i8_s10imm<string builtin_suffix> :
|
||||
GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
|
||||
Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i16_ty],
|
||||
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i16_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
class v16i8_u16imm<string builtin_suffix> :
|
||||
GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
|
||||
Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i16_ty],
|
||||
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i16_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
class v16i8_rr<string builtin_suffix> :
|
||||
GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
|
||||
Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
|
||||
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
class v8i16_s10imm<string builtin_suffix> :
|
||||
GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
|
||||
Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty, llvm_i16_ty],
|
||||
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i16_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
class v8i16_u16imm<string builtin_suffix> :
|
||||
GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
|
||||
Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty, llvm_i16_ty],
|
||||
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i16_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
class v8i16_rr<string builtin_suffix> :
|
||||
GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
|
||||
Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
class v4i32_rr<string builtin_suffix> :
|
||||
GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
class v4i32_u7imm<string builtin_suffix> :
|
||||
GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty, cell_i7_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, cell_i7_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
class v4i32_s10imm<string builtin_suffix> :
|
||||
GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty, llvm_i16_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i16_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
class v4i32_u16imm<string builtin_suffix> :
|
||||
GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty, llvm_i16_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i16_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
class v4f32_rr<string builtin_suffix> :
|
||||
GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
|
||||
Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
|
||||
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
class v4f32_rrr<string builtin_suffix> :
|
||||
GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
|
||||
Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
|
||||
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
class v2f64_rr<string builtin_suffix> :
|
||||
GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
|
||||
Intrinsic<[llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
|
||||
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
// All Cell SPU intrinsics start with "llvm.spu.".
|
||||
|
@ -117,60 +117,60 @@ let TargetPrefix = "spu" in {
|
|||
def int_spu_si_bgx : v4i32_rr<"bgx">;
|
||||
def int_spu_si_mpy : // This is special:
|
||||
GCCBuiltin<"__builtin_si_mpy">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_spu_si_mpyu : // This is special:
|
||||
GCCBuiltin<"__builtin_si_mpyu">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_spu_si_mpyi : // This is special:
|
||||
GCCBuiltin<"__builtin_si_mpyi">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_i16_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_i16_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_spu_si_mpyui : // This is special:
|
||||
GCCBuiltin<"__builtin_si_mpyui">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_i16_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_i16_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_spu_si_mpya : // This is special:
|
||||
GCCBuiltin<"__builtin_si_mpya">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_spu_si_mpyh : // This is special:
|
||||
GCCBuiltin<"__builtin_si_mpyh">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty, llvm_v8i16_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v8i16_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_spu_si_mpys : // This is special:
|
||||
GCCBuiltin<"__builtin_si_mpys">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_spu_si_mpyhh : // This is special:
|
||||
GCCBuiltin<"__builtin_si_mpyhh">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_spu_si_mpyhha : // This is special:
|
||||
GCCBuiltin<"__builtin_si_mpyhha">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_spu_si_mpyhhu : // This is special:
|
||||
GCCBuiltin<"__builtin_si_mpyhhu">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_spu_si_mpyhhau : // This is special:
|
||||
GCCBuiltin<"__builtin_si_mpyhhau">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
def int_spu_si_shli: v4i32_u7imm<"shli">;
|
||||
|
||||
def int_spu_si_shlqbi:
|
||||
GCCBuiltin<!strconcat("__builtin_si_", "shlqbi")>,
|
||||
Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty],
|
||||
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
def int_spu_si_shlqbii: v16i8_u7imm<"shlqbii">;
|
||||
def int_spu_si_shlqby:
|
||||
GCCBuiltin<!strconcat("__builtin_si_", "shlqby")>,
|
||||
Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty],
|
||||
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_spu_si_shlqbyi: v16i8_u7imm<"shlqbyi">;
|
||||
|
||||
|
|
|
@ -18,26 +18,27 @@
|
|||
// Non-altivec intrinsics.
|
||||
let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
|
||||
// dcba/dcbf/dcbi/dcbst/dcbt/dcbz/dcbzl(PPC970) instructions.
|
||||
def int_ppc_dcba : Intrinsic<[llvm_void_ty, llvm_ptr_ty], [IntrWriteMem]>;
|
||||
def int_ppc_dcbf : Intrinsic<[llvm_void_ty, llvm_ptr_ty], [IntrWriteMem]>;
|
||||
def int_ppc_dcbi : Intrinsic<[llvm_void_ty, llvm_ptr_ty], [IntrWriteMem]>;
|
||||
def int_ppc_dcbst : Intrinsic<[llvm_void_ty, llvm_ptr_ty], [IntrWriteMem]>;
|
||||
def int_ppc_dcbt : Intrinsic<[llvm_void_ty, llvm_ptr_ty], [IntrWriteMem]>;
|
||||
def int_ppc_dcbtst: Intrinsic<[llvm_void_ty, llvm_ptr_ty], [IntrWriteMem]>;
|
||||
def int_ppc_dcbz : Intrinsic<[llvm_void_ty, llvm_ptr_ty], [IntrWriteMem]>;
|
||||
def int_ppc_dcbzl : Intrinsic<[llvm_void_ty, llvm_ptr_ty], [IntrWriteMem]>;
|
||||
def int_ppc_dcba : Intrinsic<[llvm_void_ty], [llvm_ptr_ty], [IntrWriteMem]>;
|
||||
def int_ppc_dcbf : Intrinsic<[llvm_void_ty], [llvm_ptr_ty], [IntrWriteMem]>;
|
||||
def int_ppc_dcbi : Intrinsic<[llvm_void_ty], [llvm_ptr_ty], [IntrWriteMem]>;
|
||||
def int_ppc_dcbst : Intrinsic<[llvm_void_ty], [llvm_ptr_ty], [IntrWriteMem]>;
|
||||
def int_ppc_dcbt : Intrinsic<[llvm_void_ty], [llvm_ptr_ty], [IntrWriteMem]>;
|
||||
def int_ppc_dcbtst: Intrinsic<[llvm_void_ty], [llvm_ptr_ty], [IntrWriteMem]>;
|
||||
def int_ppc_dcbz : Intrinsic<[llvm_void_ty], [llvm_ptr_ty], [IntrWriteMem]>;
|
||||
def int_ppc_dcbzl : Intrinsic<[llvm_void_ty], [llvm_ptr_ty], [IntrWriteMem]>;
|
||||
|
||||
// sync instruction
|
||||
def int_ppc_sync : Intrinsic<[llvm_void_ty], [IntrWriteMem]>;
|
||||
def int_ppc_sync : Intrinsic<[llvm_void_ty], [], [IntrWriteMem]>;
|
||||
}
|
||||
|
||||
|
||||
let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
|
||||
/// PowerPC_Vec_Intrinsic - Base class for all altivec intrinsics.
|
||||
class PowerPC_Vec_Intrinsic<string GCCIntSuffix, list<LLVMType> types,
|
||||
class PowerPC_Vec_Intrinsic<string GCCIntSuffix, list<LLVMType> ret_types,
|
||||
list<LLVMType> param_types,
|
||||
list<IntrinsicProperty> properties>
|
||||
: GCCBuiltin<!strconcat("__builtin_altivec_", GCCIntSuffix)>,
|
||||
Intrinsic<types, properties>;
|
||||
Intrinsic<ret_types, param_types, properties>;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -48,34 +49,34 @@ let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
|
|||
/// vector and returns one. These intrinsics have no side effects.
|
||||
class PowerPC_Vec_FF_Intrinsic<string GCCIntSuffix>
|
||||
: PowerPC_Vec_Intrinsic<GCCIntSuffix,
|
||||
[llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
|
||||
[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
|
||||
|
||||
/// PowerPC_Vec_FFF_Intrinsic - A PowerPC intrinsic that takes two v4f32
|
||||
/// vectors and returns one. These intrinsics have no side effects.
|
||||
class PowerPC_Vec_FFF_Intrinsic<string GCCIntSuffix>
|
||||
: PowerPC_Vec_Intrinsic<GCCIntSuffix,
|
||||
[llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
|
||||
[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
/// PowerPC_Vec_BBB_Intrinsic - A PowerPC intrinsic that takes two v16f8
|
||||
/// vectors and returns one. These intrinsics have no side effects.
|
||||
class PowerPC_Vec_BBB_Intrinsic<string GCCIntSuffix>
|
||||
: PowerPC_Vec_Intrinsic<GCCIntSuffix,
|
||||
[llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
|
||||
[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
/// PowerPC_Vec_HHH_Intrinsic - A PowerPC intrinsic that takes two v8i16
|
||||
/// vectors and returns one. These intrinsics have no side effects.
|
||||
class PowerPC_Vec_HHH_Intrinsic<string GCCIntSuffix>
|
||||
: PowerPC_Vec_Intrinsic<GCCIntSuffix,
|
||||
[llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
/// PowerPC_Vec_WWW_Intrinsic - A PowerPC intrinsic that takes two v4i32
|
||||
/// vectors and returns one. These intrinsics have no side effects.
|
||||
class PowerPC_Vec_WWW_Intrinsic<string GCCIntSuffix>
|
||||
: PowerPC_Vec_Intrinsic<GCCIntSuffix,
|
||||
[llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
|
||||
[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
|
||||
|
@ -85,146 +86,150 @@ class PowerPC_Vec_WWW_Intrinsic<string GCCIntSuffix>
|
|||
let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
|
||||
// Data Stream Control.
|
||||
def int_ppc_altivec_dss : GCCBuiltin<"__builtin_altivec_dss">,
|
||||
Intrinsic<[llvm_void_ty, llvm_i32_ty], [IntrWriteMem]>;
|
||||
Intrinsic<[llvm_void_ty], [llvm_i32_ty], [IntrWriteMem]>;
|
||||
def int_ppc_altivec_dssall : GCCBuiltin<"__builtin_altivec_dssall">,
|
||||
Intrinsic<[llvm_void_ty], [IntrWriteMem]>;
|
||||
Intrinsic<[llvm_void_ty], [], [IntrWriteMem]>;
|
||||
def int_ppc_altivec_dst : GCCBuiltin<"__builtin_altivec_dst">,
|
||||
Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty],
|
||||
Intrinsic<[llvm_void_ty],
|
||||
[llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty],
|
||||
[IntrWriteMem]>;
|
||||
def int_ppc_altivec_dstt : GCCBuiltin<"__builtin_altivec_dstt">,
|
||||
Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty],
|
||||
Intrinsic<[llvm_void_ty],
|
||||
[llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty],
|
||||
[IntrWriteMem]>;
|
||||
def int_ppc_altivec_dstst : GCCBuiltin<"__builtin_altivec_dstst">,
|
||||
Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty],
|
||||
Intrinsic<[llvm_void_ty],
|
||||
[llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty],
|
||||
[IntrWriteMem]>;
|
||||
def int_ppc_altivec_dststt : GCCBuiltin<"__builtin_altivec_dststt">,
|
||||
Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty],
|
||||
Intrinsic<[llvm_void_ty],
|
||||
[llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty],
|
||||
[IntrWriteMem]>;
|
||||
|
||||
// VSCR access.
|
||||
def int_ppc_altivec_mfvscr : GCCBuiltin<"__builtin_altivec_mfvscr">,
|
||||
Intrinsic<[llvm_v8i16_ty], [IntrReadMem]>;
|
||||
Intrinsic<[llvm_v8i16_ty], [], [IntrReadMem]>;
|
||||
def int_ppc_altivec_mtvscr : GCCBuiltin<"__builtin_altivec_mtvscr">,
|
||||
Intrinsic<[llvm_void_ty, llvm_v4i32_ty], [IntrWriteMem]>;
|
||||
Intrinsic<[llvm_void_ty], [llvm_v4i32_ty], [IntrWriteMem]>;
|
||||
|
||||
|
||||
// Loads. These don't map directly to GCC builtins because they represent the
|
||||
// source address with a single pointer.
|
||||
def int_ppc_altivec_lvx :
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_ptr_ty], [IntrReadMem]>;
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_ptr_ty], [IntrReadMem]>;
|
||||
def int_ppc_altivec_lvxl :
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_ptr_ty], [IntrReadMem]>;
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_ptr_ty], [IntrReadMem]>;
|
||||
def int_ppc_altivec_lvebx :
|
||||
Intrinsic<[llvm_v16i8_ty, llvm_ptr_ty], [IntrReadMem]>;
|
||||
Intrinsic<[llvm_v16i8_ty], [llvm_ptr_ty], [IntrReadMem]>;
|
||||
def int_ppc_altivec_lvehx :
|
||||
Intrinsic<[llvm_v8i16_ty, llvm_ptr_ty], [IntrReadMem]>;
|
||||
Intrinsic<[llvm_v8i16_ty], [llvm_ptr_ty], [IntrReadMem]>;
|
||||
def int_ppc_altivec_lvewx :
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_ptr_ty], [IntrReadMem]>;
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_ptr_ty], [IntrReadMem]>;
|
||||
|
||||
// Stores. These don't map directly to GCC builtins because they represent the
|
||||
// source address with a single pointer.
|
||||
def int_ppc_altivec_stvx :
|
||||
Intrinsic<[llvm_void_ty, llvm_v4i32_ty, llvm_ptr_ty],
|
||||
Intrinsic<[llvm_void_ty], [llvm_v4i32_ty, llvm_ptr_ty],
|
||||
[IntrWriteMem]>;
|
||||
def int_ppc_altivec_stvxl :
|
||||
Intrinsic<[llvm_void_ty, llvm_v4i32_ty, llvm_ptr_ty],
|
||||
Intrinsic<[llvm_void_ty], [llvm_v4i32_ty, llvm_ptr_ty],
|
||||
[IntrWriteMem]>;
|
||||
def int_ppc_altivec_stvebx :
|
||||
Intrinsic<[llvm_void_ty, llvm_v16i8_ty, llvm_ptr_ty],
|
||||
Intrinsic<[llvm_void_ty], [llvm_v16i8_ty, llvm_ptr_ty],
|
||||
[IntrWriteMem]>;
|
||||
def int_ppc_altivec_stvehx :
|
||||
Intrinsic<[llvm_void_ty, llvm_v8i16_ty, llvm_ptr_ty],
|
||||
Intrinsic<[llvm_void_ty], [llvm_v8i16_ty, llvm_ptr_ty],
|
||||
[IntrWriteMem]>;
|
||||
def int_ppc_altivec_stvewx :
|
||||
Intrinsic<[llvm_void_ty, llvm_v4i32_ty, llvm_ptr_ty],
|
||||
Intrinsic<[llvm_void_ty], [llvm_v4i32_ty, llvm_ptr_ty],
|
||||
[IntrWriteMem]>;
|
||||
|
||||
// Comparisons setting a vector.
|
||||
def int_ppc_altivec_vcmpbfp : GCCBuiltin<"__builtin_altivec_vcmpbfp">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vcmpeqfp : GCCBuiltin<"__builtin_altivec_vcmpeqfp">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vcmpgefp : GCCBuiltin<"__builtin_altivec_vcmpgefp">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vcmpgtfp : GCCBuiltin<"__builtin_altivec_vcmpgtfp">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
def int_ppc_altivec_vcmpequw : GCCBuiltin<"__builtin_altivec_vcmpequw">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vcmpgtsw : GCCBuiltin<"__builtin_altivec_vcmpgtsw">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vcmpgtuw : GCCBuiltin<"__builtin_altivec_vcmpgtuw">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
def int_ppc_altivec_vcmpequh : GCCBuiltin<"__builtin_altivec_vcmpequh">,
|
||||
Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vcmpgtsh : GCCBuiltin<"__builtin_altivec_vcmpgtsh">,
|
||||
Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vcmpgtuh : GCCBuiltin<"__builtin_altivec_vcmpgtuh">,
|
||||
Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
def int_ppc_altivec_vcmpequb : GCCBuiltin<"__builtin_altivec_vcmpequb">,
|
||||
Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
|
||||
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vcmpgtsb : GCCBuiltin<"__builtin_altivec_vcmpgtsb">,
|
||||
Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
|
||||
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vcmpgtub : GCCBuiltin<"__builtin_altivec_vcmpgtub">,
|
||||
Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
|
||||
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
// Predicate Comparisons. The first operand specifies interpretation of CR6.
|
||||
def int_ppc_altivec_vcmpbfp_p : GCCBuiltin<"__builtin_altivec_vcmpbfp_p">,
|
||||
Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_v4f32_ty,llvm_v4f32_ty],
|
||||
Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4f32_ty,llvm_v4f32_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vcmpeqfp_p : GCCBuiltin<"__builtin_altivec_vcmpeqfp_p">,
|
||||
Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_v4f32_ty,llvm_v4f32_ty],
|
||||
Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4f32_ty,llvm_v4f32_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vcmpgefp_p : GCCBuiltin<"__builtin_altivec_vcmpgefp_p">,
|
||||
Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_v4f32_ty,llvm_v4f32_ty],
|
||||
Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4f32_ty,llvm_v4f32_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vcmpgtfp_p : GCCBuiltin<"__builtin_altivec_vcmpgtfp_p">,
|
||||
Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_v4f32_ty,llvm_v4f32_ty],
|
||||
Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4f32_ty,llvm_v4f32_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
def int_ppc_altivec_vcmpequw_p : GCCBuiltin<"__builtin_altivec_vcmpequw_p">,
|
||||
Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_v4i32_ty,llvm_v4i32_ty],
|
||||
Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4i32_ty,llvm_v4i32_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vcmpgtsw_p : GCCBuiltin<"__builtin_altivec_vcmpgtsw_p">,
|
||||
Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_v4i32_ty,llvm_v4i32_ty],
|
||||
Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4i32_ty,llvm_v4i32_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vcmpgtuw_p : GCCBuiltin<"__builtin_altivec_vcmpgtuw_p">,
|
||||
Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_v4i32_ty,llvm_v4i32_ty],
|
||||
Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4i32_ty,llvm_v4i32_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
def int_ppc_altivec_vcmpequh_p : GCCBuiltin<"__builtin_altivec_vcmpequh_p">,
|
||||
Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_v8i16_ty,llvm_v8i16_ty],
|
||||
Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v8i16_ty,llvm_v8i16_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vcmpgtsh_p : GCCBuiltin<"__builtin_altivec_vcmpgtsh_p">,
|
||||
Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_v8i16_ty,llvm_v8i16_ty],
|
||||
Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v8i16_ty,llvm_v8i16_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vcmpgtuh_p : GCCBuiltin<"__builtin_altivec_vcmpgtuh_p">,
|
||||
Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_v8i16_ty,llvm_v8i16_ty],
|
||||
Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v8i16_ty,llvm_v8i16_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
def int_ppc_altivec_vcmpequb_p : GCCBuiltin<"__builtin_altivec_vcmpequb_p">,
|
||||
Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_v16i8_ty,llvm_v16i8_ty],
|
||||
Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v16i8_ty,llvm_v16i8_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vcmpgtsb_p : GCCBuiltin<"__builtin_altivec_vcmpgtsb_p">,
|
||||
Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_v16i8_ty,llvm_v16i8_ty],
|
||||
Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v16i8_ty,llvm_v16i8_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vcmpgtub_p : GCCBuiltin<"__builtin_altivec_vcmpgtub_p">,
|
||||
Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_v16i8_ty,llvm_v16i8_ty],
|
||||
Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v16i8_ty,llvm_v16i8_ty],
|
||||
[IntrNoMem]>;
|
||||
}
|
||||
|
||||
|
@ -275,150 +280,150 @@ def int_ppc_altivec_vsubcuw : PowerPC_Vec_WWW_Intrinsic<"vsubcuw">;
|
|||
let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
|
||||
// Saturating multiply-adds.
|
||||
def int_ppc_altivec_vmhaddshs : GCCBuiltin<"__builtin_altivec_vmhaddshs">,
|
||||
Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty,
|
||||
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
|
||||
llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
|
||||
def int_ppc_altivec_vmhraddshs : GCCBuiltin<"__builtin_altivec_vmhraddshs">,
|
||||
Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty,
|
||||
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
|
||||
llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
|
||||
|
||||
def int_ppc_altivec_vmaddfp : GCCBuiltin<"__builtin_altivec_vmaddfp">,
|
||||
Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty,
|
||||
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
|
||||
llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
|
||||
def int_ppc_altivec_vnmsubfp : GCCBuiltin<"__builtin_altivec_vnmsubfp">,
|
||||
Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty,
|
||||
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
|
||||
llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
|
||||
|
||||
// Vector Multiply Sum Intructions.
|
||||
def int_ppc_altivec_vmsummbm : GCCBuiltin<"__builtin_altivec_vmsummbm">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v16i8_ty, llvm_v16i8_ty,
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty, llvm_v16i8_ty,
|
||||
llvm_v4i32_ty], [IntrNoMem]>;
|
||||
def int_ppc_altivec_vmsumshm : GCCBuiltin<"__builtin_altivec_vmsumshm">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty,
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
|
||||
llvm_v4i32_ty], [IntrNoMem]>;
|
||||
def int_ppc_altivec_vmsumshs : GCCBuiltin<"__builtin_altivec_vmsumshs">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty,
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
|
||||
llvm_v4i32_ty], [IntrNoMem]>;
|
||||
def int_ppc_altivec_vmsumubm : GCCBuiltin<"__builtin_altivec_vmsumubm">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v16i8_ty, llvm_v16i8_ty,
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty, llvm_v16i8_ty,
|
||||
llvm_v4i32_ty], [IntrNoMem]>;
|
||||
def int_ppc_altivec_vmsumuhm : GCCBuiltin<"__builtin_altivec_vmsumuhm">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty,
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
|
||||
llvm_v4i32_ty], [IntrNoMem]>;
|
||||
def int_ppc_altivec_vmsumuhs : GCCBuiltin<"__builtin_altivec_vmsumuhs">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty,
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
|
||||
llvm_v4i32_ty], [IntrNoMem]>;
|
||||
|
||||
// Vector Multiply Intructions.
|
||||
def int_ppc_altivec_vmulesb : GCCBuiltin<"__builtin_altivec_vmulesb">,
|
||||
Intrinsic<[llvm_v8i16_ty, llvm_v16i8_ty, llvm_v16i8_ty],
|
||||
Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vmulesh : GCCBuiltin<"__builtin_altivec_vmulesh">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vmuleub : GCCBuiltin<"__builtin_altivec_vmuleub">,
|
||||
Intrinsic<[llvm_v8i16_ty, llvm_v16i8_ty, llvm_v16i8_ty],
|
||||
Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vmuleuh : GCCBuiltin<"__builtin_altivec_vmuleuh">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
def int_ppc_altivec_vmulosb : GCCBuiltin<"__builtin_altivec_vmulosb">,
|
||||
Intrinsic<[llvm_v8i16_ty, llvm_v16i8_ty, llvm_v16i8_ty],
|
||||
Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vmulosh : GCCBuiltin<"__builtin_altivec_vmulosh">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vmuloub : GCCBuiltin<"__builtin_altivec_vmuloub">,
|
||||
Intrinsic<[llvm_v8i16_ty, llvm_v16i8_ty, llvm_v16i8_ty],
|
||||
Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vmulouh : GCCBuiltin<"__builtin_altivec_vmulouh">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
// Vector Sum Intructions.
|
||||
def int_ppc_altivec_vsumsws : GCCBuiltin<"__builtin_altivec_vsumsws">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vsum2sws : GCCBuiltin<"__builtin_altivec_vsum2sws">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vsum4sbs : GCCBuiltin<"__builtin_altivec_vsum4sbs">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v16i8_ty, llvm_v4i32_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty, llvm_v4i32_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vsum4shs : GCCBuiltin<"__builtin_altivec_vsum4shs">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v4i32_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v4i32_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vsum4ubs : GCCBuiltin<"__builtin_altivec_vsum4ubs">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v16i8_ty, llvm_v4i32_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty, llvm_v4i32_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
// Other multiplies.
|
||||
def int_ppc_altivec_vmladduhm : GCCBuiltin<"__builtin_altivec_vmladduhm">,
|
||||
Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty,
|
||||
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
|
||||
llvm_v8i16_ty], [IntrNoMem]>;
|
||||
|
||||
// Packs.
|
||||
def int_ppc_altivec_vpkpx : GCCBuiltin<"__builtin_altivec_vpkpx">,
|
||||
Intrinsic<[llvm_v8i16_ty, llvm_v4i32_ty, llvm_v4i32_ty],
|
||||
Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vpkshss : GCCBuiltin<"__builtin_altivec_vpkshss">,
|
||||
Intrinsic<[llvm_v16i8_ty, llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vpkshus : GCCBuiltin<"__builtin_altivec_vpkshus">,
|
||||
Intrinsic<[llvm_v16i8_ty, llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vpkswss : GCCBuiltin<"__builtin_altivec_vpkswss">,
|
||||
Intrinsic<[llvm_v16i8_ty, llvm_v4i32_ty, llvm_v4i32_ty],
|
||||
Intrinsic<[llvm_v16i8_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vpkswus : GCCBuiltin<"__builtin_altivec_vpkswus">,
|
||||
Intrinsic<[llvm_v8i16_ty, llvm_v4i32_ty, llvm_v4i32_ty],
|
||||
Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
|
||||
[IntrNoMem]>;
|
||||
// vpkuhum is lowered to a shuffle.
|
||||
def int_ppc_altivec_vpkuhus : GCCBuiltin<"__builtin_altivec_vpkuhus">,
|
||||
Intrinsic<[llvm_v16i8_ty, llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
|
||||
[IntrNoMem]>;
|
||||
// vpkuwum is lowered to a shuffle.
|
||||
def int_ppc_altivec_vpkuwus : GCCBuiltin<"__builtin_altivec_vpkuwus">,
|
||||
Intrinsic<[llvm_v8i16_ty, llvm_v4i32_ty, llvm_v4i32_ty],
|
||||
Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
// Unpacks.
|
||||
def int_ppc_altivec_vupkhpx : GCCBuiltin<"__builtin_altivec_vupkhpx">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty], [IntrNoMem]>;
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
|
||||
def int_ppc_altivec_vupkhsb : GCCBuiltin<"__builtin_altivec_vupkhsb">,
|
||||
Intrinsic<[llvm_v8i16_ty, llvm_v16i8_ty], [IntrNoMem]>;
|
||||
Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty], [IntrNoMem]>;
|
||||
def int_ppc_altivec_vupkhsh : GCCBuiltin<"__builtin_altivec_vupkhsh">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty], [IntrNoMem]>;
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
|
||||
def int_ppc_altivec_vupklpx : GCCBuiltin<"__builtin_altivec_vupklpx">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty], [IntrNoMem]>;
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
|
||||
def int_ppc_altivec_vupklsb : GCCBuiltin<"__builtin_altivec_vupklsb">,
|
||||
Intrinsic<[llvm_v8i16_ty, llvm_v16i8_ty], [IntrNoMem]>;
|
||||
Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty], [IntrNoMem]>;
|
||||
def int_ppc_altivec_vupklsh : GCCBuiltin<"__builtin_altivec_vupklsh">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty], [IntrNoMem]>;
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
|
||||
|
||||
|
||||
// FP <-> integer conversion.
|
||||
def int_ppc_altivec_vcfsx : GCCBuiltin<"__builtin_altivec_vcfsx">,
|
||||
Intrinsic<[llvm_v4f32_ty, llvm_v4i32_ty, llvm_i32_ty],
|
||||
Intrinsic<[llvm_v4f32_ty], [llvm_v4i32_ty, llvm_i32_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vcfux : GCCBuiltin<"__builtin_altivec_vcfux">,
|
||||
Intrinsic<[llvm_v4f32_ty, llvm_v4i32_ty, llvm_i32_ty],
|
||||
Intrinsic<[llvm_v4f32_ty], [llvm_v4i32_ty, llvm_i32_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vctsxs : GCCBuiltin<"__builtin_altivec_vctsxs">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v4f32_ty, llvm_i32_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_i32_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_ppc_altivec_vctuxs : GCCBuiltin<"__builtin_altivec_vctuxs">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v4f32_ty, llvm_i32_ty],
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_i32_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
def int_ppc_altivec_vrfim : GCCBuiltin<"__builtin_altivec_vrfim">,
|
||||
Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
|
||||
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
|
||||
def int_ppc_altivec_vrfin : GCCBuiltin<"__builtin_altivec_vrfin">,
|
||||
Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
|
||||
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
|
||||
def int_ppc_altivec_vrfip : GCCBuiltin<"__builtin_altivec_vrfip">,
|
||||
Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
|
||||
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
|
||||
def int_ppc_altivec_vrfiz : GCCBuiltin<"__builtin_altivec_vrfiz">,
|
||||
Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
|
||||
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
|
||||
}
|
||||
|
||||
def int_ppc_altivec_vsl : PowerPC_Vec_WWW_Intrinsic<"vsl">;
|
||||
|
@ -447,15 +452,15 @@ def int_ppc_altivec_vrlw : PowerPC_Vec_WWW_Intrinsic<"vrlw">;
|
|||
let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
|
||||
// Miscellaneous.
|
||||
def int_ppc_altivec_lvsl :
|
||||
Intrinsic<[llvm_v16i8_ty, llvm_ptr_ty], [IntrNoMem]>;
|
||||
Intrinsic<[llvm_v16i8_ty], [llvm_ptr_ty], [IntrNoMem]>;
|
||||
def int_ppc_altivec_lvsr :
|
||||
Intrinsic<[llvm_v16i8_ty, llvm_ptr_ty], [IntrNoMem]>;
|
||||
Intrinsic<[llvm_v16i8_ty], [llvm_ptr_ty], [IntrNoMem]>;
|
||||
|
||||
def int_ppc_altivec_vperm : GCCBuiltin<"__builtin_altivec_vperm_4si">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty,
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty,
|
||||
llvm_v4i32_ty, llvm_v16i8_ty], [IntrNoMem]>;
|
||||
def int_ppc_altivec_vsel : GCCBuiltin<"__builtin_altivec_vsel_4si">,
|
||||
Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty,
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty,
|
||||
llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -269,7 +269,7 @@ namespace {
|
|||
bool PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty,
|
||||
int VT, unsigned ArgNo, std::string &Suffix);
|
||||
void VerifyIntrinsicPrototype(Intrinsic::ID ID, Function *F,
|
||||
unsigned Count, ...);
|
||||
unsigned RetNum, unsigned ParamNum, ...);
|
||||
void VerifyAttrs(Attributes Attrs, const Type *Ty,
|
||||
bool isReturnValue, const Value *V);
|
||||
void VerifyFunctionAttrs(const FunctionType *FT, const AttrListPtr &Attrs,
|
||||
|
@ -1507,11 +1507,11 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty,
|
|||
/// VerifyIntrinsicPrototype - TableGen emits calls to this function into
|
||||
/// Intrinsics.gen. This implements a little state machine that verifies the
|
||||
/// prototype of intrinsics.
|
||||
void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID,
|
||||
Function *F,
|
||||
unsigned Count, ...) {
|
||||
void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID, Function *F,
|
||||
unsigned RetNum,
|
||||
unsigned ParamNum, ...) {
|
||||
va_list VA;
|
||||
va_start(VA, Count);
|
||||
va_start(VA, ParamNum);
|
||||
const FunctionType *FTy = F->getFunctionType();
|
||||
|
||||
// For overloaded intrinsics, the Suffix of the function name must match the
|
||||
|
@ -1519,13 +1519,31 @@ void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID,
|
|||
// suffix, to be checked at the end.
|
||||
std::string Suffix;
|
||||
|
||||
if (FTy->getNumParams() + FTy->isVarArg() != Count - 1) {
|
||||
if (FTy->getNumParams() + FTy->isVarArg() != ParamNum) {
|
||||
CheckFailed("Intrinsic prototype has incorrect number of arguments!", F);
|
||||
return;
|
||||
}
|
||||
|
||||
// Note that "arg#0" is the return type.
|
||||
for (unsigned ArgNo = 0; ArgNo < Count; ++ArgNo) {
|
||||
const Type *Ty = FTy->getReturnType();
|
||||
const StructType *ST = dyn_cast<StructType>(Ty);
|
||||
|
||||
// Verify the return types.
|
||||
if (ST && ST->getNumElements() != RetNum) {
|
||||
CheckFailed("Intrinsic prototype has incorrect number of return types!", F);
|
||||
return;
|
||||
}
|
||||
|
||||
for (unsigned ArgNo = 0; ArgNo < RetNum; ++ArgNo) {
|
||||
int VT = va_arg(VA, int); // An MVT::SimpleValueType when non-negative.
|
||||
|
||||
if (ST) Ty = ST->getElementType(ArgNo);
|
||||
|
||||
if (!PerformTypeCheck(ID, F, Ty, VT, ArgNo, Suffix))
|
||||
break;
|
||||
}
|
||||
|
||||
// Verify the parameter types.
|
||||
for (unsigned ArgNo = 0; ArgNo < ParamNum; ++ArgNo) {
|
||||
int VT = va_arg(VA, int); // An MVT::SimpleValueType when non-negative.
|
||||
|
||||
if (VT == MVT::isVoid && ArgNo > 0) {
|
||||
|
@ -1534,10 +1552,7 @@ void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID,
|
|||
break;
|
||||
}
|
||||
|
||||
const Type *Ty = (ArgNo == 0) ?
|
||||
FTy->getReturnType() : FTy->getParamType(ArgNo - 1);
|
||||
|
||||
if (!PerformTypeCheck(ID, F, Ty, VT, ArgNo, Suffix))
|
||||
if (!PerformTypeCheck(ID, F, FTy->getParamType(ArgNo), VT, ArgNo, Suffix))
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -471,7 +471,8 @@ bool TreePatternNode::UpdateNodeType(const std::vector<unsigned char> &ExtVTs,
|
|||
}
|
||||
|
||||
if (getExtTypeNum(0) == MVT::iPTR || getExtTypeNum(0) == MVT::iPTRAny) {
|
||||
if (ExtVTs[0] == MVT::iPTR || ExtVTs[0] == MVT::iPTRAny || ExtVTs[0] == EMVT::isInt)
|
||||
if (ExtVTs[0] == MVT::iPTR || ExtVTs[0] == MVT::iPTRAny ||
|
||||
ExtVTs[0] == EMVT::isInt)
|
||||
return false;
|
||||
if (EMVT::isExtIntegerInVTs(ExtVTs)) {
|
||||
std::vector<unsigned char> FVTs = FilterEVTs(ExtVTs, isInteger);
|
||||
|
@ -885,18 +886,22 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
|
|||
bool MadeChange = false;
|
||||
|
||||
// Apply the result type to the node.
|
||||
MadeChange = UpdateNodeType(Int->ArgVTs[0], TP);
|
||||
unsigned NumRetVTs = Int->IS.RetVTs.size();
|
||||
unsigned NumParamVTs = Int->IS.ParamVTs.size();
|
||||
|
||||
if (getNumChildren() != Int->ArgVTs.size())
|
||||
for (unsigned i = 0, e = NumRetVTs; i != e; ++i)
|
||||
MadeChange |= UpdateNodeType(Int->IS.RetVTs[i], TP);
|
||||
|
||||
if (getNumChildren() != NumParamVTs + NumRetVTs)
|
||||
TP.error("Intrinsic '" + Int->Name + "' expects " +
|
||||
utostr(Int->ArgVTs.size()-1) + " operands, not " +
|
||||
utostr(getNumChildren()-1) + " operands!");
|
||||
utostr(NumParamVTs + NumRetVTs - 1) + " operands, not " +
|
||||
utostr(getNumChildren() - 1) + " operands!");
|
||||
|
||||
// Apply type info to the intrinsic ID.
|
||||
MadeChange |= getChild(0)->UpdateNodeType(MVT::iPTR, TP);
|
||||
|
||||
for (unsigned i = 1, e = getNumChildren(); i != e; ++i) {
|
||||
MVT::SimpleValueType OpVT = Int->ArgVTs[i];
|
||||
for (unsigned i = NumRetVTs, e = getNumChildren(); i != e; ++i) {
|
||||
MVT::SimpleValueType OpVT = Int->IS.ParamVTs[i - NumRetVTs];
|
||||
MadeChange |= getChild(i)->UpdateNodeType(OpVT, TP);
|
||||
MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
|
||||
}
|
||||
|
@ -1232,7 +1237,7 @@ TreePatternNode *TreePattern::ParseTreePattern(DagInit *Dag) {
|
|||
|
||||
// If this intrinsic returns void, it must have side-effects and thus a
|
||||
// chain.
|
||||
if (Int.ArgVTs[0] == MVT::isVoid) {
|
||||
if (Int.IS.RetVTs[0] == MVT::isVoid) {
|
||||
Operator = getDAGPatterns().get_intrinsic_void_sdnode();
|
||||
} else if (Int.ModRef != CodeGenIntrinsic::NoMem) {
|
||||
// Has side-effects, requires chain.
|
||||
|
|
|
@ -30,16 +30,34 @@ namespace llvm {
|
|||
std::string GCCBuiltinName;// Name of the corresponding GCC builtin, or "".
|
||||
std::string TargetPrefix; // Target prefix, e.g. "ppc" for t-s intrinsics.
|
||||
|
||||
/// ArgVTs - The MVT::SimpleValueType for each argument type. Note that
|
||||
/// this list is only populated when in the context of a target .td file.
|
||||
/// When building Intrinsics.td, this isn't available, because we don't know
|
||||
/// the target pointer size.
|
||||
std::vector<MVT::SimpleValueType> ArgVTs;
|
||||
/// IntrinsicSignature - This structure holds the return values and
|
||||
/// parameter values of an intrinsic. If the number of return values is > 1,
|
||||
/// then the intrinsic implicitly returns a first-class aggregate. The
|
||||
/// numbering of the types starts at 0 with the first return value and
|
||||
/// continues from there throug the parameter list. This is useful for
|
||||
/// "matching" types.
|
||||
struct IntrinsicSignature {
|
||||
/// RetVTs - The MVT::SimpleValueType for each return type. Note that this
|
||||
/// list is only populated when in the context of a target .td file. When
|
||||
/// building Intrinsics.td, this isn't available, because we don't know
|
||||
/// the target pointer size.
|
||||
std::vector<MVT::SimpleValueType> RetVTs;
|
||||
|
||||
/// RetTypeDefs - The records for each return type.
|
||||
std::vector<Record*> RetTypeDefs;
|
||||
|
||||
/// ParamVTs - The MVT::SimpleValueType for each parameter type. Note that
|
||||
/// this list is only populated when in the context of a target .td file.
|
||||
/// When building Intrinsics.td, this isn't available, because we don't
|
||||
/// know the target pointer size.
|
||||
std::vector<MVT::SimpleValueType> ParamVTs;
|
||||
|
||||
/// ParamTypeDefs - The records for each parameter type.
|
||||
std::vector<Record*> ParamTypeDefs;
|
||||
};
|
||||
|
||||
IntrinsicSignature IS;
|
||||
|
||||
/// ArgTypeDefs - The records for each argument type.
|
||||
///
|
||||
std::vector<Record*> ArgTypeDefs;
|
||||
|
||||
// Memory mod/ref behavior of this intrinsic.
|
||||
enum {
|
||||
NoMem, ReadArgMem, ReadMem, WriteArgMem, WriteMem
|
||||
|
|
|
@ -438,25 +438,27 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
|
|||
isCommutative = false;
|
||||
|
||||
if (DefName.size() <= 4 ||
|
||||
std::string(DefName.begin(), DefName.begin()+4) != "int_")
|
||||
std::string(DefName.begin(), DefName.begin() + 4) != "int_")
|
||||
throw "Intrinsic '" + DefName + "' does not start with 'int_'!";
|
||||
|
||||
EnumName = std::string(DefName.begin()+4, DefName.end());
|
||||
|
||||
if (R->getValue("GCCBuiltinName")) // Ignore a missing GCCBuiltinName field.
|
||||
GCCBuiltinName = R->getValueAsString("GCCBuiltinName");
|
||||
TargetPrefix = R->getValueAsString("TargetPrefix");
|
||||
|
||||
TargetPrefix = R->getValueAsString("TargetPrefix");
|
||||
Name = R->getValueAsString("LLVMName");
|
||||
|
||||
if (Name == "") {
|
||||
// If an explicit name isn't specified, derive one from the DefName.
|
||||
Name = "llvm.";
|
||||
|
||||
for (unsigned i = 0, e = EnumName.size(); i != e; ++i)
|
||||
if (EnumName[i] == '_')
|
||||
Name += '.';
|
||||
else
|
||||
Name += EnumName[i];
|
||||
Name += (EnumName[i] == '_') ? '.' : EnumName[i];
|
||||
} else {
|
||||
// Verify it starts with "llvm.".
|
||||
if (Name.size() <= 5 ||
|
||||
std::string(Name.begin(), Name.begin()+5) != "llvm.")
|
||||
std::string(Name.begin(), Name.begin() + 5) != "llvm.")
|
||||
throw "Intrinsic '" + DefName + "'s name does not start with 'llvm.'!";
|
||||
}
|
||||
|
||||
|
@ -464,26 +466,37 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
|
|||
// "llvm.<targetprefix>.".
|
||||
if (!TargetPrefix.empty()) {
|
||||
if (Name.size() < 6+TargetPrefix.size() ||
|
||||
std::string(Name.begin()+5, Name.begin()+6+TargetPrefix.size())
|
||||
!= (TargetPrefix+"."))
|
||||
throw "Intrinsic '" + DefName + "' does not start with 'llvm." +
|
||||
std::string(Name.begin() + 5, Name.begin() + 6 + TargetPrefix.size())
|
||||
!= (TargetPrefix + "."))
|
||||
throw "Intrinsic '" + DefName + "' does not start with 'llvm." +
|
||||
TargetPrefix + ".'!";
|
||||
}
|
||||
|
||||
// Parse the list of argument types.
|
||||
ListInit *TypeList = R->getValueAsListInit("Types");
|
||||
// Parse the list of return types.
|
||||
ListInit *TypeList = R->getValueAsListInit("RetTypes");
|
||||
for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) {
|
||||
Record *TyEl = TypeList->getElementAsRecord(i);
|
||||
assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
|
||||
MVT::SimpleValueType VT = getValueType(TyEl->getValueAsDef("VT"));
|
||||
isOverloaded |= VT == MVT::iAny || VT == MVT::fAny || VT == MVT::iPTRAny;
|
||||
ArgVTs.push_back(VT);
|
||||
ArgTypeDefs.push_back(TyEl);
|
||||
IS.RetVTs.push_back(VT);
|
||||
IS.RetTypeDefs.push_back(TyEl);
|
||||
}
|
||||
if (ArgVTs.size() == 0)
|
||||
|
||||
if (IS.RetVTs.size() == 0)
|
||||
throw "Intrinsic '"+DefName+"' needs at least a type for the ret value!";
|
||||
|
||||
|
||||
// Parse the list of parameter types.
|
||||
TypeList = R->getValueAsListInit("ParamTypes");
|
||||
for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) {
|
||||
Record *TyEl = TypeList->getElementAsRecord(i);
|
||||
assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
|
||||
MVT::SimpleValueType VT = getValueType(TyEl->getValueAsDef("VT"));
|
||||
isOverloaded |= VT == MVT::iAny || VT == MVT::fAny || VT == MVT::iPTRAny;
|
||||
IS.ParamVTs.push_back(VT);
|
||||
IS.ParamTypeDefs.push_back(TyEl);
|
||||
}
|
||||
|
||||
// Parse the intrinsic properties.
|
||||
ListInit *PropList = R->getValueAsListInit("Properties");
|
||||
for (unsigned i = 0, e = PropList->getSize(); i != e; ++i) {
|
||||
|
|
|
@ -138,7 +138,27 @@ static void EmitTypeForValueType(std::ostream &OS, MVT::SimpleValueType VT) {
|
|||
}
|
||||
}
|
||||
|
||||
static void EmitTypeGenerate(std::ostream &OS, Record *ArgType,
|
||||
static void EmitTypeGenerate(std::ostream &OS, const Record *ArgType,
|
||||
unsigned &ArgNo);
|
||||
|
||||
static void EmitTypeGenerate(std::ostream &OS,
|
||||
const std::vector<Record*> &ArgTypes,
|
||||
unsigned &ArgNo) {
|
||||
if (ArgTypes.size() == 1) {
|
||||
EmitTypeGenerate(OS, ArgTypes.front(), ArgNo);
|
||||
return;
|
||||
}
|
||||
|
||||
OS << "StructType::get(";
|
||||
|
||||
for (std::vector<Record*>::const_iterator
|
||||
I = ArgTypes.begin(), E = ArgTypes.end(); I != E; ++I)
|
||||
EmitTypeGenerate(OS, *I, ArgNo);
|
||||
|
||||
OS << ", NULL)";
|
||||
}
|
||||
|
||||
static void EmitTypeGenerate(std::ostream &OS, const Record *ArgType,
|
||||
unsigned &ArgNo) {
|
||||
MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT"));
|
||||
|
||||
|
@ -184,17 +204,37 @@ static void EmitTypeGenerate(std::ostream &OS, Record *ArgType,
|
|||
/// RecordListComparator - Provide a determinstic comparator for lists of
|
||||
/// records.
|
||||
namespace {
|
||||
typedef std::pair<std::vector<Record*>, std::vector<Record*> > RecPair;
|
||||
struct RecordListComparator {
|
||||
bool operator()(const std::vector<Record*> &LHS,
|
||||
const std::vector<Record*> &RHS) const {
|
||||
bool operator()(const RecPair &LHS,
|
||||
const RecPair &RHS) const {
|
||||
unsigned i = 0;
|
||||
const std::vector<Record*> *LHSVec = &LHS.first;
|
||||
const std::vector<Record*> *RHSVec = &RHS.first;
|
||||
unsigned RHSSize = RHSVec->size();
|
||||
unsigned LHSSize = LHSVec->size();
|
||||
|
||||
do {
|
||||
if (i == RHS.size()) return false; // RHS is shorter than LHS.
|
||||
if (LHS[i] != RHS[i])
|
||||
return LHS[i]->getName() < RHS[i]->getName();
|
||||
} while (++i != LHS.size());
|
||||
|
||||
return i != RHS.size();
|
||||
if (i == RHSSize) return false; // RHS is shorter than LHS.
|
||||
if ((*LHSVec)[i] != (*RHSVec)[i])
|
||||
return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName();
|
||||
} while (++i != LHSSize);
|
||||
|
||||
if (i != RHSSize) return false;
|
||||
|
||||
i = 0;
|
||||
LHSVec = &LHS.second;
|
||||
RHSVec = &RHS.second;
|
||||
RHSSize = RHSVec->size();
|
||||
LHSSize = LHSVec->size();
|
||||
|
||||
for (i = 0; i != LHSSize; ++i) {
|
||||
if (i == RHSSize) return false; // RHS is shorter than LHS.
|
||||
if ((*LHSVec)[i] != (*RHSVec)[i])
|
||||
return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName();
|
||||
}
|
||||
|
||||
return i != RHSSize;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -209,26 +249,33 @@ void IntrinsicEmitter::EmitVerifier(const std::vector<CodeGenIntrinsic> &Ints,
|
|||
// This checking can emit a lot of very common code. To reduce the amount of
|
||||
// code that we emit, batch up cases that have identical types. This avoids
|
||||
// problems where GCC can run out of memory compiling Verifier.cpp.
|
||||
typedef std::map<std::vector<Record*>, std::vector<unsigned>,
|
||||
RecordListComparator> MapTy;
|
||||
typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy;
|
||||
MapTy UniqueArgInfos;
|
||||
|
||||
// Compute the unique argument type info.
|
||||
for (unsigned i = 0, e = Ints.size(); i != e; ++i)
|
||||
UniqueArgInfos[Ints[i].ArgTypeDefs].push_back(i);
|
||||
UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs,
|
||||
Ints[i].IS.ParamTypeDefs)].push_back(i);
|
||||
|
||||
// Loop through the array, emitting one comparison for each batch.
|
||||
for (MapTy::iterator I = UniqueArgInfos.begin(),
|
||||
E = UniqueArgInfos.end(); I != E; ++I) {
|
||||
for (unsigned i = 0, e = I->second.size(); i != e; ++i) {
|
||||
for (unsigned i = 0, e = I->second.size(); i != e; ++i)
|
||||
OS << " case Intrinsic::" << Ints[I->second[i]].EnumName << ":\t\t// "
|
||||
<< Ints[I->second[i]].Name << "\n";
|
||||
}
|
||||
|
||||
const std::vector<Record*> &ArgTypes = I->first;
|
||||
OS << " VerifyIntrinsicPrototype(ID, IF, " << ArgTypes.size() << ", ";
|
||||
for (unsigned j = 0; j != ArgTypes.size(); ++j) {
|
||||
Record *ArgType = ArgTypes[j];
|
||||
const RecPair &ArgTypes = I->first;
|
||||
const std::vector<Record*> &RetTys = ArgTypes.first;
|
||||
const std::vector<Record*> &ParamTys = ArgTypes.second;
|
||||
|
||||
OS << " VerifyIntrinsicPrototype(ID, IF, " << RetTys.size() << ", "
|
||||
<< ParamTys.size();
|
||||
|
||||
// Emit return types.
|
||||
for (unsigned j = 0, je = RetTys.size(); j != je; ++j) {
|
||||
Record *ArgType = RetTys[j];
|
||||
OS << ", ";
|
||||
|
||||
if (ArgType->isSubClassOf("LLVMMatchType")) {
|
||||
unsigned Number = ArgType->getValueAsInt("Number");
|
||||
assert(Number < j && "Invalid matching number!");
|
||||
|
@ -236,11 +283,28 @@ void IntrinsicEmitter::EmitVerifier(const std::vector<CodeGenIntrinsic> &Ints,
|
|||
} else {
|
||||
MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT"));
|
||||
OS << getEnumName(VT);
|
||||
if (VT == MVT::isVoid && j != 0 && j != ArgTypes.size()-1)
|
||||
|
||||
if (VT == MVT::isVoid && j != 0 && j != je - 1)
|
||||
throw "Var arg type not last argument";
|
||||
}
|
||||
}
|
||||
|
||||
// Emit the parameter types.
|
||||
for (unsigned j = 0, je = ParamTys.size(); j != je; ++j) {
|
||||
Record *ArgType = ParamTys[j];
|
||||
OS << ", ";
|
||||
|
||||
if (ArgType->isSubClassOf("LLVMMatchType")) {
|
||||
unsigned Number = ArgType->getValueAsInt("Number");
|
||||
assert(Number < j + RetTys.size() && "Invalid matching number!");
|
||||
OS << "~" << Number;
|
||||
} else {
|
||||
MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT"));
|
||||
OS << getEnumName(VT);
|
||||
|
||||
if (VT == MVT::isVoid && j != 0 && j != je - 1)
|
||||
throw "Var arg type not last argument";
|
||||
}
|
||||
if (j != ArgTypes.size()-1)
|
||||
OS << ", ";
|
||||
}
|
||||
|
||||
OS << ");\n";
|
||||
|
@ -259,43 +323,47 @@ void IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints,
|
|||
|
||||
// Similar to GET_INTRINSIC_VERIFIER, batch up cases that have identical
|
||||
// types.
|
||||
typedef std::map<std::vector<Record*>, std::vector<unsigned>,
|
||||
RecordListComparator> MapTy;
|
||||
typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy;
|
||||
MapTy UniqueArgInfos;
|
||||
|
||||
// Compute the unique argument type info.
|
||||
for (unsigned i = 0, e = Ints.size(); i != e; ++i)
|
||||
UniqueArgInfos[Ints[i].ArgTypeDefs].push_back(i);
|
||||
UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs,
|
||||
Ints[i].IS.ParamTypeDefs)].push_back(i);
|
||||
|
||||
// Loop through the array, emitting one generator for each batch.
|
||||
for (MapTy::iterator I = UniqueArgInfos.begin(),
|
||||
E = UniqueArgInfos.end(); I != E; ++I) {
|
||||
for (unsigned i = 0, e = I->second.size(); i != e; ++i) {
|
||||
for (unsigned i = 0, e = I->second.size(); i != e; ++i)
|
||||
OS << " case Intrinsic::" << Ints[I->second[i]].EnumName << ":\t\t// "
|
||||
<< Ints[I->second[i]].Name << "\n";
|
||||
}
|
||||
|
||||
const std::vector<Record*> &ArgTypes = I->first;
|
||||
unsigned N = ArgTypes.size();
|
||||
const RecPair &ArgTypes = I->first;
|
||||
const std::vector<Record*> &RetTys = ArgTypes.first;
|
||||
const std::vector<Record*> &ParamTys = ArgTypes.second;
|
||||
|
||||
unsigned N = ParamTys.size();
|
||||
|
||||
if (N > 1 &&
|
||||
getValueType(ArgTypes[N-1]->getValueAsDef("VT")) == MVT::isVoid) {
|
||||
getValueType(ParamTys[N - 1]->getValueAsDef("VT")) == MVT::isVoid) {
|
||||
OS << " IsVarArg = true;\n";
|
||||
--N;
|
||||
}
|
||||
|
||||
|
||||
unsigned ArgNo = 0;
|
||||
OS << " ResultTy = ";
|
||||
EmitTypeGenerate(OS, ArgTypes[0], ArgNo);
|
||||
EmitTypeGenerate(OS, RetTys, ArgNo);
|
||||
OS << ";\n";
|
||||
|
||||
for (unsigned j = 1; j != N; ++j) {
|
||||
for (unsigned j = 0; j != N; ++j) {
|
||||
OS << " ArgTys.push_back(";
|
||||
EmitTypeGenerate(OS, ArgTypes[j], ArgNo);
|
||||
EmitTypeGenerate(OS, ParamTys[j], ArgNo);
|
||||
OS << ");\n";
|
||||
}
|
||||
|
||||
OS << " break;\n";
|
||||
}
|
||||
|
||||
OS << " }\n";
|
||||
OS << "#endif\n\n";
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue