summaryrefslogtreecommitdiff
path: root/old/power/power_regfp.sail
diff options
context:
space:
mode:
Diffstat (limited to 'old/power/power_regfp.sail')
-rw-r--r--old/power/power_regfp.sail1483
1 files changed, 1483 insertions, 0 deletions
diff --git a/old/power/power_regfp.sail b/old/power/power_regfp.sail
new file mode 100644
index 00000000..1f421186
--- /dev/null
+++ b/old/power/power_regfp.sail
@@ -0,0 +1,1483 @@
+(*========================================================================*)
+(* *)
+(* Copyright (c) 2015-2017 Gabriel Kerneis, Susmit Sarkar, Kathyrn Gray *)
+(* Copyright (c) 2015-2017 Peter Sewell *)
+(* All rights reserved. *)
+(* *)
+(* This software was developed by the University of Cambridge Computer *)
+(* Laboratory as part of the Rigorous Engineering of Mainstream Systems *)
+(* (REMS) project, funded by EPSRC grant EP/K008528/1. *)
+(* *)
+(* Redistribution and use in source and binary forms, with or without *)
+(* modification, are permitted provided that the following conditions *)
+(* are met: *)
+(* 1. Redistributions of source code must retain the above copyright *)
+(* notice, this list of conditions and the following disclaimer. *)
+(* 2. Redistributions in binary form must reproduce the above copyright *)
+(* notice, this list of conditions and the following disclaimer in *)
+(* the documentation and/or other materials provided with the *)
+(* distribution. *)
+(* *)
+(* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' *)
+(* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *)
+(* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *)
+(* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR *)
+(* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *)
+(* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *)
+(* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF *)
+(* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND *)
+(* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, *)
+(* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT *)
+(* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF *)
+(* SUCH DAMAGE. *)
+(*========================================================================*)
+
+let (vector <0, 32, inc, string >) GPRs =
+ [ "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"
+ ]
+
+let (vector <0, 1024, inc, string >) SPRs =
+ [ 1="XER", 8="LR", 9="CTR"(*, 256=VRSAVE (*32 bit, so not 64, caught by type checker at last*)*), 259="SPRG3", 260="SPRG4", 261="SPRG5", 262="SPRG6", 263="SPRG7"
+ ]
+
+let (vector <0, 1024, inc, string >) DCRs =
+ [ 0="DCR0", 1="DCR1" ; default=undefined]
+
+function nat length_spr i = switch i {
+ case 1 -> 64
+ case 8 -> 64
+ case 9 -> 64
+ case 259 -> 64
+ case 260 -> 64
+ case 261 -> 64
+ case 262 -> 64
+ case 263 -> 64
+}
+
+let CIA_fp = RFull("CIA")
+let NIA_fp = RFull("NIA")
+let mode64bit_fp = RFull("mode64bit")
+let bigendianmode_fp = RFull("bigendianmode")
+
+val ast -> (regfps,regfps,regfps,niafps,diafp,instruction_kind) effect {rreg} initial_analysis
+function (regfps,regfps,regfps,niafps,diafp,instruction_kind) initial_analysis (instr) = {
+ iR := [|| ||];
+ oR := [|| ||];
+ aR := [|| ||];
+ ik := IK_simple;
+ Nias := [|| NIAFP_successor ||];
+ Dia := DIAFP_none;
+ switch instr {
+ case (B (LI, AA, LK)) -> {
+ oR := NIA_fp :: oR;
+ if AA then iR := CIA_fp :: iR;
+ if LK then oR := RFull("LR") :: oR;
+ (bit[64]) nia' := if AA then EXTS(LI : 0b00) else CIA + EXTS(LI : 0b00);
+ Nias := [|| NIAFP_concrete_address(nia') ||];
+ ik := IK_branch
+ }
+ case (Bc (BO, BI, BD, AA, LK)) -> {
+ iR := mode64bit_fp :: iR;
+ iR := RFull("CTR") :: iR;
+ if ~(BO[2]) then oR := RFull("CTR") :: oR;
+ iR := RSliceBit("CR",BI + 32) :: iR;
+ (* TODO: actually whether CIA is read and NIA written depends on runtime data *)
+ (* if ctr_ok .. *)
+ oR := NIA_fp :: oR;
+ if AA then iR := CIA_fp :: iR;
+ Nias := [|| NIAFP_successor, NIAFP_concrete_address(if AA then EXTS(BD : 0b00) else CIA + EXTS(BD : 0b00)) ||];
+ if LK then {oR := RFull("LR") :: oR; iR := CIA_fp :: iR};
+ ik := IK_branch
+ }
+ case (Bclr (BO, BI, BH, LK)) -> {
+ iR := mode64bit_fp :: iR;
+ iR := RFull("CTR") :: iR;
+ if ~(BO[2]) then oR := RFull("CTR") :: oR;
+ iR := RSliceBit("CR",BI + 32) :: iR;
+ (* TODO: actually whether LR is read, NIA written depends on runtime data *)
+ (* if ctr_ok .. *) iR := RSlice("LR",0,61) :: iR;
+ oR := NIA_fp :: oR;
+ Nias := [|| NIAFP_successor, NIAFP_indirect_address ||];
+ if LK then {oR := RFull("LR") :: oR; iR := CIA_fp :: iR;};
+ ik := IK_branch;
+ }
+ case (Bcctr (BO, BI, BH, LK)) -> {
+ iR := RSliceBit("CR",BI + 32) :: iR;
+ (* TODO: actually whether CTR is read and NIA written depends on runtime data *)
+ (* if cond_ok *) iR := RSlice("CTR",0,61) :: iR;
+ oR := NIA_fp :: oR;
+ Nias := [|| NIAFP_successor, NIAFP_indirect_address ||];
+ if LK then {oR := RFull("LR") :: oR; iR := CIA_fp :: iR;};
+ ik := IK_branch;
+ }
+ case (Crand (BT, BA, BB)) -> {
+ iR := RSliceBit("CR",BA + 32) :: RSliceBit("CR",BB + 32) :: iR;
+ oR := RSliceBit("CR",BT + 32) :: oR;
+ }
+ case (Crnand (BT, BA, BB)) -> {
+ iR := RSliceBit("CR",BA + 32) :: RSliceBit("CR",BB + 32) :: iR;
+ oR := RSliceBit("CR",BT + 32) :: oR;
+ }
+ case (Cror (BT, BA, BB)) -> {
+ iR := RSliceBit("CR",BA + 32) :: RSliceBit("CR",BB + 32) :: iR;
+ oR := RSliceBit("CR",BT + 32) :: oR;
+ }
+ case (Crxor (BT, BA, BB)) -> {
+ iR := RSliceBit("CR",BA + 32) :: RSliceBit("CR",BB + 32) :: iR;
+ oR := RSliceBit("CR",BT + 32) :: oR;
+ }
+ case (Crnor (BT, BA, BB)) -> {
+ iR := RSliceBit("CR",BA + 32) :: RSliceBit("CR",BB + 32) :: iR;
+ oR := RSliceBit("CR",BT + 32) :: oR;
+ }
+ case (Creqv (BT, BA, BB)) -> {
+ iR := RSliceBit("CR",BA + 32) :: RSliceBit("CR",BB + 32) :: iR;
+ oR := RSliceBit("CR",BT + 32) :: oR;
+ }
+ case (Crandc (BT, BA, BB)) -> {
+ iR := RSliceBit("CR",BA + 32) :: RSliceBit("CR",BB + 32) :: iR;
+ oR := RSliceBit("CR",BT + 32) :: oR;
+ }
+ case (Crorc (BT, BA, BB)) -> {
+ iR := RSliceBit("CR",BA + 32) :: RSliceBit("CR",BB + 32) :: iR;
+ oR := RSliceBit("CR",BT + 32) :: oR;
+ }
+ case (Mcrf (BF, BFA)) -> {
+ iR := RSlice("CR",4 * BFA + 32,4 * BFA + 35) :: iR;
+ oR := RSlice("CR",4 * BF + 32,4 * BF + 35) :: oR;
+ }
+ case (Sc (LEV)) -> {
+ (* fake test end instruction *)
+ ();
+ }
+ case (Scv (LEV)) -> ()
+ case (Lbz (RT, RA, D)) -> {
+ if RA == 0 then () else iR := (RFull(GPRs[RA])) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ ik := IK_mem_read(Read_plain);
+ }
+ case (Lbzx (RT, RA, RB)) -> {
+ if RA == 0 then () else iR := (RFull(GPRs[RA])) :: iR;
+ iR := RFull(GPRs[RB]) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ ik := IK_mem_read(Read_plain);
+ }
+ case (Lbzu (RT, RA, D)) -> {
+ iR := RFull(GPRs[RA]) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RA]) :: RFull(GPRs[RT]) :: oR;
+ ik := IK_mem_read(Read_plain);
+ }
+ case (Lbzux (RT, RA, RB)) -> {
+ iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RA]) :: RFull(GPRs[RT]) :: oR;
+ ik := IK_mem_read(Read_plain);
+ }
+ case (Lhz (RT, RA, D)) -> {
+ if RA == 0 then () else iR := (RFull(GPRs[RA])) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ ik := IK_mem_read(Read_plain);
+ }
+ case (Lhzx (RT, RA, RB)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ iR := RFull(GPRs[RB]) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ ik := IK_mem_read(Read_plain);
+ }
+ case (Lhzu (RT, RA, D)) -> {
+ iR := RFull(GPRs[RA]) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RA]) :: RFull(GPRs[RT]) :: oR;
+ ik := IK_mem_read(Read_plain);
+ }
+ case (Lhzux (RT, RA, RB)) -> {
+ iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RA]) :: RFull(GPRs[RT]) :: oR;
+ ik := IK_mem_read(Read_plain);
+ }
+ case (Lha (RT, RA, D)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ ik := IK_mem_read(Read_plain);
+ }
+ case (Lhax (RT, RA, RB)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ iR := RFull(GPRs[RB]) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ ik := IK_mem_read(Read_plain);
+ }
+ case (Lhau (RT, RA, D)) -> {
+ iR := RFull(GPRs[RA]) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RA]) :: RFull(GPRs[RT]) :: oR;
+ ik := IK_mem_read(Read_plain);
+ }
+ case (Lhaux (RT, RA, RB)) -> {
+ iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RA]) :: RFull(GPRs[RT]) :: oR;
+ ik := IK_mem_read(Read_plain);
+ }
+ case (Lwz (RT, RA, D)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ ik := IK_mem_read(Read_plain);
+ }
+ case (Lwzx (RT, RA, RB)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ iR := RFull(GPRs[RB]) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ ik := IK_mem_read(Read_plain);
+ }
+ case (Lwzu (RT, RA, D)) -> {
+ iR := RFull(GPRs[RA]) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RA]) :: RFull(GPRs[RT]) :: oR;
+ ik := IK_mem_read(Read_plain);
+ }
+ case (Lwzux (RT, RA, RB)) -> {
+ iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RA]) :: RFull(GPRs[RT]) :: oR;
+ ik := IK_mem_read(Read_plain);
+ }
+ case (Lwa (RT, RA, DS)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ ik := IK_mem_read(Read_plain);
+ }
+ case (Lwax (RT, RA, RB)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ iR := RFull(GPRs[RB]) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ ik := IK_mem_read(Read_plain);
+ }
+ case (Lwaux (RT, RA, RB)) -> {
+ iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RA]) :: RFull(GPRs[RT]) :: oR;
+ ik := IK_mem_read(Read_plain);
+ }
+ case (Ld (RT, RA, DS)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ ik := IK_mem_read(Read_plain);
+ }
+ case (Ldx (RT, RA, RB)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ iR := RFull(GPRs[RB]) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ ik := IK_mem_read(Read_plain);
+ }
+ case (Ldu (RT, RA, DS)) -> {
+ iR := RFull(GPRs[RA]) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RA]) :: RFull(GPRs[RT]) :: oR;
+ ik := IK_mem_read(Read_plain);
+ }
+ case (Ldux (RT, RA, RB)) -> {
+ iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RA]) :: RFull(GPRs[RT]) :: oR;
+ ik := IK_mem_read(Read_plain);
+ }
+ case (Stb (RS, RA, D)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ aR := iR;
+ iR := RSlice(GPRs[RS],56,63) :: iR;
+ ik := IK_mem_write(Write_plain);
+ }
+ case (Stbx (RS, RA, RB)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ iR := RFull(GPRs[RB]) :: iR;
+ aR := iR;
+ iR := RSlice(GPRs[RS],56,63) :: iR;
+ ik := IK_mem_write(Write_plain);
+ }
+ case (Stbu (RS, RA, D)) -> {
+ iR := RFull(GPRs[RA]) :: iR;
+ aR := iR;
+ iR := RSlice(GPRs[RS],56,63) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ ik := IK_mem_write(Write_plain);
+ }
+ case (Stbux (RS, RA, RB)) -> {
+ iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ aR := iR;
+ iR := RSlice(GPRs[RS],56,63) :: iR;
+ ik := IK_mem_write(Write_plain);
+ }
+ case (Sth (RS, RA, D)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ aR := iR;
+ iR := RSlice(GPRs[RS],48,63) :: iR;
+ ik := IK_mem_write(Write_plain);
+ }
+ case (Sthx (RS, RA, RB)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ iR := RFull(GPRs[RB]) :: iR;
+ aR := iR;
+ iR := RFull(GPRs[RB]) :: RSlice(GPRs[RS],48,63) :: iR;
+ ik := IK_mem_write(Write_plain);
+ }
+ case (Sthu (RS, RA, D)) -> {
+ iR := RFull(GPRs[RA]) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ iR := RSlice(GPRs[RS],48,63) :: iR;
+ ik := IK_mem_write(Write_plain);
+ }
+ case (Sthux (RS, RA, RB)) -> {
+ iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ aR := iR;
+ iR := RSlice(GPRs[RS],48,63) :: iR;
+ ik := IK_mem_write(Write_plain);
+ }
+ case (Stw (RS, RA, D)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ aR := iR;
+ iR := RSlice(GPRs[RS],32,63) :: iR;
+ ik := IK_mem_write(Write_plain);
+ }
+ case (Stwx (RS, RA, RB)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ iR := RFull(GPRs[RB]) :: iR;
+ aR := iR;
+ iR := RSlice(GPRs[RS],32,63) :: iR;
+ ik := IK_mem_write(Write_plain);
+ }
+ case (Stwu (RS, RA, D)) -> {
+ iR := RFull(GPRs[RA]) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ aR := iR;
+ iR := RSlice(GPRs[RS],32,63) :: iR;
+ ik := IK_mem_write(Write_plain);
+ }
+ case (Stwux (RS, RA, RB)) -> {
+ iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ aR := iR;
+ iR := RSlice(GPRs[RS],32,63) :: iR;
+ ik := IK_mem_write(Write_plain);
+ }
+ case (Std (RS, RA, DS)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ aR := iR;
+ iR := RFull(GPRs[RS]) :: iR;
+ ik := IK_mem_write(Write_plain);
+ }
+ case (Stdx (RS, RA, RB)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ iR := RFull(GPRs[RB]) :: iR;
+ aR := iR;
+ iR := RFull(GPRs[RS]) :: iR;
+ ik := IK_mem_write(Write_plain);
+ }
+ case (Stdu (RS, RA, DS)) -> {
+ iR := RFull(GPRs[RA]) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ aR := iR;
+ iR := RFull(GPRs[RS]) :: iR;
+ ik := IK_mem_write(Write_plain);
+ }
+ case (Stdux (RS, RA, RB)) -> {
+ iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ aR := iR;
+ iR := RFull(GPRs[RS]) :: iR;
+ ik := IK_mem_write(Write_plain);
+ }
+ case (Lq (RTp, RA, DQ, PT)) -> {
+ iR := bigendianmode_fp :: iR;
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RTp]) :: RFull(GPRs[RTp + 1]) :: oR;
+ ik := IK_mem_read(Read_plain);
+ }
+ case (Stq (RSp, RA, DS)) -> {
+ iR := bigendianmode_fp :: iR;
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ aR := iR;
+ iR := RFull(GPRs[RSp]) :: RFull(GPRs[RSp + 1]) :: iR;
+ ik := IK_mem_write(Write_plain);
+ }
+ case (Lhbrx (RT, RA, RB)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ iR := RFull(GPRs[RB]) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ ik := IK_mem_read(Read_plain);
+ }
+ case (Sthbrx (RS, RA, RB)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ iR := RFull(GPRs[RB]) :: iR;
+ aR := iR;
+ iR := RSlice(GPRs[RS],56,63) :: RSlice(GPRs[RS],48,55) :: iR;
+ ik := IK_mem_write(Write_plain);
+ }
+ case (Lwbrx (RT, RA, RB)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ iR := RFull(GPRs[RB]) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ ik := IK_mem_read(Read_plain);
+ }
+ case (Stwbrx (RS, RA, RB)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ iR := RFull(GPRs[RB]) :: iR;
+ aR := iR;
+ iR := RSlice(GPRs[RS],56,63) :: RSlice(GPRs[RS],48,55) :: RSlice(GPRs[RS],40,47) :: RSlice(GPRs[RS],32,39) :: iR;
+ ik := IK_mem_write(Write_plain);
+ }
+ case (Ldbrx (RT, RA, RB)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ iR := RFull(GPRs[RB]) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ ik := IK_mem_read(Read_plain);
+ }
+ case (Stdbrx (RS, RA, RB)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ iR := RFull(GPRs[RB]) :: iR;
+ aR := iR;
+ iR := RSlice(GPRs[RS],56,63) :: RSlice(GPRs[RS],48,55) :: RSlice(GPRs[RS],40,47) :: RSlice(GPRs[RS],32,39) :: RSlice(GPRs[RS],24,31) :: RSlice(GPRs[RS],16,23) :: RSlice(GPRs[RS],8,15) :: RSlice(GPRs[RS],0,7) :: iR;
+ ik := IK_mem_write(Write_plain);
+ }
+ case (Lmw (RT, RA, D)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ i := 0;
+ aR := iR;
+ foreach (r from RT to 31 by 1 in inc) {
+ oR := RFull(GPRs[r]) :: oR;
+ i := i + 32
+ };
+ ik := IK_mem_read(Read_plain);
+ }
+ case (Stmw (RS, RA, D)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ aR := iR;
+ i := 0;
+ foreach (r from RS to 31 by 1 in inc) {
+ iR := RSlice(GPRs[r],32,63) :: iR;
+ i := i + 32
+ };
+ ik := IK_mem_write(Write_plain);
+ }
+ case (Lswi (RT, RA, NB)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ aR := iR;
+ ([|31|]) r := 0;
+ r := RT - 1;
+ 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 := ([|31|]) (r + 1) mod 32;
+ oR := RFull(GPRs[r]) :: oR;
+ };
+ oR := RSlice(GPRs[r],i,i + 7) :: oR;
+ j := j + 8;
+ i := i + 8;
+ if i == 64 then i := 32;
+ };
+ ik := IK_mem_read(Read_plain);
+ }
+ case (Lswx (RT, RA, RB)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ iR := RFull(GPRs[RB]) :: RSlice("XER",57,63) :: iR;
+ aR := iR;
+ (* as long as XER[57 .. 63] is unknown all registers could be written to *)
+ foreach (r from 0 to 31 by 1 in inc) {oR := RFull(GPRs[r]) :: oR};
+ ik := IK_mem_read(Read_plain);
+ }
+ case (Stswi (RS, RA, NB)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ aR := iR;
+ ([|31|]) r := 0;
+ r := RS - 1;
+ 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;
+ iR := RSlice(GPRs[r],i,i + 7) :: iR;
+ j := j + 8;
+ i := i + 8;
+ if i == 64 then i := 32
+ };
+ ik := IK_mem_write(Write_plain);
+ }
+ case (Stswx (RS, RA, RB)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ ([|31|]) r := 0;
+ iR := RFull(GPRs[RB]) :: RSlice("XER",57,63) :: iR;
+ aR := iR;
+ r := RS - 1;
+ i := 32;
+ ([|128|]) n_top := 0b1111111; (* maximal XER[57 .. 63]; *)
+ j := 0;
+ foreach (n from n_top to 1 by 1 in dec) {
+ if i == 32 then r := ([|32|]) (r + 1) mod 32;
+ iR := RSlice(GPRs[r],i,i + 7) :: iR;
+ i := i + 8;
+ j := j + 8;
+ if i == 64 then i := 32
+ };
+ ik := IK_mem_write(Write_plain);
+ }
+ case (Addi (RT, RA, SI)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ }
+ case (Addis (RT, RA, SI)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ }
+ case (Add (RT, RA, RB, OE, Rc)) -> {
+ iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ if OE then {
+ iR := RField("XER","SO") :: iR; (* set_SO_OV *)
+ oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *)
+ }
+ }
+ case (Subf (RT, RA, RB, OE, Rc)) -> {
+ iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ if OE then {
+ iR := RField("XER","SO") :: iR; (* set_SO_OV *)
+ oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *)
+ }
+ }
+ case (Addic (RT, RA, SI)) -> {
+ iR := RFull(GPRs[RA]) :: iR;
+ oR := RFull(GPRs[RT]) :: RField("XER","CA") :: oR;
+ }
+ case (AddicDot (RT, RA, SI)) -> {
+ iR := RFull(GPRs[RA]) :: iR;
+ oR := RFull(GPRs[RT]) :: RField("XER","CA") :: oR;
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ }
+ case (Subfic (RT, RA, SI)) -> {
+ iR := RFull(GPRs[RA]) :: iR;
+ oR := RFull(GPRs[RT]) :: RField("XER","CA") :: oR;
+ }
+ case (Addc (RT, RA, RB, OE, Rc)) -> {
+ iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ oR := RField("XER","CA") :: oR;
+ if OE then {
+ iR := RField("XER","SO") :: iR; (* set_SO_OV *)
+ oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *)
+ }
+ }
+ case (Subfc (RT, RA, RB, OE, Rc)) -> {
+ iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ oR := RField("XER","CA") :: oR;
+ if OE then {
+ iR := RField("XER","SO") :: iR; (* set_SO_OV *)
+ oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *)
+ }
+ }
+ case (Adde (RT, RA, RB, OE, Rc)) -> {
+ iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR;
+ iR := RField("XER","CA") :: iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ oR := RField("XER","CA") :: oR;
+ if OE then {
+ iR := RField("XER","SO") :: iR; (* set_SO_OV *)
+ oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *)
+ }
+ }
+ case (Subfe (RT, RA, RB, OE, Rc)) -> {
+ iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR;
+ iR := RField("XER","CA") :: iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ oR := RField("XER","CA") :: oR;
+ if OE then {
+ iR := RField("XER","SO") :: iR; (* set_SO_OV *)
+ oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *)
+ }
+ }
+ case (Addme (RT, RA, OE, Rc)) -> {
+ iR := RFull(GPRs[RA]) :: RField("XER","CA") :: iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ oR := RField("XER","CA") :: oR;
+ if OE then {
+ iR := RField("XER","SO") :: iR; (* set_SO_OV *)
+ oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *)
+ }
+ }
+ case (Subfme (RT, RA, OE, Rc)) -> {
+ iR := RFull(GPRs[RA]) :: RField("XER","CA") :: iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ oR := RField("XER","CA") :: oR;
+ if OE then {
+ iR := RField("XER","SO") :: iR; (* set_SO_OV *)
+ oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *)
+ }
+ }
+ case (Addze (RT, RA, OE, Rc)) -> {
+ iR := RFull(GPRs[RA]) :: RField("XER","CA") :: iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ oR := RField("XER","CA") :: oR;
+ if OE then {
+ iR := RField("XER","SO") :: iR; (* set_SO_OV *)
+ oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *)
+ }
+ }
+ case (Subfze (RT, RA, OE, Rc)) -> {
+ iR := RFull(GPRs[RA]) :: RField("XER","CA") :: iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ oR := RField("XER","CA") :: oR;
+ if OE then {
+ iR := RField("XER","SO") :: iR; (* set_SO_OV *)
+ oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *)
+ }
+ }
+ case (Neg (RT, RA, OE, Rc)) -> {
+ iR := RFull(GPRs[RA]) :: iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ if OE then {
+ iR := RField("XER","SO") :: iR; (* set_SO_OV *)
+ oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *)
+ }
+ }
+ case (Mulli (RT, RA, SI)) -> {
+ iR := RFull(GPRs[RA]) :: iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ }
+ case (Mullw (RT, RA, RB, OE, Rc)) -> {
+ iR := RSlice(GPRs[RA],32,63) :: RSlice(GPRs[RB],32,63) :: iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ if OE then {
+ iR := RField("XER","SO") :: iR; (* set_SO_OV *)
+ oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *)
+ }
+ }
+ case (Mulhw (RT, RA, RB, Rc)) -> {
+ iR := RSlice(GPRs[RA],32,63) :: RSlice(GPRs[RB],32,63) :: iR;
+ oR := RSlice(GPRs[RT],32,63) :: RSlice(GPRs[RT],0,31) :: oR;
+ if Rc then {
+ iR := mode64bit_fp :: iR;
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ }
+ case (Mulhwu (RT, RA, RB, Rc)) -> {
+ iR := RSlice(GPRs[RA],32,63) :: RSlice(GPRs[RB],32,63) :: iR;
+ oR := RSlice(GPRs[RT],32,63) :: RSlice(GPRs[RT],0,31) :: oR;
+ if Rc then {
+ iR := mode64bit_fp :: iR;
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ }
+ case (Divw (RT, RA, RB, OE, Rc)) -> {
+ iR := RSlice(GPRs[RA],32,63) :: RSlice(GPRs[RB],32,63) :: iR;
+ oR := RSlice(GPRs[RT],32,63) :: RSlice(GPRs[RT],0,31) :: oR;
+ if Rc then {
+ iR := mode64bit_fp :: iR;
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ if OE then {
+ iR := RField("XER","SO") :: iR; (* set_SO_OV *)
+ oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *)
+ }
+ }
+ case (Divwu (RT, RA, RB, OE, Rc)) -> {
+ iR := RSlice(GPRs[RA],32,63) :: RSlice(GPRs[RB],32,63) :: iR;
+ oR := RSlice(GPRs[RT],32,63) :: RSlice(GPRs[RT],0,31) :: oR;
+ if Rc then {
+ iR := mode64bit_fp :: iR;
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ if OE then {
+ iR := RField("XER","SO") :: iR; (* set_SO_OV *)
+ oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *)
+ }
+ }
+ case (Divwe (RT, RA, RB, OE, Rc)) -> {
+ iR := RSlice(GPRs[RA],32,63) :: RSlice(GPRs[RB],32,63) :: iR;
+ oR := RSlice(GPRs[RT],32,63) :: RSlice(GPRs[RT],0,31) :: oR;
+ if Rc then {
+ iR := mode64bit_fp :: iR;
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ if OE then {
+ iR := RField("XER","SO") :: iR; (* set_SO_OV *)
+ oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *)
+ }
+ }
+ case (Divweu (RT, RA, RB, OE, Rc)) -> {
+ iR := RSlice(GPRs[RA],32,63) :: RSlice(GPRs[RB],32,63) :: iR;
+ oR := RSlice(GPRs[RT],32,63) :: RSlice(GPRs[RT],0,31) :: oR;
+ if Rc then {
+ iR := mode64bit_fp :: iR;
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ if OE then {
+ iR := RField("XER","SO") :: iR; (* set_SO_OV *)
+ oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *)
+ }
+ }
+ case (Mulld (RT, RA, RB, OE, Rc)) -> {
+ iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ if OE then {
+ iR := RField("XER","SO") :: iR; (* set_SO_OV *)
+ oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *)
+ }
+ }
+ case (Mulhd (RT, RA, RB, Rc)) -> {
+ iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ }
+ case (Mulhdu (RT, RA, RB, Rc)) -> {
+ iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ }
+ case (Divd (RT, RA, RB, OE, Rc)) -> {
+ iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ if OE then {
+ iR := RField("XER","SO") :: iR; (* set_SO_OV *)
+ oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *)
+ }
+ }
+ case (Divdu (RT, RA, RB, OE, Rc)) -> {
+ iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ if OE then {
+ iR := RField("XER","SO") :: iR; (* set_SO_OV *)
+ oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *)
+ }
+ }
+ case (Divde (RT, RA, RB, OE, Rc)) -> {
+ iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ if OE then {
+ iR := RField("XER","SO") :: iR; (* set_SO_OV *)
+ oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *)
+ }
+ }
+ case (Divdeu (RT, RA, RB, OE, Rc)) -> {
+ iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ if OE then {
+ iR := RField("XER","SO") :: iR; (* set_SO_OV *)
+ oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *)
+ }
+ }
+ case (Cmpi (BF, L, RA, SI)) -> {
+ iR := (if L == 0 then RSlice(GPRs[RA],32,63) else RFull(GPRs[RA])) :: iR;
+ iR := RField("XER","SO") :: iR;
+ oR := RSlice("CR",4 * BF + 32,4 * BF + 35) :: oR;
+ }
+ case (Cmp (BF, L, RA, RB)) -> {
+ if L == 0 then
+ iR := RSlice(GPRs[RA],32,63) :: RSlice(GPRs[RB],32,63) :: iR
+ else iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR;
+ iR := RField("XER","SO") :: iR;
+ oR := RSlice("CR",4 * BF,4 * BF + 35) :: oR;
+ }
+ case (Cmpli (BF, L, RA, UI)) -> {
+ iR := (if L == 0 then RSlice(GPRs[RA],32,63) else RFull(GPRs[RA])) :: iR;
+ iR := RField("XER","SO") :: iR;
+ oR := RSlice("CR",4 * BF + 32,4 * BF + 35) :: oR;
+ }
+ case (Cmpl (BF, L, RA, RB)) -> {
+ if L == 0 then
+ iR := RSlice(GPRs[RA],32,63) :: RSlice(GPRs[RB],32,63) :: iR
+ else
+ iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR;
+ iR := RField("XER","SO") :: iR;
+ oR := RSlice("CR",4 * BF + 32,4 * BF + 35) :: oR;
+ }
+(* case (Twi (TO, RA, SI)) -> {
+ iR := RSlice(GPRs[RA],32,63) :: iR;
+ }
+ case (Tw (TO, RA, RB)) -> {
+ iR := RSlice(GPRs[RA],32,63) :: RSlice(GPRs[RB],32,63) :: iR;
+ }
+ case (Tdi (TO, RA, SI)) -> ()
+ case (Td (TO, RA, RB)) -> () *)
+ case (Isel (RT, RA, RB, BC)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ iR := RSliceBit("CR",BC + 32) :: iR;
+ iR := RFull(GPRs[RB]) :: iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ }
+ case (Andi (RS, RA, UI)) -> {
+ iR := RFull(GPRs[RS]) :: RField("XER","SO") :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ }
+ case (Andis (RS, RA, UI)) -> {
+ iR := RFull(GPRs[RS]) :: RField("XER","SO") :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ }
+ case (Ori (RS, RA, UI)) -> {
+ iR := RFull(GPRs[RS]) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ }
+ case (Oris (RS, RA, UI)) -> {
+ iR := RFull(GPRs[RS]) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ }
+ case (Xori (RS, RA, UI)) -> {
+ iR := RFull(GPRs[RS]) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ }
+ case (Xoris (RS, RA, UI)) -> {
+ iR := RFull(GPRs[RS]) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ }
+ case (And (RS, RA, RB, Rc)) -> {
+ iR := RFull(GPRs[RS]) :: RFull(GPRs[RB]) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ }
+ }
+ case (Xor (RS, RA, RB, Rc)) -> {
+ if RS == RB then {
+ iR := RFull(GPRs[RS]) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ }
+ else {
+ iR := RFull(GPRs[RS]) :: RFull(GPRs[RB]) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ };
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ }
+ }
+ case (Nand (RS, RA, RB, Rc)) -> {
+ iR := RFull(GPRs[RS]) :: RFull(GPRs[RB]) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ }
+ }
+ case (Or (RS, RA, RB, Rc)) -> {
+ iR := RFull(GPRs[RS]) :: RFull(GPRs[RB]) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ }
+ }
+ case (Nor (RS, RA, RB, Rc)) -> {
+ iR := RFull(GPRs[RS]) :: RFull(GPRs[RB]) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ }
+ }
+ case (Eqv (RS, RA, RB, Rc)) -> {
+ iR := RFull(GPRs[RS]) :: RFull(GPRs[RB]) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ }
+ }
+ case (Andc (RS, RA, RB, Rc)) -> {
+ iR := RFull(GPRs[RS]) :: RFull(GPRs[RB]) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ }
+ }
+ case (Orc (RS, RA, RB, Rc)) -> {
+ iR := RFull(GPRs[RS]) :: RFull(GPRs[RB]) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ }
+ }
+ case (Extsb (RS, RA, Rc)) -> {
+ iR := RSliceBit(GPRs[RS],56) :: iR;
+ iR := RSlice(GPRs[RS],56,63) :: iR;
+ oR := RSlice(GPRs[RA],56,63) :: oR;
+ oR := RSlice(GPRs[RA],0,55) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ }
+ }
+ case (Extsh (RS, RA, Rc)) -> {
+ iR := RSliceBit(GPRs[RS],48) :: iR;
+ iR := RSlice(GPRs[RS],48,63) :: iR;
+ oR := RSlice(GPRs[RA],48,63) :: oR;
+ oR := RSlice(GPRs[RA],0,47) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ }
+ }
+ case (Cntlzw (RS, RA, Rc)) -> {
+ iR := RFull(GPRs[RS]) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ }
+ }
+ case (Cmpb (RS, RA, RB)) -> {
+ foreach (n from 0 to 7 by 1 in inc) {
+ iR := RSlice(GPRs[RS],8 * n,8 * n + 7) :: RSlice(GPRs[RB],8 * n,8 * n + 7) :: iR;
+ oR := RSlice(GPRs[RA],8 * n,8 * n + 7) :: oR;
+ }
+ }
+ case (Popcntb (RS, RA)) -> {
+ foreach (i from 0 to 7 by 1 in inc) {
+ foreach (j from 0 to 7 by 1 in inc) iR := RSliceBit(GPRs[RS],i * 8 + j) :: iR;
+ oR := RSlice(GPRs[RA],i * 8,i * 8 + 7) :: oR;
+ }
+ }
+ case (Popcntw (RS, RA)) -> {
+ foreach (i from 0 to 1 by 1 in inc) {
+ foreach (j from 0 to 31 by 1 in inc) iR := RSliceBit(GPRs[RS],i * 32 + j) :: iR;
+ oR := RSlice(GPRs[RA],i * 32,i * 32 + 31) :: oR;
+ }
+ }
+ case (Prtyd (RS, RA)) -> {
+ foreach (i from 0 to 7 by 1 in inc) iR := RSliceBit(GPRs[RS],i * 8 + 7) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ }
+ case (Prtyw (RS, RA)) -> {
+ foreach (i from 0 to 3 by 1 in inc) iR := RSliceBit(GPRs[RS],i * 8 + 7) :: iR;
+ foreach (i from 4 to 7 by 1 in inc) iR := RSliceBit(GPRs[RS],i * 8 + 7) :: iR;
+ oR := RSlice(GPRs[RA],0,31) :: oR;
+ oR := RSlice(GPRs[RA],32,63) :: oR;
+ }
+ case (Extsw (RS, RA, Rc)) -> {
+ iR := RSliceBit(GPRs[RS],32) :: iR;
+ iR := RSlice(GPRs[RS],32,63) :: iR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ oR := RFull(GPRs[RA]) :: oR;
+ }
+ case (Cntlzd (RS, RA, Rc)) -> {
+ iR := RFull(GPRs[RS]) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ }
+ case (Popcntd (RS, RA)) -> {
+ foreach (i from 0 to 63 by 1 in inc) iR := RSliceBit(GPRs[RS],i) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ }
+ (* TODO: here the footprint depends on dynamic data *)
+ case (Bpermd (RS, RA, RB)) -> {
+ foreach (i from 0 to 7 by 1 in inc) {
+ iR := RSlice(GPRs[RS],8 * i,8 * i + 7) :: iR;
+ iR := RFull(GPRs[RB]) :: iR; (* this is actually only a single bit, *)
+ (* which one it is depends on the read before *)
+ oR := RFull(GPRs[RA]) :: oR;
+ }
+ }
+ case (Rlwinm (RS, RA, SH, MB, ME, Rc)) -> {
+ iR := RSlice(GPRs[RS],32,63) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ }
+ case (Rlwnm (RS, RA, RB, MB, ME, Rc)) -> {
+ iR := RSlice(GPRs[RB],59,63) :: RSlice(GPRs[RS],32,63) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ }
+ case (Rlwimi (RS, RA, SH, MB, ME, Rc)) -> {
+ iR := RSlice(GPRs[RS],32,63) :: iR;
+ iR := RFull(GPRs[RA]) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ }
+ case (Rldicl (RS, RA, sh, mb, Rc)) -> {
+ iR := RFull(GPRs[RS]) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ }
+ case (Rldicr (RS, RA, sh, me, Rc)) -> {
+ iR := RFull(GPRs[RS]) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ }
+ case (Rldic (RS, RA, sh, mb, Rc)) -> {
+ iR := RFull(GPRs[RS]) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ }
+ case (Rldcl (RS, RA, RB, mb, Rc)) -> {
+ iR := RSlice(GPRs[RB],58,63) :: iR;
+ iR := RFull(GPRs[RS]) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ }
+ case (Rldcr (RS, RA, RB, me, Rc)) -> {
+ iR := RSlice(GPRs[RB],58,63) :: iR;
+ iR := RFull(GPRs[RS]) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ }
+ case (Rldimi (RS, RA, sh, mb, Rc)) -> {
+ iR := RFull(GPRs[RS]) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ }
+ case (Slw (RS, RA, RB, Rc)) -> {
+ iR := RSlice(GPRs[RB],59,63) :: iR;
+ iR := RSlice(GPRs[RS],32,63) :: iR;
+ iR := RSliceBit(GPRs[RB],58) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ }
+ case (Srw (RS, RA, RB, Rc)) -> {
+ iR := RSlice(GPRs[RB],59,63) :: iR;
+ iR := RSlice(GPRs[RS],32,63) :: iR;
+ iR := RSliceBit(GPRs[RB],58) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ }
+ case (Srawi (RS, RA, SH, Rc)) -> {
+ iR := RSlice(GPRs[RS],32,63) :: iR;
+ iR := RSliceBit(GPRs[RS],32) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ oR := RField("XER","CA") :: oR;
+ }
+ case (Sraw (RS, RA, RB, Rc)) -> {
+ iR := RSlice(GPRs[RB],59,63) :: iR;
+ iR := RSlice(GPRs[RS],32,63) :: RSliceBit(GPRs[RB],58) :: RSliceBit(GPRs[RS],32) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ oR := RField("XER","CA") :: oR;
+ }
+ case (Sld (RS, RA, RB, Rc)) -> {
+ iR := RSlice(GPRs[RB],58,63) :: RFull(GPRs[RS]) :: iR;
+ iR := RSliceBit(GPRs[RB],57) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ }
+ case (Srd (RS, RA, RB, Rc)) -> {
+ iR := RSlice(GPRs[RB],58,63) :: RFull(GPRs[RS]) :: iR;
+ iR := RSliceBit(GPRs[RB],57) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ }
+ case (Sradi (RS, RA, sh, Rc)) -> {
+ iR := RFull(GPRs[RS]) :: iR;
+ iR := RSliceBit(GPRs[RS],0) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ oR := RField("XER","CA") :: oR;
+ }
+ case (Srad (RS, RA, RB, Rc)) -> {
+ iR := RSlice(GPRs[RB],58,63) :: RFull(GPRs[RS]) :: RSliceBit(GPRs[RB],57) :: RSliceBit(GPRs[RS],0) :: iR;
+ oR := RFull(GPRs[RA]) :: oR;
+ if Rc then {
+ iR := RField("XER","SO") :: iR;
+ oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *)
+ };
+ oR := RField("XER","CA") :: oR;
+ }
+ case (Cdtbcd (RS, RA)) -> {
+ foreach (i from 0 to 1 by 1 in inc) {
+ n := i * 32;
+ iR := RSlice(GPRs[RS],n + 12,n + 31) :: iR;
+ oR := RSlice(GPRs[RA],n + 0,n + 31) :: oR;
+ }
+ }
+ case (Cbcdtd (RS, RA)) -> {
+ foreach (i from 0 to 1 by 1 in inc) {
+ n := i * 32;
+ iR := RSlice(GPRs[RS],n + 8,n + 31) :: iR;
+ oR := RSlice(GPRs[RA],n + 0,n + 31) :: oR;
+ }
+ }
+ case (Addg6s (RT, RA, RB)) -> {
+ foreach (i from 0 to 15 by 1 in inc) {
+ iR := RSlice(GPRs[RA],4 * i,63) :: iR;
+ iR := RSlice(GPRs[RB],4 * i,63) :: iR;
+ };
+ oR := RFull(GPRs[RT]) :: oR;
+ }
+ case (Mtspr (RS, spr)) -> {
+ n := spr[5 .. 9] : spr[0 .. 4];
+ if n == 1 then {
+ iR := RFull(GPRs[RS]) :: iR;
+ oR := RFull("XER") :: oR;
+ }
+ else {
+ (* the below is debatable: to determine the length of that register, does it
+ * really need to read the content? *)
+ iR := RFull(SPRs[n]) ::iR;
+ if length_spr(n) == 64 then {
+ iR := RFull(GPRs[RS]) :: iR;
+ oR := RFull(SPRs[n]) :: oR;
+ }
+ else if n == 152 then {
+ iR := RSlice(GPRs[RS],32,63) :: iR;
+ oR := RFull("CTRL") :: oR;
+ }
+ else ();
+ }
+ }
+ case (Mfspr (RT, spr)) -> {
+ n := spr[5 .. 9] : spr[0 .. 4];
+ iR := RFull(SPRs[n]) :: iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ }
+ case (Mtcrf (RS, FXM)) -> {
+ iR := RFull("CR") :: RSlice(GPRs[RS],32,63) :: iR;
+ oR := RFull("CR") :: oR;
+ }
+ case (Mfcr (RT)) -> {
+ iR := RFull("CR") :: iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ }
+ case (Mtocrf (RS, FXM)) -> {
+ ([|7|]) n := 0;
+ count := 0;
+ foreach (i from 0 to 7 by 1 in inc)
+ if FXM[i] == 1
+ then {
+ n := i;
+ count := count + 1
+ }
+ else ();
+ if count == 1
+ then {
+ oR := RSlice("CR",4 * n + 32,4 * n + 35) :: oR;
+ iR := RSlice(GPRs[RS],4 * n + 32,4 * n + 35) :: iR;
+ }
+ else oR := RFull("CR") :: oR;
+ }
+ case (Mfocrf (RT, FXM)) -> {
+ ([|7|]) n := 0;
+ count := 0;
+ foreach (i from 0 to 7 by 1 in inc)
+ if FXM[i] == 1
+ then {
+ n := i;
+ count := count + 1
+ }
+ else ();
+ if count == 1
+ then {
+ iR := RSlice("CR",4 * n + 32,4 * n + 35) :: iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ }
+ else oR := RFull(GPRs[RT]) :: oR;
+ }
+ case (Mcrxr (BF)) -> {
+ iR := RSlice("XER",32,35) :: iR;
+ oR := RSlice("CR",4 * BF + 32,4 * BF + 35) :: RSlice("XER",32,35) :: oR;
+ }
+ case (Dlmzb (RS, RA, RB, Rc)) -> ()
+ case (Macchws (RT, RA, RB, OE, Rc)) -> ()
+ case (Macchwu (RT, RA, RB, OE, Rc)) -> ()
+ case (Macchwsu (RT, RA, RB, OE, Rc)) -> ()
+ case (Machhws (RT, RA, RB, OE, Rc)) -> ()
+ case (Machhwu (RT, RA, RB, OE, Rc)) -> ()
+ case (Machhwsu (RT, RA, RB, OE, Rc)) -> ()
+ case (Maclhw (RT, RA, RB, OE, Rc)) -> ()
+ case (Maclhws (RT, RA, RB, OE, Rc)) -> ()
+ case (Maclhwu (RT, RA, RB, OE, Rc)) -> ()
+ case (Maclhwsu (RT, RA, RB, OE, Rc)) -> ()
+ case (Mulchw (RT, RA, RB, Rc)) -> ()
+ case (Mulchwu (RT, RA, RB, Rc)) -> ()
+ case (Mulhhw (RT, RA, RB, Rc)) -> ()
+ case (Mulhhwu (RT, RA, RB, Rc)) -> ()
+ case (Mullhw (RT, RA, RB, Rc)) -> ()
+ case (Mullhwu (RT, RA, RB, Rc)) -> ()
+ case (Nmacchw (RT, RA, RB, OE, Rc)) -> ()
+ case (Nmacchws (RT, RA, RB, OE, Rc)) -> ()
+ case (Nmachhw (RT, RA, RB, OE, Rc)) -> ()
+ case (Nmachhws (RT, RA, RB, OE, Rc)) -> ()
+ case (Nmaclhw (RT, RA, RB, OE, Rc)) -> ()
+ case (Nmaclhws (RT, RA, RB, OE, Rc)) -> ()
+ case (Icbi (RA, RB)) -> ()
+ case (Icbt (CT, RA, RB)) -> ()
+ case (Dcba (RA, RB)) -> ()
+ case (Dcbt (TH, RA, RB)) -> ()
+ case (Dcbtst (TH, RA, RB)) -> ()
+ case (Dcbz (RA, RB)) -> ()
+ case (Dcbst (RA, RB)) -> ()
+ case (Dcbf (L, RA, RB)) -> ()
+ case Isync -> {
+ ik := IK_barrier(Barrier_Isync);
+ }
+ case (Lbarx (RT, RA, RB, EH)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ iR := RFull(GPRs[RB]) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ ik := IK_mem_read(Read_reserve);
+ }
+ case (Lharx (RT, RA, RB, EH)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ iR := RFull(GPRs[RB]) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ ik := IK_mem_read(Read_reserve);
+ }
+ case (Lwarx (RT, RA, RB, EH)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ iR := RFull(GPRs[RB]) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ ik := IK_mem_read(Read_reserve);
+ }
+ case (Stbcx (RS, RA, RB)) -> {
+ ik := IK_mem_write(Write_conditional);
+ }
+ case (Sthcx (RS, RA, RB)) -> {
+ ik := IK_mem_write(Write_conditional);
+ }
+ case (Stwcx (RS, RA, RB)) -> {
+ ik := IK_mem_write(Write_conditional);
+ }
+ case (Ldarx (RT, RA, RB, EH)) -> {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ iR := RFull(GPRs[RB]) :: iR;
+ aR := iR;
+ oR := RFull(GPRs[RT]) :: oR;
+ ik := IK_mem_read(Read_reserve);
+ }
+ case (Stdcx (RS, RA, RB)) -> {
+ ik := IK_mem_write(Write_conditional);
+ }
+ case (Sync (L)) -> {
+ ik := switch L {
+ case 0b00 -> { IK_barrier(Barrier_Sync) }
+ case 0b01 -> { IK_barrier(Barrier_LwSync) }
+ }
+ }
+ case Eieio -> {
+ ik := IK_barrier(Barrier_Eieio)
+ }
+ case (Wait (WC)) -> ()
+ };
+ (iR,oR,aR,Nias,Dia,ik)
+}
+
+val ast -> (regfps,regfps,regfps,niafps,diafp,instruction_kind) effect {rreg} recalculate_lswx_reg_footprint
+(* run when footprint transition is taken, supplying n_top = XER[57 .. 63] as a parameter *)
+function (regfps,regfps,regfps,niafps,diafp,instruction_kind) recalculate_lswx_reg_footprint instr = {
+ (regfps) iR := [|| ||];
+ (regfps) oR := [|| ||];
+ Nias := [|| NIAFP_successor ||];
+ Dia := DIAFP_none;
+ ik := IK_mem_read(Read_plain);
+ let (RT,RA,RB) = switch instr {case (Lswx (RT, RA, RB)) -> (RT,RA,RB)} in {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ ([|31|]) r := 0;
+ iR := RFull(GPRs[RB]) :: RSlice("XER",57,63) :: iR;
+ aR := iR;
+ r := RT - 1;
+ i := 32;
+ ([|128|]) n_top := XER[57 .. 63];
+ if n_top == 0 then
+ oR := RFull(GPRs[RT]) :: oR
+ else {
+ j := 0;
+ n_r := n_top quot 4;
+ n_mod := n_top mod 4;
+ n_r := if n_mod == 0 then n_r else n_r + 1;
+ foreach (n from n_r to 1 by 1 in dec) {
+ r := ([|32|]) (r + 1) mod 32;
+ j := j + 32;
+ oR := RFull(GPRs[r]) :: oR
+ }
+ };
+ (iR,oR,aR,Nias,Dia,ik)}
+}
+
+val ast -> (regfps,regfps,regfps,niafps,diafp,instruction_kind) effect {rreg} recalculate_stswx_reg_footprint
+(* run when footprint transition is taken, supplying n_top = XER[57 .. 63] as a parameter *)
+function (regfps,regfps,regfps,niafps,diafp,instruction_kind) recalculate_stswx_reg_footprint instr = {
+ (regfps) iR := [|| ||];
+ (regfps) oR := [|| ||];
+ Nias := [|| NIAFP_successor ||];
+ Dia := DIAFP_none;
+ ik := IK_mem_write(Write_plain);
+ let (RS,RA,RB) = switch instr {case (Stswx (RS, RA, RB)) -> (RS,RA,RB)} in {
+ if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR;
+ ([|31|]) r := 0;
+ iR := RFull(GPRs[RB]) :: RSlice("XER",57,63) :: iR;
+ aR := iR;
+ r := RS - 1;
+ i := 32;
+ ([|128|]) n_top := XER[57 .. 63];
+ j := 0;
+ foreach (n from n_top to 1 by 1 in dec) {
+ if i == 32 then r := ([|32|]) (r + 1) mod 32;
+ iR := RSlice(GPRs[r],i,i + 7) :: iR;
+ i := i + 8;
+ j := j + 8;
+ if i == 64 then i := 32
+ };
+ ik := IK_mem_write(Write_plain);
+ (iR,oR,aR,Nias,Dia,ik)}
+}