2 BinaryPattern
= re
.compile(r
'([01]+)')
3 FieldPattern
= re
.compile(r
'([a-zA-Z][a-zA-Z0-9]*)\[([0-9]+)\]')
4 ImmedPattern
= re
.compile(r
'\{(\-?[0-9:|]+)\}')
5 RangePattern
= re
.compile(r
'\|?([0-9]+):([0-9]+)')
6 SinglePattern
= re
.compile(r
'\|?([0-9]+)')
7 ParamPattern
= re
.compile(r
'([a-zA-Z][a-zA-Z0-9_]*)(.*)')
9 InsnFile
= open('Instructions.def', 'r')
10 df
= open('opcodes.h', 'w')
11 rf
= open('decode_insn.h', 'w')
12 ef
= open('execute_insn.h', 'w')
13 af
= open('disasm_insn.h', 'w')
14 kf
= open('opcodes_attr.h', 'w')
19 OriginalOrder
= [ 'Op_zero' ]
26 line
= line
.rstrip('\r\n')
28 if line
== "" or line
[0] != "@":
31 tuples
= re
.split('\t+', line
)
36 (bitpattern
, mnemonic
, assembly
, regspecs
, action
) = tuples
37 # Create opcode bitmask
38 tuples
= bitpattern
.split()
42 m
= BinaryPattern
.match(token
)
46 CodeBits
.append([InsnLen
, bits
])
48 m
= FieldPattern
.match(token
)
50 name
, width
= m
.groups()
53 Param
[name
] = [InsnLen
, width
]
55 m
= ImmedPattern
.match(token
)
62 m
= RangePattern
.match(bits
)
64 high
, low
= m
.groups()
69 Immed
.append([InsnLen
, high
, low
])
70 # print "Range", high, low, bits
72 m
= SinglePattern
.match(bits
)
78 Immed
.append([InsnLen
, where
, where
])
79 # print "Single", where, bits
83 if not (InsnLen
== 16 or InsnLen
== 32):
85 print('Illegal instruction length', InsnLen
)
90 for pos
, bits
in CodeBits
:
92 code |
= int(bits
, 2) << pos
93 mask |
= (2**len(bits
)-1) << pos
96 Param
[f
][0] = InsnLen
- Param
[f
][0]
98 if Param
[f
][0] != Field
[f
][0] or Param
[f
][1] != Field
[f
][1]:
100 print('Redefinition of field', f
)
105 for i
in range(0, len(Immed
)):
106 Immed
[i
][0] = InsnLen
- Immed
[i
][0]
107 mnemonic
= mnemonic
.strip()
108 mnemonic
= mnemonic
.lower()
109 op
= 'Op_' + mnemonic
.replace('.', '_')
110 OriginalOrder
.append(op
)
111 Opcode
[op
] = [ code
, mask
, signed
, int(InsnLen
/8), regspecs
.strip(), Immed
, action
.strip(), assembly
.strip() ]
112 Mnemonic
[op
] = mnemonic
115 OriginalOrder
.append('Op_illegal')
118 Opcode
['Op_zero' ] = (0, 0, False, 0, '-,-,-', 0, '', 'UNKNOWN')
119 Opcode
['Op_illegal'] = (0, 0, False, 0, '-,-,-', 0, '', 'ILLEGAL')
120 Mnemonic
['Op_zero' ] = 'ZERO'
121 Mnemonic
['Op_illegal'] = 'ILLEGAL'
123 for op
in OriginalOrder
:
124 code
, mask
, signed
, len, regspecs
, Immed
, action
, assembly
= Opcode
[op
]
125 tokens
= re
.split('[,()]', assembly
)
133 if t
== 'immed' or t
== 'constant':
134 format
= format
.replace(t
, '%d')
136 have_immed
= ', p->op.immed'
138 have_immed
= ', p->op_constant'
140 elif t
[0] == 'r' or t
[0] == 'f':
141 format
= format
.replace(t
, '%s')
143 t
= t
.replace('f', 'r')
145 t
= t
.replace('rd', 'p->op_rd')
146 t
= t
.replace('rs1', 'p->op_rs1')
147 t
= t
.replace('rs2', 'p->op.rs2')
148 t
= t
.replace('rs3', 'p->op.rs3')
149 t
= t
.replace('immed', 'p->op.immed')
150 t
= t
.replace('constant', 'p->op_constant')
151 params
+= ', '+regs
+'['+t
+']'
155 af
.write(' case {:s}: n += sprintf(buf, \"{:s}\"{:s}); break;\n'.format(op
, format
, params
))
159 mo
= ParamPattern
.match(x
)
162 param
, expr
= mo
.groups()
163 if not param
in Field
:
165 pos
, width
= Field
[param
]
166 # extract = '((ir>>{:d})&0x{:x})'.format(32-pos-width, 32-width)
167 extract
= '((ir>>{:d})&0x{:x})'.format(pos
, (1<<width
)-1)
168 return extract
+ expr
177 for op
in OriginalOrder
:
178 if op
== 'Op_zero' or op
== 'Op_illegal':
180 code
, mask
, signed
, len, regspecs
, Immed
, action
, assembly
= Opcode
[op
]
181 rf
.write(' if ((ir&0x{:08x})==0x{:08x}) {{ '.format(mask
, code
))
183 reglist
= regspecs
.split(',');
184 flagspecs
= reglist
[0].split(',')[0]
191 reg
= [ '64', '64', '64', '64' ]
193 for i
, spec
in enumerate(reglist
[1:]):
196 spec
= spec
.replace('cfd+8', 'crd+8+32')
197 spec
= spec
.replace('ds2+8', 'cs2+8+32')
198 spec
= spec
.replace('cfs2+8', 'crs2+8+32')
199 spec
= spec
.replace('fd', 'rd+32')
200 spec
= spec
.replace('fs1', 'rs1+32')
201 spec
= spec
.replace('fs2', 'rs2+32')
202 spec
= spec
.replace('fs3', 'fs3+32')
203 reg
[i
] = ExpandField(spec
)
204 if spec
.find('s3') != -1:
208 (pos
, hi
, lo
) = Immed
.pop(0)
210 imm
+= '|(((ir<<{:d})>>{:d})<<{:d})'.format(32-pos
-width
, 32-width
, lo
)
211 for (pos
, hi
, lo
) in Immed
:
214 imm
+= '|(((ir>>{:d})&0x{:x})<<{:d})'.format(pos
, mask
, lo
)
215 if assembly
.find('constant') != -1:
217 rf
.write("*p=fmtC({:s}, {:s}, {:s}, {:s})".format(op
, reg
[0], reg
[1], imm
))
219 rf
.write("*p=fmtR({:s}, {:s}, {:s}, {:s}, {:s}, {:s})".format(op
, reg
[0], reg
[1], reg
[2], reg
[3], imm
))
220 if (Opcode
[op
][3] == 2):
224 Opcode
[op
][4] = regspecs
;
225 rf
.write("; return; }\n")
229 InOrder
= [ 'Op_zero' ]
231 # 1 short ops with long constants (cannot be memory)
233 if op
in KonstOp
and op
not in ReadOp
and op
not in WriteOp
:
234 if op
in ReadOp
or op
in WriteOp
:
235 print("Short op ", op
, "in KonstOp and MemOp!")
238 lastShortKonstOp
= op
239 # 2 short ops not memory read or write operations
241 if op
not in ReadOp
and op
not in WriteOp
and op
not in KonstOp
:
243 # 3 short ops that are memory read operations
244 firstShortMemOp
= None
246 if op
in ReadOp
and op
not in WriteOp
and op
not in KonstOp
:
248 if firstShortMemOp
== None:
250 # 4 short ops that are memory write or read-modify-write operations
253 if op
in WriteOp
and op
not in KonstOp
:
256 if firstWriteOp
== None:
259 # 5 long ops that are memory write or read-modify-write operations
261 if op
in WriteOp
and op
not in KonstOp
:
265 # 6 long ops that are memory read operations
267 if op
in ReadOp
and op
not in WriteOp
and op
not in KonstOp
:
271 # 7 long ops without long constants that do not have three operands
273 if op
not in ThreeOp
and op
not in ReadOp
and op
not in WriteOp
and op
not in KonstOp
:
276 # 8 long ops without long constants that do have three operands
279 if op
in ThreeOp
and op
not in ReadOp
and op
not in WriteOp
and op
not in KonstOp
:
281 if firstThreeOp
== None:
284 # 9 long ops with long constants
285 firstLongKonstOp
= None
287 if op
in KonstOp
and op
not in ReadOp
and op
not in WriteOp
:
289 if firstLongKonstOp
== None:
290 firstLongKonstOp
= op
292 InOrder
.append('Op_illegal')
295 df
.write('enum Opcode_t {')
300 df
.write('{:>20s},'.format(op
))
302 df
.write('{:>20s},'.format('Number_of_opcodes'))
305 df
.write('#define validOp(op) (Op_zero < op && op < Op_illegal)\n')
306 df
.write('#define shortOp(op) (op <= {:s})\n'.format(lastShortOp
))
307 df
.write('#define konstOp(op) (op <= {:s} || op >= {:s})\n'.format(lastShortKonstOp
, firstLongKonstOp
))
308 df
.write('#define memOp(op) ({:s} <= op && op <= {:s})\n'.format(firstShortMemOp
, lastLongMemOp
))
309 df
.write('#define writeOp(op) ({:s} <= op && op <= {:s})\n'.format(firstWriteOp
, lastWriteOp
))
310 df
.write('#define threeOp(op) (op >= {:s})\n'.format(firstThreeOp
))
314 df
.write('enum units_t {')
315 for u
in sorted(Flags
):
316 if f
== '-' or not u
.islower():
319 FunctionalUnits
.append(unit
)
320 df
.write(' {:s},\n'.format(unit
))
321 df
.write(' {:s},\n'.format('Number_of_units'))
326 for f
in sorted(Flags
):
327 if f
== '-' or f
.islower():
329 df
.write('#define attr_{:s} 0x{:08x}\n'.format(f
, val
))
332 # write opcodes_attr.h
333 for i
, op
in enumerate(InOrder
):
334 init
= '{:16s} 0'.format('"'+Mnemonic
[op
]+'",')
335 flags
= Opcode
[op
][4]
336 flags
= flags
.split(',')
339 if letter
== '-' or letter
.islower():
341 init
+= ' | attr_' + letter
344 if letter
== '-' or not letter
.islower():
346 unit
+= 'Unit_' + letter
347 kf
.write(' {{ {:s}, {:s} }},\n'.format(init
, unit
))
351 if op
== 'Op_zero' or op
== 'Op_illegal':
353 code
, mask
, signed
, len, regspecs
, Immed
, action
, assembly
= Opcode
[op
]
354 action
= action
.replace('rd', 'p->op_rd')
355 action
= action
.replace('rs1', 'p->op_rs1')
356 action
= action
.replace('rs2', 'p->op.rs2')
357 action
= action
.replace('rs3', 'p->op.rs3')
358 action
= action
.replace('immed', 'p->op.immed')
359 action
= action
.replace('constant', 'p->op_constant')
360 ef
.write('case {:>20s}: {:s}; INCPC({:d}); break;\n'.format(op
, action
, len))