Skip to content

Commit

Permalink
Remove duplicate code (riscv#121)
Browse files Browse the repository at this point in the history
* Remove duplicate code

* Fix unit test
  • Loading branch information
pavelkryukov authored May 23, 2022
1 parent 2415a34 commit 86808b1
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 45 deletions.
50 changes: 14 additions & 36 deletions parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@
pp = pprint.PrettyPrinter(indent=2)
logging.basicConfig(level=logging.INFO, format='%(levelname)s:: %(message)s')

def parse_constant(string):
return int(string, 0)

def process_enc_line(line, ext):
'''
This function processes each line of the encoding files (rv*). As part of
Expand Down Expand Up @@ -61,15 +58,7 @@ def process_enc_line(line, ext):
# check each field for it's length and overlapping bits
# ex: 1..0=5 will result in an error --> x<y
# ex: 5..0=0 2..1=2 --> overlapping bits
temp_instr = ['-'] * 32
entries = [
x[0] for x in re.findall(
r'((\d)+\.\.(\d)+\=((0b\d+)|(0x[0-9a-fA-F]+)|(\d)+))*',
remaining) if x[0] != ''
]
for temp_entry in entries:
entry = temp_entry.split('=')[0]
s2, s1 = entry.split('..')
for (s2, s1, entry) in fixed_ranges.findall(remaining):
msb = int(s2)
lsb = int(s1)

Expand All @@ -80,37 +69,26 @@ def process_enc_line(line, ext):
)
raise SystemExit(1)

for ind in range(lsb, msb):
# overlapping bits
if temp_instr[ind] == 'X':
logging.error(
f'{line.split(" ")[0]:<10} has {ind} bit overlapping in it\'s opcodes'
)
raise SystemExit(1)
temp_instr[ind] = 'X'

# illegal value assigned as per bit width
entry_value = parse_constant(temp_entry.split('=')[1])
entry_value = int(entry, 0)
if entry_value >= (1 << (msb - lsb + 1)):
logging.error(
f'{line.split(" ")[0]:<10} has an illegal value {entry_value} assigned as per the bit width {msb - lsb}'
)
raise SystemExit(1)

# extract bit pattern assignments of the form hi..lo=val. fixed_ranges is a
# regex expression present in constants.py. The extracted patterns are
# captured as a list in args where each entry is a tuple (msb, lsb, value)
args = fixed_ranges.sub(' ', remaining)
for ind in range(lsb, msb + 1):
# overlapping bits
if encoding[31 - ind] != '-':
logging.error(
f'{line.split(" ")[0]:<10} has {ind} bit overlapping in it\'s opcodes'
)
raise SystemExit(1)
bit = str((entry_value >> (ind - lsb)) & 1)
encoding[31 - ind] = bit

# parse through the args and assign constants 1/0 to bits which need to be
# hardcoded for this instruction
for (msb, lsb, value) in fixed_ranges.findall(remaining):
value = int(value, 0)
msb = int(msb, 0)
lsb = int(lsb, 0)
value = f"{value:032b}"
for i in range(0, msb - lsb + 1):
encoding[31 - (i + lsb)] = value[31 - i]
# extract bit pattern assignments of the form hi..lo=val
remaining = fixed_ranges.sub(' ', remaining)

# do the same as above but for <lsb>=<val> pattern. single_fixed is a regex
# expression present in constants.py
Expand All @@ -125,7 +103,7 @@ def process_enc_line(line, ext):

# check if all args of the instruction are present in arg_lut present in
# constants.py
args = single_fixed.sub(' ', args).split()
args = single_fixed.sub(' ', remaining).split()
encoding_args = ['-'] * 32
for a in args:
if a not in arg_lut:
Expand Down
11 changes: 2 additions & 9 deletions test.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,6 @@
import logging
import unittest

class ConstantParseTest(unittest.TestCase):
def test_constant(self):
self.assertEqual(parse_constant('10'), 10)
self.assertEqual(parse_constant('0xa'), 10)
self.assertEqual(parse_constant('0xA'), 10)
self.assertEqual(parse_constant('0b1010'), 10)

class EncodingLineTest(unittest.TestCase):
def setUp(self):
logger = logging.getLogger()
Expand All @@ -20,7 +13,7 @@ def assertError(self, string):
self.assertRaises(SystemExit, process_enc_line, string, 'rv_i')

def test_lui(self):
name, data = process_enc_line('lui rd imm20 6..2=0x0D 1..0=3', 'rv_i')
name, data = process_enc_line('lui rd imm20 6..2=0x0D 1=1 0=1', 'rv_i')
self.assertEqual(name, 'lui')
self.assertEqual(data['extension'], ['rv_i'])
self.assertEqual(data['match'], '0x37')
Expand All @@ -40,4 +33,4 @@ def test_overlapping_field(self):
self.assertError('jol rd rs1 jimm20 6..2=0x1b 1..0=3')

def test_illegal_field(self):
self.assertError('jol rd jimm128 2..0=10')
self.assertError('jol rd jimm128 2..0=3')

0 comments on commit 86808b1

Please sign in to comment.