@@ -47,11 +47,19 @@ def asm_signature(cls):
4747 return signature
4848
4949 @classmethod
50- def extract_field (cls , field , machinecode ):
50+ def extract_field (cls , field , word ):
5151 fname = "field_{}" .format (field )
5252 base = getattr (cls , fname ).base
5353 size = getattr (cls , fname ).size
54- return (machinecode >> base ) & (2 ** size - 1 )
54+ if not isinstance (base , list ):
55+ base = [base ]
56+ size = [size ]
57+ off = 0
58+ value = 0
59+ for part in range (len (base )):
60+ value |= ((word >> base [part ]) & (2 ** size [part ] - 1 )) << off
61+ off += size [part ]
62+ return value << getattr (cls , fname ).offset
5563
5664 @classmethod
5765 def set_field (cls , field , word , value ):
@@ -61,7 +69,7 @@ def set_field(cls, field, word, value):
6169 if not isinstance (base , list ):
6270 base = [base ]
6371 size = [size ]
64- off = 0
72+ off = getattr ( cls , fname ). offset
6573 for part in range (len (base )):
6674 word |= (((value >> off ) & (2 ** size [part ] - 1 )) << base [part ])
6775 off += size [part ]
@@ -82,6 +90,14 @@ def get_isa_format(cls, *, asdict: bool=False):
8290 fields = [field ._asdict () for field in fields ]
8391 return {"id" : cls .isa_format_id , "fields" : fields }
8492
93+ @classmethod
94+ def match (cls , word : int ):
95+ """Try to match a machine code to this instruction"""
96+ for field in cls .get_static_fields ():
97+ if cls .extract_field (field .name , word ) != field .value :
98+ return False
99+ return True
100+
85101 def ops_from_string (self , ops : str ):
86102 """
87103 Extract operands from string
@@ -126,11 +142,13 @@ def decode(self, word: int):
126142 assert self .extract_field (field .name , word ) == field .value
127143 else :
128144 attr = getattr (self , field .name )
145+ value = self .extract_field (field .name , word )
129146 if isinstance (attr , Register ):
130- attr .set (self .extract_field (field .name , word ))
147+ attr .set (value )
148+ elif isinstance (attr , Immediate ):
149+ attr .set_from_bits (value )
131150 else :
132- assert isinstance (attr , Immediate )
133- attr .set_from_bits (self .extract_field (field .name , word ))
151+ setattr (self , field .name , value )
134152
135153 def encode (self ) -> int :
136154 """
@@ -661,18 +679,6 @@ class WrappedClass(wrapped): # pylint: disable=too-few-public-methods
661679 assert fid in dir (wrapped ), "Invalid field {} for {}" .format (fid , wrapped .__name__ )
662680 setattr (wrapped , fid , getattr (wrapped , fid )._replace (value = kwargs [field ]))
663681
664- @classmethod
665- def match (cls , word : int ):
666- """Try to match a machine code to this instruction"""
667- if not cls .field_opcode :
668- return False
669-
670- for field in cls .get_static_fields ():
671- if cls .extract_field (field .name , word ) != field .value :
672- return False
673-
674- return True
675-
676682 WrappedClass .__name__ = wrapped .__name__
677683 WrappedClass .__module__ = wrapped .__module__
678684 WrappedClass .__qualname__ = wrapped .__qualname__
@@ -701,8 +707,6 @@ def wrapper(wrapped):
701707 class WrappedClass (wrapped ): # pylint: disable=too-few-public-methods
702708 """Generic wrapper class"""
703709
704- #TODO
705-
706710 WrappedClass .__name__ = wrapped .__name__
707711 WrappedClass .__module__ = wrapped .__module__
708712 WrappedClass .__qualname__ = wrapped .__qualname__
0 commit comments