annotate python/ppci/target/basetarget.py @ 386:2a970e7270e2

Added repeat assembler macro
author Windel Bouwman
date Thu, 01 May 2014 17:40:59 +0200
parents d056b552d3f4
children
rev   line source
362
c05ab629976a Added CPUID for arm
Windel Bouwman
parents: 354
diff changeset
1 import types
200
5e391d9a3381 Split off asm nodes
Windel Bouwman
parents: 199
diff changeset
2 from ppci import CompilerError
385
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
3 from ..bitfun import encode_imm32
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
4 import struct
199
a690473b79e2 Added msp430 target
Windel Bouwman
parents:
diff changeset
5
a690473b79e2 Added msp430 target
Windel Bouwman
parents:
diff changeset
6 """
a690473b79e2 Added msp430 target
Windel Bouwman
parents:
diff changeset
7 Base classes for defining a target
a690473b79e2 Added msp430 target
Windel Bouwman
parents:
diff changeset
8 """
a690473b79e2 Added msp430 target
Windel Bouwman
parents:
diff changeset
9
234
Windel Bouwman
parents: 219
diff changeset
10 class Instruction:
292
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents: 290
diff changeset
11 """ Base instruction class """
234
Windel Bouwman
parents: 219
diff changeset
12 def encode(self):
335
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
13 return bytes()
292
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents: 290
diff changeset
14
335
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
15 def relocations(self):
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
16 return []
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
17
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
18 def symbols(self):
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
19 return []
234
Windel Bouwman
parents: 219
diff changeset
20
381
6df89163e114 Fix section and ldr pseudo instruction
Windel Bouwman
parents: 366
diff changeset
21 def literals(self, add_literal):
6df89163e114 Fix section and ldr pseudo instruction
Windel Bouwman
parents: 366
diff changeset
22 pass
6df89163e114 Fix section and ldr pseudo instruction
Windel Bouwman
parents: 366
diff changeset
23
234
Windel Bouwman
parents: 219
diff changeset
24
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 277
diff changeset
25 class Nop(Instruction):
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 277
diff changeset
26 """ Instruction that does nothing and has zero size """
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 277
diff changeset
27 def encode(self):
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 277
diff changeset
28 return bytes()
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 277
diff changeset
29
354
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 346
diff changeset
30 def __repr__(self):
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 346
diff changeset
31 return 'NOP'
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 346
diff changeset
32
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 277
diff changeset
33
234
Windel Bouwman
parents: 219
diff changeset
34 class PseudoInstruction(Instruction):
Windel Bouwman
parents: 219
diff changeset
35 pass
Windel Bouwman
parents: 219
diff changeset
36
Windel Bouwman
parents: 219
diff changeset
37
Windel Bouwman
parents: 219
diff changeset
38 class Label(PseudoInstruction):
206
6c6bf8890d8a Added push and pop encodings
Windel Bouwman
parents: 205
diff changeset
39 def __init__(self, name):
6c6bf8890d8a Added push and pop encodings
Windel Bouwman
parents: 205
diff changeset
40 self.name = name
6c6bf8890d8a Added push and pop encodings
Windel Bouwman
parents: 205
diff changeset
41
235
ff40407c0240 Fix ALabel to Label
Windel Bouwman
parents: 234
diff changeset
42 def __repr__(self):
ff40407c0240 Fix ALabel to Label
Windel Bouwman
parents: 234
diff changeset
43 return '{}:'.format(self.name)
ff40407c0240 Fix ALabel to Label
Windel Bouwman
parents: 234
diff changeset
44
335
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
45 def symbols(self):
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
46 return [self.name]
235
ff40407c0240 Fix ALabel to Label
Windel Bouwman
parents: 234
diff changeset
47
ff40407c0240 Fix ALabel to Label
Windel Bouwman
parents: 234
diff changeset
48
234
Windel Bouwman
parents: 219
diff changeset
49 class Comment(PseudoInstruction):
Windel Bouwman
parents: 219
diff changeset
50 def __init__(self, txt):
Windel Bouwman
parents: 219
diff changeset
51 self.txt = txt
249
e41e4109addd Added current position arrow
Windel Bouwman
parents: 236
diff changeset
52
235
ff40407c0240 Fix ALabel to Label
Windel Bouwman
parents: 234
diff changeset
53 def encode(self):
ff40407c0240 Fix ALabel to Label
Windel Bouwman
parents: 234
diff changeset
54 return bytes()
249
e41e4109addd Added current position arrow
Windel Bouwman
parents: 236
diff changeset
55
234
Windel Bouwman
parents: 219
diff changeset
56 def __repr__(self):
Windel Bouwman
parents: 219
diff changeset
57 return '; {}'.format(self.txt)
Windel Bouwman
parents: 219
diff changeset
58
235
ff40407c0240 Fix ALabel to Label
Windel Bouwman
parents: 234
diff changeset
59
234
Windel Bouwman
parents: 219
diff changeset
60 class Alignment(PseudoInstruction):
Windel Bouwman
parents: 219
diff changeset
61 def __init__(self, a):
Windel Bouwman
parents: 219
diff changeset
62 self.align = a
235
ff40407c0240 Fix ALabel to Label
Windel Bouwman
parents: 234
diff changeset
63
ff40407c0240 Fix ALabel to Label
Windel Bouwman
parents: 234
diff changeset
64 def __repr__(self):
ff40407c0240 Fix ALabel to Label
Windel Bouwman
parents: 234
diff changeset
65 return 'ALIGN({})'.format(self.align)
ff40407c0240 Fix ALabel to Label
Windel Bouwman
parents: 234
diff changeset
66
234
Windel Bouwman
parents: 219
diff changeset
67 def encode(self):
Windel Bouwman
parents: 219
diff changeset
68 pad = []
335
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
69 # TODO
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
70 address = 0
235
ff40407c0240 Fix ALabel to Label
Windel Bouwman
parents: 234
diff changeset
71 while (address % self.align) != 0:
234
Windel Bouwman
parents: 219
diff changeset
72 address += 1
Windel Bouwman
parents: 219
diff changeset
73 pad.append(0)
Windel Bouwman
parents: 219
diff changeset
74 return bytes(pad)
Windel Bouwman
parents: 219
diff changeset
75
292
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents: 290
diff changeset
76
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
77 class Register:
199
a690473b79e2 Added msp430 target
Windel Bouwman
parents:
diff changeset
78 def __init__(self, name):
a690473b79e2 Added msp430 target
Windel Bouwman
parents:
diff changeset
79 self.name = name
a690473b79e2 Added msp430 target
Windel Bouwman
parents:
diff changeset
80
366
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 364
diff changeset
81 def __gt__(self, other):
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 364
diff changeset
82 return self.num > other.num
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 364
diff changeset
83
199
a690473b79e2 Added msp430 target
Windel Bouwman
parents:
diff changeset
84
364
c49459768aaa Work on globals
Windel Bouwman
parents: 363
diff changeset
85 class LabelAddress:
c49459768aaa Work on globals
Windel Bouwman
parents: 363
diff changeset
86 def __init__(self, name):
c49459768aaa Work on globals
Windel Bouwman
parents: 363
diff changeset
87 self.name = name
c49459768aaa Work on globals
Windel Bouwman
parents: 363
diff changeset
88
c49459768aaa Work on globals
Windel Bouwman
parents: 363
diff changeset
89
199
a690473b79e2 Added msp430 target
Windel Bouwman
parents:
diff changeset
90 class Target:
201
d5debbfc0200 Added all 27 core instructions of msp430
Windel Bouwman
parents: 200
diff changeset
91 def __init__(self, name, desc=''):
d5debbfc0200 Added all 27 core instructions of msp430
Windel Bouwman
parents: 200
diff changeset
92 self.name = name
d5debbfc0200 Added all 27 core instructions of msp430
Windel Bouwman
parents: 200
diff changeset
93 self.desc = desc
200
5e391d9a3381 Split off asm nodes
Windel Bouwman
parents: 199
diff changeset
94 self.registers = []
341
4d204f6f7d4e Rewrite of assembler parts
Windel Bouwman
parents: 335
diff changeset
95 self.byte_sizes = {'int' : 4} # For front end!
354
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 346
diff changeset
96 self.byte_sizes['byte'] = 1
341
4d204f6f7d4e Rewrite of assembler parts
Windel Bouwman
parents: 335
diff changeset
97
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
98 # For lowering:
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
99 self.lower_functions = {}
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
100
341
4d204f6f7d4e Rewrite of assembler parts
Windel Bouwman
parents: 335
diff changeset
101 # For assembler:
4d204f6f7d4e Rewrite of assembler parts
Windel Bouwman
parents: 335
diff changeset
102 self.assembler_rules = []
4d204f6f7d4e Rewrite of assembler parts
Windel Bouwman
parents: 335
diff changeset
103 self.asm_keywords = []
4d204f6f7d4e Rewrite of assembler parts
Windel Bouwman
parents: 335
diff changeset
104
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
105 self.generate_base_rules()
385
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
106 self.reloc_map = reloc_map # TODO: make this target specific.
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
107
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
108 def generate_base_rules(self):
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
109 # Base rules for constants:
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
110 self.add_rule('imm32', ['val32'], lambda x: x[0].val)
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
111 self.add_rule('imm32', ['imm16'], lambda x: x[0])
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
112
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
113 self.add_rule('imm16', ['val16'], lambda x: x[0].val)
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
114 self.add_rule('imm16', ['imm12'], lambda x: x[0])
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
115
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
116 self.add_rule('imm12', ['val12'], lambda x: x[0].val)
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
117 self.add_rule('imm12', ['imm8'], lambda x: x[0])
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
118
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
119 self.add_rule('imm8', ['val8'], lambda x: x[0].val)
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
120 self.add_rule('imm8', ['imm5'], lambda x: x[0])
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
121
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
122 self.add_rule('imm5', ['val5'], lambda x: x[0].val)
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
123 self.add_rule('imm5', ['imm3'], lambda x: x[0])
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
124
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
125 self.add_rule('imm3', ['val3'], lambda x: x[0].val)
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
126
341
4d204f6f7d4e Rewrite of assembler parts
Windel Bouwman
parents: 335
diff changeset
127 def add_keyword(self, kw):
4d204f6f7d4e Rewrite of assembler parts
Windel Bouwman
parents: 335
diff changeset
128 self.asm_keywords.append(kw)
4d204f6f7d4e Rewrite of assembler parts
Windel Bouwman
parents: 335
diff changeset
129
4d204f6f7d4e Rewrite of assembler parts
Windel Bouwman
parents: 335
diff changeset
130 def add_instruction(self, rhs, f):
4d204f6f7d4e Rewrite of assembler parts
Windel Bouwman
parents: 335
diff changeset
131 self.add_rule('instruction', rhs, f)
4d204f6f7d4e Rewrite of assembler parts
Windel Bouwman
parents: 335
diff changeset
132
4d204f6f7d4e Rewrite of assembler parts
Windel Bouwman
parents: 335
diff changeset
133 def add_rule(self, lhs, rhs, f):
362
c05ab629976a Added CPUID for arm
Windel Bouwman
parents: 354
diff changeset
134 if type(f) is int:
c05ab629976a Added CPUID for arm
Windel Bouwman
parents: 354
diff changeset
135 f2 = lambda x: f
c05ab629976a Added CPUID for arm
Windel Bouwman
parents: 354
diff changeset
136 else:
c05ab629976a Added CPUID for arm
Windel Bouwman
parents: 354
diff changeset
137 f2 = f
386
2a970e7270e2 Added repeat assembler macro
Windel Bouwman
parents: 385
diff changeset
138 assert type(f2) in [types.FunctionType, types.MethodType]
362
c05ab629976a Added CPUID for arm
Windel Bouwman
parents: 354
diff changeset
139 self.assembler_rules.append((lhs, rhs, f2))
200
5e391d9a3381 Split off asm nodes
Windel Bouwman
parents: 199
diff changeset
140
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
141 def lower_frame_to_stream(self, frame, outs):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
142 """ Lower instructions from frame to output stream """
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
143 for im in frame.instructions:
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
144 if isinstance(im.assem, Instruction):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
145 outs.emit(im.assem)
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
146 else:
381
6df89163e114 Fix section and ldr pseudo instruction
Windel Bouwman
parents: 366
diff changeset
147 # TODO assert isinstance(Abs
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
148 ins = self.lower_functions[im.assem](im)
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
149 outs.emit(ins)
201
d5debbfc0200 Added all 27 core instructions of msp430
Windel Bouwman
parents: 200
diff changeset
150
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
151 def add_lowering(self, cls, f):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
152 """ Add a function to the table of lowering options for this target """
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
153 self.lower_functions[cls] = f
385
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
154
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
155 def add_reloc(self, name, f):
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
156 self.reloc_map[name] = f
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
157
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
158
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
159
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
160 def align(x, m):
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
161 while ((x % m) != 0):
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
162 x = x + 1
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
163 return x
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
164
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
165 def wrap_negative(x, bits):
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
166 b = struct.unpack('<I', struct.pack('<i', x))[0]
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
167 mask = (1 << bits) - 1
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
168 return b & mask
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
169
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
170
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
171 reloc_map = {}
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
172
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
173 def reloc(t):
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
174 def f(c):
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
175 reloc_map[t] = c
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
176 return f
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
177
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
178
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
179 @reloc('lit_add_8')
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
180 def apply_lit8(reloc, sym_value, section, reloc_value):
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
181 assert sym_value % 4 == 0
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
182 offset = (sym_value - (align(reloc_value + 2, 4)))
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
183 assert offset in range(0, 1024, 4), str(offset)+str( self.dst.sections)
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
184 rel8 = offset >> 2
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
185 section.data[reloc.offset] = rel8
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
186
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
187
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
188 @reloc('wrap_new11')
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
189 def apply_wrap_new11(reloc, sym_value, section, reloc_value):
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
190 offset = sym_value - (align(reloc_value, 2) + 4)
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
191 assert offset in range(-2048, 2046, 2)
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
192 imm11 = wrap_negative(offset >> 1, 11)
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
193 section.data[reloc.offset] = (imm11 & 0xff)
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
194 section.data[reloc.offset + 1] |= (imm11 >> 8) & 0x7
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
195
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
196
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
197 @reloc('rel8')
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
198 def apply_rel8(reloc, sym_value, section, reloc_value):
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
199 assert sym_value % 2 == 0
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
200 offset = sym_value - (align(reloc_value, 2) + 4)
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
201 assert offset in range(-256, 254, 2), str(offset) + str(reloc)
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
202 imm8 = wrap_negative(offset >> 1, 8)
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
203 section.data[reloc.offset] = imm8
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
204
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
205
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
206 @reloc('bl_imm11_imm10')
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
207 def apply_bl_imm11(reloc, sym_value, section, reloc_value):
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
208 assert sym_value % 2 == 0
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
209 offset = sym_value - (align(reloc_value, 2) + 4)
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
210 assert offset in range(-16777216, 16777214, 2), str(offset)
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
211 imm32 = wrap_negative(offset >> 1, 32)
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
212 imm11 = imm32 & 0x7FF
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
213 imm10 = (imm32 >> 11) & 0x3FF
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
214 s = (imm32 >> 24) & 0x1
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
215 section.data[reloc.offset + 2] = imm11 & 0xFF
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
216 section.data[reloc.offset + 3] |= (imm11 >> 8) & 0x7
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
217 section.data[reloc.offset] = imm10 & 0xff
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
218 section.data[reloc.offset + 1] |= ((imm10 >> 8) & 0x3) | (s << 2)
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
219
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
220 @reloc('b_imm11_imm6')
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
221 def apply_b_imm11_imm6(reloc, sym_value, section, reloc_value):
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
222 assert sym_value % 2 == 0
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
223 offset = sym_value - (align(reloc_value, 2) + 4)
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
224 assert offset in range(-1048576, 1048574, 2), str(offset)
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
225 imm32 = wrap_negative(offset >> 1, 32)
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
226 imm11 = imm32 & 0x7FF
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
227 imm6 = (imm32 >> 11) & 0x3F
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
228 s = (imm32 >> 24) & 0x1
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
229 section.data[reloc.offset + 2] = imm11 & 0xFF
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
230 section.data[reloc.offset + 3] |= (imm11 >> 8) & 0x7
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
231 section.data[reloc.offset] |= imm6
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
232 section.data[reloc.offset + 1] |= (s << 2)
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
233
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
234 # ARM reloc!!
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
235 # TODO: move to target classes???
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
236 @reloc('b_imm24')
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
237 def apply_b_imm24(reloc, sym_value, section, reloc_value):
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
238 assert sym_value % 4 == 0
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
239 assert reloc_value % 4 == 0
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
240 offset = (sym_value - (reloc_value + 8))
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
241 rel24 = wrap_negative(offset >> 2, 24)
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
242 section.data[reloc.offset+2] = (rel24 >> 16) & 0xFF
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
243 section.data[reloc.offset+1] = (rel24 >> 8) & 0xFF
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
244 section.data[reloc.offset+0] = rel24 & 0xFF
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
245
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
246
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
247 @reloc('ldr_imm12')
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
248 def apply_ldr_imm12(reloc, sym_value, section, reloc_value):
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
249 assert sym_value % 4 == 0
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
250 assert reloc_value % 4 == 0
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
251 offset = (sym_value - (reloc_value + 8))
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
252 U = 1
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
253 if offset < 0:
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
254 offset = -offset
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
255 U = 0
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
256 assert offset < 4096, str(sym) + str(section) + str(reloc)
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
257 section.data[reloc.offset+2] |= (U << 7)
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
258 section.data[reloc.offset+1] |= (offset >> 8) & 0xF
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
259 section.data[reloc.offset+0] = offset & 0xFF
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
260
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
261 @reloc('adr_imm12')
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
262 def apply_adr_imm12(reloc, sym_value, section, reloc_value):
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
263 assert sym_value % 4 == 0
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
264 assert reloc_value % 4 == 0
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
265 offset = (sym_value - (reloc_value + 8))
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
266 U = 2
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
267 if offset < 0:
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
268 offset = -offset
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
269 U = 1
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
270 assert offset < 4096
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
271 offset = encode_imm32(offset)
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
272 section.data[reloc.offset+2] |= (U << 6)
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
273 section.data[reloc.offset+1] |= (offset >> 8) & 0xF
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
274 section.data[reloc.offset+0] = offset & 0xFF
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
275
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
276 @reloc('absaddr32')
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
277 def apply_absaddr32(reloc, sym_value, section, reloc_value):
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
278 assert sym_value % 4 == 0
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
279 assert reloc_value % 4 == 0
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
280 offset = sym_value
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
281 section.data[reloc.offset+3] = (offset >> 24) & 0xFF
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
282 section.data[reloc.offset+2] = (offset >> 16) & 0xFF
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
283 section.data[reloc.offset+1] = (offset >> 8) & 0xFF
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 381
diff changeset
284 section.data[reloc.offset+0] = offset & 0xFF