From 2d1baa0c7d4e2557c3652c5519c264b60ffc1aa5 Mon Sep 17 00:00:00 2001 From: Alastair Reid Date: Tue, 28 Apr 2026 12:17:16 +0100 Subject: [PATCH 1/7] .isa grammar: foreign types are specified by name, not type --- libISA/isa_ast.ml | 2 +- libISA/isa_fmt.ml | 2 +- libISA/isa_parser.mly | 6 +++--- libISA/isa_utils.ml | 2 +- libISA/isa_visitor.ml | 6 +++--- libISA/tcheck.ml | 10 +++++++--- 6 files changed, 16 insertions(+), 12 deletions(-) diff --git a/libISA/isa_ast.ml b/libISA/isa_ast.ml index cc1a1849..4d0d1418 100644 --- a/libISA/isa_ast.ml +++ b/libISA/isa_ast.ml @@ -193,7 +193,7 @@ declaration = | Decl_FunInstance of Ident.t * (Ident.t * Value.value option) list * Loc.t | Decl_FunFFI of string * bool * Ident.t * (Ident.t * Value.value) list * Loc.t | Decl_VarFFI of string * bool * Ident.t * Loc.t - | Decl_TypeFFI of string * bool * ty * Loc.t + | Decl_TypeFFI of string * bool * Ident.t * Loc.t | Decl_Operator1 of unop * Ident.t list * Loc.t | Decl_Operator2 of binop * Ident.t list * Loc.t | Decl_Config of Ident.t * ty * expr * Loc.t diff --git a/libISA/isa_fmt.ml b/libISA/isa_fmt.ml index 3ce1cd7e..6590f4ab 100644 --- a/libISA/isa_fmt.ml +++ b/libISA/isa_fmt.ml @@ -920,7 +920,7 @@ let declaration ?(short=false) (fmt : PP.formatter) (x : AST.declaration) : unit ffi_direction is_export kw_type nm - ty t + tycon t | Decl_Operator1 (op, fs, loc) -> kw_underscore_operator1 fmt; nbsp fmt; diff --git a/libISA/isa_parser.mly b/libISA/isa_parser.mly index fd0e5a7a..b18baf51 100644 --- a/libISA/isa_parser.mly +++ b/libISA/isa_parser.mly @@ -679,9 +679,9 @@ let ffi_definition := | "foreign"; is_export=ffi_direction; "var"; nm=STRINGLIT; "="; v=path; ";"; { Decl_VarFFI(nm, is_export, v, Range($symbolstartpos, $endpos)) } - | "foreign"; is_export=ffi_direction; - "type"; nm=STRINGLIT; "="; t=ty; ";"; - { Decl_TypeFFI(nm, is_export, t, Range($symbolstartpos, $endpos)) } + | "foreign"; "export"; (* foreign import of types not currently supported *) + "type"; nm=STRINGLIT; "="; t=path; ";"; + { Decl_TypeFFI(nm, true, t, Range($symbolstartpos, $endpos)) } let ffi_parameter_value := | p = ident ; "=>" ; v = literal_expression ; { (p, v) } diff --git a/libISA/isa_utils.ml b/libISA/isa_utils.ml index 151ac987..668b4fed 100644 --- a/libISA/isa_utils.ml +++ b/libISA/isa_utils.ml @@ -513,7 +513,7 @@ let decl_name (x : declaration) : Ident.t option = | Decl_FunInstance (f, _, loc) -> Some f | Decl_FunFFI (nm, is_export, f, _, loc) -> Some f | Decl_VarFFI (nm, is_export, v, loc) -> Some v - | Decl_TypeFFI (nm, is_export, t, loc) -> None + | Decl_TypeFFI (nm, is_export, t, loc) -> Some t | Decl_Operator1 (op, vs, loc) -> None | Decl_Operator2 (op, vs, loc) -> None | Decl_Config (v, ty, e, loc) -> Some v diff --git a/libISA/isa_visitor.ml b/libISA/isa_visitor.ml index 8139b711..fe4e22ba 100644 --- a/libISA/isa_visitor.ml +++ b/libISA/isa_visitor.ml @@ -665,9 +665,9 @@ let visit_decl (vis : isaVisitor) (x : declaration) : declaration = | Decl_VarFFI (nm, is_export, v, loc) -> let v' = visit_var vis Definition v in if v == v' then x else Decl_VarFFI (nm, is_export, v', loc) - | Decl_TypeFFI (nm, is_export, t, loc) -> - let t' = visit_type vis t in - if t == t' then x else Decl_TypeFFI (nm, is_export, t', loc) + | Decl_TypeFFI (nm, is_export, tc, loc) -> + let tc' = visit_var vis Definition tc in + if tc == tc' then x else Decl_TypeFFI (nm, is_export, tc', loc) | Decl_Operator1 (op, vs, loc) -> let vs' = mapNoCopy (visit_var vis Definition) vs in if vs == vs' then x else Decl_Operator1 (op, vs', loc) diff --git a/libISA/tcheck.ml b/libISA/tcheck.ml index 4ba20582..43bc0bec 100644 --- a/libISA/tcheck.ml +++ b/libISA/tcheck.ml @@ -3293,9 +3293,13 @@ let tc_declaration (env : GlobalEnv.t) (d : AST.declaration) : | Decl_VarFFI (nm, is_export, v, loc) -> let v' = get_var (Env.mkEnv env) loc v in [ Decl_VarFFI (nm, is_export, v'.name, loc) ] - | Decl_TypeFFI (nm, is_export, t, loc) -> - let t' = tc_type (Env.mkEnv env) loc t in - [ Decl_TypeFFI (nm, is_export, t', loc) ] + | Decl_TypeFFI (nm, is_export, tc, loc) -> + let tc' = GlobalEnv.renameType env tc in + if (tc' = Builtin_idents.sintN) || (GlobalEnv.isTycon env tc') then ( + [ Decl_TypeFFI (nm, is_export, tc', loc) ] + ) else ( + raise (IsNotA (loc, "type constructor", Ident.to_string tc)) + ) | Decl_Operator1 (op, funs, loc) -> let funs' = List.concat From feaf1028162d832e260fceb47d8aa8eb887c4a6f Mon Sep 17 00:00:00 2001 From: Alastair Reid Date: Wed, 29 Apr 2026 11:33:35 +0100 Subject: [PATCH 2/7] FFI: Make foreign type/var work without config files In several places, support for foreign types such as enums and for foreign variables was incomplete and did not work if you replaced the configuration json file with the new .isa foreign import/export declarations. --- bin/iii.ml | 9 ++-- libISA/backend_c.ml | 113 ++++++++++++++++++++++++-------------------- 2 files changed, 65 insertions(+), 57 deletions(-) diff --git a/bin/iii.ml b/bin/iii.ml index 3f33bfae..6731291e 100644 --- a/bin/iii.ml +++ b/bin/iii.ml @@ -199,12 +199,9 @@ let read_foreign_idents (export : bool) (ds : AST.declaration list) : Ident.t list = List.filter_map (fun d -> match d with - | Decl_FunFFI (nm, is_export, f, [], loc) when is_export = export -> Some f - | Decl_FunFFI (nm, is_export, f, ps, loc) when is_export = export -> - let name = Ident.name_with_tag f in - raise (Utils.InternalError - (loc, Format.asprintf "No specialized function '%s' created" name, - (fun fmt -> FMT.declaration fmt d), __LOC__ )) + | Decl_FunFFI (nm, is_export, f, _, loc) when is_export = export -> Some f + | Decl_VarFFI (nm, is_export, f, loc) when is_export = export -> Some f + | Decl_TypeFFI (nm, is_export, f, loc) when is_export = export -> Some f | _ -> None ) ds diff --git a/libISA/backend_c.ml b/libISA/backend_c.ml index d25f4cc2..a6fed9e7 100644 --- a/libISA/backend_c.ml +++ b/libISA/backend_c.ml @@ -1569,7 +1569,7 @@ let mk_ffi_conversion (loc : Loc.t) (indirect : bool) (c_name : Ident.t) (asl_na when Ident.equal f cvt_sintN_int -> mk_ffi_convert_large_bits (Z.to_int n.v) | _ -> - let msg = PP.asprintf "Type '%a' cannot be used in functions that are imported or exported between ASL and C" + let msg = PP.asprintf "Type '%a' cannot be used in functions that are imported from or exported to C" FMT.ty asl_type in raise (Error.TypeError (loc, msg)) @@ -1908,26 +1908,62 @@ let mk_ffi_import_wrapper (pp_proto, pp_wrapper) +(* Make list of foreign import/export pairs based either on old-style config files + * or new-style foreign import/export declarations. + *) +let get_ffi (get_exports : bool) (decls : AST.declaration list) : (string * Ident.t) list = + (* old-style imports/exports are specified via a configuration json file *) + let key = if get_exports then "exports" else "imports" in + let raw_exports = if !new_ffi then Configuration.get_strings key else [] in + let old_exports = List.filter_map (fun d -> + ( match d with + | AST.Decl_Record (x, _, _, _) + | AST.Decl_Enum (x, _, _) + | AST.Decl_Var (x, _, _) + | AST.Decl_Config (x, _, _, _) + | AST.Decl_Const (x, _, _, _) + | AST.Decl_FunType (x, _, _) + when List.mem (Ident.name x) raw_exports + -> Some (Ident.name x, x) + | _ + -> None + )) + decls + in + + (* new-style imports/exports are specified using foreign import/export declarations *) + let new_exports = List.filter_map (fun d -> + ( match d with + | AST.Decl_FunFFI (nm, is_export, x, _, _) + | AST.Decl_TypeFFI (nm, is_export, x, _) + when is_export = get_exports + -> Some (nm, x) + | _ + -> None + )) decls + in + old_exports @ new_exports + + let mk_ffi_infos (is_import : bool) (decl_map : AST.declaration list Bindings.t) - (c_names : string list) : + (xs : (string * Ident.t) list) : (Ident.t * Ident.t * AST.function_type * Loc.t) list = let missing : string list ref = ref [] in - let infos = List.filter_map (fun c_name -> - let asl_ident = Ident.mk_fident c_name in + let infos = List.filter_map (fun (c_name, isa_ident) -> let c_ident = Ident.mk_ident c_name in - let info = ( match Bindings.find_opt asl_ident decl_map with + let info = ( match Bindings.find_opt isa_ident decl_map with | Some ds -> ( match List.find_opt (function AST.Decl_FunType _ -> true | _ -> false) ds with - | Some (AST.Decl_FunType (_, fty, loc)) -> Some (c_ident, asl_ident, fty, loc) + | Some (AST.Decl_FunType (_, fty, loc)) -> Some (c_ident, isa_ident, fty, loc) | _ -> None ) | _ -> None ) in - if Option.is_none info && not (is_enumerated_type c_ident) then begin + if Option.is_none info && not (is_enumerated_type isa_ident) then begin missing := c_name :: !missing end; info - ) c_names + ) xs in if not (Utils.is_empty !missing) then begin let direction = if is_import then "Import" else "Export" in @@ -1936,32 +1972,6 @@ let mk_ffi_infos (is_import : bool) (decl_map : AST.declaration list Bindings.t) end; infos -let mk_new_ffi_infos (is_import : bool) - (decl_map : AST.declaration list Bindings.t) (ds : AST.declaration list) : - (Ident.t * Ident.t * AST.function_type * Loc.t) list = - List.filter_map (fun x -> - match x with - | AST.Decl_FunFFI (nm, is_export, f, ps, loc) when is_export = not is_import -> - let c_ident = Ident.mk_ident nm in - let info = ( match Bindings.find_opt f decl_map with - | Some ds -> - ( match List.find_opt (function AST.Decl_FunType _ -> true | _ -> false) ds with - | Some (AST.Decl_FunType (_, fty, loc)) -> Some (c_ident, f, fty, loc) - | _ -> None - ) - | _ -> None - ) in - if Option.is_none info then begin - let direction = if is_import then "Import" else "Export" in - let pp fmt = FMT.declaration fmt x in - let fname = Ident.name_with_tag f in - raise (InternalError - (loc, PP.asprintf "%sed function '%s' is not defined" direction fname, pp, __LOC__)) - end; - info - | _ -> None) - ds - (* Build ffi wrapper functions *) let mk_ffi_wrappers (is_import : bool) (infos : (Ident.t * Ident.t * AST.function_type * Loc.t) list) : @@ -1987,12 +1997,16 @@ let mk_ffi_wrappers (is_import : bool) let pp_defns fmt : unit = List.iter (fun f -> f fmt) mk_defns in (pp_protos, pp_defns) -let ffi_track_enums (decl_map : (AST.declaration list) Bindings.t) (exports : string list) : unit = - List.iter (fun c_name -> - let c_ident = Ident.mk_ident c_name in - ( match Bindings.find_opt c_ident decl_map with - | Some (Decl_Enum (tc, es, loc) :: _) -> - add_enumerated_type tc es +let ffi_track_enums (decl_map : (AST.declaration list) Bindings.t) (exports : (string * Ident.t) list) : unit = + List.iter (fun (c_name, isa_ident) -> + ( match Bindings.find_opt isa_ident decl_map with + | Some ds -> + List.iter (fun d -> + ( match d with + | AST.Decl_Enum (tc, es, loc) -> add_enumerated_type tc es + | _ -> () + )) + ds | _ -> () )) @@ -2019,7 +2033,7 @@ let config_getter_prefix = "ASL_get_config_" (* Generate ASL functions for reading/writing configuration variables. * These will then be exported so that C code can read/write the variables. *) -let mk_ffi_config (decls : AST.declaration list) : (string list * AST.declaration list) = +let mk_ffi_config (decls : AST.declaration list) : ((string * Ident.t) list * AST.declaration list) = let configs = List.filter_map (fun x -> ( match x with | AST.Decl_Config (v, ty, i, loc) -> Some (v, ty, loc) @@ -2028,7 +2042,7 @@ let mk_ffi_config (decls : AST.declaration list) : (string list * AST.declaratio decls in - let mk_functions ((v, ty, loc) : (Ident.t * AST.ty * Loc.t)) : (string list * AST.declaration list) = + let mk_functions ((v, ty, loc) : (Ident.t * AST.ty * Loc.t)) : ((string * Ident.t) list * AST.declaration list) = let getter_name = config_getter_prefix ^ Ident.name v in let getter_id = Ident.mk_fident getter_name in let getter_fty : AST.function_type = { @@ -2064,7 +2078,7 @@ let mk_ffi_config (decls : AST.declaration list) : (string list * AST.declaratio let setter_defn = AST.Decl_FunDefn (setter_id, setter_fty, setter_body, loc) in let setter_type = AST.Decl_FunType (setter_id, setter_fty, loc) in - ([getter_name; setter_name], [getter_defn; getter_type; setter_defn; setter_type]) + ([(getter_name, getter_id); (setter_name, setter_id)], [getter_defn; getter_type; setter_defn; setter_type]) in let (names, decls) = List.map mk_functions configs |> List.split in @@ -2275,22 +2289,19 @@ let _ = let (cfg_exports, cfg_funs) = mk_ffi_config decls in let decls' = decls @ cfg_funs in let decl_map = Isa_utils.decls_map_of decls' in - let imports = if !new_ffi then Configuration.get_strings "imports" else [] in - let exports = if !new_ffi then Configuration.get_strings "exports" else [] in + + let imports = get_ffi false decls' in + let exports = get_ffi true decls' in ffi_track_enums decl_map exports; ffi_track_return_types decls'; let ffi_import_infos = mk_ffi_infos true decl_map imports in - let new_ffi_import_infos = mk_new_ffi_infos true decl_map decls' in - let (ffi_import_protos, ffi_import_defns) = - mk_ffi_wrappers true (ffi_import_infos @ new_ffi_import_infos) + let (ffi_import_protos, ffi_import_defns) = mk_ffi_wrappers true ffi_import_infos in let ffi_export_infos = mk_ffi_infos false decl_map (cfg_exports @ exports) in - let new_ffi_export_infos = mk_new_ffi_infos false decl_map decls' in - let (ffi_export_protos, ffi_export_defns) = - mk_ffi_wrappers false (ffi_export_infos @ new_ffi_export_infos) + let (ffi_export_protos, ffi_export_defns) = mk_ffi_wrappers false ffi_export_infos in let ffi_protos (fmt : PP.formatter) : unit = From f7b7ec44c1cfb9fbf8549cca02b36c9b805a989e Mon Sep 17 00:00:00 2001 From: Alastair Reid Date: Wed, 29 Apr 2026 11:33:13 +0100 Subject: [PATCH 3/7] IIC: the new FFI requires use of xform_monomorphize --- bin/iic.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/iic.py b/bin/iic.py index dd737d32..9eb49a78 100755 --- a/bin/iic.py +++ b/bin/iic.py @@ -343,6 +343,7 @@ def mk_script(args, output_directory): if args.O0: script = [] script.append(":filter_unlisted_functions imports") + script.append(":xform_monomorphize") script.append(":filter_reachable_from --no-keep-builtins exports") if args.Oarrays: script.append(":xform_arrays") if args.Obounded: script.append(":xform_bounded") From ffa03080d6170c231cdbf2186e1e45c11e45b76a Mon Sep 17 00:00:00 2001 From: Alastair Reid Date: Wed, 29 Apr 2026 11:34:14 +0100 Subject: [PATCH 4/7] tcheck: Treat FFI functions more like function definitions --- libISA/tcheck.ml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libISA/tcheck.ml b/libISA/tcheck.ml index 43bc0bec..3159d862 100644 --- a/libISA/tcheck.ml +++ b/libISA/tcheck.ml @@ -3358,6 +3358,8 @@ let genPrototypes (ds : AST.declaration list) : | Decl_FunDefn (qid, fty, _, loc) -> post := d :: !post; pre := Decl_FunType (qid, fty, loc) :: !pre + | Decl_FunFFI (_, _, _, _, _) -> + post := d :: !post; | _ -> pre := d :: !pre) ds; (List.rev !pre, List.rev !post) From a9001e0470ca647875b511b8bfab497faff18bf9 Mon Sep 17 00:00:00 2001 From: Alastair Reid Date: Tue, 28 Apr 2026 17:16:52 +0100 Subject: [PATCH 5/7] Tests: change to use FFI syntax instead of command line --- tests/backends/ffi_export_00.isa | 5 +++- tests/backends/ffi_export_01.isa | 21 +++++++++++++++- tests/backends/ffi_export_01.json | 26 -------------------- tests/backends/ffi_import_00.isa | 19 ++++++-------- tests/backends/ffi_import_01.isa | 19 +++++++++++++- tests/backends/ffi_import_01.json | 25 ------------------- tests/lit/check_monomorphization/config.json | 5 ---- tests/lit/check_monomorphization/test_00.isa | 4 ++- 8 files changed, 52 insertions(+), 72 deletions(-) delete mode 100644 tests/backends/ffi_export_01.json delete mode 100644 tests/backends/ffi_import_01.json delete mode 100644 tests/lit/check_monomorphization/config.json diff --git a/tests/backends/ffi_export_00.isa b/tests/backends/ffi_export_00.isa index 627d5994..3f89260c 100644 --- a/tests/backends/ffi_export_00.isa +++ b/tests/backends/ffi_export_00.isa @@ -1,8 +1,11 @@ -// RUN: %aslrun %s --import=FFI_Call128 --export=FFI_Extract128_32 --extra-c=%S/ffi_export_00.c | filecheck %s +// RUN: %aslrun %s --extra-c=%S/ffi_export_00.c | filecheck %s // Copyright (C) 2025-2026 Intel Corporation // UNSUPPORTED: interpreter +foreign import function "FFI_Call128" = FFI_Call128 with {}; +foreign export function "FFI_Extract128_32" = FFI_Extract128_32 with {}; + // Function imported from C function FFI_Call128(x : Bits(128)) -> Bits(32); diff --git a/tests/backends/ffi_export_01.isa b/tests/backends/ffi_export_01.isa index 013b0d54..3ad8a26b 100644 --- a/tests/backends/ffi_export_01.isa +++ b/tests/backends/ffi_export_01.isa @@ -1,8 +1,27 @@ -// RUN: %aslrun %s --configuration=%S/ffi_export_01.json --extra-c=%S/ffi_export_01.c | filecheck %s +// RUN: %aslrun %s --extra-c=%S/ffi_export_01.c | filecheck %s // Copyright (C) 2025-2026 Intel Corporation // UNSUPPORTED: interpreter +foreign export type "E" = E; +foreign export function "FFI_bits8" = FFI_bits8 with {}; +foreign export function "FFI_bits16" = FFI_bits16 with {}; +foreign export function "FFI_bits32" = FFI_bits32 with {}; +foreign export function "FFI_bits64" = FFI_bits64 with {}; +foreign export function "FFI_bits2" = FFI_bits2 with {}; +foreign export function "FFI_bits17" = FFI_bits17 with {}; +foreign export function "FFI_bits65" = FFI_bits65 with {}; +foreign export function "FFI_bits127" = FFI_bits127 with {}; +foreign export function "FFI_bits128" = FFI_bits128 with {}; +foreign export function "FFI_string" = FFI_string with {}; +foreign export function "FFI_E" = FFI_E with {}; +foreign export function "FFI_Boolean" = FFI_Boolean with {}; +foreign export function "FFI_integer" = FFI_integer with {}; +foreign export function "FFI_sint17" = FFI_sint17 with {}; +foreign export function "FFI_int_bool" = FFI_int_bool with {}; + +foreign import function "FFI_test_exports" = FFI_test_exports with {}; + enumeration E = { A, B, C }; // to be exported diff --git a/tests/backends/ffi_export_01.json b/tests/backends/ffi_export_01.json deleted file mode 100644 index 1f733fdc..00000000 --- a/tests/backends/ffi_export_01.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "__comment": [ - "Export the interface required by ffi_export_01.c" - ], - "exports": [ - "E", - "FFI_bits8", - "FFI_bits16", - "FFI_bits32", - "FFI_bits64", - "FFI_bits2", - "FFI_bits17", - "FFI_bits65", - "FFI_bits127", - "FFI_bits128", - "FFI_string", - "FFI_E", - "FFI_Boolean", - "FFI_integer", - "FFI_sint17", - "FFI_int_bool" - ], - "imports": [ - "FFI_test_exports" - ] -} diff --git a/tests/backends/ffi_import_00.isa b/tests/backends/ffi_import_00.isa index afaf2637..70ac913e 100644 --- a/tests/backends/ffi_import_00.isa +++ b/tests/backends/ffi_import_00.isa @@ -1,30 +1,25 @@ -// RUN: %aslrun %s --import=FFI_Invert32 --import=FFI_Invert128 --extra-c=%S/ffi_import_00.c | filecheck %s +// RUN: %aslrun %s --extra-c=%S/ffi_import_00.c | filecheck %s // Copyright (C) 2025-2026 Intel Corporation // UNSUPPORTED: interpreter +foreign import function "FFI_Invert32" = FFI_Invert with { size => 32 }; +foreign import function "FFI_Invert128" = FFI_Invert with { size => 128 }; + // The following functions will be replaced by // a version that is defined externally. // Normally, the internal and external version have // similar behaviour but, for testing purposes, the // internal version is the identity function // and the external version inverts its argument. -function FFI_Invert32(x : Bits(32)) -> Bits(32) -begin - return x; -end - -function FFI_Invert128(x : Bits(128)) -> Bits(128) -begin - return x; -end +function FFI_Invert(implicit size : {0..}, x : Bits(size)) -> Bits(size); function main() -> Builtin::Foreign::CInt begin - Std::Print::Bits::Hex(FFI_Invert32(32'x3)); Print("\n"); + Std::Print::Bits::Hex(FFI_Invert(32'x3)); Print("\n"); // CHECK: 32'xfffffffc - Std::Print::Bits::Hex(FFI_Invert128(128'x3)); Print("\n"); + Std::Print::Bits::Hex(FFI_Invert(128'x3)); Print("\n"); // CHECK: 128'xfffffffffffffffffffffffffffffffc return Builtin::Foreign::CInt::From_Integer(0); diff --git a/tests/backends/ffi_import_01.isa b/tests/backends/ffi_import_01.isa index cb1584ff..433c9d54 100644 --- a/tests/backends/ffi_import_01.isa +++ b/tests/backends/ffi_import_01.isa @@ -1,8 +1,25 @@ -// RUN: %aslrun %s --configuration=%S/ffi_import_01.json --extra-c=%S/ffi_import_01.c | filecheck %s +// RUN: %aslrun %s --extra-c=%S/ffi_import_01.c | filecheck %s // Copyright (C) 2025-2026 Intel Corporation // UNSUPPORTED: interpreter +foreign export type "E" = E; +foreign import function "FFI_null_bits8" = FFI_null_bits8 with {}; +foreign import function "FFI_null_bits16" = FFI_null_bits16 with {}; +foreign import function "FFI_null_bits32" = FFI_null_bits32 with {}; +foreign import function "FFI_null_bits64" = FFI_null_bits64 with {}; +foreign import function "FFI_null_bits2" = FFI_null_bits2 with {}; +foreign import function "FFI_null_bits17" = FFI_null_bits17 with {}; +foreign import function "FFI_null_bits65" = FFI_null_bits65 with {}; +foreign import function "FFI_null_bits127" = FFI_null_bits127 with {}; +foreign import function "FFI_null_bits128" = FFI_null_bits128 with {}; +foreign import function "FFI_null_string" = FFI_null_string with {}; +foreign import function "FFI_null_E" = FFI_null_E with {}; +foreign import function "FFI_null_Boolean" = FFI_null_Boolean with {}; +foreign import function "FFI_null_integer" = FFI_null_integer with {}; +foreign import function "FFI_null_sint17" = FFI_null_sint17 with {}; +foreign import function "FFI_int_bool" = FFI_int_bool with {}; + enumeration E = { A, B, C }; // to be defined externally diff --git a/tests/backends/ffi_import_01.json b/tests/backends/ffi_import_01.json deleted file mode 100644 index 3077f6b3..00000000 --- a/tests/backends/ffi_import_01.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "__comment": [ - "Import the interface required by ffi_import_01.asl" - ], - "exports": [ - "E" - ], - "imports": [ - "FFI_null_bits8", - "FFI_null_bits16", - "FFI_null_bits32", - "FFI_null_bits64", - "FFI_null_bits2", - "FFI_null_bits17", - "FFI_null_bits65", - "FFI_null_bits127", - "FFI_null_bits128", - "FFI_null_string", - "FFI_null_E", - "FFI_null_Boolean", - "FFI_null_integer", - "FFI_null_sint17", - "FFI_int_bool" - ] -} diff --git a/tests/lit/check_monomorphization/config.json b/tests/lit/check_monomorphization/config.json deleted file mode 100644 index 6e6570c8..00000000 --- a/tests/lit/check_monomorphization/config.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "exports": [ - "A" - ] -} diff --git a/tests/lit/check_monomorphization/test_00.isa b/tests/lit/check_monomorphization/test_00.isa index 87eb0d2a..0bb13d6a 100644 --- a/tests/lit/check_monomorphization/test_00.isa +++ b/tests/lit/check_monomorphization/test_00.isa @@ -1,4 +1,4 @@ -// RUN: %iii --batchmode --configuration=%S/config.json --project=%S/iii.prj %s | filecheck %s +// RUN: %iii --batchmode --project=%S/iii.prj %s | filecheck %s // Copyright (C) 2024-2026 Intel Corporation function C(x : Bits(N)) -> Integer @@ -16,6 +16,8 @@ begin return B(0b0); end +foreign export function "A" = A with {}; + // CHECK: WARNING: Bitwidth parameters are not statically known in the following definitions. // CHECK-NEXT: This will cause code generation to fail. // From 1db4d71a8262c87fd50b88abdc98a76a2f2687d1 Mon Sep 17 00:00:00 2001 From: Alastair Reid Date: Mon, 17 Aug 2026 16:04:05 +0100 Subject: [PATCH 6/7] FFI: map SInt(N) to int64_t (if selected) The FFI was mapping SInt(N) to 'int' even when it was mapping Integer to int64_t. This caused problems because enabling -Obounded was changing the type of FFI functions. This fix makes them match. --- libISA/backend_c.ml | 4 ++-- tests/backends/ffi_import_01.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libISA/backend_c.ml b/libISA/backend_c.ml index a6fed9e7..0238bbed 100644 --- a/libISA/backend_c.ml +++ b/libISA/backend_c.ml @@ -1544,8 +1544,8 @@ let mk_ffi_conversion (loc : Loc.t) (indirect : bool) (c_name : Ident.t) (asl_na { asl_name = asl_name; asl_type = asl_type; c_name = c_name; - pp_c_type = Some (fun fmt -> PP.fprintf fmt "int%a" ptr ()); - pp_c_decl = (fun fmt -> PP.fprintf fmt "int %a%a" ptr () ident c_name); + pp_c_type = Some (fun fmt -> PP.fprintf fmt "%s%a" !ffi_integer ptr ()); + pp_c_decl = (fun fmt -> PP.fprintf fmt "%s %a%a" !ffi_integer ptr () ident c_name); pp_c_ref = (fun fmt -> PP.fprintf fmt "&%a" ident c_name); pp_asl_to_c = (fun fmt -> PP.fprintf fmt "%a%a = %a;" diff --git a/tests/backends/ffi_import_01.c b/tests/backends/ffi_import_01.c index 49f9e6b4..bb03e7bd 100644 --- a/tests/backends/ffi_import_01.c +++ b/tests/backends/ffi_import_01.c @@ -23,7 +23,7 @@ const char* FFI_null_string(const char *x) { return x; } enum E FFI_null_E(enum E x) { return x; } bool FFI_null_Boolean(bool x) { return x; } int64_t FFI_null_integer(int64_t x) { return x; } -int FFI_null_sint17(int x) { return x; } +int64_t FFI_null_sint17(int64_t x) { return x; } void FFI_int_bool(int64_t x, int64_t* ret1, bool* ret2) { From e3bd2b16407cbeeaa6dc63a337c417351dce8ecd Mon Sep 17 00:00:00 2001 From: Alastair Reid Date: Fri, 21 Aug 2026 10:42:21 +0100 Subject: [PATCH 7/7] Opam.locked: Update dune to 3.24.2 I noticed that github tests were first installing 3.22.2 and then installing 3.24.2 so I am hoping that selecting 3.24.2 initially will make CI tests run faster --- isa-tools.opam.locked | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/isa-tools.opam.locked b/isa-tools.opam.locked index f39293d3..e9796657 100644 --- a/isa-tools.opam.locked +++ b/isa-tools.opam.locked @@ -40,7 +40,7 @@ depends: [ "conf-python-3" {= "9.0.0"} "cppo" {= "1.8.0"} "crunch" {= "4.0.0"} - "dune" {= "3.22.2"} + "dune" {= "3.24.2"} "fmt" {= "0.11.0"} "fpath" {= "0.7.3"} "linenoise" {= "1.5.1"} @@ -85,4 +85,4 @@ build: [ "@doc" {with-doc} ] ] -dev-repo: "git+https://github.com/IntelLabs/isa-tools.git" \ No newline at end of file +dev-repo: "git+https://github.com/IntelLabs/isa-tools.git"