Mercurial > hg > sv-dependency-builds
comparison src/fftw-3.3.5/genfft/simd.ml @ 42:2cd0e3b3e1fd
Current fftw source
author | Chris Cannam |
---|---|
date | Tue, 18 Oct 2016 13:40:26 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
41:481f5f8c5634 | 42:2cd0e3b3e1fd |
---|---|
1 (* | |
2 * Copyright (c) 1997-1999 Massachusetts Institute of Technology | |
3 * Copyright (c) 2003, 2007-14 Matteo Frigo | |
4 * Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology | |
5 * | |
6 * This program is free software; you can redistribute it and/or modify | |
7 * it under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; either version 2 of the License, or | |
9 * (at your option) any later version. | |
10 * | |
11 * This program is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 * GNU General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License | |
17 * along with this program; if not, write to the Free Software | |
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
19 * | |
20 *) | |
21 | |
22 open Expr | |
23 open List | |
24 open Printf | |
25 open Variable | |
26 open Annotate | |
27 open Simdmagic | |
28 open C | |
29 | |
30 let realtype = "V" | |
31 let realtypep = realtype ^ " *" | |
32 let constrealtype = "const " ^ realtype | |
33 let constrealtypep = constrealtype ^ " *" | |
34 let alignment_mod = 2 | |
35 | |
36 (* | |
37 * SIMD C AST unparser | |
38 *) | |
39 let foldr_string_concat l = fold_right (^) l "" | |
40 | |
41 let rec unparse_by_twiddle nam tw src = | |
42 sprintf "%s(&(%s),%s)" nam (Variable.unparse tw) (unparse_expr src) | |
43 | |
44 and unparse_store dst = function | |
45 | Times (NaN MULTI_A, x) -> | |
46 sprintf "STM%d(&(%s),%s,%s,&(%s));\n" | |
47 !Simdmagic.store_multiple | |
48 (Variable.unparse dst) (unparse_expr x) | |
49 (Variable.vstride_of_locative dst) | |
50 (Variable.unparse_for_alignment alignment_mod dst) | |
51 | Times (NaN MULTI_B, Plus stuff) -> | |
52 sprintf "STN%d(&(%s)%s,%s);\n" | |
53 !Simdmagic.store_multiple | |
54 (Variable.unparse dst) | |
55 (List.fold_right (fun x a -> "," ^ (unparse_expr x) ^ a) stuff "") | |
56 (Variable.vstride_of_locative dst) | |
57 | src_expr -> | |
58 sprintf "ST(&(%s),%s,%s,&(%s));\n" | |
59 (Variable.unparse dst) (unparse_expr src_expr) | |
60 (Variable.vstride_of_locative dst) | |
61 (Variable.unparse_for_alignment alignment_mod dst) | |
62 | |
63 and unparse_expr = | |
64 let rec unparse_plus = function | |
65 | [a] -> unparse_expr a | |
66 | |
67 | (Uminus (Times (NaN I, b))) :: c :: d -> op2 "VFNMSI" [b] (c :: d) | |
68 | c :: (Uminus (Times (NaN I, b))) :: d -> op2 "VFNMSI" [b] (c :: d) | |
69 | (Uminus (Times (NaN CONJ, b))) :: c :: d -> op2 "VFNMSCONJ" [b] (c :: d) | |
70 | c :: (Uminus (Times (NaN CONJ, b))) :: d -> op2 "VFNMSCONJ" [b] (c :: d) | |
71 | (Times (NaN I, b)) :: c :: d -> op2 "VFMAI" [b] (c :: d) | |
72 | c :: (Times (NaN I, b)) :: d -> op2 "VFMAI" [b] (c :: d) | |
73 | (Times (NaN CONJ, b)) :: (Uminus c) :: d -> op2 "VFMSCONJ" [b] (c :: d) | |
74 | (Uminus c) :: (Times (NaN CONJ, b)) :: d -> op2 "VFMSCONJ" [b] (c :: d) | |
75 | (Times (NaN CONJ, b)) :: c :: d -> op2 "VFMACONJ" [b] (c :: d) | |
76 | c :: (Times (NaN CONJ, b)) :: d -> op2 "VFMACONJ" [b] (c :: d) | |
77 | (Times (NaN _, b)) :: (Uminus c) :: d -> failwith "VFMS NaN" | |
78 | (Uminus c) :: (Times (NaN _, b)) :: d -> failwith "VFMS NaN" | |
79 | |
80 | (Uminus (Times (a, b))) :: c :: d -> op3 "VFNMS" a b (c :: d) | |
81 | c :: (Uminus (Times (a, b))) :: d -> op3 "VFNMS" a b (c :: d) | |
82 | (Times (a, b)) :: (Uminus c) :: d -> op3 "VFMS" a b (c :: negate d) | |
83 | (Uminus c) :: (Times (a, b)) :: d -> op3 "VFMS" a b (c :: negate d) | |
84 | (Times (a, b)) :: c :: d -> op3 "VFMA" a b (c :: d) | |
85 | c :: (Times (a, b)) :: d -> op3 "VFMA" a b (c :: d) | |
86 | |
87 | (Uminus a :: b) -> op2 "VSUB" b [a] | |
88 | (b :: Uminus a :: c) -> op2 "VSUB" (b :: c) [a] | |
89 | (a :: b) -> op2 "VADD" [a] b | |
90 | [] -> failwith "unparse_plus" | |
91 and op3 nam a b c = | |
92 nam ^ "(" ^ (unparse_expr a) ^ ", " ^ (unparse_expr b) ^ ", " ^ | |
93 (unparse_plus c) ^ ")" | |
94 and op2 nam a b = | |
95 nam ^ "(" ^ (unparse_plus a) ^ ", " ^ (unparse_plus b) ^ ")" | |
96 and op1 nam a = | |
97 nam ^ "(" ^ (unparse_expr a) ^ ")" | |
98 and negate = function | |
99 | [] -> [] | |
100 | (Uminus x) :: y -> x :: negate y | |
101 | x :: y -> (Uminus x) :: negate y | |
102 | |
103 in function | |
104 | CTimes(Load tw, src) | |
105 when Variable.is_constant tw && !Magic.generate_bytw -> | |
106 unparse_by_twiddle "BYTW" tw src | |
107 | CTimesJ(Load tw, src) | |
108 when Variable.is_constant tw && !Magic.generate_bytw -> | |
109 unparse_by_twiddle "BYTWJ" tw src | |
110 | Load v when is_locative(v) -> | |
111 sprintf "LD(&(%s), %s, &(%s))" (Variable.unparse v) | |
112 (Variable.vstride_of_locative v) | |
113 (Variable.unparse_for_alignment alignment_mod v) | |
114 | Load v when is_constant(v) -> sprintf "LDW(&(%s))" (Variable.unparse v) | |
115 | Load v -> Variable.unparse v | |
116 | Num n -> sprintf "LDK(%s)" (Number.to_konst n) | |
117 | NaN n -> failwith "NaN in unparse_expr" | |
118 | Plus [] -> "0.0 /* bug */" | |
119 | Plus [a] -> " /* bug */ " ^ (unparse_expr a) | |
120 | Plus a -> unparse_plus a | |
121 | Times(NaN I,b) -> op1 "VBYI" b | |
122 | Times(NaN CONJ,b) -> op1 "VCONJ" b | |
123 | Times(a,b) -> | |
124 sprintf "VMUL(%s, %s)" (unparse_expr a) (unparse_expr b) | |
125 | CTimes(a,Times(NaN I, b)) -> | |
126 sprintf "VZMULI(%s, %s)" (unparse_expr a) (unparse_expr b) | |
127 | CTimes(a,b) -> | |
128 sprintf "VZMUL(%s, %s)" (unparse_expr a) (unparse_expr b) | |
129 | CTimesJ(a,Times(NaN I, b)) -> | |
130 sprintf "VZMULIJ(%s, %s)" (unparse_expr a) (unparse_expr b) | |
131 | CTimesJ(a,b) -> | |
132 sprintf "VZMULJ(%s, %s)" (unparse_expr a) (unparse_expr b) | |
133 | Uminus a when !Magic.vneg -> op1 "VNEG" a | |
134 | Uminus a -> failwith "SIMD Uminus" | |
135 | _ -> failwith "unparse_expr" | |
136 | |
137 and unparse_decl x = C.unparse_decl x | |
138 | |
139 and unparse_ast ast = | |
140 let rec unparse_assignment = function | |
141 | Assign (v, x) when Variable.is_locative v -> | |
142 unparse_store v x | |
143 | Assign (v, x) -> | |
144 (Variable.unparse v) ^ " = " ^ (unparse_expr x) ^ ";\n" | |
145 | |
146 and unparse_annotated force_bracket = | |
147 let rec unparse_code = function | |
148 | ADone -> "" | |
149 | AInstr i -> unparse_assignment i | |
150 | ASeq (a, b) -> | |
151 (unparse_annotated false a) ^ (unparse_annotated false b) | |
152 and declare_variables l = | |
153 let rec uvar = function | |
154 [] -> failwith "uvar" | |
155 | [v] -> (Variable.unparse v) ^ ";\n" | |
156 | a :: b -> (Variable.unparse a) ^ ", " ^ (uvar b) | |
157 in let rec vvar l = | |
158 let s = if !Magic.compact then 15 else 1 in | |
159 if (List.length l <= s) then | |
160 match l with | |
161 [] -> "" | |
162 | _ -> realtype ^ " " ^ (uvar l) | |
163 else | |
164 (vvar (Util.take s l)) ^ (vvar (Util.drop s l)) | |
165 in vvar (List.filter Variable.is_temporary l) | |
166 in function | |
167 Annotate (_, _, decl, _, code) -> | |
168 if (not force_bracket) && (Util.null decl) then | |
169 unparse_code code | |
170 else "{\n" ^ | |
171 (declare_variables decl) ^ | |
172 (unparse_code code) ^ | |
173 "}\n" | |
174 | |
175 (* ---- *) | |
176 and unparse_plus = function | |
177 | [] -> "" | |
178 | (CUminus a :: b) -> " - " ^ (parenthesize a) ^ (unparse_plus b) | |
179 | (a :: b) -> " + " ^ (parenthesize a) ^ (unparse_plus b) | |
180 and parenthesize x = match x with | |
181 | (CVar _) -> unparse_ast x | |
182 | (CCall _) -> unparse_ast x | |
183 | (Integer _) -> unparse_ast x | |
184 | _ -> "(" ^ (unparse_ast x) ^ ")" | |
185 | |
186 in match ast with | |
187 | Asch a -> (unparse_annotated true a) | |
188 | Return x -> "return " ^ unparse_ast x ^ ";" | |
189 | Simd_leavefun -> "VLEAVE();" | |
190 | For (a, b, c, d) -> | |
191 "for (" ^ | |
192 unparse_ast a ^ "; " ^ unparse_ast b ^ "; " ^ unparse_ast c | |
193 ^ ")" ^ unparse_ast d | |
194 | If (a, d) -> | |
195 "if (" ^ | |
196 unparse_ast a | |
197 ^ ")" ^ unparse_ast d | |
198 | Block (d, s) -> | |
199 if (s == []) then "" | |
200 else | |
201 "{\n" ^ | |
202 foldr_string_concat (map unparse_decl d) ^ | |
203 foldr_string_concat (map unparse_ast s) ^ | |
204 "}\n" | |
205 | x -> C.unparse_ast x | |
206 | |
207 and unparse_function = function | |
208 Fcn (typ, name, args, body) -> | |
209 let rec unparse_args = function | |
210 [Decl (a, b)] -> a ^ " " ^ b | |
211 | (Decl (a, b)) :: s -> a ^ " " ^ b ^ ", " | |
212 ^ unparse_args s | |
213 | [] -> "" | |
214 | _ -> failwith "unparse_function" | |
215 in | |
216 (typ ^ " " ^ name ^ "(" ^ unparse_args args ^ ")\n" ^ | |
217 unparse_ast body) | |
218 | |
219 let extract_constants f = | |
220 let constlist = flatten (map expr_to_constants (C.ast_to_expr_list f)) | |
221 in map | |
222 (fun n -> | |
223 Tdecl | |
224 ("DVK(" ^ (Number.to_konst n) ^ ", " ^ (Number.to_string n) ^ | |
225 ");\n")) | |
226 (unique_constants constlist) |