1function codegen_unop_template (unop, bfunc, ifunc, ufunc, ffunc, dfunc, ...
2    fcfunc, dcfunc)
3%CODEGEN_UNOP_TEMPLATE create unop functions
4%
5% codegen_unop_template (unop, bfunc, ifunc, ufunc, ffunc, dfunc, ...
6%       fcfunc, dcfunc)
7%
8%       unop:   operator name
9%
10%   strings defining each function, or empty if no such unary operator:
11%
12%       bfunc:  bool
13%       ifunc:  int8, int16, int32, int64
14%       ufunc:  uint8, uint16, uint32, uint64
15%       ffunc:  float
16%       dfunc:  double
17%       fcfunc: GxB_FC32_t
18%       dcfunc: GxB_FC64_t
19%
20% Generate functions for a unary operator, for all types.
21%
22% The 'identity' operator is unique: it is used for typecasting, and all 13*13
23% pairs of functions are generated.  The other unary operators are defined only
24% for a single type (ctype == atype).
25
26% SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
27% SPDX-License-Identifier: Apache-2.0
28
29fprintf ('\n%-9s', unop) ;
30
31types = {
32'bool',
33'int8_t',
34'int16_t',
35'int32_t',
36'int64_t',
37'uint8_t',
38'uint16_t',
39'uint32_t',
40'uint64_t',
41'float',
42'double',
43'GxB_FC32_t',
44'GxB_FC64_t' } ;
45
46bits = [
478
488
4916
5032
5164
528
5316
5432
5564
5632
5764
5864
59128 ] ;
60
61ntypes = length (types) ;
62
63for code1 = 1:ntypes
64    ctype = types {code1} ;
65    cbits = bits (code1) ;
66
67    % determine the function
68    if (isequal (ctype, 'bool'))
69        func = bfunc ;
70    elseif (ctype (1) == 'i')
71        func = ifunc ;
72    elseif (ctype (1) == 'u')
73        func = ufunc ;
74    elseif (isequal (ctype, 'float'))
75        func = ffunc ;
76    elseif (isequal (ctype, 'double'))
77        func = dfunc ;
78    elseif (isequal (ctype, 'GxB_FC32_t'))
79        func = fcfunc ;
80    elseif (isequal (ctype, 'GxB_FC64_t'))
81        func = dcfunc ;
82    end
83
84    if (isempty (func))
85        % skip this operator
86        continue ;
87    end
88
89    if (isequal (unop, 'identity'))
90        % create identity operators for all pairs of types
91        code2s = 1:ntypes ;
92    else
93        % create operators only for code1 == code2
94        code2s = code1 ;
95    end
96
97    for code2 = code2s
98        atype = types {code2} ;
99
100        % determine the casting function
101        fcast = 'GB_ctype zarg = (GB_ctype) xarg' ;
102
103        if (isequal (atype, ctype))
104
105            % no typecasting
106            fcast = 'GB_ctype zarg = xarg' ;
107
108        elseif (isequal (atype, 'GxB_FC32_t'))
109
110            % typecasting from GxB_FC32_t
111            if (isequal (ctype, 'bool'))
112                % to bool from GxB_FC32_t
113                fcast = 'GB_ctype zarg = (crealf (xarg) != 0) || (cimagf (xarg) != 0)' ;
114            elseif (contains (ctype, 'int'))
115                % to integer from GxB_FC32_t
116                fcast = sprintf ('GB_ctype zarg = GB_cast_to_%s ((double) crealf (xarg))', ctype) ;
117            elseif (isequal (ctype, 'float') || isequal (ctype, 'double'))
118                % to float or double from GxB_FC32_t
119                fcast = 'GB_ctype zarg = (GB_ctype) crealf (xarg)' ;
120            elseif (isequal (ctype, 'GxB_FC64_t'))
121                % to GxB_FC64_t from GxB_FC32_t
122                fcast = 'GB_ctype zarg = GxB_CMPLX ((double) crealf (xarg), (double) cimagf (xarg))' ;
123            end
124
125        elseif (isequal (atype, 'GxB_FC64_t'))
126
127            % typecasting from GxB_FC64_t
128            if (isequal (ctype, 'bool'))
129                % to bool from GxB_FC64_t
130                fcast = 'GB_ctype zarg = (creal (xarg) != 0) || (cimag (xarg) != 0)' ;
131            elseif (contains (ctype, 'int'))
132                % to integer from GxB_FC64_t
133                fcast = sprintf ('GB_ctype zarg = GB_cast_to_%s (creal (xarg))', ctype) ;
134            elseif (isequal (ctype, 'float') || isequal (ctype, 'double'))
135                % to float or double from GxB_FC64_t
136                fcast = 'GB_ctype zarg = (GB_ctype) creal (xarg)' ;
137            elseif (isequal (ctype, 'GxB_FC32_t'))
138                % to GxB_FC32_t from GxB_FC64_t
139                fcast = 'GB_ctype zarg = GxB_CMPLXF ((float) creal (xarg), (float) cimag (xarg))' ;
140            end
141
142        elseif (isequal (atype, 'float') || isequal (atype, 'double'))
143
144            % typecasting from float or double
145            if (isequal (ctype, 'bool'))
146                % to bool from float or double
147                fcast = 'GB_ctype zarg = (xarg != 0)' ;
148            elseif (contains (ctype, 'int'))
149                % to integer from float or double
150                fcast = sprintf ('GB_ctype zarg = GB_cast_to_%s ((double) (xarg))', ctype) ;
151            elseif (isequal (ctype, 'GxB_FC32_t'))
152                % to GxB_FC32_t from float or double
153                fcast = 'GB_ctype zarg = GxB_CMPLXF ((float) (xarg), 0)' ;
154            elseif (isequal (ctype, 'GxB_FC64_t'))
155                % to GxB_FC64_t from float or double
156                fcast = 'GB_ctype zarg = GxB_CMPLX ((double) (xarg), 0)' ;
157            end
158
159        elseif (isequal (ctype, 'GxB_FC32_t'))
160
161            % typecasting to GxB_FC32_t to any real type
162            fcast = 'GB_ctype zarg = GxB_CMPLXF ((float) (xarg), 0)' ;
163
164        elseif (isequal (ctype, 'GxB_FC64_t'))
165
166            % typecasting to GxB_FC32_t to any real type
167            fcast = 'GB_ctype zarg = GxB_CMPLX ((double) (xarg), 0)' ;
168
169        end
170
171        codegen_unop_method (unop, func, fcast, ctype, atype) ;
172    end
173end
174
175