summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Norton2018-02-22 17:23:27 +0000
committerRobert Norton2018-02-22 17:23:27 +0000
commit5308167903db5e81c07a5aff9f20c83f33afcb9c (patch)
treeba0aae862b7c43d98328b0840bdb64f74cdcbfdc
parent51c122d99a1a481bc916f766ae6bd2a6a66de6d2 (diff)
wip
-rw-r--r--etc/tosail2.perl9
-rw-r--r--mips_new_tc/mips_ast_decl.sail6
-rw-r--r--mips_new_tc/mips_epilogue.sail3
-rw-r--r--mips_new_tc/mips_insts.sail1048
-rw-r--r--mips_new_tc/mips_prelude.sail274
-rw-r--r--mips_new_tc/mips_ri.sail2
-rw-r--r--mips_new_tc/mips_tlb.sail157
-rw-r--r--mips_new_tc/mips_wrappers.sail2
-rw-r--r--mips_new_tc/prelude.sail65
-rw-r--r--src/Makefile4
10 files changed, 860 insertions, 710 deletions
diff --git a/etc/tosail2.perl b/etc/tosail2.perl
index 893e2be8..eda6506d 100644
--- a/etc/tosail2.perl
+++ b/etc/tosail2.perl
@@ -53,6 +53,15 @@ while (<>) {
s!\((\w+)\) (\w+)!$2 : $1!g;
}
+ # fix scattered union declaration
+ s!scattered\s+type\s+(\w+)\s+=\s+const\s+union!scattered union $1!;
+
+ # fix scattered union members
+ s!union\s+(\w+)\s+member\s+(\w+)\s+(\w+)!union clause $1 = $3 : $2!;
+
+ # fix scattered function declaration (drops type, assumes separate val dec.)
+ s!scattered\s+function\s+([^\s]+)\s+(\w+)!scattered function $2!;
+
# fix any bits[n]
s!bit\s*\[([^\]]+)\]!bits\($1\)!g;
diff --git a/mips_new_tc/mips_ast_decl.sail b/mips_new_tc/mips_ast_decl.sail
index 5d06eacb..e39bc270 100644
--- a/mips_new_tc/mips_ast_decl.sail
+++ b/mips_new_tc/mips_ast_decl.sail
@@ -35,10 +35,10 @@
/* misp_insts.sail: mips instruction decode and execute clauses and AST node
declarations */
-scattered type ast = const union
+scattered union ast
val execute : ast -> unit effect {barr, eamem, escape, rmem, rreg, undef, wmv, wreg}
-scattered function unit execute
+scattered function execute
val decode : bits(32) -> option(ast) effect pure
-scattered function option(ast) decode
+scattered function decode
diff --git a/mips_new_tc/mips_epilogue.sail b/mips_new_tc/mips_epilogue.sail
index abec9ee9..c7477a50 100644
--- a/mips_new_tc/mips_epilogue.sail
+++ b/mips_new_tc/mips_epilogue.sail
@@ -38,4 +38,5 @@ end decode
end execute
end ast
-function option(ast) supported_instructions (ast) instr = Some(instr)
+val supported_instructions : ast -> option(ast)
+function supported_instructions instr = Some(instr)
diff --git a/mips_new_tc/mips_insts.sail b/mips_new_tc/mips_insts.sail
index 86ee1256..b02c51e0 100644
--- a/mips_new_tc/mips_insts.sail
+++ b/mips_new_tc/mips_insts.sail
@@ -43,20 +43,20 @@
the simplest possible instruction, no undefined behaviour or exceptions
reg, reg, immediate */
-union ast member regregimm16 DADDIU
+union clause ast = DADDIU : regregimm16
function clause decode (0b011001 @ rs : regno @ rt : regno @ imm : imm16) =
Some(DADDIU(rs, rt, imm))
function clause execute (DADDIU (rs, rt, imm)) =
{
- wGPR(rt) = rGPR(rs) + (bits(64)) (EXTS(imm))
+ wGPR(rt) = rGPR(rs) + EXTS(imm)
}
/* DADDU Doubleword Add Unsigned -- another very simple instruction,
reg, reg, reg */
-union ast member regregreg DADDU
+union clause ast = DADDU : regregreg
function clause decode (0b000000 @ rs : regno @ rt : regno @ rd : regno @ 0b00000 @ 0b101101) =
Some(DADDU(rs, rt, rd))
@@ -69,14 +69,14 @@ function clause execute (DADDU (rs, rt, rd)) =
/* DADDI Doubleword Add Immediate
reg, reg, imm with possible exception */
-union ast member regregimm16 DADDI
+union clause ast = DADDI : regregimm16
function clause decode (0b011000 @ rs : regno @ rt : regno @ imm : imm16) =
Some(DADDI(rs, rt, imm))
function clause execute (DADDI (rs, rt, imm)) =
{
- let sum65 : bits(65) = ((bits(65)) (EXTS(rGPR(rs))) + (bits(65)) (EXTS(imm))) in
+ let sum65 : bits(65) = EXTS(rGPR(rs)) + EXTS(imm) in
{
if (sum65[64] != sum65[63]) then
(SignalException(Ov))
@@ -88,14 +88,14 @@ function clause execute (DADDI (rs, rt, imm)) =
/* DADD Doubleword Add
reg, reg, reg with possible exception */
-union ast member regregreg DADD
+union clause ast = DADD : regregreg
function clause decode (0b000000 @ rs : regno @ rt : regno @ rd : regno @ 0b00000 @ 0b101100) =
Some(DADD(rs, rt, rd))
function clause execute (DADD (rs, rt, rd)) =
{
- let sum65 : bits(65) = ((bits(65)) (EXTS(rGPR(rs))) + (bits(65)) (EXTS(rGPR(rt)))) in
+ let sum65 : bits(65) = EXTS(rGPR(rs)) + EXTS(rGPR(rt)) in
{
if sum65[64] != sum65[63] then
(SignalException(Ov))
@@ -106,39 +106,39 @@ function clause execute (DADD (rs, rt, rd)) =
/* ADD 32-bit add -- reg, reg, reg with possible undefined behaviour or exception */
-union ast member regregreg ADD
+union clause ast = ADD : regregreg
function clause decode (0b000000 @ rs : regno @ rt : regno @ rd : regno @ 0b00000 @ 0b100000) =
Some(ADD(rs, rt, rd))
function clause execute (ADD(rs, rt, rd)) =
{
- (bits(64)) opA = rGPR(rs);
- (bits(64)) opB = rGPR(rt);
+ opA : bits(64) = rGPR(rs);
+ opB : bits(64) = rGPR(rt);
if NotWordVal(opA) | NotWordVal(opB) then
- wGPR(rd) = (bits(64)) undefined /* XXX could exit instead */
+ wGPR(rd) = undefined /* XXX could exit instead */
else
- let sum33 : bits(33) = ((bits(33)) (EXTS(opA[31 .. 0])) + (bits(33)) (EXTS(opB[31 .. 0]))) in
+ let sum33 : bits(33) = EXTS(opA[31 .. 0]) + EXTS(opB[31 .. 0])in
if sum33[32] != sum33[31] then
(SignalException(Ov))
else
- wGPR(rd) = (bits(64)) (EXTS(sum33[31..0]))
+ 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
+union clause ast = ADDI : regregimm16
function clause decode (0b001000 @ rs : regno @ rt : regno @ imm : imm16) =
Some(ADDI(rs, rt, imm))
function clause execute (ADDI(rs, rt, imm)) =
{
- (bits(64)) opA = rGPR(rs);
+ opA = rGPR(rs);
if NotWordVal(opA) then
- wGPR(rt) = (bits(64)) undefined /* XXX could exit instead */
+ wGPR(rt) = undefined /* XXX could exit instead */
else
- let sum33 = (bits(33)) (EXTS(opA[31 .. 0])) + (bits(33)) (EXTS(imm)) in
+ let sum33 : bits(33) = EXTS(opA[31 .. 0]) + EXTS(imm) in
if sum33[32] != sum33[31] then
(SignalException(Ov))
else
@@ -147,36 +147,36 @@ function clause execute (ADDI(rs, rt, imm)) =
/* ADDU 32-bit add immediate -- reg, reg, reg with possible undefined behaviour */
-union ast member regregreg ADDU
+union clause ast = ADDU : regregreg
function clause decode (0b000000 @ rs : regno @ rt : regno @ rd : regno @ 0b00000 @ 0b100001) =
Some(ADDU(rs, rt, rd))
function clause execute (ADDU(rs, rt, rd)) =
{
- (bits(64)) opA = rGPR(rs);
- (bits(64)) opB = rGPR(rt);
+ opA = rGPR(rs);
+ opB = rGPR(rt);
if NotWordVal(opA) | NotWordVal(opB) then
- wGPR(rd) = (bits(64)) undefined
+ wGPR(rd) = undefined
else
- wGPR(rd) = (bits(64)) (EXTS(opA[31..0] + opB[31..0]))
+ wGPR(rd) = EXTZ(opA[31..0] + opB[31..0])
}
/* ADDIU 32-bit add immediate -- reg, reg, imm with possible undefined behaviour */
-union ast member regregimm16 ADDIU
+union clause ast = ADDIU : regregimm16
function clause decode (0b001001 @ rs : regno @ rt : regno @ imm : imm16) =
Some(ADDIU(rs, rt, imm))
function clause execute (ADDIU(rs, rt, imm)) =
{
- (bits(64)) opA = rGPR(rs);
+ opA = rGPR(rs);
if NotWordVal(opA) then
- wGPR(rt) = (bits(64)) undefined /* XXX could exit instead */
+ wGPR(rt) = undefined /* XXX could exit instead */
else
- wGPR(rt) = (bits(64)) (EXTS((opA[31 .. 0]) + (bits(32)) (EXTS(imm))))
+ wGPR(rt) = EXTS((opA[31 .. 0]) + EXTS(imm))
}
/**************************************************************************************/
@@ -185,7 +185,7 @@ function clause execute (ADDIU(rs, rt, imm)) =
/* DSUBU doubleword subtract 'unsigned' reg, reg, reg */
-union ast member regregreg DSUBU
+union clause ast = DSUBU : regregreg
function clause decode (0b000000 @ rs : regno @ rt : regno @ rd : regno @ 0b00000 @ 0b101111) =
Some(DSUBU(rs, rt, rd))
@@ -197,14 +197,14 @@ function clause execute (DSUBU (rs, rt, rd)) =
/* DSUB reg, reg, reg with possible exception */
-union ast member regregreg DSUB
+union clause ast = DSUB : regregreg
function clause decode (0b000000 @ rs : regno @ rt : regno @ rd : regno @ 0b00000 @ 0b101110) =
Some(DSUB(rs, rt, rd))
function clause execute (DSUB (rs, rt, rd)) =
{
- let temp65 : bits(65) = (bits(65)) (EXTS(rGPR(rs))) - (bits(65)) (EXTS(rGPR(rt))) in
+ let temp65 : bits(65) = EXTS(rGPR(rs)) - EXTS(rGPR(rt)) in
{
if temp65[64] != temp65[63] then
(SignalException(Ov))
@@ -215,19 +215,19 @@ function clause execute (DSUB (rs, rt, rd)) =
/* SUB 32-bit sub -- reg, reg, reg with possible undefined behaviour or exception */
-union ast member regregreg SUB
+union clause ast = SUB : regregreg
function clause decode (0b000000 @ rs : regno @ rt : regno @ rd : regno @ 0b00000 @ 0b100010) =
Some(SUB(rs, rt, rd))
function clause execute (SUB(rs, rt, rd)) =
{
- (bits(64)) opA = rGPR(rs);
- (bits(64)) opB = rGPR(rt);
+ opA = rGPR(rs);
+ opB = rGPR(rt);
if NotWordVal(opA) | NotWordVal(opB) then
- wGPR(rd) = (bits(64)) undefined /* XXX could instead */
+ wGPR(rd) = undefined /* XXX could instead */
else
- let temp33 : bits(33) = (EXTS(opA[31..0]) - EXTS(opB[31..0])) in
+ let temp33 : bits(33) = EXTS(opA[31..0]) - EXTS(opB[31..0]) in
if temp33[32] != temp33[31] then
(SignalException(Ov))
else
@@ -236,14 +236,14 @@ function clause execute (SUB(rs, rt, rd)) =
/* SUBU 32-bit 'unsigned' sub -- reg, reg, reg with possible undefined behaviour */
-union ast member regregreg SUBU
+union clause ast = SUBU : regregreg
function clause decode (0b000000 @ rs : regno @ rt : regno @ rd : regno @ 0b00000 @ 0b100011) =
Some(SUBU(rs, rt, rd))
function clause execute (SUBU(rs, rt, rd)) =
{
- (bits(64)) opA = rGPR(rs);
- (bits(64)) opB = rGPR(rt);
+ opA = rGPR(rs);
+ opB = rGPR(rt);
if NotWordVal(opA) | NotWordVal(opB) then
wGPR(rd) = undefined
else
@@ -256,7 +256,7 @@ function clause execute (SUBU(rs, rt, rd)) =
/* AND reg, reg, reg */
-union ast member regregreg AND
+union clause ast = AND : regregreg
function clause decode (0b000000 @ rs : regno @ rt : regno @ rd : regno @ 0b00000 @ 0b100100) =
Some(AND(rs, rt, rd))
@@ -267,7 +267,7 @@ function clause execute (AND (rs, rt, rd)) =
/* ANDI reg, reg, imm */
-union ast member regregimm16 ANDI
+union clause ast = ANDI : regregimm16
function clause decode (0b001100 @ rs : regno @ rt : regno @ imm : imm16) =
Some(ANDI(rs, rt, imm))
function clause execute (ANDI (rs, rt, imm)) =
@@ -277,7 +277,7 @@ function clause execute (ANDI (rs, rt, imm)) =
/* OR reg, reg, reg */
-union ast member regregreg OR
+union clause ast = OR : regregreg
function clause decode (0b000000 @ rs : regno @ rt : regno @ rd : regno @ 0b00000 @ 0b100101) =
Some(OR(rs, rt, rd))
function clause execute (OR (rs, rt, rd)) =
@@ -287,7 +287,7 @@ function clause execute (OR (rs, rt, rd)) =
/* ORI reg, reg, imm */
-union ast member regregimm16 ORI
+union clause ast = ORI : regregimm16
function clause decode (0b001101 @ rs : regno @ rt : regno @ imm : imm16) =
Some(ORI(rs, rt, imm))
function clause execute (ORI (rs, rt, imm)) =
@@ -297,7 +297,7 @@ function clause execute (ORI (rs, rt, imm)) =
/* NOR reg, reg, reg */
-union ast member regregreg NOR
+union clause ast = NOR : regregreg
function clause decode (0b000000 @ rs : regno @ rt : regno @ rd : regno @ 0b00000 @ 0b100111) =
Some(NOR(rs, rt, rd))
function clause execute (NOR (rs, rt, rd)) =
@@ -307,7 +307,7 @@ function clause execute (NOR (rs, rt, rd)) =
/* XOR reg, reg, reg */
-union ast member regregreg XOR
+union clause ast = XOR : regregreg
function clause decode (0b000000 @ rs : regno @ rt : regno @ rd : regno @ 0b00000 @ 0b100110) =
Some(XOR(rs, rt, rd))
function clause execute (XOR (rs, rt, rd)) =
@@ -316,7 +316,7 @@ function clause execute (XOR (rs, rt, rd)) =
}
/* XORI reg, reg, imm */
-union ast member regregimm16 XORI
+union clause ast = XORI : regregimm16
function clause decode (0b001110 @ rs : regno @ rt : regno @ imm : imm16) =
Some(XORI(rs, rt, imm))
function clause execute (XORI (rs, rt, imm)) =
@@ -325,12 +325,12 @@ function clause execute (XORI (rs, rt, imm)) =
}
/* LUI reg, imm 32-bit load immediate into upper 16 bits */
-union ast member (regno, imm16) LUI
+union clause ast = LUI : (regno, imm16)
function clause decode (0b001111 @ 0b00000 @ rt : regno @ imm : imm16) =
Some(LUI(rt, imm))
function clause execute (LUI (rt, imm)) =
{
- wGPR(rt) = EXTS(imm : 0x0000)
+ wGPR(rt) = EXTS(imm @ 0x0000)
}
/**************************************************************************************/
@@ -339,106 +339,102 @@ function clause execute (LUI (rt, imm)) =
/* DSLL reg, reg, imm5 */
-union ast member regregreg DSLL
-function clause decode (0b000000 @ 0b00000 @ rt : regno @ rd : regno @ (bits(5)) sa @ 0b111000) =
+union clause ast = DSLL : regregreg
+function clause decode (0b000000 @ 0b00000 @ rt : regno @ rd : regno @ sa : bits(5) @ 0b111000) =
Some(DSLL(rt, rd, sa))
function clause execute (DSLL (rt, rd, sa)) =
{
- wGPR(rd) = (rGPR(rt) << sa) /* make tuareg mode less blue >> */
+ wGPR(rd) = (rGPR(rt) << sa)
}
/* DSLL32 reg, reg, imm5 */
-union ast member regregreg DSLL32
-function clause decode (0b000000 @ 0b00000 @ rt : regno @ rd : regno @ (bits(5)) sa @ 0b111100) =
+union clause ast = DSLL32 : regregreg
+function clause decode (0b000000 @ 0b00000 @ rt : regno @ rd : regno @ sa : bits(5) @ 0b111100) =
Some(DSLL32(rt, rd, sa))
function clause execute (DSLL32 (rt, rd, sa)) =
{
- wGPR(rd) = (rGPR(rt) << (0b1 : sa)) /* make tuareg mode less blue >> */
+ wGPR(rd) = (rGPR(rt) << (0b1 @ sa))
}
/* DSLLV reg, reg, reg */
-union ast member regregreg DSLLV
+union clause ast = DSLLV : regregreg
function clause decode (0b000000 @ rs : regno @ rt : regno @ rd : regno @ 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) */
+ wGPR(rd) = (rGPR(rt) << ((rGPR(rs))[5 .. 0]))
}
/* DSRA arithmetic shift duplicating sign bit - reg, reg, imm5 */
-union ast member regregreg DSRA
-function clause decode (0b000000 @ 0b00000 @ rt : regno @ rd : regno @ (bits(5)) sa @ 0b111011) =
+union clause ast = DSRA : regregreg
+function clause decode (0b000000 @ 0b00000 @ rt : regno @ rd : regno @ sa : bits(5) @ 0b111011) =
Some(DSRA(rt, rd, sa))
function clause execute (DSRA (rt, rd, sa)) =
{
temp = rGPR(rt);
- wGPR(rd) = EXTZ((temp[63] ^^ sa) : (temp[63 .. sa]))
+ wGPR(rd) = temp >>_s sa
}
/* DSRA32 reg, reg, imm5 */
-union ast member regregreg DSRA32
-function clause decode (0b000000 @ 0b00000 @ rt : regno @ rd : regno @ (bits(5)) sa @ 0b111111) =
+union clause ast = DSRA32 : regregreg
+function clause decode (0b000000 @ 0b00000 @ rt : regno @ rd : regno @ sa : bits(5) @ 0b111111) =
Some(DSRA32(rt, rd, sa))
function clause execute (DSRA32 (rt, rd, sa)) =
{
temp = rGPR(rt);
- sa32 = (0b1 : sa); /* sa+32 */
- wGPR(rd) = EXTZ((temp[63] ^^ sa32) : (temp[63 .. sa32]))
+ sa32 = 0b1 @ sa; /* sa+32 */
+ wGPR(rd) = temp >>_s sa32
}
/* DSRAV reg, reg, reg */
-union ast member regregreg DSRAV
+union clause ast = DSRAV : regregreg
function clause decode (0b000000 @ rs : regno @ rt : regno @ rd : regno @ 0b00000 @ 0b010111) =
Some(DSRAV(rs, rt, rd))
function clause execute (DSRAV (rs, rt, rd)) =
{
temp = rGPR(rt);
- sa = (rGPR(rs)) [5..0];
- wGPR(rd) = EXTZ((temp[63] ^^ sa) : temp[63 .. sa])
+ sa = rGPR(rs)[5..0];
+ wGPR(rd) = temp >>_s sa
}
/* DSRL shift right logical - reg, reg, imm5 */
-union ast member regregreg DSRL
-function clause decode (0b000000 @ 0b00000 @ rt : regno @ rd : regno @ (bits(5)) sa @ 0b111010) =
+union clause ast = DSRL : regregreg
+function clause decode (0b000000 @ 0b00000 @ rt : regno @ rd : regno @ sa : bits(5) @ 0b111010) =
Some(DSRL(rt, rd, sa))
function clause execute (DSRL (rt, rd, sa)) =
{
temp = rGPR(rt);
- wGPR(rd) = EXTZ((bitzero ^^ sa) : (temp[63 .. sa]))
+ wGPR(rd) = temp >> sa;
}
/* DSRL32 reg, reg, imm5 */
-union ast member regregreg DSRL32
-function clause decode (0b000000 @ 0b00000 @ rt : regno @ rd : regno @ (bits(5)) sa @ 0b111110) =
+union clause ast = DSRL32 : regregreg
+function clause decode (0b000000 @ 0b00000 @ rt : regno @ rd : regno @ sa : bits(5) @ 0b111110) =
Some(DSRL32(rt, rd, sa))
function clause execute (DSRL32 (rt, rd, sa)) =
{
temp = rGPR(rt);
- sa32 = (0b1 : sa); /* sa+32 */
- wGPR(rd) = EXTZ((bitzero ^^ sa32) : (temp[63 .. sa32]))
+ sa32 = 0b1 @ sa; /* sa+32 */
+ wGPR(rd) = temp >> sa32;
}
/* DSRLV reg, reg, reg */
-union ast member regregreg DSRLV
+union clause ast = DSRLV : regregreg
function clause decode (0b000000 @ rs : regno @ rt : regno @ rd : regno @ 0b00000 @ 0b010110) =
Some(DSRLV(rs, rt, rd))
function clause execute (DSRLV (rs, rt, rd)) =
{
- temp = rGPR(rt);
- sa = (rGPR(rs)) [5..0];
- wGPR(rd) = EXTZ((bitzero ^^ sa) : temp[63 .. sa])
+ temp = rGPR(rt);
+ sa = rGPR(rs)[5..0];
+ wGPR(rd) = temp >> sa;
}
/**************************************************************************************/
@@ -447,28 +443,30 @@ function clause execute (DSRLV (rs, rt, rd)) =
/* SLL 32-bit shift left */
-union ast member regregreg SLL
+union clause ast = SLL : regregreg
function clause decode (0b000000 @ 0b00000 @ rt : regno @ rd : regno @ sa : regno @ 0b000000) =
Some(SLL(rt, rd, sa))
function clause execute (SLL(rt, rd, sa)) =
{
- wGPR(rd) = EXTZ((rGPR(rt)) [31 - sa .. 0] : (bitzero ^^ sa))
+ rt32 = rGPR(rt)[31..0];
+ wGPR(rd) = EXTS(rt32 << sa);
}
/* SLLV 32-bit shift left variable */
-union ast member regregreg SLLV
+union clause ast = SLLV : regregreg
function clause decode (0b000000 @ rs : regno @ rt : regno @ rd : regno @ 0b00000 @ 0b000100) =
Some(SLLV(rs, rt, rd))
function clause execute (SLLV(rs, rt, rd)) =
{
- sa = (rGPR(rs))[4..0];
- wGPR(rd) = EXTZ((rGPR(rt)) [31 - sa .. 0] : (bitzero ^^ sa))
+ sa = rGPR(rs)[4..0];
+ rt32 = rGPR(rt)[31..0];
+ wGPR(rd) = EXTS(rt32 << sa)
}
/* SRA 32-bit arithmetic shift right */
-union ast member regregreg SRA
+union clause ast = SRA : regregreg
function clause decode (0b000000 @ 0b00000 @ rt : regno @ rd : regno @ sa : regno @ 0b000011) =
Some(SRA(rt, rd, sa))
function clause execute (SRA(rt, rd, sa)) =
@@ -476,28 +474,32 @@ function clause execute (SRA(rt, rd, sa)) =
temp = rGPR(rt);
if (NotWordVal(temp)) then
wGPR(rd) = undefined
- else
- wGPR(rd) = EXTZ((temp[31] ^^ (sa+32)) : temp [31..sa])
+ else {
+ rt32 = temp[31..0];
+ wGPR(rd) = EXTS(rt32 >>_s sa);
+ }
}
/* SRAV 32-bit arithmetic shift right variable */
-union ast member regregreg SRAV
+union clause ast = SRAV : regregreg
function clause decode (0b000000 @ rs : regno @ rt : regno @ rd : regno @ 0b00000 @ 0b000111) =
Some(SRAV(rs, rt, rd))
function clause execute (SRAV(rs, rt, rd)) =
{
temp = rGPR(rt);
- sa = (rGPR(rs))[4..0];
+ sa = rGPR(rs)[4..0];
if (NotWordVal(temp)) then
wGPR(rd) = undefined
- else
- wGPR(rd) = EXTZ((temp[31] ^^ (sa+32)) : temp [31..sa])
+ else {
+ rt32 = temp[31..0];
+ wGPR(rd) = EXTS(rt32 >>_s sa)
+ }
}
/* SRL 32-bit shift right */
-union ast member regregreg SRL
+union clause ast = SRL : regregreg
function clause decode (0b000000 @ 0b00000 @ rt : regno @ rd : regno @ sa : regno @ 0b000010) =
Some(SRL(rt, rd, sa))
function clause execute (SRL(rt, rd, sa)) =
@@ -505,13 +507,15 @@ function clause execute (SRL(rt, rd, sa)) =
temp = rGPR(rt);
if (NotWordVal(temp)) then
wGPR(rd) = undefined
- else
- wGPR(rd) = EXTZ((bitzero ^^ sa) : (temp [31..sa]))
+ else {
+ rt32 = temp[31..0];
+ wGPR(rd) = EXTS(rt32 >> sa);
+ }
}
/* SRLV 32-bit shift right variable */
-union ast member regregreg SRLV
+union clause ast = SRLV : regregreg
function clause decode (0b000000 @ rs : regno @ rt : regno @ rd : regno @ 0b00000 @ 0b000110) =
Some(SRLV(rs, rt, rd))
function clause execute (SRLV(rs, rt, rd)) =
@@ -520,8 +524,10 @@ function clause execute (SRLV(rs, rt, rd)) =
sa = (rGPR(rs))[4..0];
if (NotWordVal(temp)) then
wGPR(rd) = undefined
- else
- wGPR(rd) = EXTZ((bitzero ^^ sa) : (temp [31..sa]))
+ else {
+ rt32 = temp[31..0];
+ wGPR(rd) = EXTS(rt32 >> sa);
+ }
}
/**************************************************************************************/
@@ -530,53 +536,53 @@ function clause execute (SRLV(rs, rt, rd)) =
/* SLT set if less than (signed) */
-union ast member regregreg SLT
+union clause ast = SLT : regregreg
function clause decode (0b000000 @ rs : regno @ rt : regno @ rd : regno @ 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
+ wGPR(rd) = EXTZ(if (rGPR(rs) <_s rGPR(rt)) then 0b1 else 0b0)
}
/* SLT set if less than immediate (signed) */
-union ast member regregimm16 SLTI
+union clause ast = SLTI : regregimm16
function clause decode (0b001010 @ rs : regno @ rt : regno @ imm : imm16) =
Some(SLTI(rs, rt, imm))
function clause execute (SLTI(rs, rt, imm)) =
{
- let imm_val in : = signed(imm)
- let rs_val in : = signed(rGPR(rs))
- wGPR(rt) = if (rs_val 0x0000000000000000 : < imm_val) then 0x0000000000000001 else
+ let imm_val = signed(imm) in
+ let rs_val = signed(rGPR(rs)) in
+ wGPR(rt) = EXTZ(if (rs_val < imm_val) then 0b1 else 0b0)
}
/* SLTU set if less than unsigned */
-union ast member regregreg SLTU
+union clause ast = SLTU : regregreg
function clause decode (0b000000 @ rs : regno @ rt : regno @ rd : regno @ 0b00000 @ 0b101011) =
Some(SLTU(rs, rt, rd))
function clause execute (SLTU(rs, rt, rd)) =
{
- let rs_val in : = (0b0 : (rGPR(rs)))
- let rt_val in : = (0b0 : (rGPR(rt)))
- wGPR(rd) = (if (rs_val 0 : < rt_val) then 1 else)
+ let rs_val = rGPR(rs) in
+ let rt_val = rGPR(rt) in
+ wGPR(rd) = EXTZ(if (rs_val <_u rt_val) then 0b1 else 0b0)
}
/* SLTIU set if less than immediate unsigned */
-union ast member regregimm16 SLTIU
+union clause ast = SLTIU : regregimm16
function clause decode (0b001011 @ rs : regno @ rt : regno @ imm : imm16) =
Some(SLTIU(rs, rt, imm))
function clause execute (SLTIU(rs, rt, imm)) =
{
- let rs_val in : = (0b0 : (rGPR(rs)))
- let imm_val in : = (0b0 : ((bits(64))(EXTS(imm))))
- wGPR(rt) = (if (rs_val 0 : < imm_val) then 1 else)
+ let rs_val = unsigned(rGPR(rs)) in
+ let imm_val = unsigned(imm) in
+ wGPR(rt) = EXTZ(if (rs_val < imm_val) then 0b1 else 0b0)
}
/* MOVN move if non-zero */
-union ast member regregreg MOVN
+union clause ast = MOVN : regregreg
function clause decode (0b000000 @ rs : regno @ rt : regno @ rd : regno @ 0b00000 @ 0b001011) =
Some(MOVN(rs, rt, rd))
function clause execute (MOVN(rs, rt, rd)) =
@@ -587,7 +593,7 @@ function clause execute (MOVN(rs, rt, rd)) =
/* MOVZ move if zero */
-union ast member regregreg MOVZ
+union clause ast = MOVZ : regregreg
function clause decode (0b000000 @ rs : regno @ rt : regno @ rd : regno @ 0b00000 @ 0b001010) =
Some(MOVZ(rs, rt, rd))
function clause execute (MOVZ(rs, rt, rd)) =
@@ -601,7 +607,7 @@ function clause execute (MOVZ(rs, rt, rd)) =
/******************************************************************************/
/* MFHI move from HI register */
-union ast member regno MFHI
+union clause ast = MFHI : regno
function clause decode (0b000000 @ 0b0000000000 @ rd : regno @ 0b00000 @ 0b010000) =
Some(MFHI(rd))
function clause execute (MFHI(rd)) =
@@ -610,7 +616,7 @@ function clause execute (MFHI(rd)) =
}
/* MFLO move from LO register */
-union ast member regno MFLO
+union clause ast = MFLO : regno
function clause decode (0b000000 @ 0b0000000000 @ rd : regno @ 0b00000 @ 0b010010) =
Some(MFLO(rd))
function clause execute (MFLO(rd)) =
@@ -619,7 +625,7 @@ function clause execute (MFLO(rd)) =
}
/* MTHI move to HI register */
-union ast member regno MTHI
+union clause ast = MTHI : regno
function clause decode (0b000000 @ rs : regno @ 0b000000000000000 @ 0b010001) =
Some(MTHI(rs))
function clause execute (MTHI(rs)) =
@@ -628,7 +634,7 @@ function clause execute (MTHI(rs)) =
}
/* MTLO move to LO register */
-union ast member regno MTLO
+union clause ast = MTLO : regno
function clause decode (0b000000 @ rs : regno @ 0b000000000000000 @ 0b010011) =
Some(MTLO(rs))
function clause execute (MTLO(rs)) =
@@ -637,14 +643,14 @@ function clause execute (MTLO(rs)) =
}
/* MUL 32-bit multiply into GPR */
-union ast member regregreg MUL
+union clause ast = MUL : regregreg
function clause decode (0b011100 @ rs : regno @ rt : regno @ rd : regno @ 0b00000 @ 0b000010) =
Some(MUL(rs, rt, rd))
function clause execute (MUL(rs, rt, rd)) =
{
rsVal = rGPR(rs);
rtVal = rGPR(rt);
- (bits(64)) result = EXTS((rsVal[31..0]) *_s (rtVal[31..0]));
+ result : bits(64) = EXTS((rsVal[31..0]) *_s (rtVal[31..0]));
wGPR(rd) = if (NotWordVal(rsVal) | NotWordVal(rtVal)) then
undefined
else
@@ -657,144 +663,144 @@ function clause execute (MUL(rs, rt, rd)) =
}
/* MULT 32-bit multiply into HI/LO */
-union ast member (regno, regno) MULT
+union clause ast = MULT : (regno, regno)
function clause decode (0b000000 @ rs : regno @ rt : regno @ 0b00000 @ 0b00000 @ 0b011000) =
Some(MULT(rs, rt))
function clause execute (MULT(rs, rt)) =
{
rsVal = rGPR(rs);
rtVal = rGPR(rt);
- (bits(64)) result = if (NotWordVal(rsVal) | NotWordVal(rtVal)) then
+ result : bits(64) = if (NotWordVal(rsVal) | NotWordVal(rtVal)) then
undefined
else
- EXTS((rsVal[31..0]) *_s (rtVal[31..0]));
+ (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
+union clause ast = MULTU : (regno, regno)
function clause decode (0b000000 @ rs : regno @ rt : regno @ 0b00000 @ 0b00000 @ 0b011001) =
Some(MULTU(rs, rt))
function clause execute (MULTU(rs, rt)) =
{
rsVal = rGPR(rs);
rtVal = rGPR(rt);
- (bits(64)) result = if (NotWordVal(rsVal) | NotWordVal(rtVal)) then
+ result : bits(64) = if (NotWordVal(rsVal) | NotWordVal(rtVal)) then
undefined
else
- EXTS((rsVal[31..0]) * (rtVal[31..0]));
+ (rsVal[31..0]) *_u (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
+union clause ast = DMULT : (regno, regno)
function clause decode (0b000000 @ rs : regno @ rt : regno @ 0b00000 @ 0b00000 @ 0b011100) =
Some(DMULT(rs, rt))
function clause execute (DMULT(rs, rt)) =
{
- (bits(128)) result = rGPR(rs) *_s rGPR(rt);
+ 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
+union clause ast = DMULTU : (regno, regno)
function clause decode (0b000000 @ rs : regno @ rt : regno @ 0b00000 @ 0b00000 @ 0b011101) =
Some(DMULTU(rs, rt))
function clause execute (DMULTU(rs, rt)) =
{
- (bits(128)) result = rGPR(rs) * rGPR(rt);
+ result = rGPR(rs) *_u 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
+union clause ast = MADD : (regno, regno)
function clause decode (0b011100 @ rs : regno @ rt : regno @ 0b00000 @ 0b00000 @ 0b000000) =
Some(MADD(rs, rt))
function clause execute (MADD(rs, rt)) =
{
rsVal = rGPR(rs);
rtVal = rGPR(rt);
- (bits(64)) mul_result = if (NotWordVal(rsVal) | NotWordVal(rtVal)) then
+ mul_result : bits(64) = if (NotWordVal(rsVal) | NotWordVal(rtVal)) then
undefined
else
rsVal[31..0] *_s rtVal[31..0];
- (bits(64)) result = mul_result + (HI[31..0] : LO[31..0]);
+ 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
+union clause ast = MADDU : (regno, regno)
function clause decode (0b011100 @ rs : regno @ rt : regno @ 0b00000 @ 0b00000 @ 0b000001) =
Some(MADDU(rs, rt))
function clause execute (MADDU(rs, rt)) =
{
rsVal = rGPR(rs);
rtVal = rGPR(rt);
- (bits(64)) mul_result = if (NotWordVal(rsVal) | NotWordVal(rtVal)) then
+ mul_result : bits(64) = if (NotWordVal(rsVal) | NotWordVal(rtVal)) then
undefined
else
- rsVal[31..0] * rtVal[31..0];
- (bits(64)) result = mul_result + (HI[31..0] : LO[31..0]);
+ rsVal[31..0] *_u rtVal[31..0];
+ 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
+union clause ast = MSUB : (regno, regno)
function clause decode (0b011100 @ rs : regno @ rt : regno @ 0b00000 @ 0b00000 @ 0b000100) =
Some(MSUB(rs, rt))
function clause execute (MSUB(rs, rt)) =
{
rsVal = rGPR(rs);
rtVal = rGPR(rt);
- (bits(64)) mul_result = if (NotWordVal(rsVal) | NotWordVal(rtVal)) then
+ mul_result : bits(64) = if (NotWordVal(rsVal) | NotWordVal(rtVal)) then
undefined
else
rsVal[31..0] *_s rtVal[31..0];
- (bits(64)) result = (HI[31..0] : LO[31..0]) - mul_result;
+ 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
+union clause ast = MSUBU : (regno, regno)
function clause decode (0b011100 @ rs : regno @ rt : regno @ 0b00000 @ 0b00000 @ 0b000101) =
Some(MSUBU(rs, rt))
function clause execute (MSUBU(rs, rt)) =
{
rsVal = rGPR(rs);
rtVal = rGPR(rt);
- (bits(64)) mul_result = if (NotWordVal(rsVal) | NotWordVal(rtVal)) then
+ mul_result : bits(64) = if (NotWordVal(rsVal) | NotWordVal(rtVal)) then
undefined
else
- rsVal[31..0] * rtVal[31..0];
- (bits(64)) result = (HI[31..0] : LO[31..0]) - mul_result;
+ rsVal[31..0] *_u rtVal[31..0];
+ 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
+union clause ast = DIV : (regno, regno)
function clause decode (0b000000 @ rs : regno @ rt : regno @ 0b00000 @ 0b00000 @ 0b011010) =
Some(DIV(rs, rt))
function clause execute (DIV(rs, rt)) =
{
rsVal = rGPR(rs);
rtVal = rGPR(rt);
- let q : (bits(32), (bits(32))r) = (
- if (NotWordVal(rsVal) | NotWordVal(rtVal) | (rtVal == 0)) then
- ((bits(32)) undefined, (bits(32)) undefined)
+ let (q, r) =
+ if (NotWordVal(rsVal) | NotWordVal(rtVal) | (rtVal == 0x0000000000000000)) then
+ (undefined : bits(32), undefined : bits(32))
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
- ((bits(32)) (to_svec(qi)), (bits(32)) (to_svec(ri))))
+ let si = signed((rsVal[31..0])) in
+ let ti = signed((rtVal[31..0])) in
+ let qi = quot_round_zero(si, ti) in
+ let ri = si - (ti*qi) in
+ (to_bits(32, qi), to_bits(32, ri))
in
{
HI = EXTS(r);
@@ -803,22 +809,22 @@ function clause execute (DIV(rs, rt)) =
}
/* DIVU 32-bit unsigned divide into HI/LO */
-union ast member (regno, regno) DIVU
+union clause ast = DIVU : (regno, regno)
function clause decode (0b000000 @ rs : regno @ rt : regno @ 0b00000 @ 0b00000 @ 0b011011) =
Some(DIVU(rs, rt))
function clause execute (DIVU(rs, rt)) =
{
rsVal = rGPR(rs);
rtVal = rGPR(rt);
- let q : (bits(32), (bits(32))r) = (
- if (NotWordVal(rsVal) | NotWordVal(rtVal) | rtVal == 0) then
- ((bits(32)) undefined, (bits(32)) undefined)
+ let (q, r) =
+ if (NotWordVal(rsVal) | NotWordVal(rtVal) | rtVal == 0x0000000000000000) then
+ (undefined : bits(32), undefined : bits(32))
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
- ((bits(32)) (to_svec(qi)), (bits(32)) (to_svec(ri))))
+ let qi = quot_round_zero(si, ti) in
+ let ri = rem_round_zero(si, ti) in
+ (to_bits(32, qi), to_bits(32, ri))
in
{
HI = EXTS(r);
@@ -827,19 +833,20 @@ function clause execute (DIVU(rs, rt)) =
}
/* DDIV 64-bit divide into HI/LO */
-union ast member (regno, regno) DDIV
+union clause ast = DDIV : (regno, regno)
function clause decode (0b000000 @ rs : regno @ rt : regno @ 0b00000 @ 0b00000 @ 0b011110) =
Some(DDIV(rs, rt))
function clause execute (DDIV(rs, rt)) =
{
rsVal = signed(rGPR(rs));
rtVal = signed(rGPR(rt));
- let ((bits(64))q, (bits(64))r) = (if (rtVal == 0)
- then ((bits(64)) undefined, (bits(64)) undefined)
+ let (q , r) =
+ if (rtVal == 0)
+ then (undefined : bits(64), undefined : bits(64))
else
- let qi = (rsVal quot rtVal) in
- let ri = (rsVal - (qi * rtVal)) in
- ((bits(64)) (to_svec(qi)), (bits(64)) (to_svec(ri)))) in
+ let qi = quot_round_zero(rsVal, rtVal) in
+ let ri = (rsVal - (qi * rtVal)) in
+ (to_bits(64, qi), to_bits(64, ri)) in
{
LO = q;
HI = r;
@@ -847,18 +854,20 @@ function clause execute (DDIV(rs, rt)) =
}
/* DDIV 64-bit divide into HI/LO */
-union ast member (regno, regno) DDIVU
+union clause ast = DDIVU : (regno, regno)
function clause decode (0b000000 @ rs : regno @ rt : regno @ 0b00000 @ 0b00000 @ 0b011111) =
Some(DDIVU(rs, rt))
function clause execute (DDIVU(rs, rt)) =
{
- (int) rsVal = rGPR(rs);
- (int) rtVal = rGPR(rt);
- let ((bits(64))q, (bits(64))r) = (if (rtVal == 0)
- then ((bits(64)) undefined, (bits(64)) undefined)
- else let qi = (rsVal quot rtVal) in
- let ri = (rsVal mod rtVal) in
- ((bits(64)) (to_svec(qi)), (bits(64)) (to_svec(ri)))) in
+ rsVal = unsigned(rGPR(rs));
+ rtVal = unsigned(rGPR(rt));
+ let (q, r) =
+ if (rtVal == 0)
+ then (undefined : bits(64), undefined : bits(64))
+ else
+ let qi = quot_round_zero(rsVal, rtVal) in
+ let ri = rem_round_zero(rsVal, rtVal) in
+ (to_bits(64, qi), to_bits(64, ri)) in
{
LO = q;
HI = r;
@@ -870,44 +879,44 @@ function clause execute (DDIVU(rs, rt)) =
/**************************************************************************************/
/* J - jump, the simplest control flow instruction, with branch delay slot */
-union ast member (bits(26)) J
-function clause decode (0b000010 @ (bits(26)) offset) =
+union clause ast = J : bits(26)
+function clause decode (0b000010 @ offset : bits(26)) =
Some(J(offset))
function clause execute (J(offset)) =
{
- delayedPC = (PC + 4)[63..28] : offset : 0b00;
- branchPending = 1
+ delayedPC = (PC + 4)[63..28] @ offset @ 0b00;
+ branchPending = 0b1
}
/* JAL - jump and link */
-union ast member (bits(26)) JAL
-function clause decode (0b000011 @ (bits(26)) offset) =
+union clause ast = JAL : bits(26)
+function clause decode (0b000011 @ offset : bits(26)) =
Some(JAL(offset))
function clause execute (JAL(offset)) =
{
- delayedPC = (PC + 4)[63..28] : offset : 0b00;
- branchPending = 1;
+ delayedPC = (PC + 4)[63..28] @ offset @ 0b00;
+ branchPending = 0b1;
wGPR(0b11111) = PC + 8;
}
/* JR -- jump via register */
-union ast member regno JR
+union clause ast = JR : regno
function clause decode (0b000000 @ rs : regno @ 0b00000 @ 0b00000 @ hint : regno @ 0b001000) =
Some(JR(rs)) /* hint is ignored */
function clause execute (JR(rs)) =
{
delayedPC = rGPR(rs);
- branchPending = 1;
+ branchPending = 0b1;
}
/* JALR -- jump via register with link */
-union ast member (regno, regno) JALR
+union clause ast = JALR : (regno, regno)
function clause decode (0b000000 @ rs : regno @ 0b00000 @ rd : regno @ hint : regno @ 0b001001) =
Some(JALR(rs, rd)) /* hint is ignored */
function clause execute (JALR(rs, rd)) =
{
delayedPC = rGPR(rs);
- branchPending = 1;
+ branchPending = 0b1;
wGPR(rd) = PC + 8;
}
@@ -916,7 +925,7 @@ function clause execute (JALR(rs, rd)) =
/* Conditional branch instructions with two register operands */
/**************************************************************************************/
-union ast member (regno, regno, imm16, bool, bool) BEQ
+union clause ast = BEQ : (regno, regno, imm16, bool, bool)
function clause decode (0b000100 @ rs : regno @ rt : regno @ imm : imm16) =
Some(BEQ(rs, rt, imm, false, false)) /* BEQ */
function clause decode (0b010100 @ rs : regno @ rt : regno @ imm : imm16) =
@@ -929,9 +938,9 @@ function clause execute (BEQ(rs, rd, imm, ne, likely)) =
{
if ((rGPR(rs) == rGPR(rd)) ^ ne) then
{
- let offset : bits(64) = (EXTS(imm : 0b00) + 4) in
+ let offset : bits(64) = (EXTS(imm @ 0b00) + 4) in
delayedPC = PC + offset;
- branchPending = 1;
+ branchPending = 0b1;
}
else
{
@@ -950,7 +959,7 @@ function clause execute (BEQ(rs, rd, imm, ne, likely)) =
/* Conditional branch instructions with single register operand */
/**************************************************************************************/
-union ast member (regno, imm16, Comparison, bool, bool) BCMPZ
+union clause ast = BCMPZ : (regno, imm16, Comparison, bool, bool)
function clause decode (0b000001 @ rs : regno @ 0b00000 @ imm : imm16) =
Some(BCMPZ(rs, imm, LT, false, false)) /* BLTZ */
function clause decode (0b000001 @ rs : regno @ 0b10000 @ imm : imm16) =
@@ -981,14 +990,14 @@ function clause decode (0b010110 @ rs : regno @ 0b00000 @ imm : imm16) =
function clause execute (BCMPZ(rs, imm, cmp, link, likely)) =
{
- (bits(64)) linkVal = PC + 8;
+ linkVal = PC + 8;
regVal = rGPR(rs);
- condition = compare(cmp, regVal, 0);
+ condition = compare(cmp, regVal, EXTZ(0b0));
if (condition) then
{
- let offset : bits(64) = (EXTS(imm : 0b00) + 4) in
+ let offset : bits(64) = (EXTS(imm @ 0b00) + 4) in
delayedPC = PC + offset;
- branchPending = 1;
+ branchPending = 0b1;
}
else if (likely) then
{
@@ -1003,62 +1012,62 @@ function clause execute (BCMPZ(rs, imm, cmp, link, likely)) =
/**************************************************************************************/
/* Co-opt syscall 0xfffff for use as thread start in pccmem */
-union ast member unit SYSCALL_THREAD_START
+union clause ast = SYSCALL_THREAD_START : unit
function clause decode (0b000000 @ 0xfffff @ 0b001100) =
- Some((ast) SYSCALL_THREAD_START)
+ 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
+union clause ast = ImplementationDefinedStopFetching : unit
function clause execute (ImplementationDefinedStopFetching) = ()
-union ast member unit SYSCALL
-function clause decode (0b000000 @ (bits(20)) code @ 0b001100) =
- Some((ast) SYSCALL) /* code is ignored */
+union clause ast = SYSCALL : unit
+function clause decode (0b000000 @ code : bits(20) @ 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 @ (bits(20)) code @ 0b001101) =
- Some((ast) BREAK) /* code is ignored */
+union clause ast = BREAK : unit
+function clause decode (0b000000 @ code : bits(20) @ 0b001101) =
+ Some(BREAK) /* code is ignored */
function clause execute (BREAK) =
{
(SignalException(Bp))
}
/* Accept WAIT as a NOP */
-union ast member unit WAIT
+union clause ast = WAIT : unit
function clause decode (0b010000 @ 0x80000 @ 0b100000) =
- Some((ast) WAIT) /* we only accept code == 0 */
+ 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 @ rs : regno @ rt : regno @ (bits(10)) code @ 0b110000) =
+union clause ast = TRAPREG : (regno, regno, Comparison)
+function clause decode (0b000000 @ rs : regno @ rt : regno @ code : bits(10) @ 0b110000) =
Some(TRAPREG(rs, rt, GE)) /* TGE */
-function clause decode (0b000000 @ rs : regno @ rt : regno @ (bits(10)) code @ 0b110001) =
+function clause decode (0b000000 @ rs : regno @ rt : regno @ code : bits(10) @ 0b110001) =
Some(TRAPREG(rs, rt, GEU)) /* TGEU */
-function clause decode (0b000000 @ rs : regno @ rt : regno @ (bits(10)) code @ 0b110010) =
+function clause decode (0b000000 @ rs : regno @ rt : regno @ code : bits(10) @ 0b110010) =
Some(TRAPREG(rs, rt, LT)) /* TLT */
-function clause decode (0b000000 @ rs : regno @ rt : regno @ (bits(10)) code @ 0b110011) =
+function clause decode (0b000000 @ rs : regno @ rt : regno @ code : bits(10) @ 0b110011) =
Some(TRAPREG(rs, rt, LTU)) /* TLTU */
-function clause decode (0b000000 @ rs : regno @ rt : regno @ (bits(10)) code @ 0b110100) =
+function clause decode (0b000000 @ rs : regno @ rt : regno @ code : bits(10) @ 0b110100) =
Some(TRAPREG(rs, rt, EQ)) /* TEQ */
-function clause decode (0b000000 @ rs : regno @ rt : regno @ (bits(10)) code @ 0b110110) =
+function clause decode (0b000000 @ rs : regno @ rt : regno @ code : bits(10) @ 0b110110) =
Some(TRAPREG(rs, rt, NE)) /* TNE */
function clause execute (TRAPREG(rs, rt, cmp)) =
{
- rs_val rGPR : =(rs);
- rt_val rGPR : =(rt);
+ rs_val = rGPR(rs);
+ rt_val = rGPR(rt);
condition = compare(cmp, rs_val, rt_val);
if (condition) then
(SignalException(Tr))
@@ -1066,7 +1075,7 @@ function clause execute (TRAPREG(rs, rt, cmp)) =
/* Trap instructions with one register and one immediate operand */
-union ast member (regno, imm16, Comparison) TRAPIMM
+union clause ast = TRAPIMM : (regno, imm16, Comparison)
function clause decode (0b000001 @ rs : regno @ 0b01100 @ imm : imm16) =
Some(TRAPIMM(rs, imm, EQ)) /* TEQI */
function clause decode (0b000001 @ rs : regno @ 0b01110 @ imm : imm16) =
@@ -1081,8 +1090,8 @@ function clause decode (0b000001 @ rs : regno @ 0b01011 @ imm : imm16) =
Some(TRAPIMM(rs, imm, LTU)) /* TLTIU */
function clause execute (TRAPIMM(rs, imm, cmp)) =
{
- rs_val rGPR : =(rs);
- (bits(64)) imm_val EXTS : =(imm);
+ rs_val = rGPR(rs);
+ imm_val : bits(64) = EXTS(imm);
condition = compare(cmp, rs_val, imm_val);
if (condition) then
(SignalException(Tr))
@@ -1092,7 +1101,7 @@ function clause execute (TRAPIMM(rs, imm, cmp)) =
/* Load instructions -- various width/signs */
/**************************************************************************************/
-union ast member (WordType, bool, bool, regno, regno, imm16) Load
+union clause ast = Load : (WordType, bool, bool, regno, regno, imm16)
function clause decode (0b100000 @ base : regno @ rt : regno @ offset : imm16) =
Some(Load(B, true, false, base, rt, offset)) /* LB */
function clause decode (0b100100 @ base : regno @ rt : regno @ offset : imm16) =
@@ -1112,39 +1121,41 @@ function clause decode (0b110000 @ base : regno @ rt : regno @ offset : imm16) =
function clause decode (0b110100 @ base : regno @ rt : regno @ offset : imm16) =
Some(Load(D, false, true, base, rt, offset)) /* LLD */
-val extendLoad : forall 'sz. (bits('sz), bool) -> bits(64) effect pure
-function extendLoad(memResult, signed) = {
- if (signed) then
+val extendLoad : forall 'sz, 'sz <= 64 . (bits('sz), bool) -> bits(64) effect pure
+function extendLoad(memResult, sign) = {
+ if (sign) then
EXTS(memResult)
else
EXTZ(memResult)
}
-function clause execute (Load(width, signed, linked, base, rt, offset)) =
+function clause execute (Load(width, sign, linked, base, rt, offset)) =
{
- (bits(64)) vAddr = addrWrapper(EXTS(offset) + rGPR(base), LoadData, width);
+ vAddr : bits(64) = addrWrapper(EXTS(offset) + rGPR(base), LoadData, width);
if ~ (isAddressAligned(vAddr, width)) then
(SignalExceptionBadAddr(AdEL, vAddr)) /* unaligned access */
else
let pAddr = (TLBTranslate(vAddr, LoadData)) in
{
- (bits(64)) memResult = if (linked) then
+ memResult : bits(64) = if (linked) then
{
CP0LLBit = 0b1;
CP0LLAddr = pAddr;
- w = wordWidthBytes(width);
- if w == 1 then extendLoad(MEMr_reserve_wrapper(pAddr, 1), signed)
- else if w == 2 then extendLoad(MEMr_reserve_wrapper(pAddr, 2), signed)
- else if w == 4 then extendLoad(MEMr_reserve_wrapper(pAddr, 4), signed)
- else extendLoad(MEMr_reserve_wrapper(pAddr, 8), signed)
+ match width {
+ B => extendLoad(MEMr_reserve_wrapper(pAddr, 1), sign),
+ H => extendLoad(MEMr_reserve_wrapper(pAddr, 2), sign),
+ W => extendLoad(MEMr_reserve_wrapper(pAddr, 4), sign),
+ D => extendLoad(MEMr_reserve_wrapper(pAddr, 8), sign)
+ }
}
else
{
- w = wordWidthBytes(width);
- if w == 1 then extendLoad(MEMr_reserve_wrapper(pAddr, 1), signed)
- else if w == 2 then extendLoad(MEMr_reserve_wrapper(pAddr, 2), signed)
- else if w == 4 then extendLoad(MEMr_reserve_wrapper(pAddr, 4), signed)
- else extendLoad(MEMr_reserve_wrapper(pAddr, 8), signed);
+ match width {
+ B => extendLoad(MEMr_wrapper(pAddr, 1), sign),
+ H => extendLoad(MEMr_wrapper(pAddr, 2), sign),
+ W => extendLoad(MEMr_wrapper(pAddr, 4), sign),
+ D => extendLoad(MEMr_wrapper(pAddr, 8), sign)
+ }
};
wGPR(rt) = memResult
}
@@ -1154,7 +1165,7 @@ function clause execute (Load(width, signed, linked, base, rt, offset)) =
/* Store instructions -- various widths */
/**************************************************************************************/
-union ast member (WordType, bool, regno, regno, imm16) Store
+union clause ast = Store : (WordType, bool, regno, regno, imm16)
function clause decode (0b101000 @ base : regno @ rt : regno @ offset : imm16) =
Some(Store(B, false, base, rt, offset)) /* SB */
function clause decode (0b101001 @ base : regno @ rt : regno @ offset : imm16) =
@@ -1169,8 +1180,8 @@ function clause decode (0b111100 @ base : regno @ rt : regno @ offset : imm16) =
Some(Store(D, true, base, rt, offset)) /* SCD */
function clause execute (Store(width, conditional, base, rt, offset)) =
{
- (bits(64)) vAddr = addrWrapper(EXTS(offset) + rGPR(base), StoreData, width);
- (bits(64)) rt_val rGPR : =(rt);
+ vAddr : bits(64) = addrWrapper(EXTS(offset) + rGPR(base), StoreData, width);
+ rt_val = rGPR(rt);
if ~ (isAddressAligned(vAddr, width)) then
(SignalExceptionBadAddr(AdES, vAddr)) /* unaligned access */
else
@@ -1178,21 +1189,21 @@ function clause execute (Store(width, conditional, base, rt, offset)) =
{
if (conditional) then
{
- success = if (CP0LLBit[0]) then (bool) match width
+ success : bool = if (CP0LLBit[0]) then match width
{
- B => MEMw_conditional_wrapper(pAddr, 1, rt_val[7..0])
- H => MEMw_conditional_wrapper(pAddr, 2, rt_val[15..0])
- W => MEMw_conditional_wrapper(pAddr, 4, rt_val[31..0])
+ B => MEMw_conditional_wrapper(pAddr, 1, rt_val[7..0]),
+ H => MEMw_conditional_wrapper(pAddr, 2, rt_val[15..0]),
+ W => MEMw_conditional_wrapper(pAddr, 4, rt_val[31..0]),
D => MEMw_conditional_wrapper(pAddr, 8, rt_val)
} else false;
- wGPR(rt) = EXTZ([bool_to_bit(success)])
+ wGPR(rt) = EXTZ(success)
}
else
match width
{
- B => MEMw_wrapper(pAddr, 1) = rt_val[7..0]
- H => MEMw_wrapper(pAddr, 2) = rt_val[15..0]
- W => MEMw_wrapper(pAddr, 4) = rt_val[31..0]
+ B => MEMw_wrapper(pAddr, 1) = rt_val[7..0],
+ H => MEMw_wrapper(pAddr, 2) = rt_val[15..0],
+ W => MEMw_wrapper(pAddr, 4) = rt_val[31..0],
D => MEMw_wrapper(pAddr, 8) = rt_val
}
}
@@ -1200,161 +1211,163 @@ function clause execute (Store(width, conditional, base, rt, offset)) =
/* LWL - Load word left (big-endian only) */
-union ast member regregimm16 LWL
+union clause ast = LWL : regregimm16
function clause decode(0b100010 @ base : regno @ rt : regno @ offset : imm16) =
Some(LWL(base, rt, offset))
function clause execute(LWL(base, rt, offset)) =
{
/* XXX length check not quite right, but conservative */
- (bits(64)) vAddr = addrWrapper(EXTS(offset) + rGPR(base), LoadData, W);
+ vAddr = addrWrapper(EXTS(offset) + rGPR(base), LoadData, W);
let pAddr = (TLBTranslate(vAddr, LoadData)) in
{
- mem_val interest : = MEMr_wrapper (pAddr[63..2] : 0b00, 4); /* read word of */
- reg_val rGPR : =(rt);
- wGPR(rt) = EXTS((bits(32)) match vAddr[1..0]
+ mem_val = MEMr_wrapper (pAddr[63..2] @ 0b00, 4); /* read word of interest */
+ reg_val = rGPR(rt);
+ result : bits(32) = match vAddr[1..0]
{
- 0b00 => mem_val
- 0b01 => mem_val[23..0] : reg_val[07..0]
- 0b10 => mem_val[15..0] : reg_val[15..0]
- 0b11 => mem_val[07..0] : reg_val[23..0]
- });
+ 0b00 => mem_val,
+ 0b01 => mem_val[23..0] @ reg_val[07..0],
+ 0b10 => mem_val[15..0] @ reg_val[15..0],
+ 0b11 => mem_val[07..0] @ reg_val[23..0]
+ };
+ wGPR(rt) = EXTS(result);
}
}
-union ast member regregimm16 LWR
+union clause ast = LWR : regregimm16
function clause decode(0b100110 @ base : regno @ rt : regno @ offset : imm16) =
Some(LWR(base, rt, offset))
function clause execute(LWR(base, rt, offset)) =
{
/* XXX length check not quite right, but conservative */
- (bits(64)) vAddr = addrWrapper(EXTS(offset) + rGPR(base), LoadData, W);
+ vAddr = addrWrapper(EXTS(offset) + rGPR(base), LoadData, W);
let pAddr = (TLBTranslate(vAddr, LoadData)) in
{
- mem_val interest : = MEMr_wrapper (pAddr[63..2] : 0b00, 4); /* read word of */
- reg_val rGPR : =(rt);
- wGPR(rt) = EXTS((bits(32)) match vAddr[1..0] /* it is acceptable to sign extend in all cases */
+ mem_val = MEMr_wrapper(pAddr[63..2] @ 0b00, 4); /* read word of interest */
+ reg_val = rGPR(rt);
+ result : bits(32) = match vAddr[1..0]
{
- 0b00 => reg_val[31..8] : mem_val[31..24]
- 0b01 => reg_val[31..16] : mem_val[31..16]
- 0b10 => reg_val[31..24] : mem_val[31..8]
+ 0b00 => reg_val[31..8] @ mem_val[31..24],
+ 0b01 => reg_val[31..16] @ mem_val[31..16],
+ 0b10 => reg_val[31..24] @ mem_val[31..8],
0b11 => mem_val
- });
+ };
+ wGPR(rt) = EXTS(result)
}
}
/* SWL - Store word left */
-union ast member regregimm16 SWL
+union clause ast = SWL : regregimm16
function clause decode(0b101010 @ base : regno @ rt : regno @ offset : imm16) =
Some(SWL(base, rt, offset))
function clause execute(SWL(base, rt, offset)) =
{
/* XXX length check not quite right, but conservative */
- (bits(64)) vAddr = addrWrapper(EXTS(offset) + rGPR(base), StoreData, W);
- let pAddr = (TLBTranslate(vAddr, StoreData)) in
+ vAddr = addrWrapper(EXTS(offset) + rGPR(base), StoreData, W);
+ let pAddr = TLBTranslate(vAddr, StoreData) in
{
- reg_val rGPR : =(rt);
+ reg_val = rGPR(rt);
match vAddr[1..0]
{
- 0b00 => (MEMw_wrapper(pAddr, 4) = reg_val[31..0])
- 0b01 => (MEMw_wrapper(pAddr, 3) = reg_val[31..8])
- 0b10 => (MEMw_wrapper(pAddr, 2) = reg_val[31..16])
+ 0b00 => (MEMw_wrapper(pAddr, 4) = reg_val[31..0]),
+ 0b01 => (MEMw_wrapper(pAddr, 3) = reg_val[31..8]),
+ 0b10 => (MEMw_wrapper(pAddr, 2) = reg_val[31..16]),
0b11 => (MEMw_wrapper(pAddr, 1) = reg_val[31..24])
}
}
}
-union ast member regregimm16 SWR
+union clause ast = SWR : regregimm16
function clause decode(0b101110 @ base : regno @ rt : regno @ offset : imm16) =
Some(SWR(base, rt, offset))
function clause execute(SWR(base, rt, offset)) =
{
/* XXX length check not quite right, but conservative */
- (bits(64)) vAddr = addrWrapper(EXTS(offset) + rGPR(base), StoreData, W);
- let TLBTranslate : pAddr(vAddr, StoreData)) in
+ vAddr = addrWrapper(EXTS(offset) + rGPR(base), StoreData, W);
+ let pAddr = TLBTranslate(vAddr, StoreData) in
{
- wordAddr = pAddr[63..2] : 0b00;
- reg_val rGPR : =(rt);
+ wordAddr = pAddr[63..2] @ 0b00;
+ reg_val = rGPR(rt);
match vAddr[1..0]
{
- 0b00 => (MEMw_wrapper(wordAddr, 1) = reg_val[7..0])
- 0b01 => (MEMw_wrapper(wordAddr, 2) = reg_val[15..0])
- 0b10 => (MEMw_wrapper(wordAddr, 3) = reg_val[23..0])
+ 0b00 => (MEMw_wrapper(wordAddr, 1) = reg_val[7..0]),
+ 0b01 => (MEMw_wrapper(wordAddr, 2) = reg_val[15..0]),
+ 0b10 => (MEMw_wrapper(wordAddr, 3) = reg_val[23..0]),
0b11 => (MEMw_wrapper(wordAddr, 4) = reg_val[31..0])
}
}
}
/* Load double-word left */
-union ast member regregimm16 LDL
+union clause ast = LDL : regregimm16
function clause decode(0b011010 @ base : regno @ rt : regno @ offset : imm16) =
Some(LDL(base, rt, offset))
function clause execute(LDL(base, rt, offset)) =
{
/* XXX length check not quite right, but conservative */
- (bits(64)) vAddr = addrWrapper(EXTS(offset) + rGPR(base), LoadData, D);
- let pAddr = (TLBTranslate(vAddr, StoreData)) in
+ vAddr = addrWrapper(EXTS(offset) + rGPR(base), LoadData, D);
+ let pAddr = TLBTranslate(vAddr, StoreData) in
{
- mem_val interest : = MEMr_wrapper (pAddr[63..3] : 0b000, 8); /* read double of */
- reg_val rGPR : =(rt);
- wGPR(rt) = match vAddr[2..0]
+ mem_val = MEMr_wrapper(pAddr[63..3] @ 0b000, 8); /* read double of interest */
+ reg_val = rGPR(rt);
+ wGPR(rt) = match vAddr[2..0]
{
- 0b000 => mem_val
- 0b001 => mem_val[55..0] : reg_val[7..0]
- 0b010 => mem_val[47..0] : reg_val[15..0]
- 0b011 => mem_val[39..0] : reg_val[23..0]
- 0b100 => mem_val[31..0] : reg_val[31..0]
- 0b101 => mem_val[23..0] : reg_val[39..0]
- 0b110 => mem_val[15..0] : reg_val[47..0]
- 0b111 => mem_val[07..0] : reg_val[55..0]
+ 0b000 => mem_val,
+ 0b001 => mem_val[55..0] @ reg_val[7..0],
+ 0b010 => mem_val[47..0] @ reg_val[15..0],
+ 0b011 => mem_val[39..0] @ reg_val[23..0],
+ 0b100 => mem_val[31..0] @ reg_val[31..0],
+ 0b101 => mem_val[23..0] @ reg_val[39..0],
+ 0b110 => mem_val[15..0] @ reg_val[47..0],
+ 0b111 => mem_val[07..0] @ reg_val[55..0]
};
}
}
/* Load double-word right */
-union ast member regregimm16 LDR
+union clause ast = LDR : regregimm16
function clause decode(0b011011 @ base : regno @ rt : regno @ offset : imm16) =
Some(LDR(base, rt, offset))
function clause execute(LDR(base, rt, offset)) =
{
/* XXX length check not quite right, but conservative */
- (bits(64)) vAddr = addrWrapper(EXTS(offset) + rGPR(base), LoadData, D);
- let pAddr = (TLBTranslate(vAddr, StoreData)) in
+ vAddr = addrWrapper(EXTS(offset) + rGPR(base), LoadData, D);
+ let pAddr = TLBTranslate(vAddr, StoreData) in
{
- mem_val interest : = MEMr_wrapper (pAddr[63..3] : 0b000, 8); /* read double of */
- reg_val rGPR : =(rt);
+ mem_val = MEMr_wrapper(pAddr[63..3] @ 0b000, 8); /* read double of interest */
+ reg_val = rGPR(rt);
wGPR(rt) = match vAddr[2..0]
{
- 0b000 => reg_val[63..08] : mem_val[63..56]
- 0b001 => reg_val[63..16] : mem_val[63..48]
- 0b010 => reg_val[63..24] : mem_val[63..40]
- 0b011 => reg_val[63..32] : mem_val[63..32]
- 0b100 => reg_val[63..40] : mem_val[63..24]
- 0b101 => reg_val[63..48] : mem_val[63..16]
- 0b110 => reg_val[63..56] : mem_val[63..08]
+ 0b000 => reg_val[63..08] @ mem_val[63..56],
+ 0b001 => reg_val[63..16] @ mem_val[63..48],
+ 0b010 => reg_val[63..24] @ mem_val[63..40],
+ 0b011 => reg_val[63..32] @ mem_val[63..32],
+ 0b100 => reg_val[63..40] @ mem_val[63..24],
+ 0b101 => reg_val[63..48] @ mem_val[63..16],
+ 0b110 => reg_val[63..56] @ mem_val[63..08],
0b111 => mem_val
};
}
}
/* SDL - Store double-word left */
-union ast member regregimm16 SDL
+union clause ast = SDL : regregimm16
function clause decode(0b101100 @ base : regno @ rt : regno @ offset : imm16) =
Some(SDL(base, rt, offset))
function clause execute(SDL(base, rt, offset)) =
{
/* XXX length check not quite right, but conservative */
- (bits(64)) vAddr = addrWrapper(EXTS(offset) + rGPR(base), StoreData, D);
- let pAddr = (TLBTranslate(vAddr, StoreData)) in
+ vAddr = addrWrapper(EXTS(offset) + rGPR(base), StoreData, D);
+ let pAddr = TLBTranslate(vAddr, StoreData) in
{
- reg_val rGPR : =(rt);
+ reg_val = rGPR(rt);
match vAddr[2..0]
{
- 0b000 => (MEMw_wrapper(pAddr, 8) = reg_val[63..00])
- 0b001 => (MEMw_wrapper(pAddr, 7) = reg_val[63..08])
- 0b010 => (MEMw_wrapper(pAddr, 6) = reg_val[63..16])
- 0b011 => (MEMw_wrapper(pAddr, 5) = reg_val[63..24])
- 0b100 => (MEMw_wrapper(pAddr, 4) = reg_val[63..32])
- 0b101 => (MEMw_wrapper(pAddr, 3) = reg_val[63..40])
- 0b110 => (MEMw_wrapper(pAddr, 2) = reg_val[63..48])
+ 0b000 => (MEMw_wrapper(pAddr, 8) = reg_val[63..00]),
+ 0b001 => (MEMw_wrapper(pAddr, 7) = reg_val[63..08]),
+ 0b010 => (MEMw_wrapper(pAddr, 6) = reg_val[63..16]),
+ 0b011 => (MEMw_wrapper(pAddr, 5) = reg_val[63..24]),
+ 0b100 => (MEMw_wrapper(pAddr, 4) = reg_val[63..32]),
+ 0b101 => (MEMw_wrapper(pAddr, 3) = reg_val[63..40]),
+ 0b110 => (MEMw_wrapper(pAddr, 2) = reg_val[63..48]),
0b111 => (MEMw_wrapper(pAddr, 1) = reg_val[63..56])
}
}
@@ -1362,26 +1375,26 @@ function clause execute(SDL(base, rt, offset)) =
/* SDR - Store double-word right */
-union ast member regregimm16 SDR
+union clause ast = SDR : regregimm16
function clause decode(0b101101 @ base : regno @ rt : regno @ offset : imm16) =
Some(SDR(base, rt, offset))
function clause execute(SDR(base, rt, offset)) =
{
/* XXX length check not quite right, but conservative */
- (bits(64)) vAddr = addrWrapper(EXTS(offset) + rGPR(base), StoreData, D);
- let pAddr = (TLBTranslate(vAddr, StoreData)) in
+ vAddr = addrWrapper(EXTS(offset) + rGPR(base), StoreData, D);
+ let pAddr = TLBTranslate(vAddr, StoreData) in
{
- reg_val rGPR : =(rt);
- wordAddr = pAddr[63..3] : 0b000;
+ reg_val = rGPR(rt);
+ wordAddr = pAddr[63..3] @ 0b000;
match vAddr[2..0]
{
- 0b000 => (MEMw_wrapper(wordAddr, 1) = reg_val[07..0])
- 0b001 => (MEMw_wrapper(wordAddr, 2) = reg_val[15..0])
- 0b010 => (MEMw_wrapper(wordAddr, 3) = reg_val[23..0])
- 0b011 => (MEMw_wrapper(wordAddr, 4) = reg_val[31..0])
- 0b100 => (MEMw_wrapper(wordAddr, 5) = reg_val[39..0])
- 0b101 => (MEMw_wrapper(wordAddr, 6) = reg_val[47..0])
- 0b110 => (MEMw_wrapper(wordAddr, 7) = reg_val[55..0])
+ 0b000 => (MEMw_wrapper(wordAddr, 1) = reg_val[07..0]),
+ 0b001 => (MEMw_wrapper(wordAddr, 2) = reg_val[15..0]),
+ 0b010 => (MEMw_wrapper(wordAddr, 3) = reg_val[23..0]),
+ 0b011 => (MEMw_wrapper(wordAddr, 4) = reg_val[31..0]),
+ 0b100 => (MEMw_wrapper(wordAddr, 5) = reg_val[39..0]),
+ 0b101 => (MEMw_wrapper(wordAddr, 6) = reg_val[47..0]),
+ 0b110 => (MEMw_wrapper(wordAddr, 7) = reg_val[55..0]),
0b111 => (MEMw_wrapper(wordAddr, 8) = reg_val[63..0])
}
}
@@ -1389,7 +1402,7 @@ function clause execute(SDR(base, rt, offset)) =
/* CACHE - manipulate (non-existent) caches */
-union ast member regregimm16 CACHE
+union clause ast = CACHE : regregimm16
function clause decode (0b101111 @ base : regno @ op : regno @ imm : imm16) =
Some(CACHE(base, op, imm))
function clause execute (CACHE(base, op, imm)) =
@@ -1397,7 +1410,7 @@ function clause execute (CACHE(base, op, imm)) =
/* PREF - prefetching into (non-existent) caches */
-union ast member regregimm16 PREF
+union clause ast = PREF : regregimm16
function clause decode (0b110011 @ base : regno @ op : regno @ imm : imm16) =
Some(PREF(base, op, imm))
function clause execute (PREF(base, op, imm)) =
@@ -1405,242 +1418,245 @@ function clause execute (PREF(base, op, imm)) =
/* SYNC - Memory barrier */
-union ast member unit SYNC
+union clause ast = SYNC : unit
function clause decode (0b000000 @ 0b00000 @ 0b00000 @ 0b00000 @ stype : regno @ 0b001111) =
- Some((ast) SYNC) /* stype is currently ignored */
+ Some(SYNC) /* stype is currently ignored */
function clause execute(SYNC) =
MEM_sync()
-union ast member (regno, regno, bits(3), bool) MFC0
-function clause decode (0b010000 @ 0b00000 @ rt : regno @ rd : regno @ 0b00000000 @ (bits(3)) sel) =
+union clause ast = MFC0 : (regno, regno, bits(3), bool)
+function clause decode (0b010000 @ 0b00000 @ rt : regno @ rd : regno @ 0b00000000 @ sel : bits(3)) =
Some(MFC0(rt, rd, sel, false)) /* MFC0 */
-function clause decode (0b010000 @ 0b00001 @ rt : regno @ rd : regno @ 0b00000000 @ (bits(3)) sel) =
+function clause decode (0b010000 @ 0b00001 @ rt : regno @ rd : regno @ 0b00000000 @ sel : bits(3)) =
Some(MFC0(rt, rd, sel, true)) /* DMFC0 */
function clause execute (MFC0(rt, rd, sel, double)) = {
checkCP0Access();
- let result : bits(64) = match rd, sel
+ let result : bits(64) = match (rd, sel)
{
- (0b00000,0b000) => let idx : bits(31) = EXTZ(TLBIndex) in
- (0x00000000 : TLBProbe : idx) /* 0, TLB Index */
- (0b00001,0b000) => EXTZ(TLBRandom) /* 1, TLB Random */
- (0b00010,0b000) => TLBEntryLo0 /* 2, TLB EntryLo0 */
- (0b00011,0b000) => TLBEntryLo1 /* 3, TLB EntryLo1 */
- (0b00100,0b000) => TLBContext /* 4, TLB Context */
- (0b00101,0b000) => EXTZ(TLBPageMask : 0x000) /* 5, TLB PageMask */
- (0b00110,0b000) => EXTZ(TLBWired) /* 6, TLB Wired */
- (0b00111,0b000) => EXTZ(CP0HWREna) /* 7, HWREna */
- (0b01000,0b000) => CP0BadVAddr /* 8, BadVAddr reg */
- (0b01000,0b001) => 0 /* 8, BadInstr reg XXX TODO */
- (0b01001,0b000) => EXTZ(CP0Count) /* 9, Count reg */
- (0b01010,0b000) => TLBEntryHi /* 10, TLB EntryHi */
- (0b01011,0b000) => EXTZ(CP0Compare) /* 11, Compare reg */
- (0b01100,0b000) => EXTZ(CP0Status) /* 12, Status reg */
- (0b01101,0b000) => EXTZ(CP0Cause) /* 13, Cause reg */
- (0b01110,0b000) => CP0EPC /* 14, EPC */
- (0b01111,0b000) => EXTZ(0x00000400) /* 15, sel 0: PrID processor ID */
- (0b01111,0b110) => 0 /* 15, sel 6: CHERI core ID */
- (0b01111,0b111) => 0 /* 15, sel 7: CHERI thread ID */
- (0b10000,0b000) => EXTZ(0b1 /* M */ /* 16, sel 0: Config0 */
- : 0b000000000000000 /* Impl */
- : 0b1 /* BE */
- : 0b10 /* AT */
- : 0b000 /* AR */
- : 0b001 /* MT standard TLB */
- : 0b0000 /* zero */
- : 0b000)
- (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. */
- : [bool_to_bit(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 */
- (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. */
- (0b10000,0b011) => 0x0000000000002000 /* 16, sel 3: Config3 zero except for bit 13 == ulri */
- (0b10000,0b101) => 0x0000000000000000 /* 16, sel 5: Config5 beri specific -- no extended TLB */
- (0b10001,0b000) => CP0LLAddr /* 17, sel 0: LLAddr */
- (0b10010,0b000) => 0 /* 18, WatchLo */
- (0b10011,0b000) => 0 /* 19, WatchHi */
- (0b10100,0b000) => TLBXContext /* 20, XContext */
- (0b11110,0b000) => CP0ErrorEPC /* 30, ErrorEPC */
- _ => (SignalException(ResI))
+ (0b00000,0b000) => let idx : bits(31) = EXTZ(TLBIndex) in
+ (0x00000000 @ TLBProbe @ idx), /* 0, TLB Index */
+ (0b00001,0b000) => EXTZ(TLBRandom), /* 1, TLB Random */
+ (0b00010,0b000) => TLBEntryLo0.bits(), /* 2, TLB EntryLo0 */
+ (0b00011,0b000) => TLBEntryLo1.bits(), /* 3, TLB EntryLo1 */
+ (0b00100,0b000) => TLBContext.bits(), /* 4, TLB Context */
+ (0b00101,0b000) => EXTZ(TLBPageMask @ 0x000), /* 5, TLB PageMask */
+ (0b00110,0b000) => EXTZ(TLBWired), /* 6, TLB Wired */
+ (0b00111,0b000) => EXTZ(CP0HWREna), /* 7, HWREna */
+ (0b01000,0b000) => CP0BadVAddr, /* 8, BadVAddr reg */
+ (0b01000,0b001) => EXTZ(0b0), /* 8, BadInstr reg XXX TODO */
+ (0b01001,0b000) => EXTZ(CP0Count), /* 9, Count reg */
+ (0b01010,0b000) => TLBEntryHi.bits(),/* 10, TLB EntryHi */
+ (0b01011,0b000) => EXTZ(CP0Compare), /* 11, Compare reg */
+ (0b01100,0b000) => EXTZ(CP0Status.bits()), /* 12, Status reg */
+ (0b01101,0b000) => EXTZ(CP0Cause.bits()), /* 13, Cause reg */
+ (0b01110,0b000) => CP0EPC, /* 14, EPC */
+ (0b01111,0b000) => EXTZ(0x00000400), /* 15, sel 0: PrID processor ID */
+ (0b01111,0b110) => EXTZ(0b0), /* 15, sel 6: CHERI core ID */
+ (0b01111,0b111) => EXTZ(0b0), /* 15, sel 7: CHERI thread ID */
+ (0b10000,0b000) => EXTZ(0b1 /* M */ /* 16, sel 0: Config0 */
+ @ 0b000000000000000 /* Impl */
+ @ 0b1 /* BE */
+ @ 0b10 /* AT */
+ @ 0b000 /* AR */
+ @ 0b001 /* MT standard TLB */
+ @ 0b0000 /* zero */
+ @ 0b000),
+ (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. */
+ @ bool_to_bits(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 */
+ (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. */
+ (0b10000,0b011) => 0x0000000000002000, /* 16, sel 3: Config3 zero except for bit 13 == ulri */
+ (0b10000,0b101) => 0x0000000000000000, /* 16, sel 5: Config5 beri specific -- no extended TLB */
+ (0b10001,0b000) => CP0LLAddr, /* 17, sel 0: LLAddr */
+ (0b10010,0b000) => EXTZ(0b0), /* 18, WatchLo */
+ (0b10011,0b000) => EXTZ(0b0), /* 19, WatchHi */
+ (0b10100,0b000) => TLBXContext.bits(), /* 20, XContext */
+ (0b11110,0b000) => CP0ErrorEPC, /* 30, ErrorEPC */
+ _ => (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
+union clause ast = HCF : unit
function clause decode (0b010000 @ 0b00100 @ rt : regno @ 0b10111 @ 0b00000000000) =
- Some((ast) HCF)
+ Some(HCF)
function clause decode (0b010000 @ 0b00100 @ rt : regno @ 0b11010 @ 0b00000000000) =
- Some((ast) HCF)
+ Some(HCF)
function clause execute (HCF) =
() /* halt instruction actually executed by interpreter framework */
-union ast member (regno, regno, bits(3), bool) MTC0
-function clause decode (0b010000 @ 0b00100 @ rt : regno @ rd : regno @ 0b00000000 @ (bits(3)) sel) =
+union clause ast = MTC0 : (regno, regno, bits(3), bool)
+function clause decode (0b010000 @ 0b00100 @ rt : regno @ rd : regno @ 0b00000000 @ sel : bits(3)) =
Some(MTC0(rt, rd, sel, false)) /* MTC0 */
-function clause decode (0b010000 @ 0b00101 @ rt : regno @ rd : regno @ 0b00000000 @ (bits(3)) sel) =
+function clause decode (0b010000 @ 0b00101 @ rt : regno @ rd : regno @ 0b00000000 @ sel : bits(3)) =
Some(MTC0(rt, rd, sel, true)) /* DMTC0 */
function clause execute (MTC0(rt, rd, sel, double)) = {
checkCP0Access();
- let reg_val in : = (rGPR(rt))
- match rd, sel
+ let reg_val = rGPR(rt) in
+ match (rd, sel)
{
- (0b00000,0b000) => TLBIndex = mask(reg_val) /* NB no write to TLBProbe */
- (0b00001,0b000) => () /* TLBRandom is read only */
- (0b00010,0b000) => TLBEntryLo0 = reg_val
- (0b00011,0b000) => TLBEntryLo1 = reg_val
- (0b00100,0b000) => (TLBContext.PTEBase) = (reg_val[63..23])
- (0b00100,0b010) => CP0UserLocal = reg_val
- (0b00101,0b000) => TLBPageMask = (reg_val[28..13])
- (0b00110,0b000) => {
+ (0b00000,0b000) => TLBIndex = mask(reg_val), /* NB no write to TLBProbe */
+ (0b00001,0b000) => (), /* TLBRandom is read only */
+ (0b00010,0b000) => TLBEntryLo0->bits() = reg_val,
+ (0b00011,0b000) => TLBEntryLo1->bits() = reg_val,
+ (0b00100,0b000) => TLBContext->PTEBase() = reg_val[63..23],
+ (0b00100,0b010) => CP0UserLocal = reg_val,
+ (0b00101,0b000) => TLBPageMask = reg_val[28..13],
+ (0b00110,0b000) => {
TLBWired = mask(reg_val);
TLBRandom = TLBIndexMax;
- }
- (0b00111,0b000) => CP0HWREna = (reg_val[31..29] : 0b0000000000000000000000000 : reg_val[3..0])
- (0b01000,0b000) => () /* BadVAddr read only */
- (0b01001,0b000) => CP0Count = reg_val[31..0]
- (0b01010,0b000) => {
- (TLBEntryHi.R) = (reg_val[63..62]);
- (TLBEntryHi.VPN2) = (reg_val[39..13]);
- (TLBEntryHi.ASID) = (reg_val[7..0]);
- }
- (0b01011,0b000) => { /* 11, sel 0: Compare reg */
+ },
+ (0b00111,0b000) => CP0HWREna = (reg_val[31..29] @ 0b0000000000000000000000000 @ reg_val[3..0]),
+ (0b01000,0b000) => (), /* BadVAddr read only */
+ (0b01001,0b000) => CP0Count = reg_val[31..0],
+ (0b01010,0b000) => {
+ TLBEntryHi->R() = reg_val[63..62];
+ TLBEntryHi->VPN2() = reg_val[39..13];
+ TLBEntryHi->ASID() = reg_val[7..0];
+ },
+ (0b01011,0b000) => { /* 11, sel 0: Compare reg */
CP0Compare = reg_val[31..0];
- (CP0Cause[15]) = bitzero;
- }
- (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];
- }
- (0b01101,0b000) => { /* 13 Cause */
- CP0Cause.IV = reg_val[23]; /* TODO special interrupt vector not implemeneted */
- let ip = (bits(8)) (CP0Cause.IP) in
- CP0Cause.IP = ((ip[7..2]) : (reg_val[9..8]));
- }
- (0b01110,0b000) => CP0EPC = reg_val EPC : /* 14, */
- (0b10000,0b000) => () /* XXX ignore K0 cache config 16: Config0 */
- (0b10100,0b000) => (TLBXContext.PTEBase) = (reg_val[63..33])
- (0b11110,0b000) => CP0ErrorEPC = reg_val ErrorEPC : /* 30, */
- _ => (SignalException(ResI))
+ CP0Cause->IP() = CP0Cause.IP() & 0x7f; /* clear IP7 */
+ },
+ (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];
+ },
+ (0b01101,0b000) => { /* 13 Cause */
+ CP0Cause->IV() = reg_val[23]; /* TODO special interrupt vector not implemeneted */
+ let ip = CP0Cause.IP() in
+ CP0Cause->IP() = ((ip[7..2]) @ (reg_val[9..8]));
+ },
+ (0b01110,0b000) => CP0EPC = reg_val, /* 14, EPC */
+ (0b10000,0b000) => (), /* XXX ignore K0 cache config 16: Config0 */
+ (0b10100,0b000) => TLBXContext->XPTEBase() = reg_val[63..33],
+ (0b11110,0b000) => CP0ErrorEPC = reg_val, /* 30, ErrorEPC */
+ _ => (SignalException(ResI))
}
}
-function unit TLBWriteEntry((TLBIndexT) idx) = {
- pagemask = (bits(16)) (EXTZ(TLBPageMask)); /* XXX EXTZ here forces register read in ocaml shallow embedding */
+val TLBWriteEntry : TLBIndexT -> unit effect {rreg, wreg, escape}
+function TLBWriteEntry(idx) = {
+ pagemask = TLBPageMask;
match pagemask {
- 0x0000 => ()
- 0x0003 => ()
- 0x000f => ()
- 0x003f => ()
- 0x00ff => ()
- 0x03ff => ()
- 0x0fff => ()
- 0x3fff => ()
- 0xffff => ()
+ 0x0000 => (),
+ 0x0003 => (),
+ 0x000f => (),
+ 0x003f => (),
+ 0x00ff => (),
+ 0x03ff => (),
+ 0x0fff => (),
+ 0x3fff => (),
+ 0xffff => (),
_ => (SignalException(MCheck))
};
- let idxr = unsigned(idx) in {
- ((TLBEntries[idxr]).pagemask) = pagemask;
- ((TLBEntries[idxr]).r ) = TLBEntryHi.R;
- ((TLBEntries[idxr]).vpn2 ) = TLBEntryHi.VPN2;
- ((TLBEntries[idxr]).asid ) = TLBEntryHi.ASID;
- ((TLBEntries[idxr]).g ) = ((TLBEntryLo0.G) & (TLBEntryLo1.G));
- ((TLBEntries[idxr]).valid ) = bitone;
- ((TLBEntries[idxr]).caps0 ) = TLBEntryLo0.CapS;
- ((TLBEntries[idxr]).capl0 ) = TLBEntryLo0.CapL;
- ((TLBEntries[idxr]).pfn0 ) = TLBEntryLo0.PFN;
- ((TLBEntries[idxr]).c0 ) = TLBEntryLo0.C;
- ((TLBEntries[idxr]).d0 ) = TLBEntryLo0.D;
- ((TLBEntries[idxr]).v0 ) = TLBEntryLo0.V;
- ((TLBEntries[idxr]).caps1 ) = TLBEntryLo1.CapS;
- ((TLBEntries[idxr]).capl1 ) = TLBEntryLo1.CapL;
- ((TLBEntries[idxr]).pfn1 ) = TLBEntryLo1.PFN;
- ((TLBEntries[idxr]).c1 ) = TLBEntryLo1.C;
- ((TLBEntries[idxr]).d1 ) = TLBEntryLo1.D;
- ((TLBEntries[idxr]).v1 ) = TLBEntryLo1.V;
+ let i as atom(_) = unsigned(idx) in
+ let entry = TLBEntries[i] in {
+ entry.pagemask() = pagemask;
+ entry.r() = TLBEntryHi.R();
+ entry.vpn2() = TLBEntryHi.VPN2();
+ entry.asid() = TLBEntryHi.ASID();
+ entry.g() = ((TLBEntryLo0.G()) & (TLBEntryLo1.G()));
+ entry.valid() = bitone;
+ entry.caps0() = TLBEntryLo0.CapS();
+ entry.capl0() = TLBEntryLo0.CapL();
+ entry.pfn0() = TLBEntryLo0.PFN();
+ entry.c0() = TLBEntryLo0.C();
+ entry.d0() = TLBEntryLo0.D();
+ entry.v0() = TLBEntryLo0.V();
+ entry.caps1() = TLBEntryLo1.CapS();
+ entry.capl1() = TLBEntryLo1.CapL();
+ entry.pfn1() = TLBEntryLo1.PFN();
+ entry.c1() = TLBEntryLo1.C();
+ entry.d1() = TLBEntryLo1.D();
+ entry.v1() = TLBEntryLo1.V();
}
}
-union ast member TLBWI
+union clause ast = TLBWI : unit
function clause decode (0b010000 @ 0b10000000000000000000 @ 0b000010) = Some(TLBWI : ast)
function clause execute (TLBWI) = {
checkCP0Access();
TLBWriteEntry(TLBIndex);
}
-union ast member TLBWR
+union clause ast = TLBWR : unit
function clause decode (0b010000 @ 0b10000000000000000000 @ 0b000110) = Some(TLBWR : ast)
function clause execute (TLBWR) = {
checkCP0Access();
TLBWriteEntry(TLBRandom);
}
-union ast member TLBR
+union clause ast = TLBR : unit
function clause decode (0b010000 @ 0b10000000000000000000 @ 0b000001) = Some(TLBR : ast)
function clause execute (TLBR) = {
checkCP0Access();
- let entry = TLBEntries[unsigned(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;
+ let i as atom(_) = unsigned(TLBIndex) in
+ let entry = reg_deref(TLBEntries[i]) 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
+union clause ast = TLBP : unit
function clause decode (0b010000 @ 0b10000000000000000000 @ 0b001000) = Some(TLBP : ast)
function clause execute ((TLBP)) = {
checkCP0Access();
- let result = tlbSearch(TLBEntryHi) in
+ let result = tlbSearch(TLBEntryHi.bits()) in
match result {
(Some(idx)) => {
TLBProbe = [bitzero];
TLBIndex = idx;
- }
+ },
None => {
TLBProbe = [bitone];
TLBIndex = 0b000000;
@@ -1648,41 +1664,45 @@ function clause execute ((TLBP)) = {
}
}
-union ast member (regno, regno) RDHWR
+union clause ast = RDHWR : (regno, regno)
function clause decode (0b011111 @ 0b00000 @ rt : regno @ rd : regno @ 0b00000 @ 0b111011) =
Some(RDHWR(rt, rd))
function clause execute (RDHWR(rt, rd)) = {
let accessLevel = getAccessLevel() in
- if ((accessLevel != Kernel) & (~((CP0Status.CU)[28])) & ~(CP0HWREna[rd])) then
+ let haveAccessLevel : bool = accessLevel == Kernel in
+ let haveCU0 : bool = bitone == (CP0Status.CU()[0]) in
+ let rdi as atom(_) = unsigned(rd) in
+ let haveHWREna : bool = bitone == (CP0HWREna[rdi]) in
+ if ~(haveAccessLevel | haveCU0 | haveHWREna) then
(SignalException(ResI));
let temp : bits(64) = match rd {
- 0b00000 => EXTZ([bitzero]) /* CPUNum */
- 0b00001 => EXTZ([bitzero]) /* SYNCI_step */
- 0b00010 => EXTZ(CP0Count) /* Count */
- 0b00011 => EXTZ([bitone]) /* Count resolution */
- 0b11101 => CP0UserLocal /* User local register */
+ 0b00000 => EXTZ([bitzero]), /* CPUNum */
+ 0b00001 => EXTZ([bitzero]), /* SYNCI_step */
+ 0b00010 => EXTZ(CP0Count), /* Count */
+ 0b00011 => EXTZ([bitone]), /* Count resolution */
+ 0b11101 => CP0UserLocal, /* User local register */
_ => (SignalException(ResI))
} in
wGPR(rt) = temp;
}
-union ast member unit ERET
+union clause ast = ERET : unit
function clause decode (0b010000 @ 0b1 @ 0b0000000000000000000 @ 0b011000) =
- Some((ast) ERET)
+ Some(ERET)
function clause execute (ERET) =
{
checkCP0Access();
ERETHook();
CP0LLBit = 0b0;
- if (CP0Status.ERL == bitone) then
+ if (CP0Status.ERL() == bitone) then
{
nextPC = CP0ErrorEPC;
- CP0Status.ERL = 0;
+ CP0Status->ERL() = 0b0;
}
else
{
nextPC = CP0EPC;
- CP0Status.EXL = 0;
+ CP0Status->EXL() = 0b0;
}
}
diff --git a/mips_new_tc/mips_prelude.sail b/mips_new_tc/mips_prelude.sail
index 4c11a4b1..04d00219 100644
--- a/mips_new_tc/mips_prelude.sail
+++ b/mips_new_tc/mips_prelude.sail
@@ -35,9 +35,6 @@
/* 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 PC : bits(64)
register nextPC : bits(64)
@@ -80,9 +77,9 @@ bitfield ContextReg : bits(64) = {
}
bitfield XContextReg : bits(64) = {
- PTEBase : 63.. 33,
- R : 32.. 31,
- BadVPN2 : 30.. 4,
+ XPTEBase : 63.. 33,
+ XR : 32.. 31,
+ XBadVPN2 : 30.. 4,
}
let TLBNumEntries = 64
@@ -128,7 +125,137 @@ register TLBWired : TLBIndexT
register TLBEntryHi : TLBEntryHiReg
register TLBXContext : XContextReg
-register TLBEntries : vector(64, dec, TLBEntry)
+register TLBEntry00 : TLBEntry
+register TLBEntry01 : TLBEntry
+register TLBEntry02 : TLBEntry
+register TLBEntry03 : TLBEntry
+register TLBEntry04 : TLBEntry
+register TLBEntry05 : TLBEntry
+register TLBEntry06 : TLBEntry
+register TLBEntry07 : TLBEntry
+register TLBEntry08 : TLBEntry
+register TLBEntry09 : TLBEntry
+register TLBEntry10 : TLBEntry
+register TLBEntry11 : TLBEntry
+register TLBEntry12 : TLBEntry
+register TLBEntry13 : TLBEntry
+register TLBEntry14 : TLBEntry
+register TLBEntry15 : TLBEntry
+register TLBEntry16 : TLBEntry
+register TLBEntry17 : TLBEntry
+register TLBEntry18 : TLBEntry
+register TLBEntry19 : TLBEntry
+register TLBEntry20 : TLBEntry
+register TLBEntry21 : TLBEntry
+register TLBEntry22 : TLBEntry
+register TLBEntry23 : TLBEntry
+register TLBEntry24 : TLBEntry
+register TLBEntry25 : TLBEntry
+register TLBEntry26 : TLBEntry
+register TLBEntry27 : TLBEntry
+register TLBEntry28 : TLBEntry
+register TLBEntry29 : TLBEntry
+register TLBEntry30 : TLBEntry
+register TLBEntry31 : TLBEntry
+register TLBEntry32 : TLBEntry
+register TLBEntry33 : TLBEntry
+register TLBEntry34 : TLBEntry
+register TLBEntry35 : TLBEntry
+register TLBEntry36 : TLBEntry
+register TLBEntry37 : TLBEntry
+register TLBEntry38 : TLBEntry
+register TLBEntry39 : TLBEntry
+register TLBEntry40 : TLBEntry
+register TLBEntry41 : TLBEntry
+register TLBEntry42 : TLBEntry
+register TLBEntry43 : TLBEntry
+register TLBEntry44 : TLBEntry
+register TLBEntry45 : TLBEntry
+register TLBEntry46 : TLBEntry
+register TLBEntry47 : TLBEntry
+register TLBEntry48 : TLBEntry
+register TLBEntry49 : TLBEntry
+register TLBEntry50 : TLBEntry
+register TLBEntry51 : TLBEntry
+register TLBEntry52 : TLBEntry
+register TLBEntry53 : TLBEntry
+register TLBEntry54 : TLBEntry
+register TLBEntry55 : TLBEntry
+register TLBEntry56 : TLBEntry
+register TLBEntry57 : TLBEntry
+register TLBEntry58 : TLBEntry
+register TLBEntry59 : TLBEntry
+register TLBEntry60 : TLBEntry
+register TLBEntry61 : TLBEntry
+register TLBEntry62 : TLBEntry
+register TLBEntry63 : TLBEntry
+
+let TLBEntries : vector(64, dec, register(TLBEntry)) = [
+ ref TLBEntry63,
+ ref TLBEntry62,
+ ref TLBEntry61,
+ ref TLBEntry60,
+ ref TLBEntry59,
+ ref TLBEntry58,
+ ref TLBEntry57,
+ ref TLBEntry56,
+ ref TLBEntry55,
+ ref TLBEntry54,
+ ref TLBEntry53,
+ ref TLBEntry52,
+ ref TLBEntry51,
+ ref TLBEntry50,
+ ref TLBEntry49,
+ ref TLBEntry48,
+ ref TLBEntry47,
+ ref TLBEntry46,
+ ref TLBEntry45,
+ ref TLBEntry44,
+ ref TLBEntry43,
+ ref TLBEntry42,
+ ref TLBEntry41,
+ ref TLBEntry40,
+ ref TLBEntry39,
+ ref TLBEntry38,
+ ref TLBEntry37,
+ ref TLBEntry36,
+ ref TLBEntry35,
+ ref TLBEntry34,
+ ref TLBEntry33,
+ ref TLBEntry32,
+ ref TLBEntry31,
+ ref TLBEntry30,
+ ref TLBEntry29,
+ ref TLBEntry28,
+ ref TLBEntry27,
+ ref TLBEntry26,
+ ref TLBEntry25,
+ ref TLBEntry24,
+ ref TLBEntry23,
+ ref TLBEntry22,
+ ref TLBEntry21,
+ ref TLBEntry20,
+ ref TLBEntry19,
+ ref TLBEntry18,
+ ref TLBEntry17,
+ ref TLBEntry16,
+ ref TLBEntry15,
+ ref TLBEntry14,
+ ref TLBEntry13,
+ ref TLBEntry12,
+ ref TLBEntry11,
+ ref TLBEntry10,
+ ref TLBEntry09,
+ ref TLBEntry08,
+ ref TLBEntry07,
+ ref TLBEntry06,
+ ref TLBEntry05,
+ ref TLBEntry04,
+ ref TLBEntry03,
+ ref TLBEntry02,
+ ref TLBEntry01,
+ ref TLBEntry00
+]
register CP0Compare : bits(32)
register CP0Cause : CauseReg
@@ -180,19 +307,21 @@ register UART_RVALID : bits(1)
/* Check whether a given 64-bit vector is a properly sign extended 32-bit word */
val NotWordVal : bits(64) -> bool effect pure
-function bool NotWordVal (word) =
+function NotWordVal (word) =
(word[31] ^^ 32) != word[63..32]
/* Read numbered GP reg. (r0 is always zero) */
val rGPR : bits(5) -> bits(64) effect {rreg}
function rGPR idx = {
- if idx == 0 then 0 else GPR[idx]
+ let i as atom(_) = unsigned(idx) in
+ if i == 0 then 0x0000000000000000 else GPR[i]
}
/* Write numbered GP reg. (writes to r0 ignored) */
val wGPR : (bits(5), bits(64)) -> unit effect {wreg}
function wGPR (idx, v) = {
- if idx == 0 then () else GPR[idx] = v
+ let i as atom(_) = unsigned(idx) in
+ if i == 0 then () else GPR[i] = v
}
val MEMr : forall 'n. ( bits(64) , atom('n) ) -> (bits(8 * 'n)) effect { rmem }
@@ -212,52 +341,52 @@ enum Exception =
/* Return the ISA defined code for an exception condition */
function ExceptionCode (ex) : Exception -> bits(5)=
- match ex
+ let x : bits(8) = match ex
{
- Interrupt => mask(0x00), /* Interrupt */
- TLBMod => mask(0x01), /* TLB modification exception */
- TLBL => mask(0x02), /* TLB exception (load or fetch) */
- TLBS => mask(0x03), /* TLB exception (store) */
- AdEL => mask(0x04), /* Address error (load or fetch) */
- AdES => mask(0x05), /* Address error (store) */
- Sys => mask(0x08), /* Syscall */
- Bp => mask(0x09), /* Breakpoint */
- ResI => mask(0x0a), /* Reserved instruction */
- CpU => mask(0x0b), /* Coprocessor Unusable */
- Ov => mask(0x0c), /* Arithmetic overflow */
- Tr => mask(0x0d), /* Trap */
- C2E => mask(0x12), /* C2E coprocessor 2 exception */
- C2Trap => mask(0x12), /* C2Trap maps to same exception code, different vector */
- XTLBRefillL => mask(0x02),
- XTLBRefillS => mask(0x03),
- XTLBInvL => mask(0x02),
- XTLBInvS => mask(0x03),
- MCheck => mask(0x18)
- }
-
-
-val SignalExceptionMIPS : forall ('o : Type) . (Exception, bits(64)) -> 'o effect {escape}
+ Interrupt => 0x00, /* Interrupt */
+ TLBMod => 0x01, /* TLB modification exception */
+ TLBL => 0x02, /* TLB exception (load or fetch) */
+ TLBS => 0x03, /* TLB exception (store) */
+ AdEL => 0x04, /* Address error (load or fetch) */
+ AdES => 0x05, /* Address error (store) */
+ Sys => 0x08, /* Syscall */
+ Bp => 0x09, /* Breakpoint */
+ ResI => 0x0a, /* Reserved instruction */
+ CpU => 0x0b, /* Coprocessor Unusable */
+ Ov => 0x0c, /* Arithmetic overflow */
+ Tr => 0x0d, /* Trap */
+ C2E => 0x12, /* C2E coprocessor 2 exception */
+ C2Trap => 0x12, /* C2Trap maps to same exception code, different vector */
+ XTLBRefillL => 0x02,
+ XTLBRefillS => 0x03,
+ XTLBInvL => 0x02,
+ XTLBInvS => 0x03,
+ MCheck => 0x18
+ } in x[4..0]
+
+
+val SignalExceptionMIPS : forall ('o : Type) . (Exception, bits(64)) -> 'o effect {escape, rreg, wreg}
function SignalExceptionMIPS (ex, kccBase) =
{
/* Only update EPC and BD if not already in EXL mode */
- if (~ (CP0Status.EXL)) then
+ if (~ (CP0Status.EXL())) then
{
if (inBranchDelay[0]) then
{
CP0EPC = PC - 4;
- CP0Cause.BD = 1;
+ CP0Cause->BD() = 0b1;
}
else
{
CP0EPC = PC;
- CP0Cause.BD = 0;
+ CP0Cause->BD() = 0b0;
}
};
/* choose an exception vector to branch to. Some are not supported
e.g. Reset */
vectorOffset =
- if (CP0Status.EXL) then
+ if (CP0Status.EXL()) then
0x180 /* Always use common vector if in exception mode already */
else if ((ex == XTLBRefillL) | (ex == XTLBRefillS)) then
0x080
@@ -265,15 +394,15 @@ function SignalExceptionMIPS (ex, kccBase) =
0x280 /* Special vector for CHERI traps */
else
0x180; /* Common vector */
- vectorBase : bits(64) = if CP0Status.BEV then
+ vectorBase : bits(64) = 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 = vectorBase + EXTS(vectorOffset) - kccBase;
- CP0Cause.ExcCode = ExceptionCode(ex);
- CP0Status.EXL = 1;
+ CP0Cause->ExcCode() = ExceptionCode(ex);
+ CP0Status->EXL() = 0b1;
exit (());
}
@@ -289,11 +418,11 @@ function SignalExceptionBadAddr(ex, badAddr) =
val SignalExceptionTLB : forall ('o : Type) . (Exception, bits(64)) -> 'o effect {escape, rreg, wreg}
function SignalExceptionTLB(ex, 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]);
+ TLBContext->BadVPN2() = (badAddr[31..13]);
+ TLBXContext->XBadVPN2()= (badAddr[39..13]);
+ TLBXContext->XR() = (badAddr[63..62]);
+ TLBEntryHi->R() = (badAddr[63..62]);
+ TLBEntryHi->VPN2() = (badAddr[39..13]);
SignalException(ex);
}
@@ -301,9 +430,9 @@ enum MemAccessType = {Instruction, LoadData, StoreData}
enum AccessLevel = {User, Supervisor, Kernel}
function getAccessLevel() : unit -> AccessLevel=
- if ((CP0Status.EXL) | (CP0Status.ERL)) then
+ if ((CP0Status.EXL()) | (CP0Status.ERL())) then
Kernel
- else match CP0Status.KSU
+ else match CP0Status.KSU()
{
0b00 => Kernel,
0b01 => Supervisor,
@@ -311,30 +440,32 @@ function getAccessLevel() : unit -> AccessLevel=
_ => User /* behaviour undefined, assume user */
}
+val checkCP0Access : unit->unit effect{escape, rreg, wreg}
function checkCP0Access () =
{
let accessLevel = getAccessLevel() in
- if ((accessLevel != Kernel) & (~(CP0Status[28] /*CU0*/))) then
+ if ((accessLevel != Kernel) & (~(CP0Status.CU()[0]))) then
{
- (CP0Cause.CE) = 0b00;
+ CP0Cause->CE() = 0b00;
SignalException(CpU);
}
}
+val incrementCP0Count : unit -> unit effect {rreg,wreg,escape}
function 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 */
+ CP0Cause->IP() = CP0Cause.IP() | 0x80; /* IP7 is timer interrupt */
};
- let ims = CP0Status.IM in
- let ips = CP0Cause.IP in
- let ie = CP0Status.IE in
- let exl = CP0Status.EXL in
- let erl = CP0Status.ERL in
+ let ims = CP0Status.IM() in
+ let 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(Interrupt);
}
@@ -367,22 +498,19 @@ enum Comparison = {
val compare : (Comparison, bits(64), bits(64)) -> bool
function compare (cmp, valA, valB) =
- /* sail comparisons are signed so extend to 65 bits for unsigned comparisons */
- let valA65 = (0b0 : valA) in
- let valB65 = (0b0 : valB) in
match cmp {
EQ => valA == valB,
NE => valA != valB,
- GE => valA >= valB,
- GEU => valA65 >= valB65,
- GT => valA > valB,
- LE => valA <= valB,
- LT => valA < valB,
- LTU => valA65 < valB65
+ GE => valA >=_s valB,
+ GEU => valA >=_u valB,
+ GT => valB <_s valA,
+ LE => valB >=_s valA,
+ LT => valA <_s valB,
+ LTU => valA <_u valB
}
enum WordType = { B, H, W, D}
-val wordWidthBytes : Wordwidthbytes -> range(1, 8)
+val wordWidthBytes : WordType -> range(1, 8)
function wordWidthBytes(w) =
match w {
B => 1,
@@ -415,10 +543,11 @@ let alignment_width = 16
val isAddressAligned : (bits(64), WordType) -> bool
function isAddressAligned (addr, wordType) =
let a = unsigned(addr) in
- quot(a, alignment_width) == quot(a + wordWidthBytes(wordType) - 1, alignment_width)
+ a / alignment_width == (a + wordWidthBytes(wordType) - 1) / alignment_width
-/*val reverse_endianness : forall Nat 'W, 'W >= 1. ([:'W:], bits(8 * 'W)) -> bits(8 * 'W) effect pure'
+val reverse_endianness = "reverse_endianness" : forall 'W, 'W >= 1. bits(8 * 'W) -> bits(8 * 'W) effect pure
+/*
function rec forall Nat 'W, 'W >= 1. bits(8 * 'W) reverse_endianness' (w, value) =
{
([:8 * 'W:]) width = length(value);
@@ -427,15 +556,16 @@ function rec forall Nat 'W, 'W >= 1. bits(8 * 'W) reverse_endianness' (w, value)
else value[7..0] : reverse_endianness'(w - 1, value[(width - 1) .. 8])
}
-val reverse_endianness : forall Nat 'W, 'W >= 1. bits(8 * 'W) -> bits(8 * 'W) effect pure
+
function rec forall Nat 'W, 'W >= 1. bits(8 * 'W) reverse_endianness ((bits(8 * 'W)) value) =
{
reverse_endianness'(sizeof 'W, value)
}*/
-val MEMr_wrapper : forall 'n, 1 <= 'n <=8 . (bits(64), atom('n)) -> bits(8*n) effect {rmem}
-function MEMr_wrapper (addr, size) = reverse_endianness(MEMr (addr, size)) /* TODO
+val MEMr_wrapper : forall 'n, 1 <= 'n <=8 . (bits(64), atom('n)) -> bits(8*'n) effect {rmem}
+function MEMr_wrapper (addr, size) = reverse_endianness(MEMr (addr, size))
+/* TODO
if (addr == 0x000000007f000000) then
{
let rvalid = UART_RVALID in
@@ -450,6 +580,6 @@ function MEMr_wrapper (addr, size) = reverse_endianness(MEMr (addr, size)) /* TO
else
reverse_endianness(MEMr(addr, size)) /* MEMr assumes little endian */ */
-val MEMr_reserve_wrapper : forall 'n. ( bits(64) , atom('n) ) -> (bits(8 * 'n)) effect { rmem }
+val MEMr_reserve_wrapper : forall 'n, 1 <= 'n <= 8 . ( bits(64) , atom('n) ) -> (bits(8 * 'n)) effect { rmem }
function MEMr_reserve_wrapper (addr , size) =
reverse_endianness(MEMr_reserve(addr, size))
diff --git a/mips_new_tc/mips_ri.sail b/mips_new_tc/mips_ri.sail
index eb047771..5a221df7 100644
--- a/mips_new_tc/mips_ri.sail
+++ b/mips_new_tc/mips_ri.sail
@@ -35,7 +35,7 @@
/* 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
+union clause ast = RI : unit
function clause decode _ = Some(RI)
function clause execute (RI) =
SignalException (ResI)
diff --git a/mips_new_tc/mips_tlb.sail b/mips_new_tc/mips_tlb.sail
index fc6a68f4..4ac2cb90 100644
--- a/mips_new_tc/mips_tlb.sail
+++ b/mips_new_tc/mips_tlb.sail
@@ -33,109 +33,116 @@
/*========================================================================*/
val tlbEntryMatch : (bits(2), bits(27), bits(8), TLBEntry) -> bool effect pure
-
-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
+function tlbEntryMatch(r, vpn2, asid, 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
+ let vpnMask : bits(27) = ~(EXTZ(entryMask)) in
(entryValid &
(r == entryR) &
- ((vpn2 & ~((bits(27)) (EXTZ(entryMask)))) == ((entryVPN) & ~((bits(27)) (EXTZ(entryMask))))) &
+ ((vpn2 & vpnMask) == ((entryVPN) & vpnMask)) &
((asid == (entryASID)) | (entryG)))
-function option(TLBIndexT) tlbSearch((bits(64)) VAddr) =
+val tlbSearch : bits(64) -> option(TLBIndexT) effect {rreg}
+function tlbSearch(VAddr) =
let r = (VAddr[63..62]) in
let vpn2 = (VAddr[39..13]) in
- let asid = TLBEntryHi.ASID in {
+ let asid = TLBEntryHi.ASID() in {
foreach (idx from 0 to 63) {
- if(tlbEntryMatch(r, vpn2, asid, (TLBEntries[idx]))) then
- return (Some ((TLBIndexT) (to_vec(idx))))
+ if(tlbEntryMatch(r, vpn2, asid, reg_deref(TLBEntries[idx]))) then
+ return Some(to_bits(6, idx))
};
None
}
-function (bits(64), bool) TLBTranslate2 ((bits(64)) vAddr, (MemAccessType) accessType) = {
+/** For given virtual address and accessType returns physical address and
+bool flag indicating whether capability stores / loads are permitted for
+page (depending on access type). */
+
+val TLBTranslate2 : (bits(64), MemAccessType) -> (bits(64), bool) effect {rreg, wreg, undef, escape}
+function TLBTranslate2 (vAddr, accessType) = {
let idx = tlbSearch(vAddr) in
match idx {
- (Some(idx)) =>
- let entry = (TLBEntries[idx]) in
- let entryMask = entry.pagemask in
-
- let evenOddBit = ([|12:28|]) match (bits(16))(entryMask) {
- 0x0000 => 12
- 0x0003 => 14
- 0x000f => 16
- 0x003f => 18
- 0x00ff => 20
- 0x03ff => 22
- 0x0fff => 24
- 0x3fff => 26
- 0xffff => 28
- _ => undefined
- } in
- let isOdd = (vAddr[evenOddBit]) in
- let if : caps, capl, pfn, d, v (isOdd) then
- ((bits(1)) (entry.caps1), (bits(1)) (entry.capl1), (bits(24)) (entry.pfn1), (bits(1)) (entry.d1), (bits(1)) (entry.v1))
+ Some(idx) =>
+ let i as atom(_) = unsigned(idx) in
+ let entry = reg_deref(TLBEntries[i]) in
+ let entryMask = entry.pagemask() in
+ let 'evenOddBit : range(12,28) = match (entryMask) {
+ 0x0000 => 12,
+ 0x0003 => 14,
+ 0x000f => 16,
+ 0x003f => 18,
+ 0x00ff => 20,
+ 0x03ff => 22,
+ 0x0fff => 24,
+ 0x3fff => 26,
+ 0xffff => 28,
+ _ => undefined
+ } in
+ let isOdd = (vAddr[evenOddBit]) in
+ let (caps : bits(1), capl : bits(1), pfn : bits(24), d : bits(1), v : bits(1)) =
+ 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
- ((bits(1)) (entry.caps0), (bits(1)) (entry.capl0), (bits(24)) (entry.pfn0), (bits(1)) (entry.d0), (bits(1)) (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
- let res = (bits(64)) (EXTZ(pfn[23..(evenOddBit - 12)] : vAddr[(evenOddBit - 1) .. 0])) in
- (res, (bool) (if (accessType == StoreData) then caps else capl)) /* FIXME: get rid of explicit cast here */
- None => (SignalExceptionTLB(
- if (accessType == StoreData) then XTLBRefillS else XTLBRefillL, vAddr))
+ let res : bits(64) = EXTZ(pfn[23..(evenOddBit - 12)] @ vAddr[(evenOddBit - 1) .. 0]) in
+ (res, bits_to_bool(if (accessType == StoreData) then caps else capl)),
+ None => SignalExceptionTLB(
+ if (accessType == StoreData) then XTLBRefillS else XTLBRefillL, vAddr)
}
}
-val cast_AccessLevel : cast AccessLevel -> [|0:2|] effect pure
-
-function [|0:2|] cast_AccessLevel level =
-{
- switch level {
- User => 0
- Supervisor => 1
- Kernel => 2
+val cast_AccessLevel : AccessLevel -> int effect pure
+function cast_AccessLevel level =
+ match level {
+ User => 0,
+ Supervisor => 1,
+ Kernel => 2
}
-}
/* perform TLB translation. bool is CHERI specific TLB bits noStoreCap/suppressTag */
-function (bits(64), bool) TLBTranslateC ((bits(64)) vAddr, (MemAccessType) accessType) =
+val TLBTranslateC : (bits(64), MemAccessType) -> (bits(64), bool) effect {escape, rreg, undef, wreg}
+function TLBTranslateC (vAddr, accessType) =
{
let currentAccessLevel = getAccessLevel() in
let compat32 = (vAddr[61..31] == 0b1111111111111111111111111111111) in
- let AccessLevel : requiredLevel, addr, option(bits(64)))) match (bits(2)) (vAddr[63..62]) {
- 0b11 => match compat32, (bits(2)) (vAddr[30..29]) { /* xkseg */
- (true, 0b11) => (Kernel, (option(bits(64))) None) /* kseg3 mapped 32-bit compat */
- (true, 0b10) => (Supervisor, (option(bits(64))) None) /* sseg mapped 32-bit compat */
- (true, 0b01) => (Kernel, Some((bits(64)) (EXTZ(vAddr[28..0])))) /* kseg1 unmapped uncached 32-bit compat */
- (true, 0b00) => (Kernel, Some((bits(64)) (EXTZ(vAddr[28..0])))) /* kseg0 unmapped cached 32-bit compat */
- (_, _) => (Kernel, (option(bits(64))) None) /* xkseg mapped */
- }
- 0b10 => (Kernel, Some((bits(64)) (EXTZ(vAddr[58..0])))) /* xkphys bits 61-59 are cache mode (ignored) */
- 0b01 => (Supervisor, (option(bits(64))) None) /* xsseg - supervisor mapped */
- 0b00 => (User, (option(bits(64))) None) /* xuseg - user mapped */
+ let (requiredLevel, addr) : (AccessLevel, option(bits(64))) = match (vAddr[63..62]) {
+ 0b11 => match (compat32, vAddr[30..29]) { /* xkseg */
+ (true, 0b11) => (Kernel, None : option(bits(64))), /* kseg3 mapped 32-bit compat */
+ (true, 0b10) => (Supervisor, None : option(bits(64))), /* sseg mapped 32-bit compat */
+ (true, 0b01) => (Kernel, Some(0x00000000 @ 0b000 @ vAddr[28..0])), /* kseg1 unmapped uncached 32-bit compat */
+ (true, 0b00) => (Kernel, Some(0x00000000 @ 0b000 @ vAddr[28..0])), /* kseg0 unmapped cached 32-bit compat */
+ (_, _) => (Kernel, None : option(bits(64))) /* xkseg mapped */
+ },
+ 0b10 => (Kernel, Some(0b00000 @ vAddr[58..0])), /* xkphys bits 61-59 are cache mode (ignored) */
+ 0b01 => (Supervisor, None : option(bits(64))), /* xsseg - supervisor mapped */
+ 0b00 => (User, None : option(bits(64))) /* xuseg - user mapped */
} in
- if (((nat)currentAccessLevel) < ((nat)requiredLevel)) then
- (SignalExceptionBadAddr(if (accessType == StoreData) then AdES else AdEL, vAddr))
+ if (cast_AccessLevel(currentAccessLevel) < cast_AccessLevel(requiredLevel)) then
+ SignalExceptionBadAddr(if (accessType == StoreData) then AdES else AdEL, vAddr)
else
- let bit : pa, c[64], bool)) match addr {
- (Some(a)) => (a, false)
- None => if ((~(compat32)) & (unsigned(vAddr[61..0]) > MAX_VA)) then
- (SignalExceptionBadAddr(if (accessType == StoreData) then AdES else AdEL, vAddr))
- else
- TLBTranslate2(vAddr, accessType)
+ let (pa, c) : (bits(64), bool) = match addr {
+ Some(a) => (a, false),
+ 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))
+ SignalExceptionBadAddr(if (accessType == StoreData) then AdES else AdEL, vAddr)
else
(pa, c)
}
-function (bits(64)) TLBTranslate ((bits(64)) vAddr, (MemAccessType) accessType) =
- let TLBTranslateC : addr, c(vAddr, accessType) in addr
+/* TLB translate function for MIPS (throws away capability flag) */
+val TLBTranslate : (bits(64), MemAccessType) -> bits(64) effect {rreg, wreg, escape, undef}
+function TLBTranslate (vAddr, accessType) =
+ let (addr, c) = TLBTranslateC(vAddr, accessType) in addr
diff --git a/mips_new_tc/mips_wrappers.sail b/mips_new_tc/mips_wrappers.sail
index 281cb452..d0a4cdb2 100644
--- a/mips_new_tc/mips_wrappers.sail
+++ b/mips_new_tc/mips_wrappers.sail
@@ -60,7 +60,7 @@ val addrWrapper : (bits(64), MemAccessType, WordType) -> bits(64)
function addrWrapper(addr, accessType, width) =
addr
-val TranslatePC : bits(64) -> bits(64)
+val TranslatePC : bits(64) -> bits(64) effect {rreg, wreg, escape, undef}
function TranslatePC (vAddr) = {
incrementCP0Count();
if (vAddr[1..0] != 0b00) then /* bad PC alignment */
diff --git a/mips_new_tc/prelude.sail b/mips_new_tc/prelude.sail
index 9d7c84cb..53cb0510 100644
--- a/mips_new_tc/prelude.sail
+++ b/mips_new_tc/prelude.sail
@@ -3,14 +3,6 @@ default Order dec
type bits ('n : Int) = vector('n, dec, bit)
union option ('a : Type) = {None, Some : 'a}
-val eq_atom = {ocaml: "eq_int", lem: "eq"} : forall 'n 'm. (atom('n), atom('m)) -> bool
-val lteq_atom = "lteq" : forall 'n 'm. (atom('n), atom('m)) -> bool
-val gteq_atom = "gteq" : forall 'n 'm. (atom('n), atom('m)) -> bool
-val lt_atom = "lt" : forall 'n 'm. (atom('n), atom('m)) -> bool
-val gt_atom = "gt" : forall 'n 'm. (atom('n), atom('m)) -> bool
-
-val eq_int = {ocaml: "eq_int", lem: "eq"} : (int, int) -> bool
-
val eq_vec = {ocaml: "eq_list", lem: "eq_vec"} : forall 'n. (bits('n), bits('n)) -> bool
val eq_string = {ocaml: "eq_string", lem: "eq"} : (string, string) -> bool
@@ -64,32 +56,18 @@ val vector_concat = {ocaml: "append", lem: "append_list"} : forall ('n : Int) ('
overload append = {bitvector_concat, vector_concat}
-val not_bool = "not" : bool -> bool
-
val not_vec = "not_vec" : forall 'n. bits('n) -> bits('n)
overload ~ = {not_bool, not_vec}
-val neq_atom = {lem: "neq"} : forall 'n 'm. (atom('n), atom('m)) -> bool
-
-function neq_atom (x, y) = not_bool(eq_atom(x, y))
-
-val neq_int = {lem: "neq"} : (int, int) -> bool
-
-function neq_int (x, y) = not_bool(eq_int(x, y))
-
val neq_vec = {lem: "neq"} : forall 'n. (bits('n), bits('n)) -> bool
-
function neq_vec (x, y) = not_bool(eq_vec(x, y))
val neq_anything = {lem: "neq"} : forall ('a : Type). ('a, 'a) -> bool
-
function neq_anything (x, y) = not_bool(x == y)
overload operator != = {neq_atom, neq_int, neq_vec, neq_anything}
-val and_bool = "and_bool" : (bool, bool) -> bool
-
val builtin_and_vec = {ocaml: "and_vec"} : forall 'n. (bits('n), bits('n)) -> bits('n)
val and_vec = {lem: "and_vec"} : forall 'n. (bits('n), bits('n)) -> bits('n)
@@ -98,8 +76,6 @@ function and_vec (xs, ys) = builtin_and_vec(xs, ys)
overload operator & = {and_bool, and_vec}
-val or_bool = "or_bool" : (bool, bool) -> bool
-
val builtin_or_vec = {ocaml: "or_vec"} : forall 'n. (bits('n), bits('n)) -> bits('n)
val or_vec = {lem: "or_vec"} : forall 'n. (bits('n), bits('n)) -> bits('n)
@@ -133,8 +109,8 @@ val __raw_SetSlice_bits : forall 'n 'w.
val __raw_GetSlice_bits : forall 'n 'w.
(atom('n), atom('w), bits('n), int) -> bits('w)
-val "shiftl" : forall 'm. (bits('m), int) -> bits('m)
-val "shiftr" : forall 'm. (bits('m), int) -> bits('m)
+val "shiftl" : forall 'm 'n, 'n >= 0. (bits('m), atom('n)) -> bits('m)
+val "shiftr" : forall 'm 'n, 'n >= 0. (bits('m), atom('n)) -> bits('m)
val __SignExtendSlice = {lem: "exts_slice"} : forall 'm. (bits('m), int, int) -> bits('m)
@@ -212,26 +188,18 @@ overload operator * = {mult_range, mult_int, mult_real}
val Sqrt = {ocaml: "sqrt_real", lem: "realSqrt"} : real -> real
-val gteq_int = "gteq" : (int, int) -> bool
-
val gteq_real = {ocaml: "gteq_real", lem: "gteq"} : (real, real) -> bool
overload operator >= = {gteq_atom, gteq_int, gteq_real}
-val lteq_int = "lteq" : (int, int) -> bool
-
val lteq_real = {ocaml: "lteq_real", lem: "lteq"} : (real, real) -> bool
overload operator <= = {lteq_atom, lteq_int, lteq_real}
-val gt_int = "gt" : (int, int) -> bool
-
val gt_real = {ocaml: "gt_real", lem: "gt"} : (real, real) -> bool
overload operator > = {gt_atom, gt_int, gt_real}
-val lt_int = "lt" : (int, int) -> bool
-
val lt_real = {ocaml: "lt_real", lem: "lt"} : (real, real) -> bool
overload operator < = {lt_atom, lt_int, lt_real}
@@ -282,8 +250,8 @@ overload max = {max_nat, max_int}
val __WriteRAM = "write_ram" : forall 'n 'm.
(atom('m), atom('n), bits('m), bits('m), bits(8 * 'n)) -> unit effect {wmv}
-val __RISCV_write : forall 'n. (bits(64), atom('n), bits(8 * 'n)) -> unit effect {wmv}
-function __RISCV_write (addr, width, data) = __WriteRAM(64, width, 0x0000_0000_0000_0000, addr, data)
+val __MIPS_write : forall 'n. (bits(64), atom('n), bits(8 * 'n)) -> unit effect {wmv}
+function __MIPS_write (addr, width, data) = __WriteRAM(64, width, 0x0000_0000_0000_0000, addr, data)
val __TraceMemoryWrite : forall 'n 'm.
(atom('n), bits('m), bits(8 * 'n)) -> unit
@@ -291,14 +259,15 @@ val __TraceMemoryWrite : forall 'n 'm.
val __ReadRAM = "read_ram" : forall 'n 'm.
(atom('m), atom('n), bits('m), bits('m)) -> bits(8 * 'n) effect {rmem}
-val __RISCV_read : forall 'n. (bits(64), atom('n)) -> bits(8 * 'n) effect {rmem}
-function __RISCV_read (addr, width) = __ReadRAM(64, width, 0x0000_0000_0000_0000, addr)
+val __MIPS_read : forall 'n. (bits(64), atom('n)) -> bits(8 * 'n) effect {rmem}
+function __MIPS_read (addr, width) = __ReadRAM(64, width, 0x0000_0000_0000_0000, addr)
val __TraceMemoryRead : forall 'n 'm. (atom('n), bits('m), bits(8 * 'n)) -> unit
val replicate_bits = "replicate_bits" : forall 'n 'm. (bits('n), atom('m)) -> bits('n * 'm)
-infix 4 ^^
+infix 8 ^^
+val operator ^^ : forall 'n 'm . (bits('n), atom('m)) -> bits('n * 'm)
function operator ^^ (bs, n) = replicate_bits (bs, n)
val cast ex_nat : nat -> {'n, 'n >= 0. atom('n)}
@@ -369,11 +338,21 @@ val cast bit_to_bool : bit -> bool
function bit_to_bool bitone = true
and bit_to_bool bitzero = false
-infix 7 >>
-infix 7 <<
+val cast bits_to_bool : bits(1) -> bool
+function bits_to_bool x = bit_to_bool(x[0])
+
+infix 1 >>
+infix 1 <<
+infix 1 >>_s
val operator >> = "shift_bits_right" : forall 'n 'm. (bits('n), bits('m)) -> bits('n)
val operator << = "shift_bits_left" : forall 'n 'm. (bits('n), bits('m)) -> bits('n)
+val operator >>_s = "shift_bits_right_arith" : forall 'n 'm. (bits('n), bits('m)) -> bits('n)
+
+infix 7 *_s
+val operator *_s = "mult_svec" : forall 'n . (bits('n), bits('n)) -> bits(2 * 'n)
+infix 7 *_u
+val operator *_u = "mult_vec" : forall 'n . (bits('n), bits('n)) -> bits(2 * 'n)
val vector64 : int -> bits(64)
@@ -391,3 +370,7 @@ val vector_update_subrange_inc = {ocaml: "update_subrange", lem: "update_subrang
(vector('n, inc, bit), atom('m), atom('o), vector('o - ('m - 1), inc, bit)) -> vector('n, inc, bit)
overload vector_update_subrange = {vector_update_subrange_dec, vector_update_subrange_inc}
+
+val mask : forall 'm 'n , 'm >= 'n > 0 . bits('m) -> bits('n)
+function mask bs = bs['n - 1 .. 0]
+
diff --git a/src/Makefile b/src/Makefile
index e44f13fb..8bf4802a 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -119,7 +119,7 @@ MIPS_SAIL_DIR:=$(SAIL_DIR)/mips_new_tc
MIPS_SAILS_PRE:=$(SAIL_LIB_DIR)/flow.sail $(MIPS_SAIL_DIR)/prelude.sail $(MIPS_SAIL_DIR)/mips_prelude.sail $(MIPS_SAIL_DIR)/mips_tlb.sail $(MIPS_SAIL_DIR)/mips_wrappers.sail $(MIPS_SAIL_DIR)/mips_ast_decl.sail $(MIPS_SAIL_DIR)/mips_insts.sail $(MIPS_SAIL_DIR)/mips_ri.sail $(MIPS_SAIL_DIR)/mips_epilogue.sail
-MIPS_SAILS:=$(MIPS_SAILS_PRE) $(SAIL_DIR)/etc/regfp.sail $(MIPS_SAIL_DIR)/mips_regfp.sail
+MIPS_SAILS:=$(MIPS_SAILS_PRE)
MIPS_NOTLB_SAILS_PRE:=$(SAIL_LIB_DIR)/flow.sail $(MIPS_SAIL_DIR)/prelude.sail $(MIPS_SAIL_DIR)/mips_prelude.sail $(MIPS_SAIL_DIR)/mips_tlb_stub.sail $(MIPS_SAIL_DIR)/mips_wrappers.sail $(MIPS_SAIL_DIR)/mips_ast_decl.sail $(MIPS_SAIL_DIR)/mips_insts.sail $(MIPS_SAIL_DIR)/mips_epilogue.sail
@@ -176,7 +176,7 @@ _build/Mips.thy: _build/mips_types.lem
_build/mips_notlb.lem: $(MIPS_NOTLB_SAILS) ./sail.native
mkdir -p _build
cd _build ; \
- ../sail.native -lem_ast -o mips_notlb $(MIPS_NOTLB_SAILS)
+ ../sail.native -lem_ast -o mips_notlb $(MIPS_NOTLB_SAILS_PRE)
_build/mips_notlb.ml: $(MIPS_NOTLB_SAILS_PRE) ./sail.native
mkdir -p _build