add dump function for regs
[soc.git] / src / soc / decoder / isa / caller.py
1 from functools import wraps
2 from soc.decoder.orderedset import OrderedSet
3 from soc.decoder.selectable_int import SelectableInt, selectconcat
4
5 def create_args(reglist, extra=None):
6 args = OrderedSet()
7 for reg in reglist:
8 args.add(reg)
9 args = list(args)
10 if extra:
11 args = [extra] + args
12 return args
13
14 class Mem:
15
16 def __init__(self):
17 self.mem = []
18 for i in range(128):
19 self.mem.append(i)
20
21 def __call__(self, addr, sz):
22 res = []
23 for s in range(sz): # TODO: big/little-end
24 res.append(SelectableInt(self.mem[addr.value + s], 8))
25 print ("memread", addr, sz, res)
26 return selectconcat(*res)
27
28 def memassign(self, addr, sz, val):
29 print ("memassign", addr, sz, val)
30 for s in range(sz):
31 byte = (val.value) >> (s*8) & 0xff # TODO: big/little-end
32 self.mem[addr.value + s] = byte
33
34
35 class GPR(dict):
36 def __init__(self, decoder, regfile):
37 dict.__init__(self)
38 self.sd = decoder
39 for i in range(32):
40 self[i] = SelectableInt(regfile[i], 64)
41
42 def __call__(self, ridx):
43 return self[ridx]
44
45 def set_form(self, form):
46 self.form = form
47
48 def getz(self, rnum):
49 #rnum = rnum.value # only SelectableInt allowed
50 print("GPR getzero", rnum)
51 if rnum == 0:
52 return SelectableInt(0, 64)
53 return self[rnum]
54
55 def _get_regnum(self, attr):
56 getform = self.sd.sigforms[self.form]
57 rnum = getattr(getform, attr)
58 return rnum
59
60 def ___getitem__(self, attr):
61 print("GPR getitem", attr)
62 rnum = self._get_regnum(attr)
63 return self.regfile[rnum]
64
65 def dump(self):
66 for i in range(len(self)):
67 print("reg", i, hex(self[i].value))
68
69
70
71 class ISACaller:
72 # decoder2 - an instance of power_decoder2
73 # regfile - a list of initial values for the registers
74 def __init__(self, decoder2, regfile):
75 self.gpr = GPR(decoder2, regfile)
76 self.mem = Mem()
77 self.namespace = {'GPR': self.gpr,
78 'MEM': self.mem,
79 'memassign': self.memassign
80 }
81 self.decoder = decoder2
82
83 def memassign(self, ea, sz, val):
84 self.mem.memassign(ea, sz, val)
85
86 def prep_namespace(self):
87 si = yield self.decoder.SI
88 self.namespace.SI = SelectableInt(si, bits=16)
89
90 def call(self, name):
91 function, read_regs, uninit_regs, write_regs = self.instrs[name]
92 input_names = create_args(read_regs | uninit_regs)
93 print(input_names)
94
95 inputs = []
96 for name in input_names:
97 regnum = yield getattr(self.decoder, name)
98 print('reading reg %d' % regnum)
99 inputs.append(self.gpr(regnum))
100 print(inputs)
101 results = function(self, *inputs)
102 print(results)
103
104 output_names = create_args(write_regs)
105 for name, output in zip(output_names, results):
106 regnum = yield getattr(self.decoder, name)
107 print('writing reg %d' % regnum)
108 self.gpr[regnum] = output
109
110
111 def inject():
112 """ Decorator factory. """
113 def variable_injector(func):
114 @wraps(func)
115 def decorator(*args, **kwargs):
116 try:
117 func_globals = func.__globals__ # Python 2.6+
118 except AttributeError:
119 func_globals = func.func_globals # Earlier versions.
120
121 context = args[0].namespace
122 saved_values = func_globals.copy() # Shallow copy of dict.
123 func_globals.update(context)
124
125 result = func(*args, **kwargs)
126 #exec (func.__code__, func_globals)
127
128 #finally:
129 # func_globals = saved_values # Undo changes.
130
131 return result
132
133 return decorator
134
135 return variable_injector
136