had to add fixed_width parameter temporarily to confirm that the
[ieee754fpu.git] / src / ieee754 / part / partsig.py
index 3ba38a586ee572a67994c101757b83b839e7ec46..61b64e661e4ff1a3e3b2d8e3896c18be923947eb 100644 (file)
@@ -81,6 +81,7 @@ class PartType:  # TODO decide name
     def blanklanes(self):
         return 0
 
+
 # this one would be an elwidth version
 # see https://bugs.libre-soc.org/show_bug.cgi?id=713#c34
 # it requires an "adapter" which is the layout() function
@@ -88,43 +89,54 @@ class PartType:  # TODO decide name
 # function and this class then "understands" the relationship
 # between elwidth and the PartitionPoints that were created
 # by layout()
-class ElWidthPartType:  # TODO decide name
+class ElwidPartType:  # TODO decide name
     def __init__(self, psig):
         self.psig = psig
 
     def get_mask(self):
-        ppoints = self.psig.scope.partpoints
-        return ppoints.values()  # i think
+        return list(self.psig._shape.partpoints.values())  # i think
 
     def get_switch(self):
-        return self.psig.elwidth
+        return self.psig.scope.elwid       # switch on elwid: match get_cases()
 
     def get_cases(self):
-        pbits = self.psig.scope.bitp
-        return pbits
+        return self.psig._shape.bitp.keys() # all possible values of elwid
 
     @property
     def blanklanes(self):
-        return 0  # TODO
+        return self.psig.shape.blankmask
 
 
 class SimdShape(Shape):
     """a SIMD variant of Shape. supports:
-        * fixed overall width with variable (maxed-out) element lengths
-        * fixed element widths with overall size auto-determined
-        * both fixed overall width and fixed element widths
+    * fixed overall width with variable (maxed-out) element lengths
+    * fixed element widths with overall size auto-determined
+    * both fixed overall width and fixed element widths
+
+    naming is preserved to be compatible with Shape().
     """
-    def __init__(self, scope, width=None, signed=False, widths_at_elwid=None):
+    def __init__(self, scope, width=None, # this is actually widths_at_elwid
+                              signed=False,
+                              fixed_width=None): # fixed overall width
+        widths_at_elwid = width
+        print ("SimdShape width", width, "fixed_width", fixed_width)
         # this check is done inside layout but do it again here anyway
-        assert width == None and widths_at_elwidth == None, \
-            "both width and widths_at_elwidth cannot be None"
+        assert fixed_width != None or widths_at_elwid != None, \
+            "both width (widths_at_elwid) and fixed_width cannot be None"
         (pp, bitp, lpoints, bmask, fixed_width, lane_shapes, part_wid) = \
-            layout(scope.elwid, scope.vec_el_counts, widths_at_elwid, width)
+            layout(scope.elwid,
+                   scope.vec_el_counts,
+                   widths_at_elwid,
+                   fixed_width)
         self.partpoints = pp
-        self.bitp = bitp       # binary values for partpoints at each elwidth
-        self.lpoints = lpoints # layout ranges
-        self.blankmask = bmask # blanking mask (partitions always padding)
-        self.partwid = partwid # smallest alignment start point for elements
+        self.bitp = bitp        # binary values for partpoints at each elwidth
+        self.lpoints = lpoints  # layout ranges
+        self.blankmask = bmask  # blanking mask (partitions always padding)
+        self.partwid = part_wid # smallest alignment start point for elements
+
+        # pass through the calculated width to Shape() so that when/if
+        # objects using this Shape are downcast, they know exactly how to
+        # get *all* bits and need know absolutely nothing about SIMD at all
         Shape.__init__(self, fixed_width, signed)
 
 
@@ -132,17 +144,24 @@ class SimdSignal(UserValue):
     # XXX ################################################### XXX
     # XXX Keep these functions in the same order as ast.Value XXX
     # XXX ################################################### XXX
-    def __init__(self, mask, *args, src_loc_at=0, **kwargs):
+    def __init__(self, mask, shape=None, *args,
+                       src_loc_at=0, fixed_width=None, **kwargs):
         super().__init__(src_loc_at=src_loc_at)
-        self.sig = Signal(*args, **kwargs)
-        width = len(self.sig)  # get signal width
+        print ("SimdSignal shape", shape)
         # create partition points
-        if False: # isinstance(mask, SimdScope): # mask parameter is a SimdScope
-            self.ptype = ElwidPartType(self, scope=mask)
-            # parse the args, get elwid from SimdMode,
-            # get module as well, call self.set_module(mask.module)
-            self.partpoints = ptype.partpoints
+        if isinstance(mask, SimdScope): # mask parameter is a SimdScope
+            self.scope = mask
+            self.ptype = ElwidPartType(self)
+            # adapt shape to a SimdShape
+            if not isinstance(shape, SimdShape):
+                shape = SimdShape(self.scope, shape, fixed_width=fixed_width)
+            self._shape = shape
+            self.sig = Signal(shape, *args, **kwargs)
+            # get partpoints from SimdShape
+            self.partpoints = shape.partpoints
         else:
+            self.sig = Signal(shape, *args, **kwargs)
+            width = len(self.sig)  # get signal width
             if isinstance(mask, PartitionPoints):
                 self.partpoints = mask
             else: