Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 23 additions & 10 deletions bin/iic.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,10 +253,10 @@ def run(cmd):
'sc': ['-DASL_SC'] + sc_types_include,
}

def get_c_flags(iii, backend):
def get_c_flags(iii, iii_flags, backend):
if "opam" in iii:
# iii has been installed: query it for flags
c_flags = subprocess.check_output([iii, "--print-c-flags"]).decode('utf-8').strip().split()
c_flags = subprocess.check_output([iii, "--print-c-flags"] + iii_flags).decode('utf-8').strip().split()
else:
# iii has not been installed so let's assume that it is being run
# directly out of the build tree and the path looks like this ../_build/install/default/bin/iii
Expand All @@ -276,10 +276,10 @@ def get_c_flags(iii, backend):
'sc': ["-lsystemc"],
}

def get_ld_flags(iii, backend):
def get_ld_flags(iii, iii_flags, backend):
if "opam" in iii:
# iii has been installed: query it for flags
ld_flags = subprocess.check_output([iii, "--print-ld-flags"]).decode('utf-8').strip().split()
ld_flags = subprocess.check_output([iii, "--print-ld-flags"] + iii_flags).decode('utf-8').strip().split()
else:
# iii has not been installed so let's assume that it is being run
# directly out of the build tree and the path looks like this ../_build/install/default/bin/iii
Expand Down Expand Up @@ -422,11 +422,12 @@ def generate_config_file(config_file, exports, imports):
print("}", file=f)
report(f"# Generated configuration file {config_file}\n")

def run_iii(iii, args, isa_files, project_file, configurations):
def run_iii(iii, iii_flags, args, isa_files, project_file, configurations):
iii_cmd = [
iii,
"--batchmode", "--nobanner",
]
iii_cmd.extend(iii_flags)
iii_cmd.append("--check-call-markers")
iii_cmd.append("--check-exception-markers")
if args.constraint_checks: print("Warning: ignoring --check-constraints")
Expand Down Expand Up @@ -523,6 +524,7 @@ def main() -> int:
parser.add_argument("--generate-cxx", help="generate C++ code", action="store_true", default=False)
parser.add_argument("--import", dest="imports", help="import this symbol (C generation only)", action='append', default=[])
parser.add_argument("--line-info", help="insert line directives into C code", action=argparse.BooleanOptionalAction)
parser.add_argument("--language-version", help="select language version", choices=['2026-00', '2026-01'], default='2026-00')
parser.add_argument("--new-ffi", help="use the new FFI", action="store_true", default=False)
parser.add_argument("--ffi-integer", help="select type for Integer in new FFI (default: int)", choices=['int', 'int64_t'], default='int')
parser.add_argument("--runtime-checks", help="perform runtime checks (array bounds, etc.)", action=argparse.BooleanOptionalAction)
Expand Down Expand Up @@ -568,23 +570,33 @@ def main() -> int:
print("Error: must specify --generate-cxx with --const-ref")
exit(1)

# flags to select language version
language_flags = {
'2026-00': ['--lang-hex-is-int'],
'2026-01': ['--lang-hex-is-bits'],
}

iii_flags = []
iii_flags = language_flags[args.language_version]

# when running tests, we need to be able to use iii without having installed it
iii = pathlib.Path(__file__).parent / "iii"
if not iii.exists():
iii = pathlib.Path(__file__).parent / "iii.exe"
iii = str(iii)

if args.print_c_flags:
print(' '.join(get_c_flags(iii, args.backend)))
print(' '.join(get_c_flags(iii, iii_flags, args.backend)))
elif args.print_ld_flags:
print(' '.join(get_ld_flags(iii, args.backend)))
print(' '.join(get_ld_flags(iii, iii_flags, args.backend)))
elif not args.build:
print(mk_script(args, args.output_dir))
elif args.run and args.backend == "interpreter":
iii_cmd = [
iii,
"--batchmode", "--nobanner",
]
iii_cmd.extend(iii_flags)
iii_cmd.append("--check-call-markers")
iii_cmd.append("--check-exception-markers")
if args.constraint_checks: print("Warning: ignoring --check-constraints")
Expand All @@ -608,6 +620,7 @@ def main() -> int:
f"--exec=:generate_mlir --output-file={mlir_file}",
"--exec=:quit",
]
iii_cmd.extend(iii_flags)
iii_cmd.extend(args.isa_files)
generate_config_file(config_file, ["main"] + args.exports, args.imports)
run(iii_cmd)
Expand All @@ -625,12 +638,12 @@ def main() -> int:
generate_project(old_project_file, script) # deprecated
generate_project(project_file, script)
generate_config_file(config_filename, ["main"] + args.exports, args.imports)
run_iii(iii, args, args.isa_files, project_file, [config_filename]+args.configuration)
run_iii(iii, iii_flags, args, args.isa_files, project_file, [config_filename]+args.configuration)
if args.show_final_isa:
pass
elif args.run:
c_flags = get_c_flags(iii, backend)
ld_flags = get_ld_flags(iii, backend)
c_flags = get_c_flags(iii, iii_flags, backend)
ld_flags = get_ld_flags(iii, iii_flags, backend)
compile_and_link(args.generate_cxx, c_files, args.extra_c, exe_file, working_directory, c_flags, ld_flags)
run([exe_file])
if not args.save_temps: shutil.rmtree(working_directory)
Expand Down
2 changes: 2 additions & 0 deletions bin/iii.ml
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,8 @@ let options =
("--batchmode", Arg.Set opt_batchmode, " Fail on error");
("--legacy-prelude", Arg.Set opt_enable_legacy_prelude, " Enable use of legacy ISA function names");
("--no-legacy-prelude", Arg.Clear opt_enable_legacy_prelude, " Disable use of legacy ISA function names");
("--lang-hex-is-bits", Arg.Set Isa_lexer.lang_hex_is_bits, " Hex literals have type Bits()");
("--lang-hex-is-int", Arg.Clear Isa_lexer.lang_hex_is_bits," Hex literals have type Integer");
("--configuration", Arg.String Configuration.read_configuration_file,
" Load JSON configuration file");
("--exec", Arg.String add_exec, " Execute command");
Expand Down
11 changes: 10 additions & 1 deletion libISA/isa_lexer.mll
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ open Isa_parser (* The type token is defined in parser.mli *)

exception Eof

let lang_hex_is_bits = ref true

let keywords : (string * Isa_parser.token) list = [
("UNSPECIFIED", UNSPECIFIED);
("_", UNDERSCORE);
Expand Down Expand Up @@ -125,7 +127,14 @@ rule token = parse
{ BITSLIT(Primops.mkBits (int_of_string len) (Z.of_string_base 10 digits)) }
| (['0'-'9']+ as len) '\'' 'x' (['0'-'9' 'A'-'F' 'a'-'f' '_']+ as nibbles) (* deprecated *)
{ BITSLIT(Primops.mkBits (int_of_string len) (Z.of_string_base 16 nibbles)) }
| '0''x'(['0'-'9' 'A'-'F' 'a'-'f' '_']+ as nibbles) { INTLIT(None, Z.of_string_base 16 nibbles) } (* todo: change to BITLIT *)
| '0''x'(['0'-'9' 'A'-'F' 'a'-'f' '_']+ as nibbles)
{
if !lang_hex_is_bits then
let x = Utils.drop_chars nibbles '_' in
BITSLIT(Primops.mkBits (4 * String.length x) (Z.of_string_base 16 x))
else
INTLIT(None, Z.of_string_base 16 nibbles)
}
| 'i' (['0'-'9']+ as len) '\'' 'b' (['0'-'1']+ as bits) { INTLIT(Some (int_of_string len), Z.of_string_base 2 bits) }
| 'i' (['0'-'9']+ as len) '\'' 'd' (['0'-'9']+ as digits) { INTLIT(Some (int_of_string len), Z.of_string digits) }
| 'i' (['0'-'9']+ as len) '\'' 'x' (['0'-'9' 'A'-'F' 'a'-'f']+ as nibbles) { INTLIT(Some (int_of_string len), Z.of_string_base 16 nibbles) }
Expand Down
16 changes: 8 additions & 8 deletions tests/backends/info_00.isa
Original file line number Diff line number Diff line change
Expand Up @@ -33,24 +33,24 @@ begin

// Some runtimes optimize the handling of 64-bit values
// so test the extreme values and near neighbors.
let max_64 := 0x7fff_ffff_ffff_ffff;
let min_64 := -0x8000_0000_0000_0000;
let max_64 := Std::Bits::Unsigned(0x7fff_ffff_ffff_ffff);
let min_64 := -Std::Bits::Unsigned(0x8000_0000_0000_0000);
Std::Info(1, "{max_64}");
// CHECK: {{^9223372036854775807$}}
Std::Info(1, "{min_64}");
// CHECK: {{^-9223372036854775808$}}

let max_64m1 := 0x7fff_ffff_ffff_fffe;
let min_64p1 := -0x7fff_ffff_ffff_ffff;
let max_64m1 := Std::Bits::Unsigned(0x7fff_ffff_ffff_fffe);
let min_64p1 := -Std::Bits::Unsigned(0x7fff_ffff_ffff_ffff);
Std::Info(1, "{max_64m1}");
// CHECK: {{^9223372036854775806$}}
Std::Info(1, "{min_64p1}");
// CHECK: {{^-9223372036854775807$}}

// Most runtimes use 128 bits as the default int sizes
// so test the extreme values and near neighbors.
let max_128 := 0x7fff_ffff_ffff_ffff_ffff_ffff_ffff_ffff;
let min_128 := -0x8000_0000_0000_0000_0000_0000_0000_0000;
let max_128 := Std::Bits::Unsigned(0x7fff_ffff_ffff_ffff_ffff_ffff_ffff_ffff);
let min_128 := -Std::Bits::Unsigned(0x8000_0000_0000_0000_0000_0000_0000_0000);
Std::Info(1, "{max_128}");
// CHECK-c23: {{^0x7fffffffffffffffffffffffffffffff$}}
// CHECK-fallback: {{^0x7fffffffffffffffffffffffffffffff$}}
Expand All @@ -60,8 +60,8 @@ begin
// CHECK-fallback: {{^-0x80000000000000000000000000000000$}}
// CHECK-interpreter: {{^-170141183460469231731687303715884105728$}}

let max_128m1 := 0x7fff_ffff_ffff_ffff_ffff_ffff_ffff_fffe;
let min_128p1 := -0x7fff_ffff_ffff_ffff_ffff_ffff_ffff_ffff;
let max_128m1 := Std::Bits::Unsigned(0x7fff_ffff_ffff_ffff_ffff_ffff_ffff_fffe);
let min_128p1 := -Std::Bits::Unsigned(0x7fff_ffff_ffff_ffff_ffff_ffff_ffff_ffff);
Std::Info(1, "{max_128m1}");
// CHECK-c23: {{^0x7ffffffffffffffffffffffffffffffe$}}
// CHECK-fallback: {{^0x7ffffffffffffffffffffffffffffffe$}}
Expand Down
4 changes: 2 additions & 2 deletions tests/backends/int_print_dec.isa
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ begin
Std::Print::Integer::Dec(-42); Print("\n");
// CHECK: {{^-42$}}

let max_128 := 0x7fff_ffff_ffff_ffff_ffff_ffff_ffff_ffff;
let max_128 := Std::Bits::Unsigned(0x7fff_ffff_ffff_ffff_ffff_ffff_ffff_ffff);
Std::Print::Integer::Dec(max_128); Print("\n");
// CHECK-ac: {{^0x7fffffffffffffffffffffffffffffff$}}
// CHECK-c23: {{^0x7fffffffffffffffffffffffffffffff$}}
// CHECK-fallback: {{^0x7fffffffffffffff_ffffffffffffffff$}}
// CHECK-interpreter: {{^170141183460469231731687303715884105727$}}
// CHECK-sc: {{^0x7fffffffffffffffffffffffffffffff$}}

let min_128 := -0x8000_0000_0000_0000_0000_0000_0000_0000;
let min_128 := -Std::Bits::Unsigned(0x8000_0000_0000_0000_0000_0000_0000_0000);
Std::Print::Integer::Dec(min_128); Print("\n");
// CHECK-ac: {{^-0x80000000000000000000000000000000$}}
// CHECK-c23: {{^-0x80000000000000000000000000000000$}}
Expand Down
16 changes: 8 additions & 8 deletions tests/backends/int_print_hex.isa
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,31 @@ begin

// Some runtimes optimize the handling of 64-bit values
// so test the extreme values and near neighbors.
let max_64 := 0x7fff_ffff_ffff_ffff;
let min_64 := -0x8000_0000_0000_0000;
let max_64 := Std::Bits::Unsigned(0x7fff_ffff_ffff_ffff);
let min_64 := -Std::Bits::Unsigned(0x8000_0000_0000_0000);
Std::Print::Integer::Hex(max_64); Print("\n");
// CHECK: {{^0x7fffffffffffffff$}}
Std::Print::Integer::Hex(min_64); Print("\n");
// CHECK: {{^-0x8000000000000000$}}

let max_64m1 := 0x7fff_ffff_ffff_fffe;
let min_64p1 := -0x7fff_ffff_ffff_ffff;
let max_64m1 := Std::Bits::Unsigned(0x7fff_ffff_ffff_fffe);
let min_64p1 := -Std::Bits::Unsigned(0x7fff_ffff_ffff_ffff);
Std::Print::Integer::Hex(max_64m1); Print("\n");
// CHECK: {{^0x7ffffffffffffffe$}}
Std::Print::Integer::Hex(min_64p1); Print("\n");
// CHECK: {{^-0x7fffffffffffffff$}}

// Most runtimes use 128 bits as the default int sizes
// so test the extreme values and near neighbors.
let max_128 := 0x7fff_ffff_ffff_ffff_ffff_ffff_ffff_ffff;
let min_128 := -0x8000_0000_0000_0000_0000_0000_0000_0000;
let max_128 := Std::Bits::Unsigned(0x7fff_ffff_ffff_ffff_ffff_ffff_ffff_ffff);
let min_128 := -Std::Bits::Unsigned(0x8000_0000_0000_0000_0000_0000_0000_0000);
Std::Print::Integer::Hex(max_128); Print("\n");
// CHECK: {{^0x7fffffffffffffffffffffffffffffff$}}
Std::Print::Integer::Hex(min_128); Print("\n");
// CHECK: {{^-0x80000000000000000000000000000000$}}

let max_128m1 := 0x7fff_ffff_ffff_ffff_ffff_ffff_ffff_fffe;
let min_128p1 := -0x7fff_ffff_ffff_ffff_ffff_ffff_ffff_ffff;
let max_128m1 := Std::Bits::Unsigned(0x7fff_ffff_ffff_ffff_ffff_ffff_ffff_fffe);
let min_128p1 := -Std::Bits::Unsigned(0x7fff_ffff_ffff_ffff_ffff_ffff_ffff_ffff);
Std::Print::Integer::Hex(max_128m1); Print("\n");
// CHECK: {{^0x7ffffffffffffffffffffffffffffffe$}}
Std::Print::Integer::Hex(min_128p1); Print("\n");
Expand Down
8 changes: 4 additions & 4 deletions tests/backends/sintN_cvt_from_int_00.isa
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ end

function main() -> Builtin::Foreign::CInt
begin
Std::Print::SInt::Hex(FUT_8(0x0)); Print("\n");
Std::Print::SInt::Hex(FUT_8(0)); Print("\n");
// CHECK: i8'x0
Std::Print::SInt::Hex(FUT_8(0x7f)); Print("\n");
Std::Print::SInt::Hex(FUT_8(127)); Print("\n");
// CHECK: i8'x7f
Std::Print::SInt::Hex(FUT_8(-0x1)); Print("\n");
Std::Print::SInt::Hex(FUT_8(-1)); Print("\n");
// CHECK: -i8'x1
Std::Print::SInt::Hex(FUT_8(-0x80)); Print("\n");
Std::Print::SInt::Hex(FUT_8(-128)); Print("\n");
// CHECK: -i8'x80

return Builtin::Foreign::CInt::From_Integer(0);
Expand Down
2 changes: 1 addition & 1 deletion tests/backends/stmt_case_04.isa
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
function Test(x : Integer) -> Integer
begin
case x of
when 0x1_0000_0000_0000_0000 => return 1;
when 18_446_744_073_709_551_616 => return 1; // 2^64
// CHECK: Unimplemented large (> 64 bit) integer pattern
otherwise => return 10;
end;
Expand Down
6 changes: 4 additions & 2 deletions tests/lit.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ sc_types_dir = os.environ.get("SC_TYPES_DIR")
xdsl_isa_dir = os.environ.get("XDSL_ISA_DIR")
isa_CC = os.environ.get("ISA_CC")

lang_version = "2026-01"

# Lit configuration
if backend is None:
config.name = "ISA"
Expand All @@ -34,8 +36,8 @@ if proc.returncode == 0 and "1" in proc.stdout:

config.substitutions.append(('%backend', backend))
config.substitutions.append(('%iii', iii_bin_path))
config.substitutions.append(('%aslrun', f"{iic_path} --backend={backend} -O0 --run"))
config.substitutions.append(('%aslopt', f"{iic_path} --show-final-isa"))
config.substitutions.append(('%aslrun', f"{iic_path} --language-version={lang_version} --backend={backend} -O0 --run"))
config.substitutions.append(('%aslopt', f"{iic_path} --language-version={lang_version} --show-final-isa"))
config.environment["ISA_DIR"] = isa_path
config.environment["ISA_PATH"] = f":{isa_path}:."
if ac_types_dir: config.environment["AC_TYPES_DIR"] = ac_types_dir
Expand Down
2 changes: 1 addition & 1 deletion tests/lit/tcheck/funcall06.isa
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

function F(x : Integer, y : Integer := 1, z : Integer := 2) -> Integer
begin
return x * 0x100 + y * 0x10 + z;
return x * 256 + y * 16 + z;
end

function main() -> Builtin::Foreign::CInt
Expand Down
6 changes: 1 addition & 5 deletions tests/test_cases_backend.ml
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,7 @@ let expr : test_case list =

( "literal hex",
[ Backend_C; Backend_Verilog ],
"function F() -> Integer begin return 0x01_0; end" );

( "literal hex (negative)",
[ Backend_C; Backend_Verilog ],
"function F() -> Integer begin return -0x01_0; end" );
"function F() -> Bits(12) begin return 0x01_0; end" );

( "literal bitvector",
[ Backend_C; Backend_Verilog ],
Expand Down
4 changes: 2 additions & 2 deletions tests/xform_constprop_test.ml
Original file line number Diff line number Diff line change
Expand Up @@ -342,11 +342,11 @@ let constprop_tests : unit Alcotest.test_case list =
"var i : Integer; function Foo(x : Integer) begin end"
"case i of
when 16 => Foo(i);
when 0x20 => Foo(i);
when 32 => Foo(i);
endcase;"
"case i of
when 16 => Foo(16);
when 0x20 => Foo(32);
when 32 => Foo(32);
endcase;");
("case stmt bitvectors", `Quick, test_cp_stmts
"var i : Bits(8); function Foo(x : Bits(8)) begin end"
Expand Down