Mercurial > hg > sv-dependency-builds
diff src/fftw-3.3.5/genfft/simd.ml @ 127:7867fa7e1b6b
Current fftw source
author | Chris Cannam <cannam@all-day-breakfast.com> |
---|---|
date | Tue, 18 Oct 2016 13:40:26 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/fftw-3.3.5/genfft/simd.ml Tue Oct 18 13:40:26 2016 +0100 @@ -0,0 +1,226 @@ +(* + * Copyright (c) 1997-1999 Massachusetts Institute of Technology + * Copyright (c) 2003, 2007-14 Matteo Frigo + * Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + *) + +open Expr +open List +open Printf +open Variable +open Annotate +open Simdmagic +open C + +let realtype = "V" +let realtypep = realtype ^ " *" +let constrealtype = "const " ^ realtype +let constrealtypep = constrealtype ^ " *" +let alignment_mod = 2 + +(* + * SIMD C AST unparser + *) +let foldr_string_concat l = fold_right (^) l "" + +let rec unparse_by_twiddle nam tw src = + sprintf "%s(&(%s),%s)" nam (Variable.unparse tw) (unparse_expr src) + +and unparse_store dst = function + | Times (NaN MULTI_A, x) -> + sprintf "STM%d(&(%s),%s,%s,&(%s));\n" + !Simdmagic.store_multiple + (Variable.unparse dst) (unparse_expr x) + (Variable.vstride_of_locative dst) + (Variable.unparse_for_alignment alignment_mod dst) + | Times (NaN MULTI_B, Plus stuff) -> + sprintf "STN%d(&(%s)%s,%s);\n" + !Simdmagic.store_multiple + (Variable.unparse dst) + (List.fold_right (fun x a -> "," ^ (unparse_expr x) ^ a) stuff "") + (Variable.vstride_of_locative dst) + | src_expr -> + sprintf "ST(&(%s),%s,%s,&(%s));\n" + (Variable.unparse dst) (unparse_expr src_expr) + (Variable.vstride_of_locative dst) + (Variable.unparse_for_alignment alignment_mod dst) + +and unparse_expr = + let rec unparse_plus = function + | [a] -> unparse_expr a + + | (Uminus (Times (NaN I, b))) :: c :: d -> op2 "VFNMSI" [b] (c :: d) + | c :: (Uminus (Times (NaN I, b))) :: d -> op2 "VFNMSI" [b] (c :: d) + | (Uminus (Times (NaN CONJ, b))) :: c :: d -> op2 "VFNMSCONJ" [b] (c :: d) + | c :: (Uminus (Times (NaN CONJ, b))) :: d -> op2 "VFNMSCONJ" [b] (c :: d) + | (Times (NaN I, b)) :: c :: d -> op2 "VFMAI" [b] (c :: d) + | c :: (Times (NaN I, b)) :: d -> op2 "VFMAI" [b] (c :: d) + | (Times (NaN CONJ, b)) :: (Uminus c) :: d -> op2 "VFMSCONJ" [b] (c :: d) + | (Uminus c) :: (Times (NaN CONJ, b)) :: d -> op2 "VFMSCONJ" [b] (c :: d) + | (Times (NaN CONJ, b)) :: c :: d -> op2 "VFMACONJ" [b] (c :: d) + | c :: (Times (NaN CONJ, b)) :: d -> op2 "VFMACONJ" [b] (c :: d) + | (Times (NaN _, b)) :: (Uminus c) :: d -> failwith "VFMS NaN" + | (Uminus c) :: (Times (NaN _, b)) :: d -> failwith "VFMS NaN" + + | (Uminus (Times (a, b))) :: c :: d -> op3 "VFNMS" a b (c :: d) + | c :: (Uminus (Times (a, b))) :: d -> op3 "VFNMS" a b (c :: d) + | (Times (a, b)) :: (Uminus c) :: d -> op3 "VFMS" a b (c :: negate d) + | (Uminus c) :: (Times (a, b)) :: d -> op3 "VFMS" a b (c :: negate d) + | (Times (a, b)) :: c :: d -> op3 "VFMA" a b (c :: d) + | c :: (Times (a, b)) :: d -> op3 "VFMA" a b (c :: d) + + | (Uminus a :: b) -> op2 "VSUB" b [a] + | (b :: Uminus a :: c) -> op2 "VSUB" (b :: c) [a] + | (a :: b) -> op2 "VADD" [a] b + | [] -> failwith "unparse_plus" + and op3 nam a b c = + nam ^ "(" ^ (unparse_expr a) ^ ", " ^ (unparse_expr b) ^ ", " ^ + (unparse_plus c) ^ ")" + and op2 nam a b = + nam ^ "(" ^ (unparse_plus a) ^ ", " ^ (unparse_plus b) ^ ")" + and op1 nam a = + nam ^ "(" ^ (unparse_expr a) ^ ")" + and negate = function + | [] -> [] + | (Uminus x) :: y -> x :: negate y + | x :: y -> (Uminus x) :: negate y + + in function + | CTimes(Load tw, src) + when Variable.is_constant tw && !Magic.generate_bytw -> + unparse_by_twiddle "BYTW" tw src + | CTimesJ(Load tw, src) + when Variable.is_constant tw && !Magic.generate_bytw -> + unparse_by_twiddle "BYTWJ" tw src + | Load v when is_locative(v) -> + sprintf "LD(&(%s), %s, &(%s))" (Variable.unparse v) + (Variable.vstride_of_locative v) + (Variable.unparse_for_alignment alignment_mod v) + | Load v when is_constant(v) -> sprintf "LDW(&(%s))" (Variable.unparse v) + | Load v -> Variable.unparse v + | Num n -> sprintf "LDK(%s)" (Number.to_konst n) + | NaN n -> failwith "NaN in unparse_expr" + | Plus [] -> "0.0 /* bug */" + | Plus [a] -> " /* bug */ " ^ (unparse_expr a) + | Plus a -> unparse_plus a + | Times(NaN I,b) -> op1 "VBYI" b + | Times(NaN CONJ,b) -> op1 "VCONJ" b + | Times(a,b) -> + sprintf "VMUL(%s, %s)" (unparse_expr a) (unparse_expr b) + | CTimes(a,Times(NaN I, b)) -> + sprintf "VZMULI(%s, %s)" (unparse_expr a) (unparse_expr b) + | CTimes(a,b) -> + sprintf "VZMUL(%s, %s)" (unparse_expr a) (unparse_expr b) + | CTimesJ(a,Times(NaN I, b)) -> + sprintf "VZMULIJ(%s, %s)" (unparse_expr a) (unparse_expr b) + | CTimesJ(a,b) -> + sprintf "VZMULJ(%s, %s)" (unparse_expr a) (unparse_expr b) + | Uminus a when !Magic.vneg -> op1 "VNEG" a + | Uminus a -> failwith "SIMD Uminus" + | _ -> failwith "unparse_expr" + +and unparse_decl x = C.unparse_decl x + +and unparse_ast ast = + let rec unparse_assignment = function + | Assign (v, x) when Variable.is_locative v -> + unparse_store v x + | Assign (v, x) -> + (Variable.unparse v) ^ " = " ^ (unparse_expr x) ^ ";\n" + + and unparse_annotated force_bracket = + let rec unparse_code = function + | ADone -> "" + | AInstr i -> unparse_assignment i + | ASeq (a, b) -> + (unparse_annotated false a) ^ (unparse_annotated false b) + and declare_variables l = + let rec uvar = function + [] -> failwith "uvar" + | [v] -> (Variable.unparse v) ^ ";\n" + | a :: b -> (Variable.unparse a) ^ ", " ^ (uvar b) + in let rec vvar l = + let s = if !Magic.compact then 15 else 1 in + if (List.length l <= s) then + match l with + [] -> "" + | _ -> realtype ^ " " ^ (uvar l) + else + (vvar (Util.take s l)) ^ (vvar (Util.drop s l)) + in vvar (List.filter Variable.is_temporary l) + in function + Annotate (_, _, decl, _, code) -> + if (not force_bracket) && (Util.null decl) then + unparse_code code + else "{\n" ^ + (declare_variables decl) ^ + (unparse_code code) ^ + "}\n" + +(* ---- *) + and unparse_plus = function + | [] -> "" + | (CUminus a :: b) -> " - " ^ (parenthesize a) ^ (unparse_plus b) + | (a :: b) -> " + " ^ (parenthesize a) ^ (unparse_plus b) + and parenthesize x = match x with + | (CVar _) -> unparse_ast x + | (CCall _) -> unparse_ast x + | (Integer _) -> unparse_ast x + | _ -> "(" ^ (unparse_ast x) ^ ")" + + in match ast with + | Asch a -> (unparse_annotated true a) + | Return x -> "return " ^ unparse_ast x ^ ";" + | Simd_leavefun -> "VLEAVE();" + | For (a, b, c, d) -> + "for (" ^ + unparse_ast a ^ "; " ^ unparse_ast b ^ "; " ^ unparse_ast c + ^ ")" ^ unparse_ast d + | If (a, d) -> + "if (" ^ + unparse_ast a + ^ ")" ^ unparse_ast d + | Block (d, s) -> + if (s == []) then "" + else + "{\n" ^ + foldr_string_concat (map unparse_decl d) ^ + foldr_string_concat (map unparse_ast s) ^ + "}\n" + | x -> C.unparse_ast x + +and unparse_function = function + Fcn (typ, name, args, body) -> + let rec unparse_args = function + [Decl (a, b)] -> a ^ " " ^ b + | (Decl (a, b)) :: s -> a ^ " " ^ b ^ ", " + ^ unparse_args s + | [] -> "" + | _ -> failwith "unparse_function" + in + (typ ^ " " ^ name ^ "(" ^ unparse_args args ^ ")\n" ^ + unparse_ast body) + +let extract_constants f = + let constlist = flatten (map expr_to_constants (C.ast_to_expr_list f)) + in map + (fun n -> + Tdecl + ("DVK(" ^ (Number.to_konst n) ^ ", " ^ (Number.to_string n) ^ + ");\n")) + (unique_constants constlist)