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