comparison python/target/basetarget.py @ 290:7b38782ed496

File moves
author Windel Bouwman
date Sun, 24 Nov 2013 11:24:15 +0100
parents python/target.py@02385f62f250
children 534b94b40aa8
comparison
equal deleted inserted replaced
289:bd2593de3ff8 290:7b38782ed496
1 from asmnodes import ASymbol, AInstruction, ANumber
2 from ppci import CompilerError
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 # standard immediates:
14
15 class Imm8:
16 def __init__(self, imm):
17 assert imm < 256
18 self.imm = imm
19
20 @classmethod
21 def Create(cls, vop):
22 if type(vop) is ANumber and vop.number < 256:
23 return cls(vop.number)
24
25 class Imm7:
26 def __init__(self, imm):
27 assert imm < 128
28 self.imm = imm
29
30 @classmethod
31 def Create(cls, vop):
32 if type(vop) is ANumber and vop.number < 128:
33 return cls(vop.number)
34
35 class Imm3:
36 def __init__(self, imm):
37 assert imm < 8
38 assert type(imm) is int
39 self.imm = imm
40
41 @classmethod
42 def Create(cls, vop):
43 if type(vop) is ANumber and vop.number < 8:
44 return cls(vop.number)
45
46 class Imm32:
47 def __init__(self, imm):
48 assert imm < 2**32
49 assert type(imm) is int
50 self.imm = imm
51
52 @classmethod
53 def Create(cls, vop):
54 if type(vop) is ANumber and vop.number < 2**32:
55 return cls(vop.number)
56
57
58 class LabelRef:
59 def __init__(self, name):
60 assert type(name) is str
61 self.name = name
62
63 @classmethod
64 def Create(cls, vop):
65 if type(vop) is ASymbol:
66 return cls(vop.name)
67
68 class Instruction:
69 def encode(self):
70 raise NotImplementedError('Instruction {0} has no encode yet, TODO'.format(type(self)))
71 def resolve(self, f):
72 pass
73
74
75 class Nop(Instruction):
76 """ Instruction that does nothing and has zero size """
77 def encode(self):
78 return bytes()
79
80
81
82 class PseudoInstruction(Instruction):
83 pass
84
85
86 class Label(PseudoInstruction):
87 def __init__(self, name):
88 self.name = name
89 self.address = 0
90
91 def __repr__(self):
92 return '{}:'.format(self.name)
93
94 def encode(self):
95 return bytes()
96
97 @classmethod
98 def Create(cls, vop):
99 if type(vop) is ASymbol:
100 name = vop.name
101 return cls(name)
102
103
104 class Comment(PseudoInstruction):
105 def __init__(self, txt):
106 self.txt = txt
107
108 def encode(self):
109 return bytes()
110
111 def __repr__(self):
112 return '; {}'.format(self.txt)
113
114
115 class Alignment(PseudoInstruction):
116 def __init__(self, a):
117 self.align = a
118
119 def __repr__(self):
120 return 'ALIGN({})'.format(self.align)
121
122 def encode(self):
123 pad = []
124 address = self.address
125 while (address % self.align) != 0:
126 address += 1
127 pad.append(0)
128 return bytes(pad)
129
130 class DebugInfo(PseudoInstruction):
131 def __init__(self, i):
132 self.info = i
133
134 def __repr__(self):
135 return 'DebugInfo: {}'.format(self.info)
136
137 def encode(self):
138 return bytes()
139
140 class Register(Operand):
141 def __init__(self, name):
142 self.name = name
143
144
145 class Target:
146 def __init__(self, name, desc=''):
147 self.name = name
148 self.desc = desc
149 self.registers = []
150 self.instructions = []
151
152 def instruction(self, cls):
153 """ Decorator function that registers an instruction to this target """
154 self.addInstruction(cls)
155 return cls
156
157 def check(self):
158 """ Check target """
159 for i in self.instructions:
160 assert hasattr(i, 'mnemonic')
161 assert hasattr(i, 'operands'), str(i)
162 assert type(i.mnemonic) is str
163 assert type(i.operands) is tuple, str(i)
164
165 def addInstruction(self, ins_class):
166 self.instructions.append(ins_class)
167
168 def mapOperand(self, operand):
169 """ Try to map an operand to a target type """
170 if type(operand) is ASymbol:
171 # Try to map to register:
172 regs = {}
173 for r in self.registers:
174 regs[r.name] = r
175 if operand.name in regs:
176 return regs[operand.name]
177 raise CompilerError('Cannot map {0}'.format(operand))
178
179 def mapInstruction(self, vi):
180 assert type(vi) is AInstruction
181 """ Map ast tree to real instruction for this target """
182
183 # map to real operands:
184 if vi.mnemonic.upper() == 'ALIGN' and len(vi.operands) == 1:
185 if type(vi.operands[0]) == ANumber:
186 return Alignment(vi.operands[0].number)
187
188 # look for a suitable instruction
189 for ic in self.instructions:
190 if ic.mnemonic.upper() == vi.mnemonic.upper() and len(ic.operands) == len(vi.operands):
191 # Try to map operands to the correct operand types:
192 rops = [roptype.Create(vop) for roptype, vop in zip(ic.operands, vi.operands)]
193
194 # Check if we succeeded:
195 if all(isinstance(rop, optype) for rop, optype in zip(rops, ic.operands)):
196 return ic(*rops)
197 raise CompilerError('No suitable instruction found for "{0}"'.format(vi))
198