summaryrefslogtreecommitdiff
path: root/mips
diff options
context:
space:
mode:
Diffstat (limited to 'mips')
-rw-r--r--mips/Makefile23
-rw-r--r--mips/mips_epilogue.sail41
-rw-r--r--mips/mips_extras.lem73
-rw-r--r--mips/mips_extras_embed.lem53
-rw-r--r--mips/mips_extras_embed_sequential.lem58
-rw-r--r--mips/mips_extras_ml.ml120
-rw-r--r--mips/mips_insts.sail1675
-rw-r--r--mips/mips_prelude.sail609
-rw-r--r--mips/mips_regfp.sail451
-rw-r--r--mips/mips_ri.sail42
-rw-r--r--mips/mips_tlb.sail128
-rw-r--r--mips/mips_tlb_stub.sail40
-rw-r--r--mips/mips_wrappers.sail70
-rw-r--r--mips/run_embed.ml404
14 files changed, 0 insertions, 3787 deletions
diff --git a/mips/Makefile b/mips/Makefile
deleted file mode 100644
index 03d7ae15..00000000
--- a/mips/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-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_epilogue.sail b/mips/mips_epilogue.sail
deleted file mode 100644
index 50993949..00000000
--- a/mips/mips_epilogue.sail
+++ /dev/null
@@ -1,41 +0,0 @@
-(*========================================================================*)
-(* *)
-(* Copyright (c) 2015-2017 Robert M. Norton *)
-(* 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. *)
-(*========================================================================*)
-
-(* mips_epilogue.sail: end of decode, execute and AST definitions. *)
-
-end decode
-end execute
-end ast
-
-function option<ast> supported_instructions (instr) = Some(instr)
diff --git a/mips/mips_extras.lem b/mips/mips_extras.lem
deleted file mode 100644
index be576fb2..00000000
--- a/mips/mips_extras.lem
+++ /dev/null
@@ -1,73 +0,0 @@
-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 mips_read_memory_functions : memory_reads =
- [ ("MEMr", (MR Read_plain memory_parameter_transformer));
- ("MEMr_reserve", (MR Read_reserve memory_parameter_transformer));
- ]
-
-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 mips_memory_writes : memory_writes =
- []
-
-let mips_memory_eas : memory_write_eas =
- [ ("MEMea", (MEA Write_plain memory_parameter_transformer));
- ("MEMea_conditional", (MEA Write_conditional memory_parameter_transformer));
- ]
-
-let mips_memory_vals : memory_write_vals =
- [ ("MEMval", (MV memory_parameter_transformer_option_address Nothing));
- ("MEMval_conditional", (MV memory_parameter_transformer_option_address
- (Just
- (fun (IState interp context) b ->
- let bit = 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 bit) context)))));
- ]
-
-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
- (Just
- (fun (IState interp context) b ->
- let bit = 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 bit) context)))));
- ]
-
-let mips_barrier_functions = [
- ("MEM_sync", Barrier_MIPS_SYNC);
- ]
diff --git a/mips/mips_extras_embed.lem b/mips/mips_extras_embed.lem
deleted file mode 100644
index 8abc9747..00000000
--- a/mips/mips_extras_embed.lem
+++ /dev/null
@@ -1,53 +0,0 @@
-open import Pervasives
-open import Pervasives_extra
-open import Sail_impl_base
-open import Sail_values
-open import Prompt
-
-val MEMr : (vector bitU * integer) -> M (vector bitU)
-val MEMr_reserve : (vector bitU * integer) -> M (vector bitU)
-val MEMr_tag : (vector bitU * integer) -> M (vector bitU)
-val MEMr_tag_reserve : (vector bitU * integer) -> M (vector bitU)
-
-let MEMr (addr,size) = read_mem false Read_plain addr size
-let MEMr_reserve (addr,size) = read_mem false Read_reserve addr size
-
-let MEMr_tag (addr,size) = read_mem false Read_plain addr size
-let MEMr_tag_reserve (addr,size) = read_mem false Read_reserve addr size
-
-
-val MEMea : (vector bitU * integer) -> M unit
-val MEMea_conditional : (vector bitU * integer) -> M unit
-val MEMea_tag : (vector bitU * integer) -> M unit
-val MEMea_tag_conditional : (vector bitU * integer) -> M unit
-
-let MEMea (addr,size) = write_mem_ea Write_plain addr size
-let MEMea_conditional (addr,size) = write_mem_ea Write_conditional addr size
-
-let MEMea_tag (addr,size) = write_mem_ea Write_plain addr size
-let MEMea_tag_conditional (addr,size) = write_mem_ea Write_conditional addr size
-
-
-val MEMval : (vector bitU * integer * vector bitU) -> M unit
-val MEMval_conditional : (vector bitU * integer * vector bitU) -> M bitU
-val MEMval_tag : (vector bitU * integer * vector bitU) -> M unit
-val MEMval_tag_conditional : (vector bitU * integer * vector bitU) -> M bitU
-
-let MEMval (_,_,v) = write_mem_val v >>= fun _ -> return ()
-let MEMval_conditional (_,_,v) = write_mem_val v >>= fun b -> return (if b then B1 else B0)
-let MEMval_tag (_,_,v) = write_mem_val v >>= fun _ -> return ()
-let MEMval_tag_conditional (_,_,v) = write_mem_val v >>= fun b -> return (if b then B1 else B0)
-
-(* TODO *)
-val TAGw : (vector bitU * vector bitU) -> M unit
-let TAGw (addr, tag) = failwith "TAGw not implemented"
-
-val MEM_sync : unit -> M unit
-
-let MEM_sync () = barrier Barrier_Isync
-
-
-let duplicate (bit,len) =
- let bits = repeat [bit] len in
- let start = len - 1 in
- Vector bits start false
diff --git a/mips/mips_extras_embed_sequential.lem b/mips/mips_extras_embed_sequential.lem
deleted file mode 100644
index 708c1f63..00000000
--- a/mips/mips_extras_embed_sequential.lem
+++ /dev/null
@@ -1,58 +0,0 @@
-open import Pervasives
-open import Pervasives_extra
-open import Sail_impl_base
-open import Sail_values
-open import State
-
-val MEMr : forall 'a 'b. Size 'b => (bitvector 'a * integer) -> M (bitvector 'b)
-val MEMr_reserve : forall 'a 'b. Size 'b => (bitvector 'a * integer) -> M (bitvector 'b)
-val MEMr_tag : forall 'a 'b. Size 'b => (bitvector 'a * integer) -> M (bitU * bitvector 'b)
-val MEMr_tag_reserve : forall 'a 'b. Size 'b => (bitvector 'a * integer) -> M (bitU * bitvector 'b)
-
-let MEMr (addr,size) = read_mem false Read_plain addr size
-let MEMr_reserve (addr,size) = read_mem false Read_reserve addr size
-
-let MEMr_tag (addr,size) =
- read_mem false Read_plain addr size >>= fun v ->
- read_tag false Read_plain addr >>= fun t ->
- return (t, v)
-
-let MEMr_tag_reserve (addr,size) =
- read_mem false Read_plain addr size >>= fun v ->
- read_tag false Read_plain addr >>= fun t ->
- return (t, v)
-
-
-val MEMea : forall 'a. (bitvector 'a * integer) -> M unit
-val MEMea_conditional : forall 'a. (bitvector 'a * integer) -> M unit
-val MEMea_tag : forall 'a. (bitvector 'a * integer) -> M unit
-val MEMea_tag_conditional : forall 'a. (bitvector 'a * integer) -> M unit
-
-let MEMea (addr,size) = write_mem_ea Write_plain addr size
-let MEMea_conditional (addr,size) = write_mem_ea Write_conditional addr size
-
-let MEMea_tag (addr,size) = write_mem_ea Write_plain addr size
-let MEMea_tag_conditional (addr,size) = write_mem_ea Write_conditional addr size
-
-
-val MEMval : forall 'a 'b. (bitvector 'a * integer * bitvector 'b) -> M unit
-val MEMval_conditional : forall 'a 'b. (bitvector 'a * integer * bitvector 'b) -> M bitU
-val MEMval_tag : forall 'a 'b. (bitvector 'a * integer * bitU * bitvector 'b) -> M unit
-val MEMval_tag_conditional : forall 'a 'b. (bitvector 'a * integer * bitU * bitvector 'b) -> M bitU
-
-let MEMval (_,_,v) = write_mem_val v >>= fun _ -> return ()
-let MEMval_conditional (_,_,v) = write_mem_val v >>= fun b -> return (if b then B1 else B0)
-let MEMval_tag (_,_,t,v) = write_mem_val v >>= fun _ -> write_tag t >>= fun _ -> return ()
-let MEMval_tag_conditional (_,_,t,v) = write_mem_val v >>= fun b -> write_tag t >>= fun _ -> return (if b then B1 else B0)
-
-val MEM_sync : unit -> M unit
-
-let MEM_sync () = barrier Barrier_MIPS_SYNC
-
-
-(* TODO: Consider moving this to sail_values.lem (after fixing and implementing
- a default index ordering) *)
-let duplicate (bit,len) =
- let bits = repeat [bitU_to_bool bit] len in
- let start = len - 1 in
- Bitvector (wordFromBitlist bits) start false
diff --git a/mips/mips_extras_ml.ml b/mips/mips_extras_ml.ml
deleted file mode 100644
index d4ea0681..00000000
--- a/mips/mips_extras_ml.ml
+++ /dev/null
@@ -1,120 +0,0 @@
-open Sail_values
-open Big_int_Z
-open Printf
-
-let big_int_to_hex i = Z.format "%x" i
-
-module Mem = struct
- include Map.Make(struct
- type t = big_int
- let compare = compare_big_int
- end)
-end
-
-let cap_size_shift = ref 5;; (* caps every 2**5 = 32 bytes *)
-let mem_pages = (ref Mem.empty : (Bytes.t Mem.t) ref);;
-let tag_mem = (ref Mem.empty : (bool Mem.t) ref);;
-
-let page_shift_bits = 20 (* 1M page *)
-let page_size_bytes = 1 lsl page_shift_bits;;
-
-
-let page_no_of_addr a = shift_right_big_int a page_shift_bits;;
-let bottom_addr_of_page p = shift_left_big_int p page_shift_bits
-let top_addr_of_page p = shift_left_big_int (succ_big_int p) page_shift_bits
-let get_page p =
- try
- Mem.find p !mem_pages
- with Not_found ->
- let new_page = Bytes.create page_size_bytes in
- mem_pages := Mem.add p new_page !mem_pages;
- new_page
-
-let rec add_mem_bytes addr buf off len =
- let page_no = page_no_of_addr addr in
- let page_bot = bottom_addr_of_page page_no in
- let page_top = top_addr_of_page page_no in
- let page_off = int_of_big_int (sub_big_int addr page_bot) in
- let page = get_page page_no in
- let bytes_left_in_page = sub_big_int page_top addr in
- let to_copy = min_int (int_of_big_int bytes_left_in_page) len in
- Bytes.blit buf off page page_off to_copy;
- if (to_copy < len) then
- add_mem_bytes page_top buf (off + to_copy) (len - to_copy)
-
-let rec read_mem_bytes addr len =
- let page_no = page_no_of_addr addr in
- let page_bot = bottom_addr_of_page page_no in
- let page_top = top_addr_of_page page_no in
- let page_off = int_of_big_int (sub_big_int addr page_bot) in
- let page = get_page page_no in
- let bytes_left_in_page = sub_big_int page_top addr in
- let to_get = min_int (int_of_big_int bytes_left_in_page) len in
- let bytes = Bytes.sub page page_off to_get in
- if to_get >= len then
- bytes
- else
- Bytes.cat bytes (read_mem_bytes page_top (len - to_get))
-
-let _MEMea (addr, size) = ()
-let _MEMea_conditional = _MEMea
-let _MEMea_tag = _MEMea
-let _MEMea_tag_conditional = _MEMea
-
-let _MEMval (addr, size, data) =
- (* assumes data is decreasing vector to be stored in little-endian byte order in mem *)
- let s = int_of_big_int size in
- let a = unsigned_big(addr) in
- let buf = Bytes.create s in
- for i = 0 to (s - 1) do
- let bit_idx = i * 8 in
- let byte = unsigned_int(slice_raw (data, big_int_of_int bit_idx, big_int_of_int (bit_idx + 7))) in
- Bytes.set buf (s-1-i) (char_of_int byte);
- done;
- if !trace_writes then
- tracef "MEM[%s] <- %s\n" (big_int_to_hex a) (string_of_value data);
- add_mem_bytes a buf 0 s
-
-let _MEMval_tag (addr, size, tag, data) =
- let addr_bi = (unsigned_big(addr)) in
- begin
- _MEMval (addr, size, data);
- tag_mem := Mem.add (shift_right_big_int addr_bi !cap_size_shift) (to_bool tag) !tag_mem;
- end
-
-
-let _MEMval_conditional (addr, size, data) =
- let _ = _MEMval (addr, size, data) in
- Vone
-
-let _MEMval_tag_conditional (addr, size, tag, data) =
- let _ = _MEMval_tag (addr, size, tag, data) in
- Vone
-
-let _MEMr (addr, size) = begin
- let s = int_of_big_int size in
- let a = unsigned_big(addr) in
- let bytes = read_mem_bytes a s in
- let ret = ref (to_vec_dec_int (0, 0)) in
- for i = 0 to (s - 1) do
- let byte = Bytes.get bytes i in
- let byte_vec = to_vec_dec_int (8, int_of_char byte) in
- ret := vector_concat byte_vec (!ret);
- (*printf "MEM [%s] -> %x %s %s\n" (big_int_to_hex byte_addr) byte (string_of_value byte_vec) (string_of_value !ret);*)
- done;
- ret := set_start_to_length (!ret);
- !ret;
-end
-let _MEMr_reserve = _MEMr
-
-let _MEMr_tag (addr, size) =
- let data = _MEMr(addr, size) in
- let addr_bi = unsigned_big(addr) in
- let tag = try
- Mem.find (shift_right_big_int addr_bi !cap_size_shift) !tag_mem
- with Not_found -> false in
- (bool_to_bit tag, data)
-
-let _MEMr_tag_reserve = _MEMr_tag
-
-let _MEM_sync _ = ()
diff --git a/mips/mips_insts.sail b/mips/mips_insts.sail
deleted file mode 100644
index d127f6db..00000000
--- a/mips/mips_insts.sail
+++ /dev/null
@@ -1,1675 +0,0 @@
-(*========================================================================*)
-(* *)
-(* Copyright (c) 2015-2017 Robert M. Norton *)
-(* 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. *)
-(*========================================================================*)
-
-(* misp_insts.sail: mips instruction decode and execute clauses and AST node
- declarations *)
-
-scattered function unit execute
-scattered typedef ast = const union
-
-val bit[32] -> option<ast> effect pure decode
-scattered function option<ast> decode
-
-(**************************************************************************************)
-(* [D]ADD[I][U] various forms of ADD *)
-(**************************************************************************************)
-
-(* DADDIU Doubleword Add Immediate Unsigned --
- the simplest possible instruction, no undefined behaviour or exceptions
- reg, reg, immediate *)
-
-union ast member regregimm16 DADDIU
-
-function clause decode (0b011001 : (regno) rs : (regno) rt : (imm16) imm) =
- Some(DADDIU(rs, rt, imm))
-
-function clause execute (DADDIU (rs, rt, imm)) =
- {
- wGPR(rt) := rGPR(rs) + EXTS(imm)
- }
-
-(* DADDU Doubleword Add Unsigned -- another very simple instruction,
- reg, reg, reg *)
-
-union ast member regregreg DADDU
-
-function clause decode (0b000000 : (regno) rs : (regno) rt : (regno) rd : 0b00000 : 0b101101) =
- Some(DADDU(rs, rt, rd))
-
-function clause execute (DADDU (rs, rt, rd)) =
- {
- wGPR(rd) := rGPR(rs) + rGPR(rt)
- }
-
-(* DADDI Doubleword Add Immediate
- reg, reg, imm with possible exception *)
-
-union ast member regregimm16 DADDI
-
-function clause decode (0b011000 : (regno) rs : (regno) rt : (imm16) imm) =
- Some(DADDI(rs, rt, imm))
-
-function clause execute (DADDI (rs, rt, imm)) =
- {
- let (bit[65]) sum65 = (EXTS(rGPR(rs)) + EXTS(imm)) in
- {
- if (sum65[64] != sum65[63]) then
- (SignalException(Ov))
- else
- wGPR(rt) := sum65[63..0]
- }
- }
-
-(* DADD Doubleword Add
- reg, reg, reg with possible exception *)
-
-union ast member regregreg DADD
-
-function clause decode (0b000000 : (regno) rs : (regno) rt : (regno) rd : 0b00000 : 0b101100) =
- Some(DADD(rs, rt, rd))
-
-function clause execute (DADD (rs, rt, rd)) =
- {
- let (bit[65]) sum65 = (EXTS(rGPR(rs)) + EXTS(rGPR(rt))) in
- {
- if sum65[64] != sum65[63] then
- (SignalException(Ov))
- else
- wGPR(rd) := sum65[63..0]
- }
- }
-
-(* ADD 32-bit add -- reg, reg, reg with possible undefined behaviour or exception *)
-
-union ast member regregreg ADD
-
-function clause decode (0b000000 : (regno) rs : (regno) rt : (regno) rd : 0b00000 : 0b100000) =
- Some(ADD(rs, rt, rd))
-
-function clause execute (ADD(rs, rt, rd)) =
- {
- (bit[64]) opA := rGPR(rs);
- (bit[64]) opB := rGPR(rt);
- if NotWordVal(opA) | NotWordVal(opB) then
- wGPR(rd) := undefined (* XXX could exit instead *)
- else
- let (bit[33]) sum33 = (EXTS(opA[31 .. 0]) + EXTS(opB[31 .. 0])) in
- if sum33[32] != sum33[31] then
- (SignalException(Ov))
- else
- wGPR(rd) := EXTS(sum33[31..0])
- }
-
-(* ADDI 32-bit add immediate -- reg, reg, imm with possible undefined behaviour or exception *)
-
-union ast member regregimm16 ADDI
-
-function clause decode (0b001000 : (regno) rs : (regno) rt : (imm16) imm) =
- Some(ADDI(rs, rt, imm))
-
-function clause execute (ADDI(rs, rt, imm)) =
- {
- (bit[64]) opA := rGPR(rs);
- if NotWordVal(opA) then
- wGPR(rt) := undefined (* XXX could exit instead *)
- else
- let (bit[33]) sum33 = (EXTS(opA[31 .. 0]) + EXTS(imm)) in
- if sum33[32] != sum33[31] then
- (SignalException(Ov))
- else
- wGPR(rt) := EXTS(sum33[31..0])
- }
-
-(* ADDU 32-bit add immediate -- reg, reg, reg with possible undefined behaviour *)
-
-union ast member regregreg ADDU
-
-function clause decode (0b000000 : (regno) rs : (regno) rt : (regno) rd : 0b00000 : 0b100001) =
- Some(ADDU(rs, rt, rd))
-
-function clause execute (ADDU(rs, rt, rd)) =
- {
- (bit[64]) opA := rGPR(rs);
- (bit[64]) opB := rGPR(rt);
- if NotWordVal(opA) | NotWordVal(opB) then
- wGPR(rd) := undefined
- else
- wGPR(rd) := EXTS(opA[31..0] + opB[31..0])
- }
-
-
-(* ADDIU 32-bit add immediate -- reg, reg, imm with possible undefined behaviour *)
-
-union ast member regregimm16 ADDIU
-
-function clause decode (0b001001 : (regno) rs : (regno) rt : (imm16) imm) =
- Some(ADDIU(rs, rt, imm))
-
-function clause execute (ADDIU(rs, rt, imm)) =
- {
- (bit[64]) opA := rGPR(rs);
- if NotWordVal(opA) then
- wGPR(rt) := undefined (* XXX could exit instead *)
- else
- wGPR(rt) := EXTS((opA[31 .. 0]) + EXTS(imm))
- }
-
-(**************************************************************************************)
-(* [D]SUB[U] various forms of SUB *)
-(**************************************************************************************)
-
-(* DSUBU doubleword subtract 'unsigned' reg, reg, reg *)
-
-union ast member regregreg DSUBU
-
-function clause decode (0b000000 : (regno) rs : (regno) rt : (regno) rd : 0b00000 : 0b101111) =
- Some(DSUBU(rs, rt, rd))
-
-function clause execute (DSUBU (rs, rt, rd)) =
- {
- wGPR(rd) := rGPR(rs) - rGPR(rt)
- }
-
-(* DSUB reg, reg, reg with possible exception *)
-
-union ast member regregreg DSUB
-
-function clause decode (0b000000 : (regno) rs : (regno) rt : (regno) rd : 0b00000 : 0b101110) =
- Some(DSUB(rs, rt, rd))
-
-function clause execute (DSUB (rs, rt, rd)) =
- {
- let (bit[65]) temp65 = (EXTS(rGPR(rs)) - EXTS(rGPR(rt))) in
- {
- if temp65[64] != temp65[63] then
- (SignalException(Ov))
- else
- wGPR(rd) := temp65[63..0]
- }
- }
-
-(* SUB 32-bit sub -- reg, reg, reg with possible undefined behaviour or exception *)
-
-union ast member regregreg SUB
-
-function clause decode (0b000000 : (regno) rs : (regno) rt : (regno) rd : 0b00000 : 0b100010) =
- Some(SUB(rs, rt, rd))
-
-function clause execute (SUB(rs, rt, rd)) =
- {
- (bit[64]) opA := rGPR(rs);
- (bit[64]) opB := rGPR(rt);
- if NotWordVal(opA) | NotWordVal(opB) then
- wGPR(rd) := undefined (* XXX could instead *)
- else
- let (bit[33]) temp33 = (EXTS(opA[31..0]) - EXTS(opB[31..0])) in
- if temp33[32] != temp33[31] then
- (SignalException(Ov))
- else
- wGPR(rd) := EXTS(temp33[31..0])
- }
-
-(* SUBU 32-bit 'unsigned' sub -- reg, reg, reg with possible undefined behaviour *)
-
-union ast member regregreg SUBU
-function clause decode (0b000000 : (regno) rs : (regno) rt : (regno) rd : 0b00000 : 0b100011) =
- Some(SUBU(rs, rt, rd))
-
-function clause execute (SUBU(rs, rt, rd)) =
- {
- (bit[64]) opA := rGPR(rs);
- (bit[64]) opB := rGPR(rt);
- if NotWordVal(opA) | NotWordVal(opB) then
- wGPR(rd) := undefined
- else
- wGPR(rd) := EXTS(opA[31..0] - opB[31..0])
- }
-
-(**************************************************************************************)
-(* Logical bitwise operations *)
-(**************************************************************************************)
-
-(* AND reg, reg, reg *)
-
-union ast member regregreg AND
-function clause decode (0b000000 : (regno) rs : (regno) rt : (regno) rd : 0b00000 : 0b100100) =
- Some(AND(rs, rt, rd))
-
-function clause execute (AND (rs, rt, rd)) =
- {
- wGPR(rd) := (rGPR(rs) & rGPR(rt))
- }
-
-(* ANDI reg, reg, imm *)
-
-union ast member regregimm16 ANDI
-function clause decode (0b001100 : (regno) rs : (regno) rt : (imm16) imm) =
- Some(ANDI(rs, rt, imm))
-function clause execute (ANDI (rs, rt, imm)) =
- {
- wGPR(rt) := (rGPR(rs) & EXTZ(imm))
- }
-
-(* OR reg, reg, reg *)
-
-union ast member regregreg OR
-function clause decode (0b000000 : (regno) rs : (regno) rt : (regno) rd : 0b00000 : 0b100101) =
- Some(OR(rs, rt, rd))
-function clause execute (OR (rs, rt, rd)) =
- {
- wGPR(rd) := (rGPR(rs) | rGPR(rt))
- }
-
-(* ORI reg, reg, imm *)
-
-union ast member regregimm16 ORI
-function clause decode (0b001101 : (regno) rs : (regno) rt : (imm16) imm) =
- Some(ORI(rs, rt, imm))
-function clause execute (ORI (rs, rt, imm)) =
- {
- wGPR(rt) := (rGPR(rs) | EXTZ(imm))
- }
-
-(* NOR reg, reg, reg *)
-
-union ast member regregreg NOR
-function clause decode (0b000000 : (regno) rs : (regno) rt : (regno) rd : 0b00000 : 0b100111) =
- Some(NOR(rs, rt, rd))
-function clause execute (NOR (rs, rt, rd)) =
- {
- wGPR(rd) := ~(rGPR(rs) | rGPR(rt))
- }
-
-(* XOR reg, reg, reg *)
-
-union ast member regregreg XOR
-function clause decode (0b000000 : (regno) rs : (regno) rt : (regno) rd : 0b00000 : 0b100110) =
- Some(XOR(rs, rt, rd))
-function clause execute (XOR (rs, rt, rd)) =
- {
- wGPR(rd) := (rGPR(rs) ^ rGPR(rt))
- }
-
-(* XORI reg, reg, imm *)
-union ast member regregimm16 XORI
-function clause decode (0b001110 : (regno) rs : (regno) rt : (imm16) imm) =
- Some(XORI(rs, rt, imm))
-function clause execute (XORI (rs, rt, imm)) =
- {
- wGPR(rt) := (rGPR(rs) ^ EXTZ(imm))
- }
-
-(* LUI reg, imm 32-bit load immediate into upper 16 bits *)
-union ast member (regno, imm16) LUI
-function clause decode (0b001111 : 0b00000 : (regno) rt : (imm16) imm) =
- Some(LUI(rt, imm))
-function clause execute (LUI (rt, imm)) =
- {
- wGPR(rt) := EXTS(imm : 0x0000)
- }
-
-(**************************************************************************************)
-(* 64-bit shift operations *)
-(**************************************************************************************)
-
-(* DSLL reg, reg, imm5 *)
-
-union ast member regregreg DSLL
-function clause decode (0b000000 : 0b00000 : (regno) rt : (regno) rd : (bit[5]) sa : 0b111000) =
- Some(DSLL(rt, rd, sa))
-function clause execute (DSLL (rt, rd, sa)) =
- {
-
- wGPR(rd) := (rGPR(rt) << sa) (* make tuareg mode less blue >> *)
- }
-
-(* DSLL32 reg, reg, imm5 *)
-
-union ast member regregreg DSLL32
-function clause decode (0b000000 : 0b00000 : (regno) rt : (regno) rd : (bit[5]) sa : 0b111100) =
- Some(DSLL32(rt, rd, sa))
-function clause execute (DSLL32 (rt, rd, sa)) =
- {
- wGPR(rd) := (rGPR(rt) << (0b1 : sa)) (* make tuareg mode less blue >> *)
- }
-
-(* DSLLV reg, reg, reg *)
-
-union ast member regregreg DSLLV
-function clause decode (0b000000 : (regno) rs : (regno) rt : (regno) rd : 0b00000 : 0b010100) =
- Some(DSLLV(rs, rt, rd))
-function clause execute (DSLLV (rs, rt, rd)) =
- {
- wGPR(rd) := (rGPR(rt) << ((rGPR(rs))[5 .. 0])) (* make tuareg mode less blue >> *)
- (* alternative slicing based version of above
- sa := (rGPR(rt))[5 .. 0];
- v := rGPR(rs);
- wGPR(rd) := v[(63-sa) .. 0] : (0b0 ^^ sa) *)
- }
-
-(* DSRA arithmetic shift duplicating sign bit - reg, reg, imm5 *)
-
-union ast member regregreg DSRA
-function clause decode (0b000000 : 0b00000 : (regno) rt : (regno) rd : (bit[5]) sa : 0b111011) =
- Some(DSRA(rt, rd, sa))
-function clause execute (DSRA (rt, rd, sa)) =
- {
- temp := rGPR(rt);
- wGPR(rd) := ((temp[63] ^^ sa) : (temp[63 .. sa]))
- }
-
-(* DSRA32 reg, reg, imm5 *)
-
-union ast member regregreg DSRA32
-function clause decode (0b000000 : 0b00000 : (regno) rt : (regno) rd : (bit[5]) sa : 0b111111) =
- Some(DSRA32(rt, rd, sa))
-function clause execute (DSRA32 (rt, rd, sa)) =
- {
- temp := rGPR(rt);
- sa32 := (0b1 : sa); (* sa+32 *)
- wGPR(rd) := ((temp[63] ^^ sa32) : (temp[63 .. sa32]))
- }
-
-(* DSRAV reg, reg, reg *)
-union ast member regregreg DSRAV
-function clause decode (0b000000 : (regno) rs : (regno) rt : (regno) rd : 0b00000 : 0b010111) =
- Some(DSRAV(rs, rt, rd))
-function clause execute (DSRAV (rs, rt, rd)) =
- {
- temp := rGPR(rt);
- sa := (rGPR(rs)) [5..0];
- wGPR(rd) := ((temp[63] ^^ sa) : temp[63 .. sa])
- }
-
-(* DSRL shift right logical - reg, reg, imm5 *)
-
-union ast member regregreg DSRL
-function clause decode (0b000000 : 0b00000 : (regno) rt : (regno) rd : (bit[5]) sa : 0b111010) =
- Some(DSRL(rt, rd, sa))
-function clause execute (DSRL (rt, rd, sa)) =
- {
- temp := rGPR(rt);
- wGPR(rd) := ((bitzero ^^ sa) : (temp[63 .. sa]))
- }
-
-(* DSRL32 reg, reg, imm5 *)
-
-union ast member regregreg DSRL32
-function clause decode (0b000000 : 0b00000 : (regno) rt : (regno) rd : (bit[5]) sa : 0b111110) =
- Some(DSRL32(rt, rd, sa))
-function clause execute (DSRL32 (rt, rd, sa)) =
- {
- temp := rGPR(rt);
- sa32 := (0b1 : sa); (* sa+32 *)
- wGPR(rd) := ((bitzero ^^ sa32) : (temp[63 .. sa32]))
- }
-
-(* DSRLV reg, reg, reg *)
-
-union ast member regregreg DSRLV
-function clause decode (0b000000 : (regno) rs : (regno) rt : (regno) rd : 0b00000 : 0b010110) =
- Some(DSRLV(rs, rt, rd))
-function clause execute (DSRLV (rs, rt, rd)) =
- {
- temp := rGPR(rt);
- sa := (rGPR(rs)) [5..0];
- wGPR(rd) := ((bitzero ^^ sa) : temp[63 .. sa])
- }
-
-(**************************************************************************************)
-(* 32-bit shift operations *)
-(**************************************************************************************)
-
-(* SLL 32-bit shift left *)
-
-union ast member regregreg SLL
-function clause decode (0b000000 : 0b00000 : (regno) rt : (regno) rd : (regno) sa : 0b000000) =
- Some(SLL(rt, rd, sa))
-function clause execute (SLL(rt, rd, sa)) =
- {
- wGPR(rd) := EXTS((rGPR(rt)) [(31-sa)..0] : (bitzero ^^ sa))
- }
-
-(* SLLV 32-bit shift left variable *)
-
-union ast member regregreg SLLV
-function clause decode (0b000000 : (regno) rs : (regno) rt : (regno) rd : 0b00000 : 0b000100) =
- Some(SLLV(rs, rt, rd))
-function clause execute (SLLV(rs, rt, rd)) =
- {
- sa := (rGPR(rs))[4..0];
- wGPR(rd) := EXTS((rGPR(rt)) [(31-sa)..0] : (bitzero ^^ sa))
- }
-
-(* SRA 32-bit arithmetic shift right *)
-
-union ast member regregreg SRA
-function clause decode (0b000000 : 0b00000 : (regno) rt : (regno) rd : (regno) sa : 0b000011) =
- Some(SRA(rt, rd, sa))
-function clause execute (SRA(rt, rd, sa)) =
- {
- temp := rGPR(rt);
- if (NotWordVal(temp)) then
- wGPR(rd) := undefined
- else
- wGPR(rd) := (temp[31] ^^ (sa+32)) : temp [31..sa]
- }
-
-(* SRAV 32-bit arithmetic shift right variable *)
-
-union ast member regregreg SRAV
-function clause decode (0b000000 : (regno) rs : (regno) rt : (regno) rd : 0b00000 : 0b000111) =
- Some(SRAV(rs, rt, rd))
-function clause execute (SRAV(rs, rt, rd)) =
- {
- temp := rGPR(rt);
- sa := (rGPR(rs))[4..0];
- if (NotWordVal(temp)) then
- wGPR(rd) := undefined
- else
- wGPR(rd) := (temp[31] ^^ (sa+32)) : temp [31..sa]
- }
-
-(* SRL 32-bit shift right *)
-
-union ast member regregreg SRL
-function clause decode (0b000000 : 0b00000 : (regno) rt : (regno) rd : (regno) sa : 0b000010) =
- Some(SRL(rt, rd, sa))
-function clause execute (SRL(rt, rd, sa)) =
- {
- temp := rGPR(rt);
- if (NotWordVal(temp)) then
- wGPR(rd) := undefined
- else
- wGPR(rd) := EXTS((bitzero ^^ sa) : (temp [31..sa]))
- }
-
-(* SRLV 32-bit shift right variable *)
-
-union ast member regregreg SRLV
-function clause decode (0b000000 : (regno) rs : (regno) rt : (regno) rd : 0b00000 : 0b000110) =
- Some(SRLV(rs, rt, rd))
-function clause execute (SRLV(rs, rt, rd)) =
- {
- temp := rGPR(rt);
- sa := (rGPR(rs))[4..0];
- if (NotWordVal(temp)) then
- wGPR(rd) := undefined
- else
- wGPR(rd) := EXTS((bitzero ^^ sa) : (temp [31..sa]))
- }
-
-(**************************************************************************************)
-(* set less than / conditional move *)
-(**************************************************************************************)
-
-(* SLT set if less than (signed) *)
-
-union ast member regregreg SLT
-function clause decode (0b000000 : (regno) rs : (regno) rt : (regno) rd : 0b00000 : 0b101010) =
- Some(SLT(rs, rt, rd))
-function clause execute (SLT(rs, rt, rd)) =
- {
- wGPR(rd) := if (rGPR(rs) <_s rGPR(rt)) then 1 else 0
- }
-
-(* SLT set if less than immediate (signed) *)
-
-union ast member regregimm16 SLTI
-function clause decode (0b001010 : (regno) rs : (regno) rt : (imm16) imm) =
- Some(SLTI(rs, rt, imm))
-function clause execute (SLTI(rs, rt, imm)) =
- {
- let imm_val = signed(imm) in
- let rs_val = signed(rGPR(rs)) in
- wGPR(rt) := if (rs_val < imm_val) then 0x0000000000000001 else 0x0000000000000000
- }
-
-(* SLTU set if less than unsigned *)
-
-union ast member regregreg SLTU
-function clause decode (0b000000 : (regno) rs : (regno) rt : (regno) rd : 0b00000 : 0b101011) =
- Some(SLTU(rs, rt, rd))
-function clause execute (SLTU(rs, rt, rd)) =
- {
- let rs_val = (0b0 : (rGPR(rs))) in
- let rt_val = (0b0 : (rGPR(rt))) in
- wGPR(rd) := (if (rs_val < rt_val) then 1 else 0)
- }
-
-(* SLTIU set if less than immediate unsigned *)
-
-union ast member regregimm16 SLTIU
-function clause decode (0b001011 : (regno) rs : (regno) rt : (imm16) imm) =
- Some(SLTIU(rs, rt, imm))
-function clause execute (SLTIU(rs, rt, imm)) =
- {
- let rs_val = (0b0 : (rGPR(rs))) in
- let imm_val = (0b0 : ((bit[64])(EXTS(imm)))) in
- wGPR(rt) := (if (rs_val < imm_val) then 1 else 0)
- }
-
-(* MOVN move if non-zero *)
-
-union ast member regregreg MOVN
-function clause decode (0b000000 : (regno) rs : (regno) rt : (regno) rd : 0b00000 : 0b001011) =
- Some(MOVN(rs, rt, rd))
-function clause execute (MOVN(rs, rt, rd)) =
- {
- if (rGPR(rt) != 0x0000000000000000) then
- wGPR(rd) := rGPR(rs)
- }
-
-(* MOVZ move if zero *)
-
-union ast member regregreg MOVZ
-function clause decode (0b000000 : (regno) rs : (regno) rt : (regno) rd : 0b00000 : 0b001010) =
- Some(MOVZ(rs, rt, rd))
-function clause execute (MOVZ(rs, rt, rd)) =
- {
- if (rGPR(rt) == 0x0000000000000000) then
- wGPR(rd) := rGPR(rs)
- }
-
-(******************************************************************************)
-(* MUL/DIV instructions *)
-(******************************************************************************)
-
-(* MFHI move from HI register *)
-union ast member regno MFHI
-function clause decode (0b000000 : 0b0000000000 : (regno) rd : 0b00000 : 0b010000) =
- Some(MFHI(rd))
-function clause execute (MFHI(rd)) =
- {
- wGPR(rd) := HI
- }
-
-(* MFLO move from LO register *)
-union ast member regno MFLO
-function clause decode (0b000000 : 0b0000000000 : (regno) rd : 0b00000 : 0b010010) =
- Some(MFLO(rd))
-function clause execute (MFLO(rd)) =
- {
- wGPR(rd) := LO
- }
-
-(* MTHI move to HI register *)
-union ast member regno MTHI
-function clause decode (0b000000 : (regno) rs : 0b000000000000000 : 0b010001) =
- Some(MTHI(rs))
-function clause execute (MTHI(rs)) =
- {
- HI := rGPR(rs)
- }
-
-(* MTLO move to LO register *)
-union ast member regno MTLO
-function clause decode (0b000000 : (regno) rs : 0b000000000000000 : 0b010011) =
- Some(MTLO(rs))
-function clause execute (MTLO(rs)) =
- {
- LO := rGPR(rs)
- }
-
-(* MUL 32-bit multiply into GPR *)
-union ast member regregreg MUL
-function clause decode (0b011100 : (regno) rs : (regno) rt : (regno) rd : 0b00000 : 0b000010) =
- Some(MUL(rs, rt, rd))
-function clause execute (MUL(rs, rt, rd)) =
- {
- rsVal := rGPR(rs);
- rtVal := rGPR(rt);
- (bit[64]) result := (rsVal[31..0]) *_s (rtVal[31..0]);
- wGPR(rd) := if (NotWordVal(rsVal) | NotWordVal(rtVal)) then
- undefined
- else
- EXTS(result[31..0]);
- (* HI and LO are technically undefined after MUL, but this causes problems with tests and
- (potentially) context switch so just leave them alone
- HI := undefined;
- LO := undefined;
- *)
- }
-
-(* MULT 32-bit multiply into HI/LO *)
-union ast member (regno, regno) MULT
-function clause decode (0b000000 : (regno) rs : (regno) rt : 0b00000 : 0b00000 : 0b011000) =
- Some(MULT(rs, rt))
-function clause execute (MULT(rs, rt)) =
- {
- rsVal := rGPR(rs);
- rtVal := rGPR(rt);
- (bit[64]) result := if (NotWordVal(rsVal) | NotWordVal(rtVal)) then
- undefined
- else
- (rsVal[31..0]) *_s (rtVal[31..0]);
- HI := EXTS(result[63..32]);
- LO := EXTS(result[31..0]);
- }
-
-(* MULTU 32-bit unsignedm rultiply into HI/LO *)
-union ast member (regno, regno) MULTU
-function clause decode (0b000000 : (regno) rs : (regno) rt : 0b00000 : 0b00000 : 0b011001) =
- Some(MULTU(rs, rt))
-function clause execute (MULTU(rs, rt)) =
- {
- rsVal := rGPR(rs);
- rtVal := rGPR(rt);
- (bit[64]) result := if (NotWordVal(rsVal) | NotWordVal(rtVal)) then
- undefined
- else
- (rsVal[31..0]) * (rtVal[31..0]);
- HI := EXTS(result[63..32]);
- LO := EXTS(result[31..0]);
- }
-
-(* DMULT 64-bit multiply into HI/LO *)
-union ast member (regno, regno) DMULT
-function clause decode (0b000000 : (regno) rs : (regno) rt : 0b00000 : 0b00000 : 0b011100) =
- Some(DMULT(rs, rt))
-function clause execute (DMULT(rs, rt)) =
- {
- (bit[128]) result := (rGPR(rs)) *_s (rGPR(rt));
- HI := (result[127..64]);
- LO := (result[63..0]);
- }
-
-(* DMULTU 64-bit unsigned multiply into HI/LO *)
-union ast member (regno, regno) DMULTU
-function clause decode (0b000000 : (regno) rs : (regno) rt : 0b00000 : 0b00000 : 0b011101) =
- Some(DMULTU(rs, rt))
-function clause execute (DMULTU(rs, rt)) =
- {
- (bit[128]) result := (rGPR(rs)) * (rGPR(rt));
- HI := (result[127..64]);
- LO := (result[63..0]);
- }
-
-(* MADD 32-bit signed multiply and add into HI/LO *)
-union ast member (regno, regno) MADD
-function clause decode (0b011100 : (regno) rs : (regno) rt : 0b00000 : 0b00000 : 0b000000) =
- Some(MADD(rs, rt))
-function clause execute (MADD(rs, rt)) =
- {
- rsVal := rGPR(rs);
- rtVal := rGPR(rt);
- (bit[64]) mul_result := if (NotWordVal(rsVal) | NotWordVal(rtVal)) then
- undefined
- else
- ((rsVal[31..0]) *_s (rtVal[31..0]));
- (bit[64]) result := mul_result + (HI[31..0] : LO[31..0]);
- HI := EXTS(result[63..32]);
- LO := EXTS(result[31..0]);
- }
-
-(* MADDU 32-bit unsigned multiply and add into HI/LO *)
-union ast member (regno, regno) MADDU
-function clause decode (0b011100 : (regno) rs : (regno) rt : 0b00000 : 0b00000 : 0b000001) =
- Some(MADDU(rs, rt))
-function clause execute (MADDU(rs, rt)) =
- {
- rsVal := rGPR(rs);
- rtVal := rGPR(rt);
- (bit[64]) mul_result := if (NotWordVal(rsVal) | NotWordVal(rtVal)) then
- undefined
- else
- ((rsVal[31..0]) * (rtVal[31..0]));
- (bit[64]) result := mul_result + (HI[31..0] : LO[31..0]);
- HI := EXTS(result[63..32]);
- LO := EXTS(result[31..0]);
- }
-
-(* MSUB 32-bit signed multiply and sub from HI/LO *)
-union ast member (regno, regno) MSUB
-function clause decode (0b011100 : (regno) rs : (regno) rt : 0b00000 : 0b00000 : 0b000100) =
- Some(MSUB(rs, rt))
-function clause execute (MSUB(rs, rt)) =
- {
- rsVal := rGPR(rs);
- rtVal := rGPR(rt);
- (bit[64]) mul_result := if (NotWordVal(rsVal) | NotWordVal(rtVal)) then
- undefined
- else
- ((rsVal[31..0]) *_s (rtVal[31..0]));
- (bit[64]) result := (HI[31..0] : LO[31..0]) - mul_result;
- HI := EXTS(result[63..32]);
- LO := EXTS(result[31..0]);
- }
-
-(* MSUBU 32-bit unsigned multiply and sub from HI/LO *)
-union ast member (regno, regno) MSUBU
-function clause decode (0b011100 : (regno) rs : (regno) rt : 0b00000 : 0b00000 : 0b000101) =
- Some(MSUBU(rs, rt))
-function clause execute (MSUBU(rs, rt)) =
- {
- rsVal := rGPR(rs);
- rtVal := rGPR(rt);
- (bit[64]) mul_result := if (NotWordVal(rsVal) | NotWordVal(rtVal)) then
- undefined
- else
- ((rsVal[31..0]) * (rtVal[31..0]));
- (bit[64]) result := (HI[31..0] : LO[31..0]) - mul_result;
- HI := EXTS(result[63..32]);
- LO := EXTS(result[31..0]);
- }
-
-(* DIV 32-bit divide into HI/LO *)
-union ast member (regno, regno) DIV
-function clause decode (0b000000 : (regno) rs : (regno) rt : 0b00000 : 0b00000 : 0b011010) =
- Some(DIV(rs, rt))
-function clause execute (DIV(rs, rt)) =
- {
- rsVal := rGPR(rs);
- rtVal := rGPR(rt);
- let ((bit[32]) q, (bit[32])r) = (
- if (NotWordVal(rsVal) | NotWordVal(rtVal) | (rtVal == 0)) then
- (undefined, undefined)
- else
- let si = (signed((rsVal[31..0]))) in
- let ti = (signed((rtVal[31..0]))) in
- let qi = (si quot ti) in
- let ri = (si - (ti*qi)) in
- ((bit[32]) qi, (bit[32]) ri))
- in
- {
- HI := EXTS(r);
- LO := EXTS(q);
- }
- }
-
-(* DIVU 32-bit unsigned divide into HI/LO *)
-union ast member (regno, regno) DIVU
-function clause decode (0b000000 : (regno) rs : (regno) rt : 0b00000 : 0b00000 : 0b011011) =
- Some(DIVU(rs, rt))
-function clause execute (DIVU(rs, rt)) =
- {
- rsVal := rGPR(rs);
- rtVal := rGPR(rt);
- let ((bit[32]) q, (bit[32])r) = (
- if (NotWordVal(rsVal) | NotWordVal(rtVal) | rtVal == 0) then
- (undefined, undefined)
- else
- let si = unsigned(rsVal[31..0]) in
- let ti = unsigned(rtVal[31..0]) in
- let qi = (si quot ti) in
- let ri = (si mod ti) in
- ((bit[32]) qi, (bit[32]) ri))
- in
- {
- HI := EXTS(r);
- LO := EXTS(q);
- }
- }
-
-(* DDIV 64-bit divide into HI/LO *)
-union ast member (regno, regno) DDIV
-function clause decode (0b000000 : (regno) rs : (regno) rt : 0b00000 : 0b00000 : 0b011110) =
- Some(DDIV(rs, rt))
-function clause execute (DDIV(rs, rt)) =
- {
- rsVal := signed(rGPR(rs));
- rtVal := signed(rGPR(rt));
- let ((bit[64])q, (bit[64])r) = (if (rtVal == 0)
- then (undefined, undefined)
- else
- let qi = (rsVal quot rtVal) in
- let ri = (rsVal - (qi * rtVal)) in
- ((bit[64]) qi, (bit[64]) ri)) in
- {
- LO := q;
- HI := r;
- }
- }
-
-(* DDIV 64-bit divide into HI/LO *)
-union ast member (regno, regno) DDIVU
-function clause decode (0b000000 : (regno) rs : (regno) rt : 0b00000 : 0b00000 : 0b011111) =
- Some(DDIVU(rs, rt))
-function clause execute (DDIVU(rs, rt)) =
- {
- (int) rsVal := rGPR(rs);
- (int) rtVal := rGPR(rt);
- let ((bit[64])q, (bit[64])r) = (if (rtVal == 0)
- then (undefined, undefined)
- else let qi = (rsVal quot rtVal) in
- let ri = (rsVal mod rtVal) in
- ((bit[64]) qi, (bit[64]) ri)) in
- {
- LO := q;
- HI := r;
- }
- }
-
-(**************************************************************************************)
-(* Jump instructions -- unconditional branches *)
-(**************************************************************************************)
-
-(* J - jump, the simplest control flow instruction, with branch delay slot *)
-union ast member (bit[26]) J
-function clause decode (0b000010 : (bit[26]) offset) =
- Some(J(offset))
-function clause execute (J(offset)) =
- {
- delayedPC := (PC + 4)[63..28] : offset : 0b00;
- branchPending := 1
- }
-
-(* JAL - jump and link *)
-union ast member (bit[26]) JAL
-function clause decode (0b000011 : (bit[26]) offset) =
- Some(JAL(offset))
-function clause execute (JAL(offset)) =
- {
- delayedPC := (PC + 4)[63..28] : offset : 0b00;
- branchPending := 1;
- wGPR(31) := PC + 8;
- }
-
-(* JR -- jump via register *)
-union ast member regno JR
-function clause decode (0b000000 : (regno) rs : 0b00000 : 0b00000 : (regno) hint : 0b001000) =
- Some(JR(rs)) (* hint is ignored *)
-function clause execute (JR(rs)) =
- {
- delayedPC := rGPR(rs);
- branchPending := 1;
- }
-
-(* JALR -- jump via register with link *)
-union ast member (regno, regno) JALR
-function clause decode (0b000000 : (regno) rs : 0b00000 : (regno) rd : (regno) hint : 0b001001) =
- Some(JALR(rs, rd)) (* hint is ignored *)
-function clause execute (JALR(rs, rd)) =
- {
- delayedPC := rGPR(rs);
- branchPending := 1;
- wGPR(rd) := PC + 8;
- }
-
-(**************************************************************************************)
-(* B[N]EQ[L] - branch on (not) equal (likely) *)
-(* Conditional branch instructions with two register operands *)
-(**************************************************************************************)
-
-union ast member (regno, regno, imm16, bool, bool) BEQ
-function clause decode (0b000100 : (regno) rs : (regno) rt : (imm16) imm) =
- Some(BEQ(rs, rt, imm, false, false)) (* BEQ *)
-function clause decode (0b010100 : (regno) rs : (regno) rt : (imm16) imm) =
- Some(BEQ(rs, rt, imm, false, true)) (* BEQL *)
-function clause decode (0b000101 : (regno) rs : (regno) rt : (imm16) imm) =
- Some(BEQ(rs, rt, imm, true , false)) (* BNE *)
-function clause decode (0b010101 : (regno) rs : (regno) rt : (imm16) imm) =
- Some(BEQ(rs, rt, imm, true , true)) (* BNEL *)
-function clause execute (BEQ(rs, rd, imm, ne, likely)) =
- {
- if ((rGPR(rs) == rGPR(rd)) ^ ne) then
- {
- let (bit[64]) offset = (EXTS(imm : 0b00) + 4) in
- delayedPC := PC + offset;
- branchPending := 1;
- }
- else
- {
- if (likely) then
- nextPC := PC + 8; (* skip branch delay *)
- }
- }
-
-(*
-
- Branches comparing with zero (single register operand, possible link in r31)
-*)
-
-(**************************************************************************************)
-(* BGEZ[AL][L] - branch on comparison with zero (possibly link, likely) *)
-(* Conditional branch instructions with single register operand *)
-(**************************************************************************************)
-
-union ast member (regno, imm16, Comparison, bool, bool) BCMPZ
-function clause decode (0b000001 : (regno) rs : 0b00000 : (imm16) imm) =
- Some(BCMPZ(rs, imm, LT, false, false)) (* BLTZ *)
-function clause decode (0b000001 : (regno) rs : 0b10000 : (imm16) imm) =
- Some(BCMPZ(rs, imm, LT, true, false)) (* BLTZAL *)
-function clause decode (0b000001 : (regno) rs : 0b00010 : (imm16) imm) =
- Some(BCMPZ(rs, imm, LT, false, true)) (* BLTZL *)
-function clause decode (0b000001 : (regno) rs : 0b10010 : (imm16) imm) =
- Some(BCMPZ(rs, imm, LT, true, true)) (* BLTZALL *)
-
-function clause decode (0b000001 : (regno) rs : 0b00001 : (imm16) imm) =
- Some(BCMPZ(rs, imm, GE, false, false)) (* BGEZ *)
-function clause decode (0b000001 : (regno) rs : 0b10001 : (imm16) imm) =
- Some(BCMPZ(rs, imm, GE, true, false)) (* BGEZAL *)
-function clause decode (0b000001 : (regno) rs : 0b00011 : (imm16) imm) =
- Some(BCMPZ(rs, imm, GE, false, true)) (* BGEZL *)
-function clause decode (0b000001 : (regno) rs : 0b10011 : (imm16) imm) =
- Some(BCMPZ(rs, imm, GE, true, true)) (* BGEZALL *)
-
-function clause decode (0b000111 : (regno) rs : 0b00000 : (imm16) imm) =
- Some(BCMPZ(rs, imm, GT, false, false)) (* BGTZ *)
-function clause decode (0b010111 : (regno) rs : 0b00000 : (imm16) imm) =
- Some(BCMPZ(rs, imm, GT, false, true)) (* BGTZL *)
-
-function clause decode (0b000110 : (regno) rs : 0b00000 : (imm16) imm) =
- Some(BCMPZ(rs, imm, LE, false, false)) (* BLEZ *)
-function clause decode (0b010110 : (regno) rs : 0b00000 : (imm16) imm) =
- Some(BCMPZ(rs, imm, LE, false, true)) (* BLEZL *)
-
-function clause execute (BCMPZ(rs, imm, cmp, link, likely)) =
- {
- (bit[64]) linkVal := PC + 8;
- regVal := rGPR(rs);
- condition := compare(cmp, regVal, 0);
- if (condition) then
- {
- let (bit[64]) offset = (EXTS(imm : 0b00) + 4) in
- delayedPC := PC + offset;
- branchPending := 1;
- }
- else if (likely) then
- {
- nextPC := PC + 8 (* skip branch delay *)
- };
- if (link) then
- wGPR(31) := linkVal
- }
-
-(**************************************************************************************)
-(* SYSCALL/BREAK/WAIT/Trap *)
-(**************************************************************************************)
-
-(* Co-opt syscall 0xfffff for use as thread start in pccmem *)
-union ast member unit SYSCALL_THREAD_START
-function clause decode (0b000000 : 0xfffff : 0b001100) =
- Some(SYSCALL_THREAD_START)
-function clause execute (SYSCALL_THREAD_START) = ()
-
-
-(* fake stop fetching instruction for ppcmem, execute doesn't do anything,
- decode never produces it *)
-
-union ast member unit ImplementationDefinedStopFetching
-function clause execute (ImplementationDefinedStopFetching) = ()
-
-
-union ast member unit SYSCALL
-function clause decode (0b000000 : (bit[20]) code : 0b001100) =
- Some(SYSCALL) (* code is ignored *)
-function clause execute (SYSCALL) =
- {
- (SignalException(Sys))
- }
-
-(* BREAK is identical to SYSCALL exception for the exception raised *)
-union ast member unit BREAK
-function clause decode (0b000000 : (bit[20]) code : 0b001101) =
- Some(BREAK) (* code is ignored *)
-function clause execute (BREAK) =
- {
- (SignalException(Bp))
- }
-
-(* Accept WAIT as a NOP *)
-union ast member unit WAIT
-function clause decode (0b010000 : 0x80000 : 0b100000) =
- Some(WAIT) (* we only accept code == 0 *)
-function clause execute (WAIT) = {
- nextPC := PC;
-}
-
-(* Trap instructions with two register operands *)
-union ast member (regno, regno, Comparison) TRAPREG
-function clause decode (0b000000 : (regno) rs : (regno) rt : (bit[10]) code : 0b110000) =
- Some(TRAPREG(rs, rt, GE)) (* TGE *)
-function clause decode (0b000000 : (regno) rs : (regno) rt : (bit[10]) code : 0b110001) =
- Some(TRAPREG(rs, rt, GEU)) (* TGEU *)
-function clause decode (0b000000 : (regno) rs : (regno) rt : (bit[10]) code : 0b110010) =
- Some(TRAPREG(rs, rt, LT)) (* TLT *)
-function clause decode (0b000000 : (regno) rs : (regno) rt : (bit[10]) code : 0b110011) =
- Some(TRAPREG(rs, rt, LTU)) (* TLTU *)
-function clause decode (0b000000 : (regno) rs : (regno) rt : (bit[10]) code : 0b110100) =
- Some(TRAPREG(rs, rt, EQ)) (* TEQ *)
-function clause decode (0b000000 : (regno) rs : (regno) rt : (bit[10]) code : 0b110110) =
- Some(TRAPREG(rs, rt, NE)) (* TNE *)
-function clause execute (TRAPREG(rs, rt, cmp)) =
- {
- rs_val := rGPR(rs);
- rt_val := rGPR(rt);
- condition := compare(cmp, rs_val, rt_val);
- if (condition) then
- (SignalException(Tr))
- }
-
-
-(* Trap instructions with one register and one immediate operand *)
-union ast member (regno, imm16, Comparison) TRAPIMM
-function clause decode (0b000001 : (regno) rs : 0b01100 : (imm16) imm) =
- Some(TRAPIMM(rs, imm, EQ)) (* TEQI *)
-function clause decode (0b000001 : (regno) rs : 0b01110 : (imm16) imm) =
- Some(TRAPIMM(rs, imm, NE)) (* TNEI *)
-function clause decode (0b000001 : (regno) rs : 0b01000 : (imm16) imm) =
- Some(TRAPIMM(rs, imm, GE)) (* TGEI *)
-function clause decode (0b000001 : (regno) rs : 0b01001 : (imm16) imm) =
- Some(TRAPIMM(rs, imm, GEU)) (* TGEIU *)
-function clause decode (0b000001 : (regno) rs : 0b01010 : (imm16) imm) =
- Some(TRAPIMM(rs, imm, LT)) (* TLTI *)
-function clause decode (0b000001 : (regno) rs : 0b01011 : (imm16) imm) =
- Some(TRAPIMM(rs, imm, LTU)) (* TLTIU *)
-function clause execute (TRAPIMM(rs, imm, cmp)) =
- {
- rs_val := rGPR(rs);
- imm_val := EXTS(imm);
- condition := compare(cmp, rs_val, imm_val);
- if (condition) then
- (SignalException(Tr))
- }
-
-(**************************************************************************************)
-(* Load instructions -- various width/signs *)
-(**************************************************************************************)
-
-union ast member (WordType, bool, bool, regno, regno, imm16) Load
-function clause decode (0b100000 : (regno) base : (regno) rt : (imm16) offset) =
- Some(Load(B, true, false, base, rt, offset)) (* LB *)
-function clause decode (0b100100 : (regno) base : (regno) rt : (imm16) offset) =
- Some(Load(B, false, false, base, rt, offset)) (* LBU *)
-function clause decode (0b100001 : (regno) base : (regno) rt : (imm16) offset) =
- Some(Load(H, true, false, base, rt, offset)) (* LH *)
-function clause decode (0b100101 : (regno) base : (regno) rt : (imm16) offset) =
- Some(Load(H, false, false, base, rt, offset)) (* LHU *)
-function clause decode (0b100011 : (regno) base : (regno) rt : (imm16) offset) =
- Some(Load(W, true, false, base, rt, offset)) (* LW *)
-function clause decode (0b100111 : (regno) base : (regno) rt : (imm16) offset) =
- Some(Load(W, false, false, base, rt, offset)) (* LWU *)
-function clause decode (0b110111 : (regno) base : (regno) rt : (imm16) offset) =
- Some(Load(D, false, false, base, rt, offset)) (* LD *)
-function clause decode (0b110000 : (regno) base : (regno) rt : (imm16) offset) =
- Some(Load(W, true, true, base, rt, offset)) (* LL *)
-function clause decode (0b110100 : (regno) base : (regno) rt : (imm16) offset) =
- Some(Load(D, false, true, base, rt, offset)) (* LLD *)
-function clause execute (Load(width, signed, linked, base, rt, offset)) =
- {
- (bit[64]) vAddr := addrWrapper(EXTS(offset) + rGPR(base), LoadData, width);
- if ~ (isAddressAligned(vAddr, width)) then
- (SignalExceptionBadAddr(AdEL, vAddr)) (* unaligned access *)
- else
- let pAddr = (TLBTranslate(vAddr, LoadData)) in
- {
- memResult := if (linked) then
- {
- CP0LLBit := 0b1;
- CP0LLAddr := pAddr;
- MEMr_reserve_wrapper(pAddr, wordWidthBytes(width));
- }
- else
- MEMr_wrapper(pAddr, wordWidthBytes(width));
- if (signed) then
- wGPR(rt) := EXTS(memResult)
- else
- wGPR(rt) := EXTZ(memResult)
- }
- }
-
-(**************************************************************************************)
-(* Store instructions -- various widths *)
-(**************************************************************************************)
-
-union ast member (WordType, bool, regno, regno, imm16) Store
-function clause decode (0b101000 : (regno) base : (regno) rt : (imm16) offset) =
- Some(Store(B, false, base, rt, offset)) (* SB *)
-function clause decode (0b101001 : (regno) base : (regno) rt : (imm16) offset) =
- Some(Store(H, false, base, rt, offset)) (* SH *)
-function clause decode (0b101011 : (regno) base : (regno) rt : (imm16) offset) =
- Some(Store(W, false, base, rt, offset)) (* SW *)
-function clause decode (0b111111 : (regno) base : (regno) rt : (imm16) offset) =
- Some(Store(D, false, base, rt, offset)) (* SD *)
-function clause decode (0b111000 : (regno) base : (regno) rt : (imm16) offset) =
- Some(Store(W, true, base, rt, offset)) (* SC *)
-function clause decode (0b111100 : (regno) base : (regno) rt : (imm16) offset) =
- Some(Store(D, true, base, rt, offset)) (* SCD *)
-function clause execute (Store(width, conditional, base, rt, offset)) =
- {
- (bit[64]) vAddr := addrWrapper(EXTS(offset) + rGPR(base), StoreData, width);
- (bit[64]) rt_val := rGPR(rt);
- if ~ (isAddressAligned(vAddr, width)) then
- (SignalExceptionBadAddr(AdES, vAddr)) (* unaligned access *)
- else
- let pAddr = (TLBTranslate(vAddr, StoreData)) in
- {
- if (conditional) then
- {
- success := if (CP0LLBit[0]) then switch(width)
- {
- case B -> MEMw_conditional_wrapper(pAddr, 1, rt_val[7..0])
- case H -> MEMw_conditional_wrapper(pAddr, 2, rt_val[15..0])
- case W -> MEMw_conditional_wrapper(pAddr, 4, rt_val[31..0])
- case D -> MEMw_conditional_wrapper(pAddr, 8, rt_val)
- } else false;
- wGPR(rt) := EXTZ([success])
- }
- else
- switch(width)
- {
- case B -> MEMw_wrapper(pAddr, 1) := rt_val[7..0]
- case H -> MEMw_wrapper(pAddr, 2) := rt_val[15..0]
- case W -> MEMw_wrapper(pAddr, 4) := rt_val[31..0]
- case D -> MEMw_wrapper(pAddr, 8) := rt_val
- }
- }
- }
-
-(* LWL - Load word left (big-endian only) *)
-
-union ast member regregimm16 LWL
-function clause decode(0b100010 : (regno) base : (regno) rt : (imm16) offset) =
- Some(LWL(base, rt, offset))
-function clause execute(LWL(base, rt, offset)) =
- {
- (* XXX length check not quite right, but conservative *)
- (bit[64]) vAddr := addrWrapper(EXTS(offset) + rGPR(base), LoadData, W);
- let pAddr = (TLBTranslate(vAddr, LoadData)) in
- {
- mem_val := MEMr_wrapper (pAddr[63..2] : 0b00, 4); (* read word of interest *)
- reg_val := rGPR(rt);
- wGPR(rt) := EXTS(switch(vAddr[1..0])
- {
- case 0b00 -> mem_val
- case 0b01 -> mem_val[23..0] : reg_val[07..0]
- case 0b10 -> mem_val[15..0] : reg_val[15..0]
- case 0b11 -> mem_val[07..0] : reg_val[23..0]
- });
- }
- }
-union ast member regregimm16 LWR
-function clause decode(0b100110 : (regno) base : (regno) rt : (imm16) offset) =
- Some(LWR(base, rt, offset))
-function clause execute(LWR(base, rt, offset)) =
- {
- (* XXX length check not quite right, but conservative *)
- (bit[64]) vAddr := addrWrapper(EXTS(offset) + rGPR(base), LoadData, W);
- let pAddr = (TLBTranslate(vAddr, LoadData)) in
- {
- mem_val := MEMr_wrapper (pAddr[63..2] : 0b00, 4); (* read word of interest *)
- reg_val := rGPR(rt);
- wGPR(rt) := EXTS(switch(vAddr[1..0]) (* it is acceptable to sign extend in all cases *)
- {
- case 0b00 -> reg_val[31..8] : mem_val[31..24]
- case 0b01 -> reg_val[31..16] : mem_val[31..16]
- case 0b10 -> reg_val[31..24] : mem_val[31..8]
- case 0b11 -> mem_val
- });
- }
- }
-
-(* SWL - Store word left *)
-union ast member regregimm16 SWL
-function clause decode(0b101010 : (regno) base : (regno) rt : (imm16) offset) =
- Some(SWL(base, rt, offset))
-function clause execute(SWL(base, rt, offset)) =
- {
- (* XXX length check not quite right, but conservative *)
- (bit[64]) vAddr := addrWrapper(EXTS(offset) + rGPR(base), StoreData, W);
- let pAddr = (TLBTranslate(vAddr, StoreData)) in
- {
- reg_val := rGPR(rt);
- switch (vAddr[1..0])
- {
- case 0b00 -> (MEMw_wrapper(pAddr, 4) := reg_val[31..0])
- case 0b01 -> (MEMw_wrapper(pAddr, 3) := reg_val[31..8])
- case 0b10 -> (MEMw_wrapper(pAddr, 2) := reg_val[31..16])
- case 0b11 -> (MEMw_wrapper(pAddr, 1) := reg_val[31..24])
- }
- }
- }
-
-union ast member regregimm16 SWR
-function clause decode(0b101110 : (regno) base : (regno) rt : (imm16) offset) =
- Some(SWR(base, rt, offset))
-function clause execute(SWR(base, rt, offset)) =
- {
- (* XXX length check not quite right, but conservative *)
- (bit[64]) vAddr := addrWrapper(EXTS(offset) + rGPR(base), StoreData, W);
- let (pAddr) = (TLBTranslate(vAddr, StoreData)) in
- {
- wordAddr := pAddr[63..2] : 0b00;
- reg_val := rGPR(rt);
- switch (vAddr[1..0])
- {
- case 0b00 -> (MEMw_wrapper(wordAddr, 1) := reg_val[7..0])
- case 0b01 -> (MEMw_wrapper(wordAddr, 2) := reg_val[15..0])
- case 0b10 -> (MEMw_wrapper(wordAddr, 3) := reg_val[23..0])
- case 0b11 -> (MEMw_wrapper(wordAddr, 4) := reg_val[31..0])
- }
- }
- }
-
-(* Load double-word left *)
-union ast member regregimm16 LDL
-function clause decode(0b011010 : (regno) base : (regno) rt : (imm16) offset) =
- Some(LDL(base, rt, offset))
-function clause execute(LDL(base, rt, offset)) =
- {
- (* XXX length check not quite right, but conservative *)
- (bit[64]) vAddr := addrWrapper(EXTS(offset) + rGPR(base), LoadData, D);
- let pAddr = (TLBTranslate(vAddr, StoreData)) in
- {
- mem_val := MEMr_wrapper (pAddr[63..3] : 0b000, 8); (* read double of interest *)
- reg_val := rGPR(rt);
- wGPR(rt) := switch(vAddr[2..0])
- {
- case 0b000 -> mem_val
- case 0b001 -> mem_val[55..0] : reg_val[7..0]
- case 0b010 -> mem_val[47..0] : reg_val[15..0]
- case 0b011 -> mem_val[39..0] : reg_val[23..0]
- case 0b100 -> mem_val[31..0] : reg_val[31..0]
- case 0b101 -> mem_val[23..0] : reg_val[39..0]
- case 0b110 -> mem_val[15..0] : reg_val[47..0]
- case 0b111 -> mem_val[07..0] : reg_val[55..0]
- };
- }
- }
-
-(* Load double-word right *)
-union ast member regregimm16 LDR
-function clause decode(0b011011 : (regno) base : (regno) rt : (imm16) offset) =
- Some(LDR(base, rt, offset))
-function clause execute(LDR(base, rt, offset)) =
- {
- (* XXX length check not quite right, but conservative *)
- (bit[64]) vAddr := addrWrapper(EXTS(offset) + rGPR(base), LoadData, D);
- let pAddr = (TLBTranslate(vAddr, StoreData)) in
- {
- mem_val := MEMr_wrapper (pAddr[63..3] : 0b000, 8); (* read double of interest *)
- reg_val := rGPR(rt);
- wGPR(rt) := switch(vAddr[2..0])
- {
- case 0b000 -> reg_val[63..08] : mem_val[63..56]
- case 0b001 -> reg_val[63..16] : mem_val[63..48]
- case 0b010 -> reg_val[63..24] : mem_val[63..40]
- case 0b011 -> reg_val[63..32] : mem_val[63..32]
- case 0b100 -> reg_val[63..40] : mem_val[63..24]
- case 0b101 -> reg_val[63..48] : mem_val[63..16]
- case 0b110 -> reg_val[63..56] : mem_val[63..08]
- case 0b111 -> mem_val
- };
- }
- }
-
-(* SDL - Store double-word left *)
-union ast member regregimm16 SDL
-function clause decode(0b101100 : (regno) base : (regno) rt : (imm16) offset) =
- Some(SDL(base, rt, offset))
-function clause execute(SDL(base, rt, offset)) =
- {
- (* XXX length check not quite right, but conservative *)
- (bit[64]) vAddr := addrWrapper(EXTS(offset) + rGPR(base), StoreData, D);
- let pAddr = (TLBTranslate(vAddr, StoreData)) in
- {
- reg_val := rGPR(rt);
- switch (vAddr[2..0])
- {
- case 0b000 -> (MEMw_wrapper(pAddr, 8) := reg_val[63..00])
- case 0b001 -> (MEMw_wrapper(pAddr, 7) := reg_val[63..08])
- case 0b010 -> (MEMw_wrapper(pAddr, 6) := reg_val[63..16])
- case 0b011 -> (MEMw_wrapper(pAddr, 5) := reg_val[63..24])
- case 0b100 -> (MEMw_wrapper(pAddr, 4) := reg_val[63..32])
- case 0b101 -> (MEMw_wrapper(pAddr, 3) := reg_val[63..40])
- case 0b110 -> (MEMw_wrapper(pAddr, 2) := reg_val[63..48])
- case 0b111 -> (MEMw_wrapper(pAddr, 1) := reg_val[63..56])
- }
- }
- }
-
-
-(* SDR - Store double-word right *)
-union ast member regregimm16 SDR
-function clause decode(0b101101 : (regno) base : (regno) rt : (imm16) offset) =
- Some(SDR(base, rt, offset))
-function clause execute(SDR(base, rt, offset)) =
- {
- (* XXX length check not quite right, but conservative *)
- (bit[64]) vAddr := addrWrapper(EXTS(offset) + rGPR(base), StoreData, D);
- let pAddr = (TLBTranslate(vAddr, StoreData)) in
- {
- reg_val := rGPR(rt);
- wordAddr := pAddr[63..3] : 0b000;
- switch (vAddr[2..0])
- {
- case 0b000 -> (MEMw_wrapper(wordAddr, 1) := reg_val[07..0])
- case 0b001 -> (MEMw_wrapper(wordAddr, 2) := reg_val[15..0])
- case 0b010 -> (MEMw_wrapper(wordAddr, 3) := reg_val[23..0])
- case 0b011 -> (MEMw_wrapper(wordAddr, 4) := reg_val[31..0])
- case 0b100 -> (MEMw_wrapper(wordAddr, 5) := reg_val[39..0])
- case 0b101 -> (MEMw_wrapper(wordAddr, 6) := reg_val[47..0])
- case 0b110 -> (MEMw_wrapper(wordAddr, 7) := reg_val[55..0])
- case 0b111 -> (MEMw_wrapper(wordAddr, 8) := reg_val[63..0])
- }
- }
- }
-
-(* CACHE - manipulate (non-existent) caches *)
-
-union ast member regregimm16 CACHE
-function clause decode (0b101111 : (regno) base : (regno) op : (imm16) imm) =
- Some(CACHE(base, op, imm))
-function clause execute (CACHE(base, op, imm)) =
- checkCP0Access () (* pretty much a NOP because no caches *)
-
-(* PREF - prefetching into (non-existent) caches *)
-
-union ast member regregimm16 PREF
-function clause decode (0b110011 : (regno) base : (regno) op : (imm16) imm) =
- Some(PREF(base, op, imm))
-function clause execute (PREF(base, op, imm)) =
- () (* XXX NOP *)
-
-
-(* SYNC - Memory barrier *)
-union ast member unit SYNC
-function clause decode (0b000000 : 0b00000 : 0b00000 : 0b00000 : (regno) stype : 0b001111) =
- Some(SYNC()) (* stype is currently ignored *)
-function clause execute(SYNC) =
- MEM_sync()
-
-union ast member (regno, regno, bit[3], bool) MFC0
-function clause decode (0b010000 : 0b00000 : (regno) rt : (regno) rd : 0b00000000 : (bit[3]) sel) =
- Some(MFC0(rt, rd, sel, false)) (* MFC0 *)
-function clause decode (0b010000 : 0b00001 : (regno) rt : (regno) rd : 0b00000000 : (bit[3]) sel) =
- Some(MFC0(rt, rd, sel, true)) (* DMFC0 *)
-function clause execute (MFC0(rt, rd, sel, double)) = {
- checkCP0Access();
- let (bit[64]) result = switch (rd, sel)
- {
- case (0b00000,0b000) -> let (bit[31]) idx = EXTZ(TLBIndex) in
- (0x00000000 : [TLBProbe] : idx) (* 0, TLB Index *)
- case (0b00001,0b000) -> EXTZ(TLBRandom) (* 1, TLB Random *)
- case (0b00010,0b000) -> TLBEntryLo0 (* 2, TLB EntryLo0 *)
- case (0b00011,0b000) -> TLBEntryLo1 (* 3, TLB EntryLo1 *)
- case (0b00100,0b000) -> TLBContext (* 4, TLB Context *)
- case (0b00101,0b000) -> EXTZ(TLBPageMask : 0x000) (* 5, TLB PageMask *)
- case (0b00110,0b000) -> EXTZ(TLBWired) (* 6, TLB Wired *)
- case (0b00111,0b000) -> EXTZ(CP0HWREna) (* 7, HWREna *)
- case (0b01000,0b000) -> CP0BadVAddr (* 8, BadVAddr reg *)
- case (0b01000,0b001) -> 0 (* 8, BadInstr reg XXX TODO *)
- case (0b01001,0b000) -> EXTZ(CP0Count) (* 9, Count reg *)
- case (0b01010,0b000) -> TLBEntryHi (* 10, TLB EntryHi *)
- case (0b01011,0b000) -> EXTZ(CP0Compare) (* 11, Compare reg *)
- case (0b01100,0b000) -> EXTZ(CP0Status) (* 12, Status reg *)
- case (0b01101,0b000) -> EXTZ(CP0Cause) (* 13, Cause reg *)
- case (0b01110,0b000) -> CP0EPC (* 14, EPC *)
- case (0b01111,0b000) -> EXTZ(0x00000400) (* 15, sel 0: PrID processor ID *)
- case (0b01111,0b110) -> 0 (* 15, sel 6: CHERI core ID *)
- case (0b01111,0b111) -> 0 (* 15, sel 7: CHERI thread ID *)
- case (0b10000,0b000) -> EXTZ(0b1 (* M *) (* 16, sel 0: Config0 *)
- : 0b000000000000000 (* Impl *)
- : 0b1 (* BE *)
- : 0b10 (* AT *)
- : 0b000 (* AR *)
- : 0b001 (* MT standard TLB *)
- : 0b0000 (* zero *)
- : 0b000)
- case (0b10000,0b001) -> EXTZ( (* 16, sel 1: Config1 *)
- 0b1 (* M *)
- : TLBIndexMax (* MMU size-1 *)
- : 0b000 (* IS icache sets *)
- : 0b000 (* IL icache lines *)
- : 0b000 (* IA icache assoc. *)
- : 0b000 (* DS dcache sets *)
- : 0b000 (* DL dcache lines *)
- : 0b000 (* DA dcache assoc. *)
- : [have_cp2] (* C2 CP2 presence *)
- : 0b0 (* MD MDMX implemented *)
- : 0b0 (* PC performance counters *)
- : 0b0 (* WR watch registers *)
- : 0b0 (* CA 16e code compression *)
- : 0b0 (* EP EJTAG *)
- : 0b0) (* FP FPU present *)
- case (0b10000,0b010) -> EXTZ( (* 16, sel 2: Config2 *)
- 0b1 (* M *)
- : 0b000 (* TU L3 control *)
- : 0b0000 (* TS L3 sets *)
- : 0b0000 (* TL L3 lines *)
- : 0b0000 (* TA L3 assoc. *)
- : 0b0000 (* SU L2 control *)
- : 0b0000 (* SS L2 sets *)
- : 0b0000 (* SL L2 lines *)
- : 0b0000) (* SA L2 assoc. *)
- case (0b10000,0b011) -> 0x0000000000002000 (* 16, sel 3: Config3 zero except for bit 13 == ulri *)
- case (0b10000,0b101) -> 0x0000000000000000 (* 16, sel 5: Config5 beri specific -- no extended TLB *)
- case (0b10001,0b000) -> CP0LLAddr (* 17, sel 0: LLAddr *)
- case (0b10010,0b000) -> 0 (* 18, WatchLo *)
- case (0b10011,0b000) -> 0 (* 19, WatchHi *)
- case (0b10100,0b000) -> TLBXContext (* 20, XContext *)
- case (0b11110,0b000) -> CP0ErrorEPC (* 30, ErrorEPC *)
- case _ -> (SignalException(ResI))
- } in
- wGPR(rt) := if (double) then result else EXTS(result[31..0])
-}
-
-(* simulator halt instruction "MTC0 rt, r23" (cheri specific behaviour) *)
-union ast member unit HCF
-function clause decode (0b010000 : 0b00100 : (regno) rt : 0b10111 : 0b00000000000) =
- Some(HCF())
-
-function clause decode (0b010000 : 0b00100 : (regno) rt : 0b11010 : 0b00000000000) =
- Some(HCF())
-
-function clause execute (HCF) =
- () (* halt instruction actually executed by interpreter framework *)
-
-union ast member (regno, regno, bit[3], bool) MTC0
-function clause decode (0b010000 : 0b00100 : (regno) rt : (regno) rd : 0b00000000 : (bit[3]) sel) =
- Some(MTC0(rt, rd, sel, false)) (* MTC0 *)
-function clause decode (0b010000 : 0b00101 : (regno) rt : (regno) rd : 0b00000000 : (bit[3]) sel) =
- Some(MTC0(rt, rd, sel, true)) (* DMTC0 *)
-function clause execute (MTC0(rt, rd, sel, double)) = {
- checkCP0Access();
- let reg_val = (rGPR(rt)) in
- switch (rd, sel)
- {
- case (0b00000,0b000) -> TLBIndex := mask(reg_val) (* NB no write to TLBProbe *)
- case (0b00001,0b000) -> () (* TLBRandom is read only *)
- case (0b00010,0b000) -> TLBEntryLo0 := reg_val
- case (0b00011,0b000) -> TLBEntryLo1 := reg_val
- case (0b00100,0b000) -> (TLBContext.PTEBase) := (reg_val[63..23])
- case (0b00100,0b010) -> CP0UserLocal := reg_val
- case (0b00101,0b000) -> TLBPageMask := (reg_val[28..13])
- case (0b00110,0b000) -> {
- TLBWired := mask(reg_val);
- TLBRandom := TLBIndexMax;
- }
- case (0b00111,0b000) -> CP0HWREna := (reg_val[31..29] : 0b0000000000000000000000000 : reg_val[3..0])
- case (0b01000,0b000) -> () (* BadVAddr read only *)
- case (0b01001,0b000) -> CP0Count := reg_val[31..0]
- case (0b01010,0b000) -> {
- (TLBEntryHi.R) := (reg_val[63..62]);
- (TLBEntryHi.VPN2) := (reg_val[39..13]);
- (TLBEntryHi.ASID) := (reg_val[7..0]);
- }
- case (0b01011,0b000) -> { (* 11, sel 0: Compare reg *)
- CP0Compare := reg_val[31..0];
- (CP0Cause[15]) := bitzero;
- }
- case (0b01100,0b000) -> { (* 12 Status *)
- (CP0Status.CU) := reg_val[31..28];
- (CP0Status.BEV) := reg_val[22];
- (CP0Status.IM) := reg_val[15..8];
- (CP0Status.KX) := reg_val[7];
- (CP0Status.SX) := reg_val[6];
- (CP0Status.UX) := reg_val[5];
- (CP0Status.KSU) := reg_val[4..3];
- (CP0Status.ERL) := reg_val[2];
- (CP0Status.EXL) := reg_val[1];
- (CP0Status.IE) := reg_val[0];
- }
- case (0b01101,0b000) -> { (* 13 Cause *)
- CP0Cause.IV := reg_val[23]; (* TODO special interrupt vector not implemeneted *)
- let ip = (bit[8]) (CP0Cause.IP) in
- CP0Cause.IP := ((ip[7..2]) : (reg_val[9..8]));
- }
- case (0b01110,0b000) -> CP0EPC := reg_val (* 14, EPC *)
- case (0b10000,0b000) -> () (* XXX ignore K0 cache config 16: Config0 *)
- case (0b10100,0b000) -> (TLBXContext.PTEBase) := (reg_val[63..33])
- case (0b11110,0b000) -> CP0ErrorEPC := reg_val (* 30, ErrorEPC *)
- case _ -> (SignalException(ResI))
- }
-}
-
-function unit TLBWriteEntry((TLBIndexT) idx) = {
- pagemask := EXTZ(TLBPageMask); (* XXX EXTZ here forces register read in ocaml shallow embedding *)
- switch(pagemask) {
- case 0x0000 -> ()
- case 0x0003 -> ()
- case 0x000f -> ()
- case 0x003f -> ()
- case 0x00ff -> ()
- case 0x03ff -> ()
- case 0x0fff -> ()
- case 0x3fff -> ()
- case 0xffff -> ()
- case _ -> (SignalException(MCheck))
- };
- ((TLBEntries[idx]).pagemask) := pagemask;
- ((TLBEntries[idx]).r ) := TLBEntryHi.R;
- ((TLBEntries[idx]).vpn2 ) := TLBEntryHi.VPN2;
- ((TLBEntries[idx]).asid ) := TLBEntryHi.ASID;
- ((TLBEntries[idx]).g ) := ((TLBEntryLo0.G) & (TLBEntryLo1.G));
- ((TLBEntries[idx]).valid ) := bitone;
- ((TLBEntries[idx]).caps0 ) := TLBEntryLo0.CapS;
- ((TLBEntries[idx]).capl0 ) := TLBEntryLo0.CapL;
- ((TLBEntries[idx]).pfn0 ) := TLBEntryLo0.PFN;
- ((TLBEntries[idx]).c0 ) := TLBEntryLo0.C;
- ((TLBEntries[idx]).d0 ) := TLBEntryLo0.D;
- ((TLBEntries[idx]).v0 ) := TLBEntryLo0.V;
- ((TLBEntries[idx]).caps1 ) := TLBEntryLo1.CapS;
- ((TLBEntries[idx]).capl1 ) := TLBEntryLo1.CapL;
- ((TLBEntries[idx]).pfn1 ) := TLBEntryLo1.PFN;
- ((TLBEntries[idx]).c1 ) := TLBEntryLo1.C;
- ((TLBEntries[idx]).d1 ) := TLBEntryLo1.D;
- ((TLBEntries[idx]).v1 ) := TLBEntryLo1.V;
-}
-
-union ast member TLBWI
-function clause decode (0b010000 : 0b10000000000000000000 : 0b000010) = Some(TLBWI)
-function clause execute (TLBWI) = {
- checkCP0Access();
- TLBWriteEntry(TLBIndex);
-}
-
-union ast member TLBWR
-function clause decode (0b010000 : 0b10000000000000000000 : 0b000110) = Some(TLBWR)
-function clause execute (TLBWR) = {
- checkCP0Access();
- TLBWriteEntry(TLBRandom);
-}
-
-union ast member TLBR
-function clause decode (0b010000 : 0b10000000000000000000 : 0b000001) = Some(TLBR)
-function clause execute (TLBR) = {
- checkCP0Access();
- let entry = TLBEntries[TLBIndex] in {
- TLBPageMask := entry.pagemask;
- TLBEntryHi.R := entry.r;
- TLBEntryHi.VPN2 := entry.vpn2;
- TLBEntryHi.ASID := entry.asid;
- TLBEntryLo0.CapS:= entry.caps0;
- TLBEntryLo0.CapL:= entry.capl0;
- TLBEntryLo0.PFN := entry.pfn0;
- TLBEntryLo0.C := entry.c0;
- TLBEntryLo0.D := entry.d0;
- TLBEntryLo0.V := entry.v0;
- TLBEntryLo0.G := entry.g;
- TLBEntryLo1.CapS:= entry.caps1;
- TLBEntryLo1.CapL:= entry.capl1;
- TLBEntryLo1.PFN := entry.pfn1;
- TLBEntryLo1.C := entry.c1;
- TLBEntryLo1.D := entry.d1;
- TLBEntryLo1.V := entry.v1;
- TLBEntryLo1.G := entry.g;
- }
-}
-
-union ast member TLBP
-function clause decode (0b010000 : 0b10000000000000000000 : 0b001000) = Some(TLBP)
-function clause execute ((TLBP)) = {
- checkCP0Access();
- let result = tlbSearch(TLBEntryHi) in
- switch(result) {
- case (Some(idx)) -> {
- TLBProbe := [bitzero];
- TLBIndex := idx;
- }
- case None -> {
- TLBProbe := [bitone];
- TLBIndex := 0;
- }
- }
-}
-
-union ast member (regno, regno) RDHWR
-function clause decode (0b011111 : 0b00000 : (regno) rt : (regno) rd : 0b00000 : 0b111011) =
- Some(RDHWR(rt, rd))
-function clause execute (RDHWR(rt, rd)) = {
- let accessLevel = getAccessLevel() in
- if ((accessLevel != Kernel) & (~((CP0Status.CU)[0])) & ~(CP0HWREna[rd])) then
- (SignalException(ResI));
- let (bit[64]) temp = switch (rd) {
- case 0b00000 -> EXTZ([bitzero]) (* CPUNum *)
- case 0b00001 -> EXTZ([bitzero]) (* SYNCI_step *)
- case 0b00010 -> EXTZ(CP0Count) (* Count *)
- case 0b00011 -> EXTZ([bitone]) (* Count resolution *)
- case 0b11101 -> CP0UserLocal (* User local register *)
- case _ -> (SignalException(ResI))
- } in
- wGPR(rt) := temp;
-}
-
-union ast member unit ERET
-function clause decode (0b010000 : 0b1 : 0b0000000000000000000 : 0b011000) =
- Some(ERET)
-function clause execute (ERET) =
- {
- checkCP0Access();
- ERETHook();
- CP0LLBit := 0b0;
- if (CP0Status.ERL == bitone) then
- {
- nextPC := CP0ErrorEPC;
- CP0Status.ERL := 0;
- }
- else
- {
- nextPC := CP0EPC;
- CP0Status.EXL := 0;
- }
- }
diff --git a/mips/mips_prelude.sail b/mips/mips_prelude.sail
deleted file mode 100644
index c3197eda..00000000
--- a/mips/mips_prelude.sail
+++ /dev/null
@@ -1,609 +0,0 @@
-(*========================================================================*)
-(* *)
-(* Copyright (c) 2015-2017 Robert M. Norton *)
-(* 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. *)
-(*========================================================================*)
-
-(* mips_prelude.sail: declarations of mips registers, and functions common
- to mips instructions (e.g. address translation) *)
-
-(* bit vectors have indices decreasing from left i.e. msb is highest index *)
-default Order dec
-
-register (bit[64]) PC
-register (bit[64]) nextPC
-
-(* CP0 Registers *)
-
-typedef CauseReg = register bits [ 31 : 0 ] {
- 31 : BD; (* branch delay *)
- (*30 : Z0;*)
- 29 .. 28 : CE; (* for coprocessor enable exception *)
- (*27 .. 24 : Z1;*)
- 23 : IV; (* special interrupt vector not supported *)
- 22 : WP; (* watchpoint exception occurred *)
- (*21 .. 16 : Z2; *)
- 15 .. 8 : IP; (* interrupt pending bits *)
- (*7 : Z3;*)
- 6 .. 2 : ExcCode; (* code of last exception *)
- (*1 .. 0 : Z4;*)
-}
-
-typedef TLBEntryLoReg = register bits [63 : 0] {
- 63 : CapS;
- 62 : CapL;
- 29 .. 6 : PFN;
- 5 .. 3 : C;
- 2 : D;
- 1 : V;
- 0 : G;
-}
-
-typedef TLBEntryHiReg = register bits [63 : 0] {
- 63 .. 62 : R;
- 39 .. 13 : VPN2;
- 7 .. 0 : ASID;
-}
-
-typedef ContextReg = register bits [63 : 0] {
- 63 .. 23 : PTEBase;
- 22 .. 4 : BadVPN2;
- (*3 .. 0 : ZR;*)
-}
-
-typedef XContextReg = register bits [63 : 0] {
- 63 .. 33: PTEBase;
- 32 .. 31: R;
- 30 .. 4: BadVPN2;
-}
-
-let ([:64:]) TLBNumEntries = 64
-typedef TLBIndexT = (bit[6])
-let (TLBIndexT) TLBIndexMax = 0b111111
-
-let MAX_U64 = unsigned(0xffffffffffffffff)
-let MAX_VA = unsigned(0xffffffffff)
-let MAX_PA = unsigned(0xfffffffff)
-
-typedef TLBEntry = register bits [116 : 0] {
- 116 .. 101: pagemask;
- 100 .. 99 : r ;
- 98 .. 72 : vpn2 ;
- 71 .. 64 : asid ;
- 63 : g ;
- 62 : valid ;
- 61 : caps1 ;
- 60 : capl1 ;
- 59 .. 36 : pfn1 ;
- 35 .. 33 : c1 ;
- 32 : d1 ;
- 31 : v1 ;
- 30 : caps0 ;
- 29 : capl0 ;
- 28 .. 5 : pfn0 ;
- 4 .. 2 : c0 ;
- 1 : d0 ;
- 0 : v0 ;
-}
-
-register (bit[1]) TLBProbe
-register (TLBIndexT) TLBIndex
-register (TLBIndexT) TLBRandom
-register (TLBEntryLoReg) TLBEntryLo0
-register (TLBEntryLoReg) TLBEntryLo1
-register (ContextReg) TLBContext
-register (bit[16]) TLBPageMask
-register (TLBIndexT) TLBWired
-register (TLBEntryHiReg) TLBEntryHi
-register (XContextReg) TLBXContext
-
-register (TLBEntry) TLBEntry00
-register (TLBEntry) TLBEntry01
-register (TLBEntry) TLBEntry02
-register (TLBEntry) TLBEntry03
-register (TLBEntry) TLBEntry04
-register (TLBEntry) TLBEntry05
-register (TLBEntry) TLBEntry06
-register (TLBEntry) TLBEntry07
-register (TLBEntry) TLBEntry08
-register (TLBEntry) TLBEntry09
-register (TLBEntry) TLBEntry10
-register (TLBEntry) TLBEntry11
-register (TLBEntry) TLBEntry12
-register (TLBEntry) TLBEntry13
-register (TLBEntry) TLBEntry14
-register (TLBEntry) TLBEntry15
-register (TLBEntry) TLBEntry16
-register (TLBEntry) TLBEntry17
-register (TLBEntry) TLBEntry18
-register (TLBEntry) TLBEntry19
-register (TLBEntry) TLBEntry20
-register (TLBEntry) TLBEntry21
-register (TLBEntry) TLBEntry22
-register (TLBEntry) TLBEntry23
-register (TLBEntry) TLBEntry24
-register (TLBEntry) TLBEntry25
-register (TLBEntry) TLBEntry26
-register (TLBEntry) TLBEntry27
-register (TLBEntry) TLBEntry28
-register (TLBEntry) TLBEntry29
-register (TLBEntry) TLBEntry30
-register (TLBEntry) TLBEntry31
-register (TLBEntry) TLBEntry32
-register (TLBEntry) TLBEntry33
-register (TLBEntry) TLBEntry34
-register (TLBEntry) TLBEntry35
-register (TLBEntry) TLBEntry36
-register (TLBEntry) TLBEntry37
-register (TLBEntry) TLBEntry38
-register (TLBEntry) TLBEntry39
-register (TLBEntry) TLBEntry40
-register (TLBEntry) TLBEntry41
-register (TLBEntry) TLBEntry42
-register (TLBEntry) TLBEntry43
-register (TLBEntry) TLBEntry44
-register (TLBEntry) TLBEntry45
-register (TLBEntry) TLBEntry46
-register (TLBEntry) TLBEntry47
-register (TLBEntry) TLBEntry48
-register (TLBEntry) TLBEntry49
-register (TLBEntry) TLBEntry50
-register (TLBEntry) TLBEntry51
-register (TLBEntry) TLBEntry52
-register (TLBEntry) TLBEntry53
-register (TLBEntry) TLBEntry54
-register (TLBEntry) TLBEntry55
-register (TLBEntry) TLBEntry56
-register (TLBEntry) TLBEntry57
-register (TLBEntry) TLBEntry58
-register (TLBEntry) TLBEntry59
-register (TLBEntry) TLBEntry60
-register (TLBEntry) TLBEntry61
-register (TLBEntry) TLBEntry62
-register (TLBEntry) TLBEntry63
-
-let (vector <0, 64, inc, (TLBEntry)>) TLBEntries = [
-TLBEntry00,
-TLBEntry01,
-TLBEntry02,
-TLBEntry03,
-TLBEntry04,
-TLBEntry05,
-TLBEntry06,
-TLBEntry07,
-TLBEntry08,
-TLBEntry09,
-TLBEntry10,
-TLBEntry11,
-TLBEntry12,
-TLBEntry13,
-TLBEntry14,
-TLBEntry15,
-TLBEntry16,
-TLBEntry17,
-TLBEntry18,
-TLBEntry19,
-TLBEntry20,
-TLBEntry21,
-TLBEntry22,
-TLBEntry23,
-TLBEntry24,
-TLBEntry25,
-TLBEntry26,
-TLBEntry27,
-TLBEntry28,
-TLBEntry29,
-TLBEntry30,
-TLBEntry31,
-TLBEntry32,
-TLBEntry33,
-TLBEntry34,
-TLBEntry35,
-TLBEntry36,
-TLBEntry37,
-TLBEntry38,
-TLBEntry39,
-TLBEntry40,
-TLBEntry41,
-TLBEntry42,
-TLBEntry43,
-TLBEntry44,
-TLBEntry45,
-TLBEntry46,
-TLBEntry47,
-TLBEntry48,
-TLBEntry49,
-TLBEntry50,
-TLBEntry51,
-TLBEntry52,
-TLBEntry53,
-TLBEntry54,
-TLBEntry55,
-TLBEntry56,
-TLBEntry57,
-TLBEntry58,
-TLBEntry59,
-TLBEntry60,
-TLBEntry61,
-TLBEntry62,
-TLBEntry63
-]
-
-register (bit[32]) CP0Compare
-register (CauseReg) CP0Cause
-register (bit[64]) CP0EPC
-register (bit[64]) CP0ErrorEPC
-register (bit[1]) CP0LLBit
-register (bit[64]) CP0LLAddr
-register (bit[64]) CP0BadVAddr
-register (bit[32]) CP0Count
-register (bit[32]) CP0HWREna
-register (bit[64]) CP0UserLocal
-
-typedef StatusReg = register bits [31:0] {
- 31 .. 28 : CU; (* co-processor enable bits *)
- (* RP/FR/RE/MX/PX not implemented *)
- 22 : BEV; (* use boot exception vectors (initialised to one) *)
- (* TS/SR/NMI not implemented *)
- 15 .. 8 : IM; (* Interrupt mask *)
- 7 : KX; (* kernel 64-bit enable *)
- 6 : SX; (* supervisor 64-bit enable *)
- 5 : UX; (* user 64-bit enable *)
- 4 .. 3 : KSU; (* Processor mode *)
- 2 : ERL; (* error level (should be initialised to one, but BERI is different) *)
- 1 : EXL; (* exception level *)
- 0 : IE; (* interrupt enable *)
-}
-register (StatusReg) CP0Status
-
-(* Implementation registers -- not ISA defined *)
-register (bit[1]) branchPending (* Set by branch instructions to implement branch delay *)
-register (bit[1]) inBranchDelay (* Needs to be set by outside world when in branch delay slot *)
-register (bit[64]) delayedPC (* Set by branch instructions to implement branch delay *)
-
-(* General purpose registers *)
-
-register (bit[64]) GPR00 (* should never be read or written *)
-register (bit[64]) GPR01
-register (bit[64]) GPR02
-register (bit[64]) GPR03
-register (bit[64]) GPR04
-register (bit[64]) GPR05
-register (bit[64]) GPR06
-register (bit[64]) GPR07
-register (bit[64]) GPR08
-register (bit[64]) GPR09
-register (bit[64]) GPR10
-register (bit[64]) GPR11
-register (bit[64]) GPR12
-register (bit[64]) GPR13
-register (bit[64]) GPR14
-register (bit[64]) GPR15
-register (bit[64]) GPR16
-register (bit[64]) GPR17
-register (bit[64]) GPR18
-register (bit[64]) GPR19
-register (bit[64]) GPR20
-register (bit[64]) GPR21
-register (bit[64]) GPR22
-register (bit[64]) GPR23
-register (bit[64]) GPR24
-register (bit[64]) GPR25
-register (bit[64]) GPR26
-register (bit[64]) GPR27
-register (bit[64]) GPR28
-register (bit[64]) GPR29
-register (bit[64]) GPR30
-register (bit[64]) GPR31
-
-(* Special registers For MUL/DIV *)
-register (bit[64]) HI
-register (bit[64]) LO
-
-let (vector <0, 32, inc, (register<(bit[64])>) >) GPR =
- [ GPR00, GPR01, GPR02, GPR03, GPR04, GPR05, GPR06, GPR07, GPR08, GPR09, GPR10,
- GPR11, GPR12, GPR13, GPR14, GPR15, GPR16, GPR17, GPR18, GPR19, GPR20,
- GPR21, GPR22, GPR23, GPR24, GPR25, GPR26, GPR27, GPR28, GPR29, GPR30, GPR31
- ]
-
-(* JTAG Uart registers *)
-
-register (bit[8]) UART_WDATA
-register (bit[1]) UART_WRITTEN
-register (bit[8]) UART_RDATA
-register (bit[1]) UART_RVALID
-
-(* Check whether a given 64-bit vector is a properly sign extended 32-bit word *)
-val bit[64] -> bool effect pure NotWordVal
-function bool NotWordVal (word) =
- (word[31] ^^ 32) != word[63..32]
-
-(* Read numbered GP reg. (r0 is always zero) *)
-val bit[5] -> bit[64] effect {rreg} rGPR
-function bit[64] rGPR idx = {
- if idx == 0 then 0 else GPR[idx]
-}
-
-(* Write numbered GP reg. (writes to r0 ignored) *)
-val (bit[5], bit[64]) -> unit effect {wreg} wGPR
-function unit wGPR (idx, v) = {
- if idx == 0 then () else GPR[idx] := v
-}
-
-val extern forall Nat 'n. ( bit[64] , [|'n|] ) -> (bit[8 * 'n]) effect { rmem } MEMr
-val extern forall Nat 'n. ( bit[64] , [|'n|] ) -> (bit[8 * 'n]) effect { rmem } MEMr_reserve
-val extern unit -> unit effect { barr } MEM_sync
-
-val extern forall Nat 'n. ( bit[64] , [|'n|]) -> unit effect { eamem } MEMea
-val extern forall Nat 'n. ( bit[64] , [|'n|]) -> unit effect { eamem } MEMea_conditional
-val extern forall Nat 'n. ( bit[64] , [|'n|] , bit[8*'n]) -> unit effect { wmv } MEMval
-val extern forall Nat 'n. ( bit[64] , [|'n|] , bit[8*'n]) -> bool effect { wmv } MEMval_conditional
-
-typedef Exception = enumerate
-{
- Int; TLBMod; TLBL; TLBS; AdEL; AdES; Sys; Bp; ResI; CpU; Ov; Tr; C2E; C2Trap;
- XTLBRefillL; XTLBRefillS; XTLBInvL; XTLBInvS; MCheck
-}
-
-(* Return the ISA defined code for an exception condition *)
-function (bit[5]) ExceptionCode ((Exception) ex) =
- switch (ex)
- {
- case Int -> mask(0x00) (* Interrupt *)
- case TLBMod -> mask(0x01) (* TLB modification exception *)
- case TLBL -> mask(0x02) (* TLB exception (load or fetch) *)
- case TLBS -> mask(0x03) (* TLB exception (store) *)
- case AdEL -> mask(0x04) (* Address error (load or fetch) *)
- case AdES -> mask(0x05) (* Address error (store) *)
- case Sys -> mask(0x08) (* Syscall *)
- case Bp -> mask(0x09) (* Breakpoint *)
- case ResI -> mask(0x0a) (* Reserved instruction *)
- case CpU -> mask(0x0b) (* Coprocessor Unusable *)
- case Ov -> mask(0x0c) (* Arithmetic overflow *)
- case Tr -> mask(0x0d) (* Trap *)
- case C2E -> mask(0x12) (* C2E coprocessor 2 exception *)
- case C2Trap -> mask(0x12) (* C2Trap maps to same exception code, different vector *)
- case XTLBRefillL -> mask(0x02)
- case XTLBRefillS -> mask(0x03)
- case XTLBInvL -> mask(0x02)
- case XTLBInvS -> mask(0x03)
- case MCheck -> mask(0x18)
- }
-
-
-
-function forall Type 'o. 'o SignalExceptionMIPS ((Exception) ex, (bit[64]) kccBase) =
- {
- (* Only update EPC and BD if not already in EXL mode *)
- if (~ (CP0Status.EXL)) then
- {
- if (inBranchDelay[0]) then
- {
- CP0EPC := PC - 4;
- CP0Cause.BD := 1;
- }
- else
- {
- CP0EPC := PC;
- CP0Cause.BD := 0;
- }
- };
-
- (* choose an exception vector to branch to. Some are not supported
- e.g. Reset *)
- vectorOffset :=
- if (CP0Status.EXL) then
- 0x180 (* Always use common vector if in exception mode already *)
- else if ((ex == XTLBRefillL) | (ex == XTLBRefillS)) then
- 0x080
- else if (ex == C2Trap) then
- 0x280 (* Special vector for CHERI traps *)
- else
- 0x180; (* Common vector *)
- (bit[64]) vectorBase := if CP0Status.BEV then
- 0xFFFFFFFFBFC00200
- else
- 0xFFFFFFFF80000000;
- (* On CHERI we have to subtract KCC.base so that we end up at the
- right absolute vector address after indirecting via new PCC *)
- nextPC := ((bit[64])(vectorBase + EXTS(vectorOffset))) - kccBase;
- CP0Cause.ExcCode := ExceptionCode(ex);
- CP0Status.EXL := 1;
- exit ();
- }
-
-val forall Type 'o . Exception -> 'o effect {escape, rreg, wreg} SignalException
-
-function forall Type 'o. 'o SignalExceptionBadAddr((Exception) ex, (bit[64]) badAddr) =
- {
- CP0BadVAddr := badAddr;
- SignalException(ex);
- }
-
-function forall Type 'o. 'o SignalExceptionTLB((Exception) ex, (bit[64]) badAddr) = {
- CP0BadVAddr := badAddr;
- (TLBContext.BadVPN2) := (badAddr[31..13]);
- (TLBXContext.BadVPN2):= (badAddr[39..13]);
- (TLBXContext.R) := (badAddr[63..62]);
- (TLBEntryHi.R) := (badAddr[63..62]);
- (TLBEntryHi.VPN2) := (badAddr[39..13]);
- SignalException(ex);
-}
-
-typedef MemAccessType = enumerate {Instruction; LoadData; StoreData}
-typedef AccessLevel = enumerate {User; Supervisor; Kernel}
-
-function AccessLevel getAccessLevel() =
- if ((CP0Status.EXL) | (CP0Status.ERL)) then
- Kernel
- else switch (CP0Status.KSU)
- {
- case 0b00 -> Kernel
- case 0b01 -> Supervisor
- case 0b10 -> User
- case _ -> User (* behaviour undefined, assume user *)
- }
-
-function ([|2|]) int_of_accessLevel((AccessLevel)x) =
- switch (x) {
- case User -> 0
- case Supervisor -> 1
- case Kernel -> 2
- }
-
-function unit checkCP0Access () =
- {
- let accessLevel = getAccessLevel() in
- if ((accessLevel != Kernel) & (~(CP0Status[28] (*CU0*)))) then
- {
- (CP0Cause.CE) := 0b00;
- SignalException(CpU);
- }
- }
-
-function unit incrementCP0Count() = {
- TLBRandom := (if (TLBRandom == TLBWired)
- then (TLBIndexMax) else (TLBRandom - 1));
-
- CP0Count := (CP0Count + 1);
- if (CP0Count == CP0Compare) then {
- (CP0Cause[15]) := bitone; (* XXX indexing IP field here doesn't seem to work *)
- };
-
- let (bit[8]) ims = CP0Status.IM in
- let (bit[8]) ips = CP0Cause.IP in
- let ie = CP0Status.IE in
- let exl = CP0Status.EXL in
- let erl = CP0Status.ERL in
- if ((~(exl)) & (~(erl)) & ie & ((ips & ims) != 0x00)) then
- SignalException(Int);
-}
-
-typedef regno = bit[5] (* a register number *)
-typedef imm16 = bit[16] (* 16-bit immediate *)
-(* a commonly used instruction format with three register operands *)
-typedef regregreg = (regno, regno, regno)
-(* a commonly used instruction format with two register operands and 16-bit immediate *)
-typedef regregimm16 = (regno, regno, imm16)
-
-typedef decode_failure = enumerate {
- no_matching_pattern;
- unsupported_instruction;
- illegal_instruction;
- internal_error
-}
-
-(* Used by branch and trap instructions *)
-typedef Comparison = enumerate {
- EQ; (* equal *)
- NE; (* not equal *)
- GE; (* signed greater than or equal *)
- GEU;(* unsigned greater than or equal *)
- GT; (* signed strictly greater than *)
- LE; (* signed less than or equal *)
- LT; (* signed strictly less than *)
- LTU;(* unsigned less than or qual *)
-}
-function bool compare ((Comparison)cmp, (bit[64]) valA, (bit[64]) valB) =
- (* sail comparisons are signed so extend to 65 bits for unsigned comparisons *)
- let valA65 = (0b0 : valA) in
- let valB65 = (0b0 : valB) in
- switch(cmp) {
- case EQ -> valA == valB
- case NE -> valA != valB
- case GE -> valA >= valB
- case GEU -> valA65 >= valB65
- case GT -> valA > valB
- case LE -> valA <= valB
- case LT -> valA < valB
- case LTU -> valA65 < valB65
- }
-typedef WordType = enumerate { B; H; W; D}
-
-function forall Nat 'r, 'r IN {1,2,4,8}.[:'r:] wordWidthBytes((WordType) w) =
- switch(w) {
- case B -> 1
- case H -> 2
- case W -> 4
- case D -> 8
- }
-
-
-(* This function checks that memory accesses are naturally aligned
- -- it is disabled in favour of BERI specific behaviour below.
-function bool isAddressAligned(addr, (WordType) wordType) =
- switch (wordType) {
- case B -> true
- case H -> (addr[0] == 0)
- case W -> (addr[1..0] == 0b00)
- case D -> (addr[2..0] == 0b000)
- }
-*)
-
-(* BERI relaxes the natural alignment requirement for loads and stores
- but still throws an exception if an access spans a cache line
- boundary. Here we assume this is 32 bytes so that we don't have to
- worry about clearing multiple tags when an access spans more than
- one capability. Capability load/stores are still naturally
- aligned. Provided this is a factor of smallest supported page size
- (4k) we don't need to worry about accesses spanning page boundaries
- either.
-*)
-let alignment_width = 16
-function (bool) isAddressAligned (addr, (WordType) wordType) =
- let a = unsigned(addr) in
- ((a quot alignment_width) == (a + wordWidthBytes(wordType) - 1) quot alignment_width)
-
-val forall Nat 'W. bit[8 * 'W] -> bit[8 * 'W] effect pure reverse_endianness
-function rec forall Nat 'W . bit[8 * 'W] reverse_endianness ((bit[8 * 'W]) value) =
-{
- (nat) width := length(value);
- if width <= 8 then value
- else value[7..0] : reverse_endianness(value[(width - 1) .. 8])
-}
-
-function forall Nat 'n. (bit[8 * 'n]) effect { rmem } MEMr_wrapper ((bit[64]) addr, ([:'n:]) size) =
- if (addr == 0x000000007f000000) then
- {
- let rvalid = (bit[1]) UART_RVALID in
- let rdata = mask(0x00000000 : UART_RDATA : [rvalid] : 0b0000000 : 0x0000) in
- {
- UART_RVALID := [bitzero];
- rdata
- }
- }
- else if (addr == 0x000000007f000004) then
- mask(0x000000000004ffff) (* Always plenty of write space available and jtag activity *)
- else
- reverse_endianness(MEMr(addr, size)) (* MEMr assumes little endian *)
-
-function forall Nat 'n. (bit[8 * 'n]) effect { rmem } MEMr_reserve_wrapper ((bit[64]) addr , ([:'n:]) size) =
- reverse_endianness(MEMr_reserve(addr, size))
diff --git a/mips/mips_regfp.sail b/mips/mips_regfp.sail
deleted file mode 100644
index 13165f67..00000000
--- a/mips/mips_regfp.sail
+++ /dev/null
@@ -1,451 +0,0 @@
-(*========================================================================*)
-(* *)
-(* Copyright (c) 2015-2017 Robert M. Norton *)
-(* 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. *)
-(*========================================================================*)
-
-let (vector <0, 32, inc, string >) GPRs =
- [ "GPR00", "GPR01", "GPR02", "GPR03", "GPR04", "GPR05", "GPR06", "GPR07", "GPR08", "GPR09", "GPR10",
- "GPR11", "GPR12", "GPR13", "GPR14", "GPR15", "GPR16", "GPR17", "GPR18", "GPR19", "GPR20",
- "GPR21", "GPR22", "GPR23", "GPR24", "GPR25", "GPR26", "GPR27", "GPR28", "GPR29", "GPR30", "GPR31"
- ]
-
-let CIA_fp = RFull("CIA")
-let NIA_fp = RFull("NIA")
-
-function (regfps,regfps,regfps,niafps,diafp,instruction_kind) initial_analysis (instr) = {
- iR := [|| ||];
- oR := [|| ||];
- aR := [|| ||];
- ik := IK_simple;
- Nias := [|| ||];
- Dia := DIAFP_none;
-
- switch instr {
- case (DADDIU (rs, rt, imm)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else oR := RFull(GPRs[rt]) :: oR;
- }
- case (DADDU (rs, rt, rd)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (DADDI (rs, rt, imm)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else oR := RFull(GPRs[rt]) :: oR;
- }
- case (DADD (rs, rt, rd)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else oR := RFull(GPRs[rt]) :: oR;
- }
- case (ADD(rs, rt, rd)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (ADDI(rs, rt, imm)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else oR := RFull(GPRs[rt]) :: oR;
- }
- case (ADDU(rs, rt, rd)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (ADDIU(rs, rt, imm)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else oR := RFull(GPRs[rt]) :: oR;
- }
- case (DSUBU (rs, rt, rd)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (DSUB (rs, rt, rd)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (SUB(rs, rt, rd)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (SUBU(rs, rt, rd)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (AND (rs, rt, rd)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (ANDI (rs, rt, imm)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else oR := RFull(GPRs[rt]) :: oR;
- }
- case (OR (rs, rt, rd)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (ORI (rs, rt, imm)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else oR := RFull(GPRs[rt]) :: oR;
- }
- case (NOR (rs, rt, rd)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (XOR (rs, rt, rd)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (XORI (rs, rt, imm)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else oR := RFull(GPRs[rt]) :: oR;
- }
- case (LUI (rt, imm)) -> {
- if rt == 0 then () else oR := RFull(GPRs[rt]) :: oR;
- }
- case (DSLL (rt, rd, sa)) -> {
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (DSLL32 (rt, rd, sa)) -> {
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (DSLLV (rs, rt, rd)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (DSRA (rt, rd, sa)) -> {
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (DSRA32 (rt, rd, sa)) -> {
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (DSRAV (rs, rt, rd)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (DSRL (rt, rd, sa)) -> {
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (DSRL32 (rt, rd, sa)) -> {
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (DSRLV (rs, rt, rd)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (SLL(rt, rd, sa)) -> {
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (SLLV(rs, rt, rd)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (SRA(rt, rd, sa)) -> {
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (SRAV(rs, rt, rd)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (SRL(rt, rd, sa)) -> {
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (SRLV(rs, rt, rd)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (SLT(rs, rt, rd)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (SLTI(rs, rt, imm)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else oR := RFull(GPRs[rt]) :: oR;
- }
- case (SLTU(rs, rt, rd)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (SLTIU(rs, rt, imm)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else oR := RFull(GPRs[rt]) :: oR;
- }
- case (MOVN(rs, rt, rd)) -> {
- (* XXX don't always write rd *)
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (MOVZ(rs, rt, rd)) -> {
- (* XXX don't always write rd *)
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (MFHI(rd)) -> {
- iR := RFull("HI") :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (MFLO(rd)) -> {
- iR := RFull("LO") :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (MTHI(rs)) -> {
- oR := RFull("HI") :: oR;
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- }
- case (MTLO(rs)) -> {
- oR := RFull("LO") :: oR;
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- }
- case (MUL(rs, rt, rd)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- if rd == 0 then () else oR := RFull(GPRs[rd]) :: oR;
- }
- case (MULT(rs, rt)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- oR := RFull("HI") :: RFull ("LO") :: oR;
- }
- case (MULTU(rs, rt)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- oR := RFull("HI") :: RFull ("LO") :: oR;
- }
- case (DMULT(rs, rt)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- oR := RFull("HI") :: RFull ("LO") :: oR;
- }
- case (DMULTU(rs, rt)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- oR := RFull("HI") :: RFull ("LO") :: oR;
- }
- case (MADD(rs, rt)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- iR := RFull("HI") :: RFull ("LO") :: iR;
- oR := RFull("HI") :: RFull ("LO") :: oR;
- }
- case (MADDU(rs, rt)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- iR := RFull("HI") :: RFull ("LO") :: iR;
- oR := RFull("HI") :: RFull ("LO") :: oR;
- }
- case (MSUB(rs, rt)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- iR := RFull("HI") :: RFull ("LO") :: iR;
- oR := RFull("HI") :: RFull ("LO") :: oR;
- }
- case (MSUBU(rs, rt)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- iR := RFull("HI") :: RFull ("LO") :: iR;
- oR := RFull("HI") :: RFull ("LO") :: oR;
- }
- case (DIV(rs, rt)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- oR := RFull("HI") :: RFull ("LO") :: oR;
- }
- case (DIVU(rs, rt)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- oR := RFull("HI") :: RFull ("LO") :: oR;
- }
- case (DDIV(rs, rt)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- oR := RFull("HI") :: RFull ("LO") :: oR;
- }
- case (DDIVU(rs, rt)) -> {
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- oR := RFull("HI") :: RFull ("LO") :: oR;
- }
- case (J(offset)) -> {
- ik := IK_branch;
- Dia := DIAFP_concrete((PC + 4)[63..28] : offset : 0b00);
- }
- case (JAL(offset)) -> {
- ik := IK_branch;
- oR := RFull("GPR31") :: oR;
- Dia := DIAFP_concrete((PC + 4)[63..28] : offset : 0b00);
- }
- case (JR(rs)) -> {
- ik := IK_branch;
- iR := RFull(GPRs[rs]) :: iR;
- Dia := DIAFP_reg(RFull(GPRs[rs]));
- }
- case (JALR(rs, rd)) -> {
- ik := IK_branch;
- iR := RFull(GPRs[rs]) :: iR;
- oR := RFull("GPR31") :: oR;
- Dia := DIAFP_reg(RFull(GPRs[rs]));
- }
- case (BEQ(rs, rd, imm, ne, likely)) -> {
- ik := IK_branch;
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if rd == 0 then () else iR := RFull(GPRs[rd]) :: iR;
- let (bit[64]) offset = (EXTS(imm : 0b00) + 4) in
- Dia := DIAFP_concrete (PC + offset);
- }
- case (BCMPZ(rs, imm, cmp, link, likely)) -> {
- ik := IK_branch;
- if rs == 0 then () else iR := RFull(GPRs[rs]) :: iR;
- if link then
- oR := RFull("GPR31") :: oR;
- let (bit[64]) offset = (EXTS(imm : 0b00) + 4) in
- Dia := DIAFP_concrete (PC + offset);
- }
- case (SYSCALL_THREAD_START) -> ()
-(*
-
- case (SYSCALL) =
- case (BREAK) =
- case (WAIT) = {
- case (TRAPREG(rs, rt, cmp)) =
- case (TRAPIMM(rs, imm, cmp)) =
-*)
- case (Load(width, signed, linked, base, rt, offset)) -> {
- ik := IK_mem_read (if linked then Read_reserve else Read_plain);
- if linked then oR := RFull("CP0LLBit")::RFull("CP0LLAddr")::oR else ();
- if base == 0 then () else aR := RFull(GPRs[base]) :: aR;
- iR := aR;
- if rt == 0 then () else oR := RFull(GPRs[rt]) :: oR;
- }
- case (Store(width, conditional, base, rt, offset)) -> {
- ik := IK_mem_write(if conditional then Write_conditional else Write_plain);
- if base == 0 then () else aR := RFull(GPRs[base]) :: aR;
- iR := aR;
- if conditional then iR := RFull("CP0LLBit")::iR else ();
- if (conditional & (rt != 0)) then oR := RFull(GPRs[rt])::oR else ();
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- }
- case (LWL(base, rt, offset)) -> {
- ik := IK_mem_read(Read_plain);
- if base == 0 then () else aR := RFull(GPRs[base]) :: aR;
- iR := aR;
- if rt == 0 then () else oR := RFull(GPRs[rt]) :: oR;
- }
- case (LWR(base, rt, offset)) -> {
- ik := IK_mem_read(Read_plain);
- if base == 0 then () else aR := RFull(GPRs[base]) :: aR;
- iR := aR;
- if rt == 0 then () else oR := RFull(GPRs[rt]) :: oR;
- }
- case (SWL(base, rt, offset)) -> {
- ik := IK_mem_write(Write_plain);
- if base == 0 then () else aR := RFull(GPRs[base]) :: aR;
- iR := aR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- }
- case (SWR(base, rt, offset)) -> {
- ik := IK_mem_write(Write_plain);
- if base == 0 then () else aR := RFull(GPRs[base]) :: aR;
- iR := aR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- }
- case (LDL(base, rt, offset)) -> {
- ik := IK_mem_read(Read_plain);
- if base == 0 then () else aR := RFull(GPRs[base]) :: aR;
- iR := aR;
- if rt == 0 then () else oR := RFull(GPRs[rt]) :: oR;
- }
- case (LDR(base, rt, offset)) -> {
- ik := IK_mem_read(Read_plain);
- if base == 0 then () else aR := RFull(GPRs[base]) :: aR;
- iR := aR;
- if rt == 0 then () else oR := RFull(GPRs[rt]) :: oR;
- }
- case (SDL(base, rt, offset)) -> {
- ik := IK_mem_write(Write_plain);
- if base == 0 then () else aR := RFull(GPRs[base]) :: aR;
- iR := aR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- }
- case (SDR(base, rt, offset)) -> {
- ik := IK_mem_write(Write_plain);
- if base == 0 then () else aR := RFull(GPRs[base]) :: aR;
- iR := aR;
- if rt == 0 then () else iR := RFull(GPRs[rt]) :: iR;
- }
-(*
- case (CACHE(base, op, imm)) =
- case (PREF(base, op, imm)) =
-*)
- case (SYNC) -> {
- iK := IK_barrier(Barrier_MIPS_SYNC);
- }
-(*
- case (MFC0(rt, rd, sel, double))
- case (HCF)
- case (MTC0(rt, rd, sel, double))
- case (TLBWI)
- case (TLBWR)
- case (TLBR)
- case ((TLBP))
- case (RDHWR(rt, rd))
- case (ERET)
-*)
- };
- (iR,oR,aR,Nias,Dia,ik)
-}
diff --git a/mips/mips_ri.sail b/mips/mips_ri.sail
deleted file mode 100644
index 3f368111..00000000
--- a/mips/mips_ri.sail
+++ /dev/null
@@ -1,42 +0,0 @@
-(*========================================================================*)
-(* *)
-(* Copyright (c) 2015-2017 Robert M. Norton *)
-(* 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. *)
-(*========================================================================*)
-
-(* mips_ri.sail: only use if want unknown instructions to throw
- exception (like real hardware) instead of die (convenient for ppcmem) *)
-
-union ast member unit RI
-function clause decode _ = Some(RI)
-function clause execute (RI) =
- SignalException (ResI)
-
diff --git a/mips/mips_tlb.sail b/mips/mips_tlb.sail
deleted file mode 100644
index d72e0e75..00000000
--- a/mips/mips_tlb.sail
+++ /dev/null
@@ -1,128 +0,0 @@
-(*========================================================================*)
-(* *)
-(* Copyright (c) 2015-2017 Robert M. Norton *)
-(* 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 bool tlbEntryMatch(r, vpn2, asid, (TLBEntry) entry) =
- let entryValid = entry.valid in
- let entryR = entry.r in
- let entryMask = entry.pagemask in
- let entryVPN = entry.vpn2 in
- let entryASID = entry.asid in
- let entryG = entry.g in
- (entryValid &
- (r == entryR) &
- ((vpn2 & ~(EXTZ(entryMask))) == ((entryVPN) & ~(EXTZ(entryMask)))) &
- ((asid == (entryASID)) | (entryG)))
-
-function option<TLBIndexT> tlbSearch((bit[64]) VAddr) =
- let r = (VAddr[63..62]) in
- let vpn2 = (VAddr[39..13]) in
- let asid = TLBEntryHi.ASID in {
- foreach (idx from 0 to 63) {
- if(tlbEntryMatch(r, vpn2, asid, (TLBEntries[idx]))) then
- return (Some ((TLBIndexT) idx))
- };
- None
- }
-
-function (bit[64], bool) TLBTranslate2 ((bit[64]) vAddr, (MemAccessType) accessType) = {
- let idx = tlbSearch(vAddr) in
- switch(idx) {
- case (Some(idx)) ->
- let entry = (TLBEntries[idx]) in
- let entryMask = entry.pagemask in
-
- let evenOddBit = switch(entryMask) {
- case 0x0000 -> 12
- case 0x0003 -> 14
- case 0x000f -> 16
- case 0x003f -> 18
- case 0x00ff -> 20
- case 0x03ff -> 22
- case 0x0fff -> 24
- case 0x3fff -> 26
- case 0xffff -> 28
- case _ -> undefined
- } in
- let isOdd = (vAddr[evenOddBit]) in
- let (caps, capl, (bit[24])pfn, d, v) = if (isOdd) then
- (entry.caps1, entry.capl1, entry.pfn1, entry.d1, entry.v1)
- else
- (entry.caps0, entry.capl0, entry.pfn0, entry.d0, entry.v0) in
- if (~(v)) then
- (SignalExceptionTLB(if (accessType == StoreData) then XTLBInvS else XTLBInvL, vAddr))
- else if ((accessType == StoreData) & ~(d)) then
- (SignalExceptionTLB(TLBMod, vAddr))
- else
- (EXTZ(pfn[23..((evenOddBit)-(12))] : vAddr[((evenOddBit)-(1)) .. 0]),
- if (accessType == StoreData) then caps else capl)
- case None -> (SignalExceptionTLB(
- if (accessType == StoreData) then XTLBRefillS else XTLBRefillL, vAddr))
- }
-}
-
-(* perform TLB translation. bool is CHERI specific TLB bits noStoreCap/suppressTag *)
-function (bit[64], bool) TLBTranslateC ((bit[64]) vAddr, (MemAccessType) accessType) =
- {
- let currentAccessLevel = getAccessLevel() in
- let compat32 = (vAddr[61..31] == 0b1111111111111111111111111111111) in
- let (requiredLevel, addr) = switch(vAddr[63..62]) {
- case 0b11 -> switch(compat32, vAddr[30..29]) { (* xkseg *)
- case (true, 0b11) -> (Kernel, None) (* kseg3 mapped 32-bit compat *)
- case (true, 0b10) -> (Supervisor, None) (* sseg mapped 32-bit compat *)
- case (true, 0b01) -> (Kernel, Some(EXTZ(vAddr[28..0]))) (* kseg1 unmapped uncached 32-bit compat *)
- case (true, 0b00) -> (Kernel, Some(EXTZ(vAddr[28..0]))) (* kseg0 unmapped cached 32-bit compat *)
- case (_, _) -> (Kernel, None) (* xkseg mapped *)
- }
- case 0b10 -> (Kernel, Some(EXTZ(vAddr[58..0]))) (* xkphys bits 61-59 are cache mode (ignored) *)
- case 0b01 -> (Supervisor, None) (* xsseg - supervisor mapped *)
- case 0b00 -> (User, None) (* xuseg - user mapped *)
- } in
- if ((int_of_accessLevel(currentAccessLevel)) < (int_of_accessLevel(requiredLevel))) then
- (SignalExceptionBadAddr(if (accessType == StoreData) then AdES else AdEL, vAddr))
- else
- let (pa, c) = switch(addr) {
- case (Some(a)) -> (a, false)
- case None -> if ((~(compat32)) & (unsigned(vAddr[61..0]) > MAX_VA)) then
- (SignalExceptionBadAddr(if (accessType == StoreData) then AdES else AdEL, vAddr))
- else
- TLBTranslate2(vAddr, accessType)
- }
- in if (unsigned(pa) > MAX_PA) then
- (SignalExceptionBadAddr(if (accessType == StoreData) then AdES else AdEL, vAddr))
- else
- (pa, c)
- }
-
-function (bit[64]) TLBTranslate ((bit[64]) vAddr, (MemAccessType) accessType) =
- let (addr, c) = TLBTranslateC(vAddr, accessType) in addr
diff --git a/mips/mips_tlb_stub.sail b/mips/mips_tlb_stub.sail
deleted file mode 100644
index a9970a4e..00000000
--- a/mips/mips_tlb_stub.sail
+++ /dev/null
@@ -1,40 +0,0 @@
-(*========================================================================*)
-(* *)
-(* Copyright (c) 2015-2017 Robert M. Norton *)
-(* 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 option<TLBIndexT> tlbSearch((bit[64]) VAddr) = None
-
-function (bit[64]) TLBTranslate ((bit[64]) vAddr, (MemAccessType) accessType) =
- vAddr
-
-function (bit[64], bool) TLBTranslateC ((bit[64]) vAddr, (MemAccessType) accessType) = (vAddr, false)
diff --git a/mips/mips_wrappers.sail b/mips/mips_wrappers.sail
deleted file mode 100644
index 02131204..00000000
--- a/mips/mips_wrappers.sail
+++ /dev/null
@@ -1,70 +0,0 @@
-(*========================================================================*)
-(* *)
-(* Copyright (c) 2015-2017 Robert M. Norton *)
-(* 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. *)
-(*========================================================================*)
-
-(* mips_wrappers.sail: wrappers functions and hooks for CHERI extensibility
- (mostly identity functions here) *)
-
-function unit effect {wmem} MEMw_wrapper(addr, size, data) =
- let ledata = reverse_endianness(data) in
- if (addr == 0x000000007f000000) then
- {
- UART_WDATA := ledata[7..0];
- UART_WRITTEN := 1;
- } else {
- MEMea(addr, size);
- MEMval(addr, size, ledata);
- }
-
-function bool effect {wmem} MEMw_conditional_wrapper(addr, size, data) =
- {
- MEMea_conditional(addr, size);
- MEMval_conditional(addr, size, reverse_endianness(data))
- }
-
-function bit[64] addrWrapper((bit[64]) addr, (MemAccessType) accessType, (WordType) width) =
- addr
-
-function (bit[64]) TranslatePC ((bit[64]) vAddr) = {
- incrementCP0Count();
- if (vAddr[1..0] != 0b00) then (* bad PC alignment *)
- (SignalExceptionBadAddr(AdEL, vAddr))
- else
- TLBTranslate(vAddr, Instruction)
-}
-
-let have_cp2 = false
-
-function unit SignalException ((Exception) ex) = SignalExceptionMIPS(ex, 0x0000000000000000)
-
-function unit ERETHook() = ()
diff --git a/mips/run_embed.ml b/mips/run_embed.ml
deleted file mode 100644
index 1bb6d5f6..00000000
--- a/mips/run_embed.ml
+++ /dev/null
@@ -1,404 +0,0 @@
-(**************************************************************************)
-(* Sail *)
-(* *)
-(* Copyright (c) 2013-2017 *)
-(* Kathyrn Gray *)
-(* Shaked Flur *)
-(* Stephen Kell *)
-(* Gabriel Kerneis *)
-(* Robert Norton-Wright *)
-(* Christopher Pulte *)
-(* Peter Sewell *)
-(* *)
-(* 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. *)
-(**************************************************************************)
-
-open Printf ;;
-open Big_int_Z ;;
-open Sail_values;;
-open Mips_extras_ml;;
-
-let interact_print = ref true
-let result_print = ref true
-let error_print = ref true
-let interactf : ('a, out_channel, unit) format -> 'a =
- function f -> if !interact_print then printf f else ifprintf stderr f
-let errorf : ('a, out_channel, unit) format -> 'a =
- function f -> if !error_print then printf f else ifprintf stderr f
-let resultf : ('a, out_channel, unit) format -> 'a =
- function f -> if !result_print then printf f else ifprintf stderr f
-
-let rec foldli f acc ?(i=0) = function
- | [] -> acc
- | x::xs -> foldli f (f i acc x) ~i:(i+1) xs;;
-
-let big_int_to_hex i = Z.format "%x" i
-let big_int_to_hex64 i = Z.format "%016x" i
-
-let input_buf = (ref [] : int list ref);;
-
-let max_cut_off = ref false
-let max_instr = ref 0
-let model_arg = ref "cheri"
-let raw_list = ref []
-
-let args = [
- ("--model", Arg.Set_string model_arg, "CPU model to use (mips, cheri, cheri128)");
- ("--max_instruction", Arg.Int (fun i -> max_cut_off := true; max_instr := i), "only run i instructions, then stop");
- ("--trace", Arg.Set trace_writes, "trace all register writes"); (* trace_writes is in sail_values.ml *)
- ("--quiet", Arg.Clear interact_print, "suppress trace of PC");
- ("--undef", Arg.String (fun s -> undef_val := bit_of_string s), "value to use for undef (u,0,1)");
-]
-
-module type ISA_model = sig
- type ast
- val init_model : unit -> unit
- val inc_nextPC : unit -> unit
- val get_pc : unit -> big_int
- val translate_pc : unit -> big_int option
- val get_opcode : big_int -> value
- val decode : value -> ast option
- val execute : ast -> unit
- val is_halt : ast -> bool
- val print_results : unit -> unit
-end
-
-let rec debug_print_gprs gprs start stop =
- let gpr_val = vector_access gprs (big_int_of_int start) in
- let gpr_str =
- if has_undef gpr_val then
- "uuuuuuuuuuuuuuuu"
- else
- big_int_to_hex64 (unsigned_big(gpr_val)) in
- resultf "DEBUG MIPS REG %.2d 0x%s\n" start gpr_str;
- if start < stop
- then debug_print_gprs gprs (start + 1) stop
- else ()
-
-let cap_reg_to_string reg =
- "0b" ^ (string_of_bit_array (get_barray reg))
-
-let read_bit_reg = function
- | Vregister (array,_,_,_,_) -> (!array).(0) = Vone
- | _ -> failwith "read_bit_reg of non-reg"
-
-let rec debug_print_caps capregs start stop =
- let cap_val = vector_access capregs (big_int_of_int start) in
- let cap_str = cap_reg_to_string cap_val in
- resultf "DEBUG CAP REG %.2d %s\n" start cap_str;
- if start < stop
- then debug_print_caps capregs (start + 1) stop
- else ()
-
-let handle_uart uart_written uart_wdata uart_rdata uart_rvalid =
- (try
- let (pending, _, _) = Unix.select [Unix.stdin] [] [] 0.0 in
- if pending != [] then
- input_buf := (!input_buf) @ [(input_byte stdin)]
- with _ -> ());
-
- if (read_bit_reg uart_written) then
- begin
- let b = unsigned_int(uart_wdata) in
- printf "%c" (Char.chr b);
- printf "%!";
- set_register uart_written (to_vec_dec_int (1,0))
- end;
-
- if not (read_bit_reg uart_rvalid) then
- (match !input_buf with
- | x :: xs ->
- begin
- set_register uart_rdata (to_vec_dec_int (8, x));
- set_register uart_rvalid (to_vec_dec_int (1, 1));
- input_buf := xs;
- end
- | _ -> ())
-
-module MIPS_model : ISA_model = struct
- type ast = Mips_embed._ast
-
- let init_model () =
- let start_addr = (to_vec_dec_big (bi64, big_int_of_string "0x9000000040000000")) in
- set_register Mips_embed._nextPC start_addr;
- set_register_field_bit Mips_embed._CP0Status "BEV" Vone
-
- let inc_nextPC () =
- handle_uart Mips_embed._UART_WRITTEN Mips_embed._UART_WDATA Mips_embed._UART_RDATA Mips_embed._UART_RVALID;
-
- set_register Mips_embed._inBranchDelay Mips_embed._branchPending;
- set_register Mips_embed._branchPending (to_vec_dec_int (1, 0));
- set_register Mips_embed._PC Mips_embed._nextPC;
- let inBranchDelay = read_bit_reg Mips_embed._inBranchDelay in
- if inBranchDelay then
- set_register Mips_embed._nextPC Mips_embed._delayedPC
- else
- let pc_vaddr = unsigned_big(Mips_embed._PC) in
- let npc_addr = add_int_big_int 4 pc_vaddr in
- let npc_vec = to_vec_dec_big (bi64, npc_addr) in
- set_register Mips_embed._nextPC npc_vec
-
- let get_pc () = unsigned_big (Mips_embed._PC)
-
- let translate_pc () =
- try
- Some (unsigned_big(Mips_embed._TranslatePC(Mips_embed._PC)))
- with Sail_exit -> None
-
- let get_opcode pc_a = Mips_embed._reverse_endianness(_MEMr (to_vec_dec_big (bi64, pc_a), bi4))
-
- let decode = Mips_embed._decode
-
- let execute = Mips_embed._execute
- let is_halt i = (i = Mips_embed.HCF)
- let print_results () =
- begin
- resultf "DEBUG MIPS PC 0x%s\n" (big_int_to_hex (unsigned_big Mips_embed._PC));
- debug_print_gprs Mips_embed._GPR 0 31;
- end
-end
-
-module CHERI_model : ISA_model = struct
- type ast = Cheri_embed._ast
-
- let init_model () =
- let start_addr = (to_vec_dec_big (bi64, big_int_of_string "0x9000000040000000")) in
- set_register Cheri_embed._nextPC start_addr;
- set_register_field_bit Cheri_embed._CP0Status "BEV" Vone;
- let initial_cap_val_int = big_int_of_string "0x100000000fffffffe00000000000000000000000000000000ffffffffffffffff" in
- let initial_cap_vec = to_vec_dec ((big_int_of_int 257), initial_cap_val_int) in
- set_register Cheri_embed._PCC initial_cap_vec;
- set_register Cheri_embed._nextPCC initial_cap_vec;
- set_register Cheri_embed._delayedPCC initial_cap_vec;
- cap_size_shift := 5; (* configure memory model cap_size in mips_extras_ml *)
- for i = 0 to 31 do
- set_register (vector_access_int Cheri_embed._CapRegs i) initial_cap_vec
- done
-
- let inc_nextPC () =
- handle_uart Cheri_embed._UART_WRITTEN Cheri_embed._UART_WDATA Cheri_embed._UART_RDATA Cheri_embed._UART_RVALID;
-
- set_register Cheri_embed._inBranchDelay Cheri_embed._branchPending;
- set_register Cheri_embed._branchPending (to_vec_dec_int (1, 0));
- set_register Cheri_embed._PC Cheri_embed._nextPC;
- set_register Cheri_embed._PCC Cheri_embed._nextPCC;
- let inBranchDelay = read_bit_reg Cheri_embed._inBranchDelay in
- if inBranchDelay then
- begin
- set_register Cheri_embed._nextPC Cheri_embed._delayedPC;
- set_register Cheri_embed._nextPCC Cheri_embed._delayedPCC;
- end
- else
- let pc_vaddr = unsigned_big(Cheri_embed._PC) in
- let npc_addr = add_int_big_int 4 pc_vaddr in
- let npc_vec = to_vec_dec_big (bi64, npc_addr) in
- begin
- set_register Cheri_embed._nextPC npc_vec;
- set_register Cheri_embed._inCCallDelay (to_vec_dec_int (1, 0))
- end
-
- let get_pc () = unsigned_big (Cheri_embed._PC)
-
- let translate_pc () =
- try
- Some (unsigned_big(Cheri_embed._TranslatePC(Cheri_embed._PC)))
- with Sail_exit -> None
-
- let get_opcode pc_a = Cheri_embed._reverse_endianness(_MEMr (to_vec_dec_big (bi64, pc_a), bi4))
-
- let decode = Cheri_embed._decode
-
- let execute = Cheri_embed._execute
- let is_halt i = (i = Cheri_embed.HCF)
- let print_results () =
- begin
- resultf "DEBUG MIPS PC 0x%s\n" (big_int_to_hex (unsigned_big Cheri_embed._PC));
- debug_print_gprs Cheri_embed._GPR 0 31;
- resultf "DEBUG CAP PCC %s\n" (cap_reg_to_string Cheri_embed._PCC);
- debug_print_caps Cheri_embed._CapRegs 0 31;
- end
-end
-
-module CHERI128_model : ISA_model = struct
- type ast = Cheri128_embed._ast
-
- let init_model () =
- let start_addr = (to_vec_dec_big (bi64, big_int_of_string "0x9000000040000000")) in
- set_register Cheri128_embed._nextPC start_addr;
- set_register_field_bit Cheri128_embed._CP0Status "BEV" Vone;
- let initial_cap_val_int = big_int_of_string "0x1fffe6000000100000000000000000000" in (* hex((0x10000 << 64) + (48 << 105) + (0x7fff << 113) + (1 << 128)) T=0x10000 E=48 perms=0x7fff tag=1 *)
- let initial_cap_vec = to_vec_dec ((bi129), initial_cap_val_int) in
- set_register Cheri128_embed._PCC initial_cap_vec;
- set_register Cheri128_embed._nextPCC initial_cap_vec;
- set_register Cheri128_embed._delayedPCC initial_cap_vec;
- cap_size_shift := 4; (* configure memory model cap_size in mips_extras_ml *)
- for i = 0 to 31 do
- set_register (vector_access_int Cheri128_embed._CapRegs i) initial_cap_vec
- done
-
- let inc_nextPC () =
- handle_uart Cheri128_embed._UART_WRITTEN Cheri128_embed._UART_WDATA Cheri128_embed._UART_RDATA Cheri128_embed._UART_RVALID;
-
- set_register Cheri128_embed._inBranchDelay Cheri128_embed._branchPending;
- set_register Cheri128_embed._branchPending (to_vec_dec_int (1, 0));
- set_register Cheri128_embed._PC Cheri128_embed._nextPC;
- set_register Cheri128_embed._PCC Cheri128_embed._nextPCC;
- let inBranchDelay = read_bit_reg Cheri128_embed._inBranchDelay in
- if inBranchDelay then
- begin
- set_register Cheri128_embed._nextPC Cheri128_embed._delayedPC;
- set_register Cheri128_embed._nextPCC Cheri128_embed._delayedPCC;
- end
- else
- let pc_vaddr = unsigned_big(Cheri128_embed._PC) in
- let npc_addr = add_int_big_int 4 pc_vaddr in
- let npc_vec = to_vec_dec_big (bi64, npc_addr) in
- begin
- set_register Cheri128_embed._nextPC npc_vec;
- set_register Cheri128_embed._inCCallDelay (to_vec_dec_int (1, 0))
- end
-
- let get_pc () = unsigned_big (Cheri128_embed._PC)
-
- let translate_pc () =
- try
- Some (unsigned_big(Cheri128_embed._TranslatePC(Cheri128_embed._PC)))
- with Sail_exit -> None
-
- let get_opcode pc_a = Cheri128_embed._reverse_endianness(_MEMr (to_vec_dec_big (bi64, pc_a), bi4))
-
- let decode = Cheri128_embed._decode
-
- let execute = Cheri128_embed._execute
- let is_halt i = (i = Cheri128_embed.HCF)
- let print_results () =
- begin
- resultf "DEBUG MIPS PC 0x%s\n" (big_int_to_hex (unsigned_big Cheri128_embed._PC));
- debug_print_gprs Cheri128_embed._GPR 0 31;
- resultf "DEBUG CAP PCC %s\n" (cap_reg_to_string Cheri128_embed._PCC);
- debug_print_caps Cheri128_embed._CapRegs 0 31;
- end
-end
-
-let time_it action arg =
- let start_time = Sys.time () in
- let ret = action arg in
- let finish_time = Sys.time () in
- (finish_time -. start_time, ret)
-
-let rec fde_loop (model, count) =
- if !max_cut_off && count = !max_instr
- then begin
- resultf "\nEnding evaluation due to reaching cut off point of %d instructions\n" count;
- count
- end
- else
- begin
- let module Model = (val model : ISA_model) in
-
- Model.inc_nextPC ();
- if !interact_print then
- interactf "\n**** instruction %d from address %s ****\n"
- count (big_int_to_hex64 (Model.get_pc ()));
- let m_paddr = Model.translate_pc () in
- match m_paddr with
- | Some pc ->
- let opcode = Model.get_opcode pc in
- if !interact_print then
- interactf "decode: 0x%x\n" (unsigned_int(opcode));
- let instruction = Model.decode opcode in
- let i = match instruction with
- | Some (i) -> i
- | _ -> begin
- errorf "\n**** Decode error ****\n";
- exit 1;
- end
- in
- if Model.is_halt i then
- begin
- Model.print_results ();
- resultf "\nSUCCESS program terminated after %d instructions\n" count;
- count
- end
- else
- begin
- (try
- Model.execute(i)
- with Sail_exit -> ()); (* exception during execute *)
- fde_loop (model, count + 1)
- end
- | None -> (* Exception during PC translation *)
- fde_loop (model, count + 1)
- end
-
-let rec load_raw_file buf addr len chan =
- let to_read = min_int len page_size_bytes in
- really_input chan buf 0 to_read;
- add_mem_bytes addr buf 0 to_read;
- if (len > to_read) then
- load_raw_file buf (add_int_big_int to_read addr) (len - to_read) chan
-
-let get_model = function
- | "cheri128" -> (module CHERI128_model : ISA_model)
- | "cheri" -> (module CHERI_model : ISA_model)
- | "mips" -> (module MIPS_model : ISA_model)
- | _ -> failwith "unknown model name"
-
-let anon_raw s =
- (* some input validation would be nice... *)
- let len = String.length s in
- let atidx = try
- String.index s '@'
- with Not_found -> raise (Arg.Bad "expected argument of form file@addr") in
- let f = String.sub s 0 atidx in
- let addr = String.sub s (atidx+1) (len - atidx -1) in
- raw_list := (!raw_list) @ [(f, big_int_of_string addr)]
-
-let load_raw_arg (f, a) =
- let buf = Bytes.create page_size_bytes in
- let chan = open_in_bin f in
- let len = in_channel_length chan in
- load_raw_file buf a len chan
-
-let run () =
- (* Turn off line-buffering of standard input to allow responsive console input *)
- if Unix.isatty (Unix.stdin) then begin
- let tattrs = Unix.tcgetattr (Unix.stdin) in
- Unix.tcsetattr (Unix.stdin) (Unix.TCSANOW) ({tattrs with c_icanon=false})
- end;
- Arg.parse args anon_raw "" ;
- List.iter load_raw_arg !raw_list;
- let model = get_model !model_arg in
- let module Model = (val model : ISA_model) in
- Model.init_model ();
- let (t, count) = time_it fde_loop (model, 0) in
- resultf "Execution time: %f seconds %f IPS \n" t (float(count) /. t);;
-
-run () ;;