aboutsummaryrefslogtreecommitdiff
path: root/riscv/dispatch
blob: 231853cb1881d949c74e25ca07dd76cd1d65606c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#!/usr/bin/env python
import sys

if len(sys.argv) == 3:
  numfiles = int(sys.argv[1])
  tablesz = int(sys.argv[2])
  filenum = numfiles+1
else:
  filenum = int(sys.argv[1])
  numfiles = int(sys.argv[2])
  tablesz = int(sys.argv[3])

match = {}
mask = {}
seen = {}
for line in sys.stdin:
  (name, mtch, msk) = line.split('(')[1].split(')')[0].split(',')
  match[name] = int(mtch,16)
  mask[name] = int(msk,16)

redundant = {}
for name in match.iterkeys():
  if (mask[name] & (tablesz-1)) == mask[name]:
    for i in range(match[name]+1, tablesz):
      if (i & mask[name]) == match[name]:
        redundant[i] = match[name]

illegal = -1
for i in range(0, tablesz):
  used = 0
  for name in match.iterkeys():
    if match[name] % tablesz == (i & mask[name]):
      used = 1
  if not used and illegal == -1:
    illegal = i
  elif not used:
    redundant[i] = illegal

if filenum == numfiles:
  print '#include "processor.h"'
  print 'const insn_func_t processor_t::dispatch_table[%d] = {' % (2*tablesz)
  for xl in [32, 64]:
    for i in range(0, tablesz):
      func = i
      if i in redundant:
        func = redundant[i]
      print '  &processor_t::insn_func_%d_%d,' % (xl, func)
  print '};'

if filenum == numfiles+1:
  print '#define get_insn_func(insn, sr) \\'
  print '  processor_t::dispatch_table[((((sr) & SR_S) ? (sr & SR_S64) : (SR_U64)) ? %d : 0) + ((insn).bits %% %d)]' % (tablesz, tablesz)
  
  print 'static const insn_func_t dispatch_table[%d];' % (2*tablesz)
  for i in range(0, tablesz):
    if i not in redundant:
      print 'reg_t insn_func_32_%d(insn_t insn, reg_t reg);' % i
      print 'reg_t insn_func_64_%d(insn_t insn, reg_t reg);' % i
  sys.exit(0)

print '#include "insn_header.h"'

for i in range(0, tablesz):
  for xl in [32, 64]:
    if i % numfiles != filenum or i in redundant:
      continue

    print 'reg_t processor_t::insn_func_%d_%d(insn_t insn, reg_t pc)' % (xl, i)
    print '{'
    for name in match.iterkeys():
      if match[name] % tablesz == (i & mask[name]):
        print '  if((insn.bits & 0x%x) == 0x%x)' % (mask[name] & ~(tablesz-1), \
                                                    match[name] & ~(tablesz-1))
        print '  {'
        print '    int xprlen = %d;' % xl
        print '    reg_t npc = sext_xprlen(pc + insn_length(0x%x));' % match[name]
        print '    #include "insns/%s.h"' % name
        print '    return npc;'
        print '  }'
        print '  else',

    print '  throw trap_illegal_instruction;'
    print '}\n'