├── compiler ├── src │ ├── CIL │ │ ├── .keep │ │ └── .gitignore │ ├── syscall_t.ml │ ├── help.mli │ ├── latex_printer.mli │ ├── pp_riscv.mli │ ├── config.mli │ ├── pp_arm_m4.mli │ ├── slicing.mli │ ├── array_expand.mli │ ├── syscall_ocaml.mli │ ├── debugInfo.mli │ ├── tt_arm_m4.mli │ ├── parseio.mli │ ├── checkAnnot.mli │ ├── interval.mli │ ├── intervalGraphColoring.mli │ ├── printFexpr.mli │ ├── scopeTree.mli │ ├── pp_x86.mli │ ├── interval.ml │ ├── iInfo.ml │ ├── pp_stack_alloc.mli │ ├── printLinear.mli │ └── removeUnusedResults.mli ├── tests │ ├── fail │ │ ├── x86-64 │ │ │ ├── string.jazz │ │ │ ├── swap_type_mismatch.jazz │ │ │ ├── shift.jazz │ │ │ ├── swap128.jazz │ │ │ ├── zxspill.jazz │ │ │ ├── por_reg.jazz │ │ │ ├── por_reg_intrinsic.jazz │ │ │ ├── por_mem.jazz │ │ │ ├── por_32.jazz │ │ │ ├── swap_int.jazz │ │ │ ├── swap_bool.jazz │ │ │ ├── por_mem_intrinsic.jazz │ │ │ ├── por_32_intrinsic.jazz │ │ │ └── unaligned_slice_copy.jazz │ │ ├── typing │ │ │ └── x86-64 │ │ │ │ ├── global_int.jazz │ │ │ │ ├── global_in_global_def.jazz │ │ │ │ ├── only_param.jazz │ │ │ │ ├── init_global.jazz │ │ │ │ ├── bug_488.jazz │ │ │ │ ├── export_stack_res.jazz │ │ │ │ ├── lval_param.jazz │ │ │ │ ├── bug_69.jazz │ │ │ │ ├── unsupported_primitive.jazz │ │ │ │ ├── subarray_non_const_len.jazz │ │ │ │ ├── write_constant_pointer_direct_array.jazz │ │ │ │ ├── vector_expr.jazz │ │ │ │ ├── non_inline_stack_res.jazz │ │ │ │ ├── non_inline_stack_arg.jazz │ │ │ │ └── export_reg_array_res.jazz │ │ ├── common │ │ │ ├── typealias_duplicate.jazz │ │ │ ├── typealias_notfound.jazz │ │ │ ├── var_initialize_if.jazz │ │ │ ├── typealias_arrayelement.jazz │ │ │ ├── typealias_arrayelement_integer.jazz │ │ │ ├── var_initialize_undecl.jazz │ │ │ ├── storage_signature_mismatch.jazz │ │ │ ├── inline-remains.jazz │ │ │ ├── typealias_annotation_param.jazz │ │ │ ├── not-unrollable-for-loop.jazz │ │ │ └── bug_1214.jazz │ │ ├── param_expansion │ │ │ └── x86-64 │ │ │ │ ├── array_size_mismatch.jazz │ │ │ │ ├── operator_global.jazz │ │ │ │ ├── array_size_mismatch2.jazz │ │ │ │ ├── array_too_large_global.jazz │ │ │ │ ├── expression_global2.jazz │ │ │ │ ├── expression_global.jazz │ │ │ │ ├── operator_arg.jazz │ │ │ │ ├── expression_arg.jazz │ │ │ │ ├── operator_res.jazz │ │ │ │ ├── expression_res.jazz │ │ │ │ ├── global_not_constant.jazz │ │ │ │ ├── array_too_large_arg.jazz │ │ │ │ ├── global_array_not_constant.jazz │ │ │ │ ├── array_too_large_expr.jazz │ │ │ │ └── array_too_large_lval.jazz │ │ ├── register_allocation │ │ │ ├── arm-m4 │ │ │ │ ├── bug_201.jazz │ │ │ │ ├── too_many_args.jazz │ │ │ │ ├── too_many_large_ret.jazz │ │ │ │ ├── no_mmx.jazz │ │ │ │ ├── no_vector.jazz │ │ │ │ └── too_many_ret.jazz │ │ │ └── x86-64 │ │ │ │ ├── unknown_type_register.jazz │ │ │ │ ├── too_many_args.jazz │ │ │ │ ├── too_many_large_args.jazz │ │ │ │ ├── bug_421.jazz │ │ │ │ ├── merge_across_banks.jazz │ │ │ │ ├── no_register_bank.jazz │ │ │ │ ├── bug_309.jazz │ │ │ │ ├── bug_426_bis.jazz │ │ │ │ ├── var_unallocated.jazz │ │ │ │ ├── bug_426.jazz │ │ │ │ ├── bug_310.jazz │ │ │ │ ├── bug_523.jazz │ │ │ │ ├── too_many_ret.jazz │ │ │ │ ├── too_many_large_ret.jazz │ │ │ │ ├── conflicting_variables.jazz │ │ │ │ ├── already_allocated.jazz │ │ │ │ └── conflicting_register.jazz │ │ ├── namespaces │ │ │ └── common │ │ │ │ └── duplicate.jazz │ │ ├── slh │ │ │ └── x86-64 │ │ │ │ ├── msf_lval.jazz │ │ │ │ ├── invalid_type.jazz │ │ │ │ ├── export_takes_msf.jazz │ │ │ │ ├── mov_msf.jazz │ │ │ │ ├── no_msf.jazz │ │ │ │ ├── assign_kills_msf.jazz │ │ │ │ ├── protect_kills_msf.jazz │ │ │ │ ├── intrinsic_kills_msf.jazz │ │ │ │ ├── function_kills_msf.jazz │ │ │ │ ├── function_needs_msf.jazz │ │ │ │ ├── if_wrong_update.jazz │ │ │ │ └── while_wrong_update.jazz │ │ ├── arm-m4 │ │ │ ├── mov_imm_shifted.jazz │ │ │ ├── mov_imm_too_large.jazz │ │ │ ├── mvn_imm_shifted.jazz │ │ │ ├── mvn_imm_too_large.jazz │ │ │ ├── add_imm_too_large.jazz │ │ │ ├── and_imm_too_large.jazz │ │ │ ├── bic_imm_shifted.jazz │ │ │ ├── bic_imm_too_large.jazz │ │ │ ├── eor_imm_shifted.jazz │ │ │ ├── eor_imm_too_large.jazz │ │ │ ├── movw_set_flags.jazz │ │ │ ├── orr_imm_shifted.jazz │ │ │ ├── orr_imm_too_large.jazz │ │ │ ├── rsb_imm_too_large.jazz │ │ │ ├── sub_imm_too_large.jazz │ │ │ ├── addw_set_flags.jazz │ │ │ ├── subw_set_flags.jazz │ │ │ ├── and_imm_shifted.jazz │ │ │ ├── mov_shiftedw_set_flags.jazz │ │ │ ├── add_shift.jazz │ │ │ ├── adc_imm_too_large.jazz │ │ │ ├── cmp_imm_too_large.jazz │ │ │ ├── tst_imm_shifted.jazz │ │ │ ├── tst_imm_too_large.jazz │ │ │ ├── bug_1112.jazz │ │ │ └── bug_667.jazz │ │ ├── lower_spill │ │ │ ├── needs_to_be_spilled_not_spilled.jazz │ │ │ └── needs_to_be_spilled_overwritten.jazz │ │ ├── array_expansion │ │ │ └── x86-64 │ │ │ │ ├── export_param.jazz │ │ │ │ ├── index_out_of_bounds_lv.jazz │ │ │ │ ├── export_return.jazz │ │ │ │ ├── index_not_constant_lv.jazz │ │ │ │ ├── default_scale_2.jazz │ │ │ │ ├── index_out_of_bounds.jazz │ │ │ │ ├── default_scale.jazz │ │ │ │ ├── default_scale_lv_2.jazz │ │ │ │ ├── array_param_not_reg.jazz │ │ │ │ ├── bug_333.jazz │ │ │ │ ├── index_not_constant.jazz │ │ │ │ ├── type_mismatch_param.jazz │ │ │ │ ├── default_scale_param.jazz │ │ │ │ ├── default_scale_lv.jazz │ │ │ │ ├── sub_array_param_not_reg.jazz │ │ │ │ ├── type_mismatch_param_sub.jazz │ │ │ │ ├── index_not_constant_param.jazz │ │ │ │ ├── array_return_not_reg.jazz │ │ │ │ ├── default_scale_return.jazz │ │ │ │ ├── type_mismatch_return.jazz │ │ │ │ ├── sub_array_return_not_reg.jazz │ │ │ │ ├── type_mismatch_return_sub.jazz │ │ │ │ ├── whole_array_lv.jazz │ │ │ │ ├── sub_array_lv.jazz │ │ │ │ └── whole_array.jazz │ │ ├── asmgen │ │ │ ├── x86-64 │ │ │ │ ├── invalid_scale.jazz │ │ │ │ ├── incompatible_args.jazz │ │ │ │ └── uninit_flag.jazz │ │ │ └── arm-m4 │ │ │ │ └── address_too_complex.jazz │ │ ├── stack_allocation │ │ │ ├── x86-64 │ │ │ │ ├── out_of_bounds_read.jazz │ │ │ │ ├── out_of_bounds_write.jazz │ │ │ │ ├── out_of_bounds_read_neg.jazz │ │ │ │ ├── out_of_bounds_write_neg.jazz │ │ │ │ ├── return_subslice.jazz │ │ │ │ ├── out_of_bounds_read_partial.jazz │ │ │ │ ├── merge_params.jazz │ │ │ │ ├── return_ptr_global.jazz │ │ │ │ ├── return_ptr_local.jazz │ │ │ │ ├── local_stack_to_pointer.jazz │ │ │ │ ├── merge_too_large_param.jazz │ │ │ │ ├── range_overflow.jazz │ │ │ │ ├── reg_var_expected.jazz │ │ │ │ ├── pointer_to_local_stack.jazz │ │ │ │ ├── no_region_reg_ptr.jazz │ │ │ │ ├── no_region_stack_ptr.jazz │ │ │ │ ├── write_constant_pointer_arg.jazz │ │ │ │ ├── merge_param_global.jazz │ │ │ │ ├── merge_same_trivial.jazz │ │ │ │ ├── stack_ptr_in_expr.jazz │ │ │ │ ├── bad_range_alignment.jazz │ │ │ │ ├── merge_too_large_global.jazz │ │ │ │ ├── bad_alignment.jazz │ │ │ │ ├── merge_same.jazz │ │ │ │ ├── write_constant_stack_global.jazz │ │ │ │ ├── array_access_too_complex.jazz │ │ │ │ ├── write_constant_pointer_global.jazz │ │ │ │ ├── condition_move_ptr.jazz │ │ │ │ ├── merge_same_var.jazz │ │ │ │ ├── regions_not_equal_array.jazz │ │ │ │ ├── regions_not_equal_subarray.jazz │ │ │ │ ├── protect_ptr_arg.jazz │ │ │ │ ├── protect_ptr_res.jazz │ │ │ │ ├── bug_54.jazz │ │ │ │ ├── merge_globals.jazz │ │ │ │ ├── unaligned_sub_offset_unscaled.jazz │ │ │ │ ├── unaligned_sub_offset.jazz │ │ │ │ └── merge_global_param.jazz │ │ │ ├── arm-m4 │ │ │ │ └── cannot_compute_address.jazz │ │ │ └── risc-v │ │ │ │ └── cannot_compute_address.jazz │ │ ├── annotation │ │ │ └── x86-64 │ │ │ │ ├── calldepth.jazz │ │ │ │ ├── stacksize.jazz │ │ │ │ └── stackalign.jazz │ │ ├── unroll │ │ │ └── x86-64 │ │ │ │ ├── bug_29.jazz │ │ │ │ └── bug_150.jazz │ │ ├── risc-v │ │ │ └── basics.jazz │ │ ├── pointers │ │ │ └── x86-64 │ │ │ │ └── test_writable_arguments.jazz │ │ └── subarrays │ │ │ └── x86-64 │ │ │ ├── partial_region.jazz │ │ │ └── unscaled_access.jazz │ ├── safety │ │ ├── success │ │ │ ├── common │ │ │ │ ├── bug_385.jazz │ │ │ │ ├── copy.jazz │ │ │ │ ├── int_shift.jazz │ │ │ │ ├── nested_for.jazz │ │ │ │ ├── bug_386.jazz │ │ │ │ ├── randombytes.jazz │ │ │ │ └── swap.jazz │ │ │ ├── x86-64 │ │ │ │ ├── not.jazz │ │ │ │ ├── msbclear.jazz │ │ │ │ ├── array-export.jazz │ │ │ │ ├── flags.jazz │ │ │ │ ├── dynglob.jazz │ │ │ │ ├── decompile.jazz │ │ │ │ ├── div.jazz │ │ │ │ ├── align2.jazz │ │ │ │ ├── while_heur_flag.jazz │ │ │ │ ├── bounded_while.jazz │ │ │ │ ├── loop1.jazz │ │ │ │ ├── bug_314.jazz │ │ │ │ ├── align.jazz │ │ │ │ ├── trusted-termination.jazz │ │ │ │ └── carry_flags.jazz │ │ │ ├── riscv │ │ │ │ ├── dynglob.jazz │ │ │ │ ├── align.jazz │ │ │ │ ├── align2.jazz │ │ │ │ ├── bounded_while.jazz │ │ │ │ └── loop1.jazz │ │ │ └── arm-m4 │ │ │ │ ├── align.jazz │ │ │ │ ├── dynglob.jazz │ │ │ │ ├── align2.jazz │ │ │ │ ├── bounded_while.jazz │ │ │ │ ├── loop1.jazz │ │ │ │ └── carry_flags.jazz │ │ ├── fail │ │ │ ├── x86-64 │ │ │ │ ├── shld.jazz │ │ │ │ ├── array-export.jazz │ │ │ │ ├── bad_align.jazz │ │ │ │ ├── popcnt.jazz │ │ │ │ ├── bad_align2.jazz │ │ │ │ ├── carry_flags_err.jazz │ │ │ │ ├── carry_flags_err2.jazz │ │ │ │ ├── decompile_fail.jazz │ │ │ │ └── mul0.jazz │ │ │ ├── common │ │ │ │ ├── wint_overflow.jazz │ │ │ │ ├── not_in_bounds.jazz │ │ │ │ ├── array_init.jazz │ │ │ │ ├── init-join.jazz │ │ │ │ ├── fail_land.jazz │ │ │ │ └── fail_land2.jazz │ │ │ ├── arm-m4 │ │ │ │ ├── array-export.jazz │ │ │ │ ├── bad_align.jazz │ │ │ │ └── bad_align2.jazz │ │ │ └── risc-v │ │ │ │ ├── array-export.jazz │ │ │ │ ├── bad_align.jazz │ │ │ │ └── bad_align2.jazz │ │ └── dune │ ├── success │ │ ├── common │ │ │ ├── dead_spill.jazz │ │ │ ├── immediate.jazz │ │ │ ├── swap_word.jazz │ │ │ ├── bug_870.jazz │ │ │ ├── annotations.jazz │ │ │ ├── bug_1296.jazz │ │ │ ├── bug_729.jazz │ │ │ ├── intshift.jazz │ │ │ ├── bug_540.jazz │ │ │ ├── bug_815.jazz │ │ │ ├── test_keep.jazz │ │ │ ├── bug_1292.jazz │ │ │ ├── call-export.jazz │ │ │ ├── bug_483.jazz │ │ │ ├── t_array_expand.jazz │ │ │ ├── spill_pointer.jazz │ │ │ ├── varalreadyset.jazz │ │ │ ├── test_type_eq.jazz │ │ │ ├── cast_int.jazz │ │ │ ├── bug_871.jazz │ │ │ ├── inline_label_duplication.jazz │ │ │ ├── bug_607.jazz │ │ │ └── integer_notation.jazz │ │ ├── x86-64 │ │ │ ├── clflush.jazz │ │ │ ├── bug_730.jazz │ │ │ ├── bug_224.jazz │ │ │ ├── test_bool.jazz │ │ │ ├── test_minus_one.jazz │ │ │ ├── vector_arguments.jazz │ │ │ ├── addr_0.jazz │ │ │ ├── inline_call_to_export.jazz │ │ │ ├── fences.jazz │ │ │ ├── pack.jazz │ │ │ ├── test_cast_sopn.jazz │ │ │ ├── bug_681.jazz │ │ │ ├── test_global.jazz │ │ │ ├── test_movcc.jazz │ │ │ ├── too_large_immediate.jazz │ │ │ ├── test_for.jazz │ │ │ ├── dynglob.jazz │ │ │ ├── prefetch.jazz │ │ │ ├── sar.jazz │ │ │ ├── bug_1139.jazz │ │ │ ├── bug_200.jazz │ │ │ ├── test_mem.jazz │ │ │ ├── array_add.jazz │ │ │ ├── test_lowereq.jazz │ │ │ ├── bug_54.jazz │ │ │ ├── concat_2u128.jazz │ │ │ ├── inline-if.jazz │ │ │ ├── strings.jazz │ │ │ ├── unroll_nested_loop.jazz │ │ │ ├── dead_code_arr_init.jazz │ │ │ ├── bug_1138.jazz │ │ │ ├── glob_in_regptr.jazz │ │ │ ├── bug_599.jazz │ │ │ ├── test_global_string_literal.jazz │ │ │ ├── vpermd.jazz │ │ │ ├── test_lea_sub.jazz │ │ │ ├── bswap.jazz │ │ │ ├── bug_340.jazz │ │ │ ├── ifelse.jazz │ │ │ ├── truncate_if.jazz │ │ │ ├── test_lnot.jazz │ │ │ ├── set0_through_pointer.jazz │ │ │ ├── bug_455.jazz │ │ │ ├── call_conv_windows.jazz │ │ │ ├── cqo.jazz │ │ │ ├── inline_regptr.jazz │ │ │ ├── test_inline_var.jazz │ │ │ ├── vmovhpd.jazz │ │ │ ├── vmovlpd.jazz │ │ │ ├── eval_for.jazz │ │ │ ├── arraycopy.jazz │ │ │ ├── refmod.jazz │ │ │ ├── test_glob_array_while2.jazz │ │ │ ├── por.jazz │ │ │ ├── sha256.jazz │ │ │ ├── vpsxldq.jazz │ │ │ ├── arr_init_param.jazz │ │ │ ├── calldepth.jazz │ │ │ ├── test_move_ptr_to_stack.jazz │ │ │ ├── inline-literal-arg.jazz │ │ │ ├── pdep.jazz │ │ │ ├── pext.jazz │ │ │ ├── clc-stc.jazz │ │ │ ├── init-in-loop.jazz │ │ │ └── init_stack-array_in_inline-fn.jazz │ │ ├── arm-m4 │ │ │ ├── large_stack │ │ │ │ ├── reg_ptr.jazz │ │ │ │ ├── reg_ptr_large.jazz │ │ │ │ ├── sub_reg_ptr_large.jazz │ │ │ │ ├── large_internal_stack.jazz │ │ │ │ ├── very_large_internal_stack.jazz │ │ │ │ └── sub_reg_ptr_template.jinc │ │ │ ├── neg.jazz │ │ │ ├── bug_375.jazz │ │ │ ├── mulu.jazz │ │ │ ├── stack_array.jazz │ │ │ ├── sub_using_RSB.jazz │ │ │ ├── intrinsic_umaal.jazz │ │ │ ├── intrinsic_clz.jazz │ │ │ ├── load_immediate.jazz │ │ │ ├── test_global_string_literal.jazz │ │ │ ├── cmove.jazz │ │ │ ├── conditions.jazz │ │ │ ├── bug_1112.jazz │ │ │ ├── intrinsic_bfc.jazz │ │ │ ├── intrinsic_smulw_hw.jazz │ │ │ ├── intrinsic_bfi.jazz │ │ │ └── intrinsic_rev.jazz │ │ ├── risc-v │ │ │ ├── large_stack │ │ │ │ ├── reg_ptr.jazz │ │ │ │ ├── reg_ptr_large.jazz │ │ │ │ ├── large_internal_stack.jazz │ │ │ │ └── very_large_internal_stack.jazz │ │ │ ├── neg.jazz │ │ │ ├── load.jazz │ │ │ ├── div.jazz │ │ │ ├── intrinsic_div.jazz │ │ │ ├── intrinsic_rem.jazz │ │ │ ├── rem.jazz │ │ │ ├── intrinsic_sll.jazz │ │ │ ├── intrinsic_sra.jazz │ │ │ ├── intrinsic_srl.jazz │ │ │ ├── sll.jazz │ │ │ ├── sra.jazz │ │ │ ├── srl.jazz │ │ │ ├── intrinsic_sub.jazz │ │ │ └── slt.jazz │ │ ├── noextract │ │ │ └── x86-64 │ │ │ │ └── empty.jazz │ │ ├── require │ │ │ └── common │ │ │ │ ├── file1.jazz │ │ │ │ └── file2.jazz │ │ ├── namespaces │ │ │ └── common │ │ │ │ ├── qident.jazz │ │ │ │ ├── sum.jinc │ │ │ │ ├── export.jazz │ │ │ │ └── map.jinc │ │ ├── tunneling │ │ │ └── x86-64 │ │ │ │ └── tunneling.jazz │ │ ├── slh │ │ │ └── x86-64 │ │ │ │ ├── init_msf.jazz │ │ │ │ ├── protect_128.jazz │ │ │ │ ├── protect_256.jazz │ │ │ │ ├── protect_8.jazz │ │ │ │ ├── protect_16.jazz │ │ │ │ ├── protect_32.jazz │ │ │ │ ├── protect_64.jazz │ │ │ │ ├── function_kills_msf_2.jazz │ │ │ │ ├── function_kills_msf_1.jazz │ │ │ │ ├── spill_mmx.jazz │ │ │ │ └── mmx.jazz │ │ ├── subroutines │ │ │ └── x86-64 │ │ │ │ ├── id.jazz │ │ │ │ ├── literal-argument.jazz │ │ │ │ ├── global.jazz │ │ │ │ ├── memptr.jazz │ │ │ │ ├── loop.jazz │ │ │ │ └── substack.jazz │ │ ├── syscall │ │ │ └── x86-64 │ │ │ │ └── align.jazz │ │ ├── subarrays │ │ │ ├── arm-m4 │ │ │ │ ├── global.jazz │ │ │ │ ├── reg_ptr_const.jazz │ │ │ │ ├── global_const.jazz │ │ │ │ ├── reg_ptr_const_large.jazz │ │ │ │ ├── stack_ptr.jazz │ │ │ │ ├── reg_ptr_unscaled.jazz │ │ │ │ ├── reg_ptr_scaled.jazz │ │ │ │ ├── reg_ptr_const_zero.jazz │ │ │ │ └── index_var.jazz │ │ │ ├── risc-v │ │ │ │ ├── global.jazz │ │ │ │ ├── reg_ptr_const.jazz │ │ │ │ ├── global_const.jazz │ │ │ │ ├── reg_ptr_const_large.jazz │ │ │ │ ├── stack_ptr.jazz │ │ │ │ ├── reg_ptr_unscaled.jazz │ │ │ │ └── reg_ptr_const_zero.jazz │ │ │ └── x86-64 │ │ │ │ ├── global.jazz │ │ │ │ ├── reg_ptr_const.jazz │ │ │ │ ├── global_const.jazz │ │ │ │ ├── stack_ptr.jazz │ │ │ │ ├── align2.jazz │ │ │ │ ├── reg_ptr_scaled.jazz │ │ │ │ ├── reg_ptr_unscaled.jazz │ │ │ │ ├── index_var.jazz │ │ │ │ ├── reg_ptr_const_zero.jazz │ │ │ │ ├── nested.jazz │ │ │ │ └── nested_var.jazz │ │ ├── pointers │ │ │ └── x86-64 │ │ │ │ ├── zerofill.jazz │ │ │ │ └── test_writable_arguments.jazz │ │ └── typing │ │ │ └── x86-64 │ │ │ └── assign_constant_pointer_local_var.jazz │ ├── exec │ │ ├── return-undef.jazz │ │ ├── for.jazz │ │ ├── inline-call.jazz │ │ ├── cmoveptr.jazz │ │ └── vpsxldq.jazz │ ├── sct-checker │ │ ├── success │ │ │ ├── bug_1189.jazz │ │ │ ├── bug_852.jazz │ │ │ ├── conditional-expr.jazz │ │ │ ├── while.jazz │ │ │ ├── movmsf.jazz │ │ │ └── bug_1097.jazz │ │ ├── fail │ │ │ ├── bug_1179.jazz │ │ │ ├── bug_1189_warning.jazz │ │ │ ├── bug_887.jazz │ │ │ ├── spill.jazz │ │ │ └── functions.jazz │ │ └── common.mli │ ├── warning │ │ ├── x86-64 │ │ │ ├── reg_const_ptr.jazz │ │ │ ├── lea.jazz │ │ │ ├── ignored_zero_extension.jazz │ │ │ └── extra_assignment.jazz │ │ ├── risc-v │ │ │ └── load_constant_warning.jazz │ │ └── common │ │ │ └── bug_1347.jazz │ └── pending │ │ └── x86-64 │ │ ├── cmoveptr.jazz │ │ └── even.jazz ├── examples │ ├── gimli │ │ ├── .gitignore │ │ ├── x86-64 │ │ │ ├── gimliv.jazz │ │ │ ├── gimliv1.jazz │ │ │ └── test.exp │ │ └── proofs │ │ │ ├── ec.config │ │ │ └── .gitignore │ ├── extraction-unit-tests │ │ ├── .gitignore │ │ ├── ec.config │ │ ├── sdiv.jazz │ │ ├── gcd.jazz │ │ └── add_in_mem.jazz │ ├── x86-64 │ │ ├── retz.jazz │ │ ├── identity.jazz │ │ ├── add1.jazz │ │ ├── noset0.jazz │ │ ├── bt.jazz │ │ ├── test_amikoj.jazz │ │ ├── threeway.jazz │ │ ├── test_var_alloc2.jazz │ │ ├── memcmp.jazz │ │ ├── al3.jazz │ │ └── nesteed_array.jazz │ └── siphash │ │ └── x86-64 │ │ └── makefile ├── safetylib │ ├── domains │ │ ├── safetySymEq.mli │ │ ├── safetyCongr.mli │ │ ├── safetyPointsTo.mli │ │ └── safetyDisjunctive.mli │ └── dune ├── syscall │ ├── Makefile │ └── jasmin_syscall.h ├── CCT │ ├── fail │ │ ├── doc_leak_store.jazz │ │ ├── load_on_secret.jazz │ │ ├── load_on_poly.jazz │ │ ├── doc_leak_cond.jazz │ │ ├── H_L_L.jazz │ │ ├── doc_leak_arr_load.jazz │ │ ├── div_secret.jazz │ │ ├── mod_secret.jazz │ │ ├── doit │ │ │ └── x86_64 │ │ │ │ ├── rol.jazz │ │ │ │ └── xchg.jazz │ │ ├── randombytes.jazz │ │ ├── doc_bad_call.jazz │ │ └── secret_ptr.jazz │ └── success │ │ ├── doc_store.jazz │ │ ├── doc_zero.jazz │ │ ├── unused_poly.jazz │ │ ├── doc_load_mem.jazz │ │ ├── doc_add_restr.jazz │ │ ├── doc_add_SP.jazz │ │ ├── doit │ │ ├── by_stack.jazz │ │ └── bug_927.jazz │ │ ├── doc_set0_incr.jazz │ │ ├── div.jazz │ │ ├── randombytes.jazz │ │ └── speculative │ │ └── bug_660.jazz ├── scripts │ ├── update-cast-int │ ├── replace-new-memory-syntax.sh │ └── replace-new-memory-syntax-sedscript ├── linter │ ├── dune │ ├── Error │ │ └── CompileError.ml │ └── Checker │ │ └── DeadVariables.mli ├── dune-project ├── entry │ └── jasminc.ml ├── .gitignore └── uint63 │ ├── dune │ ├── js │ └── dune │ └── native │ └── dune ├── proofs ├── lang │ └── ocaml │ │ ├── .keep │ │ └── .gitignore └── compiler │ └── jasmin_compiler.v ├── docs ├── .gitignore ├── source │ ├── compiler │ │ ├── passes │ │ │ ├── array_copy.md │ │ │ ├── array_init.md │ │ │ ├── array_init_rm.md │ │ │ ├── asm_gen.md │ │ │ ├── tunneling.md │ │ │ ├── linearization.md │ │ │ ├── merge_varmaps.md │ │ │ ├── remove_global.md │ │ │ ├── loop_unrolling.md │ │ │ ├── lower_spill.md │ │ │ ├── reg_alloc.md │ │ │ ├── stack_alloc.md │ │ │ ├── stack_zero.md │ │ │ ├── function_inlining.md │ │ │ ├── inst_select.md │ │ │ ├── make_ref_arguments.md │ │ │ ├── propagate_inline.md │ │ │ ├── constant_propagation.md │ │ │ ├── deadcode_elimination.md │ │ │ ├── liverange_splitting.md │ │ │ ├── lower_slh.md │ │ │ ├── expansion_reg_arrays.md │ │ │ ├── load_constants.md │ │ │ ├── removal_unused_functions.md │ │ │ ├── rm_unused_ret_value.md │ │ │ ├── lower_addr.md │ │ │ └── wint_word.md │ │ └── advanced │ │ │ └── index.md │ └── language │ │ └── semantics │ │ └── index.md ├── requirements.txt ├── README.md └── shell.nix ├── changes ├── 01-feature │ ├── 00000-title.md │ ├── 1342-enable-wint-swap.md │ ├── 1356-auto-spill.md │ ├── 1316-functorize-safety.md │ └── 1328-declassify-operator.jazz ├── 02-bugfix │ ├── 00000-title.md │ ├── 1341-extract-wint-spill.md │ └── 1348-fix-warn-duplicate-glob-var.md ├── 03-other │ ├── 00000-title.md │ ├── 1353-only-delimited-annotations.md │ ├── 1346-deprecate-open-annotations.md │ ├── 1340-print-less-brackets.md │ ├── 1336-deprecated-mem-syntax.md │ └── 1355-optional-empty-lvals.md └── 04-documentation │ └── 00000-title.md ├── eclib ├── easycrypt.project ├── tests.config └── JModel.ec ├── .editorconfig ├── Makefile.compiler └── scripts ├── nixpkgs.nix ├── z3.nix └── generate-release-changelog.sh /compiler/src/CIL/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /proofs/lang/ocaml/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | *~ -------------------------------------------------------------------------------- /compiler/src/CIL/.gitignore: -------------------------------------------------------------------------------- 1 | *.ml 2 | *.mli 3 | -------------------------------------------------------------------------------- /proofs/lang/ocaml/.gitignore: -------------------------------------------------------------------------------- 1 | *.ml 2 | *.mli 3 | -------------------------------------------------------------------------------- /changes/01-feature/00000-title.md: -------------------------------------------------------------------------------- 1 | ## New features 2 | -------------------------------------------------------------------------------- /changes/02-bugfix/00000-title.md: -------------------------------------------------------------------------------- 1 | ## Bug fixes 2 | -------------------------------------------------------------------------------- /changes/03-other/00000-title.md: -------------------------------------------------------------------------------- 1 | ## Other changes 2 | -------------------------------------------------------------------------------- /changes/04-documentation/00000-title.md: -------------------------------------------------------------------------------- 1 | ## Documentation 2 | -------------------------------------------------------------------------------- /compiler/tests/fail/x86-64/string.jazz: -------------------------------------------------------------------------------- 1 | u8[0] z = "\xgg"; 2 | -------------------------------------------------------------------------------- /compiler/tests/fail/typing/x86-64/global_int.jazz: -------------------------------------------------------------------------------- 1 | int g = 42; 2 | -------------------------------------------------------------------------------- /docs/source/compiler/passes/array_copy.md: -------------------------------------------------------------------------------- 1 | # Array Copy 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/source/compiler/passes/array_init.md: -------------------------------------------------------------------------------- 1 | # Array Init 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/source/compiler/passes/array_init_rm.md: -------------------------------------------------------------------------------- 1 | # Removes array-init 2 | -------------------------------------------------------------------------------- /docs/source/compiler/passes/asm_gen.md: -------------------------------------------------------------------------------- 1 | # ASM generation 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/source/compiler/passes/tunneling.md: -------------------------------------------------------------------------------- 1 | # Tunelling 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /eclib/easycrypt.project: -------------------------------------------------------------------------------- 1 | [general] 2 | provers = Z3@4.13 3 | rdirs = . 4 | -------------------------------------------------------------------------------- /eclib/tests.config: -------------------------------------------------------------------------------- 1 | [test-jasmin] 2 | args = -timeout=1 3 | okdirs = . 4 | -------------------------------------------------------------------------------- /compiler/examples/gimli/.gitignore: -------------------------------------------------------------------------------- 1 | test 2 | testv 3 | testv1 4 | test*.out 5 | -------------------------------------------------------------------------------- /compiler/src/syscall_t.ml: -------------------------------------------------------------------------------- 1 | type 'a syscall_t = 2 | | RandomBytes of 'a 3 | -------------------------------------------------------------------------------- /docs/source/compiler/passes/linearization.md: -------------------------------------------------------------------------------- 1 | # Linearization 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/source/compiler/passes/merge_varmaps.md: -------------------------------------------------------------------------------- 1 | # Merge varmaps 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/source/compiler/passes/remove_global.md: -------------------------------------------------------------------------------- 1 | # Remove global 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /compiler/src/help.mli: -------------------------------------------------------------------------------- 1 | val show_intrinsics : 'asm Sopn.asmOp -> unit -> unit 2 | -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | sphinx-rtd-theme 2 | myst-parser 3 | sphinx-copybutton 4 | -------------------------------------------------------------------------------- /docs/source/compiler/passes/loop_unrolling.md: -------------------------------------------------------------------------------- 1 | # Loop unrolling 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/source/compiler/passes/lower_spill.md: -------------------------------------------------------------------------------- 1 | # Lowering of spills 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/source/compiler/passes/reg_alloc.md: -------------------------------------------------------------------------------- 1 | # Register allocation 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/source/compiler/passes/stack_alloc.md: -------------------------------------------------------------------------------- 1 | # Stack allocation 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/source/compiler/passes/stack_zero.md: -------------------------------------------------------------------------------- 1 | # Stack zeroization 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /compiler/tests/fail/common/typealias_duplicate.jazz: -------------------------------------------------------------------------------- 1 | 2 | type x = u64; 3 | type x = u64; -------------------------------------------------------------------------------- /compiler/tests/fail/param_expansion/x86-64/array_size_mismatch.jazz: -------------------------------------------------------------------------------- 1 | u64[4] g = {1}; 2 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | ## How to build 2 | 3 | Run `nix-shell --pure --run 'make html'`. 4 | -------------------------------------------------------------------------------- /docs/source/compiler/passes/function_inlining.md: -------------------------------------------------------------------------------- 1 | # Function Inlining 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/source/compiler/passes/inst_select.md: -------------------------------------------------------------------------------- 1 | # Instruction selection 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/source/compiler/passes/make_ref_arguments.md: -------------------------------------------------------------------------------- 1 | # Make ref arguments 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/source/compiler/passes/propagate_inline.md: -------------------------------------------------------------------------------- 1 | # Propagate Inline 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /compiler/safetylib/domains/safetySymEq.mli: -------------------------------------------------------------------------------- 1 | module SymExprImpl : SafetyInterfaces.SymExpr 2 | -------------------------------------------------------------------------------- /compiler/src/latex_printer.mli: -------------------------------------------------------------------------------- 1 | val pp_prog : Format.formatter -> Syntax.pprogram -> unit 2 | -------------------------------------------------------------------------------- /docs/source/compiler/passes/constant_propagation.md: -------------------------------------------------------------------------------- 1 | # Constant Propagation 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/source/compiler/passes/deadcode_elimination.md: -------------------------------------------------------------------------------- 1 | # Dead-code Elimination 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/source/compiler/passes/liverange_splitting.md: -------------------------------------------------------------------------------- 1 | # Liverange splitting 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/source/compiler/passes/lower_slh.md: -------------------------------------------------------------------------------- 1 | # Lowering of SLH instructions 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /compiler/safetylib/domains/safetyCongr.mli: -------------------------------------------------------------------------------- 1 | module AbsNumCongr : SafetyInterfaces.AbsNumType 2 | -------------------------------------------------------------------------------- /compiler/safetylib/domains/safetyPointsTo.mli: -------------------------------------------------------------------------------- 1 | module PointsToImpl : SafetyInterfaces.PointsTo 2 | -------------------------------------------------------------------------------- /compiler/tests/fail/common/typealias_notfound.jazz: -------------------------------------------------------------------------------- 1 | export fn test() { 2 | reg regtype x; 3 | } -------------------------------------------------------------------------------- /compiler/tests/fail/common/var_initialize_if.jazz: -------------------------------------------------------------------------------- 1 | fn test () { 2 | reg u32 x = 0 if true; 3 | } 4 | -------------------------------------------------------------------------------- /compiler/tests/fail/typing/x86-64/global_in_global_def.jazz: -------------------------------------------------------------------------------- 1 | u8 one = 1; 2 | u16 two = one + one; 3 | -------------------------------------------------------------------------------- /docs/source/compiler/passes/expansion_reg_arrays.md: -------------------------------------------------------------------------------- 1 | # Expansion of register arrays 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/source/compiler/passes/load_constants.md: -------------------------------------------------------------------------------- 1 | # Load constants in conditions (RISC-V) 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/source/compiler/passes/removal_unused_functions.md: -------------------------------------------------------------------------------- 1 | # Removal of unused functions 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/source/compiler/passes/rm_unused_ret_value.md: -------------------------------------------------------------------------------- 1 | # Remove unused returned values 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /compiler/examples/extraction-unit-tests/.gitignore: -------------------------------------------------------------------------------- 1 | add_in_mem.ec 2 | gcd.ec 3 | loops.ec 4 | sdiv.ec 5 | -------------------------------------------------------------------------------- /compiler/examples/gimli/x86-64/gimliv.jazz: -------------------------------------------------------------------------------- 1 | param bool use_shufb = true; 2 | 3 | require "gimliv.jinc" 4 | -------------------------------------------------------------------------------- /compiler/examples/gimli/x86-64/gimliv1.jazz: -------------------------------------------------------------------------------- 1 | param bool use_shufb = false; 2 | 3 | require "gimliv.jinc" 4 | -------------------------------------------------------------------------------- /compiler/src/pp_riscv.mli: -------------------------------------------------------------------------------- 1 | 2 | val print_prog : Format.formatter -> Riscv_instr_decl.riscv_prog -> unit 3 | -------------------------------------------------------------------------------- /compiler/tests/fail/param_expansion/x86-64/operator_global.jazz: -------------------------------------------------------------------------------- 1 | param int N = 2; 2 | u64[N&N] a={1,2}; 3 | -------------------------------------------------------------------------------- /compiler/tests/fail/register_allocation/arm-m4/bug_201.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main (reg u64 state) { 3 | } 4 | -------------------------------------------------------------------------------- /compiler/tests/fail/register_allocation/x86-64/unknown_type_register.jazz: -------------------------------------------------------------------------------- 1 | export fn f (reg bool a) { } 2 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/common/bug_385.jazz: -------------------------------------------------------------------------------- 1 | export fn main(reg u32 n) { 2 | n += 1 >> 3; 3 | } 4 | -------------------------------------------------------------------------------- /compiler/tests/success/common/dead_spill.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 x) { 3 | #spill(x); 4 | } 5 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/clflush.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn flush(reg u64 p) { 3 | #CLFLUSH(p); 4 | } 5 | -------------------------------------------------------------------------------- /docs/source/compiler/passes/lower_addr.md: -------------------------------------------------------------------------------- 1 | # Lowering of complex addressing modes (RISC-V) 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/source/compiler/passes/wint_word.md: -------------------------------------------------------------------------------- 1 | # Replace word-sized integers with machine words 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /compiler/src/config.mli: -------------------------------------------------------------------------------- 1 | val target_system : string 2 | (** Build-time configuration of the target system. *) 3 | -------------------------------------------------------------------------------- /compiler/src/pp_arm_m4.mli: -------------------------------------------------------------------------------- 1 | 2 | val print_prog : 3 | Format.formatter -> Arm_instr_decl.arm_prog -> unit 4 | -------------------------------------------------------------------------------- /compiler/src/slicing.mli: -------------------------------------------------------------------------------- 1 | open Prog 2 | val slice : string list -> ('info, 'asm) prog -> ('info, 'asm) prog 3 | -------------------------------------------------------------------------------- /compiler/tests/exec/return-undef.jazz: -------------------------------------------------------------------------------- 1 | inline 2 | fn f() -> reg u64 { 3 | reg u64 x; 4 | return x; 5 | } 6 | -------------------------------------------------------------------------------- /compiler/tests/fail/namespaces/common/duplicate.jazz: -------------------------------------------------------------------------------- 1 | namespace A { fn f() {} } 2 | namespace A { fn f() {} } 3 | -------------------------------------------------------------------------------- /compiler/tests/fail/param_expansion/x86-64/array_size_mismatch2.jazz: -------------------------------------------------------------------------------- 1 | param int N = 4; 2 | u64[N] g = {1}; 3 | -------------------------------------------------------------------------------- /compiler/tests/fail/param_expansion/x86-64/array_too_large_global.jazz: -------------------------------------------------------------------------------- 1 | u64[0x10000000000000000] a = { 1 }; 2 | -------------------------------------------------------------------------------- /compiler/tests/fail/slh/x86-64/msf_lval.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u64 p) { 3 | [p] = #init_msf(); 4 | } 5 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/x86-64/not.jazz: -------------------------------------------------------------------------------- 1 | export fn main(reg u64 b) 2 | { 3 | b = #NOT_64(b); 4 | } 5 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/bug_730.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u64 p) { 3 | [p] = (2u32)[1, 0]; 4 | } 5 | -------------------------------------------------------------------------------- /compiler/examples/x86-64/retz.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn zero() -> reg u64 { 3 | reg u64 z; 4 | z = 0; 5 | return z; 6 | } 7 | -------------------------------------------------------------------------------- /compiler/syscall/Makefile: -------------------------------------------------------------------------------- 1 | all: jasmin_syscall.o 2 | 3 | jasmin_syscall.o: jasmin_syscall.c jasmin_syscall.h 4 | -------------------------------------------------------------------------------- /compiler/tests/fail/param_expansion/x86-64/expression_global2.jazz: -------------------------------------------------------------------------------- 1 | param int N = 2; 2 | u64[(uint)(64u)N] g = {1}; 3 | -------------------------------------------------------------------------------- /compiler/tests/fail/typing/x86-64/only_param.jazz: -------------------------------------------------------------------------------- 1 | export fn main () { 2 | reg u64 x; 3 | reg u64[x] a; 4 | } 5 | -------------------------------------------------------------------------------- /compiler/tests/success/arm-m4/large_stack/reg_ptr.jazz: -------------------------------------------------------------------------------- 1 | param int N = 1025; 2 | require "reg_ptr_template.jinc" 3 | -------------------------------------------------------------------------------- /compiler/tests/success/risc-v/large_stack/reg_ptr.jazz: -------------------------------------------------------------------------------- 1 | param int N = 1025; 2 | require "reg_ptr_template.jinc" 3 | -------------------------------------------------------------------------------- /compiler/CCT/fail/doc_leak_store.jazz: -------------------------------------------------------------------------------- 1 | #[ct = "secret -> secret"] 2 | fn leak_store(reg u64 p) { 3 | [p] = 0; 4 | } 5 | -------------------------------------------------------------------------------- /compiler/examples/extraction-unit-tests/ec.config: -------------------------------------------------------------------------------- 1 | [default] 2 | bin = easycrypt 3 | 4 | [test-all] 5 | okdirs = . 6 | 7 | -------------------------------------------------------------------------------- /compiler/tests/fail/param_expansion/x86-64/expression_global.jazz: -------------------------------------------------------------------------------- 1 | param int N = (uint)(64u) 3; 2 | u64[N] a = {1,2}; 3 | -------------------------------------------------------------------------------- /compiler/tests/fail/param_expansion/x86-64/operator_arg.jazz: -------------------------------------------------------------------------------- 1 | param int N = 2; 2 | 3 | inline fn f (reg u64[N&N] a) { } 4 | -------------------------------------------------------------------------------- /compiler/tests/fail/register_allocation/arm-m4/too_many_args.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn too_many_args(reg u32 a b c d e) {} 3 | -------------------------------------------------------------------------------- /compiler/tests/fail/register_allocation/x86-64/too_many_args.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn too_many_args(reg u64 a b c d e f g) {} 3 | -------------------------------------------------------------------------------- /compiler/tests/safety/fail/x86-64/shld.jazz: -------------------------------------------------------------------------------- 1 | export fn undefined(reg u16 x y) { 2 | ?{}, _ = #SHLD_16(x, y, 17); 3 | } 4 | -------------------------------------------------------------------------------- /compiler/tests/sct-checker/success/bug_1189.jazz: -------------------------------------------------------------------------------- 1 | export fn foo() { 2 | inline int j; 3 | for j = 1 to 2 {} 4 | } 5 | -------------------------------------------------------------------------------- /compiler/tests/success/arm-m4/large_stack/reg_ptr_large.jazz: -------------------------------------------------------------------------------- 1 | param int N = 16385; 2 | require "reg_ptr_template.jinc" 3 | -------------------------------------------------------------------------------- /compiler/tests/success/risc-v/large_stack/reg_ptr_large.jazz: -------------------------------------------------------------------------------- 1 | param int N = 16385; 2 | require "reg_ptr_template.jinc" 3 | -------------------------------------------------------------------------------- /compiler/src/array_expand.mli: -------------------------------------------------------------------------------- 1 | open Prog 2 | 3 | val init_tbl : ('info, 'asm) func -> Sv.t * (Wsize.wsize * var array) Hv.t 4 | -------------------------------------------------------------------------------- /compiler/tests/fail/typing/x86-64/init_global.jazz: -------------------------------------------------------------------------------- 1 | u64[1] g = {1}; 2 | 3 | export fn main () { 4 | ArrayInit(g); 5 | } 6 | -------------------------------------------------------------------------------- /compiler/tests/success/common/immediate.jazz: -------------------------------------------------------------------------------- 1 | u8 a = 123; 2 | u8 b = -17; 3 | u8 c = 0xab; 4 | u8 d = 0Xcd; 5 | u8 e = -0XAA; 6 | -------------------------------------------------------------------------------- /compiler/tests/warning/x86-64/reg_const_ptr.jazz: -------------------------------------------------------------------------------- 1 | fn f (reg const ptr u64[3] r) -> reg ptr u64[3] { 2 | return r; 3 | } 4 | -------------------------------------------------------------------------------- /compiler/CCT/success/doc_store.jazz: -------------------------------------------------------------------------------- 1 | #[ct = "public × secret -> ()"] 2 | fn store(reg u64 p, reg u64 x) { 3 | [p] = x; 4 | } 5 | -------------------------------------------------------------------------------- /compiler/src/syscall_ocaml.mli: -------------------------------------------------------------------------------- 1 | type state 2 | 3 | val initial_state : unit -> state 4 | val sc_sem : state Syscall.syscall_sem 5 | -------------------------------------------------------------------------------- /compiler/tests/fail/common/typealias_arrayelement.jazz: -------------------------------------------------------------------------------- 1 | 2 | 3 | type x = u64[3]; 4 | 5 | 6 | fn test() { 7 | reg x[3] y; 8 | } -------------------------------------------------------------------------------- /compiler/tests/fail/common/typealias_arrayelement_integer.jazz: -------------------------------------------------------------------------------- 1 | 2 | type x = int; 3 | 4 | 5 | fn test() { 6 | reg x[t] y; 7 | } -------------------------------------------------------------------------------- /compiler/tests/fail/common/var_initialize_undecl.jazz: -------------------------------------------------------------------------------- 1 | export fn main() -> reg u32 { 2 | reg u32 x = x; 3 | return x; 4 | } 5 | -------------------------------------------------------------------------------- /compiler/tests/fail/x86-64/swap_type_mismatch.jazz: -------------------------------------------------------------------------------- 1 | export fn main(reg u64 x, reg ptr u8[8] y) { 2 | x, y = #swap(y, x); 3 | } 4 | -------------------------------------------------------------------------------- /compiler/tests/success/arm-m4/large_stack/sub_reg_ptr_large.jazz: -------------------------------------------------------------------------------- 1 | param int N = 65536; 2 | require "sub_reg_ptr_template.jinc" 3 | -------------------------------------------------------------------------------- /compiler/tests/success/arm-m4/neg.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn neg(reg u32 x) -> reg u32 { 3 | x = x; 4 | x = -x; 5 | return x; 6 | } 7 | -------------------------------------------------------------------------------- /compiler/tests/success/noextract/x86-64/empty.jazz: -------------------------------------------------------------------------------- 1 | fn return_uninit() -> reg u64 { 2 | reg u64 res; 3 | return res; 4 | } 5 | -------------------------------------------------------------------------------- /compiler/tests/success/risc-v/neg.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn neg(reg u32 x) -> reg u32 { 3 | x = x; 4 | x = -x; 5 | return x; 6 | } 7 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/bug_224.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u64 x) { 3 | while { 4 | x -= 1; 5 | } (x > 0) 6 | } 7 | -------------------------------------------------------------------------------- /compiler/CCT/success/doc_zero.jazz: -------------------------------------------------------------------------------- 1 | #[ct = "() -> public"] 2 | fn zero() -> reg u64 { 3 | reg u64 z; 4 | z = 0; 5 | return z; 6 | } -------------------------------------------------------------------------------- /compiler/CCT/success/unused_poly.jazz: -------------------------------------------------------------------------------- 1 | #[ct="l1 × l2 -> l1"] 2 | fn drop2 (reg u64 x, reg u64 y) -> reg u64 { 3 | return x; 4 | } 5 | -------------------------------------------------------------------------------- /compiler/examples/x86-64/identity.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn identity(reg u64 x) -> reg u64 { 3 | reg u64 r; 4 | r = x; 5 | return r; 6 | } 7 | -------------------------------------------------------------------------------- /compiler/tests/fail/arm-m4/mov_imm_shifted.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 x) { 3 | x = #MOV(0x000cb000); 4 | [x] = x; 5 | } 6 | -------------------------------------------------------------------------------- /compiler/tests/fail/arm-m4/mov_imm_too_large.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 x) { 3 | x = #MOV(0x000acaca); 4 | [x] = x; 5 | } 6 | -------------------------------------------------------------------------------- /compiler/tests/fail/arm-m4/mvn_imm_shifted.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 x) { 3 | x = #MVN(0x000cb000); 4 | [x] = x; 5 | } 6 | -------------------------------------------------------------------------------- /compiler/tests/fail/arm-m4/mvn_imm_too_large.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 x) { 3 | x = #MVN(0x0000caca); 4 | [x] = x; 5 | } 6 | -------------------------------------------------------------------------------- /compiler/tests/fail/common/storage_signature_mismatch.jazz: -------------------------------------------------------------------------------- 1 | export fn sum() -> stack u32 { 2 | reg u32 r = 0; 3 | return r; 4 | } 5 | -------------------------------------------------------------------------------- /compiler/tests/fail/lower_spill/needs_to_be_spilled_not_spilled.jazz: -------------------------------------------------------------------------------- 1 | export fn main () { 2 | reg u32 x; 3 | #unspill(x); 4 | } 5 | -------------------------------------------------------------------------------- /compiler/tests/fail/param_expansion/x86-64/expression_arg.jazz: -------------------------------------------------------------------------------- 1 | param int N = (uint)(64u) 3; 2 | 3 | inline fn f (reg u64[N] a) { } 4 | -------------------------------------------------------------------------------- /compiler/tests/fail/register_allocation/x86-64/too_many_large_args.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn too_many_args(reg u256 a b c d e f g h i) {} 3 | -------------------------------------------------------------------------------- /compiler/tests/safety/fail/common/wint_overflow.jazz: -------------------------------------------------------------------------------- 1 | param int big = 137; 2 | 3 | export fn wint_overflow() { reg si8 small = big; } 4 | -------------------------------------------------------------------------------- /docs/source/compiler/advanced/index.md: -------------------------------------------------------------------------------- 1 | # Advanced details 2 | 3 | :::{toctree} 4 | 5 | add_instructions 6 | memory_layout 7 | ::: 8 | -------------------------------------------------------------------------------- /compiler/tests/fail/arm-m4/add_imm_too_large.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 x) { 3 | x = #ADD(x, 0x0000caca); 4 | [x] = x; 5 | } 6 | -------------------------------------------------------------------------------- /compiler/tests/fail/arm-m4/and_imm_too_large.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 x) { 3 | x = #AND(x, 0x0000caca); 4 | [x] = x; 5 | } 6 | -------------------------------------------------------------------------------- /compiler/tests/fail/arm-m4/bic_imm_shifted.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 x) { 3 | x = #BIC(x, 0x000cb000); 4 | [x] = x; 5 | } 6 | -------------------------------------------------------------------------------- /compiler/tests/fail/arm-m4/bic_imm_too_large.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 x) { 3 | x = #BIC(x, 0x0000caca); 4 | [x] = x; 5 | } 6 | -------------------------------------------------------------------------------- /compiler/tests/fail/arm-m4/eor_imm_shifted.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 x) { 3 | x = #EOR(x, 0x000cb000); 4 | [x] = x; 5 | } 6 | -------------------------------------------------------------------------------- /compiler/tests/fail/arm-m4/eor_imm_too_large.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 x) { 3 | x = #EOR(x, 0x0000caca); 4 | [x] = x; 5 | } 6 | -------------------------------------------------------------------------------- /compiler/tests/fail/arm-m4/movw_set_flags.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 x) { 3 | ?{}, x = #MOVS(0x0000caca); 4 | [x] = x; 5 | } 6 | -------------------------------------------------------------------------------- /compiler/tests/fail/arm-m4/orr_imm_shifted.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 x) { 3 | x = #ORR(x, 0x000cb000); 4 | [x] = x; 5 | } 6 | -------------------------------------------------------------------------------- /compiler/tests/fail/arm-m4/orr_imm_too_large.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 x) { 3 | x = #ORR(x, 0x0000caca); 4 | [x] = x; 5 | } 6 | -------------------------------------------------------------------------------- /compiler/tests/fail/arm-m4/rsb_imm_too_large.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 x) { 3 | x = #RSB(x, 0x0000caca); 4 | [x] = x; 5 | } 6 | -------------------------------------------------------------------------------- /compiler/tests/fail/arm-m4/sub_imm_too_large.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 x) { 3 | x = #SUB(x, 0x0000caca); 4 | [x] = x; 5 | } 6 | -------------------------------------------------------------------------------- /compiler/tests/fail/typing/x86-64/bug_488.jazz: -------------------------------------------------------------------------------- 1 | export fn test(reg u256 x) -> reg u256 { 2 | x = #VPMULH_4u64(x, x); 3 | return x; 4 | } 5 | -------------------------------------------------------------------------------- /compiler/tests/success/arm-m4/bug_375.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main() -> reg u32 { 3 | reg u32 x; 4 | x = !1; 5 | return x; 6 | } 7 | -------------------------------------------------------------------------------- /compiler/tests/success/arm-m4/large_stack/large_internal_stack.jazz: -------------------------------------------------------------------------------- 1 | param int N = 1025; 2 | require "large_internal_stack_template.jinc" 3 | -------------------------------------------------------------------------------- /compiler/tests/success/risc-v/large_stack/large_internal_stack.jazz: -------------------------------------------------------------------------------- 1 | param int N = 1025; 2 | require "large_internal_stack_template.jinc" 3 | -------------------------------------------------------------------------------- /compiler/examples/gimli/proofs/ec.config: -------------------------------------------------------------------------------- 1 | [default] 2 | bin = easycrypt 3 | args = -I Jasmin:../../../../eclib 4 | 5 | [test-all] 6 | okdirs = . 7 | -------------------------------------------------------------------------------- /compiler/examples/x86-64/add1.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn add1(reg u64 arg) -> reg u64 { 3 | reg u64 z; 4 | z = arg; 5 | z += 1; 6 | return z; 7 | } 8 | -------------------------------------------------------------------------------- /compiler/tests/fail/arm-m4/addw_set_flags.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 x) { 3 | ?{}, x = #ADDS(x, 0x00000aca); 4 | [x] = x; 5 | } 6 | -------------------------------------------------------------------------------- /compiler/tests/fail/arm-m4/subw_set_flags.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 x) { 3 | ?{}, x = #SUBS(x, 0x00000aca); 4 | [x] = x; 5 | } 6 | -------------------------------------------------------------------------------- /compiler/tests/fail/slh/x86-64/invalid_type.jazz: -------------------------------------------------------------------------------- 1 | fn main(reg u32 x, #[msf] reg u32 msf) { 2 | x = #protect(x, msf); 3 | [x] = 0; 4 | } 5 | -------------------------------------------------------------------------------- /compiler/tests/fail/typing/x86-64/export_stack_res.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn bad() -> stack u64 { 3 | stack u64 x; 4 | x = 0; 5 | return x; 6 | } 7 | -------------------------------------------------------------------------------- /compiler/tests/success/arm-m4/large_stack/very_large_internal_stack.jazz: -------------------------------------------------------------------------------- 1 | param int N = 65536; 2 | require "large_internal_stack_template.jinc" 3 | -------------------------------------------------------------------------------- /compiler/tests/success/common/swap_word.jazz: -------------------------------------------------------------------------------- 1 | export fn main (reg u32 x y) -> reg u32 { 2 | x, y = #swap(x, y); 3 | x = x; 4 | return x; 5 | } -------------------------------------------------------------------------------- /compiler/tests/success/require/common/file1.jazz: -------------------------------------------------------------------------------- 1 | fn add(reg u32 x y) -> reg u32 { 2 | reg u32 r; 3 | r = x + y; 4 | return r; 5 | } 6 | -------------------------------------------------------------------------------- /compiler/tests/success/risc-v/large_stack/very_large_internal_stack.jazz: -------------------------------------------------------------------------------- 1 | param int N = 65536; 2 | require "large_internal_stack_template.jinc" 3 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/test_bool.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn f(reg u64 x) -> reg u64 { 3 | reg u64 r; 4 | r = x; 5 | r &= 42; 6 | return r; 7 | } 8 | -------------------------------------------------------------------------------- /compiler/CCT/fail/load_on_secret.jazz: -------------------------------------------------------------------------------- 1 | #[ct = "secret * _ -> ()"] 2 | fn mem3(reg u64 p, reg u64 x) { 3 | reg u64 r; 4 | 5 | [p] = x; 6 | 7 | } -------------------------------------------------------------------------------- /compiler/tests/fail/arm-m4/and_imm_shifted.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 x) -> reg u32 { 3 | x = #AND(x, 0x000cb000); 4 | return x; 5 | } 6 | -------------------------------------------------------------------------------- /compiler/tests/fail/arm-m4/mov_shiftedw_set_flags.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 x) { 3 | ?{}, x = #MOVS(0x0000cb00); 4 | [x] = x; 5 | } 6 | -------------------------------------------------------------------------------- /compiler/tests/fail/x86-64/shift.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main() -> reg u64 { 3 | reg u64 x; 4 | x = 1; 5 | x <<= x; 6 | return x; 7 | } 8 | -------------------------------------------------------------------------------- /compiler/tests/fail/x86-64/swap128.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u128 x y) -> reg u128, reg u128 { 3 | y, x = #swap(x, y); 4 | return y, x; 5 | } 6 | -------------------------------------------------------------------------------- /compiler/CCT/success/doc_load_mem.jazz: -------------------------------------------------------------------------------- 1 | #[ct = "public -> secret"] 2 | fn load_mem(reg u64 p) -> reg u64 { 3 | reg u64 r; 4 | r = [p]; 5 | return r; 6 | } -------------------------------------------------------------------------------- /compiler/scripts/update-cast-int: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | for f in $(find . -name "*.jazz" -o -name "*.jinc") 3 | do 4 | sed -i 's/(int)/(uint)/g' "$f" 5 | done 6 | -------------------------------------------------------------------------------- /compiler/src/debugInfo.mli: -------------------------------------------------------------------------------- 1 | val source_positions : Location.t -> string list 2 | (** List of .file and .loc directives to decorate assembly listings. *) 3 | -------------------------------------------------------------------------------- /compiler/tests/fail/register_allocation/x86-64/bug_421.jazz: -------------------------------------------------------------------------------- 1 | export fn cqo128() { 2 | reg u128 x; 3 | x = #set0_128(); 4 | x = #CQO_128(x); 5 | } 6 | -------------------------------------------------------------------------------- /compiler/tests/success/common/bug_870.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn rand(reg ptr u8[32] io) -> reg ptr u8[32] { 3 | io = #randombytes(io); 4 | return io; 5 | } 6 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/test_minus_one.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn test(reg u64 x) -> reg u64 { 3 | reg u64 r; 4 | r = x; 5 | r *= -1; 6 | return r; 7 | } 8 | -------------------------------------------------------------------------------- /compiler/CCT/success/doc_add_restr.jazz: -------------------------------------------------------------------------------- 1 | #[ct = "_ × public -> secret"] 2 | fn add_restr(reg u64 x, reg u64 y) -> reg u64 { 3 | x = x + y; 4 | return x; 5 | } -------------------------------------------------------------------------------- /compiler/src/tt_arm_m4.mli: -------------------------------------------------------------------------------- 1 | val tt_prim : 2 | (string -> exn) 3 | -> (string * 'a Sopn.prim_constructor) list 4 | -> string 5 | -> _ option 6 | -> 'a 7 | -------------------------------------------------------------------------------- /compiler/tests/fail/arm-m4/add_shift.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 x, reg u32 y) -> reg u32 { 3 | reg u32 z; 4 | z = x + (y << 50); 5 | return z; 6 | } 7 | -------------------------------------------------------------------------------- /compiler/tests/fail/typing/x86-64/lval_param.jazz: -------------------------------------------------------------------------------- 1 | param int x = 3; 2 | 3 | fn test(reg u64 y) -> reg u64 { 4 | x = 4; 5 | y += x; 6 | return y; 7 | } 8 | -------------------------------------------------------------------------------- /compiler/tests/safety/fail/common/not_in_bounds.jazz: -------------------------------------------------------------------------------- 1 | export fn f (reg ptr u32[2] t) -> reg ptr u32[2] { 2 | t[-1] = 2; 3 | t[2] = 2; 4 | return t; 5 | } 6 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/vector_arguments.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn xor256(reg u256 a b) -> reg u256 { 3 | reg u256 r; 4 | 5 | r = a ^ b; 6 | 7 | return r; 8 | } -------------------------------------------------------------------------------- /compiler/examples/x86-64/noset0.jazz: -------------------------------------------------------------------------------- 1 | export fn f() -> reg u64, reg u64 { 2 | reg u64 r1, r2; 3 | r1 = 0; 4 | _,_,_,_,_, r2 = #set0 (); 5 | return r1, r2; 6 | } 7 | -------------------------------------------------------------------------------- /compiler/linter/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name linter) 3 | (public_name jasmin.linter) 4 | (libraries jasmin cmdliner) 5 | ) 6 | 7 | (include_subdirs unqualified) 8 | 9 | -------------------------------------------------------------------------------- /compiler/tests/fail/array_expansion/x86-64/export_param.jazz: -------------------------------------------------------------------------------- 1 | export fn main (reg u64[3] x) -> reg u64 { 2 | reg u64 res; 3 | res = x[0]; 4 | return res; 5 | } 6 | -------------------------------------------------------------------------------- /compiler/tests/fail/asmgen/x86-64/invalid_scale.jazz: -------------------------------------------------------------------------------- 1 | export fn f (reg ptr u64[2] r, reg u64 i) -> reg u64 { 2 | reg u64 res = r[3*i+2]; 3 | return res; 4 | } 5 | -------------------------------------------------------------------------------- /compiler/tests/fail/param_expansion/x86-64/operator_res.jazz: -------------------------------------------------------------------------------- 1 | param int N = 2; 2 | 3 | inline fn f () -> reg u64[N&N] { 4 | reg u64[N&N] a; 5 | return a; 6 | } 7 | -------------------------------------------------------------------------------- /compiler/tests/fail/slh/x86-64/export_takes_msf.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u64 y) -> reg u64 { 3 | reg u64 x; 4 | x = #mov_msf(y); 5 | return x; 6 | } 7 | -------------------------------------------------------------------------------- /compiler/tests/fail/slh/x86-64/mov_msf.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main() -> reg u64 { 3 | reg u64 x; 4 | x = 0; 5 | x = #mov_msf(x); 6 | return x; 7 | } 8 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/out_of_bounds_read.jazz: -------------------------------------------------------------------------------- 1 | export fn main (reg ptr u64[1] r) -> reg u64 { 2 | reg u64 res = r[2]; 3 | return res; 4 | } 5 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/out_of_bounds_write.jazz: -------------------------------------------------------------------------------- 1 | export fn main (reg ptr u64[1] r) -> reg ptr u64[1] { 2 | r[2] = 1; 3 | return r; 4 | } 5 | -------------------------------------------------------------------------------- /compiler/tests/safety/fail/x86-64/array-export.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg ptr u8[4] a, reg u64 i) -> reg u8 { 3 | reg u8 x; 4 | x = a[i]; 5 | return x; 6 | } 7 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/addr_0.jazz: -------------------------------------------------------------------------------- 1 | export fn main(reg u64 p) -> reg u64 { 2 | reg u64 r; 3 | r = [:u64 p]; 4 | r += [:u64 p - 8]; 5 | return r; 6 | } -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/inline_call_to_export.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn sum(reg u64 x y) -> reg u64 { 3 | reg u64 z; 4 | z = #LEA(x + y); 5 | return z; 6 | } 7 | -------------------------------------------------------------------------------- /docs/source/language/semantics/index.md: -------------------------------------------------------------------------------- 1 | # Semantics reference 2 | 3 | :::{toctree} 4 | 5 | scalar_types 6 | arrays 7 | system_calls 8 | spilling 9 | ::: 10 | -------------------------------------------------------------------------------- /compiler/CCT/fail/load_on_poly.jazz: -------------------------------------------------------------------------------- 1 | #[ct = "l1 -> _"] 2 | fn load(reg u64 x) -> reg u64 { 3 | 4 | reg u64 t; 5 | 6 | t = [x]; 7 | 8 | return t; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/dune-project: -------------------------------------------------------------------------------- 1 | (lang dune 3.7) 2 | (name jasmin) 3 | (package (name jasmin)) 4 | (license MIT) 5 | (authors "The Jasmin development team") 6 | (using menhir 2.1) 7 | -------------------------------------------------------------------------------- /compiler/entry/jasminc.ml: -------------------------------------------------------------------------------- 1 | (* -------------------------------------------------------------------- *) 2 | module J = Jasminc 3 | 4 | let () = J.Main_compiler.main () 5 | -------------------------------------------------------------------------------- /compiler/tests/fail/asmgen/arm-m4/address_too_complex.jazz: -------------------------------------------------------------------------------- 1 | export fn f (reg ptr u32[2] r, reg u32 i) -> reg u32 { 2 | reg u32 res = r[i+2]; 3 | return res; 4 | } 5 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/out_of_bounds_read_neg.jazz: -------------------------------------------------------------------------------- 1 | export fn main (reg ptr u64[1] r) -> reg u64 { 2 | reg u64 res = r[-1]; 3 | return res; 4 | } 5 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/out_of_bounds_write_neg.jazz: -------------------------------------------------------------------------------- 1 | export fn main (reg ptr u64[1] r) -> reg ptr u64[1] { 2 | r[-2] = 1; 3 | return r; 4 | } 5 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/return_subslice.jazz: -------------------------------------------------------------------------------- 1 | export fn sub(reg ptr u8[4] p) -> reg ptr u8[1] { 2 | reg ptr u8[1] r = p[0:1]; 3 | return r; 4 | } 5 | -------------------------------------------------------------------------------- /compiler/tests/safety/fail/arm-m4/array-export.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg ptr u32[4] a, reg u32 i) -> reg u32 { 3 | reg u32 x; 4 | x = a[i]; 5 | return x; 6 | } 7 | -------------------------------------------------------------------------------- /compiler/tests/safety/fail/risc-v/array-export.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg ptr u32[4] a, reg u32 i) -> reg u32 { 3 | reg u32 x; 4 | x = a[i]; 5 | return x; 6 | } 7 | -------------------------------------------------------------------------------- /compiler/tests/success/arm-m4/mulu.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn test(reg u32 x y) -> reg u32 { 3 | reg u32 lo hi; 4 | hi, lo = x * y; 5 | lo ^= hi; 6 | return lo; 7 | } 8 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/fences.jazz: -------------------------------------------------------------------------------- 1 | export fn test_lfence() { #LFENCE(); } 2 | export fn test_mfence() { #MFENCE(); } 3 | export fn test_sfence() { #SFENCE(); } 4 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/pack.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn pack() -> reg u64 { 3 | reg u64 r; 4 | 5 | r = (64u) (8u1)[0, 0, 0, 0, 0, 1, 1, 1]; // 7 6 | 7 | return r; 8 | } 9 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/test_cast_sopn.jazz: -------------------------------------------------------------------------------- 1 | export fn foo (reg u128 x y) -> reg u256 { 2 | reg u256 z; 3 | z = (256u)#VPAND(x, y); 4 | return z; 5 | } 6 | -------------------------------------------------------------------------------- /compiler/CCT/fail/doc_leak_cond.jazz: -------------------------------------------------------------------------------- 1 | #[ct = "secret -> secret"] 2 | fn leak_cond(reg u64 x) -> reg u64 { 3 | reg u64 y = 0; 4 | if (x == 0) { y = 1; } 5 | return y; 6 | } -------------------------------------------------------------------------------- /compiler/CCT/success/doc_add_SP.jazz: -------------------------------------------------------------------------------- 1 | #[ct = "secret × public -> secret"] 2 | fn add_SP(reg u64 x, reg u64 y) -> reg u64 { 3 | reg u64 t; 4 | t = x + y; 5 | return t; 6 | } -------------------------------------------------------------------------------- /compiler/CCT/success/doit/by_stack.jazz: -------------------------------------------------------------------------------- 1 | #[ct="secret -> secret"] 2 | export fn id(reg u32 x) -> reg u32 { 3 | stack u32 s; 4 | s = x; 5 | x = s; 6 | return x; 7 | } 8 | -------------------------------------------------------------------------------- /compiler/linter/Error/CompileError.ml: -------------------------------------------------------------------------------- 1 | type t = { 2 | location : Jasmin.Location.t; 3 | level : int; 4 | code : string; 5 | to_text : Format.formatter -> unit; 6 | } 7 | -------------------------------------------------------------------------------- /compiler/src/parseio.mli: -------------------------------------------------------------------------------- 1 | (* -------------------------------------------------------------------- *) 2 | val parse_program : ?name:string -> Utils.IO.input -> Syntax.pprogram 3 | -------------------------------------------------------------------------------- /compiler/tests/fail/param_expansion/x86-64/expression_res.jazz: -------------------------------------------------------------------------------- 1 | param int N = (uint)(64u) 3; 2 | 3 | inline fn f () -> reg u64[N] { 4 | reg u64[N] a; 5 | return a; 6 | } 7 | -------------------------------------------------------------------------------- /compiler/tests/fail/register_allocation/arm-m4/too_many_large_ret.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn too_many_large_ret() -> reg u64 { 3 | reg u64 x; 4 | x = 0; 5 | return x; 6 | } 7 | -------------------------------------------------------------------------------- /compiler/tests/fail/slh/x86-64/no_msf.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u64 x) { 3 | reg u64 msf; 4 | 5 | msf = 0; 6 | x = #protect(x, msf); 7 | [x] = 0; 8 | } 9 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/out_of_bounds_read_partial.jazz: -------------------------------------------------------------------------------- 1 | export fn main (reg ptr u64[1] r) -> reg u64 { 2 | reg u64 res = r.[1]; 3 | return res; 4 | } 5 | -------------------------------------------------------------------------------- /compiler/tests/fail/x86-64/zxspill.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn zxspill(reg u8 x) -> reg u64 { 3 | stack u64 s; 4 | reg u64 r; 5 | s = (64u) x; 6 | r = s; 7 | return r; 8 | } 9 | -------------------------------------------------------------------------------- /compiler/tests/success/arm-m4/stack_array.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn id_by_stack(reg u32 x) -> reg u32 { 3 | stack u32[4] s; 4 | s[1] = x; 5 | x = s[1]; 6 | return x; 7 | } 8 | -------------------------------------------------------------------------------- /compiler/tests/warning/x86-64/lea.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn f () -> reg u64 { 3 | reg u64 res res1; 4 | res = 0; 5 | res1 = 4; 6 | res += 3 + res1; 7 | return res; 8 | } 9 | -------------------------------------------------------------------------------- /compiler/CCT/fail/H_L_L.jazz: -------------------------------------------------------------------------------- 1 | #[ct="secret * public -> public"] 2 | fn add_H_L_L(reg u64 x, reg u64 ya) -> reg u64 { 3 | 4 | reg u64 t; 5 | 6 | t = x + ya; 7 | 8 | return t; 9 | } -------------------------------------------------------------------------------- /compiler/src/checkAnnot.mli: -------------------------------------------------------------------------------- 1 | val check_stack_size : (Expr.stk_fun_extra * _ Prog.func) list -> unit 2 | (** Check the stacksize, stackallocsize & stackalign annotations, if any *) 3 | -------------------------------------------------------------------------------- /compiler/tests/exec/for.jazz: -------------------------------------------------------------------------------- 1 | require "../success/x86-64/eval_for.jazz" 2 | 3 | inline 4 | fn test_param() -> inline int { 5 | inline int i; 6 | i = n; 7 | return i; 8 | } 9 | -------------------------------------------------------------------------------- /compiler/tests/fail/arm-m4/adc_imm_too_large.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 x) { 3 | reg bool c; 4 | c, x += x; 5 | x = #ADC(x, 0x0000caca, c); 6 | [x] = x; 7 | } 8 | -------------------------------------------------------------------------------- /compiler/tests/fail/arm-m4/cmp_imm_too_large.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 x) { 3 | reg bool n z c v; 4 | n, z, c, v = #CMP(x, 0x0000caca); 5 | [x] = x if z; 6 | } 7 | -------------------------------------------------------------------------------- /compiler/tests/fail/arm-m4/tst_imm_shifted.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 x) { 3 | reg bool n, z, c, v; 4 | n, z, c, v = #TST(x, 0x000cb000); 5 | [x] = x if z; 6 | } 7 | -------------------------------------------------------------------------------- /compiler/tests/fail/param_expansion/x86-64/global_not_constant.jazz: -------------------------------------------------------------------------------- 1 | u64[1] a = { 1 }; 2 | u64 b = a[1]; 3 | // a[1] is not defined, and thus constant propagation is impossible 4 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/merge_params.jazz: -------------------------------------------------------------------------------- 1 | export fn f (reg ptr u64[1] a, reg ptr u64[1] b) -> reg ptr u64[1] { 2 | a[0:1] = b[0:1]; 3 | return a; 4 | } 5 | -------------------------------------------------------------------------------- /compiler/tests/fail/x86-64/por_reg.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn por_mmx_reg(reg u64 x y) -> reg u64 { 3 | #[mmx] reg u64 a = x; 4 | a |= y; 5 | x = a; 6 | return x; 7 | } 8 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/x86-64/msbclear.jazz: -------------------------------------------------------------------------------- 1 | export fn test(reg u32 a b) -> reg u64 { 2 | reg u64 r; 3 | a = a; 4 | ?{}, r = (64u)#ADD_32(a, b); 5 | return r; 6 | } 7 | -------------------------------------------------------------------------------- /compiler/tests/success/namespaces/common/qident.jazz: -------------------------------------------------------------------------------- 1 | namespace N { u32 g = 42; } 2 | 3 | export 4 | fn main() -> reg u32 { 5 | reg u32 r; 6 | r = N::g; 7 | return r; 8 | } 9 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/bug_681.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn load_small(reg u32 x) -> reg u16 { 3 | stack u32 s; 4 | reg u16 r; 5 | s = x; 6 | r = s; 7 | return r; 8 | } 9 | -------------------------------------------------------------------------------- /compiler/tests/fail/arm-m4/tst_imm_too_large.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 x) { 3 | reg bool n, z, c, v; 4 | n, z, c, v = #TST(x, 0x0000caca); 5 | [x] = x if z; 6 | } 7 | -------------------------------------------------------------------------------- /compiler/tests/fail/asmgen/x86-64/incompatible_args.jazz: -------------------------------------------------------------------------------- 1 | export fn main () -> reg u64 { 2 | reg u64 res; 3 | stack u128 s; 4 | s = 3000000; 5 | res = s; 6 | return res; 7 | } 8 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/x86-64/array-export.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg ptr u8[4] a, reg u64 i) -> reg u8 { 3 | reg u8 x; 4 | i &= 3; 5 | x = a[i]; 6 | return x; 7 | } 8 | -------------------------------------------------------------------------------- /compiler/tests/sct-checker/fail/bug_1179.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main() { 3 | stack u64 s; 4 | reg u64 x = 0; 5 | if false { 6 | x = s; 7 | } 8 | [ x ] = 0; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/tests/success/common/annotations.jazz: -------------------------------------------------------------------------------- 1 | #[test = "This 2 | is 3 | a 4 | multiline 5 | annotation with tabs and \" special {| |} characters 6 | "] 7 | export fn noop() {} 8 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/test_global.jazz: -------------------------------------------------------------------------------- 1 | u64 __38 = 38; 2 | 3 | export 4 | fn main(reg u64 x) -> reg u64 { 5 | reg u64 r; 6 | r = x; 7 | r *= __38; 8 | return r; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/test_movcc.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn identity(reg u64 x, reg u64 y) -> reg u64 { 3 | reg u64 r; 4 | r = x; 5 | r = x if (x == y); 6 | return r; 7 | } 8 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root=true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | charset = utf-8 7 | 8 | [*.{ml,mli}] 9 | indent_style = space 10 | indent_size = 2 11 | -------------------------------------------------------------------------------- /changes/01-feature/1342-enable-wint-swap.md: -------------------------------------------------------------------------------- 1 | - The `#swap` pseudo-operator can also be applied to word-sized integers 2 | ([PR #1342](https://github.com/jasmin-lang/jasmin/pull/1342)). 3 | -------------------------------------------------------------------------------- /compiler/CCT/fail/doc_leak_arr_load.jazz: -------------------------------------------------------------------------------- 1 | #[ct = "public × secret -> public"] 2 | fn leak_arr_load(reg ptr u64[4] t, reg u64 i) -> reg u64 { 3 | reg u64 x; 4 | x = t[i]; 5 | return x; 6 | } -------------------------------------------------------------------------------- /compiler/examples/x86-64/bt.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn f(reg u64 x) -> reg u64 { 3 | reg u64 y; 4 | reg bool cf; 5 | y = x; 6 | cf = #BT(x, 4); 7 | _, y += x + cf; 8 | return y; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/src/interval.mli: -------------------------------------------------------------------------------- 1 | type interval = { min : int; max : int } 2 | type t = interval 3 | 4 | val size : t -> int 5 | val pp_interval : ?closed:bool -> Format.formatter -> t -> unit 6 | -------------------------------------------------------------------------------- /compiler/src/intervalGraphColoring.mli: -------------------------------------------------------------------------------- 1 | open Prog 2 | 3 | type graph = (int * int) Mv.t 4 | type color = var 5 | type coloring = color Mv.t 6 | 7 | val solve : int -> graph -> coloring 8 | -------------------------------------------------------------------------------- /compiler/tests/fail/register_allocation/x86-64/merge_across_banks.jazz: -------------------------------------------------------------------------------- 1 | export fn mmadd(reg u64 x) -> reg u64 { 2 | #[mmx] reg u64 y; 3 | y = x + x; 4 | x = y; 5 | return x; 6 | } 7 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/return_ptr_global.jazz: -------------------------------------------------------------------------------- 1 | u32[1] g = { 0xabcd }; 2 | 3 | export fn main() -> reg ptr u32[1] { 4 | reg ptr u32[1] p = g; 5 | return p; 6 | } 7 | -------------------------------------------------------------------------------- /compiler/tests/fail/typing/x86-64/bug_69.jazz: -------------------------------------------------------------------------------- 1 | export fn f (reg u64 x y) -> reg u64 { 2 | reg u64 z; 3 | x = x; 4 | y = y; 5 | ?{}, z = (32u)#AND(x, y); 6 | return z; 7 | } 8 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/too_large_immediate.jazz: -------------------------------------------------------------------------------- 1 | export fn main () -> reg u64 { 2 | reg u64 res; 3 | stack u64 s; 4 | s = 10000000000; 5 | res = s; 6 | return res; 7 | } 8 | -------------------------------------------------------------------------------- /compiler/tests/warning/x86-64/ignored_zero_extension.jazz: -------------------------------------------------------------------------------- 1 | export fn main (reg u64 x) -> reg u64 { 2 | reg u64 res = x; 3 | ?{}, res = (64u)#AND_64(res, res); 4 | return res; 5 | } 6 | -------------------------------------------------------------------------------- /changes/03-other/1353-only-delimited-annotations.md: -------------------------------------------------------------------------------- 1 | - Annotations without delimiting square brackets are no longer supported 2 | ([PR #1353](https://github.com/jasmin-lang/jasmin/pull/1353)). 3 | -------------------------------------------------------------------------------- /compiler/.gitignore: -------------------------------------------------------------------------------- 1 | _build 2 | _c_build 3 | *.native 4 | *.byte 5 | *.exe 6 | lib*.a 7 | report.log 8 | /jasmin.mlpack 9 | /jasminc 10 | /jasmin2tex 11 | /jasmin-ct 12 | /jasmin2ec 13 | -------------------------------------------------------------------------------- /compiler/CCT/fail/div_secret.jazz: -------------------------------------------------------------------------------- 1 | #[ct="secret -> secret"] 2 | export fn div(reg u32 x) -> reg u32 { 3 | reg u32 d q; 4 | x = x; 5 | d = 3; 6 | q = x / d; 7 | q = q; 8 | return q; 9 | } -------------------------------------------------------------------------------- /compiler/examples/x86-64/test_amikoj.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn f(reg u64 x) -> reg u64 { 3 | reg u64 a; 4 | reg u64 b; 5 | reg u64 c; 6 | a = x; 7 | b = a; 8 | c = b + a; 9 | return c; 10 | } 11 | -------------------------------------------------------------------------------- /compiler/tests/fail/x86-64/por_reg_intrinsic.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn por_mmx_reg(reg u64 x y) -> reg u64 { 3 | #[mmx] reg u64 a = x; 4 | a = #POR(a, y); 5 | x = a; 6 | return x; 7 | } 8 | -------------------------------------------------------------------------------- /compiler/tests/success/common/bug_1296.jazz: -------------------------------------------------------------------------------- 1 | param int x = 2; 2 | param int y = 1 << x; 3 | 4 | export fn load(reg ptr u8[y] v) -> reg u32 { 5 | reg u32 r = v[:u32 0]; 6 | return r; 7 | } 8 | -------------------------------------------------------------------------------- /compiler/tests/success/common/bug_729.jazz: -------------------------------------------------------------------------------- 1 | export fn id(reg u32 x) -> reg u32 { x = x; return x; } 2 | 3 | export 4 | fn whynot(reg u32 a) -> reg u32 { 5 | a = id(a); 6 | return a; 7 | } 8 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/test_for.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn f() -> reg u64 { 3 | reg u64 r; 4 | inline int i; 5 | r = 0; 6 | for i = 3 downto 0 { 7 | r += 1; 8 | } 9 | return r; 10 | } 11 | -------------------------------------------------------------------------------- /compiler/tests/fail/array_expansion/x86-64/index_out_of_bounds_lv.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn test() -> reg u64 { 3 | reg u64 x; 4 | reg u64[1] t; 5 | t[-1] = 42; 6 | x = t[-1]; 7 | return x; 8 | } 9 | -------------------------------------------------------------------------------- /compiler/tests/fail/param_expansion/x86-64/array_too_large_arg.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u64[0x10000000000000000] a) -> reg u64 { 3 | reg u64 r; 4 | r = a[0]; 5 | 6 | return r; 7 | } 8 | -------------------------------------------------------------------------------- /compiler/tests/fail/param_expansion/x86-64/global_array_not_constant.jazz: -------------------------------------------------------------------------------- 1 | u64[1] a = { 1 }; 2 | u64[3] b = { 0, a[1], 2 }; 3 | // a[1] is not defined, and thus constant propagation is impossible 4 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/return_ptr_local.jazz: -------------------------------------------------------------------------------- 1 | export fn main () -> reg ptr u32[1] { 2 | stack u32[1] s; 3 | s[0] = 0; 4 | reg mut ptr u32[1] r = s; 5 | return r; 6 | } 7 | -------------------------------------------------------------------------------- /compiler/tests/fail/x86-64/por_mem.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn por_mem(reg u64 x y) -> reg u64 { 3 | stack u64 s = x; 4 | #[mmx] reg u64 a = y; 5 | s |= a; 6 | x = s; 7 | return x; 8 | } 9 | -------------------------------------------------------------------------------- /compiler/tests/success/common/intshift.jazz: -------------------------------------------------------------------------------- 1 | export fn test_int_shift(reg u32 x) -> reg u32 { 2 | inline int i; 3 | x = x; 4 | for i = 0 to 4 { 5 | x += 1 << i; 6 | } 7 | return x; 8 | } 9 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/dynglob.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn test_imm(reg u64 x) -> reg u64 { 3 | reg u64 y; 4 | global u64 g; 5 | g = 42; 6 | y = x; 7 | y += g; 8 | return y; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/prefetch.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn test_prefetch(reg u64 p) { 3 | #PREFETCHT0(p); 4 | #PREFETCHT1(p + 1); 5 | #PREFETCHT2(p + 2 * p + 8); 6 | #PREFETCHNTA(p); 7 | } 8 | -------------------------------------------------------------------------------- /compiler/tests/warning/risc-v/load_constant_warning.jazz: -------------------------------------------------------------------------------- 1 | export fn foo(reg u32 x) -> reg u32 { 2 | 3 | while (x < 10) { 4 | x = x + 1; 5 | } 6 | 7 | x = x; 8 | return x; 9 | 10 | } -------------------------------------------------------------------------------- /compiler/CCT/success/doc_set0_incr.jazz: -------------------------------------------------------------------------------- 1 | #[ct = "_ × public -> _ × public"] 2 | fn set0_incr (reg ptr u64[4] t, reg u64 i) -> reg ptr u64[4], reg u64 { 3 | t[i] = 0; 4 | i += 1; 5 | return t, i; 6 | } -------------------------------------------------------------------------------- /compiler/scripts/replace-new-memory-syntax.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | for f in $(find . -name "*.jazz" -o -name "*.jinc") 3 | do 4 | sed -i -f $(dirname $0)/replace-new-memory-syntax-sedscript "$f" 5 | done 6 | 7 | -------------------------------------------------------------------------------- /compiler/src/printFexpr.mli: -------------------------------------------------------------------------------- 1 | val pp_fexpr : Format.formatter -> Fexpr.fexpr -> unit 2 | val pp_rexpr : Format.formatter -> Fexpr.rexpr -> unit 3 | val pp_lexpr : Format.formatter -> Fexpr.lexpr -> unit 4 | -------------------------------------------------------------------------------- /compiler/src/scopeTree.mli: -------------------------------------------------------------------------------- 1 | open Prog 2 | 3 | val get_declaration_sites : ('info, 'asm) pfunc -> Spv.t Utils.Miloc.t 4 | (** Computes for each instruction the set of variables to declare before it. *) 5 | -------------------------------------------------------------------------------- /compiler/tests/fail/annotation/x86-64/calldepth.jazz: -------------------------------------------------------------------------------- 1 | /* no call: max call depth is 1 */ 2 | 3 | #[calldepth=2] 4 | export fn f () -> reg u64 { 5 | reg u64 res; 6 | res = 0; 7 | return res; 8 | } 9 | -------------------------------------------------------------------------------- /compiler/tests/fail/register_allocation/x86-64/no_register_bank.jazz: -------------------------------------------------------------------------------- 1 | export fn main () -> reg u64 { 2 | reg u64 res; 3 | reg int toto; 4 | toto = 0; 5 | res = (64u)toto; 6 | return res; 7 | } 8 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/local_stack_to_pointer.jazz: -------------------------------------------------------------------------------- 1 | export fn f (reg ptr u64[2] r) -> reg ptr u64[2] { 2 | stack u64[1] a; 3 | a[0]=0; 4 | r[0:1] = a[0:1]; 5 | return r; 6 | } 7 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/merge_too_large_param.jazz: -------------------------------------------------------------------------------- 1 | export fn f (reg ptr u64[1] r) -> reg ptr u64[1] { 2 | stack u64[2] a; 3 | a[0]=0; 4 | r[0:1] = a[0:1]; 5 | return r; 6 | } 7 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/range_overflow.jazz: -------------------------------------------------------------------------------- 1 | export fn main (reg u64 x) -> reg u64 { 2 | stack u64[3] a; 3 | stack u64[2] b; 4 | b = a[2:2]; 5 | x = b[0]; 6 | return x; 7 | } 8 | -------------------------------------------------------------------------------- /compiler/tests/fail/typing/x86-64/unsupported_primitive.jazz: -------------------------------------------------------------------------------- 1 | export fn f(reg u64 x) -> reg u64 { 2 | reg u64 r; 3 | 4 | _, x = x ^ x * x; 5 | 6 | r = x; 7 | 8 | return r; 9 | 10 | } -------------------------------------------------------------------------------- /compiler/tests/fail/x86-64/por_32.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn por_32(reg u32 x y) -> reg u32 { 3 | #[mmx] reg u32 a = x; 4 | #[mmx] reg u32 b = y; 5 | a |= b; 6 | x = a; 7 | return x; 8 | } 9 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/common/copy.jazz: -------------------------------------------------------------------------------- 1 | export fn test(reg u32 x) -> reg u32 { 2 | reg u32[1] r; 3 | stack u32[1] s; 4 | r[0] = x; 5 | s = #copy_32(r); 6 | x = s[0]; 7 | return x; 8 | } 9 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/sar.jazz: -------------------------------------------------------------------------------- 1 | export fn test(reg u64 in) -> reg u64 2 | { 3 | reg u32 u; 4 | reg u64 r; 5 | 6 | u = in; 7 | u >>s= 16; 8 | r = (64u)u; 9 | return r; 10 | } 11 | -------------------------------------------------------------------------------- /compiler/tests/warning/common/bug_1347.jazz: -------------------------------------------------------------------------------- 1 | namespace A { 2 | u32 g = 0; 3 | u64 g = 1; 4 | } 5 | 6 | namespace B { 7 | namespace C { u32 x = 2; } 8 | namespace C { u16 x = 3; } 9 | } 10 | -------------------------------------------------------------------------------- /compiler/CCT/fail/mod_secret.jazz: -------------------------------------------------------------------------------- 1 | #[ct="secret -> secret"] 2 | export fn mod(reg u32 x) -> reg u32 { 3 | reg u32 d q; 4 | x = x; 5 | d = 3; 6 | q = x % d; 7 | q = q; 8 | return q; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/examples/gimli/proofs/.gitignore: -------------------------------------------------------------------------------- 1 | Array12.ec 2 | BArray48.ec 3 | WArray48.ec 4 | gimli_arm.ec 5 | gimli_avx.ec 6 | gimli_x86.ec 7 | gimli_arm_ct.ec 8 | gimli_avx_ct.ec 9 | gimli_x86_ct.ec 10 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/reg_var_expected.jazz: -------------------------------------------------------------------------------- 1 | export fn main () -> reg u64 { 2 | stack u64 s; 3 | reg u64 res; 4 | 5 | s = 0; 6 | res = [s]; 7 | 8 | return res; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/tests/fail/x86-64/swap_int.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u8 a) -> reg u8 { 3 | inline int i j; 4 | i = 0; 5 | j = 1; 6 | i, j = #swap(i, j); 7 | a = a if i < j; 8 | return a; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/x86-64/flags.jazz: -------------------------------------------------------------------------------- 1 | export fn f(reg u64 x) -> reg u64 { 2 | reg u64 r; 3 | reg bool c; 4 | r = x; 5 | ?{ "==" = c }, x = #SUB(x, 1); 6 | r = x if !c; 7 | return r; 8 | } 9 | -------------------------------------------------------------------------------- /compiler/tests/success/common/bug_540.jazz: -------------------------------------------------------------------------------- 1 | u32 g = 540; 2 | 3 | export fn bug_540() -> reg u32 { 4 | inline int i; 5 | reg u32 r; 6 | r = 0; 7 | i = g; 8 | r += i; 9 | return r; 10 | } 11 | -------------------------------------------------------------------------------- /compiler/tests/success/tunneling/x86-64/tunneling.jazz: -------------------------------------------------------------------------------- 1 | export fn test (reg u64 x) -> reg u64 { 2 | reg u64 r; 3 | r=x; 4 | if (r>5) {if (r>6) {} else {}} else {if (r>2) {} else {}} 5 | return r; 6 | } 7 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/bug_1139.jazz: -------------------------------------------------------------------------------- 1 | export fn carry(reg u64 x) -> reg u8 { 2 | reg bool c; 3 | _, c, _, _, _ = #CMP(x, 0); 4 | _, x += 1 + c; 5 | reg u8 r = #SETcc(c); 6 | return r; 7 | } 8 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/bug_200.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn exp(reg u64 e) -> reg u64 { 3 | reg u64 m; 4 | reg bool c; 5 | m = 1; 6 | c = e != 0; 7 | m = e if c; 8 | return m; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/uint63/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name uint63) 3 | (public_name jasmin.uint63) 4 | (modules :standard \ uint63_31 uint63_63) 5 | (virtual_modules uint63) 6 | (default_implementation uint63_native)) 7 | -------------------------------------------------------------------------------- /compiler/tests/fail/lower_spill/needs_to_be_spilled_overwritten.jazz: -------------------------------------------------------------------------------- 1 | export fn main () -> reg u32 { 2 | reg u32 res; 3 | res = 0; 4 | #spill(res); 5 | res = 2; 6 | #unspill(res); 7 | return res; 8 | } 9 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/pointer_to_local_stack.jazz: -------------------------------------------------------------------------------- 1 | export fn bad (reg ptr u64[1] p) -> reg u64 { 2 | stack u64[1] s; 3 | reg u64 r; 4 | 5 | s = p; 6 | r = s[0]; 7 | return r; 8 | } 9 | -------------------------------------------------------------------------------- /compiler/tests/fail/typing/x86-64/subarray_non_const_len.jazz: -------------------------------------------------------------------------------- 1 | export fn main () -> reg u64 { 2 | stack u64[4] a; 3 | reg u64 i, res; 4 | i = 2; 5 | a[0:i] = a[0:i]; 6 | res = a[0]; 7 | return res; 8 | } 9 | -------------------------------------------------------------------------------- /compiler/tests/fail/x86-64/swap_bool.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u8 a) -> reg u8 { 3 | reg bool b c; 4 | b = a != 0; 5 | c = a reg u32 4 | { 5 | a = (a << 3) - a; 6 | a = 2 - a; 7 | return a; 8 | } 9 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/test_mem.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn f(reg u64 p, reg u64 i) -> reg u64 { 3 | reg u64 r; 4 | stack u64 x; 5 | r = [p + 8 * i]; 6 | x = [p + 8 * i]; 7 | r ^= x; 8 | return r; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/safetylib/dune: -------------------------------------------------------------------------------- 1 | (include_subdirs unqualified) 2 | 3 | (library 4 | (name jasmin_checksafety) 5 | (flags (:standard -w -9-27-32-39-67)) 6 | (libraries jasmin yojson apron.octMPQ apron.ppl apron.boxMPQ)) 7 | -------------------------------------------------------------------------------- /compiler/tests/fail/slh/x86-64/assign_kills_msf.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u64 x) { 3 | reg u64 msf; 4 | 5 | msf = #init_msf(); 6 | msf = msf; 7 | x = #protect(x, msf); 8 | [x] = 0; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/tests/fail/unroll/x86-64/bug_29.jazz: -------------------------------------------------------------------------------- 1 | export fn main (reg u64 io) -> reg u64 { 2 | inline int i; 3 | reg u64 res; 4 | for i = 0 to (uint)io { 5 | res = i; 6 | } 7 | return res; 8 | } 9 | 10 | -------------------------------------------------------------------------------- /compiler/tests/fail/x86-64/por_mem_intrinsic.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn por_mem(reg u64 x y) -> reg u64 { 3 | stack u64 s = x; 4 | #[mmx] reg u64 a = y; 5 | s = #POR(s, a); 6 | x = s; 7 | return x; 8 | } 9 | -------------------------------------------------------------------------------- /compiler/tests/safety/fail/arm-m4/bad_align.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 pt) -> reg u32 { 3 | reg u32 tmp; 4 | 5 | tmp = [:u32 pt + 0]; 6 | tmp = [#aligned:u32 pt + 1]; 7 | 8 | return tmp; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/tests/safety/fail/risc-v/bad_align.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 pt) -> reg u32 { 3 | reg u32 tmp; 4 | 5 | tmp = [:u32 pt + 0]; 6 | tmp = [#aligned:u32 pt + 1]; 7 | 8 | return tmp; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/tests/safety/fail/x86-64/bad_align.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u64 pt) -> reg u64 { 3 | reg u64 tmp; 4 | 5 | tmp = [:u64 pt + 0]; 6 | tmp = [#aligned:u64 pt + 1]; 7 | 8 | return tmp; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/tests/success/common/bug_815.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn snd(reg u32 x y) -> reg u32 { 3 | stack u32[1] a b; 4 | a[0] = x; 5 | b[0] = y; 6 | a, b = #swap(a, b); 7 | x = a[0]; 8 | return x; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/tests/success/slh/x86-64/init_msf.jazz: -------------------------------------------------------------------------------- 1 | export fn foo () -> reg u64 { 2 | reg u64 msf; 3 | msf = #init_msf(); 4 | return msf; 5 | } 6 | 7 | export fn foo2() { 8 | _ = #init_msf(); 9 | } 10 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/array_add.jazz: -------------------------------------------------------------------------------- 1 | export fn test () -> reg u64 { 2 | stack u64[2] t; 3 | reg u64 p r; 4 | t[0] = 0; 5 | t[1] = 1; 6 | p = 0; 7 | r = t[(uint)p + 1]; 8 | return r; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/test_lowereq.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn f(reg u64 x) -> reg u64 { 3 | reg bool eqf; 4 | reg u64 r, one; 5 | eqf = x == 0; 6 | r = 0; 7 | one = 1; 8 | r = one if eqf; 9 | return r; 10 | } 11 | -------------------------------------------------------------------------------- /eclib/JModel.ec: -------------------------------------------------------------------------------- 1 | (** This module has been deprecated since May 2023 and is only provided for compatibility purposes. 2 | * Please use JModel_x86 or JLeakage directly instead. *) 3 | require export JModel_x86 JLeakage. 4 | -------------------------------------------------------------------------------- /Makefile.compiler: -------------------------------------------------------------------------------- 1 | all: 2 | $(MAKE) -C compiler 3 | 4 | clean: 5 | $(MAKE) -C compiler clean 6 | $(MAKE) -C eclib clean 7 | 8 | install: 9 | $(MAKE) -C compiler install 10 | $(MAKE) -C eclib install 11 | 12 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/no_region_reg_ptr.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn g () -> reg u64 { 3 | reg ptr u64[1] r; 4 | reg u64 res; 5 | 6 | r[0] = 0; 7 | res = r[0]; 8 | 9 | return res; 10 | } 11 | -------------------------------------------------------------------------------- /compiler/tests/fail/x86-64/por_32_intrinsic.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn por_32(reg u32 x y) -> reg u32 { 3 | #[mmx] reg u32 a = x; 4 | #[mmx] reg u32 b = y; 5 | a = #POR_32(a, b); 6 | x = a; 7 | return x; 8 | } 9 | -------------------------------------------------------------------------------- /changes/03-other/1346-deprecate-open-annotations.md: -------------------------------------------------------------------------------- 1 | - Annotations must be enclosed within square brackets; syntax without square 2 | brackets is now deprecated 3 | ([PR 1346](https://github.com/jasmin-lang/jasmin/pull/1346)). 4 | -------------------------------------------------------------------------------- /compiler/tests/fail/array_expansion/x86-64/export_return.jazz: -------------------------------------------------------------------------------- 1 | export fn main () -> reg u64[3] { 2 | reg u64[3] r; 3 | 4 | inline int i; 5 | for i = 0 to 3 { 6 | r[i] = 0; 7 | } 8 | 9 | return r; 10 | } 11 | -------------------------------------------------------------------------------- /compiler/tests/fail/common/inline-remains.jazz: -------------------------------------------------------------------------------- 1 | export fn main(reg u32 x) -> reg u32 { 2 | reg u32 r; 3 | #[inline] 4 | if x reg u32 { 2 | reg u32 res; 3 | #[mmx] reg u32 tmp; 4 | 5 | res = 0; 6 | tmp = res; 7 | res = tmp; 8 | 9 | return res; 10 | } 11 | -------------------------------------------------------------------------------- /compiler/tests/fail/slh/x86-64/protect_kills_msf.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main() -> reg u64 { 3 | reg u64 msf; 4 | msf = #init_msf(); 5 | msf = #protect(msf, msf); 6 | msf = #protect(msf, msf); 7 | return msf; 8 | } 9 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/no_region_stack_ptr.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn g () -> reg u64 { 3 | stack ptr u64[1] sp; 4 | reg u64 res; 5 | 6 | sp[0] = 0; 7 | res = sp[0]; 8 | 9 | return res; 10 | } 11 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/write_constant_pointer_arg.jazz: -------------------------------------------------------------------------------- 1 | export fn foo (reg ptr u64[4] p) -> reg u64 { 2 | reg u64 r; 3 | reg ptr u64[4] s; 4 | s = p; 5 | s[0] = 1; 6 | r = s[0]; 7 | return r; 8 | } 9 | -------------------------------------------------------------------------------- /compiler/tests/safety/fail/common/array_init.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn bad_read() -> reg u32 { 3 | stack u32[2] t; 4 | reg u32 r; 5 | t[0] = 42; 6 | t[1] = 33; 7 | ArrayInit(t); 8 | r = t[0]; 9 | return r; 10 | } 11 | -------------------------------------------------------------------------------- /compiler/tests/success/common/test_keep.jazz: -------------------------------------------------------------------------------- 1 | #[stacksize=8] 2 | export 3 | fn main(reg u32 x) -> reg u32 { 4 | stack u32[1] a b; 5 | a[0] = x; 6 | #[keep] 7 | b[0] = x; 8 | x = a[0]; 9 | return x; 10 | } 11 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/bug_54.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main () -> reg u8 { 3 | reg u8 res; 4 | stack u8[3] a; 5 | stack u8[4] b; 6 | b[1] = 42; 7 | a[0:2] = b[1:2]; 8 | res = a[0]; 9 | return res; 10 | } 11 | -------------------------------------------------------------------------------- /compiler/CCT/fail/doit/x86_64/rol.jazz: -------------------------------------------------------------------------------- 1 | // This is CT in the ordinary sense, but not DOIT as ROL is not DOIT. 2 | #[ct="secret -> secret"] 3 | export fn rol(reg u32 x) -> reg u32 { 4 | x < reg u8 { 4 | reg bool unitialized; 5 | reg u8 byte; 6 | byte = #SETcc(unitialized); 7 | return byte; 8 | 9 | } 10 | -------------------------------------------------------------------------------- /compiler/tests/fail/register_allocation/x86-64/bug_309.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn test(reg u64 x) -> reg u64 { 3 | reg u64 r; 4 | reg bool cf; 5 | cf, x = x + x; 6 | ?{}, r = #set0(); 7 | r = x if cf; 8 | return r; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/merge_param_global.jazz: -------------------------------------------------------------------------------- 1 | u64[2] g = {0,1}; 2 | 3 | export fn f (reg ptr u64[1] r) -> reg ptr u64[1] { 4 | reg ptr u64[2] rg; 5 | rg = g; 6 | r[0:1] = rg[0:1]; 7 | return r; 8 | } 9 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/merge_same_trivial.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn f () -> reg u64 { 3 | stack u64[2] a; 4 | reg u64 res; 5 | a[0] = 1; 6 | a[1:1] = a[0:1]; 7 | res = a[1]; 8 | return res; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/tests/safety/dune: -------------------------------------------------------------------------------- 1 | (tests 2 | (libraries jasmin.jasmin jasmin_checksafety testlib) 3 | (deps 4 | (glob_files_rec success/*) 5 | (glob_files_rec fail/*)) 6 | (modules run) 7 | (names 8 | run)) 9 | 10 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/riscv/dynglob.jazz: -------------------------------------------------------------------------------- 1 | export fn main(reg ptr u32[8] s) -> reg u32 { 2 | global u32 index; 3 | index = 5; 4 | reg u32 i; 5 | i = index; 6 | reg u32 r; 7 | r = s[i]; 8 | return r; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/x86-64/dynglob.jazz: -------------------------------------------------------------------------------- 1 | export fn main(reg ptr u8[8] s) -> reg u8 { 2 | global u64 index; 3 | index = 5; 4 | reg u64 i; 5 | i = index; 6 | reg u8 r; 7 | r = s[i]; 8 | return r; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/tests/sct-checker/success/bug_852.jazz: -------------------------------------------------------------------------------- 1 | inline 2 | fn reset(stack u64 t) { 3 | [t] = 0; 4 | } 5 | 6 | export 7 | fn main(reg u64 x) { 8 | _ = #init_msf(); 9 | stack u64 s; 10 | s = x; 11 | reset(s); 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/concat_2u128.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn concat_2u128(reg u64 x y z) { 3 | reg u128 a b; 4 | reg u256 c; 5 | a = [:u128 x]; 6 | b = [:u128 y]; 7 | c = (2u128)[a, b]; 8 | [:u256 z] = c; 9 | } 10 | -------------------------------------------------------------------------------- /scripts/nixpkgs.nix: -------------------------------------------------------------------------------- 1 | import (fetchTarball { 2 | url = "https://github.com/NixOS/nixpkgs/archive/c6f52ebd45e5925c188d1a20119978aa4ffd5ef6.tar.gz"; 3 | sha256 = "sha256:0gwxhs3j1nglyymbaqyqg8miz0rk84n4ijag5s4bx6yfb6vrd4lv"; 4 | }) 5 | -------------------------------------------------------------------------------- /compiler/src/pp_x86.mli: -------------------------------------------------------------------------------- 1 | open Wsize 2 | (* -------------------------------------------------------------------- *) 3 | exception InvalidRegSize of wsize 4 | 5 | val print_prog : 6 | Format.formatter -> X86_instr_decl.x86_prog -> unit 7 | -------------------------------------------------------------------------------- /compiler/tests/fail/risc-v/basics.jazz: -------------------------------------------------------------------------------- 1 | // Should be implemented in the long run, fails for now 2 | 3 | export 4 | fn copy_cast_lowering(reg u32 r) -> reg u32, reg u16 { 5 | reg u16 c; 6 | c = r; 7 | return r, c; 8 | } 9 | -------------------------------------------------------------------------------- /compiler/tests/safety/fail/x86-64/popcnt.jazz: -------------------------------------------------------------------------------- 1 | export fn off_by_one(reg u64 x) -> reg u8 { 2 | inline int i; 3 | stack u8[64] s; 4 | for i = 0 to 64 { s[i] = i; } 5 | ?{}, x = #POPCNT(x); 6 | reg u8 r = s[x]; 7 | return r; 8 | } 9 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/arm-m4/align.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 pt) -> reg u32 { 3 | reg u32 tmp; 4 | 5 | tmp = [:u32 pt + 0]; 6 | tmp = [:u32 pt + 4]; 7 | tmp = [:u32 pt + 12]; 8 | 9 | return tmp; 10 | } 11 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/arm-m4/dynglob.jazz: -------------------------------------------------------------------------------- 1 | export fn main(reg ptr u32[8] s) -> reg u32 { 2 | global u32 index; 3 | index = 5; 4 | reg u32 i; 5 | i = index; 6 | reg u32 r; 7 | r = s[i]; 8 | return r; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/riscv/align.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 pt) -> reg u32 { 3 | reg u32 tmp; 4 | 5 | tmp = [:u32 pt + 0]; 6 | tmp = [:u32 pt + 4]; 7 | tmp = [:u32 pt + 12]; 8 | 9 | return tmp; 10 | } 11 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/inline-if.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn test() -> reg u64 { 3 | reg u64 r; 4 | inline u64 c; 5 | c = 42; 6 | if c >= 1234 { 7 | r = 1; 8 | } else { 9 | r = 0; 10 | } 11 | return r; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/strings.jazz: -------------------------------------------------------------------------------- 1 | u8[1] z = "\x00"; 2 | u8[1] q = "\""; 3 | u8[14] x = "\"; 4 | u8[2] y = \""; 5 | u8[1] nl = "\n"; 6 | u8[9] hw = "食飽未"; 7 | u8[1] escaped = "\\"; 8 | u8[25] nested = "“\"Is 'this' quoted?\"”"; 9 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/unroll_nested_loop.jazz: -------------------------------------------------------------------------------- 1 | export fn test(reg u64 buffer) 2 | { 3 | inline int i j; 4 | for i = 0 to 4 { 5 | for j = 0 to 1 << i { 6 | [:u8 buffer + 16 * i + j] = 1; 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /changes/01-feature/1356-auto-spill.md: -------------------------------------------------------------------------------- 1 | - When one of the “auto-spill” flag is set on the command-line, automatically 2 | insert spill and unspill operations in the program 3 | ([PR #1356](https://github.com/jasmin-lang/jasmin/pull/1356)). 4 | -------------------------------------------------------------------------------- /compiler/CCT/success/doit/bug_927.jazz: -------------------------------------------------------------------------------- 1 | #[ct="secret * secret -> secret"] 2 | export fn multiplications(reg u64 x y) -> reg u64 { 3 | x = x; 4 | reg u64 z t; 5 | z, t = x * y; 6 | t *= z; 7 | t *= 17; 8 | return t; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/tests/fail/register_allocation/x86-64/bug_426_bis.jazz: -------------------------------------------------------------------------------- 1 | fn foo(reg u64 x y) -> reg u64 { 2 | return x; 3 | } 4 | 5 | export 6 | fn dummy(reg u64 p) -> reg u64 { 7 | p = p; 8 | p = foo(p, p); 9 | return p; 10 | } 11 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/stack_ptr_in_expr.jazz: -------------------------------------------------------------------------------- 1 | export fn main (reg ptr u64[1] r) -> reg u64 { 2 | stack ptr u64[1] sp; 3 | reg u64 res; 4 | 5 | sp = r; 6 | res = sp[0] + 1; 7 | 8 | return res; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/tests/fail/typing/x86-64/write_constant_pointer_direct_array.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main() -> reg u64{ 3 | reg u64 a; 4 | stack u64[1] s; 5 | reg const ptr u64[1] p = s; 6 | p[0] = 1; 7 | a = p[0]; 8 | return a; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/common/int_shift.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 x) -> reg u32 { 3 | inline int i; 4 | reg u32 r; 5 | r = x; 6 | for i = 0 to (1 << 3) - (5 >> 1) { 7 | r += x; 8 | } 9 | return r; 10 | } 11 | -------------------------------------------------------------------------------- /compiler/tests/success/slh/x86-64/protect_128.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn foo (reg u128 x) -> reg u128 { 3 | reg u64 msf; 4 | msf = #init_msf(); 5 | 6 | reg u128 y; 7 | y = #protect_128(x, msf); 8 | 9 | return y; 10 | } 11 | -------------------------------------------------------------------------------- /compiler/tests/success/slh/x86-64/protect_256.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn foo (reg u256 x) -> reg u256 { 3 | reg u64 msf; 4 | msf = #init_msf(); 5 | 6 | reg u256 y; 7 | y = #protect_256(x, msf); 8 | 9 | return y; 10 | } 11 | -------------------------------------------------------------------------------- /compiler/tests/success/slh/x86-64/protect_8.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn foo(reg u64 p) -> { 3 | reg u64 msf; 4 | msf = #init_msf(); 5 | 6 | reg u8 x; 7 | x = 0; 8 | x = #protect_8(x, msf); 9 | 10 | [:u8 p] = x; 11 | } 12 | -------------------------------------------------------------------------------- /compiler/tests/success/subroutines/x86-64/id.jazz: -------------------------------------------------------------------------------- 1 | fn id(reg u64 x) -> reg u64 { reg u64 r; r = x; return r; } 2 | 3 | export 4 | fn a(reg u64 x, reg u64 y) -> reg u64 { 5 | reg u64 r; 6 | r = id(y); 7 | r += x; 8 | return r; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/tests/success/syscall/x86-64/align.jazz: -------------------------------------------------------------------------------- 1 | #[stackalign=u128] 2 | export 3 | fn randombyte() -> reg u8 { 4 | stack u8[1] buf; 5 | reg u8 r; 6 | buf = #randombytes(buf); 7 | r = buf[0]; 8 | return r; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/tests/fail/array_expansion/x86-64/index_not_constant_lv.jazz: -------------------------------------------------------------------------------- 1 | export fn main () -> reg u64 { 2 | reg u64[4] r; 3 | reg u64 res; 4 | 5 | reg u64 j; 6 | j = 0; 7 | r[j] = 0; 8 | res = r[j]; 9 | 10 | return res; 11 | } 12 | -------------------------------------------------------------------------------- /compiler/tests/fail/common/typealias_annotation_param.jazz: -------------------------------------------------------------------------------- 1 | 2 | type arch_size = u64; 3 | 4 | #[stackzero=loop] 5 | export fn main0(reg u64 p) { f(p); } 6 | 7 | #[stackzero=loop, stackzerosize=arch_size] 8 | export fn main1(reg u64 p) { f(p); } 9 | -------------------------------------------------------------------------------- /compiler/tests/fail/register_allocation/x86-64/var_unallocated.jazz: -------------------------------------------------------------------------------- 1 | export fn f () -> reg u64 { 2 | reg bool b; // maybe this should be rejected by typechecking 3 | reg u64 res; 4 | if (b) { 5 | res = 2; 6 | } 7 | return res; 8 | } 9 | -------------------------------------------------------------------------------- /compiler/tests/fail/slh/x86-64/intrinsic_kills_msf.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u64 x) { 3 | reg u64 msf; 4 | 5 | msf = #init_msf(); 6 | #[keep] 7 | msf = #MOV(msf); 8 | x = #protect(x, msf); 9 | [x] = 0; 10 | } 11 | -------------------------------------------------------------------------------- /compiler/tests/fail/typing/x86-64/vector_expr.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn toto () -> reg u64 { 3 | reg u256 x; 4 | reg u128 v; 5 | reg u64 r; 6 | x = 0; 7 | v = 1; 8 | x = x +4u64 v; 9 | 10 | r = 0; 11 | return r; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/success/slh/x86-64/protect_16.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn foo(reg u64 p) -> { 3 | reg u64 msf; 4 | msf = #init_msf(); 5 | 6 | reg u16 x; 7 | x = 0; 8 | x = #protect_16(x, msf); 9 | 10 | [:u16 p] = x; 11 | } 12 | -------------------------------------------------------------------------------- /compiler/tests/success/slh/x86-64/protect_32.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn foo(reg u64 p) -> { 3 | reg u64 msf; 4 | msf = #init_msf(); 5 | 6 | reg u32 x; 7 | x = 0; 8 | x = #protect_32(x, msf); 9 | 10 | [:u32 p] = x; 11 | } 12 | -------------------------------------------------------------------------------- /compiler/tests/success/slh/x86-64/protect_64.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn foo(reg u64 p) -> { 3 | reg u64 msf; 4 | msf = #init_msf(); 5 | 6 | reg u64 x; 7 | x = 0; 8 | x = #protect(x, msf); 9 | 10 | [:u64 p] = x; 11 | } 12 | -------------------------------------------------------------------------------- /changes/03-other/1340-print-less-brackets.md: -------------------------------------------------------------------------------- 1 | - Pretty-printing of Jasmin programs and expressions use less parentheses, 2 | taking into account priority and associativity of operators 3 | ([PR #1340](https://github.com/jasmin-lang/jasmin/pull/1340)). 4 | -------------------------------------------------------------------------------- /compiler/tests/fail/register_allocation/x86-64/bug_426.jazz: -------------------------------------------------------------------------------- 1 | fn foo(reg u64 x y) -> reg u64 { 2 | [x] = 0; 3 | return y; 4 | } 5 | 6 | export 7 | fn dummy(reg u64 p) -> reg u64 { 8 | p = p; 9 | _ = foo(p, p); 10 | return p; 11 | } 12 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/bad_range_alignment.jazz: -------------------------------------------------------------------------------- 1 | export fn f () -> reg u32 { 2 | reg u32 res; 3 | stack u64[2] a; 4 | stack u32[10] b; 5 | a[0]=0; 6 | b[1:2] = a[:u32 0:2]; 7 | res = b[1]; 8 | return res; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/merge_too_large_global.jazz: -------------------------------------------------------------------------------- 1 | u64[2] g = {1, 2}; 2 | 3 | export fn main () -> reg u64 { 4 | stack u64[3] s; 5 | reg u64 res; 6 | 7 | s[0:2] = g; 8 | res = s[0]; 9 | 10 | return res; 11 | } 12 | -------------------------------------------------------------------------------- /compiler/tests/safety/fail/arm-m4/bad_align2.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 pt) -> reg u32 { 3 | reg u32 tmp, i; 4 | 5 | i = 0; 6 | while (i < 16) { 7 | tmp = [:u32 pt + i]; 8 | i += 1; 9 | } 10 | 11 | return tmp; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/safety/fail/risc-v/bad_align2.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 pt) -> reg u32 { 3 | reg u32 tmp, i; 4 | 5 | i = 0; 6 | while (i < 16) { 7 | tmp = [:u32 pt + i]; 8 | i += 1; 9 | } 10 | 11 | return tmp; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/safety/fail/x86-64/bad_align2.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u64 pt) -> reg u64 { 3 | reg u64 tmp, i; 4 | 5 | i = 0; 6 | while (i < 16) { 7 | tmp = [:u64 pt + i]; 8 | i += 1; 9 | } 10 | 11 | return tmp; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/success/common/bug_1292.jazz: -------------------------------------------------------------------------------- 1 | export fn f(reg u32 a) { 2 | if a < 0 { 3 | reg u32 x = 0; 4 | #spill(x); 5 | #unspill(x); 6 | } else { 7 | reg u32 x = 0; 8 | #spill(x); 9 | #unspill(x); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /compiler/tests/success/common/call-export.jazz: -------------------------------------------------------------------------------- 1 | export fn aux(reg u32 x) -> reg u32 { 2 | reg u32 y; 3 | y = x; 4 | return y; 5 | } 6 | 7 | export fn main(reg u32 a) -> reg u32 { 8 | #[inline] 9 | a = aux(a); 10 | return a; 11 | } 12 | -------------------------------------------------------------------------------- /compiler/tests/success/require/common/file2.jazz: -------------------------------------------------------------------------------- 1 | require "file1.jazz" 2 | require "../common/file1.jazz" 3 | 4 | export fn main(reg u32 x y) -> reg u32 { 5 | reg u32 r1 r2; 6 | r1 = add(x,y); 7 | r2 = r1; 8 | return r2; 9 | } 10 | 11 | -------------------------------------------------------------------------------- /compiler/tests/success/risc-v/load.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn load(reg u32 arg) -> reg u32 { 3 | reg u32 x; 4 | x = [arg]; 5 | 6 | x = [x + 3]; 7 | x = [x - 3]; 8 | 9 | reg u32 res; 10 | res = x; 11 | return res; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/CCT/fail/randombytes.jazz: -------------------------------------------------------------------------------- 1 | #[ct="() -> secret"] 2 | export 3 | fn main() -> reg u64 { 4 | stack u64[1] s; 5 | reg u64 r; 6 | s = #randombytes(s); 7 | r = s[0]; 8 | while (r < 64) { 9 | r += 64; 10 | } 11 | return r; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/src/interval.ml: -------------------------------------------------------------------------------- 1 | type interval = { min : int; max : int } 2 | type t = interval 3 | 4 | let size i = i.max - i.min 5 | 6 | let pp_interval ?(closed=false) fmt { min ; max } = 7 | Format.fprintf fmt "[%d; %d%s" min max (if closed then "]" else "[") 8 | -------------------------------------------------------------------------------- /compiler/tests/fail/common/not-unrollable-for-loop.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 x) -> reg u32 { 3 | reg u32 r = 0; 4 | inline int i j; 5 | for i = 0 to 4 { 6 | for j = 0 to x { 7 | r += 1; 8 | } 9 | } 10 | return r; 11 | } 12 | -------------------------------------------------------------------------------- /compiler/tests/fail/register_allocation/arm-m4/no_vector.jazz: -------------------------------------------------------------------------------- 1 | export fn main () -> reg u32 { 2 | reg u32 res; 3 | reg u256 tmp; 4 | 5 | tmp = 0; 6 | res = 1; 7 | if (tmp >= 0) { 8 | res = 0; 9 | } 10 | 11 | return res; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/bad_alignment.jazz: -------------------------------------------------------------------------------- 1 | export fn f (reg u64 i) -> reg u32 { 2 | reg u32 res; 3 | stack u64[2] a; 4 | stack u32[10] b; 5 | a[i]=0; 6 | b[1:2] = a[:u32 i:2]; 7 | res = b[1]; 8 | return res; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/tests/safety/fail/x86-64/carry_flags_err.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn test() -> reg u64 { 3 | reg bool cf; 4 | reg u64 i; 5 | 6 | i = 2; 7 | cf, i -= 1; 8 | if (!cf){ 9 | while (true) { i += 1;} 10 | } 11 | 12 | return i; 13 | } 14 | -------------------------------------------------------------------------------- /compiler/tests/safety/fail/x86-64/carry_flags_err2.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn test() -> reg u64 { 3 | reg bool cf; 4 | reg u64 i; 5 | 6 | i = 0; 7 | cf, i -= 1; 8 | if (cf){ 9 | while (true) { i += 1;} 10 | } 11 | 12 | return i; 13 | } 14 | -------------------------------------------------------------------------------- /compiler/tests/success/arm-m4/intrinsic_umaal.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn umaal(reg u32 a b c d) -> reg u32 { 3 | reg bool f; 4 | f = c > d; 5 | a, b = #UMAAL(a, b, c, d); 6 | a, b = #UMAALcc(a, b, c, d, f, a, b); 7 | a ^= b; 8 | return a; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/merge_same.jazz: -------------------------------------------------------------------------------- 1 | export fn foo () -> reg u64 { 2 | reg u64 r; 3 | stack u64[4] s; 4 | reg ptr u64[4] rt; 5 | 6 | s[2] = 0; 7 | rt = s; 8 | s[0:2] = rt[2:2]; 9 | r = s[0]; 10 | return r; 11 | } 12 | -------------------------------------------------------------------------------- /compiler/tests/safety/fail/common/init-join.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 x) -> reg u32 { 3 | reg u32 r; 4 | if x > 0 { 5 | r = 0; 6 | } 7 | return r; 8 | } 9 | 10 | inline fn test() { 11 | #[inline] _ = main(0); 12 | } 13 | exec test() 14 | -------------------------------------------------------------------------------- /compiler/tests/success/arm-m4/intrinsic_clz.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 x) -> reg u32 { 3 | reg u32 y; 4 | y = #CLZ(x); 5 | 6 | reg bool b; 7 | ?{ " reg u32 { 3 | reg u32[5] x; 4 | reg u32 z; 5 | x[0] = 0; 6 | x[1] = 0; 7 | x[2] = 0; 8 | x[3] = 0; 9 | x[4] = 0; 10 | z = x[0]; 11 | return z; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/success/namespaces/common/sum.jinc: -------------------------------------------------------------------------------- 1 | /* Parameters: 2 | param int N; 3 | */ 4 | fn sum(reg u32[N] t) -> reg u32 { 5 | reg u32 s; 6 | inline int c; 7 | s = 0; 8 | for c = 0 to N { 9 | s += t[c]; 10 | } 11 | return s; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/success/subroutines/x86-64/literal-argument.jazz: -------------------------------------------------------------------------------- 1 | fn inc(reg u64 x) -> reg u64 { 2 | x = #LEA(x + 1); 3 | return x; 4 | } 5 | 6 | export 7 | fn one() -> reg u64 { 8 | reg u64 r; 9 | #[inline] r = inc(0); 10 | return r; 11 | } 12 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/dead_code_arr_init.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn foo (reg u64 x) -> reg u64 { 3 | stack u64[1] t; 4 | ArrayInit(t); 5 | ArrayInit(t); 6 | ArrayInit(t); 7 | t[0] = x; 8 | x = t[0]; 9 | return x; 10 | } 11 | 12 | 13 | -------------------------------------------------------------------------------- /compiler/uint63/js/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name uint63_js) 3 | (public_name jasmin.uint63-js) 4 | (implements jasmin.uint63)) 5 | 6 | (rule 7 | (targets uint63.ml) 8 | (deps (:gen-file ../uint63_31.ml)) 9 | (action (copy# %{gen-file} %{targets}))) 10 | -------------------------------------------------------------------------------- /changes/02-bugfix/1341-extract-wint-spill.md: -------------------------------------------------------------------------------- 1 | - Fix extraction to EasyCrypt of (un)spill operations involving word-sized integers 2 | ([PR #1341](https://github.com/jasmin-lang/jasmin/pull/1341); 3 | fixes [#1335](https://github.com/jasmin-lang/jasmin/issues/1335)). 4 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/write_constant_stack_global.jazz: -------------------------------------------------------------------------------- 1 | u64[4] glob_t = { 0, 1, 2, 3 }; 2 | 3 | export fn foo () -> reg u64 { 4 | reg u64 r; 5 | stack u64[4] s; 6 | s = glob_t; 7 | s[0] = 1; 8 | r = s[0]; 9 | return r; 10 | } 11 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/common/nested_for.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn f() -> reg u32 { 3 | reg u32 r; 4 | inline int i j; 5 | 6 | r = 0; 7 | for i = 0 to 4 { 8 | for j = 0 to 4 { 9 | r += 1; 10 | } 11 | } 12 | 13 | return r; 14 | } 15 | -------------------------------------------------------------------------------- /compiler/tests/success/arm-m4/load_immediate.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn load_immediate() { 3 | reg u32 x; 4 | 5 | x = 0x000cb000; // This needs a MOV and a MOVT. 6 | [x] = x; 7 | x = 0x000acaca; // This needs a MOV and a MOVT. 8 | [x] = x; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/tests/success/subarrays/arm-m4/global.jazz: -------------------------------------------------------------------------------- 1 | // reg ptr of global 2 | 3 | u32[2] g = {1, 2}; 4 | 5 | export fn main () -> reg u32 { 6 | reg ptr u32[2] r; 7 | reg u32 res; 8 | 9 | r = g; // ADR 10 | res = r[0]; 11 | 12 | return res; 13 | } 14 | -------------------------------------------------------------------------------- /compiler/tests/success/subarrays/risc-v/global.jazz: -------------------------------------------------------------------------------- 1 | // reg ptr of global 2 | 3 | u32[2] g = {1, 2}; 4 | 5 | export fn main () -> reg u32 { 6 | reg ptr u32[2] r; 7 | reg u32 res; 8 | 9 | r = g; // LA 10 | res = r[0]; 11 | 12 | return res; 13 | } 14 | -------------------------------------------------------------------------------- /compiler/tests/success/subarrays/x86-64/global.jazz: -------------------------------------------------------------------------------- 1 | // reg ptr of global 2 | 3 | u32[2] g = {1, 2}; 4 | 5 | export fn main () -> reg u32 { 6 | reg ptr u32[2] r; 7 | reg u32 res; 8 | 9 | r = g; // LEA 10 | res = r[0]; 11 | 12 | return res; 13 | } 14 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/bug_1138.jazz: -------------------------------------------------------------------------------- 1 | export fn iszero(reg u32 x) -> reg u32 { 2 | reg bool of, cf, sf, zf; 3 | reg u32 r = 0, one = 1; 4 | of, cf, sf, _, zf = #TEST_32(x, x); 5 | reg bool b = _EQ(of, cf, sf, zf); 6 | r = one if b; 7 | return r; 8 | } 9 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/glob_in_regptr.jazz: -------------------------------------------------------------------------------- 1 | u64[2] g = {1, 2}; 2 | 3 | export fn main () -> reg u64 { 4 | reg u64 res; 5 | stack u64[2] s; 6 | reg ptr u64[2] r; 7 | 8 | s = g; 9 | r = s; 10 | res = r[0]; 11 | 12 | return res; 13 | } 14 | -------------------------------------------------------------------------------- /docs/shell.nix: -------------------------------------------------------------------------------- 1 | { pkgs ? import { } }: 2 | 3 | with pkgs; 4 | 5 | mkShell { 6 | packages = [ 7 | graphviz 8 | (python3.withPackages 9 | (ps: [ ps.myst-parser ps.sphinx ps.sphinx-rtd-theme ps.sphinx-copybutton ])) 10 | ]; 11 | } 12 | -------------------------------------------------------------------------------- /compiler/src/iInfo.ml: -------------------------------------------------------------------------------- 1 | type t = Location.i_loc * Annotations.annotations 2 | let dummy = Location.i_dummy, [] 3 | let with_location (l, _) = (l, []) 4 | let is_inline (_, annot) = Annotations.has_symbol "inline" annot 5 | let var_info_of_ii (l, _) = Location.(l.base_loc) 6 | -------------------------------------------------------------------------------- /compiler/tests/fail/array_expansion/x86-64/default_scale_2.jazz: -------------------------------------------------------------------------------- 1 | export fn main () -> reg u64 { 2 | reg u64[4] r; 3 | reg u64 res; 4 | 5 | inline int i; 6 | for i = 0 to 4 { 7 | r[i] = 0; 8 | } 9 | 10 | res = r.[0]; 11 | 12 | return res; 13 | } 14 | -------------------------------------------------------------------------------- /compiler/tests/fail/param_expansion/x86-64/array_too_large_expr.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main() -> reg u64 { 3 | stack u64[1] a; 4 | 5 | _ = a[0:0x10000000000000000]; 6 | a[0] = 0; 7 | 8 | reg u64 r; 9 | r = a[0]; 10 | 11 | return r; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/fail/param_expansion/x86-64/array_too_large_lval.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main() -> reg u64 { 3 | stack u64[1] a; 4 | 5 | a[0:0x10000000000000000] = a; 6 | a[0] = 0; 7 | 8 | reg u64 r; 9 | r = a[0]; 10 | 11 | return r; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/array_access_too_complex.jazz: -------------------------------------------------------------------------------- 1 | export fn main (reg u64 i) -> reg u64 { 2 | stack u64[2] s; 3 | reg ptr u64[1] r; 4 | 5 | s[0] = 0; 6 | r = s[i/(i+1):1]; 7 | 8 | reg u64 res = r[0]; 9 | return res; 10 | } 11 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/write_constant_pointer_global.jazz: -------------------------------------------------------------------------------- 1 | u64[4] glob_t = { 0, 1, 2, 3 }; 2 | 3 | export fn foo () -> reg u64 { 4 | reg u64 r; 5 | reg ptr u64[4] s; 6 | s = glob_t; 7 | s[0] = 1; 8 | r = s[0]; 9 | return r; 10 | } 11 | -------------------------------------------------------------------------------- /compiler/tests/fail/unroll/x86-64/bug_150.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u64 x) -> reg u64 { 3 | inline int i; 4 | reg u64 y; 5 | y = 0; 6 | for i = 0 to 10 { 7 | #[inline] 8 | if (x == i) { 9 | y = x; 10 | } 11 | } 12 | return y; 13 | } 14 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/common/bug_386.jazz: -------------------------------------------------------------------------------- 1 | export fn main(){ 2 | stack u16[3 * 4] a; 3 | reg u32 i; 4 | i = 0; 5 | while (i < 3 * 3) { 6 | inline int k; 7 | for k = 0 to 4 { 8 | a[i] = 0; 9 | i += 1; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/bug_599.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn test(reg u64 a b) -> reg u64 { 3 | reg bool cond; 4 | reg u64 res one; 5 | 6 | ?{ "!=" = cond } = #CMP_64(a, b); 7 | res = 0; 8 | one = 1; 9 | res = one if(cond); 10 | 11 | return res; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/test_global_string_literal.jazz: -------------------------------------------------------------------------------- 1 | u8[10] test = "Teststring"; 2 | 3 | export fn main() -> reg u8 4 | { 5 | reg u8 res tmp; 6 | res = 0x54; 7 | 8 | tmp = test[0]; 9 | res = res ^ tmp; 10 | 11 | return res; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/vpermd.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn test_vpermd(reg u64 tmp) 3 | { 4 | reg u256 t0 t1; 5 | 6 | t0 = #set0_256(); 7 | t1 = #set0_256(); 8 | 9 | t0 = #VPERMD(t0, t1); 10 | t0 = #VPERMD(t0, [:u256 tmp]); 11 | [:u256 tmp] = t0; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/examples/siphash/x86-64/makefile: -------------------------------------------------------------------------------- 1 | JASMINC ?= ../../../jasminc 2 | 3 | all: run 4 | ./run 5 | 6 | siphash.s: siphash.jazz 7 | $(JASMINC) -o $@ $< 8 | 9 | run: siphash.c siphash.s run.c 10 | $(CC) -O2 -o $@ $^ 11 | 12 | clean: 13 | rm -f run siphash.s 14 | -------------------------------------------------------------------------------- /compiler/syscall/jasmin_syscall.h: -------------------------------------------------------------------------------- 1 | #include 2 | #ifndef JASMIN_SYSCALL 3 | #define JASMIN_SYSCALL 4 | /* FIXME this need xlen to be Uptr */ 5 | uint8_t* __jasmin_syscall_randombytes__(uint8_t* x, uint64_t xlen) 6 | asm("__jasmin_syscall_randombytes__"); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /compiler/tests/fail/array_expansion/x86-64/index_out_of_bounds.jazz: -------------------------------------------------------------------------------- 1 | export fn main () -> reg u64 { 2 | reg u64[4] r; 3 | reg u64 res; 4 | 5 | inline int i; 6 | for i = 0 to 4 { 7 | r[i] = 0; 8 | } 9 | 10 | res = r[5]; 11 | 12 | return res; 13 | } 14 | -------------------------------------------------------------------------------- /compiler/tests/success/arm-m4/test_global_string_literal.jazz: -------------------------------------------------------------------------------- 1 | u8[10] test = "Teststring"; 2 | 3 | export fn main() -> reg u32 4 | { 5 | reg u32 res tmp; 6 | res = 0x54; 7 | 8 | tmp = (32u)test[0]; 9 | res = res ^ tmp; 10 | 11 | return res; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/examples/x86-64/threeway.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn threeway(reg u64 x) -> reg u64 { 3 | reg u64 r; 4 | reg bool below equal; 5 | ?{ " reg u64 { 2 | reg u64[4] r; 3 | reg u64 res; 4 | 5 | inline int i; 6 | for i = 0 to 4 { 7 | r[i] = 0; 8 | } 9 | 10 | res = (64u)r[:u8 0]; 11 | 12 | return res; 13 | } 14 | -------------------------------------------------------------------------------- /compiler/tests/success/subarrays/arm-m4/reg_ptr_const.jazz: -------------------------------------------------------------------------------- 1 | // sub-reg ptr with constant index 2 | 3 | export fn main (reg ptr u32[2] r) -> reg u32 { 4 | reg ptr u32[1] r2; 5 | reg u32 res; 6 | 7 | r2 = r[1:1]; // ADD 8 | res = r2[0]; 9 | 10 | return res; 11 | } 12 | -------------------------------------------------------------------------------- /compiler/tests/success/subarrays/x86-64/reg_ptr_const.jazz: -------------------------------------------------------------------------------- 1 | // sub-reg ptr with constant index 2 | 3 | export fn main (reg ptr u32[2] r) -> reg u32 { 4 | reg ptr u32[1] r2; 5 | reg u32 res; 6 | 7 | r2 = r[1:1]; // LEA 8 | res = r2[0]; 9 | 10 | return res; 11 | } 12 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/test_lea_sub.jazz: -------------------------------------------------------------------------------- 1 | param int n = 17; 2 | 3 | export fn f(reg u64 r1, reg u64 r2) -> reg u64 { 4 | reg u64 r; 5 | r1 = -3 + r1; 6 | r1 = 2*r1 - 10; 7 | r1 = r2 + 4 * r1 - 15; 8 | r1 = 2*r1 + - n; 9 | r = r1; 10 | return r; 11 | } 12 | -------------------------------------------------------------------------------- /compiler/examples/extraction-unit-tests/sdiv.jazz: -------------------------------------------------------------------------------- 1 | /* Extraction bug */ 2 | export fn main() -> reg u64, reg u64 { 3 | reg u64 a b c d e f; 4 | 5 | a = 1; 6 | b = -1; 7 | c = a /64s b; 8 | 9 | d = -4; 10 | e = 3; 11 | f = d %64s e; 12 | 13 | return c, f; 14 | } 15 | -------------------------------------------------------------------------------- /compiler/tests/exec/inline-call.jazz: -------------------------------------------------------------------------------- 1 | require "../success/x86-64/inline_call_to_export.jazz" 2 | 3 | /* Inline call to an export function from an inline function. */ 4 | inline 5 | fn test() -> reg u64 { 6 | reg u64 a; 7 | #[inline] a = sum(42, 24); 8 | return a; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/tests/fail/slh/x86-64/function_kills_msf.jazz: -------------------------------------------------------------------------------- 1 | fn f(reg u64 msf) -> reg u64 { 2 | return msf; 3 | } 4 | 5 | export 6 | fn main(reg u64 x) { 7 | reg u64 msf; 8 | msf = #init_msf(); 9 | msf = f(msf); 10 | x = #protect(x, msf); 11 | [x] = 0; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/arm-m4/cannot_compute_address.jazz: -------------------------------------------------------------------------------- 1 | export fn main (reg ptr u32[2] r) -> reg u32 { 2 | stack ptr u32[1] sp; 3 | reg ptr u32[1] r1; 4 | reg u32 res; 5 | 6 | sp = r[1:1]; 7 | r1 = sp; 8 | res = r1[0]; 9 | 10 | return res; 11 | } 12 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/risc-v/cannot_compute_address.jazz: -------------------------------------------------------------------------------- 1 | export fn main (reg ptr u32[2] r) -> reg u32 { 2 | stack ptr u32[1] sp; 3 | reg ptr u32[1] r1; 4 | reg u32 res; 5 | 6 | sp = r[1:1]; 7 | r1 = sp; 8 | res = r1[0]; 9 | 10 | return res; 11 | } 12 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/condition_move_ptr.jazz: -------------------------------------------------------------------------------- 1 | export fn main (reg u64 x) -> reg u64 { 2 | reg ptr u64[1] r r1 r2; 3 | stack u64[1] s; 4 | s[0] = 0; 5 | r1 = s; r2 = s; 6 | r = (x==0) ? r1 : r2; 7 | reg u64 res = r[0]; 8 | return res; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/merge_same_var.jazz: -------------------------------------------------------------------------------- 1 | export fn main (reg u64 i) -> reg u64 { 2 | stack u64[2] s; 3 | reg ptr u64[1] r; 4 | reg u64 res; 5 | 6 | s[0] = 0; 7 | r = s[0:1]; 8 | s[i:1] = r; 9 | res = s[i]; 10 | 11 | return res; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/regions_not_equal_array.jazz: -------------------------------------------------------------------------------- 1 | export fn main (reg u64 i) -> reg u64 { 2 | stack u64[2] s; 3 | reg ptr u64[2] r; 4 | reg u64 res; 5 | 6 | s[0] = 0; 7 | r = s[i:2]; 8 | s = r; 9 | res = s[1]; 10 | 11 | return res; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/safety/fail/common/fail_land.jazz: -------------------------------------------------------------------------------- 1 | export fn BS2POLVECq(reg u32 b) 2 | { 3 | reg u32 tmp; 4 | 5 | b = 100; 6 | tmp = 0xfe; // 255 7 | b &= tmp; 8 | 9 | tmp = 1; 10 | if (b != 100){ 11 | while (true) { b += tmp; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /compiler/tests/safety/fail/common/fail_land2.jazz: -------------------------------------------------------------------------------- 1 | export fn BS2POLVECq(reg u32 b) 2 | { 3 | reg u32 tmp; 4 | tmp = 0xfff; // 4095 5 | b &= tmp; 6 | 7 | tmp = 4094; 8 | if (b > tmp){ 9 | tmp = 1; 10 | while (true) { b += tmp; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/safety/fail/x86-64/decompile_fail.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn test() { 3 | reg bool cf, zf ; 4 | reg u64 i, a; 5 | 6 | a = 17; 7 | (_, cf, _, _, zf) = #CMP_64(a, ((64u) 16)); 8 | // a > 16 9 | while ((! cf) && (! zf)) 10 | { 11 | i += 1; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/x86-64/decompile.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn test() { 3 | reg bool cf, zf ; 4 | reg u64 i, a; 5 | 6 | a = 16; 7 | (_, cf, _, _, zf) = #CMP_64(a, ((64u) 16)); 8 | // a > 16 9 | while ((! cf) && (! zf)) 10 | { 11 | i += 1; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/x86-64/div.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn test_large_div(reg u64 x y) -> reg u64 { 3 | x = x; 4 | y = y; 5 | reg u64 a b c q r; 6 | a = x & 0xff; 7 | b = y; 8 | c = 0x400; 9 | ?{RAX=q, RDX=r} = #DIV(a, b, c); 10 | q ^= r; 11 | return q; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/success/common/spill_pointer.jazz: -------------------------------------------------------------------------------- 1 | u32[1] C = {1}; 2 | 3 | export 4 | fn main() -> reg u32 5 | { 6 | reg ptr u32[1] Cp; 7 | stack ptr u32[1] Cps; 8 | reg u32 c; 9 | 10 | Cp = C; 11 | Cps = Cp; 12 | Cp = Cps; 13 | c = Cp[0]; 14 | return c; 15 | } 16 | -------------------------------------------------------------------------------- /compiler/tests/success/subarrays/risc-v/reg_ptr_const.jazz: -------------------------------------------------------------------------------- 1 | // sub-reg ptr with constant index 2 | 3 | export fn main (reg ptr u32[2] r) -> reg u32 { 4 | reg ptr u32[1] r2; 5 | reg u32 res; 6 | 7 | r2 = r[1:1]; // ADDI 8 | res = r2[0]; 9 | 10 | return res; 11 | } 12 | -------------------------------------------------------------------------------- /proofs/compiler/jasmin_compiler.v: -------------------------------------------------------------------------------- 1 | (** This module is meant as the minimal dependency of extracted code. *) 2 | Require compiler. 3 | Require psem_defs. 4 | Require arm_params. 5 | Require x86_params. 6 | Require riscv_params. 7 | Require sem_params_of_arch_extra. 8 | Require wint_int. 9 | -------------------------------------------------------------------------------- /compiler/src/pp_stack_alloc.mli: -------------------------------------------------------------------------------- 1 | val pp_region : debug:bool -> Format.formatter -> Stack_alloc.region -> unit 2 | val pp_symbolic_zone : debug:bool -> Format.formatter -> Stack_alloc.symbolic_zone -> unit 3 | val pp_sub_region : debug:bool -> Format.formatter -> Stack_alloc.sub_region -> unit 4 | -------------------------------------------------------------------------------- /compiler/tests/fail/array_expansion/x86-64/default_scale_lv_2.jazz: -------------------------------------------------------------------------------- 1 | export fn main () -> reg u64 { 2 | reg u64[4] r; 3 | reg u64 res; 4 | 5 | inline int i; 6 | for i = 0 to 4 { 7 | r[i] = 0; 8 | } 9 | 10 | r.[0] = 2; 11 | res = r[0]; 12 | 13 | return res; 14 | } 15 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/arm-m4/align2.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 pt) -> reg u32 { 3 | reg u32 tmp res i; 4 | 5 | res = 0; 6 | i = 0; 7 | while (i < 16) { 8 | tmp = [:u32 pt + 4*i]; 9 | res += tmp; 10 | i += 1; 11 | } 12 | 13 | return res; 14 | } 15 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/riscv/align2.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u32 pt) -> reg u32 { 3 | reg u32 tmp res i; 4 | 5 | res = 0; 6 | i = 0; 7 | while (i < 16) { 8 | tmp = [:u32 pt + 4*i]; 9 | res += tmp; 10 | i += 1; 11 | } 12 | 13 | return res; 14 | } 15 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/x86-64/align2.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u64 pt) -> reg u64 { 3 | reg u64 tmp res i; 4 | 5 | res = 0; 6 | i = 0; 7 | while (i < 16) { 8 | tmp = [:u64 pt + 8*i]; 9 | res += tmp; 10 | i += 1; 11 | } 12 | 13 | return res; 14 | } 15 | -------------------------------------------------------------------------------- /compiler/tests/success/arm-m4/cmove.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn cond_swap(reg u32 p q cond) { 3 | reg u32 a b c d; 4 | reg bool f; 5 | f = cond != 0; 6 | a = [p]; 7 | b = [q]; 8 | c = b; 9 | d = a; 10 | c = a if !f; 11 | d = b if !f; 12 | [p] = c; 13 | [q] = d; 14 | } 15 | -------------------------------------------------------------------------------- /compiler/tests/success/slh/x86-64/function_kills_msf_2.jazz: -------------------------------------------------------------------------------- 1 | fn f(reg u64 x) { 2 | [x] = x; 3 | } 4 | 5 | export fn main(reg u64 x r) -> reg u64 { 6 | reg u64 ms; 7 | ms = #init_msf(); 8 | f(x); 9 | r = #protect(r, ms); 10 | r = r; 11 | return r; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/success/subarrays/arm-m4/global_const.jazz: -------------------------------------------------------------------------------- 1 | // sub-global with constant index 2 | 3 | u32[2] g = {1, 2}; 4 | 5 | export fn main () -> reg u32 { 6 | reg ptr u32[1] r; 7 | reg u32 res; 8 | 9 | r = g[1:1]; // ADR 10 | res = r[0]; 11 | 12 | return res; 13 | } 14 | -------------------------------------------------------------------------------- /compiler/tests/success/subarrays/risc-v/global_const.jazz: -------------------------------------------------------------------------------- 1 | // sub-global with constant index 2 | 3 | u32[2] g = {1, 2}; 4 | 5 | export fn main () -> reg u32 { 6 | reg ptr u32[1] r; 7 | reg u32 res; 8 | 9 | r = g[1:1]; // LA 10 | res = r[0]; 11 | 12 | return res; 13 | } 14 | -------------------------------------------------------------------------------- /compiler/tests/success/subarrays/x86-64/global_const.jazz: -------------------------------------------------------------------------------- 1 | // sub-global with constant index 2 | 3 | u32[2] g = {1, 2}; 4 | 5 | export fn main () -> reg u32 { 6 | reg ptr u32[1] r; 7 | reg u32 res; 8 | 9 | r = g[1:1]; // LEA 10 | res = r[0]; 11 | 12 | return res; 13 | } 14 | -------------------------------------------------------------------------------- /changes/02-bugfix/1348-fix-warn-duplicate-glob-var.md: -------------------------------------------------------------------------------- 1 | - Warn as expected when defining two (global) variables with the same name in 2 | the same namespace 3 | ([PR 1348](https://github.com/jasmin-lang/jasmin/pull/1346); 4 | fixes [#1347](https://github.com/jasmin-lang/jasmin/issues/1347)). 5 | -------------------------------------------------------------------------------- /compiler/CCT/success/div.jazz: -------------------------------------------------------------------------------- 1 | #[ct="public -> public"] 2 | export fn add_div_mod(reg u32 x) -> reg u32 { 3 | reg u32 x1 x2 d q q1 r r1; 4 | x1 = x; x2 = x; 5 | d = 3; 6 | q = x1 / d; 7 | q1 = q; 8 | r = x2 % d; 9 | r = r1; 10 | r = r + q1; 11 | r = r; 12 | return r; 13 | } -------------------------------------------------------------------------------- /compiler/tests/fail/arm-m4/bug_1112.jazz: -------------------------------------------------------------------------------- 1 | param int N = 9; 2 | 3 | export fn main(reg u32 x) -> reg u32 { 4 | reg u32[N] r; 5 | inline int i; 6 | for i = 0 to N { r[i] = x; } 7 | for i = 0 to N { 8 | #[keep] 9 | ?{}, r[i] = #MULS(r[i], x); 10 | } 11 | return x; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/regions_not_equal_subarray.jazz: -------------------------------------------------------------------------------- 1 | export fn main (reg u64 i) -> reg u64 { 2 | stack u64[2] s; 3 | reg ptr u64[1] r; 4 | reg u64 res; 5 | 6 | s[0] = 0; 7 | r = s[i:1]; 8 | s[i+1:1] = r; 9 | res = s[1]; 10 | 11 | return res; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/x86-64/while_heur_flag.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn test() -> reg u64 { 3 | reg bool zf; 4 | reg u64 i, acc; 5 | 6 | i = 42; 7 | acc = 0; 8 | while 9 | { 10 | acc += i; 11 | ?{zf}, i = #DEC(i); 12 | 13 | } (!zf) 14 | 15 | return acc; 16 | } 17 | -------------------------------------------------------------------------------- /compiler/tests/success/arm-m4/conditions.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn test_conditions(reg u32 x y) -> reg u32 { 3 | reg bool eq neq; 4 | ?{ "==" = eq, "!=" = neq } = #CMP(x, y); 5 | 6 | reg u32 r; 7 | r = 0; 8 | r = x if eq; 9 | r = y if neq; 10 | 11 | r = r; 12 | return r; 13 | } 14 | -------------------------------------------------------------------------------- /compiler/tests/success/common/varalreadyset.jazz: -------------------------------------------------------------------------------- 1 | inline fn consume(reg u32 x) -> reg u32 { 2 | if x > 0 { 3 | x = 0; 4 | } 5 | return x; 6 | } 7 | 8 | export fn main(reg u32 a) -> reg u32, reg u32 { 9 | reg u32 x = a; 10 | reg u32 y = consume(x); 11 | return x, y; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/success/subarrays/arm-m4/reg_ptr_const_large.jazz: -------------------------------------------------------------------------------- 1 | // sub-reg ptr with large constant index 2 | 3 | export fn main (reg ptr u32[6000] r) -> reg u32 { 4 | reg ptr u32[1] r2; 5 | reg u32 res; 6 | 7 | r2 = r[5000:1]; 8 | res = r2[0]; 9 | 10 | return res; 11 | } 12 | -------------------------------------------------------------------------------- /compiler/tests/success/subarrays/arm-m4/stack_ptr.jazz: -------------------------------------------------------------------------------- 1 | // spill and unspill of reg ptr 2 | 3 | export fn main (reg ptr u32[2] r) -> reg u32 { 4 | stack ptr u32[2] s; 5 | reg u32 res; 6 | 7 | s = r; // STR 8 | r = s; // LDR 9 | 10 | res = r[0]; 11 | 12 | return res; 13 | } 14 | -------------------------------------------------------------------------------- /compiler/tests/success/subarrays/risc-v/reg_ptr_const_large.jazz: -------------------------------------------------------------------------------- 1 | // sub-reg ptr with large constant index 2 | 3 | export fn main (reg ptr u32[6000] r) -> reg u32 { 4 | reg ptr u32[1] r2; 5 | reg u32 res; 6 | 7 | r2 = r[5000:1]; 8 | res = r2[0]; 9 | 10 | return res; 11 | } 12 | -------------------------------------------------------------------------------- /compiler/tests/success/subarrays/x86-64/stack_ptr.jazz: -------------------------------------------------------------------------------- 1 | // spill and unspill of reg ptr 2 | 3 | export fn main (reg ptr u32[2] r) -> reg u32 { 4 | stack ptr u32[2] s; 5 | reg u32 res; 6 | 7 | s = r; // MOV 8 | r = s; // MOV 9 | 10 | res = r[0]; 11 | 12 | return res; 13 | } 14 | -------------------------------------------------------------------------------- /compiler/tests/success/subroutines/x86-64/global.jazz: -------------------------------------------------------------------------------- 1 | u64[2] glob = { 1, 2}; 2 | 3 | inline 4 | fn load(stack u64[2] p) -> reg u64 { 5 | reg u64 r; 6 | r = p[0]; 7 | return r; 8 | } 9 | 10 | export 11 | fn test() -> reg u64 { 12 | reg u64 x; 13 | x = load(glob); 14 | return x; 15 | } 16 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/bswap.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn f(reg u32 a) -> reg u32 { 3 | reg u32 b, c; 4 | b = a; 5 | c = #BSWAP_32(b); 6 | return c; 7 | } 8 | 9 | export 10 | fn g(reg u64 p) { 11 | reg u64 a, b; 12 | a = [p + 0]; 13 | b = #BSWAP(a); 14 | [p + 8] = b; 15 | } 16 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/bug_340.jazz: -------------------------------------------------------------------------------- 1 | inline fn xor(reg u256 a b) -> reg u256 { 2 | reg u256 c; 3 | c = a ^ b; 4 | return c; 5 | } 6 | 7 | export 8 | fn main(reg u256 x) -> reg u256 { 9 | reg u256[1] a; 10 | a[0] = x; 11 | x = xor(a[0], a[0]); 12 | return x; 13 | } 14 | -------------------------------------------------------------------------------- /compiler/uint63/native/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name uint63_native) 3 | (public_name jasmin.uint63-native) 4 | (implements jasmin.uint63)) 5 | 6 | (rule 7 | (targets uint63.ml) 8 | (deps (:gen-file ../uint63_%{ocaml-config:int_size}.ml)) 9 | (action (copy# %{gen-file} %{targets}))) 10 | -------------------------------------------------------------------------------- /compiler/tests/fail/slh/x86-64/function_needs_msf.jazz: -------------------------------------------------------------------------------- 1 | fn my_protect(reg u64 x msf) -> reg u64 { 2 | x = #protect(x, msf); 3 | return x; 4 | } 5 | 6 | export 7 | fn main(reg u64 x) { 8 | reg u64 msf; 9 | 10 | msf = 0; 11 | x = my_protect(x, msf); 12 | [x] = 0; 13 | } 14 | -------------------------------------------------------------------------------- /compiler/tests/fail/slh/x86-64/if_wrong_update.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main() -> reg u64 { 3 | reg u64 msf; 4 | 5 | msf = #init_msf(); 6 | 7 | inline bool b; 8 | b = msf == 0; 9 | if (b) { 10 | msf = #update_msf(!b, msf); 11 | } 12 | 13 | return msf; 14 | } 15 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/arm-m4/bounded_while.jazz: -------------------------------------------------------------------------------- 1 | param int N = 4; 2 | 3 | export 4 | fn test() -> reg u32 { 5 | stack u32[N] t; 6 | reg u32 i; 7 | i = 0; 8 | #[bounded] 9 | while (i < N) { 10 | t[i] = i; 11 | i += 1; 12 | } 13 | i = t[N/2]; 14 | return i; 15 | } 16 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/riscv/bounded_while.jazz: -------------------------------------------------------------------------------- 1 | param int N = 4; 2 | 3 | export 4 | fn test() -> reg u32 { 5 | stack u32[N] t; 6 | reg u32 i; 7 | i = 0; 8 | #[bounded] 9 | while (i < N) { 10 | t[i] = i; 11 | i += 1; 12 | } 13 | i = t[N/2]; 14 | return i; 15 | } 16 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/x86-64/bounded_while.jazz: -------------------------------------------------------------------------------- 1 | param int N = 4; 2 | 3 | export 4 | fn test() -> reg u64 { 5 | stack u64[N] t; 6 | reg u64 i; 7 | i = 0; 8 | #[bounded] 9 | while (i < N) { 10 | t[i] = i; 11 | i += 1; 12 | } 13 | i = t[N/2]; 14 | return i; 15 | } 16 | -------------------------------------------------------------------------------- /compiler/tests/success/arm-m4/bug_1112.jazz: -------------------------------------------------------------------------------- 1 | param int N = 7; 2 | 3 | export fn main(reg u32 x) -> reg u32 { 4 | reg u32[N] r; 5 | inline int i; 6 | for i = 0 to N { r[i] = x; } 7 | for i = 0 to N { 8 | #[keep] 9 | ?{}, r[i] = #MULS(r[i], x); 10 | } 11 | return x; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/success/pointers/x86-64/zerofill.jazz: -------------------------------------------------------------------------------- 1 | fn zerofill(reg mut ptr u64[1] x) -> reg ptr u64[1] { 2 | x[0] = 0; 3 | return x; 4 | } 5 | 6 | export 7 | fn main() -> reg u64 { 8 | stack u64[1] s; 9 | s = zerofill(s); 10 | reg u64 r; 11 | r = s[0]; 12 | return r; 13 | } 14 | -------------------------------------------------------------------------------- /compiler/tests/success/slh/x86-64/function_kills_msf_1.jazz: -------------------------------------------------------------------------------- 1 | fn f() { 2 | reg u64 x; 3 | x = 0; 4 | if (x == 0) {} 5 | } 6 | 7 | export 8 | fn main(reg u64 x) { 9 | reg u64 msf; 10 | msf = #init_msf(); 11 | f(); 12 | x = #protect(x, msf); 13 | [x] = 0; 14 | } 15 | -------------------------------------------------------------------------------- /compiler/tests/success/subarrays/risc-v/stack_ptr.jazz: -------------------------------------------------------------------------------- 1 | // spill and unspill of reg ptr 2 | 3 | export fn main (reg ptr u32[2] r) -> reg u32 { 4 | stack ptr u32[2] s; 5 | reg u32 res; 6 | 7 | s = r; // STORE 8 | r = s; // LOAD 9 | 10 | res = r[0]; 11 | 12 | return res; 13 | } 14 | -------------------------------------------------------------------------------- /compiler/CCT/fail/doc_bad_call.jazz: -------------------------------------------------------------------------------- 1 | #[ct = "secret × public -> secret"] 2 | fn add_SP(reg u64 x, reg u64 y) -> reg u64 { 3 | reg u64 t; 4 | t = x + y; 5 | return t; 6 | } 7 | 8 | #[ct = "secret -> secret"] 9 | fn bad_call(reg u64 x) -> reg u64 { 10 | x = add_SP(x, x); 11 | return x; 12 | } -------------------------------------------------------------------------------- /compiler/CCT/fail/doit/x86_64/xchg.jazz: -------------------------------------------------------------------------------- 1 | // This is CT in the ordinary sense, but not DOIT as XCHG is not DOIT. 2 | #[ct="secret * secret -> secret * secret"] 3 | export fn xchange(reg u32 a, reg u32 b) -> reg u32, reg u32 { 4 | a = a; 5 | b = b; 6 | a, b = #swap(a, b); 7 | return a, b; 8 | } 9 | -------------------------------------------------------------------------------- /compiler/examples/x86-64/test_var_alloc2.jazz: -------------------------------------------------------------------------------- 1 | export fn test () -> reg u64 2 | { 3 | reg u64 x1; 4 | reg u64 x2; 5 | 6 | x1 = 0; 7 | x2 = 1; 8 | _, x1 += x2; 9 | // x2 = x1; 10 | x2 = #LEA(x1 + 1); 11 | x2 += x1; 12 | return x2; 13 | } 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /compiler/tests/fail/array_expansion/x86-64/array_param_not_reg.jazz: -------------------------------------------------------------------------------- 1 | fn f (reg u64[4] r) -> reg u64 { 2 | reg u64 res; 3 | res = r[0]; 4 | return res; 5 | } 6 | 7 | export fn main () -> reg u64 { 8 | stack u64[4] s; 9 | reg u64 res; 10 | 11 | res = f(s); 12 | 13 | return res; 14 | } 15 | -------------------------------------------------------------------------------- /compiler/tests/fail/array_expansion/x86-64/bug_333.jazz: -------------------------------------------------------------------------------- 1 | inline 2 | fn bar(reg u64 o, reg u256 v) { 3 | [:u256 o] = v; 4 | } 5 | 6 | export 7 | fn foo(reg u64 o) { 8 | inline int i; 9 | reg u256[8] v; 10 | 11 | for i = 0 to 11 { 12 | bar(o, v[i]); 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /compiler/tests/fail/array_expansion/x86-64/index_not_constant.jazz: -------------------------------------------------------------------------------- 1 | export fn main () -> reg u64 { 2 | reg u64[4] r; 3 | reg u64 res; 4 | 5 | inline int i; 6 | for i = 0 to 4 { 7 | r[i] = 0; 8 | } 9 | 10 | reg u64 j; 11 | j = 0; 12 | res = r[j]; 13 | 14 | return res; 15 | } 16 | -------------------------------------------------------------------------------- /compiler/tests/fail/array_expansion/x86-64/type_mismatch_param.jazz: -------------------------------------------------------------------------------- 1 | fn f (reg u64[4] r) -> reg u64 { 2 | reg u64 res; 3 | res = r[0]; 4 | return res; 5 | } 6 | 7 | export fn main () -> reg u64 { 8 | reg u32[8] r; 9 | reg u64 res; 10 | 11 | res = f(r); 12 | 13 | return res; 14 | } 15 | -------------------------------------------------------------------------------- /compiler/tests/fail/slh/x86-64/while_wrong_update.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main() -> reg u64 { 3 | reg u64 msf; 4 | 5 | msf = #init_msf(); 6 | 7 | inline bool b; 8 | b = msf == 0; 9 | while (b) { 10 | msf = #update_msf(!b, msf); 11 | } 12 | 13 | return msf; 14 | } 15 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/protect_ptr_arg.jazz: -------------------------------------------------------------------------------- 1 | export fn main () -> reg u64 { 2 | stack u64[1] s; 3 | reg ptr u64[1] r; 4 | reg u64 msf; 5 | 6 | msf = #init_msf(); 7 | s[0] = 0; 8 | r = #protect_ptr(s, msf); 9 | 10 | reg u64 res = r[0]; 11 | return res; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/pending/x86-64/cmoveptr.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn test(reg u64 a) -> reg u8 { 3 | stack u8[2] s; 4 | reg ptr u8[1] p q r; 5 | reg u8 f; 6 | s[0] = 0; 7 | s[1] = 1; 8 | p = s[0:1]; 9 | q = s[1:1]; 10 | r = p; 11 | r = q if a reg u64 { 2 | reg u64 z; 3 | reg u64 x = 0; 4 | stack u64[2] t; 5 | inline int i; 6 | for i = 0 to 2 { 7 | t[x] = 0; /* leak x */ 8 | x = secret; 9 | } 10 | z = t[0]; 11 | return z; 12 | } -------------------------------------------------------------------------------- /compiler/tests/success/common/test_type_eq.jazz: -------------------------------------------------------------------------------- 1 | param int n = 1; 2 | 3 | inline 4 | fn f(reg u32[n] x) -> reg u32[n] { return x; } 5 | export 6 | fn g() -> reg u32 { 7 | reg u32[n] a; 8 | reg u32[n] b; 9 | b[0] = 0; 10 | a = #copy_32(b); 11 | b = f(a); 12 | reg u32 r = b[0]; 13 | return r; 14 | } 15 | -------------------------------------------------------------------------------- /compiler/tests/success/namespaces/common/export.jazz: -------------------------------------------------------------------------------- 1 | namespace a { 2 | export fn main(reg u32 x) -> reg u32 { 3 | x = x; 4 | return x; 5 | } 6 | } 7 | 8 | namespace b { 9 | export fn main(reg u32 x y) -> reg u32 { 10 | x = x; 11 | x += y; 12 | return x; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /compiler/tests/success/subarrays/x86-64/align2.jazz: -------------------------------------------------------------------------------- 1 | export fn main (reg u64 i) -> reg u32 { 2 | stack u64[20] s; 3 | reg ptr u8[8] r; 4 | reg u32 res; 5 | 6 | s[:u32 0] = 0; 7 | r = s[i:1]; 8 | r[:u64 0] = 1; 9 | s[i:1] = r; 10 | 11 | res = s[:u32 0]; 12 | return res; 13 | } 14 | -------------------------------------------------------------------------------- /compiler/tests/success/subarrays/x86-64/reg_ptr_scaled.jazz: -------------------------------------------------------------------------------- 1 | // sub-reg ptr with variable index (scaled) 2 | 3 | export fn main (reg ptr u32[2] r, reg u64 i) -> reg u32 { 4 | reg ptr u32[1] r2; 5 | reg u32 res; 6 | 7 | r2 = r[i:1]; // LEA 8 | res = r2[0]; 9 | 10 | return res; 11 | } 12 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/ifelse.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn test(reg u64 x, reg u64 y) -> reg u64 { 3 | reg u64 result; 4 | if x != 0 { 5 | result = x; 6 | } else if y != 0 { 7 | result = y; 8 | } else { 9 | result = 0; 10 | } 11 | return result; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/truncate_if.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn a(reg u64 x y) -> reg u32 { 3 | reg u32 z; 4 | z = x; 5 | z = y reg u32 { 11 | reg u32 z; 12 | z = x; 13 | z = x if y reg u8 { 5 | reg u8 r; 6 | #[inline] r = test(42); 7 | return r; 8 | } 9 | 10 | inline 11 | fn one() -> reg u8 { 12 | reg u8 r; 13 | #[inline] r = test(-42); 14 | return r; 15 | } 16 | -------------------------------------------------------------------------------- /compiler/tests/fail/array_expansion/x86-64/default_scale_param.jazz: -------------------------------------------------------------------------------- 1 | fn f (reg u64[4] r) -> reg u64 { 2 | reg u64 res; 3 | res = r[0]; 4 | return res; 5 | } 6 | 7 | export fn main () -> reg u64 { 8 | reg u64[4] r; 9 | reg u64 res; 10 | 11 | res = f(r.[0:4]); 12 | 13 | return res; 14 | } 15 | -------------------------------------------------------------------------------- /compiler/tests/fail/x86-64/unaligned_slice_copy.jazz: -------------------------------------------------------------------------------- 1 | // Cannot copy by chunks of 4 bytes starting at offset 3 bytes 2 | export fn main() -> reg u32 { 3 | stack u8[8] s; 4 | s[:u64 0] = 0; 5 | stack u32[1] d; 6 | d = #copy_32(s[3:4]); 7 | reg u32 r; 8 | r = d[0]; 9 | return r; 10 | } 11 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/arm-m4/loop1.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn poly1305(reg u32 in, reg u32 inlen) -> reg u32 { 3 | reg u8 tmp; 4 | reg u32 r; 5 | 6 | r = 0; 7 | 8 | while (inlen > 0 ) { 9 | tmp = [:u8 in + 0]; 10 | in += 1; 11 | inlen -= 1; 12 | } 13 | 14 | return r; 15 | } 16 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/riscv/loop1.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn poly1305(reg u32 in, reg u32 inlen) -> reg u32 { 3 | reg u8 tmp; 4 | reg u32 r; 5 | 6 | r = 0; 7 | 8 | while (inlen > 0 ) { 9 | tmp = [:u8 in + 0]; 10 | in += 1; 11 | inlen -= 1; 12 | } 13 | 14 | return r; 15 | } 16 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/x86-64/loop1.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn poly1305(reg u64 in, reg u64 inlen) -> reg u64 { 3 | reg u8 tmp; 4 | reg u64 r; 5 | 6 | r = 0; 7 | 8 | while (inlen > 0 ) { 9 | tmp = [:u8 in + 0]; 10 | in += 1; 11 | inlen -= 1; 12 | } 13 | 14 | return r; 15 | } 16 | -------------------------------------------------------------------------------- /compiler/tests/success/arm-m4/intrinsic_bfc.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn bfc(reg u32 x) -> reg u32 { 3 | x = #BFC(x, 0, 1); 4 | x = #BFC(x, 31, 1); 5 | x = #BFC(x, 0, 32); 6 | 7 | reg bool b; 8 | ?{ " reg u32 3 | */ 4 | fn map(reg ptr u32[4] p) -> reg ptr u32[4] { 5 | inline int i; 6 | for i = 0 to 4 { 7 | reg u32 t; 8 | t = p[i]; 9 | t = f(t); 10 | p[i] = t; 11 | } 12 | return p; 13 | } 14 | -------------------------------------------------------------------------------- /compiler/tests/success/subarrays/arm-m4/reg_ptr_unscaled.jazz: -------------------------------------------------------------------------------- 1 | // sub-reg ptr with variable index (unscaled) 2 | 3 | export fn main (reg ptr u32[2] r, reg u32 i) -> reg u32 { 4 | reg ptr u32[1] r2; 5 | reg u32 res; 6 | 7 | r2 = r.[i:1]; // ADD 8 | res = r2.[0]; 9 | 10 | return res; 11 | } 12 | -------------------------------------------------------------------------------- /compiler/tests/success/subarrays/risc-v/reg_ptr_unscaled.jazz: -------------------------------------------------------------------------------- 1 | // sub-reg ptr with variable index (unscaled) 2 | 3 | export fn main (reg ptr u32[2] r, reg u32 i) -> reg u32 { 4 | reg ptr u32[1] r2; 5 | reg u32 res; 6 | 7 | r2 = r.[i:1]; // ADD 8 | res = r2.[0]; 9 | 10 | return res; 11 | } 12 | -------------------------------------------------------------------------------- /compiler/tests/success/subarrays/x86-64/reg_ptr_unscaled.jazz: -------------------------------------------------------------------------------- 1 | // sub-reg ptr with variable index (unscaled) 2 | 3 | export fn main (reg ptr u32[2] r, reg u64 i) -> reg u32 { 4 | reg ptr u32[1] r2; 5 | reg u32 res; 6 | 7 | r2 = r.[i:1]; // LEA 8 | res = r2.[0]; 9 | 10 | return res; 11 | } 12 | -------------------------------------------------------------------------------- /compiler/linter/Checker/DeadVariables.mli: -------------------------------------------------------------------------------- 1 | 2 | 3 | open LivenessAnalyser 4 | open Annotation 5 | 6 | (** 7 | Dead Variable Checker : 8 | This module check if an affected variable is used in the program. 9 | *) 10 | val check_prog : (domain annotation, 'asm) Jasmin.Prog.prog -> CompileError.t list 11 | -------------------------------------------------------------------------------- /compiler/scripts/replace-new-memory-syntax-sedscript: -------------------------------------------------------------------------------- 1 | s/( *\(u[0-9]*\) *) *\[ *#aligned/[#aligned:\1/g 2 | s/( *\(u[0-9]*\) *) *\[ *#unaligned/[#unaligned:\1/g 3 | s/( *\(u[0-9]*\) *) *\[/[:\1 /g 4 | s/\[ *#aligned *\(u[0-9]*\)/[#aligned:\1/g 5 | s/\[ *#unaligned *\(u[0-9]*\)/[#unaligned:\1/g 6 | s/\[ *\(u[0-9]*\)/[:\1/g -------------------------------------------------------------------------------- /compiler/tests/fail/array_expansion/x86-64/default_scale_lv.jazz: -------------------------------------------------------------------------------- 1 | export fn main () -> reg u64 { 2 | reg u64[4] r; 3 | reg u64 res; 4 | 5 | inline int i; 6 | for i = 0 to 4 { 7 | r[i] = 0; 8 | } 9 | 10 | r[:u32 0] = 2; 11 | r[:u32 1] = 1; 12 | res = r[0]; 13 | 14 | return res; 15 | } 16 | -------------------------------------------------------------------------------- /compiler/tests/fail/array_expansion/x86-64/sub_array_param_not_reg.jazz: -------------------------------------------------------------------------------- 1 | fn f (reg u64[4] r) -> reg u64 { 2 | reg u64 res; 3 | res = r[0]; 4 | return res; 5 | } 6 | 7 | export fn main () -> reg u64 { 8 | stack u64[4] s; 9 | reg u64 res; 10 | 11 | res = f(s[0:4]); 12 | 13 | return res; 14 | } 15 | -------------------------------------------------------------------------------- /compiler/tests/fail/array_expansion/x86-64/type_mismatch_param_sub.jazz: -------------------------------------------------------------------------------- 1 | fn f (reg u64[4] r) -> reg u64 { 2 | reg u64 res; 3 | res = r[0]; 4 | return res; 5 | } 6 | 7 | export fn main () -> reg u64 { 8 | reg u32[8] r; 9 | reg u64 res; 10 | 11 | res = f(r[0:8]); 12 | 13 | return res; 14 | } 15 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/x86-64/bug_314.jazz: -------------------------------------------------------------------------------- 1 | inline fn f(reg u32 i) { 2 | reg bool zf; 3 | while { 4 | _,_,_,zf,i = #DEC_32(i); 5 | } (!zf) 6 | } 7 | 8 | inline fn g() { 9 | reg u32 i; 10 | i = 42; 11 | f(2); 12 | } 13 | 14 | export fn test1() { g(); } 15 | export fn test2() { g(); } 16 | -------------------------------------------------------------------------------- /compiler/tests/success/common/cast_int.jazz: -------------------------------------------------------------------------------- 1 | inline 2 | fn test() -> inline int 3 | { 4 | inline int i j; 5 | i = 0; 6 | j = 1 << i; 7 | return j; 8 | } 9 | 10 | export 11 | fn main() -> reg u32 { 12 | reg u32 n; 13 | inline int k; 14 | k = test(); 15 | n = k; 16 | return n; 17 | } 18 | -------------------------------------------------------------------------------- /compiler/tests/success/slh/x86-64/spill_mmx.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u64 x) -> reg u64 { 3 | reg u64 ms; 4 | ms = #init_msf(); 5 | 6 | #[mmx] reg u64 _ms; 7 | _ms = #mov_msf(ms); 8 | 9 | ms = #mov_msf(_ms); 10 | 11 | x = #protect(x, ms); 12 | x = x; 13 | return x; 14 | } 15 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/test_lnot.jazz: -------------------------------------------------------------------------------- 1 | param int n = 17; 2 | 3 | export fn f(reg u64 r1) -> reg u64, reg u64 { 4 | reg u64 r = r1; 5 | r1 = !r; 6 | r = !n; 7 | return r1, r; 8 | } 9 | 10 | export fn g(reg u64 r1) -> reg u64 { 11 | reg u64 r; 12 | r = r1; 13 | r = !r; 14 | return r; 15 | } 16 | -------------------------------------------------------------------------------- /compiler/CCT/fail/secret_ptr.jazz: -------------------------------------------------------------------------------- 1 | #[ct="secret -> secret"] 2 | export 3 | fn pointers(reg u64 a) -> reg u8 { 4 | stack u8[2] s; 5 | reg ptr u8[1] p q r; 6 | reg u8 f; 7 | p = s[0:1]; 8 | q = s[1:1]; 9 | r = p; 10 | r = q if a 3 | Wsize.wsize -> 4 | ('reg, 'regx, 'xreg, 'rflag, 'cond, 'asm_op, 'extra_op) Arch_extra.extended_op Sopn.asmOp -> 5 | Format.formatter -> 6 | ('reg, 'regx, 'xreg, 'rflag, 'cond, 'asm_op, 'extra_op) Arch_extra.extended_op Linear.lprog -> 7 | unit 8 | -------------------------------------------------------------------------------- /compiler/tests/fail/register_allocation/x86-64/bug_310.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn test(reg u64 x y) -> reg u64 { 3 | reg u64 r; 4 | r = y; 5 | reg bool valid; 6 | if x > 56 { 7 | valid = true; 8 | } else { 9 | valid = false; 10 | } 11 | if valid { 12 | r = x; 13 | } 14 | return r; 15 | } 16 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/protect_ptr_res.jazz: -------------------------------------------------------------------------------- 1 | export fn main () -> reg u64 { 2 | stack u64[1] s; 3 | reg ptr u64[1] r; 4 | reg u64 msf; 5 | 6 | msf = #init_msf(); 7 | s[0] = 0; 8 | r = s; 9 | s = #protect_ptr(r, msf); 10 | 11 | reg u64 res = s[0]; 12 | return res; 13 | } 14 | -------------------------------------------------------------------------------- /compiler/tests/success/common/bug_871.jazz: -------------------------------------------------------------------------------- 1 | inline fn get(inline u32 i) -> reg u32 { 2 | reg u32 r; 3 | global u32 g; 4 | g = i; 5 | r = g; 6 | return r; 7 | } 8 | 9 | export 10 | fn main() -> reg u32 { 11 | reg u32 a b; 12 | a = get(0xa); 13 | b = get(0xb); 14 | b += a; 15 | return b; 16 | } 17 | -------------------------------------------------------------------------------- /compiler/tests/success/subarrays/x86-64/index_var.jazz: -------------------------------------------------------------------------------- 1 | // checks that using a variable as index in a subarray is ok 2 | export fn main (reg u64 i) -> reg u64 { 3 | stack u64[4] s; 4 | reg ptr u64[1] r; 5 | reg u64 res; 6 | 7 | s[i] = 0; 8 | r = s[i:1]; 9 | res = r[0]; 10 | 11 | return res; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/success/subroutines/x86-64/memptr.jazz: -------------------------------------------------------------------------------- 1 | fn load (reg u64 p) -> reg u64 { 2 | reg u64 x; 3 | x = [p]; 4 | return x; 5 | } 6 | 7 | export 8 | fn main(reg u64 cptr) -> reg u64 { 9 | reg u64 tmp result; 10 | tmp = cptr; 11 | result = load(tmp); 12 | result += tmp; 13 | return result; 14 | } -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/set0_through_pointer.jazz: -------------------------------------------------------------------------------- 1 | /* This should not use XOR to compute 0, even if the command-line flag -set0 is given */ 2 | export 3 | fn zero() -> reg u64 { 4 | stack u64[1] s; 5 | reg u64 r; 6 | reg ptr u64[1] p; 7 | p = s; 8 | p[0] = 0; 9 | r = p[0]; 10 | return r; 11 | } 12 | -------------------------------------------------------------------------------- /compiler/tests/fail/register_allocation/arm-m4/too_many_ret.jazz: -------------------------------------------------------------------------------- 1 | /* This fails early with a type error, the error in regalloc cannot be 2 | triggered. */ 3 | 4 | export 5 | fn too_many_ret() -> reg u32, reg u32, reg u32 { 6 | reg u32 x y z; 7 | x = 0; 8 | y = 1; 9 | z = 2; 10 | return x, y, z; 11 | } 12 | -------------------------------------------------------------------------------- /compiler/tests/fail/register_allocation/x86-64/bug_523.jazz: -------------------------------------------------------------------------------- 1 | export fn main () -> reg u64 { 2 | reg u64 res; 3 | reg u64 rot1 rot2; 4 | 5 | res = 0; 6 | rot1 = 0; 7 | rot2 = 0; 8 | res < reg u64, reg u64, reg u64 { 6 | reg u64 x y z; 7 | x = 0; 8 | y = 1; 9 | z = 2; 10 | return x, y, z; 11 | } 12 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/x86-64/align.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u64 pt) -> reg u64 { 3 | reg u64 tmp; 4 | stack u256 tmp256; 5 | 6 | tmp = [:u64 pt + 0]; 7 | tmp = [:u64 pt + 8]; 8 | tmp = [:u64 pt + 24]; 9 | 10 | tmp256 = [:u256 pt + 0]; 11 | tmp256 = [:u256 pt + 32]; 12 | return tmp; 13 | } 14 | -------------------------------------------------------------------------------- /compiler/tests/success/subarrays/arm-m4/reg_ptr_scaled.jazz: -------------------------------------------------------------------------------- 1 | // sub-reg ptr with variable index (scaled) 2 | 3 | export fn main (reg ptr u32[2] r, reg u32 i) -> reg u32 { 4 | reg ptr u32[1] r2; 5 | reg u32 res; 6 | 7 | r2 = r[i:1]; // ADD with shift of operand 8 | res = r2[0]; 9 | 10 | return res; 11 | } 12 | -------------------------------------------------------------------------------- /compiler/tests/success/subroutines/x86-64/loop.jazz: -------------------------------------------------------------------------------- 1 | fn aux(reg u64 x) -> reg u64 { return x; } 2 | 3 | export 4 | fn main(reg u64 x) -> reg u64 { 5 | reg u64 result; 6 | 7 | result = x; 8 | 9 | while { result = aux(result); } (x > 0) { 10 | result = aux(result); 11 | x -= 1; 12 | } 13 | 14 | return result; 15 | } 16 | -------------------------------------------------------------------------------- /compiler/tests/success/subroutines/x86-64/substack.jazz: -------------------------------------------------------------------------------- 1 | fn double(reg u64 x) -> reg u64 { 2 | stack u64 y; 3 | y = x; 4 | x += y; 5 | return x; 6 | } 7 | 8 | export 9 | fn main(reg u64 x) -> reg u64 { 10 | reg u64 r; 11 | 12 | r = x; 13 | r = double(r); 14 | r = double(r); 15 | 16 | return r; 17 | } -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/bug_455.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u64 y) { 3 | reg u64 x; 4 | 5 | // Commenting either of the following two lines makes compilation succeed. 6 | x = #MOV(y); // Using x = y; makes compilation succeed. 7 | x = 1; 8 | 9 | x = y if x == 0; 10 | [x] = x; 11 | } 12 | -------------------------------------------------------------------------------- /compiler/examples/x86-64/memcmp.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn memcmp(reg u64 p, reg u64 q, reg u64 n) -> reg u64 { 3 | reg u64 r, z, i, a, b; 4 | r = 1; 5 | i = 0; 6 | while (i < n) { 7 | a = [p + 0]; 8 | b = [q + 0]; 9 | z = 0; 10 | r = z if a != b; 11 | 12 | p += 8; 13 | q += 8; 14 | i += 1; 15 | } 16 | return r; 17 | } 18 | -------------------------------------------------------------------------------- /compiler/tests/safety/fail/x86-64/mul0.jazz: -------------------------------------------------------------------------------- 1 | // Simple checks that lower bits of multiplications are computed. 2 | export fn addNumber() { 3 | reg u64 r; 4 | reg u64 A B; 5 | 6 | A = 2; 7 | B = 22; 8 | 9 | _,_,_,_,_,_,r = #IMUL_64 (A, B); 10 | 11 | if (r != 42){ 12 | while (true) { A = 1; } 13 | } 14 | } -------------------------------------------------------------------------------- /compiler/tests/sct-checker/success/conditional-expr.jazz: -------------------------------------------------------------------------------- 1 | #[sct=" 2 | secret * 3 | { ptr: public, val: public } * 4 | { ptr: public, val: public } -> 5 | { ptr: secret, val: secret }"] 6 | fn leak_cond(reg u64 sec, reg ptr u64[1] x y) -> reg ptr u64[1] { 7 | x = sec == 0 ? x : y; 8 | return x; 9 | } 10 | -------------------------------------------------------------------------------- /compiler/tests/success/subarrays/arm-m4/reg_ptr_const_zero.jazz: -------------------------------------------------------------------------------- 1 | // sub-reg ptr with constant index 0 2 | 3 | export fn main (reg ptr u32[2] r) -> reg u32 { 4 | reg ptr u32[1] r2; 5 | reg u32 tmp res; 6 | 7 | r2 = r[0:1]; // MOV 8 | tmp = r[0]; 9 | res = r2[0]; 10 | res += tmp; 11 | 12 | return res; 13 | } 14 | -------------------------------------------------------------------------------- /compiler/tests/success/subarrays/risc-v/reg_ptr_const_zero.jazz: -------------------------------------------------------------------------------- 1 | // sub-reg ptr with constant index 0 2 | 3 | export fn main (reg ptr u32[2] r) -> reg u32 { 4 | reg ptr u32[1] r2; 5 | reg u32 tmp res; 6 | 7 | r2 = r[0:1]; // MV 8 | tmp = r[0]; 9 | res = r2[0]; 10 | res += tmp; 11 | 12 | return res; 13 | } 14 | -------------------------------------------------------------------------------- /compiler/tests/success/subarrays/x86-64/reg_ptr_const_zero.jazz: -------------------------------------------------------------------------------- 1 | // sub-reg ptr with constant index 0 2 | 3 | export fn main (reg ptr u32[2] r) -> reg u32 { 4 | reg ptr u32[1] r2; 5 | reg u32 tmp res; 6 | 7 | r2 = r[0:1]; // MOV 8 | tmp = r[0]; 9 | res = r2[0]; 10 | res += tmp; 11 | 12 | return res; 13 | } 14 | -------------------------------------------------------------------------------- /changes/03-other/1355-optional-empty-lvals.md: -------------------------------------------------------------------------------- 1 | - When an intrinsic operator does not return any result, the equal sign and the 2 | empty list of L-values can be omitted (e.g., it is now possible to write 3 | instructions such as `#LFENCE();` or `#spill(x);`) 4 | ([PR #1355](https://github.com/jasmin-lang/jasmin/pull/1355)). 5 | 6 | -------------------------------------------------------------------------------- /compiler/examples/gimli/x86-64/test.exp: -------------------------------------------------------------------------------- 1 | 00000000 9e3779ba 3c6ef37a daa66d46 2 | 78dde724 1715611a b54cdb2e 53845566 3 | f1bbcfc8 8ff34a5a 2e2ac522 cc624026 4 | ---------------------- 5 | ba11c85a 91bad119 380ce880 d24c2c68 6 | 3eceffea 277a921c 4f73a0bd da5a9cd8 7 | 84b673f0 34e52ff7 9e2bef49 f41bb8d6 8 | ---------------------- 9 | -------------------------------------------------------------------------------- /compiler/tests/success/subarrays/x86-64/nested.jazz: -------------------------------------------------------------------------------- 1 | export fn main () -> reg u64 { 2 | reg u64 res; 3 | stack u64[4] s; 4 | reg ptr u64[3] r1; 5 | reg ptr u64[2] r2; 6 | 7 | r1 = s[1:3]; 8 | r2 = r1[1:2]; 9 | r2[0] = 2; 10 | r1[1:2] = r2; 11 | s[1:3] = r1; 12 | 13 | res = s[2]; 14 | return res; 15 | } 16 | -------------------------------------------------------------------------------- /compiler/tests/fail/pointers/x86-64/test_writable_arguments.jazz: -------------------------------------------------------------------------------- 1 | fn f(reg ptr u64[1] t) -> reg ptr u64[1] { 2 | t[0] = 1; 3 | return t; 4 | } 5 | 6 | export fn gfail() -> reg u64{ 7 | stack u64[1] s; 8 | reg const ptr u64[1] t; 9 | t = s; 10 | s = f(t); 11 | reg u64 r; 12 | r = s[0]; 13 | return r; 14 | } 15 | 16 | -------------------------------------------------------------------------------- /compiler/tests/fail/register_allocation/x86-64/too_many_large_ret.jazz: -------------------------------------------------------------------------------- 1 | /* This fails early with a type error, the error in regalloc cannot be 2 | triggered. */ 3 | 4 | export 5 | fn too_many_large_ret() -> reg u256, reg u256, reg u256 { 6 | reg u256 x y z; 7 | x = 0; 8 | y = 1; 9 | z = 2; 10 | return x, y, z; 11 | } 12 | -------------------------------------------------------------------------------- /compiler/tests/fail/typing/x86-64/non_inline_stack_res.jazz: -------------------------------------------------------------------------------- 1 | fn init () -> stack u64[2] { 2 | stack u64[2] t; 3 | t[0] = 0; 4 | t[1] = 0; 5 | return t; 6 | } 7 | 8 | export fn main() -> reg u64 { 9 | stack u64[2] t; 10 | reg u64 r; 11 | t = init(); 12 | r = t[0]; 13 | r += t[1]; 14 | return r; 15 | } 16 | 17 | -------------------------------------------------------------------------------- /compiler/tests/success/risc-v/div.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn div(reg u32 arg0, reg u32 arg1) -> reg u32 { 3 | reg u32 x; 4 | 5 | // Signed 6 | x = arg0 /32s arg1; 7 | [x] = x; 8 | 9 | // Unsigned 10 | x = arg0 /32u arg1; 11 | [x] = x; 12 | 13 | reg u32 res; 14 | res = x; 15 | return res; 16 | } 17 | -------------------------------------------------------------------------------- /compiler/tests/success/risc-v/intrinsic_div.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn div(reg u32 arg0, reg u32 arg1) -> reg u32 { 3 | reg u32 x; 4 | 5 | // Signed 6 | x = #DIV(arg0, arg1); 7 | [x] = x; 8 | 9 | // Unsigned 10 | x = #DIVU(arg0, arg1); 11 | [x] = x; 12 | 13 | reg u32 res; 14 | res = x; 15 | 16 | return res; 17 | } 18 | -------------------------------------------------------------------------------- /compiler/tests/success/risc-v/intrinsic_rem.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn div(reg u32 arg0, reg u32 arg1) -> reg u32 { 3 | reg u32 x; 4 | 5 | // Signed 6 | x = #REM(arg0, arg1); 7 | [x] = x; 8 | 9 | // Unsigned 10 | x = #REMU(arg0, arg1); 11 | [x] = x; 12 | 13 | reg u32 res; 14 | res = x; 15 | 16 | return res; 17 | } 18 | -------------------------------------------------------------------------------- /compiler/tests/success/risc-v/rem.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn rem(reg u32 arg0, reg u32 arg1) -> reg u32 { 3 | reg u32 x; 4 | 5 | // Signed 6 | x = arg0 %32s arg1; 7 | [x] = x; 8 | 9 | // Unsigned 10 | x = arg0 %32u arg1; 11 | [x] = x; 12 | 13 | reg u32 res; 14 | res = x; 15 | return res; 16 | } 17 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/call_conv_windows.jazz: -------------------------------------------------------------------------------- 1 | export fn foo () -> reg u256 { 2 | reg u256[16] xmm; 3 | reg u256 xmm0; 4 | inline int i; 5 | for i = 0 to 16 { 6 | xmm[i] = #set0_256(); 7 | } 8 | 9 | for i = 0 to 16 { 10 | xmm[0] ^= xmm[i]; 11 | } 12 | 13 | xmm0 = xmm[0]; 14 | return xmm0; 15 | 16 | } -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/cqo.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn test_cqo(reg u64 x) -> reg u64 { 3 | reg u16 u v; 4 | reg u32 y; 5 | reg u64 z r; 6 | u = x; 7 | u = #CQO_16(u); 8 | v = u; 9 | y = x; 10 | y = #CQO_32(y); 11 | v |= y; 12 | z = x; 13 | z = #CQO(z); 14 | v |= z; 15 | r = (64u) v; 16 | return r; 17 | } 18 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/inline_regptr.jazz: -------------------------------------------------------------------------------- 1 | inline 2 | fn one(reg ptr u64[1] a) -> reg u64, reg ptr u64[1] { 3 | reg u64 result; 4 | a[0] = 1; 5 | result = a[0]; 6 | return result, a; 7 | } 8 | 9 | export 10 | fn main() -> reg u64 { 11 | stack u64[1] s; 12 | reg u64 n ; 13 | n, s = one(s); 14 | return n; 15 | } 16 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/test_inline_var.jazz: -------------------------------------------------------------------------------- 1 | inline 2 | fn addn (reg u64 r, inline u64 n) -> reg u64 { 3 | r = r + n; 4 | r = r + (n + n); 5 | return r; 6 | } 7 | 8 | export fn f(reg u64 r1) -> reg u64 { 9 | reg u64 r; 10 | r = r1; 11 | r = addn(r, 6); 12 | r = addn(r, 3); 13 | r = addn(r, 5); 14 | return r; 15 | } 16 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/vmovhpd.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn test_vmovhpd(reg u64 tmp) { 3 | reg u128 x; 4 | 5 | x = #set0_128(); 6 | [:u64 tmp] = #VMOVHPD(x); 7 | } 8 | 9 | export 10 | fn vmovhpd_to_stack(reg u128 x) -> reg u64 { 11 | stack u64 y; 12 | reg u64 z; 13 | y = #VMOVHPD(x); 14 | z = y; 15 | return z; 16 | } 17 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/vmovlpd.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn test_vmovlpd(reg u64 tmp) { 3 | reg u128 x; 4 | 5 | x = #set0_128(); 6 | [:u64 tmp] = #VMOVLPD(x); 7 | } 8 | 9 | export 10 | fn vmovlpd_to_stack(reg u128 x) -> reg u64 { 11 | stack u64 y; 12 | reg u64 z; 13 | y = #VMOVLPD(x); 14 | z = y; 15 | return z; 16 | } 17 | -------------------------------------------------------------------------------- /compiler/safetylib/domains/safetyDisjunctive.mli: -------------------------------------------------------------------------------- 1 | open SafetyInterfaces 2 | 3 | (* Disjunctive domain. Leaves are already constrained under the branch 4 | conditions. *) 5 | module AbsDisj (A : AbsNumProdT) : AbsDisjType 6 | 7 | (* Lifts a non-relational domain without disjunctions. *) 8 | module LiftToDisj (A : AbsNumType) : AbsDisjType 9 | -------------------------------------------------------------------------------- /compiler/tests/fail/array_expansion/x86-64/index_not_constant_param.jazz: -------------------------------------------------------------------------------- 1 | fn f (reg u64[4] r) -> reg u64 { 2 | reg u64 res; 3 | res = r[0]; 4 | return res; 5 | } 6 | 7 | export fn main () -> reg u64 { 8 | reg u64[4] r; 9 | reg u64 res; 10 | reg u64 i; 11 | 12 | i = 0; 13 | res = f(r[i:4]); 14 | 15 | return res; 16 | } 17 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/x86-64/trusted-termination.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn eventually_terminates() -> reg u64 { 3 | reg u64 r c; 4 | stack u8[1] b; 5 | ?{}, c = #set0(); 6 | #[no_termination_check] 7 | while { 8 | b = #randombytes(b); 9 | } (b[0] != 0) { 10 | c += 1; 11 | } 12 | r = c; 13 | return r; 14 | } 15 | -------------------------------------------------------------------------------- /compiler/tests/sct-checker/fail/bug_887.jazz: -------------------------------------------------------------------------------- 1 | /* In this example, r is public most of the time, except when the loop exits. */ 2 | #[sct="secret → ()"] 3 | fn test_venv(reg u64 s) { 4 | reg u64 i r; 5 | r = 0; 6 | i = 0; 7 | while { 8 | r = s; 9 | } (i < 10) { 10 | r = 0; 11 | i += 1; 12 | } 13 | [r] = 0; 14 | } 15 | -------------------------------------------------------------------------------- /compiler/tests/success/pointers/x86-64/test_writable_arguments.jazz: -------------------------------------------------------------------------------- 1 | fn f(reg ptr u64[1] t) -> reg ptr u64[1] { 2 | t[0] = 1; 3 | return t; 4 | } 5 | 6 | export fn g() -> reg u64{ 7 | stack u64[1] s; 8 | reg ptr u64[1] t; 9 | t = s; 10 | s = f((0 <= 1) ? t : t); 11 | reg u64 r; 12 | r = s[0]; 13 | return r; 14 | } 15 | -------------------------------------------------------------------------------- /compiler/tests/success/slh/x86-64/mmx.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn main(reg u64 x) -> reg u64 { 3 | reg u64 msf; 4 | msf = #init_msf(); 5 | 6 | #[mmx] reg u64 _msf; 7 | _msf = #mov_msf(msf); 8 | 9 | #[mmx] reg u64 _x; 10 | _x = x; 11 | 12 | _x = #protect(_x, _msf); 13 | 14 | x = _x; 15 | return x; 16 | } 17 | -------------------------------------------------------------------------------- /compiler/tests/success/subarrays/arm-m4/index_var.jazz: -------------------------------------------------------------------------------- 1 | // checks that using a variable as index in a subarray is ok 2 | export fn main (reg u32 i) -> reg u32 { 3 | stack u32[4] s; 4 | reg ptr u32[1] r; 5 | reg u32 res tmp; 6 | 7 | tmp = 0; 8 | s[i] = tmp; 9 | r = s[i:1]; 10 | res = r[0]; 11 | 12 | return res; 13 | } 14 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/eval_for.jazz: -------------------------------------------------------------------------------- 1 | param int n = 12; 2 | 3 | 4 | export 5 | fn test_for() -> reg u64 { 6 | reg u64[n] t; 7 | reg u64 sum; 8 | 9 | inline int i; 10 | 11 | for i = 0 to n { 12 | t[i] = i; 13 | } 14 | 15 | ?{}, sum = #set0(); 16 | 17 | for i = 0 to n { 18 | sum += t[i]; 19 | } 20 | 21 | return sum; 22 | } 23 | -------------------------------------------------------------------------------- /compiler/examples/extraction-unit-tests/gcd.jazz: -------------------------------------------------------------------------------- 1 | inline 2 | fn euclid(reg ui64 a b) -> reg ui64 { 3 | while (a != 0) { 4 | reg ui64 r; 5 | r = b % a; 6 | b = a; 7 | a = r; 8 | } 9 | return b; 10 | } 11 | 12 | export 13 | fn gcd(reg ui64 x y) -> reg ui64 { 14 | y = y; 15 | x = euclid(x, y); 16 | return x; 17 | } 18 | -------------------------------------------------------------------------------- /compiler/tests/fail/arm-m4/bug_667.jazz: -------------------------------------------------------------------------------- 1 | export fn main () -> reg u32 { 2 | stack u32[1] s1 s2; 3 | reg u32 aux res; 4 | 5 | aux = 0; 6 | s1[0] = aux; 7 | s2[0] = aux; 8 | aux = s1[0]; 9 | res = s2[aux]; // this is the problematic line, we need to take a reg ptr of s2 to do that 10 | res += aux; 11 | 12 | return res; 13 | } 14 | -------------------------------------------------------------------------------- /compiler/tests/pending/x86-64/even.jazz: -------------------------------------------------------------------------------- 1 | /* To prove safety of the array access, 2 | we need a reduction between the interval and the congruence domains */ 3 | export 4 | fn even() -> reg u64 { 5 | stack u16[1] a; 6 | reg u64 i; 7 | i = 0; 8 | while (i reg u64 { 3 | reg bool cf; 4 | reg u64 i; 5 | 6 | i = 1; 7 | cf, i -= 1; 8 | if (cf){ 9 | while (true) { i += 1;} 10 | } 11 | 12 | i = 0; 13 | cf, i -= 1; 14 | if (!cf){ 15 | while (true) { i += 1;} 16 | } 17 | 18 | return i; 19 | } 20 | -------------------------------------------------------------------------------- /compiler/tests/sct-checker/fail/spill.jazz: -------------------------------------------------------------------------------- 1 | #[sct = "public × secret → public"] 2 | fn spill2( 3 | reg u64 pub, 4 | reg u64 sec 5 | ) -> 6 | reg u64 7 | { 8 | reg u64 msf; 9 | msf = #init_msf(); 10 | #spill(pub, sec); 11 | [pub] = sec; 12 | #unspill(pub, sec); 13 | [pub] = sec; 14 | return pub; 15 | } 16 | -------------------------------------------------------------------------------- /compiler/tests/sct-checker/success/while.jazz: -------------------------------------------------------------------------------- 1 | #[sct = "public × secret → public"] 2 | fn while_first_branch( 3 | reg u64 pub, 4 | reg u64 sec 5 | ) -> 6 | reg u64 7 | { 8 | reg bool b; 9 | b = 0 < sec; 10 | while { 11 | b = 0 < pub; 12 | } (b) { 13 | pub -= 1; 14 | } 15 | return pub; 16 | } 17 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/arraycopy.jazz: -------------------------------------------------------------------------------- 1 | param int N = 4; 2 | 3 | export 4 | fn test(reg u64 x) -> reg u64 { 5 | 6 | reg u64[N] r; 7 | stack u64[N] s; 8 | reg u64 q; 9 | inline int i; 10 | 11 | for i = 0 to N { s[i] = x; } 12 | 13 | r = #copy(s); 14 | q = x; 15 | 16 | for i = 0 to N { q += r[i]; } 17 | 18 | return q; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/refmod.jazz: -------------------------------------------------------------------------------- 1 | /* 64-bit modulo */ 2 | export 3 | fn f(reg u64 x y) -> reg u64 { 4 | reg u64 r; 5 | x = x; /* This line allows the compiler to comply with register allocation constrainte */ 6 | r = 1; 7 | y = r if y <= 0; 8 | r = x % y; 9 | r = r; /* Same comment */ 10 | return r; 11 | } 12 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/test_glob_array_while2.jazz: -------------------------------------------------------------------------------- 1 | u64[4] glob_t = { 0, 1, 2, 3 }; 2 | 3 | export fn sum () -> reg u64 { 4 | reg u64 r; 5 | reg u64 i; 6 | reg ptr u64[4] gt1; 7 | 8 | r = 0; 9 | i = 0; 10 | gt1 = glob_t; 11 | while (i < 4) { 12 | r += gt1[i]; 13 | i += 1; 14 | } 15 | return r; 16 | } 17 | 18 | -------------------------------------------------------------------------------- /compiler/tests/fail/register_allocation/x86-64/conflicting_variables.jazz: -------------------------------------------------------------------------------- 1 | fn f(reg u64 arg) -> reg u64 { 2 | reg u64 res; 3 | res = arg + 3; 4 | return res; 5 | } 6 | 7 | export fn main (reg u64 x) -> reg u64 { 8 | reg u64 res; 9 | reg u64 z; 10 | z = x; 11 | res = f (z); 12 | z += res; 13 | res = z; 14 | return res; 15 | } 16 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/bug_54.jazz: -------------------------------------------------------------------------------- 1 | // With the current implementation, this fails. We could imagine a different 2 | // implementation where this works. 3 | 4 | export 5 | fn main () -> reg u64 { 6 | reg u64 res; 7 | stack u64[3] a, b; 8 | b[1] = 42; 9 | a[0:2] = b[1:2]; 10 | res = a[0]; 11 | return res; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/arm-m4/carry_flags.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn test() -> reg u32 { 3 | reg bool cf; 4 | reg u32 i; 5 | 6 | i = -2; 7 | cf, i += 1; 8 | if (cf){ 9 | while (true) { i += 1;} 10 | } 11 | 12 | i = -1; 13 | cf, i += 1; 14 | if (!cf){ 15 | while (true) { i += 1;} 16 | } 17 | 18 | return i; 19 | } 20 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/common/randombytes.jazz: -------------------------------------------------------------------------------- 1 | export fn test1() -> reg u32 { 2 | stack u32[1] r; 3 | reg u32 x; 4 | r = #randombytes(r); 5 | x = r[0]; 6 | return x; 7 | } 8 | 9 | export fn test2() -> reg u32 { 10 | stack u32[2] r; 11 | reg u32 x; 12 | r[1:1] = #randombytes(r[1:1]); 13 | x = r[1]; 14 | return x; 15 | } 16 | -------------------------------------------------------------------------------- /compiler/tests/sct-checker/common.mli: -------------------------------------------------------------------------------- 1 | open Jasmin 2 | module Arch : Arch_full.Arch 3 | 4 | val load_file : 5 | string -> 6 | ( unit, 7 | ( Arch.reg, 8 | Arch.regx, 9 | Arch.xreg, 10 | Arch.rflag, 11 | Arch.cond, 12 | Arch.asm_op, 13 | Arch.extra_op ) 14 | Arch_extra.extended_op ) 15 | Prog.prog 16 | -------------------------------------------------------------------------------- /compiler/tests/success/risc-v/intrinsic_sll.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn lsl(reg u32 arg0, reg u32 arg1) -> reg u32 { 3 | reg u32 x; 4 | 5 | // Registers. 6 | x = #SLL(arg0, arg1); 7 | [x] = x; 8 | 9 | // Immediates. 10 | x = #SLLI(arg0, 1); 11 | [x] = x; 12 | 13 | reg u32 res; 14 | res = x; 15 | return res; 16 | } 17 | -------------------------------------------------------------------------------- /compiler/tests/success/risc-v/intrinsic_sra.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn asr(reg u32 arg0, reg u32 arg1) -> reg u32 { 3 | reg u32 x; 4 | 5 | // Registers. 6 | x = #SRA(arg0, arg1); 7 | [x] = x; 8 | 9 | // Immediates. 10 | x = #SRAI(arg0, 1); 11 | [x] = x; 12 | 13 | reg u32 res; 14 | res = x; 15 | return res; 16 | } 17 | -------------------------------------------------------------------------------- /compiler/tests/success/risc-v/intrinsic_srl.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn lsr(reg u32 arg0, reg u32 arg1) -> reg u32 { 3 | reg u32 x; 4 | 5 | // Registers. 6 | x = #SRL(arg0, arg1); 7 | [x] = x; 8 | 9 | // Immediates. 10 | x = #SRLI(arg0, 1); 11 | [x] = x; 12 | 13 | reg u32 res; 14 | res = x; 15 | return res; 16 | } 17 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/por.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn por(reg u64 x y p) -> reg u64 { 3 | #[mmx] reg u64 a b; 4 | stack u64 s; 5 | a = x; 6 | b = y; 7 | s = x; 8 | a = #POR(a, b); 9 | a = #POR(a, [p]); 10 | a = #POR(a, s); 11 | a |= b; 12 | a |= [p]; 13 | a |= s; 14 | x = a; 15 | return x; 16 | } 17 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/sha256.jazz: -------------------------------------------------------------------------------- 1 | export fn test_sha256(reg ptr u128[2] t) -> reg u128 { 2 | reg u128 a = t[0], b = t[1]; 3 | b = #SHA256MSG1(b, t[0]); 4 | a = #SHA256MSG1(a, b); 5 | b = #SHA256MSG2(b, t[1]); 6 | a = #SHA256MSG2(a, b); 7 | b = #SHA256RNDS2(b, t[0], a); 8 | a = #SHA256RNDS2(a, b, a); 9 | return a; 10 | } 11 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/vpsxldq.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn test(reg u64 p) { 3 | reg u128 a, b, c; 4 | reg u256 d, e, f; 5 | 6 | a = [:u128 p + 0]; 7 | b = #VPSLLDQ_128(a, 1); 8 | c = #VPSRLDQ_128(b, 2); 9 | [:u128 p + 16] = c; 10 | 11 | d = [:u256 p + 0]; 12 | e = #VPSLLDQ_256(d, 3); 13 | f = #VPSRLDQ_256(e, 4); 14 | [:u256 p + 32] = f; 15 | } 16 | -------------------------------------------------------------------------------- /compiler/tests/warning/x86-64/extra_assignment.jazz: -------------------------------------------------------------------------------- 1 | inline fn f () -> inline u64 { 2 | inline u64 res; 3 | res = 0; 4 | return res; 5 | } 6 | 7 | inline fn g () -> reg u64 { 8 | reg u64 res; 9 | res = f(); 10 | return res; 11 | } 12 | 13 | export fn main () -> reg u64 { 14 | reg u64 res; 15 | res = g(); 16 | return res; 17 | } 18 | -------------------------------------------------------------------------------- /compiler/examples/x86-64/al3.jazz: -------------------------------------------------------------------------------- 1 | inline 2 | fn swap(reg u64[2] u) -> reg u64[2] { 3 | reg u64[2] z; 4 | z[1] = u[0]; 5 | z[0] = u[1]; 6 | return z; 7 | } 8 | 9 | export 10 | fn f() -> reg u64 { 11 | reg u64[2] x; 12 | reg u64[2] y; 13 | reg u64 r; 14 | x[1] = 1; 15 | x[0] = 0; 16 | 17 | y = swap(x); 18 | x = y; 19 | r = x[0]; 20 | return r; 21 | } 22 | -------------------------------------------------------------------------------- /compiler/tests/fail/subarrays/x86-64/partial_region.jazz: -------------------------------------------------------------------------------- 1 | export fn main () -> reg u32 { 2 | reg u32 res tmp; 3 | stack u32[4] s; 4 | reg ptr u32[2] r; 5 | 6 | s[0] = 0; 7 | r = s[2:2]; 8 | r[0] = 0; 9 | tmp = r[0]; 10 | r = s[2:2]; // r is not valid 11 | res = r[0]; // reading is ko 12 | res += tmp; 13 | 14 | return res; 15 | } 16 | -------------------------------------------------------------------------------- /compiler/tests/sct-checker/fail/functions.jazz: -------------------------------------------------------------------------------- 1 | #[sct = "public → ()"] inline fn leak(reg u64 c) { if c != 0 {} } 2 | 3 | u8[6] g = "jasmin"; 4 | 5 | #[sct = "transient → public"] fn call_kills_msf(reg u64 c) -> reg u64 { 6 | reg u64 m x; 7 | m = #init_msf(); 8 | x = g[:u64 c]; 9 | leak(0); 10 | x = #protect(x, m); 11 | return x; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/success/common/inline_label_duplication.jazz: -------------------------------------------------------------------------------- 1 | inline fn ble::e () -> reg u32 { 2 | reg u32 x = 0; 3 | return x; 4 | } 5 | 6 | inline fn ble__e () -> reg u32 { 7 | reg u32 x = 1; 8 | return x; 9 | } 10 | 11 | export fn out() -> reg u32 { 12 | reg u32 x = ble::e(); 13 | reg u32 y = ble__e(); 14 | return y; 15 | } -------------------------------------------------------------------------------- /changes/01-feature/1316-functorize-safety.md: -------------------------------------------------------------------------------- 1 | - The safety checker used to support only x86-64, it now also supports ARMv7 and RISC-V. 2 | It has not been specialized yet to these new architectures, so it might be imprecise. 3 | ([PR #1316](https://github.com/jasmin-lang/jasmin/pull/1316); 4 | fixes [#1315](https://github.com/jasmin-lang/jasmin/issues/1315)). 5 | -------------------------------------------------------------------------------- /compiler/CCT/success/randombytes.jazz: -------------------------------------------------------------------------------- 1 | #[ct="secret * secret -> secret"] 2 | export 3 | fn toss(reg u64 a b) -> reg u64 { 4 | stack u8[1] s; 5 | reg u8 t; 6 | reg u64 r; 7 | reg u64[2] input; 8 | input[0] = a; 9 | input[1] = b; 10 | s = #randombytes(s); 11 | t = s[0]; 12 | r = input[0]; 13 | r = input[1] if t reg u64 { 3 | reg u64 msf; 4 | msf = #init_msf(); 5 | return msf; 6 | } 7 | 8 | #[sct="transient → public"] 9 | export 10 | fn protect_leak(reg u64 x) -> reg u64 { 11 | reg u64 msf; 12 | msf = f(); 13 | x = #protect(x, msf); 14 | x = x; 15 | return x; 16 | } 17 | -------------------------------------------------------------------------------- /compiler/tests/fail/annotation/x86-64/stacksize.jazz: -------------------------------------------------------------------------------- 1 | param int n = 4; 2 | 3 | /* Stack size is 32 bytes. */ 4 | #[stacksize=17] 5 | export 6 | fn main(reg u64 x) -> reg u64 { 7 | reg u64 result; 8 | stack u64[n] tab; 9 | inline int i; 10 | for i = 0 to n { tab[i] = x; } 11 | result = 0; 12 | for i = 0 to n { result += tab[i]; } 13 | return result; 14 | } 15 | -------------------------------------------------------------------------------- /compiler/tests/safety/success/common/swap.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn swapw(reg u32 x y) -> reg u32, reg u32 { 3 | x = x; 4 | y = y; 5 | x, y = #swap(x, y); 6 | return x, y; 7 | } 8 | 9 | export 10 | fn swapa(reg u32 x) -> reg u32 { 11 | stack u32[1] a b; 12 | a[0] = x; 13 | b[0] = x; 14 | a, b = #swap(a, b); 15 | x = a[0]; 16 | return x; 17 | } 18 | -------------------------------------------------------------------------------- /compiler/tests/success/arm-m4/intrinsic_smulw_hw.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn smulw_hw(reg u32 x y) -> reg u32 { 3 | reg u32 r; 4 | r = #SMULWB(x, y); 5 | r = #SMULWT(r, y); 6 | 7 | reg bool b; 8 | ?{ " reg u32 { 3 | reg u32 x; 4 | 5 | // Registers. 6 | x = arg0 << (arg1 & 31); 7 | [x] = x; 8 | 9 | // Immediates. 10 | x = arg0 << 1; 11 | x <<= 1; 12 | [x] = x; 13 | 14 | reg u32 res; 15 | res = x; 16 | return res; 17 | } 18 | -------------------------------------------------------------------------------- /compiler/tests/success/risc-v/sra.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn asr(reg u32 arg0, reg u32 arg1) -> reg u32 { 3 | reg u32 x; 4 | 5 | // Registers. 6 | x = arg0 >>s (arg1 & 31); 7 | [x] = x; 8 | 9 | // Immediates. 10 | x = arg0 >>s 1; 11 | x >>s= 1; 12 | [x] = x; 13 | 14 | reg u32 res; 15 | res = x; 16 | return res; 17 | } 18 | -------------------------------------------------------------------------------- /compiler/tests/success/risc-v/srl.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn lsr(reg u32 arg0, reg u32 arg1) -> reg u32 { 3 | reg u32 x; 4 | 5 | // Registers. 6 | x = arg0 >> (arg1 & 31); 7 | [x] = x; 8 | 9 | // Immediates. 10 | x = arg0 >> 1; 11 | x >>= 1; 12 | [x] = x; 13 | 14 | reg u32 res; 15 | res = x; 16 | return res; 17 | } 18 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/arr_init_param.jazz: -------------------------------------------------------------------------------- 1 | param int size = 10; 2 | 3 | export fn test() -> reg u64 { 4 | stack u64[size + 2] t; 5 | inline int i; 6 | reg u64 r; 7 | 8 | ArrayInit(t); 9 | 10 | for i = 0 to size + 2 { 11 | t[i] = 0; 12 | } 13 | r = 0; 14 | for i = 0 to size + 2 { 15 | r += t[i]; 16 | } 17 | return r; 18 | } -------------------------------------------------------------------------------- /compiler/tests/fail/annotation/x86-64/stackalign.jazz: -------------------------------------------------------------------------------- 1 | param int n = 4; 2 | 3 | /* Stack alignment is u64. */ 4 | #[stackalign="u32"] 5 | export 6 | fn main(reg u64 x) -> reg u64 { 7 | reg u64 result; 8 | stack u64[n] tab; 9 | inline int i; 10 | for i = 0 to n { tab[i] = x; } 11 | result = 0; 12 | for i = 0 to n { result += tab[i]; } 13 | return result; 14 | } 15 | -------------------------------------------------------------------------------- /compiler/tests/fail/register_allocation/x86-64/already_allocated.jazz: -------------------------------------------------------------------------------- 1 | /* Should fail because cf at line 9 correspond to the flag xf */ 2 | export 3 | fn add1(reg u64 arg) -> reg u64 { 4 | reg u64 z; 5 | reg bool cf; 6 | z = arg; 7 | cf, z = #adc(z,z,false); 8 | // of cf xf pf zf 9 | _,_,cf,_,_,z = #ADC(z,z,cf); 10 | ?{}, z = #ADC(z,z,cf); 11 | return z; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/merge_globals.jazz: -------------------------------------------------------------------------------- 1 | u64[2] g1 = {0,1}; 2 | u64[2] g2 = {0,1}; 3 | 4 | fn f () -> reg u64 { 5 | reg u64 res; 6 | reg ptr u64[2] rg; 7 | rg = g1; 8 | rg[0:1] = g2[0:1]; 9 | res = rg[0]; 10 | return res; 11 | } 12 | 13 | export fn dummy() -> reg u64 { 14 | reg u64 r; 15 | r = f(); 16 | return r; 17 | } 18 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/unaligned_sub_offset_unscaled.jazz: -------------------------------------------------------------------------------- 1 | export fn main (reg u64 i) -> reg u64 { 2 | stack u64[4] s; 3 | reg ptr u64[2] r; 4 | reg u64 res; 5 | 6 | s[i] = 0; 7 | r = s.[i:2]; // unscaled access: r is known to be aligned on U8 8 | res = r[0]; // but not to be aligned on U64 -> error 9 | 10 | return res; 11 | } 12 | -------------------------------------------------------------------------------- /compiler/tests/fail/typing/x86-64/non_inline_stack_arg.jazz: -------------------------------------------------------------------------------- 1 | fn f (stack u64[1] x) -> reg u64 { 2 | reg u64 r; 3 | x[0] = 0; 4 | r = x[0]; 5 | return r; 6 | } 7 | 8 | export fn e (reg u64 i) -> reg u64 { 9 | stack u64[1] y; 10 | reg u64 r1 r2; 11 | y[0] = i; 12 | r1 = f(y); 13 | r2 = y[0]; 14 | r1 += r2; 15 | return r1; 16 | } 17 | 18 | -------------------------------------------------------------------------------- /compiler/tests/sct-checker/success/movmsf.jazz: -------------------------------------------------------------------------------- 1 | fn reset_msf() -> #[msf] reg u64 { 2 | reg u64 msf; 3 | msf = #init_msf(); 4 | return msf; 5 | } 6 | 7 | #[sct="transient -> ()"] 8 | fn main(reg u64 x) { 9 | reg u64 msf; 10 | msf = #init_msf(); 11 | if x < 1 { 12 | msf = reset_msf(); 13 | x = #protect(x, msf); 14 | [x] = 0; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/calldepth.jazz: -------------------------------------------------------------------------------- 1 | fn f () -> reg u64 { 2 | reg u64 res; 3 | res = 0; 4 | return res; 5 | } 6 | 7 | /* conditional call */ 8 | 9 | #[calldepth=2] 10 | export fn g (reg u64 x) -> reg u64 { 11 | reg u64 res; 12 | 13 | if (x == 0) { 14 | res = 0; 15 | } else { 16 | res = f (); 17 | } 18 | 19 | return res; 20 | } 21 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/test_move_ptr_to_stack.jazz: -------------------------------------------------------------------------------- 1 | export fn foo() -> reg u64 { 2 | reg ptr u64[2] p; 3 | stack u64[2] s, s1; 4 | reg u64 r; 5 | inline int i; 6 | p = s; 7 | for i = 0 to 2 { 8 | p[i] = (64u)i; 9 | } 10 | s1 = p; 11 | r = 0; 12 | for i = 0 to 2 { 13 | r += s1[i]; 14 | } 15 | return r; 16 | } 17 | 18 | 19 | -------------------------------------------------------------------------------- /compiler/tests/fail/subarrays/x86-64/unscaled_access.jazz: -------------------------------------------------------------------------------- 1 | // should this succeed? 2 | 3 | param int N = 10; 4 | 5 | export fn main (reg u32 i) -> reg u32 { 6 | stack u32[N] s; 7 | stack u32[5] s2; 8 | reg u32 res; 9 | inline int j; 10 | 11 | for j = 0 to N { 12 | s[j] = 0; 13 | } 14 | s2 = s.[i:5]; 15 | res = s2[0]; 16 | return res; 17 | } 18 | -------------------------------------------------------------------------------- /compiler/tests/success/arm-m4/intrinsic_bfi.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn bfi(reg u32 x) -> reg u32 { 3 | reg u32 y; 4 | y = 0; 5 | y = #BFI(y, x, 0, 1); 6 | y = #BFI(y, x, 31, 1); 7 | y = #BFI(y, x, 0, 32); 8 | 9 | reg bool b; 10 | ?{ " inline int { 3 | inline int y; 4 | y = x + 1; 5 | return y; 6 | } 7 | 8 | export 9 | fn snd(reg u64 a b) -> reg u64 { 10 | inline int k; 11 | reg u64[2] t; 12 | reg u64 r; 13 | t[0] = a; 14 | t[1] = b; 15 | k = inc(0); 16 | r = t[k]; 17 | return r; 18 | } 19 | -------------------------------------------------------------------------------- /compiler/examples/extraction-unit-tests/add_in_mem.jazz: -------------------------------------------------------------------------------- 1 | type pointer = ui64; 2 | 3 | export fn add_mem (reg pointer out in1 in2, reg ui64 len) { 4 | reg ui64 i = 0; 5 | reg u64 d x y; 6 | while (i < len) { 7 | x = [(64u)(in1 + 8*i)]; 8 | y = [(64u)(in2 + 8*i)]; 9 | d = x + y; 10 | [(64u)(out + 8*i)] = d; 11 | i += 1; 12 | } 13 | } 14 | 15 | 16 | -------------------------------------------------------------------------------- /compiler/tests/fail/array_expansion/x86-64/array_return_not_reg.jazz: -------------------------------------------------------------------------------- 1 | fn f () -> reg u64[4] { 2 | reg u64[4] r; 3 | 4 | inline int i; 5 | for i = 0 to 4 { 6 | r[i] = 0; 7 | } 8 | 9 | return r; 10 | } 11 | 12 | export fn main () -> reg u64 { 13 | stack u64[4] s; 14 | reg u64 res; 15 | 16 | s = f(); 17 | res = s[0]; 18 | 19 | return res; 20 | } 21 | -------------------------------------------------------------------------------- /compiler/tests/fail/register_allocation/x86-64/conflicting_register.jazz: -------------------------------------------------------------------------------- 1 | /* Should fail because cf is erase at line 9 and used at line 10 */ 2 | export 3 | fn add1(reg u64 arg) -> reg u64 { 4 | reg u64 z; 5 | reg bool cf; 6 | z = arg; 7 | cf, z = #adc(z,z,false); 8 | // of cf xf pf zf 9 | _,_,_,_,_,z = #ADC(z,z,cf); 10 | ?{}, z = #ADC(z,z,cf); 11 | return z; 12 | } 13 | 14 | -------------------------------------------------------------------------------- /compiler/tests/fail/typing/x86-64/export_reg_array_res.jazz: -------------------------------------------------------------------------------- 1 | inline fn init (reg u64[2] t1) -> reg u64[2] 2 | { 3 | t1[0] = 0; 4 | t1[1] = 0; 5 | return t1; 6 | } 7 | 8 | export fn test3 () -> reg u64[2] 9 | { 10 | reg u64[2] t1; 11 | reg u64[2] t2; 12 | t2 = init(t1); 13 | t1 = init(t1); 14 | return t1; 15 | } 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /compiler/tests/sct-checker/success/bug_1097.jazz: -------------------------------------------------------------------------------- 1 | #[sct="transient × transient -> public"] 2 | export fn main(reg u64 bound data) -> reg u64 { 3 | _ = #init_msf(); 4 | reg u64 sample; 5 | #[no_termination_check] 6 | while { 7 | sample = [data]; 8 | #declassify(sample); 9 | _ = #init_msf(); 10 | } (sample > bound) 11 | 12 | return sample; 13 | } 14 | -------------------------------------------------------------------------------- /compiler/tests/success/arm-m4/intrinsic_rev.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn rev(reg u32 x) -> reg u32 { 3 | reg u32 y; 4 | reg bool nf, zf, vf, cf; 5 | 6 | y = #REV(x); 7 | x = #REV16(y); 8 | y = #REVSH(x); 9 | 10 | (nf, zf, vf, cf) = #CMP(x,y); 11 | 12 | y = #REVcc(x, cf, y); 13 | x = #REV16cc(y, cf, x); 14 | y = #REVSHcc(x, cf, y); 15 | 16 | return y; 17 | } 18 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/pdep.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn test_pdep32(reg u64 tmp) 3 | { 4 | reg u32 a b c; 5 | 6 | a = 0xFF; 7 | b = 0x02; 8 | c = #PDEP_32(a, b); 9 | [:u32 tmp] = c; 10 | } 11 | 12 | export 13 | fn test_pdep64(reg u64 tmp) 14 | { 15 | reg u64 a b c; 16 | 17 | a = 0xFF; 18 | b = 0x02; 19 | c = #PDEP_64(a, b); 20 | [:u64 tmp] = c; 21 | } 22 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/pext.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn test_pext32(reg u64 tmp) 3 | { 4 | reg u32 a b c; 5 | 6 | a = 0xFF; 7 | b = 0x02; 8 | c = #PEXT_32(a, b); 9 | [:u32 tmp] = c; 10 | } 11 | 12 | export 13 | fn test_pext64(reg u64 tmp) 14 | { 15 | reg u64 a b c; 16 | 17 | a = 0xFF; 18 | b = 0x02; 19 | c = #PEXT_64(a, b); 20 | [:u64 tmp] = c; 21 | } 22 | -------------------------------------------------------------------------------- /changes/01-feature/1328-declassify-operator.jazz: -------------------------------------------------------------------------------- 1 | - Declassification can be expressed using a pseudo-operator that applies to a 2 | single variable: `() = #declassify(x)`; the legacy annotation `#[declassify]` 3 | on assignements is deprecated 4 | ([PR #1328](https://github.com/jasmin-lang/jasmin/pull/1328); 5 | fixes [#746](https://github.com/jasmin-lang/jasmin/issues/746)). 6 | -------------------------------------------------------------------------------- /compiler/tests/fail/array_expansion/x86-64/default_scale_return.jazz: -------------------------------------------------------------------------------- 1 | fn f () -> reg u64[4] { 2 | reg u64[4] r; 3 | 4 | inline int i; 5 | for i = 0 to 4 { 6 | r[i] = 0; 7 | } 8 | 9 | return r; 10 | } 11 | 12 | export fn main () -> reg u64 { 13 | reg u64[4] r; 14 | reg u64 res; 15 | 16 | r.[0:4] = f(); 17 | res = r[0]; 18 | 19 | return res; 20 | } 21 | -------------------------------------------------------------------------------- /compiler/tests/fail/array_expansion/x86-64/type_mismatch_return.jazz: -------------------------------------------------------------------------------- 1 | fn f () -> reg u64[4] { 2 | reg u64[4] r; 3 | 4 | inline int i; 5 | for i = 0 to 4 { 6 | r[i] = 0; 7 | } 8 | 9 | return r; 10 | } 11 | 12 | export fn main () -> reg u64 { 13 | reg u32[8] r; 14 | reg u64 res; 15 | 16 | r = f(); 17 | res = r[:u64 0]; 18 | 19 | return res; 20 | } 21 | -------------------------------------------------------------------------------- /compiler/tests/fail/common/bug_1214.jazz: -------------------------------------------------------------------------------- 1 | inline fn consume(reg ptr u32[1] x) -> reg ptr u32[1] { 2 | if x[0] > 0 { 3 | x[0] = 0; 4 | } 5 | return x; 6 | } 7 | 8 | export fn main(reg u32 a) -> reg u32 { 9 | stack u32[1] s; 10 | s[0] = a; 11 | reg ptr u32[1] x = s; 12 | reg ptr u32[1] y = consume(x); 13 | a = x[0]; 14 | a += y[0]; 15 | return a; 16 | } 17 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/unaligned_sub_offset.jazz: -------------------------------------------------------------------------------- 1 | export fn main (reg u64 i) -> reg u64 { 2 | stack u32[4] s; 3 | reg ptr u32[2] r; 4 | reg u64 res; 5 | 6 | s[i] = 0; 7 | s[i+1] = 0; 8 | r = s[i:2]; // scaled access: r is known to be aligned on U32 9 | res = r[:u64 0]; // but not to be aligned on U64 -> error 10 | 11 | return res; 12 | } 13 | -------------------------------------------------------------------------------- /compiler/tests/success/arm-m4/large_stack/sub_reg_ptr_template.jinc: -------------------------------------------------------------------------------- 1 | export fn main () -> reg u32 { 2 | stack u32[N] s; 3 | reg ptr u32[N] r; 4 | reg ptr u32[1] r2; 5 | reg u32 n i res; 6 | 7 | i = 0; 8 | res = 0; 9 | n = N; 10 | while (i < n) { 11 | s[i] = res; 12 | } 13 | r = s; 14 | r2 = r[N-1:1]; 15 | res = r2[0]; 16 | 17 | return res; 18 | } 19 | -------------------------------------------------------------------------------- /compiler/tests/success/subarrays/x86-64/nested_var.jazz: -------------------------------------------------------------------------------- 1 | export fn main (reg u64 i1, reg u64 i2) -> reg u64 { 2 | reg u64 res; 3 | stack u64[4] s; 4 | reg ptr u64[3] r1; 5 | reg ptr u64[2] r2; 6 | 7 | r1 = s[i1:3]; 8 | r2 = r1[i2:2]; 9 | r2[0] = 2; 10 | r1[i2:2] = r2; 11 | s[i1:3] = r1; 12 | 13 | res = i1+i2; 14 | res = s[res]; 15 | return res; 16 | } 17 | -------------------------------------------------------------------------------- /compiler/tests/success/typing/x86-64/assign_constant_pointer_local_var.jazz: -------------------------------------------------------------------------------- 1 | /* The type checker should not reject this program, as it does not write to the 2 | constant pointer. */ 3 | export 4 | fn main() -> reg u64{ 5 | reg u64 a; 6 | stack u64[1] s; 7 | reg const ptr u64[1] p; 8 | s[0] = 42; 9 | p = s; 10 | a = p[0]; 11 | a ^= s[0]; 12 | return a; 13 | } 14 | -------------------------------------------------------------------------------- /compiler/tests/exec/vpsxldq.jazz: -------------------------------------------------------------------------------- 1 | require "../success/x86-64/vpsxldq.jazz" 2 | 3 | inline 4 | fn etest() -> reg u256[2] { 5 | global u128 g; 6 | reg u64 p; 7 | reg u256[2] r; 8 | p = 0x480; 9 | 10 | g = 0x12345678901234567890123456789012; 11 | [:u128 p + 0] = g; 12 | 13 | #[inline] test(p); 14 | 15 | r[0] = [:u256 p + 0]; 16 | r[1] = [:u256 p + 32]; 17 | 18 | return r; 19 | } 20 | -------------------------------------------------------------------------------- /compiler/tests/fail/array_expansion/x86-64/sub_array_return_not_reg.jazz: -------------------------------------------------------------------------------- 1 | fn f () -> reg u64[4] { 2 | reg u64[4] r; 3 | 4 | inline int i; 5 | for i = 0 to 4 { 6 | r[i] = 0; 7 | } 8 | 9 | return r; 10 | } 11 | 12 | export fn main () -> reg u64 { 13 | stack u64[4] s; 14 | reg u64 res; 15 | 16 | s[0:4] = f(); 17 | res = s[0]; 18 | 19 | return res; 20 | } 21 | -------------------------------------------------------------------------------- /compiler/tests/fail/array_expansion/x86-64/type_mismatch_return_sub.jazz: -------------------------------------------------------------------------------- 1 | fn f () -> reg u64[4] { 2 | reg u64[4] r; 3 | 4 | inline int i; 5 | for i = 0 to 4 { 6 | r[i] = 0; 7 | } 8 | 9 | return r; 10 | } 11 | 12 | export fn main () -> reg u64 { 13 | reg u32[8] r; 14 | reg u64 res; 15 | 16 | r[0:8] = f(); 17 | res = r[:u64 0]; 18 | 19 | return res; 20 | } 21 | -------------------------------------------------------------------------------- /compiler/tests/fail/stack_allocation/x86-64/merge_global_param.jazz: -------------------------------------------------------------------------------- 1 | u64[2] g = {0,1}; 2 | 3 | fn f (reg ptr u64[1] r1) -> reg u64 { 4 | reg u64 res; 5 | reg ptr u64[2] rg; 6 | rg = g; 7 | rg[0:1] = r1[0:1]; 8 | res = rg[0]; 9 | return res; 10 | } 11 | 12 | export fn dummy() -> reg u64 { 13 | stack u64[1] s; 14 | reg u64 r; 15 | r = f(s); 16 | return r; 17 | } 18 | -------------------------------------------------------------------------------- /compiler/tests/success/common/bug_607.jazz: -------------------------------------------------------------------------------- 1 | fn f(reg ptr u64[1] a, reg u64 x) -> reg ptr u64[1], reg u64 { 2 | stack ptr u64[1] s; 3 | s = a; 4 | a = s; 5 | return a, x; 6 | } 7 | 8 | export 9 | fn main() { 10 | reg u64 x; 11 | x = 0; 12 | 13 | stack u64[1] a; 14 | a[0] = 0; 15 | 16 | if (false) { 17 | _, _ = f(a, x); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /compiler/tests/success/common/integer_notation.jazz: -------------------------------------------------------------------------------- 1 | /* 2 | Test for all valid integer syntaxes 3 | */ 4 | u32[11] y = { 5 | 0b11110000, 6 | 0b111_111_11, 7 | 0B111_00_11, 8 | 9 | 0o01234567, 10 | 0o765_4_321, 11 | 0O76543210, 12 | 13 | 1000000000, 14 | 1000_0000_000, 15 | 16 | 0x01234567, 17 | 0x765_b_32aac, 18 | 0X76aab3210 19 | }; 20 | -------------------------------------------------------------------------------- /compiler/tests/success/risc-v/intrinsic_sub.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn sub(reg u32 arg0, reg u32 arg1) -> reg u32 { 3 | reg u32 x; 4 | 5 | // Registers. 6 | x = #SUB(arg0, arg1); 7 | [x] = x; 8 | 9 | // Direct subtraction between a register and an immediate is absent from the RISCV I extension 10 | 11 | reg u32 res; 12 | res = x; 13 | return res; 14 | } 15 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/clc-stc.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn test_stc() -> reg u64 { 3 | reg bool cf; 4 | reg u64 r; 5 | ?{}, r = #set0(); 6 | cf = #STC(); 7 | _, r += r + cf; 8 | return r; 9 | } 10 | 11 | export 12 | fn test_clc() -> reg u64 { 13 | reg u64 r; 14 | reg bool cf; 15 | ?{}, r = #set0(); 16 | cf = #CLC(); 17 | _, r += r + cf; 18 | return r; 19 | } 20 | -------------------------------------------------------------------------------- /compiler/examples/x86-64/nesteed_array.jazz: -------------------------------------------------------------------------------- 1 | export fn foo (reg u64 x) -> reg u64 { 2 | stack u64[256] a; 3 | reg u64 r; 4 | inline int i j; 5 | for i = 0 to 32 { 6 | for j = 0 to 8 { 7 | a[8*i + j] = x; /* this currently doesn't work */ 8 | } 9 | } 10 | r = 0; 11 | for i = 0 to 256 { 12 | r += a[i]; 13 | } 14 | return r; 15 | } 16 | 17 | -------------------------------------------------------------------------------- /compiler/tests/fail/array_expansion/x86-64/whole_array_lv.jazz: -------------------------------------------------------------------------------- 1 | fn f (reg ptr u64[4] r) -> reg ptr u64[4] { 2 | return r; 3 | } 4 | 5 | export fn main () -> reg u64 { 6 | stack u64[4] s; 7 | reg u64[4] r; 8 | reg u64 res; 9 | 10 | // makeReferenceArguments introduces an equality 11 | // r = regptr; 12 | // which is rejected 13 | r = f(s); 14 | 15 | return res; 16 | } 17 | -------------------------------------------------------------------------------- /compiler/tests/success/risc-v/slt.jazz: -------------------------------------------------------------------------------- 1 | export 2 | fn slt(reg u32 arg0, reg u32 arg1) -> reg u32 { 3 | reg u32 x; 4 | 5 | // Registers. 6 | x = #SLT(arg0, arg1); 7 | [x] = x; 8 | x = #SLTI(arg0, 5); 9 | [x] = x; 10 | x = #SLTU(arg0, arg1); 11 | [x] = x; 12 | x = #SLTIU(arg0, 5); 13 | 14 | reg u32 res; 15 | res = x; 16 | return res; 17 | } 18 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/init-in-loop.jazz: -------------------------------------------------------------------------------- 1 | /* The following function is safe. Its compilation raises an “internal 2 | compilation error” as the one-varmap checker cannot prove that y is 3 | properly initialized. 4 | */ 5 | export 6 | fn main() -> reg u64 { 7 | reg u64 x y; 8 | x = 2; 9 | while (x > 0) { 10 | y = 1; 11 | x -= 1; 12 | } 13 | return y; 14 | } 15 | -------------------------------------------------------------------------------- /compiler/tests/success/x86-64/init_stack-array_in_inline-fn.jazz: -------------------------------------------------------------------------------- 1 | inline 2 | fn f(reg u64 n) -> stack u64[1] { 3 | stack u64[1] y; 4 | while (n >u 0) { 5 | y[0] = 0; 6 | n -= 1; 7 | } 8 | return y; 9 | } 10 | 11 | export 12 | fn main(#[public] reg u64 p) -> #[public] reg u64 { 13 | stack u64[1] x; 14 | reg u64 r; 15 | x = f(p); 16 | r = x[0]; 17 | return r; 18 | } 19 | -------------------------------------------------------------------------------- /scripts/generate-release-changelog.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | OUT=CHANGELOG_UNRELEASED.md 4 | 5 | echo "Add the lines below to CHANGELOG.md" > ${OUT} 6 | echo "" >> ${OUT} 7 | 8 | changelog_entries_with_title=(changes/*/*.md) 9 | for f in "${changelog_entries_with_title[@]}"; do 10 | cat ${f} >> ${OUT} 11 | echo "" >> ${OUT} 12 | done 13 | 14 | echo "Output written in ${OUT}" 15 | -------------------------------------------------------------------------------- /compiler/src/removeUnusedResults.mli: -------------------------------------------------------------------------------- 1 | open Prog 2 | 3 | (** Remove unused results. 4 | 5 | Based on global liveness information, this removes from non-export function the 6 | returned values that are never used by the callers. 7 | 8 | FIXME: this assumes that the program never calls export functions. 9 | 10 | *) 11 | val analyse : ('a * ('info, 'asm) func) list -> funname -> bool list option 12 | -------------------------------------------------------------------------------- /compiler/tests/fail/array_expansion/x86-64/sub_array_lv.jazz: -------------------------------------------------------------------------------- 1 | fn f (reg ptr u64[4] r) -> reg ptr u64[4] { 2 | return r; 3 | } 4 | 5 | export fn main () -> reg u64 { 6 | stack u64[4] s; 7 | reg u64[4] r; 8 | reg u64 res; 9 | 10 | // makeReferenceArguments introduces an equality 11 | // r[0:4] = regptr; 12 | // which is rejected 13 | r[0:4] = f(s); 14 | 15 | return res; 16 | } 17 | -------------------------------------------------------------------------------- /compiler/tests/fail/array_expansion/x86-64/whole_array.jazz: -------------------------------------------------------------------------------- 1 | fn f (reg ptr u64[4] s) -> reg u64 { 2 | reg u64 res; 3 | res = s[0]; 4 | return res; 5 | } 6 | 7 | export fn main () -> reg u64 { 8 | reg u64[4] r; 9 | reg u64 res; 10 | 11 | // makeReferenceArguments introduces an equality 12 | // regptr = r; 13 | // which is rejected 14 | res = f(r); 15 | 16 | return res; 17 | } 18 | --------------------------------------------------------------------------------