203
|
1 from asmnodes import ASymbol, AInstruction, ALabel
|
200
|
2 from ppci import CompilerError
|
199
|
3
|
|
4 """
|
|
5 Base classes for defining a target
|
|
6 """
|
|
7
|
|
8 # Machine code interface:
|
|
9 class Operand:
|
|
10 """ Single machine operand """
|
|
11 pass
|
|
12
|
|
13 class Register(Operand):
|
|
14 def __init__(self, name):
|
|
15 self.name = name
|
|
16
|
|
17 class Instruction:
|
201
|
18 def encode(self):
|
|
19 raise NotImplementedError('TODO')
|
199
|
20
|
|
21 class Target:
|
201
|
22 def __init__(self, name, desc=''):
|
|
23 self.name = name
|
|
24 self.desc = desc
|
200
|
25 self.registers = []
|
199
|
26 self.instructions = []
|
200
|
27
|
201
|
28 def instruction(self, cls):
|
|
29 """ Decorator function that registers an instruction to this target """
|
202
|
30 self.addInstruction(cls)
|
201
|
31 return cls
|
|
32
|
202
|
33 def addInstruction(self, ins_class):
|
|
34 self.instructions.append(ins_class)
|
|
35
|
200
|
36 def mapOperand(self, operand):
|
|
37 """ Try to map an operand to a target type """
|
|
38 if type(operand) is ASymbol:
|
|
39 # Try to map to register:
|
|
40 regs = {}
|
|
41 for r in self.registers:
|
|
42 regs[r.name] = r
|
|
43 if operand.name in regs:
|
|
44 return regs[operand.name]
|
201
|
45 raise CompilerError('Cannot map {0}'.format(operand))
|
199
|
46
|
200
|
47 def mapInstruction(self, vi):
|
203
|
48 assert type(vi) is AInstruction
|
200
|
49 """ Map ast tree to real instruction for this target """
|
199
|
50
|
200
|
51 # map to real operands:
|
|
52
|
|
53 # look for a suitable instruction
|
|
54 for ic in self.instructions:
|
203
|
55 if ic.mnemonic == vi.mnemonic and len(ic.operands) == len(vi.operands):
|
|
56 # Try to map operands to the correct operand types:
|
|
57 rops = [roptype.Create(vop) for roptype, vop in zip(ic.operands, vi.operands)]
|
|
58
|
|
59 # Check if we succeeded:
|
|
60 optypes = tuple(map(type, rops))
|
|
61 if ic.operands == optypes:
|
|
62 return ic(*rops)
|
201
|
63 raise CompilerError('No suitable instruction found for "{0}"'.format(vi))
|
200
|
64
|