Mercurial > lcfOS
annotate python/ppci/target/basetarget.py @ 381:6df89163e114
Fix section and ldr pseudo instruction
author | Windel Bouwman |
---|---|
date | Sat, 26 Apr 2014 17:41:56 +0200 |
parents | 39bf68bf1891 |
children | d056b552d3f4 |
rev | line source |
---|---|
362 | 1 import types |
200 | 2 from ppci import CompilerError |
199 | 3 |
4 """ | |
5 Base classes for defining a target | |
6 """ | |
7 | |
234 | 8 class Instruction: |
292 | 9 """ Base instruction class """ |
234 | 10 def encode(self): |
335 | 11 return bytes() |
292 | 12 |
335 | 13 def relocations(self): |
14 return [] | |
15 | |
16 def symbols(self): | |
17 return [] | |
234 | 18 |
381 | 19 def literals(self, add_literal): |
20 pass | |
21 | |
234 | 22 |
280
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
277
diff
changeset
|
23 class Nop(Instruction): |
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
277
diff
changeset
|
24 """ Instruction that does nothing and has zero size """ |
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
277
diff
changeset
|
25 def encode(self): |
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
277
diff
changeset
|
26 return bytes() |
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
277
diff
changeset
|
27 |
354 | 28 def __repr__(self): |
29 return 'NOP' | |
30 | |
280
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
277
diff
changeset
|
31 |
234 | 32 class PseudoInstruction(Instruction): |
33 pass | |
34 | |
35 | |
36 class Label(PseudoInstruction): | |
206 | 37 def __init__(self, name): |
38 self.name = name | |
39 | |
235 | 40 def __repr__(self): |
41 return '{}:'.format(self.name) | |
42 | |
335 | 43 def symbols(self): |
44 return [self.name] | |
235 | 45 |
46 | |
234 | 47 class Comment(PseudoInstruction): |
48 def __init__(self, txt): | |
49 self.txt = txt | |
249 | 50 |
235 | 51 def encode(self): |
52 return bytes() | |
249 | 53 |
234 | 54 def __repr__(self): |
55 return '; {}'.format(self.txt) | |
56 | |
235 | 57 |
234 | 58 class Alignment(PseudoInstruction): |
59 def __init__(self, a): | |
60 self.align = a | |
235 | 61 |
62 def __repr__(self): | |
63 return 'ALIGN({})'.format(self.align) | |
64 | |
234 | 65 def encode(self): |
66 pad = [] | |
335 | 67 # TODO |
68 address = 0 | |
235 | 69 while (address % self.align) != 0: |
234 | 70 address += 1 |
71 pad.append(0) | |
72 return bytes(pad) | |
73 | |
292 | 74 |
346 | 75 class Register: |
199 | 76 def __init__(self, name): |
77 self.name = name | |
78 | |
366 | 79 def __gt__(self, other): |
80 return self.num > other.num | |
81 | |
199 | 82 |
364 | 83 class LabelAddress: |
84 def __init__(self, name): | |
85 self.name = name | |
86 | |
87 | |
199 | 88 class Target: |
201 | 89 def __init__(self, name, desc=''): |
90 self.name = name | |
91 self.desc = desc | |
200 | 92 self.registers = [] |
341 | 93 self.byte_sizes = {'int' : 4} # For front end! |
354 | 94 self.byte_sizes['byte'] = 1 |
341 | 95 |
346 | 96 # For lowering: |
97 self.lower_functions = {} | |
98 | |
341 | 99 # For assembler: |
100 self.assembler_rules = [] | |
101 self.asm_keywords = [] | |
102 | |
346 | 103 self.generate_base_rules() |
104 | |
105 def generate_base_rules(self): | |
345 | 106 # Base rules for constants: |
107 self.add_rule('imm32', ['val32'], lambda x: x[0].val) | |
108 self.add_rule('imm32', ['imm16'], lambda x: x[0]) | |
109 | |
110 self.add_rule('imm16', ['val16'], lambda x: x[0].val) | |
111 self.add_rule('imm16', ['imm12'], lambda x: x[0]) | |
112 | |
113 self.add_rule('imm12', ['val12'], lambda x: x[0].val) | |
114 self.add_rule('imm12', ['imm8'], lambda x: x[0]) | |
115 | |
116 self.add_rule('imm8', ['val8'], lambda x: x[0].val) | |
117 self.add_rule('imm8', ['imm5'], lambda x: x[0]) | |
118 | |
119 self.add_rule('imm5', ['val5'], lambda x: x[0].val) | |
120 self.add_rule('imm5', ['imm3'], lambda x: x[0]) | |
121 | |
122 self.add_rule('imm3', ['val3'], lambda x: x[0].val) | |
123 | |
341 | 124 def add_keyword(self, kw): |
125 self.asm_keywords.append(kw) | |
126 | |
127 def add_instruction(self, rhs, f): | |
128 self.add_rule('instruction', rhs, f) | |
129 | |
130 def add_rule(self, lhs, rhs, f): | |
362 | 131 if type(f) is int: |
132 f2 = lambda x: f | |
133 else: | |
134 f2 = f | |
135 assert type(f2) is types.FunctionType | |
136 self.assembler_rules.append((lhs, rhs, f2)) | |
200 | 137 |
346 | 138 def lower_frame_to_stream(self, frame, outs): |
139 """ Lower instructions from frame to output stream """ | |
140 for im in frame.instructions: | |
141 if isinstance(im.assem, Instruction): | |
142 outs.emit(im.assem) | |
143 else: | |
381 | 144 # TODO assert isinstance(Abs |
346 | 145 ins = self.lower_functions[im.assem](im) |
146 outs.emit(ins) | |
201 | 147 |
346 | 148 def add_lowering(self, cls, f): |
149 """ Add a function to the table of lowering options for this target """ | |
150 self.lower_functions[cls] = f |