200
|
1 from asmnodes import ASymbol, AInstruction
|
|
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 """
|
|
30 self.instructions.append(cls)
|
|
31 return cls
|
|
32
|
200
|
33 def mapOperand(self, operand):
|
|
34 """ Try to map an operand to a target type """
|
|
35 if type(operand) is ASymbol:
|
|
36 # Try to map to register:
|
|
37 regs = {}
|
|
38 for r in self.registers:
|
|
39 regs[r.name] = r
|
|
40 if operand.name in regs:
|
|
41 return regs[operand.name]
|
201
|
42 raise CompilerError('Cannot map {0}'.format(operand))
|
199
|
43
|
200
|
44 def mapInstruction(self, vi):
|
|
45 """ Map ast tree to real instruction for this target """
|
199
|
46
|
200
|
47 # map to real operands:
|
|
48 rops = tuple(map(self.mapOperand, vi.operands))
|
|
49 optypes = tuple(map(type, rops))
|
|
50
|
|
51 # look for a suitable instruction
|
|
52 for ic in self.instructions:
|
|
53 if ic.mnemonic == vi.opcode and ic.operands == optypes:
|
|
54 ri = ic(*rops)
|
|
55 return ri
|
201
|
56 raise CompilerError('No suitable instruction found for "{0}"'.format(vi))
|
200
|
57
|