2
0

decodetree.py 38 KB

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