From 6ebb65b9ed16a9815ff90779214850cd1e29c612 Mon Sep 17 00:00:00 2001 From: Milky2018 <842376130@qq.com> Date: Mon, 12 May 2025 08:37:11 +0000 Subject: [PATCH 01/13] Support for SSA Pnot conversion to virtasm. --- src/riscv_generate.ml | 20 +++++++++++++++++++- src/riscv_virtasm_generate.ml | 23 +++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/riscv_generate.ml b/src/riscv_generate.ml index ce299b2..65855b6 100644 --- a/src/riscv_generate.ml +++ b/src/riscv_generate.ml @@ -524,7 +524,25 @@ let deal_with_prim tac rd (prim: Primitive.prim) args = | Pprintln -> Vec.push tac (CallExtern { rd; fn = "puts"; args }) - + | Pnot -> + Vec.push tac (Not { rd; rs1 = List.hd args }) + (* | Primitive.Pccall { func_name = "";_} -> _ + | Primitive.Pnot -> _ + | Primitive.Praise -> _ + | Primitive.Punreachable -> _ + | Primitive.Pcatch -> _ + | Primitive.Psequand -> _ + | Primitive.Psequor -> _ + | Primitive.Pstringequal -> _ + | Primitive.Pclosure_to_extern_ref -> _ + | Primitive.Pnull_string_extern -> _ + | Primitive.Perror_to_string -> _ + | Primitive.Pany_to_string -> _ + | Primitive.Pintrinsic -> _ + | Primitive.Pcast -> _ + | Primitive.Pcompare -> _ + | Primitive.Pset_enum_field -> _ + | Primitive.Pmake_value_or_error *) | _ -> failwith (Printf.sprintf "unknown primitive %s" (Primitive.sexp_of_prim prim |> S.to_string)) diff --git a/src/riscv_virtasm_generate.ml b/src/riscv_virtasm_generate.ml index 35c9087..666baf1 100644 --- a/src/riscv_virtasm_generate.ml +++ b/src/riscv_virtasm_generate.ml @@ -232,6 +232,9 @@ let convert_single name body terminator (inst: Riscv_ssa.t) = Vec.push body (Inst.Xor { rd = slot_v rd; rs1 = slot_v rs1; rs2 = slot_v rs2 }); Vec.push body (Inst.Sltu { rd = slot_v rd; rs1 = Slot.Reg Zero; rs2 = slot_v rd }) + | Not { rd; rs1 } -> + Vec.push body (Inst.Slti { rd = slot_v rd; rs1 = slot_v rs1; imm = 1 }) + | Call { rd; fn; args } -> let r = slot_v rd in let int_args = Vec.empty () in @@ -332,6 +335,26 @@ let convert_single name body terminator (inst: Riscv_ssa.t) = | Jump label -> terminator := Term.J (label_of label) + (* | Neg -> _ + | Sll -> _ + | Slli -> _ + | Slti -> _ + | FAdd -> _ + | FSub -> _ + | FMul -> _ + | FDiv -> _ + | FLess -> _ + | FLeq -> _ + | FGreat -> _ + | FGeq -> _ + | FEq -> _ + | FNeq -> _ + | FNeg -> _ + | AssignFP -> _ + | JumpIndirect -> _ + | FnDecl -> _ + | GlobalVarDecl -> _ + | ExtArray _ -> _ *) | _ -> failwith (Printf.sprintf "unsupported ssa: %s" (to_string inst)) From 16cf2a21d0f3d059ddaa13dcb2e698958f450277 Mon Sep 17 00:00:00 2001 From: Milky2018 <842376130@qq.com> Date: Mon, 12 May 2025 09:12:44 +0000 Subject: [PATCH 02/13] Bugfix for "break" expression conversion. --- src/riscv_generate.ml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/riscv_generate.ml b/src/riscv_generate.ml index 65855b6..a92bbc9 100644 --- a/src/riscv_generate.ml +++ b/src/riscv_generate.ml @@ -932,6 +932,12 @@ let rec do_convert tac (expr: Mcore.expr) = Vec.push tac (Jump loop_name); unit + | Cexpr_break { label; _ } -> + (* Jumps to exit of the loop. *) + let loop_name = Printf.sprintf "loophead_%s_%d" label.name label.stamp in + Vec.push tac (Jump ("loopexit_" ^ loop_name)); + unit + (* Assigns mutable variables. *) | Cexpr_assign { var; expr; ty } -> let rd = do_convert tac expr in @@ -978,12 +984,6 @@ let rec do_convert tac (expr: Mcore.expr) = List.iter visit fields; rd - | Cexpr_break { label; _ } -> - (* Jumps to exit of the loop. *) - let loop_name = Printf.sprintf "%s_%d" label.name label.stamp in - Vec.push tac (Jump ("exit_" ^ loop_name)); - unit - | Cexpr_tuple { exprs; ty; _ } -> let rd = new_temp ty in let tys = From 521fd10c4847f1d9acf3eb63cb983d14fb28617c Mon Sep 17 00:00:00 2001 From: Milky2018 <842376130@qq.com> Date: Tue, 13 May 2025 05:37:15 +0000 Subject: [PATCH 03/13] Implement virtasm "sll, slli, srli, slti". --- src/riscv_virtasm.ml | 6 ++++-- src/riscv_virtasm_generate.ml | 40 +++++++++++++++++++++++++++++------ 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/riscv_virtasm.ml b/src/riscv_virtasm.ml index 8d0897f..cb20288 100644 --- a/src/riscv_virtasm.ml +++ b/src/riscv_virtasm.ml @@ -210,6 +210,8 @@ module Inst = struct | Sltw of r_slot | Sltu of r_slot | Sltuw of r_slot + | Slti of i_slot + | Sltiw of i_slot | Sll of r_slot (* shift left logical *) | Sllw of r_slot @@ -222,12 +224,12 @@ module Inst = struct | Slli of i_slot (* shift left logical immediate *) | Slliw of i_slot + | Srli of i_slot (* shift right logical immediate *) | Srliw of i_slot + | Srai of i_slot (* shift right arithmetic immediate *) | Sraiw of i_slot - | Slti of i_slot - | Sltiw of i_slot (* Multiplication and Division Instructions *) (* Memory Access Instructions *) | Lb of mem_slot diff --git a/src/riscv_virtasm_generate.ml b/src/riscv_virtasm_generate.ml index 666baf1..c62cf66 100644 --- a/src/riscv_virtasm_generate.ml +++ b/src/riscv_virtasm_generate.ml @@ -113,6 +113,25 @@ let convert_single name body terminator (inst: Riscv_ssa.t) = | T_uint64 -> Inst.Remu r | _ -> die (Printf.sprintf "rem: unexpected type %s" (Mtype.to_string rd.ty))) + (* Shift *) + + | Sll ({ rd; rs1; rs2 } as x) -> + let r = rslot x in + (* Note we use rs1 type in leftshift *) + (match rs1.ty with + | T_uint | T_int -> Vec.push body (Inst.Sllw r) + | T_uint64 | T_int64 -> Vec.push body (Inst.Sll r) + | _ -> die (Printf.sprintf "sll: unexpected type %s" (Mtype.to_string rs1.ty))) + + | Slli { rd; rs; imm } -> + let r = ({ rd = slot_v rd; rs1 = slot_v rs; imm } : Slots.i_slot) in + (match rs.ty with + | T_uint | T_int -> Vec.push body (Inst.Slliw r) + | T_uint64 | T_int64 -> Vec.push body (Inst.Slli r) + | _ -> die (Printf.sprintf "slli: unexpected type %s" (Mtype.to_string rs.ty))) + + (* Logical; assumes rs1 is unsigned *) + (* Arithmetic; assumes rs1 is signed *) | Sra ({ rd; rs1; rs2 } as x) -> let r = rslot x in @@ -141,9 +160,9 @@ let convert_single name body terminator (inst: Riscv_ssa.t) = | Srli ({ rd; rs; imm }) -> let r = ({ rd = slot_v rd; rs1 = slot_v rs; imm } : Slots.i_slot) in (match rs.ty with - | T_uint -> Vec.push body (Inst.Sraiw r) - | T_uint64 -> Vec.push body (Inst.Srai r) - | _ -> die (Printf.sprintf "srai: unexpected type %s" (Mtype.to_string rs.ty))) + | T_uint -> Vec.push body (Inst.Srliw r) + | T_uint64 -> Vec.push body (Inst.Srli r) + | _ -> die (Printf.sprintf "srli: unexpected type %s" (Mtype.to_string rs.ty))) | And ({ rd; rs1; rs2 } as x) -> let r = rslot x in @@ -232,6 +251,18 @@ let convert_single name body terminator (inst: Riscv_ssa.t) = Vec.push body (Inst.Xor { rd = slot_v rd; rs1 = slot_v rs1; rs2 = slot_v rs2 }); Vec.push body (Inst.Sltu { rd = slot_v rd; rs1 = Slot.Reg Zero; rs2 = slot_v rd }) + | Slti { rd; rs; imm } -> + (* rd = rs1 < rs2 *) + let r = ({ + rd = slot_v rd; + rs1 = slot_v rs; + imm + }: Slots.i_slot) in + Vec.push body (match rs.ty with + | T_int -> Inst.Sltiw r + | T_int64 -> Inst.Slti r + | _ -> die (Printf.sprintf "slti: unexpected type %s" (Mtype.to_string rs.ty))) + | Not { rd; rs1 } -> Vec.push body (Inst.Slti { rd = slot_v rd; rs1 = slot_v rs1; imm = 1 }) @@ -336,9 +367,6 @@ let convert_single name body terminator (inst: Riscv_ssa.t) = | Jump label -> terminator := Term.J (label_of label) (* | Neg -> _ - | Sll -> _ - | Slli -> _ - | Slti -> _ | FAdd -> _ | FSub -> _ | FMul -> _ From 688344ac9001455e5fdfd25524aa8d49ed3c9bae Mon Sep 17 00:00:00 2001 From: Milky2018 <842376130@qq.com> Date: Tue, 13 May 2025 05:37:59 +0000 Subject: [PATCH 04/13] Bugfix for convert "i64->i32" and "u64->i32". --- src/riscv_generate.ml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/riscv_generate.ml b/src/riscv_generate.ml index a92bbc9..3d2fe16 100644 --- a/src/riscv_generate.ml +++ b/src/riscv_generate.ml @@ -154,7 +154,7 @@ let deal_with_prim tac rd (prim: Primitive.prim) args = (* Discard higher bits by shifting, but arithmetic *) let temp = new_temp Mtype.T_uint64 in Vec.push tac (Slli { rd = temp; rs = arg; imm = 32 }); - Vec.push tac (Srai { rd; rs = temp; imm = 32 }) + Vec.push tac (Srli { rd; rs = temp; imm = 32 }) | I32, U32 | U32, I32 | I32, I64 -> (* Simply do nothing *) @@ -527,7 +527,6 @@ let deal_with_prim tac rd (prim: Primitive.prim) args = | Pnot -> Vec.push tac (Not { rd; rs1 = List.hd args }) (* | Primitive.Pccall { func_name = "";_} -> _ - | Primitive.Pnot -> _ | Primitive.Praise -> _ | Primitive.Punreachable -> _ | Primitive.Pcatch -> _ From aa5ae6714cdc719044ebb75903cd80889ed9b4da Mon Sep 17 00:00:00 2001 From: Milky2018 <842376130@qq.com> Date: Thu, 15 May 2025 09:33:42 +0000 Subject: [PATCH 05/13] Test file support for g++ and diff output. --- test.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/test.py b/test.py index 9b43868..e5b8c0c 100755 --- a/test.py +++ b/test.py @@ -23,6 +23,7 @@ def __exit__(self, exc_type, exc_value, traceback): parser.add_argument("-v", "--verbose", action="store_true", help="on rebuild, makes interpreter output detailed values") parser.add_argument("-c", "--compile-only", action="store_true", help="compile without executing tests") parser.add_argument("-t", "--test", type=str, help="execute this test case only") +parser.add_argument("--gcc", action="store_true", help="use gcc instead of clang++") args = parser.parse_args() @@ -57,7 +58,10 @@ def try_remove(path): if args.build and not args.wasm: print("Building SSA interpreter...") os.makedirs("test/build", exist_ok=True) - os.system(f"clang++ -std=c++20 {verbose} test/interpreter.cpp -Wall -g -o test/build/interpreter") + if args.gcc: + os.system(f"g++ -std=c++20 {verbose} test/interpreter.cpp -Wall -g -o test/build/interpreter") + else: + os.system(f"clang++ -std=c++20 {verbose} test/interpreter.cpp -Wall -g -o test/build/interpreter") print("Done.") exit(0) @@ -102,6 +106,11 @@ def try_remove(path): if diff == 0: print("Passed.") else: + print("Failed.") + print("Expected output:") + os.system(f"cat src/{src}/{src}.ans") + print("Actual output:") + os.system(f"cat build/output.txt") success = False exit(not success) \ No newline at end of file From 912e9409c24cb665d2009ecbd71e17a23d3d64bf Mon Sep 17 00:00:00 2001 From: Milky2018 <842376130@qq.com> Date: Fri, 16 May 2025 02:52:05 +0000 Subject: [PATCH 06/13] Bugfix: operand types correction for SSA: SLTI, SRAI. JumpIndirect convert to VASM. --- src/riscv_generate.ml | 2 +- src/riscv_virtasm_generate.ml | 27 +++++++++++++++++++++------ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/riscv_generate.ml b/src/riscv_generate.ml index 3d2fe16..34be708 100644 --- a/src/riscv_generate.ml +++ b/src/riscv_generate.ml @@ -154,7 +154,7 @@ let deal_with_prim tac rd (prim: Primitive.prim) args = (* Discard higher bits by shifting, but arithmetic *) let temp = new_temp Mtype.T_uint64 in Vec.push tac (Slli { rd = temp; rs = arg; imm = 32 }); - Vec.push tac (Srli { rd; rs = temp; imm = 32 }) + Vec.push tac (Srai { rd; rs = temp; imm = 32 }) | I32, U32 | U32, I32 | I32, I64 -> (* Simply do nothing *) diff --git a/src/riscv_virtasm_generate.ml b/src/riscv_virtasm_generate.ml index c62cf66..ebe97ed 100644 --- a/src/riscv_virtasm_generate.ml +++ b/src/riscv_virtasm_generate.ml @@ -86,6 +86,13 @@ let convert_single name body terminator (inst: Riscv_ssa.t) = | T_uint -> Vec.push body (Inst.Subw r); Vec.push body (Zextw { rd = r.rd; rs = r.rd }) | _ -> Vec.push body (Inst.Sub r)) + | Neg ({rd ; rs1}) -> + let r = ({ rd = slot_v rd; rs1 = Slot.Reg Zero ; rs2 = slot_v rs1}: Slots.r_slot) in + (match rd.ty with + | T_int -> Vec.push body (Inst.Subw r); Vec.push body (Zextw { rd = r.rd; rs = r.rd }) + | T_int64 -> Vec.push body (Inst.Sub r) + | _ -> die (Printf.sprintf "neg: unexpected type %s" (Mtype.to_string rd.ty))) + | Mul ({ rd; rs1; rs2 } as x) -> let r = rslot x in (match rd.ty with @@ -153,8 +160,8 @@ let convert_single name body terminator (inst: Riscv_ssa.t) = | Srai ({ rd; rs; imm }) -> let r = ({ rd = slot_v rd; rs1 = slot_v rs; imm } : Slots.i_slot) in (match rs.ty with - | T_int -> Vec.push body (Inst.Sraiw r) - | T_int64 -> Vec.push body (Inst.Srai r) + | T_int | T_uint -> Vec.push body (Inst.Sraiw r) + | T_int64 | T_uint64 -> Vec.push body (Inst.Srai r) | _ -> die (Printf.sprintf "srai: unexpected type %s" (Mtype.to_string rs.ty))) | Srli ({ rd; rs; imm }) -> @@ -259,8 +266,8 @@ let convert_single name body terminator (inst: Riscv_ssa.t) = imm }: Slots.i_slot) in Vec.push body (match rs.ty with - | T_int -> Inst.Sltiw r - | T_int64 -> Inst.Slti r + | T_int | T_uint -> Inst.Sltiw r + | T_int64 | T_uint64 -> Inst.Slti r | _ -> die (Printf.sprintf "slti: unexpected type %s" (Mtype.to_string rs.ty))) | Not { rd; rs1 } -> @@ -366,7 +373,16 @@ let convert_single name body terminator (inst: Riscv_ssa.t) = | Jump label -> terminator := Term.J (label_of label) - (* | Neg -> _ + + | JumpIndirect { rs; possibilities } -> (* TODO: Optimizations on possibilities *) + terminator := Term.Jalr { + rd = Slot.Reg Zero; + rs1 = slot_v rs; + offset = 0; + }; + + (* Floating point instructions *) + (* | FAdd -> _ | FSub -> _ | FMul -> _ @@ -379,7 +395,6 @@ let convert_single name body terminator (inst: Riscv_ssa.t) = | FNeq -> _ | FNeg -> _ | AssignFP -> _ - | JumpIndirect -> _ | FnDecl -> _ | GlobalVarDecl -> _ | ExtArray _ -> _ *) From d053c9a1e10ec51c814572ee0821aee9678f0b02 Mon Sep 17 00:00:00 2001 From: Milky2018 <842376130@qq.com> Date: Fri, 16 May 2025 06:02:01 +0000 Subject: [PATCH 07/13] Bugfix: in SSA generation for switch_constr, the type of off should be an int. --- src/riscv_generate.ml | 5 +++-- src/riscv_virtasm_generate.ml | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/riscv_generate.ml b/src/riscv_generate.ml index 34be708..ffd663d 100644 --- a/src/riscv_generate.ml +++ b/src/riscv_generate.ml @@ -1156,7 +1156,7 @@ let rec do_convert tac (expr: Mcore.expr) = (* Choose which place to jump to *) let jtable = new_temp Mtype.T_bytes in let ptr_sz = new_temp Mtype.T_int in - let off = new_temp Mtype.T_bytes in + let off = new_temp Mtype.T_int in let altered = new_temp Mtype.T_bytes in let target = new_temp Mtype.T_bytes in @@ -1244,6 +1244,7 @@ let rec do_convert tac (expr: Mcore.expr) = let values = List.map (fun (t, _) -> match t with + | Constant.C_bool b -> Bool.to_int b | Constant.C_int { v } -> Int32.to_int v | Constant.C_char v -> Uchar.to_int v | _ -> failwith "TODO: unsupported switch constant type" @@ -1254,7 +1255,7 @@ let rec do_convert tac (expr: Mcore.expr) = let mn = List.fold_left (fun mn x -> min mn x) 2147483647 values in (* Sparse values, convert to if-else *) - if mx - mn >= 256 then ( + if mx - mn >= 256 || len < 16 then ( let ifexit = new_label "match_ifexit_" in List.iter2 (fun x (_, expr) -> let equal = new_temp Mtype.T_bool in diff --git a/src/riscv_virtasm_generate.ml b/src/riscv_virtasm_generate.ml index ebe97ed..5b00991 100644 --- a/src/riscv_virtasm_generate.ml +++ b/src/riscv_virtasm_generate.ml @@ -46,7 +46,7 @@ let slot_v v = (** Terminator and body are output arguments *) let convert_single name body terminator (inst: Riscv_ssa.t) = - let die msg = failwith (Printf.sprintf "riscv_virtasm_generate.ml: %s" msg) in + let die msg = failwith (Printf.sprintf "riscv_virtasm_generate.ml: %s. Complete SSA instruction: %s" msg (Riscv_ssa.to_string inst)) in let rslot ({ rd; rs1; rs2 }: Riscv_ssa.r_type) = ({ From 9185db2e0cb4fb5e0a25deed046f9f56d100e728 Mon Sep 17 00:00:00 2001 From: Milky2018 <842376130@qq.com> Date: Fri, 16 May 2025 07:16:18 +0000 Subject: [PATCH 08/13] Implement Pstringequal and corresponding tests. --- src/riscv_generate.ml | 8 +++++++- test/interpreter.cpp | 5 +++++ test/src/string01/string01.ans | 1 + test/src/string01/string01.mbt | 4 ++++ test/src/string02/string02.ans | 4 ++++ test/src/string02/string02.mbt | 9 +++++++++ 6 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 test/src/string01/string01.ans create mode 100644 test/src/string01/string01.mbt create mode 100644 test/src/string02/string02.ans create mode 100644 test/src/string02/string02.mbt diff --git a/src/riscv_generate.ml b/src/riscv_generate.ml index ffd663d..6a6b731 100644 --- a/src/riscv_generate.ml +++ b/src/riscv_generate.ml @@ -526,13 +526,19 @@ let deal_with_prim tac rd (prim: Primitive.prim) args = Vec.push tac (CallExtern { rd; fn = "puts"; args }) | Pnot -> Vec.push tac (Not { rd; rs1 = List.hd args }) + | Pstringequal -> + let cmp_res = new_temp Mtype.T_int in + let zero = new_temp Mtype.T_bytes in + Vec.push tac (CallExtern { rd = cmp_res; fn = "strcmp"; args }); + Vec.push tac (AssignInt64 { rd = zero; imm = 0L }); + Vec.push tac (Eq { rd; rs1 = cmp_res; rs2 = zero }); + (* | Primitive.Pccall { func_name = "";_} -> _ | Primitive.Praise -> _ | Primitive.Punreachable -> _ | Primitive.Pcatch -> _ | Primitive.Psequand -> _ | Primitive.Psequor -> _ - | Primitive.Pstringequal -> _ | Primitive.Pclosure_to_extern_ref -> _ | Primitive.Pnull_string_extern -> _ | Primitive.Perror_to_string -> _ diff --git a/test/interpreter.cpp b/test/interpreter.cpp index d909b18..43db751 100644 --- a/test/interpreter.cpp +++ b/test/interpreter.cpp @@ -308,6 +308,11 @@ int64_t interpret(std::string label) { continue; } + if (args[2] == "strcmp") { + VAL(1) = (int64_t) strcmp((char*) VAL(3), (char*) VAL(4)); + continue; + } + if (args[2] == "memset") { memset((void*) VAL(3), VAL(4), VAL(5)); VAL(1) = unit; diff --git a/test/src/string01/string01.ans b/test/src/string01/string01.ans new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/test/src/string01/string01.ans @@ -0,0 +1 @@ +5 diff --git a/test/src/string01/string01.mbt b/test/src/string01/string01.mbt new file mode 100644 index 0000000..ac0ff84 --- /dev/null +++ b/test/src/string01/string01.mbt @@ -0,0 +1,4 @@ +fn main { + let x = "hello" + println(x.length()) +} \ No newline at end of file diff --git a/test/src/string02/string02.ans b/test/src/string02/string02.ans new file mode 100644 index 0000000..7565230 --- /dev/null +++ b/test/src/string02/string02.ans @@ -0,0 +1,4 @@ +false +true +false +true diff --git a/test/src/string02/string02.mbt b/test/src/string02/string02.mbt new file mode 100644 index 0000000..223d1f3 --- /dev/null +++ b/test/src/string02/string02.mbt @@ -0,0 +1,9 @@ +fn main { + let x = "hello" + let y = "world" + let z = "hello" + println(x == y) + println(x == z) + println(x == y) + println(x == x) +} \ No newline at end of file From 8d10624eb6fb74876e4a6e9b52a7112d1adcc482 Mon Sep 17 00:00:00 2001 From: Milky2018 <842376130@qq.com> Date: Tue, 27 May 2025 03:17:31 +0000 Subject: [PATCH 09/13] When writing SSA to files, adding type infos. --- src/riscv_ssa.ml | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/riscv_ssa.ml b/src/riscv_ssa.ml index a972d0a..2757fff 100644 --- a/src/riscv_ssa.ml +++ b/src/riscv_ssa.ml @@ -253,7 +253,7 @@ let rec sizeof ty = (* Optimized option uses special values to indicate None for integer types *) (* So the size is equal to the underlying integer type *) - | Mtype.T_optimized_option { elem } -> sizeof elem + (* | Mtype.T_optimized_option { elem } -> sizeof elem *) (* Same size as the underlying type *) | Mtype.T_maybe_uninit x -> sizeof x @@ -266,15 +266,15 @@ let rec sizeof ty = (** Emits SSA form. We choose a less human-readable form to facilitate verifier. *) let to_string t = let rtype op ({ rd; rs1; rs2 }: r_type) = - Printf.sprintf "%s %s %s %s" op rd.name rs1.name rs2.name + Printf.sprintf "%s %s:%s %s:%s %s:%s" op rd.name (Mtype.to_string rd.ty) rs1.name (Mtype.to_string rs1.ty) rs2.name (Mtype.to_string rs2.ty) in let r2type op ({ rd; rs1; }: r2_type) = - Printf.sprintf "%s %s %s" op rd.name rs1.name + Printf.sprintf "%s %s:%s %s:%s" op rd.name (Mtype.to_string rd.ty) rs1.name (Mtype.to_string rs1.ty) in let itype op ({ rd; rs; imm } : i_type) = - Printf.sprintf "%s %s %s %d" op rd.name rs.name imm + Printf.sprintf "%s %s:%s %s:%s %d" op rd.name (Mtype.to_string rd.ty) rs.name (Mtype.to_string rs.ty) imm in (* Deals with signedness: signed or unsigned *) @@ -283,7 +283,7 @@ let to_string t = let width = (match rd.ty with | T_uint | T_uint64 -> "u" | _ -> "") in - Printf.sprintf "%s%s %s %s %s" op width rd.name rs1.name rs2.name + Printf.sprintf "%s%s %s:%s %s:%s %s:%s" op width rd.name (Mtype.to_string rd.ty) rs1.name (Mtype.to_string rs1.ty) rs2.name (Mtype.to_string rs2.ty) in (* Deals with width: 32 or 64 bit *) @@ -291,7 +291,7 @@ let to_string t = let width = (match rd.ty with | T_int | T_uint -> "w" | _ -> "") in - Printf.sprintf "%s%s %s %s %s" op width rd.name rs1.name rs2.name + Printf.sprintf "%s%s %s:%s %s:%s %s:%s" op width rd.name (Mtype.to_string rd.ty) rs1.name (Mtype.to_string rs1.ty) rs2.name (Mtype.to_string rs2.ty) in (* Deals with both width and signedness *) @@ -301,14 +301,14 @@ let to_string t = | T_uint -> "uw" | T_uint64 -> "u" | _ -> "") in - Printf.sprintf "%s%s %s %s %s" op width rd.name rs1.name rs2.name + Printf.sprintf "%s%s %s:%s %s:%s %s:%s" op width rd.name (Mtype.to_string rd.ty) rs1.name (Mtype.to_string rs1.ty) rs2.name (Mtype.to_string rs2.ty) in let itypew op ({ rd; rs; imm }: i_type) = let width = (match rd.ty with | T_int | T_uint -> "w" | _ -> "") in - Printf.sprintf "%s%s %s %s %d" op width rd.name rs.name imm + Printf.sprintf "%s%s %s:%s %s:%s %d" op width rd.name (Mtype.to_string rd.ty) rs.name (Mtype.to_string rs.ty) imm in (* Dedicated for slt *) @@ -319,7 +319,7 @@ let to_string t = | T_int -> "sltiw" | T_uint64 -> "sltiuw" | _ -> "") in - Printf.sprintf "%s %s %s %d" width rd.name rs.name imm + Printf.sprintf "%s %s:%s %s:%s %d" width rd.name (Mtype.to_string rd.ty) rs.name (Mtype.to_string rs.ty) imm in (* Similarly, `srl` and `sra` are instructions where `rs` matters rather than `rd` *) @@ -328,7 +328,7 @@ let to_string t = let width = (match rs.ty with | T_uint | T_int -> "w" | _ -> "") in - Printf.sprintf "%s%s %s %s %d" op width rd.name rs.name imm + Printf.sprintf "%s%s %s:%s %s:%s %d" op width rd.name (Mtype.to_string rd.ty) rs.name (Mtype.to_string rs.ty) imm in let die x = @@ -555,4 +555,8 @@ let new_temp ty = let new_label prefix = let name = prefix ^ Int.to_string !slot in slot := !slot + 1; - name \ No newline at end of file + name + +let write_to_file file_postfix ssa = + let out_noopt = Printf.sprintf "%s%s" !Driver_config.Linkcore_Opt.output_file file_postfix in + Basic_io.write out_noopt (String.concat "\n" (List.map to_string ssa)); \ No newline at end of file From 2a54da64771d8e71d70a0d932ab8dbf83e65551e Mon Sep 17 00:00:00 2001 From: Milky2018 <842376130@qq.com> Date: Tue, 27 May 2025 03:18:11 +0000 Subject: [PATCH 10/13] Add a function to revert the optimized_option type to its representative type. --- src/riscv_generate.ml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/riscv_generate.ml b/src/riscv_generate.ml index 6a6b731..a7055b1 100644 --- a/src/riscv_generate.ml +++ b/src/riscv_generate.ml @@ -69,6 +69,14 @@ let nameof (x: Mtype.t) = match x with let remove_space = String.map (fun c -> if c = ' ' then '_' else c) +let revert_optimized_option_type = function +| Mtype.T_optimized_option { elem } -> + (match elem with + | Mtype.T_char | T_bool | T_unit | T_byte -> Mtype.T_int + | Mtype.T_int | T_uint -> Mtype.T_int64 + | _ -> failwith (Printf.sprintf "riscv_generate.ml: bad optimized_option type %s in revert" (Mtype.to_string elem))) +| otherwise -> otherwise + (** Push the correct sequence of instruction based on primitives. *) let deal_with_prim tac rd (prim: Primitive.prim) args = let die () = @@ -139,6 +147,7 @@ let deal_with_prim tac rd (prim: Primitive.prim) args = (* But convert is where we must take some action *) else let arg = List.hd args in + let arg = { arg with ty = revert_optimized_option_type arg.ty } in (match from, to_ with | I32, U8 | U32, U8 -> (* Discard higher bits by masking them away *) From 7539c9d607b459018a4ad7bd816e0e3711db0fc3 Mon Sep 17 00:00:00 2001 From: Milky2018 <842376130@qq.com> Date: Tue, 27 May 2025 03:19:07 +0000 Subject: [PATCH 11/13] Extract some logics to `write_to_file` for convenience. --- src/riscv_opt_gather.ml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/riscv_opt_gather.ml b/src/riscv_opt_gather.ml index 066fe8e..6a32279 100644 --- a/src/riscv_opt_gather.ml +++ b/src/riscv_opt_gather.ml @@ -3,8 +3,7 @@ open Riscv_opt open Riscv_ssa let opt tac = - let out_noopt = Printf.sprintf "%s-no-opt.ssa" !Driver_config.Linkcore_Opt.output_file in - Basic_io.write out_noopt (String.concat "\n" (List.map Riscv_ssa.to_string tac)); + Riscv_ssa.write_to_file "-no-opt.ssa" tac; List.iter (fun top -> match top with | FnDecl { fn; args } -> Hashtbl.add params fn args @@ -12,14 +11,16 @@ let opt tac = iter_fn2 build_cfg tac; let ssa = Riscv_tac2ssa.ssa_of_tac tac in - + + Riscv_ssa.write_to_file "-opt0.ssa" ssa; + for i = 1 to 3 do + Riscv_ssa.write_to_file (Printf.sprintf "-opt%d.ssa" i) ssa; Riscv_opt_inline.inline ssa; Riscv_opt_peephole.peephole ssa; Riscv_opt_escape.lower_malloc ssa; done; let s = map_fn ssa_of_cfg ssa in - let out = Printf.sprintf "%s.ssa" !Driver_config.Linkcore_Opt.output_file in - Basic_io.write out (String.concat "\n" (List.map Riscv_ssa.to_string s)); + write_to_file ".ssa" s; s \ No newline at end of file From 090138719cdffdd916d2814826aa30072e35ace3 Mon Sep 17 00:00:00 2001 From: Milky2018 <842376130@qq.com> Date: Wed, 28 May 2025 02:59:57 +0000 Subject: [PATCH 12/13] Merge conficts resolved. --- src/riscv_generate.ml | 2 +- src/riscv_ssa.ml | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/riscv_generate.ml b/src/riscv_generate.ml index 3b89ac8..6263b57 100644 --- a/src/riscv_generate.ml +++ b/src/riscv_generate.ml @@ -163,7 +163,7 @@ let deal_with_prim tac rd (prim: Primitive.prim) args = (* Discard higher bits by shifting, but arithmetic *) let temp = new_temp Mtype.T_uint64 in Vec.push tac (Slli { rd = temp; rs = arg; imm = 32 }); - Vec.push tac (Srli { rd; rs = temp; imm = 32 }) + Vec.push tac (Srai { rd; rs = temp; imm = 32 }) | I32, U32 | U32, I32 | I32, I64 -> (* Simply do nothing *) diff --git a/src/riscv_ssa.ml b/src/riscv_ssa.ml index 2757fff..c28d720 100644 --- a/src/riscv_ssa.ml +++ b/src/riscv_ssa.ml @@ -266,15 +266,15 @@ let rec sizeof ty = (** Emits SSA form. We choose a less human-readable form to facilitate verifier. *) let to_string t = let rtype op ({ rd; rs1; rs2 }: r_type) = - Printf.sprintf "%s %s:%s %s:%s %s:%s" op rd.name (Mtype.to_string rd.ty) rs1.name (Mtype.to_string rs1.ty) rs2.name (Mtype.to_string rs2.ty) + Printf.sprintf "%s %s %s %s" op rd.name rs1.name rs2.name in let r2type op ({ rd; rs1; }: r2_type) = - Printf.sprintf "%s %s:%s %s:%s" op rd.name (Mtype.to_string rd.ty) rs1.name (Mtype.to_string rs1.ty) + Printf.sprintf "%s %s %s" op rd.name rs1.name in let itype op ({ rd; rs; imm } : i_type) = - Printf.sprintf "%s %s:%s %s:%s %d" op rd.name (Mtype.to_string rd.ty) rs.name (Mtype.to_string rs.ty) imm + Printf.sprintf "%s %s %s %d" op rd.name rs.name imm in (* Deals with signedness: signed or unsigned *) @@ -283,7 +283,7 @@ let to_string t = let width = (match rd.ty with | T_uint | T_uint64 -> "u" | _ -> "") in - Printf.sprintf "%s%s %s:%s %s:%s %s:%s" op width rd.name (Mtype.to_string rd.ty) rs1.name (Mtype.to_string rs1.ty) rs2.name (Mtype.to_string rs2.ty) + Printf.sprintf "%s%s %s %s %s" op width rd.name rs1.name rs2.name in (* Deals with width: 32 or 64 bit *) @@ -291,7 +291,7 @@ let to_string t = let width = (match rd.ty with | T_int | T_uint -> "w" | _ -> "") in - Printf.sprintf "%s%s %s:%s %s:%s %s:%s" op width rd.name (Mtype.to_string rd.ty) rs1.name (Mtype.to_string rs1.ty) rs2.name (Mtype.to_string rs2.ty) + Printf.sprintf "%s%s %s %s %s" op width rd.name rs1.name rs2.name in (* Deals with both width and signedness *) @@ -301,14 +301,14 @@ let to_string t = | T_uint -> "uw" | T_uint64 -> "u" | _ -> "") in - Printf.sprintf "%s%s %s:%s %s:%s %s:%s" op width rd.name (Mtype.to_string rd.ty) rs1.name (Mtype.to_string rs1.ty) rs2.name (Mtype.to_string rs2.ty) + Printf.sprintf "%s%s %s %s %s" op width rd.name rs1.name rs2.name in let itypew op ({ rd; rs; imm }: i_type) = let width = (match rd.ty with | T_int | T_uint -> "w" | _ -> "") in - Printf.sprintf "%s%s %s:%s %s:%s %d" op width rd.name (Mtype.to_string rd.ty) rs.name (Mtype.to_string rs.ty) imm + Printf.sprintf "%s%s %s %s %d" op width rd.name rs.name imm in (* Dedicated for slt *) @@ -319,7 +319,7 @@ let to_string t = | T_int -> "sltiw" | T_uint64 -> "sltiuw" | _ -> "") in - Printf.sprintf "%s %s:%s %s:%s %d" width rd.name (Mtype.to_string rd.ty) rs.name (Mtype.to_string rs.ty) imm + Printf.sprintf "%s %s %s %d" width rd.name rs.name imm in (* Similarly, `srl` and `sra` are instructions where `rs` matters rather than `rd` *) @@ -328,7 +328,7 @@ let to_string t = let width = (match rs.ty with | T_uint | T_int -> "w" | _ -> "") in - Printf.sprintf "%s%s %s:%s %s:%s %d" op width rd.name (Mtype.to_string rd.ty) rs.name (Mtype.to_string rs.ty) imm + Printf.sprintf "%s%s %s %s %d" op width rd.name rs.name imm in let die x = From 1307fa4455b73c0366e5e2bf57b88bce05caab30 Mon Sep 17 00:00:00 2001 From: Milky2018 <842376130@qq.com> Date: Wed, 28 May 2025 09:17:10 +0000 Subject: [PATCH 13/13] Revert "Merge conficts resolved." This reverts commit 090138719cdffdd916d2814826aa30072e35ace3. --- src/riscv_generate.ml | 2 +- src/riscv_ssa.ml | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/riscv_generate.ml b/src/riscv_generate.ml index 6263b57..3b89ac8 100644 --- a/src/riscv_generate.ml +++ b/src/riscv_generate.ml @@ -163,7 +163,7 @@ let deal_with_prim tac rd (prim: Primitive.prim) args = (* Discard higher bits by shifting, but arithmetic *) let temp = new_temp Mtype.T_uint64 in Vec.push tac (Slli { rd = temp; rs = arg; imm = 32 }); - Vec.push tac (Srai { rd; rs = temp; imm = 32 }) + Vec.push tac (Srli { rd; rs = temp; imm = 32 }) | I32, U32 | U32, I32 | I32, I64 -> (* Simply do nothing *) diff --git a/src/riscv_ssa.ml b/src/riscv_ssa.ml index c28d720..2757fff 100644 --- a/src/riscv_ssa.ml +++ b/src/riscv_ssa.ml @@ -266,15 +266,15 @@ let rec sizeof ty = (** Emits SSA form. We choose a less human-readable form to facilitate verifier. *) let to_string t = let rtype op ({ rd; rs1; rs2 }: r_type) = - Printf.sprintf "%s %s %s %s" op rd.name rs1.name rs2.name + Printf.sprintf "%s %s:%s %s:%s %s:%s" op rd.name (Mtype.to_string rd.ty) rs1.name (Mtype.to_string rs1.ty) rs2.name (Mtype.to_string rs2.ty) in let r2type op ({ rd; rs1; }: r2_type) = - Printf.sprintf "%s %s %s" op rd.name rs1.name + Printf.sprintf "%s %s:%s %s:%s" op rd.name (Mtype.to_string rd.ty) rs1.name (Mtype.to_string rs1.ty) in let itype op ({ rd; rs; imm } : i_type) = - Printf.sprintf "%s %s %s %d" op rd.name rs.name imm + Printf.sprintf "%s %s:%s %s:%s %d" op rd.name (Mtype.to_string rd.ty) rs.name (Mtype.to_string rs.ty) imm in (* Deals with signedness: signed or unsigned *) @@ -283,7 +283,7 @@ let to_string t = let width = (match rd.ty with | T_uint | T_uint64 -> "u" | _ -> "") in - Printf.sprintf "%s%s %s %s %s" op width rd.name rs1.name rs2.name + Printf.sprintf "%s%s %s:%s %s:%s %s:%s" op width rd.name (Mtype.to_string rd.ty) rs1.name (Mtype.to_string rs1.ty) rs2.name (Mtype.to_string rs2.ty) in (* Deals with width: 32 or 64 bit *) @@ -291,7 +291,7 @@ let to_string t = let width = (match rd.ty with | T_int | T_uint -> "w" | _ -> "") in - Printf.sprintf "%s%s %s %s %s" op width rd.name rs1.name rs2.name + Printf.sprintf "%s%s %s:%s %s:%s %s:%s" op width rd.name (Mtype.to_string rd.ty) rs1.name (Mtype.to_string rs1.ty) rs2.name (Mtype.to_string rs2.ty) in (* Deals with both width and signedness *) @@ -301,14 +301,14 @@ let to_string t = | T_uint -> "uw" | T_uint64 -> "u" | _ -> "") in - Printf.sprintf "%s%s %s %s %s" op width rd.name rs1.name rs2.name + Printf.sprintf "%s%s %s:%s %s:%s %s:%s" op width rd.name (Mtype.to_string rd.ty) rs1.name (Mtype.to_string rs1.ty) rs2.name (Mtype.to_string rs2.ty) in let itypew op ({ rd; rs; imm }: i_type) = let width = (match rd.ty with | T_int | T_uint -> "w" | _ -> "") in - Printf.sprintf "%s%s %s %s %d" op width rd.name rs.name imm + Printf.sprintf "%s%s %s:%s %s:%s %d" op width rd.name (Mtype.to_string rd.ty) rs.name (Mtype.to_string rs.ty) imm in (* Dedicated for slt *) @@ -319,7 +319,7 @@ let to_string t = | T_int -> "sltiw" | T_uint64 -> "sltiuw" | _ -> "") in - Printf.sprintf "%s %s %s %d" width rd.name rs.name imm + Printf.sprintf "%s %s:%s %s:%s %d" width rd.name (Mtype.to_string rd.ty) rs.name (Mtype.to_string rs.ty) imm in (* Similarly, `srl` and `sra` are instructions where `rs` matters rather than `rd` *) @@ -328,7 +328,7 @@ let to_string t = let width = (match rs.ty with | T_uint | T_int -> "w" | _ -> "") in - Printf.sprintf "%s%s %s %s %d" op width rd.name rs.name imm + Printf.sprintf "%s%s %s:%s %s:%s %d" op width rd.name (Mtype.to_string rd.ty) rs.name (Mtype.to_string rs.ty) imm in let die x =