identify [0]*16 pattern and produce repeat-of-int
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 4 Apr 2020 12:44:04 +0000 (13:44 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 4 Apr 2020 12:44:04 +0000 (13:44 +0100)
libreriscv
src/soc/decoder/power_pseudo.py
src/soc/decoder/pseudo/parser.py
src/soc/decoder/selectable_int.py

index 6c7c31673fad55da82c22fbbcac3f9b5c49e6cc7..36ca948926f4c13b6e121948606a4d1aed8394f6 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 6c7c31673fad55da82c22fbbcac3f9b5c49e6cc7
+Subproject commit 36ca948926f4c13b6e121948606a4d1aed8394f6
index cab7321fbd1c6f99f3af55c17ff40a876044ccf9..d66d3f2b7fc99ef9337b207da20fe53dae8b71fb 100644 (file)
@@ -96,8 +96,14 @@ addpcis = """
 D <- d0||d1||d2
 """
 
+testmul = """
+x <- [0] * 16
+RT <- (RA) + EXTS(SI || [0]*16)
+"""
+
+code = testmul
 #code = testreg
-code = cnttzd
+#code = cnttzd
 #code = cmpi
 #code = cmpeqb
 #code = addpcis
index 6c7ea8f6a7981095b2af6a9d42d2b32721f3d82a..6c67265b9c51478bd7aaae7ceb17ffea32612e82 100644 (file)
@@ -133,9 +133,24 @@ def check_concat(node):  # checks if the comparison is already a concat
     print("func", node.func.id)
     if node.func.id != 'concat':
         return [node]
+    if node.keywords: # a repeated list-constant, don't optimise
+        return [node]
     return node.args
 
 
+# identify SelectableInt pattern
+def identify_sint_mul_pattern(p):
+    if not isinstance(p[3], ast.Constant):
+        return False
+    if not isinstance(p[1], ast.List):
+        return False
+    l = p[1].elts
+    if len(l) != 1:
+        return False
+    elt = l[0]
+    return isinstance(elt, ast.Constant)
+
+
 ##########   Parser (tokens -> AST) ######
 
 # also part of Ply
@@ -401,6 +416,10 @@ class PowerParser:
                 p[0] = ast.Call(ast.Name("concat"), l, [])
             elif p[2] in ['<', '>', '=', '<=', '>=']:
                 p[0] = binary_ops[p[2]]((p[1], p[3]))
+            elif identify_sint_mul_pattern(p):
+                keywords=[ast.keyword(arg='repeat', value=p[3])]
+                l = p[1].elts
+                p[0] = ast.Call(ast.Name("concat"), l, keywords)
             else:
                 p[0] = ast.BinOp(p[1], binary_ops[p[2]], p[3])
         elif len(p) == 3:
index 8b5715bbf21692186a08dab39ca667c5e9114e1e..b8998b89a7c32059fdb44436b24ecfe79c8ebfb5 100644 (file)
@@ -179,12 +179,20 @@ def selectassign(lhs, idx, rhs):
         lhs[t] = rhs[f]
 
 
-def selectconcat(*args):
+def selectconcat(*args, repeat=1):
+    if repeat != 1 and len(args) == 1 and isinstance(args[0], int):
+        args = [SelectableInt(args[0], 1)]
+    if repeat != 1: # multiplies the incoming arguments
+        tmp = []
+        for i in range(repeat):
+            tmp += args
+        args = tmp
     res = copy(args[0])
     for i in args[1:]:
         assert isinstance(i, SelectableInt), "can only concat SIs, sorry"
         res.bits += i.bits
         res.value = (res.value << i.bits) | i.value
+    print ("concat", repeat, res)
     return res