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