OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [tags/] [gnu-src/] [gcc-4.5.1/] [gcc-4.5.1-or32-1.0rc2/] [gcc/] [config/] [arm/] [neon-gen.ml] - Diff between revs 282 and 384

Only display areas with differences | Details | Blame | View Log

Rev 282 Rev 384
(* Auto-generate ARM Neon intrinsics header file.
(* Auto-generate ARM Neon intrinsics header file.
   Copyright (C) 2006, 2007, 2009 Free Software Foundation, Inc.
   Copyright (C) 2006, 2007, 2009 Free Software Foundation, Inc.
   Contributed by CodeSourcery.
   Contributed by CodeSourcery.
   This file is part of GCC.
   This file is part of GCC.
   GCC is free software; you can redistribute it and/or modify it under
   GCC 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
   the terms of the GNU General Public License as published by the Free
   Software Foundation; either version 3, or (at your option) any later
   Software Foundation; either version 3, or (at your option) any later
   version.
   version.
   GCC is distributed in the hope that it will be useful, but WITHOUT ANY
   GCC is distributed in the hope that it will be useful, but WITHOUT ANY
   WARRANTY; without even the implied warranty of MERCHANTABILITY or
   WARRANTY; without even the implied warranty of MERCHANTABILITY or
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   for more details.
   for more details.
   You should have received a copy of the GNU General Public License
   You should have received a copy of the GNU General Public License
   along with GCC; see the file COPYING3.  If not see
   along with GCC; see the file COPYING3.  If not see
   .
   .
   This is an O'Caml program.  The O'Caml compiler is available from:
   This is an O'Caml program.  The O'Caml compiler is available from:
     http://caml.inria.fr/
     http://caml.inria.fr/
   Or from your favourite OS's friendly packaging system. Tested with version
   Or from your favourite OS's friendly packaging system. Tested with version
   3.09.2, though other versions will probably work too.
   3.09.2, though other versions will probably work too.
   Compile with:
   Compile with:
     ocamlc -c neon.ml
     ocamlc -c neon.ml
     ocamlc -o neon-gen neon.cmo neon-gen.ml
     ocamlc -o neon-gen neon.cmo neon-gen.ml
   Run with:
   Run with:
     ./neon-gen > arm_neon.h
     ./neon-gen > arm_neon.h
*)
*)
open Neon
open Neon
(* The format codes used in the following functions are documented at:
(* The format codes used in the following functions are documented at:
     http://caml.inria.fr/pub/docs/manual-ocaml/libref/Format.html\
     http://caml.inria.fr/pub/docs/manual-ocaml/libref/Format.html\
     #6_printflikefunctionsforprettyprinting
     #6_printflikefunctionsforprettyprinting
   (one line, remove the backslash.)
   (one line, remove the backslash.)
*)
*)
(* Following functions can be used to approximate GNU indentation style.  *)
(* Following functions can be used to approximate GNU indentation style.  *)
let start_function () =
let start_function () =
  Format.printf "@[";
  Format.printf "@[";
  ref 0
  ref 0
let end_function nesting =
let end_function nesting =
  match !nesting with
  match !nesting with
    0 -> Format.printf "@;@;@]"
    0 -> Format.printf "@;@;@]"
  | _ -> failwith ("Bad nesting (ending function at level "
  | _ -> failwith ("Bad nesting (ending function at level "
                   ^ (string_of_int !nesting) ^ ")")
                   ^ (string_of_int !nesting) ^ ")")
let open_braceblock nesting =
let open_braceblock nesting =
  begin match !nesting with
  begin match !nesting with
    0 -> Format.printf "@,@<0>{@[@,"
    0 -> Format.printf "@,@<0>{@[@,"
  | _ -> Format.printf "@,@[  @<0>{@[@,"
  | _ -> Format.printf "@,@[  @<0>{@[@,"
  end;
  end;
  incr nesting
  incr nesting
let close_braceblock nesting =
let close_braceblock nesting =
  decr nesting;
  decr nesting;
  match !nesting with
  match !nesting with
    0 -> Format.printf "@]@,@<0>}"
    0 -> Format.printf "@]@,@<0>}"
  | _ -> Format.printf "@]@,@<0>}@]"
  | _ -> Format.printf "@]@,@<0>}@]"
let print_function arity fnname body =
let print_function arity fnname body =
  let ffmt = start_function () in
  let ffmt = start_function () in
  Format.printf "__extension__ static __inline ";
  Format.printf "__extension__ static __inline ";
  let inl = "__attribute__ ((__always_inline__))" in
  let inl = "__attribute__ ((__always_inline__))" in
  begin match arity with
  begin match arity with
    Arity0 ret ->
    Arity0 ret ->
      Format.printf "%s %s@,%s (void)" (string_of_vectype ret) inl fnname
      Format.printf "%s %s@,%s (void)" (string_of_vectype ret) inl fnname
  | Arity1 (ret, arg0) ->
  | Arity1 (ret, arg0) ->
      Format.printf "%s %s@,%s (%s __a)" (string_of_vectype ret) inl fnname
      Format.printf "%s %s@,%s (%s __a)" (string_of_vectype ret) inl fnname
                                        (string_of_vectype arg0)
                                        (string_of_vectype arg0)
  | Arity2 (ret, arg0, arg1) ->
  | Arity2 (ret, arg0, arg1) ->
      Format.printf "%s %s@,%s (%s __a, %s __b)"
      Format.printf "%s %s@,%s (%s __a, %s __b)"
        (string_of_vectype ret) inl fnname (string_of_vectype arg0)
        (string_of_vectype ret) inl fnname (string_of_vectype arg0)
        (string_of_vectype arg1)
        (string_of_vectype arg1)
  | Arity3 (ret, arg0, arg1, arg2) ->
  | Arity3 (ret, arg0, arg1, arg2) ->
      Format.printf "%s %s@,%s (%s __a, %s __b, %s __c)"
      Format.printf "%s %s@,%s (%s __a, %s __b, %s __c)"
        (string_of_vectype ret) inl fnname (string_of_vectype arg0)
        (string_of_vectype ret) inl fnname (string_of_vectype arg0)
        (string_of_vectype arg1) (string_of_vectype arg2)
        (string_of_vectype arg1) (string_of_vectype arg2)
  | Arity4 (ret, arg0, arg1, arg2, arg3) ->
  | Arity4 (ret, arg0, arg1, arg2, arg3) ->
      Format.printf "%s %s@,%s (%s __a, %s __b, %s __c, %s __d)"
      Format.printf "%s %s@,%s (%s __a, %s __b, %s __c, %s __d)"
        (string_of_vectype ret) inl fnname (string_of_vectype arg0)
        (string_of_vectype ret) inl fnname (string_of_vectype arg0)
        (string_of_vectype arg1) (string_of_vectype arg2)
        (string_of_vectype arg1) (string_of_vectype arg2)
        (string_of_vectype arg3)
        (string_of_vectype arg3)
  end;
  end;
  open_braceblock ffmt;
  open_braceblock ffmt;
  let rec print_lines = function
  let rec print_lines = function
    [] -> ()
    [] -> ()
  | [line] -> Format.printf "%s" line
  | [line] -> Format.printf "%s" line
  | line::lines -> Format.printf "%s@," line; print_lines lines in
  | line::lines -> Format.printf "%s@," line; print_lines lines in
  print_lines body;
  print_lines body;
  close_braceblock ffmt;
  close_braceblock ffmt;
  end_function ffmt
  end_function ffmt
let return_by_ptr features = List.mem ReturnPtr features
let return_by_ptr features = List.mem ReturnPtr features
let union_string num elts base =
let union_string num elts base =
  let itype = inttype_for_array num elts in
  let itype = inttype_for_array num elts in
  let iname = string_of_inttype itype
  let iname = string_of_inttype itype
  and sname = string_of_vectype (T_arrayof (num, elts)) in
  and sname = string_of_vectype (T_arrayof (num, elts)) in
  Printf.sprintf "union { %s __i; %s __o; } %s" sname iname base
  Printf.sprintf "union { %s __i; %s __o; } %s" sname iname base
let rec signed_ctype = function
let rec signed_ctype = function
    T_uint8x8 | T_poly8x8 -> T_int8x8
    T_uint8x8 | T_poly8x8 -> T_int8x8
  | T_uint8x16 | T_poly8x16 -> T_int8x16
  | T_uint8x16 | T_poly8x16 -> T_int8x16
  | T_uint16x4 | T_poly16x4 -> T_int16x4
  | T_uint16x4 | T_poly16x4 -> T_int16x4
  | T_uint16x8 | T_poly16x8 -> T_int16x8
  | T_uint16x8 | T_poly16x8 -> T_int16x8
  | T_uint32x2 -> T_int32x2
  | T_uint32x2 -> T_int32x2
  | T_uint32x4 -> T_int32x4
  | T_uint32x4 -> T_int32x4
  | T_uint64x1 -> T_int64x1
  | T_uint64x1 -> T_int64x1
  | T_uint64x2 -> T_int64x2
  | T_uint64x2 -> T_int64x2
  (* Cast to types defined by mode in arm.c, not random types pulled in from
  (* Cast to types defined by mode in arm.c, not random types pulled in from
     the  header in use. This fixes incompatible pointer errors when
     the  header in use. This fixes incompatible pointer errors when
     compiling with C++.  *)
     compiling with C++.  *)
  | T_uint8 | T_int8 -> T_intQI
  | T_uint8 | T_int8 -> T_intQI
  | T_uint16 | T_int16 -> T_intHI
  | T_uint16 | T_int16 -> T_intHI
  | T_uint32 | T_int32 -> T_intSI
  | T_uint32 | T_int32 -> T_intSI
  | T_uint64 | T_int64 -> T_intDI
  | T_uint64 | T_int64 -> T_intDI
  | T_float32 -> T_floatSF
  | T_float32 -> T_floatSF
  | T_poly8 -> T_intQI
  | T_poly8 -> T_intQI
  | T_poly16 -> T_intHI
  | T_poly16 -> T_intHI
  | T_arrayof (n, elt) -> T_arrayof (n, signed_ctype elt)
  | T_arrayof (n, elt) -> T_arrayof (n, signed_ctype elt)
  | T_ptrto elt -> T_ptrto (signed_ctype elt)
  | T_ptrto elt -> T_ptrto (signed_ctype elt)
  | T_const elt -> T_const (signed_ctype elt)
  | T_const elt -> T_const (signed_ctype elt)
  | x -> x
  | x -> x
let add_cast ctype cval =
let add_cast ctype cval =
  let stype = signed_ctype ctype in
  let stype = signed_ctype ctype in
  if ctype <> stype then
  if ctype <> stype then
    Printf.sprintf "(%s) %s" (string_of_vectype stype) cval
    Printf.sprintf "(%s) %s" (string_of_vectype stype) cval
  else
  else
    cval
    cval
let cast_for_return to_ty = "(" ^ (string_of_vectype to_ty) ^ ")"
let cast_for_return to_ty = "(" ^ (string_of_vectype to_ty) ^ ")"
(* Return a tuple of a list of declarations to go at the start of the function,
(* Return a tuple of a list of declarations to go at the start of the function,
   and a list of statements needed to return THING.  *)
   and a list of statements needed to return THING.  *)
let return arity return_by_ptr thing =
let return arity return_by_ptr thing =
  match arity with
  match arity with
    Arity0 (ret) | Arity1 (ret, _) | Arity2 (ret, _, _) | Arity3 (ret, _, _, _)
    Arity0 (ret) | Arity1 (ret, _) | Arity2 (ret, _, _) | Arity3 (ret, _, _, _)
  | Arity4 (ret, _, _, _, _) ->
  | Arity4 (ret, _, _, _, _) ->
    match ret with
    match ret with
      T_arrayof (num, vec) ->
      T_arrayof (num, vec) ->
        if return_by_ptr then
        if return_by_ptr then
          let sname = string_of_vectype ret in
          let sname = string_of_vectype ret in
          [Printf.sprintf "%s __rv;" sname],
          [Printf.sprintf "%s __rv;" sname],
          [thing ^ ";"; "return __rv;"]
          [thing ^ ";"; "return __rv;"]
        else
        else
          let uname = union_string num vec "__rv" in
          let uname = union_string num vec "__rv" in
          [uname ^ ";"], ["__rv.__o = " ^ thing ^ ";"; "return __rv.__i;"]
          [uname ^ ";"], ["__rv.__o = " ^ thing ^ ";"; "return __rv.__i;"]
    | T_void -> [], [thing ^ ";"]
    | T_void -> [], [thing ^ ";"]
    | _ ->
    | _ ->
        [], ["return " ^ (cast_for_return ret) ^ thing ^ ";"]
        [], ["return " ^ (cast_for_return ret) ^ thing ^ ";"]
let rec element_type ctype =
let rec element_type ctype =
  match ctype with
  match ctype with
    T_arrayof (_, v) -> element_type v
    T_arrayof (_, v) -> element_type v
  | _ -> ctype
  | _ -> ctype
let params return_by_ptr ps =
let params return_by_ptr ps =
  let pdecls = ref [] in
  let pdecls = ref [] in
  let ptype t p =
  let ptype t p =
    match t with
    match t with
      T_arrayof (num, elts) ->
      T_arrayof (num, elts) ->
        let uname = union_string num elts (p ^ "u") in
        let uname = union_string num elts (p ^ "u") in
        let decl = Printf.sprintf "%s = { %s };" uname p in
        let decl = Printf.sprintf "%s = { %s };" uname p in
        pdecls := decl :: !pdecls;
        pdecls := decl :: !pdecls;
        p ^ "u.__o"
        p ^ "u.__o"
    | _ -> add_cast t p in
    | _ -> add_cast t p in
  let plist = match ps with
  let plist = match ps with
    Arity0 _ -> []
    Arity0 _ -> []
  | Arity1 (_, t1) -> [ptype t1 "__a"]
  | Arity1 (_, t1) -> [ptype t1 "__a"]
  | Arity2 (_, t1, t2) -> [ptype t1 "__a"; ptype t2 "__b"]
  | Arity2 (_, t1, t2) -> [ptype t1 "__a"; ptype t2 "__b"]
  | Arity3 (_, t1, t2, t3) -> [ptype t1 "__a"; ptype t2 "__b"; ptype t3 "__c"]
  | Arity3 (_, t1, t2, t3) -> [ptype t1 "__a"; ptype t2 "__b"; ptype t3 "__c"]
  | Arity4 (_, t1, t2, t3, t4) ->
  | Arity4 (_, t1, t2, t3, t4) ->
      [ptype t1 "__a"; ptype t2 "__b"; ptype t3 "__c"; ptype t4 "__d"] in
      [ptype t1 "__a"; ptype t2 "__b"; ptype t3 "__c"; ptype t4 "__d"] in
  match ps with
  match ps with
    Arity0 ret | Arity1 (ret, _) | Arity2 (ret, _, _) | Arity3 (ret, _, _, _)
    Arity0 ret | Arity1 (ret, _) | Arity2 (ret, _, _) | Arity3 (ret, _, _, _)
  | Arity4 (ret, _, _, _, _) ->
  | Arity4 (ret, _, _, _, _) ->
      if return_by_ptr then
      if return_by_ptr then
        !pdecls, add_cast (T_ptrto (element_type ret)) "&__rv.val[0]" :: plist
        !pdecls, add_cast (T_ptrto (element_type ret)) "&__rv.val[0]" :: plist
      else
      else
        !pdecls, plist
        !pdecls, plist
let modify_params features plist =
let modify_params features plist =
  let is_flipped =
  let is_flipped =
    List.exists (function Flipped _ -> true | _ -> false) features in
    List.exists (function Flipped _ -> true | _ -> false) features in
  if is_flipped then
  if is_flipped then
    match plist with
    match plist with
      [ a; b ] -> [ b; a ]
      [ a; b ] -> [ b; a ]
    | _ ->
    | _ ->
      failwith ("Don't know how to flip args " ^ (String.concat ", " plist))
      failwith ("Don't know how to flip args " ^ (String.concat ", " plist))
  else
  else
    plist
    plist
(* !!! Decide whether to add an extra information word based on the shape
(* !!! Decide whether to add an extra information word based on the shape
   form.  *)
   form.  *)
let extra_word shape features paramlist bits =
let extra_word shape features paramlist bits =
  let use_word =
  let use_word =
    match shape with
    match shape with
      All _ | Long | Long_noreg _ | Wide | Wide_noreg _ | Narrow
      All _ | Long | Long_noreg _ | Wide | Wide_noreg _ | Narrow
    | By_scalar _ | Wide_scalar | Wide_lane | Binary_imm _ | Long_imm
    | By_scalar _ | Wide_scalar | Wide_lane | Binary_imm _ | Long_imm
    | Narrow_imm -> true
    | Narrow_imm -> true
    | _ -> List.mem InfoWord features
    | _ -> List.mem InfoWord features
  in
  in
    if use_word then
    if use_word then
      paramlist @ [string_of_int bits]
      paramlist @ [string_of_int bits]
    else
    else
      paramlist
      paramlist
(* Bit 0 represents signed (1) vs unsigned (0), or float (1) vs poly (0).
(* Bit 0 represents signed (1) vs unsigned (0), or float (1) vs poly (0).
   Bit 1 represents floats & polynomials (1), or ordinary integers (0).
   Bit 1 represents floats & polynomials (1), or ordinary integers (0).
   Bit 2 represents rounding (1) vs none (0).  *)
   Bit 2 represents rounding (1) vs none (0).  *)
let infoword_value elttype features =
let infoword_value elttype features =
  let bits01 =
  let bits01 =
    match elt_class elttype with
    match elt_class elttype with
      Signed | ConvClass (Signed, _) | ConvClass (_, Signed) -> 0b001
      Signed | ConvClass (Signed, _) | ConvClass (_, Signed) -> 0b001
    | Poly -> 0b010
    | Poly -> 0b010
    | Float -> 0b011
    | Float -> 0b011
    | _ -> 0b000
    | _ -> 0b000
  and rounding_bit = if List.mem Rounding features then 0b100 else 0b000 in
  and rounding_bit = if List.mem Rounding features then 0b100 else 0b000 in
  bits01 lor rounding_bit
  bits01 lor rounding_bit
(* "Cast" type operations will throw an exception in mode_of_elt (actually in
(* "Cast" type operations will throw an exception in mode_of_elt (actually in
   elt_width, called from there). Deal with that here, and generate a suffix
   elt_width, called from there). Deal with that here, and generate a suffix
   with multiple modes ().  *)
   with multiple modes ().  *)
let rec mode_suffix elttype shape =
let rec mode_suffix elttype shape =
  try
  try
    let mode = mode_of_elt elttype shape in
    let mode = mode_of_elt elttype shape in
    string_of_mode mode
    string_of_mode mode
  with MixedMode (dst, src) ->
  with MixedMode (dst, src) ->
    let dstmode = mode_of_elt dst shape
    let dstmode = mode_of_elt dst shape
    and srcmode = mode_of_elt src shape in
    and srcmode = mode_of_elt src shape in
    string_of_mode dstmode ^ string_of_mode srcmode
    string_of_mode dstmode ^ string_of_mode srcmode
let print_variant opcode features shape name (ctype, asmtype, elttype) =
let print_variant opcode features shape name (ctype, asmtype, elttype) =
  let bits = infoword_value elttype features in
  let bits = infoword_value elttype features in
  let modesuf = mode_suffix elttype shape in
  let modesuf = mode_suffix elttype shape in
  let return_by_ptr = return_by_ptr features in
  let return_by_ptr = return_by_ptr features in
  let pdecls, paramlist = params return_by_ptr ctype in
  let pdecls, paramlist = params return_by_ptr ctype in
  let paramlist' = modify_params features paramlist in
  let paramlist' = modify_params features paramlist in
  let paramlist'' = extra_word shape features paramlist' bits in
  let paramlist'' = extra_word shape features paramlist' bits in
  let parstr = String.concat ", " paramlist'' in
  let parstr = String.concat ", " paramlist'' in
  let builtin = Printf.sprintf "__builtin_neon_%s%s (%s)"
  let builtin = Printf.sprintf "__builtin_neon_%s%s (%s)"
                  (builtin_name features name) modesuf parstr in
                  (builtin_name features name) modesuf parstr in
  let rdecls, stmts = return ctype return_by_ptr builtin in
  let rdecls, stmts = return ctype return_by_ptr builtin in
  let body = pdecls @ rdecls @ stmts
  let body = pdecls @ rdecls @ stmts
  and fnname = (intrinsic_name name) ^ "_" ^ (string_of_elt elttype) in
  and fnname = (intrinsic_name name) ^ "_" ^ (string_of_elt elttype) in
  print_function ctype fnname body
  print_function ctype fnname body
(* When this function processes the element types in the ops table, it rewrites
(* When this function processes the element types in the ops table, it rewrites
   them in a list of tuples (a,b,c):
   them in a list of tuples (a,b,c):
     a : C type as an "arity", e.g. Arity1 (T_poly8x8, T_poly8x8)
     a : C type as an "arity", e.g. Arity1 (T_poly8x8, T_poly8x8)
     b : Asm type : a single, processed element type, e.g. P16. This is the
     b : Asm type : a single, processed element type, e.g. P16. This is the
         type which should be attached to the asm opcode.
         type which should be attached to the asm opcode.
     c : Variant type : the unprocessed type for this variant (e.g. in add
     c : Variant type : the unprocessed type for this variant (e.g. in add
         instructions which don't care about the sign, b might be i16 and c
         instructions which don't care about the sign, b might be i16 and c
         might be s16.)
         might be s16.)
*)
*)
let print_op (opcode, features, shape, name, munge, types) =
let print_op (opcode, features, shape, name, munge, types) =
  let sorted_types = List.sort compare types in
  let sorted_types = List.sort compare types in
  let munged_types = List.map
  let munged_types = List.map
    (fun elt -> let c, asm = munge shape elt in c, asm, elt) sorted_types in
    (fun elt -> let c, asm = munge shape elt in c, asm, elt) sorted_types in
  List.iter
  List.iter
    (fun variant -> print_variant opcode features shape name variant)
    (fun variant -> print_variant opcode features shape name variant)
    munged_types
    munged_types
let print_ops ops =
let print_ops ops =
  List.iter print_op ops
  List.iter print_op ops
(* Output type definitions. Table entries are:
(* Output type definitions. Table entries are:
     cbase : "C" name for the type.
     cbase : "C" name for the type.
     abase : "ARM" base name for the type (i.e. int in int8x8_t).
     abase : "ARM" base name for the type (i.e. int in int8x8_t).
     esize : element size.
     esize : element size.
     enum : element count.
     enum : element count.
*)
*)
let deftypes () =
let deftypes () =
  let typeinfo = [
  let typeinfo = [
    (* Doubleword vector types.  *)
    (* Doubleword vector types.  *)
    "__builtin_neon_qi", "int", 8, 8;
    "__builtin_neon_qi", "int", 8, 8;
    "__builtin_neon_hi", "int", 16, 4;
    "__builtin_neon_hi", "int", 16, 4;
    "__builtin_neon_si", "int", 32, 2;
    "__builtin_neon_si", "int", 32, 2;
    "__builtin_neon_di", "int", 64, 1;
    "__builtin_neon_di", "int", 64, 1;
    "__builtin_neon_sf", "float", 32, 2;
    "__builtin_neon_sf", "float", 32, 2;
    "__builtin_neon_poly8", "poly", 8, 8;
    "__builtin_neon_poly8", "poly", 8, 8;
    "__builtin_neon_poly16", "poly", 16, 4;
    "__builtin_neon_poly16", "poly", 16, 4;
    "__builtin_neon_uqi", "uint", 8, 8;
    "__builtin_neon_uqi", "uint", 8, 8;
    "__builtin_neon_uhi", "uint", 16, 4;
    "__builtin_neon_uhi", "uint", 16, 4;
    "__builtin_neon_usi", "uint", 32, 2;
    "__builtin_neon_usi", "uint", 32, 2;
    "__builtin_neon_udi", "uint", 64, 1;
    "__builtin_neon_udi", "uint", 64, 1;
    (* Quadword vector types.  *)
    (* Quadword vector types.  *)
    "__builtin_neon_qi", "int", 8, 16;
    "__builtin_neon_qi", "int", 8, 16;
    "__builtin_neon_hi", "int", 16, 8;
    "__builtin_neon_hi", "int", 16, 8;
    "__builtin_neon_si", "int", 32, 4;
    "__builtin_neon_si", "int", 32, 4;
    "__builtin_neon_di", "int", 64, 2;
    "__builtin_neon_di", "int", 64, 2;
    "__builtin_neon_sf", "float", 32, 4;
    "__builtin_neon_sf", "float", 32, 4;
    "__builtin_neon_poly8", "poly", 8, 16;
    "__builtin_neon_poly8", "poly", 8, 16;
    "__builtin_neon_poly16", "poly", 16, 8;
    "__builtin_neon_poly16", "poly", 16, 8;
    "__builtin_neon_uqi", "uint", 8, 16;
    "__builtin_neon_uqi", "uint", 8, 16;
    "__builtin_neon_uhi", "uint", 16, 8;
    "__builtin_neon_uhi", "uint", 16, 8;
    "__builtin_neon_usi", "uint", 32, 4;
    "__builtin_neon_usi", "uint", 32, 4;
    "__builtin_neon_udi", "uint", 64, 2
    "__builtin_neon_udi", "uint", 64, 2
  ] in
  ] in
  List.iter
  List.iter
    (fun (cbase, abase, esize, enum) ->
    (fun (cbase, abase, esize, enum) ->
      let attr =
      let attr =
        match enum with
        match enum with
          1 -> ""
          1 -> ""
        | _ -> Printf.sprintf "\t__attribute__ ((__vector_size__ (%d)))"
        | _ -> Printf.sprintf "\t__attribute__ ((__vector_size__ (%d)))"
                              (esize * enum / 8) in
                              (esize * enum / 8) in
      Format.printf "typedef %s %s%dx%d_t%s;@\n" cbase abase esize enum attr)
      Format.printf "typedef %s %s%dx%d_t%s;@\n" cbase abase esize enum attr)
    typeinfo;
    typeinfo;
  Format.print_newline ();
  Format.print_newline ();
  (* Extra types not in .  *)
  (* Extra types not in .  *)
  Format.printf "typedef float float32_t;\n";
  Format.printf "typedef float float32_t;\n";
  Format.printf "typedef __builtin_neon_poly8 poly8_t;\n";
  Format.printf "typedef __builtin_neon_poly8 poly8_t;\n";
  Format.printf "typedef __builtin_neon_poly16 poly16_t;\n"
  Format.printf "typedef __builtin_neon_poly16 poly16_t;\n"
(* Output structs containing arrays, for load & store instructions etc.  *)
(* Output structs containing arrays, for load & store instructions etc.  *)
let arrtypes () =
let arrtypes () =
  let typeinfo = [
  let typeinfo = [
    "int", 8;    "int", 16;
    "int", 8;    "int", 16;
    "int", 32;   "int", 64;
    "int", 32;   "int", 64;
    "uint", 8;   "uint", 16;
    "uint", 8;   "uint", 16;
    "uint", 32;  "uint", 64;
    "uint", 32;  "uint", 64;
    "float", 32; "poly", 8;
    "float", 32; "poly", 8;
    "poly", 16
    "poly", 16
  ] in
  ] in
  let writestruct elname elsize regsize arrsize =
  let writestruct elname elsize regsize arrsize =
    let elnum = regsize / elsize in
    let elnum = regsize / elsize in
    let structname =
    let structname =
      Printf.sprintf "%s%dx%dx%d_t" elname elsize elnum arrsize in
      Printf.sprintf "%s%dx%dx%d_t" elname elsize elnum arrsize in
    let sfmt = start_function () in
    let sfmt = start_function () in
    Format.printf "typedef struct %s" structname;
    Format.printf "typedef struct %s" structname;
    open_braceblock sfmt;
    open_braceblock sfmt;
    Format.printf "%s%dx%d_t val[%d];" elname elsize elnum arrsize;
    Format.printf "%s%dx%d_t val[%d];" elname elsize elnum arrsize;
    close_braceblock sfmt;
    close_braceblock sfmt;
    Format.printf " %s;" structname;
    Format.printf " %s;" structname;
    end_function sfmt;
    end_function sfmt;
  in
  in
    for n = 2 to 4 do
    for n = 2 to 4 do
      List.iter
      List.iter
        (fun (elname, elsize) ->
        (fun (elname, elsize) ->
          writestruct elname elsize 64 n;
          writestruct elname elsize 64 n;
          writestruct elname elsize 128 n)
          writestruct elname elsize 128 n)
        typeinfo
        typeinfo
    done
    done
let print_lines = List.iter (fun s -> Format.printf "%s@\n" s)
let print_lines = List.iter (fun s -> Format.printf "%s@\n" s)
(* Do it.  *)
(* Do it.  *)
let _ =
let _ =
  print_lines [
  print_lines [
"/* ARM NEON intrinsics include file. This file is generated automatically";
"/* ARM NEON intrinsics include file. This file is generated automatically";
"   using neon-gen.ml.  Please do not edit manually.";
"   using neon-gen.ml.  Please do not edit manually.";
"";
"";
"   Copyright (C) 2006, 2007, 2009 Free Software Foundation, Inc.";
"   Copyright (C) 2006, 2007, 2009 Free Software Foundation, Inc.";
"   Contributed by CodeSourcery.";
"   Contributed by CodeSourcery.";
"";
"";
"   This file is part of GCC.";
"   This file is part of GCC.";
"";
"";
"   GCC is free software; you can redistribute it and/or modify it";
"   GCC is free software; you can redistribute it and/or modify it";
"   under the terms of the GNU General Public License as published";
"   under the terms of the GNU General Public License as published";
"   by the Free Software Foundation; either version 3, or (at your";
"   by the Free Software Foundation; either version 3, or (at your";
"   option) any later version.";
"   option) any later version.";
"";
"";
"   GCC is distributed in the hope that it will be useful, but WITHOUT";
"   GCC is distributed in the hope that it will be useful, but WITHOUT";
"   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY";
"   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY";
"   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public";
"   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public";
"   License for more details.";
"   License for more details.";
"";
"";
"   Under Section 7 of GPL version 3, you are granted additional";
"   Under Section 7 of GPL version 3, you are granted additional";
"   permissions described in the GCC Runtime Library Exception, version";
"   permissions described in the GCC Runtime Library Exception, version";
"   3.1, as published by the Free Software Foundation.";
"   3.1, as published by the Free Software Foundation.";
"";
"";
"   You should have received a copy of the GNU General Public License and";
"   You should have received a copy of the GNU General Public License and";
"   a copy of the GCC Runtime Library Exception along with this program;";
"   a copy of the GCC Runtime Library Exception along with this program;";
"   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see";
"   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see";
"   .  */";
"   .  */";
"";
"";
"#ifndef _GCC_ARM_NEON_H";
"#ifndef _GCC_ARM_NEON_H";
"#define _GCC_ARM_NEON_H 1";
"#define _GCC_ARM_NEON_H 1";
"";
"";
"#ifndef __ARM_NEON__";
"#ifndef __ARM_NEON__";
"#error You must enable NEON instructions (e.g. -mfloat-abi=softfp -mfpu=neon) to use arm_neon.h";
"#error You must enable NEON instructions (e.g. -mfloat-abi=softfp -mfpu=neon) to use arm_neon.h";
"#else";
"#else";
"";
"";
"#ifdef __cplusplus";
"#ifdef __cplusplus";
"extern \"C\" {";
"extern \"C\" {";
"#endif";
"#endif";
"";
"";
"#include ";
"#include ";
""];
""];
  deftypes ();
  deftypes ();
  arrtypes ();
  arrtypes ();
  Format.print_newline ();
  Format.print_newline ();
  print_ops ops;
  print_ops ops;
  Format.print_newline ();
  Format.print_newline ();
  print_ops reinterp;
  print_ops reinterp;
  print_lines [
  print_lines [
"#ifdef __cplusplus";
"#ifdef __cplusplus";
"}";
"}";
"#endif";
"#endif";
"#endif";
"#endif";
"#endif"]
"#endif"]
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.