874a06973f3666d63917ce2adcf4a11f4efc4690
[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(0, len(self), 8):
67 s = []
68 for j in range(8):
69 s.append("%08x" % self[i+j].value)
70 s = ' '.join(s)
71 print("reg", "%2d" % i, s)
72
73
74 class ISACaller:
75 # decoder2 - an instance of power_decoder2
76 # regfile - a list of initial values for the registers
77 def __init__(self, decoder2, regfile):
78 self.gpr = GPR(decoder2, regfile)
79 self.mem = Mem()
80 self.namespace = {'GPR': self.gpr,
81 'MEM': self.mem,
82 'memassign': self.memassign
83 }
84 self.decoder = decoder2
85
86 def memassign(self, ea, sz, val):
87 self.mem.memassign(ea, sz, val)
88
89 def prep_namespace(self):
90 si = yield self.decoder.SI
91 self.namespace['SI'] = SelectableInt(si, bits=16)
92
93 def call(self, name):
94 yield from self.prep_namespace()
95
96 function, read_regs, uninit_regs, write_regs = self.instrs[name]
97 input_names = create_args(read_regs | uninit_regs)
98 print(input_names)
99
100 inputs = []
101 for name in input_names:
102 regnum = yield getattr(self.decoder, name)
103 print('reading reg %d' % regnum)
104 inputs.append(self.gpr(regnum))
105 print(inputs)
106 results = function(self, *inputs)
107 print(results)
108
109 output_names = create_args(write_regs)
110 for name, output in zip(output_names, results):
111 regnum = yield getattr(self.decoder, name)
112 print('writing reg %d' % regnum)
113 self.gpr[regnum] = output.narrow(64)
114
115
116 def inject():
117 """ Decorator factory. """
118 def variable_injector(func):
119 @wraps(func)
120 def decorator(*args, **kwargs):
121 try:
122 func_globals = func.__globals__ # Python 2.6+
123 except AttributeError:
124 func_globals = func.func_globals # Earlier versions.
125
126 context = args[0].namespace
127 saved_values = func_globals.copy() # Shallow copy of dict.
128 func_globals.update(context)
129
130 result = func(*args, **kwargs)
131 #exec (func.__code__, func_globals)
132
133 #finally:
134 # func_globals = saved_values # Undo changes.
135
136 return result
137
138 return decorator
139
140 return variable_injector
141