1*fd3907ccSCallum Fare//===-- APIDefs.td - Base definitions for Offload tablegen -*- tablegen -*-===// 2*fd3907ccSCallum Fare// 3*fd3907ccSCallum Fare// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*fd3907ccSCallum Fare// See https://llvm.org/LICENSE.txt for license information. 5*fd3907ccSCallum Fare// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*fd3907ccSCallum Fare// 7*fd3907ccSCallum Fare//===----------------------------------------------------------------------===// 8*fd3907ccSCallum Fare// 9*fd3907ccSCallum Fare// This file contains the class definitions used to implement the Offload API, 10*fd3907ccSCallum Fare// as well as helper functions used to help populate relevant records. 11*fd3907ccSCallum Fare// See offload/API/README.md for more detailed documentation. 12*fd3907ccSCallum Fare// 13*fd3907ccSCallum Fare//===----------------------------------------------------------------------===// 14*fd3907ccSCallum Fare 15*fd3907ccSCallum Fare// Prefix for API naming. This could be hard-coded in the future when a value 16*fd3907ccSCallum Fare// is agreed upon. 17*fd3907ccSCallum Faredefvar PREFIX = "OL"; 18*fd3907ccSCallum Faredefvar prefix = !tolower(PREFIX); 19*fd3907ccSCallum Fare 20*fd3907ccSCallum Fare// Parameter flags 21*fd3907ccSCallum Faredefvar PARAM_IN = 0x1; 22*fd3907ccSCallum Faredefvar PARAM_OUT = 0x2; 23*fd3907ccSCallum Faredefvar PARAM_OPTIONAL = 0x4; 24*fd3907ccSCallum Faredefvar PARAM_IN_OPTIONAL = !or(PARAM_IN, PARAM_OPTIONAL); 25*fd3907ccSCallum Faredefvar PARAM_OUT_OPTIONAL = !or(PARAM_OUT, PARAM_OPTIONAL); 26*fd3907ccSCallum Fare 27*fd3907ccSCallum Fare// Does the type end with '_handle_t'? 28*fd3907ccSCallum Fareclass IsHandleType<string Type> { 29*fd3907ccSCallum Fare // size("_handle_t") == 9 30*fd3907ccSCallum Fare bit ret = !if(!lt(!size(Type), 9), 0, 31*fd3907ccSCallum Fare !ne(!find(Type, "_handle_t", !sub(!size(Type), 9)), -1)); 32*fd3907ccSCallum Fare} 33*fd3907ccSCallum Fare 34*fd3907ccSCallum Fare// Does the type end with '*'? 35*fd3907ccSCallum Fareclass IsPointerType<string Type> { 36*fd3907ccSCallum Fare bit ret = !ne(!find(Type, "*", !sub(!size(Type), 1)), -1); 37*fd3907ccSCallum Fare} 38*fd3907ccSCallum Fare 39*fd3907ccSCallum Fare// Describes the valid range of a pointer parameter that reperesents an array 40*fd3907ccSCallum Fareclass Range<string Begin, string End> { 41*fd3907ccSCallum Fare string begin = Begin; 42*fd3907ccSCallum Fare string end = End; 43*fd3907ccSCallum Fare} 44*fd3907ccSCallum Fare 45*fd3907ccSCallum Fare// Names the parameters that indicate the type and size of the data pointed to 46*fd3907ccSCallum Fare// by an opaque pointer parameter 47*fd3907ccSCallum Fareclass TypeInfo<string TypeEnum, string TypeSize> { 48*fd3907ccSCallum Fare string enum = TypeEnum; 49*fd3907ccSCallum Fare string size = TypeSize; 50*fd3907ccSCallum Fare} 51*fd3907ccSCallum Fare 52*fd3907ccSCallum Fareclass Param<string Type, string Name, string Desc, bits<3> Flags = 0> { 53*fd3907ccSCallum Fare string type = Type; 54*fd3907ccSCallum Fare string name = Name; 55*fd3907ccSCallum Fare string desc = Desc; 56*fd3907ccSCallum Fare bits<3> flags = Flags; 57*fd3907ccSCallum Fare Range range = Range<"", "">; 58*fd3907ccSCallum Fare TypeInfo type_info = TypeInfo<"", "">; 59*fd3907ccSCallum Fare bit IsHandle = IsHandleType<type>.ret; 60*fd3907ccSCallum Fare bit IsPointer = IsPointerType<type>.ret; 61*fd3907ccSCallum Fare} 62*fd3907ccSCallum Fare 63*fd3907ccSCallum Fare// A parameter whose range is described by other parameters in the function. 64*fd3907ccSCallum Fareclass RangedParam<string Type, string Name, string Desc, bits<3> Flags, Range ParamRange> : Param<Type, Name, Desc, Flags> { 65*fd3907ccSCallum Fare let range = ParamRange; 66*fd3907ccSCallum Fare} 67*fd3907ccSCallum Fare 68*fd3907ccSCallum Fare// A parameter (normally of type void*) which has its pointee type and size 69*fd3907ccSCallum Fare// described by other parameters in the function. 70*fd3907ccSCallum Fareclass TypeTaggedParam<string Type, string Name, string Desc, bits<3> Flags, TypeInfo ParamTypeInfo> : Param<Type, Name, Desc, Flags> { 71*fd3907ccSCallum Fare let type_info = ParamTypeInfo; 72*fd3907ccSCallum Fare} 73*fd3907ccSCallum Fare 74*fd3907ccSCallum Fareclass Return<string Value, list<string> Conditions = []> { 75*fd3907ccSCallum Fare string value = Value; 76*fd3907ccSCallum Fare list<string> conditions = Conditions; 77*fd3907ccSCallum Fare} 78*fd3907ccSCallum Fare 79*fd3907ccSCallum Fareclass ShouldCheckHandle<Param P> { 80*fd3907ccSCallum Fare bit ret = !and(P.IsHandle, !eq(!and(PARAM_OPTIONAL, P.flags), 0)); 81*fd3907ccSCallum Fare} 82*fd3907ccSCallum Fare 83*fd3907ccSCallum Fareclass ShouldCheckPointer<Param P> { 84*fd3907ccSCallum Fare bit ret = !and(P.IsPointer, !eq(!and(PARAM_OPTIONAL, P.flags), 0)); 85*fd3907ccSCallum Fare} 86*fd3907ccSCallum Fare 87*fd3907ccSCallum Fare// For a list of returns that contains a specific return code, find and append 88*fd3907ccSCallum Fare// new conditions to that return 89*fd3907ccSCallum Fareclass AppendConditionsToReturn<list<Return> Returns, string ReturnValue, 90*fd3907ccSCallum Fare list<string> Conditions> { 91*fd3907ccSCallum Fare list<Return> ret = 92*fd3907ccSCallum Fare !foreach(Ret, Returns, 93*fd3907ccSCallum Fare !if(!eq(Ret.value, ReturnValue), 94*fd3907ccSCallum Fare Return<Ret.value, Ret.conditions#Conditions>, Ret)); 95*fd3907ccSCallum Fare} 96*fd3907ccSCallum Fare 97*fd3907ccSCallum Fare// Add null handle checks to a function's return value descriptions 98*fd3907ccSCallum Fareclass AddHandleChecksToReturns<list<Param> Params, list<Return> Returns> { 99*fd3907ccSCallum Fare list<string> handle_params = 100*fd3907ccSCallum Fare !foreach(P, Params, !if(ShouldCheckHandle<P>.ret, P.name, "")); 101*fd3907ccSCallum Fare list<string> handle_params_filt = 102*fd3907ccSCallum Fare !filter(param, handle_params, !ne(param, "")); 103*fd3907ccSCallum Fare list<string> handle_param_conds = 104*fd3907ccSCallum Fare !foreach(handle, handle_params_filt, "`NULL == "#handle#"`"); 105*fd3907ccSCallum Fare 106*fd3907ccSCallum Fare // Does the list of returns already contain ERROR_INVALID_NULL_HANDLE? 107*fd3907ccSCallum Fare bit returns_has_inv_handle = !foldl( 108*fd3907ccSCallum Fare 0, Returns, HasErr, Ret, 109*fd3907ccSCallum Fare !or(HasErr, !eq(Ret.value, PREFIX#"_ERRC_INVALID_NULL_HANDLE"))); 110*fd3907ccSCallum Fare 111*fd3907ccSCallum Fare list<Return> returns_out = !if(returns_has_inv_handle, 112*fd3907ccSCallum Fare AppendConditionsToReturn<Returns, PREFIX # "_ERRC_INVALID_NULL_HANDLE", handle_param_conds>.ret, 113*fd3907ccSCallum Fare !listconcat(Returns, [Return<PREFIX # "_ERRC_INVALID_NULL_HANDLE", handle_param_conds>]) 114*fd3907ccSCallum Fare ); 115*fd3907ccSCallum Fare} 116*fd3907ccSCallum Fare 117*fd3907ccSCallum Fare// Add null pointer checks to a function's return value descriptions 118*fd3907ccSCallum Fareclass AddPointerChecksToReturns<list<Param> Params, list<Return> Returns> { 119*fd3907ccSCallum Fare list<string> ptr_params = 120*fd3907ccSCallum Fare !foreach(P, Params, !if(ShouldCheckPointer<P>.ret, P.name, "")); 121*fd3907ccSCallum Fare list<string> ptr_params_filt = !filter(param, ptr_params, !ne(param, "")); 122*fd3907ccSCallum Fare list<string> ptr_param_conds = 123*fd3907ccSCallum Fare !foreach(ptr, ptr_params_filt, "`NULL == "#ptr#"`"); 124*fd3907ccSCallum Fare 125*fd3907ccSCallum Fare // Does the list of returns already contain ERROR_INVALID_NULL_POINTER? 126*fd3907ccSCallum Fare bit returns_has_inv_ptr = !foldl( 127*fd3907ccSCallum Fare 0, Returns, HasErr, Ret, 128*fd3907ccSCallum Fare !or(HasErr, !eq(Ret.value, PREFIX#"_ERRC_INVALID_NULL_POINTER"))); 129*fd3907ccSCallum Fare list<Return> returns_out = !if(returns_has_inv_ptr, 130*fd3907ccSCallum Fare AppendConditionsToReturn<Returns, PREFIX # "_ERRC_INVALID_NULL_POINTER", ptr_param_conds>.ret, 131*fd3907ccSCallum Fare !listconcat(Returns, [Return<PREFIX # "_ERRC_INVALID_NULL_POINTER", ptr_param_conds>]) 132*fd3907ccSCallum Fare ); 133*fd3907ccSCallum Fare} 134*fd3907ccSCallum Fare 135*fd3907ccSCallum Faredefvar DefaultReturns = [Return<PREFIX#"_RESULT_SUCCESS">, 136*fd3907ccSCallum Fare Return<PREFIX#"_ERRC_UNINITIALIZED">, 137*fd3907ccSCallum Fare Return<PREFIX#"_ERRC_DEVICE_LOST">]; 138*fd3907ccSCallum Fare 139*fd3907ccSCallum Fareclass APIObject { 140*fd3907ccSCallum Fare string name; 141*fd3907ccSCallum Fare string desc; 142*fd3907ccSCallum Fare} 143*fd3907ccSCallum Fare 144*fd3907ccSCallum Fareclass Function : APIObject { 145*fd3907ccSCallum Fare list<Param> params; 146*fd3907ccSCallum Fare list<Return> returns; 147*fd3907ccSCallum Fare list<string> details = []; 148*fd3907ccSCallum Fare list<string> analogues = []; 149*fd3907ccSCallum Fare 150*fd3907ccSCallum Fare list<Return> returns_with_def = !listconcat(DefaultReturns, returns); 151*fd3907ccSCallum Fare list<Return> all_returns = AddPointerChecksToReturns<params, 152*fd3907ccSCallum Fare AddHandleChecksToReturns<params, returns_with_def>.returns_out>.returns_out; 153*fd3907ccSCallum Fare} 154*fd3907ccSCallum Fare 155*fd3907ccSCallum Fareclass Etor<string Name, string Desc> { 156*fd3907ccSCallum Fare string name = Name; 157*fd3907ccSCallum Fare string desc = Desc; 158*fd3907ccSCallum Fare string tagged_type; 159*fd3907ccSCallum Fare} 160*fd3907ccSCallum Fare 161*fd3907ccSCallum Fareclass TaggedEtor<string Name, string Type, string Desc> : Etor<Name, Desc> { 162*fd3907ccSCallum Fare let tagged_type = Type; 163*fd3907ccSCallum Fare} 164*fd3907ccSCallum Fare 165*fd3907ccSCallum Fareclass Enum : APIObject { 166*fd3907ccSCallum Fare // This refers to whether the enumerator descriptions specify a return 167*fd3907ccSCallum Fare // type for functions where this enum may be used as an output type. If set, 168*fd3907ccSCallum Fare // all Etor values must be TaggedEtor records 169*fd3907ccSCallum Fare bit is_typed = 0; 170*fd3907ccSCallum Fare 171*fd3907ccSCallum Fare list<Etor> etors = []; 172*fd3907ccSCallum Fare} 173*fd3907ccSCallum Fare 174*fd3907ccSCallum Fareclass StructMember<string Type, string Name, string Desc> { 175*fd3907ccSCallum Fare string type = Type; 176*fd3907ccSCallum Fare string name = Name; 177*fd3907ccSCallum Fare string desc = Desc; 178*fd3907ccSCallum Fare} 179*fd3907ccSCallum Fare 180*fd3907ccSCallum Faredefvar DefaultPropStructMembers = 181*fd3907ccSCallum Fare [StructMember<prefix#"_structure_type_t", "stype", 182*fd3907ccSCallum Fare "type of this structure">, 183*fd3907ccSCallum Fare StructMember<"void*", "pNext", "pointer to extension-specific structure">]; 184*fd3907ccSCallum Fare 185*fd3907ccSCallum Fareclass StructHasInheritedMembers<string BaseClass> { 186*fd3907ccSCallum Fare bit ret = !or(!eq(BaseClass, prefix#"_base_properties_t"), 187*fd3907ccSCallum Fare !eq(BaseClass, prefix#"_base_desc_t")); 188*fd3907ccSCallum Fare} 189*fd3907ccSCallum Fare 190*fd3907ccSCallum Fareclass Struct : APIObject { 191*fd3907ccSCallum Fare string base_class = ""; 192*fd3907ccSCallum Fare list<StructMember> members; 193*fd3907ccSCallum Fare list<StructMember> all_members = 194*fd3907ccSCallum Fare !if(StructHasInheritedMembers<base_class>.ret, 195*fd3907ccSCallum Fare DefaultPropStructMembers, [])#members; 196*fd3907ccSCallum Fare} 197*fd3907ccSCallum Fare 198*fd3907ccSCallum Fareclass Typedef : APIObject { string value; } 199*fd3907ccSCallum Fare 200*fd3907ccSCallum Fareclass FptrTypedef : APIObject { 201*fd3907ccSCallum Fare list<Param> params; 202*fd3907ccSCallum Fare list<Return> returns; 203*fd3907ccSCallum Fare} 204*fd3907ccSCallum Fare 205*fd3907ccSCallum Fareclass Macro : APIObject { 206*fd3907ccSCallum Fare string value; 207*fd3907ccSCallum Fare 208*fd3907ccSCallum Fare string condition; 209*fd3907ccSCallum Fare string alt_value; 210*fd3907ccSCallum Fare} 211*fd3907ccSCallum Fare 212*fd3907ccSCallum Fareclass Handle : APIObject; 213