From: Luke Kenneth Casson Leighton Date: Fri, 3 Apr 2020 14:20:30 +0000 (+0100) Subject: add less-than, greater-than, signed, and le/ge X-Git-Tag: div_pipeline~1557 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7719f0a001bf74a78d541fd04fb3ca9752f1851c;p=soc.git add less-than, greater-than, signed, and le/ge --- diff --git a/src/soc/decoder/power_pseudo.py b/src/soc/decoder/power_pseudo.py index e5d1a969..78add9ef 100644 --- a/src/soc/decoder/power_pseudo.py +++ b/src/soc/decoder/power_pseudo.py @@ -70,7 +70,7 @@ else if a > EXTS(SI) then """ cmpi = """ -CR[0:1] <- c +RA[0:1] <- 0b11 """ @@ -194,6 +194,10 @@ def test(): yield Delay(1e-6) # read regs, drop them into dict for function + for rname in gsc.parser.uninit_regs: + d[rname] = SelectableInt(0, 64) # uninitialised (to zero) + print ("uninitialised", rname, get_reg_hex(d[rname])) + for rname in gsc.parser.read_regs: regidx = yield getattr(decode.sigforms['X'], rname) d[rname] = gsc.gpr[regidx] diff --git a/src/soc/decoder/pseudo/lexer.py b/src/soc/decoder/pseudo/lexer.py index ba517c4f..992ab7b6 100644 --- a/src/soc/decoder/pseudo/lexer.py +++ b/src/soc/decoder/pseudo/lexer.py @@ -241,6 +241,10 @@ class PowerLexer: 'COLON', 'EQ', 'ASSIGN', + 'LTU', + 'GTU', + 'LE', + 'GE', 'LT', 'GT', 'PLUS', @@ -283,6 +287,10 @@ class PowerLexer: t_COLON = r':' t_EQ = r'=' t_ASSIGN = r'<-' + t_LTU = r'u' + t_LE = r'<=' + t_GE = r'>=' t_LT = r'<' t_GT = r'>' t_PLUS = r'\+' diff --git a/src/soc/decoder/pseudo/parser.py b/src/soc/decoder/pseudo/parser.py index 3d487aaf..8ce1b8c2 100644 --- a/src/soc/decoder/pseudo/parser.py +++ b/src/soc/decoder/pseudo/parser.py @@ -41,6 +41,18 @@ def Assign(left, right): return ast.Assign([ast.AssTuple(ass_list)], right) elif isinstance(left, ast.Subscript): return ast.Assign([left], right) + # XXX HMMM probably not needed... + ls = left.slice + if isinstance(ls, ast.Slice): + lower, upper, step = ls.lower, ls.upper, ls.step + print ("slice assign", lower, upper, step) + if step is None: + ls = (lower, upper, None) + else: + ls = (lower, upper, step) + ls = ast.Tuple(ls) + return ast.Call(ast.Name("selectassign"), + [left.value, ls, right], []) else: print ("Assign fail") raise SyntaxError("Can't do that yet") @@ -66,6 +78,12 @@ def Assign(left, right): # factor: ('+'|'-'|'~') factor | power # comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' +def make_le_compare(arg): + (left, right) = arg + return ast.Compare(left, [ast.Le()], [right]) +def make_ge_compare(arg): + (left, right) = arg + return ast.Compare(left, [ast.Ge()], [right]) def make_lt_compare(arg): (left, right) = arg return ast.Compare(left, [ast.Lt()], [right]) @@ -81,6 +99,8 @@ binary_ops = { "-": ast.Sub(), "*": ast.Mult(), "/": ast.Div(), + "<=": make_le_compare, + ">=": make_ge_compare, "<": make_lt_compare, ">": make_gt_compare, "=": make_eq_compare, @@ -108,7 +128,7 @@ def check_concat(node): # checks if the comparison is already a concat class PowerParser: precedence = ( - ("left", "EQ", "GT", "LT"), + ("left", "EQ", "GT", "LT", "LE", "GE", "LTU", "GTU"), ("left", "PLUS", "MINUS"), ("left", "MULT", "DIV"), ) @@ -118,6 +138,7 @@ class PowerParser: for rname in ['RA', 'RB', 'RC', 'RT', 'RS']: self.gprs[rname] = None self.read_regs = [] + self.uninit_regs = [] self.write_regs = [] # The grammar comments come from Python's Grammar/Grammar file @@ -227,6 +248,8 @@ class PowerParser: name = p[1].id elif isinstance(p[1], ast.Subscript): name = p[1].value.id + if name in self.gprs: + self.uninit_regs.append(name) # add to list of uninitialised print ("expr assign", name, p[1]) if name in self.gprs: self.write_regs.append(name) # add to list of regs to write @@ -308,8 +331,12 @@ class PowerParser: | comparison MINUS comparison | comparison MULT comparison | comparison DIV comparison - | comparison LT comparison | comparison EQ comparison + | comparison LE comparison + | comparison GE comparison + | comparison LTU comparison + | comparison GTU comparison + | comparison LT comparison | comparison GT comparison | PLUS comparison | MINUS comparison @@ -317,7 +344,11 @@ class PowerParser: | power""" if len(p) == 4: print (list(p)) - if p[2] == '||': + if p[2] == 'u': + p[0] = ast.Call(ast.Name("gtu"), (p[1], p[3]), []) + elif p[2] == '||': l = check_concat(p[1]) + check_concat(p[3]) p[0] = ast.Call(ast.Name("concat"), l, []) elif p[2] in ['<', '>', '=']: diff --git a/src/soc/decoder/selectable_int.py b/src/soc/decoder/selectable_int.py index 4ca2de36..5a188330 100644 --- a/src/soc/decoder/selectable_int.py +++ b/src/soc/decoder/selectable_int.py @@ -89,9 +89,42 @@ class SelectableInt: value = value << start self.value = (self.value & ~mask) | (value & mask) + def __ge__(self, other): + if isinstance(other, SelectableInt): + assert other.bits == self.bits + other = other.value + if isinstance(other, int): + return other >= self.value + assert False + + def __le__(self, other): + if isinstance(other, SelectableInt): + assert other.bits == self.bits + other = other.value + if isinstance(other, int): + return other <= self.value + assert False + + def __gt__(self, other): + if isinstance(other, SelectableInt): + assert other.bits == self.bits + other = other.value + if isinstance(other, int): + return other > self.value + assert False + + def __lt__(self, other): + if isinstance(other, SelectableInt): + assert other.bits == self.bits + other = other.value + if isinstance(other, int): + return other < self.value + assert False + def __eq__(self, other): if isinstance(other, SelectableInt): - return other.value == self.value and other.bits == self.bits + assert other.bits == self.bits + other = other.value if isinstance(other, int): return other == self.value assert False @@ -100,6 +133,21 @@ class SelectableInt: return "SelectableInt(value={:x}, bits={})".format(self.value, self.bits) +def selectltu(lhs, rhs): + """ less-than (unsigned) + """ + if isinstance(rhs, SelectableInt): + rhs = rhs.value + return lhs.value < rhs + +def selectgtu(lhs, rhs): + """ greater-than (unsigned) + """ + if isinstance(rhs, SelectableInt): + rhs = rhs.value + return lhs.value > rhs + + # XXX this probably isn't needed... def selectassign(lhs, idx, rhs): if isinstance(idx, tuple): @@ -153,7 +201,6 @@ class SelectableIntTestCase(unittest.TestCase): self.assertEqual(d.value, a.value | b.value) self.assertEqual(e.value, a.value ^ b.value) self.assertEqual(f.value, 0xF0) - def test_get(self): a = SelectableInt(0xa2, 8)