decodetree.py 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073
  1. #!/usr/bin/env python
  2. # Copyright (c) 2018 Linaro Limited
  3. #
  4. # This library is free software; you can redistribute it and/or
  5. # modify it under the terms of the GNU Lesser General Public
  6. # License as published by the Free Software Foundation; either
  7. # version 2 of the License, or (at your option) any later version.
  8. #
  9. # This library is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. # Lesser General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU Lesser General Public
  15. # License along with this library; if not, see <http://www.gnu.org/licenses/>.
  16. #
  17. #
  18. # Generate a decoding tree from a specification file.
  19. # See the syntax and semantics in docs/devel/decodetree.rst.
  20. #
  21. import os
  22. import re
  23. import sys
  24. import getopt
  25. insnwidth = 32
  26. insnmask = 0xffffffff
  27. fields = {}
  28. arguments = {}
  29. formats = {}
  30. patterns = []
  31. allpatterns = []
  32. translate_prefix = 'trans'
  33. translate_scope = 'static '
  34. input_file = ''
  35. output_file = None
  36. output_fd = None
  37. insntype = 'uint32_t'
  38. decode_function = 'decode'
  39. re_ident = '[a-zA-Z][a-zA-Z0-9_]*'
  40. def error_with_file(file, lineno, *args):
  41. """Print an error message from file:line and args and exit."""
  42. global output_file
  43. global output_fd
  44. if lineno:
  45. r = '{0}:{1}: error:'.format(file, lineno)
  46. elif input_file:
  47. r = '{0}: error:'.format(file)
  48. else:
  49. r = 'error:'
  50. for a in args:
  51. r += ' ' + str(a)
  52. r += '\n'
  53. sys.stderr.write(r)
  54. if output_file and output_fd:
  55. output_fd.close()
  56. os.remove(output_file)
  57. exit(1)
  58. def error(lineno, *args):
  59. error_with_file(input_file, lineno, args)
  60. def output(*args):
  61. global output_fd
  62. for a in args:
  63. output_fd.write(a)
  64. if sys.version_info >= (3, 4):
  65. re_fullmatch = re.fullmatch
  66. else:
  67. def re_fullmatch(pat, str):
  68. return re.match('^' + pat + '$', str)
  69. def output_autogen():
  70. output('/* This file is autogenerated by scripts/decodetree.py. */\n\n')
  71. def str_indent(c):
  72. """Return a string with C spaces"""
  73. return ' ' * c
  74. def str_fields(fields):
  75. """Return a string uniquely identifing FIELDS"""
  76. r = ''
  77. for n in sorted(fields.keys()):
  78. r += '_' + n
  79. return r[1:]
  80. def str_match_bits(bits, mask):
  81. """Return a string pretty-printing BITS/MASK"""
  82. global insnwidth
  83. i = 1 << (insnwidth - 1)
  84. space = 0x01010100
  85. r = ''
  86. while i != 0:
  87. if i & mask:
  88. if i & bits:
  89. r += '1'
  90. else:
  91. r += '0'
  92. else:
  93. r += '.'
  94. if i & space:
  95. r += ' '
  96. i >>= 1
  97. return r
  98. def is_pow2(x):
  99. """Return true iff X is equal to a power of 2."""
  100. return (x & (x - 1)) == 0
  101. def ctz(x):
  102. """Return the number of times 2 factors into X."""
  103. r = 0
  104. while ((x >> r) & 1) == 0:
  105. r += 1
  106. return r
  107. def is_contiguous(bits):
  108. shift = ctz(bits)
  109. if is_pow2((bits >> shift) + 1):
  110. return shift
  111. else:
  112. return -1
  113. def eq_fields_for_args(flds_a, flds_b):
  114. if len(flds_a) != len(flds_b):
  115. return False
  116. for k, a in flds_a.items():
  117. if k not in flds_b:
  118. return False
  119. return True
  120. def eq_fields_for_fmts(flds_a, flds_b):
  121. if len(flds_a) != len(flds_b):
  122. return False
  123. for k, a in flds_a.items():
  124. if k not in flds_b:
  125. return False
  126. b = flds_b[k]
  127. if a.__class__ != b.__class__ or a != b:
  128. return False
  129. return True
  130. class Field:
  131. """Class representing a simple instruction field"""
  132. def __init__(self, sign, pos, len):
  133. self.sign = sign
  134. self.pos = pos
  135. self.len = len
  136. self.mask = ((1 << len) - 1) << pos
  137. def __str__(self):
  138. if self.sign:
  139. s = 's'
  140. else:
  141. s = ''
  142. return str(self.pos) + ':' + s + str(self.len)
  143. def str_extract(self):
  144. if self.sign:
  145. extr = 'sextract32'
  146. else:
  147. extr = 'extract32'
  148. return '{0}(insn, {1}, {2})'.format(extr, self.pos, self.len)
  149. def __eq__(self, other):
  150. return self.sign == other.sign and self.sign == other.sign
  151. def __ne__(self, other):
  152. return not self.__eq__(other)
  153. # end Field
  154. class MultiField:
  155. """Class representing a compound instruction field"""
  156. def __init__(self, subs, mask):
  157. self.subs = subs
  158. self.sign = subs[0].sign
  159. self.mask = mask
  160. def __str__(self):
  161. return str(self.subs)
  162. def str_extract(self):
  163. ret = '0'
  164. pos = 0
  165. for f in reversed(self.subs):
  166. if pos == 0:
  167. ret = f.str_extract()
  168. else:
  169. ret = 'deposit32({0}, {1}, {2}, {3})' \
  170. .format(ret, pos, 32 - pos, f.str_extract())
  171. pos += f.len
  172. return ret
  173. def __ne__(self, other):
  174. if len(self.subs) != len(other.subs):
  175. return True
  176. for a, b in zip(self.subs, other.subs):
  177. if a.__class__ != b.__class__ or a != b:
  178. return True
  179. return False
  180. def __eq__(self, other):
  181. return not self.__ne__(other)
  182. # end MultiField
  183. class ConstField:
  184. """Class representing an argument field with constant value"""
  185. def __init__(self, value):
  186. self.value = value
  187. self.mask = 0
  188. self.sign = value < 0
  189. def __str__(self):
  190. return str(self.value)
  191. def str_extract(self):
  192. return str(self.value)
  193. def __cmp__(self, other):
  194. return self.value - other.value
  195. # end ConstField
  196. class FunctionField:
  197. """Class representing a field passed through an expander"""
  198. def __init__(self, func, base):
  199. self.mask = base.mask
  200. self.sign = base.sign
  201. self.base = base
  202. self.func = func
  203. def __str__(self):
  204. return self.func + '(' + str(self.base) + ')'
  205. def str_extract(self):
  206. return self.func + '(' + self.base.str_extract() + ')'
  207. def __eq__(self, other):
  208. return self.func == other.func and self.base == other.base
  209. def __ne__(self, other):
  210. return not self.__eq__(other)
  211. # end FunctionField
  212. class Arguments:
  213. """Class representing the extracted fields of a format"""
  214. def __init__(self, nm, flds, extern):
  215. self.name = nm
  216. self.extern = extern
  217. self.fields = sorted(flds)
  218. def __str__(self):
  219. return self.name + ' ' + str(self.fields)
  220. def struct_name(self):
  221. return 'arg_' + self.name
  222. def output_def(self):
  223. if not self.extern:
  224. output('typedef struct {\n')
  225. for n in self.fields:
  226. output(' int ', n, ';\n')
  227. output('} ', self.struct_name(), ';\n\n')
  228. # end Arguments
  229. class General:
  230. """Common code between instruction formats and instruction patterns"""
  231. def __init__(self, name, lineno, base, fixb, fixm, udfm, fldm, flds):
  232. self.name = name
  233. self.file = input_file
  234. self.lineno = lineno
  235. self.base = base
  236. self.fixedbits = fixb
  237. self.fixedmask = fixm
  238. self.undefmask = udfm
  239. self.fieldmask = fldm
  240. self.fields = flds
  241. def __str__(self):
  242. return self.name + ' ' + str_match_bits(self.fixedbits, self.fixedmask)
  243. def str1(self, i):
  244. return str_indent(i) + self.__str__()
  245. # end General
  246. class Format(General):
  247. """Class representing an instruction format"""
  248. def extract_name(self):
  249. global decode_function
  250. return decode_function + '_extract_' + self.name
  251. def output_extract(self):
  252. output('static void ', self.extract_name(), '(',
  253. self.base.struct_name(), ' *a, ', insntype, ' insn)\n{\n')
  254. for n, f in self.fields.items():
  255. output(' a->', n, ' = ', f.str_extract(), ';\n')
  256. output('}\n\n')
  257. # end Format
  258. class Pattern(General):
  259. """Class representing an instruction pattern"""
  260. def output_decl(self):
  261. global translate_scope
  262. global translate_prefix
  263. output('typedef ', self.base.base.struct_name(),
  264. ' arg_', self.name, ';\n')
  265. output(translate_scope, 'bool ', translate_prefix, '_', self.name,
  266. '(DisasContext *ctx, arg_', self.name, ' *a);\n')
  267. def output_code(self, i, extracted, outerbits, outermask):
  268. global translate_prefix
  269. ind = str_indent(i)
  270. arg = self.base.base.name
  271. output(ind, '/* ', self.file, ':', str(self.lineno), ' */\n')
  272. if not extracted:
  273. output(ind, self.base.extract_name(), '(&u.f_', arg, ', insn);\n')
  274. for n, f in self.fields.items():
  275. output(ind, 'u.f_', arg, '.', n, ' = ', f.str_extract(), ';\n')
  276. output(ind, 'if (', translate_prefix, '_', self.name,
  277. '(ctx, &u.f_', arg, ')) return true;\n')
  278. # end Pattern
  279. class MultiPattern(General):
  280. """Class representing an overlapping set of instruction patterns"""
  281. def __init__(self, lineno, pats, fixb, fixm, udfm):
  282. self.file = input_file
  283. self.lineno = lineno
  284. self.pats = pats
  285. self.base = None
  286. self.fixedbits = fixb
  287. self.fixedmask = fixm
  288. self.undefmask = udfm
  289. def __str__(self):
  290. r = "{"
  291. for p in self.pats:
  292. r = r + ' ' + str(p)
  293. return r + "}"
  294. def output_decl(self):
  295. for p in self.pats:
  296. p.output_decl()
  297. def output_code(self, i, extracted, outerbits, outermask):
  298. global translate_prefix
  299. ind = str_indent(i)
  300. for p in self.pats:
  301. if outermask != p.fixedmask:
  302. innermask = p.fixedmask & ~outermask
  303. innerbits = p.fixedbits & ~outermask
  304. output(ind, 'if ((insn & ',
  305. '0x{0:08x}) == 0x{1:08x}'.format(innermask, innerbits),
  306. ') {\n')
  307. output(ind, ' /* ',
  308. str_match_bits(p.fixedbits, p.fixedmask), ' */\n')
  309. p.output_code(i + 4, extracted, p.fixedbits, p.fixedmask)
  310. output(ind, '}\n')
  311. else:
  312. p.output_code(i, extracted, p.fixedbits, p.fixedmask)
  313. #end MultiPattern
  314. def parse_field(lineno, name, toks):
  315. """Parse one instruction field from TOKS at LINENO"""
  316. global fields
  317. global re_ident
  318. global insnwidth
  319. # A "simple" field will have only one entry;
  320. # a "multifield" will have several.
  321. subs = []
  322. width = 0
  323. func = None
  324. for t in toks:
  325. if re_fullmatch('!function=' + re_ident, t):
  326. if func:
  327. error(lineno, 'duplicate function')
  328. func = t.split('=')
  329. func = func[1]
  330. continue
  331. if re_fullmatch('[0-9]+:s[0-9]+', t):
  332. # Signed field extract
  333. subtoks = t.split(':s')
  334. sign = True
  335. elif re_fullmatch('[0-9]+:[0-9]+', t):
  336. # Unsigned field extract
  337. subtoks = t.split(':')
  338. sign = False
  339. else:
  340. error(lineno, 'invalid field token "{0}"'.format(t))
  341. po = int(subtoks[0])
  342. le = int(subtoks[1])
  343. if po + le > insnwidth:
  344. error(lineno, 'field {0} too large'.format(t))
  345. f = Field(sign, po, le)
  346. subs.append(f)
  347. width += le
  348. if width > insnwidth:
  349. error(lineno, 'field too large')
  350. if len(subs) == 1:
  351. f = subs[0]
  352. else:
  353. mask = 0
  354. for s in subs:
  355. if mask & s.mask:
  356. error(lineno, 'field components overlap')
  357. mask |= s.mask
  358. f = MultiField(subs, mask)
  359. if func:
  360. f = FunctionField(func, f)
  361. if name in fields:
  362. error(lineno, 'duplicate field', name)
  363. fields[name] = f
  364. # end parse_field
  365. def parse_arguments(lineno, name, toks):
  366. """Parse one argument set from TOKS at LINENO"""
  367. global arguments
  368. global re_ident
  369. flds = []
  370. extern = False
  371. for t in toks:
  372. if re_fullmatch('!extern', t):
  373. extern = True
  374. continue
  375. if not re_fullmatch(re_ident, t):
  376. error(lineno, 'invalid argument set token "{0}"'.format(t))
  377. if t in flds:
  378. error(lineno, 'duplicate argument "{0}"'.format(t))
  379. flds.append(t)
  380. if name in arguments:
  381. error(lineno, 'duplicate argument set', name)
  382. arguments[name] = Arguments(name, flds, extern)
  383. # end parse_arguments
  384. def lookup_field(lineno, name):
  385. global fields
  386. if name in fields:
  387. return fields[name]
  388. error(lineno, 'undefined field', name)
  389. def add_field(lineno, flds, new_name, f):
  390. if new_name in flds:
  391. error(lineno, 'duplicate field', new_name)
  392. flds[new_name] = f
  393. return flds
  394. def add_field_byname(lineno, flds, new_name, old_name):
  395. return add_field(lineno, flds, new_name, lookup_field(lineno, old_name))
  396. def infer_argument_set(flds):
  397. global arguments
  398. global decode_function
  399. for arg in arguments.values():
  400. if eq_fields_for_args(flds, arg.fields):
  401. return arg
  402. name = decode_function + str(len(arguments))
  403. arg = Arguments(name, flds.keys(), False)
  404. arguments[name] = arg
  405. return arg
  406. def infer_format(arg, fieldmask, flds):
  407. global arguments
  408. global formats
  409. global decode_function
  410. const_flds = {}
  411. var_flds = {}
  412. for n, c in flds.items():
  413. if c is ConstField:
  414. const_flds[n] = c
  415. else:
  416. var_flds[n] = c
  417. # Look for an existing format with the same argument set and fields
  418. for fmt in formats.values():
  419. if arg and fmt.base != arg:
  420. continue
  421. if fieldmask != fmt.fieldmask:
  422. continue
  423. if not eq_fields_for_fmts(flds, fmt.fields):
  424. continue
  425. return (fmt, const_flds)
  426. name = decode_function + '_Fmt_' + str(len(formats))
  427. if not arg:
  428. arg = infer_argument_set(flds)
  429. fmt = Format(name, 0, arg, 0, 0, 0, fieldmask, var_flds)
  430. formats[name] = fmt
  431. return (fmt, const_flds)
  432. # end infer_format
  433. def parse_generic(lineno, is_format, name, toks):
  434. """Parse one instruction format from TOKS at LINENO"""
  435. global fields
  436. global arguments
  437. global formats
  438. global patterns
  439. global allpatterns
  440. global re_ident
  441. global insnwidth
  442. global insnmask
  443. fixedmask = 0
  444. fixedbits = 0
  445. undefmask = 0
  446. width = 0
  447. flds = {}
  448. arg = None
  449. fmt = None
  450. for t in toks:
  451. # '&Foo' gives a format an explcit argument set.
  452. if t[0] == '&':
  453. tt = t[1:]
  454. if arg:
  455. error(lineno, 'multiple argument sets')
  456. if tt in arguments:
  457. arg = arguments[tt]
  458. else:
  459. error(lineno, 'undefined argument set', t)
  460. continue
  461. # '@Foo' gives a pattern an explicit format.
  462. if t[0] == '@':
  463. tt = t[1:]
  464. if fmt:
  465. error(lineno, 'multiple formats')
  466. if tt in formats:
  467. fmt = formats[tt]
  468. else:
  469. error(lineno, 'undefined format', t)
  470. continue
  471. # '%Foo' imports a field.
  472. if t[0] == '%':
  473. tt = t[1:]
  474. flds = add_field_byname(lineno, flds, tt, tt)
  475. continue
  476. # 'Foo=%Bar' imports a field with a different name.
  477. if re_fullmatch(re_ident + '=%' + re_ident, t):
  478. (fname, iname) = t.split('=%')
  479. flds = add_field_byname(lineno, flds, fname, iname)
  480. continue
  481. # 'Foo=number' sets an argument field to a constant value
  482. if re_fullmatch(re_ident + '=[+-]?[0-9]+', t):
  483. (fname, value) = t.split('=')
  484. value = int(value)
  485. flds = add_field(lineno, flds, fname, ConstField(value))
  486. continue
  487. # Pattern of 0s, 1s, dots and dashes indicate required zeros,
  488. # required ones, or dont-cares.
  489. if re_fullmatch('[01.-]+', t):
  490. shift = len(t)
  491. fms = t.replace('0', '1')
  492. fms = fms.replace('.', '0')
  493. fms = fms.replace('-', '0')
  494. fbs = t.replace('.', '0')
  495. fbs = fbs.replace('-', '0')
  496. ubm = t.replace('1', '0')
  497. ubm = ubm.replace('.', '0')
  498. ubm = ubm.replace('-', '1')
  499. fms = int(fms, 2)
  500. fbs = int(fbs, 2)
  501. ubm = int(ubm, 2)
  502. fixedbits = (fixedbits << shift) | fbs
  503. fixedmask = (fixedmask << shift) | fms
  504. undefmask = (undefmask << shift) | ubm
  505. # Otherwise, fieldname:fieldwidth
  506. elif re_fullmatch(re_ident + ':s?[0-9]+', t):
  507. (fname, flen) = t.split(':')
  508. sign = False
  509. if flen[0] == 's':
  510. sign = True
  511. flen = flen[1:]
  512. shift = int(flen, 10)
  513. if shift + width > insnwidth:
  514. error(lineno, 'field {0} exceeds insnwidth'.format(fname))
  515. f = Field(sign, insnwidth - width - shift, shift)
  516. flds = add_field(lineno, flds, fname, f)
  517. fixedbits <<= shift
  518. fixedmask <<= shift
  519. undefmask <<= shift
  520. else:
  521. error(lineno, 'invalid token "{0}"'.format(t))
  522. width += shift
  523. # We should have filled in all of the bits of the instruction.
  524. if not (is_format and width == 0) and width != insnwidth:
  525. error(lineno, 'definition has {0} bits'.format(width))
  526. # Do not check for fields overlaping fields; one valid usage
  527. # is to be able to duplicate fields via import.
  528. fieldmask = 0
  529. for f in flds.values():
  530. fieldmask |= f.mask
  531. # Fix up what we've parsed to match either a format or a pattern.
  532. if is_format:
  533. # Formats cannot reference formats.
  534. if fmt:
  535. error(lineno, 'format referencing format')
  536. # If an argument set is given, then there should be no fields
  537. # without a place to store it.
  538. if arg:
  539. for f in flds.keys():
  540. if f not in arg.fields:
  541. error(lineno, 'field {0} not in argument set {1}'
  542. .format(f, arg.name))
  543. else:
  544. arg = infer_argument_set(flds)
  545. if name in formats:
  546. error(lineno, 'duplicate format name', name)
  547. fmt = Format(name, lineno, arg, fixedbits, fixedmask,
  548. undefmask, fieldmask, flds)
  549. formats[name] = fmt
  550. else:
  551. # Patterns can reference a format ...
  552. if fmt:
  553. # ... but not an argument simultaneously
  554. if arg:
  555. error(lineno, 'pattern specifies both format and argument set')
  556. if fixedmask & fmt.fixedmask:
  557. error(lineno, 'pattern fixed bits overlap format fixed bits')
  558. fieldmask |= fmt.fieldmask
  559. fixedbits |= fmt.fixedbits
  560. fixedmask |= fmt.fixedmask
  561. undefmask |= fmt.undefmask
  562. else:
  563. (fmt, flds) = infer_format(arg, fieldmask, flds)
  564. arg = fmt.base
  565. for f in flds.keys():
  566. if f not in arg.fields:
  567. error(lineno, 'field {0} not in argument set {1}'
  568. .format(f, arg.name))
  569. if f in fmt.fields.keys():
  570. error(lineno, 'field {0} set by format and pattern'.format(f))
  571. for f in arg.fields:
  572. if f not in flds.keys() and f not in fmt.fields.keys():
  573. error(lineno, 'field {0} not initialized'.format(f))
  574. pat = Pattern(name, lineno, fmt, fixedbits, fixedmask,
  575. undefmask, fieldmask, flds)
  576. patterns.append(pat)
  577. allpatterns.append(pat)
  578. # Validate the masks that we have assembled.
  579. if fieldmask & fixedmask:
  580. error(lineno, 'fieldmask overlaps fixedmask (0x{0:08x} & 0x{1:08x})'
  581. .format(fieldmask, fixedmask))
  582. if fieldmask & undefmask:
  583. error(lineno, 'fieldmask overlaps undefmask (0x{0:08x} & 0x{1:08x})'
  584. .format(fieldmask, undefmask))
  585. if fixedmask & undefmask:
  586. error(lineno, 'fixedmask overlaps undefmask (0x{0:08x} & 0x{1:08x})'
  587. .format(fixedmask, undefmask))
  588. if not is_format:
  589. allbits = fieldmask | fixedmask | undefmask
  590. if allbits != insnmask:
  591. error(lineno, 'bits left unspecified (0x{0:08x})'
  592. .format(allbits ^ insnmask))
  593. # end parse_general
  594. def build_multi_pattern(lineno, pats):
  595. """Validate the Patterns going into a MultiPattern."""
  596. global patterns
  597. global insnmask
  598. if len(pats) < 2:
  599. error(lineno, 'less than two patterns within braces')
  600. fixedmask = insnmask
  601. undefmask = insnmask
  602. # Collect fixed/undefmask for all of the children.
  603. # Move the defining lineno back to that of the first child.
  604. for p in pats:
  605. fixedmask &= p.fixedmask
  606. undefmask &= p.undefmask
  607. if p.lineno < lineno:
  608. lineno = p.lineno
  609. repeat = True
  610. while repeat:
  611. if fixedmask == 0:
  612. error(lineno, 'no overlap in patterns within braces')
  613. fixedbits = None
  614. for p in pats:
  615. thisbits = p.fixedbits & fixedmask
  616. if fixedbits is None:
  617. fixedbits = thisbits
  618. elif fixedbits != thisbits:
  619. fixedmask &= ~(fixedbits ^ thisbits)
  620. break
  621. else:
  622. repeat = False
  623. mp = MultiPattern(lineno, pats, fixedbits, fixedmask, undefmask)
  624. patterns.append(mp)
  625. # end build_multi_pattern
  626. def parse_file(f):
  627. """Parse all of the patterns within a file"""
  628. global patterns
  629. # Read all of the lines of the file. Concatenate lines
  630. # ending in backslash; discard empty lines and comments.
  631. toks = []
  632. lineno = 0
  633. nesting = 0
  634. saved_pats = []
  635. for line in f:
  636. lineno += 1
  637. # Expand and strip spaces, to find indent.
  638. line = line.rstrip()
  639. line = line.expandtabs()
  640. len1 = len(line)
  641. line = line.lstrip()
  642. len2 = len(line)
  643. # Discard comments
  644. end = line.find('#')
  645. if end >= 0:
  646. line = line[:end]
  647. t = line.split()
  648. if len(toks) != 0:
  649. # Next line after continuation
  650. toks.extend(t)
  651. else:
  652. # Allow completely blank lines.
  653. if len1 == 0:
  654. continue
  655. indent = len1 - len2
  656. # Empty line due to comment.
  657. if len(t) == 0:
  658. # Indentation must be correct, even for comment lines.
  659. if indent != nesting:
  660. error(lineno, 'indentation ', indent, ' != ', nesting)
  661. continue
  662. start_lineno = lineno
  663. toks = t
  664. # Continuation?
  665. if toks[-1] == '\\':
  666. toks.pop()
  667. continue
  668. name = toks[0]
  669. del toks[0]
  670. # End nesting?
  671. if name == '}':
  672. if nesting == 0:
  673. error(start_lineno, 'mismatched close brace')
  674. if len(toks) != 0:
  675. error(start_lineno, 'extra tokens after close brace')
  676. nesting -= 2
  677. if indent != nesting:
  678. error(start_lineno, 'indentation ', indent, ' != ', nesting)
  679. pats = patterns
  680. patterns = saved_pats.pop()
  681. build_multi_pattern(lineno, pats)
  682. toks = []
  683. continue
  684. # Everything else should have current indentation.
  685. if indent != nesting:
  686. error(start_lineno, 'indentation ', indent, ' != ', nesting)
  687. # Start nesting?
  688. if name == '{':
  689. if len(toks) != 0:
  690. error(start_lineno, 'extra tokens after open brace')
  691. saved_pats.append(patterns)
  692. patterns = []
  693. nesting += 2
  694. toks = []
  695. continue
  696. # Determine the type of object needing to be parsed.
  697. if name[0] == '%':
  698. parse_field(start_lineno, name[1:], toks)
  699. elif name[0] == '&':
  700. parse_arguments(start_lineno, name[1:], toks)
  701. elif name[0] == '@':
  702. parse_generic(start_lineno, True, name[1:], toks)
  703. else:
  704. parse_generic(start_lineno, False, name, toks)
  705. toks = []
  706. # end parse_file
  707. class Tree:
  708. """Class representing a node in a decode tree"""
  709. def __init__(self, fm, tm):
  710. self.fixedmask = fm
  711. self.thismask = tm
  712. self.subs = []
  713. self.base = None
  714. def str1(self, i):
  715. ind = str_indent(i)
  716. r = '{0}{1:08x}'.format(ind, self.fixedmask)
  717. if self.format:
  718. r += ' ' + self.format.name
  719. r += ' [\n'
  720. for (b, s) in self.subs:
  721. r += '{0} {1:08x}:\n'.format(ind, b)
  722. r += s.str1(i + 4) + '\n'
  723. r += ind + ']'
  724. return r
  725. def __str__(self):
  726. return self.str1(0)
  727. def output_code(self, i, extracted, outerbits, outermask):
  728. ind = str_indent(i)
  729. # If we identified all nodes below have the same format,
  730. # extract the fields now.
  731. if not extracted and self.base:
  732. output(ind, self.base.extract_name(),
  733. '(&u.f_', self.base.base.name, ', insn);\n')
  734. extracted = True
  735. # Attempt to aid the compiler in producing compact switch statements.
  736. # If the bits in the mask are contiguous, extract them.
  737. sh = is_contiguous(self.thismask)
  738. if sh > 0:
  739. # Propagate SH down into the local functions.
  740. def str_switch(b, sh=sh):
  741. return '(insn >> {0}) & 0x{1:x}'.format(sh, b >> sh)
  742. def str_case(b, sh=sh):
  743. return '0x{0:x}'.format(b >> sh)
  744. else:
  745. def str_switch(b):
  746. return 'insn & 0x{0:08x}'.format(b)
  747. def str_case(b):
  748. return '0x{0:08x}'.format(b)
  749. output(ind, 'switch (', str_switch(self.thismask), ') {\n')
  750. for b, s in sorted(self.subs):
  751. assert (self.thismask & ~s.fixedmask) == 0
  752. innermask = outermask | self.thismask
  753. innerbits = outerbits | b
  754. output(ind, 'case ', str_case(b), ':\n')
  755. output(ind, ' /* ',
  756. str_match_bits(innerbits, innermask), ' */\n')
  757. s.output_code(i + 4, extracted, innerbits, innermask)
  758. output(ind, ' return false;\n')
  759. output(ind, '}\n')
  760. # end Tree
  761. def build_tree(pats, outerbits, outermask):
  762. # Find the intersection of all remaining fixedmask.
  763. innermask = ~outermask & insnmask
  764. for i in pats:
  765. innermask &= i.fixedmask
  766. if innermask == 0:
  767. text = 'overlapping patterns:'
  768. for p in pats:
  769. text += '\n' + p.file + ':' + str(p.lineno) + ': ' + str(p)
  770. error_with_file(pats[0].file, pats[0].lineno, text)
  771. fullmask = outermask | innermask
  772. # Sort each element of pats into the bin selected by the mask.
  773. bins = {}
  774. for i in pats:
  775. fb = i.fixedbits & innermask
  776. if fb in bins:
  777. bins[fb].append(i)
  778. else:
  779. bins[fb] = [i]
  780. # We must recurse if any bin has more than one element or if
  781. # the single element in the bin has not been fully matched.
  782. t = Tree(fullmask, innermask)
  783. for b, l in bins.items():
  784. s = l[0]
  785. if len(l) > 1 or s.fixedmask & ~fullmask != 0:
  786. s = build_tree(l, b | outerbits, fullmask)
  787. t.subs.append((b, s))
  788. return t
  789. # end build_tree
  790. def prop_format(tree):
  791. """Propagate Format objects into the decode tree"""
  792. # Depth first search.
  793. for (b, s) in tree.subs:
  794. if isinstance(s, Tree):
  795. prop_format(s)
  796. # If all entries in SUBS have the same format, then
  797. # propagate that into the tree.
  798. f = None
  799. for (b, s) in tree.subs:
  800. if f is None:
  801. f = s.base
  802. if f is None:
  803. return
  804. if f is not s.base:
  805. return
  806. tree.base = f
  807. # end prop_format
  808. def main():
  809. global arguments
  810. global formats
  811. global patterns
  812. global allpatterns
  813. global translate_scope
  814. global translate_prefix
  815. global output_fd
  816. global output_file
  817. global input_file
  818. global insnwidth
  819. global insntype
  820. global insnmask
  821. global decode_function
  822. decode_scope = 'static '
  823. long_opts = ['decode=', 'translate=', 'output=', 'insnwidth=',
  824. 'static-decode=']
  825. try:
  826. (opts, args) = getopt.getopt(sys.argv[1:], 'o:w:', long_opts)
  827. except getopt.GetoptError as err:
  828. error(0, err)
  829. for o, a in opts:
  830. if o in ('-o', '--output'):
  831. output_file = a
  832. elif o == '--decode':
  833. decode_function = a
  834. decode_scope = ''
  835. elif o == '--static-decode':
  836. decode_function = a
  837. elif o == '--translate':
  838. translate_prefix = a
  839. translate_scope = ''
  840. elif o in ('-w', '--insnwidth'):
  841. insnwidth = int(a)
  842. if insnwidth == 16:
  843. insntype = 'uint16_t'
  844. insnmask = 0xffff
  845. elif insnwidth != 32:
  846. error(0, 'cannot handle insns of width', insnwidth)
  847. else:
  848. assert False, 'unhandled option'
  849. if len(args) < 1:
  850. error(0, 'missing input file')
  851. for filename in args:
  852. input_file = filename
  853. f = open(filename, 'r')
  854. parse_file(f)
  855. f.close()
  856. t = build_tree(patterns, 0, 0)
  857. prop_format(t)
  858. if output_file:
  859. output_fd = open(output_file, 'w')
  860. else:
  861. output_fd = sys.stdout
  862. output_autogen()
  863. for n in sorted(arguments.keys()):
  864. f = arguments[n]
  865. f.output_def()
  866. # A single translate function can be invoked for different patterns.
  867. # Make sure that the argument sets are the same, and declare the
  868. # function only once.
  869. out_pats = {}
  870. for i in allpatterns:
  871. if i.name in out_pats:
  872. p = out_pats[i.name]
  873. if i.base.base != p.base.base:
  874. error(0, i.name, ' has conflicting argument sets')
  875. else:
  876. i.output_decl()
  877. out_pats[i.name] = i
  878. output('\n')
  879. for n in sorted(formats.keys()):
  880. f = formats[n]
  881. f.output_extract()
  882. output(decode_scope, 'bool ', decode_function,
  883. '(DisasContext *ctx, ', insntype, ' insn)\n{\n')
  884. i4 = str_indent(4)
  885. if len(allpatterns) != 0:
  886. output(i4, 'union {\n')
  887. for n in sorted(arguments.keys()):
  888. f = arguments[n]
  889. output(i4, i4, f.struct_name(), ' f_', f.name, ';\n')
  890. output(i4, '} u;\n\n')
  891. t.output_code(4, False, 0, 0)
  892. output(i4, 'return false;\n')
  893. output('}\n')
  894. if output_file:
  895. output_fd.close()
  896. # end main
  897. if __name__ == '__main__':
  898. main()