1515from .types import Immediate , Register
1616from .variant import RV32I
1717
18- Field = namedtuple ("Field" , ["name" , "base" , "size" , "description" , "static" , "value" ])
19- Field .__new__ .__defaults__ = (None , None , None , None , False , None )
18+ Field = namedtuple ("Field" , ["name" , "base" , "size" , "offset" , " description" , "static" , "value" ])
19+ Field .__new__ .__defaults__ = (None , None , None , 0 , None , False , None )
2020
2121class Instruction (metaclass = ABCMeta ):
2222 """
@@ -58,7 +58,14 @@ 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 word | ((value & (2 ** size - 1 )) << base )
61+ if not isinstance (base , list ):
62+ base = [base ]
63+ size = [size ]
64+ off = 0
65+ for part in range (len (base )):
66+ word |= (((value >> off ) & (2 ** size [part ] - 1 )) << base [part ])
67+ off += size [part ]
68+ return word
6269
6370 @classmethod
6471 def get_fields (cls ):
@@ -131,7 +138,7 @@ def encode(self) -> int:
131138 """
132139 word = 0
133140 for field in self .get_fields ():
134- if field .static :
141+ if field .value is not None :
135142 word = self .set_field (field .name , word , field .value )
136143 else :
137144 value = getattr (self , field .name )
@@ -207,8 +214,8 @@ class InstructionRType(InstructionFunct3Type, InstructionFunct7Type, metaclass=A
207214 asm_arg_signature = "<rd>, <rs1>, <rs2>"
208215
209216 field_rd = Field (name = "rd" , base = 7 , size = 5 , description = "" )
210- field_rs1 = Field (name = "rd " , base = 15 , size = 5 , description = "" )
211- field_rs2 = Field (name = "rd " , base = 20 , size = 5 , description = "" )
217+ field_rs1 = Field (name = "rs1 " , base = 15 , size = 5 , description = "" )
218+ field_rs2 = Field (name = "rs2 " , base = 20 , size = 5 , description = "" )
212219
213220 def __init__ (self , rd : int = None , rs1 : int = None , rs2 : int = None ):
214221 super (InstructionRType , self ).__init__ ()
@@ -217,8 +224,8 @@ def __init__(self, rd: int = None, rs1: int = None, rs2: int = None):
217224 self .rs1 = rs1
218225 self .rs2 = rs2
219226
220- def ops_from_string (self , ops ):
221- (self .rd , self .rs1 , self .rs2 ) = [int (op [1 :]) for op in ops . split ( "," ) ]
227+ def ops_from_list (self , ops ):
228+ (self .rd , self .rs1 , self .rs2 ) = [int (op [1 :]) for op in ops ]
222229
223230 def randomize (self , variant : Variant ):
224231 self .rd = randrange (0 , variant .xlen )
@@ -268,7 +275,7 @@ class InstructionIType(InstructionFunct3Type, metaclass=ABCMeta):
268275
269276 field_rd = Field (name = "rd" , base = 7 , size = 5 , description = "" )
270277 field_rs1 = Field (name = "rs1" , base = 15 , size = 5 , description = "" )
271- field_imm = Field (name = "imm" , base = 20 , size = 5 , description = "" )
278+ field_imm = Field (name = "imm" , base = 20 , size = 12 , description = "" )
272279
273280 def __init__ (self , rd : int = None , rs1 : int = None , imm : int = None ):
274281 super (InstructionIType , self ).__init__ ()
@@ -279,9 +286,15 @@ def __init__(self, rd: int = None, rs1: int = None, imm: int = None):
279286 self .imm .set (imm )
280287
281288 def ops_from_list (self , ops ):
289+ if len (ops ) == 0 : # ecall
290+ return
282291 self .rd = int (ops [0 ][1 :])
283- self .rs1 = int (ops [1 ][1 :])
284- self .imm .set (int (ops [2 ]))
292+ if ops [1 ][0 ] == "x" :
293+ self .rs1 = int (ops [1 ][1 :])
294+ self .imm .set (int (ops [2 ], 0 ))
295+ else : # Load
296+ self .rs1 = int (ops [2 ][1 :])
297+ self .imm .set (int (ops [1 ], 0 ))
285298
286299 def randomize (self , variant : Variant ):
287300 self .rd = randrange (0 , variant .xlen )
@@ -300,12 +313,6 @@ def __str__(self) -> str:
300313 return "{} x{}, x{}, {}" .format (self .mnemonic , self .rd , self .rs1 ,
301314 self .imm )
302315
303- def __eq__ (self , other ) -> bool :
304- if not super ().__eq__ (other ):
305- return False
306- return self .rd == other .rd and self .rs1 == other .rs1 and self .imm == other .imm
307-
308-
309316class InstructionILType (InstructionIType , metaclass = ABCMeta ):
310317 """
311318 I-type instruction specialization for stores. The produce a different
@@ -335,21 +342,24 @@ class InstructionISType(InstructionFunct3Type,InstructionFunct7Type, metaclass=A
335342 :type imm: int
336343 """
337344
345+ isa_format_id = "IS"
346+
338347 field_rd = Field (name = "rd" , base = 7 , size = 5 , description = "" )
339348 field_rs1 = Field (name = "rs1" , base = 15 , size = 5 , description = "" )
340349 field_shamt = Field (name = "shamt" , base = 20 , size = 5 , description = "" )
341350
351+ asm_arg_signature = "<rd>, <rs1>, <shamt>"
352+
342353 def __init__ (self , rd : int = None , rs1 : int = None , shamt : int = None ):
343354 super (InstructionISType , self ).__init__ ()
344355 self .rd = rd
345356 self .rs1 = rs1
346357 self .shamt = Immediate (bits = 5 , init = shamt )
347358
348- def ops_from_string (self , ops ):
349- ops = ops .split ("," )
359+ def ops_from_list (self , ops ):
350360 self .rd = int (ops [0 ][1 :])
351361 self .rs1 = int (ops [1 ][1 :])
352- self .shamt .set (int (ops [2 ]))
362+ self .shamt .set (int (ops [2 ], 0 ))
353363
354364 def randomize (self , variant : Variant ):
355365 self .rd = randrange (0 , variant .xlen )
@@ -383,17 +393,25 @@ class InstructionSType(InstructionFunct3Type, metaclass=ABCMeta):
383393 :param imm: Offset of store, for calculation of address relative to rs1
384394 :type imm: int
385395 """
396+
397+ isa_format_id = "S"
398+
399+ field_rs1 = Field (name = "rs1" , base = 15 , size = 5 , description = "" )
400+ field_rs2 = Field (name = "rs2" , base = 20 , size = 5 , description = "" )
401+ field_imm = Field (name = "imm" , base = [7 , 25 ], size = [5 , 7 ], description = "" )
402+
403+ asm_arg_signature = "<rs2>, <imm>(<rs1>)"
404+
386405 def __init__ (self , rs1 : int = None , rs2 : int = None , imm : int = None ):
387406 super (InstructionSType , self ).__init__ ()
388407 self .rs1 = rs1
389408 self .rs2 = rs2
390409 self .imm = Immediate (bits = 12 , signed = True , init = imm )
391410
392- def ops_from_string (self , ops ):
393- ops = ops .split ("," )
394- self .rs1 = int (ops [0 ][1 :])
395- self .rs2 = int (ops [1 ][ops [1 ].find ("(" ) + 2 :- 1 ])
396- self .imm .set (int (ops [1 ][0 :ops [1 ].find ("(" )]))
411+ def ops_from_list (self , ops ):
412+ self .rs1 = int (ops [2 ][1 :])
413+ self .rs2 = int (ops [0 ][1 :])
414+ self .imm .set (int (ops [1 ], 0 ))
397415
398416 def randomize (self , variant : Variant ):
399417 self .rs1 = randrange (0 , variant .xlen )
@@ -411,12 +429,6 @@ def __str__(self):
411429 return "{} x{}, {}(x{})" .format (self .mnemonic , self .rs2 , self .imm ,
412430 self .rs1 )
413431
414- def __eq__ (self , other ):
415- if not super ().__eq__ (other ):
416- return False
417- return self .rs1 == other .rs1 and self .rs2 == other .rs2 and self .imm == other .imm
418-
419-
420432class InstructionBType (InstructionFunct3Type , metaclass = ABCMeta ):
421433 """
422434 B-type instructions encode branches. Branches have two source registers that
@@ -430,35 +442,31 @@ class InstructionBType(InstructionFunct3Type, metaclass=ABCMeta):
430442 16-bit aligned)
431443 :type imm: int
432444 """
445+
446+ isa_format_id = "B"
447+
448+ field_rs1 = Field (name = "rs1" , base = 15 , size = 5 , description = "" )
449+ field_rs2 = Field (name = "rs2" , base = 20 , size = 5 , description = "" )
450+ field_imm = Field (name = "imm" , base = [7 , 25 ], size = [5 , 7 ], offset = 1 , description = "" )
451+
452+ asm_arg_signature = "<rs1>, <rs2>, <imm>"
453+
433454 def __init__ (self , rs1 : int = None , rs2 : int = None , imm : int = None ):
434455 super (InstructionBType , self ).__init__ ()
435456 self .rs1 = rs1
436457 self .rs2 = rs2
437- self .imm = Immediate (bits = 13 , signed = True , lsb0 = True )
438- if imm is not None :
439- self .imm .set (imm )
458+ self .imm = Immediate (bits = 13 , signed = True , lsb0 = True , init = imm )
440459
441- def ops_from_string (self , ops ):
442- ops = ops .split ("," )
460+ def ops_from_list (self , ops ):
443461 self .rs1 = int (ops [0 ][1 :])
444462 self .rs2 = int (ops [1 ][1 :])
445- self .imm .set (int (ops [2 ]))
463+ self .imm .set (int (ops [2 ], 0 ))
446464
447465 def randomize (self , variant : Variant ):
448466 self .rs1 = randrange (0 , variant .xlen )
449467 self .rs2 = randrange (0 , variant .xlen )
450468 self .imm .randomize ()
451469
452- def decode (self , machinecode : int ):
453- self .rs1 = (machinecode >> 15 ) & 0x1F
454- self .rs2 = (machinecode >> 20 ) & 0x1F
455- imm11 = (machinecode >> 7 ) & 0x1
456- imm1to4 = (machinecode >> 8 ) & 0xF
457- imm5to10 = (machinecode >> 25 ) & 0x3F
458- imm12 = (machinecode >> 31 ) & 0x1
459- self .imm .set_from_bits ((imm12 << 12 ) | (imm11 << 11 ) | (imm5to10 << 5 )
460- | (imm1to4 << 1 ))
461-
462470 def inopstr (self , model ):
463471 opstr = "{:>3}={}, " .format ("x{}" .format (self .rs1 ),
464472 model .state .intreg [self .rs1 ])
@@ -470,12 +478,6 @@ def __str__(self):
470478 return "{} x{}, x{}, .{:+}" .format (self .mnemonic , self .rs1 , self .rs2 ,
471479 self .imm )
472480
473- def __eq__ (self , other ):
474- if not super ().__eq__ (other ):
475- return False
476- return self .rs1 == other .rs1 and self .rs2 == other .rs2 and self .imm == other .imm
477-
478-
479481class InstructionUType (Instruction , metaclass = ABCMeta ):
480482 """
481483 U-type instructions are used for constant formation and set the upper bits of a register.
@@ -485,15 +487,18 @@ class InstructionUType(Instruction, metaclass=ABCMeta):
485487 :param imm: Immediate (20-bit, unsigned)
486488 :type imm: int
487489 """
490+
491+ field_rd = Field (name = "rd" , base = 7 , size = 5 , description = "" )
492+ field_imm = Field (name = "imm" , base = 12 , size = 20 , description = "" )
493+
488494 def __init__ (self , rd : int = None , imm : int = None ):
489495 super (InstructionUType , self ).__init__ ()
490496 self .rd = rd # pylint: disable=invalid-name
491497 self .imm = Immediate (bits = 20 , init = imm )
492498
493- def ops_from_string (self , ops ):
494- ops = ops .split ("," )
499+ def ops_from_list (self , ops ):
495500 self .rd = int (ops [0 ][1 :])
496- self .imm .set (int (ops [1 ]))
501+ self .imm .set (int (ops [1 ], 0 ))
497502
498503 def randomize (self , variant : Variant ):
499504 self .rd = randrange (0 , variant .xlen )
@@ -506,11 +511,6 @@ def outopstr(self, model):
506511 def __str__ (self ):
507512 return "{} x{}, {}" .format (self .mnemonic , self .rd , self .imm )
508513
509- def __eq__ (self , other ):
510- if not super ().__eq__ (other ):
511- return False
512- return self .rd == other .rd and self .imm == other .imm
513-
514514
515515class InstructionJType (Instruction , metaclass = ABCMeta ):
516516 """
@@ -539,10 +539,6 @@ def outopstr(self, model):
539539 def __str__ (self ):
540540 return "{} x{}, .{:+}" .format (self .mnemonic , self .rd , self .imm )
541541
542- def __eq__ (self , other ):
543- if not super ().__eq__ (other ):
544- return False
545- return self .rd == other .rd and self .imm == other .imm
546542
547543class InstructionCType (Instruction , metaclass = ABCMeta ):
548544 """
0 commit comments