Skip to content

Commit 6f866e8

Browse files
committed
Generalize decode and encode
This probably needs some rework
1 parent 4c89fae commit 6f866e8

File tree

1 file changed

+15
-92
lines changed

1 file changed

+15
-92
lines changed

riscvmodel/isa.py

Lines changed: 15 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,11 @@ def extract_field(cls, field, machinecode):
5454
return (machinecode >> base) & (2**size - 1)
5555

5656
@classmethod
57-
def set_field(cls, field, machinecode, value):
57+
def set_field(cls, field, word, value):
5858
fname = "field_{}".format(field)
5959
base = getattr(cls, fname).base
6060
size = getattr(cls, fname).size
61-
return machinecode | ((value & (2**size - 1)) << base)
61+
return word | ((value & (2**size - 1)) << base)
6262

6363
@classmethod
6464
def get_fields(cls):
@@ -129,6 +129,19 @@ def encode(self) -> int:
129129
"""
130130
TODO: document
131131
"""
132+
word = 0
133+
for field in self.get_fields():
134+
if field.static:
135+
word = self.set_field(field.name, word, field.value)
136+
else:
137+
value = getattr(self, field.name)
138+
if isinstance(value, Immediate):
139+
word = self.set_field(field.name, word, value.unsigned())
140+
elif isinstance(value, bool):
141+
word = self.set_field(field.name, word, 1 if value else 0)
142+
else:
143+
word = self.set_field(field.name, word, value)
144+
return word
132145

133146
def __str__(self):
134147
"""
@@ -212,16 +225,6 @@ def randomize(self, variant: Variant):
212225
self.rs1 = randrange(0, variant.xlen)
213226
self.rs2 = randrange(0, variant.xlen)
214227

215-
def decode(self, machinecode: int):
216-
self.rd = (machinecode >> 7) & 0x1F
217-
self.rs1 = (machinecode >> 15) & 0x1F
218-
self.rs2 = (machinecode >> 20) & 0x1F
219-
220-
def encode(self) -> int:
221-
word = self.opcode | (self._funct3 << 12) | (self._funct7 << 25)
222-
word |= (self.rd << 7) | (self.rs1 << 15) | (self.rs2 << 20)
223-
return word
224-
225228
def inopstr(self, model):
226229
opstr = "{:>3}={}, ".format("x{}".format(self.rs1),
227230
model.state.intreg[self.rs1])
@@ -285,11 +288,6 @@ def randomize(self, variant: Variant):
285288
self.rs1 = randrange(0, variant.xlen)
286289
self.imm.randomize()
287290

288-
def decode(self, machinecode: int):
289-
self.rd = (machinecode >> 7) & 0x1F
290-
self.rs1 = (machinecode >> 15) & 0x1F
291-
self.imm.set_from_bits((machinecode >> 20) & 0xFFF)
292-
293291
def inopstr(self, model) -> str:
294292
return "{:>3}={} ".format("x{}".format(self.rs1),
295293
model.state.intreg[self.rs1])
@@ -298,11 +296,6 @@ def outopstr(self, model) -> str:
298296
return "{:>3}={} ".format("x{}".format(self.rd),
299297
model.state.intreg[self.rd])
300298

301-
def encode(self) -> int:
302-
code = self.opcode | (self._funct3 << 12)
303-
code |= (self.rd << 7) | (self.rs1 << 15) | (self.imm.unsigned() << 20)
304-
return code
305-
306299
def __str__(self) -> str:
307300
return "{} x{}, x{}, {}".format(self.mnemonic, self.rd, self.rs1,
308301
self.imm)
@@ -358,17 +351,6 @@ def ops_from_string(self, ops):
358351
self.rs1 = int(ops[1][1:])
359352
self.shamt.set(int(ops[2]))
360353

361-
def decode(self, machinecode: int):
362-
self.rd = (machinecode >> 7) & 0x1F
363-
self.rs1 = (machinecode >> 15) & 0x1F
364-
self.shamt.set_from_bits((machinecode >> 20) & 0x1F)
365-
366-
def encode(self) -> int:
367-
code = self.opcode | (self._funct3 << 12) | (self._funct7 << 25)
368-
code |= (self.rd << 7) | (self.rs1 << 15) | (
369-
self.shamt.unsigned() << 20)
370-
return code
371-
372354
def randomize(self, variant: Variant):
373355
self.rd = randrange(0, variant.xlen)
374356
self.rs1 = randrange(0, variant.xlen)
@@ -418,21 +400,6 @@ def randomize(self, variant: Variant):
418400
self.rs2 = randrange(0, variant.xlen)
419401
self.imm.randomize()
420402

421-
def decode(self, machinecode: int):
422-
self.rs1 = (machinecode >> 15) & 0x1F
423-
self.rs2 = (machinecode >> 20) & 0x1F
424-
imm5 = (machinecode >> 7) & 0x1F
425-
imm7 = (machinecode >> 25) & 0x7F
426-
self.imm.set_from_bits((imm7 << 5) | imm5)
427-
428-
def encode(self) -> int:
429-
imm5 = self.imm.unsigned() & 0x1F
430-
imm7 = (self.imm.unsigned() >> 5) & 0x7F
431-
code = self.opcode | (self._funct3 << 12) | (self.rs1 << 15) | (
432-
self.rs2 << 20)
433-
code |= (imm7 << 25) | (imm5 << 7)
434-
return code
435-
436403
def inopstr(self, model):
437404
opstr = "{:>3}={}, ".format("x{}".format(self.rs1),
438405
model.state.intreg[self.rs1])
@@ -492,17 +459,6 @@ def decode(self, machinecode: int):
492459
self.imm.set_from_bits((imm12 << 12) | (imm11 << 11) | (imm5to10 << 5)
493460
| (imm1to4 << 1))
494461

495-
def encode(self) -> int:
496-
imm12 = (self.imm.unsigned() >> 12) & 0x1
497-
imm11 = (self.imm.unsigned() >> 11) & 0x1
498-
imm1to4 = (self.imm.unsigned() >> 1) & 0xF
499-
imm5to10 = (self.imm.unsigned() >> 5) & 0x3F
500-
code = self.opcode | (self._funct3 << 12) | (self.rs1 << 15) | (
501-
self.rs2 << 20)
502-
code |= (imm12 << 31) | (imm5to10 << 25) | (imm1to4 << 8) | (
503-
imm11 << 7)
504-
return code
505-
506462
def inopstr(self, model):
507463
opstr = "{:>3}={}, ".format("x{}".format(self.rs1),
508464
model.state.intreg[self.rs1])
@@ -543,13 +499,6 @@ def randomize(self, variant: Variant):
543499
self.rd = randrange(0, variant.xlen)
544500
self.imm.randomize()
545501

546-
def decode(self, machinecode: int):
547-
self.rd = (machinecode >> 7) & 0x1F
548-
self.imm.set_from_bits((machinecode >> 12) & 0xFFFFF)
549-
550-
def encode(self):
551-
return self.opcode | (self.rd << 7) | (self.imm.unsigned() << 12)
552-
553502
def outopstr(self, model):
554503
return "{:>3}={} ".format("x{}".format(self.rd),
555504
model.state.intreg[self.rd])
@@ -583,25 +532,6 @@ def randomize(self, variant: Variant):
583532
self.rd = randrange(0, variant.xlen)
584533
self.imm.randomize()
585534

586-
def decode(self, machinecode: int):
587-
self.rd = (machinecode >> 7) & 0x1F
588-
imm12to19 = (machinecode >> 12) & 0xFF
589-
imm11 = (machinecode >> 20) & 0x1
590-
imm1to10 = (machinecode >> 21) & 0x3FF
591-
imm20 = (machinecode >> 31) & 0x1
592-
self.imm.set_from_bits((imm20 << 20) | (imm12to19 << 12)
593-
| (imm11 << 11) | (imm1to10 << 1))
594-
595-
def encode(self):
596-
imm20 = (self.imm.unsigned() >> 20) & 0x1
597-
imm12to19 = (self.imm.unsigned() >> 12) & 0xFF
598-
imm11 = (self.imm.unsigned() >> 11) & 0x1
599-
imm1to10 = (self.imm.unsigned() >> 1) & 0x3FF
600-
code = self.opcode | (self.rd << 7)
601-
code |= (imm20 << 31) | (imm1to10 << 21) | (imm11 << 20) | (
602-
imm12to19 << 12)
603-
return code
604-
605535
def outopstr(self, model):
606536
return "{:>3}={} ".format("x{}".format(self.rd),
607537
model.state.intreg[self.rd])
@@ -654,13 +584,6 @@ def __init__(self, rd: int = None, rs: int = None):
654584
self.rd = rd # pylint: disable=invalid-name
655585
self.rs = rs # pylint: disable=invalid-name
656586

657-
def decode(self, machinecode: int):
658-
self.rd = (machinecode >> 7) & 0x1F
659-
self.rs = (machinecode >> 2) & 0x1F
660-
661-
def encode(self):
662-
pass
663-
664587
def randomize(self, variant: Variant):
665588
self.rd = randrange(8, 16)
666589
self.rs = randrange(8, 16)

0 commit comments

Comments
 (0)