SVM-Form
 
-* svstate SVxd, SVyd, SVzd, SVRM
+* svremap SVxd, SVyd, SVzd, SVRM
 
 Pseudo-code:
 
     SVSHAPE1[0:31] <- [0] * 32
     SVSHAPE2[0:31] <- [0] * 32
     SVSHAPE3[0:31] <- [0] * 32
-    # set up FRT and FRB
+    # set up template in SVSHAPE0, then copy to 1-3
     SVSHAPE0[0:5] <- (0b0 || SVxd)   # xdim
-    SVSHAPE3[0:5] <- (0b0 || SVxd)   # xdim
+    SVSHAPE0[6:11] <- (0b0 || SVyd)   # ydim
+    SVSHAPE0[12:17] <- (0b0 || SVzd)   # zdim
+    SVSHAPE0[28:29] <- 0b11           # skip z
+    # copy
+    SVSHAPE1[0:31] <- SVSHAPE0[0:31]
+    SVSHAPE2[0:31] <- SVSHAPE0[0:31]
+    SVSHAPE3[0:31] <- SVSHAPE0[0:31]
     # set up FRA
-    SVSHAPE0[0:5] <- (0b0 || SVxd)   # xdim
-    SVSHAPE0[6:11] <- (0b0 || SVyd)  # ydim
-    SVSHAPE0[18:20] <- 0b010          # permute y,x,z
+    SVSHAPE1[18:20] <- 0b001          # permute x,z,y
+    SVSHAPE1[28:29] <- 0b01           # skip z
+    # FRC
+    SVSHAPE2[18:20] <- 0b001          # permute x,z,y
+    SVSHAPE2[28:29] <- 0b11           # skip y
 
 Special Registers Altered:
 
 
     SVyd (11:15)
          Simple-V "REMAP" y-dimension size
          Formats: SVM
+    SVzd (16:20)
+         Simple-V "REMAP" z-dimension size
+         Formats: SVM
     SX,S (28,6:10)
          Fields SX and S are concatenated to specify a
          VSR to be used as a source.
 
     "TAR": 0,
     "MSR": 0,
     "SVSTATE": 0,
+    "SVSHAPE0": 0,
+    "SVSHAPE1": 0,
+    "SVSHAPE2": 0,
+    "SVSHAPE3": 0,
 
     "CA": 0,
     "CA32": 0,
         self.gpr = GPR(decoder2, self, self.svstate, regfile)
         self.fpr = GPR(decoder2, self, self.svstate, fpregfile)
         self.spr = SPR(decoder2, initial_sprs) # initialise SPRs before MMU
+        for i in range(4):
+            sname = 'SVSHAPE%d' % i
+            if sname not in self.spr:
+                self.spr[sname] = SVSHAPE(0)
+
         # "raw" memory
         self.mem = Mem(row_bytes=8, initial_mem=initial_mem)
         self.imem = Mem(row_bytes=4, initial_mem=initial_insns)
                                'NIA': self.pc.NIA,
                                'CIA': self.pc.CIA,
                                'SVSTATE': self.svstate.spr,
+                               'SVSHAPE0': self.spr['SVSHAPE0'],
+                               'SVSHAPE1': self.spr['SVSHAPE1'],
+                               'SVSHAPE2': self.spr['SVSHAPE2'],
+                               'SVSHAPE3': self.spr['SVSHAPE3'],
                                'CR': self.cr,
                                'MSR': self.msr,
                                'undefined': undefined,
             illegal = False
             name = 'setvl'
 
+        # and svremap not being supported by binutils (.long)
+        if asmop.startswith('svremap'):
+            illegal = False
+            name = 'svremap'
+
         # sigh also deal with ffmadds not being supported by binutils (.long)
         if asmop == 'ffmadds':
             illegal = False
 
--- /dev/null
+from nmigen import Module, Signal
+from nmigen.back.pysim import Simulator, Delay, Settle
+from nmutil.formaltest import FHDLTestCase
+import unittest
+from openpower.decoder.isa.caller import ISACaller
+from openpower.decoder.power_decoder import (create_pdecode)
+from openpower.decoder.power_decoder2 import (PowerDecode2)
+from openpower.simulator.program import Program
+from openpower.decoder.isa.caller import ISACaller, SVP64State
+from openpower.decoder.selectable_int import SelectableInt
+from openpower.decoder.orderedset import OrderedSet
+from openpower.decoder.isa.all import ISA
+from openpower.decoder.isa.test_caller import Register, run_tst
+from openpower.sv.trans.svp64 import SVP64Asm
+from openpower.consts import SVP64CROffs
+from copy import deepcopy
+from openpower.decoder.helpers import fp64toselectable
+from openpower.decoder.isafunctions.double2single import DOUBLE2SINGLE
+
+class DecoderTestCase(FHDLTestCase):
+
+    def _check_regs(self, sim, expected):
+        for i in range(32):
+            self.assertEqual(sim.gpr(i), SelectableInt(expected[i], 64))
+
+    def test_sv_remap(self):
+        """>>> lst = ["svremap 2, 2, 3, 0"
+                        ]
+        """
+        lst = SVP64Asm(["svremap 2, 2, 3, 0"
+                        ])
+        lst = list(lst)
+
+        fprs = [0] * 32
+        if False:
+            av = [7.0, -9.8, 2.0, -32.3] # first half of array 0..3
+            bv = [-2.0, 2.0, -9.8, 32.3] # second half of array 4..7
+            coe = [-1.0, 4.0, 3.1, 6.2]  # coefficients
+            res = []
+            # work out the results with the twin mul/add-sub
+            for i, (a, b, c) in enumerate(zip(av, bv, coe)):
+                fprs[i+2] = fp64toselectable(a)
+                fprs[i+6] = fp64toselectable(b)
+                fprs[i+10] = fp64toselectable(c)
+                mul = a * c
+                t = a + mul
+                u = b - mul
+                t = DOUBLE2SINGLE(fp64toselectable(t)) # convert to Power single
+                u = DOUBLE2SINGLE(fp64toselectable(u)) # from double
+                res.append((t, u))
+                print ("FFT", i, "in", a, b, "coeff", c, "mul",
+                       mul, "res", t, u)
+
+        # SVSTATE (in this case, VL=12, to cover all of matrix)
+        svstate = SVP64State()
+        svstate.vl[0:7] = 12 # VL
+        svstate.maxvl[0:7] = 12 # MAXVL
+        print ("SVSTATE", bin(svstate.spr.asint()))
+
+        with Program(lst, bigendian=False) as program:
+            sim = self.run_tst_program(program, svstate=svstate,
+                                       initial_fprs=fprs)
+            print ("spr svshape0", sim.spr['SVSHAPE0'])
+            print ("spr svshape1", sim.spr['SVSHAPE1'])
+            print ("spr svshape2", sim.spr['SVSHAPE2'])
+            print ("spr svshape3", sim.spr['SVSHAPE3'])
+            # confirm that the results are as expected
+            #for i, (t, u) in enumerate(res):
+            #    self.assertEqual(sim.fpr(i+2), t)
+            #    self.assertEqual(sim.fpr(i+6), u)
+
+    def run_tst_program(self, prog, initial_regs=None,
+                              svstate=None,
+                              initial_mem=None,
+                              initial_fprs=None):
+        if initial_regs is None:
+            initial_regs = [0] * 32
+        simulator = run_tst(prog, initial_regs, mem=initial_mem,
+                                                initial_fprs=initial_fprs,
+                                                svstate=svstate)
+
+        print ("GPRs")
+        simulator.gpr.dump()
+        print ("FPRs")
+        simulator.fpr.dump()
+
+        return simulator
+
+
+if __name__ == "__main__":
+    unittest.main()
 
     this saves drastically on the size of the regfile
     """
     short_list = {'PIDR', 'DAR', 'PRTBL', 'DSISR', 'SVSRR0', 'SVSTATE',
+                  'SVSTATE0', 'SVSTATE1', 'SVSTATE2', 'SVSTATE3',
                   'SPRG0_priv', 'SPRG1_priv', 'SPRG2_priv', 'SPRG3_priv',
                   'SPRG3'
                  }
 
         if self.include_ca_in_write:
             if name in ['CA', 'CA32']:
                 self.write_regs.add(name)
-        if name in ['CR', 'LR', 'CTR', 'TAR', 'FPSCR', 'MSR', 'SVSTATE']:
+        if name in ['CR', 'LR', 'CTR', 'TAR', 'FPSCR', 'MSR',
+                     'SVSTATE', 'SVSHAPE0', 'SVSHAPE1', 'SVSHAPE2', 'SVSHAPE3']:
             self.special_regs.add(name)
             self.write_regs.add(name)  # and add to list to write
         p[0] = ast.Name(id=name, ctx=ast.Load())
 
             yield ".long 0x%x" % insn
             return
 
+        # and svremap
+        if opcode == 'svremap':
+            insn = 22 << (31-5)          # opcode 22, bits 0-5
+            fields = list(map(int, fields))
+            insn |= fields[0] << (31-10) # SVxd       , bits 6-10
+            insn |= fields[1] << (31-15) # SVyd       , bits 11-15
+            insn |= fields[2] << (31-16) # SVzd       , bits 16-20
+            insn |= fields[3] << (31-21) # SVRM       , bits 21-25
+            insn |= 0b00001   << (31-30) # XO       , bits 26..30
+            log ("svremap", bin(insn))
+            yield ".long 0x%x" % insn
+            return
+
         # identify if is a svp64 mnemonic
         if not opcode.startswith('sv.'):
             yield insn  # unaltered
     for line in lines:
         ls = line.split("#")
         # identify macros
-        if ls[0].strip().startswith("setvl"):
+        op = ls[0].strip()
+        if op.startswith("setvl") or op.startswith("svremap"):
             ws, line = get_ws(ls[0])
             lst = list(isa.translate_one(ls[0].strip(), macros))
             lst = '; '.join(lst)
              #'sv.lhzbr 5.v, 11(9.v), 15',
              #'sv.lwzbr 5.v, 11(9.v), 15',
              'sv.ffmadds 6.v, 2.v, 4.v, 6.v',
+             'svremap 2, 2, 3, 0',
     ]
     isa = SVP64Asm(lst, macros=macros)
     print ("list", list(isa))