summaryrefslogtreecommitdiff
path: root/risc-v
diff options
context:
space:
mode:
authorRobert Norton2017-07-27 13:18:32 +0100
committerRobert Norton2017-07-27 13:18:46 +0100
commit2b8ab9a1d1438ee8462e5140711fa5f6f4074aef (patch)
tree5f62562881dfd37057d986a3f2305112b75755c8 /risc-v
parente472553a0bc8c1c59d2e1e460cbd9395727a0279 (diff)
implement RV64I based on version 2.0 user spec.
Diffstat (limited to 'risc-v')
-rw-r--r--risc-v/risc-v.sail2173
1 files changed, 235 insertions, 1938 deletions
diff --git a/risc-v/risc-v.sail b/risc-v/risc-v.sail
index 92e8da51..edf95c62 100644
--- a/risc-v/risc-v.sail
+++ b/risc-v/risc-v.sail
@@ -1,1966 +1,263 @@
default Order dec
-register (bit[64]) x0
-register (bit[64]) x1
-register (bit[64]) x2
-register (bit[64]) x3
-register (bit[64]) x4
-register (bit[64]) x5
-register (bit[64]) x6
-register (bit[64]) x7
-register (bit[64]) x8
-register (bit[64]) x9
-register (bit[64]) x10
-register (bit[64]) x11
-register (bit[64]) x12
-register (bit[64]) x13
-register (bit[64]) x14
-register (bit[64]) x15
-register (bit[64]) x16
-register (bit[64]) x17
-register (bit[64]) x18
-register (bit[64]) x19
-register (bit[64]) x20
-register (bit[64]) x21
-register (bit[64]) x22
-register (bit[64]) x23
-register (bit[64]) x24
-register (bit[64]) x25
-register (bit[64]) x26
-register (bit[64]) x27
-register (bit[64]) x28
-register (bit[64]) x29
-register (bit[64]) x30
-register (bit[64]) x31
-
-let (vector <0, 32, inc, (register<(bit[64])>) >) x =
+typedef regval = bit[64]
+typedef regno = bit[5]
+
+register (regval) x0
+register (regval) x1
+register (regval) x2
+register (regval) x3
+register (regval) x4
+register (regval) x5
+register (regval) x6
+register (regval) x7
+register (regval) x8
+register (regval) x9
+register (regval) x10
+register (regval) x11
+register (regval) x12
+register (regval) x13
+register (regval) x14
+register (regval) x15
+register (regval) x16
+register (regval) x17
+register (regval) x18
+register (regval) x19
+register (regval) x20
+register (regval) x21
+register (regval) x22
+register (regval) x23
+register (regval) x24
+register (regval) x25
+register (regval) x26
+register (regval) x27
+register (regval) x28
+register (regval) x29
+register (regval) x30
+register (regval) x31
+
+register (bit[64]) PC
+register (bit[64]) nextPC
+
+let (vector <0, 32, inc, (register<(regval)>)>) GPRs =
[x0, x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,x16,x17,x18,x19,x20,x21,x22,x23,x24,x25,x26,x27,x28,x29,x30,x31]
-typedef arithr = enumerate { ADD; SLL; SLT; SLTU; XOR; SRL; OR; AND }
-
-
-scattered function unit execute
-scattered typedef ast = const union
-
-val bit[32] -> ast effect pure decode
-
-scattered function ast decode
-
-union ast member (bit[5], bit[5], arithr, bit[5]) Arithr1
-
-function clause decode (0b0000000 :
-(bit[5]) src2 :
-(bit[5]) src1 :
-(bit[3]) arithr_op :
-(bit[5]) dest :
-0b0110011 ) =
-Arithr1(src2,src1, (([|7|]) arithr_op), dest)
-
-
-function clause execute (Arithr1(src2,src1, arithr_op, dest)) =
- {
- switch arithr_op {
- case ADD -> x[dest] := x[src1] + x[src2]
-(* case SLL ->
- case SLT ->
- case SLTU ->
- case XOR ->
- case SRL ->
- case OR ->
- case AND -> *)
- }
-}
-
-end ast
-end decode
-end execute
-
-(*val extern forall Nat 'm, Nat 'n. (implicit<'m>,bit['n]) -> bit['m] effect pure EXTS
-
-(* XXX binary coded decimal *)
-function forall Type 'a . 'a DEC_TO_BCD ( x ) = x
-function forall Type 'a . 'a BCD_TO_DEC ( x ) = x
-(* XXX carry out *)
-function forall Nat 'a . bit carry_out ( (bit['a]) _,carry ) = carry
-(* XXX Storage control *)
-function forall Type 'a . 'a real_addr ( x ) = x
-(* XXX For stvxl and lvxl - what does that do? *)
-function forall Type 'a . unit mark_as_not_likely_to_be_needed_again_anytime_soon ( x ) = ()
-
-(* XXX *)
-val extern forall Nat 'k, Nat 'r,
- 0 <= 'k, 'k <= 64, 'r + 'k = 64.
- (bit[64], [|'k|]) -> [|0:'r|] effect pure countLeadingZeroes
-
-function forall Nat 'n, Nat 'm .
- bit['m] EXTS_EXPLICIT((bit['n]) v, ([|'m|]) m) =
- (v[0] ^^ (m - length(v))) : v
-
-val forall Nat 'n, Nat 'm, 0 <= 'n, 'n <= 'm, 'm <= 63 .
- ([|'n|],[|'m|]) -> bit[64]
- effect pure
- MASK
-
-function (bit[64]) MASK(start, stop) = {
- (bit[64]) mask_temp := 0;
- if(start > stop) then {
- mask_temp[start .. 63] := bitone ^^ (64 - start);
- mask_temp[0 .. stop] := bitone ^^ (stop + 1);
- } else {
- mask_temp[start .. stop ] := bitone ^^ (stop - start + 1);
- };
- mask_temp;
-}
-
-val forall Nat 'n, 0 <= 'n, 'n <= 63 .
- (bit[64], [|'n|]) -> bit[64] effect pure ROTL
-
-function (bit[64]) ROTL(v, n) = v[n .. 63] : v[0 .. (n-1)]
-
-(* Branch facility registers *)
-
-typedef cr = register bits [ 32 : 63 ] {
- 32 .. 35 : CR0;
- 32 : LT; 33 : GT; 34 : EQ; 35 : SO;
- 36 .. 39 : CR1;
- 36 : FX; 37 : FEX; 38 : VX; 39 : OX;
- 40 .. 43 : CR2;
- 44 .. 47 : CR3;
- 48 .. 51 : CR4;
- 52 .. 55 : CR5;
- 56 .. 59 : CR6;
- (* name clashing - do we need hierarchical naming for fields, or do
- we just don't care? LT, GT, etc. are not used in the code anyway.
- 56 : LT; 57 : GT; 58 : EQ; 59 : SO;
- *)
- 60 .. 63 : CR7;
-}
-register (cr) CR
-
-register (bit[64]) CTR
-register (bit[64]) LR
-
-typedef xer = register bits [ 0 : 63 ] {
- 32 : SO;
- 33 : OV;
- 34 : CA;
-}
-register (xer) XER
-
-register alias CA = XER.CA
-
-(* Fixed-point registers *)
-
-register (bit[64]) GPR0
-register (bit[64]) GPR1
-register (bit[64]) GPR2
-register (bit[64]) GPR3
-register (bit[64]) GPR4
-register (bit[64]) GPR5
-register (bit[64]) GPR6
-register (bit[64]) GPR7
-register (bit[64]) GPR8
-register (bit[64]) GPR9
-register (bit[64]) GPR10
-register (bit[64]) GPR11
-register (bit[64]) GPR12
-register (bit[64]) GPR13
-register (bit[64]) GPR14
-register (bit[64]) GPR15
-register (bit[64]) GPR16
-register (bit[64]) GPR17
-register (bit[64]) GPR18
-register (bit[64]) GPR19
-register (bit[64]) GPR20
-register (bit[64]) GPR21
-register (bit[64]) GPR22
-register (bit[64]) GPR23
-register (bit[64]) GPR24
-register (bit[64]) GPR25
-register (bit[64]) GPR26
-register (bit[64]) GPR27
-register (bit[64]) GPR28
-register (bit[64]) GPR29
-register (bit[64]) GPR30
-register (bit[64]) GPR31
-
-let (vector <0, 32, inc, (register<(bit[64])>) >) GPR =
- [ GPR0, GPR1, GPR2, GPR3, GPR4, GPR5, GPR6, GPR7, GPR8, GPR9, GPR10,
- GPR11, GPR12, GPR13, GPR14, GPR15, GPR16, GPR17, GPR18, GPR19, GPR20,
- GPR21, GPR22, GPR23, GPR24, GPR25, GPR26, GPR27, GPR28, GPR29, GPR30, GPR31
- ]
-
-register (bit[32:63]) VRSAVE
-
-register (bit[64]) SPRG4
-register (bit[64]) SPRG5
-register (bit[64]) SPRG6
-register (bit[64]) SPRG7
-
-(* XXX bogus, length should be 1024 with many more values - cf. mfspr
- definition - eg. SPRG4 to SPRG7 are at offsets 260 to 263, VRSAVE is 256,
- etc. *)
-let (vector <0, 10, inc, (register<(bit[64])>) >) SPR =
- [ undefined, XER, undefined, undefined,
- undefined, undefined, undefined, undefined,
- LR, CTR
- ]
-
-(* XXX DCR is implementation-dependent; also, some DCR are only 32 bits
- instead of 64, and mtdcrux/mfdcrux do special tricks in that case, not
- shown in pseudo-code. We just define two dummy DCR here, using sparse
- vector definition. *)
-register (vector <0, 64, inc, bit>) DCR0
-register (vector <0, 64, inc, bit>) DCR1
-let (vector <0, 2** 64, inc, (register<(vector<0, 64, inc, bit>)>) >) DCR =
- [ 0=DCR0, 1=DCR1 ]
-
-(* Floating-point registers *)
-
-register (bit[64]) FPR0
-register (bit[64]) FPR1
-register (bit[64]) FPR2
-register (bit[64]) FPR3
-register (bit[64]) FPR4
-register (bit[64]) FPR5
-register (bit[64]) FPR6
-register (bit[64]) FPR7
-register (bit[64]) FPR8
-register (bit[64]) FPR9
-register (bit[64]) FPR10
-register (bit[64]) FPR11
-register (bit[64]) FPR12
-register (bit[64]) FPR13
-register (bit[64]) FPR14
-register (bit[64]) FPR15
-register (bit[64]) FPR16
-register (bit[64]) FPR17
-register (bit[64]) FPR18
-register (bit[64]) FPR19
-register (bit[64]) FPR20
-register (bit[64]) FPR21
-register (bit[64]) FPR22
-register (bit[64]) FPR23
-register (bit[64]) FPR24
-register (bit[64]) FPR25
-register (bit[64]) FPR26
-register (bit[64]) FPR27
-register (bit[64]) FPR28
-register (bit[64]) FPR29
-register (bit[64]) FPR30
-register (bit[64]) FPR31
-
-let (vector <0, 32, inc, (register<(bit[64])>) >) FPR =
- [ FPR0, FPR1, FPR2, FPR3, FPR4, FPR5, FPR6, FPR7, FPR8, FPR9, FPR10,
- FPR11, FPR12, FPR13, FPR14, FPR15, FPR16, FPR17, FPR18, FPR19, FPR20,
- FPR21, FPR22, FPR23, FPR24, FPR25, FPR26, FPR27, FPR28, FPR29, FPR30, FPR31
- ]
-
-typedef fpscr = register bits [ 0 : 63 ] {
- 32 : FX;
- 33 : FEX;
- 34 : VX;
- 35 : OX;
- 36 : UX;
- 37 : ZX;
- 38 : XX;
- 39 : VXSNAN;
- 40 : VXISI;
- 41 : VXIDI;
- 42 : VXZDZ;
- 43 : VXIMZ;
- 44 : VXVC;
- 45 : FR;
- 46 : FI;
- 47 .. 51 : FPRF;
- 47 : C;
- 48 .. 51 : FPCC;
- 48 : FL; 49 : FG; 50 : FE; 51 : FU;
- 53 : VXSOFT;
- 54 : VXSQRT;
- 55 : VXCVI;
- 56 : VE;
- 57 : OE;
- 58 : UE;
- 59 : ZE;
- 60 : XE;
- 61 : NI;
- 62 .. 63 : RN;
-}
-register (fpscr) FPSCR
+function (regval) rGPR ((regno) r) =
+ if (r == 0) then
+ 0
+ else
+ GPRs[r]
-(* Pair-wise access to FPR registers *)
+function unit wGPR((regno) r, (regval) v) =
+ if (r != 0) then
+ GPRs[r] := v
-register alias FPRp0 = FPR0 : FPR1
-register alias FPRp2 = FPR2 : FPR3
-register alias FPRp4 = FPR4 : FPR5
-register alias FPRp6 = FPR6 : FPR7
-register alias FPRp8 = FPR8 : FPR9
-register alias FPRp10 = FPR10 : FPR11
-register alias FPRp12 = FPR12 : FPR13
-register alias FPRp14 = FPR14 : FPR15
-register alias FPRp16 = FPR16 : FPR17
-register alias FPRp18 = FPR18 : FPR19
-register alias FPRp20 = FPR20 : FPR21
-register alias FPRp22 = FPR22 : FPR23
-register alias FPRp24 = FPR24 : FPR25
-register alias FPRp26 = FPR26 : FPR27
-register alias FPRp28 = FPR28 : FPR29
-register alias FPRp30 = FPR30 : FPR31
-
-let (vector <0, 32, inc, (register<(bit[128])>)>) FPRp =
- [ 0 = FPRp0, 2 = FPRp2, 4 = FPRp4, 6 = FPRp6, 8 = FPRp8, 10 = FPRp10,
- 12 = FPRp12, 14 = FPRp14, 16 = FPRp16, 18 = FPRp18, 20 = FPRp20, 22 =
- FPRp22, 24 = FPRp24, 26 = FPRp26, 28 = FPRp28, 30 = FPRp30 ]
-
-
-(* XXX *)
-val bit[32] -> bit[64] effect pure DOUBLE
-val bit[64] -> bit[32] effect { undef } SINGLE
-
-function bit[64] DOUBLE word = {
- (bit[64]) temp := 0;
- if word[1..8] > 0 & word[1..8] < 255
- then {
- temp[0..1] := word[0..1];
- temp[2] := ~(word[1]);
- temp[3] := ~(word[1]);
- temp[4] := ~(word[1]);
- temp[5..63] := word[2..31] : 0b00000000000000000000000000000;
- } else if word[1..8] == 0 & word[9..31] != 0
- then {
- sign := word[0];
- exp := 0-126;
- (bit[53]) frac := 0b0 : word[9..31] : 0b00000000000000000000000000000;
- foreach (i from 0 to 52) {
- if frac[0] == 0
- then { frac[0..52] := frac[1..52] : 0b0;
- exp := exp -1; }
- else ()
- };
- temp[0] := sign;
- temp[1..11] := (bit[10]) exp + 1023;
- temp[12..63] := frac[1..52];
- } else {
- temp[0..1] := word[0..1];
- temp[2] := word[1];
- temp[3] := word[1];
- temp[4] := word[1];
- temp[5..63] := word[2..31] : 0b00000000000000000000000000000;
- };
- temp
-}
-
-function bit[32] SINGLE ((bit[64]) frs) = {
- (bit[32]) word := 0;
- if (frs[1..11] > 896) | (frs[1..63] == 0)
- then { word[0..1] := frs[0..1];
- word[2..31] := frs[5..34]; }
- else if (874 <= frs[1..11]) & (frs[1..11] <= 896)
- then {
- sign := frs[0];
- (bit[10]) exp := frs[1..11] - 1023;
- (bit[53]) frac := 0b1 : frs[12..63];
- foreach (i from 0 to 53) {
- if exp < (0-126)
- then { frac[0..52] := 0b0 : frac[0..51];
- exp := exp + 1; }
- else ()};
- } else word := undefined;
- word
-}
-
-(* Vector registers *)
-
-register (bit[128]) VR0
-register (bit[128]) VR1
-register (bit[128]) VR2
-register (bit[128]) VR3
-register (bit[128]) VR4
-register (bit[128]) VR5
-register (bit[128]) VR6
-register (bit[128]) VR7
-register (bit[128]) VR8
-register (bit[128]) VR9
-register (bit[128]) VR10
-register (bit[128]) VR11
-register (bit[128]) VR12
-register (bit[128]) VR13
-register (bit[128]) VR14
-register (bit[128]) VR15
-register (bit[128]) VR16
-register (bit[128]) VR17
-register (bit[128]) VR18
-register (bit[128]) VR19
-register (bit[128]) VR20
-register (bit[128]) VR21
-register (bit[128]) VR22
-register (bit[128]) VR23
-register (bit[128]) VR24
-register (bit[128]) VR25
-register (bit[128]) VR26
-register (bit[128]) VR27
-register (bit[128]) VR28
-register (bit[128]) VR29
-register (bit[128]) VR30
-register (bit[128]) VR31
-
-let (vector <0, 32, inc, (register<(bit[128])>) >) VR =
- [ VR0, VR1, VR2, VR3, VR4, VR5, VR6, VR7, VR8, VR9, VR10,
- VR11, VR12, VR13, VR14, VR15, VR16, VR17, VR18, VR19, VR20,
- VR21, VR22, VR23, VR24, VR25, VR26, VR27, VR28, VR29, VR30, VR31
- ]
-
-typedef vscr = register bits [ 96 : 127 ] {
- 111 : NJ;
- 127 : SAT;
-}
-register (vscr) VSCR
-
-(* XXX extend with zeroes -- the resulting size in completely unknown and depends of context *)
-val extern forall Nat 'n, Nat 'm. bit['n] -> bit['m] effect pure EXTZ
-
-(* Chop has a very weird definition where the resulting size depends of
- context, but in practice it is used with the following definition everywhere,
- except in vaddcuw which probably needs to be patched accordingly. *)
-val forall Nat 'n, Nat 'm, 'm <= 'n. (bit['n], [|'m|]) -> bit['m] effect pure Chop
-function forall Nat 'm. (bit['m]) Chop(x, y) = x[0..y]
-
-val forall Nat 'n, Nat 'm, Nat 'k, 'n <= 0, 0 <= 'm.
- (implicit<'k>, int, [|'n|], [|'m|]) -> bit['k] effect { wreg } Clamp
-
-function forall Nat 'n, Nat 'm, Nat 'k, 'n <= 0, 0 <= 'm. (bit['k])
-Clamp((int) x, ([|'n|]) y, ([|'m|]) z) = {
- ([|'n:'m|]) result := 0;
- if (x<y) then {
- result := y;
- VSCR.SAT := 1;
- } else if (x > z) then {
- result := z;
- VSCR.SAT := 1;
- } else {
- result := x;
- };
- (bit['k]) result;
-}
-
-(* XXX *)
-val extern bit[32] -> bit[32] effect pure RoundToSPIntCeil
-val extern bit[32] -> bit[32] effect pure RoundToSPIntFloor
-val extern bit[32] -> bit[32] effect pure RoundToSPIntNear
-val extern bit[32] -> bit[32] effect pure RoundToSPIntTrunc
-val extern bit[32] -> bit[32] effect pure RoundToNearSP
-val extern bit[32] -> bit[32] effect pure ReciprocalEstimateSP
-val extern bit[32] -> bit[32] effect pure ReciprocalSquareRootEstimateSP
-val extern bit[32] -> bit[32] effect pure LogBase2EstimateSP
-val extern bit[32] -> bit[32] effect pure Power2EstimateSP
-val extern (bit[32], bit[5]) -> bit[32] effect pure ConvertSPtoSXWsaturate
-val extern (bit[32], bit[5]) -> bit[32] effect pure ConvertSPtoUXWsaturate
-
-
-register (bit[64]) NIA (* next instruction address *)
-register (bit[64]) CIA (* current instruction address *)
-
-
-val extern forall Nat 'n. ( bit[64] , [|'n|] , bit[8*'n]) -> unit effect { wmem } MEMw
val extern forall Nat 'n. ( bit[64] , [|'n|] ) -> (bit[8 * 'n]) effect { rmem } MEMr
-val extern forall Nat 'n. ( bit[64] , [|'n|] ) -> (bit[8 * 'n]) effect { rmem } MEMr_reserve
-val extern forall Nat 'n. ( bit[64] , [|'n|] , bit[8*'n]) -> bool effect { wmem } MEMw_conditional
+val extern forall Nat 'n. ( bit[64] , [|'n|]) -> unit effect { eamem } MEMea
+val extern forall Nat 'n. ( bit[64] , [|'n|] , bit[8*'n]) -> unit effect { wmv } MEMval
-val extern unit -> unit effect { barr } I_Sync
-val extern unit -> unit effect { barr } H_Sync (*corresponds to Sync in barrier kinds*)
-val extern unit -> unit effect { barr } LW_Sync
-val extern unit -> unit effect { barr } EIEIO_Sync
+(* Ideally these would be sail builtin *)
+function (bit[64]) shift_right_arith64 ((bit[64]) v, (bit[6]) shift) =
+ let (bit[128]) v128 = EXTS(v) in
+ (v128 >> shift)[63..0]
-val forall Nat 'n, Nat 'm, 'n *8 = 'm. (implicit<'m>,(bit['m])) -> (bit['m]) effect pure byte_reverse
-function forall Nat 'n, Nat 'm, 'n*8 = 'm. (bit['m]) effect pure byte_reverse((bit['m]) input) = {
- (bit['m]) output := 0;
- j := length(input);
- foreach (i from 0 to (length(input)) by 8) {
- output[i..i+7] := input[j-7 ..j];
- j := j-8; };
- output
-}
+function (bit[32]) shift_right_arith32 ((bit[32]) v, (bit[5]) shift) =
+ let (bit[64]) v64 = EXTS(v) in
+ (v64 >> shift)[31..0]
-(* XXX effect for trap? *)
-val extern unit -> unit effect pure trap
-
-register (bit[1]) mode64bit
-register (bit[1]) bigendianmode
-
-val (bit[64],bit) -> unit effect {rreg,wreg} set_overflow_cr0
-function (unit) set_overflow_cr0(target_register,new_xer_so) = {
- (if mode64bit
- then m := 0
- else m := 32);
- (bit[64]) zero := 0;
- (if target_register[m..63] <_s zero[m..63]
- then c := 0b100
- else if target_register[m..63] >_s zero[m..63]
- then c := 0b010
- else c := 0b001);
- CR.CR0 := c:[new_xer_so]
-}
-
-function (unit) set_SO_OV(overflow) = {
- XER.OV := overflow;
- XER.SO := (XER.SO | overflow);
-}
+typedef uop = enumerate {LUI; AUIPC} (* upper immediate ops *)
+typedef bop = enumerate {BEQ; BNE; BLT; BGE; BLTU; BGEU} (* branch ops *)
+typedef iop = enumerate {ADDI; SLTI; SLTIU; XORI; ORI; ANDI} (* immediate ops *)
+typedef sop = enumerate {SLLI; SRLI; SRAI} (* shift ops *)
+typedef rop = enumerate {ADD; SUB; SLL; SLT; SLTU; XOR; SRL; SRA; OR; AND} (* reg-reg ops *)
+typedef ropw = enumerate {ADDW; SUBW; SLLW; SRLW; SRAW} (* reg-reg 32-bit ops *)
scattered function unit execute
scattered typedef ast = const union
-val bit[32] -> ast effect pure decode
-
-scattered function ast decode
-
-union ast member (bit[24], bit, bit) B
-
-function clause decode (0b010010 :
-(bit[24]) LI :
-[AA] :
-[LK] as instr) =
- B (LI,AA,LK)
-
-function clause execute (B (LI, AA, LK)) =
- {
- if AA then NIA := EXTS (LI : 0b00) else NIA := CIA + EXTS (LI : 0b00);
- if LK then LR := CIA + 4 else ()
- }
-
-union ast member (bit[5], bit[5], bit[14], bit, bit) Bc
-
-function clause decode (0b010000 :
-(bit[5]) BO :
-(bit[5]) BI :
-(bit[14]) BD :
-[AA] :
-[LK] as instr) =
- Bc (BO,BI,BD,AA,LK)
-
-function clause execute (Bc (BO, BI, BD, AA, LK)) =
- {
- if mode64bit then M := 0 else M := 32;
- ctr_temp := CTR;
- if ~ (BO[2])
- then {
- ctr_temp := ctr_temp - 1;
- CTR := ctr_temp
- }
- else ();
- ctr_ok := (BO[2] | ~ (ctr_temp[M .. 63] == 0) ^ BO[3]);
- cond_ok := (BO[0] | CR[BI + 32] ^ ~ (BO[1]));
- if ctr_ok & cond_ok
- then if AA then NIA := EXTS (BD : 0b00) else NIA := CIA + EXTS (BD : 0b00)
- else ();
- if LK then LR := CIA + 4 else ()
- }
-
-union ast member (bit[5], bit[5], bit[2], bit) Bclr
-
-function clause decode (0b010011 :
-(bit[5]) BO :
-(bit[5]) BI :
-(bit[3]) _ :
-(bit[2]) BH :
-0b0000010000 :
-[LK] as instr) =
- Bclr (BO,BI,BH,LK)
-
-function clause execute (Bclr (BO, BI, BH, LK)) =
- {
- if mode64bit then M := 0 else M := 32;
- ctr_temp := CTR;
- if ~ (BO[2])
- then {
- ctr_temp := ctr_temp - 1;
- CTR := ctr_temp
- }
- else ();
- ctr_ok := (BO[2] | ~ (ctr_temp[M .. 63] == 0) ^ BO[3]);
- cond_ok := (BO[0] | CR[BI + 32] ^ ~ (BO[1]));
- if ctr_ok & cond_ok then NIA := LR[0 .. 61] : 0b00 else ();
- if LK then LR := CIA + 4 else ()
- }
-
-union ast member (bit[5], bit[5], bit[2], bit) Bcctr
-
-function clause decode (0b010011 :
-(bit[5]) BO :
-(bit[5]) BI :
-(bit[3]) _ :
-(bit[2]) BH :
-0b1000010000 :
-[LK] as instr) =
- Bcctr (BO,BI,BH,LK)
-
-function clause execute (Bcctr (BO, BI, BH, LK)) =
- {
- cond_ok := (BO[0] | CR[BI + 32] ^ ~ (BO[1]));
- if cond_ok then NIA := CTR[0 .. 61] : 0b00 else ();
- if LK then LR := CIA + 4 else ()
- }
-
-union ast member (bit[7]) Sc
-
-function clause decode (0b010001 :
-(bit[5]) _ :
-(bit[5]) _ :
-(bit[4]) _ :
-(bit[7]) LEV :
-(bit[3]) _ :
-0b1 :
-(bit[1]) _ as instr) =
- Sc (LEV)
-
-function clause execute (Sc (LEV)) = ()
-
-union ast member (bit[5], bit[5], bit[16]) Lbzu
-
-function clause decode (0b100011 :
-(bit[5]) RT :
-(bit[5]) RA :
-(bit[16]) D as instr) =
- Lbzu (RT,RA,D)
-
-function clause execute (Lbzu (RT, RA, D)) =
- {
- (bit[64]) EA := 0;
- EA := GPR[RA] + EXTS (D);
- GPR[RT] :=
- 0b00000000000000000000000000000000000000000000000000000000 : MEMr (EA,1);
- GPR[RA] := EA
- }
-
-union ast member (bit[5], bit[5], bit[5]) Lbzux
-
-function clause decode (0b011111 :
-(bit[5]) RT :
-(bit[5]) RA :
-(bit[5]) RB :
-0b0001110111 :
-(bit[1]) _ as instr) =
- Lbzux (RT,RA,RB)
-
-function clause execute (Lbzux (RT, RA, RB)) =
- {
- (bit[64]) EA := 0;
- EA := GPR[RA] + GPR[RB];
- GPR[RT] :=
- 0b00000000000000000000000000000000000000000000000000000000 : MEMr (EA,1);
- GPR[RA] := EA
- }
-
-union ast member (bit[5], bit[5], bit[16]) Lhzu
-
-function clause decode (0b101001 :
-(bit[5]) RT :
-(bit[5]) RA :
-(bit[16]) D as instr) =
- Lhzu (RT,RA,D)
-
-function clause execute (Lhzu (RT, RA, D)) =
- {
- (bit[64]) EA := 0;
- EA := GPR[RA] + EXTS (D);
- GPR[RT] := 0b000000000000000000000000000000000000000000000000 : MEMr (EA,2);
- GPR[RA] := EA
- }
-
-union ast member (bit[5], bit[5], bit[5]) Lhzux
-
-function clause decode (0b011111 :
-(bit[5]) RT :
-(bit[5]) RA :
-(bit[5]) RB :
-0b0100110111 :
-(bit[1]) _ as instr) =
- Lhzux (RT,RA,RB)
-
-function clause execute (Lhzux (RT, RA, RB)) =
- {
- (bit[64]) EA := 0;
- EA := GPR[RA] + GPR[RB];
- GPR[RT] := 0b000000000000000000000000000000000000000000000000 : MEMr (EA,2);
- GPR[RA] := EA
- }
-
-union ast member (bit[5], bit[5], bit[16]) Lhau
-
-function clause decode (0b101011 :
-(bit[5]) RT :
-(bit[5]) RA :
-(bit[16]) D as instr) =
- Lhau (RT,RA,D)
-
-function clause execute (Lhau (RT, RA, D)) =
- {
- (bit[64]) EA := 0;
- EA := GPR[RA] + EXTS (D);
- GPR[RT] := EXTS (MEMr (EA,2));
- GPR[RA] := EA
- }
-
-union ast member (bit[5], bit[5], bit[5]) Lhaux
-
-function clause decode (0b011111 :
-(bit[5]) RT :
-(bit[5]) RA :
-(bit[5]) RB :
-0b0101110111 :
-(bit[1]) _ as instr) =
- Lhaux (RT,RA,RB)
-
-function clause execute (Lhaux (RT, RA, RB)) =
- {
- (bit[64]) EA := 0;
- EA := GPR[RA] + GPR[RB];
- GPR[RT] := EXTS (MEMr (EA,2));
- GPR[RA] := EA
- }
-
-union ast member (bit[5], bit[5], bit[16]) Lwz
-
-function clause decode (0b100000 :
-(bit[5]) RT :
-(bit[5]) RA :
-(bit[16]) D as instr) =
- Lwz (RT,RA,D)
-
-function clause execute (Lwz (RT, RA, D)) =
- {
- (bit[64]) b := 0;
- (bit[64]) EA := 0;
- if RA == 0 then b := 0 else b := GPR[RA];
- EA := b + EXTS (D);
- GPR[RT] := 0b00000000000000000000000000000000 : MEMr (EA,4)
- }
-
-union ast member (bit[5], bit[5], bit[16]) Lwzu
-
-function clause decode (0b100001 :
-(bit[5]) RT :
-(bit[5]) RA :
-(bit[16]) D as instr) =
- Lwzu (RT,RA,D)
-
-function clause execute (Lwzu (RT, RA, D)) =
- {
- (bit[64]) EA := 0;
- EA := GPR[RA] + EXTS (D);
- GPR[RT] := 0b00000000000000000000000000000000 : MEMr (EA,4);
- GPR[RA] := EA
- }
-
-union ast member (bit[5], bit[5], bit[5]) Lwzux
-
-function clause decode (0b011111 :
-(bit[5]) RT :
-(bit[5]) RA :
-(bit[5]) RB :
-0b0000110111 :
-(bit[1]) _ as instr) =
- Lwzux (RT,RA,RB)
-
-function clause execute (Lwzux (RT, RA, RB)) =
- {
- (bit[64]) EA := 0;
- EA := GPR[RA] + GPR[RB];
- GPR[RT] := 0b00000000000000000000000000000000 : MEMr (EA,4);
- GPR[RA] := EA
- }
-
-union ast member (bit[5], bit[5], bit[5]) Lwaux
-
-function clause decode (0b011111 :
-(bit[5]) RT :
-(bit[5]) RA :
-(bit[5]) RB :
-0b0101110101 :
-(bit[1]) _ as instr) =
- Lwaux (RT,RA,RB)
-
-function clause execute (Lwaux (RT, RA, RB)) =
- {
- (bit[64]) EA := 0;
- EA := GPR[RA] + GPR[RB];
- GPR[RT] := EXTS (MEMr (EA,4));
- GPR[RA] := EA
- }
-
-union ast member (bit[5], bit[5], bit[14]) Ld
-
-function clause decode (0b111010 :
-(bit[5]) RT :
-(bit[5]) RA :
-(bit[14]) DS :
-0b00 as instr) =
- Ld (RT,RA,DS)
-
-function clause execute (Ld (RT, RA, DS)) =
- {
- (bit[64]) b := 0;
- (bit[64]) EA := 0;
- if RA == 0 then b := 0 else b := GPR[RA];
- EA := b + EXTS (DS : 0b00);
- GPR[RT] := MEMr (EA,8)
- }
-
-union ast member (bit[5], bit[5], bit[14]) Ldu
-
-function clause decode (0b111010 :
-(bit[5]) RT :
-(bit[5]) RA :
-(bit[14]) DS :
-0b01 as instr) =
- Ldu (RT,RA,DS)
-
-function clause execute (Ldu (RT, RA, DS)) =
- {
- (bit[64]) EA := 0;
- EA := GPR[RA] + EXTS (DS : 0b00);
- GPR[RT] := MEMr (EA,8);
- GPR[RA] := EA
- }
-
-union ast member (bit[5], bit[5], bit[5]) Ldux
-
-function clause decode (0b011111 :
-(bit[5]) RT :
-(bit[5]) RA :
-(bit[5]) RB :
-0b0000110101 :
-(bit[1]) _ as instr) =
- Ldux (RT,RA,RB)
-
-function clause execute (Ldux (RT, RA, RB)) =
- {
- (bit[64]) EA := 0;
- EA := GPR[RA] + GPR[RB];
- GPR[RT] := MEMr (EA,8);
- GPR[RA] := EA
- }
-
-union ast member (bit[5], bit[5], bit[16]) Stbu
-
-function clause decode (0b100111 :
-(bit[5]) RS :
-(bit[5]) RA :
-(bit[16]) D as instr) =
- Stbu (RS,RA,D)
-
-function clause execute (Stbu (RS, RA, D)) =
- {
- (bit[64]) EA := 0;
- EA := GPR[RA] + EXTS (D);
- MEMw(EA,1) := (GPR[RS])[56 .. 63];
- GPR[RA] := EA
- }
-
-union ast member (bit[5], bit[5], bit[5]) Stbux
-
-function clause decode (0b011111 :
-(bit[5]) RS :
-(bit[5]) RA :
-(bit[5]) RB :
-0b0011110111 :
-(bit[1]) _ as instr) =
- Stbux (RS,RA,RB)
-
-function clause execute (Stbux (RS, RA, RB)) =
- {
- (bit[64]) EA := 0;
- EA := GPR[RA] + GPR[RB];
- MEMw(EA,1) := (GPR[RS])[56 .. 63];
- GPR[RA] := EA
- }
-
-union ast member (bit[5], bit[5], bit[16]) Sthu
-
-function clause decode (0b101101 :
-(bit[5]) RS :
-(bit[5]) RA :
-(bit[16]) D as instr) =
- Sthu (RS,RA,D)
-
-function clause execute (Sthu (RS, RA, D)) =
- {
- (bit[64]) EA := 0;
- EA := GPR[RA] + EXTS (D);
- MEMw(EA,2) := (GPR[RS])[48 .. 63];
- GPR[RA] := EA
- }
-
-union ast member (bit[5], bit[5], bit[5]) Sthux
-
-function clause decode (0b011111 :
-(bit[5]) RS :
-(bit[5]) RA :
-(bit[5]) RB :
-0b0110110111 :
-(bit[1]) _ as instr) =
- Sthux (RS,RA,RB)
-
-function clause execute (Sthux (RS, RA, RB)) =
- {
- (bit[64]) EA := 0;
- EA := GPR[RA] + GPR[RB];
- MEMw(EA,2) := (GPR[RS])[48 .. 63];
- GPR[RA] := EA
- }
-
-union ast member (bit[5], bit[5], bit[16]) Stw
-
-function clause decode (0b100100 :
-(bit[5]) RS :
-(bit[5]) RA :
-(bit[16]) D as instr) =
- Stw (RS,RA,D)
-
-function clause execute (Stw (RS, RA, D)) =
- {
- (bit[64]) b := 0;
- (bit[64]) EA := 0;
- if RA == 0 then b := 0 else b := GPR[RA];
- EA := b + EXTS (D);
- MEMw(EA,4) := (GPR[RS])[32 .. 63]
- }
-
-union ast member (bit[5], bit[5], bit[16]) Stwu
-
-function clause decode (0b100101 :
-(bit[5]) RS :
-(bit[5]) RA :
-(bit[16]) D as instr) =
- Stwu (RS,RA,D)
-
-function clause execute (Stwu (RS, RA, D)) =
- {
- (bit[64]) EA := 0;
- EA := GPR[RA] + EXTS (D);
- MEMw(EA,4) := (GPR[RS])[32 .. 63];
- GPR[RA] := EA
- }
-
-union ast member (bit[5], bit[5], bit[5]) Stwux
-
-function clause decode (0b011111 :
-(bit[5]) RS :
-(bit[5]) RA :
-(bit[5]) RB :
-0b0010110111 :
-(bit[1]) _ as instr) =
- Stwux (RS,RA,RB)
-
-function clause execute (Stwux (RS, RA, RB)) =
- {
- (bit[64]) EA := 0;
- EA := GPR[RA] + GPR[RB];
- MEMw(EA,4) := (GPR[RS])[32 .. 63];
- GPR[RA] := EA
- }
-
-union ast member (bit[5], bit[5], bit[14]) Std
-
-function clause decode (0b111110 :
-(bit[5]) RS :
-(bit[5]) RA :
-(bit[14]) DS :
-0b00 as instr) =
- Std (RS,RA,DS)
-
-function clause execute (Std (RS, RA, DS)) =
- {
- (bit[64]) b := 0;
- (bit[64]) EA := 0;
- if RA == 0 then b := 0 else b := GPR[RA];
- EA := b + EXTS (DS : 0b00);
- MEMw(EA,8) := GPR[RS]
- }
-
-union ast member (bit[5], bit[5], bit[14]) Stdu
-
-function clause decode (0b111110 :
-(bit[5]) RS :
-(bit[5]) RA :
-(bit[14]) DS :
-0b01 as instr) =
- Stdu (RS,RA,DS)
-
-function clause execute (Stdu (RS, RA, DS)) =
- {
- (bit[64]) EA := 0;
- EA := GPR[RA] + EXTS (DS : 0b00);
- MEMw(EA,8) := GPR[RS];
- GPR[RA] := EA
- }
-
-union ast member (bit[5], bit[5], bit[5]) Stdux
-
-function clause decode (0b011111 :
-(bit[5]) RS :
-(bit[5]) RA :
-(bit[5]) RB :
-0b0010110101 :
-(bit[1]) _ as instr) =
- Stdux (RS,RA,RB)
-
-function clause execute (Stdux (RS, RA, RB)) =
- {
- (bit[64]) EA := 0;
- EA := GPR[RA] + GPR[RB];
- MEMw(EA,8) := GPR[RS];
- GPR[RA] := EA
- }
-
-union ast member (bit[5], bit[5], bit[12], bit[4]) Lq
+val bit[32] -> option<ast> effect pure decode
-function clause decode (0b111000 :
-(bit[5]) RTp :
-(bit[5]) RA :
-(bit[12]) DQ :
-(bit[4]) PT as instr) =
- Lq (RTp,RA,DQ,PT)
+scattered function option<ast> decode
-function clause execute (Lq (RTp, RA, DQ, PT)) =
- {
- (bit[64]) EA := 0;
- (bit[64]) b := 0;
- if RA == 0 then b := 0 else b := GPR[RA];
- EA := b + EXTS (DQ : 0b0000);
- (bit[128]) mem := MEMr (EA,16);
- if bigendianmode
- then {
- GPR[RTp] := mem[0 .. 63];
- GPR[RTp + 1] := mem[64 .. 127]
- }
- else {
- (bit[128]) bytereverse := byte_reverse (mem);
- GPR[RTp] := bytereverse[0 .. 63];
- GPR[RTp + 1] := bytereverse[64 .. 127]
- }
- }
-
-union ast member (bit[5], bit[5], bit[14]) Stq
-
-function clause decode (0b111110 :
-(bit[5]) RSp :
-(bit[5]) RA :
-(bit[14]) DS :
-0b10 as instr) =
- Stq (RSp,RA,DS)
-
-function clause execute (Stq (RSp, RA, DS)) =
- {
- (bit[64]) b := 0;
- (bit[64]) EA := 0;
- {
- (bit[64]) EA := 0;
- (bit[64]) b := 0;
- if RA == 0 then b := 0 else b := GPR[RA];
- EA := b + EXTS (DS : 0b00);
- (bit[128]) mem := 0;
- mem[0..63] := GPR[RSp];
- mem[64..127] := GPR[RSp + 1];
- if ~ (bigendianmode) then mem := byte_reverse (mem) else ();
- MEMw(EA,16) := mem
- };
- EA := b + EXTS (DS : 0b00);
- MEMw(EA,8) := RSp
- }
+union ast member ((bit[20]), regno, uop) UTYPE
-union ast member (bit[5], bit[5], bit[16]) Lmw
+function clause decode ((bit[20]) imm : (regno) rd : 0b0110111) = Some(UTYPE(imm, rd, LUI))
+function clause decode ((bit[20]) imm : (regno) rd : 0b0010111) = Some(UTYPE(imm, rd, AUIPC))
-function clause decode (0b101110 :
-(bit[5]) RT :
-(bit[5]) RA :
-(bit[16]) D as instr) =
- Lmw (RT,RA,D)
+function clause execute (UTYPE(imm, rd, op)) =
+ let (bit[64]) off = EXTS(imm : 0x000) in
+ let ret = switch (op) {
+ case LUI -> off
+ case AUIPC -> PC + off
+ } in
+ wGPR(rd, ret)
-function clause execute (Lmw (RT, RA, D)) =
- {
- (bit[64]) b := 0;
- (bit[64]) EA := 0;
- if RA == 0 then b := 0 else b := GPR[RA];
- EA := b + EXTS (D);
- size := ([|32|]) (32 - RT) * 4;
- buffer := MEMr (EA,size);
- i := 0;
- foreach (r from RT to 31 by 1 in inc)
- {
- GPR[r] := 0b00000000000000000000000000000000 : buffer[i .. i + 31];
- i := i + 32
+union ast member ((bit[20]), regno) JAL
+function clause decode ((bit[20]) imm : (regno) rd : 0b1101111) = Some (JAL(imm, rd))
+function clause execute (JAL(imm, rd)) =
+ let (bit[64]) offset = EXTS(imm[19] : imm[7..0] : imm[8] : imm[18..13] : imm[12..9] : 0b0) in {
+ nextPC := PC + offset;
+ wGPR(rd, PC + 4);
}
- }
-union ast member (bit[5], bit[5], bit[5]) Lswi
-
-function clause decode (0b011111 :
-(bit[5]) RT :
-(bit[5]) RA :
-(bit[5]) NB :
-0b1001010101 :
-(bit[1]) _ as instr) =
- Lswi (RT,RA,NB)
-
-function clause execute (Lswi (RT, RA, NB)) =
- {
- (bit[64]) EA := 0;
- if RA == 0 then EA := 0 else EA := GPR[RA];
- ([|32|]) r := 0;
- r := RT - 1;
- ([|32|]) size := if NB == 0 then 32 else NB;
- (bit[256]) membuffer := MEMr (EA,size);
- j := 0;
- i := 32;
- foreach (n from (if NB == 0 then 32 else NB) to 1 by 1 in dec)
- {
- if i == 32
- then {
- r := ([|32|]) (r + 1) mod 32;
- GPR[r] := 0
- }
- else ();
- (GPR[r])[i..i + 7] := membuffer[j .. j + 7];
- j := j + 8;
- i := i + 8;
- if i == 64 then i := 32 else ();
- EA := EA + 1
+union ast member((bit[12]), regno, regno) JALR
+function clause decode ((bit[12]) imm : (regno) rs1 : 0b000 : (regno) rd : 0b1100111) =
+ Some(JALR(imm, rs1, rd))
+function clause execute (JALR(imm, rs1, rd)) =
+ let (bit[64]) newPC = rGPR(rs1) + EXTS(imm) in {
+ nextPC := newPC[63..1] : 0b0;
+ wGPR(rd, PC + 4);
}
- }
-
-union ast member (bit[5], bit[5], bit[16]) Addi
-
-function clause decode (0b001110 :
-(bit[5]) RT :
-(bit[5]) RA :
-(bit[16]) SI as instr) =
- Addi (RT,RA,SI)
-
-function clause execute (Addi (RT, RA, SI)) =
- if RA == 0 then GPR[RT] := EXTS (SI) else GPR[RT] := GPR[RA] + EXTS (SI)
-
-union ast member (bit[5], bit[5], bit[16]) Addis
-
-function clause decode (0b001111 :
-(bit[5]) RT :
-(bit[5]) RA :
-(bit[16]) SI as instr) =
- Addis (RT,RA,SI)
-
-function clause execute (Addis (RT, RA, SI)) =
- if RA == 0
- then GPR[RT] := EXTS (SI : 0b0000000000000000)
- else GPR[RT] := GPR[RA] + EXTS (SI : 0b0000000000000000)
-
-union ast member (bit[5], bit[5], bit[5], bit, bit) Add
-
-function clause decode (0b011111 :
-(bit[5]) RT :
-(bit[5]) RA :
-(bit[5]) RB :
-[OE] :
-0b100001010 :
-[Rc] as instr) =
- Add (RT,RA,RB,OE,Rc)
-
-function clause execute (Add (RT, RA, RB, OE, Rc)) =
- let (temp, overflow, _) = (GPR[RA] +_s GPR[RB]) in
- {
- GPR[RT] := temp;
- if Rc
- then {
- xer_so := XER.SO;
- if OE & overflow then xer_so := overflow else ();
- set_overflow_cr0 (temp,xer_so)
- }
- else ();
- if OE then set_SO_OV (overflow) else ()
- }
-
-union ast member (bit[5], bit[5], bit[5], bit, bit) Subf
-
-function clause decode (0b011111 :
-(bit[5]) RT :
-(bit[5]) RA :
-(bit[5]) RB :
-[OE] :
-0b000101000 :
-[Rc] as instr) =
- Subf (RT,RA,RB,OE,Rc)
-function clause execute (Subf (RT, RA, RB, OE, Rc)) =
- let (t, overflow, _) = (~ (GPR[RA]) +_s GPR[RB]) in
- {
- (bit[64]) temp := t + 1;
- GPR[RT] := temp;
- if Rc
- then {
- xer_so := XER.SO;
- if OE & overflow then xer_so := overflow else ();
- set_overflow_cr0 (temp,xer_so)
- }
- else ();
- if OE then set_SO_OV (overflow) else ()
+union ast member ((bit[12]), regno, regno, bop) BTYPE
+function clause decode ((bit[7]) imm7 : (regno) rs2 : (regno) rs1 : 0b000 : (bit[5]) imm5 : 0b1100011) = Some(BTYPE(imm7[6] : imm5[0] : imm7[5..0] : imm5[4..1], rs2, rs1, BEQ))
+function clause decode ((bit[7]) imm7 : (regno) rs2 : (regno) rs1 : 0b001 : (bit[5]) imm5 : 0b1100011) = Some(BTYPE(imm7[6] : imm5[0] : imm7[5..0] : imm5[4..1], rs2, rs1, BNE))
+function clause decode ((bit[7]) imm7 : (regno) rs2 : (regno) rs1 : 0b100 : (bit[5]) imm5 : 0b1100011) = Some(BTYPE(imm7[6] : imm5[0] : imm7[5..0] : imm5[4..1], rs2, rs1, BLT))
+function clause decode ((bit[7]) imm7 : (regno) rs2 : (regno) rs1 : 0b101 : (bit[5]) imm5 : 0b1100011) = Some(BTYPE(imm7[6] : imm5[0] : imm7[5..0] : imm5[4..1], rs2, rs1, BGE))
+function clause decode ((bit[7]) imm7 : (regno) rs2 : (regno) rs1 : 0b110 : (bit[5]) imm5 : 0b1100011) = Some(BTYPE(imm7[6] : imm5[0] : imm7[5..0] : imm5[4..1], rs2, rs1, BLTU))
+function clause decode ((bit[7]) imm7 : (regno) rs2 : (regno) rs1 : 0b111 : (bit[5]) imm5 : 0b1100011) = Some(BTYPE(imm7[6] : imm5[0] : imm7[5..0] : imm5[4..1], rs2, rs1, BGEU))
+
+function clause execute (BTYPE(imm, rs2, rs1, op)) =
+ let rs1_val = rGPR(rs1) in
+ let rs2_val = rGPR(rs2) in
+ let taken = switch(op) {
+ case BEQ -> rs1_val == rs2_val
+ case BNE -> rs1_val != rs2_val
+ case BLT -> rs1_val <_s rs2_val
+ case BGE -> rs1_val >=_s rs2_val
+ case BLTU -> rs1_val <_u rs2_val
+ case BGEU -> rs1_val >= rs2_val (* XXX is this signed or unsigned? *)
+ } in
+ if (taken) then
+ nextPC := PC + EXTS(imm : 0b0)
+
+union ast member ((bit[12]), regno, regno, iop) ITYPE
+function clause decode ((bit[12]) imm : (regno) rs1 : 0b000 : (regno) rd : 0b0010011) = Some(ITYPE(imm, rs1, rd, ADDI))
+function clause decode ((bit[12]) imm : (regno) rs1 : 0b010 : (regno) rd : 0b0010011) = Some(ITYPE(imm, rs1, rd, SLTI))
+function clause decode ((bit[12]) imm : (regno) rs1 : 0b011 : (regno) rd : 0b0010011) = Some(ITYPE(imm, rs1, rd, SLTIU))
+function clause decode ((bit[12]) imm : (regno) rs1 : 0b100 : (regno) rd : 0b0010011) = Some(ITYPE(imm, rs1, rd, XORI))
+function clause decode ((bit[12]) imm : (regno) rs1 : 0b110 : (regno) rd : 0b0010011) = Some(ITYPE(imm, rs1, rd, ORI))
+function clause decode ((bit[12]) imm : (regno) rs1 : 0b111 : (regno) rd : 0b0010011) = Some(ITYPE(imm, rs1, rd, ANDI))
+function clause execute (ITYPE (imm, rs1, rd, op)) =
+ let rs1_val = rGPR(rs1) in
+ let imm64 = (bit[64]) (EXTS(imm)) in
+ let (bit[64]) result = switch(op) {
+ case ADDI -> rs1_val + imm64
+ case SLTI -> EXTZ(rs1_val <_s imm64)
+ case SLTIU -> EXTZ(rs1_val <_u imm64)
+ case XORI -> rs1_val ^ imm64
+ case ORI -> rs1_val | imm64
+ case ANDI -> rs1_val & imm64
+ } in
+ wGPR(rd, result)
+
+union ast member ((bit[6]), regno, regno, sop) SHIFTIOP
+function clause decode (0b000000 : (bit[6]) shamt : (regno) rs1 : 0b001 : (regno) rd : 0b0010011) = Some(SHIFTIOP(shamt, rs1, rd, SLLI))
+function clause decode (0b000000 : (bit[6]) shamt : (regno) rs1 : 0b101 : (regno) rd : 0b0010011) = Some(SHIFTIOP(shamt, rs1, rd, SRLI))
+function clause decode (0b010000 : (bit[6]) shamt : (regno) rs1 : 0b101 : (regno) rd : 0b0010011) = Some(SHIFTIOP(shamt, rs1, rd, SRAI))
+function clause execute (SHIFTIOP(shamt, rs1, rd, op)) =
+ let rs1_val = rGPR(rs1) in
+ let result = switch(op) {
+ case SLLI -> rs1_val >> shamt
+ case SRLI -> rs1_val << shamt
+ case SRAI -> shift_right_arith64(rs1_val, shamt)
+ } in
+ wGPR(rd, result)
+
+union ast member (regno, regno, regno, rop) RTYPE
+function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b000 : (regno) rd : 0b0110011) = Some(RTYPE(rs2, rs1, rd, ADD))
+function clause decode (0b0100000 : (regno) rs2 : (regno) rs1 : 0b000 : (regno) rd : 0b0110011) = Some(RTYPE(rs2, rs1, rd, SUB))
+function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b001 : (regno) rd : 0b0110011) = Some(RTYPE(rs2, rs1, rd, SLL))
+function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b010 : (regno) rd : 0b0110011) = Some(RTYPE(rs2, rs1, rd, SLT))
+function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b011 : (regno) rd : 0b0110011) = Some(RTYPE(rs2, rs1, rd, SLTU))
+function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b100 : (regno) rd : 0b0110011) = Some(RTYPE(rs2, rs1, rd, XOR))
+function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b101 : (regno) rd : 0b0110011) = Some(RTYPE(rs2, rs1, rd, SRL))
+function clause decode (0b0100000 : (regno) rs2 : (regno) rs1 : 0b101 : (regno) rd : 0b0110011) = Some(RTYPE(rs2, rs1, rd, SRA))
+function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b110 : (regno) rd : 0b0110011) = Some(RTYPE(rs2, rs1, rd, OR))
+function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b111 : (regno) rd : 0b0110011) = Some(RTYPE(rs2, rs1, rd, AND))
+function clause execute (RTYPE(rs2, rs1, rd, op)) =
+ let rs1_val = rGPR(rs1) in
+ let rs2_val = rGPR(rs2) in
+ let (bit[64]) result = switch(op) {
+ case ADD -> rs1_val + rs2_val
+ case SUB -> rs1_val - rs2_val
+ case SLL -> rs1_val << (rs2_val[5..0])
+ case SLT -> EXTZ(rs1_val <_s rs2_val)
+ case SLTU -> EXTZ(rs1_val <_u rs2_val)
+ case XOR -> rs1_val ^ rs2_val
+ case SRL -> rs1_val >> (rs2_val[5..0])
+ case SRA -> shift_right_arith64(rs1_val, rs2_val[5..0])
+ case OR -> rs1_val | rs2_val
+ case AND -> rs1_val & rs2_val
+ } in
+ wGPR(rd, result)
+
+union ast member ((bit[12]), regno, regno, bool, [|8|]) LOAD
+function clause decode ((bit[12]) imm : (regno) rs1 : 0b000 : (regno) rd : 0b0000011) = Some(LOAD(imm, rs1, rd, false, 1))
+function clause decode ((bit[12]) imm : (regno) rs1 : 0b001 : (regno) rd : 0b0000011) = Some(LOAD(imm, rs1, rd, false, 2))
+function clause decode ((bit[12]) imm : (regno) rs1 : 0b010 : (regno) rd : 0b0000011) = Some(LOAD(imm, rs1, rd, false, 4))
+function clause decode ((bit[12]) imm : (regno) rs1 : 0b011 : (regno) rd : 0b0000011) = Some(LOAD(imm, rs1, rd, false, 8))
+function clause decode ((bit[12]) imm : (regno) rs1 : 0b100 : (regno) rd : 0b0000011) = Some(LOAD(imm, rs1, rd, true, 1))
+function clause decode ((bit[12]) imm : (regno) rs1 : 0b101 : (regno) rd : 0b0000011) = Some(LOAD(imm, rs1, rd, true, 2))
+function clause decode ((bit[12]) imm : (regno) rs1 : 0b110 : (regno) rd : 0b0000011) = Some(LOAD(imm, rs1, rd, true, 4))
+function clause execute(LOAD(imm, rs1, rd, unsigned, width)) =
+ let (bit[64]) addr = rGPR(rs1) + EXTS(imm) in
+ let (bit[64]) result = if unsigned then
+ EXTZ(MEMr(addr, width))
+ else
+ EXTS(MEMr(addr, width)) in
+ wGPR(rd, result)
+
+union ast member ((bit[12]), regno, regno, [|8|]) STORE
+function clause decode ((bit[7]) imm7 : (regno) rs2 : (regno) rs1 : 0b000 : (bit[5]) imm5 : 0b0100011) = Some(STORE(imm7 : imm5, rs2, rs1, 1))
+function clause decode ((bit[7]) imm7 : (regno) rs2 : (regno) rs1 : 0b001 : (bit[5]) imm5 : 0b0100011) = Some(STORE(imm7 : imm5, rs2, rs1, 2))
+function clause decode ((bit[7]) imm7 : (regno) rs2 : (regno) rs1 : 0b010 : (bit[5]) imm5 : 0b0100011) = Some(STORE(imm7 : imm5, rs2, rs1, 4))
+function clause decode ((bit[7]) imm7 : (regno) rs2 : (regno) rs1 : 0b011 : (bit[5]) imm5 : 0b0100011) = Some(STORE(imm7 : imm5, rs2, rs1, 8))
+function clause execute (STORE(imm, rs2, rs1, width)) =
+ let (bit[64]) addr = rGPR(rs1) + EXTS(imm) in {
+ MEMea(addr, width);
+ MEMval(addr, width, rGPR(rs2));
}
-union ast member (bit[5], bit[5], bit[16]) Addic
-
-function clause decode (0b001100 :
-(bit[5]) RT :
-(bit[5]) RA :
-(bit[16]) SI as instr) =
- Addic (RT,RA,SI)
-
-function clause execute (Addic (RT, RA, SI)) =
- let (temp, _, carry) = (GPR[RA] +_s EXTS (SI)) in
- {
- GPR[RT] := temp;
- CA := carry
- }
-
-union ast member (bit[5], bit[5], bit[16]) AddicDot
-
-function clause decode (0b001101 :
-(bit[5]) RT :
-(bit[5]) RA :
-(bit[16]) SI as instr) =
- AddicDot (RT,RA,SI)
-
-function clause execute (AddicDot (RT, RA, SI)) =
- let (temp, overflow, carry) = (GPR[RA] +_s EXTS (SI)) in
- {
- GPR[RT] := temp;
- CA := carry;
- set_overflow_cr0 (temp,overflow)
- }
-
-union ast member (bit[5], bit[5], bit, bit) Neg
-
-function clause decode (0b011111 :
-(bit[5]) RT :
-(bit[5]) RA :
-(bit[5]) _ :
-[OE] :
-0b001101000 :
-[Rc] as instr) =
- Neg (RT,RA,OE,Rc)
-
-function clause execute (Neg (RT, RA, OE, Rc)) =
- let (temp, overflow, _) = (~ (GPR[RA]) +_s (bit) 1) in
- {
- GPR[RT] := temp;
- if Rc then set_overflow_cr0 (temp,XER.SO) else ()
- }
-
-union ast member (bit[5], bit[5], bit[5], bit, bit) Mullw
-
-function clause decode (0b011111 :
-(bit[5]) RT :
-(bit[5]) RA :
-(bit[5]) RB :
-[OE] :
-0b011101011 :
-[Rc] as instr) =
- Mullw (RT,RA,RB,OE,Rc)
-
-function clause execute (Mullw (RT, RA, RB, OE, Rc)) =
- let (prod, overflow, _) = ((GPR[RA])[32 .. 63] *_s (GPR[RB])[32 .. 63]) in
- {
- GPR[RT] := prod;
- if Rc
- then {
- xer_so := XER.SO;
- if OE & overflow then xer_so := overflow else ();
- set_overflow_cr0 (prod,xer_so)
- }
- else ();
- if OE then set_SO_OV (overflow) else ()
- }
-
-union ast member (bit[3], bit, bit[5], bit[16]) Cmpi
-
-function clause decode (0b001011 :
-(bit[3]) BF :
-(bit[1]) _ :
-[L] :
-(bit[5]) RA :
-(bit[16]) SI as instr) =
- Cmpi (BF,L,RA,SI)
-
-function clause execute (Cmpi (BF, L, RA, SI)) =
- {
- (bit[64]) a := 0;
- if L == 0 then a := EXTS ((GPR[RA])[32 .. 63]) else a := GPR[RA];
- if a < EXTS (SI)
- then c := 0b100
- else if a > EXTS (SI) then c := 0b010 else c := 0b001;
- CR[4 * BF + 32..4 * BF + 35] := c : [XER.SO]
- }
-
-union ast member (bit[3], bit, bit[5], bit[5]) Cmp
-
-function clause decode (0b011111 :
-(bit[3]) BF :
-(bit[1]) _ :
-[L] :
-(bit[5]) RA :
-(bit[5]) RB :
-0b0000000000 :
-(bit[1]) _ as instr) =
- Cmp (BF,L,RA,RB)
-
-function clause execute (Cmp (BF, L, RA, RB)) =
- {
- (bit[64]) a := 0;
- (bit[64]) b := 0;
- if L == 0
- then {
- a := EXTS ((GPR[RA])[32 .. 63]);
- b := EXTS ((GPR[RB])[32 .. 63])
- }
- else {
- a := GPR[RA];
- b := GPR[RB]
- };
- if a < b then c := 0b100 else if a > b then c := 0b010 else c := 0b001;
- CR[4 * BF + 32..4 * BF + 35] := c : [XER.SO]
- }
-
-union ast member (bit[5], bit[5], bit[16]) Ori
-
-function clause decode (0b011000 :
-(bit[5]) RS :
-(bit[5]) RA :
-(bit[16]) UI as instr) =
- Ori (RS,RA,UI)
-
-function clause execute (Ori (RS, RA, UI)) =
- GPR[RA] := (GPR[RS] | 0b000000000000000000000000000000000000000000000000 : UI)
-
-union ast member (bit[5], bit[5], bit[16]) Oris
-
-function clause decode (0b011001 :
-(bit[5]) RS :
-(bit[5]) RA :
-(bit[16]) UI as instr) =
- Oris (RS,RA,UI)
-
-function clause execute (Oris (RS, RA, UI)) =
- GPR[RA] :=
- (GPR[RS] | 0b00000000000000000000000000000000 : UI : 0b0000000000000000)
-
-union ast member (bit[5], bit[5], bit[16]) Xori
-
-function clause decode (0b011010 :
-(bit[5]) RS :
-(bit[5]) RA :
-(bit[16]) UI as instr) =
- Xori (RS,RA,UI)
-
-function clause execute (Xori (RS, RA, UI)) =
- GPR[RA] := GPR[RS] ^ 0b000000000000000000000000000000000000000000000000 : UI
-
-union ast member (bit[5], bit[5], bit[5], bit) Or
-
-function clause decode (0b011111 :
-(bit[5]) RS :
-(bit[5]) RA :
-(bit[5]) RB :
-0b0110111100 :
-[Rc] as instr) =
- Or (RS,RA,RB,Rc)
-
-function clause execute (Or (RS, RA, RB, Rc)) =
- {
- (bit[64]) temp := (GPR[RS] | GPR[RB]);
- GPR[RA] := temp;
- if Rc then set_overflow_cr0 (temp,XER.SO) else ()
- }
-
-union ast member (bit[5], bit[5], bit) Extsw
-
-function clause decode (0b011111 :
-(bit[5]) RS :
-(bit[5]) RA :
-(bit[5]) _ :
-0b1111011010 :
-[Rc] as instr) =
- Extsw (RS,RA,Rc)
-
-function clause execute (Extsw (RS, RA, Rc)) =
- {
- s := (GPR[RS])[32];
- (bit[64]) temp := 0;
- temp := (GPR[RS])[32 .. 63];
- temp := s ^^ 32;
- if Rc then set_overflow_cr0 (temp,XER.SO) else ();
- GPR[RA] := temp
- }
-
-union ast member (bit[5], bit[5], bit[6], bit[6], bit) Rldicr
-
-function clause decode (0b011110 :
-(bit[5]) RS :
-(bit[5]) RA :
-(bit[5]) _ :
-(bit[6]) me :
-0b001 :
-(bit[1]) _ :
-[Rc] as instr) =
- Rldicr (RS,RA,instr[16 .. 20] : instr[30 .. 30],me,Rc)
-
-function clause execute (Rldicr (RS, RA, sh, me, Rc)) =
- {
- n := [sh[5]] : sh[0 .. 4];
- r := ROTL (GPR[RS],n);
- e := [me[5]] : me[0 .. 4];
- m := MASK (0,e);
- (bit[64]) temp := (r & m);
- GPR[RA] := temp;
- if Rc then set_overflow_cr0 (temp,XER.SO) else ()
- }
-
-union ast member (bit[5], bit[10]) Mtspr
-
-function clause decode (0b011111 :
-(bit[5]) RS :
-(bit[10]) spr :
-0b0111010011 :
-(bit[1]) _ as instr) =
- Mtspr (RS,spr)
-
-function clause execute (Mtspr (RS, spr)) =
- {
- n := spr[5 .. 9] : spr[0 .. 4];
- if n == 13
- then trap ()
- else if length (SPR[n]) == 64
- then SPR[n] := GPR[RS]
- else SPR[n] := (GPR[RS])[32 .. 63]
- }
-
-union ast member (bit[5], bit[10]) Mfspr
-
-function clause decode (0b011111 :
-(bit[5]) RT :
-(bit[10]) spr :
-0b0101010011 :
-(bit[1]) _ as instr) =
- Mfspr (RT,spr)
-
-function clause execute (Mfspr (RT, spr)) =
- {
- n := spr[5 .. 9] : spr[0 .. 4];
- if length (SPR[n]) == 64
- then GPR[RT] := SPR[n]
- else GPR[RT] := 0b00000000000000000000000000000000 : SPR[n]
- }
-
-union ast member (bit[5], bit[8]) Mtcrf
-
-function clause decode (0b011111 :
-(bit[5]) RS :
-0b0 :
-(bit[8]) FXM :
-(bit[1]) _ :
-0b0010010000 :
-(bit[1]) _ as instr) =
- Mtcrf (RS,FXM)
-
-function clause execute (Mtcrf (RS, FXM)) =
- {
- mask :=
- (FXM[0] ^^ 4) :
- (FXM[1] ^^ 4) :
- (FXM[2] ^^ 4) :
- (FXM[3] ^^ 4) :
- (FXM[4] ^^ 4) : (FXM[5] ^^ 4) : (FXM[6] ^^ 4) : (FXM[7] ^^ 4);
- CR :=
- ((bit[32]) ((GPR[RS])[32 .. 63] & mask) |
- (bit[32]) (CR & ~ ((bit[32]) mask)))
- }
-
-union ast member (bit[5]) Mfcr
-
-function clause decode (0b011111 :
-(bit[5]) RT :
-0b0 :
-(bit[9]) _ :
-0b0000010011 :
-(bit[1]) _ as instr) =
- Mfcr (RT)
-
-function clause execute (Mfcr (RT)) =
- GPR[RT] := 0b00000000000000000000000000000000 : CR
-
-union ast member (bit[5], bit[5], bit[16]) Lfsu
-
-function clause decode (0b110001 :
-(bit[5]) FRT :
-(bit[5]) RA :
-(bit[16]) D as instr) =
- Lfsu (FRT,RA,D)
-
-function clause execute (Lfsu (FRT, RA, D)) =
- {
- (bit[64]) EA := 0;
- EA := GPR[RA] + EXTS (D);
- FPR[FRT] := DOUBLE (MEMr (EA,4));
- GPR[RA] := EA
- }
-
-union ast member (bit[5], bit[5], bit[5]) Lfsux
-
-function clause decode (0b011111 :
-(bit[5]) FRT :
-(bit[5]) RA :
-(bit[5]) RB :
-0b1000110111 :
-(bit[1]) _ as instr) =
- Lfsux (FRT,RA,RB)
-
-function clause execute (Lfsux (FRT, RA, RB)) =
- {
- (bit[64]) EA := 0;
- EA := GPR[RA] + GPR[RB];
- FPR[FRT] := DOUBLE (MEMr (EA,4));
- GPR[RA] := EA
- }
-
-union ast member (bit[5], bit[5], bit[16]) Lfd
-
-function clause decode (0b110010 :
-(bit[5]) FRT :
-(bit[5]) RA :
-(bit[16]) D as instr) =
- Lfd (FRT,RA,D)
-
-function clause execute (Lfd (FRT, RA, D)) =
- {
- (bit[64]) b := 0;
- (bit[64]) EA := 0;
- if RA == 0 then b := 0 else b := GPR[RA];
- EA := b + EXTS (D);
- FPR[FRT] := MEMr (EA,8)
- }
-
-union ast member (bit[5], bit[5], bit[16]) Lfdu
-
-function clause decode (0b110011 :
-(bit[5]) FRT :
-(bit[5]) RA :
-(bit[16]) D as instr) =
- Lfdu (FRT,RA,D)
-
-function clause execute (Lfdu (FRT, RA, D)) =
- {
- (bit[64]) EA := 0;
- EA := GPR[RA] + EXTS (D);
- FPR[FRT] := MEMr (EA,8);
- GPR[RA] := EA
- }
-
-union ast member (bit[5], bit[5], bit[5]) Lfdux
-
-function clause decode (0b011111 :
-(bit[5]) FRT :
-(bit[5]) RA :
-(bit[5]) RB :
-0b1001110111 :
-(bit[1]) _ as instr) =
- Lfdux (FRT,RA,RB)
-
-function clause execute (Lfdux (FRT, RA, RB)) =
- {
- (bit[64]) EA := 0;
- EA := GPR[RA] + GPR[RB];
- FPR[FRT] := MEMr (EA,8);
- GPR[RA] := EA
- }
-
-union ast member (bit[5], bit[5], bit[16]) Stfsu
-
-function clause decode (0b110101 :
-(bit[5]) FRS :
-(bit[5]) RA :
-(bit[16]) D as instr) =
- Stfsu (FRS,RA,D)
-
-function clause execute (Stfsu (FRS, RA, D)) =
- {
- (bit[64]) EA := 0;
- EA := GPR[RA] + EXTS (D);
- MEMw(EA,4) := SINGLE (FPR[FRS]);
- GPR[RA] := EA
- }
-
-union ast member (bit[5], bit[5], bit[5]) Stfsux
-
-function clause decode (0b011111 :
-(bit[5]) FRS :
-(bit[5]) RA :
-(bit[5]) RB :
-0b1010110111 :
-(bit[1]) _ as instr) =
- Stfsux (FRS,RA,RB)
-
-function clause execute (Stfsux (FRS, RA, RB)) =
- {
- (bit[64]) EA := 0;
- EA := GPR[RA] + GPR[RB];
- MEMw(EA,4) := SINGLE (FPR[FRS]);
- GPR[RA] := EA
- }
-
-union ast member (bit[5], bit[5], bit[16]) Stfd
-
-function clause decode (0b110110 :
-(bit[5]) FRS :
-(bit[5]) RA :
-(bit[16]) D as instr) =
- Stfd (FRS,RA,D)
-
-function clause execute (Stfd (FRS, RA, D)) =
- {
- (bit[64]) b := 0;
- (bit[64]) EA := 0;
- if RA == 0 then b := 0 else b := GPR[RA];
- EA := b + EXTS (D);
- MEMw(EA,8) := FPR[FRS]
- }
-
-union ast member (bit[5], bit[5], bit[16]) Stfdu
-
-function clause decode (0b110111 :
-(bit[5]) FRS :
-(bit[5]) RA :
-(bit[16]) D as instr) =
- Stfdu (FRS,RA,D)
-
-function clause execute (Stfdu (FRS, RA, D)) =
- {
- (bit[64]) EA := 0;
- EA := GPR[RA] + EXTS (D);
- MEMw(EA,8) := FPR[FRS];
- GPR[RA] := EA
- }
-
-union ast member (bit[5], bit[5], bit[5]) Stfdux
-
-function clause decode (0b011111 :
-(bit[5]) FRS :
-(bit[5]) RA :
-(bit[5]) RB :
-0b1011110111 :
-(bit[1]) _ as instr) =
- Stfdux (FRS,RA,RB)
-
-function clause execute (Stfdux (FRS, RA, RB)) =
- {
- (bit[64]) EA := 0;
- EA := GPR[RA] + GPR[RB];
- MEMw(EA,8) := FPR[FRS];
- GPR[RA] := EA
- }
-
-union ast member (bit[5], bit[5], bit[14]) Lfdp
-
-function clause decode (0b111001 :
-(bit[5]) FRTp :
-(bit[5]) RA :
-(bit[14]) DS :
-0b0 :
-0b0 as instr) =
- Lfdp (FRTp,RA,DS)
-
-function clause execute (Lfdp (FRTp, RA, DS)) =
- {
- (bit[64]) b := 0;
- (bit[64]) EA := 0;
- if RA == 0 then b := 0 else b := GPR[RA];
- EA := b + EXTS (DS : 0b00);
- FPRp[FRTp] := MEMr (EA,16)
- }
-
-union ast member (bit[5], bit[5], bit[5]) Lfdpx
-
-function clause decode (0b011111 :
-(bit[5]) FRTp :
-(bit[5]) RA :
-(bit[5]) RB :
-0b1100010111 :
-(bit[1]) _ as instr) =
- Lfdpx (FRTp,RA,RB)
-
-function clause execute (Lfdpx (FRTp, RA, RB)) =
- {
- (bit[64]) b := 0;
- (bit[64]) EA := 0;
- if RA == 0 then b := 0 else b := GPR[RA];
- EA := b + GPR[RB];
- FPRp[FRTp] := MEMr (EA,16)
- }
-
-union ast member (bit[5], bit[5], bit[14]) Stfdp
-
-function clause decode (0b111101 :
-(bit[5]) FRSp :
-(bit[5]) RA :
-(bit[14]) DS :
-0b0 :
-0b0 as instr) =
- Stfdp (FRSp,RA,DS)
-
-function clause execute (Stfdp (FRSp, RA, DS)) =
- {
- (bit[64]) b := 0;
- (bit[64]) EA := 0;
- if RA == 0 then b := 0 else b := GPR[RA];
- EA := b + EXTS (DS : 0b00);
- MEMw(EA,16) := FPRp[FRSp]
- }
-
-union ast member (bit[5], bit[5], bit[5]) Stfdpx
-
-function clause decode (0b011111 :
-(bit[5]) FRSp :
-(bit[5]) RA :
-(bit[5]) RB :
-0b1110010111 :
-(bit[1]) _ as instr) =
- Stfdpx (FRSp,RA,RB)
-
-function clause execute (Stfdpx (FRSp, RA, RB)) =
- {
- (bit[64]) b := 0;
- (bit[64]) EA := 0;
- if RA == 0 then b := 0 else b := GPR[RA];
- EA := b + GPR[RB];
- MEMw(EA,16) := FPRp[FRSp]
- }
-
-union ast member (bit[5], bit) Mffs
-
-function clause decode (0b111111 :
-(bit[5]) FRT :
-(bit[5]) _ :
-(bit[5]) _ :
-0b1001000111 :
-[Rc] as instr) =
- Mffs (FRT,Rc)
-
-function clause execute (Mffs (FRT, Rc)) = ()
-
-union ast member (bit[3], bit[3]) Mcrfs
-
-function clause decode (0b111111 :
-(bit[3]) BF :
-(bit[2]) _ :
-(bit[3]) BFA :
-(bit[2]) _ :
-(bit[5]) _ :
-0b0001000000 :
-(bit[1]) _ as instr) =
- Mcrfs (BF,BFA)
-
-function clause execute (Mcrfs (BF, BFA)) = ()
-
-union ast member (bit[5], bit[5], bit[5]) Lvx
-
-function clause decode (0b011111 :
-(bit[5]) VRT :
-(bit[5]) RA :
-(bit[5]) RB :
-0b0001100111 :
-(bit[1]) _ as instr) =
- Lvx (VRT,RA,RB)
-
-function clause execute (Lvx (VRT, RA, RB)) =
- {
- (bit[64]) b := 0;
- (bit[64]) EA := 0;
- if RA == 0 then b := 0 else b := GPR[RA];
- EA := b + GPR[RB];
- VR[VRT] :=
- MEMr
- (EA & 0b1111111111111111111111111111111111111111111111111111111111110000,16)
- }
-
-union ast member (bit[5], bit[5], bit[5]) Stvx
-
-function clause decode (0b011111 :
-(bit[5]) VRS :
-(bit[5]) RA :
-(bit[5]) RB :
-0b0011100111 :
-(bit[1]) _ as instr) =
- Stvx (VRS,RA,RB)
-
-function clause execute (Stvx (VRS, RA, RB)) =
- {
- (bit[64]) b := 0;
- (bit[64]) EA := 0;
- if RA == 0 then b := 0 else b := GPR[RA];
- EA := b + GPR[RB];
- MEMw(EA & 0b1111111111111111111111111111111111111111111111111111111111110000,16) :=
- VR[VRS]
- }
-
-union ast member (bit[5]) Mtvscr
-
-function clause decode (0b000100 :
-(bit[10]) _ :
-(bit[5]) VRB :
-0b11001000100 as instr) =
- Mtvscr (VRB)
-
-function clause execute (Mtvscr (VRB)) = VSCR := (VR[VRB])[96 .. 127]
-
-union ast member (bit[5]) Mfvscr
-
-function clause decode (0b000100 :
-(bit[5]) VRT :
-(bit[10]) _ :
-0b11000000100 as instr) =
- Mfvscr (VRT)
-
-function clause execute (Mfvscr (VRT)) =
- VR[VRT] :=
- 0b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 :
- VSCR
-
-union ast member (bit[2]) Sync
-
-function clause decode (0b011111 :
-(bit[3]) _ :
-(bit[2]) L :
-(bit[5]) _ :
-(bit[5]) _ :
-0b1001010110 :
-(bit[1]) _ as instr) =
- Sync (L)
-
-function clause execute (Sync (L)) =
- switch L { case 0b00 -> { H_Sync (()) } case 0b01 -> { LW_Sync (()) } }
-
-union ast member (bit[5]) Mbar
-
-function clause decode (0b011111 :
-(bit[5]) MO :
-(bit[5]) _ :
-(bit[5]) _ :
-0b1101010110 :
-(bit[1]) _ as instr) =
- Mbar (MO)
-
-function clause execute (Mbar (MO)) = ()
-
-
-typedef decode_failure = enumerate { no_matching_pattern; unsupported_instruction; illegal_instruction }
-
-function clause decode _ = exit no_matching_pattern
+union ast member ((bit[12]), regno, regno) ADDIW
+function clause decode ((bit[12]) imm : (regno) rs1 : 0b000 : (regno) rd : 0b0011011) = Some(ADDIW(imm, rs1, rd))
+function clause execute (ADDIW(imm, rs1, rd)) =
+ let (bit[64]) imm64 = EXTS(imm) in
+ let (bit[64]) result64 = imm64 + rGPR(rs1) in
+ let (bit[64]) result32 = EXTS(result64[31..0]) in
+ wGPR(rd, result32)
+
+union ast member ((bit[5]), regno, regno, sop) SHIFTW
+function clause decode (0b0000000 : (bit[5]) shamt : (regno) rs1 : 0b001 : (regno) rd : 0b0011011) = Some(SHIFTW(shamt, rs1, rd, SLLI))
+function clause decode (0b0000000 : (bit[5]) shamt : (regno) rs1 : 0b101 : (regno) rd : 0b0011011) = Some(SHIFTW(shamt, rs1, rd, SRLI))
+function clause decode (0b0100000 : (bit[5]) shamt : (regno) rs1 : 0b101 : (regno) rd : 0b0011011) = Some(SHIFTW(shamt, rs1, rd, SRAI))
+function clause execute (SHIFTW(shamt, rs1, rd, op)) =
+ let rs1_val = (rGPR(rs1))[31..0] in
+ let result = switch(op) {
+ case SLLI -> rs1_val >> shamt
+ case SRLI -> rs1_val << shamt
+ case SRAI -> shift_right_arith32(rs1_val, shamt)
+ } in
+ wGPR(rd, EXTS(result))
+
+union ast member (regno, regno, regno, ropw) RTYPEW
+function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b000 : (regno) rd : 0b0111011) = Some(RTYPEW(rs2, rs1, rd, ADDW))
+function clause decode (0b0100000 : (regno) rs2 : (regno) rs1 : 0b000 : (regno) rd : 0b0111011) = Some(RTYPEW(rs2, rs1, rd, SUBW))
+function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b001 : (regno) rd : 0b0111011) = Some(RTYPEW(rs2, rs1, rd, SLLW))
+function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b101 : (regno) rd : 0b0111011) = Some(RTYPEW(rs2, rs1, rd, SRLW))
+function clause decode (0b0100000 : (regno) rs2 : (regno) rs1 : 0b101 : (regno) rd : 0b0111011) = Some(RTYPEW(rs2, rs1, rd, SRAW))
+function clause execute (RTYPEW(rs2, rs1, rd, op)) =
+ let rs1_val = (rGPR(rs1))[31..0] in
+ let rs2_val = (rGPR(rs2))[31..0] in
+ let (bit[32]) result = switch(op) {
+ case ADDW -> rs1_val + rs2_val
+ case SUBW -> rs1_val - rs2_val
+ case SLLW -> rs1_val << (rs2_val[4..0])
+ case SRLW -> rs1_val >> (rs2_val[4..0])
+ case SRAW -> shift_right_arith32(rs1_val, rs2_val[4..0])
+ } in
+ wGPR(rd, EXTS(result))
+end ast
end decode
end execute
-end ast
-
-val ast -> ast effect pure supported_instructions
-function ast supported_instructions ((ast) instr) = {
- switch instr {
- case (Mbar(_)) -> exit unsupported_instruction
- case (Sync(0b10)) -> exit unsupported_instruction
- case (Sync(0b11)) -> exit unsupported_instruction
- case _ -> instr
- }
-}
-
-val ast -> bit effect pure illegal_instructions_pred
-function bit illegal_instructions_pred ((ast) instr) = {
- switch instr {
- case (Bcctr(BO,BI,BH,LK)) -> ~(BO[2])
- case (Lbzu(RT,RA,D)) -> (RA == 0) | (RA == RT)
- case (Lbzux(RT,RA,_)) ->(RA == 0) | (RA == RT)
- case (Lhzu(RT,RA,D)) -> (RA == 0) | (RA == RT)
- case (Lhzux(RT,RA,RB)) -> (RA == 0) | (RA == RT)
- case (Lhau(RT,RA,D)) -> (RA == 0) | (RA == RT)
- case (Lhaux(RT,RA,RB)) -> (RA == 0) | (RA == RT)
- case (Lwzu(RA,RT,D)) -> (RA == 0) | (RA == RT)
- case (Lwzux(RT,RA,RB)) -> (RA == 0) | (RA == RT)
- case (Lwaux(RA,RT,RB)) -> (RA == 0) | (RA == RT)
- case (Ldu(RT,RA,DS)) -> (RA == 0) | (RA == RT)
- case (Ldux(RT,RA,RB)) -> (RA == 0) | (RA == RT)
- case (Stbu(RS,RA,D)) -> (RA == 0)
- case (Stbux(RS,RA,RB)) -> (RA == 0)
- case (Sthu(RS,RA,RB)) -> (RA == 0)
- case (Sthux(RS,RA,RB)) -> (RA == 0)
- case (Stwu(RS,RA,D)) -> (RA == 0)
- case (Stwux(RS,RA,RB)) -> (RA == 0)
- case (Stdu(RS,RA,DS)) -> (RA == 0)
- case (Stdux(RS,RA,RB)) -> (RA == 0)
- case (Lmw(RT,RA,D)) -> (RA == 0) | ((RT <= RA) & (RA <= 31))
- case (Lswi(RT,RA,NB)) ->
- let (([|32|]) n) = (if ~(NB == 0) then NB else 32) in
- let ceil =
- (if (n mod 4) == 0
- then n quot 4 else (n quot 4) + 1) in
- (RT <= RA) & (RA <= ((bit[5]) (((bit[5]) (RT + ceil)) -1)))
- (* Can't read XER at the time meant, so will need to rethink *)
- (* case (Lswx(RT,RA,RB)) ->
- let (([|32|]) n) = (XER[57..63]) in
- let ceil =
- (if (n mod 4 == 0)
- then n quot 4 else (n quot 4) + 1) in
- let ((bit[5]) upper_bound) = (RT + ceil) in
- (RT <= RA & RA <= upper_bound) |
- (RT <= RB & RB <= upper_bound) |
- (RT == RA) | (RT == RB)*)
- case (Lfsu(FRT,RA,D)) -> (RA == 0)
- case (Lfsux(FRT,RA,RB)) -> (RA == 0)
- case (Lfdu(FRT,RA,D)) -> (RA == 0)
- case (Lfdux(FRT,RA,RB)) -> (RA == 0)
- case (Stfsu(FRS,RA,D)) -> (RA == 0)
- case (Stfsux(FRS,RA,RB)) -> (RA == 0)
- case (Stfdu(FRS,D,RA)) -> (RA == 0)
- case (Stfdux(FRS,RA,RB)) -> (RA == 0)
- case (Lfdp(FRTp,RA,DS)) -> (FRTp mod 2 == 1)
- case (Stfdp(FRSp,RA,DS)) -> (FRSp mod 2 == 1)
- case (Lfdpx(FRTp,RA,RB)) -> (FRTp mod 2 == 1)
- case (Stfdpx(FRSp,RA,RB)) -> (FRSp mod 2 == 1)
- case (Lq(RTp,RA,DQ,Pt)) -> ((RTp mod 2 ==1) | RTp == RA)
- case (Stq(RSp,RA,RS)) -> (RSp mod 2 == 1)
- case (Mtspr(RS, spr)) ->
- ~ ((spr == 1) | (spr == 8) | (spr == 9) | (spr == 256) |
- (spr == 512) | (spr == 896) | (spr == 898))
-(*One of these causes a stack overflow error, don't want to debug why now*)
- (*case (Mfspr(RT, spr)) ->
- ~ ((spr == 1) | (spr == 8) | (spr == 9) | (spr == 136) |
- (spr == 256) | (spr == 259) | (spr == 260) | (spr == 261) |
- (spr == 262) | (spr == 263) | (spr == 268) | (spr == 268) |
- (spr == 269) | (spr == 512) | (spr == 526) | (spr == 526) |
- (spr == 527) | (spr == 896) | (spr == 898))
- case (Se_illegal) -> true
- case (E_lhau(RT,RA,D8)) -> (RA == 0 | RA == RT)
- case (E_Lhzu(RT,RA,D8)) -> (RA == 0 | RA == RT)
- case (E_lwzu(RT,RA,D8)) -> (RA == 0 | RA == RT)
- case (E_stbu(RS,RA,D8)) -> (RA == 0)
- case (E_sthu(RS,RA,D8)) -> (RA == 0)
- case (E_stwu(RS,RA,D8)) -> (RA == 0)
- case (E_lmw(RT,RA,D8)) -> (RT <= RA & RA <= 31)*)
- case _ -> false
- }
-}
-
-val ast -> ast effect pure illegal_instructions
-function ast illegal_instructions ((ast) instr) =
- if (illegal_instructions_pred ((ast) instr))
- then exit illegal_instruction else instr
-
-(* fetch-decode-execute *)
-function unit fde () = {
- NIA := CIA + 4;
- instr := decode(MEMr(CIA, 4));
- instr := supported_instructions(instr);
- execute(instr);
- CIA := NIA;
-}*)