15
15
from .types import Immediate , Register
16
16
from .variant import RV32I
17
17
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 )
20
20
21
21
class Instruction (metaclass = ABCMeta ):
22
22
"""
@@ -58,7 +58,14 @@ def set_field(cls, field, word, value):
58
58
fname = "field_{}" .format (field )
59
59
base = getattr (cls , fname ).base
60
60
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
62
69
63
70
@classmethod
64
71
def get_fields (cls ):
@@ -131,7 +138,7 @@ def encode(self) -> int:
131
138
"""
132
139
word = 0
133
140
for field in self .get_fields ():
134
- if field .static :
141
+ if field .value is not None :
135
142
word = self .set_field (field .name , word , field .value )
136
143
else :
137
144
value = getattr (self , field .name )
@@ -207,8 +214,8 @@ class InstructionRType(InstructionFunct3Type, InstructionFunct7Type, metaclass=A
207
214
asm_arg_signature = "<rd>, <rs1>, <rs2>"
208
215
209
216
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 = "" )
212
219
213
220
def __init__ (self , rd : int = None , rs1 : int = None , rs2 : int = None ):
214
221
super (InstructionRType , self ).__init__ ()
@@ -217,8 +224,8 @@ def __init__(self, rd: int = None, rs1: int = None, rs2: int = None):
217
224
self .rs1 = rs1
218
225
self .rs2 = rs2
219
226
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 ]
222
229
223
230
def randomize (self , variant : Variant ):
224
231
self .rd = randrange (0 , variant .xlen )
@@ -268,7 +275,7 @@ class InstructionIType(InstructionFunct3Type, metaclass=ABCMeta):
268
275
269
276
field_rd = Field (name = "rd" , base = 7 , size = 5 , description = "" )
270
277
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 = "" )
272
279
273
280
def __init__ (self , rd : int = None , rs1 : int = None , imm : int = None ):
274
281
super (InstructionIType , self ).__init__ ()
@@ -279,9 +286,15 @@ def __init__(self, rd: int = None, rs1: int = None, imm: int = None):
279
286
self .imm .set (imm )
280
287
281
288
def ops_from_list (self , ops ):
289
+ if len (ops ) == 0 : # ecall
290
+ return
282
291
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 ))
285
298
286
299
def randomize (self , variant : Variant ):
287
300
self .rd = randrange (0 , variant .xlen )
@@ -300,12 +313,6 @@ def __str__(self) -> str:
300
313
return "{} x{}, x{}, {}" .format (self .mnemonic , self .rd , self .rs1 ,
301
314
self .imm )
302
315
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
-
309
316
class InstructionILType (InstructionIType , metaclass = ABCMeta ):
310
317
"""
311
318
I-type instruction specialization for stores. The produce a different
@@ -335,21 +342,24 @@ class InstructionISType(InstructionFunct3Type,InstructionFunct7Type, metaclass=A
335
342
:type imm: int
336
343
"""
337
344
345
+ isa_format_id = "IS"
346
+
338
347
field_rd = Field (name = "rd" , base = 7 , size = 5 , description = "" )
339
348
field_rs1 = Field (name = "rs1" , base = 15 , size = 5 , description = "" )
340
349
field_shamt = Field (name = "shamt" , base = 20 , size = 5 , description = "" )
341
350
351
+ asm_arg_signature = "<rd>, <rs1>, <shamt>"
352
+
342
353
def __init__ (self , rd : int = None , rs1 : int = None , shamt : int = None ):
343
354
super (InstructionISType , self ).__init__ ()
344
355
self .rd = rd
345
356
self .rs1 = rs1
346
357
self .shamt = Immediate (bits = 5 , init = shamt )
347
358
348
- def ops_from_string (self , ops ):
349
- ops = ops .split ("," )
359
+ def ops_from_list (self , ops ):
350
360
self .rd = int (ops [0 ][1 :])
351
361
self .rs1 = int (ops [1 ][1 :])
352
- self .shamt .set (int (ops [2 ]))
362
+ self .shamt .set (int (ops [2 ], 0 ))
353
363
354
364
def randomize (self , variant : Variant ):
355
365
self .rd = randrange (0 , variant .xlen )
@@ -383,17 +393,25 @@ class InstructionSType(InstructionFunct3Type, metaclass=ABCMeta):
383
393
:param imm: Offset of store, for calculation of address relative to rs1
384
394
:type imm: int
385
395
"""
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
+
386
405
def __init__ (self , rs1 : int = None , rs2 : int = None , imm : int = None ):
387
406
super (InstructionSType , self ).__init__ ()
388
407
self .rs1 = rs1
389
408
self .rs2 = rs2
390
409
self .imm = Immediate (bits = 12 , signed = True , init = imm )
391
410
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 ))
397
415
398
416
def randomize (self , variant : Variant ):
399
417
self .rs1 = randrange (0 , variant .xlen )
@@ -411,12 +429,6 @@ def __str__(self):
411
429
return "{} x{}, {}(x{})" .format (self .mnemonic , self .rs2 , self .imm ,
412
430
self .rs1 )
413
431
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
-
420
432
class InstructionBType (InstructionFunct3Type , metaclass = ABCMeta ):
421
433
"""
422
434
B-type instructions encode branches. Branches have two source registers that
@@ -430,35 +442,31 @@ class InstructionBType(InstructionFunct3Type, metaclass=ABCMeta):
430
442
16-bit aligned)
431
443
:type imm: int
432
444
"""
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
+
433
454
def __init__ (self , rs1 : int = None , rs2 : int = None , imm : int = None ):
434
455
super (InstructionBType , self ).__init__ ()
435
456
self .rs1 = rs1
436
457
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 )
440
459
441
- def ops_from_string (self , ops ):
442
- ops = ops .split ("," )
460
+ def ops_from_list (self , ops ):
443
461
self .rs1 = int (ops [0 ][1 :])
444
462
self .rs2 = int (ops [1 ][1 :])
445
- self .imm .set (int (ops [2 ]))
463
+ self .imm .set (int (ops [2 ], 0 ))
446
464
447
465
def randomize (self , variant : Variant ):
448
466
self .rs1 = randrange (0 , variant .xlen )
449
467
self .rs2 = randrange (0 , variant .xlen )
450
468
self .imm .randomize ()
451
469
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
-
462
470
def inopstr (self , model ):
463
471
opstr = "{:>3}={}, " .format ("x{}" .format (self .rs1 ),
464
472
model .state .intreg [self .rs1 ])
@@ -470,12 +478,6 @@ def __str__(self):
470
478
return "{} x{}, x{}, .{:+}" .format (self .mnemonic , self .rs1 , self .rs2 ,
471
479
self .imm )
472
480
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
-
479
481
class InstructionUType (Instruction , metaclass = ABCMeta ):
480
482
"""
481
483
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):
485
487
:param imm: Immediate (20-bit, unsigned)
486
488
:type imm: int
487
489
"""
490
+
491
+ field_rd = Field (name = "rd" , base = 7 , size = 5 , description = "" )
492
+ field_imm = Field (name = "imm" , base = 12 , size = 20 , description = "" )
493
+
488
494
def __init__ (self , rd : int = None , imm : int = None ):
489
495
super (InstructionUType , self ).__init__ ()
490
496
self .rd = rd # pylint: disable=invalid-name
491
497
self .imm = Immediate (bits = 20 , init = imm )
492
498
493
- def ops_from_string (self , ops ):
494
- ops = ops .split ("," )
499
+ def ops_from_list (self , ops ):
495
500
self .rd = int (ops [0 ][1 :])
496
- self .imm .set (int (ops [1 ]))
501
+ self .imm .set (int (ops [1 ], 0 ))
497
502
498
503
def randomize (self , variant : Variant ):
499
504
self .rd = randrange (0 , variant .xlen )
@@ -506,11 +511,6 @@ def outopstr(self, model):
506
511
def __str__ (self ):
507
512
return "{} x{}, {}" .format (self .mnemonic , self .rd , self .imm )
508
513
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
-
514
514
515
515
class InstructionJType (Instruction , metaclass = ABCMeta ):
516
516
"""
@@ -539,10 +539,6 @@ def outopstr(self, model):
539
539
def __str__ (self ):
540
540
return "{} x{}, .{:+}" .format (self .mnemonic , self .rd , self .imm )
541
541
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
546
542
547
543
class InstructionCType (Instruction , metaclass = ABCMeta ):
548
544
"""
0 commit comments