From 9e1309ab7c1a137324c88c272c5a76c4c8bce016 Mon Sep 17 00:00:00 2001 From: Shaked Flur Date: Thu, 30 Nov 2017 15:40:43 +0000 Subject: match what rmem (ppcmem2) expects from ISA Makefiles --- mips/Makefile | 23 + mips/mips_extras.lem | 14 +- risc-v/Makefile | 24 +- risc-v/riscv_extras.lem | 12 +- x86/Makefile | 23 +- x86/gen/ast.hgen | 26 ++ x86/gen/fold.hgen | 26 ++ x86/gen/herdtools_ast_to_shallow_ast.hgen | 28 ++ x86/gen/herdtools_types_to_shallow_types.hgen | 93 ++++ x86/gen/lexer.hgen | 399 +++++++++++++++++ x86/gen/lexer_intel.hgen | 161 +++++++ x86/gen/map.hgen | 26 ++ x86/gen/parser.hgen | 600 +++++++++++++++++++++++++ x86/gen/parser_intel.hgen | 601 ++++++++++++++++++++++++++ x86/gen/pretty.hgen | 50 +++ x86/gen/sail_trans_out.hgen | 1 + x86/gen/shallow_ast_to_herdtools_ast.hgen | 27 ++ x86/gen/shallow_types_to_herdtools_types.hgen | 97 +++++ x86/gen/token_types.hgen | 29 ++ x86/gen/tokens.hgen | 28 ++ x86/gen/trans_sail.hgen | 28 ++ x86/gen/types.hgen | 134 ++++++ x86/gen/types_sail_trans_out.hgen | 1 + x86/gen/types_trans_sail.hgen | 61 +++ x86/x86_extras.lem | 53 +++ x86/x86_extras_embed.lem | 24 + x86/x86_extras_embed_sequential.lem | 24 + 27 files changed, 2589 insertions(+), 24 deletions(-) create mode 100644 mips/Makefile create mode 100644 x86/gen/ast.hgen create mode 100644 x86/gen/fold.hgen create mode 100644 x86/gen/herdtools_ast_to_shallow_ast.hgen create mode 100644 x86/gen/herdtools_types_to_shallow_types.hgen create mode 100644 x86/gen/lexer.hgen create mode 100644 x86/gen/lexer_intel.hgen create mode 100644 x86/gen/map.hgen create mode 100644 x86/gen/parser.hgen create mode 100644 x86/gen/parser_intel.hgen create mode 100644 x86/gen/pretty.hgen create mode 100644 x86/gen/sail_trans_out.hgen create mode 100644 x86/gen/shallow_ast_to_herdtools_ast.hgen create mode 100644 x86/gen/shallow_types_to_herdtools_types.hgen create mode 100644 x86/gen/token_types.hgen create mode 100644 x86/gen/tokens.hgen create mode 100644 x86/gen/trans_sail.hgen create mode 100644 x86/gen/types.hgen create mode 100644 x86/gen/types_sail_trans_out.hgen create mode 100644 x86/gen/types_trans_sail.hgen create mode 100644 x86/x86_extras.lem create mode 100644 x86/x86_extras_embed.lem create mode 100644 x86/x86_extras_embed_sequential.lem diff --git a/mips/Makefile b/mips/Makefile new file mode 100644 index 00000000..03d7ae15 --- /dev/null +++ b/mips/Makefile @@ -0,0 +1,23 @@ +SAIL:=../src/sail.native +LEM:=../../lem/lem + +# SOURCES:=mips_prelude.sail mips_tlb.sail mips_wrappers.sail mips_insts.sail mips_ri.sail mips_epilogue.sail ../etc/regfp.sail mips_regfp.sail +SOURCES:=mips_prelude.sail mips_tlb_stub.sail mips_wrappers.sail mips_insts.sail mips_epilogue.sail ../etc/regfp.sail mips_regfp.sail + + +all: mips.lem mips.ml mips_embed.lem + +mips.lem: $(SOURCES) + $(SAIL) -lem_ast -o $(BUILD)/mips $(SOURCES) + +mips.ml: mips.lem ../src/lem_interp/interp_ast.lem + $(LEM) -ocaml -lib ../src/lem_interp/ $< + + +mips_embed.lem: $(SOURCES) +# also generates mips_embed_sequential.lem, mips_embed_types.lem, mips_toFromInterp.lem + $(SAIL) -lem -lem_lib Mips_extras_embed -o mips $(SOURCES) + +clean: + rm -f mips.lem mips.ml + rm -f mips_embed*.lem mips_toFromInterp.lem diff --git a/mips/mips_extras.lem b/mips/mips_extras.lem index 1fbba038..be576fb2 100644 --- a/mips/mips_extras.lem +++ b/mips/mips_extras.lem @@ -31,25 +31,25 @@ let memory_parameter_transformer_option_address _mode v = end -let read_memory_functions : memory_reads = +let mips_read_memory_functions : memory_reads = [ ("MEMr", (MR Read_plain memory_parameter_transformer)); ("MEMr_reserve", (MR Read_reserve memory_parameter_transformer)); ] -let read_memory_tagged_functions : memory_read_taggeds = +let mips_read_memory_tagged_functions : memory_read_taggeds = [ ("MEMr_tag", (MRT Read_plain memory_parameter_transformer)); ("MEMr_tag_reserve", (MRT Read_reserve memory_parameter_transformer)); ] -let memory_writes : memory_writes = +let mips_memory_writes : memory_writes = [] -let memory_eas : memory_write_eas = +let mips_memory_eas : memory_write_eas = [ ("MEMea", (MEA Write_plain memory_parameter_transformer)); ("MEMea_conditional", (MEA Write_conditional memory_parameter_transformer)); ] -let memory_vals : memory_write_vals = +let mips_memory_vals : memory_write_vals = [ ("MEMval", (MV memory_parameter_transformer_option_address Nothing)); ("MEMval_conditional", (MV memory_parameter_transformer_option_address (Just @@ -58,7 +58,7 @@ let memory_vals : memory_write_vals = (IState (Interp.add_answer_to_stack interp bit) context))))); ] -let memory_vals_tagged : memory_write_vals_tagged = +let mips_memory_vals_tagged : memory_write_vals_tagged = [ ("MEMval_tag", (MVT memory_parameter_transformer_option_address Nothing)); ("MEMval_tag_conditional", (MVT memory_parameter_transformer_option_address @@ -68,6 +68,6 @@ let memory_vals_tagged : memory_write_vals_tagged = (IState (Interp.add_answer_to_stack interp bit) context))))); ] -let barrier_functions = [ +let mips_barrier_functions = [ ("MEM_sync", Barrier_MIPS_SYNC); ] diff --git a/risc-v/Makefile b/risc-v/Makefile index 8449c7c4..bc46e4c2 100644 --- a/risc-v/Makefile +++ b/risc-v/Makefile @@ -1,14 +1,22 @@ - SAIL:=../src/sail.native +LEM:=../../lem/lem + SOURCES:=riscv_types.sail riscv.sail ../etc/regfp.sail riscv_regfp.sail -all: lem_ast shallow -lem_ast: $(SOURCES) $(SAIL) - $(SAIL) -lem_ast $(SOURCES) -o riscv -shallow: $(SOURCES) $(SAIL) - $(SAIL) -lem_lib Riscv_extras_embed -lem $(SOURCES) -o riscv +all: riscv.lem riscv.ml riscv_embed.lem + +riscv.lem: $(SOURCES) + $(SAIL) -lem_ast -o riscv $(SOURCES) + +riscv.ml: riscv.lem ../src/lem_interp/interp_ast.lem + $(LEM) -ocaml -lib ../src/lem_interp/ $< + + +riscv_embed.lem: $(SOURCES) +# also generates riscv_embed_sequential.lem, riscv_embed_types.lem, riscv_toFromInterp.lem + $(SAIL) -lem -lem_lib Riscv_extras_embed -o riscv $(SOURCES) clean: - rm -f riscv.lem riscv_embed*.lem riscv_toFromInterp.lem - rm -f riscv_type*.lem + rm -f riscv.lem riscv.ml + rm -f riscv_embed*.lem riscv_toFromInterp.lem diff --git a/risc-v/riscv_extras.lem b/risc-v/riscv_extras.lem index 30043779..4ca5f9b7 100644 --- a/risc-v/riscv_extras.lem +++ b/risc-v/riscv_extras.lem @@ -31,7 +31,7 @@ let memory_parameter_transformer_option_address _mode v = end -let read_memory_functions : memory_reads = +let riscv_read_memory_functions : memory_reads = [ ("MEMr", (MR Read_plain memory_parameter_transformer)); ("MEMr_acquire", (MR Read_RISCV_acquire memory_parameter_transformer)); ("MEMr_strong_acquire", (MR Read_RISCV_strong_acquire memory_parameter_transformer)); @@ -41,10 +41,10 @@ let read_memory_functions : memory_reads = (MR Read_RISCV_reserved_acquire memory_parameter_transformer)); ] -let memory_writes : memory_writes = +let riscv_memory_writes : memory_writes = [] -let memory_eas : memory_write_eas = +let riscv_memory_eas : memory_write_eas = [ ("MEMea", (MEA Write_plain memory_parameter_transformer)); ("MEMea_release", (MEA Write_RISCV_release memory_parameter_transformer)); ("MEMea_strong_release", (MEA Write_RISCV_strong_release memory_parameter_transformer)); @@ -55,7 +55,7 @@ let memory_eas : memory_write_eas = memory_parameter_transformer)); ] -let memory_vals : memory_write_vals = +let riscv_memory_vals : memory_write_vals = [ ("MEMval", (MV memory_parameter_transformer_option_address Nothing)); ("MEMval_release", (MV memory_parameter_transformer_option_address Nothing)); ("MEMval_strong_release", (MV memory_parameter_transformer_option_address Nothing)); @@ -66,14 +66,14 @@ let memory_vals : memory_write_vals = ] -let speculate_conditional_success : excl_res = +let riscv_speculate_conditional_success : excl_res = let f = fun (IState interp context) b -> let bool_res = Interp_ast.V_lit (L_aux (if b then L_one else L_zero) Interp_ast.Unknown) in IState (Interp.add_answer_to_stack interp bool_res) context in Just ("speculate_conditional_success", (ER (Just f))) -let barrier_functions = +let riscv_barrier_functions = [ ("MEM_fence_rw_rw", Barrier_RISCV_rw_rw); ("MEM_fence_r_rw", Barrier_RISCV_r_rw); ("MEM_fence_r_r", Barrier_RISCV_r_r); diff --git a/x86/Makefile b/x86/Makefile index 2bc4c1a4..6863714d 100644 --- a/x86/Makefile +++ b/x86/Makefile @@ -1,3 +1,20 @@ -all: - ../src/sail.native -o x86 -lem -lem_lib X86_extras_embed ../etc/regfp.sail x64.sail - ../src/sail.native -o x86 -lem_ast ../etc/regfp.sail x64.sail +SAIL=../src/sail.native +LEM:=../../lem/lem + +SOURCES=../etc/regfp.sail x64.sail + +all: x86.lem x86.ml x86_embed.lem + +x86.lem: + $(SAIL) -lem_ast -o x86 $(SOURCES) + +x86.ml: x86.lem ../src/lem_interp/interp_ast.lem + $(LEM) -ocaml -lib ../src/lem_interp/ $< + +x86_embed.lem: $(SOURCES) +# also generates x86_embed_sequential.lem, x86_embed_types.lem, x86_toFromInterp.lem + $(SAIL) -lem -lem_lib X86_extras_embed -o x86 $(SOURCES) + +clean: + rm -f x86.lem x86.ml + rm -f x86_embed*.lem x86_toFromInterp.lem diff --git a/x86/gen/ast.hgen b/x86/gen/ast.hgen new file mode 100644 index 00000000..83488eda --- /dev/null +++ b/x86/gen/ast.hgen @@ -0,0 +1,26 @@ +| `X86BINOP of bool * x86Binop * x86Size * x86Dest_src +| `X86BITOP of bool * x86Bitop * x86Size * x86Bit_offset +| `X86CALL of x86Imm_rm +| `X86CLC +| `X86CMC +| `X86CMPXCHG of bool * x86Size * x86Rm * reg +| `X86DIV of x86Size * x86Rm +| `X86JCC of x86Cond * bit64 +| `X86JMP of x86Rm +| `X86LEA of x86Size * x86Dest_src +| `X86LEAVE +| `X86LOOP of x86Cond * bit64 +| `X86MFENCE +| `X86MONOP of bool * x86Monop * x86Size * x86Rm +| `X86MOV of x86Cond * x86Size * x86Dest_src +| `X86MOVSX of x86Size * x86Dest_src * x86Size +| `X86MOVZX of x86Size * x86Dest_src * x86Size +| `X86MUL of x86Size * x86Rm +| `X86NOP +| `X86POP of x86Rm +| `X86PUSH of x86Imm_rm +| `X86RET of bit64 +| `X86SET of x86Cond * bool * x86Rm +| `X86STC +| `X86XADD of bool * x86Size * x86Rm * reg +| `X86XCHG of bool * x86Size * x86Rm * reg diff --git a/x86/gen/fold.hgen b/x86/gen/fold.hgen new file mode 100644 index 00000000..df546a13 --- /dev/null +++ b/x86/gen/fold.hgen @@ -0,0 +1,26 @@ +| `X86BINOP (_, _, _, ds) -> fold_dest_src ds c +| `X86BITOP (_, _, _, bo) -> fold_bit_offset bo c +| `X86CALL irm -> fold_imm_rm irm c +| `X86CLC -> c +| `X86CMC -> c +| `X86CMPXCHG (_, _, rm, r) -> fold_rm rm (fold_reg r c) +| `X86DIV (_, rm) -> fold_rm rm c +| `X86JCC _ -> c +| `X86JMP rm -> fold_rm rm c +| `X86LEA (_, ds) -> fold_dest_src ds c +| `X86LEAVE -> c +| `X86LOOP _ -> c +| `X86MFENCE -> c +| `X86MONOP (_, _, _, rm) -> fold_rm rm c +| `X86MOV (_, _, ds) -> fold_dest_src ds c +| `X86MOVSX (_, ds, _) -> fold_dest_src ds c +| `X86MOVZX (_, ds, _) -> fold_dest_src ds c +| `X86MUL (_, rm) -> fold_rm rm c +| `X86NOP -> c +| `X86POP rm -> fold_rm rm c +| `X86PUSH irm -> fold_imm_rm irm c +| `X86RET _ -> c +| `X86SET (_, _, rm) -> fold_rm rm c +| `X86STC -> c +| `X86XADD (_, _, rm, r) -> fold_rm rm (fold_reg r c) +| `X86XCHG (_, _, rm, r) -> fold_rm rm (fold_reg r c) diff --git a/x86/gen/herdtools_ast_to_shallow_ast.hgen b/x86/gen/herdtools_ast_to_shallow_ast.hgen new file mode 100644 index 00000000..c709ee6c --- /dev/null +++ b/x86/gen/herdtools_ast_to_shallow_ast.hgen @@ -0,0 +1,28 @@ +| `X86BINOP(locked, binop, sz, dest_src) -> Binop (translate_bool locked, translate_binop binop, translate_size sz, translate_dest_src dest_src) +| `X86BITOP(locked, op, sz, bo) -> Bitop (translate_bool locked, translate_bitop op, translate_size sz, translate_bitoffset bo) +| `X86CALL (imm_rm) -> CALL (translate_imm_rm imm_rm) +| `X86CLC -> CLC +| `X86CMC -> CMC +| `X86CMPXCHG (locked, sz, rm , reg) -> CMPXCHG (translate_bool locked, translate_size sz, translate_rm rm, translate_reg reg) +| `X86DIV (sz, rm) -> X86_DIV (translate_size sz, translate_rm rm) +| `X86StopFetching -> HLT +| `X86JCC (cond, imm64) -> Jcc (translate_cond cond, translate_imm64 imm64) +| `X86JMP (rm) -> JMP (translate_rm rm) +| `X86LEA (sz, dest_src) -> LEA (translate_size sz, translate_dest_src dest_src) +| `X86LEAVE -> LEAVE +| `X86LOOP (cond, imm64) -> LOOP (translate_cond cond, translate_imm64 imm64) +| `X86MFENCE -> MFENCE +| `X86MONOP (locked, monop, sz, rm) -> Monop (translate_bool locked, translate_monop monop, translate_size sz, translate_rm rm) +| `X86MOV (cond, sz, dest_src) -> MOV (translate_cond cond, translate_size sz, translate_dest_src dest_src) +| `X86MOVSX (sz1, dest_src, sz2) -> MOVSX (translate_size sz1, translate_dest_src dest_src, translate_size sz2) +| `X86MOVZX (sz1, dest_src, sz2) -> MOVZX (translate_size sz1, translate_dest_src dest_src, translate_size sz2) +| `X86MUL (sz, rm) -> X86_MUL (translate_size sz, translate_rm rm) +| `X86NOP -> NOP (Nat_big_num.of_int 0) +| `X86POP (rm) -> POP (translate_rm rm) +| `X86PUSH (imm_rm) -> PUSH (translate_imm_rm imm_rm) +| `X86RET (imm64) -> RET (translate_imm64 imm64) +| `X86SET (cond, b, rm) -> SET (translate_cond cond, translate_bool b, translate_rm rm) +| `X86STC -> STC +| `X86XADD (locked, sz, rm, reg) -> XADD (translate_bool locked, translate_size sz, translate_rm rm, translate_reg reg) +| `X86XCHG (locked, sz, rm, reg) -> XCHG (translate_bool locked, translate_size sz, translate_rm rm, translate_reg reg) + diff --git a/x86/gen/herdtools_types_to_shallow_types.hgen b/x86/gen/herdtools_types_to_shallow_types.hgen new file mode 100644 index 00000000..44e16991 --- /dev/null +++ b/x86/gen/herdtools_types_to_shallow_types.hgen @@ -0,0 +1,93 @@ +let is_inc = false + +let translate_bool = function + | true -> Sail_values.B1 + | false -> Sail_values.B0 + +let translate_binop = function + | X86ADD -> X86_Add + | X86OR -> X86_Or + | X86ADC -> X86_Adc + | X86SBB -> X86_Sbb + | X86AND -> X86_And + | X86SUB -> X86_Sub + | X86XOR -> X86_Xor + | X86CMP -> X86_Cmp + | X86ROL -> X86_Rol + | X86ROR -> X86_Ror + | X86RCL -> X86_Rcl + | X86RCR -> X86_Rcr + | X86SHL -> X86_Shl + | X86SHR -> X86_Shr + | X86TEST -> X86_Test + | X86SAR -> X86_Sar + +let translate_bitop = function + | X86Btc -> Btc + | X86Bts -> Bts + | X86Btr -> Btr + +let translate_size = function + | X86S8(high) -> Sz8 (translate_bool high) + | X86S16 -> Sz16 + | X86S32 -> Sz32 + | X86S64 -> Sz64 + +let translate_reg r = Nat_big_num.of_int (reg_to_int r) + +let translate_scale s = + Sail_values.to_vec0 is_inc (Nat_big_num.of_int 2, Nat_big_num.of_int s) + +let translate_imm64 i = Sail_values.to_vec0 is_inc (Nat_big_num.of_int 64, i) + +let translate_msi = function + | Some (scale, reg) -> Some (translate_scale scale, translate_reg reg) + | None -> None + +let translate_base = function + | X86HGenBase.NoBase -> X86_embed_types.NoBase + | X86HGenBase.RegBase(r) -> X86_embed_types.RegBase (translate_reg r) + | X86HGenBase.RipBase -> X86_embed_types.RipBase + +let translate_rm = function + | X86HGenBase.Reg (r) -> X86_embed_types.X86_Reg (translate_reg r) + | X86HGenBase.Mem (m_si, base, imm) -> X86_embed_types.Mem (translate_msi m_si, translate_base base, translate_imm64 imm) + | X86HGenBase.Sym (s) -> X86_embed_types.Mem (None, X86_embed_types.NoBase, translate_imm64 Nat_big_num.zero) + +let translate_dest_src = function + | X86HGenBase.R_rm (reg, rm) -> X86_embed_types.R_rm (translate_reg reg, translate_rm rm) + | X86HGenBase.Rm_i (rm, imm64) -> X86_embed_types.Rm_i (translate_rm rm, translate_imm64 imm64) + | X86HGenBase.Rm_r (rm, reg) -> X86_embed_types.Rm_r (translate_rm rm, translate_reg reg) + +let translate_imm_rm = function + | X86HGenBase.Imm (imm) -> X86_embed_types.Imm (translate_imm64 imm) + | X86HGenBase.Rm (rm) -> X86_embed_types.Rm (translate_rm rm) + +let translate_bitoffset = function + | X86HGenBase.Bit_rm_imm (rm, imm) -> Bit_rm_imm (translate_rm rm, translate_imm64 (Nat_big_num.of_int imm)) + | X86HGenBase.Bit_rm_r (rm, r) -> Bit_rm_r (translate_rm rm, translate_reg r) + +let translate_cond = function + | X86O -> X86_O + | X86NO -> X86_NO + | X86B -> X86_B + | X86NB -> X86_NB + | X86E -> X86_E + | X86NE -> X86_NE + | X86NA -> X86_NA + | X86A -> X86_A + | X86S -> X86_S + | X86NS -> X86_NS + | X86P -> X86_P + | X86NP -> X86_NP + | X86L -> X86_L + | X86NL -> X86_NL + | X86NG -> X86_NG + | X86G -> X86_G + | X86ALWAYS -> X86_ALWAYS + +let translate_monop = function + | X86DEC -> X86_Dec + | X86INC -> X86_Inc + | X86NOT -> X86_Not + | X86NEG -> X86_Neg diff --git a/x86/gen/lexer.hgen b/x86/gen/lexer.hgen new file mode 100644 index 00000000..56944e6d --- /dev/null +++ b/x86/gen/lexer.hgen @@ -0,0 +1,399 @@ +"addb" , BINOP { txt = "ADDB"; op = X86ADD; sz = X86BYTE }; +"orb" , BINOP { txt = "ORB"; op = X86OR; sz = X86BYTE }; +"adcb" , BINOP { txt = "ADCB"; op = X86ADC; sz = X86BYTE }; +"sbbb" , BINOP { txt = "SBBB"; op = X86SBB; sz = X86BYTE }; +"andb" , BINOP { txt = "ANDB"; op = X86AND; sz = X86BYTE }; +"subb" , BINOP { txt = "SUBB"; op = X86SUB; sz = X86BYTE }; +"xorb" , BINOP { txt = "XORB"; op = X86XOR; sz = X86BYTE }; +"cmpb" , BINOP { txt = "CMPB"; op = X86CMP; sz = X86BYTE }; +"rolb" , BINOP { txt = "ROLB"; op = X86ROL; sz = X86BYTE }; +"rorb" , BINOP { txt = "RORB"; op = X86ROR; sz = X86BYTE }; +"shlb" , BINOP { txt = "SHLB"; op = X86SHL; sz = X86BYTE }; +"shrb" , BINOP { txt = "SHRB"; op = X86SHR; sz = X86BYTE }; +"testb" , BINOP { txt = "TESTB"; op = X86TEST; sz = X86BYTE }; +"sarb" , BINOP { txt = "SARB"; op = X86SAR; sz = X86BYTE }; +"addw" , BINOP { txt = "ADDW"; op = X86ADD; sz = X86WORD }; +"orw" , BINOP { txt = "ORW"; op = X86OR; sz = X86WORD }; +"adcw" , BINOP { txt = "ADCW"; op = X86ADC; sz = X86WORD }; +"sbbw" , BINOP { txt = "SBBW"; op = X86SBB; sz = X86WORD }; +"andw" , BINOP { txt = "ANDW"; op = X86AND; sz = X86WORD }; +"subw" , BINOP { txt = "SUBW"; op = X86SUB; sz = X86WORD }; +"xorw" , BINOP { txt = "XORW"; op = X86XOR; sz = X86WORD }; +"cmpw" , BINOP { txt = "CMPW"; op = X86CMP; sz = X86WORD }; +"rolw" , BINOP { txt = "ROLW"; op = X86ROL; sz = X86WORD }; +"rorw" , BINOP { txt = "RORW"; op = X86ROR; sz = X86WORD }; +"shlw" , BINOP { txt = "SHLW"; op = X86SHL; sz = X86WORD }; +"shrw" , BINOP { txt = "SHRW"; op = X86SHR; sz = X86WORD }; +"testw" , BINOP { txt = "TESTW"; op = X86TEST; sz = X86WORD }; +"sarw" , BINOP { txt = "SARW"; op = X86SAR; sz = X86WORD }; +"addl" , BINOP { txt = "ADDL"; op = X86ADD; sz = X86LONG }; +"orl" , BINOP { txt = "ORL"; op = X86OR; sz = X86LONG }; +"adcl" , BINOP { txt = "ADCL"; op = X86ADC; sz = X86LONG }; +"sbbl" , BINOP { txt = "SBBL"; op = X86SBB; sz = X86LONG }; +"andl" , BINOP { txt = "ANDL"; op = X86AND; sz = X86LONG }; +"subl" , BINOP { txt = "SUBL"; op = X86SUB; sz = X86LONG }; +"xorl" , BINOP { txt = "XORL"; op = X86XOR; sz = X86LONG }; +"cmpl" , BINOP { txt = "CMPL"; op = X86CMP; sz = X86LONG }; +"roll" , BINOP { txt = "ROLL"; op = X86ROL; sz = X86LONG }; +"rorl" , BINOP { txt = "RORL"; op = X86ROR; sz = X86LONG }; +"shll" , BINOP { txt = "SHLL"; op = X86SHL; sz = X86LONG }; +"shrl" , BINOP { txt = "SHRL"; op = X86SHR; sz = X86LONG }; +"testl" , BINOP { txt = "TESTL"; op = X86TEST; sz = X86LONG }; +"sarl" , BINOP { txt = "SARL"; op = X86SAR; sz = X86LONG }; +"addq" , BINOP { txt = "ADDQ"; op = X86ADD; sz = X86QUAD }; +"orq" , BINOP { txt = "ORQ"; op = X86OR; sz = X86QUAD }; +"adcq" , BINOP { txt = "ADCQ"; op = X86ADC; sz = X86QUAD }; +"sbbq" , BINOP { txt = "SBBQ"; op = X86SBB; sz = X86QUAD }; +"andq" , BINOP { txt = "ANDQ"; op = X86AND; sz = X86QUAD }; +"subq" , BINOP { txt = "SUBQ"; op = X86SUB; sz = X86QUAD }; +"xorq" , BINOP { txt = "XORQ"; op = X86XOR; sz = X86QUAD }; +"cmpq" , BINOP { txt = "CMPQ"; op = X86CMP; sz = X86QUAD }; +"rolq" , BINOP { txt = "ROLQ"; op = X86ROL; sz = X86QUAD }; +"rorq" , BINOP { txt = "RORQ"; op = X86ROR; sz = X86QUAD }; +"shlq" , BINOP { txt = "SHLQ"; op = X86SHL; sz = X86QUAD }; +"shrq" , BINOP { txt = "SHRQ"; op = X86SHR; sz = X86QUAD }; +"testq" , BINOP { txt = "TESTQ"; op = X86TEST; sz = X86QUAD }; +"sarq" , BINOP { txt = "SARQ"; op = X86SAR; sz = X86QUAD }; +"add" , BINOP { txt = "ADDQ"; op = X86ADD; sz = X86NONE }; +"or" , BINOP { txt = "OR"; op = X86OR; sz = X86NONE }; +"adc" , BINOP { txt = "ADC"; op = X86ADC; sz = X86NONE }; +"sbb" , BINOP { txt = "SBB"; op = X86SBB; sz = X86NONE }; +"and" , BINOP { txt = "AND"; op = X86AND; sz = X86NONE }; +"sub" , BINOP { txt = "SUB"; op = X86SUB; sz = X86NONE }; +"xor" , BINOP { txt = "XOR"; op = X86XOR; sz = X86NONE }; +"cmp" , BINOP { txt = "CMP"; op = X86CMP; sz = X86NONE }; +"rol" , BINOP { txt = "ROL"; op = X86ROL; sz = X86NONE }; +"ror" , BINOP { txt = "ROR"; op = X86ROR; sz = X86NONE }; +"shl" , BINOP { txt = "SHL"; op = X86SHL; sz = X86NONE }; +"shr" , BINOP { txt = "SHR"; op = X86SHR; sz = X86NONE }; +"test" , BINOP { txt = "TEST"; op = X86TEST; sz = X86NONE }; +"sar" , BINOP { txt = "SAR"; op = X86SAR; sz = X86NONE }; +"btcw" , BITOP { txt = "BTSW"; op = X86Btc; sz = X86WORD }; +"btsw" , BITOP { txt = "BTCW"; op = X86Bts; sz = X86WORD }; +"btrw" , BITOP { txt = "BTRW"; op = X86Btr; sz = X86WORD }; +"btcl" , BITOP { txt = "BTSL"; op = X86Btc; sz = X86LONG }; +"btsl" , BITOP { txt = "BTCL"; op = X86Bts; sz = X86LONG }; +"btrl" , BITOP { txt = "BTRL"; op = X86Btr; sz = X86LONG }; +"btcq" , BITOP { txt = "BTSQ"; op = X86Btc; sz = X86QUAD }; +"btsq" , BITOP { txt = "BTCQ"; op = X86Bts; sz = X86QUAD }; +"btrq" , BITOP { txt = "BTRQ"; op = X86Btr; sz = X86QUAD }; +"btc" , BITOP { txt = "BTS"; op = X86Btc; sz = X86NONE }; +"bts" , BITOP { txt = "BTC"; op = X86Bts; sz = X86NONE }; +"btr" , BITOP { txt = "BTR"; op = X86Btr; sz = X86NONE }; +"call" , CALL { txt = "CALL" }; +"clc" , CLC { txt = "CLC" }; +"cmc" , CMC { txt = "CMC" }; +"cmpxchgb" , CMPXCHG { txt = "CMPXCHGB"; sz = X86BYTE }; +"cmpxchgw" , CMPXCHG { txt = "CMPXCHGW"; sz = X86WORD }; +"cmpxchgl" , CMPXCHG { txt = "CMPXCHGL"; sz = X86LONG }; +"cmpxchgq" , CMPXCHG { txt = "CMPXCHGQ"; sz = X86QUAD }; +"cmpxchg" , CMPXCHG { txt = "CMPXCHG"; sz = X86NONE }; +"divb" , DIV { txt = "DIVB"; sz = X86BYTE }; +"divw" , DIV { txt = "DIVW"; sz = X86WORD }; +"divl" , DIV { txt = "DIVL"; sz = X86LONG }; +"divq" , DIV { txt = "DIVQ"; sz = X86QUAD }; +"div" , DIV { txt = "DIV"; sz = X86NONE }; +"jo" , JCC { txt = "JO"; cond = X86O }; +"jb" , JCC { txt = "JB"; cond = X86B }; +"jc" , JCC { txt = "JC"; cond = X86B }; +"jnae" , JCC { txt = "JNAE"; cond = X86B }; +"je" , JCC { txt = "JE"; cond = X86E }; +"jz" , JCC { txt = "JZ"; cond = X86E }; +"ja" , JCC { txt = "JA"; cond = X86A }; +"jnbe" , JCC { txt = "JNBE"; cond = X86A }; +"js" , JCC { txt = "JS"; cond = X86S }; +"jp" , JCC { txt = "JP"; cond = X86P }; +"jpe" , JCC { txt = "JPE"; cond = X86P }; +"jl" , JCC { txt = "JL"; cond = X86L }; +"jnge" , JCC { txt = "JNGE"; cond = X86L }; +"jg" , JCC { txt = "JG"; cond = X86G }; +"jnle" , JCC { txt = "JNLE"; cond = X86G }; +"jno" , JCC { txt = "JNO"; cond = X86NO }; +"jnb" , JCC { txt = "JNB"; cond = X86NB }; +"jnc" , JCC { txt = "JNC"; cond = X86NB }; +"jae" , JCC { txt = "JAE"; cond = X86NB }; +"jne" , JCC { txt = "JNE"; cond = X86NE }; +"jnz" , JCC { txt = "JNZ"; cond = X86NE }; +"jna" , JCC { txt = "JNA"; cond = X86NA }; +"jbe" , JCC { txt = "JBE"; cond = X86NA }; +"jns" , JCC { txt = "JNS"; cond = X86NS }; +"jnp" , JCC { txt = "JNP"; cond = X86NP }; +"jpo" , JCC { txt = "JPO"; cond = X86NP }; +"jnl" , JCC { txt = "JNL"; cond = X86NL }; +"jge" , JCC { txt = "JGE"; cond = X86NL }; +"jng" , JCC { txt = "JNG"; cond = X86NG }; +"jle" , JCC { txt = "JLE"; cond = X86NG }; +"jmp" , JMP { txt = "JMP" }; +"leaw" , LEA { txt = "LEAW"; sz = X86BYTE }; +"leal" , LEA { txt = "LEAL"; sz = X86LONG }; +"leaq" , LEA { txt = "LEAQ"; sz = X86QUAD }; +"lea" , LEA { txt = "LEA"; sz = X86NONE }; +"leave" , LEAVE { txt = "LEAVE" }; +"loopo" , LOOP { txt = "LOOPO"; cond = X86O }; +"loopb" , LOOP { txt = "LOOPB"; cond = X86B }; +"loopc" , LOOP { txt = "LOOPC"; cond = X86B }; +"loopnae" , LOOP { txt = "LOOPNAE"; cond = X86B }; +"loope" , LOOP { txt = "LOOPE"; cond = X86E }; +"loopz" , LOOP { txt = "LOOPZ"; cond = X86E }; +"loopa" , LOOP { txt = "LOOPA"; cond = X86A }; +"loopnbe" , LOOP { txt = "LOOPNBE"; cond = X86A }; +"loops" , LOOP { txt = "LOOPS"; cond = X86S }; +"loopp" , LOOP { txt = "LOOPP"; cond = X86P }; +"looppe" , LOOP { txt = "LOOPPE"; cond = X86P }; +"loopl" , LOOP { txt = "LOOPL"; cond = X86L }; +"loopnge" , LOOP { txt = "LOOPNGE"; cond = X86L }; +"loopg" , LOOP { txt = "LOOPG"; cond = X86G }; +"loopnle" , LOOP { txt = "LOOPNLE"; cond = X86G }; +"loopno" , LOOP { txt = "LOOPNO"; cond = X86NO }; +"loopnb" , LOOP { txt = "LOOPNB"; cond = X86NB }; +"loopnc" , LOOP { txt = "LOOPNC"; cond = X86NB }; +"loopae" , LOOP { txt = "LOOPAE"; cond = X86NB }; +"loopne" , LOOP { txt = "LOOPNE"; cond = X86NE }; +"loopnz" , LOOP { txt = "LOOPNZ"; cond = X86NE }; +"loopna" , LOOP { txt = "LOOPNA"; cond = X86NA }; +"loopbe" , LOOP { txt = "LOOPBE"; cond = X86NA }; +"loopns" , LOOP { txt = "LOOPNS"; cond = X86NS }; +"loopnp" , LOOP { txt = "LOOPNP"; cond = X86NP }; +"looppo" , LOOP { txt = "LOOPPO"; cond = X86NP }; +"loopnl" , LOOP { txt = "LOOPNL"; cond = X86NL }; +"loopge" , LOOP { txt = "LOOPGE"; cond = X86NL }; +"loopng" , LOOP { txt = "LOOPNG"; cond = X86NG }; +"loople" , LOOP { txt = "LOOPLE"; cond = X86NG }; +"mfence" , MFENCE { txt = "MFENCE" }; +"decb" , MONOP { txt = "DECB"; op = X86DEC; sz = X86BYTE }; +"incb" , MONOP { txt = "INCB"; op = X86INC; sz = X86BYTE }; +"notb" , MONOP { txt = "NOTB"; op = X86NOT; sz = X86BYTE }; +"negb" , MONOP { txt = "NEGB"; op = X86NEG; sz = X86BYTE }; +"decw" , MONOP { txt = "DECW"; op = X86DEC; sz = X86WORD }; +"incw" , MONOP { txt = "INCW"; op = X86INC; sz = X86WORD }; +"notw" , MONOP { txt = "NOTW"; op = X86NOT; sz = X86WORD }; +"negw" , MONOP { txt = "NEGW"; op = X86NEG; sz = X86WORD }; +"decl" , MONOP { txt = "DECL"; op = X86DEC; sz = X86LONG }; +"incl" , MONOP { txt = "INCL"; op = X86INC; sz = X86LONG }; +"notl" , MONOP { txt = "NOTL"; op = X86NOT; sz = X86LONG }; +"negl" , MONOP { txt = "NEGL"; op = X86NEG; sz = X86LONG }; +"decq" , MONOP { txt = "DECQ"; op = X86DEC; sz = X86QUAD }; +"incq" , MONOP { txt = "INCQ"; op = X86INC; sz = X86QUAD }; +"notq" , MONOP { txt = "NOTQ"; op = X86NOT; sz = X86QUAD }; +"negq" , MONOP { txt = "NEGQ"; op = X86NEG; sz = X86QUAD }; +"dec" , MONOP { txt = "DEC"; op = X86DEC; sz = X86NONE }; +"inc" , MONOP { txt = "INC"; op = X86INC; sz = X86NONE }; +"not" , MONOP { txt = "NOT"; op = X86NOT; sz = X86NONE }; +"neg" , MONOP { txt = "NEG"; op = X86NEG; sz = X86NONE }; +"cmovow" , CMOV { txt = "CMOVOW"; cond = X86O; sz = X86WORD }; +"cmovbw" , CMOV { txt = "CMOVBW"; cond = X86B; sz = X86WORD }; +"cmovcw" , CMOV { txt = "CMOVCW"; cond = X86B; sz = X86WORD }; +"cmovnaew" , CMOV { txt = "CMOVNAEW"; cond = X86B; sz = X86WORD }; +"cmovew" , CMOV { txt = "CMOVEW"; cond = X86E; sz = X86WORD }; +"cmovzw" , CMOV { txt = "CMOVZW"; cond = X86E; sz = X86WORD }; +"cmovaw" , CMOV { txt = "CMOVAW"; cond = X86A; sz = X86WORD }; +"cmovnbew" , CMOV { txt = "CMOVNBEW"; cond = X86A; sz = X86WORD }; +"cmovsw" , CMOV { txt = "CMOVSW"; cond = X86S; sz = X86WORD }; +"cmovpw" , CMOV { txt = "CMOVPW"; cond = X86P; sz = X86WORD }; +"cmovpew" , CMOV { txt = "CMOVPEW"; cond = X86P; sz = X86WORD }; +"cmovlw" , CMOV { txt = "CMOVLW"; cond = X86L; sz = X86WORD }; +"cmovngew" , CMOV { txt = "CMOVNGEW"; cond = X86L; sz = X86WORD }; +"cmovgw" , CMOV { txt = "CMOVGW"; cond = X86G; sz = X86WORD }; +"cmovnlew" , CMOV { txt = "CMOVNLEW"; cond = X86G; sz = X86WORD }; +"cmovnow" , CMOV { txt = "CMOVNOW"; cond = X86NO; sz = X86WORD }; +"cmovnbw" , CMOV { txt = "CMOVNBW"; cond = X86NB; sz = X86WORD }; +"cmovncw" , CMOV { txt = "CMOVNCW"; cond = X86NB; sz = X86WORD }; +"cmovaew" , CMOV { txt = "CMOVAEW"; cond = X86NB; sz = X86WORD }; +"cmovnew" , CMOV { txt = "CMOVNEW"; cond = X86NE; sz = X86WORD }; +"cmovnzw" , CMOV { txt = "CMOVNZW"; cond = X86NE; sz = X86WORD }; +"cmovnaw" , CMOV { txt = "CMOVNAW"; cond = X86NA; sz = X86WORD }; +"cmovbew" , CMOV { txt = "CMOVBEW"; cond = X86NA; sz = X86WORD }; +"cmovnsw" , CMOV { txt = "CMOVNSW"; cond = X86NS; sz = X86WORD }; +"cmovnpw" , CMOV { txt = "CMOVNPW"; cond = X86NP; sz = X86WORD }; +"cmovpow" , CMOV { txt = "CMOVPOW"; cond = X86NP; sz = X86WORD }; +"cmovnlw" , CMOV { txt = "CMOVNLW"; cond = X86NL; sz = X86WORD }; +"cmovgew" , CMOV { txt = "CMOVGEW"; cond = X86NL; sz = X86WORD }; +"cmovngw" , CMOV { txt = "CMOVNGW"; cond = X86NG; sz = X86WORD }; +"cmovlew" , CMOV { txt = "CMOVLEW"; cond = X86NG; sz = X86WORD }; +"cmovol" , CMOV { txt = "CMOVOL"; cond = X86O; sz = X86LONG }; +"cmovbl" , CMOV { txt = "CMOVBL"; cond = X86B; sz = X86LONG }; +"cmovcl" , CMOV { txt = "CMOVCL"; cond = X86B; sz = X86LONG }; +"cmovnael" , CMOV { txt = "CMOVNAEL"; cond = X86B; sz = X86LONG }; +"cmovel" , CMOV { txt = "CMOVEL"; cond = X86E; sz = X86LONG }; +"cmovzl" , CMOV { txt = "CMOVZL"; cond = X86E; sz = X86LONG }; +"cmoval" , CMOV { txt = "CMOVAL"; cond = X86A; sz = X86LONG }; +"cmovnbel" , CMOV { txt = "CMOVNBEL"; cond = X86A; sz = X86LONG }; +"cmovsl" , CMOV { txt = "CMOVSL"; cond = X86S; sz = X86LONG }; +"cmovpl" , CMOV { txt = "CMOVPL"; cond = X86P; sz = X86LONG }; +"cmovpel" , CMOV { txt = "CMOVPEL"; cond = X86P; sz = X86LONG }; +"cmovll" , CMOV { txt = "CMOVLL"; cond = X86L; sz = X86LONG }; +"cmovngel" , CMOV { txt = "CMOVNGEL"; cond = X86L; sz = X86LONG }; +"cmovgl" , CMOV { txt = "CMOVGL"; cond = X86G; sz = X86LONG }; +"cmovnlel" , CMOV { txt = "CMOVNLEL"; cond = X86G; sz = X86LONG }; +"cmovnol" , CMOV { txt = "CMOVNOL"; cond = X86NO; sz = X86LONG }; +"cmovnbl" , CMOV { txt = "CMOVNBL"; cond = X86NB; sz = X86LONG }; +"cmovncl" , CMOV { txt = "CMOVNCL"; cond = X86NB; sz = X86LONG }; +"cmovael" , CMOV { txt = "CMOVAEL"; cond = X86NB; sz = X86LONG }; +"cmovnel" , CMOV { txt = "CMOVNEL"; cond = X86NE; sz = X86LONG }; +"cmovnzl" , CMOV { txt = "CMOVNZL"; cond = X86NE; sz = X86LONG }; +"cmovnal" , CMOV { txt = "CMOVNAL"; cond = X86NA; sz = X86LONG }; +"cmovbel" , CMOV { txt = "CMOVBEL"; cond = X86NA; sz = X86LONG }; +"cmovnsl" , CMOV { txt = "CMOVNSL"; cond = X86NS; sz = X86LONG }; +"cmovnpl" , CMOV { txt = "CMOVNPL"; cond = X86NP; sz = X86LONG }; +"cmovpol" , CMOV { txt = "CMOVPOL"; cond = X86NP; sz = X86LONG }; +"cmovnll" , CMOV { txt = "CMOVNLL"; cond = X86NL; sz = X86LONG }; +"cmovgel" , CMOV { txt = "CMOVGEL"; cond = X86NL; sz = X86LONG }; +"cmovngl" , CMOV { txt = "CMOVNGL"; cond = X86NG; sz = X86LONG }; +"cmovlel" , CMOV { txt = "CMOVLEL"; cond = X86NG; sz = X86LONG }; +"cmovoq" , CMOV { txt = "CMOVOQ"; cond = X86O; sz = X86QUAD }; +"cmovbq" , CMOV { txt = "CMOVBQ"; cond = X86B; sz = X86QUAD }; +"cmovcq" , CMOV { txt = "CMOVCQ"; cond = X86B; sz = X86QUAD }; +"cmovnaeq" , CMOV { txt = "CMOVNAEQ"; cond = X86B; sz = X86QUAD }; +"cmoveq" , CMOV { txt = "CMOVEQ"; cond = X86E; sz = X86QUAD }; +"cmovzq" , CMOV { txt = "CMOVZQ"; cond = X86E; sz = X86QUAD }; +"cmovaq" , CMOV { txt = "CMOVAQ"; cond = X86A; sz = X86QUAD }; +"cmovnbeq" , CMOV { txt = "CMOVNBEQ"; cond = X86A; sz = X86QUAD }; +"cmovsq" , CMOV { txt = "CMOVSQ"; cond = X86S; sz = X86QUAD }; +"cmovpq" , CMOV { txt = "CMOVPQ"; cond = X86P; sz = X86QUAD }; +"cmovpeq" , CMOV { txt = "CMOVPEQ"; cond = X86P; sz = X86QUAD }; +"cmovlq" , CMOV { txt = "CMOVLQ"; cond = X86L; sz = X86QUAD }; +"cmovngeq" , CMOV { txt = "CMOVNGEQ"; cond = X86L; sz = X86QUAD }; +"cmovgq" , CMOV { txt = "CMOVGQ"; cond = X86G; sz = X86QUAD }; +"cmovnleq" , CMOV { txt = "CMOVNLEQ"; cond = X86G; sz = X86QUAD }; +"cmovnoq" , CMOV { txt = "CMOVNOQ"; cond = X86NO; sz = X86QUAD }; +"cmovnbq" , CMOV { txt = "CMOVNBQ"; cond = X86NB; sz = X86QUAD }; +"cmovncq" , CMOV { txt = "CMOVNCQ"; cond = X86NB; sz = X86QUAD }; +"cmovaeq" , CMOV { txt = "CMOVAEQ"; cond = X86NB; sz = X86QUAD }; +"cmovneq" , CMOV { txt = "CMOVNEQ"; cond = X86NE; sz = X86QUAD }; +"cmovnzq" , CMOV { txt = "CMOVNZQ"; cond = X86NE; sz = X86QUAD }; +"cmovnaq" , CMOV { txt = "CMOVNAQ"; cond = X86NA; sz = X86QUAD }; +"cmovbeq" , CMOV { txt = "CMOVBEQ"; cond = X86NA; sz = X86QUAD }; +"cmovnsq" , CMOV { txt = "CMOVNSQ"; cond = X86NS; sz = X86QUAD }; +"cmovnpq" , CMOV { txt = "CMOVNPQ"; cond = X86NP; sz = X86QUAD }; +"cmovpoq" , CMOV { txt = "CMOVPOQ"; cond = X86NP; sz = X86QUAD }; +"cmovnlq" , CMOV { txt = "CMOVNLQ"; cond = X86NL; sz = X86QUAD }; +"cmovgeq" , CMOV { txt = "CMOVGEQ"; cond = X86NL; sz = X86QUAD }; +"cmovngq" , CMOV { txt = "CMOVNGQ"; cond = X86NG; sz = X86QUAD }; +"cmovleq" , CMOV { txt = "CMOVLEQ"; cond = X86NG; sz = X86QUAD }; +"cmovo" , CMOV { txt = "CMOVO"; cond = X86O; sz = X86NONE }; +"cmovb" , CMOV { txt = "CMOVB"; cond = X86B; sz = X86NONE }; +"cmovc" , CMOV { txt = "CMOVC"; cond = X86B; sz = X86NONE }; +"cmovnae" , CMOV { txt = "CMOVNAE"; cond = X86B; sz = X86NONE }; +"cmove" , CMOV { txt = "CMOVE"; cond = X86E; sz = X86NONE }; +"cmovz" , CMOV { txt = "CMOVZ"; cond = X86E; sz = X86NONE }; +"cmova" , CMOV { txt = "CMOVA"; cond = X86A; sz = X86NONE }; +"cmovnbe" , CMOV { txt = "CMOVNBE"; cond = X86A; sz = X86NONE }; +"cmovs" , CMOV { txt = "CMOVS"; cond = X86S; sz = X86NONE }; +"cmovp" , CMOV { txt = "CMOVP"; cond = X86P; sz = X86NONE }; +"cmovpe" , CMOV { txt = "CMOVPE"; cond = X86P; sz = X86NONE }; +"cmovl" , CMOV { txt = "CMOVL"; cond = X86L; sz = X86NONE }; +"cmovnge" , CMOV { txt = "CMOVNGE"; cond = X86L; sz = X86NONE }; +"cmovg" , CMOV { txt = "CMOVG"; cond = X86G; sz = X86NONE }; +"cmovnle" , CMOV { txt = "CMOVNLE"; cond = X86G; sz = X86NONE }; +"cmovno" , CMOV { txt = "CMOVNO"; cond = X86NO; sz = X86NONE }; +"cmovnb" , CMOV { txt = "CMOVNB"; cond = X86NB; sz = X86NONE }; +"cmovnc" , CMOV { txt = "CMOVNC"; cond = X86NB; sz = X86NONE }; +"cmovae" , CMOV { txt = "CMOVAE"; cond = X86NB; sz = X86NONE }; +"cmovne" , CMOV { txt = "CMOVNE"; cond = X86NE; sz = X86NONE }; +"cmovnz" , CMOV { txt = "CMOVNZ"; cond = X86NE; sz = X86NONE }; +"cmovna" , CMOV { txt = "CMOVNA"; cond = X86NA; sz = X86NONE }; +"cmovbe" , CMOV { txt = "CMOVBE"; cond = X86NA; sz = X86NONE }; +"cmovns" , CMOV { txt = "CMOVNS"; cond = X86NS; sz = X86NONE }; +"cmovnp" , CMOV { txt = "CMOVNP"; cond = X86NP; sz = X86NONE }; +"cmovpo" , CMOV { txt = "CMOVPO"; cond = X86NP; sz = X86NONE }; +"cmovnl" , CMOV { txt = "CMOVNL"; cond = X86NL; sz = X86NONE }; +"cmovge" , CMOV { txt = "CMOVGE"; cond = X86NL; sz = X86NONE }; +"cmovng" , CMOV { txt = "CMOVNG"; cond = X86NG; sz = X86NONE }; +"cmovle" , CMOV { txt = "CMOVLE"; cond = X86NG; sz = X86NONE }; +"movb" , MOV { txt = "MOVB"; sz = X86BYTE }; +"movw" , MOV { txt = "MOVW"; sz = X86WORD }; +"movl" , MOV { txt = "MOVL"; sz = X86LONG }; +"movq" , MOV { txt = "MOVQ"; sz = X86QUAD }; +"mov" , MOV { txt = "MOV"; sz = X86NONE }; +"movabs" , MOV { txt = "MOVABS"; sz = X86QUAD }; +"movsbw" , MOVSX { txt = "MOVSBW"; sz1 = X86BYTE; sz2 = X86WORD }; +"movsbl" , MOVSX { txt = "MOVSBL"; sz1 = X86BYTE; sz2 = X86LONG }; +"movsbq" , MOVSX { txt = "MOVSBQ"; sz1 = X86BYTE; sz2 = X86QUAD }; +"movswl" , MOVSX { txt = "MOVSWL"; sz1 = X86WORD; sz2 = X86LONG }; +"movswq" , MOVSX { txt = "MOVSWQ"; sz1 = X86WORD; sz2 = X86QUAD }; +"movslq" , MOVSX { txt = "MOVSWQ"; sz1 = X86LONG; sz2 = X86QUAD }; +"movzbw" , MOVZX { txt = "MOVZBW"; sz1 = X86BYTE; sz2 = X86WORD }; +"movzbl" , MOVZX { txt = "MOVZBL"; sz1 = X86BYTE; sz2 = X86LONG }; +"movzbq" , MOVZX { txt = "MOVZBQ"; sz1 = X86BYTE; sz2 = X86QUAD }; +"movzwl" , MOVZX { txt = "MOVZWL"; sz1 = X86WORD; sz2 = X86LONG }; +"movzwq" , MOVZX { txt = "MOVZWQ"; sz1 = X86WORD; sz2 = X86QUAD }; +"mulb" , MUL { txt = "MULB"; sz = X86BYTE }; +"mulw" , MUL { txt = "MULW"; sz = X86WORD }; +"mull" , MUL { txt = "MULL"; sz = X86LONG }; +"mulq" , MUL { txt = "MULQ"; sz = X86QUAD }; +"mul" , MUL { txt = "MUL"; sz = X86NONE }; +"nop" , NOP { txt = "NOP" }; +"pop" , POP { txt = "POP" }; +"push" , PUSH { txt = "PUSH" }; +"ret" , PUSH { txt = "RET" }; +"setob" , SET { txt = "SETOB"; cond = X86O }; +"setbb" , SET { txt = "SETBB"; cond = X86B }; +"setcb" , SET { txt = "SETCB"; cond = X86B }; +"setnaeb" , SET { txt = "SETNAEB"; cond = X86B }; +"seteb" , SET { txt = "SETEB"; cond = X86E }; +"setzb" , SET { txt = "SETZB"; cond = X86E }; +"setab" , SET { txt = "SETAB"; cond = X86A }; +"setnbeb" , SET { txt = "SETNBEB"; cond = X86A }; +"setsb" , SET { txt = "SETSB"; cond = X86S }; +"setpb" , SET { txt = "SETPB"; cond = X86P }; +"setpeb" , SET { txt = "SETPEB"; cond = X86P }; +"setlb" , SET { txt = "SETLB"; cond = X86L }; +"setngeb" , SET { txt = "SETNGEB"; cond = X86L }; +"setgb" , SET { txt = "SETGB"; cond = X86G }; +"setnleb" , SET { txt = "SETNLEB"; cond = X86G }; +"setnob" , SET { txt = "SETNOB"; cond = X86NO }; +"setnbb" , SET { txt = "SETNBB"; cond = X86NB }; +"setncb" , SET { txt = "SETNCB"; cond = X86NB }; +"setaeb" , SET { txt = "SETAEB"; cond = X86NB }; +"setneb" , SET { txt = "SETNEB"; cond = X86NE }; +"setnzb" , SET { txt = "SETNZB"; cond = X86NE }; +"setnab" , SET { txt = "SETNAB"; cond = X86NA }; +"setbeb" , SET { txt = "SETBEB"; cond = X86NA }; +"setnsb" , SET { txt = "SETNSB"; cond = X86NS }; +"setnpb" , SET { txt = "SETNPB"; cond = X86NP }; +"setpob" , SET { txt = "SETPOB"; cond = X86NP }; +"setnlb" , SET { txt = "SETNLB"; cond = X86NL }; +"setgeb" , SET { txt = "SETGEB"; cond = X86NL }; +"setngb" , SET { txt = "SETNGB"; cond = X86NG }; +"setleb" , SET { txt = "SETLEB"; cond = X86NG }; +"seto" , SET { txt = "SETO"; cond = X86O }; +"setb" , SET { txt = "SETB"; cond = X86B }; +"setc" , SET { txt = "SETC"; cond = X86B }; +"setnae" , SET { txt = "SETNAE"; cond = X86B }; +"sete" , SET { txt = "SETE"; cond = X86E }; +"setz" , SET { txt = "SETZ"; cond = X86E }; +"seta" , SET { txt = "SETA"; cond = X86A }; +"setnbe" , SET { txt = "SETNBE"; cond = X86A }; +"sets" , SET { txt = "SETS"; cond = X86S }; +"setp" , SET { txt = "SETP"; cond = X86P }; +"setpe" , SET { txt = "SETPE"; cond = X86P }; +"setl" , SET { txt = "SETL"; cond = X86L }; +"setnge" , SET { txt = "SETNGE"; cond = X86L }; +"setg" , SET { txt = "SETG"; cond = X86G }; +"setnle" , SET { txt = "SETNLE"; cond = X86G }; +"setno" , SET { txt = "SETNO"; cond = X86NO }; +"setnb" , SET { txt = "SETNB"; cond = X86NB }; +"setnc" , SET { txt = "SETNC"; cond = X86NB }; +"setae" , SET { txt = "SETAE"; cond = X86NB }; +"setne" , SET { txt = "SETNE"; cond = X86NE }; +"setnz" , SET { txt = "SETNZ"; cond = X86NE }; +"setna" , SET { txt = "SETNA"; cond = X86NA }; +"setbe" , SET { txt = "SETBE"; cond = X86NA }; +"setns" , SET { txt = "SETNS"; cond = X86NS }; +"setnp" , SET { txt = "SETNP"; cond = X86NP }; +"setpo" , SET { txt = "SETPO"; cond = X86NP }; +"setnl" , SET { txt = "SETNL"; cond = X86NL }; +"setge" , SET { txt = "SETGE"; cond = X86NL }; +"setng" , SET { txt = "SETNG"; cond = X86NG }; +"setle" , SET { txt = "SETLE"; cond = X86NG }; +"stc" , STC { txt = "STC" }; +"xaddb" , XADD { txt = "XADDB"; sz = X86BYTE }; +"xaddw" , XADD { txt = "XADDW"; sz = X86WORD }; +"xaddl" , XADD { txt = "XADDL"; sz = X86LONG }; +"xaddq" , XADD { txt = "XADDQ"; sz = X86QUAD }; +"xadd" , XADD { txt = "XADD"; sz = X86NONE }; +"xchgb" , XCHG { txt = "XCHGB"; sz = X86BYTE }; +"xchgw" , XCHG { txt = "XCHGW"; sz = X86WORD }; +"xchgl" , XCHG { txt = "XCHGL"; sz = X86LONG }; +"xchgq" , XCHG { txt = "XCHGQ"; sz = X86QUAD }; +"xchg" , XCHG { txt = "XCHG"; sz = X86NONE }; diff --git a/x86/gen/lexer_intel.hgen b/x86/gen/lexer_intel.hgen new file mode 100644 index 00000000..e1854a14 --- /dev/null +++ b/x86/gen/lexer_intel.hgen @@ -0,0 +1,161 @@ +"add" , BINOP { txt = "ADDQ"; op = X86ADD; sz = X86NONE }; +"or" , BINOP { txt = "OR"; op = X86OR; sz = X86NONE }; +"adc" , BINOP { txt = "ADC"; op = X86ADC; sz = X86NONE }; +"sbb" , BINOP { txt = "SBB"; op = X86SBB; sz = X86NONE }; +"and" , BINOP { txt = "AND"; op = X86AND; sz = X86NONE }; +"sub" , BINOP { txt = "SUB"; op = X86SUB; sz = X86NONE }; +"xor" , BINOP { txt = "XOR"; op = X86XOR; sz = X86NONE }; +"cmp" , BINOP { txt = "CMP"; op = X86CMP; sz = X86NONE }; +"rol" , BINOP { txt = "ROL"; op = X86ROL; sz = X86NONE }; +"ror" , BINOP { txt = "ROR"; op = X86ROR; sz = X86NONE }; +"shl" , BINOP { txt = "SHL"; op = X86SHL; sz = X86NONE }; +"shr" , BINOP { txt = "SHR"; op = X86SHR; sz = X86NONE }; +"test" , BINOP { txt = "TEST"; op = X86TEST; sz = X86NONE }; +"sar" , BINOP { txt = "SAR"; op = X86SAR; sz = X86NONE }; +"btc" , BITOP { txt = "BTS"; op = X86Btc; sz = X86NONE }; +"bts" , BITOP { txt = "BTC"; op = X86Bts; sz = X86NONE }; +"btr" , BITOP { txt = "BTR"; op = X86Btr; sz = X86NONE }; +"call" , CALL { txt = "CALL" }; +"clc" , CLC { txt = "CLC" }; +"cmc" , CMC { txt = "CMC" }; +"cmpxchg" , CMPXCHG { txt = "CMPXCHG"; sz = X86NONE }; +"div" , DIV { txt = "DIV"; sz = X86NONE }; +"jo" , JCC { txt = "JO"; cond = X86O }; +"jb" , JCC { txt = "JB"; cond = X86B }; +"jc" , JCC { txt = "JC"; cond = X86B }; +"jnae" , JCC { txt = "JNAE"; cond = X86B }; +"je" , JCC { txt = "JE"; cond = X86E }; +"jz" , JCC { txt = "JZ"; cond = X86E }; +"ja" , JCC { txt = "JA"; cond = X86A }; +"jnbe" , JCC { txt = "JNBE"; cond = X86A }; +"js" , JCC { txt = "JS"; cond = X86S }; +"jp" , JCC { txt = "JP"; cond = X86P }; +"jpe" , JCC { txt = "JPE"; cond = X86P }; +"jl" , JCC { txt = "JL"; cond = X86L }; +"jnge" , JCC { txt = "JNGE"; cond = X86L }; +"jg" , JCC { txt = "JG"; cond = X86G }; +"jnle" , JCC { txt = "JNLE"; cond = X86G }; +"jno" , JCC { txt = "JNO"; cond = X86NO }; +"jnb" , JCC { txt = "JNB"; cond = X86NB }; +"jnc" , JCC { txt = "JNC"; cond = X86NB }; +"jae" , JCC { txt = "JAE"; cond = X86NB }; +"jne" , JCC { txt = "JNE"; cond = X86NE }; +"jnz" , JCC { txt = "JNZ"; cond = X86NE }; +"jna" , JCC { txt = "JNA"; cond = X86NA }; +"jbe" , JCC { txt = "JBE"; cond = X86NA }; +"jns" , JCC { txt = "JNS"; cond = X86NS }; +"jnp" , JCC { txt = "JNP"; cond = X86NP }; +"jpo" , JCC { txt = "JPO"; cond = X86NP }; +"jnl" , JCC { txt = "JNL"; cond = X86NL }; +"jge" , JCC { txt = "JGE"; cond = X86NL }; +"jng" , JCC { txt = "JNG"; cond = X86NG }; +"jle" , JCC { txt = "JLE"; cond = X86NG }; +"jmp" , JMP { txt = "JMP" }; +"lea" , LEA { txt = "LEA"; sz = X86NONE }; +"leave" , LEAVE { txt = "LEAVE" }; +"loopo" , LOOP { txt = "LOOPO"; cond = X86O }; +"loopb" , LOOP { txt = "LOOPB"; cond = X86B }; +"loopc" , LOOP { txt = "LOOPC"; cond = X86B }; +"loopnae" , LOOP { txt = "LOOPNAE"; cond = X86B }; +"loope" , LOOP { txt = "LOOPE"; cond = X86E }; +"loopz" , LOOP { txt = "LOOPZ"; cond = X86E }; +"loopa" , LOOP { txt = "LOOPA"; cond = X86A }; +"loopnbe" , LOOP { txt = "LOOPNBE"; cond = X86A }; +"loops" , LOOP { txt = "LOOPS"; cond = X86S }; +"loopp" , LOOP { txt = "LOOPP"; cond = X86P }; +"looppe" , LOOP { txt = "LOOPPE"; cond = X86P }; +"loopl" , LOOP { txt = "LOOPL"; cond = X86L }; +"loopnge" , LOOP { txt = "LOOPNGE"; cond = X86L }; +"loopg" , LOOP { txt = "LOOPG"; cond = X86G }; +"loopnle" , LOOP { txt = "LOOPNLE"; cond = X86G }; +"loopno" , LOOP { txt = "LOOPNO"; cond = X86NO }; +"loopnb" , LOOP { txt = "LOOPNB"; cond = X86NB }; +"loopnc" , LOOP { txt = "LOOPNC"; cond = X86NB }; +"loopae" , LOOP { txt = "LOOPAE"; cond = X86NB }; +"loopne" , LOOP { txt = "LOOPNE"; cond = X86NE }; +"loopnz" , LOOP { txt = "LOOPNZ"; cond = X86NE }; +"loopna" , LOOP { txt = "LOOPNA"; cond = X86NA }; +"loopbe" , LOOP { txt = "LOOPBE"; cond = X86NA }; +"loopns" , LOOP { txt = "LOOPNS"; cond = X86NS }; +"loopnp" , LOOP { txt = "LOOPNP"; cond = X86NP }; +"looppo" , LOOP { txt = "LOOPPO"; cond = X86NP }; +"loopnl" , LOOP { txt = "LOOPNL"; cond = X86NL }; +"loopge" , LOOP { txt = "LOOPGE"; cond = X86NL }; +"loopng" , LOOP { txt = "LOOPNG"; cond = X86NG }; +"loople" , LOOP { txt = "LOOPLE"; cond = X86NG }; +"mfence" , MFENCE { txt = "MFENCE" }; +"dec" , MONOP { txt = "DEC"; op = X86DEC; sz = X86NONE }; +"inc" , MONOP { txt = "INC"; op = X86INC; sz = X86NONE }; +"not" , MONOP { txt = "NOT"; op = X86NOT; sz = X86NONE }; +"neg" , MONOP { txt = "NEG"; op = X86NEG; sz = X86NONE }; +"cmovo" , CMOV { txt = "CMOVO"; cond = X86O; sz = X86NONE }; +"cmovb" , CMOV { txt = "CMOVB"; cond = X86B; sz = X86NONE }; +"cmovc" , CMOV { txt = "CMOVC"; cond = X86B; sz = X86NONE }; +"cmovnae" , CMOV { txt = "CMOVNAE"; cond = X86B; sz = X86NONE }; +"cmove" , CMOV { txt = "CMOVE"; cond = X86E; sz = X86NONE }; +"cmovz" , CMOV { txt = "CMOVZ"; cond = X86E; sz = X86NONE }; +"cmova" , CMOV { txt = "CMOVA"; cond = X86A; sz = X86NONE }; +"cmovnbe" , CMOV { txt = "CMOVNBE"; cond = X86A; sz = X86NONE }; +"cmovs" , CMOV { txt = "CMOVS"; cond = X86S; sz = X86NONE }; +"cmovp" , CMOV { txt = "CMOVP"; cond = X86P; sz = X86NONE }; +"cmovpe" , CMOV { txt = "CMOVPE"; cond = X86P; sz = X86NONE }; +"cmovl" , CMOV { txt = "CMOVL"; cond = X86L; sz = X86NONE }; +"cmovnge" , CMOV { txt = "CMOVNGE"; cond = X86L; sz = X86NONE }; +"cmovg" , CMOV { txt = "CMOVG"; cond = X86G; sz = X86NONE }; +"cmovnle" , CMOV { txt = "CMOVNLE"; cond = X86G; sz = X86NONE }; +"cmovno" , CMOV { txt = "CMOVNO"; cond = X86NO; sz = X86NONE }; +"cmovnb" , CMOV { txt = "CMOVNB"; cond = X86NB; sz = X86NONE }; +"cmovnc" , CMOV { txt = "CMOVNC"; cond = X86NB; sz = X86NONE }; +"cmovae" , CMOV { txt = "CMOVAE"; cond = X86NB; sz = X86NONE }; +"cmovne" , CMOV { txt = "CMOVNE"; cond = X86NE; sz = X86NONE }; +"cmovnz" , CMOV { txt = "CMOVNZ"; cond = X86NE; sz = X86NONE }; +"cmovna" , CMOV { txt = "CMOVNA"; cond = X86NA; sz = X86NONE }; +"cmovbe" , CMOV { txt = "CMOVBE"; cond = X86NA; sz = X86NONE }; +"cmovns" , CMOV { txt = "CMOVNS"; cond = X86NS; sz = X86NONE }; +"cmovnp" , CMOV { txt = "CMOVNP"; cond = X86NP; sz = X86NONE }; +"cmovpo" , CMOV { txt = "CMOVPO"; cond = X86NP; sz = X86NONE }; +"cmovnl" , CMOV { txt = "CMOVNL"; cond = X86NL; sz = X86NONE }; +"cmovge" , CMOV { txt = "CMOVGE"; cond = X86NL; sz = X86NONE }; +"cmovng" , CMOV { txt = "CMOVNG"; cond = X86NG; sz = X86NONE }; +"cmovle" , CMOV { txt = "CMOVLE"; cond = X86NG; sz = X86NONE }; +"mov" , MOV { txt = "MOV"; sz = X86NONE }; +"movsx" , MOVSX { txt = "MOVSBW"; sz1 = X86NONE; sz2 = X86NONE }; +"movzx" , MOVZX { txt = "MOVZBW"; sz1 = X86NONE; sz2 = X86NONE }; +"mul" , MUL { txt = "MUL"; sz = X86NONE }; +"nop" , NOP { txt = "NOP" }; +"pop" , POP { txt = "POP" }; +"push" , PUSH { txt = "PUSH" }; +"ret" , PUSH { txt = "RET" }; +"seto" , SET { txt = "SETO"; cond = X86O }; +"setb" , SET { txt = "SETB"; cond = X86B }; +"setc" , SET { txt = "SETC"; cond = X86B }; +"setnae" , SET { txt = "SETNAE"; cond = X86B }; +"sete" , SET { txt = "SETE"; cond = X86E }; +"setz" , SET { txt = "SETZ"; cond = X86E }; +"seta" , SET { txt = "SETA"; cond = X86A }; +"setnbe" , SET { txt = "SETNBE"; cond = X86A }; +"sets" , SET { txt = "SETS"; cond = X86S }; +"setp" , SET { txt = "SETP"; cond = X86P }; +"setpe" , SET { txt = "SETPE"; cond = X86P }; +"setl" , SET { txt = "SETL"; cond = X86L }; +"setnge" , SET { txt = "SETNGE"; cond = X86L }; +"setg" , SET { txt = "SETG"; cond = X86G }; +"setnle" , SET { txt = "SETNLE"; cond = X86G }; +"setno" , SET { txt = "SETNO"; cond = X86NO }; +"setnb" , SET { txt = "SETNB"; cond = X86NB }; +"setnc" , SET { txt = "SETNC"; cond = X86NB }; +"setae" , SET { txt = "SETAE"; cond = X86NB }; +"setne" , SET { txt = "SETNE"; cond = X86NE }; +"setnz" , SET { txt = "SETNZ"; cond = X86NE }; +"setna" , SET { txt = "SETNA"; cond = X86NA }; +"setbe" , SET { txt = "SETBE"; cond = X86NA }; +"setns" , SET { txt = "SETNS"; cond = X86NS }; +"setnp" , SET { txt = "SETNP"; cond = X86NP }; +"setpo" , SET { txt = "SETPO"; cond = X86NP }; +"setnl" , SET { txt = "SETNL"; cond = X86NL }; +"setge" , SET { txt = "SETGE"; cond = X86NL }; +"setng" , SET { txt = "SETNG"; cond = X86NG }; +"setle" , SET { txt = "SETLE"; cond = X86NG }; +"stc" , STC { txt = "STC" }; +"xadd" , XADD { txt = "XADD"; sz = X86NONE }; +"xchg" , XCHG { txt = "XCHG"; sz = X86NONE }; diff --git a/x86/gen/map.hgen b/x86/gen/map.hgen new file mode 100644 index 00000000..843e8832 --- /dev/null +++ b/x86/gen/map.hgen @@ -0,0 +1,26 @@ +| `X86BINOP (locked, bop, sz, ds) -> `X86BINOP (locked, bop, sz, map_dest_src ds) +| `X86BITOP (locked, bop, sz, bo) -> `X86BITOP (locked, bop, sz, map_bit_offset bo) +| `X86CALL irm -> `X86CALL (map_imm_rm irm) +| `X86CLC -> `X86CLC +| `X86CMC -> `X86CMC +| `X86CMPXCHG (locked, sz, rm, r) -> `X86CMPXCHG (locked, sz, map_rm rm, map_reg r) +| `X86DIV (sz, rm) -> `X86DIV (sz, map_rm rm) +| `X86JCC x -> `X86JCC x +| `X86JMP rm -> `X86JMP (map_rm rm) +| `X86LEA (sz, ds) -> `X86LEA (sz, map_dest_src ds) +| `X86LEAVE -> `X86LEAVE +| `X86LOOP x -> `X86LOOP x +| `X86MFENCE -> `X86MFENCE +| `X86MONOP (locked, mop, sz, rm) -> `X86MONOP (locked, mop, sz, map_rm rm) +| `X86MOV (cnd, sz, ds) -> `X86MOV (cnd, sz, map_dest_src ds) +| `X86MOVSX (sz1, ds, sz2) -> `X86MOVSX (sz1, map_dest_src ds, sz2) +| `X86MOVZX (sz1, ds, sz2) -> `X86MOVZX (sz1, map_dest_src ds, sz2) +| `X86MUL (sz, rm) -> `X86MUL (sz, map_rm rm) +| `X86NOP -> `X86NOP +| `X86POP rm -> `X86POP (map_rm rm) +| `X86PUSH irm -> `X86PUSH (map_imm_rm irm) +| `X86RET i -> `X86RET i +| `X86SET (cnd, b, rm) -> `X86SET (cnd, b, map_rm rm) +| `X86STC -> `X86STC +| `X86XADD (locked, sz, rm, r) -> `X86XADD (locked, sz, map_rm rm, map_reg r) +| `X86XCHG (locked, sz, rm, r) -> `X86XCHG (locked, sz, map_rm rm, map_reg r) diff --git a/x86/gen/parser.hgen b/x86/gen/parser.hgen new file mode 100644 index 00000000..b3c9dc72 --- /dev/null +++ b/x86/gen/parser.hgen @@ -0,0 +1,600 @@ +| BINOP imm COMMA addr + { `X86BINOP (false, $1.op, suffix_size $1.sz, Rm_i ($4, bit64_of_int $2)) } +| LOCK BINOP imm COMMA addr + { check_binop_lockable $2.op + ; `X86BINOP (true, $2.op, suffix_size $2.sz, Rm_i ($5, bit64_of_int $3)) } +| BINOP imm COMMA breg + { check_size ($1.sz, X86BYTE) + ; `X86BINOP (false, $1.op, X86S8 ($4.high), Rm_i (Reg (IReg ($4.reg)), bit64_of_int $2)) + } +| BINOP breg COMMA breg + { check_size ($1.sz, X86BYTE) + ; check_byte_regs ($2, $4) + ; `X86BINOP (false, $1.op, X86S8 ($4.high), Rm_r (Reg (IReg ($4.reg)), IReg ($2.reg))) + } +| BINOP addr COMMA breg + { check_size ($1.sz, X86BYTE) + ; `X86BINOP (false, $1.op, X86S8 ($4.high), R_rm (IReg ($4.reg), $2)) + } +| BINOP breg COMMA addr + { check_size ($1.sz, X86BYTE) + ; `X86BINOP (false, $1.op, X86S8 ($2.high), Rm_r ($4, IReg ($2.reg))) + } +| LOCK BINOP breg COMMA addr + { check_binop_lockable $2.op + ; check_size ($2.sz, X86BYTE) + ; `X86BINOP (true, $2.op, X86S8 ($3.high), Rm_r ($5, IReg ($3.reg))) + } +| BINOP imm COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86BINOP (false, $1.op, X86S16, Rm_i (Reg $4, bit64_of_int $2)) + } +| BINOP wreg COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86BINOP (false, $1.op, X86S16, Rm_r (Reg $4, $2)) + } +| BINOP addr COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86BINOP (false, $1.op, X86S16, R_rm ($4, $2)) + } +| BINOP wreg COMMA addr + { check_size ($1.sz, X86WORD) + ; `X86BINOP (false, $1.op, X86S16, Rm_r ($4, $2)) + } +| LOCK BINOP wreg COMMA addr + { check_binop_lockable $2.op + ; check_size ($2.sz, X86WORD) + ; `X86BINOP (true, $2.op, X86S16, Rm_r ($5, $3)) + } +| BINOP imm COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86BINOP (false, $1.op, X86S32, Rm_i (Reg $4, bit64_of_int $2)) + } +| BINOP lreg COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86BINOP (false, $1.op, X86S32, Rm_r (Reg $4, $2)) + } +| BINOP addr COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86BINOP (false, $1.op, X86S32, R_rm ($4, $2)) + } +| BINOP lreg COMMA addr + { check_size ($1.sz, X86LONG) + ; `X86BINOP (false, $1.op, X86S32, Rm_r ($4, $2)) + } +| LOCK BINOP lreg COMMA addr + { check_binop_lockable $2.op + ; check_size ($2.sz, X86LONG) + ; `X86BINOP (true, $2.op, X86S32, Rm_r ($5, $3)) + } +| BINOP imm COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86BINOP (false, $1.op, X86S64, Rm_i (Reg $4, bit64_of_int $2)) + } +| BINOP qreg COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86BINOP (false, $1.op, X86S64, Rm_r (Reg $4, $2)) + } +| BINOP addr COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86BINOP (false, $1.op, X86S64, R_rm ($4, $2)) + } +| BINOP qreg COMMA addr + { check_size ($1.sz, X86QUAD) + ; `X86BINOP (false, $1.op, X86S64, Rm_r ($4, $2)) + } +| LOCK BINOP qreg COMMA addr + { check_binop_lockable $2.op + ; check_size ($2.sz, X86QUAD) + ; `X86BINOP (true, $2.op, X86S64, Rm_r ($5, $3)) + } +| BITOP imm COMMA addr + { `X86BITOP (false, $1.op, suffix_size $1.sz, Bit_rm_imm ($4, $2)) + } +| LOCK BITOP imm COMMA addr + { `X86BITOP (true, $2.op, suffix_size $2.sz, Bit_rm_imm ($5, $3)) + } +| BITOP imm COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86BITOP (false, $1.op, X86S16, Bit_rm_imm (Reg $4, $2)) + } +| LOCK BITOP imm COMMA wreg + { check_size ($2.sz, X86WORD) + ; `X86BITOP (true, $2.op, X86S16, Bit_rm_imm (Reg $5, $3)) + } +| BITOP wreg COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86BITOP (true, $1.op, X86S16, Bit_rm_r (Reg $4, $2)) + } +| LOCK BITOP wreg COMMA wreg + { check_size ($2.sz, X86WORD) + ; `X86BITOP (false, $2.op, X86S16, Bit_rm_r (Reg $5, $3)) + } +| BITOP wreg COMMA addr + { check_size ($1.sz, X86WORD) + ; `X86BITOP (false, $1.op, X86S16, Bit_rm_r ($4, $2)) + } +| LOCK BITOP wreg COMMA addr + { check_size ($2.sz, X86WORD) + ; `X86BITOP (true, $2.op, X86S16, Bit_rm_r ($5, $3)) + } +| BITOP imm COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86BITOP (false, $1.op, X86S32, Bit_rm_imm (Reg $4, $2)) + } +| LOCK BITOP imm COMMA lreg + { check_size ($2.sz, X86LONG) + ; `X86BITOP (true, $2.op, X86S32, Bit_rm_imm (Reg $5, $3)) + } +| BITOP lreg COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86BITOP (false, $1.op, X86S32, Bit_rm_r (Reg $4, $2)) + } +| LOCK BITOP lreg COMMA lreg + { check_size ($2.sz, X86LONG) + ; `X86BITOP (true, $2.op, X86S32, Bit_rm_r (Reg $5, $3)) + } +| BITOP lreg COMMA addr + { check_size ($1.sz, X86LONG) + ; `X86BITOP (false, $1.op, X86S32, Bit_rm_r ($4, $2)) + } +| LOCK BITOP lreg COMMA addr + { check_size ($2.sz, X86LONG) + ; `X86BITOP (true, $2.op, X86S32, Bit_rm_r ($5, $3)) + } +| BITOP imm COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86BITOP (false, $1.op, X86S64, Bit_rm_imm (Reg $4, $2)) + } +| LOCK BITOP imm COMMA qreg + { check_size ($2.sz, X86QUAD) + ; `X86BITOP (true, $2.op, X86S64, Bit_rm_imm (Reg $5, $3)) + } +| BITOP qreg COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86BITOP (false, $1.op, X86S64, Bit_rm_r (Reg $4, $2)) + } +| LOCK BITOP qreg COMMA qreg + { check_size ($2.sz, X86QUAD) + ; `X86BITOP (true, $2.op, X86S64, Bit_rm_r (Reg $5, $3)) + } +| BITOP qreg COMMA addr + { check_size ($1.sz, X86QUAD) + ; `X86BITOP (false, $1.op, X86S64, Bit_rm_r ($4, $2)) + } +| LOCK BITOP qreg COMMA addr + { check_size ($2.sz, X86QUAD) + ; `X86BITOP (true, $2.op, X86S64, Bit_rm_r ($5, $3)) + } +| CALL big_imm + { `X86CALL (Imm $2) } +| CALL addr + { `X86CALL (Rm $2) } +| CALL qreg + { `X86CALL (Rm (Reg $2)) } +| CLC + { `X86CLC } +| CMC + { `X86CMC } +| CMOV addr COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86MOV ($1.cond, X86S16, R_rm ($4, $2)) + } +| CMOV addr COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86MOV ($1.cond, X86S32, R_rm ($4, $2)) + } +| CMOV addr COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86MOV ($1.cond, X86S64, R_rm ($4, $2)) + } +| CMOV wreg COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86MOV ($1.cond, X86S16, R_rm ($4, Reg $2)) + } +| CMOV lreg COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86MOV ($1.cond, X86S32, R_rm ($4, Reg $2)) + } +| CMOV qreg COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86MOV ($1.cond, X86S64, R_rm ($4, Reg $2)) + } +| CMPXCHG breg COMMA breg + { check_size ($1.sz, X86BYTE) + ; check_byte_regs ($2, $4) + ; `X86CMPXCHG (false, X86S8 ($2.high), Reg (IReg ($4.reg)), IReg ($2.reg)) + } +| CMPXCHG breg COMMA addr + { check_size ($1.sz, X86BYTE) + ; `X86CMPXCHG (false, X86S8 ($2.high), $4, IReg ($2.reg)) + } +| LOCK CMPXCHG breg COMMA addr + { check_size ($2.sz, X86BYTE) + ; `X86CMPXCHG (true, X86S8 ($3.high), $5, IReg ($3.reg)) + } +| CMPXCHG wreg COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86CMPXCHG (false, X86S16, Reg $4, $2) + } +| CMPXCHG wreg COMMA addr + { check_size ($1.sz, X86WORD) + ; `X86CMPXCHG (false, X86S16, $4, $2) + } +| LOCK CMPXCHG wreg COMMA addr + { check_size ($2.sz, X86WORD) + ; `X86CMPXCHG (true, X86S16, $5, $3) + } +| CMPXCHG lreg COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86CMPXCHG (false, X86S32, Reg $4, $2) + } +| CMPXCHG lreg COMMA addr + { check_size ($1.sz, X86LONG) + ; `X86CMPXCHG (false, X86S32, $4, $2) + } +| LOCK CMPXCHG lreg COMMA addr + { check_size ($2.sz, X86LONG) + ; `X86CMPXCHG (true, X86S32, $5, $3) + } +| CMPXCHG qreg COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86CMPXCHG (false, X86S64, Reg $4, $2) + } +| CMPXCHG qreg COMMA addr + { check_size ($1.sz, X86QUAD) + ; `X86CMPXCHG (false, X86S64, $4, $2) + } +| LOCK CMPXCHG qreg COMMA addr + { check_size ($2.sz, X86QUAD) + ; `X86CMPXCHG (true, X86S64, $5, $3) + } +| DIV addr + { `X86DIV (suffix_size $1.sz, $2) } +| DIV breg + { check_size ($1.sz, X86BYTE) + ; `X86DIV (X86S8 ($2.high), Reg (IReg ($2.reg))) + } +| DIV wreg + { check_size ($1.sz, X86WORD) + ; `X86DIV (X86S16, Reg $2) + } +| DIV lreg + { check_size ($1.sz, X86LONG) + ; `X86DIV (X86S32, Reg $2) + } +| DIV qreg + { check_size ($1.sz, X86QUAD) + ; `X86DIV (X86S64, Reg $2) + } +| JCC big_num + { `X86JCC ($1.cond, $2) } +| JMP big_num + { `X86JCC (X86ALWAYS, $2) } +| JMP addr + { `X86JMP $2 } +| JMP qreg + { `X86JMP (Reg $2) } +| LEA addr COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86LEA (X86S16, R_rm ($4, $2)) + } +| LEA addr COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86LEA (X86S32, R_rm ($4, $2)) + } +| LEA addr COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86LEA (X86S64, R_rm ($4, $2)) + } +| LEAVE + { `X86LEAVE } +| LOOP big_num + { `X86LOOP ($1.cond, $2) } +| MFENCE + { `X86MFENCE } +| MONOP addr + { `X86MONOP (false, $1.op, suffix_size $1.sz, $2) } +| LOCK MONOP addr + { `X86MONOP (true, $2.op, suffix_size $2.sz, $3) } +| MONOP breg + { check_size ($1.sz, X86BYTE) + ; `X86MONOP (false, $1.op, X86S8 ($2.high), Reg (IReg $2.reg)) + } +| MONOP wreg + { check_size ($1.sz, X86WORD) + ; `X86MONOP (false, $1.op, X86S16, Reg $2) + } +| MONOP lreg + { check_size ($1.sz, X86LONG) + ; `X86MONOP (false, $1.op, X86S32, Reg $2) + } +| MONOP qreg + { check_size ($1.sz, X86QUAD) + ; `X86MONOP (false, $1.op, X86S64, Reg $2) + } +| MOV big_imm COMMA addr + { `X86MOV (X86ALWAYS, suffix_size $1.sz, Rm_i ($4, $2)) } +| MOV imm COMMA breg + { check_size ($1.sz, X86BYTE) + ; `X86MOV (X86ALWAYS, X86S8 ($4.high), Rm_i (Reg (IReg $4.reg), bit64_of_int $2)) + } +| MOV breg COMMA breg + { check_size ($1.sz, X86BYTE) + ; check_byte_regs ($2, $4) + ; `X86MOV (X86ALWAYS, X86S8 ($4.high), Rm_r (Reg (IReg $4.reg), (IReg $2.reg))) + } +| MOV addr COMMA breg + { check_size ($1.sz, X86BYTE) + ; `X86MOV (X86ALWAYS, X86S8 ($4.high), R_rm (IReg $4.reg, $2)) + } +| MOV breg COMMA addr + { check_size ($1.sz, X86BYTE) + ; `X86MOV (X86ALWAYS, X86S8 ($2.high), Rm_r ($4, IReg $2.reg)) + } +| MOV imm COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86MOV (X86ALWAYS, X86S16, Rm_i (Reg $4, bit64_of_int $2)) + } +| MOV wreg COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86MOV (X86ALWAYS, X86S16, Rm_r (Reg $4, $2)) + } +| MOV addr COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86MOV (X86ALWAYS, X86S16, R_rm ($4, $2)) + } +| MOV wreg COMMA addr + { check_size ($1.sz, X86WORD) + ; `X86MOV (X86ALWAYS, X86S16, Rm_r ($4, $2)) + } +| MOV imm COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86MOV (X86ALWAYS, X86S32, Rm_i (Reg $4, bit64_of_int $2)) + } +| MOV lreg COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86MOV (X86ALWAYS, X86S32, Rm_r (Reg $4, $2)) + } +| MOV addr COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86MOV (X86ALWAYS, X86S32, R_rm ($4, $2)) + } +| MOV lreg COMMA addr + { check_size ($1.sz, X86LONG) + ; `X86MOV (X86ALWAYS, X86S32, Rm_r ($4, $2)) + } +| MOV big_imm COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86MOV (X86ALWAYS, X86S64, Rm_i (Reg $4, $2)) + } +| MOV qreg COMMA qreg + { check_size ($1.sz, X86QUAD) + ; if $1.txt = "MOVABS" then failwith "movabs expects and immediate" else () + ; `X86MOV (X86ALWAYS, X86S64, Rm_r (Reg $4, $2)) + } +| MOV addr COMMA qreg + { check_size ($1.sz, X86QUAD) + ; if $1.txt = "MOVABS" then failwith "movabs expects and immediate" else () + ; `X86MOV (X86ALWAYS, X86S64, R_rm ($4, $2)) + } +| MOV qreg COMMA addr + { check_size ($1.sz, X86QUAD) + ; if $1.txt = "MOVABS" then failwith "movabs expects and immediate" else () + ; `X86MOV (X86ALWAYS, X86S64, Rm_r ($4, $2)) + } +| MOVSX breg COMMA wreg + { check_size ($1.sz1, X86BYTE) + ; check_size ($1.sz2, X86WORD) + ; `X86MOVSX (X86S16, R_rm ($4, Reg (IReg $2.reg)), X86S8 $2.high) + } +| MOVSX breg COMMA lreg + { check_size ($1.sz1, X86BYTE) + ; check_size ($1.sz2, X86LONG) + ; `X86MOVSX (X86S32, R_rm ($4, Reg (IReg $2.reg)), X86S8 $2.high) + } +| MOVSX breg COMMA qreg + { check_size ($1.sz1, X86BYTE) + ; check_size ($1.sz2, X86QUAD) + ; `X86MOVSX (X86S64, R_rm ($4, Reg (IReg $2.reg)), X86S8 $2.high) + } +| MOVSX wreg COMMA lreg + { check_size ($1.sz1, X86WORD) + ; check_size ($1.sz2, X86LONG) + ; `X86MOVSX (X86S32, R_rm ($4, Reg $2), X86S16) + } +| MOVSX wreg COMMA qreg + { check_size ($1.sz1, X86WORD) + ; check_size ($1.sz2, X86QUAD) + ; `X86MOVSX (X86S64, R_rm ($4, Reg $2), X86S16) + } +| MOVSX lreg COMMA qreg + { check_size ($1.sz1, X86LONG) + ; check_size ($1.sz2, X86QUAD) + ; `X86MOVSX (X86S64, R_rm ($4, Reg $2), X86S32) + } +| MOVSX addr COMMA wreg + { check_size ($1.sz2, X86WORD) + ; `X86MOVSX (X86S16, R_rm ($4, $2), suffix_size $1.sz1) + } +| MOVSX addr COMMA lreg + { check_size ($1.sz2, X86LONG) + ; `X86MOVSX (X86S32, R_rm ($4, $2), suffix_size $1.sz1) + } +| MOVSX addr COMMA qreg + { check_size ($1.sz2, X86QUAD) + ; `X86MOVSX (X86S64, R_rm ($4, $2), suffix_size $1.sz1) + } +| MOVZX breg COMMA wreg + { check_size ($1.sz1, X86BYTE) + ; check_size ($1.sz2, X86WORD) + ; `X86MOVZX (X86S16, R_rm ($4, Reg (IReg $2.reg)), X86S8 $2.high) + } +| MOVZX breg COMMA lreg + { check_size ($1.sz1, X86BYTE) + ; check_size ($1.sz2, X86LONG) + ; `X86MOVZX (X86S32, R_rm ($4, Reg (IReg $2.reg)), X86S8 $2.high) + } +| MOVZX breg COMMA qreg + { check_size ($1.sz1, X86BYTE) + ; check_size ($1.sz2, X86QUAD) + ; `X86MOVZX (X86S64, R_rm ($4, Reg (IReg $2.reg)), X86S8 $2.high) + } +| MOVZX wreg COMMA lreg + { check_size ($1.sz1, X86WORD) + ; check_size ($1.sz2, X86LONG) + ; `X86MOVZX (X86S32, R_rm ($4, Reg $2), X86S16) + } +| MOVZX wreg COMMA qreg + { check_size ($1.sz1, X86WORD) + ; check_size ($1.sz2, X86QUAD) + ; `X86MOVZX (X86S64, R_rm ($4, Reg $2), X86S16) + } +| MOVZX addr COMMA wreg + { check_size ($1.sz2, X86WORD) + ; `X86MOVZX (X86S16, R_rm ($4, $2), suffix_size $1.sz1) + } +| MOVZX addr COMMA lreg + { check_size ($1.sz2, X86LONG) + ; `X86MOVZX (X86S32, R_rm ($4, $2), suffix_size $1.sz1) + } +| MOVZX addr COMMA qreg + { check_size ($1.sz2, X86QUAD) + ; `X86MOVZX (X86S64, R_rm ($4, $2), suffix_size $1.sz1) + } +| MUL addr + { `X86MUL (suffix_size $1.sz, $2) } +| MUL breg + { check_size ($1.sz, X86BYTE) + ; `X86MUL (X86S8 ($2.high), Reg (IReg $2.reg)) + } +| MUL wreg + { check_size ($1.sz, X86WORD) + ; `X86MUL (X86S16, Reg $2) + } +| MUL lreg + { check_size ($1.sz, X86LONG) + ; `X86MUL (X86S32, Reg $2) + } +| MUL qreg + { check_size ($1.sz, X86QUAD) + ; `X86MUL (X86S64, Reg $2) + } +| NOP + { `X86NOP } +| POP qreg + { `X86POP (Reg $2) } +| POP addr + { `X86POP $2 } +| PUSH big_imm + { `X86PUSH (Imm $2) } +| PUSH addr + { `X86PUSH (Rm $2) } +| PUSH qreg + { `X86PUSH (Rm (Reg $2)) } +| RET big_imm + { `X86RET $2 } +| SET breg + { `X86SET ($1.cond, $2.high, Reg (IReg $2.reg)) } +| SET addr + { `X86SET ($1.cond, false, $2) } +| STC + { `X86STC } +| XADD breg COMMA breg + { check_size ($1.sz, X86BYTE) + ; check_byte_regs ($2, $4) + ; `X86XADD (false, X86S8 ($2.high), Reg (IReg $4.reg), (IReg $2.reg)) + } +| XADD breg COMMA addr + { check_size ($1.sz, X86BYTE) + ; `X86XADD (false, X86S8 ($2.high), $4, (IReg $2.reg)) + } +| LOCK XADD breg COMMA addr + { check_size ($2.sz, X86BYTE) + ; `X86XADD (true, X86S8 ($3.high), $5, (IReg $3.reg)) + } +| XADD wreg COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86XADD (false, X86S16, Reg $4, $2) + } +| XADD wreg COMMA addr + { check_size ($1.sz, X86WORD) + ; `X86XADD (false, X86S16, $4, $2) + } +| LOCK XADD wreg COMMA addr + { check_size ($2.sz, X86WORD) + ; `X86XADD (true, X86S16, $5, $3) + } +| XADD lreg COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86XADD (false, X86S32, Reg $4, $2) + } +| XADD lreg COMMA addr + { check_size ($1.sz, X86LONG) + ; `X86XADD (false, X86S32, $4, $2) + } +| LOCK XADD lreg COMMA addr + { check_size ($2.sz, X86LONG) + ; `X86XADD (true, X86S32, $5, $3) + } +| XADD qreg COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86XADD (false, X86S64, Reg $4, $2) + } +| XADD qreg COMMA addr + { check_size ($1.sz, X86QUAD) + ; `X86XADD (false, X86S64, $4, $2) + } +| LOCK XADD qreg COMMA addr + { check_size ($2.sz, X86QUAD) + ; `X86XADD (true, X86S64, $5, $3) + } +| XCHG breg COMMA breg + { check_size ($1.sz, X86BYTE) + ; check_byte_regs ($2, $4) + ; `X86XCHG (false, X86S8 ($2.high), Reg (IReg $4.reg), IReg $2.reg) + } +| XCHG breg COMMA addr + { check_size ($1.sz, X86BYTE) + ; `X86XCHG (false, X86S8 ($2.high), $4, (IReg $2.reg)) + } +| LOCK XCHG breg COMMA addr + { check_size ($2.sz, X86BYTE) + ; `X86XCHG (true, X86S8 ($3.high), $5, (IReg $3.reg)) + } +| XCHG wreg COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86XCHG (false, X86S16, Reg $4, $2) + } +| XCHG wreg COMMA addr + { check_size ($1.sz, X86WORD) + ; `X86XCHG (false, X86S16, $4, $2) + } +| LOCK XCHG wreg COMMA addr + { check_size ($2.sz, X86WORD) + ; `X86XCHG (true, X86S16, $5, $3) + } +| XCHG lreg COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86XCHG (false, X86S32, Reg $4, $2) + } +| XCHG lreg COMMA addr + { check_size ($1.sz, X86LONG) + ; `X86XCHG (false, X86S32, $4, $2) + } +| LOCK XCHG lreg COMMA addr + { check_size ($2.sz, X86LONG) + ; `X86XCHG (true, X86S32, $5, $3) + } +| XCHG qreg COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86XCHG (false, X86S64, Reg $4, $2) + } +| XCHG qreg COMMA addr + { check_size ($1.sz, X86QUAD) + ; `X86XCHG (false, X86S64, $4, $2) + } +| LOCK XCHG qreg COMMA addr + { check_size ($2.sz, X86QUAD) + ; `X86XCHG (true, X86S64, $5, $3) + } diff --git a/x86/gen/parser_intel.hgen b/x86/gen/parser_intel.hgen new file mode 100644 index 00000000..72fa0ede --- /dev/null +++ b/x86/gen/parser_intel.hgen @@ -0,0 +1,601 @@ +| BINOP addr COMMA imm + { `X86BINOP (false, $1.op, suffix_size $1.sz, Rm_i ($2, bit64_of_int $4)) + (* XXX size is ambigious -- should require anotation *) } +| LOCK BINOP addr COMMA imm + { check_binop_lockable $2.op + ; `X86BINOP (true, $2.op, suffix_size $2.sz, Rm_i ($3, bit64_of_int $5)) } +| BINOP breg COMMA imm + { check_size ($1.sz, X86BYTE) + ; `X86BINOP (false, $1.op, X86S8 ($2.high), Rm_i (Reg (IReg ($2.reg)), bit64_of_int $4)) + } +| BINOP breg COMMA breg + { check_size ($1.sz, X86BYTE) + ; check_byte_regs ($2, $4) + ; `X86BINOP (false, $1.op, X86S8 ($2.high), Rm_r (Reg (IReg ($2.reg)), IReg ($4.reg))) + } +| BINOP addr COMMA breg + { check_size ($1.sz, X86BYTE) + ; `X86BINOP (false, $1.op, X86S8 ($4.high), Rm_r ($2, IReg ($4.reg))) + } +| LOCK BINOP addr COMMA breg + { check_binop_lockable $2.op; + check_size ($2.sz, X86BYTE) + ; `X86BINOP (true, $2.op, X86S8 ($5.high), Rm_r ($3, IReg ($5.reg))) + } +| BINOP breg COMMA addr + { check_size ($1.sz, X86BYTE) + ; `X86BINOP (false, $1.op, X86S8 ($2.high), R_rm (IReg ($2.reg), $4)) + } +| BINOP wreg COMMA imm + { check_size ($1.sz, X86WORD) + ; `X86BINOP (false, $1.op, X86S16, Rm_i (Reg $2, bit64_of_int $4)) + } +| BINOP wreg COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86BINOP (false, $1.op, X86S16, Rm_r (Reg $2, $4)) + } +| BINOP addr COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86BINOP (false, $1.op, X86S16, Rm_r ($2, $4)) + } +| LOCK BINOP addr COMMA wreg + { check_binop_lockable $2.op; + check_size ($2.sz, X86WORD) + ; `X86BINOP (true, $2.op, X86S16, Rm_r ($3, $5)) + } +| BINOP wreg COMMA addr + { check_size ($1.sz, X86WORD) + ; `X86BINOP (false, $1.op, X86S16, R_rm ($2, $4)) + } +| BINOP lreg COMMA imm + { check_size ($1.sz, X86LONG) + ; `X86BINOP (false, $1.op, X86S32, Rm_i (Reg $2, bit64_of_int $4)) + } +| BINOP lreg COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86BINOP (false, $1.op, X86S32, Rm_r (Reg $2, $4)) + } +| BINOP addr COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86BINOP (false, $1.op, X86S32, Rm_r ($2, $4)) + } +| LOCK BINOP addr COMMA lreg + { check_binop_lockable $2.op; + check_size ($2.sz, X86LONG) + ; `X86BINOP (true, $2.op, X86S32, Rm_r ($3, $5)) + } +| BINOP lreg COMMA addr + { check_size ($1.sz, X86LONG) + ; `X86BINOP (false, $1.op, X86S32, R_rm ($2, $4)) + } +| BINOP qreg COMMA imm + { check_size ($1.sz, X86QUAD) + ; `X86BINOP (false, $1.op, X86S64, Rm_i (Reg $2, bit64_of_int $4)) + } +| BINOP qreg COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86BINOP (false, $1.op, X86S64, Rm_r (Reg $2, $4)) + } +| BINOP addr COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86BINOP (false, $1.op, X86S64, Rm_r ($2, $4)) + } +| LOCK BINOP addr COMMA qreg + { check_binop_lockable $2.op; + check_size ($2.sz, X86QUAD) + ; `X86BINOP (true, $2.op, X86S64, Rm_r ($3, $5)) + } +| BINOP qreg COMMA addr + { check_size ($1.sz, X86QUAD) + ; `X86BINOP (false, $1.op, X86S64, R_rm ($2, $4)) + } +| BITOP addr COMMA imm + { `X86BITOP (false, $1.op, suffix_size $1.sz, Bit_rm_imm ($2, $4)) + } +| LOCK BITOP addr COMMA imm + { `X86BITOP (true, $2.op, suffix_size $2.sz, Bit_rm_imm ($3, $5)) + } +| BITOP wreg COMMA imm + { check_size ($1.sz, X86WORD) + ; `X86BITOP (false, $1.op, X86S16, Bit_rm_imm (Reg $2, $4)) + } +| LOCK BITOP wreg COMMA imm + { check_size ($2.sz, X86WORD) + ; `X86BITOP (true, $2.op, X86S16, Bit_rm_imm (Reg $3, $5)) + } +| BITOP wreg COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86BITOP (true, $1.op, X86S16, Bit_rm_r (Reg $2, $4)) + } +| LOCK BITOP wreg COMMA wreg + { check_size ($2.sz, X86WORD) + ; `X86BITOP (false, $2.op, X86S16, Bit_rm_r (Reg $3, $5)) + } +| BITOP addr COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86BITOP (false, $1.op, X86S16, Bit_rm_r ($2, $4)) + } +| LOCK BITOP addr COMMA wreg + { check_size ($2.sz, X86WORD) + ; `X86BITOP (true, $2.op, X86S16, Bit_rm_r ($3, $5)) + } +| BITOP lreg COMMA imm + { check_size ($1.sz, X86LONG) + ; `X86BITOP (false, $1.op, X86S32, Bit_rm_imm (Reg $2, $4)) + } +| LOCK BITOP lreg COMMA imm + { check_size ($2.sz, X86LONG) + ; `X86BITOP (true, $2.op, X86S32, Bit_rm_imm (Reg $3, $5)) + } +| BITOP lreg COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86BITOP (false, $1.op, X86S32, Bit_rm_r (Reg $2, $4)) + } +| LOCK BITOP lreg COMMA lreg + { check_size ($2.sz, X86LONG) + ; `X86BITOP (true, $2.op, X86S32, Bit_rm_r (Reg $3, $5)) + } +| BITOP addr COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86BITOP (false, $1.op, X86S32, Bit_rm_r ($2, $4)) + } +| LOCK BITOP addr COMMA lreg + { check_size ($2.sz, X86LONG) + ; `X86BITOP (true, $2.op, X86S32, Bit_rm_r ($3, $5)) + } +| BITOP qreg COMMA imm + { check_size ($1.sz, X86QUAD) + ; `X86BITOP (false, $1.op, X86S64, Bit_rm_imm (Reg $2, $4)) + } +| LOCK BITOP qreg COMMA imm + { check_size ($2.sz, X86QUAD) + ; `X86BITOP (true, $2.op, X86S64, Bit_rm_imm (Reg $3, $5)) + } +| BITOP qreg COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86BITOP (false, $1.op, X86S64, Bit_rm_r (Reg $2, $4)) + } +| LOCK BITOP qreg COMMA qreg + { check_size ($2.sz, X86QUAD) + ; `X86BITOP (true, $2.op, X86S64, Bit_rm_r (Reg $3, $5)) + } +| BITOP addr COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86BITOP (false, $1.op, X86S64, Bit_rm_r ($2, $4)) + } +| LOCK BITOP addr COMMA qreg + { check_size ($2.sz, X86QUAD) + ; `X86BITOP (true, $2.op, X86S64, Bit_rm_r ($3, $5)) + } +| CALL big_imm + { `X86CALL (Imm $2) } +| CALL addr + { `X86CALL (Rm $2) } +| CALL qreg + { `X86CALL (Rm (Reg $2)) } +| CLC + { `X86CLC } +| CMC + { `X86CMC } +| CMOV wreg COMMA addr + { check_size ($1.sz, X86WORD) + ; `X86MOV ($1.cond, X86S16, R_rm ($2, $4)) + } +| CMOV lreg COMMA addr + { check_size ($1.sz, X86LONG) + ; `X86MOV ($1.cond, X86S32, R_rm ($2, $4)) + } +| CMOV qreg COMMA addr + { check_size ($1.sz, X86QUAD) + ; `X86MOV ($1.cond, X86S64, R_rm ($2, $4)) + } +| CMOV wreg COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86MOV ($1.cond, X86S16, R_rm ($2, Reg $4)) + } +| CMOV lreg COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86MOV ($1.cond, X86S32, R_rm ($2, Reg $4)) + } +| CMOV qreg COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86MOV ($1.cond, X86S64, R_rm ($2, Reg $4)) + } +| CMPXCHG breg COMMA breg + { check_size ($1.sz, X86BYTE) + ; check_byte_regs ($2, $4) + ; `X86CMPXCHG (false, X86S8 ($2.high), Reg (IReg ($2.reg)), IReg ($4.reg)) + } +| CMPXCHG addr COMMA breg + { check_size ($1.sz, X86BYTE) + ; `X86CMPXCHG (false, X86S8 ($4.high), $2, IReg ($4.reg)) + } +| LOCK CMPXCHG addr COMMA breg + { check_size ($2.sz, X86BYTE) + ; `X86CMPXCHG (true, X86S8 ($5.high), $3, IReg ($5.reg)) + } +| CMPXCHG wreg COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86CMPXCHG (false, X86S16, Reg $2, $4) + } +| CMPXCHG addr COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86CMPXCHG (false, X86S16, $2, $4) + } +| LOCK CMPXCHG addr COMMA wreg + { check_size ($2.sz, X86WORD) + ; `X86CMPXCHG (true, X86S16, $3, $5) + } +| CMPXCHG lreg COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86CMPXCHG (false, X86S32, Reg $2, $4) + } +| CMPXCHG addr COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86CMPXCHG (false, X86S32, $2, $4) + } +| LOCK CMPXCHG addr COMMA lreg + { check_size ($2.sz, X86LONG) + ; `X86CMPXCHG (true, X86S32, $3, $5) + } +| CMPXCHG qreg COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86CMPXCHG (false, X86S64, Reg $2, $4) + } +| CMPXCHG addr COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86CMPXCHG (false, X86S64, $2, $4) + } +| LOCK CMPXCHG addr COMMA qreg + { check_size ($2.sz, X86QUAD) + ; `X86CMPXCHG (true, X86S64, $3, $5) + } +| DIV addr + { `X86DIV (suffix_size $1.sz, $2) } +| DIV breg + { check_size ($1.sz, X86BYTE) + ; `X86DIV (X86S8 ($2.high), Reg (IReg ($2.reg))) + } +| DIV wreg + { check_size ($1.sz, X86WORD) + ; `X86DIV (X86S16, Reg $2) + } +| DIV lreg + { check_size ($1.sz, X86LONG) + ; `X86DIV (X86S32, Reg $2) + } +| DIV qreg + { check_size ($1.sz, X86QUAD) + ; `X86DIV (X86S64, Reg $2) + } +| JCC big_num + { `X86JCC ($1.cond, $2) } +| JMP big_num + { `X86JCC (X86ALWAYS, $2) } +| JMP addr + { `X86JMP $2 } +| JMP qreg + { `X86JMP (Reg $2) } +| LEA wreg COMMA addr + { check_size ($1.sz, X86WORD) + ; `X86LEA (X86S16, R_rm ($2, $4)) + } +| LEA lreg COMMA addr + { check_size ($1.sz, X86LONG) + ; `X86LEA (X86S32, R_rm ($2, $4)) + } +| LEA qreg COMMA addr + { check_size ($1.sz, X86QUAD) + ; `X86LEA (X86S64, R_rm ($2, $4)) + } +| LEAVE + { `X86LEAVE } +| LOOP big_num + { `X86LOOP ($1.cond, $2) } +| MFENCE + { `X86MFENCE } +| MONOP addr + { `X86MONOP (false, $1.op, suffix_size $1.sz, $2) } +| LOCK MONOP addr + { `X86MONOP (true, $2.op, suffix_size $2.sz, $3) } +| MONOP breg + { check_size ($1.sz, X86BYTE) + ; `X86MONOP (false, $1.op, X86S8 ($2.high), Reg (IReg $2.reg)) + } +| MONOP wreg + { check_size ($1.sz, X86WORD) + ; `X86MONOP (false, $1.op, X86S16, Reg $2) + } +| MONOP lreg + { check_size ($1.sz, X86LONG) + ; `X86MONOP (false, $1.op, X86S32, Reg $2) + } +| MONOP qreg + { check_size ($1.sz, X86QUAD) + ; `X86MONOP (false, $1.op, X86S64, Reg $2) + } +| MOV addr COMMA big_imm + { `X86MOV (X86ALWAYS, suffix_size $1.sz, Rm_i ($2, $4)) } +| MOV breg COMMA imm + { check_size ($1.sz, X86BYTE) + ; `X86MOV (X86ALWAYS, X86S8 ($2.high), Rm_i (Reg (IReg $2.reg), bit64_of_int $4)) + } +| MOV breg COMMA breg + { check_size ($1.sz, X86BYTE) + ; check_byte_regs ($2, $4) + ; `X86MOV (X86ALWAYS, X86S8 ($2.high), Rm_r (Reg (IReg $2.reg), (IReg $4.reg))) + } +| MOV addr COMMA breg + { check_size ($1.sz, X86BYTE) + ; `X86MOV (X86ALWAYS, X86S8 ($4.high), Rm_r ($2, IReg $4.reg)) + } +| MOV breg COMMA addr + { check_size ($1.sz, X86BYTE) + ; `X86MOV (X86ALWAYS, X86S8 ($2.high), R_rm (IReg $2.reg, $4)) + } +| MOV wreg COMMA imm + { check_size ($1.sz, X86WORD) + ; `X86MOV (X86ALWAYS, X86S16, Rm_i (Reg $2, bit64_of_int $4)) + } +| MOV wreg COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86MOV (X86ALWAYS, X86S16, Rm_r (Reg $2, $4)) + } +| MOV addr COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86MOV (X86ALWAYS, X86S16, Rm_r ($2, $4)) + } +| MOV wreg COMMA addr + { check_size ($1.sz, X86WORD) + ; `X86MOV (X86ALWAYS, X86S16, R_rm ($2, $4)) + } +| MOV lreg COMMA imm + { check_size ($1.sz, X86LONG) + ; `X86MOV (X86ALWAYS, X86S32, Rm_i (Reg $2, bit64_of_int $4)) + } +| MOV lreg COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86MOV (X86ALWAYS, X86S32, Rm_r (Reg $2, $4)) + } +| MOV addr COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86MOV (X86ALWAYS, X86S32, Rm_r ($2, $4)) + } +| MOV lreg COMMA addr + { check_size ($1.sz, X86LONG) + ; `X86MOV (X86ALWAYS, X86S32, R_rm ($2, $4)) + } +| MOV qreg COMMA big_imm + { check_size ($1.sz, X86QUAD) + ; `X86MOV (X86ALWAYS, X86S64, Rm_i (Reg $2, $4)) + } +| MOV qreg COMMA qreg + { check_size ($1.sz, X86QUAD) + ; if $1.txt = "MOVABS" then failwith "movabs expects an immediate" else () + ; `X86MOV (X86ALWAYS, X86S64, Rm_r (Reg $2, $4)) + } +| MOV addr COMMA qreg + { check_size ($1.sz, X86QUAD) + ; if $1.txt = "MOVABS" then failwith "movabs expects an immediate" else () + ; `X86MOV (X86ALWAYS, X86S64, Rm_r ($2, $4)) + } +| MOV qreg COMMA addr + { check_size ($1.sz, X86QUAD) + ; if $1.txt = "MOVABS" then failwith "movabs expects an immediate" else () + ; `X86MOV (X86ALWAYS, X86S64, R_rm ($2, $4)) + } +| MOVSX wreg COMMA breg + { check_size ($1.sz1, X86BYTE) + ; check_size ($1.sz2, X86WORD) + ; `X86MOVSX (X86S16, R_rm ($2, Reg (IReg $4.reg)), X86S8 $4.high) + } +| MOVSX lreg COMMA breg + { check_size ($1.sz1, X86BYTE) + ; check_size ($1.sz2, X86LONG) + ; `X86MOVSX (X86S32, R_rm ($2, Reg (IReg $4.reg)), X86S8 $4.high) + } +| MOVSX qreg COMMA breg + { check_size ($1.sz1, X86BYTE) + ; check_size ($1.sz2, X86QUAD) + ; `X86MOVSX (X86S64, R_rm ($2, Reg (IReg $4.reg)), X86S8 $4.high) + } +| MOVSX lreg COMMA wreg + { check_size ($1.sz1, X86WORD) + ; check_size ($1.sz2, X86LONG) + ; `X86MOVSX (X86S32, R_rm ($2, Reg $4), X86S16) + } +| MOVSX qreg COMMA wreg + { check_size ($1.sz1, X86WORD) + ; check_size ($1.sz2, X86QUAD) + ; `X86MOVSX (X86S64, R_rm ($2, Reg $4), X86S16) + } +| MOVSX qreg COMMA lreg + { check_size ($1.sz1, X86LONG) + ; check_size ($1.sz2, X86QUAD) + ; `X86MOVSX (X86S64, R_rm ($2, Reg $4), X86S32) + } +| MOVSX wreg COMMA addr + { check_size ($1.sz2, X86WORD) + ; `X86MOVSX (X86S16, R_rm ($2, $4), suffix_size $1.sz1) (* XXX size *) + } +| MOVSX lreg COMMA addr + { check_size ($1.sz2, X86LONG) + ; `X86MOVSX (X86S32, R_rm ($2, $4), suffix_size $1.sz1) + } +| MOVSX qreg COMMA addr + { check_size ($1.sz2, X86QUAD) + ; `X86MOVSX (X86S64, R_rm ($2, $4), suffix_size $1.sz1) + } +| MOVZX wreg COMMA breg + { check_size ($1.sz1, X86BYTE) + ; check_size ($1.sz2, X86WORD) + ; `X86MOVZX (X86S16, R_rm ($2, Reg (IReg $4.reg)), X86S8 $4.high) + } +| MOVZX lreg COMMA breg + { check_size ($1.sz1, X86BYTE) + ; check_size ($1.sz2, X86LONG) + ; `X86MOVZX (X86S32, R_rm ($2, Reg (IReg $4.reg)), X86S8 $4.high) + } +| MOVZX qreg COMMA breg + { check_size ($1.sz1, X86BYTE) + ; check_size ($1.sz2, X86QUAD) + ; `X86MOVZX (X86S64, R_rm ($2, Reg (IReg $4.reg)), X86S8 $4.high) + } +| MOVZX lreg COMMA wreg + { check_size ($1.sz1, X86WORD) + ; check_size ($1.sz2, X86LONG) + ; `X86MOVZX (X86S32, R_rm ($2, Reg $4), X86S16) + } +| MOVZX qreg COMMA wreg + { check_size ($1.sz1, X86WORD) + ; check_size ($1.sz2, X86QUAD) + ; `X86MOVZX (X86S64, R_rm ($2, Reg $4), X86S16) + } +| MOVZX wreg COMMA addr + { check_size ($1.sz2, X86WORD) + ; `X86MOVZX (X86S16, R_rm ($2, $4), suffix_size $1.sz1) (* XXX size *) + } +| MOVZX lreg COMMA addr + { check_size ($1.sz2, X86LONG) + ; `X86MOVZX (X86S32, R_rm ($2, $4), suffix_size $1.sz1) + } +| MOVZX qreg COMMA addr + { check_size ($1.sz2, X86QUAD) + ; `X86MOVZX (X86S64, R_rm ($2, $4), suffix_size $1.sz1) + } +| MUL addr + { `X86MUL (suffix_size $1.sz, $2) } +| MUL breg + { check_size ($1.sz, X86BYTE) + ; `X86MUL (X86S8 ($2.high), Reg (IReg $2.reg)) + } +| MUL wreg + { check_size ($1.sz, X86WORD) + ; `X86MUL (X86S16, Reg $2) + } +| MUL lreg + { check_size ($1.sz, X86LONG) + ; `X86MUL (X86S32, Reg $2) + } +| MUL qreg + { check_size ($1.sz, X86QUAD) + ; `X86MUL (X86S64, Reg $2) + } +| NOP + { `X86NOP } +| POP qreg + { `X86POP (Reg $2) } +| POP addr + { `X86POP $2 } +| PUSH big_imm + { `X86PUSH (Imm $2) } +| PUSH addr + { `X86PUSH (Rm $2) } +| PUSH qreg + { `X86PUSH (Rm (Reg $2)) } +| RET big_imm + { `X86RET $2 } +| SET breg + { `X86SET ($1.cond, $2.high, Reg (IReg $2.reg)) } +| SET addr + { `X86SET ($1.cond, false, $2) } +| STC + { `X86STC } +| XADD breg COMMA breg + { check_size ($1.sz, X86BYTE) + ; check_byte_regs ($2, $4) + ; `X86XADD (false, X86S8 ($2.high), Reg (IReg $2.reg), (IReg $4.reg)) + } +| XADD addr COMMA breg + { check_size ($1.sz, X86BYTE) + ; `X86XADD (false, X86S8 ($4.high), $2, (IReg $4.reg)) + } +| LOCK XADD addr COMMA breg + { check_size ($2.sz, X86BYTE) + ; `X86XADD (true, X86S8 ($5.high), $3, (IReg $5.reg)) + } +| XADD wreg COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86XADD (false, X86S16, Reg $2, $4) + } +| XADD addr COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86XADD (false, X86S16, $2, $4) + } +| LOCK XADD addr COMMA wreg + { check_size ($2.sz, X86WORD) + ; `X86XADD (true, X86S16, $3, $5) + } +| XADD lreg COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86XADD (false, X86S32, Reg $2, $4) + } +| XADD addr COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86XADD (false, X86S32, $2, $4) + } +| LOCK XADD addr COMMA lreg + { check_size ($2.sz, X86LONG) + ; `X86XADD (true, X86S32, $3, $5) + } +| XADD qreg COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86XADD (false, X86S64, Reg $2, $4) + } +| XADD addr COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86XADD (false, X86S64, $2, $4) + } +| LOCK XADD addr COMMA qreg + { check_size ($2.sz, X86QUAD) + ; `X86XADD (true, X86S64, $3, $5) + } +| XCHG breg COMMA breg + { check_size ($1.sz, X86BYTE) + ; check_byte_regs ($2, $4) + ; `X86XCHG (false, X86S8 ($2.high), Reg (IReg $2.reg), IReg $4.reg) + } +| XCHG addr COMMA breg + { check_size ($1.sz, X86BYTE) + ; `X86XCHG (false, X86S8 ($4.high), $2, (IReg $4.reg)) + } +| LOCK XCHG addr COMMA breg + { check_size ($2.sz, X86BYTE) + ; `X86XCHG (true, X86S8 ($5.high), $3, (IReg $5.reg)) + } +| XCHG wreg COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86XCHG (false, X86S16, Reg $2, $4) + } +| XCHG addr COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86XCHG (false, X86S16, $2, $4) + } +| LOCK XCHG addr COMMA wreg + { check_size ($2.sz, X86WORD) + ; `X86XCHG (true, X86S16, $3, $5) + } +| XCHG lreg COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86XCHG (false, X86S32, Reg $2, $4) + } +| XCHG addr COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86XCHG (false, X86S32, $2, $4) + } +| LOCK XCHG addr COMMA lreg + { check_size ($2.sz, X86LONG) + ; `X86XCHG (true, X86S32, $3, $5) + } +| XCHG qreg COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86XCHG (false, X86S64, Reg $2, $4) + } +| XCHG addr COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86XCHG (false, X86S64, $2, $4) + } +| LOCK XCHG addr COMMA qreg + { check_size ($2.sz, X86QUAD) + ; `X86XCHG (true, X86S64, $3, $5) + } diff --git a/x86/gen/pretty.hgen b/x86/gen/pretty.hgen new file mode 100644 index 00000000..fc0c59d4 --- /dev/null +++ b/x86/gen/pretty.hgen @@ -0,0 +1,50 @@ +| `X86BINOP (locked, bop, sz, dst_src) -> + pp_locked locked ^ pp_x86Binop bop ^ pp_x86Size sz ^ " " ^ pp_x86Dest_src (sz, dst_src) +| `X86BITOP (locked, bop, sz, bo) -> + pp_locked locked ^ pp_x86Bitop bop ^ pp_x86Size sz ^ " " ^ pp_x86Bit_offset (sz, bo) +| `X86CALL (Imm i) -> "call " ^ " $" ^ bit64_to_string i +| `X86CALL (Rm rm) -> "call " ^ pp_x86Rm (X86S64, rm) +| `X86CLC -> "clc" +| `X86CMC -> "cmc" +| `X86CMPXCHG (locked, sz, rm, r) -> + sprintf "%scmpxchg%s %s, %s" + (pp_locked locked) (pp_x86Size sz) (pp_size_reg sz r) (pp_x86Rm (sz, rm)) +| `X86DIV (sz, rm) -> "div" ^ pp_x86Size sz ^ " " ^ pp_x86Rm (sz, rm) +| `X86JCC (X86ALWAYS, i) -> "jmp " ^ bit64_to_string i +| `X86JCC (cnd, i) -> "j" ^ pp_x86Cond cnd ^ " " ^ bit64_to_string i +| `X86JMP (rm) -> "jmp " ^ pp_x86Rm(X86S64, rm) +| `X86LEA (sz, dst_src) -> + "lea" ^ (pp_x86Size sz) ^ " " ^ pp_x86Dest_src (sz, dst_src) +| `X86LEAVE -> "leave" +| `X86LOOP (cnd, i) -> "loop" ^ pp_x86Cond cnd ^ " " ^ bit64_to_string i +| `X86MFENCE -> "mfence" +| `X86MONOP (locked, mop, sz, rm) -> + pp_x86Monop mop ^ pp_x86Size sz ^ " " ^ pp_x86Rm (sz, rm) +| `X86MOV (X86ALWAYS, sz, dst_src) -> + "mov" ^ pp_x86Size sz ^ " " ^ pp_x86Dest_src (sz, dst_src) +| `X86MOV (cnd, sz, dst_src) -> + "cmov" ^ pp_x86Cond cnd ^ pp_x86Size sz ^ " " ^ pp_x86Dest_src (sz, dst_src) +| `X86MOVSX (sz1, R_rm (r, rm), sz2) -> + "movs" ^ pp_x86Size sz1 ^ pp_x86Size sz2 ^ " " ^ pp_x86Rm (sz1, rm) ^ + ", " ^ pp_size_reg sz2 r +| `X86MOVSX (sz1, _, sz2) -> failwith "bad movsx instruction" +| `X86MOVZX (sz1, R_rm (r, rm), sz2) -> + "movz" ^ pp_x86Size sz1 ^ pp_x86Size sz2 ^ " " ^ pp_x86Rm (sz1, rm) ^ + ", " ^ pp_size_reg sz2 r +| `X86MOVZX (sz1, _, sz2) -> failwith "bad movzx instruction" +| `X86MUL (sz, rm) -> "mul" ^ pp_x86Size sz ^ " " ^ pp_x86Rm (sz, rm) +| `X86NOP -> "nop" +| `X86POP rm -> "pop " ^ (pp_x86Rm (X86S64, rm)) +| `X86PUSH (Imm i) -> "push $" ^ bit64_to_string i +| `X86PUSH (Rm rm) -> "push " ^ pp_x86Rm (X86S64, rm) +| `X86RET i -> "ret " ^ bit64_to_string i +| `X86SET (cnd, b, rm) -> "set" ^ pp_x86Cond cnd ^ " " ^ pp_x86Rm (X86S8 b, rm) +| `X86STC -> "stc" +| `X86XADD (locked, sz, rm, r) -> + sprintf "%s xadd%s %s, %s" + (pp_locked locked) (pp_x86Size sz) (pp_size_reg sz r) (pp_x86Rm (sz, rm)) +| `X86XCHG (locked, sz, rm, r) -> + sprintf "%sxchg%s %s, %s" + (pp_locked locked) (pp_x86Size sz) (pp_size_reg sz r) (pp_x86Rm (sz, rm)) +| `X86ThreadStart -> "start" +| `X86StopFetching -> "hlt" diff --git a/x86/gen/sail_trans_out.hgen b/x86/gen/sail_trans_out.hgen new file mode 100644 index 00000000..948db8fa --- /dev/null +++ b/x86/gen/sail_trans_out.hgen @@ -0,0 +1 @@ +(* *) diff --git a/x86/gen/shallow_ast_to_herdtools_ast.hgen b/x86/gen/shallow_ast_to_herdtools_ast.hgen new file mode 100644 index 00000000..ed5d6680 --- /dev/null +++ b/x86/gen/shallow_ast_to_herdtools_ast.hgen @@ -0,0 +1,27 @@ +| Binop (locked, binop, sz, dest_src) -> `X86BINOP (translate_out_bool locked, translate_out_binop binop, translate_out_size sz, translate_out_dest_src dest_src) +| Bitop (locked, bitop, sz, bo) -> `X86BITOP (translate_out_bool locked, translate_out_bitop bitop, translate_out_size sz, translate_out_bitoffset bo) +| CALL (imm_rm) -> `X86CALL (translate_out_imm_rm imm_rm) +| CLC -> `X86CLC +| CMC -> `X86CMC +| CMPXCHG (locked, sz, rm , reg) -> `X86CMPXCHG (translate_out_bool locked, translate_out_size sz, translate_out_rm rm, translate_out_reg reg) +| X86_DIV (sz, rm) -> `X86DIV (translate_out_size sz, translate_out_rm rm) +| HLT -> `X86StopFetching +| Jcc (cond, imm64) -> `X86JCC (translate_out_cond cond, translate_out_imm64 imm64) +| JMP (rm) -> `X86JMP (translate_out_rm rm) +| LEA (sz, dest_src) -> `X86LEA (translate_out_size sz, translate_out_dest_src dest_src) +| LEAVE -> `X86LEAVE +| LOOP (cond, imm64) -> `X86LOOP (translate_out_cond cond, translate_out_imm64 imm64) +| MFENCE -> `X86MFENCE +| Monop (locked, monop, sz, rm) -> `X86MONOP (translate_out_bool locked, translate_out_monop monop, translate_out_size sz, translate_out_rm rm) +| MOV (cond, sz, dest_src) -> `X86MOV (translate_out_cond cond, translate_out_size sz, translate_out_dest_src dest_src) +| MOVSX (sz1, dest_src, sz2) -> `X86MOVSX (translate_out_size sz1, translate_out_dest_src dest_src, translate_out_size sz2) +| MOVZX (sz1, dest_src, sz2) -> `X86MOVZX (translate_out_size sz1, translate_out_dest_src dest_src, translate_out_size sz2) +| X86_MUL (sz, rm) -> `X86MUL (translate_out_size sz, translate_out_rm rm) +| NOP (_) -> `X86NOP +| POP (rm) -> `X86POP (translate_out_rm rm) +| PUSH (imm_rm) -> `X86PUSH (translate_out_imm_rm imm_rm) +| RET (imm64) -> `X86RET (translate_out_imm64 imm64) +| SET (cond, b, rm) -> `X86SET (translate_out_cond cond, translate_out_bool b, translate_out_rm rm) +| STC -> `X86STC +| XADD (locked, sz, rm, reg) -> `X86XADD (translate_out_bool locked, translate_out_size sz, translate_out_rm rm, translate_out_reg reg) +| XCHG (locked, sz, rm, reg) -> `X86XCHG (translate_out_bool locked, translate_out_size sz, translate_out_rm rm, translate_out_reg reg) diff --git a/x86/gen/shallow_types_to_herdtools_types.hgen b/x86/gen/shallow_types_to_herdtools_types.hgen new file mode 100644 index 00000000..ba4eccaa --- /dev/null +++ b/x86/gen/shallow_types_to_herdtools_types.hgen @@ -0,0 +1,97 @@ +let is_inc = false + +let translate_out_bool = function + | Sail_values.B1 -> true + | Sail_values.B0 -> false + | _ -> failwith "translate_out_bool Undef" + +let translate_out_binop = function + | X86_Add -> X86ADD + | X86_Or -> X86OR + | X86_Adc -> X86ADC + | X86_Sbb -> X86SBB + | X86_And -> X86AND + | X86_Sub -> X86SUB + | X86_Xor -> X86XOR + | X86_Cmp -> X86CMP + | X86_Rol -> X86ROL + | X86_Ror -> X86ROR + | X86_Rcl -> X86RCL + | X86_Rcr -> X86RCR + | X86_Shl -> X86SHL + | X86_Shr -> X86SHR + | X86_Test -> X86TEST + | X86_Sar -> X86SAR + +let translate_out_bitop = function + | Btc -> X86Btc + | Bts -> X86Bts + | Btr -> X86Btr + +let translate_out_size = function + | Sz8 (high) -> X86S8 (translate_out_bool high) + | Sz16 -> X86S16 + | Sz32 -> X86S32 + | Sz64 -> X86S64 + +let translate_out_big_bit = Sail_values.unsigned + +let translate_out_int inst = (Nat_big_num.to_int (translate_out_big_bit inst)) + +let translate_out_reg r = IReg (int_to_ireg (Nat_big_num.to_int r)) + +let translate_out_scale = translate_out_int + +let translate_out_imm64 i = translate_out_big_bit i + +let translate_out_msi = function + | Some (scale, reg) -> Some (translate_out_scale scale, translate_out_reg reg) + | None -> None + +let translate_out_base = function + | X86_embed_types.NoBase -> X86HGenBase.NoBase + | X86_embed_types.RegBase(r) -> X86HGenBase.RegBase (translate_out_reg r) + | X86_embed_types.RipBase -> X86HGenBase.RipBase + +let translate_out_rm = function + | X86_embed_types.X86_Reg (r) -> X86HGenBase.Reg (translate_out_reg r) + | X86_embed_types.Mem (m_si, base, imm) -> X86HGenBase.Mem (translate_out_msi m_si, translate_out_base base, translate_out_imm64 imm) + +let translate_out_dest_src = function + | X86_embed_types.R_rm (reg, rm) -> X86HGenBase.R_rm (translate_out_reg reg, translate_out_rm rm) + | X86_embed_types.Rm_i (rm, imm64) -> X86HGenBase.Rm_i (translate_out_rm rm, translate_out_imm64 imm64) + | X86_embed_types.Rm_r (rm, reg) -> X86HGenBase.Rm_r (translate_out_rm rm, translate_out_reg reg) + +let translate_out_imm_rm = function + | X86_embed_types.Imm (imm) -> X86HGenBase.Imm (translate_out_imm64 imm) + | X86_embed_types.Rm (rm) -> X86HGenBase.Rm (translate_out_rm rm) + +let translate_out_bitoffset = function + | Bit_rm_imm (rm, imm) -> X86HGenBase.Bit_rm_imm (translate_out_rm rm, Nat_big_num.to_int (translate_out_imm64 imm)) + | Bit_rm_r (rm, r) -> X86HGenBase.Bit_rm_r (translate_out_rm rm, translate_out_reg r) + +let translate_out_cond = function + | X86_O -> X86O + | X86_NO -> X86NO + | X86_B -> X86B + | X86_NB -> X86NB + | X86_E -> X86E + | X86_NE -> X86NE + | X86_NA -> X86NA + | X86_A -> X86A + | X86_S -> X86S + | X86_NS -> X86NS + | X86_P -> X86P + | X86_NP -> X86NP + | X86_L -> X86L + | X86_NL -> X86NL + | X86_NG -> X86NG + | X86_G -> X86G + | X86_ALWAYS -> X86ALWAYS + +let translate_out_monop = function + | X86_Dec -> X86DEC + | X86_Inc -> X86INC + | X86_Not -> X86NOT + | X86_Neg -> X86NEG + diff --git a/x86/gen/token_types.hgen b/x86/gen/token_types.hgen new file mode 100644 index 00000000..9485e544 --- /dev/null +++ b/x86/gen/token_types.hgen @@ -0,0 +1,29 @@ +type token_BINOP = { txt : string; op : x86Binop; sz : x86Suffix } +type token_BITOP = { txt : string; op : x86Bitop; sz : x86Suffix } +type token_CALL = { txt : string } +type token_CLC = { txt : string } +type token_CMC = { txt : string } +type token_CMOV = { txt : string; cond : x86Cond; sz : x86Suffix } +type token_CMPXCHG = { txt : string; sz : x86Suffix } +type token_DIV = { txt : string; sz : x86Suffix } +type token_JCC = { txt : string; cond : x86Cond } +type token_JMP = { txt : string } +type token_LEA = { txt : string; sz : x86Suffix } +type token_LEAVE = { txt : string } +type token_LOOP = { txt : string; cond : x86Cond } +type token_MFENCE = { txt : string; } +type token_MONOP = { txt : string; op : x86Monop; sz : x86Suffix } +type token_MOV = { txt : string; sz : x86Suffix } +type token_MOVABS = { txt : string } +type token_MOVSX = { txt : string; sz1 : x86Suffix; sz2 : x86Suffix } +type token_MOVZX = { txt : string; sz1 : x86Suffix; sz2 : x86Suffix } +type token_MUL = { txt : string; sz : x86Suffix } +type token_NOP = { txt : string } +type token_POP = { txt : string } +type token_PUSH = { txt : string } +type token_RET = { txt : string } +type token_SET = { txt : string; cond : x86Cond } +type token_STC = { txt : string } +type token_XADD = { txt : string; sz : x86Suffix } +type token_XCHG = { txt : string; sz : x86Suffix } + diff --git a/x86/gen/tokens.hgen b/x86/gen/tokens.hgen new file mode 100644 index 00000000..7aa5256f --- /dev/null +++ b/x86/gen/tokens.hgen @@ -0,0 +1,28 @@ +%token BINOP +%token BITOP +%token CALL +%token CLC +%token CMC +%token CMPXCHG +%token DIV +%token JCC +%token JMP +%token LEA +%token LEAVE +%token LOOP +%token MFENCE +%token MONOP +%token CMOV +%token MOV +%token MOVABS +%token MOVSX +%token MOVZX +%token MUL +%token NOP +%token POP +%token PUSH +%token RET +%token SET +%token STC +%token XADD +%token XCHG diff --git a/x86/gen/trans_sail.hgen b/x86/gen/trans_sail.hgen new file mode 100644 index 00000000..0fdfc803 --- /dev/null +++ b/x86/gen/trans_sail.hgen @@ -0,0 +1,28 @@ +(*| `X86BINOP(binop, sz, dest_src) -> ("Binop", [translate_binop binop; translate_size sz; translate_dest_src dest_src], []) +| `X86CALL (imm_rm) -> ("CALL", [translate_imm_rm imm_rm], []) +| `X86CLC -> ("CLC", [], []) +| `X86CMC -> ("CMC", [], []) +| `X86CMPXCHG (sz, rm , reg) -> ("CMPXCHG", [translate_size sz; translate_rm rm; translate_reg reg], []) +| `X86DIV (sz, rm) -> ("DIV", [translate_size sz; translate_rm rm], []) +| `X86StopFetching -> ("HLT", [], []) +| `X86JCC (cond, imm64) -> ("Jcc", [translate_cond cond; translate_imm64 imm64], []) +| `X86JMP (rm) -> ("JMP", [translate_rm rm], []) +| `X86LEA (sz, dest_src) -> ("LEA", [translate_size sz; translate_dest_src dest_src], []) +| `X86LEAVE -> ("LEAVE", [], []) +| `X86LOOP (cond, imm64) -> ("LOOP", [translate_cond cond; translate_imm64 imm64], []) +| `X86MFENCE -> ("MFENCE", [], []) +| `X86MONOP (monop, sz, rm) -> ("Monop", [translate_monop monop; translate_size sz; translate_rm rm], []) +| `X86MOV (cond, sz, dest_src) -> ("MOV", [translate_cond cond; translate_size sz; translate_dest_src dest_src], []) +| `X86MOVSX (sz1, dest_src, sz2) -> ("MOVSX", [translate_size sz1; translate_dest_src dest_src; translate_size sz2], []) +| `X86MOVZX (sz1, dest_src, sz2) -> ("MOVZX", [translate_size sz1; translate_dest_src dest_src; translate_size sz2], []) +| `X86MUL (sz, rm) -> ("MUL", [translate_size sz; translate_rm rm], []) +| `X86NOP -> ("NOP", [Nat_big_num.of_int 0], []) +| `X86POP (rm) -> ("POP", [translate_rm rm], []) +| `X86PUSH (imm_rm) -> ("PUSH", [translate_imm_rm imm_rm], []) +| `X86RET (imm64) -> ("RET", [translate_imm64 imm64], []) +| `X86SET (cond, b, rm) -> ("SET", [translate_cond cond; translate_bool b; translate_rm rm], []) +| `X86STC -> ("STC", [], []) +| `X86XADD (sz, rm, reg) -> ("XADD", [translate_size sz; translate_rm rm; translate_reg reg], []) +| `X86XCHG (sz, rm, reg) -> ("XCHG", [translate_size sz; translate_rm rm; translate_reg reg], []) + +*) \ No newline at end of file diff --git a/x86/gen/types.hgen b/x86/gen/types.hgen new file mode 100644 index 00000000..117f0f4d --- /dev/null +++ b/x86/gen/types.hgen @@ -0,0 +1,134 @@ +type bit2 = int +type bit64 = Nat_big_num.num +let bit64_of_int = Nat_big_num.of_int +let bit64_to_int = Nat_big_num.to_int +let bit64_to_string = Nat_big_num.to_string +let eq_bit64 = Nat_big_num.equal + +type x86Binop = +| X86ADD +| X86OR +| X86ADC +| X86SBB +| X86AND +| X86SUB +| X86XOR +| X86CMP +| X86ROL +| X86ROR +| X86RCL +| X86RCR +| X86SHL +| X86SHR +| X86TEST +| X86SAR + +let pp_x86Binop = function +| X86ADD -> "add" +| X86OR -> "or" +| X86ADC -> "adc" +| X86SBB -> "sbb" +| X86AND -> "and" +| X86SUB -> "sub" +| X86XOR -> "xor" +| X86CMP -> "cmp" +| X86ROL -> "rol" +| X86ROR -> "ror" +| X86RCL -> "rcl" +| X86RCR -> "rcr" +| X86SHL -> "shl" +| X86SHR -> "shr" +| X86TEST -> "test" +| X86SAR -> "sar" + +type x86Bitop = X86Bts | X86Btc | X86Btr + +let pp_x86Bitop = function +| X86Bts -> "bts" +| X86Btc -> "btc" +| X86Btr -> "btr" + +type x86Monop = +| X86DEC +| X86INC +| X86NOT +| X86NEG + +let pp_x86Monop = function +| X86DEC -> "dec" +| X86INC -> "inc" +| X86NOT -> "not" +| X86NEG -> "neg" + +type x86Cond = +| X86O +| X86NO +| X86B +| X86NB +| X86E +| X86NE +| X86NA +| X86A +| X86S +| X86NS +| X86P +| X86NP +| X86L +| X86NL +| X86NG +| X86G +| X86ALWAYS + +let pp_x86Cond = function +| X86O -> "o" +| X86NO -> "no" +| X86B -> "b" +| X86NB -> "nb" +| X86E -> "e" +| X86NE -> "ne" +| X86NA -> "na" +| X86A -> "a" +| X86S -> "s" +| X86NS -> "ns" +| X86P -> "p" +| X86NP -> "np" +| X86L -> "l" +| X86NL -> "nl" +| X86NG -> "ng" +| X86G -> "g" +| X86ALWAYS -> "" + +type x86Suffix = +| X86BYTE +| X86WORD +| X86LONG +| X86QUAD +| X86NONE + +let pp_x86Suffix = function +| X86BYTE -> "byte" +| X86WORD -> "word" +| X86LONG -> "long" +| X86QUAD -> "quad" +| X86NONE -> "" + +type x86Size = +| X86S8 of bool +| X86S16 +| X86S32 +| X86S64 + +let pp_x86Size = function +| X86S8(_) -> "b" +| X86S16 -> "w" +| X86S32 -> "l" +| X86S64 -> "q" + +let pp_locked l = if l then "lock " else "" + +let suffix_size = function +| X86BYTE -> X86S8 false +| X86WORD -> X86S16 +| X86LONG -> X86S32 +| X86QUAD -> X86S64 +| X86NONE -> X86S64 diff --git a/x86/gen/types_sail_trans_out.hgen b/x86/gen/types_sail_trans_out.hgen new file mode 100644 index 00000000..948db8fa --- /dev/null +++ b/x86/gen/types_sail_trans_out.hgen @@ -0,0 +1 @@ +(* *) diff --git a/x86/gen/types_trans_sail.hgen b/x86/gen/types_trans_sail.hgen new file mode 100644 index 00000000..f088db39 --- /dev/null +++ b/x86/gen/types_trans_sail.hgen @@ -0,0 +1,61 @@ +(*let translate_enum enum_values name value = + let rec bit_count n = + if n = 0 then 0 + else 1 + (bit_count (n lsr 1)) in + let rec find_index element = function + | h::tail -> if h = element then 0 else 1 + (find_index element tail) + | _ -> failwith "translate_enum could not find value" + in + let size = bit_count (List.length enum_values) in + let index = find_index value enum_values in + (name, Range0 (Some size), IInt.bit_list_of_integer size (Nat_big_num.of_int index)) + +let translate_binop = translate_enum [X86ADD ; X86OR ; X86ADC ; X86SBB ; X86AND ; X86SUB ; X86XOR ; X86CMP ; X86ROL ; X86ROR ; X86RCL ; X86RCR ; X86SHL ; X86SHR ; X86TEST; X86SAR] + +let translate_cond = translate_enum [X86O ; X86NO ; X86B ; X86NB ; X86E ; X86NE ; X86NA ; X86A ; X86S ; X86NS ; X86P ; X86NP ; X86L ; X86NL ; X86NG ; X86G ; X86ALWAYS ] + +let translate_monop = translate_enum [X86DEC; X86INC; X86NOT; X86NEG] + +let translate_bool value = + ("bool", Bit, [if value then Bitc_one else Bitc_zero]) + +let translate_size = function + | X86S8(high) -> ("Sz8", [translate_bool high], []) + | X86S16 -> ("Sz16", [], []) + | X86S32 -> ("Sz32", [], []) + | X86S64 -> ("Sz64", [], []) + +let translate_bits bits value = + ("bits", Bvector (Some bits), IInt.bit_list_of_integer bits (Nat_big_num.of_int value)) + +let translate_bits_big bits value = + ("bits", Bvector (Some bits), IInt.bit_list_of_integer bits value) + +let translate_reg r = translate_bits 4 (reg_to_int r) + +let translate_scale s = translate_bits 2 s + +let translate_imm64 i = translate_bits_big 64 i + +let translate_msi = function + | Some (scale, reg) -> ("Some", [translate_scale scale; translate_reg reg], []) + | None -> ("None", [], []) + +let translate_base = function + | X86HGenBase.NoBase -> ("NoBase", [], []) + | X86HGenBase.RegBase(r) -> ("RegBase", [translate_reg r], []) + | X86HGenBase.RipBase -> ("RipBase", [], []) + +let translate_rm = function + | X86HGenBase.Reg (r) -> ("Reg", [translate_reg r], []) + | X86HGenBase.Mem (m_si, base, imm) -> ("Mem", [translate_msi m_si; translate_base base; translate_imm64 imm], []) + +let translate_dest_src = function + | X86HGenBase.R_rm (reg, rm) -> ("R_rm", [translate_reg reg; translate_rm rm], []) + | X86HGenBase.Rm_i (rm, imm64) -> ("Rm_i", [translate_rm rm; translate_imm64 imm64], []) + | X86HGenBase.Rm_r (rm, reg) -> ("Rm_r", [translate_rm rm; translate_reg reg], []) + +let translate_imm_rm = function + | X86HGenBase.Imm (imm) -> ("Imm", [translate_imm64 imm], []) + | X86HGenBase.Rm (rm) -> ("Rm", [translate_rm rm], []) + *) diff --git a/x86/x86_extras.lem b/x86/x86_extras.lem new file mode 100644 index 00000000..d6498d87 --- /dev/null +++ b/x86/x86_extras.lem @@ -0,0 +1,53 @@ +open import Pervasives +open import Interp_ast +open import Interp_interface +open import Sail_impl_base +open import Interp_inter_imp +import Set_extra + +let memory_parameter_transformer mode v = + match v with + | Interp_ast.V_tuple [location;length] -> + let (v,loc_regs) = extern_with_track mode extern_vector_value location in + + match length with + | Interp_ast.V_lit (L_aux (L_num len) _) -> + (v,(natFromInteger len),loc_regs) + | Interp_ast.V_track (Interp_ast.V_lit (L_aux (L_num len) _)) size_regs -> + match loc_regs with + | Nothing -> (v,(natFromInteger len),Just (List.map (fun r -> extern_reg r Nothing) (Set_extra.toList size_regs))) + | Just loc_regs -> (v,(natFromInteger len),Just (loc_regs++(List.map (fun r -> extern_reg r Nothing) (Set_extra.toList size_regs)))) + end + | _ -> Assert_extra.failwith "expected 'V_lit (L_aux (L_num _) _)' or 'V_track (V_lit (L_aux (L_num len) _)) _'" + end + | _ -> Assert_extra.failwith ("memory_parameter_transformer: expected 'V_tuple [_;_]' given " ^ (Interp.string_of_value v)) + end + +let memory_parameter_transformer_option_address _mode v = + match v with + | Interp_ast.V_tuple [location;_] -> + Just (extern_vector_value location) + | _ -> Assert_extra.failwith ("memory_parameter_transformer_option_address: expected 'V_tuple [_;_]' given " ^ (Interp.string_of_value v)) + end + +let x86_read_memory_functions : memory_reads = + [ ("rMEM", (MR Read_plain memory_parameter_transformer)); + ("rMEM_locked", (MR Read_X86_locked memory_parameter_transformer)); + ] + +let x86_memory_writes : memory_writes = + [] + +let x86_memory_eas : memory_write_eas = + [ ("MEMea", (MEA Write_plain memory_parameter_transformer)); + ("MEMea_locked", (MEA Write_X86_locked memory_parameter_transformer)); + ] + +let x86_memory_vals : memory_write_vals = + [ ("MEMval", (MV memory_parameter_transformer_option_address Nothing)); + ] + +let x86_barrier_functions = + [ + ("X86_MFENCE", Barrier_x86_MFENCE); + ] diff --git a/x86/x86_extras_embed.lem b/x86/x86_extras_embed.lem new file mode 100644 index 00000000..f5130995 --- /dev/null +++ b/x86/x86_extras_embed.lem @@ -0,0 +1,24 @@ +open import Pervasives +open import Pervasives_extra +open import Sail_impl_base +open import Sail_values +open import Prompt + +val rMEM : (vector bitU * integer) -> M (vector bitU) +val rMEM_locked : (vector bitU * integer) -> M (vector bitU) + +let rMEM (addr,size) = read_mem false Read_plain addr size +let rMEM_locked (addr,size) = read_mem false Read_X86_locked addr size + +val MEMea : (vector bitU * integer) -> M unit +val MEMea_locked : (vector bitU * integer) -> M unit + +let MEMea (addr,size) = write_mem_ea Write_plain addr size +let MEMea_locked (addr,size) = write_mem_ea Write_X86_locked addr size + +val MEMval : (vector bitU * integer * vector bitU) -> M unit +val MEMval_conditional : (vector bitU * integer * vector bitU) -> M bitU + +let MEMval (_,_,v) = write_mem_val v >>= fun _ -> return () + +let X86_MFENCE () = barrier Barrier_x86_MFENCE diff --git a/x86/x86_extras_embed_sequential.lem b/x86/x86_extras_embed_sequential.lem new file mode 100644 index 00000000..2703b6c4 --- /dev/null +++ b/x86/x86_extras_embed_sequential.lem @@ -0,0 +1,24 @@ +open import Pervasives +open import Pervasives_extra +open import Sail_impl_base +open import Sail_values +open import State + +val rMEM : (vector bitU * integer) -> M (vector bitU) +val rMEM_locked : (vector bitU * integer) -> M (vector bitU) + +let rMEM (addr,size) = read_mem false Read_plain addr size +let rMEM_locked (addr,size) = read_mem false Read_X86_locked addr size + +val MEMea : (vector bitU * integer) -> M unit +val MEMea_locked : (vector bitU * integer) -> M unit + +let MEMea (addr,size) = write_mem_ea Write_plain addr size +let MEMea_locked (addr,size) = write_mem_ea Write_X86_locked addr size + +val MEMval : (vector bitU * integer * vector bitU) -> M unit +val MEMval_conditional : (vector bitU * integer * vector bitU) -> M bitU + +let MEMval (_,_,v) = write_mem_val v >>= fun _ -> return () + +let X86_MFENCE () = barrier Barrier_x86_MFENCE -- cgit v1.2.3 From 748318f8af7b82a01bb151f1bfcb466d0fc8291f Mon Sep 17 00:00:00 2001 From: Shaked Flur Date: Mon, 4 Dec 2017 14:47:38 +0000 Subject: renamed hgen to gen --- etc/power_header | 30 ++++ mips/gen/ast.hgen | 18 ++ mips/gen/fold.hgen | 19 ++ mips/gen/herdtools_ast_to_shallow_ast.hgen | 121 +++++++++++++ mips/gen/herdtools_types_to_shallow_types.hgen | 120 +++++++++++++ mips/gen/lexer.hgen | 116 ++++++++++++ mips/gen/map.hgen | 19 ++ mips/gen/parser.hgen | 34 ++++ mips/gen/pretty.hgen | 36 ++++ mips/gen/sail_trans_out.hgen | 98 ++++++++++ mips/gen/shallow_ast_to_herdtools_ast.hgen | 98 ++++++++++ mips/gen/shallow_types_to_herdtools_types.hgen | 39 ++++ mips/gen/token_types.hgen | 39 ++++ mips/gen/tokens.hgen | 17 ++ mips/gen/trans_sail.hgen | 122 +++++++++++++ mips/gen/types.hgen | 209 ++++++++++++++++++++++ mips/gen/types_sail_trans_out.hgen | 47 +++++ mips/gen/types_trans_sail.hgen | 44 +++++ mips/hgen/ast.hgen | 18 -- mips/hgen/fold.hgen | 19 -- mips/hgen/herdtools_ast_to_shallow_ast.hgen | 121 ------------- mips/hgen/herdtools_types_to_shallow_types.hgen | 120 ------------- mips/hgen/lexer.hgen | 116 ------------ mips/hgen/map.hgen | 19 -- mips/hgen/parser.hgen | 34 ---- mips/hgen/pretty.hgen | 36 ---- mips/hgen/sail_trans_out.hgen | 98 ---------- mips/hgen/shallow_ast_to_herdtools_ast.hgen | 98 ---------- mips/hgen/shallow_types_to_herdtools_types.hgen | 39 ---- mips/hgen/token_types.hgen | 39 ---- mips/hgen/tokens.hgen | 17 -- mips/hgen/trans_sail.hgen | 122 ------------- mips/hgen/types.hgen | 209 ---------------------- mips/hgen/types_sail_trans_out.hgen | 47 ----- mips/hgen/types_trans_sail.hgen | 44 ----- risc-v/gen/ast.hgen | 17 ++ risc-v/gen/fold.hgen | 16 ++ risc-v/gen/herdtools_ast_to_shallow_ast.hgen | 86 +++++++++ risc-v/gen/herdtools_types_to_shallow_types.hgen | 90 ++++++++++ risc-v/gen/lexer.hgen | 190 ++++++++++++++++++++ risc-v/gen/map.hgen | 15 ++ risc-v/gen/parser.hgen | 74 ++++++++ risc-v/gen/pretty.hgen | 30 ++++ risc-v/gen/pretty_xml.hgen | 137 ++++++++++++++ risc-v/gen/sail_trans_out.hgen | 23 +++ risc-v/gen/shallow_ast_to_herdtools_ast.hgen | 23 +++ risc-v/gen/shallow_types_to_herdtools_types.hgen | 84 +++++++++ risc-v/gen/token_types.hgen | 23 +++ risc-v/gen/tokens.hgen | 19 ++ risc-v/gen/trans_sail.hgen | 153 ++++++++++++++++ risc-v/gen/types.hgen | 172 ++++++++++++++++++ risc-v/gen/types_sail_trans_out.hgen | 98 ++++++++++ risc-v/gen/types_trans_sail.hgen | 57 ++++++ risc-v/hgen/ast.hgen | 17 -- risc-v/hgen/fold.hgen | 16 -- risc-v/hgen/herdtools_ast_to_shallow_ast.hgen | 86 --------- risc-v/hgen/herdtools_types_to_shallow_types.hgen | 90 ---------- risc-v/hgen/lexer.hgen | 190 -------------------- risc-v/hgen/map.hgen | 15 -- risc-v/hgen/parser.hgen | 74 -------- risc-v/hgen/pretty.hgen | 30 ---- risc-v/hgen/pretty_xml.hgen | 137 -------------- risc-v/hgen/sail_trans_out.hgen | 23 --- risc-v/hgen/shallow_ast_to_herdtools_ast.hgen | 23 --- risc-v/hgen/shallow_types_to_herdtools_types.hgen | 84 --------- risc-v/hgen/token_types.hgen | 23 --- risc-v/hgen/tokens.hgen | 19 -- risc-v/hgen/trans_sail.hgen | 153 ---------------- risc-v/hgen/types.hgen | 172 ------------------ risc-v/hgen/types_sail_trans_out.hgen | 98 ---------- risc-v/hgen/types_trans_sail.hgen | 57 ------ 71 files changed, 2533 insertions(+), 2503 deletions(-) create mode 100644 etc/power_header create mode 100644 mips/gen/ast.hgen create mode 100644 mips/gen/fold.hgen create mode 100644 mips/gen/herdtools_ast_to_shallow_ast.hgen create mode 100644 mips/gen/herdtools_types_to_shallow_types.hgen create mode 100644 mips/gen/lexer.hgen create mode 100644 mips/gen/map.hgen create mode 100644 mips/gen/parser.hgen create mode 100644 mips/gen/pretty.hgen create mode 100644 mips/gen/sail_trans_out.hgen create mode 100644 mips/gen/shallow_ast_to_herdtools_ast.hgen create mode 100644 mips/gen/shallow_types_to_herdtools_types.hgen create mode 100644 mips/gen/token_types.hgen create mode 100644 mips/gen/tokens.hgen create mode 100644 mips/gen/trans_sail.hgen create mode 100644 mips/gen/types.hgen create mode 100644 mips/gen/types_sail_trans_out.hgen create mode 100644 mips/gen/types_trans_sail.hgen delete mode 100644 mips/hgen/ast.hgen delete mode 100644 mips/hgen/fold.hgen delete mode 100644 mips/hgen/herdtools_ast_to_shallow_ast.hgen delete mode 100644 mips/hgen/herdtools_types_to_shallow_types.hgen delete mode 100644 mips/hgen/lexer.hgen delete mode 100644 mips/hgen/map.hgen delete mode 100644 mips/hgen/parser.hgen delete mode 100644 mips/hgen/pretty.hgen delete mode 100644 mips/hgen/sail_trans_out.hgen delete mode 100644 mips/hgen/shallow_ast_to_herdtools_ast.hgen delete mode 100644 mips/hgen/shallow_types_to_herdtools_types.hgen delete mode 100644 mips/hgen/token_types.hgen delete mode 100644 mips/hgen/tokens.hgen delete mode 100644 mips/hgen/trans_sail.hgen delete mode 100644 mips/hgen/types.hgen delete mode 100644 mips/hgen/types_sail_trans_out.hgen delete mode 100644 mips/hgen/types_trans_sail.hgen create mode 100644 risc-v/gen/ast.hgen create mode 100644 risc-v/gen/fold.hgen create mode 100644 risc-v/gen/herdtools_ast_to_shallow_ast.hgen create mode 100644 risc-v/gen/herdtools_types_to_shallow_types.hgen create mode 100644 risc-v/gen/lexer.hgen create mode 100644 risc-v/gen/map.hgen create mode 100644 risc-v/gen/parser.hgen create mode 100644 risc-v/gen/pretty.hgen create mode 100644 risc-v/gen/pretty_xml.hgen create mode 100644 risc-v/gen/sail_trans_out.hgen create mode 100644 risc-v/gen/shallow_ast_to_herdtools_ast.hgen create mode 100644 risc-v/gen/shallow_types_to_herdtools_types.hgen create mode 100644 risc-v/gen/token_types.hgen create mode 100644 risc-v/gen/tokens.hgen create mode 100644 risc-v/gen/trans_sail.hgen create mode 100644 risc-v/gen/types.hgen create mode 100644 risc-v/gen/types_sail_trans_out.hgen create mode 100644 risc-v/gen/types_trans_sail.hgen delete mode 100644 risc-v/hgen/ast.hgen delete mode 100644 risc-v/hgen/fold.hgen delete mode 100644 risc-v/hgen/herdtools_ast_to_shallow_ast.hgen delete mode 100644 risc-v/hgen/herdtools_types_to_shallow_types.hgen delete mode 100644 risc-v/hgen/lexer.hgen delete mode 100644 risc-v/hgen/map.hgen delete mode 100644 risc-v/hgen/parser.hgen delete mode 100644 risc-v/hgen/pretty.hgen delete mode 100644 risc-v/hgen/pretty_xml.hgen delete mode 100644 risc-v/hgen/sail_trans_out.hgen delete mode 100644 risc-v/hgen/shallow_ast_to_herdtools_ast.hgen delete mode 100644 risc-v/hgen/shallow_types_to_herdtools_types.hgen delete mode 100644 risc-v/hgen/token_types.hgen delete mode 100644 risc-v/hgen/tokens.hgen delete mode 100644 risc-v/hgen/trans_sail.hgen delete mode 100644 risc-v/hgen/types.hgen delete mode 100644 risc-v/hgen/types_sail_trans_out.hgen delete mode 100644 risc-v/hgen/types_trans_sail.hgen diff --git a/etc/power_header b/etc/power_header new file mode 100644 index 00000000..7eaf7da9 --- /dev/null +++ b/etc/power_header @@ -0,0 +1,30 @@ + +Copyright (c) 2015-2017 ??? +All rights reserved. + +This software was developed by the University of Cambridge Computer +Laboratory as part of the Rigorous Engineering of Mainstream Systems +(REMS) project, funded by EPSRC grant EP/K008528/1. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/mips/gen/ast.hgen b/mips/gen/ast.hgen new file mode 100644 index 00000000..a251adff --- /dev/null +++ b/mips/gen/ast.hgen @@ -0,0 +1,18 @@ +| `MIPSThreadStart +| `MIPSRType of mipsRTypeOp * reg * reg * reg +| `MIPSIType of mipsITypeOp * reg * reg * bit16 +| `MIPSShiftI of mipsShiftIOp * reg * reg * bit5 +| `MIPSShiftV of mipsShiftVOp * reg * reg * reg +| `MIPSMulDiv of mipsMulDivOp * reg * reg +| `MIPSMFHiLo of mipsMFHiLoOp * reg +| `MIPSLUI of reg * bit16 +| `MIPSLoad of mipsWordWidth * bool * bool * reg * reg * bit16 (* width, signed, linked, base, rt, offset *) +| `MIPSStore of mipsWordWidth * bool * reg * reg * bit16 (* width, conditional, base, rt, offset *) +| `MIPSLSLR of bool * bool * bool * reg * reg * bit16 (* store, double, left, base, rt, offset *) +| `MIPSSYNC +| `MIPSBEQ of reg * reg * bit16 * bool * bool (* rs, rt, offset, not equal, likely *) +| `MIPSBCMPZ of reg * bit16 * mipsCmp * bool * bool (* rs, offset, cmp, link, likely *) +| `MIPSJ of bit26 +| `MIPSJAL of bit26 +| `MIPSJR of reg +| `MIPSJALR of reg * reg (* rs, rd *) diff --git a/mips/gen/fold.hgen b/mips/gen/fold.hgen new file mode 100644 index 00000000..05b9c808 --- /dev/null +++ b/mips/gen/fold.hgen @@ -0,0 +1,19 @@ +| `MIPSThreadStart -> (y_reg, y_sreg) +| `MIPSRType (op, rd, rs, rt) -> fold_reg rt (fold_reg rs (fold_reg rd (y_reg, y_sreg))) +| `MIPSIType (op, rs, rt, imm) -> fold_reg rs (fold_reg rt (y_reg, y_sreg)) +| `MIPSShiftI (op, rd, rt, imm) -> fold_reg rt (fold_reg rd (y_reg, y_sreg)) +| `MIPSShiftV (op, rd, rt, rs) -> fold_reg rs (fold_reg rt (fold_reg rd (y_reg, y_sreg))) +| `MIPSMulDiv (op, rs, rt) -> fold_reg rs (fold_reg rt (y_reg, y_sreg)) +| `MIPSMFHiLo (op, rs) -> fold_reg rs (y_reg, y_sreg) +| `MIPSLUI (rt, imm) -> fold_reg rt (y_reg, y_sreg) +| `MIPSLoad (width, signed, linked, base, rt, offset) -> fold_reg rt (fold_reg base (y_reg, y_sreg)) +| `MIPSStore (width, conditional, base, rt, offset) -> fold_reg rt (fold_reg base (y_reg, y_sreg)) +| `MIPSLSLR (store, double, left, base, rt, offset) -> fold_reg rt (fold_reg base (y_reg, y_sreg)) +| `MIPSSYNC -> (y_reg, y_sreg) +| `MIPSBEQ (rs, rt, offset, ne, likely) -> fold_reg rs (fold_reg rt (y_reg, y_sreg)) +| `MIPSBCMPZ (rs, offset, cmp, link, likely) -> fold_reg rs (y_reg, y_sreg) +| `MIPSJ (offset) -> (y_reg, y_sreg) +| `MIPSJAL (offset) -> fold_reg (IReg(R31)) (y_reg, y_sreg) +| `MIPSJR (rd) -> fold_reg rd (y_reg, y_sreg) +| `MIPSJALR (rd, rs) -> fold_reg rd (fold_reg rs (y_reg, y_sreg)) + diff --git a/mips/gen/herdtools_ast_to_shallow_ast.hgen b/mips/gen/herdtools_ast_to_shallow_ast.hgen new file mode 100644 index 00000000..7b1a58d9 --- /dev/null +++ b/mips/gen/herdtools_ast_to_shallow_ast.hgen @@ -0,0 +1,121 @@ +| `MIPSThreadStart -> + SYSCALL_THREAD_START + +| `MIPSStopFetching -> + ImplementationDefinedStopFetching0 + +(* Note different argument order, which reflects difference + between instruction encoding and asm format *) +| `MIPSRType (op, rd, rs, rt) -> + (translate_rtype_op op) + ( + translate_reg "rs" rs, + translate_reg "rt" rt, + translate_reg "rd" rd + ) + + +(* Note different argument order similar to above *) +| `MIPSIType (op, rt, rs, imm) -> + (translate_itype_op op) + ( + translate_reg "rs" rs, + translate_reg "rt" rt, + translate_imm16 "imm" imm + ) + + +| `MIPSShiftI (op, rd, rt, sa) -> + (translate_shifti_op op) + ( + translate_reg "rt" rt, + translate_reg "rd" rd, + translate_imm5 "sa" sa + ) + + +| `MIPSShiftV (op, rd, rt, rs) -> + (translate_shiftv_op op) + ( + translate_reg "rs" rs, + translate_reg "rt" rt, + translate_reg "rd" rd + ) + + +| `MIPSMulDiv (op, rs, rt) -> + (translate_muldiv_op op) + ( + translate_reg "rs" rs, + translate_reg "rt" rt + ) + + +| `MIPSMFHiLo (op, rs) -> + (translate_mfhilo_op op) + ( + translate_reg "rs" rs + ) + +| `MIPSLUI (rt, imm) -> + LUI + ( + translate_reg "rt" rt, + translate_imm16 "imm" imm + ) + +| `MIPSLoad (width, signed, linked, base, rt, offset) -> + Load + ( + translate_wordsize "width" width, + translate_bool "signed" signed, + translate_bool "linked" linked, + translate_reg "base" base, + translate_reg "rt" rt, + translate_imm16 "offset" offset + ) + +| `MIPSStore (width, conditional, base, rt, offset) -> + Store + ( + translate_wordsize "width" width, + translate_bool "conditional" conditional, + translate_reg "base" base, + translate_reg "rt" rt, + translate_imm16 "offset" offset + ) + +| `MIPSLSLR (store, double, left, base, rt, offset) -> + (translate_lslr_op store double left) + ( + translate_reg "base" base, + translate_reg "rt" rt, + translate_imm16 "offset" offset + ) + +| `MIPSSYNC -> SYNC +| `MIPSBEQ (rs, rt, offset, ne, likely) -> + BEQ + (translate_reg "rs" rs, + translate_reg "rt" rt, + translate_imm16 "offset" offset, + translate_bool "ne" ne, + translate_bool "likely" likely + ) + +| `MIPSBCMPZ (rs, offset, cmp, link, likely) -> + BCMPZ + (translate_reg "rs" rs, + translate_imm16 "offset" offset, + translate_cmp "cmp" cmp, + translate_bool "link" link, + translate_bool "likely" likely + ) +| `MIPSJ (offset) -> + J (translate_imm26 "offset" offset) +| `MIPSJAL (offset) -> + JAL (translate_imm26 "offset" offset) +| `MIPSJR(rd) -> + JR (translate_reg "rd" rd) +| `MIPSJALR(rd, rs) -> + JALR (translate_reg "rd" rd, translate_reg "rs" rs) diff --git a/mips/gen/herdtools_types_to_shallow_types.hgen b/mips/gen/herdtools_types_to_shallow_types.hgen new file mode 100644 index 00000000..5a0e3bfc --- /dev/null +++ b/mips/gen/herdtools_types_to_shallow_types.hgen @@ -0,0 +1,120 @@ +let is_inc = false + +let translate_rtype_op op = uppercase (pp_rtype_op op) + +let translate_rtype_op op x = match op with + | MIPSROpADD -> ADD x + | MIPSROpADDU -> ADDU x + | MIPSROpAND -> AND x + | MIPSROpDADD -> DADD x + | MIPSROpDADDU -> DADDU x + | MIPSROpDSUB -> DSUB x + | MIPSROpDSUBU -> DSUBU x + | MIPSROpMOVN -> MOVN x + | MIPSROpMOVZ -> MOVZ x + | MIPSROpMUL -> MUL x + | MIPSROpNOR -> NOR x + | MIPSROpOR -> OR x + | MIPSROpSLT -> SLT x + | MIPSROpSLTU -> SLTU x + | MIPSROpSUB -> SUB x + | MIPSROpSUBU -> SUBU x + | MIPSROpXOR -> XOR x + +let translate_itype_op op x = match op with + | MIPSIOpADDI -> ADDI x + | MIPSIOpADDIU -> ADDIU x + | MIPSIOpANDI -> ANDI x + | MIPSIOpDADDI -> DADDI x + | MIPSIOpDADDIU -> DADDIU x + | MIPSIOpORI -> ORI x + | MIPSIOpSLTI -> SLTI x + | MIPSIOpSLTIU -> SLTIU x + | MIPSIOpXORI -> XORI x + +let translate_shifti_op op x = match op with + | MIPSDSLL -> DSLL x + | MIPSDSLL32 -> DSLL32 x + | MIPSDSRA -> DSRA x + | MIPSDSRA32 -> DSRA32 x + | MIPSDSRL -> DSRL x + | MIPSDSRL32 -> DSRL32 x + | MIPSSLL -> SLL x + | MIPSSRA -> SRA x + | MIPSSRL -> SRL x + +let translate_shiftv_op op x = match op with + | MIPSDSLLV -> DSLLV x + | MIPSDSRAV -> DSRAV x + | MIPSDSRLV -> DSRLV x + | MIPSSLLV -> SLLV x + | MIPSSRAV -> SRAV x + | MIPSSRLV -> SRLV x + +let translate_muldiv_op op x = match op with + | MIPSDDIV -> DDIV x + | MIPSDDIVU -> DDIVU x + | MIPSDIV -> DIV x + | MIPSDIVU -> DIVU x + | MIPSDMULT -> DMULT x + | MIPSDMULTU -> DMULTU x + | MIPSMADD -> MADD x + | MIPSMADDU -> MADDU x + | MIPSMSUB -> MSUB x + | MIPSMSUBU -> MSUBU x + | MIPSMULT -> MULT x + | MIPSMULTU -> MULTU x + +let translate_mfhilo_op op x = match op with + | MIPSMFHI -> MFHI x + | MIPSMFLO -> MFLO x + | MIPSMTHI -> MTHI x + | MIPSMTLO -> MTLO x + +let translate_load_op width signed linked = uppercase (pp_load_op width signed linked) + +let translate_store_op width conditional = uppercase (pp_store_op width conditional) + +let translate_lslr_op store double left x = match (store,double,left) with + | (false, false, true ) -> LWL x + | (false, false, false) -> LWR x + | (false, true , true ) -> LDL x + | (false, true , false) -> LDR x + | (true , false, true ) -> SWL x + | (true , false, false) -> SWR x + | (true , true , true ) -> SDL x + | (true , true , false) -> SDR x + +let translate_beq_op ne likely = uppercase (pp_beq_op ne likely) + +let translate_bcmpz_op cmp link likely = uppercase (pp_bcmpz_op cmp link likely) + + +let translate_reg name value = + Sail_values.to_vec0 is_inc (Nat_big_num.of_int 5,Nat_big_num.of_int (reg_to_int value)) + +let translate_imm26 name value = + Sail_values.to_vec0 is_inc (Nat_big_num.of_int 26,Nat_big_num.of_int value) +let translate_imm16 name value = + Sail_values.to_vec0 is_inc (Nat_big_num.of_int 16,Nat_big_num.of_int value) +let translate_imm5 name value = + Sail_values.to_vec0 is_inc (Nat_big_num.of_int 5,Nat_big_num.of_int value) +let translate_bool name = function + | true -> Sail_values.B1 + | false -> Sail_values.B0 + +let translate_wordsize _ = function + | MIPSByte -> Mips_embed_types.B2 + | MIPSHalf -> Mips_embed_types.H + | MIPSWord -> Mips_embed_types.W + | MIPSDouble -> Mips_embed_types.D + +let translate_cmp _ = function + | MIPS_EQ -> EQ' + | MIPS_NE -> NE + | MIPS_GE -> GE + | MIPS_GEU -> GEU + | MIPS_GT -> GT' + | MIPS_LE -> LE + | MIPS_LT -> LT' + | MIPS_LTU -> LTU diff --git a/mips/gen/lexer.hgen b/mips/gen/lexer.hgen new file mode 100644 index 00000000..c01b14cc --- /dev/null +++ b/mips/gen/lexer.hgen @@ -0,0 +1,116 @@ +"add" , RTYPE {txt="ADD" ; op=MIPSROpADD }; +"addu" , RTYPE {txt="ADDU" ; op=MIPSROpADDU }; +"and" , RTYPE {txt="AND" ; op=MIPSROpAND }; +"dadd" , RTYPE {txt="DADD" ; op=MIPSROpDADD }; +"daddu" , RTYPE {txt="DADDU" ; op=MIPSROpDADDU }; +"dsub" , RTYPE {txt="DSUB" ; op=MIPSROpDSUB }; +"dsubu" , RTYPE {txt="DSUBU" ; op=MIPSROpDSUBU }; +"movn" , RTYPE {txt="MOVN" ; op=MIPSROpMOVN }; +"movz" , RTYPE {txt="MOVZ" ; op=MIPSROpMOVZ }; +"mul" , RTYPE {txt="MUL" ; op=MIPSROpMUL }; +"nor" , RTYPE {txt="NOR" ; op=MIPSROpNOR }; +"or" , RTYPE {txt="OR" ; op=MIPSROpOR }; +"slt" , RTYPE {txt="SLT" ; op=MIPSROpSLT }; +"sltu" , RTYPE {txt="SLTU" ; op=MIPSROpSLTU }; +"sub" , RTYPE {txt="SUB" ; op=MIPSROpSUB }; +"subu" , RTYPE {txt="SUBU" ; op=MIPSROpSUBU }; +"xor" , RTYPE {txt="XOR" ; op=MIPSROpXOR }; + +"addi" , ITYPE {txt="ADDI" ; op=MIPSIOpADDI }; +"addiu" , ITYPE {txt="ADDIU" ; op=MIPSIOpADDIU }; +"andi" , ITYPE {txt="ANDI" ; op=MIPSIOpANDI }; +"daddi" , ITYPE {txt="DADDI" ; op=MIPSIOpDADDI }; +"daddiu", ITYPE {txt="DADDIU"; op=MIPSIOpDADDIU }; +"ori" , ITYPE {txt="ORI" ; op=MIPSIOpORI }; +"slti" , ITYPE {txt="SLTI" ; op=MIPSIOpSLTI }; +"sltiu" , ITYPE {txt="SLTIU" ; op=MIPSIOpSLTIU }; +"xori" , ITYPE {txt="XORI" ; op=MIPSIOpXORI }; + +"dsll" , SHIFTI {txt="DSLL" ; op=MIPSDSLL }; +"dsll32" , SHIFTI {txt="DSLL32" ; op=MIPSDSLL32 }; +"dsra" , SHIFTI {txt="DSRA" ; op=MIPSDSRA }; +"dsra32" , SHIFTI {txt="DSRA32" ; op=MIPSDSRA32 }; +"dsrl" , SHIFTI {txt="DSRL" ; op=MIPSDSRL }; +"dsrl32" , SHIFTI {txt="DSRL32" ; op=MIPSDSRL32 }; +"sll" , SHIFTI {txt="SLL" ; op=MIPSSLL }; +"sra" , SHIFTI {txt="SRA" ; op=MIPSSRA }; +"srl" , SHIFTI {txt="SRL" ; op=MIPSSRL }; + +"dsllv", SHIFTV {txt="DSLLV" ; op=MIPSDSLLV }; +"dsrav", SHIFTV {txt="DSRAV" ; op=MIPSDSRAV }; +"dsrlv", SHIFTV {txt="DSRLV" ; op=MIPSDSRLV }; +"sllv" , SHIFTV {txt="SLLV" ; op=MIPSSLLV }; +"srav" , SHIFTV {txt="SRAV" ; op=MIPSSRAV }; +"srlv" , SHIFTV {txt="SRLV" ; op=MIPSSRLV }; + +"ddiv" , MULDIV {txt="DDIV" ; op=MIPSDDIV }; +"ddivu" , MULDIV {txt="DDIVU" ; op=MIPSDDIVU }; +"div" , MULDIV {txt="DIV" ; op=MIPSDIV }; +"divu" , MULDIV {txt="DIVU" ; op=MIPSDIVU }; +"dmult" , MULDIV {txt="DMULT" ; op=MIPSDMULT }; +"dmultu", MULDIV {txt="DMULTU"; op=MIPSDMULTU }; +"madd" , MULDIV {txt="MADD" ; op=MIPSMADD }; +"maddu" , MULDIV {txt="MADDU" ; op=MIPSMADDU }; +"msub" , MULDIV {txt="MSUB" ; op=MIPSMSUB }; +"msubu" , MULDIV {txt="MSUBU" ; op=MIPSMSUBU }; +"mult" , MULDIV {txt="MULT" ; op=MIPSMULT }; +"multu" , MULDIV {txt="MULTU" ; op=MIPSMULTU }; + +"mfhi" , MFHILO {txt="MFHI" ; op=MIPSMFHI }; +"mflo" , MFHILO {txt="MFLO" ; op=MIPSMFLO }; +"mthi" , MFHILO {txt="MTHI" ; op=MIPSMTHI }; +"mtlo" , MFHILO {txt="MTLO" ; op=MIPSMTLO }; + +"lui" , LUI {txt="LUI" }; + +"lb" , LOAD {txt="LB" ; width=MIPSByte ; signed=true; linked=false }; +"lbu" , LOAD {txt="LBU" ; width=MIPSByte ; signed=false; linked=false }; +"lh" , LOAD {txt="LH" ; width=MIPSHalf ; signed=true; linked=false }; +"lhu" , LOAD {txt="LHU" ; width=MIPSHalf ; signed=false; linked=false }; +"lw" , LOAD {txt="LW" ; width=MIPSWord ; signed=true; linked=false }; +"lwu" , LOAD {txt="LWU" ; width=MIPSWord ; signed=false; linked=false }; +"ld" , LOAD {txt="LD" ; width=MIPSDouble ; signed=false; linked=false }; +"ll" , LOAD {txt="LL" ; width=MIPSWord ; signed=true; linked=true }; +"lld" , LOAD {txt="LLD" ; width=MIPSDouble ; signed=false; linked=true }; + +"sb" , STORE {txt="SB" ; width=MIPSByte ; conditional=false }; +"sh" , STORE {txt="SH" ; width=MIPSHalf ; conditional=false }; +"sw" , STORE {txt="SW" ; width=MIPSWord ; conditional=false }; +"sd" , STORE {txt="SD" ; width=MIPSDouble ; conditional=false }; +"sc" , STORE {txt="SC" ; width=MIPSWord ; conditional=true }; +"scd" , STORE {txt="SCD" ; width=MIPSDouble ; conditional=true }; + +"lwl" , LSLR {txt="LWL" ; store=false; double=false; left=true }; +"lwr" , LSLR {txt="LWR" ; store=false; double=false; left=false}; +"ldl" , LSLR {txt="LDL" ; store=false; double=true ; left=true }; +"ldr" , LSLR {txt="LDR" ; store=false; double=true ; left=false}; +"swl" , LSLR {txt="SWL" ; store=true ; double=false; left=true }; +"swr" , LSLR {txt="SWR" ; store=true ; double=false; left=false}; +"sdl" , LSLR {txt="SDL" ; store=true ; double=true ; left=true }; +"sdr" , LSLR {txt="SDR" ; store=true ; double=true ; left=false}; +"sync", SYNC {txt="SYNC"}; + +"beq", BEQ {txt="BEQ"; ne=false; likely=false }; +"beql", BEQ {txt="BEQ"; ne=false; likely=true }; +"bne", BEQ {txt="BEQ"; ne=true ; likely=false }; +"bnel", BEQ {txt="BEQ"; ne=true ; likely=true }; + +"bltz", BCMPZ {txt="BCMPZ"; cmp=MIPS_LT; likely=false; link=false }; +"bltzal", BCMPZ {txt="BCMPZ"; cmp=MIPS_LT; likely=false; link=true }; +"bltzl", BCMPZ {txt="BCMPZ"; cmp=MIPS_LT; likely=true; link=false }; +"bltzall",BCMPZ {txt="BCMPZ"; cmp=MIPS_LT; likely=true; link=true }; + +"bgez", BCMPZ {txt="BCMPZ"; cmp=MIPS_GE; likely=false; link=false }; +"bgezal", BCMPZ {txt="BCMPZ"; cmp=MIPS_GE; likely=false; link=true }; +"bgezl", BCMPZ {txt="BCMPZ"; cmp=MIPS_GE; likely=true; link=false }; +"bgezall",BCMPZ {txt="BCMPZ"; cmp=MIPS_GE; likely=true; link=true }; + +"bgtz", BCMPZ {txt="BCMPZ"; cmp=MIPS_GT; likely=false; link=false }; +"bgtzl", BCMPZ {txt="BCMPZ"; cmp=MIPS_GT; likely=true; link=false }; + +"blez", BCMPZ {txt="BCMPZ"; cmp=MIPS_LE; likely=false; link=false }; +"blezl", BCMPZ {txt="BCMPZ"; cmp=MIPS_LE; likely=true; link=false }; +"j", J {txt="J"}; +"jal", JAL {txt="JAL"}; +"jr", JR {txt="JR"}; +"jalr", JALR {txt="JALR"}; diff --git a/mips/gen/map.hgen b/mips/gen/map.hgen new file mode 100644 index 00000000..f5116bae --- /dev/null +++ b/mips/gen/map.hgen @@ -0,0 +1,19 @@ +| `MIPSThreadStart -> `MIPSThreadStart +| `MIPSRType (op, rd, rs, rt) -> `MIPSRType (op, map_reg rd, map_reg rs, map_reg rt) +| `MIPSIType (op, rs, rt, imm) -> `MIPSIType (op, map_reg rs, map_reg rt, imm) +| `MIPSShiftI (op, rd, rt, imm) -> `MIPSShiftI (op, map_reg rd, map_reg rt, imm) +| `MIPSShiftV (op, rd, rt, rs) -> `MIPSShiftV (op, map_reg rd, map_reg rt, map_reg rs) +| `MIPSMulDiv (op, rs, rt) -> `MIPSMulDiv (op, map_reg rs, map_reg rt) +| `MIPSMFHiLo (op, rs) -> `MIPSMFHiLo (op, map_reg rs) +| `MIPSLUI (rt, imm) -> `MIPSLUI (map_reg rt, imm) +| `MIPSLoad (width, signed, linked, base, rt, offset) -> `MIPSLoad (width, signed, linked, map_reg base, map_reg rt, offset) +| `MIPSStore (width, conditional, base, rt, offset) -> `MIPSStore (width, conditional, map_reg base, map_reg rt, offset) +| `MIPSLSLR (store, double, left, base, rt, offset) -> `MIPSLSLR (store, double, left, map_reg base, map_reg rt, offset) +| `MIPSSYNC -> `MIPSSYNC +| `MIPSBEQ (rs, rt, offset, ne, likely) -> `MIPSBEQ (map_reg rs, map_reg rt, offset, ne, likely) +| `MIPSBCMPZ (rs, offset, cmp, link, likely) -> `MIPSBCMPZ (map_reg rs, offset, cmp, link, likely) +| `MIPSJ (offset) -> `MIPSJ (offset) +| `MIPSJAL (offset) -> `MIPSJAL (offset) (* implicit R31? *) +| `MIPSJR (rd) -> `MIPSJR (map_reg rd) +| `MIPSJALR (rd, rs) -> `MIPSJALR(map_reg rd, map_reg rs) + diff --git a/mips/gen/parser.hgen b/mips/gen/parser.hgen new file mode 100644 index 00000000..8f573aa5 --- /dev/null +++ b/mips/gen/parser.hgen @@ -0,0 +1,34 @@ +| RTYPE reg COMMA reg COMMA reg + { `MIPSRType ($1.op, $2, $4, $6) } +| ITYPE reg COMMA reg COMMA NUM + { `MIPSIType ($1.op, $2, $4, $6) } +| SHIFTI reg COMMA reg COMMA NUM + { `MIPSShiftI ($1.op, $2, $4, $6) } +| SHIFTV reg COMMA reg COMMA reg + { `MIPSShiftV ($1.op, $2, $4, $6) } +| MULDIV reg COMMA reg + { `MIPSMulDiv ($1.op, $2, $4) } +| MFHILO reg + { `MIPSMFHiLo ($1.op, $2) } +| LUI reg COMMA NUM + { `MIPSLUI ($2, $4) } +| LOAD reg COMMA NUM LPAR reg RPAR + { `MIPSLoad ($1.width, $1.signed, $1.linked, $6, $2, $4) } +| STORE reg COMMA NUM LPAR reg RPAR + { `MIPSStore ($1.width, $1.conditional, $6, $2, $4) } +| LSLR reg COMMA NUM LPAR reg RPAR + { `MIPSLSLR ($1.store, $1.double, $1.left, $6, $2, $4) } +| SYNC + { `MIPSSYNC } +| BEQ reg COMMA reg COMMA NUM + { `MIPSBEQ ( $2, $4, $6, $1.ne, $1.likely) } +| BCMPZ reg COMMA NUM + { `MIPSBCMPZ ( $2, $4, $1.cmp, $1.link, $1.likely) } +| J NUM + { `MIPSJ ($2) } +| JAL NUM + { `MIPSJAL ($2) } +| JR reg + { `MIPSJR ($2) } +| JALR reg COMMA reg + { `MIPSJALR ($2, $4) } diff --git a/mips/gen/pretty.hgen b/mips/gen/pretty.hgen new file mode 100644 index 00000000..98f56f2e --- /dev/null +++ b/mips/gen/pretty.hgen @@ -0,0 +1,36 @@ +| `MIPSThreadStart -> "syscall 0xfffff" (* thread start *) +| `MIPSStopFetching -> "STOP" (* TODO *) +| `MIPSRType (op, rd,rs,rt) -> + sprintf "%s %s,%s,%s" (pp_rtype_op op) (pp_reg rd) (pp_reg rs) (pp_reg rt) +| `MIPSIType (op,rd,rs,imm) -> + sprintf "%s %s,%s,%d" (pp_itype_op op) (pp_reg rd) (pp_reg rs) imm +| `MIPSShiftI (op, rs, rt, imm) -> + sprintf "%s %s,%s,%d" (pp_shifti_op op) (pp_reg rs) (pp_reg rt) imm +| `MIPSShiftV (op, rd,rs,rt) -> + sprintf "%s %s,%s,%s" (pp_shiftv_op op) (pp_reg rd) (pp_reg rs) (pp_reg rt) +| `MIPSMulDiv (op, rs, rt) -> + sprintf "%s %s,%s" (pp_muldiv_op op) (pp_reg rs) (pp_reg rt) +| `MIPSMFHiLo (op, rs) -> + sprintf "%s %s" (pp_mfhilo_op op) (pp_reg rs) +| `MIPSLUI (rt, imm) -> + sprintf "lui %s,%d" (pp_reg rt) imm +| `MIPSLoad (width, signed, linked, base, rt, offset) -> + sprintf "%s %s,%d(%s)" (pp_load_op width signed linked) (pp_reg rt) offset (pp_reg base) +| `MIPSStore (width, conditional, base, rt, offset) -> + sprintf "%s %s,%d(%s)" (pp_store_op width conditional) (pp_reg rt) offset (pp_reg base) +| `MIPSLSLR (store, double, left, base, rt, offset) -> + sprintf "%s %s,%d(%s)" (pp_lslr_op store double left) (pp_reg rt) offset (pp_reg base) +| `MIPSSYNC -> "sync" +| `MIPSBEQ (rs, rt, offset, ne, likely) -> + sprintf "%s %s,%s,.%+d" (pp_beq_op ne likely) (pp_reg rs) (pp_reg rt) offset +| `MIPSBCMPZ (rs, offset, cmp, link, likely) -> + sprintf "%s,%s,.%+d" (pp_bcmpz_op cmp link likely) (pp_reg rs) offset +| `MIPSJ (offset) -> + sprintf "j %d" offset +| `MIPSJAL (offset) -> + sprintf "jal %d" offset +| `MIPSJR(rd) -> + sprintf "jr %s" (pp_reg rd) +| `MIPSJALR(rd, rs) -> + sprintf "jalr %s,%s" (pp_reg rd) (pp_reg rs) + diff --git a/mips/gen/sail_trans_out.hgen b/mips/gen/sail_trans_out.hgen new file mode 100644 index 00000000..f2d006e8 --- /dev/null +++ b/mips/gen/sail_trans_out.hgen @@ -0,0 +1,98 @@ +| ("SYSCALL_THREAD_START", []) -> `MIPSThreadStart +| ("ADD" , [rs; rt; rd]) -> `MIPSRType (MIPSROpADD , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| ("ADDU" , [rs; rt; rd]) -> `MIPSRType (MIPSROpADDU , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| ("AND" , [rs; rt; rd]) -> `MIPSRType (MIPSROpAND , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| ("DADD" , [rs; rt; rd]) -> `MIPSRType (MIPSROpDADD , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| ("DADDU" , [rs; rt; rd]) -> `MIPSRType (MIPSROpDADDU , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| ("DSUB" , [rs; rt; rd]) -> `MIPSRType (MIPSROpDSUB , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| ("DSUBU" , [rs; rt; rd]) -> `MIPSRType (MIPSROpDSUBU , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| ("MOVN" , [rs; rt; rd]) -> `MIPSRType (MIPSROpMOVN , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| ("MOVZ" , [rs; rt; rd]) -> `MIPSRType (MIPSROpMOVZ , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| ("MUL" , [rs; rt; rd]) -> `MIPSRType (MIPSROpMUL , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| ("NOR" , [rs; rt; rd]) -> `MIPSRType (MIPSROpNOR , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| ("OR" , [rs; rt; rd]) -> `MIPSRType (MIPSROpOR , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| ("SLT" , [rs; rt; rd]) -> `MIPSRType (MIPSROpSLT , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| ("SLTU" , [rs; rt; rd]) -> `MIPSRType (MIPSROpSLTU , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| ("SUB" , [rs; rt; rd]) -> `MIPSRType (MIPSROpSUB , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| ("SUBU" , [rs; rt; rd]) -> `MIPSRType (MIPSROpSUBU , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| ("XOR" , [rs; rt; rd]) -> `MIPSRType (MIPSROpXOR , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) + +| ("ADDI" , [rs; rt; imm]) -> `MIPSIType (MIPSIOpADDI ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_simm16 imm)) +| ("ADDIU" , [rs; rt; imm]) -> `MIPSIType (MIPSIOpADDIU ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_simm16 imm)) +| ("ANDI" , [rs; rt; imm]) -> `MIPSIType (MIPSIOpANDI ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_imm16 imm)) +| ("DADDI" , [rs; rt; imm]) -> `MIPSIType (MIPSIOpDADDI ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_simm16 imm)) +| ("DADDIU", [rs; rt; imm]) -> `MIPSIType (MIPSIOpDADDIU,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_simm16 imm)) +| ("ORI" , [rs; rt; imm]) -> `MIPSIType (MIPSIOpORI ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_imm16 imm)) +| ("SLTI" , [rs; rt; imm]) -> `MIPSIType (MIPSIOpSLTI ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_simm16 imm)) +| ("SLTIU" , [rs; rt; imm]) -> `MIPSIType (MIPSIOpSLTIU ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_simm16 imm)) +| ("XORI" , [rs; rt; imm]) -> `MIPSIType (MIPSIOpXORI ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_imm16 imm)) + +| ("DSLL" , [rt; rd; sa]) -> `MIPSShiftI (MIPSDSLL , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) +| ("DSLL32" , [rt; rd; sa]) -> `MIPSShiftI (MIPSDSLL32 , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) +| ("DSRA" , [rt; rd; sa]) -> `MIPSShiftI (MIPSDSRA , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) +| ("DSRA32" , [rt; rd; sa]) -> `MIPSShiftI (MIPSDSRA32 , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) +| ("DSRL" , [rt; rd; sa]) -> `MIPSShiftI (MIPSDSRL , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) +| ("DSRL32" , [rt; rd; sa]) -> `MIPSShiftI (MIPSDSRL32 , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) +| ("SLL" , [rt; rd; sa]) -> `MIPSShiftI (MIPSSLL , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) +| ("SRA" , [rt; rd; sa]) -> `MIPSShiftI (MIPSSRA , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) +| ("SRL" , [rt; rd; sa]) -> `MIPSShiftI (MIPSSRL , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) + +| "DSLLV" , [rs; rt; rd] -> `MIPSShiftV (MIPSDSLLV , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_ireg rs)) +| "DSRAV" , [rs; rt; rd] -> `MIPSShiftV (MIPSDSRAV , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_ireg rs)) +| "DSRLV" , [rs; rt; rd] -> `MIPSShiftV (MIPSDSRLV , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_ireg rs)) +| "SLLV" , [rs; rt; rd] -> `MIPSShiftV (MIPSSLLV , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_ireg rs)) +| "SRAV" , [rs; rt; rd] -> `MIPSShiftV (MIPSSRAV , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_ireg rs)) +| "SRLV" , [rs; rt; rd] -> `MIPSShiftV (MIPSSRLV , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_ireg rs)) + +| "DDIV" , [rs; rt] -> `MIPSMulDiv (MIPSDDIV , (translate_out_ireg rs), (translate_out_ireg rt)) +| "DDIVU" , [rs; rt] -> `MIPSMulDiv (MIPSDDIVU , (translate_out_ireg rs), (translate_out_ireg rt)) +| "DIV" , [rs; rt] -> `MIPSMulDiv (MIPSDIV , (translate_out_ireg rs), (translate_out_ireg rt)) +| "DIVU" , [rs; rt] -> `MIPSMulDiv (MIPSDIVU , (translate_out_ireg rs), (translate_out_ireg rt)) +| "DMULT" , [rs; rt] -> `MIPSMulDiv (MIPSDMULT , (translate_out_ireg rs), (translate_out_ireg rt)) +| "DMULTU", [rs; rt] -> `MIPSMulDiv (MIPSDMULTU , (translate_out_ireg rs), (translate_out_ireg rt)) +| "MADD" , [rs; rt] -> `MIPSMulDiv (MIPSMADD , (translate_out_ireg rs), (translate_out_ireg rt)) +| "MADDU" , [rs; rt] -> `MIPSMulDiv (MIPSMADDU , (translate_out_ireg rs), (translate_out_ireg rt)) +| "MSUB" , [rs; rt] -> `MIPSMulDiv (MIPSMSUB , (translate_out_ireg rs), (translate_out_ireg rt)) +| "MSUBU" , [rs; rt] -> `MIPSMulDiv (MIPSMSUBU , (translate_out_ireg rs), (translate_out_ireg rt)) +| "MULT" , [rs; rt] -> `MIPSMulDiv (MIPSMULT , (translate_out_ireg rs), (translate_out_ireg rt)) +| "MULTU" , [rs; rt] -> `MIPSMulDiv (MIPSMULTU , (translate_out_ireg rs), (translate_out_ireg rt)) + +| "MFHI" , [rs] -> `MIPSMFHiLo (MIPSMFHI, (translate_out_ireg rs)) +| "MFLO" , [rs] -> `MIPSMFHiLo (MIPSMFLO, (translate_out_ireg rs)) +| "MTHI" , [rs] -> `MIPSMFHiLo (MIPSMTHI, (translate_out_ireg rs)) +| "MTLO" , [rs] -> `MIPSMFHiLo (MIPSMTLO, (translate_out_ireg rs)) + +| "LUI" , [rt; imm] -> `MIPSLUI ((translate_out_ireg rt), (translate_out_imm16 imm)) +| "Load", [width; signed; linked; base; rt; offset] -> + `MIPSLoad ( + (translate_out_wordWidth width), + (translate_out_bool signed), + (translate_out_bool linked), + (translate_out_ireg base), + (translate_out_ireg rt), + (translate_out_simm16 offset) + ) +| "Store", [width; conditional; base; rt; offset] -> + `MIPSStore ( + (translate_out_wordWidth width), + (translate_out_bool conditional), + (translate_out_ireg base), + (translate_out_ireg rt), + (translate_out_simm16 offset) + ) +| "LWL", [base; rt; offset] -> `MIPSLSLR (false, false, true , (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) +| "LWR", [base; rt; offset] -> `MIPSLSLR (false, false, false, (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) +| "LDL", [base; rt; offset] -> `MIPSLSLR (false, true , true , (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) +| "LDR", [base; rt; offset] -> `MIPSLSLR (false, true , false, (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) +| "SWL", [base; rt; offset] -> `MIPSLSLR (true , false, true , (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) +| "SWR", [base; rt; offset] -> `MIPSLSLR (true , false, false, (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) +| "SDL", [base; rt; offset] -> `MIPSLSLR (true , true , true , (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) +| "SDR", [base; rt; offset] -> `MIPSLSLR (true , true , false, (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) +| "SYNC", [] -> `MIPSSYNC +| "BEQ", [rs; rt; offset; ne; likely] -> `MIPSBEQ ((translate_out_ireg rs), (translate_out_ireg rt), (translate_out_simm16 offset), (translate_out_bool ne), (translate_out_bool likely)) +| "BCMPZ", [rs; offset; cmp; link; likely] -> `MIPSBCMPZ ((translate_out_ireg rs), (translate_out_simm16 offset), (translate_out_cmp cmp), (translate_out_bool link), (translate_out_bool likely)) +| "J", [offset] -> `MIPSJ (translate_out_imm26 offset) +| "JAL", [offset] -> `MIPSJAL (translate_out_imm26 offset) +| "JR", [rd] -> `MIPSJR (translate_out_ireg rd) +| "JALR", [rd; rs] -> `MIPSJALR (translate_out_ireg rd, translate_out_ireg rs) + diff --git a/mips/gen/shallow_ast_to_herdtools_ast.hgen b/mips/gen/shallow_ast_to_herdtools_ast.hgen new file mode 100644 index 00000000..efe2c77e --- /dev/null +++ b/mips/gen/shallow_ast_to_herdtools_ast.hgen @@ -0,0 +1,98 @@ +| SYSCALL_THREAD_START -> `MIPSThreadStart +| (ADD (rs, rt, rd)) -> `MIPSRType (MIPSROpADD , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| (ADDU (rs, rt, rd)) -> `MIPSRType (MIPSROpADDU , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| (AND (rs, rt, rd)) -> `MIPSRType (MIPSROpAND , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| (DADD (rs, rt, rd)) -> `MIPSRType (MIPSROpDADD , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| (DADDU (rs, rt, rd)) -> `MIPSRType (MIPSROpDADDU , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| (DSUB (rs, rt, rd)) -> `MIPSRType (MIPSROpDSUB , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| (DSUBU (rs, rt, rd)) -> `MIPSRType (MIPSROpDSUBU , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| (MOVN (rs, rt, rd)) -> `MIPSRType (MIPSROpMOVN , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| (MOVZ (rs, rt, rd)) -> `MIPSRType (MIPSROpMOVZ , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| (MUL (rs, rt, rd)) -> `MIPSRType (MIPSROpMUL , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| (NOR (rs, rt, rd)) -> `MIPSRType (MIPSROpNOR , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| (OR (rs, rt, rd)) -> `MIPSRType (MIPSROpOR , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| (SLT (rs, rt, rd)) -> `MIPSRType (MIPSROpSLT , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| (SLTU (rs, rt, rd)) -> `MIPSRType (MIPSROpSLTU , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| (SUB (rs, rt, rd)) -> `MIPSRType (MIPSROpSUB , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| (SUBU (rs, rt, rd)) -> `MIPSRType (MIPSROpSUBU , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) +| (XOR (rs, rt, rd)) -> `MIPSRType (MIPSROpXOR , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) + +| (ADDI (rs, rt, imm)) -> `MIPSIType (MIPSIOpADDI ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_simm16 imm)) +| (ADDIU (rs, rt, imm)) -> `MIPSIType (MIPSIOpADDIU ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_simm16 imm)) +| (ANDI (rs, rt, imm)) -> `MIPSIType (MIPSIOpANDI ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_imm16 imm)) +| (DADDI (rs, rt, imm)) -> `MIPSIType (MIPSIOpDADDI ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_simm16 imm)) +| (DADDIU (rs, rt, imm)) -> `MIPSIType (MIPSIOpDADDIU,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_simm16 imm)) +| (ORI (rs, rt, imm)) -> `MIPSIType (MIPSIOpORI ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_imm16 imm)) +| (SLTI (rs, rt, imm)) -> `MIPSIType (MIPSIOpSLTI ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_simm16 imm)) +| (SLTIU (rs, rt, imm)) -> `MIPSIType (MIPSIOpSLTIU ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_simm16 imm)) +| (XORI (rs, rt, imm)) -> `MIPSIType (MIPSIOpXORI ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_imm16 imm)) + +| (DSLL (rt, rd, sa)) -> `MIPSShiftI (MIPSDSLL , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) +| (DSLL32 (rt, rd, sa)) -> `MIPSShiftI (MIPSDSLL32 , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) +| (DSRA (rt, rd, sa)) -> `MIPSShiftI (MIPSDSRA , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) +| (DSRA32 (rt, rd, sa)) -> `MIPSShiftI (MIPSDSRA32 , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) +| (DSRL (rt, rd, sa)) -> `MIPSShiftI (MIPSDSRL , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) +| (DSRL32 (rt, rd, sa)) -> `MIPSShiftI (MIPSDSRL32 , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) +| (SLL (rt, rd, sa)) -> `MIPSShiftI (MIPSSLL , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) +| (SRA (rt, rd, sa)) -> `MIPSShiftI (MIPSSRA , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) +| (SRL (rt, rd, sa)) -> `MIPSShiftI (MIPSSRL , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) + +| DSLLV (rs, rt, rd) -> `MIPSShiftV (MIPSDSLLV , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_ireg rs)) +| DSRAV (rs, rt, rd) -> `MIPSShiftV (MIPSDSRAV , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_ireg rs)) +| DSRLV (rs, rt, rd) -> `MIPSShiftV (MIPSDSRLV , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_ireg rs)) +| SLLV (rs, rt, rd) -> `MIPSShiftV (MIPSSLLV , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_ireg rs)) +| SRAV (rs, rt, rd) -> `MIPSShiftV (MIPSSRAV , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_ireg rs)) +| SRLV (rs, rt, rd) -> `MIPSShiftV (MIPSSRLV , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_ireg rs)) + +| DDIV (rs, rt) -> `MIPSMulDiv (MIPSDDIV , (translate_out_ireg rs), (translate_out_ireg rt)) +| DDIVU (rs, rt) -> `MIPSMulDiv (MIPSDDIVU , (translate_out_ireg rs), (translate_out_ireg rt)) +| DIV (rs, rt) -> `MIPSMulDiv (MIPSDIV , (translate_out_ireg rs), (translate_out_ireg rt)) +| DIVU (rs, rt) -> `MIPSMulDiv (MIPSDIVU , (translate_out_ireg rs), (translate_out_ireg rt)) +| DMULT (rs, rt) -> `MIPSMulDiv (MIPSDMULT , (translate_out_ireg rs), (translate_out_ireg rt)) +| DMULTU (rs, rt) -> `MIPSMulDiv (MIPSDMULTU , (translate_out_ireg rs), (translate_out_ireg rt)) +| MADD (rs, rt) -> `MIPSMulDiv (MIPSMADD , (translate_out_ireg rs), (translate_out_ireg rt)) +| MADDU (rs, rt) -> `MIPSMulDiv (MIPSMADDU , (translate_out_ireg rs), (translate_out_ireg rt)) +| MSUB (rs, rt) -> `MIPSMulDiv (MIPSMSUB , (translate_out_ireg rs), (translate_out_ireg rt)) +| MSUBU (rs, rt) -> `MIPSMulDiv (MIPSMSUBU , (translate_out_ireg rs), (translate_out_ireg rt)) +| MULT (rs, rt) -> `MIPSMulDiv (MIPSMULT , (translate_out_ireg rs), (translate_out_ireg rt)) +| MULTU (rs, rt) -> `MIPSMulDiv (MIPSMULTU , (translate_out_ireg rs), (translate_out_ireg rt)) + +| MFHI (rs) -> `MIPSMFHiLo (MIPSMFHI, (translate_out_ireg rs)) +| MFLO (rs) -> `MIPSMFHiLo (MIPSMFLO, (translate_out_ireg rs)) +| MTHI (rs) -> `MIPSMFHiLo (MIPSMTHI, (translate_out_ireg rs)) +| MTLO (rs) -> `MIPSMFHiLo (MIPSMTLO, (translate_out_ireg rs)) + +| LUI (rt, imm) -> `MIPSLUI ((translate_out_ireg rt), (translate_out_imm16 imm)) +| Load (width, signed, linked, base, rt, offset) -> + `MIPSLoad ( + (translate_out_wordWidth width), + (translate_out_bool signed), + (translate_out_bool linked), + (translate_out_ireg base), + (translate_out_ireg rt), + (translate_out_simm16 offset) + ) +| Store (width, conditional, base, rt, offset) -> + `MIPSStore ( + (translate_out_wordWidth width), + (translate_out_bool conditional), + (translate_out_ireg base), + (translate_out_ireg rt), + (translate_out_simm16 offset) + ) +| LWL (base, rt, offset) -> `MIPSLSLR (false, false, true , (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) +| LWR (base, rt, offset) -> `MIPSLSLR (false, false, false, (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) +| LDL (base, rt, offset) -> `MIPSLSLR (false, true , true , (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) +| LDR (base, rt, offset) -> `MIPSLSLR (false, true , false, (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) +| SWL (base, rt, offset) -> `MIPSLSLR (true , false, true , (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) +| SWR (base, rt, offset) -> `MIPSLSLR (true , false, false, (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) +| SDL (base, rt, offset) -> `MIPSLSLR (true , true , true , (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) +| SDR (base, rt, offset) -> `MIPSLSLR (true , true , false, (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) +| SYNC -> `MIPSSYNC +| BEQ (rs, rt, offset, ne, likely) -> `MIPSBEQ ((translate_out_ireg rs), (translate_out_ireg rt), (translate_out_simm16 offset), (translate_out_bool ne), (translate_out_bool likely)) +| BCMPZ (rs, offset, cmp, link, likely) -> `MIPSBCMPZ ((translate_out_ireg rs), (translate_out_simm16 offset), (translate_out_cmp cmp), (translate_out_bool link), (translate_out_bool likely)) +| J (offset) -> `MIPSJ (translate_out_imm26 offset) +| JAL (offset) -> `MIPSJAL (translate_out_imm26 offset) +| JR (rd) -> `MIPSJR (translate_out_ireg rd) +| JALR (rd, rs) -> `MIPSJALR (translate_out_ireg rd, translate_out_ireg rs) + diff --git a/mips/gen/shallow_types_to_herdtools_types.hgen b/mips/gen/shallow_types_to_herdtools_types.hgen new file mode 100644 index 00000000..a02d83b7 --- /dev/null +++ b/mips/gen/shallow_types_to_herdtools_types.hgen @@ -0,0 +1,39 @@ +let translate_out_big_bit = Sail_values.unsigned + +let translate_out_int inst = (Nat_big_num.to_int (translate_out_big_bit inst)) +let translate_out_signed_int inst bits = + let i = (Nat_big_num.to_int (translate_out_big_bit inst)) in + if (i >= (1 lsl (bits - 1))) then + (i - (1 lsl bits)) else + i + +let translate_out_ireg ireg = IReg (int_to_ireg (translate_out_int ireg)) + +let translate_out_imm26 imm = translate_out_int imm + +let translate_out_imm16 imm = translate_out_int imm +let translate_out_simm16 imm = translate_out_signed_int imm 16 + +let translate_out_imm5 imm = translate_out_int imm + +let translate_out_bool = function + | Sail_values.B1 -> true + | Sail_values.B0 -> false + | _ -> failwith "translate_out_bool Undef" + + +let translate_out_wordWidth = function + | Mips_embed_types.B2 -> MIPSByte + | Mips_embed_types.H -> MIPSHalf + | Mips_embed_types.W -> MIPSWord + | Mips_embed_types.D -> MIPSDouble + +let translate_out_cmp = function + | Mips_embed_types.EQ' -> MIPS_EQ (* equal *) + | Mips_embed_types.NE -> MIPS_NE (* not equal *) + | Mips_embed_types.GE -> MIPS_GE (* signed greater than or equal *) + | Mips_embed_types.GEU -> MIPS_GEU (* unsigned greater than or equal *) + | Mips_embed_types.GT' -> MIPS_GT (* signed strictly greater than *) + | Mips_embed_types.LE -> MIPS_LE (* signed less than or equal *) + | Mips_embed_types.LT' -> MIPS_LT (* signed strictly less than *) + | Mips_embed_types.LTU -> MIPS_LTU (* unsigned less than or qual *) diff --git a/mips/gen/token_types.hgen b/mips/gen/token_types.hgen new file mode 100644 index 00000000..170b42d3 --- /dev/null +++ b/mips/gen/token_types.hgen @@ -0,0 +1,39 @@ +type token_RTYPE = {txt : string; op : mipsRTypeOp } +type token_ITYPE = {txt : string; op : mipsITypeOp } +type token_ShiftI = {txt : string; op : mipsShiftIOp } +type token_ShiftV = {txt : string; op : mipsShiftVOp } +type token_MulDiv = {txt : string; op : mipsMulDivOp } +type token_MFHiLo = {txt : string; op : mipsMFHiLoOp } +type token_LUI = {txt : string } +type token_Load = {txt : string; width: mipsWordWidth; signed : bool; linked : bool} +type token_Store = {txt : string; width: mipsWordWidth; conditional : bool} +type token_LSLR = {txt : string; store : bool; double : bool; left: bool } (* Load/Store Left/Right *) +type token_SYNC = {txt : string} +type token_BEQ = {txt : string; ne : bool; likely : bool } +type token_BCMPZ = {txt : string; cmp : mipsCmp; likely : bool; link : bool } +type token_J = {txt : string} +type token_JAL = {txt : string} +type token_JR = {txt : string} +type token_JALR = {txt : string} +(* +(regno, imm16, Comparison) TRAPIMM + +(regno, regno) RDHWR +(regno, regno, Comparison) TRAPREG +(regno, regno, bit[3], bool) MFC0 +(regno, regno, bit[3], bool) MTC0 +(regno, regno, imm16, bool, bool) BEQ +TLBP +TLBR +TLBWI +TLBWR + +regregimm16 CACHE +regregimm16 PREF + +unit BREAK +unit ERET +unit HCF +unit SYSCALL +unit WAIT +*) \ No newline at end of file diff --git a/mips/gen/tokens.hgen b/mips/gen/tokens.hgen new file mode 100644 index 00000000..937c6354 --- /dev/null +++ b/mips/gen/tokens.hgen @@ -0,0 +1,17 @@ +%token RTYPE +%token ITYPE +%token SHIFTI +%token SHIFTV +%token MULDIV +%token MFHILO +%token LUI +%token LOAD +%token STORE +%token LSLR +%token SYNC +%token BEQ +%token BCMPZ +%token J +%token JAL +%token JR +%token JALR diff --git a/mips/gen/trans_sail.hgen b/mips/gen/trans_sail.hgen new file mode 100644 index 00000000..e42d1b19 --- /dev/null +++ b/mips/gen/trans_sail.hgen @@ -0,0 +1,122 @@ +| `MIPSThreadStart -> + ("SYSCALL_THREAD_START", [], []) +| `MIPSStopFetching -> + ("ImplementationDefinedStopFetching", + [], + []) + +(* Note different argument order, which reflects difference + between instruction encoding and asm format *) +| `MIPSRType (op, rd, rs, rt) -> + (translate_rtype_op op, + [ + translate_reg "rs" rs; + translate_reg "rt" rt; + translate_reg "rd" rd; + ], + []) + +(* Note different argument order similar to above *) +| `MIPSIType (op, rt, rs, imm) -> + (translate_itype_op op, + [ + translate_reg "rs" rs; + translate_reg "rt" rt; + translate_imm16 "imm" imm; + ], + []) + +| `MIPSShiftI (op, rd, rt, sa) -> + (translate_shifti_op op, + [ + translate_reg "rt" rt; + translate_reg "rd" rd; + translate_imm5 "sa" sa; + ], + []) + +| `MIPSShiftV (op, rd, rt, rs) -> + (translate_shiftv_op op, + [ + translate_reg "rs" rs; + translate_reg "rt" rt; + translate_reg "rd" rd; + ], + []) + +| `MIPSMulDiv (op, rs, rt) -> + (translate_muldiv_op op, + [ + translate_reg "rs" rs; + translate_reg "rt" rt; + ], + []) + +| `MIPSMFHiLo (op, rs) -> + (translate_mfhilo_op op, + [ + translate_reg "rs" rs; + ], + []) +| `MIPSLUI (rt, imm) -> + ("LUI", + [ + translate_reg "rt" rt; + translate_imm16 "imm" imm; + ], + []) +| `MIPSLoad (width, signed, linked, base, rt, offset) -> + ("Load", + [ + translate_wordsize "width" width; + translate_bool "signed" signed; + translate_bool "linked" linked; + translate_reg "base" base; + translate_reg "rt" rt; + translate_imm16 "offset" offset; + ], + []) +| `MIPSStore (width, conditional, base, rt, offset) -> + ("Store", + [ + translate_wordsize "width" width; + translate_bool "conditional" conditional; + translate_reg "base" base; + translate_reg "rt" rt; + translate_imm16 "offset" offset; + ], + []) +| `MIPSLSLR (store, double, left, base, rt, offset) -> + (translate_lslr_op store double left, + [ + translate_reg "base" base; + translate_reg "rt" rt; + translate_imm16 "offset" offset; + ], + []) +| `MIPSSYNC -> ("SYNC", [], []) +| `MIPSBEQ (rs, rt, offset, ne, likely) -> + ("BEQ", + [translate_reg "rs" rs; + translate_reg "rt" rt; + translate_imm16 "offset" offset; + translate_bool "ne" ne; + translate_bool "likely" likely; + ], []) + +| `MIPSBCMPZ (rs, offset, cmp, link, likely) -> + ("BCMPZ", + [translate_reg "rs" rs; + translate_imm16 "offset" offset; + translate_cmp "cmp" cmp; + translate_bool "link" link; + translate_bool "likely" likely; + ], []) +| `MIPSJ (offset) -> + ("J", [translate_imm26 "offset" offset;], []) +| `MIPSJAL (offset) -> + ("JAL", [translate_imm26 "offset" offset;], []) +| `MIPSJR(rd) -> + ("JR", [translate_reg "rd" rd;], []) +| `MIPSJALR(rd, rs) -> + ("JALR", [translate_reg "rd" rd; translate_reg "rs" rs;], []) diff --git a/mips/gen/types.hgen b/mips/gen/types.hgen new file mode 100644 index 00000000..a1c61f4b --- /dev/null +++ b/mips/gen/types.hgen @@ -0,0 +1,209 @@ +type mipsRTypeOp = +| MIPSROpADD +| MIPSROpADDU +| MIPSROpAND +| MIPSROpDADD +| MIPSROpDADDU +| MIPSROpDSUB +| MIPSROpDSUBU +| MIPSROpMOVN +| MIPSROpMOVZ +| MIPSROpMUL +| MIPSROpNOR +| MIPSROpOR +| MIPSROpSLT +| MIPSROpSLTU +| MIPSROpSUB +| MIPSROpSUBU +| MIPSROpXOR + +let pp_rtype_op = function +| MIPSROpADD -> "add" +| MIPSROpADDU -> "addu" +| MIPSROpAND -> "and" +| MIPSROpDADD -> "dadd" +| MIPSROpDADDU -> "daddu" +| MIPSROpDSUB -> "dsub" +| MIPSROpDSUBU -> "dsubu" +| MIPSROpMOVN -> "movn" +| MIPSROpMOVZ -> "movz" +| MIPSROpMUL -> "mul" +| MIPSROpNOR -> "nor" +| MIPSROpOR -> "or" +| MIPSROpSLT -> "slt" +| MIPSROpSLTU -> "sltu" +| MIPSROpSUB -> "sub" +| MIPSROpSUBU -> "subu" +| MIPSROpXOR -> "xor" + +type bit26 = int +type bit16 = int +type bit5 = int + +type mipsITypeOp = +| MIPSIOpADDI +| MIPSIOpADDIU +| MIPSIOpANDI +| MIPSIOpDADDI +| MIPSIOpDADDIU +| MIPSIOpORI +| MIPSIOpSLTI +| MIPSIOpSLTIU +| MIPSIOpXORI + +let pp_itype_op = function +| MIPSIOpADDI -> "addi" +| MIPSIOpADDIU -> "addiu" +| MIPSIOpANDI -> "andi" +| MIPSIOpDADDI -> "daddi" +| MIPSIOpDADDIU -> "daddiu" +| MIPSIOpORI -> "ori" +| MIPSIOpSLTI -> "slti" +| MIPSIOpSLTIU -> "sltiu" +| MIPSIOpXORI -> "xori" + +type mipsShiftIOp = +| MIPSDSLL +| MIPSDSLL32 +| MIPSDSRA +| MIPSDSRA32 +| MIPSDSRL +| MIPSDSRL32 +| MIPSSLL +| MIPSSRA +| MIPSSRL + +let pp_shifti_op = function +| MIPSDSLL -> "dsll" +| MIPSDSLL32 -> "dsll32" +| MIPSDSRA -> "dsra" +| MIPSDSRA32 -> "dsra32" +| MIPSDSRL -> "dsrl" +| MIPSDSRL32 -> "dsrl32" +| MIPSSLL -> "sll" +| MIPSSRA -> "sra" +| MIPSSRL -> "srl" + +type mipsShiftVOp = +| MIPSDSLLV +| MIPSDSRAV +| MIPSDSRLV +| MIPSSLLV +| MIPSSRAV +| MIPSSRLV + +let pp_shiftv_op = function +| MIPSDSLLV -> "dsllv" +| MIPSDSRAV -> "dsrav" +| MIPSDSRLV -> "dsrlv" +| MIPSSLLV -> "sllv" +| MIPSSRAV -> "srav" +| MIPSSRLV -> "srlv" + +type mipsMulDivOp = +| MIPSDDIV +| MIPSDDIVU +| MIPSDIV +| MIPSDIVU +| MIPSDMULT +| MIPSDMULTU +| MIPSMADD +| MIPSMADDU +| MIPSMSUB +| MIPSMSUBU +| MIPSMULT +| MIPSMULTU + +let pp_muldiv_op = function +| MIPSDDIV -> "ddiv" +| MIPSDDIVU -> "ddivu" +| MIPSDIV -> "div" +| MIPSDIVU -> "divu" +| MIPSDMULT -> "dmult" +| MIPSDMULTU -> "dmultu" +| MIPSMADD -> "madd" +| MIPSMADDU -> "maddu" +| MIPSMSUB -> "msub" +| MIPSMSUBU -> "msubu" +| MIPSMULT -> "mult" +| MIPSMULTU -> "multu" + +type mipsMFHiLoOp = +| MIPSMFHI +| MIPSMFLO +| MIPSMTHI +| MIPSMTLO + +let pp_mfhilo_op = function +| MIPSMFHI -> "mfhi" +| MIPSMFLO -> "mflo" +| MIPSMTHI -> "mthi" +| MIPSMTLO -> "mtlo" + +type mipsWordWidth = +| MIPSByte +| MIPSHalf +| MIPSWord +| MIPSDouble + +type mipsCmp = +| MIPS_EQ (* equal *) +| MIPS_NE (* not equal *) +| MIPS_GE (* signed greater than or equal *) +| MIPS_GEU (* unsigned greater than or equal *) +| MIPS_GT (* signed strictly greater than *) +| MIPS_LE (* signed less than or equal *) +| MIPS_LT (* signed strictly less than *) +| MIPS_LTU (* unsigned less than or qual *) + +let pp_load_op width signed linked = match (width, signed, linked) with + | (MIPSByte, true, false) -> "lb" + | (MIPSByte, false, false) -> "lbu" + | (MIPSHalf, true, false) -> "lh" + | (MIPSHalf, false, false) -> "lhu" + | (MIPSWord, true, false) -> "lw" + | (MIPSWord, false, false) -> "lwu" + | (MIPSDouble, false, false) -> "ld" + | (MIPSWord, true, true) -> "ll" + | (MIPSDouble, false, true) -> "lld" + | _ -> failwith "unexpected load op" + +let pp_store_op width conditional = match (width, conditional) with + | (MIPSByte, false) -> "sb" + | (MIPSHalf, false) -> "sh" + | (MIPSWord, false) -> "sw" + | (MIPSDouble, false) -> "sd" + | (MIPSWord, true) -> "sc" + | (MIPSDouble, true) -> "scd" + | _ -> failwith "unexpected store op" + +let pp_lslr_op store double left = match (store, double, left) with + | (false, false, true ) -> "lwl" + | (false, false, false) -> "lwr" + | (false, true , true ) -> "ldl" + | (false, true , false) -> "ldr" + | (true , false, true ) -> "swl" + | (true , false, false) -> "swr" + | (true , true , true ) -> "sdl" + | (true , true , false) -> "sdr" + +let pp_beq_op ne likely = match (ne, likely) with + | (false, false) -> "beq" + | (false, true) -> "beql" + | (true , false) -> "bne" + | (true , true) -> "bnel" + +let pp_bcmpz_op cmp link likely = match (cmp, likely, link) with +| (MIPS_LT, false , false ) -> "bltz" +| (MIPS_LT, false , true ) -> "bltzal" +| (MIPS_LT, true , false ) -> "bltzl" +| (MIPS_LT, true , true ) -> "bltzall" +| (MIPS_GE, false , false ) -> "bgez" +| (MIPS_GE, false , true ) -> "bgezal" +| (MIPS_GE, true , false ) -> "bgezl" +| (MIPS_GE, true , true ) -> "bgezall" +| (MIPS_GT, false , false ) -> "bgtz" +| (MIPS_GT, true , false ) -> "bgtzl" +| (MIPS_LE, false , false ) -> "blez" +| (MIPS_LE, true , false ) -> "blezl" +| _ -> failwith "unknown bcmpz instruction" diff --git a/mips/gen/types_sail_trans_out.hgen b/mips/gen/types_sail_trans_out.hgen new file mode 100644 index 00000000..ebd31fcb --- /dev/null +++ b/mips/gen/types_sail_trans_out.hgen @@ -0,0 +1,47 @@ +let translate_out_big_bit = function + | (name, Bvector _, bits) -> IInt.integer_of_bit_list bits + | _ -> assert false + +let translate_out_int inst = (Nat_big_num.to_int (translate_out_big_bit inst)) +let translate_out_signed_int inst bits = + let i = (Nat_big_num.to_int (translate_out_big_bit inst)) in + if (i >= (1 lsl (bits - 1))) then + (i - (1 lsl bits)) else + i + +let translate_out_ireg ireg = IReg (int_to_ireg (translate_out_int ireg)) + +let translate_out_imm26 imm = translate_out_int imm + +let translate_out_imm16 imm = translate_out_int imm +let translate_out_simm16 imm = translate_out_signed_int imm 16 + +let translate_out_imm5 imm = translate_out_int imm + +let translate_out_bool = function + | (name, Bit, [Bitc_one]) -> true + | (name, Bit, [Bitc_zero]) -> false + | _ -> assert false + +let translate_out_enum (name,_,bits) = + Nat_big_num.to_int (IInt.integer_of_bit_list bits) + +let translate_out_wordWidth inst = + match translate_out_enum inst with + | 0 -> MIPSByte + | 1 -> MIPSHalf + | 2 -> MIPSWord + | 3 -> MIPSDouble + | _ -> failwith "Unknown wordWidth in sail translate out" + +let translate_out_cmp inst = + match translate_out_enum inst with + | 0 -> MIPS_EQ (* equal *) + | 1 -> MIPS_NE (* not equal *) + | 2 -> MIPS_GE (* signed greater than or equal *) + | 3 -> MIPS_GEU (* unsigned greater than or equal *) + | 4 -> MIPS_GT (* signed strictly greater than *) + | 5 -> MIPS_LE (* signed less than or equal *) + | 6 -> MIPS_LT (* signed strictly less than *) + | 7 -> MIPS_LTU (* unsigned less than or qual *) + | _ -> failwith "Unknown mipsCmp in sail translate out" diff --git a/mips/gen/types_trans_sail.hgen b/mips/gen/types_trans_sail.hgen new file mode 100644 index 00000000..63880ae9 --- /dev/null +++ b/mips/gen/types_trans_sail.hgen @@ -0,0 +1,44 @@ +let translate_rtype_op op = uppercase (pp_rtype_op op) +let translate_itype_op op = uppercase (pp_itype_op op) +let translate_shifti_op op = uppercase (pp_shifti_op op) +let translate_shiftv_op op = uppercase (pp_shiftv_op op) +let translate_muldiv_op op = uppercase (pp_muldiv_op op) +let translate_mfhilo_op op = uppercase (pp_mfhilo_op op) +let translate_load_op width signed linked = uppercase (pp_load_op width signed linked) +let translate_store_op width conditional = uppercase (pp_store_op width conditional) +let translate_lslr_op store double left = uppercase (pp_lslr_op store double left) +let translate_beq_op ne likely = uppercase (pp_beq_op ne likely) +let translate_bcmpz_op cmp link likely = uppercase (pp_bcmpz_op cmp link likely) + +let translate_reg name value = + (name, Bvector (Some 5), bit_list_of_integer 5 (Nat_big_num.of_int (reg_to_int value))) +let translate_imm26 name value = + (name, Bvector (Some 26), bit_list_of_integer 26 (Nat_big_num.of_int value)) +let translate_imm16 name value = + (name, Bvector (Some 16), bit_list_of_integer 16 (Nat_big_num.of_int value)) +let translate_imm5 name value = + (name, Bvector (Some 5), bit_list_of_integer 5 (Nat_big_num.of_int value)) +let translate_bool name value = + (name, Bit, [if value then Bitc_one else Bitc_zero]) +let translate_enum enum_values name value = + let rec bit_count n = + if n = 0 then 0 + else 1 + (bit_count (n lsr 1)) in + let rec find_index element = function + | h::tail -> if h = element then 0 else 1 + (find_index element tail) + | _ -> failwith "translate_enum could not find value" + in + let size = bit_count (List.length enum_values) in + let index = find_index value enum_values in + (name, Range0 (Some size), IInt.bit_list_of_integer size (Nat_big_num.of_int index)) +let translate_wordsize = translate_enum [MIPSByte; MIPSHalf; MIPSWord; MIPSDouble] +let translate_cmp = translate_enum [ +MIPS_EQ ;(* equal *) +MIPS_NE ;(* not equal *) +MIPS_GE ;(* signed greater than or equal *) +MIPS_GEU ;(* unsigned greater than or equal *) +MIPS_GT ;(* signed strictly greater than *) +MIPS_LE ;(* signed less than or equal *) +MIPS_LT ;(* signed strictly less than *) +MIPS_LTU ;(* unsigned less than or qual *) +] \ No newline at end of file diff --git a/mips/hgen/ast.hgen b/mips/hgen/ast.hgen deleted file mode 100644 index a251adff..00000000 --- a/mips/hgen/ast.hgen +++ /dev/null @@ -1,18 +0,0 @@ -| `MIPSThreadStart -| `MIPSRType of mipsRTypeOp * reg * reg * reg -| `MIPSIType of mipsITypeOp * reg * reg * bit16 -| `MIPSShiftI of mipsShiftIOp * reg * reg * bit5 -| `MIPSShiftV of mipsShiftVOp * reg * reg * reg -| `MIPSMulDiv of mipsMulDivOp * reg * reg -| `MIPSMFHiLo of mipsMFHiLoOp * reg -| `MIPSLUI of reg * bit16 -| `MIPSLoad of mipsWordWidth * bool * bool * reg * reg * bit16 (* width, signed, linked, base, rt, offset *) -| `MIPSStore of mipsWordWidth * bool * reg * reg * bit16 (* width, conditional, base, rt, offset *) -| `MIPSLSLR of bool * bool * bool * reg * reg * bit16 (* store, double, left, base, rt, offset *) -| `MIPSSYNC -| `MIPSBEQ of reg * reg * bit16 * bool * bool (* rs, rt, offset, not equal, likely *) -| `MIPSBCMPZ of reg * bit16 * mipsCmp * bool * bool (* rs, offset, cmp, link, likely *) -| `MIPSJ of bit26 -| `MIPSJAL of bit26 -| `MIPSJR of reg -| `MIPSJALR of reg * reg (* rs, rd *) diff --git a/mips/hgen/fold.hgen b/mips/hgen/fold.hgen deleted file mode 100644 index 05b9c808..00000000 --- a/mips/hgen/fold.hgen +++ /dev/null @@ -1,19 +0,0 @@ -| `MIPSThreadStart -> (y_reg, y_sreg) -| `MIPSRType (op, rd, rs, rt) -> fold_reg rt (fold_reg rs (fold_reg rd (y_reg, y_sreg))) -| `MIPSIType (op, rs, rt, imm) -> fold_reg rs (fold_reg rt (y_reg, y_sreg)) -| `MIPSShiftI (op, rd, rt, imm) -> fold_reg rt (fold_reg rd (y_reg, y_sreg)) -| `MIPSShiftV (op, rd, rt, rs) -> fold_reg rs (fold_reg rt (fold_reg rd (y_reg, y_sreg))) -| `MIPSMulDiv (op, rs, rt) -> fold_reg rs (fold_reg rt (y_reg, y_sreg)) -| `MIPSMFHiLo (op, rs) -> fold_reg rs (y_reg, y_sreg) -| `MIPSLUI (rt, imm) -> fold_reg rt (y_reg, y_sreg) -| `MIPSLoad (width, signed, linked, base, rt, offset) -> fold_reg rt (fold_reg base (y_reg, y_sreg)) -| `MIPSStore (width, conditional, base, rt, offset) -> fold_reg rt (fold_reg base (y_reg, y_sreg)) -| `MIPSLSLR (store, double, left, base, rt, offset) -> fold_reg rt (fold_reg base (y_reg, y_sreg)) -| `MIPSSYNC -> (y_reg, y_sreg) -| `MIPSBEQ (rs, rt, offset, ne, likely) -> fold_reg rs (fold_reg rt (y_reg, y_sreg)) -| `MIPSBCMPZ (rs, offset, cmp, link, likely) -> fold_reg rs (y_reg, y_sreg) -| `MIPSJ (offset) -> (y_reg, y_sreg) -| `MIPSJAL (offset) -> fold_reg (IReg(R31)) (y_reg, y_sreg) -| `MIPSJR (rd) -> fold_reg rd (y_reg, y_sreg) -| `MIPSJALR (rd, rs) -> fold_reg rd (fold_reg rs (y_reg, y_sreg)) - diff --git a/mips/hgen/herdtools_ast_to_shallow_ast.hgen b/mips/hgen/herdtools_ast_to_shallow_ast.hgen deleted file mode 100644 index 7b1a58d9..00000000 --- a/mips/hgen/herdtools_ast_to_shallow_ast.hgen +++ /dev/null @@ -1,121 +0,0 @@ -| `MIPSThreadStart -> - SYSCALL_THREAD_START - -| `MIPSStopFetching -> - ImplementationDefinedStopFetching0 - -(* Note different argument order, which reflects difference - between instruction encoding and asm format *) -| `MIPSRType (op, rd, rs, rt) -> - (translate_rtype_op op) - ( - translate_reg "rs" rs, - translate_reg "rt" rt, - translate_reg "rd" rd - ) - - -(* Note different argument order similar to above *) -| `MIPSIType (op, rt, rs, imm) -> - (translate_itype_op op) - ( - translate_reg "rs" rs, - translate_reg "rt" rt, - translate_imm16 "imm" imm - ) - - -| `MIPSShiftI (op, rd, rt, sa) -> - (translate_shifti_op op) - ( - translate_reg "rt" rt, - translate_reg "rd" rd, - translate_imm5 "sa" sa - ) - - -| `MIPSShiftV (op, rd, rt, rs) -> - (translate_shiftv_op op) - ( - translate_reg "rs" rs, - translate_reg "rt" rt, - translate_reg "rd" rd - ) - - -| `MIPSMulDiv (op, rs, rt) -> - (translate_muldiv_op op) - ( - translate_reg "rs" rs, - translate_reg "rt" rt - ) - - -| `MIPSMFHiLo (op, rs) -> - (translate_mfhilo_op op) - ( - translate_reg "rs" rs - ) - -| `MIPSLUI (rt, imm) -> - LUI - ( - translate_reg "rt" rt, - translate_imm16 "imm" imm - ) - -| `MIPSLoad (width, signed, linked, base, rt, offset) -> - Load - ( - translate_wordsize "width" width, - translate_bool "signed" signed, - translate_bool "linked" linked, - translate_reg "base" base, - translate_reg "rt" rt, - translate_imm16 "offset" offset - ) - -| `MIPSStore (width, conditional, base, rt, offset) -> - Store - ( - translate_wordsize "width" width, - translate_bool "conditional" conditional, - translate_reg "base" base, - translate_reg "rt" rt, - translate_imm16 "offset" offset - ) - -| `MIPSLSLR (store, double, left, base, rt, offset) -> - (translate_lslr_op store double left) - ( - translate_reg "base" base, - translate_reg "rt" rt, - translate_imm16 "offset" offset - ) - -| `MIPSSYNC -> SYNC -| `MIPSBEQ (rs, rt, offset, ne, likely) -> - BEQ - (translate_reg "rs" rs, - translate_reg "rt" rt, - translate_imm16 "offset" offset, - translate_bool "ne" ne, - translate_bool "likely" likely - ) - -| `MIPSBCMPZ (rs, offset, cmp, link, likely) -> - BCMPZ - (translate_reg "rs" rs, - translate_imm16 "offset" offset, - translate_cmp "cmp" cmp, - translate_bool "link" link, - translate_bool "likely" likely - ) -| `MIPSJ (offset) -> - J (translate_imm26 "offset" offset) -| `MIPSJAL (offset) -> - JAL (translate_imm26 "offset" offset) -| `MIPSJR(rd) -> - JR (translate_reg "rd" rd) -| `MIPSJALR(rd, rs) -> - JALR (translate_reg "rd" rd, translate_reg "rs" rs) diff --git a/mips/hgen/herdtools_types_to_shallow_types.hgen b/mips/hgen/herdtools_types_to_shallow_types.hgen deleted file mode 100644 index 5a0e3bfc..00000000 --- a/mips/hgen/herdtools_types_to_shallow_types.hgen +++ /dev/null @@ -1,120 +0,0 @@ -let is_inc = false - -let translate_rtype_op op = uppercase (pp_rtype_op op) - -let translate_rtype_op op x = match op with - | MIPSROpADD -> ADD x - | MIPSROpADDU -> ADDU x - | MIPSROpAND -> AND x - | MIPSROpDADD -> DADD x - | MIPSROpDADDU -> DADDU x - | MIPSROpDSUB -> DSUB x - | MIPSROpDSUBU -> DSUBU x - | MIPSROpMOVN -> MOVN x - | MIPSROpMOVZ -> MOVZ x - | MIPSROpMUL -> MUL x - | MIPSROpNOR -> NOR x - | MIPSROpOR -> OR x - | MIPSROpSLT -> SLT x - | MIPSROpSLTU -> SLTU x - | MIPSROpSUB -> SUB x - | MIPSROpSUBU -> SUBU x - | MIPSROpXOR -> XOR x - -let translate_itype_op op x = match op with - | MIPSIOpADDI -> ADDI x - | MIPSIOpADDIU -> ADDIU x - | MIPSIOpANDI -> ANDI x - | MIPSIOpDADDI -> DADDI x - | MIPSIOpDADDIU -> DADDIU x - | MIPSIOpORI -> ORI x - | MIPSIOpSLTI -> SLTI x - | MIPSIOpSLTIU -> SLTIU x - | MIPSIOpXORI -> XORI x - -let translate_shifti_op op x = match op with - | MIPSDSLL -> DSLL x - | MIPSDSLL32 -> DSLL32 x - | MIPSDSRA -> DSRA x - | MIPSDSRA32 -> DSRA32 x - | MIPSDSRL -> DSRL x - | MIPSDSRL32 -> DSRL32 x - | MIPSSLL -> SLL x - | MIPSSRA -> SRA x - | MIPSSRL -> SRL x - -let translate_shiftv_op op x = match op with - | MIPSDSLLV -> DSLLV x - | MIPSDSRAV -> DSRAV x - | MIPSDSRLV -> DSRLV x - | MIPSSLLV -> SLLV x - | MIPSSRAV -> SRAV x - | MIPSSRLV -> SRLV x - -let translate_muldiv_op op x = match op with - | MIPSDDIV -> DDIV x - | MIPSDDIVU -> DDIVU x - | MIPSDIV -> DIV x - | MIPSDIVU -> DIVU x - | MIPSDMULT -> DMULT x - | MIPSDMULTU -> DMULTU x - | MIPSMADD -> MADD x - | MIPSMADDU -> MADDU x - | MIPSMSUB -> MSUB x - | MIPSMSUBU -> MSUBU x - | MIPSMULT -> MULT x - | MIPSMULTU -> MULTU x - -let translate_mfhilo_op op x = match op with - | MIPSMFHI -> MFHI x - | MIPSMFLO -> MFLO x - | MIPSMTHI -> MTHI x - | MIPSMTLO -> MTLO x - -let translate_load_op width signed linked = uppercase (pp_load_op width signed linked) - -let translate_store_op width conditional = uppercase (pp_store_op width conditional) - -let translate_lslr_op store double left x = match (store,double,left) with - | (false, false, true ) -> LWL x - | (false, false, false) -> LWR x - | (false, true , true ) -> LDL x - | (false, true , false) -> LDR x - | (true , false, true ) -> SWL x - | (true , false, false) -> SWR x - | (true , true , true ) -> SDL x - | (true , true , false) -> SDR x - -let translate_beq_op ne likely = uppercase (pp_beq_op ne likely) - -let translate_bcmpz_op cmp link likely = uppercase (pp_bcmpz_op cmp link likely) - - -let translate_reg name value = - Sail_values.to_vec0 is_inc (Nat_big_num.of_int 5,Nat_big_num.of_int (reg_to_int value)) - -let translate_imm26 name value = - Sail_values.to_vec0 is_inc (Nat_big_num.of_int 26,Nat_big_num.of_int value) -let translate_imm16 name value = - Sail_values.to_vec0 is_inc (Nat_big_num.of_int 16,Nat_big_num.of_int value) -let translate_imm5 name value = - Sail_values.to_vec0 is_inc (Nat_big_num.of_int 5,Nat_big_num.of_int value) -let translate_bool name = function - | true -> Sail_values.B1 - | false -> Sail_values.B0 - -let translate_wordsize _ = function - | MIPSByte -> Mips_embed_types.B2 - | MIPSHalf -> Mips_embed_types.H - | MIPSWord -> Mips_embed_types.W - | MIPSDouble -> Mips_embed_types.D - -let translate_cmp _ = function - | MIPS_EQ -> EQ' - | MIPS_NE -> NE - | MIPS_GE -> GE - | MIPS_GEU -> GEU - | MIPS_GT -> GT' - | MIPS_LE -> LE - | MIPS_LT -> LT' - | MIPS_LTU -> LTU diff --git a/mips/hgen/lexer.hgen b/mips/hgen/lexer.hgen deleted file mode 100644 index c01b14cc..00000000 --- a/mips/hgen/lexer.hgen +++ /dev/null @@ -1,116 +0,0 @@ -"add" , RTYPE {txt="ADD" ; op=MIPSROpADD }; -"addu" , RTYPE {txt="ADDU" ; op=MIPSROpADDU }; -"and" , RTYPE {txt="AND" ; op=MIPSROpAND }; -"dadd" , RTYPE {txt="DADD" ; op=MIPSROpDADD }; -"daddu" , RTYPE {txt="DADDU" ; op=MIPSROpDADDU }; -"dsub" , RTYPE {txt="DSUB" ; op=MIPSROpDSUB }; -"dsubu" , RTYPE {txt="DSUBU" ; op=MIPSROpDSUBU }; -"movn" , RTYPE {txt="MOVN" ; op=MIPSROpMOVN }; -"movz" , RTYPE {txt="MOVZ" ; op=MIPSROpMOVZ }; -"mul" , RTYPE {txt="MUL" ; op=MIPSROpMUL }; -"nor" , RTYPE {txt="NOR" ; op=MIPSROpNOR }; -"or" , RTYPE {txt="OR" ; op=MIPSROpOR }; -"slt" , RTYPE {txt="SLT" ; op=MIPSROpSLT }; -"sltu" , RTYPE {txt="SLTU" ; op=MIPSROpSLTU }; -"sub" , RTYPE {txt="SUB" ; op=MIPSROpSUB }; -"subu" , RTYPE {txt="SUBU" ; op=MIPSROpSUBU }; -"xor" , RTYPE {txt="XOR" ; op=MIPSROpXOR }; - -"addi" , ITYPE {txt="ADDI" ; op=MIPSIOpADDI }; -"addiu" , ITYPE {txt="ADDIU" ; op=MIPSIOpADDIU }; -"andi" , ITYPE {txt="ANDI" ; op=MIPSIOpANDI }; -"daddi" , ITYPE {txt="DADDI" ; op=MIPSIOpDADDI }; -"daddiu", ITYPE {txt="DADDIU"; op=MIPSIOpDADDIU }; -"ori" , ITYPE {txt="ORI" ; op=MIPSIOpORI }; -"slti" , ITYPE {txt="SLTI" ; op=MIPSIOpSLTI }; -"sltiu" , ITYPE {txt="SLTIU" ; op=MIPSIOpSLTIU }; -"xori" , ITYPE {txt="XORI" ; op=MIPSIOpXORI }; - -"dsll" , SHIFTI {txt="DSLL" ; op=MIPSDSLL }; -"dsll32" , SHIFTI {txt="DSLL32" ; op=MIPSDSLL32 }; -"dsra" , SHIFTI {txt="DSRA" ; op=MIPSDSRA }; -"dsra32" , SHIFTI {txt="DSRA32" ; op=MIPSDSRA32 }; -"dsrl" , SHIFTI {txt="DSRL" ; op=MIPSDSRL }; -"dsrl32" , SHIFTI {txt="DSRL32" ; op=MIPSDSRL32 }; -"sll" , SHIFTI {txt="SLL" ; op=MIPSSLL }; -"sra" , SHIFTI {txt="SRA" ; op=MIPSSRA }; -"srl" , SHIFTI {txt="SRL" ; op=MIPSSRL }; - -"dsllv", SHIFTV {txt="DSLLV" ; op=MIPSDSLLV }; -"dsrav", SHIFTV {txt="DSRAV" ; op=MIPSDSRAV }; -"dsrlv", SHIFTV {txt="DSRLV" ; op=MIPSDSRLV }; -"sllv" , SHIFTV {txt="SLLV" ; op=MIPSSLLV }; -"srav" , SHIFTV {txt="SRAV" ; op=MIPSSRAV }; -"srlv" , SHIFTV {txt="SRLV" ; op=MIPSSRLV }; - -"ddiv" , MULDIV {txt="DDIV" ; op=MIPSDDIV }; -"ddivu" , MULDIV {txt="DDIVU" ; op=MIPSDDIVU }; -"div" , MULDIV {txt="DIV" ; op=MIPSDIV }; -"divu" , MULDIV {txt="DIVU" ; op=MIPSDIVU }; -"dmult" , MULDIV {txt="DMULT" ; op=MIPSDMULT }; -"dmultu", MULDIV {txt="DMULTU"; op=MIPSDMULTU }; -"madd" , MULDIV {txt="MADD" ; op=MIPSMADD }; -"maddu" , MULDIV {txt="MADDU" ; op=MIPSMADDU }; -"msub" , MULDIV {txt="MSUB" ; op=MIPSMSUB }; -"msubu" , MULDIV {txt="MSUBU" ; op=MIPSMSUBU }; -"mult" , MULDIV {txt="MULT" ; op=MIPSMULT }; -"multu" , MULDIV {txt="MULTU" ; op=MIPSMULTU }; - -"mfhi" , MFHILO {txt="MFHI" ; op=MIPSMFHI }; -"mflo" , MFHILO {txt="MFLO" ; op=MIPSMFLO }; -"mthi" , MFHILO {txt="MTHI" ; op=MIPSMTHI }; -"mtlo" , MFHILO {txt="MTLO" ; op=MIPSMTLO }; - -"lui" , LUI {txt="LUI" }; - -"lb" , LOAD {txt="LB" ; width=MIPSByte ; signed=true; linked=false }; -"lbu" , LOAD {txt="LBU" ; width=MIPSByte ; signed=false; linked=false }; -"lh" , LOAD {txt="LH" ; width=MIPSHalf ; signed=true; linked=false }; -"lhu" , LOAD {txt="LHU" ; width=MIPSHalf ; signed=false; linked=false }; -"lw" , LOAD {txt="LW" ; width=MIPSWord ; signed=true; linked=false }; -"lwu" , LOAD {txt="LWU" ; width=MIPSWord ; signed=false; linked=false }; -"ld" , LOAD {txt="LD" ; width=MIPSDouble ; signed=false; linked=false }; -"ll" , LOAD {txt="LL" ; width=MIPSWord ; signed=true; linked=true }; -"lld" , LOAD {txt="LLD" ; width=MIPSDouble ; signed=false; linked=true }; - -"sb" , STORE {txt="SB" ; width=MIPSByte ; conditional=false }; -"sh" , STORE {txt="SH" ; width=MIPSHalf ; conditional=false }; -"sw" , STORE {txt="SW" ; width=MIPSWord ; conditional=false }; -"sd" , STORE {txt="SD" ; width=MIPSDouble ; conditional=false }; -"sc" , STORE {txt="SC" ; width=MIPSWord ; conditional=true }; -"scd" , STORE {txt="SCD" ; width=MIPSDouble ; conditional=true }; - -"lwl" , LSLR {txt="LWL" ; store=false; double=false; left=true }; -"lwr" , LSLR {txt="LWR" ; store=false; double=false; left=false}; -"ldl" , LSLR {txt="LDL" ; store=false; double=true ; left=true }; -"ldr" , LSLR {txt="LDR" ; store=false; double=true ; left=false}; -"swl" , LSLR {txt="SWL" ; store=true ; double=false; left=true }; -"swr" , LSLR {txt="SWR" ; store=true ; double=false; left=false}; -"sdl" , LSLR {txt="SDL" ; store=true ; double=true ; left=true }; -"sdr" , LSLR {txt="SDR" ; store=true ; double=true ; left=false}; -"sync", SYNC {txt="SYNC"}; - -"beq", BEQ {txt="BEQ"; ne=false; likely=false }; -"beql", BEQ {txt="BEQ"; ne=false; likely=true }; -"bne", BEQ {txt="BEQ"; ne=true ; likely=false }; -"bnel", BEQ {txt="BEQ"; ne=true ; likely=true }; - -"bltz", BCMPZ {txt="BCMPZ"; cmp=MIPS_LT; likely=false; link=false }; -"bltzal", BCMPZ {txt="BCMPZ"; cmp=MIPS_LT; likely=false; link=true }; -"bltzl", BCMPZ {txt="BCMPZ"; cmp=MIPS_LT; likely=true; link=false }; -"bltzall",BCMPZ {txt="BCMPZ"; cmp=MIPS_LT; likely=true; link=true }; - -"bgez", BCMPZ {txt="BCMPZ"; cmp=MIPS_GE; likely=false; link=false }; -"bgezal", BCMPZ {txt="BCMPZ"; cmp=MIPS_GE; likely=false; link=true }; -"bgezl", BCMPZ {txt="BCMPZ"; cmp=MIPS_GE; likely=true; link=false }; -"bgezall",BCMPZ {txt="BCMPZ"; cmp=MIPS_GE; likely=true; link=true }; - -"bgtz", BCMPZ {txt="BCMPZ"; cmp=MIPS_GT; likely=false; link=false }; -"bgtzl", BCMPZ {txt="BCMPZ"; cmp=MIPS_GT; likely=true; link=false }; - -"blez", BCMPZ {txt="BCMPZ"; cmp=MIPS_LE; likely=false; link=false }; -"blezl", BCMPZ {txt="BCMPZ"; cmp=MIPS_LE; likely=true; link=false }; -"j", J {txt="J"}; -"jal", JAL {txt="JAL"}; -"jr", JR {txt="JR"}; -"jalr", JALR {txt="JALR"}; diff --git a/mips/hgen/map.hgen b/mips/hgen/map.hgen deleted file mode 100644 index f5116bae..00000000 --- a/mips/hgen/map.hgen +++ /dev/null @@ -1,19 +0,0 @@ -| `MIPSThreadStart -> `MIPSThreadStart -| `MIPSRType (op, rd, rs, rt) -> `MIPSRType (op, map_reg rd, map_reg rs, map_reg rt) -| `MIPSIType (op, rs, rt, imm) -> `MIPSIType (op, map_reg rs, map_reg rt, imm) -| `MIPSShiftI (op, rd, rt, imm) -> `MIPSShiftI (op, map_reg rd, map_reg rt, imm) -| `MIPSShiftV (op, rd, rt, rs) -> `MIPSShiftV (op, map_reg rd, map_reg rt, map_reg rs) -| `MIPSMulDiv (op, rs, rt) -> `MIPSMulDiv (op, map_reg rs, map_reg rt) -| `MIPSMFHiLo (op, rs) -> `MIPSMFHiLo (op, map_reg rs) -| `MIPSLUI (rt, imm) -> `MIPSLUI (map_reg rt, imm) -| `MIPSLoad (width, signed, linked, base, rt, offset) -> `MIPSLoad (width, signed, linked, map_reg base, map_reg rt, offset) -| `MIPSStore (width, conditional, base, rt, offset) -> `MIPSStore (width, conditional, map_reg base, map_reg rt, offset) -| `MIPSLSLR (store, double, left, base, rt, offset) -> `MIPSLSLR (store, double, left, map_reg base, map_reg rt, offset) -| `MIPSSYNC -> `MIPSSYNC -| `MIPSBEQ (rs, rt, offset, ne, likely) -> `MIPSBEQ (map_reg rs, map_reg rt, offset, ne, likely) -| `MIPSBCMPZ (rs, offset, cmp, link, likely) -> `MIPSBCMPZ (map_reg rs, offset, cmp, link, likely) -| `MIPSJ (offset) -> `MIPSJ (offset) -| `MIPSJAL (offset) -> `MIPSJAL (offset) (* implicit R31? *) -| `MIPSJR (rd) -> `MIPSJR (map_reg rd) -| `MIPSJALR (rd, rs) -> `MIPSJALR(map_reg rd, map_reg rs) - diff --git a/mips/hgen/parser.hgen b/mips/hgen/parser.hgen deleted file mode 100644 index 8f573aa5..00000000 --- a/mips/hgen/parser.hgen +++ /dev/null @@ -1,34 +0,0 @@ -| RTYPE reg COMMA reg COMMA reg - { `MIPSRType ($1.op, $2, $4, $6) } -| ITYPE reg COMMA reg COMMA NUM - { `MIPSIType ($1.op, $2, $4, $6) } -| SHIFTI reg COMMA reg COMMA NUM - { `MIPSShiftI ($1.op, $2, $4, $6) } -| SHIFTV reg COMMA reg COMMA reg - { `MIPSShiftV ($1.op, $2, $4, $6) } -| MULDIV reg COMMA reg - { `MIPSMulDiv ($1.op, $2, $4) } -| MFHILO reg - { `MIPSMFHiLo ($1.op, $2) } -| LUI reg COMMA NUM - { `MIPSLUI ($2, $4) } -| LOAD reg COMMA NUM LPAR reg RPAR - { `MIPSLoad ($1.width, $1.signed, $1.linked, $6, $2, $4) } -| STORE reg COMMA NUM LPAR reg RPAR - { `MIPSStore ($1.width, $1.conditional, $6, $2, $4) } -| LSLR reg COMMA NUM LPAR reg RPAR - { `MIPSLSLR ($1.store, $1.double, $1.left, $6, $2, $4) } -| SYNC - { `MIPSSYNC } -| BEQ reg COMMA reg COMMA NUM - { `MIPSBEQ ( $2, $4, $6, $1.ne, $1.likely) } -| BCMPZ reg COMMA NUM - { `MIPSBCMPZ ( $2, $4, $1.cmp, $1.link, $1.likely) } -| J NUM - { `MIPSJ ($2) } -| JAL NUM - { `MIPSJAL ($2) } -| JR reg - { `MIPSJR ($2) } -| JALR reg COMMA reg - { `MIPSJALR ($2, $4) } diff --git a/mips/hgen/pretty.hgen b/mips/hgen/pretty.hgen deleted file mode 100644 index 98f56f2e..00000000 --- a/mips/hgen/pretty.hgen +++ /dev/null @@ -1,36 +0,0 @@ -| `MIPSThreadStart -> "syscall 0xfffff" (* thread start *) -| `MIPSStopFetching -> "STOP" (* TODO *) -| `MIPSRType (op, rd,rs,rt) -> - sprintf "%s %s,%s,%s" (pp_rtype_op op) (pp_reg rd) (pp_reg rs) (pp_reg rt) -| `MIPSIType (op,rd,rs,imm) -> - sprintf "%s %s,%s,%d" (pp_itype_op op) (pp_reg rd) (pp_reg rs) imm -| `MIPSShiftI (op, rs, rt, imm) -> - sprintf "%s %s,%s,%d" (pp_shifti_op op) (pp_reg rs) (pp_reg rt) imm -| `MIPSShiftV (op, rd,rs,rt) -> - sprintf "%s %s,%s,%s" (pp_shiftv_op op) (pp_reg rd) (pp_reg rs) (pp_reg rt) -| `MIPSMulDiv (op, rs, rt) -> - sprintf "%s %s,%s" (pp_muldiv_op op) (pp_reg rs) (pp_reg rt) -| `MIPSMFHiLo (op, rs) -> - sprintf "%s %s" (pp_mfhilo_op op) (pp_reg rs) -| `MIPSLUI (rt, imm) -> - sprintf "lui %s,%d" (pp_reg rt) imm -| `MIPSLoad (width, signed, linked, base, rt, offset) -> - sprintf "%s %s,%d(%s)" (pp_load_op width signed linked) (pp_reg rt) offset (pp_reg base) -| `MIPSStore (width, conditional, base, rt, offset) -> - sprintf "%s %s,%d(%s)" (pp_store_op width conditional) (pp_reg rt) offset (pp_reg base) -| `MIPSLSLR (store, double, left, base, rt, offset) -> - sprintf "%s %s,%d(%s)" (pp_lslr_op store double left) (pp_reg rt) offset (pp_reg base) -| `MIPSSYNC -> "sync" -| `MIPSBEQ (rs, rt, offset, ne, likely) -> - sprintf "%s %s,%s,.%+d" (pp_beq_op ne likely) (pp_reg rs) (pp_reg rt) offset -| `MIPSBCMPZ (rs, offset, cmp, link, likely) -> - sprintf "%s,%s,.%+d" (pp_bcmpz_op cmp link likely) (pp_reg rs) offset -| `MIPSJ (offset) -> - sprintf "j %d" offset -| `MIPSJAL (offset) -> - sprintf "jal %d" offset -| `MIPSJR(rd) -> - sprintf "jr %s" (pp_reg rd) -| `MIPSJALR(rd, rs) -> - sprintf "jalr %s,%s" (pp_reg rd) (pp_reg rs) - diff --git a/mips/hgen/sail_trans_out.hgen b/mips/hgen/sail_trans_out.hgen deleted file mode 100644 index f2d006e8..00000000 --- a/mips/hgen/sail_trans_out.hgen +++ /dev/null @@ -1,98 +0,0 @@ -| ("SYSCALL_THREAD_START", []) -> `MIPSThreadStart -| ("ADD" , [rs; rt; rd]) -> `MIPSRType (MIPSROpADD , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| ("ADDU" , [rs; rt; rd]) -> `MIPSRType (MIPSROpADDU , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| ("AND" , [rs; rt; rd]) -> `MIPSRType (MIPSROpAND , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| ("DADD" , [rs; rt; rd]) -> `MIPSRType (MIPSROpDADD , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| ("DADDU" , [rs; rt; rd]) -> `MIPSRType (MIPSROpDADDU , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| ("DSUB" , [rs; rt; rd]) -> `MIPSRType (MIPSROpDSUB , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| ("DSUBU" , [rs; rt; rd]) -> `MIPSRType (MIPSROpDSUBU , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| ("MOVN" , [rs; rt; rd]) -> `MIPSRType (MIPSROpMOVN , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| ("MOVZ" , [rs; rt; rd]) -> `MIPSRType (MIPSROpMOVZ , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| ("MUL" , [rs; rt; rd]) -> `MIPSRType (MIPSROpMUL , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| ("NOR" , [rs; rt; rd]) -> `MIPSRType (MIPSROpNOR , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| ("OR" , [rs; rt; rd]) -> `MIPSRType (MIPSROpOR , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| ("SLT" , [rs; rt; rd]) -> `MIPSRType (MIPSROpSLT , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| ("SLTU" , [rs; rt; rd]) -> `MIPSRType (MIPSROpSLTU , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| ("SUB" , [rs; rt; rd]) -> `MIPSRType (MIPSROpSUB , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| ("SUBU" , [rs; rt; rd]) -> `MIPSRType (MIPSROpSUBU , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| ("XOR" , [rs; rt; rd]) -> `MIPSRType (MIPSROpXOR , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) - -| ("ADDI" , [rs; rt; imm]) -> `MIPSIType (MIPSIOpADDI ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_simm16 imm)) -| ("ADDIU" , [rs; rt; imm]) -> `MIPSIType (MIPSIOpADDIU ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_simm16 imm)) -| ("ANDI" , [rs; rt; imm]) -> `MIPSIType (MIPSIOpANDI ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_imm16 imm)) -| ("DADDI" , [rs; rt; imm]) -> `MIPSIType (MIPSIOpDADDI ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_simm16 imm)) -| ("DADDIU", [rs; rt; imm]) -> `MIPSIType (MIPSIOpDADDIU,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_simm16 imm)) -| ("ORI" , [rs; rt; imm]) -> `MIPSIType (MIPSIOpORI ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_imm16 imm)) -| ("SLTI" , [rs; rt; imm]) -> `MIPSIType (MIPSIOpSLTI ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_simm16 imm)) -| ("SLTIU" , [rs; rt; imm]) -> `MIPSIType (MIPSIOpSLTIU ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_simm16 imm)) -| ("XORI" , [rs; rt; imm]) -> `MIPSIType (MIPSIOpXORI ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_imm16 imm)) - -| ("DSLL" , [rt; rd; sa]) -> `MIPSShiftI (MIPSDSLL , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) -| ("DSLL32" , [rt; rd; sa]) -> `MIPSShiftI (MIPSDSLL32 , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) -| ("DSRA" , [rt; rd; sa]) -> `MIPSShiftI (MIPSDSRA , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) -| ("DSRA32" , [rt; rd; sa]) -> `MIPSShiftI (MIPSDSRA32 , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) -| ("DSRL" , [rt; rd; sa]) -> `MIPSShiftI (MIPSDSRL , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) -| ("DSRL32" , [rt; rd; sa]) -> `MIPSShiftI (MIPSDSRL32 , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) -| ("SLL" , [rt; rd; sa]) -> `MIPSShiftI (MIPSSLL , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) -| ("SRA" , [rt; rd; sa]) -> `MIPSShiftI (MIPSSRA , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) -| ("SRL" , [rt; rd; sa]) -> `MIPSShiftI (MIPSSRL , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) - -| "DSLLV" , [rs; rt; rd] -> `MIPSShiftV (MIPSDSLLV , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_ireg rs)) -| "DSRAV" , [rs; rt; rd] -> `MIPSShiftV (MIPSDSRAV , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_ireg rs)) -| "DSRLV" , [rs; rt; rd] -> `MIPSShiftV (MIPSDSRLV , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_ireg rs)) -| "SLLV" , [rs; rt; rd] -> `MIPSShiftV (MIPSSLLV , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_ireg rs)) -| "SRAV" , [rs; rt; rd] -> `MIPSShiftV (MIPSSRAV , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_ireg rs)) -| "SRLV" , [rs; rt; rd] -> `MIPSShiftV (MIPSSRLV , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_ireg rs)) - -| "DDIV" , [rs; rt] -> `MIPSMulDiv (MIPSDDIV , (translate_out_ireg rs), (translate_out_ireg rt)) -| "DDIVU" , [rs; rt] -> `MIPSMulDiv (MIPSDDIVU , (translate_out_ireg rs), (translate_out_ireg rt)) -| "DIV" , [rs; rt] -> `MIPSMulDiv (MIPSDIV , (translate_out_ireg rs), (translate_out_ireg rt)) -| "DIVU" , [rs; rt] -> `MIPSMulDiv (MIPSDIVU , (translate_out_ireg rs), (translate_out_ireg rt)) -| "DMULT" , [rs; rt] -> `MIPSMulDiv (MIPSDMULT , (translate_out_ireg rs), (translate_out_ireg rt)) -| "DMULTU", [rs; rt] -> `MIPSMulDiv (MIPSDMULTU , (translate_out_ireg rs), (translate_out_ireg rt)) -| "MADD" , [rs; rt] -> `MIPSMulDiv (MIPSMADD , (translate_out_ireg rs), (translate_out_ireg rt)) -| "MADDU" , [rs; rt] -> `MIPSMulDiv (MIPSMADDU , (translate_out_ireg rs), (translate_out_ireg rt)) -| "MSUB" , [rs; rt] -> `MIPSMulDiv (MIPSMSUB , (translate_out_ireg rs), (translate_out_ireg rt)) -| "MSUBU" , [rs; rt] -> `MIPSMulDiv (MIPSMSUBU , (translate_out_ireg rs), (translate_out_ireg rt)) -| "MULT" , [rs; rt] -> `MIPSMulDiv (MIPSMULT , (translate_out_ireg rs), (translate_out_ireg rt)) -| "MULTU" , [rs; rt] -> `MIPSMulDiv (MIPSMULTU , (translate_out_ireg rs), (translate_out_ireg rt)) - -| "MFHI" , [rs] -> `MIPSMFHiLo (MIPSMFHI, (translate_out_ireg rs)) -| "MFLO" , [rs] -> `MIPSMFHiLo (MIPSMFLO, (translate_out_ireg rs)) -| "MTHI" , [rs] -> `MIPSMFHiLo (MIPSMTHI, (translate_out_ireg rs)) -| "MTLO" , [rs] -> `MIPSMFHiLo (MIPSMTLO, (translate_out_ireg rs)) - -| "LUI" , [rt; imm] -> `MIPSLUI ((translate_out_ireg rt), (translate_out_imm16 imm)) -| "Load", [width; signed; linked; base; rt; offset] -> - `MIPSLoad ( - (translate_out_wordWidth width), - (translate_out_bool signed), - (translate_out_bool linked), - (translate_out_ireg base), - (translate_out_ireg rt), - (translate_out_simm16 offset) - ) -| "Store", [width; conditional; base; rt; offset] -> - `MIPSStore ( - (translate_out_wordWidth width), - (translate_out_bool conditional), - (translate_out_ireg base), - (translate_out_ireg rt), - (translate_out_simm16 offset) - ) -| "LWL", [base; rt; offset] -> `MIPSLSLR (false, false, true , (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) -| "LWR", [base; rt; offset] -> `MIPSLSLR (false, false, false, (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) -| "LDL", [base; rt; offset] -> `MIPSLSLR (false, true , true , (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) -| "LDR", [base; rt; offset] -> `MIPSLSLR (false, true , false, (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) -| "SWL", [base; rt; offset] -> `MIPSLSLR (true , false, true , (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) -| "SWR", [base; rt; offset] -> `MIPSLSLR (true , false, false, (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) -| "SDL", [base; rt; offset] -> `MIPSLSLR (true , true , true , (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) -| "SDR", [base; rt; offset] -> `MIPSLSLR (true , true , false, (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) -| "SYNC", [] -> `MIPSSYNC -| "BEQ", [rs; rt; offset; ne; likely] -> `MIPSBEQ ((translate_out_ireg rs), (translate_out_ireg rt), (translate_out_simm16 offset), (translate_out_bool ne), (translate_out_bool likely)) -| "BCMPZ", [rs; offset; cmp; link; likely] -> `MIPSBCMPZ ((translate_out_ireg rs), (translate_out_simm16 offset), (translate_out_cmp cmp), (translate_out_bool link), (translate_out_bool likely)) -| "J", [offset] -> `MIPSJ (translate_out_imm26 offset) -| "JAL", [offset] -> `MIPSJAL (translate_out_imm26 offset) -| "JR", [rd] -> `MIPSJR (translate_out_ireg rd) -| "JALR", [rd; rs] -> `MIPSJALR (translate_out_ireg rd, translate_out_ireg rs) - diff --git a/mips/hgen/shallow_ast_to_herdtools_ast.hgen b/mips/hgen/shallow_ast_to_herdtools_ast.hgen deleted file mode 100644 index efe2c77e..00000000 --- a/mips/hgen/shallow_ast_to_herdtools_ast.hgen +++ /dev/null @@ -1,98 +0,0 @@ -| SYSCALL_THREAD_START -> `MIPSThreadStart -| (ADD (rs, rt, rd)) -> `MIPSRType (MIPSROpADD , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| (ADDU (rs, rt, rd)) -> `MIPSRType (MIPSROpADDU , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| (AND (rs, rt, rd)) -> `MIPSRType (MIPSROpAND , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| (DADD (rs, rt, rd)) -> `MIPSRType (MIPSROpDADD , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| (DADDU (rs, rt, rd)) -> `MIPSRType (MIPSROpDADDU , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| (DSUB (rs, rt, rd)) -> `MIPSRType (MIPSROpDSUB , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| (DSUBU (rs, rt, rd)) -> `MIPSRType (MIPSROpDSUBU , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| (MOVN (rs, rt, rd)) -> `MIPSRType (MIPSROpMOVN , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| (MOVZ (rs, rt, rd)) -> `MIPSRType (MIPSROpMOVZ , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| (MUL (rs, rt, rd)) -> `MIPSRType (MIPSROpMUL , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| (NOR (rs, rt, rd)) -> `MIPSRType (MIPSROpNOR , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| (OR (rs, rt, rd)) -> `MIPSRType (MIPSROpOR , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| (SLT (rs, rt, rd)) -> `MIPSRType (MIPSROpSLT , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| (SLTU (rs, rt, rd)) -> `MIPSRType (MIPSROpSLTU , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| (SUB (rs, rt, rd)) -> `MIPSRType (MIPSROpSUB , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| (SUBU (rs, rt, rd)) -> `MIPSRType (MIPSROpSUBU , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) -| (XOR (rs, rt, rd)) -> `MIPSRType (MIPSROpXOR , (translate_out_ireg rd), (translate_out_ireg rs), (translate_out_ireg rt)) - -| (ADDI (rs, rt, imm)) -> `MIPSIType (MIPSIOpADDI ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_simm16 imm)) -| (ADDIU (rs, rt, imm)) -> `MIPSIType (MIPSIOpADDIU ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_simm16 imm)) -| (ANDI (rs, rt, imm)) -> `MIPSIType (MIPSIOpANDI ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_imm16 imm)) -| (DADDI (rs, rt, imm)) -> `MIPSIType (MIPSIOpDADDI ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_simm16 imm)) -| (DADDIU (rs, rt, imm)) -> `MIPSIType (MIPSIOpDADDIU,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_simm16 imm)) -| (ORI (rs, rt, imm)) -> `MIPSIType (MIPSIOpORI ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_imm16 imm)) -| (SLTI (rs, rt, imm)) -> `MIPSIType (MIPSIOpSLTI ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_simm16 imm)) -| (SLTIU (rs, rt, imm)) -> `MIPSIType (MIPSIOpSLTIU ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_simm16 imm)) -| (XORI (rs, rt, imm)) -> `MIPSIType (MIPSIOpXORI ,(translate_out_ireg rt), (translate_out_ireg rs), (translate_out_imm16 imm)) - -| (DSLL (rt, rd, sa)) -> `MIPSShiftI (MIPSDSLL , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) -| (DSLL32 (rt, rd, sa)) -> `MIPSShiftI (MIPSDSLL32 , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) -| (DSRA (rt, rd, sa)) -> `MIPSShiftI (MIPSDSRA , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) -| (DSRA32 (rt, rd, sa)) -> `MIPSShiftI (MIPSDSRA32 , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) -| (DSRL (rt, rd, sa)) -> `MIPSShiftI (MIPSDSRL , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) -| (DSRL32 (rt, rd, sa)) -> `MIPSShiftI (MIPSDSRL32 , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) -| (SLL (rt, rd, sa)) -> `MIPSShiftI (MIPSSLL , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) -| (SRA (rt, rd, sa)) -> `MIPSShiftI (MIPSSRA , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) -| (SRL (rt, rd, sa)) -> `MIPSShiftI (MIPSSRL , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_imm5 sa)) - -| DSLLV (rs, rt, rd) -> `MIPSShiftV (MIPSDSLLV , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_ireg rs)) -| DSRAV (rs, rt, rd) -> `MIPSShiftV (MIPSDSRAV , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_ireg rs)) -| DSRLV (rs, rt, rd) -> `MIPSShiftV (MIPSDSRLV , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_ireg rs)) -| SLLV (rs, rt, rd) -> `MIPSShiftV (MIPSSLLV , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_ireg rs)) -| SRAV (rs, rt, rd) -> `MIPSShiftV (MIPSSRAV , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_ireg rs)) -| SRLV (rs, rt, rd) -> `MIPSShiftV (MIPSSRLV , (translate_out_ireg rd), (translate_out_ireg rt), (translate_out_ireg rs)) - -| DDIV (rs, rt) -> `MIPSMulDiv (MIPSDDIV , (translate_out_ireg rs), (translate_out_ireg rt)) -| DDIVU (rs, rt) -> `MIPSMulDiv (MIPSDDIVU , (translate_out_ireg rs), (translate_out_ireg rt)) -| DIV (rs, rt) -> `MIPSMulDiv (MIPSDIV , (translate_out_ireg rs), (translate_out_ireg rt)) -| DIVU (rs, rt) -> `MIPSMulDiv (MIPSDIVU , (translate_out_ireg rs), (translate_out_ireg rt)) -| DMULT (rs, rt) -> `MIPSMulDiv (MIPSDMULT , (translate_out_ireg rs), (translate_out_ireg rt)) -| DMULTU (rs, rt) -> `MIPSMulDiv (MIPSDMULTU , (translate_out_ireg rs), (translate_out_ireg rt)) -| MADD (rs, rt) -> `MIPSMulDiv (MIPSMADD , (translate_out_ireg rs), (translate_out_ireg rt)) -| MADDU (rs, rt) -> `MIPSMulDiv (MIPSMADDU , (translate_out_ireg rs), (translate_out_ireg rt)) -| MSUB (rs, rt) -> `MIPSMulDiv (MIPSMSUB , (translate_out_ireg rs), (translate_out_ireg rt)) -| MSUBU (rs, rt) -> `MIPSMulDiv (MIPSMSUBU , (translate_out_ireg rs), (translate_out_ireg rt)) -| MULT (rs, rt) -> `MIPSMulDiv (MIPSMULT , (translate_out_ireg rs), (translate_out_ireg rt)) -| MULTU (rs, rt) -> `MIPSMulDiv (MIPSMULTU , (translate_out_ireg rs), (translate_out_ireg rt)) - -| MFHI (rs) -> `MIPSMFHiLo (MIPSMFHI, (translate_out_ireg rs)) -| MFLO (rs) -> `MIPSMFHiLo (MIPSMFLO, (translate_out_ireg rs)) -| MTHI (rs) -> `MIPSMFHiLo (MIPSMTHI, (translate_out_ireg rs)) -| MTLO (rs) -> `MIPSMFHiLo (MIPSMTLO, (translate_out_ireg rs)) - -| LUI (rt, imm) -> `MIPSLUI ((translate_out_ireg rt), (translate_out_imm16 imm)) -| Load (width, signed, linked, base, rt, offset) -> - `MIPSLoad ( - (translate_out_wordWidth width), - (translate_out_bool signed), - (translate_out_bool linked), - (translate_out_ireg base), - (translate_out_ireg rt), - (translate_out_simm16 offset) - ) -| Store (width, conditional, base, rt, offset) -> - `MIPSStore ( - (translate_out_wordWidth width), - (translate_out_bool conditional), - (translate_out_ireg base), - (translate_out_ireg rt), - (translate_out_simm16 offset) - ) -| LWL (base, rt, offset) -> `MIPSLSLR (false, false, true , (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) -| LWR (base, rt, offset) -> `MIPSLSLR (false, false, false, (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) -| LDL (base, rt, offset) -> `MIPSLSLR (false, true , true , (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) -| LDR (base, rt, offset) -> `MIPSLSLR (false, true , false, (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) -| SWL (base, rt, offset) -> `MIPSLSLR (true , false, true , (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) -| SWR (base, rt, offset) -> `MIPSLSLR (true , false, false, (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) -| SDL (base, rt, offset) -> `MIPSLSLR (true , true , true , (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) -| SDR (base, rt, offset) -> `MIPSLSLR (true , true , false, (translate_out_ireg base), (translate_out_ireg rt), (translate_out_simm16 offset)) -| SYNC -> `MIPSSYNC -| BEQ (rs, rt, offset, ne, likely) -> `MIPSBEQ ((translate_out_ireg rs), (translate_out_ireg rt), (translate_out_simm16 offset), (translate_out_bool ne), (translate_out_bool likely)) -| BCMPZ (rs, offset, cmp, link, likely) -> `MIPSBCMPZ ((translate_out_ireg rs), (translate_out_simm16 offset), (translate_out_cmp cmp), (translate_out_bool link), (translate_out_bool likely)) -| J (offset) -> `MIPSJ (translate_out_imm26 offset) -| JAL (offset) -> `MIPSJAL (translate_out_imm26 offset) -| JR (rd) -> `MIPSJR (translate_out_ireg rd) -| JALR (rd, rs) -> `MIPSJALR (translate_out_ireg rd, translate_out_ireg rs) - diff --git a/mips/hgen/shallow_types_to_herdtools_types.hgen b/mips/hgen/shallow_types_to_herdtools_types.hgen deleted file mode 100644 index a02d83b7..00000000 --- a/mips/hgen/shallow_types_to_herdtools_types.hgen +++ /dev/null @@ -1,39 +0,0 @@ -let translate_out_big_bit = Sail_values.unsigned - -let translate_out_int inst = (Nat_big_num.to_int (translate_out_big_bit inst)) -let translate_out_signed_int inst bits = - let i = (Nat_big_num.to_int (translate_out_big_bit inst)) in - if (i >= (1 lsl (bits - 1))) then - (i - (1 lsl bits)) else - i - -let translate_out_ireg ireg = IReg (int_to_ireg (translate_out_int ireg)) - -let translate_out_imm26 imm = translate_out_int imm - -let translate_out_imm16 imm = translate_out_int imm -let translate_out_simm16 imm = translate_out_signed_int imm 16 - -let translate_out_imm5 imm = translate_out_int imm - -let translate_out_bool = function - | Sail_values.B1 -> true - | Sail_values.B0 -> false - | _ -> failwith "translate_out_bool Undef" - - -let translate_out_wordWidth = function - | Mips_embed_types.B2 -> MIPSByte - | Mips_embed_types.H -> MIPSHalf - | Mips_embed_types.W -> MIPSWord - | Mips_embed_types.D -> MIPSDouble - -let translate_out_cmp = function - | Mips_embed_types.EQ' -> MIPS_EQ (* equal *) - | Mips_embed_types.NE -> MIPS_NE (* not equal *) - | Mips_embed_types.GE -> MIPS_GE (* signed greater than or equal *) - | Mips_embed_types.GEU -> MIPS_GEU (* unsigned greater than or equal *) - | Mips_embed_types.GT' -> MIPS_GT (* signed strictly greater than *) - | Mips_embed_types.LE -> MIPS_LE (* signed less than or equal *) - | Mips_embed_types.LT' -> MIPS_LT (* signed strictly less than *) - | Mips_embed_types.LTU -> MIPS_LTU (* unsigned less than or qual *) diff --git a/mips/hgen/token_types.hgen b/mips/hgen/token_types.hgen deleted file mode 100644 index 170b42d3..00000000 --- a/mips/hgen/token_types.hgen +++ /dev/null @@ -1,39 +0,0 @@ -type token_RTYPE = {txt : string; op : mipsRTypeOp } -type token_ITYPE = {txt : string; op : mipsITypeOp } -type token_ShiftI = {txt : string; op : mipsShiftIOp } -type token_ShiftV = {txt : string; op : mipsShiftVOp } -type token_MulDiv = {txt : string; op : mipsMulDivOp } -type token_MFHiLo = {txt : string; op : mipsMFHiLoOp } -type token_LUI = {txt : string } -type token_Load = {txt : string; width: mipsWordWidth; signed : bool; linked : bool} -type token_Store = {txt : string; width: mipsWordWidth; conditional : bool} -type token_LSLR = {txt : string; store : bool; double : bool; left: bool } (* Load/Store Left/Right *) -type token_SYNC = {txt : string} -type token_BEQ = {txt : string; ne : bool; likely : bool } -type token_BCMPZ = {txt : string; cmp : mipsCmp; likely : bool; link : bool } -type token_J = {txt : string} -type token_JAL = {txt : string} -type token_JR = {txt : string} -type token_JALR = {txt : string} -(* -(regno, imm16, Comparison) TRAPIMM - -(regno, regno) RDHWR -(regno, regno, Comparison) TRAPREG -(regno, regno, bit[3], bool) MFC0 -(regno, regno, bit[3], bool) MTC0 -(regno, regno, imm16, bool, bool) BEQ -TLBP -TLBR -TLBWI -TLBWR - -regregimm16 CACHE -regregimm16 PREF - -unit BREAK -unit ERET -unit HCF -unit SYSCALL -unit WAIT -*) \ No newline at end of file diff --git a/mips/hgen/tokens.hgen b/mips/hgen/tokens.hgen deleted file mode 100644 index 937c6354..00000000 --- a/mips/hgen/tokens.hgen +++ /dev/null @@ -1,17 +0,0 @@ -%token RTYPE -%token ITYPE -%token SHIFTI -%token SHIFTV -%token MULDIV -%token MFHILO -%token LUI -%token LOAD -%token STORE -%token LSLR -%token SYNC -%token BEQ -%token BCMPZ -%token J -%token JAL -%token JR -%token JALR diff --git a/mips/hgen/trans_sail.hgen b/mips/hgen/trans_sail.hgen deleted file mode 100644 index e42d1b19..00000000 --- a/mips/hgen/trans_sail.hgen +++ /dev/null @@ -1,122 +0,0 @@ -| `MIPSThreadStart -> - ("SYSCALL_THREAD_START", [], []) -| `MIPSStopFetching -> - ("ImplementationDefinedStopFetching", - [], - []) - -(* Note different argument order, which reflects difference - between instruction encoding and asm format *) -| `MIPSRType (op, rd, rs, rt) -> - (translate_rtype_op op, - [ - translate_reg "rs" rs; - translate_reg "rt" rt; - translate_reg "rd" rd; - ], - []) - -(* Note different argument order similar to above *) -| `MIPSIType (op, rt, rs, imm) -> - (translate_itype_op op, - [ - translate_reg "rs" rs; - translate_reg "rt" rt; - translate_imm16 "imm" imm; - ], - []) - -| `MIPSShiftI (op, rd, rt, sa) -> - (translate_shifti_op op, - [ - translate_reg "rt" rt; - translate_reg "rd" rd; - translate_imm5 "sa" sa; - ], - []) - -| `MIPSShiftV (op, rd, rt, rs) -> - (translate_shiftv_op op, - [ - translate_reg "rs" rs; - translate_reg "rt" rt; - translate_reg "rd" rd; - ], - []) - -| `MIPSMulDiv (op, rs, rt) -> - (translate_muldiv_op op, - [ - translate_reg "rs" rs; - translate_reg "rt" rt; - ], - []) - -| `MIPSMFHiLo (op, rs) -> - (translate_mfhilo_op op, - [ - translate_reg "rs" rs; - ], - []) -| `MIPSLUI (rt, imm) -> - ("LUI", - [ - translate_reg "rt" rt; - translate_imm16 "imm" imm; - ], - []) -| `MIPSLoad (width, signed, linked, base, rt, offset) -> - ("Load", - [ - translate_wordsize "width" width; - translate_bool "signed" signed; - translate_bool "linked" linked; - translate_reg "base" base; - translate_reg "rt" rt; - translate_imm16 "offset" offset; - ], - []) -| `MIPSStore (width, conditional, base, rt, offset) -> - ("Store", - [ - translate_wordsize "width" width; - translate_bool "conditional" conditional; - translate_reg "base" base; - translate_reg "rt" rt; - translate_imm16 "offset" offset; - ], - []) -| `MIPSLSLR (store, double, left, base, rt, offset) -> - (translate_lslr_op store double left, - [ - translate_reg "base" base; - translate_reg "rt" rt; - translate_imm16 "offset" offset; - ], - []) -| `MIPSSYNC -> ("SYNC", [], []) -| `MIPSBEQ (rs, rt, offset, ne, likely) -> - ("BEQ", - [translate_reg "rs" rs; - translate_reg "rt" rt; - translate_imm16 "offset" offset; - translate_bool "ne" ne; - translate_bool "likely" likely; - ], []) - -| `MIPSBCMPZ (rs, offset, cmp, link, likely) -> - ("BCMPZ", - [translate_reg "rs" rs; - translate_imm16 "offset" offset; - translate_cmp "cmp" cmp; - translate_bool "link" link; - translate_bool "likely" likely; - ], []) -| `MIPSJ (offset) -> - ("J", [translate_imm26 "offset" offset;], []) -| `MIPSJAL (offset) -> - ("JAL", [translate_imm26 "offset" offset;], []) -| `MIPSJR(rd) -> - ("JR", [translate_reg "rd" rd;], []) -| `MIPSJALR(rd, rs) -> - ("JALR", [translate_reg "rd" rd; translate_reg "rs" rs;], []) diff --git a/mips/hgen/types.hgen b/mips/hgen/types.hgen deleted file mode 100644 index a1c61f4b..00000000 --- a/mips/hgen/types.hgen +++ /dev/null @@ -1,209 +0,0 @@ -type mipsRTypeOp = -| MIPSROpADD -| MIPSROpADDU -| MIPSROpAND -| MIPSROpDADD -| MIPSROpDADDU -| MIPSROpDSUB -| MIPSROpDSUBU -| MIPSROpMOVN -| MIPSROpMOVZ -| MIPSROpMUL -| MIPSROpNOR -| MIPSROpOR -| MIPSROpSLT -| MIPSROpSLTU -| MIPSROpSUB -| MIPSROpSUBU -| MIPSROpXOR - -let pp_rtype_op = function -| MIPSROpADD -> "add" -| MIPSROpADDU -> "addu" -| MIPSROpAND -> "and" -| MIPSROpDADD -> "dadd" -| MIPSROpDADDU -> "daddu" -| MIPSROpDSUB -> "dsub" -| MIPSROpDSUBU -> "dsubu" -| MIPSROpMOVN -> "movn" -| MIPSROpMOVZ -> "movz" -| MIPSROpMUL -> "mul" -| MIPSROpNOR -> "nor" -| MIPSROpOR -> "or" -| MIPSROpSLT -> "slt" -| MIPSROpSLTU -> "sltu" -| MIPSROpSUB -> "sub" -| MIPSROpSUBU -> "subu" -| MIPSROpXOR -> "xor" - -type bit26 = int -type bit16 = int -type bit5 = int - -type mipsITypeOp = -| MIPSIOpADDI -| MIPSIOpADDIU -| MIPSIOpANDI -| MIPSIOpDADDI -| MIPSIOpDADDIU -| MIPSIOpORI -| MIPSIOpSLTI -| MIPSIOpSLTIU -| MIPSIOpXORI - -let pp_itype_op = function -| MIPSIOpADDI -> "addi" -| MIPSIOpADDIU -> "addiu" -| MIPSIOpANDI -> "andi" -| MIPSIOpDADDI -> "daddi" -| MIPSIOpDADDIU -> "daddiu" -| MIPSIOpORI -> "ori" -| MIPSIOpSLTI -> "slti" -| MIPSIOpSLTIU -> "sltiu" -| MIPSIOpXORI -> "xori" - -type mipsShiftIOp = -| MIPSDSLL -| MIPSDSLL32 -| MIPSDSRA -| MIPSDSRA32 -| MIPSDSRL -| MIPSDSRL32 -| MIPSSLL -| MIPSSRA -| MIPSSRL - -let pp_shifti_op = function -| MIPSDSLL -> "dsll" -| MIPSDSLL32 -> "dsll32" -| MIPSDSRA -> "dsra" -| MIPSDSRA32 -> "dsra32" -| MIPSDSRL -> "dsrl" -| MIPSDSRL32 -> "dsrl32" -| MIPSSLL -> "sll" -| MIPSSRA -> "sra" -| MIPSSRL -> "srl" - -type mipsShiftVOp = -| MIPSDSLLV -| MIPSDSRAV -| MIPSDSRLV -| MIPSSLLV -| MIPSSRAV -| MIPSSRLV - -let pp_shiftv_op = function -| MIPSDSLLV -> "dsllv" -| MIPSDSRAV -> "dsrav" -| MIPSDSRLV -> "dsrlv" -| MIPSSLLV -> "sllv" -| MIPSSRAV -> "srav" -| MIPSSRLV -> "srlv" - -type mipsMulDivOp = -| MIPSDDIV -| MIPSDDIVU -| MIPSDIV -| MIPSDIVU -| MIPSDMULT -| MIPSDMULTU -| MIPSMADD -| MIPSMADDU -| MIPSMSUB -| MIPSMSUBU -| MIPSMULT -| MIPSMULTU - -let pp_muldiv_op = function -| MIPSDDIV -> "ddiv" -| MIPSDDIVU -> "ddivu" -| MIPSDIV -> "div" -| MIPSDIVU -> "divu" -| MIPSDMULT -> "dmult" -| MIPSDMULTU -> "dmultu" -| MIPSMADD -> "madd" -| MIPSMADDU -> "maddu" -| MIPSMSUB -> "msub" -| MIPSMSUBU -> "msubu" -| MIPSMULT -> "mult" -| MIPSMULTU -> "multu" - -type mipsMFHiLoOp = -| MIPSMFHI -| MIPSMFLO -| MIPSMTHI -| MIPSMTLO - -let pp_mfhilo_op = function -| MIPSMFHI -> "mfhi" -| MIPSMFLO -> "mflo" -| MIPSMTHI -> "mthi" -| MIPSMTLO -> "mtlo" - -type mipsWordWidth = -| MIPSByte -| MIPSHalf -| MIPSWord -| MIPSDouble - -type mipsCmp = -| MIPS_EQ (* equal *) -| MIPS_NE (* not equal *) -| MIPS_GE (* signed greater than or equal *) -| MIPS_GEU (* unsigned greater than or equal *) -| MIPS_GT (* signed strictly greater than *) -| MIPS_LE (* signed less than or equal *) -| MIPS_LT (* signed strictly less than *) -| MIPS_LTU (* unsigned less than or qual *) - -let pp_load_op width signed linked = match (width, signed, linked) with - | (MIPSByte, true, false) -> "lb" - | (MIPSByte, false, false) -> "lbu" - | (MIPSHalf, true, false) -> "lh" - | (MIPSHalf, false, false) -> "lhu" - | (MIPSWord, true, false) -> "lw" - | (MIPSWord, false, false) -> "lwu" - | (MIPSDouble, false, false) -> "ld" - | (MIPSWord, true, true) -> "ll" - | (MIPSDouble, false, true) -> "lld" - | _ -> failwith "unexpected load op" - -let pp_store_op width conditional = match (width, conditional) with - | (MIPSByte, false) -> "sb" - | (MIPSHalf, false) -> "sh" - | (MIPSWord, false) -> "sw" - | (MIPSDouble, false) -> "sd" - | (MIPSWord, true) -> "sc" - | (MIPSDouble, true) -> "scd" - | _ -> failwith "unexpected store op" - -let pp_lslr_op store double left = match (store, double, left) with - | (false, false, true ) -> "lwl" - | (false, false, false) -> "lwr" - | (false, true , true ) -> "ldl" - | (false, true , false) -> "ldr" - | (true , false, true ) -> "swl" - | (true , false, false) -> "swr" - | (true , true , true ) -> "sdl" - | (true , true , false) -> "sdr" - -let pp_beq_op ne likely = match (ne, likely) with - | (false, false) -> "beq" - | (false, true) -> "beql" - | (true , false) -> "bne" - | (true , true) -> "bnel" - -let pp_bcmpz_op cmp link likely = match (cmp, likely, link) with -| (MIPS_LT, false , false ) -> "bltz" -| (MIPS_LT, false , true ) -> "bltzal" -| (MIPS_LT, true , false ) -> "bltzl" -| (MIPS_LT, true , true ) -> "bltzall" -| (MIPS_GE, false , false ) -> "bgez" -| (MIPS_GE, false , true ) -> "bgezal" -| (MIPS_GE, true , false ) -> "bgezl" -| (MIPS_GE, true , true ) -> "bgezall" -| (MIPS_GT, false , false ) -> "bgtz" -| (MIPS_GT, true , false ) -> "bgtzl" -| (MIPS_LE, false , false ) -> "blez" -| (MIPS_LE, true , false ) -> "blezl" -| _ -> failwith "unknown bcmpz instruction" diff --git a/mips/hgen/types_sail_trans_out.hgen b/mips/hgen/types_sail_trans_out.hgen deleted file mode 100644 index ebd31fcb..00000000 --- a/mips/hgen/types_sail_trans_out.hgen +++ /dev/null @@ -1,47 +0,0 @@ -let translate_out_big_bit = function - | (name, Bvector _, bits) -> IInt.integer_of_bit_list bits - | _ -> assert false - -let translate_out_int inst = (Nat_big_num.to_int (translate_out_big_bit inst)) -let translate_out_signed_int inst bits = - let i = (Nat_big_num.to_int (translate_out_big_bit inst)) in - if (i >= (1 lsl (bits - 1))) then - (i - (1 lsl bits)) else - i - -let translate_out_ireg ireg = IReg (int_to_ireg (translate_out_int ireg)) - -let translate_out_imm26 imm = translate_out_int imm - -let translate_out_imm16 imm = translate_out_int imm -let translate_out_simm16 imm = translate_out_signed_int imm 16 - -let translate_out_imm5 imm = translate_out_int imm - -let translate_out_bool = function - | (name, Bit, [Bitc_one]) -> true - | (name, Bit, [Bitc_zero]) -> false - | _ -> assert false - -let translate_out_enum (name,_,bits) = - Nat_big_num.to_int (IInt.integer_of_bit_list bits) - -let translate_out_wordWidth inst = - match translate_out_enum inst with - | 0 -> MIPSByte - | 1 -> MIPSHalf - | 2 -> MIPSWord - | 3 -> MIPSDouble - | _ -> failwith "Unknown wordWidth in sail translate out" - -let translate_out_cmp inst = - match translate_out_enum inst with - | 0 -> MIPS_EQ (* equal *) - | 1 -> MIPS_NE (* not equal *) - | 2 -> MIPS_GE (* signed greater than or equal *) - | 3 -> MIPS_GEU (* unsigned greater than or equal *) - | 4 -> MIPS_GT (* signed strictly greater than *) - | 5 -> MIPS_LE (* signed less than or equal *) - | 6 -> MIPS_LT (* signed strictly less than *) - | 7 -> MIPS_LTU (* unsigned less than or qual *) - | _ -> failwith "Unknown mipsCmp in sail translate out" diff --git a/mips/hgen/types_trans_sail.hgen b/mips/hgen/types_trans_sail.hgen deleted file mode 100644 index 63880ae9..00000000 --- a/mips/hgen/types_trans_sail.hgen +++ /dev/null @@ -1,44 +0,0 @@ -let translate_rtype_op op = uppercase (pp_rtype_op op) -let translate_itype_op op = uppercase (pp_itype_op op) -let translate_shifti_op op = uppercase (pp_shifti_op op) -let translate_shiftv_op op = uppercase (pp_shiftv_op op) -let translate_muldiv_op op = uppercase (pp_muldiv_op op) -let translate_mfhilo_op op = uppercase (pp_mfhilo_op op) -let translate_load_op width signed linked = uppercase (pp_load_op width signed linked) -let translate_store_op width conditional = uppercase (pp_store_op width conditional) -let translate_lslr_op store double left = uppercase (pp_lslr_op store double left) -let translate_beq_op ne likely = uppercase (pp_beq_op ne likely) -let translate_bcmpz_op cmp link likely = uppercase (pp_bcmpz_op cmp link likely) - -let translate_reg name value = - (name, Bvector (Some 5), bit_list_of_integer 5 (Nat_big_num.of_int (reg_to_int value))) -let translate_imm26 name value = - (name, Bvector (Some 26), bit_list_of_integer 26 (Nat_big_num.of_int value)) -let translate_imm16 name value = - (name, Bvector (Some 16), bit_list_of_integer 16 (Nat_big_num.of_int value)) -let translate_imm5 name value = - (name, Bvector (Some 5), bit_list_of_integer 5 (Nat_big_num.of_int value)) -let translate_bool name value = - (name, Bit, [if value then Bitc_one else Bitc_zero]) -let translate_enum enum_values name value = - let rec bit_count n = - if n = 0 then 0 - else 1 + (bit_count (n lsr 1)) in - let rec find_index element = function - | h::tail -> if h = element then 0 else 1 + (find_index element tail) - | _ -> failwith "translate_enum could not find value" - in - let size = bit_count (List.length enum_values) in - let index = find_index value enum_values in - (name, Range0 (Some size), IInt.bit_list_of_integer size (Nat_big_num.of_int index)) -let translate_wordsize = translate_enum [MIPSByte; MIPSHalf; MIPSWord; MIPSDouble] -let translate_cmp = translate_enum [ -MIPS_EQ ;(* equal *) -MIPS_NE ;(* not equal *) -MIPS_GE ;(* signed greater than or equal *) -MIPS_GEU ;(* unsigned greater than or equal *) -MIPS_GT ;(* signed strictly greater than *) -MIPS_LE ;(* signed less than or equal *) -MIPS_LT ;(* signed strictly less than *) -MIPS_LTU ;(* unsigned less than or qual *) -] \ No newline at end of file diff --git a/risc-v/gen/ast.hgen b/risc-v/gen/ast.hgen new file mode 100644 index 00000000..b1968173 --- /dev/null +++ b/risc-v/gen/ast.hgen @@ -0,0 +1,17 @@ +| `RISCVUTYPE of bit20 * reg * riscvUop +| `RISCVJAL of bit20 * reg +| `RISCVJALR of bit12 * reg * reg +| `RISCVBType of bit12 * reg * reg * riscvBop +| `RISCVIType of bit12 * reg * reg * riscvIop +| `RISCVShiftIop of bit6 * reg * reg * riscvSop +| `RISCVRType of reg * reg * reg * riscvRop +| `RISCVLoad of bit12 * reg * reg * bool * wordWidth * bool * bool +| `RISCVStore of bit12 * reg * reg * wordWidth * bool * bool +| `RISCVADDIW of bit12 * reg * reg +| `RISCVSHIFTW of bit5 * reg * reg * riscvSop +| `RISCVRTYPEW of reg * reg * reg * riscvRopw +| `RISCVFENCE of bit4 * bit4 +| `RISCVFENCEI +| `RISCVLoadRes of bool * bool * reg * wordWidth * reg +| `RISCVStoreCon of bool * bool * reg * reg * wordWidth * reg +| `RISCVAMO of riscvAmoop * bool * bool * reg * reg * wordWidth * reg diff --git a/risc-v/gen/fold.hgen b/risc-v/gen/fold.hgen new file mode 100644 index 00000000..4c51e114 --- /dev/null +++ b/risc-v/gen/fold.hgen @@ -0,0 +1,16 @@ +| `RISCVThreadStart -> (y_reg, y_sreg) +| `RISCVUTYPE (_, r0, _) -> fold_reg r0 (y_reg, y_sreg) +| `RISCVJAL (_, r0) -> fold_reg r0 (y_reg, y_sreg) +| `RISCVJALR (_, r0, r1) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) +| `RISCVBType (_, r0, r1, _) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) +| `RISCVIType (_, r0, r1, _) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) +| `RISCVShiftIop (_, r0, r1, _) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) +| `RISCVRType (r0, r1, r2, _) -> fold_reg r0 (fold_reg r1 (fold_reg r2 (y_reg, y_sreg))) +| `RISCVLoad (_, r0, r1, _, _, _, _) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) +| `RISCVStore (_, r0, r1, _, _, _) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) +| `RISCVADDIW (_, r0, r1) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) +| `RISCVSHIFTW (_, r0, r1, _) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) +| `RISCVRTYPEW (r0, r1, r2, _) -> fold_reg r0 (fold_reg r1 (fold_reg r2 (y_reg, y_sreg))) +| `RISCVLoadRes (_, _, rs1, _, rd) -> fold_reg rs1 (fold_reg rd (y_reg, y_sreg)) +| `RISCVStoreCon (_, _, rs2, rs1, _, rd) -> fold_reg rs2 (fold_reg rs1 (fold_reg rd (y_reg, y_sreg))) +| `RISCVAMO (_, _, _, rs2, rs1, _, rd) -> fold_reg rs2 (fold_reg rs1 (fold_reg rd (y_reg, y_sreg))) diff --git a/risc-v/gen/herdtools_ast_to_shallow_ast.hgen b/risc-v/gen/herdtools_ast_to_shallow_ast.hgen new file mode 100644 index 00000000..07c1d082 --- /dev/null +++ b/risc-v/gen/herdtools_ast_to_shallow_ast.hgen @@ -0,0 +1,86 @@ +| `RISCVStopFetching -> EBREAK +| `RISCVUTYPE(imm, rd, op) -> UTYPE( + translate_imm20 "imm" imm, + translate_reg "rd" rd, + translate_uop op) +| `RISCVJAL(imm, rd) -> RISCV_JAL( + translate_imm21 "imm" imm, + translate_reg "rd" rd) +| `RISCVJALR(imm, rs, rd) -> RISCV_JALR( + translate_imm12 "imm" imm, + translate_reg "rs" rd, + translate_reg "rd" rd) +| `RISCVBType(imm, rs2, rs1, op) -> BTYPE( + translate_imm13 "imm" imm, + translate_reg "rs2" rs2, + translate_reg "rs1" rs1, + translate_bop op) +| `RISCVIType(imm, rs1, rd, op) -> ITYPE( + translate_imm12 "imm" imm, + translate_reg "rs1" rs1, + translate_reg "rd" rd, + translate_iop op) +| `RISCVShiftIop(imm, rs, rd, op) -> SHIFTIOP( + translate_imm6 "imm" imm, + translate_reg "rs" rs, + translate_reg "rd" rd, + translate_sop op) +| `RISCVRType (rs2, rs1, rd, op) -> RTYPE ( + translate_reg "rs2" rs2, + translate_reg "rs1" rs1, + translate_reg "rd" rd, + translate_rop op) +| `RISCVLoad(imm, rs, rd, unsigned, width, aq, rl) -> LOAD( + translate_imm12 "imm" imm, + translate_reg "rs" rs, + translate_reg "rd" rd, + translate_bool "unsigned" unsigned, + translate_wordWidth width, + translate_bool "aq" aq, + translate_bool "rl" rl) +| `RISCVStore(imm, rs, rd, width, aq, rl) -> STORE ( + translate_imm12 "imm" imm, + translate_reg "rs" rs, + translate_reg "rd" rd, + translate_wordWidth width, + translate_bool "aq" aq, + translate_bool "rl" rl) +| `RISCVADDIW(imm, rs, rd) -> ADDIW( + translate_imm12 "imm" imm, + translate_reg "rs" rs, + translate_reg "rd" rd) +| `RISCVSHIFTW(imm, rs, rd, op) -> SHIFTW( + translate_imm5 "imm" imm, + translate_reg "rs" rs, + translate_reg "rd" rd, + translate_sop op) +| `RISCVRTYPEW(rs2, rs1, rd, op) -> RTYPEW( + translate_reg "rs2" rs2, + translate_reg "rs1" rs1, + translate_reg "rd" rd, + translate_ropw op) +| `RISCVFENCE(pred, succ) -> FENCE( + translate_imm4 "pred" pred, + translate_imm4 "succ" succ) +| `RISCVFENCEI -> FENCEI +| `RISCVLoadRes(aq, rl, rs1, width, rd) -> LOADRES( + translate_bool "aq" aq, + translate_bool "rl" rl, + translate_reg "rs1" rs1, + translate_wordWidth width, + translate_reg "rd" rd) +| `RISCVStoreCon(aq, rl, rs2, rs1, width, rd) -> STORECON( + translate_bool "aq" aq, + translate_bool "rl" rl, + translate_reg "rs2" rs2, + translate_reg "rs1" rs1, + translate_wordWidth width, + translate_reg "rd" rd) +| `RISCVAMO (op, aq, rl, rs2, rs1, width, rd) -> AMO( + translate_amoop op, + translate_bool "aq" aq, + translate_bool "rl" rl, + translate_reg "rs2" rs2, + translate_reg "rs1" rs1, + translate_wordWidth width, + translate_reg "rd" rd) diff --git a/risc-v/gen/herdtools_types_to_shallow_types.hgen b/risc-v/gen/herdtools_types_to_shallow_types.hgen new file mode 100644 index 00000000..e6edd24d --- /dev/null +++ b/risc-v/gen/herdtools_types_to_shallow_types.hgen @@ -0,0 +1,90 @@ +let is_inc = false + +let translate_reg name value = + Sail_values.to_vec0 is_inc (Nat_big_num.of_int 5,Nat_big_num.of_int (reg_to_int value)) + +let translate_uop op = match op with + | RISCVLUI -> RISCV_LUI + | RISCVAUIPC -> RISCV_AUIPC + +let translate_bop op = match op with + | RISCVBEQ -> RISCV_BEQ + | RISCVBNE -> RISCV_BNE + | RISCVBLT -> RISCV_BLT + | RISCVBGE -> RISCV_BGE + | RISCVBLTU -> RISCV_BLTU + | RISCVBGEU -> RISCV_BGEU + +let translate_iop op = match op with + | RISCVADDI -> RISCV_ADDI + | RISCVSLTI -> RISCV_SLTI + | RISCVSLTIU -> RISCV_SLTIU + | RISCVXORI -> RISCV_XORI + | RISCVORI -> RISCV_ORI + | RISCVANDI -> RISCV_ANDI + +let translate_sop op = match op with + | RISCVSLLI -> RISCV_SLLI + | RISCVSRLI -> RISCV_SRLI + | RISCVSRAI -> RISCV_SRAI + +let translate_rop op = match op with + | RISCVADD -> RISCV_ADD + | RISCVSUB -> RISCV_SUB + | RISCVSLL -> RISCV_SLL + | RISCVSLT -> RISCV_SLT + | RISCVSLTU -> RISCV_SLTU + | RISCVXOR -> RISCV_XOR + | RISCVSRL -> RISCV_SRL + | RISCVSRA -> RISCV_SRA + | RISCVOR -> RISCV_OR + | RISCVAND -> RISCV_AND + +let translate_ropw op = match op with + | RISCVADDW -> RISCV_ADDW + | RISCVSUBW -> RISCV_SUBW + | RISCVSLLW -> RISCV_SLLW + | RISCVSRLW -> RISCV_SRLW + | RISCVSRAW -> RISCV_SRAW + +let translate_amoop op = match op with + | RISCVAMOSWAP -> AMOSWAP + | RISCVAMOADD -> AMOADD + | RISCVAMOXOR -> AMOXOR + | RISCVAMOAND -> AMOAND + | RISCVAMOOR -> AMOOR + | RISCVAMOMIN -> AMOMIN + | RISCVAMOMAX -> AMOMAX + | RISCVAMOMINU -> AMOMINU + | RISCVAMOMAXU -> AMOMAXU + +let translate_wordWidth op = match op with + | RISCVBYTE -> BYTE + | RISCVHALF -> HALF + | RISCVWORD -> WORD + | RISCVDOUBLE -> DOUBLE + +let translate_bool name = function + | true -> Sail_values.B1 + | false -> Sail_values.B0 + +let translate_imm21 name value = + Sail_values.to_vec0 is_inc (Nat_big_num.of_int 21,Nat_big_num.of_int value) + +let translate_imm20 name value = + Sail_values.to_vec0 is_inc (Nat_big_num.of_int 20,Nat_big_num.of_int value) + +let translate_imm13 name value = + Sail_values.to_vec0 is_inc (Nat_big_num.of_int 13,Nat_big_num.of_int value) + +let translate_imm12 name value = + Sail_values.to_vec0 is_inc (Nat_big_num.of_int 12,Nat_big_num.of_int value) + +let translate_imm6 name value = + Sail_values.to_vec0 is_inc (Nat_big_num.of_int 6,Nat_big_num.of_int value) + +let translate_imm5 name value = + Sail_values.to_vec0 is_inc (Nat_big_num.of_int 5,Nat_big_num.of_int value) + +let translate_imm4 name value = + Sail_values.to_vec0 is_inc (Nat_big_num.of_int 4,Nat_big_num.of_int value) diff --git a/risc-v/gen/lexer.hgen b/risc-v/gen/lexer.hgen new file mode 100644 index 00000000..e42b8a62 --- /dev/null +++ b/risc-v/gen/lexer.hgen @@ -0,0 +1,190 @@ +"lui" , UTYPE { op=RISCVLUI }; +"auipc" , UTYPE { op=RISCVAUIPC }; + +"jal", JAL (); +"jalr", JALR (); + +"beq", BTYPE {op=RISCVBEQ}; +"bne", BTYPE {op=RISCVBNE}; +"blt", BTYPE {op=RISCVBLT}; +"bge", BTYPE {op=RISCVBGE}; +"bltu", BTYPE {op=RISCVBLTU}; +"bgeu", BTYPE {op=RISCVBGEU}; + +"addi", ITYPE {op=RISCVADDI}; +"stli", ITYPE {op=RISCVSLTI}; +"sltiu", ITYPE {op=RISCVSLTIU}; +"xori", ITYPE {op=RISCVXORI}; +"ori", ITYPE {op=RISCVORI}; +"andi", ITYPE {op=RISCVANDI}; + +"slli", SHIFTIOP{op=RISCVSLLI}; +"srli", SHIFTIOP{op=RISCVSRLI}; +"srai", SHIFTIOP{op=RISCVSRAI}; + +"add", RTYPE{op=RISCVADD}; +"sub", RTYPE{op=RISCVSUB}; +"sll", RTYPE{op=RISCVSLL}; +"slt", RTYPE{op=RISCVSLT}; +"sltu", RTYPE{op=RISCVSLT}; +"xor", RTYPE{op=RISCVXOR}; +"srl", RTYPE{op=RISCVSRL}; +"sra", RTYPE{op=RISCVSRA}; +"or", RTYPE{op=RISCVOR}; +"and", RTYPE{op=RISCVAND}; + +"lb", LOAD{unsigned=false; width=RISCVBYTE; aq=false; rl=false}; +"lbu", LOAD{unsigned=true; width=RISCVBYTE; aq=false; rl=false}; +"lh", LOAD{unsigned=false; width=RISCVHALF; aq=false; rl=false}; +"lhu", LOAD{unsigned=true; width=RISCVHALF; aq=false; rl=false}; +"lw", LOAD{unsigned=false; width=RISCVWORD; aq=false; rl=false}; +"lwu", LOAD{unsigned=true; width=RISCVWORD; aq=false; rl=false}; +"ld", LOAD{unsigned=false; width=RISCVDOUBLE; aq=false; rl=false}; + +"lb.aq", LOAD{unsigned=false; width=RISCVBYTE; aq=true; rl=false}; +"lbu.aq", LOAD{unsigned=true; width=RISCVBYTE; aq=true; rl=false}; +"lh.aq", LOAD{unsigned=false; width=RISCVHALF; aq=true; rl=false}; +"lhu.aq", LOAD{unsigned=true; width=RISCVHALF; aq=true; rl=false}; +"lw.aq", LOAD{unsigned=false; width=RISCVWORD; aq=true; rl=false}; +"lwu.aq", LOAD{unsigned=true; width=RISCVWORD; aq=true; rl=false}; +"ld.aq", LOAD{unsigned=false; width=RISCVDOUBLE; aq=true; rl=false}; + +"lb.aq.rl", LOAD{unsigned=false; width=RISCVBYTE; aq=true; rl=true}; +"lbu.aq.rl", LOAD{unsigned=true; width=RISCVBYTE; aq=true; rl=true}; +"lh.aq.rl", LOAD{unsigned=false; width=RISCVHALF; aq=true; rl=true}; +"lhu.aq.rl", LOAD{unsigned=true; width=RISCVHALF; aq=true; rl=true}; +"lw.aq.rl", LOAD{unsigned=false; width=RISCVWORD; aq=true; rl=true}; +"lwu.aq.rl", LOAD{unsigned=true; width=RISCVWORD; aq=true; rl=true}; +"ld.aq.rl", LOAD{unsigned=false; width=RISCVDOUBLE; aq=true; rl=true}; + +"sb", STORE{width=RISCVBYTE; aq=false; rl=false}; +"sh", STORE{width=RISCVHALF; aq=false; rl=false}; +"sw", STORE{width=RISCVWORD; aq=false; rl=false}; +"sd", STORE{width=RISCVDOUBLE; aq=false; rl=false}; + +"sb.rl", STORE{width=RISCVBYTE; aq=false; rl=true}; +"sh.rl", STORE{width=RISCVHALF; aq=false; rl=true}; +"sw.rl", STORE{width=RISCVWORD; aq=false; rl=true}; +"sd.rl", STORE{width=RISCVDOUBLE; aq=false; rl=true}; + +"sb.aq.rl", STORE{width=RISCVBYTE; aq=true; rl=true}; +"sh.aq.rl", STORE{width=RISCVHALF; aq=true; rl=true}; +"sw.aq.rl", STORE{width=RISCVWORD; aq=true; rl=true}; +"sd.aq.rl", STORE{width=RISCVDOUBLE; aq=true; rl=true}; + +"addiw", ADDIW (); + +"slliw", SHIFTW{op=RISCVSLLI}; +"srliw", SHIFTW{op=RISCVSRLI}; +"sraiw", SHIFTW{op=RISCVSRAI}; + +"addw", RTYPEW{op=RISCVADDW}; +"subw", RTYPEW{op=RISCVSUBW}; +"sslw", RTYPEW{op=RISCVSLLW}; +"srlw", RTYPEW{op=RISCVSRLW}; +"sraw", RTYPEW{op=RISCVSRAW}; + +"fence", FENCE (); +"r", FENCEOPTION Fence_R; +"w", FENCEOPTION Fence_W; +"rw", FENCEOPTION Fence_RW; + +"fence.i", FENCEI (); + +"lr.w", LOADRES {width=RISCVWORD; aq=false; rl=false}; +"lr.w.aq", LOADRES {width=RISCVWORD; aq=true; rl=false}; +"lr.w.aq.rl", LOADRES {width=RISCVWORD; aq=true; rl=true}; +"lr.d", LOADRES {width=RISCVDOUBLE; aq=false; rl=false}; +"lr.d.aq", LOADRES {width=RISCVDOUBLE; aq=true; rl=false}; +"lr.d.aq.rl", LOADRES {width=RISCVDOUBLE; aq=true; rl=true}; + +"sc.w", STORECON {width=RISCVWORD; aq=false; rl=false}; +"sc.w.rl", STORECON {width=RISCVWORD; aq=false; rl=true}; +"sc.w.aq.rl", STORECON {width=RISCVWORD; aq=true; rl=true}; +"sc.d", STORECON {width=RISCVDOUBLE; aq=false; rl=false}; +"sc.d.rl", STORECON {width=RISCVDOUBLE; aq=false; rl=true}; +"sc.d.aq.rl", STORECON {width=RISCVDOUBLE; aq=true; rl=true}; + +"amoswap.w", AMO {width=RISCVWORD; aq=false; rl=false; op=RISCVAMOSWAP}; +"amoadd.w", AMO {width=RISCVWORD; aq=false; rl=false; op=RISCVAMOADD}; +"amoand.w", AMO {width=RISCVWORD; aq=false; rl=false; op=RISCVAMOAND}; +"amoor.w", AMO {width=RISCVWORD; aq=false; rl=false; op=RISCVAMOOR}; +"amoxor.w", AMO {width=RISCVWORD; aq=false; rl=false; op=RISCVAMOXOR}; +"amomax.w", AMO {width=RISCVWORD; aq=false; rl=false; op=RISCVAMOMAX}; +"amomin.w", AMO {width=RISCVWORD; aq=false; rl=false; op=RISCVAMOMIN}; +"amomaxu.w", AMO {width=RISCVWORD; aq=false; rl=false; op=RISCVAMOMAXU}; +"amominu.w", AMO {width=RISCVWORD; aq=false; rl=false; op=RISCVAMOMINU}; + +"amoswap.d", AMO {width=RISCVDOUBLE; aq=false; rl=false; op=RISCVAMOSWAP}; +"amoadd.d", AMO {width=RISCVDOUBLE; aq=false; rl=false; op=RISCVAMOADD}; +"amoand.d", AMO {width=RISCVDOUBLE; aq=false; rl=false; op=RISCVAMOAND}; +"amoor.d", AMO {width=RISCVDOUBLE; aq=false; rl=false; op=RISCVAMOOR}; +"amoxor.d", AMO {width=RISCVDOUBLE; aq=false; rl=false; op=RISCVAMOXOR}; +"amomax.d", AMO {width=RISCVDOUBLE; aq=false; rl=false; op=RISCVAMOMAX}; +"amomin.d", AMO {width=RISCVDOUBLE; aq=false; rl=false; op=RISCVAMOMIN}; +"amomaxu.d", AMO {width=RISCVDOUBLE; aq=false; rl=false; op=RISCVAMOMAXU}; +"amominu.d", AMO {width=RISCVDOUBLE; aq=false; rl=false; op=RISCVAMOMINU}; + +"amoswap.w.aq", AMO {width=RISCVWORD; aq=true; rl=false; op=RISCVAMOSWAP}; +"amoadd.w.aq", AMO {width=RISCVWORD; aq=true; rl=false; op=RISCVAMOADD}; +"amoand.w.aq", AMO {width=RISCVWORD; aq=true; rl=false; op=RISCVAMOAND}; +"amoor.w.aq", AMO {width=RISCVWORD; aq=true; rl=false; op=RISCVAMOOR}; +"amoxor.w.aq", AMO {width=RISCVWORD; aq=true; rl=false; op=RISCVAMOXOR}; +"amomax.w.aq", AMO {width=RISCVWORD; aq=true; rl=false; op=RISCVAMOMAX}; +"amomin.w.aq", AMO {width=RISCVWORD; aq=true; rl=false; op=RISCVAMOMIN}; +"amomaxu.w.aq", AMO {width=RISCVWORD; aq=true; rl=false; op=RISCVAMOMAXU}; +"amominu.w.aq", AMO {width=RISCVWORD; aq=true; rl=false; op=RISCVAMOMINU}; + +"amoswap.d.aq", AMO {width=RISCVDOUBLE; aq=true; rl=false; op=RISCVAMOSWAP}; +"amoadd.d.aq", AMO {width=RISCVDOUBLE; aq=true; rl=false; op=RISCVAMOADD}; +"amoand.d.aq", AMO {width=RISCVDOUBLE; aq=true; rl=false; op=RISCVAMOAND}; +"amoor.d.aq", AMO {width=RISCVDOUBLE; aq=true; rl=false; op=RISCVAMOOR}; +"amoxor.d.aq", AMO {width=RISCVDOUBLE; aq=true; rl=false; op=RISCVAMOXOR}; +"amomax.d.aq", AMO {width=RISCVDOUBLE; aq=true; rl=false; op=RISCVAMOMAX}; +"amomin.d.aq", AMO {width=RISCVDOUBLE; aq=true; rl=false; op=RISCVAMOMIN}; +"amomaxu.d.aq", AMO {width=RISCVDOUBLE; aq=true; rl=false; op=RISCVAMOMAXU}; +"amominu.d.aq", AMO {width=RISCVDOUBLE; aq=true; rl=false; op=RISCVAMOMINU}; + +"amoswap.w.rl", AMO {width=RISCVWORD; aq=false; rl=true; op=RISCVAMOSWAP}; +"amoadd.w.rl", AMO {width=RISCVWORD; aq=false; rl=true; op=RISCVAMOADD}; +"amoand.w.rl", AMO {width=RISCVWORD; aq=false; rl=true; op=RISCVAMOAND}; +"amoor.w.rl", AMO {width=RISCVWORD; aq=false; rl=true; op=RISCVAMOOR}; +"amoxor.w.rl", AMO {width=RISCVWORD; aq=false; rl=true; op=RISCVAMOXOR}; +"amomax.w.rl", AMO {width=RISCVWORD; aq=false; rl=true; op=RISCVAMOMAX}; +"amomin.w.rl", AMO {width=RISCVWORD; aq=false; rl=true; op=RISCVAMOMIN}; +"amomaxu.w.rl", AMO {width=RISCVWORD; aq=false; rl=true; op=RISCVAMOMAXU}; +"amominu.w.rl", AMO {width=RISCVWORD; aq=false; rl=true; op=RISCVAMOMINU}; + +"amoswap.d.rl", AMO {width=RISCVDOUBLE; aq=false; rl=true; op=RISCVAMOSWAP}; +"amoadd.d.rl", AMO {width=RISCVDOUBLE; aq=false; rl=true; op=RISCVAMOADD}; +"amoand.d.rl", AMO {width=RISCVDOUBLE; aq=false; rl=true; op=RISCVAMOAND}; +"amoor.d.rl", AMO {width=RISCVDOUBLE; aq=false; rl=true; op=RISCVAMOOR}; +"amoxor.d.rl", AMO {width=RISCVDOUBLE; aq=false; rl=true; op=RISCVAMOXOR}; +"amomax.d.rl", AMO {width=RISCVDOUBLE; aq=false; rl=true; op=RISCVAMOMAX}; +"amomin.d.rl", AMO {width=RISCVDOUBLE; aq=false; rl=true; op=RISCVAMOMIN}; +"amomaxu.d.rl", AMO {width=RISCVDOUBLE; aq=false; rl=true; op=RISCVAMOMAXU}; +"amominu.d.rl", AMO {width=RISCVDOUBLE; aq=false; rl=true; op=RISCVAMOMINU}; + +"amoswap.w.aq.rl", AMO {width=RISCVWORD; aq=true; rl=true; op=RISCVAMOSWAP}; +"amoadd.w.aq.rl", AMO {width=RISCVWORD; aq=true; rl=true; op=RISCVAMOADD}; +"amoand.w.aq.rl", AMO {width=RISCVWORD; aq=true; rl=true; op=RISCVAMOAND}; +"amoor.w.aq.rl", AMO {width=RISCVWORD; aq=true; rl=true; op=RISCVAMOOR}; +"amoxor.w.aq.rl", AMO {width=RISCVWORD; aq=true; rl=true; op=RISCVAMOXOR}; +"amomax.w.aq.rl", AMO {width=RISCVWORD; aq=true; rl=true; op=RISCVAMOMAX}; +"amomin.w.aq.rl", AMO {width=RISCVWORD; aq=true; rl=true; op=RISCVAMOMIN}; +"amomaxu.w.aq.rl", AMO {width=RISCVWORD; aq=true; rl=true; op=RISCVAMOMAXU}; +"amominu.w.aq.rl", AMO {width=RISCVWORD; aq=true; rl=true; op=RISCVAMOMINU}; + +"amoswap.d.aq.rl", AMO {width=RISCVDOUBLE; aq=true; rl=true; op=RISCVAMOSWAP}; +"amoadd.d.aq.rl", AMO {width=RISCVDOUBLE; aq=true; rl=true; op=RISCVAMOADD}; +"amoand.d.aq.rl", AMO {width=RISCVDOUBLE; aq=true; rl=true; op=RISCVAMOAND}; +"amoor.d.aq.rl", AMO {width=RISCVDOUBLE; aq=true; rl=true; op=RISCVAMOOR}; +"amoxor.d.aq.rl", AMO {width=RISCVDOUBLE; aq=true; rl=true; op=RISCVAMOXOR}; +"amomax.d.aq.rl", AMO {width=RISCVDOUBLE; aq=true; rl=true; op=RISCVAMOMAX}; +"amomin.d.aq.rl", AMO {width=RISCVDOUBLE; aq=true; rl=true; op=RISCVAMOMIN}; +"amomaxu.d.aq.rl", AMO {width=RISCVDOUBLE; aq=true; rl=true; op=RISCVAMOMAXU}; +"amominu.d.aq.rl", AMO {width=RISCVDOUBLE; aq=true; rl=true; op=RISCVAMOMINU}; + +(** pseudo instructions *********************************************) + +"li", LI () diff --git a/risc-v/gen/map.hgen b/risc-v/gen/map.hgen new file mode 100644 index 00000000..bab5ced8 --- /dev/null +++ b/risc-v/gen/map.hgen @@ -0,0 +1,15 @@ +| `RISCVUTYPE (x, r0, y) -> `RISCVUTYPE (x, map_reg r0, y) +| `RISCVJAL (x, r0) -> `RISCVJAL (x, map_reg r0) +| `RISCVJALR (x, r0, r1) -> `RISCVJALR (x, map_reg r0, map_reg r1) +| `RISCVBType (x, r0, r1, y) -> `RISCVBType (x, map_reg r0, map_reg r1, y) +| `RISCVIType (x, r0, r1, y) -> `RISCVIType (x, map_reg r0, map_reg r1, y) +| `RISCVShiftIop (x, r0, r1, y) -> `RISCVShiftIop (x, map_reg r0, map_reg r1, y) +| `RISCVRType (r0, r1, r2, y) -> `RISCVRType (r0, map_reg r1, map_reg r2, y) +| `RISCVLoad (x, r0, r1, y, z, a, b) -> `RISCVLoad (x, map_reg r0, map_reg r1, y, z, a, b) +| `RISCVStore (x, r0, r1, y, z, a) -> `RISCVStore (x, map_reg r0, map_reg r1, y, z, a) +| `RISCVADDIW (x, r0, r1) -> `RISCVADDIW (x, map_reg r0, map_reg r1) +| `RISCVSHIFTW (x, r0, r1, y) -> `RISCVSHIFTW (x, map_reg r0, map_reg r1, y) +| `RISCVRTYPEW (r0, r1, r2, x) -> `RISCVRTYPEW (r0, map_reg r1, map_reg r2, x) +| `RISCVLoadRes (aq, rl, rs1, w, rd) -> `RISCVLoadRes (aq, rl, map_reg rs1, w, map_reg rd) +| `RISCVStoreCon (aq, rl, rs2, rs1, w, rd) -> `RISCVStoreCon (aq, rl, map_reg rs2, map_reg rs1, w, map_reg rd) +| `RISCVAMO (op, aq, rl, rs2, rs1, w, rd) -> `RISCVAMO (op, aq, rl, map_reg rs2, map_reg rs1, w, map_reg rd) diff --git a/risc-v/gen/parser.hgen b/risc-v/gen/parser.hgen new file mode 100644 index 00000000..210e38fb --- /dev/null +++ b/risc-v/gen/parser.hgen @@ -0,0 +1,74 @@ +| UTYPE reg COMMA NUM + { (* it's not clear if NUM here should be before or after filling the + lowest 12 bits with zeros, or if it should be signed or unsigned; + currently assuming: NUM does not include the 12 zeros, and is unsigned *) + if not (iskbituimm 20 $4) then failwith "immediate is not 20bit" + else `RISCVUTYPE ($4, $2, $1.op) } +| JAL reg COMMA NUM + { if not ($4 mod 2 = 0) then failwith "odd offset" + else if not (iskbitsimm 21 $4) then failwith "offset is not 21bit" + else `RISCVJAL ($4, $2) } +| JALR reg COMMA reg COMMA NUM + { if not (iskbitsimm 12 $6) then failwith "offset is not 12bit" + else `RISCVJALR ($6, $4, $2) } +| BTYPE reg COMMA reg COMMA NUM + { if not ($6 mod 2 = 0) then failwith "odd offset" + else if not (iskbitsimm 13 $6) then failwith "offset is not 13bit" + else `RISCVBType ($6, $4, $2, $1.op) } +| ITYPE reg COMMA reg COMMA NUM + { if $1.op <> RISCVSLTIU && not (iskbitsimm 12 $6) then failwith "immediate is not 12bit" + else if $1.op = RISCVSLTIU && not (iskbituimm 12 $6) then failwith "unsigned immediate is not 12bit" + else `RISCVIType ($6, $4, $2, $1.op) } +| ADDIW reg COMMA reg COMMA NUM + { if not (iskbitsimm 12 $6) then failwith "immediate is not 12bit" + else `RISCVADDIW ($6, $4, $2) } +| SHIFTIOP reg COMMA reg COMMA NUM + { if not (iskbituimm 6 $6) then failwith "unsigned immediate is not 6bit" + else `RISCVShiftIop ($6, $4, $2, $1.op) } +| SHIFTW reg COMMA reg COMMA NUM + { if not (iskbituimm 5 $6) then failwith "unsigned immediate is not 5bit" + else `RISCVSHIFTW ($6, $4, $2, $1.op) } +| RTYPE reg COMMA reg COMMA reg + { `RISCVRType ($6, $4, $2, $1.op) } +| LOAD reg COMMA NUM LPAR reg RPAR + { if not (iskbitsimm 12 $4) then failwith "offset is not 12bit" + else `RISCVLoad ($4, $6, $2, $1.unsigned, $1.width, $1.aq, $1.rl) } +| STORE reg COMMA NUM LPAR reg RPAR + { if not (iskbitsimm 12 $4) then failwith "offset is not 12bit" + else `RISCVStore ($4, $2, $6, $1.width, $1.aq, $1.rl) } +| RTYPEW reg COMMA reg COMMA reg + { `RISCVRTYPEW ($6, $4, $2, $1.op) } +| FENCE FENCEOPTION COMMA FENCEOPTION + { match ($2, $4) with + | (Fence_RW, Fence_RW) -> `RISCVFENCE (0b0011, 0b0011) + | (Fence_R, Fence_RW) -> `RISCVFENCE (0b0010, 0b0011) + | (Fence_R, Fence_R) -> `RISCVFENCE (0b0010, 0b0010) + | (Fence_RW, Fence_W) -> `RISCVFENCE (0b0011, 0b0001) + | (Fence_W, Fence_W) -> `RISCVFENCE (0b0001, 0b0001) + | (Fence_RW, Fence_R) -> failwith "'fence rw,r' is not supported" + | (Fence_R, Fence_W) -> failwith "'fence r,w' is not supported" + | (Fence_W, Fence_RW) -> failwith "'fence w,rw' is not supported" + | (Fence_W, Fence_R) -> failwith "'fence w,r' is not supported" + } +| FENCEI + { `RISCVFENCEI } +| LOADRES reg COMMA LPAR reg RPAR + { `RISCVLoadRes ($1.aq, $1.rl, $5, $1.width, $2) } +| LOADRES reg COMMA NUM LPAR reg RPAR + { if $4 <> 0 then failwith "'lr' offset must be 0" else + `RISCVLoadRes ($1.aq, $1.rl, $6, $1.width, $2) } +| STORECON reg COMMA reg COMMA LPAR reg RPAR + { `RISCVStoreCon ($1.aq, $1.rl, $4, $7, $1.width, $2) } +| STORECON reg COMMA reg COMMA NUM LPAR reg RPAR + { if $6 <> 0 then failwith "'sc' offset must be 0" else + `RISCVStoreCon ($1.aq, $1.rl, $4, $8, $1.width, $2) } +| AMO reg COMMA reg COMMA LPAR reg RPAR + { `RISCVAMO ($1.op, $1.aq, $1.rl, $4, $7, $1.width, $2) } +| AMO reg COMMA reg COMMA NUM LPAR reg RPAR + { if $6 <> 0 then failwith "'amo' offset must be 0" else + `RISCVAMO ($1.op, $1.aq, $1.rl, $4, $8, $1.width, $2) } + +/* pseudo-ops */ +| LI reg COMMA NUM + { if not (iskbitsimm 12 $4) then failwith "immediate is not 12bit (li is currently implemented only with small immediate)" + else `RISCVIType ($4, IReg R0, $2, RISCVORI) } diff --git a/risc-v/gen/pretty.hgen b/risc-v/gen/pretty.hgen new file mode 100644 index 00000000..fc1c0000 --- /dev/null +++ b/risc-v/gen/pretty.hgen @@ -0,0 +1,30 @@ +| `RISCVThreadStart -> "start" +| `RISCVStopFetching -> "stop" +| `RISCVUTYPE(imm, rd, op) -> sprintf "%s %s, %d" (pp_riscv_uop op) (pp_reg rd) imm +| `RISCVJAL(imm, rd) -> sprintf "jal %s, %d" (pp_reg rd) imm +| `RISCVJALR(imm, rs, rd) -> sprintf "jalr %s, %s, %d" (pp_reg rd) (pp_reg rs) imm +| `RISCVBType(imm, rs2, rs1, op) -> sprintf "%s %s, %s, %d" (pp_riscv_bop op) (pp_reg rs1) (pp_reg rs2) imm +| `RISCVIType(imm, rs2, rs1, op) -> sprintf "%s %s, %s, %d" (pp_riscv_iop op) (pp_reg rs1) (pp_reg rs2) imm +| `RISCVShiftIop(imm, rs, rd, op) -> sprintf "%s %s, %s, %d" (pp_riscv_sop op) (pp_reg rd) (pp_reg rs) imm +| `RISCVRType (rs2, rs1, rd, op) -> sprintf "%s %s, %s, %s" (pp_riscv_rop op) (pp_reg rd) (pp_reg rs1) (pp_reg rs2) + +| `RISCVLoad(imm, rs, rd, unsigned, width, aq, rl) -> + sprintf "%s %s, %d(%s)" (pp_riscv_load_op (unsigned, width, aq, rl)) (pp_reg rd) imm (pp_reg rs) + +| `RISCVStore(imm, rs2, rs1, width, aq, rl) -> + sprintf "%s %s, %d(%s)" (pp_riscv_store_op (width, aq, rl)) (pp_reg rs2) imm (pp_reg rs1) + +| `RISCVADDIW(imm, rs, rd) -> sprintf "addiw %s, %s, %d" (pp_reg rd) (pp_reg rs) imm +| `RISCVSHIFTW(imm, rs, rd, op) -> sprintf "%s %s, %s, %d" (pp_riscv_sop op) (pp_reg rd) (pp_reg rs) imm +| `RISCVRTYPEW(rs2, rs1, rd, op) -> sprintf "%s %s, %s, %s" (pp_riscv_ropw op) (pp_reg rd) (pp_reg rs1) (pp_reg rs2) +| `RISCVFENCE(pred, succ) -> sprintf "fence %s, %s" (pp_riscv_fence_option pred) (pp_riscv_fence_option succ) +| `RISCVFENCEI -> sprintf "fence.i" + +| `RISCVLoadRes(aq, rl, rs1, width, rd) -> + sprintf "%s %s, (%s)" (pp_riscv_load_reserved_op (aq, rl, width)) (pp_reg rd) (pp_reg rs1) + +| `RISCVStoreCon(aq, rl, rs2, rs1, width, rd) -> + sprintf "%s %s, %s, (%s)" (pp_riscv_store_conditional_op (aq, rl, width)) (pp_reg rd) (pp_reg rs2) (pp_reg rs1) + +| `RISCVAMO(op, aq, rl, rs2, rs1, width, rd) -> + sprintf "%s %s, %s, (%s)" (pp_riscv_amo_op (op, aq, rl, width)) (pp_reg rd) (pp_reg rs2) (pp_reg rs1) diff --git a/risc-v/gen/pretty_xml.hgen b/risc-v/gen/pretty_xml.hgen new file mode 100644 index 00000000..b0306161 --- /dev/null +++ b/risc-v/gen/pretty_xml.hgen @@ -0,0 +1,137 @@ +| `RISCVThreadStart -> ("op_thread_start", []) + +| `RISCVStopFetching -> ("op_stop_fetching", []) + +| `RISCVUTYPE(imm, rd, op) -> + ("op_U_type", + [ ("op", pp_riscv_uop op); + ("uimm", sprintf "%d" imm); + ("dest", pp_reg rd); + ]) + +| `RISCVJAL(imm, rd) -> + ("op_jal", + [ ("offset", sprintf "%d" imm); + ("dest", pp_reg rd); + ]) + +| `RISCVJALR(imm, rs1, rd) -> + ("op_jalr", + [ ("offset", sprintf "%d" imm); + ("base", pp_reg rs1); + ("dest", pp_reg rd); + ]) + +| `RISCVBType(imm, rs2, rs1, op) -> + ("op_branch", + [ ("op", pp_riscv_bop op); + ("offset", sprintf "%d" imm); + ("src2", pp_reg rs2); + ("src1", pp_reg rs1); + ]) + +| `RISCVIType(imm, rs1, rd, op) -> + ("op_I_type", + [ ("op", pp_riscv_iop op); + ("iimm", sprintf "%d" imm); + ("src", pp_reg rs1); + ("dest", pp_reg rd); + ]) + +| `RISCVShiftIop(imm, rs1, rd, op) -> + ("op_IS_type", + [ ("op", pp_riscv_sop op); + ("shamt", sprintf "%d" imm); + ("src", pp_reg rs1); + ("dest", pp_reg rd); + ]) + +| `RISCVSHIFTW(imm, rs1, rd, op) -> + ("op_ISW_type", + [ ("op", pp_riscv_sop op); + ("shamt", sprintf "%d" imm); + ("src", pp_reg rs1); + ("dest", pp_reg rd); + ]) + +| `RISCVRType (rs2, rs1, rd, op) -> + ("op_R_type", + [ ("op", pp_riscv_rop op); + ("src2", pp_reg rs2); + ("src1", pp_reg rs1); + ("dest", pp_reg rd); + ]) + +| `RISCVLoad(imm, rs1, rd, unsigned, width, aq, rl) -> + ("op_load", + [ ("aq", if aq then "true" else "false"); + ("rl", if rl then "true" else "false"); + ("width", pp_word_width width); + ("unsigned", if unsigned then "true" else "false"); + ("base", pp_reg rs1); + ("offset", sprintf "%d" imm); + ("dest", pp_reg rd); + ]) + +| `RISCVStore(imm, rs2, rs1, width, aq, rl) -> + ("op_store", + [ ("aq", if aq then "true" else "false"); + ("rl", if rl then "true" else "false"); + ("width", pp_word_width width); + ("src", pp_reg rs2); + ("base", pp_reg rs1); + ("offset", sprintf "%d" imm); + ]) + +| `RISCVADDIW(imm, rs1, rd) -> + ("op_addiw", + [ ("iimm", sprintf "%d" imm); + ("src", pp_reg rs1); + ("dest", pp_reg rd); + ]) + +| `RISCVRTYPEW(rs2, rs1, rd, op) -> + ("op_RW_type", + [ ("op", pp_riscv_ropw op); + ("src2", pp_reg rs2); + ("src1", pp_reg rs1); + ("dest", pp_reg rd); + ]) + +| `RISCVFENCE(pred, succ) -> + ("op_fence", + [ ("pred", pp_riscv_fence_option pred); + ("succ", pp_riscv_fence_option succ); + ]) + +| `RISCVFENCEI -> ("op_fence_i", []) + +| `RISCVLoadRes(aq, rl, rs1, width, rd) -> + ("op_lr", + [ ("aq", if aq then "true" else "false"); + ("rl", if rl then "true" else "false"); + ("width", pp_word_width width); + ("addr", pp_reg rs1); + ("dest", pp_reg rd); + ]) + +| `RISCVStoreCon(aq, rl, rs2, rs1, width, rd) -> + ("op_sc", + [ ("aq", if aq then "true" else "false"); + ("rl", if rl then "true" else "false"); + ("width", pp_word_width width); + ("addr", pp_reg rs1); + ("src", pp_reg rs2); + ("dest", pp_reg rd); + ]) + +| `RISCVAMO(op, aq, rl, rs2, rs1, width, rd) -> + ("op_amo", + [ ("op", pp_riscv_amo_op_part op); + ("aq", if aq then "true" else "false"); + ("rl", if rl then "true" else "false"); + ("width", pp_word_width width); + ("src", pp_reg rs2); + ("addr", pp_reg rs1); + ("dest", pp_reg rd); + ]) diff --git a/risc-v/gen/sail_trans_out.hgen b/risc-v/gen/sail_trans_out.hgen new file mode 100644 index 00000000..2f9a80f1 --- /dev/null +++ b/risc-v/gen/sail_trans_out.hgen @@ -0,0 +1,23 @@ +| ("EBREAK", []) -> `RISCVStopFetching +| ("UTYPE", [imm; rd; op]) -> `RISCVUTYPE(translate_out_simm20 imm, translate_out_ireg rd, translate_out_uop op) +| ("JAL", [imm; rd]) -> `RISCVJAL(translate_out_simm21 imm, translate_out_ireg rd) +| ("JALR", [imm; rs; rd]) -> `RISCVJALR(translate_out_simm12 imm, translate_out_ireg rs, translate_out_ireg rd) +| ("BTYPE", [imm; rs2; rs1; op]) -> `RISCVBType(translate_out_simm13 imm, translate_out_ireg rs2, translate_out_ireg rs1, translate_out_bop op) +| ("ITYPE", [imm; rs1; rd; op]) -> `RISCVIType(translate_out_simm12 imm, translate_out_ireg rs1, translate_out_ireg rd, translate_out_iop op) +| ("SHIFTIOP", [imm; rs; rd; op]) -> `RISCVShiftIop(translate_out_imm6 imm, translate_out_ireg rs, translate_out_ireg rd, translate_out_sop op) +| ("RTYPE", [rs2; rs1; rd; op]) -> `RISCVRType (translate_out_ireg rs2, translate_out_ireg rs1, translate_out_ireg rd, translate_out_rop op) +| ("LOAD", [imm; rs; rd; unsigned; width; aq; rl]) + -> `RISCVLoad(translate_out_simm12 imm, translate_out_ireg rs, translate_out_ireg rd, translate_out_bool unsigned, translate_out_wordWidth width, translate_out_bool aq, translate_out_bool rl) +| ("STORE", [imm; rs; rd; width; aq; rl]) + -> `RISCVStore(translate_out_simm12 imm, translate_out_ireg rs, translate_out_ireg rd, translate_out_wordWidth width, translate_out_bool aq, translate_out_bool rl) +| ("ADDIW", [imm; rs; rd]) -> `RISCVADDIW(translate_out_simm12 imm, translate_out_ireg rs, translate_out_ireg rd) +| ("SHIFTW", [imm; rs; rd; op]) -> `RISCVSHIFTW(translate_out_imm5 imm, translate_out_ireg rs, translate_out_ireg rd, translate_out_sop op) +| ("RTYPEW", [rs2; rs1; rd; op]) -> `RISCVRTYPEW(translate_out_ireg rs2, translate_out_ireg rs1, translate_out_ireg rd, translate_out_ropw op) +| ("FENCE", [pred; succ]) -> `RISCVFENCE(translate_out_imm4 pred, translate_out_imm4 succ) +| ("FENCEI", []) -> `RISCVFENCEI +| ("LOADRES", [aq; rl; rs1; width; rd]) + -> `RISCVLoadRes(translate_out_bool aq, translate_out_bool rl, translate_out_ireg rs1, translate_out_wordWidth width, translate_out_ireg rd) +| ("STORECON", [aq; rl; rs2; rs1; width; rd]) + -> `RISCVStoreCon(translate_out_bool aq, translate_out_bool rl, translate_out_ireg rs2, translate_out_ireg rs1, translate_out_wordWidth width, translate_out_ireg rd) +| ("AMO", [op; aq; rl; rs2; rs1; width; rd]) + -> `RISCVAMO(translate_out_amoop op, translate_out_bool aq, translate_out_bool rl, translate_out_ireg rs2, translate_out_ireg rs1, translate_out_wordWidth width, translate_out_ireg rd) diff --git a/risc-v/gen/shallow_ast_to_herdtools_ast.hgen b/risc-v/gen/shallow_ast_to_herdtools_ast.hgen new file mode 100644 index 00000000..3025992e --- /dev/null +++ b/risc-v/gen/shallow_ast_to_herdtools_ast.hgen @@ -0,0 +1,23 @@ +| EBREAK -> `RISCVStopFetching +| UTYPE( imm, rd, op) -> `RISCVUTYPE(translate_out_simm20 imm, translate_out_ireg rd, translate_out_uop op) +| RISCV_JAL( imm, rd) -> `RISCVJAL(translate_out_simm21 imm, translate_out_ireg rd) +| RISCV_JALR( imm, rs, rd) -> `RISCVJALR(translate_out_simm12 imm, translate_out_ireg rs, translate_out_ireg rd) +| BTYPE( imm, rs2, rs1, op) -> `RISCVBType(translate_out_simm13 imm, translate_out_ireg rs2, translate_out_ireg rs1, translate_out_bop op) +| ITYPE( imm, rs1, rd, op) -> `RISCVIType(translate_out_simm12 imm, translate_out_ireg rs1, translate_out_ireg rd, translate_out_iop op) +| SHIFTIOP( imm, rs, rd, op) -> `RISCVShiftIop(translate_out_imm6 imm, translate_out_ireg rs, translate_out_ireg rd, translate_out_sop op) +| RTYPE( rs2, rs1, rd, op) -> `RISCVRType (translate_out_ireg rs2, translate_out_ireg rs1, translate_out_ireg rd, translate_out_rop op) +| LOAD( imm, rs, rd, unsigned, width, aq, rl) + -> `RISCVLoad(translate_out_simm12 imm, translate_out_ireg rs, translate_out_ireg rd, translate_out_bool unsigned, translate_out_wordWidth width, translate_out_bool aq, translate_out_bool rl) +| STORE( imm, rs, rd, width, aq, rl) + -> `RISCVStore(translate_out_simm12 imm, translate_out_ireg rs, translate_out_ireg rd, translate_out_wordWidth width, translate_out_bool aq, translate_out_bool rl) +| ADDIW( imm, rs, rd) -> `RISCVADDIW(translate_out_simm12 imm, translate_out_ireg rs, translate_out_ireg rd) +| SHIFTW( imm, rs, rd, op) -> `RISCVSHIFTW(translate_out_imm5 imm, translate_out_ireg rs, translate_out_ireg rd, translate_out_sop op) +| RTYPEW( rs2, rs1, rd, op) -> `RISCVRTYPEW(translate_out_ireg rs2, translate_out_ireg rs1, translate_out_ireg rd, translate_out_ropw op) +| FENCE( pred, succ) -> `RISCVFENCE(translate_out_imm4 pred, translate_out_imm4 succ) +| FENCEI -> `RISCVFENCEI +| LOADRES( aq, rl, rs1, width, rd) + -> `RISCVLoadRes(translate_out_bool aq, translate_out_bool rl, translate_out_ireg rs1, translate_out_wordWidth width, translate_out_ireg rd) +| STORECON( aq, rl, rs2, rs1, width, rd) + -> `RISCVStoreCon(translate_out_bool aq, translate_out_bool rl, translate_out_ireg rs2, translate_out_ireg rs1, translate_out_wordWidth width, translate_out_ireg rd) +| AMO( op, aq, rl, rs2, rs1, width, rd) + -> `RISCVAMO(translate_out_amoop op, translate_out_bool aq, translate_out_bool rl, translate_out_ireg rs2, translate_out_ireg rs1, translate_out_wordWidth width, translate_out_ireg rd) diff --git a/risc-v/gen/shallow_types_to_herdtools_types.hgen b/risc-v/gen/shallow_types_to_herdtools_types.hgen new file mode 100644 index 00000000..6b3b7f51 --- /dev/null +++ b/risc-v/gen/shallow_types_to_herdtools_types.hgen @@ -0,0 +1,84 @@ +let translate_out_big_bit = Sail_values.unsigned + +let translate_out_int inst = (Nat_big_num.to_int (translate_out_big_bit inst)) +let translate_out_signed_int inst bits = + let i = (Nat_big_num.to_int (translate_out_big_bit inst)) in + if (i >= (1 lsl (bits - 1))) then + (i - (1 lsl bits)) else + i + +let translate_out_ireg ireg = IReg (int_to_ireg (translate_out_int ireg)) + +let translate_out_uop op = match op with + | RISCV_LUI -> RISCVLUI + | RISCV_AUIPC -> RISCVAUIPC + +let translate_out_bop op = match op with + | RISCV_BEQ -> RISCVBEQ + | RISCV_BNE -> RISCVBNE + | RISCV_BLT -> RISCVBLT + | RISCV_BGE -> RISCVBGE + | RISCV_BLTU -> RISCVBLTU + | RISCV_BGEU -> RISCVBGEU + +let translate_out_iop op = match op with + | RISCV_ADDI -> RISCVADDI + | RISCV_SLTI -> RISCVSLTI + | RISCV_SLTIU -> RISCVSLTIU + | RISCV_XORI -> RISCVXORI + | RISCV_ORI -> RISCVORI + | RISCV_ANDI -> RISCVANDI + +let translate_out_sop op = match op with + | RISCV_SLLI -> RISCVSLLI + | RISCV_SRLI -> RISCVSRLI + | RISCV_SRAI -> RISCVSRAI + +let translate_out_rop op = match op with + | RISCV_ADD -> RISCVADD + | RISCV_SUB -> RISCVSUB + | RISCV_SLL -> RISCVSLL + | RISCV_SLT -> RISCVSLT + | RISCV_SLTU -> RISCVSLTU + | RISCV_XOR -> RISCVXOR + | RISCV_SRL -> RISCVSRL + | RISCV_SRA -> RISCVSRA + | RISCV_OR -> RISCVOR + | RISCV_AND -> RISCVAND + +let translate_out_ropw op = match op with + | RISCV_ADDW -> RISCVADDW + | RISCV_SUBW -> RISCVSUBW + | RISCV_SLLW -> RISCVSLLW + | RISCV_SRLW -> RISCVSRLW + | RISCV_SRAW -> RISCVSRAW + +let translate_out_amoop op = match op with + | AMOSWAP -> RISCVAMOSWAP + | AMOADD -> RISCVAMOADD + | AMOXOR -> RISCVAMOXOR + | AMOAND -> RISCVAMOAND + | AMOOR -> RISCVAMOOR + | AMOMIN -> RISCVAMOMIN + | AMOMAX -> RISCVAMOMAX + | AMOMINU -> RISCVAMOMINU + | AMOMAXU -> RISCVAMOMAXU + +let translate_out_wordWidth op = match op with + | BYTE -> RISCVBYTE + | HALF -> RISCVHALF + | WORD -> RISCVWORD + | DOUBLE -> RISCVDOUBLE + +let translate_out_bool = function + | Sail_values.B1 -> true + | Sail_values.B0 -> false + | _ -> failwith "translate_out_bool Undef" + +let translate_out_simm21 imm = translate_out_signed_int imm 21 +let translate_out_simm20 imm = translate_out_signed_int imm 20 +let translate_out_simm13 imm = translate_out_signed_int imm 13 +let translate_out_simm12 imm = translate_out_signed_int imm 12 +let translate_out_imm6 imm = translate_out_int imm +let translate_out_imm5 imm = translate_out_int imm +let translate_out_imm4 imm = translate_out_int imm diff --git a/risc-v/gen/token_types.hgen b/risc-v/gen/token_types.hgen new file mode 100644 index 00000000..f29e318d --- /dev/null +++ b/risc-v/gen/token_types.hgen @@ -0,0 +1,23 @@ +type token_UTYPE = {op : riscvUop } +type token_JAL = unit +type token_JALR = unit +type token_BType = {op : riscvBop } +type token_IType = {op : riscvIop } +type token_ShiftIop = {op : riscvSop } +type token_RTYPE = {op : riscvRop } +type token_Load = {unsigned: bool; width : wordWidth; aq: bool; rl: bool } +type token_Store = {width : wordWidth; aq: bool; rl: bool } +type token_ADDIW = unit +type token_SHIFTW = {op : riscvSop } +type token_RTYPEW = {op : riscvRopw } +type token_FENCE = unit +type token_FENCEI = unit +type token_LoadRes = {width : wordWidth; aq: bool; rl: bool } +type token_StoreCon = {width : wordWidth; aq: bool; rl: bool } +type token_AMO = {width : wordWidth; aq: bool; rl: bool; op: riscvAmoop } + +type token_FENCEOPTION = Fence_R | Fence_W | Fence_RW + +(* pseudo-ops *) + +type token_LI = unit diff --git a/risc-v/gen/tokens.hgen b/risc-v/gen/tokens.hgen new file mode 100644 index 00000000..f812adbd --- /dev/null +++ b/risc-v/gen/tokens.hgen @@ -0,0 +1,19 @@ +%token UTYPE +%token JAL +%token JALR +%token BTYPE +%token ITYPE +%token SHIFTIOP +%token RTYPE +%token LOAD +%token STORE +%token ADDIW +%token SHIFTW +%token RTYPEW +%token FENCE +%token FENCEOPTION +%token FENCEI +%token LOADRES +%token STORECON +%token AMO +%token LI diff --git a/risc-v/gen/trans_sail.hgen b/risc-v/gen/trans_sail.hgen new file mode 100644 index 00000000..8b7cbe11 --- /dev/null +++ b/risc-v/gen/trans_sail.hgen @@ -0,0 +1,153 @@ +| `RISCVStopFetching -> ("EBREAK", [], []) +| `RISCVUTYPE(imm, rd, op) -> + ("UTYPE", + [ + translate_imm20 "imm" imm; + translate_reg "rd" rd; + translate_uop "op" op; + ], + []) +| `RISCVJAL(imm, rd) -> + ("JAL", + [ + translate_imm21 "imm" imm; + translate_reg "rd" rd; + ], + []) +| `RISCVJALR(imm, rs, rd) -> + ("JALR", + [ + translate_imm12 "imm" imm; + translate_reg "rs" rd; + translate_reg "rd" rd; + ], + []) +| `RISCVBType(imm, rs2, rs1, op) -> + ("BTYPE", + [ + translate_imm13 "imm" imm; + translate_reg "rs2" rs2; + translate_reg "rs1" rs1; + translate_bop "op" op; + ], + []) +| `RISCVIType(imm, rs1, rd, op) -> + ("ITYPE", + [ + translate_imm12 "imm" imm; + translate_reg "rs1" rs1; + translate_reg "rd" rd; + translate_iop "op" op; + ], + []) +| `RISCVShiftIop(imm, rs, rd, op) -> + ("SHIFTIOP", + [ + translate_imm6 "imm" imm; + translate_reg "rs" rs; + translate_reg "rd" rd; + translate_sop "op" op; + ], + []) +| `RISCVRType (rs2, rs1, rd, op) -> + ("RTYPE", + [ + translate_reg "rs2" rs2; + translate_reg "rs1" rs1; + translate_reg "rd" rd; + translate_rop "op" op; + ], + []) +| `RISCVLoad(imm, rs, rd, unsigned, width, aq, rl) -> + ("LOAD", + [ + translate_imm12 "imm" imm; + translate_reg "rs" rs; + translate_reg "rd" rd; + translate_bool "unsigned" unsigned; + translate_width "width" width; + translate_bool "aq" aq; + translate_bool "rl" rl; + ], + []) +| `RISCVStore(imm, rs2, rs1, width, aq, rl) -> + ("STORE", + [ + translate_imm12 "imm" imm; + translate_reg "rs2" rs2; + translate_reg "rs1" rs1; + translate_width "width" width; + translate_bool "aq" aq; + translate_bool "rl" rl; + ], + []) +| `RISCVADDIW(imm, rs, rd) -> + ("ADDIW", + [ + translate_imm12 "imm" imm; + translate_reg "rs" rs; + translate_reg "rd" rd; + ], + []) +| `RISCVSHIFTW(imm, rs, rd, op) -> + ("SHIFTW", + [ + translate_imm5 "imm" imm; + translate_reg "rs" rs; + translate_reg "rd" rd; + translate_sop "op" op; + ], + []) +| `RISCVRTYPEW(rs2, rs1, rd, op) -> + ("RTYPEW", + [ + translate_reg "rs2" rs2; + translate_reg "rs1" rs1; + translate_reg "rd" rd; + translate_ropw "op" op; + ], + []) +| `RISCVFENCE(pred, succ) -> + ("FENCE", + [ + translate_imm4 "pred" pred; + translate_imm4 "succ" succ; + ], + []) +| `RISCVFENCEI -> + ("FENCEI", + [], + []) +| `RISCVLoadRes(aq, rl, rs1, width, rd) -> + ("LOADRES", + [ + translate_bool "aq" aq; + translate_bool "rl" rl; + translate_reg "rs1" rs1; + translate_width "width" width; + translate_reg "rd" rd; + ], + []) +| `RISCVStoreCon(aq, rl, rs2, rs1, width, rd) -> + ("STORECON", + [ + translate_bool "aq" aq; + translate_bool "rl" rl; + translate_reg "rs2" rs2; + translate_reg "rs1" rs1; + translate_width "width" width; + translate_reg "rd" rd; + ], + []) +| `RISCVAMO(op, aq, rl, rs2, rs1, width, rd) -> + ("AMO", + [ + translate_amoop "op" op; + translate_bool "aq" aq; + translate_bool "rl" rl; + translate_reg "rs2" rs2; + translate_reg "rs1" rs1; + translate_width "width" width; + translate_reg "rd" rd; + ], + []) diff --git a/risc-v/gen/types.hgen b/risc-v/gen/types.hgen new file mode 100644 index 00000000..a0b75606 --- /dev/null +++ b/risc-v/gen/types.hgen @@ -0,0 +1,172 @@ +type bit20 = int +type bit12 = int +type bit6 = int +type bit5 = int +type bit4 = int + +type riscvUop = (* upper immediate ops *) +| RISCVLUI +| RISCVAUIPC + +let pp_riscv_uop = function +| RISCVLUI -> "lui" +| RISCVAUIPC -> "auipc" + + +type riscvBop = (* branch ops *) +| RISCVBEQ +| RISCVBNE +| RISCVBLT +| RISCVBGE +| RISCVBLTU +| RISCVBGEU + +let pp_riscv_bop = function +| RISCVBEQ -> "beq" +| RISCVBNE -> "bne" +| RISCVBLT -> "blt" +| RISCVBGE -> "bge" +| RISCVBLTU -> "bltu" +| RISCVBGEU -> "bgeu" + +type riscvIop = (* immediate ops *) +| RISCVADDI +| RISCVSLTI +| RISCVSLTIU +| RISCVXORI +| RISCVORI +| RISCVANDI + +let pp_riscv_iop = function +| RISCVADDI -> "addi" +| RISCVSLTI -> "slti" +| RISCVSLTIU -> "sltiu" +| RISCVXORI -> "xori" +| RISCVORI -> "ori" +| RISCVANDI -> "andi" + +type riscvSop = (* shift ops *) +| RISCVSLLI +| RISCVSRLI +| RISCVSRAI + +let pp_riscv_sop = function +| RISCVSLLI -> "slli" +| RISCVSRLI -> "srli" +| RISCVSRAI -> "srai" + +type riscvRop = (* reg-reg ops *) +| RISCVADD +| RISCVSUB +| RISCVSLL +| RISCVSLT +| RISCVSLTU +| RISCVXOR +| RISCVSRL +| RISCVSRA +| RISCVOR +| RISCVAND + +let pp_riscv_rop = function +| RISCVADD -> "add" +| RISCVSUB -> "sub" +| RISCVSLL -> "sll" +| RISCVSLT -> "slt" +| RISCVSLTU -> "sltu" +| RISCVXOR -> "xor" +| RISCVSRL -> "srl" +| RISCVSRA -> "sra" +| RISCVOR -> "or" +| RISCVAND -> "and" + +type riscvRopw = (* reg-reg 32-bit ops *) +| RISCVADDW +| RISCVSUBW +| RISCVSLLW +| RISCVSRLW +| RISCVSRAW + +let pp_riscv_ropw = function +| RISCVADDW -> "addw" +| RISCVSUBW -> "subw" +| RISCVSLLW -> "sllw" +| RISCVSRLW -> "srlw" +| RISCVSRAW -> "sraw" + +type wordWidth = + | RISCVBYTE + | RISCVHALF + | RISCVWORD + | RISCVDOUBLE + +let pp_word_width width : string = + begin match width with + | RISCVBYTE -> "b" + | RISCVHALF -> "h" + | RISCVWORD -> "w" + | RISCVDOUBLE -> "d" + end + +let pp_riscv_load_op (unsigned, width, aq, rl) = + "l" ^ + (pp_word_width width) ^ + (if unsigned then "u" else "") ^ + (if aq then ".aq" else "") ^ + (if rl then ".rl" else "") + +let pp_riscv_store_op (width, aq, rl) = + "s" ^ + (pp_word_width width) ^ + (if aq then ".aq" else "") ^ + (if rl then ".rl" else "") + +let pp_riscv_load_reserved_op (aq, rl, width) = + "lr." ^ + (pp_word_width width) ^ + (if aq then ".aq" else "") ^ + (if rl then ".rl" else "") + +let pp_riscv_store_conditional_op (aq, rl, width) = + "sc." ^ + (pp_word_width width) ^ + (if aq then ".aq" else "") ^ + (if rl then ".rl" else "") + +type riscvAmoop = + | RISCVAMOSWAP + | RISCVAMOADD + | RISCVAMOXOR + | RISCVAMOAND + | RISCVAMOOR + | RISCVAMOMIN + | RISCVAMOMAX + | RISCVAMOMINU + | RISCVAMOMAXU + +let pp_riscv_amo_op_part = function + | RISCVAMOSWAP -> "swap" + | RISCVAMOADD -> "add" + | RISCVAMOXOR -> "xor" + | RISCVAMOAND -> "and" + | RISCVAMOOR -> "or" + | RISCVAMOMIN -> "min" + | RISCVAMOMAX -> "max" + | RISCVAMOMINU -> "minu" + | RISCVAMOMAXU -> "maxu" + +let pp_riscv_amo_op (op, aq, rl, width) = + "amo" ^ + pp_riscv_amo_op_part op ^ + begin match width with + | RISCVWORD -> ".w" + | RISCVDOUBLE -> ".d" + | _ -> assert false + end ^ + (if aq then ".aq" else "") ^ + (if rl then ".rl" else "") + +let pp_riscv_fence_option = function + | 0b0011 -> "rw" + | 0b0010 -> "r" + | 0b0001 -> "w" + | _ -> failwith "unexpected fence option" diff --git a/risc-v/gen/types_sail_trans_out.hgen b/risc-v/gen/types_sail_trans_out.hgen new file mode 100644 index 00000000..66a2020c --- /dev/null +++ b/risc-v/gen/types_sail_trans_out.hgen @@ -0,0 +1,98 @@ +let translate_out_big_bit = function + | (name, Bvector _, bits) -> IInt.integer_of_bit_list bits + | _ -> assert false + +let translate_out_int inst = (Nat_big_num.to_int (translate_out_big_bit inst)) +let translate_out_signed_int inst bits = + let i = (Nat_big_num.to_int (translate_out_big_bit inst)) in + if (i >= (1 lsl (bits - 1))) then + (i - (1 lsl bits)) else + i + +let translate_out_ireg ireg = IReg (int_to_ireg (translate_out_int ireg)) + +let translate_out_simm21 imm = translate_out_signed_int imm 21 +let translate_out_simm20 imm = translate_out_signed_int imm 20 +let translate_out_simm13 imm = translate_out_signed_int imm 13 +let translate_out_simm12 imm = translate_out_signed_int imm 12 +let translate_out_imm6 imm = translate_out_int imm +let translate_out_imm5 imm = translate_out_int imm +let translate_out_imm4 imm = translate_out_int imm + +let translate_out_bool = function + | (name, Bit, [Bitc_one]) -> true + | (name, Bit, [Bitc_zero]) -> false + | _ -> assert false + +let translate_out_enum (name,_,bits) = + Nat_big_num.to_int (IInt.integer_of_bit_list bits) + +let translate_out_wordWidth w = + match translate_out_enum w with + | 0 -> RISCVBYTE + | 1 -> RISCVHALF + | 2 -> RISCVWORD + | 3 -> RISCVDOUBLE + | _ -> failwith "Unknown wordWidth in sail translate out" + +let translate_out_uop op = match translate_out_enum op with + | 0 -> RISCVLUI + | 1 -> RISCVAUIPC + | _ -> failwith "Unknown uop in sail translate out" + +let translate_out_bop op = match translate_out_enum op with +| 0 -> RISCVBEQ +| 1 -> RISCVBNE +| 2 -> RISCVBLT +| 3 -> RISCVBGE +| 4 -> RISCVBLTU +| 5 -> RISCVBGEU +| _ -> failwith "Unknown bop in sail translate out" + +let translate_out_iop op = match translate_out_enum op with +| 0 -> RISCVADDI +| 1 -> RISCVSLTI +| 2 -> RISCVSLTIU +| 3 -> RISCVXORI +| 4 -> RISCVORI +| 5 -> RISCVANDI +| _ -> failwith "Unknown iop in sail translate out" + +let translate_out_sop op = match translate_out_enum op with +| 0 -> RISCVSLLI +| 1 -> RISCVSRLI +| 2 -> RISCVSRAI +| _ -> failwith "Unknown sop in sail translate out" + +let translate_out_rop op = match translate_out_enum op with +| 0 -> RISCVADD +| 1 -> RISCVSUB +| 2 -> RISCVSLL +| 3 -> RISCVSLT +| 4 -> RISCVSLTU +| 5 -> RISCVXOR +| 6 -> RISCVSRL +| 7 -> RISCVSRA +| 8 -> RISCVOR +| 9 -> RISCVAND +| _ -> failwith "Unknown rop in sail translate out" + +let translate_out_ropw op = match translate_out_enum op with +| 0 -> RISCVADDW +| 1 -> RISCVSUBW +| 2 -> RISCVSLLW +| 3 -> RISCVSRLW +| 4 -> RISCVSRAW +| _ -> failwith "Unknown ropw in sail translate out" + +let translate_out_amoop op = match translate_out_enum op with +| 0 -> RISCVAMOSWAP +| 1 -> RISCVAMOADD +| 2 -> RISCVAMOXOR +| 3 -> RISCVAMOAND +| 4 -> RISCVAMOOR +| 5 -> RISCVAMOMIN +| 6 -> RISCVAMOMAX +| 7 -> RISCVAMOMINU +| 8 -> RISCVAMOMAXU +| _ -> failwith "Unknown amoop in sail translate out" diff --git a/risc-v/gen/types_trans_sail.hgen b/risc-v/gen/types_trans_sail.hgen new file mode 100644 index 00000000..238c7e5b --- /dev/null +++ b/risc-v/gen/types_trans_sail.hgen @@ -0,0 +1,57 @@ +let translate_enum enum_values name value = + let rec bit_count n = + if n = 0 then 0 + else 1 + (bit_count (n lsr 1)) in + let rec find_index element = function + | h::tail -> if h = element then 0 else 1 + (find_index element tail) + | _ -> failwith "translate_enum could not find value" + in + let size = bit_count (List.length enum_values) in + let index = find_index value enum_values in + (name, Range0 (Some size), IInt.bit_list_of_integer size (Nat_big_num.of_int index)) + +let translate_uop = translate_enum [RISCVLUI; RISCVAUIPC] + +let translate_bop = translate_enum [RISCVBEQ; RISCVBNE; RISCVBLT; RISCVBGE; RISCVBLTU; RISCVBGEU] (* branch ops *) + +let translate_iop = translate_enum [RISCVADDI; RISCVSLTI; RISCVSLTIU; RISCVXORI; RISCVORI; RISCVANDI] (* immediate ops *) + +let translate_sop = translate_enum [RISCVSLLI; RISCVSRLI; RISCVSRAI] (* shift ops *) + +let translate_rop = translate_enum [RISCVADD; RISCVSUB; RISCVSLL; RISCVSLT; RISCVSLTU; RISCVXOR; RISCVSRL; RISCVSRA; RISCVOR; RISCVAND] (* reg-reg ops *) + +let translate_ropw = translate_enum [RISCVADDW; RISCVSUBW; RISCVSLLW; RISCVSRLW; RISCVSRAW] (* reg-reg 32-bit ops *) + +let translate_amoop = translate_enum [RISCVAMOSWAP; RISCVAMOADD; RISCVAMOXOR; RISCVAMOAND; RISCVAMOOR; RISCVAMOMIN; RISCVAMOMAX; RISCVAMOMINU; RISCVAMOMAXU] + +let translate_width = translate_enum [RISCVBYTE; RISCVHALF; RISCVWORD; RISCVDOUBLE] + +let translate_reg name value = + (name, Bvector (Some 5), bit_list_of_integer 5 (Nat_big_num.of_int (reg_to_int value))) + +let translate_imm21 name value = + (name, Bvector (Some 21), bit_list_of_integer 21 (Nat_big_num.of_int value)) + +let translate_imm20 name value = + (name, Bvector (Some 20), bit_list_of_integer 20 (Nat_big_num.of_int value)) + +let translate_imm16 name value = + (name, Bvector (Some 16), bit_list_of_integer 16 (Nat_big_num.of_int value)) + +let translate_imm13 name value = + (name, Bvector (Some 13), bit_list_of_integer 13 (Nat_big_num.of_int value)) + +let translate_imm12 name value = + (name, Bvector (Some 12), bit_list_of_integer 12 (Nat_big_num.of_int value)) + +let translate_imm6 name value = + (name, Bvector (Some 6), bit_list_of_integer 6 (Nat_big_num.of_int value)) + +let translate_imm5 name value = + (name, Bvector (Some 5), bit_list_of_integer 5 (Nat_big_num.of_int value)) + +let translate_imm4 name value = + (name, Bvector (Some 4), bit_list_of_integer 4 (Nat_big_num.of_int value)) + +let translate_bool name value = + (name, Bit, [if value then Bitc_one else Bitc_zero]) diff --git a/risc-v/hgen/ast.hgen b/risc-v/hgen/ast.hgen deleted file mode 100644 index b1968173..00000000 --- a/risc-v/hgen/ast.hgen +++ /dev/null @@ -1,17 +0,0 @@ -| `RISCVUTYPE of bit20 * reg * riscvUop -| `RISCVJAL of bit20 * reg -| `RISCVJALR of bit12 * reg * reg -| `RISCVBType of bit12 * reg * reg * riscvBop -| `RISCVIType of bit12 * reg * reg * riscvIop -| `RISCVShiftIop of bit6 * reg * reg * riscvSop -| `RISCVRType of reg * reg * reg * riscvRop -| `RISCVLoad of bit12 * reg * reg * bool * wordWidth * bool * bool -| `RISCVStore of bit12 * reg * reg * wordWidth * bool * bool -| `RISCVADDIW of bit12 * reg * reg -| `RISCVSHIFTW of bit5 * reg * reg * riscvSop -| `RISCVRTYPEW of reg * reg * reg * riscvRopw -| `RISCVFENCE of bit4 * bit4 -| `RISCVFENCEI -| `RISCVLoadRes of bool * bool * reg * wordWidth * reg -| `RISCVStoreCon of bool * bool * reg * reg * wordWidth * reg -| `RISCVAMO of riscvAmoop * bool * bool * reg * reg * wordWidth * reg diff --git a/risc-v/hgen/fold.hgen b/risc-v/hgen/fold.hgen deleted file mode 100644 index 4c51e114..00000000 --- a/risc-v/hgen/fold.hgen +++ /dev/null @@ -1,16 +0,0 @@ -| `RISCVThreadStart -> (y_reg, y_sreg) -| `RISCVUTYPE (_, r0, _) -> fold_reg r0 (y_reg, y_sreg) -| `RISCVJAL (_, r0) -> fold_reg r0 (y_reg, y_sreg) -| `RISCVJALR (_, r0, r1) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) -| `RISCVBType (_, r0, r1, _) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) -| `RISCVIType (_, r0, r1, _) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) -| `RISCVShiftIop (_, r0, r1, _) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) -| `RISCVRType (r0, r1, r2, _) -> fold_reg r0 (fold_reg r1 (fold_reg r2 (y_reg, y_sreg))) -| `RISCVLoad (_, r0, r1, _, _, _, _) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) -| `RISCVStore (_, r0, r1, _, _, _) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) -| `RISCVADDIW (_, r0, r1) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) -| `RISCVSHIFTW (_, r0, r1, _) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) -| `RISCVRTYPEW (r0, r1, r2, _) -> fold_reg r0 (fold_reg r1 (fold_reg r2 (y_reg, y_sreg))) -| `RISCVLoadRes (_, _, rs1, _, rd) -> fold_reg rs1 (fold_reg rd (y_reg, y_sreg)) -| `RISCVStoreCon (_, _, rs2, rs1, _, rd) -> fold_reg rs2 (fold_reg rs1 (fold_reg rd (y_reg, y_sreg))) -| `RISCVAMO (_, _, _, rs2, rs1, _, rd) -> fold_reg rs2 (fold_reg rs1 (fold_reg rd (y_reg, y_sreg))) diff --git a/risc-v/hgen/herdtools_ast_to_shallow_ast.hgen b/risc-v/hgen/herdtools_ast_to_shallow_ast.hgen deleted file mode 100644 index 07c1d082..00000000 --- a/risc-v/hgen/herdtools_ast_to_shallow_ast.hgen +++ /dev/null @@ -1,86 +0,0 @@ -| `RISCVStopFetching -> EBREAK -| `RISCVUTYPE(imm, rd, op) -> UTYPE( - translate_imm20 "imm" imm, - translate_reg "rd" rd, - translate_uop op) -| `RISCVJAL(imm, rd) -> RISCV_JAL( - translate_imm21 "imm" imm, - translate_reg "rd" rd) -| `RISCVJALR(imm, rs, rd) -> RISCV_JALR( - translate_imm12 "imm" imm, - translate_reg "rs" rd, - translate_reg "rd" rd) -| `RISCVBType(imm, rs2, rs1, op) -> BTYPE( - translate_imm13 "imm" imm, - translate_reg "rs2" rs2, - translate_reg "rs1" rs1, - translate_bop op) -| `RISCVIType(imm, rs1, rd, op) -> ITYPE( - translate_imm12 "imm" imm, - translate_reg "rs1" rs1, - translate_reg "rd" rd, - translate_iop op) -| `RISCVShiftIop(imm, rs, rd, op) -> SHIFTIOP( - translate_imm6 "imm" imm, - translate_reg "rs" rs, - translate_reg "rd" rd, - translate_sop op) -| `RISCVRType (rs2, rs1, rd, op) -> RTYPE ( - translate_reg "rs2" rs2, - translate_reg "rs1" rs1, - translate_reg "rd" rd, - translate_rop op) -| `RISCVLoad(imm, rs, rd, unsigned, width, aq, rl) -> LOAD( - translate_imm12 "imm" imm, - translate_reg "rs" rs, - translate_reg "rd" rd, - translate_bool "unsigned" unsigned, - translate_wordWidth width, - translate_bool "aq" aq, - translate_bool "rl" rl) -| `RISCVStore(imm, rs, rd, width, aq, rl) -> STORE ( - translate_imm12 "imm" imm, - translate_reg "rs" rs, - translate_reg "rd" rd, - translate_wordWidth width, - translate_bool "aq" aq, - translate_bool "rl" rl) -| `RISCVADDIW(imm, rs, rd) -> ADDIW( - translate_imm12 "imm" imm, - translate_reg "rs" rs, - translate_reg "rd" rd) -| `RISCVSHIFTW(imm, rs, rd, op) -> SHIFTW( - translate_imm5 "imm" imm, - translate_reg "rs" rs, - translate_reg "rd" rd, - translate_sop op) -| `RISCVRTYPEW(rs2, rs1, rd, op) -> RTYPEW( - translate_reg "rs2" rs2, - translate_reg "rs1" rs1, - translate_reg "rd" rd, - translate_ropw op) -| `RISCVFENCE(pred, succ) -> FENCE( - translate_imm4 "pred" pred, - translate_imm4 "succ" succ) -| `RISCVFENCEI -> FENCEI -| `RISCVLoadRes(aq, rl, rs1, width, rd) -> LOADRES( - translate_bool "aq" aq, - translate_bool "rl" rl, - translate_reg "rs1" rs1, - translate_wordWidth width, - translate_reg "rd" rd) -| `RISCVStoreCon(aq, rl, rs2, rs1, width, rd) -> STORECON( - translate_bool "aq" aq, - translate_bool "rl" rl, - translate_reg "rs2" rs2, - translate_reg "rs1" rs1, - translate_wordWidth width, - translate_reg "rd" rd) -| `RISCVAMO (op, aq, rl, rs2, rs1, width, rd) -> AMO( - translate_amoop op, - translate_bool "aq" aq, - translate_bool "rl" rl, - translate_reg "rs2" rs2, - translate_reg "rs1" rs1, - translate_wordWidth width, - translate_reg "rd" rd) diff --git a/risc-v/hgen/herdtools_types_to_shallow_types.hgen b/risc-v/hgen/herdtools_types_to_shallow_types.hgen deleted file mode 100644 index e6edd24d..00000000 --- a/risc-v/hgen/herdtools_types_to_shallow_types.hgen +++ /dev/null @@ -1,90 +0,0 @@ -let is_inc = false - -let translate_reg name value = - Sail_values.to_vec0 is_inc (Nat_big_num.of_int 5,Nat_big_num.of_int (reg_to_int value)) - -let translate_uop op = match op with - | RISCVLUI -> RISCV_LUI - | RISCVAUIPC -> RISCV_AUIPC - -let translate_bop op = match op with - | RISCVBEQ -> RISCV_BEQ - | RISCVBNE -> RISCV_BNE - | RISCVBLT -> RISCV_BLT - | RISCVBGE -> RISCV_BGE - | RISCVBLTU -> RISCV_BLTU - | RISCVBGEU -> RISCV_BGEU - -let translate_iop op = match op with - | RISCVADDI -> RISCV_ADDI - | RISCVSLTI -> RISCV_SLTI - | RISCVSLTIU -> RISCV_SLTIU - | RISCVXORI -> RISCV_XORI - | RISCVORI -> RISCV_ORI - | RISCVANDI -> RISCV_ANDI - -let translate_sop op = match op with - | RISCVSLLI -> RISCV_SLLI - | RISCVSRLI -> RISCV_SRLI - | RISCVSRAI -> RISCV_SRAI - -let translate_rop op = match op with - | RISCVADD -> RISCV_ADD - | RISCVSUB -> RISCV_SUB - | RISCVSLL -> RISCV_SLL - | RISCVSLT -> RISCV_SLT - | RISCVSLTU -> RISCV_SLTU - | RISCVXOR -> RISCV_XOR - | RISCVSRL -> RISCV_SRL - | RISCVSRA -> RISCV_SRA - | RISCVOR -> RISCV_OR - | RISCVAND -> RISCV_AND - -let translate_ropw op = match op with - | RISCVADDW -> RISCV_ADDW - | RISCVSUBW -> RISCV_SUBW - | RISCVSLLW -> RISCV_SLLW - | RISCVSRLW -> RISCV_SRLW - | RISCVSRAW -> RISCV_SRAW - -let translate_amoop op = match op with - | RISCVAMOSWAP -> AMOSWAP - | RISCVAMOADD -> AMOADD - | RISCVAMOXOR -> AMOXOR - | RISCVAMOAND -> AMOAND - | RISCVAMOOR -> AMOOR - | RISCVAMOMIN -> AMOMIN - | RISCVAMOMAX -> AMOMAX - | RISCVAMOMINU -> AMOMINU - | RISCVAMOMAXU -> AMOMAXU - -let translate_wordWidth op = match op with - | RISCVBYTE -> BYTE - | RISCVHALF -> HALF - | RISCVWORD -> WORD - | RISCVDOUBLE -> DOUBLE - -let translate_bool name = function - | true -> Sail_values.B1 - | false -> Sail_values.B0 - -let translate_imm21 name value = - Sail_values.to_vec0 is_inc (Nat_big_num.of_int 21,Nat_big_num.of_int value) - -let translate_imm20 name value = - Sail_values.to_vec0 is_inc (Nat_big_num.of_int 20,Nat_big_num.of_int value) - -let translate_imm13 name value = - Sail_values.to_vec0 is_inc (Nat_big_num.of_int 13,Nat_big_num.of_int value) - -let translate_imm12 name value = - Sail_values.to_vec0 is_inc (Nat_big_num.of_int 12,Nat_big_num.of_int value) - -let translate_imm6 name value = - Sail_values.to_vec0 is_inc (Nat_big_num.of_int 6,Nat_big_num.of_int value) - -let translate_imm5 name value = - Sail_values.to_vec0 is_inc (Nat_big_num.of_int 5,Nat_big_num.of_int value) - -let translate_imm4 name value = - Sail_values.to_vec0 is_inc (Nat_big_num.of_int 4,Nat_big_num.of_int value) diff --git a/risc-v/hgen/lexer.hgen b/risc-v/hgen/lexer.hgen deleted file mode 100644 index e42b8a62..00000000 --- a/risc-v/hgen/lexer.hgen +++ /dev/null @@ -1,190 +0,0 @@ -"lui" , UTYPE { op=RISCVLUI }; -"auipc" , UTYPE { op=RISCVAUIPC }; - -"jal", JAL (); -"jalr", JALR (); - -"beq", BTYPE {op=RISCVBEQ}; -"bne", BTYPE {op=RISCVBNE}; -"blt", BTYPE {op=RISCVBLT}; -"bge", BTYPE {op=RISCVBGE}; -"bltu", BTYPE {op=RISCVBLTU}; -"bgeu", BTYPE {op=RISCVBGEU}; - -"addi", ITYPE {op=RISCVADDI}; -"stli", ITYPE {op=RISCVSLTI}; -"sltiu", ITYPE {op=RISCVSLTIU}; -"xori", ITYPE {op=RISCVXORI}; -"ori", ITYPE {op=RISCVORI}; -"andi", ITYPE {op=RISCVANDI}; - -"slli", SHIFTIOP{op=RISCVSLLI}; -"srli", SHIFTIOP{op=RISCVSRLI}; -"srai", SHIFTIOP{op=RISCVSRAI}; - -"add", RTYPE{op=RISCVADD}; -"sub", RTYPE{op=RISCVSUB}; -"sll", RTYPE{op=RISCVSLL}; -"slt", RTYPE{op=RISCVSLT}; -"sltu", RTYPE{op=RISCVSLT}; -"xor", RTYPE{op=RISCVXOR}; -"srl", RTYPE{op=RISCVSRL}; -"sra", RTYPE{op=RISCVSRA}; -"or", RTYPE{op=RISCVOR}; -"and", RTYPE{op=RISCVAND}; - -"lb", LOAD{unsigned=false; width=RISCVBYTE; aq=false; rl=false}; -"lbu", LOAD{unsigned=true; width=RISCVBYTE; aq=false; rl=false}; -"lh", LOAD{unsigned=false; width=RISCVHALF; aq=false; rl=false}; -"lhu", LOAD{unsigned=true; width=RISCVHALF; aq=false; rl=false}; -"lw", LOAD{unsigned=false; width=RISCVWORD; aq=false; rl=false}; -"lwu", LOAD{unsigned=true; width=RISCVWORD; aq=false; rl=false}; -"ld", LOAD{unsigned=false; width=RISCVDOUBLE; aq=false; rl=false}; - -"lb.aq", LOAD{unsigned=false; width=RISCVBYTE; aq=true; rl=false}; -"lbu.aq", LOAD{unsigned=true; width=RISCVBYTE; aq=true; rl=false}; -"lh.aq", LOAD{unsigned=false; width=RISCVHALF; aq=true; rl=false}; -"lhu.aq", LOAD{unsigned=true; width=RISCVHALF; aq=true; rl=false}; -"lw.aq", LOAD{unsigned=false; width=RISCVWORD; aq=true; rl=false}; -"lwu.aq", LOAD{unsigned=true; width=RISCVWORD; aq=true; rl=false}; -"ld.aq", LOAD{unsigned=false; width=RISCVDOUBLE; aq=true; rl=false}; - -"lb.aq.rl", LOAD{unsigned=false; width=RISCVBYTE; aq=true; rl=true}; -"lbu.aq.rl", LOAD{unsigned=true; width=RISCVBYTE; aq=true; rl=true}; -"lh.aq.rl", LOAD{unsigned=false; width=RISCVHALF; aq=true; rl=true}; -"lhu.aq.rl", LOAD{unsigned=true; width=RISCVHALF; aq=true; rl=true}; -"lw.aq.rl", LOAD{unsigned=false; width=RISCVWORD; aq=true; rl=true}; -"lwu.aq.rl", LOAD{unsigned=true; width=RISCVWORD; aq=true; rl=true}; -"ld.aq.rl", LOAD{unsigned=false; width=RISCVDOUBLE; aq=true; rl=true}; - -"sb", STORE{width=RISCVBYTE; aq=false; rl=false}; -"sh", STORE{width=RISCVHALF; aq=false; rl=false}; -"sw", STORE{width=RISCVWORD; aq=false; rl=false}; -"sd", STORE{width=RISCVDOUBLE; aq=false; rl=false}; - -"sb.rl", STORE{width=RISCVBYTE; aq=false; rl=true}; -"sh.rl", STORE{width=RISCVHALF; aq=false; rl=true}; -"sw.rl", STORE{width=RISCVWORD; aq=false; rl=true}; -"sd.rl", STORE{width=RISCVDOUBLE; aq=false; rl=true}; - -"sb.aq.rl", STORE{width=RISCVBYTE; aq=true; rl=true}; -"sh.aq.rl", STORE{width=RISCVHALF; aq=true; rl=true}; -"sw.aq.rl", STORE{width=RISCVWORD; aq=true; rl=true}; -"sd.aq.rl", STORE{width=RISCVDOUBLE; aq=true; rl=true}; - -"addiw", ADDIW (); - -"slliw", SHIFTW{op=RISCVSLLI}; -"srliw", SHIFTW{op=RISCVSRLI}; -"sraiw", SHIFTW{op=RISCVSRAI}; - -"addw", RTYPEW{op=RISCVADDW}; -"subw", RTYPEW{op=RISCVSUBW}; -"sslw", RTYPEW{op=RISCVSLLW}; -"srlw", RTYPEW{op=RISCVSRLW}; -"sraw", RTYPEW{op=RISCVSRAW}; - -"fence", FENCE (); -"r", FENCEOPTION Fence_R; -"w", FENCEOPTION Fence_W; -"rw", FENCEOPTION Fence_RW; - -"fence.i", FENCEI (); - -"lr.w", LOADRES {width=RISCVWORD; aq=false; rl=false}; -"lr.w.aq", LOADRES {width=RISCVWORD; aq=true; rl=false}; -"lr.w.aq.rl", LOADRES {width=RISCVWORD; aq=true; rl=true}; -"lr.d", LOADRES {width=RISCVDOUBLE; aq=false; rl=false}; -"lr.d.aq", LOADRES {width=RISCVDOUBLE; aq=true; rl=false}; -"lr.d.aq.rl", LOADRES {width=RISCVDOUBLE; aq=true; rl=true}; - -"sc.w", STORECON {width=RISCVWORD; aq=false; rl=false}; -"sc.w.rl", STORECON {width=RISCVWORD; aq=false; rl=true}; -"sc.w.aq.rl", STORECON {width=RISCVWORD; aq=true; rl=true}; -"sc.d", STORECON {width=RISCVDOUBLE; aq=false; rl=false}; -"sc.d.rl", STORECON {width=RISCVDOUBLE; aq=false; rl=true}; -"sc.d.aq.rl", STORECON {width=RISCVDOUBLE; aq=true; rl=true}; - -"amoswap.w", AMO {width=RISCVWORD; aq=false; rl=false; op=RISCVAMOSWAP}; -"amoadd.w", AMO {width=RISCVWORD; aq=false; rl=false; op=RISCVAMOADD}; -"amoand.w", AMO {width=RISCVWORD; aq=false; rl=false; op=RISCVAMOAND}; -"amoor.w", AMO {width=RISCVWORD; aq=false; rl=false; op=RISCVAMOOR}; -"amoxor.w", AMO {width=RISCVWORD; aq=false; rl=false; op=RISCVAMOXOR}; -"amomax.w", AMO {width=RISCVWORD; aq=false; rl=false; op=RISCVAMOMAX}; -"amomin.w", AMO {width=RISCVWORD; aq=false; rl=false; op=RISCVAMOMIN}; -"amomaxu.w", AMO {width=RISCVWORD; aq=false; rl=false; op=RISCVAMOMAXU}; -"amominu.w", AMO {width=RISCVWORD; aq=false; rl=false; op=RISCVAMOMINU}; - -"amoswap.d", AMO {width=RISCVDOUBLE; aq=false; rl=false; op=RISCVAMOSWAP}; -"amoadd.d", AMO {width=RISCVDOUBLE; aq=false; rl=false; op=RISCVAMOADD}; -"amoand.d", AMO {width=RISCVDOUBLE; aq=false; rl=false; op=RISCVAMOAND}; -"amoor.d", AMO {width=RISCVDOUBLE; aq=false; rl=false; op=RISCVAMOOR}; -"amoxor.d", AMO {width=RISCVDOUBLE; aq=false; rl=false; op=RISCVAMOXOR}; -"amomax.d", AMO {width=RISCVDOUBLE; aq=false; rl=false; op=RISCVAMOMAX}; -"amomin.d", AMO {width=RISCVDOUBLE; aq=false; rl=false; op=RISCVAMOMIN}; -"amomaxu.d", AMO {width=RISCVDOUBLE; aq=false; rl=false; op=RISCVAMOMAXU}; -"amominu.d", AMO {width=RISCVDOUBLE; aq=false; rl=false; op=RISCVAMOMINU}; - -"amoswap.w.aq", AMO {width=RISCVWORD; aq=true; rl=false; op=RISCVAMOSWAP}; -"amoadd.w.aq", AMO {width=RISCVWORD; aq=true; rl=false; op=RISCVAMOADD}; -"amoand.w.aq", AMO {width=RISCVWORD; aq=true; rl=false; op=RISCVAMOAND}; -"amoor.w.aq", AMO {width=RISCVWORD; aq=true; rl=false; op=RISCVAMOOR}; -"amoxor.w.aq", AMO {width=RISCVWORD; aq=true; rl=false; op=RISCVAMOXOR}; -"amomax.w.aq", AMO {width=RISCVWORD; aq=true; rl=false; op=RISCVAMOMAX}; -"amomin.w.aq", AMO {width=RISCVWORD; aq=true; rl=false; op=RISCVAMOMIN}; -"amomaxu.w.aq", AMO {width=RISCVWORD; aq=true; rl=false; op=RISCVAMOMAXU}; -"amominu.w.aq", AMO {width=RISCVWORD; aq=true; rl=false; op=RISCVAMOMINU}; - -"amoswap.d.aq", AMO {width=RISCVDOUBLE; aq=true; rl=false; op=RISCVAMOSWAP}; -"amoadd.d.aq", AMO {width=RISCVDOUBLE; aq=true; rl=false; op=RISCVAMOADD}; -"amoand.d.aq", AMO {width=RISCVDOUBLE; aq=true; rl=false; op=RISCVAMOAND}; -"amoor.d.aq", AMO {width=RISCVDOUBLE; aq=true; rl=false; op=RISCVAMOOR}; -"amoxor.d.aq", AMO {width=RISCVDOUBLE; aq=true; rl=false; op=RISCVAMOXOR}; -"amomax.d.aq", AMO {width=RISCVDOUBLE; aq=true; rl=false; op=RISCVAMOMAX}; -"amomin.d.aq", AMO {width=RISCVDOUBLE; aq=true; rl=false; op=RISCVAMOMIN}; -"amomaxu.d.aq", AMO {width=RISCVDOUBLE; aq=true; rl=false; op=RISCVAMOMAXU}; -"amominu.d.aq", AMO {width=RISCVDOUBLE; aq=true; rl=false; op=RISCVAMOMINU}; - -"amoswap.w.rl", AMO {width=RISCVWORD; aq=false; rl=true; op=RISCVAMOSWAP}; -"amoadd.w.rl", AMO {width=RISCVWORD; aq=false; rl=true; op=RISCVAMOADD}; -"amoand.w.rl", AMO {width=RISCVWORD; aq=false; rl=true; op=RISCVAMOAND}; -"amoor.w.rl", AMO {width=RISCVWORD; aq=false; rl=true; op=RISCVAMOOR}; -"amoxor.w.rl", AMO {width=RISCVWORD; aq=false; rl=true; op=RISCVAMOXOR}; -"amomax.w.rl", AMO {width=RISCVWORD; aq=false; rl=true; op=RISCVAMOMAX}; -"amomin.w.rl", AMO {width=RISCVWORD; aq=false; rl=true; op=RISCVAMOMIN}; -"amomaxu.w.rl", AMO {width=RISCVWORD; aq=false; rl=true; op=RISCVAMOMAXU}; -"amominu.w.rl", AMO {width=RISCVWORD; aq=false; rl=true; op=RISCVAMOMINU}; - -"amoswap.d.rl", AMO {width=RISCVDOUBLE; aq=false; rl=true; op=RISCVAMOSWAP}; -"amoadd.d.rl", AMO {width=RISCVDOUBLE; aq=false; rl=true; op=RISCVAMOADD}; -"amoand.d.rl", AMO {width=RISCVDOUBLE; aq=false; rl=true; op=RISCVAMOAND}; -"amoor.d.rl", AMO {width=RISCVDOUBLE; aq=false; rl=true; op=RISCVAMOOR}; -"amoxor.d.rl", AMO {width=RISCVDOUBLE; aq=false; rl=true; op=RISCVAMOXOR}; -"amomax.d.rl", AMO {width=RISCVDOUBLE; aq=false; rl=true; op=RISCVAMOMAX}; -"amomin.d.rl", AMO {width=RISCVDOUBLE; aq=false; rl=true; op=RISCVAMOMIN}; -"amomaxu.d.rl", AMO {width=RISCVDOUBLE; aq=false; rl=true; op=RISCVAMOMAXU}; -"amominu.d.rl", AMO {width=RISCVDOUBLE; aq=false; rl=true; op=RISCVAMOMINU}; - -"amoswap.w.aq.rl", AMO {width=RISCVWORD; aq=true; rl=true; op=RISCVAMOSWAP}; -"amoadd.w.aq.rl", AMO {width=RISCVWORD; aq=true; rl=true; op=RISCVAMOADD}; -"amoand.w.aq.rl", AMO {width=RISCVWORD; aq=true; rl=true; op=RISCVAMOAND}; -"amoor.w.aq.rl", AMO {width=RISCVWORD; aq=true; rl=true; op=RISCVAMOOR}; -"amoxor.w.aq.rl", AMO {width=RISCVWORD; aq=true; rl=true; op=RISCVAMOXOR}; -"amomax.w.aq.rl", AMO {width=RISCVWORD; aq=true; rl=true; op=RISCVAMOMAX}; -"amomin.w.aq.rl", AMO {width=RISCVWORD; aq=true; rl=true; op=RISCVAMOMIN}; -"amomaxu.w.aq.rl", AMO {width=RISCVWORD; aq=true; rl=true; op=RISCVAMOMAXU}; -"amominu.w.aq.rl", AMO {width=RISCVWORD; aq=true; rl=true; op=RISCVAMOMINU}; - -"amoswap.d.aq.rl", AMO {width=RISCVDOUBLE; aq=true; rl=true; op=RISCVAMOSWAP}; -"amoadd.d.aq.rl", AMO {width=RISCVDOUBLE; aq=true; rl=true; op=RISCVAMOADD}; -"amoand.d.aq.rl", AMO {width=RISCVDOUBLE; aq=true; rl=true; op=RISCVAMOAND}; -"amoor.d.aq.rl", AMO {width=RISCVDOUBLE; aq=true; rl=true; op=RISCVAMOOR}; -"amoxor.d.aq.rl", AMO {width=RISCVDOUBLE; aq=true; rl=true; op=RISCVAMOXOR}; -"amomax.d.aq.rl", AMO {width=RISCVDOUBLE; aq=true; rl=true; op=RISCVAMOMAX}; -"amomin.d.aq.rl", AMO {width=RISCVDOUBLE; aq=true; rl=true; op=RISCVAMOMIN}; -"amomaxu.d.aq.rl", AMO {width=RISCVDOUBLE; aq=true; rl=true; op=RISCVAMOMAXU}; -"amominu.d.aq.rl", AMO {width=RISCVDOUBLE; aq=true; rl=true; op=RISCVAMOMINU}; - -(** pseudo instructions *********************************************) - -"li", LI () diff --git a/risc-v/hgen/map.hgen b/risc-v/hgen/map.hgen deleted file mode 100644 index bab5ced8..00000000 --- a/risc-v/hgen/map.hgen +++ /dev/null @@ -1,15 +0,0 @@ -| `RISCVUTYPE (x, r0, y) -> `RISCVUTYPE (x, map_reg r0, y) -| `RISCVJAL (x, r0) -> `RISCVJAL (x, map_reg r0) -| `RISCVJALR (x, r0, r1) -> `RISCVJALR (x, map_reg r0, map_reg r1) -| `RISCVBType (x, r0, r1, y) -> `RISCVBType (x, map_reg r0, map_reg r1, y) -| `RISCVIType (x, r0, r1, y) -> `RISCVIType (x, map_reg r0, map_reg r1, y) -| `RISCVShiftIop (x, r0, r1, y) -> `RISCVShiftIop (x, map_reg r0, map_reg r1, y) -| `RISCVRType (r0, r1, r2, y) -> `RISCVRType (r0, map_reg r1, map_reg r2, y) -| `RISCVLoad (x, r0, r1, y, z, a, b) -> `RISCVLoad (x, map_reg r0, map_reg r1, y, z, a, b) -| `RISCVStore (x, r0, r1, y, z, a) -> `RISCVStore (x, map_reg r0, map_reg r1, y, z, a) -| `RISCVADDIW (x, r0, r1) -> `RISCVADDIW (x, map_reg r0, map_reg r1) -| `RISCVSHIFTW (x, r0, r1, y) -> `RISCVSHIFTW (x, map_reg r0, map_reg r1, y) -| `RISCVRTYPEW (r0, r1, r2, x) -> `RISCVRTYPEW (r0, map_reg r1, map_reg r2, x) -| `RISCVLoadRes (aq, rl, rs1, w, rd) -> `RISCVLoadRes (aq, rl, map_reg rs1, w, map_reg rd) -| `RISCVStoreCon (aq, rl, rs2, rs1, w, rd) -> `RISCVStoreCon (aq, rl, map_reg rs2, map_reg rs1, w, map_reg rd) -| `RISCVAMO (op, aq, rl, rs2, rs1, w, rd) -> `RISCVAMO (op, aq, rl, map_reg rs2, map_reg rs1, w, map_reg rd) diff --git a/risc-v/hgen/parser.hgen b/risc-v/hgen/parser.hgen deleted file mode 100644 index 210e38fb..00000000 --- a/risc-v/hgen/parser.hgen +++ /dev/null @@ -1,74 +0,0 @@ -| UTYPE reg COMMA NUM - { (* it's not clear if NUM here should be before or after filling the - lowest 12 bits with zeros, or if it should be signed or unsigned; - currently assuming: NUM does not include the 12 zeros, and is unsigned *) - if not (iskbituimm 20 $4) then failwith "immediate is not 20bit" - else `RISCVUTYPE ($4, $2, $1.op) } -| JAL reg COMMA NUM - { if not ($4 mod 2 = 0) then failwith "odd offset" - else if not (iskbitsimm 21 $4) then failwith "offset is not 21bit" - else `RISCVJAL ($4, $2) } -| JALR reg COMMA reg COMMA NUM - { if not (iskbitsimm 12 $6) then failwith "offset is not 12bit" - else `RISCVJALR ($6, $4, $2) } -| BTYPE reg COMMA reg COMMA NUM - { if not ($6 mod 2 = 0) then failwith "odd offset" - else if not (iskbitsimm 13 $6) then failwith "offset is not 13bit" - else `RISCVBType ($6, $4, $2, $1.op) } -| ITYPE reg COMMA reg COMMA NUM - { if $1.op <> RISCVSLTIU && not (iskbitsimm 12 $6) then failwith "immediate is not 12bit" - else if $1.op = RISCVSLTIU && not (iskbituimm 12 $6) then failwith "unsigned immediate is not 12bit" - else `RISCVIType ($6, $4, $2, $1.op) } -| ADDIW reg COMMA reg COMMA NUM - { if not (iskbitsimm 12 $6) then failwith "immediate is not 12bit" - else `RISCVADDIW ($6, $4, $2) } -| SHIFTIOP reg COMMA reg COMMA NUM - { if not (iskbituimm 6 $6) then failwith "unsigned immediate is not 6bit" - else `RISCVShiftIop ($6, $4, $2, $1.op) } -| SHIFTW reg COMMA reg COMMA NUM - { if not (iskbituimm 5 $6) then failwith "unsigned immediate is not 5bit" - else `RISCVSHIFTW ($6, $4, $2, $1.op) } -| RTYPE reg COMMA reg COMMA reg - { `RISCVRType ($6, $4, $2, $1.op) } -| LOAD reg COMMA NUM LPAR reg RPAR - { if not (iskbitsimm 12 $4) then failwith "offset is not 12bit" - else `RISCVLoad ($4, $6, $2, $1.unsigned, $1.width, $1.aq, $1.rl) } -| STORE reg COMMA NUM LPAR reg RPAR - { if not (iskbitsimm 12 $4) then failwith "offset is not 12bit" - else `RISCVStore ($4, $2, $6, $1.width, $1.aq, $1.rl) } -| RTYPEW reg COMMA reg COMMA reg - { `RISCVRTYPEW ($6, $4, $2, $1.op) } -| FENCE FENCEOPTION COMMA FENCEOPTION - { match ($2, $4) with - | (Fence_RW, Fence_RW) -> `RISCVFENCE (0b0011, 0b0011) - | (Fence_R, Fence_RW) -> `RISCVFENCE (0b0010, 0b0011) - | (Fence_R, Fence_R) -> `RISCVFENCE (0b0010, 0b0010) - | (Fence_RW, Fence_W) -> `RISCVFENCE (0b0011, 0b0001) - | (Fence_W, Fence_W) -> `RISCVFENCE (0b0001, 0b0001) - | (Fence_RW, Fence_R) -> failwith "'fence rw,r' is not supported" - | (Fence_R, Fence_W) -> failwith "'fence r,w' is not supported" - | (Fence_W, Fence_RW) -> failwith "'fence w,rw' is not supported" - | (Fence_W, Fence_R) -> failwith "'fence w,r' is not supported" - } -| FENCEI - { `RISCVFENCEI } -| LOADRES reg COMMA LPAR reg RPAR - { `RISCVLoadRes ($1.aq, $1.rl, $5, $1.width, $2) } -| LOADRES reg COMMA NUM LPAR reg RPAR - { if $4 <> 0 then failwith "'lr' offset must be 0" else - `RISCVLoadRes ($1.aq, $1.rl, $6, $1.width, $2) } -| STORECON reg COMMA reg COMMA LPAR reg RPAR - { `RISCVStoreCon ($1.aq, $1.rl, $4, $7, $1.width, $2) } -| STORECON reg COMMA reg COMMA NUM LPAR reg RPAR - { if $6 <> 0 then failwith "'sc' offset must be 0" else - `RISCVStoreCon ($1.aq, $1.rl, $4, $8, $1.width, $2) } -| AMO reg COMMA reg COMMA LPAR reg RPAR - { `RISCVAMO ($1.op, $1.aq, $1.rl, $4, $7, $1.width, $2) } -| AMO reg COMMA reg COMMA NUM LPAR reg RPAR - { if $6 <> 0 then failwith "'amo' offset must be 0" else - `RISCVAMO ($1.op, $1.aq, $1.rl, $4, $8, $1.width, $2) } - -/* pseudo-ops */ -| LI reg COMMA NUM - { if not (iskbitsimm 12 $4) then failwith "immediate is not 12bit (li is currently implemented only with small immediate)" - else `RISCVIType ($4, IReg R0, $2, RISCVORI) } diff --git a/risc-v/hgen/pretty.hgen b/risc-v/hgen/pretty.hgen deleted file mode 100644 index fc1c0000..00000000 --- a/risc-v/hgen/pretty.hgen +++ /dev/null @@ -1,30 +0,0 @@ -| `RISCVThreadStart -> "start" -| `RISCVStopFetching -> "stop" -| `RISCVUTYPE(imm, rd, op) -> sprintf "%s %s, %d" (pp_riscv_uop op) (pp_reg rd) imm -| `RISCVJAL(imm, rd) -> sprintf "jal %s, %d" (pp_reg rd) imm -| `RISCVJALR(imm, rs, rd) -> sprintf "jalr %s, %s, %d" (pp_reg rd) (pp_reg rs) imm -| `RISCVBType(imm, rs2, rs1, op) -> sprintf "%s %s, %s, %d" (pp_riscv_bop op) (pp_reg rs1) (pp_reg rs2) imm -| `RISCVIType(imm, rs2, rs1, op) -> sprintf "%s %s, %s, %d" (pp_riscv_iop op) (pp_reg rs1) (pp_reg rs2) imm -| `RISCVShiftIop(imm, rs, rd, op) -> sprintf "%s %s, %s, %d" (pp_riscv_sop op) (pp_reg rd) (pp_reg rs) imm -| `RISCVRType (rs2, rs1, rd, op) -> sprintf "%s %s, %s, %s" (pp_riscv_rop op) (pp_reg rd) (pp_reg rs1) (pp_reg rs2) - -| `RISCVLoad(imm, rs, rd, unsigned, width, aq, rl) -> - sprintf "%s %s, %d(%s)" (pp_riscv_load_op (unsigned, width, aq, rl)) (pp_reg rd) imm (pp_reg rs) - -| `RISCVStore(imm, rs2, rs1, width, aq, rl) -> - sprintf "%s %s, %d(%s)" (pp_riscv_store_op (width, aq, rl)) (pp_reg rs2) imm (pp_reg rs1) - -| `RISCVADDIW(imm, rs, rd) -> sprintf "addiw %s, %s, %d" (pp_reg rd) (pp_reg rs) imm -| `RISCVSHIFTW(imm, rs, rd, op) -> sprintf "%s %s, %s, %d" (pp_riscv_sop op) (pp_reg rd) (pp_reg rs) imm -| `RISCVRTYPEW(rs2, rs1, rd, op) -> sprintf "%s %s, %s, %s" (pp_riscv_ropw op) (pp_reg rd) (pp_reg rs1) (pp_reg rs2) -| `RISCVFENCE(pred, succ) -> sprintf "fence %s, %s" (pp_riscv_fence_option pred) (pp_riscv_fence_option succ) -| `RISCVFENCEI -> sprintf "fence.i" - -| `RISCVLoadRes(aq, rl, rs1, width, rd) -> - sprintf "%s %s, (%s)" (pp_riscv_load_reserved_op (aq, rl, width)) (pp_reg rd) (pp_reg rs1) - -| `RISCVStoreCon(aq, rl, rs2, rs1, width, rd) -> - sprintf "%s %s, %s, (%s)" (pp_riscv_store_conditional_op (aq, rl, width)) (pp_reg rd) (pp_reg rs2) (pp_reg rs1) - -| `RISCVAMO(op, aq, rl, rs2, rs1, width, rd) -> - sprintf "%s %s, %s, (%s)" (pp_riscv_amo_op (op, aq, rl, width)) (pp_reg rd) (pp_reg rs2) (pp_reg rs1) diff --git a/risc-v/hgen/pretty_xml.hgen b/risc-v/hgen/pretty_xml.hgen deleted file mode 100644 index b0306161..00000000 --- a/risc-v/hgen/pretty_xml.hgen +++ /dev/null @@ -1,137 +0,0 @@ -| `RISCVThreadStart -> ("op_thread_start", []) - -| `RISCVStopFetching -> ("op_stop_fetching", []) - -| `RISCVUTYPE(imm, rd, op) -> - ("op_U_type", - [ ("op", pp_riscv_uop op); - ("uimm", sprintf "%d" imm); - ("dest", pp_reg rd); - ]) - -| `RISCVJAL(imm, rd) -> - ("op_jal", - [ ("offset", sprintf "%d" imm); - ("dest", pp_reg rd); - ]) - -| `RISCVJALR(imm, rs1, rd) -> - ("op_jalr", - [ ("offset", sprintf "%d" imm); - ("base", pp_reg rs1); - ("dest", pp_reg rd); - ]) - -| `RISCVBType(imm, rs2, rs1, op) -> - ("op_branch", - [ ("op", pp_riscv_bop op); - ("offset", sprintf "%d" imm); - ("src2", pp_reg rs2); - ("src1", pp_reg rs1); - ]) - -| `RISCVIType(imm, rs1, rd, op) -> - ("op_I_type", - [ ("op", pp_riscv_iop op); - ("iimm", sprintf "%d" imm); - ("src", pp_reg rs1); - ("dest", pp_reg rd); - ]) - -| `RISCVShiftIop(imm, rs1, rd, op) -> - ("op_IS_type", - [ ("op", pp_riscv_sop op); - ("shamt", sprintf "%d" imm); - ("src", pp_reg rs1); - ("dest", pp_reg rd); - ]) - -| `RISCVSHIFTW(imm, rs1, rd, op) -> - ("op_ISW_type", - [ ("op", pp_riscv_sop op); - ("shamt", sprintf "%d" imm); - ("src", pp_reg rs1); - ("dest", pp_reg rd); - ]) - -| `RISCVRType (rs2, rs1, rd, op) -> - ("op_R_type", - [ ("op", pp_riscv_rop op); - ("src2", pp_reg rs2); - ("src1", pp_reg rs1); - ("dest", pp_reg rd); - ]) - -| `RISCVLoad(imm, rs1, rd, unsigned, width, aq, rl) -> - ("op_load", - [ ("aq", if aq then "true" else "false"); - ("rl", if rl then "true" else "false"); - ("width", pp_word_width width); - ("unsigned", if unsigned then "true" else "false"); - ("base", pp_reg rs1); - ("offset", sprintf "%d" imm); - ("dest", pp_reg rd); - ]) - -| `RISCVStore(imm, rs2, rs1, width, aq, rl) -> - ("op_store", - [ ("aq", if aq then "true" else "false"); - ("rl", if rl then "true" else "false"); - ("width", pp_word_width width); - ("src", pp_reg rs2); - ("base", pp_reg rs1); - ("offset", sprintf "%d" imm); - ]) - -| `RISCVADDIW(imm, rs1, rd) -> - ("op_addiw", - [ ("iimm", sprintf "%d" imm); - ("src", pp_reg rs1); - ("dest", pp_reg rd); - ]) - -| `RISCVRTYPEW(rs2, rs1, rd, op) -> - ("op_RW_type", - [ ("op", pp_riscv_ropw op); - ("src2", pp_reg rs2); - ("src1", pp_reg rs1); - ("dest", pp_reg rd); - ]) - -| `RISCVFENCE(pred, succ) -> - ("op_fence", - [ ("pred", pp_riscv_fence_option pred); - ("succ", pp_riscv_fence_option succ); - ]) - -| `RISCVFENCEI -> ("op_fence_i", []) - -| `RISCVLoadRes(aq, rl, rs1, width, rd) -> - ("op_lr", - [ ("aq", if aq then "true" else "false"); - ("rl", if rl then "true" else "false"); - ("width", pp_word_width width); - ("addr", pp_reg rs1); - ("dest", pp_reg rd); - ]) - -| `RISCVStoreCon(aq, rl, rs2, rs1, width, rd) -> - ("op_sc", - [ ("aq", if aq then "true" else "false"); - ("rl", if rl then "true" else "false"); - ("width", pp_word_width width); - ("addr", pp_reg rs1); - ("src", pp_reg rs2); - ("dest", pp_reg rd); - ]) - -| `RISCVAMO(op, aq, rl, rs2, rs1, width, rd) -> - ("op_amo", - [ ("op", pp_riscv_amo_op_part op); - ("aq", if aq then "true" else "false"); - ("rl", if rl then "true" else "false"); - ("width", pp_word_width width); - ("src", pp_reg rs2); - ("addr", pp_reg rs1); - ("dest", pp_reg rd); - ]) diff --git a/risc-v/hgen/sail_trans_out.hgen b/risc-v/hgen/sail_trans_out.hgen deleted file mode 100644 index 2f9a80f1..00000000 --- a/risc-v/hgen/sail_trans_out.hgen +++ /dev/null @@ -1,23 +0,0 @@ -| ("EBREAK", []) -> `RISCVStopFetching -| ("UTYPE", [imm; rd; op]) -> `RISCVUTYPE(translate_out_simm20 imm, translate_out_ireg rd, translate_out_uop op) -| ("JAL", [imm; rd]) -> `RISCVJAL(translate_out_simm21 imm, translate_out_ireg rd) -| ("JALR", [imm; rs; rd]) -> `RISCVJALR(translate_out_simm12 imm, translate_out_ireg rs, translate_out_ireg rd) -| ("BTYPE", [imm; rs2; rs1; op]) -> `RISCVBType(translate_out_simm13 imm, translate_out_ireg rs2, translate_out_ireg rs1, translate_out_bop op) -| ("ITYPE", [imm; rs1; rd; op]) -> `RISCVIType(translate_out_simm12 imm, translate_out_ireg rs1, translate_out_ireg rd, translate_out_iop op) -| ("SHIFTIOP", [imm; rs; rd; op]) -> `RISCVShiftIop(translate_out_imm6 imm, translate_out_ireg rs, translate_out_ireg rd, translate_out_sop op) -| ("RTYPE", [rs2; rs1; rd; op]) -> `RISCVRType (translate_out_ireg rs2, translate_out_ireg rs1, translate_out_ireg rd, translate_out_rop op) -| ("LOAD", [imm; rs; rd; unsigned; width; aq; rl]) - -> `RISCVLoad(translate_out_simm12 imm, translate_out_ireg rs, translate_out_ireg rd, translate_out_bool unsigned, translate_out_wordWidth width, translate_out_bool aq, translate_out_bool rl) -| ("STORE", [imm; rs; rd; width; aq; rl]) - -> `RISCVStore(translate_out_simm12 imm, translate_out_ireg rs, translate_out_ireg rd, translate_out_wordWidth width, translate_out_bool aq, translate_out_bool rl) -| ("ADDIW", [imm; rs; rd]) -> `RISCVADDIW(translate_out_simm12 imm, translate_out_ireg rs, translate_out_ireg rd) -| ("SHIFTW", [imm; rs; rd; op]) -> `RISCVSHIFTW(translate_out_imm5 imm, translate_out_ireg rs, translate_out_ireg rd, translate_out_sop op) -| ("RTYPEW", [rs2; rs1; rd; op]) -> `RISCVRTYPEW(translate_out_ireg rs2, translate_out_ireg rs1, translate_out_ireg rd, translate_out_ropw op) -| ("FENCE", [pred; succ]) -> `RISCVFENCE(translate_out_imm4 pred, translate_out_imm4 succ) -| ("FENCEI", []) -> `RISCVFENCEI -| ("LOADRES", [aq; rl; rs1; width; rd]) - -> `RISCVLoadRes(translate_out_bool aq, translate_out_bool rl, translate_out_ireg rs1, translate_out_wordWidth width, translate_out_ireg rd) -| ("STORECON", [aq; rl; rs2; rs1; width; rd]) - -> `RISCVStoreCon(translate_out_bool aq, translate_out_bool rl, translate_out_ireg rs2, translate_out_ireg rs1, translate_out_wordWidth width, translate_out_ireg rd) -| ("AMO", [op; aq; rl; rs2; rs1; width; rd]) - -> `RISCVAMO(translate_out_amoop op, translate_out_bool aq, translate_out_bool rl, translate_out_ireg rs2, translate_out_ireg rs1, translate_out_wordWidth width, translate_out_ireg rd) diff --git a/risc-v/hgen/shallow_ast_to_herdtools_ast.hgen b/risc-v/hgen/shallow_ast_to_herdtools_ast.hgen deleted file mode 100644 index 3025992e..00000000 --- a/risc-v/hgen/shallow_ast_to_herdtools_ast.hgen +++ /dev/null @@ -1,23 +0,0 @@ -| EBREAK -> `RISCVStopFetching -| UTYPE( imm, rd, op) -> `RISCVUTYPE(translate_out_simm20 imm, translate_out_ireg rd, translate_out_uop op) -| RISCV_JAL( imm, rd) -> `RISCVJAL(translate_out_simm21 imm, translate_out_ireg rd) -| RISCV_JALR( imm, rs, rd) -> `RISCVJALR(translate_out_simm12 imm, translate_out_ireg rs, translate_out_ireg rd) -| BTYPE( imm, rs2, rs1, op) -> `RISCVBType(translate_out_simm13 imm, translate_out_ireg rs2, translate_out_ireg rs1, translate_out_bop op) -| ITYPE( imm, rs1, rd, op) -> `RISCVIType(translate_out_simm12 imm, translate_out_ireg rs1, translate_out_ireg rd, translate_out_iop op) -| SHIFTIOP( imm, rs, rd, op) -> `RISCVShiftIop(translate_out_imm6 imm, translate_out_ireg rs, translate_out_ireg rd, translate_out_sop op) -| RTYPE( rs2, rs1, rd, op) -> `RISCVRType (translate_out_ireg rs2, translate_out_ireg rs1, translate_out_ireg rd, translate_out_rop op) -| LOAD( imm, rs, rd, unsigned, width, aq, rl) - -> `RISCVLoad(translate_out_simm12 imm, translate_out_ireg rs, translate_out_ireg rd, translate_out_bool unsigned, translate_out_wordWidth width, translate_out_bool aq, translate_out_bool rl) -| STORE( imm, rs, rd, width, aq, rl) - -> `RISCVStore(translate_out_simm12 imm, translate_out_ireg rs, translate_out_ireg rd, translate_out_wordWidth width, translate_out_bool aq, translate_out_bool rl) -| ADDIW( imm, rs, rd) -> `RISCVADDIW(translate_out_simm12 imm, translate_out_ireg rs, translate_out_ireg rd) -| SHIFTW( imm, rs, rd, op) -> `RISCVSHIFTW(translate_out_imm5 imm, translate_out_ireg rs, translate_out_ireg rd, translate_out_sop op) -| RTYPEW( rs2, rs1, rd, op) -> `RISCVRTYPEW(translate_out_ireg rs2, translate_out_ireg rs1, translate_out_ireg rd, translate_out_ropw op) -| FENCE( pred, succ) -> `RISCVFENCE(translate_out_imm4 pred, translate_out_imm4 succ) -| FENCEI -> `RISCVFENCEI -| LOADRES( aq, rl, rs1, width, rd) - -> `RISCVLoadRes(translate_out_bool aq, translate_out_bool rl, translate_out_ireg rs1, translate_out_wordWidth width, translate_out_ireg rd) -| STORECON( aq, rl, rs2, rs1, width, rd) - -> `RISCVStoreCon(translate_out_bool aq, translate_out_bool rl, translate_out_ireg rs2, translate_out_ireg rs1, translate_out_wordWidth width, translate_out_ireg rd) -| AMO( op, aq, rl, rs2, rs1, width, rd) - -> `RISCVAMO(translate_out_amoop op, translate_out_bool aq, translate_out_bool rl, translate_out_ireg rs2, translate_out_ireg rs1, translate_out_wordWidth width, translate_out_ireg rd) diff --git a/risc-v/hgen/shallow_types_to_herdtools_types.hgen b/risc-v/hgen/shallow_types_to_herdtools_types.hgen deleted file mode 100644 index 6b3b7f51..00000000 --- a/risc-v/hgen/shallow_types_to_herdtools_types.hgen +++ /dev/null @@ -1,84 +0,0 @@ -let translate_out_big_bit = Sail_values.unsigned - -let translate_out_int inst = (Nat_big_num.to_int (translate_out_big_bit inst)) -let translate_out_signed_int inst bits = - let i = (Nat_big_num.to_int (translate_out_big_bit inst)) in - if (i >= (1 lsl (bits - 1))) then - (i - (1 lsl bits)) else - i - -let translate_out_ireg ireg = IReg (int_to_ireg (translate_out_int ireg)) - -let translate_out_uop op = match op with - | RISCV_LUI -> RISCVLUI - | RISCV_AUIPC -> RISCVAUIPC - -let translate_out_bop op = match op with - | RISCV_BEQ -> RISCVBEQ - | RISCV_BNE -> RISCVBNE - | RISCV_BLT -> RISCVBLT - | RISCV_BGE -> RISCVBGE - | RISCV_BLTU -> RISCVBLTU - | RISCV_BGEU -> RISCVBGEU - -let translate_out_iop op = match op with - | RISCV_ADDI -> RISCVADDI - | RISCV_SLTI -> RISCVSLTI - | RISCV_SLTIU -> RISCVSLTIU - | RISCV_XORI -> RISCVXORI - | RISCV_ORI -> RISCVORI - | RISCV_ANDI -> RISCVANDI - -let translate_out_sop op = match op with - | RISCV_SLLI -> RISCVSLLI - | RISCV_SRLI -> RISCVSRLI - | RISCV_SRAI -> RISCVSRAI - -let translate_out_rop op = match op with - | RISCV_ADD -> RISCVADD - | RISCV_SUB -> RISCVSUB - | RISCV_SLL -> RISCVSLL - | RISCV_SLT -> RISCVSLT - | RISCV_SLTU -> RISCVSLTU - | RISCV_XOR -> RISCVXOR - | RISCV_SRL -> RISCVSRL - | RISCV_SRA -> RISCVSRA - | RISCV_OR -> RISCVOR - | RISCV_AND -> RISCVAND - -let translate_out_ropw op = match op with - | RISCV_ADDW -> RISCVADDW - | RISCV_SUBW -> RISCVSUBW - | RISCV_SLLW -> RISCVSLLW - | RISCV_SRLW -> RISCVSRLW - | RISCV_SRAW -> RISCVSRAW - -let translate_out_amoop op = match op with - | AMOSWAP -> RISCVAMOSWAP - | AMOADD -> RISCVAMOADD - | AMOXOR -> RISCVAMOXOR - | AMOAND -> RISCVAMOAND - | AMOOR -> RISCVAMOOR - | AMOMIN -> RISCVAMOMIN - | AMOMAX -> RISCVAMOMAX - | AMOMINU -> RISCVAMOMINU - | AMOMAXU -> RISCVAMOMAXU - -let translate_out_wordWidth op = match op with - | BYTE -> RISCVBYTE - | HALF -> RISCVHALF - | WORD -> RISCVWORD - | DOUBLE -> RISCVDOUBLE - -let translate_out_bool = function - | Sail_values.B1 -> true - | Sail_values.B0 -> false - | _ -> failwith "translate_out_bool Undef" - -let translate_out_simm21 imm = translate_out_signed_int imm 21 -let translate_out_simm20 imm = translate_out_signed_int imm 20 -let translate_out_simm13 imm = translate_out_signed_int imm 13 -let translate_out_simm12 imm = translate_out_signed_int imm 12 -let translate_out_imm6 imm = translate_out_int imm -let translate_out_imm5 imm = translate_out_int imm -let translate_out_imm4 imm = translate_out_int imm diff --git a/risc-v/hgen/token_types.hgen b/risc-v/hgen/token_types.hgen deleted file mode 100644 index f29e318d..00000000 --- a/risc-v/hgen/token_types.hgen +++ /dev/null @@ -1,23 +0,0 @@ -type token_UTYPE = {op : riscvUop } -type token_JAL = unit -type token_JALR = unit -type token_BType = {op : riscvBop } -type token_IType = {op : riscvIop } -type token_ShiftIop = {op : riscvSop } -type token_RTYPE = {op : riscvRop } -type token_Load = {unsigned: bool; width : wordWidth; aq: bool; rl: bool } -type token_Store = {width : wordWidth; aq: bool; rl: bool } -type token_ADDIW = unit -type token_SHIFTW = {op : riscvSop } -type token_RTYPEW = {op : riscvRopw } -type token_FENCE = unit -type token_FENCEI = unit -type token_LoadRes = {width : wordWidth; aq: bool; rl: bool } -type token_StoreCon = {width : wordWidth; aq: bool; rl: bool } -type token_AMO = {width : wordWidth; aq: bool; rl: bool; op: riscvAmoop } - -type token_FENCEOPTION = Fence_R | Fence_W | Fence_RW - -(* pseudo-ops *) - -type token_LI = unit diff --git a/risc-v/hgen/tokens.hgen b/risc-v/hgen/tokens.hgen deleted file mode 100644 index f812adbd..00000000 --- a/risc-v/hgen/tokens.hgen +++ /dev/null @@ -1,19 +0,0 @@ -%token UTYPE -%token JAL -%token JALR -%token BTYPE -%token ITYPE -%token SHIFTIOP -%token RTYPE -%token LOAD -%token STORE -%token ADDIW -%token SHIFTW -%token RTYPEW -%token FENCE -%token FENCEOPTION -%token FENCEI -%token LOADRES -%token STORECON -%token AMO -%token LI diff --git a/risc-v/hgen/trans_sail.hgen b/risc-v/hgen/trans_sail.hgen deleted file mode 100644 index 8b7cbe11..00000000 --- a/risc-v/hgen/trans_sail.hgen +++ /dev/null @@ -1,153 +0,0 @@ -| `RISCVStopFetching -> ("EBREAK", [], []) -| `RISCVUTYPE(imm, rd, op) -> - ("UTYPE", - [ - translate_imm20 "imm" imm; - translate_reg "rd" rd; - translate_uop "op" op; - ], - []) -| `RISCVJAL(imm, rd) -> - ("JAL", - [ - translate_imm21 "imm" imm; - translate_reg "rd" rd; - ], - []) -| `RISCVJALR(imm, rs, rd) -> - ("JALR", - [ - translate_imm12 "imm" imm; - translate_reg "rs" rd; - translate_reg "rd" rd; - ], - []) -| `RISCVBType(imm, rs2, rs1, op) -> - ("BTYPE", - [ - translate_imm13 "imm" imm; - translate_reg "rs2" rs2; - translate_reg "rs1" rs1; - translate_bop "op" op; - ], - []) -| `RISCVIType(imm, rs1, rd, op) -> - ("ITYPE", - [ - translate_imm12 "imm" imm; - translate_reg "rs1" rs1; - translate_reg "rd" rd; - translate_iop "op" op; - ], - []) -| `RISCVShiftIop(imm, rs, rd, op) -> - ("SHIFTIOP", - [ - translate_imm6 "imm" imm; - translate_reg "rs" rs; - translate_reg "rd" rd; - translate_sop "op" op; - ], - []) -| `RISCVRType (rs2, rs1, rd, op) -> - ("RTYPE", - [ - translate_reg "rs2" rs2; - translate_reg "rs1" rs1; - translate_reg "rd" rd; - translate_rop "op" op; - ], - []) -| `RISCVLoad(imm, rs, rd, unsigned, width, aq, rl) -> - ("LOAD", - [ - translate_imm12 "imm" imm; - translate_reg "rs" rs; - translate_reg "rd" rd; - translate_bool "unsigned" unsigned; - translate_width "width" width; - translate_bool "aq" aq; - translate_bool "rl" rl; - ], - []) -| `RISCVStore(imm, rs2, rs1, width, aq, rl) -> - ("STORE", - [ - translate_imm12 "imm" imm; - translate_reg "rs2" rs2; - translate_reg "rs1" rs1; - translate_width "width" width; - translate_bool "aq" aq; - translate_bool "rl" rl; - ], - []) -| `RISCVADDIW(imm, rs, rd) -> - ("ADDIW", - [ - translate_imm12 "imm" imm; - translate_reg "rs" rs; - translate_reg "rd" rd; - ], - []) -| `RISCVSHIFTW(imm, rs, rd, op) -> - ("SHIFTW", - [ - translate_imm5 "imm" imm; - translate_reg "rs" rs; - translate_reg "rd" rd; - translate_sop "op" op; - ], - []) -| `RISCVRTYPEW(rs2, rs1, rd, op) -> - ("RTYPEW", - [ - translate_reg "rs2" rs2; - translate_reg "rs1" rs1; - translate_reg "rd" rd; - translate_ropw "op" op; - ], - []) -| `RISCVFENCE(pred, succ) -> - ("FENCE", - [ - translate_imm4 "pred" pred; - translate_imm4 "succ" succ; - ], - []) -| `RISCVFENCEI -> - ("FENCEI", - [], - []) -| `RISCVLoadRes(aq, rl, rs1, width, rd) -> - ("LOADRES", - [ - translate_bool "aq" aq; - translate_bool "rl" rl; - translate_reg "rs1" rs1; - translate_width "width" width; - translate_reg "rd" rd; - ], - []) -| `RISCVStoreCon(aq, rl, rs2, rs1, width, rd) -> - ("STORECON", - [ - translate_bool "aq" aq; - translate_bool "rl" rl; - translate_reg "rs2" rs2; - translate_reg "rs1" rs1; - translate_width "width" width; - translate_reg "rd" rd; - ], - []) -| `RISCVAMO(op, aq, rl, rs2, rs1, width, rd) -> - ("AMO", - [ - translate_amoop "op" op; - translate_bool "aq" aq; - translate_bool "rl" rl; - translate_reg "rs2" rs2; - translate_reg "rs1" rs1; - translate_width "width" width; - translate_reg "rd" rd; - ], - []) diff --git a/risc-v/hgen/types.hgen b/risc-v/hgen/types.hgen deleted file mode 100644 index a0b75606..00000000 --- a/risc-v/hgen/types.hgen +++ /dev/null @@ -1,172 +0,0 @@ -type bit20 = int -type bit12 = int -type bit6 = int -type bit5 = int -type bit4 = int - -type riscvUop = (* upper immediate ops *) -| RISCVLUI -| RISCVAUIPC - -let pp_riscv_uop = function -| RISCVLUI -> "lui" -| RISCVAUIPC -> "auipc" - - -type riscvBop = (* branch ops *) -| RISCVBEQ -| RISCVBNE -| RISCVBLT -| RISCVBGE -| RISCVBLTU -| RISCVBGEU - -let pp_riscv_bop = function -| RISCVBEQ -> "beq" -| RISCVBNE -> "bne" -| RISCVBLT -> "blt" -| RISCVBGE -> "bge" -| RISCVBLTU -> "bltu" -| RISCVBGEU -> "bgeu" - -type riscvIop = (* immediate ops *) -| RISCVADDI -| RISCVSLTI -| RISCVSLTIU -| RISCVXORI -| RISCVORI -| RISCVANDI - -let pp_riscv_iop = function -| RISCVADDI -> "addi" -| RISCVSLTI -> "slti" -| RISCVSLTIU -> "sltiu" -| RISCVXORI -> "xori" -| RISCVORI -> "ori" -| RISCVANDI -> "andi" - -type riscvSop = (* shift ops *) -| RISCVSLLI -| RISCVSRLI -| RISCVSRAI - -let pp_riscv_sop = function -| RISCVSLLI -> "slli" -| RISCVSRLI -> "srli" -| RISCVSRAI -> "srai" - -type riscvRop = (* reg-reg ops *) -| RISCVADD -| RISCVSUB -| RISCVSLL -| RISCVSLT -| RISCVSLTU -| RISCVXOR -| RISCVSRL -| RISCVSRA -| RISCVOR -| RISCVAND - -let pp_riscv_rop = function -| RISCVADD -> "add" -| RISCVSUB -> "sub" -| RISCVSLL -> "sll" -| RISCVSLT -> "slt" -| RISCVSLTU -> "sltu" -| RISCVXOR -> "xor" -| RISCVSRL -> "srl" -| RISCVSRA -> "sra" -| RISCVOR -> "or" -| RISCVAND -> "and" - -type riscvRopw = (* reg-reg 32-bit ops *) -| RISCVADDW -| RISCVSUBW -| RISCVSLLW -| RISCVSRLW -| RISCVSRAW - -let pp_riscv_ropw = function -| RISCVADDW -> "addw" -| RISCVSUBW -> "subw" -| RISCVSLLW -> "sllw" -| RISCVSRLW -> "srlw" -| RISCVSRAW -> "sraw" - -type wordWidth = - | RISCVBYTE - | RISCVHALF - | RISCVWORD - | RISCVDOUBLE - -let pp_word_width width : string = - begin match width with - | RISCVBYTE -> "b" - | RISCVHALF -> "h" - | RISCVWORD -> "w" - | RISCVDOUBLE -> "d" - end - -let pp_riscv_load_op (unsigned, width, aq, rl) = - "l" ^ - (pp_word_width width) ^ - (if unsigned then "u" else "") ^ - (if aq then ".aq" else "") ^ - (if rl then ".rl" else "") - -let pp_riscv_store_op (width, aq, rl) = - "s" ^ - (pp_word_width width) ^ - (if aq then ".aq" else "") ^ - (if rl then ".rl" else "") - -let pp_riscv_load_reserved_op (aq, rl, width) = - "lr." ^ - (pp_word_width width) ^ - (if aq then ".aq" else "") ^ - (if rl then ".rl" else "") - -let pp_riscv_store_conditional_op (aq, rl, width) = - "sc." ^ - (pp_word_width width) ^ - (if aq then ".aq" else "") ^ - (if rl then ".rl" else "") - -type riscvAmoop = - | RISCVAMOSWAP - | RISCVAMOADD - | RISCVAMOXOR - | RISCVAMOAND - | RISCVAMOOR - | RISCVAMOMIN - | RISCVAMOMAX - | RISCVAMOMINU - | RISCVAMOMAXU - -let pp_riscv_amo_op_part = function - | RISCVAMOSWAP -> "swap" - | RISCVAMOADD -> "add" - | RISCVAMOXOR -> "xor" - | RISCVAMOAND -> "and" - | RISCVAMOOR -> "or" - | RISCVAMOMIN -> "min" - | RISCVAMOMAX -> "max" - | RISCVAMOMINU -> "minu" - | RISCVAMOMAXU -> "maxu" - -let pp_riscv_amo_op (op, aq, rl, width) = - "amo" ^ - pp_riscv_amo_op_part op ^ - begin match width with - | RISCVWORD -> ".w" - | RISCVDOUBLE -> ".d" - | _ -> assert false - end ^ - (if aq then ".aq" else "") ^ - (if rl then ".rl" else "") - -let pp_riscv_fence_option = function - | 0b0011 -> "rw" - | 0b0010 -> "r" - | 0b0001 -> "w" - | _ -> failwith "unexpected fence option" diff --git a/risc-v/hgen/types_sail_trans_out.hgen b/risc-v/hgen/types_sail_trans_out.hgen deleted file mode 100644 index 66a2020c..00000000 --- a/risc-v/hgen/types_sail_trans_out.hgen +++ /dev/null @@ -1,98 +0,0 @@ -let translate_out_big_bit = function - | (name, Bvector _, bits) -> IInt.integer_of_bit_list bits - | _ -> assert false - -let translate_out_int inst = (Nat_big_num.to_int (translate_out_big_bit inst)) -let translate_out_signed_int inst bits = - let i = (Nat_big_num.to_int (translate_out_big_bit inst)) in - if (i >= (1 lsl (bits - 1))) then - (i - (1 lsl bits)) else - i - -let translate_out_ireg ireg = IReg (int_to_ireg (translate_out_int ireg)) - -let translate_out_simm21 imm = translate_out_signed_int imm 21 -let translate_out_simm20 imm = translate_out_signed_int imm 20 -let translate_out_simm13 imm = translate_out_signed_int imm 13 -let translate_out_simm12 imm = translate_out_signed_int imm 12 -let translate_out_imm6 imm = translate_out_int imm -let translate_out_imm5 imm = translate_out_int imm -let translate_out_imm4 imm = translate_out_int imm - -let translate_out_bool = function - | (name, Bit, [Bitc_one]) -> true - | (name, Bit, [Bitc_zero]) -> false - | _ -> assert false - -let translate_out_enum (name,_,bits) = - Nat_big_num.to_int (IInt.integer_of_bit_list bits) - -let translate_out_wordWidth w = - match translate_out_enum w with - | 0 -> RISCVBYTE - | 1 -> RISCVHALF - | 2 -> RISCVWORD - | 3 -> RISCVDOUBLE - | _ -> failwith "Unknown wordWidth in sail translate out" - -let translate_out_uop op = match translate_out_enum op with - | 0 -> RISCVLUI - | 1 -> RISCVAUIPC - | _ -> failwith "Unknown uop in sail translate out" - -let translate_out_bop op = match translate_out_enum op with -| 0 -> RISCVBEQ -| 1 -> RISCVBNE -| 2 -> RISCVBLT -| 3 -> RISCVBGE -| 4 -> RISCVBLTU -| 5 -> RISCVBGEU -| _ -> failwith "Unknown bop in sail translate out" - -let translate_out_iop op = match translate_out_enum op with -| 0 -> RISCVADDI -| 1 -> RISCVSLTI -| 2 -> RISCVSLTIU -| 3 -> RISCVXORI -| 4 -> RISCVORI -| 5 -> RISCVANDI -| _ -> failwith "Unknown iop in sail translate out" - -let translate_out_sop op = match translate_out_enum op with -| 0 -> RISCVSLLI -| 1 -> RISCVSRLI -| 2 -> RISCVSRAI -| _ -> failwith "Unknown sop in sail translate out" - -let translate_out_rop op = match translate_out_enum op with -| 0 -> RISCVADD -| 1 -> RISCVSUB -| 2 -> RISCVSLL -| 3 -> RISCVSLT -| 4 -> RISCVSLTU -| 5 -> RISCVXOR -| 6 -> RISCVSRL -| 7 -> RISCVSRA -| 8 -> RISCVOR -| 9 -> RISCVAND -| _ -> failwith "Unknown rop in sail translate out" - -let translate_out_ropw op = match translate_out_enum op with -| 0 -> RISCVADDW -| 1 -> RISCVSUBW -| 2 -> RISCVSLLW -| 3 -> RISCVSRLW -| 4 -> RISCVSRAW -| _ -> failwith "Unknown ropw in sail translate out" - -let translate_out_amoop op = match translate_out_enum op with -| 0 -> RISCVAMOSWAP -| 1 -> RISCVAMOADD -| 2 -> RISCVAMOXOR -| 3 -> RISCVAMOAND -| 4 -> RISCVAMOOR -| 5 -> RISCVAMOMIN -| 6 -> RISCVAMOMAX -| 7 -> RISCVAMOMINU -| 8 -> RISCVAMOMAXU -| _ -> failwith "Unknown amoop in sail translate out" diff --git a/risc-v/hgen/types_trans_sail.hgen b/risc-v/hgen/types_trans_sail.hgen deleted file mode 100644 index 238c7e5b..00000000 --- a/risc-v/hgen/types_trans_sail.hgen +++ /dev/null @@ -1,57 +0,0 @@ -let translate_enum enum_values name value = - let rec bit_count n = - if n = 0 then 0 - else 1 + (bit_count (n lsr 1)) in - let rec find_index element = function - | h::tail -> if h = element then 0 else 1 + (find_index element tail) - | _ -> failwith "translate_enum could not find value" - in - let size = bit_count (List.length enum_values) in - let index = find_index value enum_values in - (name, Range0 (Some size), IInt.bit_list_of_integer size (Nat_big_num.of_int index)) - -let translate_uop = translate_enum [RISCVLUI; RISCVAUIPC] - -let translate_bop = translate_enum [RISCVBEQ; RISCVBNE; RISCVBLT; RISCVBGE; RISCVBLTU; RISCVBGEU] (* branch ops *) - -let translate_iop = translate_enum [RISCVADDI; RISCVSLTI; RISCVSLTIU; RISCVXORI; RISCVORI; RISCVANDI] (* immediate ops *) - -let translate_sop = translate_enum [RISCVSLLI; RISCVSRLI; RISCVSRAI] (* shift ops *) - -let translate_rop = translate_enum [RISCVADD; RISCVSUB; RISCVSLL; RISCVSLT; RISCVSLTU; RISCVXOR; RISCVSRL; RISCVSRA; RISCVOR; RISCVAND] (* reg-reg ops *) - -let translate_ropw = translate_enum [RISCVADDW; RISCVSUBW; RISCVSLLW; RISCVSRLW; RISCVSRAW] (* reg-reg 32-bit ops *) - -let translate_amoop = translate_enum [RISCVAMOSWAP; RISCVAMOADD; RISCVAMOXOR; RISCVAMOAND; RISCVAMOOR; RISCVAMOMIN; RISCVAMOMAX; RISCVAMOMINU; RISCVAMOMAXU] - -let translate_width = translate_enum [RISCVBYTE; RISCVHALF; RISCVWORD; RISCVDOUBLE] - -let translate_reg name value = - (name, Bvector (Some 5), bit_list_of_integer 5 (Nat_big_num.of_int (reg_to_int value))) - -let translate_imm21 name value = - (name, Bvector (Some 21), bit_list_of_integer 21 (Nat_big_num.of_int value)) - -let translate_imm20 name value = - (name, Bvector (Some 20), bit_list_of_integer 20 (Nat_big_num.of_int value)) - -let translate_imm16 name value = - (name, Bvector (Some 16), bit_list_of_integer 16 (Nat_big_num.of_int value)) - -let translate_imm13 name value = - (name, Bvector (Some 13), bit_list_of_integer 13 (Nat_big_num.of_int value)) - -let translate_imm12 name value = - (name, Bvector (Some 12), bit_list_of_integer 12 (Nat_big_num.of_int value)) - -let translate_imm6 name value = - (name, Bvector (Some 6), bit_list_of_integer 6 (Nat_big_num.of_int value)) - -let translate_imm5 name value = - (name, Bvector (Some 5), bit_list_of_integer 5 (Nat_big_num.of_int value)) - -let translate_imm4 name value = - (name, Bvector (Some 4), bit_list_of_integer 4 (Nat_big_num.of_int value)) - -let translate_bool name value = - (name, Bit, [if value then Bitc_one else Bitc_zero]) -- cgit v1.2.3 From 5fa993caef3c48da36f641bf3608a9515ecc40cf Mon Sep 17 00:00:00 2001 From: Shaked Flur Date: Mon, 4 Dec 2017 14:54:54 +0000 Subject: match what rmem expects from sail/arm --- arm/Makefile | 59 +- arm/aarch64_regfp.sail | 598 +++++++++++ arm/armV8.h.sail | 24 + arm/armV8.sail | 157 ++- arm/armV8_A64_lib.sail | 18 +- arm/armV8_A64_sys_regs.sail | 200 +--- arm/armV8_common_lib.sail | 10 +- arm/armV8_extras.lem | 77 ++ arm/armV8_extras_embed.lem | 59 ++ arm/armV8_extras_embed_sequential.lem | 59 ++ arm/armV8_lib.h.sail | 5 +- arm/gen/ast.hgen | 44 + arm/gen/fold.hgen | 44 + arm/gen/herdtools_ast_to_shallow_ast.hgen | 335 ++++++ arm/gen/herdtools_types_to_shallow_types.hgen | 153 +++ arm/gen/lexer.hgen | 309 ++++++ arm/gen/map.hgen | 44 + arm/gen/parser.hgen | 1396 +++++++++++++++++++++++++ arm/gen/pretty.hgen | 393 +++++++ arm/gen/regs_out_in.hgen | 155 +++ arm/gen/sail_trans_out.hgen | 326 ++++++ arm/gen/shallow_ast_to_herdtools_ast.hgen | 326 ++++++ arm/gen/shallow_types_to_herdtools_types.hgen | 154 +++ arm/gen/token_types.hgen | 85 ++ arm/gen/tokens.hgen | 78 ++ arm/gen/trans_sail.hgen | 379 +++++++ arm/gen/types.hgen | 90 ++ arm/gen/types_sail_trans_out.hgen | 189 ++++ arm/gen/types_trans_sail.hgen | 119 +++ 29 files changed, 5623 insertions(+), 262 deletions(-) create mode 100644 arm/aarch64_regfp.sail create mode 100644 arm/armV8_extras.lem create mode 100644 arm/armV8_extras_embed.lem create mode 100644 arm/armV8_extras_embed_sequential.lem create mode 100644 arm/gen/ast.hgen create mode 100644 arm/gen/fold.hgen create mode 100644 arm/gen/herdtools_ast_to_shallow_ast.hgen create mode 100644 arm/gen/herdtools_types_to_shallow_types.hgen create mode 100644 arm/gen/lexer.hgen create mode 100644 arm/gen/map.hgen create mode 100644 arm/gen/parser.hgen create mode 100644 arm/gen/pretty.hgen create mode 100644 arm/gen/regs_out_in.hgen create mode 100644 arm/gen/sail_trans_out.hgen create mode 100644 arm/gen/shallow_ast_to_herdtools_ast.hgen create mode 100644 arm/gen/shallow_types_to_herdtools_types.hgen create mode 100644 arm/gen/token_types.hgen create mode 100644 arm/gen/tokens.hgen create mode 100644 arm/gen/trans_sail.hgen create mode 100644 arm/gen/types.hgen create mode 100644 arm/gen/types_sail_trans_out.hgen create mode 100644 arm/gen/types_trans_sail.hgen diff --git a/arm/Makefile b/arm/Makefile index 18eba393..d7124df6 100644 --- a/arm/Makefile +++ b/arm/Makefile @@ -1,16 +1,5 @@ -BUILDDIR=./build - -SAIL=../sail -ifeq ("$(wildcard $(SAIL))","") - $(warning can not find Sail) -endif - -LEM=../../lem/lem -ifeq ("$(wildcard $(LEM))","") - $(warning can not find Lem) -endif - -LEMINTERPDIR=../src/lem_interp/ +SAIL:=../src/sail.native +LEM:=../../lem/lem # the order of the files is important SOURCES=armV8.h.sail\ @@ -23,39 +12,28 @@ SOURCES=armV8.h.sail\ armV8_A64_lib.sail\ armV8.sail -all: $(BUILDDIR)/armv8.ml - -clean: - rm -rf $(BUILDDIR) - -ocaml: $(BUILDDIR)/armv8_embed.ml +all: armV8.lem armV8.ml armV8_embed.lem -.PHONY: all clean ocaml +armV8.lem: $(SOURCES) + $(SAIL) -lem_ast -o armV8 $(SOURCES) -$(BUILDDIR): - mkdir -p $@ +armV8.ml: armV8.lem ../src/lem_interp/interp_ast.lem + $(LEM) -ocaml -lib ../src/lem_interp/ $< -$(BUILDDIR)/armv8.lem: $(SOURCES) | $(BUILDDIR) - $(SAIL) -lem_ast $(SOURCES) -o $(basename $@) -# sail generates the .lem file in pwd - mv $(notdir $@) $@ -$(BUILDDIR)/armv8.ml: $(BUILDDIR)/armv8.lem - $(LEM) -ocaml -lib $(LEMINTERPDIR) $< - -$(BUILDDIR)/armv8_embed.ml: $(SOURCES) | $(BUILDDIR) - $(SAIL) -ocaml $(SOURCES) -o $(basename $@) -# sail generates the .lem file in pwd - mv $(notdir $@) $@ +armV8_embed.lem: $(SOURCES) ../etc/regfp.sail aarch64_regfp.sail +# also generates armV8_embed_sequential.lem, armV8_embed_types.lem, armV8_toFromInterp.lem + $(SAIL) -lem -lem_lib ArmV8_extras_embed -o armV8 $^ +clean: + rm -f armV8.lem armV8.ml + rm -f armV8_embed*.lem armV8_toFromInterp.lem ###################################################################### ETCDIR=../etc apply_header: - -chmod u+w *.sail headache -c $(ETCDIR)/headache_config -h $(ETCDIR)/arm_header *.sail - chmod a-w *.sail .PHONY: apply_header @@ -63,10 +41,13 @@ apply_header: IDLARM=../../../rsem/idlarm pull_from_idlarm: - svn up $(IDLARM) - $(MAKE) -C $(IDLARM) - -chmod u+w *.sail + $(MAKE) -C $(IDLARM) clean + $(MAKE) -C $(IDLARM) san_sail rm -f *.sail cp -a $(IDLARM)/build/*.sail ./ - chmod a-w *.sail + cp -a $(IDLARM)/armV8_extras_embed.lem ./ + cp -a $(IDLARM)/armV8_extras_embed_sequential.lem ./ + cp -a $(IDLARM)/armV8_extras.lem ./ + mkdir -p gen + cp -a $(IDLARM)/*.hgen gen/ $(MAKE) apply_header diff --git a/arm/aarch64_regfp.sail b/arm/aarch64_regfp.sail new file mode 100644 index 00000000..148f9646 --- /dev/null +++ b/arm/aarch64_regfp.sail @@ -0,0 +1,598 @@ +(*========================================================================*) +(* *) +(* Copyright (c) 2015-2017 Shaked Flur *) +(* Copyright (c) 2015-2017 Kathyrn Gray *) +(* All rights reserved. *) +(* *) +(* This software was developed by the University of Cambridge Computer *) +(* Laboratory as part of the Rigorous Engineering of Mainstream Systems *) +(* (REMS) project, funded by EPSRC grant EP/K008528/1. *) +(* *) +(* Redistribution and use in source and binary forms, with or without *) +(* modification, are permitted provided that the following conditions *) +(* are met: *) +(* 1. Redistributions of source code must retain the above copyright *) +(* notice, this list of conditions and the following disclaimer. *) +(* 2. Redistributions in binary form must reproduce the above copyright *) +(* notice, this list of conditions and the following disclaimer in *) +(* the documentation and/or other materials provided with the *) +(* distribution. *) +(* *) +(* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' *) +(* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *) +(* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *) +(* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR *) +(* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *) +(* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *) +(* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF *) +(* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND *) +(* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, *) +(* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT *) +(* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF *) +(* SUCH DAMAGE. *) +(*========================================================================*) + +function instruction_kind rmem_kind ((AccType) acctype, (bool) exclusive) = + if exclusive then + switch acctype { + case AccType_ATOMIC -> IK_mem_read(Read_exclusive) + case AccType_ORDERED -> IK_mem_read(Read_exclusive_acquire) + case _ -> { not_implemented("unimplemented memory access"); + IK_mem_read(Read_exclusive); } + } + else + switch acctype { + case AccType_NORMAL -> IK_mem_read(Read_plain) + case AccType_ATOMIC -> IK_mem_read(Read_plain) + case AccType_STREAM -> IK_mem_read(Read_stream) + case AccType_UNPRIV -> IK_mem_read(Read_plain) + case AccType_ORDERED -> IK_mem_read(Read_acquire) + } + + +function instruction_kind wmem_kind ((AccType) acctype, (bool) exclusive) = + if exclusive then { + switch acctype { + case AccType_ATOMIC -> IK_mem_write(Write_exclusive) + case AccType_ORDERED -> IK_mem_write(Write_exclusive_release) + case _ -> { not_implemented("unimplemented memory access"); + IK_mem_write(Write_exclusive); } + } + } else { + switch acctype { + case AccType_NORMAL -> IK_mem_write(Write_plain) + case AccType_STREAM -> IK_mem_write(Write_plain) + case AccType_UNPRIV -> IK_mem_write(Write_plain) + case AccType_ORDERED -> IK_mem_write(Write_release) + case _ -> { not_implemented("unimplemented memory access"); + IK_mem_write(Write_plain) } + }; + } + + +let (vector<30,31,dec,string>) _Rs = + ["R30","R29","R28","R27","R26","R25","R24","R23","R22","R21", + "R20","R19","R18","R17","R16","R15","R14","R13","R12","R11", + "R10","R9" ,"R8" ,"R7" ,"R6" ,"R5" ,"R4" ,"R3" ,"R2" ,"R1" , + "R0"] + +let TxNestingLevelfp = RFull("TxNestingLevel") +let TXIDR_EL0_DEPTHfp = RField("TXIDR_EL0","DEPTH") + +let PSTATE_Nfp = RField("NZCV","N") +let PSTATE_Zfp = RField("NZCV","Z") +let PSTATE_Cfp = RField("NZCV","C") +let PSTATE_Vfp = RField("NZCV","V") +let PSTATE_Dfp = RField("DAIF","D") +let PSTATE_Afp = RField("DAIF","A") +let PSTATE_Ifp = RField("DAIF","I") +let PSTATE_Ffp = RField("DAIF","F") +let PSTATE_ELfp = RFull("CurrentEL") +let PSTATE_SPfp = RField("SPSel","SP") +let _PCfp = RFull("_PC") + +let NZCVfp = [|| PSTATE_Nfp, PSTATE_Zfp, PSTATE_Cfp, PSTATE_Vfp ||] + +function regfps xFP((reg_index) n) = + if n != 31 then [||RFull(_Rs[n])||] else [|| ||] + + +(* check if this is still what we want *) +function forall Nat 'N, 'N IN {32,64}. (regfps,regfps) BranchToFP (iR,oR) = + (if UsingAArch32() then iR else PSTATE_ELfp :: iR, _PCfp :: oR) + +function regfps ConditionHoldsIFP((bit[4]) _cond) = + switch _cond[3..1] { + case 0b000 -> [|| PSTATE_Zfp ||] + case 0b001 -> [|| PSTATE_Cfp ||] + case 0b010 -> [|| PSTATE_Nfp ||] + case 0b011 -> [|| PSTATE_Vfp ||] + case 0b100 -> [|| PSTATE_Cfp, PSTATE_Zfp ||] + case 0b101 -> [|| PSTATE_Nfp, PSTATE_Vfp ||] + case 0b110 -> [|| PSTATE_Nfp, PSTATE_Vfp, PSTATE_Zfp ||] + case 0b111 -> [|| ||] + } + +(* for iR if rSPFP, for oR if wSPFP *) +let rSPIFP = + (* TODO: actually this depends on runtime data: PSTATE_SP and PSTATE_EL *) + [|| PSTATE_SPfp, RFull("SP_EL0") ||] + +let wSPFP = + (* TODO: actually this depends on runtime data: PSTATE_SP and PSTATE_EL *) + ([|| PSTATE_SPfp ||], + [|| RFull("SP_EL0") ||]) + + +let CheckSPAlignmentIFP = PSTATE_ELfp :: rSPIFP + +let BigEndianIFP = + if UsingAArch32() then [|| RFull("PSTATE_E") ||] else [|| PSTATE_ELfp ||] + +let wMem'IFP = BigEndianIFP +let wMemIFP = wMem'IFP + +function (regfps,regfps,regfps,niafps,diafp,instruction_kind) effect pure initial_analysis (instr) = { + iR := [|| ||]; + oR := [|| ||]; + aR := [|| ||]; + Nias := [|| NIAFP_successor ||]; + Dia := DIAFP_none; + ik := IK_simple; + + switch instr { + case (TMStart(t)) -> { + iR := TxNestingLevelfp :: TXIDR_EL0_DEPTHfp :: iR; + (* TODO: whether the following applies depends on runtime data: + ~(TxNestingLevel >= TXIDR_EL0.DEPTH) *) + oR := TxNestingLevelfp :: append(oR,xFP(t)); + ik := IK_trans(Transaction_start); + } + case (TMCommit) -> { + iR := TxNestingLevelfp :: iR; + oR := TxNestingLevelfp :: oR; + ik := IK_trans(Transaction_commit); + } + case (TMAbort(retry,reason)) -> { + iR := TxNestingLevelfp :: iR; + ik := IK_trans(Transaction_abort); + } + case (TMTest) -> { + iR := TxNestingLevelfp :: iR; + oR := RFull("NZCV") :: oR; + } + case (CompareAndBranch(t,datasize,iszero,offset)) -> { + iR := append(iR,xFP(t)); + (* TODO: whether the following applies depends on runtime data: + IsZero(operand1) *) + let (i,o) = BranchToFP(iR,oR) in {iR := i; oR := o}; + (bit[64]) nia' := rPC() + offset; + Nias := [|| NIAFP_successor, NIAFP_concrete_address(nia') ||]; + ik := IK_cond_branch; + } + case (BranchConditional(offset,condition)) -> { + iR := append(iR,ConditionHoldsIFP(condition)); + (* TODO: whether the following applies depends on runtime data: + ConditionHolds(condition) *) + let (i,o) = BranchToFP(iR,oR) in {iR := i; oR := o}; + Nias := [|| NIAFP_successor, NIAFP_concrete_address(rPC() + offset) ||]; + ik := IK_cond_branch; + } + case (GenerateExceptionEL1(imm)) -> not_implemented("GenerateExceptionEL1") + case (GenerateExceptionEL2(imm)) -> not_implemented("GenerateExceptionEL2") + case (GenerateExceptionEL3(imm)) -> not_implemented("GenerateExceptionEL3") + case (DebugBreakpoint(comment)) -> not_implemented("DebugBreakpoint") + case (ExternalDebugBreakpoint) -> not_implemented("ExternalDebugBreakpoint") + case (DebugSwitchToExceptionLevel(target_level)) -> not_implemented("DebugSwitchToExceptionLevel") + case (MoveSystemImmediate(operand,field)) -> + switch field { + case PSTATEField_SP -> oR := PSTATE_SPfp :: oR + case PSTATEField_DAIFSet -> { + iR := append(iR, [|| PSTATE_Dfp, PSTATE_Afp, PSTATE_Ifp, PSTATE_Ffp ||]); + oR := append(oR, [|| PSTATE_Dfp, PSTATE_Afp, PSTATE_Ifp, PSTATE_Ffp ||]); + } + case PSTATEField_DAIFClr -> { + iR := append(iR, [|| PSTATE_Dfp, PSTATE_Afp, PSTATE_Ifp, PSTATE_Ffp ||]); + oR := append(oR, [|| PSTATE_Dfp, PSTATE_Afp, PSTATE_Ifp, PSTATE_Ffp ||]); + } + } + case (Hint(op)) -> + switch op { + case SystemHintOp_YIELD -> () + case SystemHintOp_WFE -> { + if EventRegistered() then () (* ClearEventRegister *) + else { + (* the execute code for this case always fails because of + WaitForEvent, declared as extern but not defined *) + not_implemented("Hint(SystemHintOp_WFE);") + } + } + case SystemHintOp_WFI -> { + (* the execute code for this case always fails because of + InterruptPending, declared as extern but not defined *) + not_implemented("Hint(SystemHintOp_WFI);") + } + case SystemHintOp_SEV -> () (*SendEvent*) + case SystemHintOp_SEVL -> + (* the execute code for this case always fails because of + EventRegisterSet, declared as extern but not defined *) + not_implemented("Hint(SystemHintOp_SEVL);") + case _ -> () (* do nothing *) + } + case (ClearExclusiveMonitor(imm)) -> () (*ClearExclusiveLocal*) + case (Barrier(op,domain,types)) -> { + ik := switch op { + case MemBarrierOp_DSB -> + switch types { + case MBReqTypes_Reads -> IK_barrier(Barrier_DSB_LD) + case MBReqTypes_Writes -> IK_barrier(Barrier_DSB_ST) + case MBReqTypes_All -> IK_barrier(Barrier_DSB) + } + case MemBarrierOp_DMB -> + switch types { + case MBReqTypes_Reads -> IK_barrier(Barrier_DMB_LD) + case MBReqTypes_Writes -> IK_barrier(Barrier_DMB_ST) + case MBReqTypes_All -> IK_barrier(Barrier_DMB) + } + case MemBarrierOp_ISB -> + IK_barrier(Barrier_ISB) + }; + } + case (System(t,sys_op0,sys_op1,sys_op2,sys_crn,sys_crm,has_result)) -> { + oR := append(oR,xFP(t)); + not_implemented("System"); (* because SysOp_R and SysOp_W *) + } + case (MoveSystemRegister(t,sys_op0,sys_op1,sys_op2,sys_crn,sys_crm,read)) -> { + if read then { + oR := append(oR,xFP(t)); + switch (sys_op0,sys_op1,sys_crn,sys_crm,sys_op2) { (* System_Get *) + case (3,3,4,2,0) -> iR := RFull("NZCV") :: iR + case (3,3,4,2,1) -> iR := RFull("DAIF") :: iR + case (3, 3, 13, 0, 2) -> iR := RFull("TPIDR_EL0") :: iR + (* TODO FIXME: higher EL TPIDRs *) + } + } + else { + iR := append(iR,xFP(t)); + switch (sys_op0,sys_op1,sys_crn,sys_crm,sys_op2) { (* System_Put *) + case (3,3,4,2,0) -> oR := RFull("NZCV") :: oR + case (3,3,4,2,1) -> oR := RFull("DAIF") :: oR + case (3, 3, 13, 0, 2) -> oR := RFull("TPIDR_EL0") :: oR + (* TODO FIXME: higher EL TPIDRs *) + } + } + } + case (ImplementationDefinedTestBeginEnd(isEnd)) -> () + case (ImplementationDefinedStopFetching) -> () + case (ImplementationDefinedThreadStart) -> () + case (TestBitAndBranch(t,datasize,bit_pos,bit_val,offset)) -> { + iR := append(xFP(t),iR); + (* TODO: whether the following applies depends on runtime data: + operand[bit_pos] == bit_val *) + let (i,o) = BranchToFP(iR,oR) in {iR := i; oR := o}; + Nias := [|| NIAFP_successor, NIAFP_concrete_address(rPC() + offset) ||]; + ik := IK_cond_branch; + } + case (BranchImmediate(branch_type,offset)) -> { + if branch_type == BranchType_CALL + then {iR := _PCfp :: iR; oR := append(xFP(30),oR)}; + let (i,o) = BranchToFP(iR,oR) in {iR := i; oR := o}; + Nias := [|| NIAFP_concrete_address(rPC() + offset) ||]; + ik := IK_simple (* IK_uncond_branch *) + } + case (BranchRegister(n,branch_type)) -> { + iR := append(iR,xFP(n)); + if branch_type == BranchType_CALL + then {iR := _PCfp :: iR; oR := append(xFP(30),oR)}; + let (i,o) = BranchToFP(iR,oR) in {iR := i; oR := o}; + Nias := if n ==31 + then [|| NIAFP_concrete_address(0) ||] + else [|| NIAFP_register(RFull(_Rs[n]))||]; + ik := IK_simple (* IK_uncond_branch *) + } + case (ExceptionReturn) -> not_implemented("ExceptionReturn") + case (DebugRestorePState) -> not_implemented("DebugRestorePState") + case (LoadLiteral(t,memop,_signed,size,offset,datasize)) -> { + (* assuming rMem doesn't touch other registers *) + iR := _PCfp :: iR; + oR := append(xFP(t),oR); + aR := _PCfp :: aR; + switch memop { + case MemOp_LOAD -> ik := IK_mem_read(Read_plain) + case MemOp_PREFETCH -> {ik := IK_simple; aR := [|| ||]} + } + } + case (LoadStoreAcqExc(n,t,t2,s,acctype,excl,pair,memop,elsize,regsize,datasize)) -> { + (boolean) rt_unknown := false; + (boolean) rn_unknown := false; + if n==31 then { + iR := append(CheckSPAlignmentIFP,iR); + iR := append(rSPIFP,iR); + aR := append(rSPIFP,aR); + } + else if rn_unknown then () + else { + iR := append(xFP(n),iR); + aR := append(xFP(n),aR); + }; + switch memop { + case MemOp_STORE -> { + if rt_unknown then () + else if pair then iR := append(xFP(t),append(xFP(t2),iR)) + else iR := append(xFP(t),iR); + if excl then { + (* TODO: the command below depends on runtime data: + AArch64_ExclusiveMonitorsPass(address, dbytes) *) + iR := append(iR,wMemIFP); + oR := append(xFP(s),oR); + ik := wmem_kind(acctype,true); + } + else { + iR := append(iR,wMemIFP); + ik := wmem_kind(acctype,false); + } + } + case MemOp_LOAD -> { + if pair then { + if rt_unknown then + oR := append(xFP(t),oR) + else if elsize == 32 then { + iR := append(iR,BigEndianIFP); + oR := append(xFP(t),append(xFP(t2),oR)); + } + else { + oR := append(xFP(t),append(xFP(t2),oR)) + }; + ik := rmem_kind(acctype,true); + } + else { + oR := append(xFP(t),oR); + ik := rmem_kind(acctype,excl); + } + + } + case MemOp_PREFETCH -> aR := [|| ||] + } + } + case (LoadStorePairNonTemp(wback,postindex,n,t,t2,acctype,memop,scale,datasize,offset)) -> { + (boolean) rt_unknown := false; + if n == 31 then { + iR := append(CheckSPAlignmentIFP,iR); + iR := append(rSPIFP,iR); + aR := append(rSPIFP,aR); + } + else { + iR := append(xFP(n),iR); + aR := append(xFP(n),aR); + }; + if wback then { + if n == 31 then + let (i,o) = wSPFP in { + iR := append(i,iR); + oR := append(o,oR); + } + else + oR := append(xFP(n),oR); + }; + switch memop { + case MemOp_STORE -> { + if rt_unknown & t == n then () + else iR := append(xFP(t),iR); + if rt_unknown & t2 == n then () + else iR := append(xFP(t2),iR); + iR := append(wMemIFP,iR); + ik := wmem_kind(acctype,false); + } + case MemOp_LOAD -> { + oR := append(xFP(t),append(xFP(t2),oR)); + ik := rmem_kind(acctype,false); + } + } + } + case (LoadImmediate(n,t,acctype,memop,_signed,wback,postindex,offset,regsize,datasize)) -> { + (boolean) wb_unknown := false; + (boolean) rt_unknown := false; + if n == 31 then { + iR := append(CheckSPAlignmentIFP,iR); + iR := append(rSPIFP,iR); + aR := append(rSPIFP,aR); + } + else { + iR := append(xFP(n),iR); + aR := append(xFP(n),aR); + }; + if wback then { + if n == 31 then + let (i,o) = wSPFP in {iR := append(i,iR); oR := append(o,oR)} + else oR := append(xFP(n),oR); + }; + switch memop { + case MemOp_STORE -> { + if rt_unknown then () + else iR := append(xFP(t),iR); + iR := append(wMemIFP,iR); + ik := wmem_kind(acctype,false); + } + case MemOp_LOAD -> { + oR := append(xFP(t),oR); + ik := rmem_kind(acctype,false); + } + case MemOp_PREFETCH -> aR := [|| ||] + } + } + case (LoadRegister(n,t,m,acctype,memop,_signed,wback,postindex,extend_type,shift,regsize,datasize)) -> { + iR := append(xFP(m),iR); + aR := append(xFP(m),aR); + (boolean) wb_unknown := false; + (boolean) rt_unknown := false; + if n == 31 then { + iR := append(CheckSPAlignmentIFP,iR); + iR := append(rSPIFP,iR); + aR := append(rSPIFP,aR); + } + else { + iR := append(xFP(n),iR); + aR := append(xFP(n),aR); + }; + if wback then { + if n == 31 then let (i,o) = wSPFP in {iR := append(i,iR); oR := append(o,oR)} + else oR := append(xFP(n),oR); + }; + switch memop { + case MemOp_STORE -> { + if rt_unknown then () + else iR := append(xFP(t),iR); + iR := append(wMemIFP,iR); + ik := wmem_kind(acctype,false); + } + case MemOp_LOAD -> { + oR := append(xFP(t),oR); + ik := rmem_kind(acctype,false); + } + case MemOp_PREFETCH -> aR := [|| ||] + } + } + case (LoadStorePair(wback,postindex,n,t,t2,acctype,memop,_signed,datasize,offset)) -> { + (boolean) rt_unknown := false; + (boolean) wb_unknown := false; + if n == 31 then { + iR := append(CheckSPAlignmentIFP,iR); + iR := append(rSPIFP,iR); + aR := append(rSPIFP,aR); + } + else { + iR := append(xFP(n),iR); + aR := append(xFP(n),aR); + }; + if wback then { + if n == 31 then let (i,o) = wSPFP in {iR := append(i,iR); oR := append(o,oR)} + else oR := append(xFP(n),oR); + }; + switch memop { + case MemOp_STORE -> { + if rt_unknown & t == n then () + else iR := append(xFP(t),iR); + if rt_unknown & t2 == n then () + else iR := append(xFP(t2),iR); + iR := append(wMemIFP,iR); + ik := wmem_kind(acctype,false); + } + case MemOp_LOAD -> { + oR := append(xFP(t),oR); + oR := append(xFP(t2),oR); + ik := rmem_kind(acctype,false); + } + } + } + case (AddSubImmediate(d,n,datasize,sub_op,setflags,imm)) -> { + iR := append(if n == 31 then rSPIFP else xFP(n),iR); + if setflags then oR := append(NZCVfp,oR); + if d ==31 & ~(setflags) then + let (i,o) = wSPFP in + { iR := append(i,iR); + oR := append(o,oR) } + else oR := append(xFP(d),oR) + } + case (BitfieldMove(d,n,datasize,inzero,extend,R,S,wmask,tmask)) -> { + if inzero then () else iR:= append(xFP(d),iR); + iR := append(xFP(n),iR); + oR := append(xFP(d),oR); + } + case (ExtractRegister(d,n,m,datasize,lsb)) -> { + iR := append(xFP(n),append(xFP(m),iR)); + oR := append(xFP(d),oR); + } + case (LogicalImmediate(d,n,datasize,setflags,op,imm)) -> { + iR := append(xFP(n),iR); + if setflags then oR := append(NZCVfp,oR); + if d ==31 & ~(setflags) then let (i,o) = wSPFP in + { iR := append(i,iR); oR := append(o,oR) } + else oR := append(xFP(d),oR) + } + case (MoveWide(d,datasize,imm,pos,opcode)) -> { + if opcode == MoveWideOp_K then iR := append(xFP(d),iR); + oR := append(xFP(d),oR); + } + case (Address(d,page,imm)) -> { + iR := _PCfp :: iR; + oR := append(xFP(d),oR); + } + case (AddSubExtendRegister(d,n,m,datasize,sub_op,setflags,extend_type,shift)) -> { + iR := append(if n == 31 then rSPIFP else xFP(n),iR); + iR := append(xFP(m),iR); + if setflags then oR := append(NZCVfp,oR); + if d ==31 & ~(setflags) then let (i,o) = wSPFP in + { iR := append(i,iR); oR := append(o,oR) } + else oR := append(xFP(d),oR) + } + case (AddSubShiftedRegister(d,n,m,datasize,sub_op,setflags,shift_type,shift_amount)) -> { + iR := append(xFP(n),append(xFP(m),iR)); + if setflags then oR := append(NZCVfp,oR); + oR := append(xFP(d),oR); + } + case (AddSubCarry(d,n,m,datasize,sub_op,setflags)) -> { + iR := append(xFP(n),append(xFP(m),iR)); + iR := PSTATE_Cfp :: iR; + if setflags then oR := append(NZCVfp,oR); + oR := append(xFP(d),oR); + } + case (ConditionalCompareImmediate(n,datasize,sub_op,condition,flags,imm)) -> { + iR := append(xFP(n),iR); + iR := append(ConditionHoldsIFP(condition),iR); + oR := append(NZCVfp,oR); + } + case (ConditionalCompareRegister(n,m,datasize,sub_op,condition,flags)) -> { + iR := append(xFP(n),append(xFP(m),iR)); + iR := append(ConditionHoldsIFP(condition),iR); + oR := append(NZCVfp,oR); + } + case (ConditionalSelect(d,n,m,datasize,condition,else_inv,else_inc)) -> { + iR := append(xFP(n),append(xFP(m),iR)); + iR := append(ConditionHoldsIFP(condition),iR); + oR := append(xFP(d),oR); + } + case (Reverse(d,n,datasize,op)) -> { + iR := append(xFP(n),iR); + oR := append(xFP(d),oR); + } + case (CountLeading(d,n,datasize,opcode)) -> { + iR := append(xFP(n),iR); + oR := append(xFP(d),oR); + } + case (Division(d,n,m,datasize,_unsigned)) -> { + iR := append(xFP(n),append(xFP(m),iR)); + oR := append(xFP(d),oR); + } + case (Shift(d,n,m,datasize,shift_type)) -> { + iR := append(xFP(m),iR); + iR := append(xFP(n),iR); + oR := append(xFP(d),oR); + } + case (CRC(d,n,m,size,crc32c)) -> { + iR := append(xFP(n),append(xFP(m),iR)); + oR := append(xFP(d),oR); + } + case (MultiplyAddSub(d,n,m,a,destsize,datasize,sub_op)) -> { + iR := append(xFP(n),iR); + iR := append(xFP(m),iR); + iR := append(xFP(a),iR); + oR := append(xFP(d),oR); + } + case (MultiplyAddSubLong(d,n,m,a,destsize,datasize,sub_op,_unsigned)) -> { + iR := append(xFP(n),iR); + iR := append(xFP(m),iR); + iR := append(xFP(a),iR); + oR := append(xFP(d),oR); + } + case (MultiplyHigh(d,n,m,a,destsize,datasize,_unsigned)) -> { + iR := append(xFP(n),append(xFP(m),iR)); + oR := append(xFP(d),oR); + } + case (LogicalShiftedRegister(d,n,m,datasize,setflags,op,shift_type,shift_amount,invert)) -> { + iR := append(xFP(n),append(xFP(m),iR)); + if setflags then oR := append(NZCVfp,oR); + oR := append(xFP(d),oR); + } + }; + (iR,oR,aR,Nias,Dia,ik) +} diff --git a/arm/armV8.h.sail b/arm/armV8.h.sail index c788855a..9105f964 100644 --- a/arm/armV8.h.sail +++ b/arm/armV8.h.sail @@ -43,6 +43,27 @@ typedef SIMD_index = [|32|] register (bit[64]) _PC +(* transactional memory registers *) +register (bit[8]) TxNestingLevel (* same size as TXIDR_EL0.DEPTH *) + +typedef TMSTATUS_type = register bits [63:0] +{ + (*63..17 : RES0;*) + 16 : IMP; + 15 : DBG; + 14 : MEM; + 13 : ERR; + 12 : INV; + 11 : SIZE; + 10 : NEST; + 9 : ABRT; + 8 : RTRY; + (*7..5 : RES0*) + 4..0 : REASON; +} +register (TMSTATUS_type) TMAbortEffect (* we abuse the register write to pass out the status value *) +register (TMSTATUS_type) TMStartEffect (* we abuse the register read to pass in the status value *) + (* General purpose registers *) register (bit[64]) R30 @@ -170,3 +191,6 @@ let IMPLEMENTATION_DEFINED = (* FIXME: ask Kathy what should we do with this *) let UNKNOWN = 0 + + +val extern unit -> bool effect {exmem} speculate_exclusive_success diff --git a/arm/armV8.sail b/arm/armV8.sail index 10c57d1e..2614c7a5 100644 --- a/arm/armV8.sail +++ b/arm/armV8.sail @@ -40,6 +40,12 @@ typedef ast = const union forall Nat 'R, 'R IN {32, 64}, (* register size *) ImplementationDefinedStopFetching; ImplementationDefinedThreadStart; + (* transactional memory, from the pre-alpha document *) + (reg_index) TMStart; + TMCommit; + (boolean,bit[5]) TMAbort; + TMTest; + (reg_index,[:'R:],boolean,bit[64]) CompareAndBranch; (bit[64],bit[4]) BranchConditional; (bit[16]) GenerateExceptionEL1; (* TODO: add to .hgen *) @@ -64,7 +70,7 @@ typedef ast = const union forall Nat 'R, 'R IN {32, 64}, (* register size *) (boolean,boolean,reg_index,reg_index,reg_index,AccType,MemOp,uinteger,[:'D:],bit[64]) LoadStorePairNonTemp; (reg_index,reg_index,AccType,MemOp,boolean,boolean,boolean,bit[64],[:'R:],[:'D:]) LoadImmediate; (reg_index,reg_index,reg_index,AccType,MemOp,boolean,boolean,boolean,ExtendType,uinteger,[:'R:],[:'D:]) LoadRegister; - (boolean,boolean,reg_index,reg_index,reg_index,AccType,MemOp,boolean,uinteger,[:'D:],bit[64]) LoadStorePair; + (boolean,boolean,reg_index,reg_index,reg_index,AccType,MemOp,boolean,[:'D:],bit[64]) LoadStorePair; (reg_index,reg_index,[:'R:],boolean,boolean,bit['R]) AddSubImmediate; (reg_index,reg_index,[:'R:],boolean,boolean,uinteger,uinteger,bit['R],bit['R]) BitfieldMove; (reg_index,reg_index,reg_index,[:'R:],uinteger) ExtractRegister; @@ -86,12 +92,91 @@ typedef ast = const union forall Nat 'R, 'R IN {32, 64}, (* register size *) (reg_index,reg_index,reg_index,reg_index,[:'R:],[:'D:],boolean,boolean) MultiplyAddSubLong; (reg_index,reg_index,reg_index,reg_index,[:'R:],[:'D:],boolean) MultiplyHigh; (reg_index,reg_index,reg_index,[:'R:],boolean,LogicalOp,ShiftType,[|63|],boolean) LogicalShiftedRegister; - } -val forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. ast<'R,'D> -> unit effect {rreg,wreg,rmem,barr,eamem,wmv,escape} execute +val forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. ast<'R,'D> -> unit effect {rreg,wreg,rmem,barr,eamem,wmv,exmem,escape} execute scattered function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. unit execute +(* TSTART - dummy decoding *) +function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. + option<(ast<'R,'D>)> effect pure decodeTMStart ((bit[5]) Rt) = +{ + (reg_index) t := UInt_reg(Rt); + + Some(TMStart(t)); +} + +(* transactional memory, from the pre-alpha document *) +function clause execute (TMStart(t)) = { + (bit[8]) nesting := TxNestingLevel; + + if nesting <_u TXIDR_EL0.DEPTH then { + TxNestingLevel := nesting + 1; + (bit[64]) status := 0; + if nesting == 0 then + status := TMStartEffect; (* fake effect *) + wX(t) := status; + } else { + (bit[64]) status := 0; + status[10] := 1; (* set the NEST bit *) + TMAbortEffect := status; (* fake effect *) + } +} + +val extern unit -> unit effect {barr} TMCommitEffect + +(* TCOMMIT - dummy decoding *) +function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. + option<(ast<'R,'D>)> effect pure decodeTMCommit () = +{ + Some(TMCommit); +} + +(* transactional memory, from the pre-alpha document *) +function clause execute (TMCommit) = { + (bit[8]) nesting := TxNestingLevel; + + if nesting == 1 then + TMCommitEffect() (* fake effect *) + else if nesting == 0 then + AArch64_UndefinedFault(); + + TxNestingLevel := nesting - 1; +} + +(* TTEST - dummy decoding *) +function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. + option<(ast<'R,'D>)> effect pure decodeTMTest () = +{ + Some(TMTest); +} + +(* transactional memory, from the pre-alpha document *) +function clause execute (TMTest) = { + if TxNestingLevel > 0 then + wPSTATE_NZCV() := 0b0000 + else + wPSTATE_NZCV() := 0b0100 +} + +(* TABORT - dummy decoding *) +function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. + option<(ast<'R,'D>)> effect pure decodeTMAbort ([R]:(bit[5]) imm5) = +{ + Some(TMAbort(R,imm5)); +} + +(* transactional memory, from the pre-alpha document *) +function clause execute (TMAbort(retry,reason)) = { + if TxNestingLevel > 0 then { + (bit[64]) status := 0; + status[4..0] := reason; (* REASON *) + status[8] := retry; (* RTRY *) + status[9] := 1; (* ABRT *) + TMAbortEffect := status; (* fake effect *) + }; +} + (* CBNZ *) (* CBZ *) function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. @@ -517,16 +602,16 @@ function clause execute ( TestBitAndBranch(t,datasize,bit_pos,bit_val,offset) ) (* BL *) function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. option<(ast<'R,'D>)> effect {escape} decodeUnconditionalBranchImmediate ([op]:0b00101:(bit[26]) imm26) = { - (BranchType) _branch_type := if op == 1 then BranchType_CALL else BranchType_JMP; + (BranchType) branch_type := if op == 1 then BranchType_CALL else BranchType_JMP; (bit[64]) offset := SignExtend(imm26:0b00); - Some(BranchImmediate(_branch_type,offset)); + Some(BranchImmediate(branch_type,offset)); } -function clause execute (BranchImmediate(_branch_type,offset)) = { - if _branch_type == BranchType_CALL then wX(30) := rPC() + 4; +function clause execute (BranchImmediate(branch_type,offset)) = { + if branch_type == BranchType_CALL then wX(30) := rPC() + 4; - BranchTo(rPC() + offset, _branch_type); + BranchTo(rPC() + offset, branch_type); } @@ -540,24 +625,24 @@ scattered function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. (* RET *) function clause decodeUnconditionalBranchRegister (0b1101011:0b00:op:0b11111:0b000000:Rn:0b00000) = { (reg_index) n := UInt_reg(Rn); - (BranchType) _branch_type := 0; (* ARM: uninitialized *) + (BranchType) branch_type := 0; (* ARM: uninitialized *) switch op { - case 0b00 -> _branch_type := BranchType_JMP - case 0b01 -> _branch_type := BranchType_CALL - case 0b10 -> _branch_type := BranchType_RET + case 0b00 -> branch_type := BranchType_JMP + case 0b01 -> branch_type := BranchType_CALL + case 0b10 -> branch_type := BranchType_RET case _ -> UnallocatedEncoding() }; - Some(BranchRegister(n,_branch_type)); + Some(BranchRegister(n,branch_type)); } -function clause execute (BranchRegister(n,_branch_type)) = +function clause execute (BranchRegister(n,branch_type)) = { (bit[64]) target := rX(n); - if _branch_type == BranchType_CALL then wX(30) := rPC() + 4; - BranchTo(target, _branch_type); + if branch_type == BranchType_CALL then wX(30) := rPC() + 4; + BranchTo(target, branch_type); } (* ERET *) @@ -717,7 +802,7 @@ function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. Some(LoadStoreAcqExc(n,t,t2,s,acctype,excl,pair,memop,elsize,regsize,datasize)); } -function clause execute ( LoadStoreAcqExc(n,t,t2,s,acctype,excl,pair,memop,elsize,regsize,datasize) ) = { +function clause execute ( LoadStoreAcqExc(n,t,t2,s,acctype,excl,pair,memop,elsize,regsize,([:'D:]) datasize) ) = { (bit[64]) address := 0; (* ARM: uninitialized *) (bit['D]) data := 0; (* ARM: uninitialized *) (*constant*) (uinteger) dbytes := datasize quot 8; @@ -760,6 +845,19 @@ function clause execute ( LoadStoreAcqExc(n,t,t2,s,acctype,excl,pair,memop,elsiz }; }; + (* this is a hack to allow the result of store-exclusive to be observed + before anything else *) + (bit) status := 0; + if memop == MemOp_STORE & excl then { + (*(bit)*) status := if speculate_exclusive_success() then 0 else 1; + wX(s) := (bit[32]) (ZeroExtend([status])); + + (* should be: + if status == 1 then return (); + *) + }; + if status == 1 then () else { + if n == 31 then { CheckSPAlignment(); address := rSP(); @@ -781,7 +879,7 @@ function clause execute ( LoadStoreAcqExc(n,t,t2,s,acctype,excl,pair,memop,elsiz (bit['R]) el2 := rX(t2); (* ARM: bit[datasize / 2] see lemma in the decoding *) data := if BigEndian() then el1:el2 else el2:el1; } else - data := rX(t); + (bit['D]) data := rX(t); if excl then { (* store {release} exclusive register|pair (atomic) *) @@ -798,7 +896,9 @@ function clause execute ( LoadStoreAcqExc(n,t,t2,s,acctype,excl,pair,memop,elsiz wMem_exclusive(empty_write_buffer, address, dbytes, acctype, data) ); }; + (* ARM: the following code was moved up, see note there wX(s) := (bit[32]) (ZeroExtend([status])); + *) } else { (* store release register (atomic) *) flush_write_buffer( @@ -860,6 +960,7 @@ function clause execute ( LoadStoreAcqExc(n,t,t2,s,acctype,excl,pair,memop,elsiz }; } }; + }; } (* LDNP *) @@ -885,7 +986,7 @@ function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. Some(LoadStorePairNonTemp(wback,postindex,n,t,t2,acctype,memop,scale,datasize,offset)); } -function clause execute ( LoadStorePairNonTemp(wback,postindex,n,t,t2,acctype,memop,scale,datasize,offset) ) = { +function clause execute ( LoadStorePairNonTemp(wback,postindex,n,t,t2,acctype,memop,scale,([:'D:]) datasize,offset) ) = { (bit[64]) address := 0; (* ARM: uninitialized *) (bit['D]) data1 := 0; (* ARM: uninitialized *) (bit['D]) data2 := 0; (* ARM: uninitialized *) @@ -930,11 +1031,11 @@ function clause execute ( LoadStorePairNonTemp(wback,postindex,n,t,t2,acctype,me switch memop { case MemOp_STORE -> { if rt_unknown & t == n then - date1 := (bit['D]) UNKNOWN + data1 := (bit['D]) UNKNOWN else data1 := rX(t); if rt_unknown & t2 == n then - date2 := (bit['D]) UNKNOWN + data2 := (bit['D]) UNKNOWN else data2 := rX(t2); @@ -951,7 +1052,7 @@ function clause execute ( LoadStorePairNonTemp(wback,postindex,n,t,t2,acctype,me data2 := read_data[((datasize * 2) - 1)..datasize]; if rt_unknown then { - date1 := (bit['D]) UNKNOWN; + data1 := (bit['D]) UNKNOWN; data2 := (bit['D]) UNKNOWN; }; wX(t) := data1; @@ -1028,7 +1129,7 @@ function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. sharedDecodeLoadImmediate(opc,size,Rn,Rt,wback,postindex,scale,offset,AccType_NORMAL,false); } -function clause execute ( LoadImmediate(n,t,acctype,memop,_signed,wback,postindex,offset,regsize,datasize) ) = { +function clause execute ( LoadImmediate(n,t,acctype,memop,_signed,wback,postindex,offset,regsize,([:'D:]) datasize) ) = { (bit[64]) address := 0; (* ARM: uninitialized *) (bit['D]) data := 0; (* ARM: uninitialized *) (boolean) wb_unknown := false; @@ -1191,7 +1292,7 @@ function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. sharedDecodeLoadRegister(Rn,Rt,Rm,opc,size,wback,postindex,scale,extend_type,shift); } -function clause execute ( LoadRegister(n,t,m,acctype,memop,_signed,wback,postindex,extend_type,shift,regsize,datasize) ) = { +function clause execute ( LoadRegister(n,t,m,acctype,memop,_signed,wback,postindex,extend_type,shift,regsize,([:'D:]) datasize) ) = { (bit[64]) offset := ExtendReg(m, extend_type, shift); (bit[64]) address := 0; (* ARM: uninitialized *) (bit['D]) data := 0; (* ARM: uninitialized *) @@ -1352,7 +1453,7 @@ function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. ([:'D:]) datasize := lsl(8, scale); (bit[64]) offset := LSL(SignExtend(imm7), scale); - Some(LoadStorePair(wback,postindex,n,t,t2,acctype,memop,_signed,scale,datasize,offset)); + Some(LoadStorePair(wback,postindex,n,t,t2,acctype,memop,_signed,datasize,offset)); } (* LDP signed offset *) @@ -1367,7 +1468,7 @@ function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. sharedDecodeLoadStorePair(L,opc,imm7,Rn,Rt,Rt2,wback,postindex); } -function clause execute ( LoadStorePair(wback,postindex,n,t,t2,acctype,memop,_signed,scale,datasize,offset) ) = { +function clause execute ( LoadStorePair(wback,postindex,n,t,t2,acctype,memop,_signed,([:'D:])datasize,offset) ) = { (bit[64]) address := 0; (* ARM: uninitialized *) (bit['D]) data1 := 0; (* ARM: uninitialized *) (bit['D]) data2 := 0; (* ARM: uninitialized *) @@ -1616,7 +1717,7 @@ function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. Some(ExtractRegister(d,n,m,datasize,lsb)); } -function clause execute ( ExtractRegister(d,n,m,datasize,lsb) ) = { +function clause execute ( ExtractRegister(d,n,m,([:'R:]) datasize,lsb) ) = { (bit['R]) result := 0; (* ARM: uninitialized *) (bit['R]) operand1 := rX(n); (bit['R]) operand2 := rX(m); @@ -1650,7 +1751,7 @@ function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. Some(LogicalImmediate(d,n,datasize,setflags,op,imm)); }} -function clause execute (LogicalImmediate(d,n,datasize,setflags,op,imm)) = { +function clause execute (LogicalImmediate(d,n,([:'R:]) datasize,setflags,op,imm)) = { (bit['R]) result := 0; (* ARM: uninitialized *) (bit['R]) operand1 := rX(n); (bit['R]) operand2 := imm; diff --git a/arm/armV8_A64_lib.sail b/arm/armV8_A64_lib.sail index 5a1b6ec3..2aa31d4f 100644 --- a/arm/armV8_A64_lib.sail +++ b/arm/armV8_A64_lib.sail @@ -730,6 +730,8 @@ function bit[64] System_Get((uinteger) op0, (uinteger) op1, (uinteger) crn, (uin switch (op0,op1,crn,crm,op2) { case (3,3,4,2,0) -> ZeroExtend(NZCV) case (3,3,4,2,1) -> ZeroExtend(DAIF) + case (3, 3, 13, 0, 2) -> TPIDR_EL0 + (* TODO FIXME: higher EL TPIDRs *) (* case (3,0,1,0,1) -> ZeroExtend(ACTLR_EL1) *) } @@ -741,6 +743,8 @@ function unit effect {wreg} System_Put((uinteger) op0, (uinteger) op1, (uinteger switch (op0,op1,crn,crm,op2) { case (3,3,4,2,0) -> NZCV := _val[31..0] case (3,3,4,2,1) -> DAIF := _val[31..0] + case (3, 3, 13, 0, 2) -> TPIDR_EL0 := _val[63..0] + (* TODO FIXME: higher EL TPIDRs *) (* case (3,0,1,0,1) -> ACTLR_EL1 := _val[31..0] *) } @@ -756,7 +760,19 @@ function unit AArch64_ExceptionReturn((bit[64]) new_pc, (bit[32]) spsr) = (** ENUMERATE:aarch64/instrs/countop/CountOp *) (** FUNCTION:ExtendType DecodeRegExtend(bits(3) op) *) -function ExtendType DecodeRegExtend ((bit[3]) op) = ([|8|]) op +function ExtendType DecodeRegExtend ((bit[3]) op) = +{ + switch op { + case 0b000 -> ExtendType_UXTB + case 0b001 -> ExtendType_UXTH + case 0b010 -> ExtendType_UXTW + case 0b011 -> ExtendType_UXTX + case 0b100 -> ExtendType_SXTB + case 0b101 -> ExtendType_SXTH + case 0b110 -> ExtendType_SXTW + case 0b111 -> ExtendType_SXTX + } +} (** FUNCTION:aarch64/instrs/extendreg/ExtendReg *) diff --git a/arm/armV8_A64_sys_regs.sail b/arm/armV8_A64_sys_regs.sail index 50c150c6..95b5c710 100644 --- a/arm/armV8_A64_sys_regs.sail +++ b/arm/armV8_A64_sys_regs.sail @@ -35,162 +35,6 @@ (*************************************************************************) (* General system control registers *) -register (bit[32]) ACTLR_EL1 (* Auxiliary Control Register (EL1) *) (* UNUSED *) -register (bit[32]) ACTLR_EL2 (* Auxiliary Control Register (EL2) *) (* UNUSED *) -register (bit[32]) ACTLR_EL3 (* Auxiliary Control Register (EL3) *) (* UNUSED *) -register (bit[32]) AFSR0_EL1 (* Auxiliary Fault Status Register 0 (EL1) *) (* UNUSED *) -register (bit[32]) AFSR0_EL2 (* Auxiliary Fault Status Register 0 (EL2) *) (* UNUSED *) -register (bit[32]) AFSR0_EL3 (* Auxiliary Fault Status Register 0 (EL3) *) (* UNUSED *) -register (bit[32]) AFSR1_EL1 (* Auxiliary Fault Status Register 1 (EL1) *) (* UNUSED *) -register (bit[32]) AFSR1_EL2 (* Auxiliary Fault Status Register 1 (EL2) *) (* UNUSED *) -register (bit[32]) AFSR1_EL3 (* Auxiliary Fault Status Register 1 (EL3) *) (* UNUSED *) -register (bit[32]) AIDR_EL1 (* Auxiliary ID Register *) (* UNUSED *) -register (bit[64]) AMAIR_EL1 (* Auxiliary Memory Attribute Indirection Register (EL1) *) (* UNUSED *) -register (bit[64]) AMAIR_EL2 (* Auxiliary Memory Attribute Indirection Register (EL2) *) (* UNUSED *) -register (bit[64]) AMAIR_EL3 (* Auxiliary Memory Attribute Indirection Register (EL3) *) (* UNUSED *) - -typedef CCSIDR_type = register bits [31:0] -{ - 31 : WT; - 30 : WB; - 29 : RA; - 28 : WA; - 27..13 : NumSets; - 12..3 : Associativity; - 2..0 : LineSize; -} -register (CCSIDR_type) CCSIDR_EL1 (* Current Cache Size ID Register *) (* UNUSED *) - -typedef CLIDR_type = register bits [63:0] -{ - (*63..33 : RES0*) - 32..30 : ICB; - 29..27 : LoUU; - 26..24 : LoC; - 23..21 : LoUIS; - 20..18 : Ctype7; - 17..15 : Ctype6; - 14..12 : Ctype5; - 11..9 : Ctype4; - 8..6 : Ctype3; - 5..3 : Ctype2; - 2..0 : Ctype1; -} -register (CLIDR_type) CLIDR_EL1 (* Cache Level ID Register *) (* UNUSED *) - -typedef CONTEXTIDR_type = register bits [31:0] { 31..0 : PROCID } -register (CONTEXTIDR_type) CONTEXTIDR_EL1 (* Context ID Register *) (* UNUSED *) - -typedef CPACR_type = register bits [31:0] -{ - (*31..29 : RES0;*) - 28 : TTA; - (*27..22 : RES0;*) - 21..20 : FPEN; - (*19..0 : RES0;*) -} -register (CPACR_type) CPACR_EL1 (* Architectural Feature Access Control Register *) (* UNUSED *) - -typedef CPTR_type = register bits [31:0] -{ - (* in EL3 all the RES are RES0 *) - 31 : TCPAC; - (*30..21 : RES0;*) - 20 : TTA; - (*19..14 : RES0;*) - (*13..12 : RES1;*) - (*11 : RES0;*) - 10 : TFP; - (*9..0 : RES1;*) -} -register (CPTR_type) CPTR_EL2 (* Architectural Feature Trap Register (EL2) *) (* UNUSED *) -register (CPTR_type) CPTR_EL3 (* Architectural Feature Trap Register (EL3) *) (* UNUSED *) - -typedef CSSELR_type = register bits [31:0] -{ - (*31..4 : RES0;*) - 3..1 : Level; - 0 : InD; -} -register (CSSELR_type) CSSELR_EL1 (* Cache Size Selection Register *) (* UNUSED *) - -typedef CTR_type = register bits [31:0] -{ - (*31 : RES1;*) - (*30..28 : RES0;*) - 27..24 : CWG; - 23..20 : ERG; - 19..16 : DminLine; - 15..14 : L1Ip; - (*13..4 : RES0;*) - 3..0 : IminLine; -} -register (CTR_type) CTR_EL0 (* Cache Type Register *) (* UNUSED *) - -typedef DACR32_type = register bits [31:0] -{ - 31..30 : D15; - 29..28 : D14; - 27..26 : D13; - 25..24 : D12; - 23..22 : D11; - 21..20 : D10; - 29..18 : D9; - 17..16 : D8; - 15..14 : D7; - 13..12 : D6; - 11..10 : D5; - 9..8 : D4; - 7..6 : D3; - 5..4 : D2; - 3..2 : D1; - 1..0 : D0; -} -register (DACR32_type) DACR32_EL2 (* Domain Access Control Register *) (* UNUSED *) - -typedef DCZID_type = register bits [31:0] -{ - (*31..5 : RES0;*) - 4 : DZP; - 3..0 : BS; -} -register (DCZID_type) DCZID_EL0 (* Data Cache Zero ID register *) (* UNUSED *) - -typedef ESR_type = register bits [31:0] -{ - 31..26 : EC; - 25 : IL; - 24..0 : ISS; -} -register (ESR_type) ESR_EL1 (* Exception Syndrome Register (EL1) *) (* UNUSED *) -register (ESR_type) ESR_EL2 (* Exception Syndrome Register (EL2) *) (* UNUSED *) -register (ESR_type) ESR_EL3 (* Exception Syndrome Register (EL3) *) (* UNUSED *) - -register (bit[64]) FAR_EL1 (* Fault Address Register (EL1) *) (* UNUSED *) -register (bit[64]) FAR_EL2 (* Fault Address Register (EL2) *) (* UNUSED *) -register (bit[64]) FAR_EL3 (* Fault Address Register (EL3) *) (* UNUSED *) - -typedef FPEXC32_type = register bits [31:0] -{ - 31 : EX; - 30 : EN; - 29 : DEX; - 28 : FP2V; - 27 : VV; - 26 : TFV; - (*25..21 : RES0;*) - (*20..11 : IMPLEMENTATION DEFINED*) - 10..8 : VECITR; - 7 : IDF; - (*6..5 : IMPLEMENTATION DEFINED*) - 4 : IXF; - 3 : UFF; - 2 : OFF; - 1 : DZF; - 0 : IOF; -} -register (FPEXC32_type) FPEXC32_EL2 (* Floating-point Exception Control register *) (* UNUSED *) -register (bit[32]) HACR_EL2 (* Hypervisor Auxiliary Control Register *) (* UNUSED *) typedef HCR_type = register bits [63:0] { @@ -231,35 +75,6 @@ typedef HCR_type = register bits [63:0] } register (HCR_type) HCR_EL2 (* Hypervisor Configuration Register *) -typedef HPFAR_type = register bits [63:0] -{ - (*63..40 : RES0;*) - 39..4 : FIPA; (* bits [47:12] of FIPA *) - (*3..0 : RES0;*) -} -register (HPFAR_type) HPFAR_EL2 (* Hypervisor IPA Fault Address Register *) (* UNUSED *) - -typedef HSTR_type = register bits [31:0] -{ - (*31..16 : RES0;*) - 15 : T15; - 14 : T14; - 13 : T13; - 12 : T12; - 11 : T11; - 10 : T10; - 9 : T9; - 8 : T8; - 7 : T7; - 6 : T6; - 5 : T5; - 4 : T4; - 3 : T3; - 2 : T2; - 1 : T1; - 0 : T0; -} -register (HSTR_type) HSTR_EL2 (* Hypervisor System Trap Register *) (* UNUSED *) typedef ID_AA64MMFR0_type = register bits [63:0] { @@ -402,6 +217,11 @@ typedef TCR_type = register bits [31:0] register (TCR_type) TCR_EL2 (* Translation Control Register (EL2) *) register (TCR_type) TCR_EL3 (* Translation Control Register (EL3) *) +register (bit[64]) TPIDR_EL0 (* EL0 Read/Write Software Thread ID Register *) +register (bit[64]) TPIDR_EL1 (* EL1 Read/Write Software Thread ID Register *) +register (bit[64]) TPIDR_EL2 (* EL2 Read/Write Software Thread ID Register *) +register (bit[64]) TPIDR_EL3 (* EL3 Read/Write Software Thread ID Register *) + (*************************************************************************) (* Debug registers *) @@ -458,9 +278,17 @@ typedef EDSCR_type = register bits [31:0] } register (EDSCR_type) EDSCR (* External Debug Status and Control Register *) +(* transactional memory, from the pre-alpha document *) +typedef TXIDR_EL0_type = register bits [63:0] +{ + (*63..8 : RES0;*) + 7..0 : DEPTH; +} +register (TXIDR_EL0_type) TXIDR_EL0 (* Transaction ID Register *) + + function unit effect pure AArch64_ResetControlRegisters((boolean) cold_reset) = { () } - diff --git a/arm/armV8_common_lib.sail b/arm/armV8_common_lib.sail index 3bae8070..9bea1cd1 100644 --- a/arm/armV8_common_lib.sail +++ b/arm/armV8_common_lib.sail @@ -513,8 +513,8 @@ val extern unit -> unit effect {barr} DataMemoryBarrier_All function unit effect {barr} DataMemoryBarrier((MBReqDomain) domain, (MBReqTypes) types) = { - if domain != MBReqDomain_FullSystem then - not_implemented("DataMemoryBarrier: not MBReqDomain_FullSystem"); + if domain != MBReqDomain_FullSystem & domain != MBReqDomain_InnerShareable then + not_implemented("DataMemoryBarrier: not MBReqDomain_FullSystem or _InnerShareable"); switch types { case MBReqTypes_Reads -> DataMemoryBarrier_Reads() @@ -725,10 +725,10 @@ function bool effect {wmv} flush_write_buffer_exclusive((write_buffer_type) writ (** FUNCTION:BranchTo(bits(N) target, BranchType branch_type) *) -function forall Nat 'N, 'N IN {32,64}. unit effect {rreg,wreg} BranchTo((bit['N]) target, (BranchType) _branch_type) = { +function forall Nat 'N, 'N IN {32,64}. unit effect {rreg,wreg} BranchTo((bit['N]) target, (BranchType) branch_type) = { (bit['N]) target' := target; (* Sail does not let you change parameter vector *) - Hint_Branch(_branch_type); + Hint_Branch(branch_type); if length(target) == 32 then { assert( UsingAArch32(), None ); _PC := ZeroExtend(target); @@ -831,7 +831,7 @@ function boolean effect {rreg} ConditionHolds((bit[4]) _cond) = case 0b111 -> result := true (* AL *) }; - (* Condition flag valuesin the set '111x' indicate always true *) + (* Condition flag values in the set '111x' indicate always true *) (* Otherwise, invert condition if necessary. *) if _cond[0] == 1 & _cond != 0b1111 then result := ~(result); diff --git a/arm/armV8_extras.lem b/arm/armV8_extras.lem new file mode 100644 index 00000000..9a187ecb --- /dev/null +++ b/arm/armV8_extras.lem @@ -0,0 +1,77 @@ +open import Pervasives +open import Interp_ast +open import Interp_interface +open import Sail_impl_base +open import Interp_inter_imp +import Set_extra + +let memory_parameter_transformer mode v = + match v with + | Interp_ast.V_tuple [location;length] -> + let (v,loc_regs) = extern_with_track mode extern_vector_value location in + + match length with + | Interp_ast.V_lit (L_aux (L_num len) _) -> + (v,(natFromInteger len),loc_regs) + + | Interp_ast.V_track (Interp_ast.V_lit (L_aux (L_num len) _)) size_regs -> + match loc_regs with + | Nothing -> (v,(natFromInteger len),Just (List.map (fun r -> extern_reg r Nothing) (Set_extra.toList size_regs))) + | Just loc_regs -> (v,(natFromInteger len),Just (loc_regs++(List.map (fun r -> extern_reg r Nothing) (Set_extra.toList size_regs)))) + end + + | _ -> Assert_extra.failwith "expected 'V_lit (L_aux (L_num _) _)' or 'V_track (V_lit (L_aux (L_num len) _)) _'" + end + | _ -> Assert_extra.failwith "expected 'V_tuple [_;_]'" + end + +let aArch64_read_memory_functions : memory_reads = + [ ("rMem_NORMAL", (MR Read_plain memory_parameter_transformer)); + ("rMem_STREAM", (MR Read_stream memory_parameter_transformer)); + ("rMem_ORDERED", (MR Read_acquire memory_parameter_transformer)); + ("rMem_ATOMIC", (MR Read_exclusive memory_parameter_transformer)); + ("rMem_ATOMIC_ORDERED", (MR Read_exclusive_acquire memory_parameter_transformer)); + ] + +let aArch64_memory_writes : memory_writes = [] + (* [ ("wMem_NORMAL", (MW Write_plain memory_parameter_transformer Nothing)); + ("wMem_ORDERED", (MW Write_release memory_parameter_transformer Nothing)); + ("wMem_ATOMIC", (MW Write_exclusive memory_parameter_transformer Nothing)); + ("wMem_ATOMIC_ORDERED", (MW Write_exclusive_release memory_parameter_transformer Nothing)); + ] *) + +let aArch64_memory_eas : memory_write_eas = + [ ("wMem_Addr_NORMAL", (MEA Write_plain memory_parameter_transformer)); + ("wMem_Addr_ORDERED", (MEA Write_release memory_parameter_transformer)); + ("wMem_Addr_ATOMIC", (MEA Write_exclusive memory_parameter_transformer)); + ("wMem_Addr_ATOMIC_ORDERED", (MEA Write_exclusive_release memory_parameter_transformer)); + ] + +let aArch64_memory_vals : memory_write_vals = + [ ("wMem_Val_NORMAL", (MV (fun mode v -> Nothing) Nothing)); + ("wMem_Val_ATOMIC", (MV (fun mode v -> Nothing) + (Just + (fun (IState interp context) b -> + (*ppcmem2 provides true for success and false for failure; but the status for ARM is reversed*) + let bit = Interp_ast.V_lit (L_aux (if b then L_zero else L_one) Interp_ast.Unknown)in + (IState (Interp.add_answer_to_stack interp bit) context))))); + ] + +let aArch64_excl_res : excl_res = + let f = fun (IState interp context) b -> + let bool_res = Interp_ast.V_lit (L_aux (if b then L_one else L_zero) Interp_ast.Unknown) in + IState (Interp.add_answer_to_stack interp bool_res) context + in + Just ("speculate_exclusive_success", (ER (Just f))) + +let aArch64_barrier_functions = + [ ("DataMemoryBarrier_Reads", Barrier_DMB_LD); + ("DataMemoryBarrier_Writes", Barrier_DMB_ST); + ("DataMemoryBarrier_All", Barrier_DMB); + ("DataSynchronizationBarrier_Reads", Barrier_DSB_LD); + ("DataSynchronizationBarrier_Writes", Barrier_DSB_ST); + ("DataSynchronizationBarrier_All", Barrier_DSB); + ("InstructionSynchronizationBarrier", Barrier_ISB); + + ("TMCommitEffect", Barrier_TM_COMMIT); + ] diff --git a/arm/armV8_extras_embed.lem b/arm/armV8_extras_embed.lem new file mode 100644 index 00000000..86570fc4 --- /dev/null +++ b/arm/armV8_extras_embed.lem @@ -0,0 +1,59 @@ +open import Pervasives +open import Sail_impl_base +open import Sail_values +open import Prompt + +val rMem_NORMAL : (vector bitU * integer) -> M (vector bitU) +val rMem_STREAM : (vector bitU * integer) -> M (vector bitU) +val rMem_ORDERED : (vector bitU * integer) -> M (vector bitU) +val rMem_ATOMICL : (vector bitU * integer) -> M (vector bitU) +val rMem_ATOMIC_ORDERED : (vector bitU * integer) -> M (vector bitU) + +let rMem_NORMAL (addr,size) = read_mem false Read_plain addr size +let rMem_STREAM (addr,size) = read_mem false Read_stream addr size +let rMem_ORDERED (addr,size) = read_mem false Read_acquire addr size +let rMem_ATOMIC (addr,size) = read_mem false Read_exclusive addr size +let rMem_ATOMIC_ORDERED (addr,size) = read_mem false Read_exclusive_acquire addr size + +val wMem_Addr_NORMAL : (vector bitU * integer) -> M unit +val wMem_Addr_ORDERED : (vector bitU * integer) -> M unit +val wMem_Addr_ATOMIC : (vector bitU * integer) -> M unit +val wMem_Addr_ATOMIC_ORDERED : (vector bitU * integer) -> M unit + +let wMem_Addr_NORMAL (addr,size) = write_mem_ea Write_plain addr size +let wMem_Addr_ORDERED (addr,size) = write_mem_ea Write_release addr size +let wMem_Addr_ATOMIC (addr,size) = write_mem_ea Write_exclusive addr size +let wMem_Addr_ATOMIC_ORDERED (addr,size) = write_mem_ea Write_exclusive_release addr size + + +val wMem_Val_NORMAL : (integer * vector bitU) -> M unit +val wMem_Val_ATOMIC : (integer * vector bitU) -> M bitU + +let wMem_Val_NORMAL (_,v) = write_mem_val v >>= fun _ -> return () +(* in ARM the status returned is inversed *) +let wMem_Val_ATOMIC (_,v) = write_mem_val v >>= fun b -> return (if b then B0 else B1) + +let speculate_exclusive_success () = excl_result () >>= fun b -> return (if b then B1 else B0) + +val DataMemoryBarrier_Reads : unit -> M unit +val DataMemoryBarrier_Writes : unit -> M unit +val DataMemoryBarrier_All : unit -> M unit +val DataSynchronizationBarrier_Reads : unit -> M unit +val DataSynchronizationBarrier_Writes : unit -> M unit +val DataSynchronizationBarrier_All : unit -> M unit +val InstructionSynchronizationBarrier : unit -> M unit + +let DataMemoryBarrier_Reads () = barrier Barrier_DMB_LD +let DataMemoryBarrier_Writes () = barrier Barrier_DMB_ST +let DataMemoryBarrier_All () = barrier Barrier_DMB +let DataSynchronizationBarrier_Reads () = barrier Barrier_DSB_LD +let DataSynchronizationBarrier_Writes () = barrier Barrier_DSB_ST +let DataSynchronizationBarrier_All () = barrier Barrier_DSB +let InstructionSynchronizationBarrier () = barrier Barrier_ISB + +val TMCommitEffect : unit -> M unit +let TMCommitEffect () = barrier Barrier_TM_COMMIT + +let duplicate_bits (Vector bits start direction,len) = + let bits' = repeat bits len in + Vector bits' start direction diff --git a/arm/armV8_extras_embed_sequential.lem b/arm/armV8_extras_embed_sequential.lem new file mode 100644 index 00000000..d2bb8330 --- /dev/null +++ b/arm/armV8_extras_embed_sequential.lem @@ -0,0 +1,59 @@ +open import Pervasives +open import Sail_impl_base +open import Sail_values +open import State + +val rMem_NORMAL : (vector bitU * integer) -> M (vector bitU) +val rMem_STREAM : (vector bitU * integer) -> M (vector bitU) +val rMem_ORDERED : (vector bitU * integer) -> M (vector bitU) +val rMem_ATOMICL : (vector bitU * integer) -> M (vector bitU) +val rMem_ATOMIC_ORDERED : (vector bitU * integer) -> M (vector bitU) + +let rMem_NORMAL (addr,size) = read_mem false Read_plain addr size +let rMem_STREAM (addr,size) = read_mem false Read_stream addr size +let rMem_ORDERED (addr,size) = read_mem false Read_acquire addr size +let rMem_ATOMIC (addr,size) = read_mem false Read_exclusive addr size +let rMem_ATOMIC_ORDERED (addr,size) = read_mem false Read_exclusive_acquire addr size + +val wMem_Addr_NORMAL : (vector bitU * integer) -> M unit +val wMem_Addr_ORDERED : (vector bitU * integer) -> M unit +val wMem_Addr_ATOMIC : (vector bitU * integer) -> M unit +val wMem_Addr_ATOMIC_ORDERED : (vector bitU * integer) -> M unit + +let wMem_Addr_NORMAL (addr,size) = write_mem_ea Write_plain addr size +let wMem_Addr_ORDERED (addr,size) = write_mem_ea Write_release addr size +let wMem_Addr_ATOMIC (addr,size) = write_mem_ea Write_exclusive addr size +let wMem_Addr_ATOMIC_ORDERED (addr,size) = write_mem_ea Write_exclusive_release addr size + + +val wMem_Val_NORMAL : (integer * vector bitU) -> M unit +val wMem_Val_ATOMIC : (integer * vector bitU) -> M bitU + +let wMem_Val_NORMAL (_,v) = write_mem_val v >>= fun _ -> return () +(* in ARM the status returned is inversed *) +let wMem_Val_ATOMIC (_,v) = write_mem_val v >>= fun b -> return (if b then B0 else B1) + +let speculate_exclusive_success () = excl_result () >>= fun b -> return (if b then B1 else B0) + +val DataMemoryBarrier_Reads : unit -> M unit +val DataMemoryBarrier_Writes : unit -> M unit +val DataMemoryBarrier_All : unit -> M unit +val DataSynchronizationBarrier_Reads : unit -> M unit +val DataSynchronizationBarrier_Writes : unit -> M unit +val DataSynchronizationBarrier_All : unit -> M unit +val InstructionSynchronizationBarrier : unit -> M unit + +let DataMemoryBarrier_Reads () = barrier Barrier_DMB_LD +let DataMemoryBarrier_Writes () = barrier Barrier_DMB_ST +let DataMemoryBarrier_All () = barrier Barrier_DMB +let DataSynchronizationBarrier_Reads () = barrier Barrier_DSB_LD +let DataSynchronizationBarrier_Writes () = barrier Barrier_DSB_ST +let DataSynchronizationBarrier_All () = barrier Barrier_DSB +let InstructionSynchronizationBarrier () = barrier Barrier_ISB + +val TMCommitEffect : unit -> M unit +let TMCommitEffect () = barrier Barrier_TM_COMMIT + +let duplicate_bits (Vector bits start direction,len) = + let bits' = repeat bits len in + Vector bits' start direction diff --git a/arm/armV8_lib.h.sail b/arm/armV8_lib.h.sail index 849472e1..d52cc5d5 100644 --- a/arm/armV8_lib.h.sail +++ b/arm/armV8_lib.h.sail @@ -187,9 +187,8 @@ typedef CountOp = enumerate {CountOp_CLZ; CountOp_CLS; CountOp_CNT} typedef ExtendType = - (* the oreder is important for decoding *) - enumerate { ExtendType_UXTB; ExtendType_UXTH; ExtendType_UXTW; ExtendType_UXTX; - ExtendType_SXTB; ExtendType_SXTH; ExtendType_SXTW; ExtendType_SXTX } + enumerate { ExtendType_SXTB; ExtendType_SXTH; ExtendType_SXTW; ExtendType_SXTX; + ExtendType_UXTB; ExtendType_UXTH; ExtendType_UXTW; ExtendType_UXTX } typedef RevOp = enumerate {RevOp_RBIT; RevOp_REV16; RevOp_REV32; RevOp_REV64} diff --git a/arm/gen/ast.hgen b/arm/gen/ast.hgen new file mode 100644 index 00000000..60f130d7 --- /dev/null +++ b/arm/gen/ast.hgen @@ -0,0 +1,44 @@ + | `AArch64TMStart of inst_reg (* t *) + | `AArch64TMCommit + | `AArch64TMAbort of boolean*bit5 (* retry,reason *) + | `AArch64TMTest + + | `AArch64ImplementationDefinedTestBeginEnd of boolean (* isEnd *) + | `AArch64ImplementationDefinedStopFetching + | `AArch64ImplementationDefinedThreadStart + | `AArch64AddSubCarry of inst_reg*inst_reg*inst_reg*reg_size*boolean*boolean (* d,n,m,datasize,sub_op,setflags *) + | `AArch64AddSubExtendRegister of inst_reg*inst_reg*inst_reg*reg_size*boolean*boolean*extendType*range0_7 (* d,n,m,datasize,sub_op,setflags,extend_type,shift *) + | `AArch64AddSubShiftedRegister of inst_reg*inst_reg*inst_reg*reg_size*boolean*boolean*shiftType*range0_63 (* d,n,m,datasize,sub_op,setflags,shift_type,shift_amount *) + | `AArch64AddSubImmediate of inst_reg*inst_reg*reg_size*boolean*boolean*reg_size_bits (* d,n,datasize,sub_op,setflags,imm *) + | `AArch64Address of inst_reg*boolean*bit64 (* d,page,imm *) + | `AArch64LogicalImmediate of inst_reg*inst_reg*reg_size*boolean*logicalOp*reg_size_bits (* d,n,datasize,setflags,op,imm *) + | `AArch64LogicalShiftedRegister of inst_reg*inst_reg*inst_reg*reg_size*boolean*logicalOp*shiftType*range0_63*boolean (* d,n,m,datasize,setflags,op,shift_type,shift_amount,invert *) + | `AArch64Shift of inst_reg*inst_reg*inst_reg*reg_size*shiftType (* d,n,m,datasize,shift_type *) + | `AArch64BranchConditional of bit64*bit4 (* offset,condition *) + | `AArch64BranchImmediate of branchType*bit64 (* branch_type,offset *) + | `AArch64BitfieldMove of inst_reg*inst_reg*reg_size*boolean*boolean*uinteger*uinteger*reg_size_bits*reg_size_bits (* d,n,datasize,inzero,extend,R,S,wmask,tmask *) + | `AArch64BranchRegister of inst_reg*branchType (* n,branch_type *) + | `AArch64CompareAndBranch of inst_reg*reg_size*boolean*bit64 (* t,datasize,iszero,offset *) + | `AArch64ConditionalCompareImmediate of inst_reg*reg_size*boolean*bit4*bit4*reg_size_bits (* n,datasize,sub_op,condition,flags,imm *) + | `AArch64ConditionalCompareRegister of inst_reg*inst_reg*reg_size*boolean*bit4*bit4 (* n,m,datasize,sub_op,condition,flags *) + | `AArch64ClearExclusiveMonitor of uinteger (* imm *) + | `AArch64CountLeading of inst_reg*inst_reg*reg_size*countOp (* d,n,datasize,opcode *) + | `AArch64CRC of inst_reg*inst_reg*inst_reg*data_size*boolean (* d,n,m,size,crc32c *) + | `AArch64ConditionalSelect of inst_reg*inst_reg*inst_reg*reg_size*bit4*boolean*boolean (* d,n,m,datasize,condition,else_inv,else_inc *) + | `AArch64Barrier of memBarrierOp*mBReqDomain*mBReqTypes (* op,domain,types *) + | `AArch64ExtractRegister of inst_reg*inst_reg*inst_reg*reg_size*uinteger (* d,n,m,datasize,lsb *) + | `AArch64Hint of systemHintOp (* op *) + | `AArch64LoadStoreAcqExc of inst_reg*inst_reg*inst_reg*inst_reg*accType*boolean*boolean*memOp*uinteger*reg_size*data_size (* n,t,t2,s,acctype,excl,pair,memop,elsize,regsize,datasize *) + | `AArch64LoadStorePair of boolean*boolean*inst_reg*inst_reg*inst_reg*accType*memOp*boolean*data_size*bit64 (* wback,postindex,n,t,t2,acctype,memop,signed,datasize,offset *) + | `AArch64LoadImmediate of inst_reg*inst_reg*accType*memOp*boolean*boolean*boolean*bit64*reg_size*data_size (* n,t,acctype,memop,signed,wback,postindex,offset,regsize,datasize *) + | `AArch64LoadLiteral of inst_reg*memOp*boolean*uinteger*bit64*data_size (* t,memop,signed,size,offset,datasize *) + | `AArch64LoadRegister of inst_reg*inst_reg*inst_reg*accType*memOp*boolean*boolean*boolean*extendType*uinteger*reg_size*data_size (* n,t,m,acctype,memop,signed,wback,postindex,extend_type,shift,regsize,datasize *) + | `AArch64MultiplyAddSub of inst_reg*inst_reg*inst_reg*inst_reg*reg_size*data_size*boolean (* d,n,m,a,destsize,datasize,sub_op *) + | `AArch64MoveWide of inst_reg*reg_size*bit16*uinteger*moveWideOp (* d,datasize,imm,pos,opcode *) + | `AArch64Reverse of inst_reg*inst_reg*reg_size*revOp (* d,n,datasize,op *) + | `AArch64Division of inst_reg*inst_reg*inst_reg*reg_size*boolean (* d,n,m,datasize,unsigned *) + | `AArch64MultiplyAddSubLong of inst_reg*inst_reg*inst_reg*inst_reg*reg_size*data_size*boolean*boolean (* d,n,m,a,destsize,datasize,sub_op,unsigned *) + | `AArch64MultiplyHigh of inst_reg*inst_reg*inst_reg*inst_reg*reg_size*data_size*boolean (* d,n,m,a,destsize,datasize,unsigned *) + | `AArch64TestBitAndBranch of inst_reg*reg_size*uinteger*bit*bit64 (* t,datasize,bit_pos,bit_val,offset *) + | `AArch64MoveSystemRegister of inst_reg*uinteger*uinteger*uinteger*uinteger*uinteger*boolean (* t,sys_op0,sys_op1,sys_op2,sys_crn,sys_crm,read *) + | `AArch64MoveSystemImmediate of bit4*pSTATEField (* operand,field *) diff --git a/arm/gen/fold.hgen b/arm/gen/fold.hgen new file mode 100644 index 00000000..4062d8e6 --- /dev/null +++ b/arm/gen/fold.hgen @@ -0,0 +1,44 @@ +| `AArch64TMStart t -> fold_reg t (y_reg, y_sreg) +| `AArch64TMCommit -> (y_reg, y_sreg) +| `AArch64TMAbort (retry,reason) -> (y_reg, y_sreg) +| `AArch64TMTest -> (y_reg, y_sreg) + +| `AArch64ImplementationDefinedStopFetching -> (y_reg, y_sreg) +| `AArch64ImplementationDefinedThreadStart -> (y_reg, y_sreg) +| `AArch64ImplementationDefinedTestBeginEnd (isEnd) -> (y_reg, y_sreg) +| `AArch64AddSubCarry (d,n,m,datasize,sub_op,setflags) -> fold_reg m (fold_reg n (fold_reg d (y_reg, y_sreg))) +| `AArch64AddSubExtendRegister (d,n,m,datasize,sub_op,setflags,extend_type,shift) -> fold_reg m (fold_reg n (fold_reg d (y_reg, y_sreg))) +| `AArch64AddSubShiftedRegister (d,n,m,datasize,sub_op,setflags,shift_type,shift_amount) -> fold_reg m (fold_reg n (fold_reg d (y_reg, y_sreg))) +| `AArch64AddSubImmediate (d,n,datasize,sub_op,setflags,imm) -> fold_reg n (fold_reg d (y_reg, y_sreg)) +| `AArch64Address (d,page,imm) -> fold_reg d (y_reg, y_sreg) +| `AArch64LogicalImmediate (d,n,datasize,setflags,op,imm) -> fold_reg n (fold_reg d (y_reg, y_sreg)) +| `AArch64LogicalShiftedRegister (d,n,m,datasize,setflags,op,shift_type,shift_amount,invert) -> fold_reg m (fold_reg n (fold_reg d (y_reg, y_sreg))) +| `AArch64Shift (d,n,m,datasize,shift_type) -> fold_reg m (fold_reg n (fold_reg d (y_reg, y_sreg))) +| `AArch64BranchConditional (offset,condition) -> (y_reg, y_sreg) +| `AArch64BranchImmediate (branch_type,offset) -> (y_reg, y_sreg) +| `AArch64BitfieldMove (d,n,datasize,inzero,extend,_R,_S,wmask,tmask) -> fold_reg n (fold_reg d (y_reg, y_sreg)) +| `AArch64BranchRegister (n,branch_type) -> fold_reg n (y_reg, y_sreg) +| `AArch64CompareAndBranch (t,datasize,iszero,offset) -> fold_reg t (y_reg, y_sreg) +| `AArch64ConditionalCompareImmediate (n,datasize,sub_op,condition,flags,imm) -> fold_reg n (y_reg, y_sreg) +| `AArch64ConditionalCompareRegister (n,m,datasize,sub_op,condition,flags) -> fold_reg m (fold_reg n (y_reg, y_sreg)) +| `AArch64ClearExclusiveMonitor (imm) -> (y_reg, y_sreg) +| `AArch64CountLeading (d,n,datasize,opcode) -> fold_reg n (fold_reg d (y_reg, y_sreg)) +| `AArch64CRC (d,n,m,size,crc32c) -> fold_reg m (fold_reg n (fold_reg d (y_reg, y_sreg))) +| `AArch64ConditionalSelect (d,n,m,datasize,condition,else_inv,else_inc) -> fold_reg m (fold_reg n (fold_reg d (y_reg, y_sreg))) +| `AArch64Barrier (op,domain,types) -> (y_reg, y_sreg) +| `AArch64ExtractRegister (d,n,m,datasize,lsb) -> fold_reg m (fold_reg n (fold_reg d (y_reg, y_sreg))) +| `AArch64Hint (op) -> (y_reg, y_sreg) +| `AArch64LoadStoreAcqExc (n,t,t2,s,acctype,excl,pair,memop,elsize,regsize,datasize) -> fold_reg s (fold_reg t2 (fold_reg t (fold_reg n (y_reg, y_sreg)))) +| `AArch64LoadStorePair (wback,postindex,n,t,t2,acctype,memop,signed,datasize,offset) -> fold_reg t2 (fold_reg t (fold_reg n (y_reg, y_sreg))) +| `AArch64LoadImmediate (n,t,acctype,memop,signed,wback,postindex,offset,regsize,datasize) -> fold_reg t (fold_reg n (y_reg, y_sreg)) +| `AArch64LoadLiteral (t,memop,signed,size,offset,datasize) -> fold_reg t (y_reg, y_sreg) +| `AArch64LoadRegister (n,t,m,acctype,memop,signed,wback,postindex,extend_type,shift,regsize,datasize) -> fold_reg m (fold_reg t (fold_reg n (y_reg, y_sreg))) +| `AArch64MultiplyAddSub (d,n,m,a,destsize,datasize,sub_op) -> fold_reg a (fold_reg m (fold_reg n (fold_reg d (y_reg, y_sreg)))) +| `AArch64MoveWide (d,datasize,imm,pos,opcode) -> fold_reg d (y_reg, y_sreg) +| `AArch64Reverse (d,n,datasize,op) -> fold_reg n (fold_reg d (y_reg, y_sreg)) +| `AArch64Division (d,n,m,datasize,unsigned) -> fold_reg m (fold_reg n (fold_reg d (y_reg, y_sreg))) +| `AArch64MultiplyAddSubLong (d,n,m,a,destsize,datasize,sub_op,unsigned) -> fold_reg a (fold_reg m (fold_reg n (fold_reg d (y_reg, y_sreg)))) +| `AArch64MultiplyHigh (d,n,m,a,destsize,datasize,unsigned) -> fold_reg a (fold_reg m (fold_reg n (fold_reg d (y_reg, y_sreg)))) +| `AArch64TestBitAndBranch (t,datasize,bit_pos,bit_val,offset) -> fold_reg t (y_reg, y_sreg) +| `AArch64MoveSystemRegister (t,sys_op0,sys_op1,sys_op2,sys_crn,sys_crm,read) -> fold_reg t (y_reg, y_sreg) +| `AArch64MoveSystemImmediate (operand,field) -> (y_reg, y_sreg) diff --git a/arm/gen/herdtools_ast_to_shallow_ast.hgen b/arm/gen/herdtools_ast_to_shallow_ast.hgen new file mode 100644 index 00000000..5a19e483 --- /dev/null +++ b/arm/gen/herdtools_ast_to_shallow_ast.hgen @@ -0,0 +1,335 @@ +| `AArch64TMStart t -> TMStart (translate_reg "t" t) + +| `AArch64TMCommit -> TMCommit + +| `AArch64TMAbort (retry,reason) -> + TMAbort + (translate_boolean "retry" retry, + translate_bit5 "reason" reason) + +| `AArch64TMTest -> TMTest + +| `AArch64ImplementationDefinedStopFetching -> + ImplementationDefinedStopFetching + +| `AArch64ImplementationDefinedThreadStart -> + ImplementationDefinedThreadStart + +| `AArch64ImplementationDefinedTestBeginEnd(isEnd) -> + ImplementationDefinedTestBeginEnd + (translate_boolean "isEnd" isEnd) + +| `AArch64AddSubCarry(d,n,m,datasize,sub_op,setflags) -> + AddSubCarry + (translate_reg "d" d, + translate_reg "n" n, + translate_reg "m" m, + translate_reg_size "datasize" datasize, + translate_boolean "sub_op" sub_op, + translate_boolean "setflags" setflags) + +| `AArch64AddSubExtendRegister (d,n,m,datasize,sub_op,setflags,extend_type,shift) -> + AddSubExtendRegister + (translate_reg "d" d, + translate_reg "n" n, + translate_reg "m" m, + translate_reg_size "datasize" datasize, + translate_boolean "sub_op" sub_op, + translate_boolean "setflags" setflags, + translate_extendType "extend_type" extend_type, + translate_range0_7 "shift" shift) + +| `AArch64AddSubShiftedRegister (d,n,m,datasize,sub_op,setflags,shift_type,shift_amount) -> + AddSubShiftedRegister + (translate_reg "d" d, + translate_reg "n" n, + translate_reg "m" m, + translate_reg_size "datasize" datasize, + translate_boolean "sub_op" sub_op, + translate_boolean "setflags" setflags, + translate_shiftType "shift_type" shift_type, + translate_range0_63 "shift_amount" shift_amount) + +| `AArch64AddSubImmediate (d,n,datasize,sub_op,setflags,imm) -> + AddSubImmediate + (translate_reg "d" d, + translate_reg "n" n, + translate_reg_size "datasize" datasize, + translate_boolean "sub_op" sub_op, + translate_boolean "setflags" setflags, + translate_reg_size_bits "imm" imm) + +| `AArch64Address (d,page,imm) -> + Address0 + (translate_reg "d" d, + translate_boolean "page" page, + translate_bit64 "imm" imm) + +| `AArch64LogicalImmediate (d,n,datasize,setflags,op,imm) -> + LogicalImmediate + (translate_reg "d" d, + translate_reg "n" n, + translate_reg_size "datasize" datasize, + translate_boolean "setflags" setflags, + translate_logicalOp "op" op, + translate_reg_size_bits "imm" imm) + +| `AArch64LogicalShiftedRegister (d,n,m,datasize,setflags,op,shift_type,shift_amount,invert) -> + LogicalShiftedRegister + (translate_reg "d" d, + translate_reg "n" n, + translate_reg "m" m, + translate_reg_size "datasize" datasize, + translate_boolean "setflags" setflags, + translate_logicalOp "op" op, + translate_shiftType "shift_type" shift_type, + translate_range0_63 "shift_amount" shift_amount, + translate_boolean "invert" invert) + +| `AArch64Shift (d,n,m,datasize,shift_type) -> + Shift + (translate_reg "d" d, + translate_reg "n" n, + translate_reg "m" m, + translate_reg_size "datasize" datasize, + translate_shiftType "shift_type" shift_type) + +| `AArch64BranchConditional (offset,condition) -> + BranchConditional + (translate_bit64 "offset" offset, + translate_bit4 "condition" condition) + +| `AArch64BranchImmediate (branch_type,offset) -> + BranchImmediate + (translate_branchType "branch_type" branch_type, + translate_bit64 "offset" offset) + +| `AArch64BitfieldMove (d,n,datasize,inzero,extend,_R,_S,wmask,tmask) -> + BitfieldMove + (translate_reg "d" d, + translate_reg "n" n, + translate_reg_size "datasize" datasize, + translate_boolean "inzero" inzero, + translate_boolean "extend" extend, + translate_uinteger "_R" _R, + translate_uinteger "_S" _S, + translate_reg_size_bits "wmask" wmask, + translate_reg_size_bits "tmask" tmask) + +| `AArch64BranchRegister (n,branch_type) -> + BranchRegister + (translate_reg "n" n, + translate_branchType "branch_type" branch_type) + +| `AArch64CompareAndBranch (t,datasize,iszero,offset) -> + CompareAndBranch + (translate_reg "t" t, + translate_reg_size "datasize" datasize, + translate_boolean "iszero" iszero, + translate_bit64 "offset" offset) + +| `AArch64ConditionalCompareImmediate (n,datasize,sub_op,condition,flags,imm) -> + ConditionalCompareImmediate + (translate_reg "n" n, + translate_reg_size "datasize" datasize, + translate_boolean "sub_op" sub_op, + translate_bit4 "condition" condition, + translate_bit4 "flags" flags, + translate_reg_size_bits "imm" imm) + +| `AArch64ConditionalCompareRegister (n,m,datasize,sub_op,condition,flags) -> + ConditionalCompareRegister + (translate_reg "n" n, + translate_reg "m" m, + translate_reg_size "datasize" datasize, + translate_boolean "sub_op" sub_op, + translate_bit4 "condition" condition, + translate_bit4 "flags" flags) + +| `AArch64ClearExclusiveMonitor (imm) -> + ClearExclusiveMonitor + (translate_uinteger "imm" imm) + +| `AArch64CountLeading (d,n,datasize,opcode) -> + CountLeading + (translate_reg "d" d, + translate_reg "n" n, + translate_reg_size "datasize" datasize, + translate_countOp "opcode" opcode) + +| `AArch64CRC (d,n,m,size,crc32c) -> + CRC + (translate_reg "d" d, + translate_reg "n" n, + translate_reg "m" m, + translate_data_size "size" size, + translate_boolean "crc32c" crc32c) + +| `AArch64ConditionalSelect (d,n,m,datasize,condition,else_inv,else_inc) -> + ConditionalSelect + (translate_reg "d" d, + translate_reg "n" n, + translate_reg "m" m, + translate_reg_size "datasize" datasize, + translate_bit4 "condition" condition, + translate_boolean "else_inv" else_inv, + translate_boolean "else_inc" else_inc) + +| `AArch64Barrier (op,domain,types) -> + Barrier2 + (translate_memBarrierOp "op" op, + translate_mBReqDomain "domain" domain, + translate_mBReqTypes "types" types) + +| `AArch64ExtractRegister (d,n,m,datasize,lsb) -> + ExtractRegister + (translate_reg "d" d, + translate_reg "n" n, + translate_reg "m" m, + translate_reg_size "datasize" datasize, + translate_uinteger "lsb" lsb) + +| `AArch64Hint (op) -> + Hint + (translate_systemHintOp "op" op) + +| `AArch64LoadStoreAcqExc (n,t,t2,s,acctype,excl,pair,memop,elsize,regsize,datasize) -> + LoadStoreAcqExc + (translate_reg "n" n, + translate_reg "t" t, + translate_reg "t2" t2, + translate_reg "s" s, + translate_accType "acctype" acctype, + translate_boolean "excl" excl, + translate_boolean "pair" pair, + translate_memOp "memop" memop, + translate_uinteger "elsize" elsize, + translate_reg_size "regsize" regsize, + translate_data_size "datasize" datasize) + +| `AArch64LoadStorePair (wback,postindex,n,t,t2,acctype,memop,signed,datasize,offset) -> + LoadStorePair + (translate_boolean "wback" wback, + translate_boolean "postindex" postindex, + translate_reg "n" n, + translate_reg "t" t, + translate_reg "t2" t2, + translate_accType "acctype" acctype, + translate_memOp "memop" memop, + translate_boolean "signed" signed, + translate_data_size "datasize" datasize, + translate_bit64 "offset" offset) + +| `AArch64LoadImmediate (n,t,acctype,memop,signed,wback,postindex,offset,regsize,datasize) -> + LoadImmediate + (translate_reg "n" n, + translate_reg "t" t, + translate_accType "acctype" acctype, + translate_memOp "memop" memop, + translate_boolean "signed" signed, + translate_boolean "wback" wback, + translate_boolean "postindex" postindex, + translate_bit64 "offset" offset, + translate_reg_size "regsize" regsize, + translate_data_size "datasize" datasize) + +| `AArch64LoadLiteral (t,memop,signed,size,offset,datasize) -> + LoadLiteral + (translate_reg "t" t, + translate_memOp "memop" memop, + translate_boolean "signed" signed, + translate_uinteger "size" size, + translate_bit64 "offset" offset, + translate_data_size "datasize" datasize) + +| `AArch64LoadRegister (n,t,m,acctype,memop,signed,wback,postindex,extend_type,shift,regsize,datasize) -> + LoadRegister + (translate_reg "n" n, + translate_reg "t" t, + translate_reg "m" m, + translate_accType "acctype" acctype, + translate_memOp "memop" memop, + translate_boolean "signed" signed, + translate_boolean "wback" wback, + translate_boolean "postindex" postindex, + translate_extendType "extend_type" extend_type, + translate_uinteger "shift" shift, + translate_reg_size "regsize" regsize, + translate_data_size "datasize" datasize) + +| `AArch64MultiplyAddSub (d,n,m,a,destsize,datasize,sub_op) -> + MultiplyAddSub + (translate_reg "d" d, + translate_reg "n" n, + translate_reg "m" m, + translate_reg "a" a, + translate_reg_size "destsize" destsize, + translate_data_size "datasize" datasize, + translate_boolean "sub_op" sub_op) + +| `AArch64MoveWide (d,datasize,imm,pos,opcode) -> + MoveWide + (translate_reg "d" d, + translate_reg_size "datasize" datasize, + translate_bit16 "imm" imm, + translate_uinteger "pos" pos, + translate_moveWideOp "opcode" opcode) + +| `AArch64Reverse (d,n,datasize,op) -> + Reverse + (translate_reg "d" d, + translate_reg "n" n, + translate_reg_size "datasize" datasize, + translate_revOp "op" op) + +| `AArch64Division (d,n,m,datasize,unsigned) -> + Division + (translate_reg "d" d, + translate_reg "n" n, + translate_reg "m" m, + translate_reg_size "datasize" datasize, + translate_boolean "unsigned" unsigned) + +| `AArch64MultiplyAddSubLong (d,n,m,a,destsize,datasize,sub_op,unsigned) -> + MultiplyAddSubLong + (translate_reg "d" d, + translate_reg "n" n, + translate_reg "m" m, + translate_reg "a" a, + translate_reg_size "destsize" destsize, + translate_data_size "datasize" datasize, + translate_boolean "sub_op" sub_op, + translate_boolean "unsigned" unsigned) + +| `AArch64MultiplyHigh (d,n,m,a,destsize,datasize,unsigned) -> + MultiplyHigh + (translate_reg "d" d, + translate_reg "n" n, + translate_reg "m" m, + translate_reg "a" a, + translate_reg_size "destsize" destsize, + translate_data_size "datasize" datasize, + translate_boolean "unsigned" unsigned) + +| `AArch64TestBitAndBranch (t,datasize,bit_pos,bit_val,offset) -> + TestBitAndBranch + (translate_reg "t" t, + translate_reg_size "datasize" datasize, + translate_uinteger "bit_pos" bit_pos, + translate_bit "bit_val" bit_val, + translate_bit64 "offset" offset) + +| `AArch64MoveSystemRegister (t,sys_op0,sys_op1,sys_op2,sys_crn,sys_crm,read) -> + MoveSystemRegister + (translate_reg "t" t, + translate_uinteger "sys_op0" sys_op0, + translate_uinteger "sys_op1" sys_op1, + translate_uinteger "sys_op2" sys_op2, + translate_uinteger "sys_crn" sys_crn, + translate_uinteger "sys_crm" sys_crm, + translate_boolean "read" read) + +| `AArch64MoveSystemImmediate (operand,field) -> + MoveSystemImmediate + (translate_bit4 "operand" operand, + translate_pSTATEField "field" field) diff --git a/arm/gen/herdtools_types_to_shallow_types.hgen b/arm/gen/herdtools_types_to_shallow_types.hgen new file mode 100644 index 00000000..e14a37e3 --- /dev/null +++ b/arm/gen/herdtools_types_to_shallow_types.hgen @@ -0,0 +1,153 @@ +open Sail_values + +let is_inc = false + +let translate_big_int bits (name : string) value = + (name, Range0 (Some bits), IInt.bit_list_of_integer bits value) + +let translate_big_bit bits (name:string) value = + Sail_values.to_vec0 is_inc (Nat_big_num.of_int bits,value) + +let translate_int (size : int) (name:string) value = (Nat_big_num.of_int value) + +let translate_bits bits (name:string) value = + Sail_values.to_vec0 is_inc (Nat_big_num.of_int bits,Nat_big_num.of_int value) + +let translate_bool _ = function + | true -> B1 + | false -> B0 + +let translate_reg_size name value = + match value with + | Set32 -> (Nat_big_num.of_int 32) + | Set64 -> (Nat_big_num.of_int 64) + +let translate_reg name value = + (Nat_big_num.of_int (inst_reg_to_int value)) + + +let translate_reg_size_bits name value = + match value with + | R32Bits value -> translate_bits 32 name value + | R64Bits value -> translate_big_bit 64 name value + +let translate_data_size name value = + match value with + | DataSize8 -> (Nat_big_num.of_int 8) + | DataSize16 -> (Nat_big_num.of_int 16) + | DataSize32 -> (Nat_big_num.of_int 32) + | DataSize64 -> (Nat_big_num.of_int 64) + +let translate_reg_index = translate_int 5 + +let translate_boolean = translate_bool + +let translate_range0_7 = translate_int 3 + +let translate_range0_63 = translate_int 6 + +let translate_bit64 = translate_big_bit 64 + +let translate_bit4 = translate_bits 4 +let translate_bit5 = translate_bits 5 +let translate_bit16 = translate_bits 16 + +let translate_bit = translate_bool + +let translate_range8_64 = translate_int 7 + +let translate_uinteger = translate_int 63 + +let translate_extendType _ = function + | ExtendType_UXTB -> ArmV8_embed_types.ExtendType_UXTB + | ExtendType_UXTH -> ArmV8_embed_types.ExtendType_UXTH + | ExtendType_UXTW -> ArmV8_embed_types.ExtendType_UXTW + | ExtendType_UXTX -> ArmV8_embed_types.ExtendType_UXTX + | ExtendType_SXTB -> ArmV8_embed_types.ExtendType_SXTB + | ExtendType_SXTH -> ArmV8_embed_types.ExtendType_SXTH + | ExtendType_SXTW -> ArmV8_embed_types.ExtendType_SXTW + | ExtendType_SXTX -> ArmV8_embed_types.ExtendType_SXTX + +let translate_shiftType _ = function + | ShiftType_LSL -> ArmV8_embed_types.ShiftType_LSL + | ShiftType_LSR -> ArmV8_embed_types.ShiftType_LSR + | ShiftType_ASR -> ArmV8_embed_types.ShiftType_ASR + | ShiftType_ROR -> ArmV8_embed_types.ShiftType_ROR + +let translate_logicalOp _ = function + | LogicalOp_AND -> ArmV8_embed_types.LogicalOp_AND + | LogicalOp_EOR -> ArmV8_embed_types.LogicalOp_EOR + | LogicalOp_ORR -> ArmV8_embed_types.LogicalOp_ORR + +let translate_branchType _ = function + | BranchType_CALL -> ArmV8_embed_types.BranchType_CALL + | BranchType_ERET -> ArmV8_embed_types.BranchType_ERET + | BranchType_DBGEXIT -> ArmV8_embed_types.BranchType_DBGEXIT + | BranchType_RET -> ArmV8_embed_types.BranchType_RET + | BranchType_JMP -> ArmV8_embed_types.BranchType_JMP + | BranchType_EXCEPTION -> ArmV8_embed_types.BranchType_EXCEPTION + | BranchType_UNKNOWN -> ArmV8_embed_types.BranchType_UNKNOWN + +let translate_countOp _ = function + | CountOp_CLZ -> ArmV8_embed_types.CountOp_CLZ + | CountOp_CLS -> ArmV8_embed_types.CountOp_CLS + | CountOp_CNT -> ArmV8_embed_types.CountOp_CNT + +let translate_memBarrierOp _ = function + | MemBarrierOp_DSB -> ArmV8_embed_types.MemBarrierOp_DSB + | MemBarrierOp_DMB -> ArmV8_embed_types.MemBarrierOp_DMB + | MemBarrierOp_ISB -> ArmV8_embed_types.MemBarrierOp_ISB + +let translate_mBReqDomain _ = function + | MBReqDomain_Nonshareable -> ArmV8_embed_types.MBReqDomain_Nonshareable + | MBReqDomain_InnerShareable -> ArmV8_embed_types.MBReqDomain_InnerShareable + | MBReqDomain_OuterShareable -> ArmV8_embed_types.MBReqDomain_OuterShareable + | MBReqDomain_FullSystem -> ArmV8_embed_types.MBReqDomain_FullSystem + +let translate_mBReqTypes _ = function + | MBReqTypes_Reads -> ArmV8_embed_types.MBReqTypes_Reads + | MBReqTypes_Writes -> ArmV8_embed_types.MBReqTypes_Writes + | MBReqTypes_All -> ArmV8_embed_types.MBReqTypes_All + +let translate_systemHintOp _ = function + | SystemHintOp_NOP -> ArmV8_embed_types.SystemHintOp_NOP + | SystemHintOp_YIELD -> ArmV8_embed_types.SystemHintOp_YIELD + | SystemHintOp_WFE -> ArmV8_embed_types.SystemHintOp_WFE + | SystemHintOp_WFI -> ArmV8_embed_types.SystemHintOp_WFI + | SystemHintOp_SEV -> ArmV8_embed_types.SystemHintOp_SEV + | SystemHintOp_SEVL -> ArmV8_embed_types.SystemHintOp_SEVL + +let translate_accType _ = function + | AccType_NORMAL -> ArmV8_embed_types.AccType_NORMAL + | AccType_VEC -> ArmV8_embed_types.AccType_VEC + | AccType_STREAM -> ArmV8_embed_types.AccType_STREAM + | AccType_VECSTREAM -> ArmV8_embed_types.AccType_VECSTREAM + | AccType_ATOMIC -> ArmV8_embed_types.AccType_ATOMIC + | AccType_ORDERED -> ArmV8_embed_types.AccType_ORDERED + | AccType_UNPRIV -> ArmV8_embed_types.AccType_UNPRIV + | AccType_IFETCH -> ArmV8_embed_types.AccType_IFETCH + | AccType_PTW -> ArmV8_embed_types.AccType_PTW + | AccType_DC -> ArmV8_embed_types.AccType_DC + | AccType_IC -> ArmV8_embed_types.AccType_IC + | AccType_AT -> ArmV8_embed_types.AccType_AT + +let translate_memOp _ = function + | MemOp_LOAD -> ArmV8_embed_types.MemOp_LOAD + | MemOp_STORE -> ArmV8_embed_types.MemOp_STORE + | MemOp_PREFETCH -> ArmV8_embed_types.MemOp_PREFETCH + +let translate_moveWideOp _ = function + | MoveWideOp_N -> ArmV8_embed_types.MoveWideOp_N + | MoveWideOp_Z -> ArmV8_embed_types.MoveWideOp_Z + | MoveWideOp_K -> ArmV8_embed_types.MoveWideOp_K + +let translate_revOp _ = function + | RevOp_RBIT -> ArmV8_embed_types.RevOp_RBIT + | RevOp_REV16 -> ArmV8_embed_types.RevOp_REV16 + | RevOp_REV32 -> ArmV8_embed_types.RevOp_REV32 + | RevOp_REV64 -> ArmV8_embed_types.RevOp_REV64 + +let translate_pSTATEField _ = function + | PSTATEField_DAIFSet -> ArmV8_embed_types.PSTATEField_DAIFSet + | PSTATEField_DAIFClr -> ArmV8_embed_types.PSTATEField_DAIFClr + | PSTATEField_SP -> ArmV8_embed_types.PSTATEField_SP diff --git a/arm/gen/lexer.hgen b/arm/gen/lexer.hgen new file mode 100644 index 00000000..6ff24317 --- /dev/null +++ b/arm/gen/lexer.hgen @@ -0,0 +1,309 @@ +(* instructions: *) + + "TSTART" , TSTART {txt="TSTART"} ; + "TCOMMIT", TCOMMIT {txt="TCOMMIT"} ; + "TABORT" , TABORT {txt="TABORT"} ; + "TTEST" , TTEST {txt="TTEST"} ; + + "ADC" , ADCSBC {txt="ADC"; sub_op = false; setflags = false} ; + "SBC" , ADCSBC {txt="SBC"; sub_op = true; setflags = false} ; + "ADCS" , ADCSBC {txt="ADCS"; sub_op = false; setflags = true} ; + "SBCS" , ADCSBC {txt="SBCS"; sub_op = true; setflags = true} ; + + "ADD" , ADDSUB {txt="ADD"; sub_op=false; setflags=false} ; + "SUB" , ADDSUB {txt="SUB"; sub_op=true; setflags=false} ; + "ADDS" , ADDSUB {txt="ADDS"; sub_op=false; setflags=true} ; + "SUBS" , ADDSUB {txt="SUBS"; sub_op=true; setflags=true} ; + + "ADR" , ADR {txt="ADR"; page=false} ; + "ADRP" , ADR {txt="ADRP"; page=true} ; + + "AND" , LOGOP {txt="AND"; op = LogicalOp_AND; setflags = false; invert = false} ; + "ANDS" , LOGOP {txt="ANDS"; op = LogicalOp_AND; setflags = true; invert = false} ; + "EOR" , LOGOP {txt="EOR"; op = LogicalOp_EOR; setflags = false; invert = false} ; + "ORR" , LOGOP {txt="ORR"; op = LogicalOp_ORR; setflags = false; invert = false} ; + "BIC" , LOGOP {txt="BIC"; op = LogicalOp_AND; setflags = false; invert = true} ; + "BICS" , LOGOP {txt="BICS"; op = LogicalOp_AND; setflags = true; invert = true} ; + "EON" , LOGOP {txt="EON"; op = LogicalOp_EOR; setflags = false; invert = true} ; + "ORN" , LOGOP {txt="ORN"; op = LogicalOp_ORR; setflags = false; invert = true} ; + + "ASRV" , SHIFTOP {txt="ASRV"; shift_type=ShiftType_ASR} ; + "LSLV" , SHIFTOP {txt="LSLV"; shift_type=ShiftType_LSL} ; + "LSRV" , SHIFTOP {txt="LSRV"; shift_type=ShiftType_LSR} ; + "RORV" , SHIFTOP {txt="RORV"; shift_type=ShiftType_ROR} ; + + "B.EQ" , BCOND {txt="B.EQ"; condition=0b0000} ; + "B.NE" , BCOND {txt="B.NE"; condition=0b0001} ; + "B.CS" , BCOND {txt="B.CS"; condition=0b0010} ; + "B.HS" , BCOND {txt="B.CS"; condition=0b0010} ; + "B.CC" , BCOND {txt="B.CC"; condition=0b0011} ; + "B.LO" , BCOND {txt="B.CC"; condition=0b0011} ; + "B.MI" , BCOND {txt="B.MI"; condition=0b0100} ; + "B.PL" , BCOND {txt="B.PL"; condition=0b0101} ; + "B.VS" , BCOND {txt="B.VS"; condition=0b0110} ; + "B.VC" , BCOND {txt="B.VC"; condition=0b0111} ; + "B.HI" , BCOND {txt="B.HI"; condition=0b1000} ; + "B.LS" , BCOND {txt="B.LS"; condition=0b1001} ; + "B.GE" , BCOND {txt="B.GE"; condition=0b1010} ; + "B.LT" , BCOND {txt="B.LT"; condition=0b1011} ; + "B.GT" , BCOND {txt="B.GT"; condition=0b1100} ; + "B.LE" , BCOND {txt="B.LE"; condition=0b1101} ; + "B.AL" , BCOND {txt="B.AL"; condition=0b1110} ; + "B.NV" , BCOND {txt="B.NV"; condition=0b1111} ; (* ARM: exists only to provide a valid disassembly + of the 0b1111 encoding, otherwise its + behavior is identical to AL *) + + "B" , B {txt="B"; branch_type=BranchType_JMP} ; + "BL" , B {txt="BL"; branch_type=BranchType_CALL} ; + + "BR" , BR {txt="BR"; branch_type=BranchType_JMP} ; + "BLR" , BR {txt="BLR"; branch_type=BranchType_CALL} ; + + "CBZ" , CBZ {txt="CBZ"; iszero=true} ; + "CBNZ" , CBZ {txt="CBNZ"; iszero=false} ; + + "BFM" , BFM {txt="BFM"; inzero=false; extend=false} ; + "SBFM" , BFM {txt="SBFM"; inzero=true; extend=true} ; + "UBFM" , BFM {txt="UBFM"; inzero=true; extend=false} ; + + "CCMN" , CCM {txt="CCMN"; sub_op=false} ; + "CCMP" , CCM {txt="CCMP"; sub_op=true} ; + + "CMN" , CM {txt="CMN"; sub_op=false} ; + "CMP" , CM {txt="CMP"; sub_op=true} ; + + "CLS" , CL {txt="CLS"; opcode=CountOp_CLS} ; + "CLZ" , CL {txt="CLZ"; opcode=CountOp_CLZ} ; + + "CRC32B" , CRC {txt="CRC32B"; size = DataSize8; crc32c = false} ; + "CRC32H" , CRC {txt="CRC32H"; size = DataSize16; crc32c = false} ; + "CRC32W" , CRC {txt="CRC32W"; size = DataSize32; crc32c = false} ; + "CRC32CB" , CRC {txt="CRC32CB"; size = DataSize8; crc32c = true} ; + "CRC32CH" , CRC {txt="CRC32CH"; size = DataSize16; crc32c = true} ; + "CRC32CW" , CRC {txt="CRC32CW"; size = DataSize32; crc32c = true} ; + + "CRC32X" , CRC32X {txt="CRC32X"; crc32c=false} ; + "CRC32CX" , CRC32X {txt="CRC32CX"; crc32c=true} ; + + "CSEL" , CSEL {txt="CSEL"; else_inv = false; else_inc = false} ; + "CSINC" , CSEL {txt="CSINC"; else_inv = false; else_inc = true} ; + "CSINV" , CSEL {txt="CSINV"; else_inv = true; else_inc = false} ; + "CSNEG" , CSEL {txt="CSNEG"; else_inv = true; else_inc = true} ; + + "CSET" , CSET {txt="CSET"; else_inv = false; else_inc = true} ; + "CSETM" , CSETM {txt="CSETM"; else_inv = true; else_inc = false} ; + + "CINC" , CON {txt="CINC"; else_inv = false; else_inc = true} ; + "CINV" , CON {txt="CINV"; else_inv = true; else_inc = false} ; + "CNEG" , CON {txt="CNEG"; else_inv = true; else_inc = true} ; + + "DMB" , MEMBARR {txt="DMB"; op=MemBarrierOp_DMB} ; + "DSB" , MEMBARR {txt="DSB"; op=MemBarrierOp_DSB} ; + + "LDAR" , LDAXR {txt="LDAR"; acctype=AccType_ORDERED; excl=false; memop=MemOp_LOAD; var32={elsize=32; datasize=DataSize32}; var64=true} ; + "LDARB" , LDAXR {txt="LDARB"; acctype=AccType_ORDERED; excl=false; memop=MemOp_LOAD; var32={elsize=8; datasize=DataSize8}; var64=false} ; + "LDARH" , LDAXR {txt="LDARH"; acctype=AccType_ORDERED; excl=false; memop=MemOp_LOAD; var32={elsize=16; datasize=DataSize16}; var64=false} ; + "LDAXR" , LDAXR {txt="LDAXR"; acctype=AccType_ORDERED; excl=true; memop=MemOp_LOAD; var32={elsize=32; datasize=DataSize32}; var64=true} ; + "LDAXRB" , LDAXR {txt="LDAXRB"; acctype=AccType_ORDERED; excl=true; memop=MemOp_LOAD; var32={elsize=8; datasize=DataSize8}; var64=false} ; + "LDAXRH" , LDAXR {txt="LDAXRH"; acctype=AccType_ORDERED; excl=true; memop=MemOp_LOAD; var32={elsize=16; datasize=DataSize16}; var64=false} ; + "LDXR" , LDAXR {txt="LDXR"; acctype=AccType_ATOMIC; excl=true; memop=MemOp_LOAD; var32={elsize=32; datasize=DataSize32}; var64=true} ; + "LDXRB" , LDAXR {txt="LDXRB"; acctype=AccType_ATOMIC; excl=true; memop=MemOp_LOAD; var32={elsize=8; datasize=DataSize8}; var64=false} ; + "LDXRH" , LDAXR {txt="LDXRH"; acctype=AccType_ATOMIC; excl=true; memop=MemOp_LOAD; var32={elsize=16; datasize=DataSize16}; var64=false} ; + "STLR" , LDAXR {txt="STLR"; acctype=AccType_ORDERED; excl=false; memop=MemOp_STORE; var32={elsize=32; datasize=DataSize32}; var64=true} ; + "STLRB" , LDAXR {txt="STLRB"; acctype=AccType_ORDERED; excl=false; memop=MemOp_STORE; var32={elsize=8; datasize=DataSize8}; var64=false} ; + "STLRH" , LDAXR {txt="STLRH"; acctype=AccType_ORDERED; excl=false; memop=MemOp_STORE; var32={elsize=16; datasize=DataSize16}; var64=false} ; + + "STLXR" , STLXR {txt="STLXR"; acctype=AccType_ORDERED; var32={elsize=32; datasize=DataSize32}; var64=true} ; + "STLXRB" , STLXR {txt="STLXRB"; acctype=AccType_ORDERED; var32={elsize=8; datasize=DataSize8}; var64=false} ; + "STLXRH" , STLXR {txt="STLXRH"; acctype=AccType_ORDERED; var32={elsize=16; datasize=DataSize16}; var64=false} ; + "STXR" , STLXR {txt="STXR"; acctype=AccType_ATOMIC; var32={elsize=32; datasize=DataSize32}; var64=true} ; + "STXRB" , STLXR {txt="STXRB"; acctype=AccType_ATOMIC; var32={elsize=8; datasize=DataSize8}; var64=false} ; + "STXRH" , STLXR {txt="STXRH"; acctype=AccType_ATOMIC; var32={elsize=16; datasize=DataSize16}; var64=false} ; + + + "LDAXP" , LDXP {txt="LDAXP"; acctype=AccType_ORDERED} ; + "LDXP" , LDXP {txt="LDXP"; acctype=AccType_ATOMIC} ; + + "STLXP" , STXP {txt="STLXP"; acctype=AccType_ORDERED} ; + "STXP" , STXP {txt="STXP"; acctype=AccType_ATOMIC} ; + + "LDR" , LDSTR {txt="LDR"; memop=MemOp_LOAD; signed=false; lit32=true; var32=Some {datasize=DataSize32}; var64=Some {datasize=DataSize64}; lit64=Some {datasize=DataSize64; size=8}} ; + "LDRB" , LDSTR {txt="LDRB"; memop=MemOp_LOAD; signed=false; lit32=false; var32=Some {datasize=DataSize8}; var64=None; lit64=None} ; + "LDRH" , LDSTR {txt="LDRH"; memop=MemOp_LOAD; signed=false; lit32=false; var32=Some {datasize=DataSize16}; var64=None; lit64=None} ; + "LDRSB" , LDSTR {txt="LDRSB"; memop=MemOp_LOAD; signed=true; lit32=false; var32=Some {datasize=DataSize8}; var64=Some {datasize=DataSize8}; lit64=None} ; + "LDRSH" , LDSTR {txt="LDRSH"; memop=MemOp_LOAD; signed=true; lit32=false; var32=Some {datasize=DataSize16}; var64=Some {datasize=DataSize16}; lit64=None} ; + "LDRSW" , LDSTR {txt="LDRSW"; memop=MemOp_LOAD; signed=true; lit32=false; var32=None; var64=Some {datasize=DataSize32}; lit64=Some {datasize=DataSize32; size=4}} ; + "STR" , LDSTR {txt="STR"; memop=MemOp_STORE; signed=false; lit32=false; var32=Some {datasize=DataSize32}; var64=Some {datasize=DataSize64}; lit64=None} ; + "STRB" , LDSTR {txt="STRB"; memop=MemOp_STORE; signed=false; lit32=false; var32=Some {datasize=DataSize8}; var64=None; lit64=None} ; + "STRH" , LDSTR {txt="STRH"; memop=MemOp_STORE; signed=false; lit32=false; var32=Some {datasize=DataSize16}; var64=None; lit64=None} ; + + "LDTR" , LDSTTUR {txt="LDTR"; memop=MemOp_LOAD; acctype=AccType_UNPRIV; signed=false; off32=Some {datasize=DataSize32}; off64=Some {datasize=DataSize64}} ; + "LDTRB" , LDSTTUR {txt="LDTRB"; memop=MemOp_LOAD; acctype=AccType_UNPRIV; signed=false; off32=Some {datasize=DataSize8}; off64=None} ; + "LDTRH" , LDSTTUR {txt="LDTRH"; memop=MemOp_LOAD; acctype=AccType_UNPRIV; signed=false; off32=Some {datasize=DataSize16}; off64=None} ; + "LDTRSB" , LDSTTUR {txt="LDTRSB"; memop=MemOp_LOAD; acctype=AccType_UNPRIV; signed=true; off32=Some {datasize=DataSize8}; off64=Some {datasize=DataSize8}} ; + "LDTRSH" , LDSTTUR {txt="LDTRSH"; memop=MemOp_LOAD; acctype=AccType_UNPRIV; signed=true; off32=Some {datasize=DataSize16}; off64=Some {datasize=DataSize16}} ; + "LDTRSW" , LDSTTUR {txt="LDTRSW"; memop=MemOp_LOAD; acctype=AccType_UNPRIV; signed=true; off32=None; off64=Some {datasize=DataSize32}} ; + "LDUR" , LDSTTUR {txt="LDUR"; memop=MemOp_LOAD; acctype=AccType_NORMAL; signed=false; off32=Some {datasize=DataSize32}; off64=Some {datasize=DataSize64}} ; + "LDURB" , LDSTTUR {txt="LDURB"; memop=MemOp_LOAD; acctype=AccType_NORMAL; signed=false; off32=Some {datasize=DataSize8}; off64=None} ; + "LDURH" , LDSTTUR {txt="LDURH"; memop=MemOp_LOAD; acctype=AccType_NORMAL; signed=false; off32=Some {datasize=DataSize16}; off64=None} ; + "LDURSB" , LDSTTUR {txt="LDURSB"; memop=MemOp_LOAD; acctype=AccType_NORMAL; signed=true; off32=Some {datasize=DataSize8}; off64=Some {datasize=DataSize8}} ; + "LDURSH" , LDSTTUR {txt="LDURSH"; memop=MemOp_LOAD; acctype=AccType_NORMAL; signed=true; off32=Some {datasize=DataSize16}; off64=Some {datasize=DataSize16}} ; + "LDURSW" , LDSTTUR {txt="LDURSW"; memop=MemOp_LOAD; acctype=AccType_NORMAL; signed=true; off32=None; off64=Some {datasize=DataSize32}} ; + "STTR" , LDSTTUR {txt="STTR"; memop=MemOp_STORE; acctype=AccType_UNPRIV; signed=false; off32=Some {datasize=DataSize32}; off64=Some {datasize=DataSize64}} ; + "STTRB" , LDSTTUR {txt="STTRB"; memop=MemOp_STORE; acctype=AccType_UNPRIV; signed=false; off32=Some {datasize=DataSize8}; off64=None} ; + "STTRH" , LDSTTUR {txt="STTRH"; memop=MemOp_STORE; acctype=AccType_UNPRIV; signed=false; off32=Some {datasize=DataSize16}; off64=None} ; + "STUR" , LDSTTUR {txt="STUR"; memop=MemOp_STORE; acctype=AccType_NORMAL; signed=false; off32=Some {datasize=DataSize32}; off64=Some {datasize=DataSize64}} ; + "STURB" , LDSTTUR {txt="STURB"; memop=MemOp_STORE; acctype=AccType_NORMAL; signed=false; off32=Some {datasize=DataSize8}; off64=None} ; + "STURH" , LDSTTUR {txt="STURH"; memop=MemOp_STORE; acctype=AccType_NORMAL; signed=false; off32=Some {datasize=DataSize16}; off64=None} ; + + "MADD" , MADDSUB {txt="MADD"; sub_op=false} ; + "MSUB" , MADDSUB {txt="MSUB"; sub_op=true} ; + + "MUL" , MUL {txt="MUL"; sub_op=false} ; + "MNEG" , MUL {txt="MNEG"; sub_op=true} ; + + "MOVK" , MOVWIDE {txt="MOVK"; opcode=MoveWideOp_K} ; + "MOVN" , MOVWIDE {txt="MOVN"; opcode=MoveWideOp_N} ; + "MOVZ" , MOVWIDE {txt="MOVZ"; opcode=MoveWideOp_Z} ; + + "NEG" , NEG {txt="NEG"; setflags=false} ; + "NEGS" , NEG {txt="NEGS"; setflags=true} ; + + "NGC" , NGC {txt="NGC"; setflags=false} ; + "NGCS" , NGC {txt="NGCS"; setflags=true} ; + + "RBIT" , REV {txt="RBIT"; op32=Some RevOp_RBIT; op64=RevOp_RBIT} ; + "REV" , REV {txt="REV"; op32=Some RevOp_REV32; op64=RevOp_REV64} ; + "REV16" , REV {txt="REV16"; op32=Some RevOp_REV16; op64=RevOp_REV16} ; + "REV32" , REV {txt="REV32"; op32=None; op64=RevOp_REV32} ; + + "SDIV" , DIV {txt="SDIV"; unsigned=false} ; + "UDIV" , DIV {txt="UDIV"; unsigned=true} ; + + "SMADDL" , MADDSUBL {txt="SMADDL"; sub_op=false; unsigned=false} ; + "SMSUBL" , MADDSUBL {txt="SMSUBL"; sub_op=true; unsigned=false} ; + "UMADDL" , MADDSUBL {txt="UMADDL"; sub_op=false; unsigned=true} ; + "UMSUBL" , MADDSUBL {txt="UMSUBL"; sub_op=true; unsigned=true} ; + + "SMULH" , MULH {txt="SMULH"; unsigned=false} ; + "UMULH" , MULH {txt="UMULH"; unsigned=true} ; + + "SMULL" , MULL {txt="SMULL"; unsigned=false} ; + "UMULL" , MULL {txt="UMULL"; unsigned=true} ; + + "LDP" , LDSTP {txt="LDP"; memop=MemOp_LOAD} ; + "STP" , LDSTP {txt="STP"; memop=MemOp_STORE} ; + + "TBZ" , TBZ {txt="TBZ"; bit_val=false} ; + "TBNZ" , TBZ {txt="TBNZ"; bit_val=true} ; + + "SBFIZ" , BFIZ {txt="SBFIZ"; extend=true} ; + "UBFIZ" , BFIZ {txt="UBFIZ"; extend=false} ; + + "SBFX" , BFX {txt="SBFX"; extend=true} ; + "UBFX" , BFX {txt="UBFX"; extend=false} ; + + "SMNEGL" , MNEGL {txt="SMNEGL"; unsigned=false} ; + "UMNEGL" , MNEGL {txt="UMNEGL"; unsigned=true} ; + + "BFI" , BFI {txt="BFI"} ; + "BFXIL" , BFXIL {txt="BFXIL"} ; + "CLREX" , CLREX {txt="CLREX"} ; + "EXTR" , EXTR {txt="EXTR"} ; + "HINT" , HINT {txt="HINT"} ; + "ISB" , ISB {txt="ISB"} ; + "LDPSW" , LDPSW {txt="LDPSW"} ; + "MOV" , MOV {txt="MOV"} ; + "MVN" , MVN {txt="MVN"} ; + "NOP" , NOP {txt="NOP"} ; + "PRFM" , PRFM {txt="PRFM"} ; + "PRFUM" , PRFUM {txt="PRFUM"} ; + "RET" , RET {txt="RET"} ; + "TST" , TST {txt="TST"} ; + "MRS" , MRS {txt="MRS"} ; + "MSR" , MSR {txt="MSR"} ; + + +(*** instructions/operands ***) + + "LSL" , SHIFT {txt="LSL"; shift_type=ShiftType_LSL} ; + "LSR" , SHIFT {txt="LSR"; shift_type=ShiftType_LSR} ; + "ASR" , SHIFT {txt="ASR"; shift_type=ShiftType_ASR} ; + "ROR" , SHIFT {txt="ROR"; shift_type=ShiftType_ROR} ; + + "UXTB" , EXTEND {txt="UXTB"; _type=ExtendType_UXTB; inst=Some {extend=false; imms=7}} ; + "UXTH" , EXTEND {txt="UXTH"; _type=ExtendType_UXTH; inst=Some {extend=false; imms=15}} ; + "UXTW" , EXTEND {txt="UXTW"; _type=ExtendType_UXTW; inst=None} ; + "UXTX" , EXTEND {txt="UXTX"; _type=ExtendType_UXTX; inst=None} ; + "SXTB" , EXTEND {txt="SXTB"; _type=ExtendType_SXTB; inst=Some {extend=true; imms=7}} ; + "SXTH" , EXTEND {txt="SXTH"; _type=ExtendType_SXTH; inst=Some {extend=true; imms=15}} ; + "SXTW" , EXTEND {txt="SXTW"; _type=ExtendType_SXTW; inst=Some {extend=true; imms=31}} ; + "SXTX" , EXTEND {txt="SXTX"; _type=ExtendType_SXTX; inst=None} ; + +(*** operands: ***) + + "EQ" , COND 0b0000 ; + "NE" , COND 0b0001 ; + "CS" , COND 0b0010 ; + "HS" , COND 0b0010 ; + "CC" , COND 0b0011 ; + "LO" , COND 0b0011 ; + "MI" , COND 0b0100 ; + "PL" , COND 0b0101 ; + "VS" , COND 0b0110 ; + "VC" , COND 0b0111 ; + "HI" , COND 0b1000 ; + "LS" , COND 0b1001 ; + "GE" , COND 0b1010 ; + "LT" , COND 0b1011 ; + "GT" , COND 0b1100 ; + "LE" , COND 0b1101 ; + "AL" , COND 0b1110 ; + "NV" , COND 0b1111 ; (* ARM: exists only to provide a valid disassembly + of the 0b1111 encoding, otherwise its + behavior is identical to AL *) + + "OSHLD" , BARROP {domain=MBReqDomain_OuterShareable; types=MBReqTypes_Reads} ; + "OSHST" , BARROP {domain=MBReqDomain_OuterShareable; types=MBReqTypes_Writes} ; + "OSH" , BARROP {domain=MBReqDomain_OuterShareable; types=MBReqTypes_All} ; + "NSHLD" , BARROP {domain=MBReqDomain_Nonshareable; types=MBReqTypes_Reads} ; + "NSHST" , BARROP {domain=MBReqDomain_Nonshareable; types=MBReqTypes_Writes} ; + "NSH" , BARROP {domain=MBReqDomain_Nonshareable; types=MBReqTypes_All} ; + "ISHLD" , BARROP {domain=MBReqDomain_InnerShareable; types=MBReqTypes_Reads} ; + "ISHST" , BARROP {domain=MBReqDomain_InnerShareable; types=MBReqTypes_Writes} ; + "ISH" , BARROP {domain=MBReqDomain_InnerShareable; types=MBReqTypes_All} ; + "LD" , BARROP {domain=MBReqDomain_FullSystem; types=MBReqTypes_Reads} ; + "ST" , BARROP {domain=MBReqDomain_FullSystem; types=MBReqTypes_Writes} ; + "SY" , BARROP {domain=MBReqDomain_FullSystem; types=MBReqTypes_All} ; + + "PLDL1KEEP" , PRFOP (X (Ireg R0)) ; + "PLDL1STRM" , PRFOP (X (Ireg R1)) ; + "PLDL2KEEP" , PRFOP (X (Ireg R2)) ; + "PLDL2STRM" , PRFOP (X (Ireg R3)) ; + "PLDL3KEEP" , PRFOP (X (Ireg R4)) ; + "PLDL3STRM" , PRFOP (X (Ireg R5)) ; + + "PLIL1KEEP" , PRFOP (X (Ireg R8)) ; + "PLIL1STRM" , PRFOP (X (Ireg R9)) ; + "PLIL2KEEP" , PRFOP (X (Ireg R10)) ; + "PLIL2STRM" , PRFOP (X (Ireg R11)) ; + "PLIL3KEEP" , PRFOP (X (Ireg R12)) ; + "PLIL3STRM" , PRFOP (X (Ireg R13)) ; + + "PSTL1KEEP" , PRFOP (X (Ireg R16)) ; + "PSTL1STRM" , PRFOP (X (Ireg R17)) ; + "PSTL2KEEP" , PRFOP (X (Ireg R18)) ; + "PSTL2STRM" , PRFOP (X (Ireg R19)) ; + "PSTL3KEEP" , PRFOP (X (Ireg R20)) ; + "PSTL3STRM" , PRFOP (X (Ireg R21)) ; + + "NZCV" , SYSREG {sys_op0=0b11; sys_op1=0b011; sys_op2=0b000; sys_crn=0b0100; sys_crm=0b0010} ; + "DAIF" , SYSREG {sys_op0=0b11; sys_op1=0b011; sys_op2=0b001; sys_crn=0b0100; sys_crm=0b0010} ; + "TPIDR_EL0" , SYSREG {sys_op0=0b11; sys_op1=0b011; sys_op2=0b010; sys_crn=0b1101; sys_crm=0b0000} ; + "TPIDR_EL1" , SYSREG {sys_op0=0b11; sys_op1=0b000; sys_op2=0b100; sys_crn=0b1101; sys_crm=0b0000} ; + "TPIDR_EL2" , SYSREG {sys_op0=0b11; sys_op1=0b100; sys_op2=0b010; sys_crn=0b1101; sys_crm=0b0000} ; + "TPIDR_EL3" , SYSREG {sys_op0=0b11; sys_op1=0b011; sys_op2=0b011; sys_crn=0b1101; sys_crm=0b0000} ; + + "SPSel" , PSTATEFIELD (PSTATEField_SP) ; + "DAIFSet" , PSTATEFIELD (PSTATEField_DAIFSet) ; + "DAIFClr" , PSTATEFIELD (PSTATEField_DAIFClr) ; diff --git a/arm/gen/map.hgen b/arm/gen/map.hgen new file mode 100644 index 00000000..62899c91 --- /dev/null +++ b/arm/gen/map.hgen @@ -0,0 +1,44 @@ +| `AArch64TMStart t -> `AArch64TMStart (map_reg t) +| `AArch64TMCommit -> `AArch64TMCommit +| `AArch64TMAbort (retry,reason) -> `AArch64TMAbort (retry,reason) +| `AArch64TMTest -> `AArch64TMTest + +| `AArch64ImplementationDefinedStopFetching -> `AArch64ImplementationDefinedStopFetching +| `AArch64ImplementationDefinedThreadStart -> `AArch64ImplementationDefinedThreadStart +| `AArch64ImplementationDefinedTestBeginEnd (isEnd) -> `AArch64ImplementationDefinedTestBeginEnd (isEnd) +| `AArch64AddSubCarry (d,n,m,datasize,sub_op,setflags) -> `AArch64AddSubCarry (map_reg d,map_reg n,map_reg m,datasize,sub_op,setflags) +| `AArch64AddSubExtendRegister (d,n,m,datasize,sub_op,setflags,extend_type,shift) -> `AArch64AddSubExtendRegister (map_reg d,map_reg n,map_reg m,datasize,sub_op,setflags,extend_type,shift) +| `AArch64AddSubShiftedRegister (d,n,m,datasize,sub_op,setflags,shift_type,shift_amount) -> `AArch64AddSubShiftedRegister (map_reg d,map_reg n,map_reg m,datasize,sub_op,setflags,shift_type,shift_amount) +| `AArch64AddSubImmediate (d,n,datasize,sub_op,setflags,imm) -> `AArch64AddSubImmediate (map_reg d,map_reg n,datasize,sub_op,setflags,imm) +| `AArch64Address (d,page,imm) -> `AArch64Address (map_reg d,page,imm) +| `AArch64LogicalImmediate (d,n,datasize,setflags,op,imm) -> `AArch64LogicalImmediate (map_reg d,map_reg n,datasize,setflags,op,imm) +| `AArch64LogicalShiftedRegister (d,n,m,datasize,setflags,op,shift_type,shift_amount,invert) -> `AArch64LogicalShiftedRegister (map_reg d,map_reg n,map_reg m,datasize,setflags,op,shift_type,shift_amount,invert) +| `AArch64Shift (d,n,m,datasize,shift_type) -> `AArch64Shift (map_reg d,map_reg n,map_reg m,datasize,shift_type) +| `AArch64BranchConditional (offset,condition) -> `AArch64BranchConditional (offset,condition) +| `AArch64BranchImmediate (branch_type,offset) -> `AArch64BranchImmediate (branch_type,offset) +| `AArch64BitfieldMove (d,n,datasize,inzero,extend,_R,_S,wmask,tmask) -> `AArch64BitfieldMove (map_reg d,map_reg n,datasize,inzero,extend,_R,_S,wmask,tmask) +| `AArch64BranchRegister (n,branch_type) -> `AArch64BranchRegister (map_reg n,branch_type) +| `AArch64CompareAndBranch (t,datasize,iszero,offset) -> `AArch64CompareAndBranch (map_reg t,datasize,iszero,offset) +| `AArch64ConditionalCompareImmediate (n,datasize,sub_op,condition,flags,imm) -> `AArch64ConditionalCompareImmediate (map_reg n,datasize,sub_op,condition,flags,imm) +| `AArch64ConditionalCompareRegister (n,m,datasize,sub_op,condition,flags) -> `AArch64ConditionalCompareRegister (map_reg n,map_reg m,datasize,sub_op,condition,flags) +| `AArch64ClearExclusiveMonitor (imm) -> `AArch64ClearExclusiveMonitor (imm) +| `AArch64CountLeading (d,n,datasize,opcode) -> `AArch64CountLeading (map_reg d,map_reg n,datasize,opcode) +| `AArch64CRC (d,n,m,size,crc32c) -> `AArch64CRC (map_reg d,map_reg n,map_reg m,size,crc32c) +| `AArch64ConditionalSelect (d,n,m,datasize,condition,else_inv,else_inc) -> `AArch64ConditionalSelect (map_reg d,map_reg n,map_reg m,datasize,condition,else_inv,else_inc) +| `AArch64Barrier (op,domain,types) -> `AArch64Barrier (op,domain,types) +| `AArch64ExtractRegister (d,n,m,datasize,lsb) -> `AArch64ExtractRegister (map_reg d,map_reg n,map_reg m,datasize,lsb) +| `AArch64Hint (op) -> `AArch64Hint (op) +| `AArch64LoadStoreAcqExc (n,t,t2,s,acctype,excl,pair,memop,elsize,regsize,datasize) -> `AArch64LoadStoreAcqExc (map_reg n,map_reg t,map_reg t2,map_reg s,acctype,excl,pair,memop,elsize,regsize,datasize) +| `AArch64LoadStorePair (wback,postindex,n,t,t2,acctype,memop,signed,datasize,offset) -> `AArch64LoadStorePair (wback,postindex,map_reg n,map_reg t,map_reg t2,acctype,memop,signed,datasize,offset) +| `AArch64LoadImmediate (n,t,acctype,memop,signed,wback,postindex,offset,regsize,datasize) -> `AArch64LoadImmediate (map_reg n,map_reg t,acctype,memop,signed,wback,postindex,offset,regsize,datasize) +| `AArch64LoadLiteral (t,memop,signed,size,offset,datasize) -> `AArch64LoadLiteral (map_reg t,memop,signed,size,offset,datasize) +| `AArch64LoadRegister (n,t,m,acctype,memop,signed,wback,postindex,extend_type,shift,regsize,datasize) -> `AArch64LoadRegister (map_reg n,map_reg t,map_reg m,acctype,memop,signed,wback,postindex,extend_type,shift,regsize,datasize) +| `AArch64MultiplyAddSub (d,n,m,a,destsize,datasize,sub_op) -> `AArch64MultiplyAddSub (map_reg d,map_reg n,map_reg m,map_reg a,destsize,datasize,sub_op) +| `AArch64MoveWide (d,datasize,imm,pos,opcode) -> `AArch64MoveWide (map_reg d,datasize,imm,pos,opcode) +| `AArch64Reverse (d,n,datasize,op) -> `AArch64Reverse (map_reg d,map_reg n,datasize,op) +| `AArch64Division (d,n,m,datasize,unsigned) -> `AArch64Division (map_reg d,map_reg n,map_reg m,datasize,unsigned) +| `AArch64MultiplyAddSubLong (d,n,m,a,destsize,datasize,sub_op,unsigned) -> `AArch64MultiplyAddSubLong (map_reg d,map_reg n,map_reg m,map_reg a,destsize,datasize,sub_op,unsigned) +| `AArch64MultiplyHigh (d,n,m,a,destsize,datasize,unsigned) -> `AArch64MultiplyHigh (map_reg d,map_reg n,map_reg m,map_reg a,destsize,datasize,unsigned) +| `AArch64TestBitAndBranch (t,datasize,bit_pos,bit_val,offset) -> `AArch64TestBitAndBranch (map_reg t,datasize,bit_pos,bit_val,offset) +| `AArch64MoveSystemRegister (t,sys_op0,sys_op1,sys_op2,sys_crn,sys_crm,read) -> `AArch64MoveSystemRegister (map_reg t,sys_op0,sys_op1,sys_op2,sys_crn,sys_crm,read) +| `AArch64MoveSystemImmediate (operand,field) -> `AArch64MoveSystemImmediate (operand,field) diff --git a/arm/gen/parser.hgen b/arm/gen/parser.hgen new file mode 100644 index 00000000..94ce6fcf --- /dev/null +++ b/arm/gen/parser.hgen @@ -0,0 +1,1396 @@ + /* TSTART */ + | TSTART xreg + { if not (isregzr $2) then error_registers ("expected " ^ $1.txt ^ " ") + else `AArch64TMStart $2 } + + /* TCOMMIT */ + | TCOMMIT + { `AArch64TMCommit } + + /* TABORT */ + | TABORT imm + { if not (iskbituimm 6 $2) then error_arg " must be in the range 0 to 63" + else `AArch64TMAbort (($2 lsr 5) <> 0, $2 mod 32) } + + /* TTEST */ + | TTEST + {`AArch64TMTest} + + | ADCSBC wreg COMMA wreg COMMA wreg + { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , ") + else `AArch64AddSubCarry ($2,$4,$6,Set32,$1.sub_op,$1.setflags) } + | ADCSBC xreg COMMA xreg COMMA xreg + { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , ") + else `AArch64AddSubCarry ($2,$4,$6,Set64,$1.sub_op,$1.setflags) } + + /* ADC/ADCS/SBC/SBCS */ + + | ADCSBC wreg COMMA wreg COMMA wreg + { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , ") + else `AArch64AddSubCarry ($2,$4,$6,Set32,$1.sub_op,$1.setflags) } + | ADCSBC xreg COMMA xreg COMMA xreg + { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , ") + else `AArch64AddSubCarry ($2,$4,$6,Set64,$1.sub_op,$1.setflags) } + + /* ADD/SUB/ADDS/SUBS (extended register), and when noted (shifted register) */ + + | ADDSUB wreg COMMA wreg COMMA wreg + { (* ambiguous with (shifted register) *) + if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then + error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") + else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then + error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") + else `AArch64AddSubExtendRegister ($2,$4,$6,Set32,$1.sub_op,$1.setflags,ExtendType_UXTW,0) } + | ADDSUB wreg COMMA wreg COMMA wreg COMMA EXTEND + { if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then + error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") + else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then + error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") + else `AArch64AddSubExtendRegister ($2,$4,$6,Set32,$1.sub_op,$1.setflags,$8._type,0) } + | ADDSUB wreg COMMA wreg COMMA wreg COMMA SHIFT + { if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") + else if (not $1.setflags) && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") + else if not ($8.shift_type = ShiftType_LSL) then error_arg " must be one of UXTB,UXTH,UXTW,UXTX,SXTB,SXTH,SXTW,SXTX,LSL" + else `AArch64AddSubExtendRegister ($2,$4,$6,Set32,$1.sub_op,$1.setflags,ExtendType_UXTW,0) } + | ADDSUB wreg COMMA wreg COMMA wreg COMMA EXTEND imm + { if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") + else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") + else if not (0 <= $9 && $9 <= 4) then error_arg " must be in the range 0 to 4" + else `AArch64AddSubExtendRegister ($2,$4,$6,Set32,$1.sub_op,$1.setflags,$8._type,$9) } + | ADDSUB wreg COMMA wreg COMMA wreg COMMA SHIFT imm + { if (issp $2 || issp $4) then + begin + (* (extended register) *) + if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") + else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") + else if not ($8.shift_type = ShiftType_LSL) then error_arg " must be one of UXTB,UXTH,UXTW,UXTX,SXTB,SXTH,SXTW,SXTX,LSL" + else if not (0 <= $9 && $9 <= 4) then error_arg " must be in the range 0 to 4" + else `AArch64AddSubExtendRegister ($2,$4,$6,Set32,$1.sub_op,$1.setflags,ExtendType_UXTW,$9) + end + else + begin + (* (shifted register) *) + if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, #}") + else if $8.shift_type = ShiftType_ROR then error_arg " must be one of LSL,LSR,ASR" + else if not (0 <= $9 && $9 <= 31) then error_arg " must be in the range 0 to 31" + else `AArch64AddSubShiftedRegister ($2,$4,$6,Set32,$1.sub_op,$1.setflags,$8.shift_type,$9) + end } + + | ADDSUB xreg COMMA xreg COMMA xreg + { (* ambiguous with (shifted register) *) + if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") + else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") + else `AArch64AddSubExtendRegister ($2,$4,$6,Set64,$1.sub_op,$1.setflags,ExtendType_UXTX,0) } + | ADDSUB xreg COMMA xreg COMMA wreg COMMA EXTEND + { if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") + else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") + else if $8._type = ExtendType_UXTX || $8._type = ExtendType_SXTX then error_arg " doesn't match " + else `AArch64AddSubExtendRegister ($2,$4,$6,Set64,$1.sub_op,$1.setflags,$8._type,0) } + | ADDSUB xreg COMMA xreg COMMA wreg COMMA SHIFT + { if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") + else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") + else if not ($8.shift_type = ShiftType_LSL) then error_arg " must be one of UXTB,UXTH,UXTW,UXTX,SXTB,SXTH,SXTW,SXTX,LSL" + else `AArch64AddSubExtendRegister ($2,$4,$6,Set64,$1.sub_op,$1.setflags,ExtendType_UXTX,0) } + | ADDSUB xreg COMMA xreg COMMA wreg COMMA EXTEND imm + { if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") + else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") + else if not (0 <= $9 && $9 <= 4) then error_arg " must be in the range 0 to 4." + else if $8._type = ExtendType_UXTX || $8._type = ExtendType_SXTX then error_arg " doesn't match " + else `AArch64AddSubExtendRegister ($2,$4,$6,Set64,$1.sub_op,$1.setflags,$8._type,$9) } + | ADDSUB xreg COMMA xreg COMMA wreg COMMA SHIFT imm + { if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") + else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") + else if not ($8.shift_type = ShiftType_LSL) then error_arg " must be one of UXTB,UXTH,UXTW,UXTX,SXTB,SXTH,SXTW,SXTX,LSL" + else if not (0 <= $9 && $9 <= 4) then error_arg " must be in the range 0 to 4." + else `AArch64AddSubExtendRegister ($2,$4,$6,Set64,$1.sub_op,$1.setflags,ExtendType_UXTX,$9) } + | ADDSUB xreg COMMA xreg COMMA xreg COMMA EXTEND + { if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") + else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") + else if not ($8._type = ExtendType_UXTX || $8._type = ExtendType_SXTX) then error_arg " doesn't match " + else `AArch64AddSubExtendRegister ($2,$4,$6,Set64,$1.sub_op,$1.setflags,$8._type,0) } + | ADDSUB xreg COMMA xreg COMMA xreg COMMA SHIFT + { if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") + else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") + else if not ($8.shift_type = ShiftType_LSL) then error_arg " must be one of UXTB,UXTH,UXTW,UXTX,SXTB,SXTH,SXTW,SXTX,LSL" + else `AArch64AddSubExtendRegister ($2,$4,$6,Set64,$1.sub_op,$1.setflags,ExtendType_UXTX,0) } + | ADDSUB xreg COMMA xreg COMMA xreg COMMA EXTEND imm + { if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") + else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") + else if not (0 <= $9 && $9 <= 4) then error_arg " must be in the range 0 to 4." + else if not ($8._type = ExtendType_UXTX || $8._type = ExtendType_SXTX) then error_arg " doesn't match " + else `AArch64AddSubExtendRegister ($2,$4,$6,Set64,$1.sub_op,$1.setflags,$8._type,$9) } + | ADDSUB xreg COMMA xreg COMMA xreg COMMA SHIFT imm + { if (issp $2 || issp $4) then + begin + (* (extended register) *) + if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") + else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") + else if not ($8.shift_type = ShiftType_LSL) then error_arg " must be one of UXTB,UXTH,UXTW,UXTX,SXTB,SXTH,SXTW,SXTX,LSL" + else if not (0 <= $9 && $9 <= 4) then error_arg " must be in the range 0 to 4." + else `AArch64AddSubExtendRegister ($2,$4,$6,Set64,$1.sub_op,$1.setflags,ExtendType_UXTX,$9) + end + else + begin + (* (shifted register) *) + if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, #}") + else if $8.shift_type = ShiftType_ROR then error_arg " must be one of LSL,LSR,ASR" + else if not (0 <= $9 && $9 <= 63) then error_arg " must be in the range 0 to 63" + else `AArch64AddSubShiftedRegister ($2,$4,$6,Set64,$1.sub_op,$1.setflags,$8.shift_type,$9) + end } + + /* ADD/SUB/ADDS/SUBS (immediate) */ + + | ADDSUB wreg COMMA wreg COMMA imm + { if $1.setflags && not (isregzr $2 && isregsp $4) then error_registers ("expected " ^ $1.txt ^ " , , #{, }") + else if not $1.setflags && not (isregsp $2 && isregsp $4) then error_registers ("expected " ^ $1.txt ^ " , , #{, }") + else if not (0 <= $6 && $6 <= 4095) then error_arg " must be in the range 0 to 4095" + else `AArch64AddSubImmediate ($2,$4,Set32,$1.sub_op,$1.setflags,reg_size_bits_R32_of_int $6) } + | ADDSUB wreg COMMA wreg COMMA imm COMMA SHIFT imm + { if $1.setflags && not (isregzr $2 && isregsp $4) then error_registers ("expected " ^ $1.txt ^ " , , #{, }") + else if not $1.setflags && not (isregsp $2 && isregsp $4) then error_registers ("expected " ^ $1.txt ^ " , , #{, }") + else if not (0 <= $6 && $6 <= 4095) then error_arg " must be in the range 0 to 4095" + else if not ($8.shift_type = ShiftType_LSL && ($9 = 0 || $9 = 12)) then error_arg " must be 'LSL #0' or 'LSL #12'" + else `AArch64AddSubImmediate ($2,$4,Set32,$1.sub_op,$1.setflags,reg_size_bits_R32_of_int ($6 lsl $9)) } + | ADDSUB xreg COMMA xreg COMMA imm + { if $1.setflags && not (isregzr $2 && isregsp $4) then error_registers ("expected " ^ $1.txt ^ " , , #{, }") + else if not $1.setflags && not (isregsp $2 && isregsp $4) then error_registers ("expected " ^ $1.txt ^ " , , #{, }") + else if not (0 <= $6 && $6 <= 4095) then error_arg " must be in the range 0 to 4095" + else `AArch64AddSubImmediate ($2,$4,Set64,$1.sub_op,$1.setflags,reg_size_bits_R64_of_int $6) } + | ADDSUB xreg COMMA xreg COMMA imm COMMA SHIFT imm + { if $1.setflags && not (isregzr $2 && isregsp $4) then error_registers ("expected " ^ $1.txt ^ " , , #{, }") + else if not $1.setflags && not (isregsp $2 && isregsp $4) then error_registers ("expected " ^ $1.txt ^ " , , #{, }") + else if not (0 <= $6 && $6 <= 4095) then error_arg " must be in the range 0 to 4095" + else if not ($8.shift_type = ShiftType_LSL && ($9 = 0 || $9 = 12)) then error_arg " must be 'LSL #0' or 'LSL #12'" + else `AArch64AddSubImmediate ($2,$4,Set64,$1.sub_op,$1.setflags,reg_size_bits_R64_of_int ($6 lsl $9)) } + + /* ADR/ADRP */ +/* + | ADR xreg COMMA NAME + { if not (isregzr $2) then error_registers ("expected " ^ $1.txt ^ " ,