Mercurial > lcfOS
comparison python/target/arminstructions.py @ 340:c7cc54c0dfdf devel
Test featurebranch
author | Windel Bouwman |
---|---|
date | Sun, 23 Feb 2014 16:24:01 +0100 |
parents | d1ecc493384e |
children | 4d204f6f7d4e |
comparison
equal
deleted
inserted
replaced
339:6ee17c4dd6b8 | 340:c7cc54c0dfdf |
---|---|
1 import struct | 1 import struct |
2 from ppci.asmnodes import ASymbol, AInstruction, ANumber, AUnop, ABinop | 2 from ppci.asmnodes import ASymbol, AInstruction, ANumber, AUnop, ABinop |
3 from .basetarget import Register, Instruction, Target, Label, LabelRef | 3 from .basetarget import Register, Instruction, Target, Label, LabelRef |
4 from .basetarget import Imm32, Imm8, Imm7, Imm3 | 4 from .basetarget import Imm32, Imm8, Imm7, Imm3 |
5 | 5 |
6 from .armtokens import ThumbToken, ArmToken | |
7 from .armregisters import R0 | |
8 | |
9 def add_rule(rhs, f): | |
10 pass | |
6 | 11 |
7 def u16(h): | 12 def u16(h): |
8 return struct.pack('<H', h) | 13 return struct.pack('<H', h) |
9 | 14 |
10 def u32(x): | 15 def u32(x): |
11 return struct.pack('<I', x) | 16 return struct.pack('<I', x) |
12 | 17 |
13 | 18 |
14 def val2bit(v, bits): | 19 thumb_assembly_rules = [] |
15 b = [] | 20 arm_assembly_rules = [] |
16 for i in range(bits): | |
17 b.append(bool((1<<i) & v)) | |
18 #b.reverse() | |
19 return b | |
20 | |
21 | |
22 def bit_range(b, e): | |
23 getter = lambda s: s[b:e] | |
24 def setter(s, v): | |
25 s[b:e] = v | |
26 return property(getter, setter) | |
27 | |
28 class ArmToken: | |
29 def __init__(self): | |
30 self.bit_value = 0 | |
31 | |
32 def set_bit(self, i, value): | |
33 value = bool(value) | |
34 assert i in range(0, 16) | |
35 mask = 1 << i | |
36 if value: | |
37 self.bit_value |= mask | |
38 else: | |
39 self.bit_value &= (~mask) | |
40 | |
41 def __getitem__(self, key): | |
42 return False | |
43 | |
44 def __setitem__(self, key, value): | |
45 if type(key) is int: | |
46 self.set_bit(key, value) | |
47 elif type(key) is slice: | |
48 assert key.step is None | |
49 bits = key.stop - key.start | |
50 value_bits = val2bit(value, bits) | |
51 for i in range(key.start, key.stop): | |
52 self.set_bit(i, value_bits[i - key.start]) | |
53 else: | |
54 raise KeyError() | |
55 | |
56 rd = bit_range(0, 3) | |
57 | |
58 def encode(self): | |
59 return u16(self.bit_value) | |
60 | 21 |
61 | 22 |
62 # Operands: | 23 # Operands: |
63 | 24 |
64 class ArmRegister(Register): | |
65 def __init__(self, num, name): | |
66 super().__init__(name) | |
67 self.num = num | |
68 | |
69 def __repr__(self): | |
70 return self.name | |
71 | |
72 @classmethod | |
73 def Create(cls, vop): | |
74 if type(vop) is ASymbol: | |
75 name = vop.name | |
76 regs = {} | |
77 for r in registers: | |
78 regs[r.name] = r | |
79 if name in regs: | |
80 r = regs[name] | |
81 if isinstance(r, cls): | |
82 return r | |
83 | |
84 | |
85 class Reg8Op(ArmRegister): | |
86 pass | |
87 | |
88 | |
89 class Reg16Op(ArmRegister): | |
90 pass | |
91 | |
92 | |
93 R0 = Reg8Op(0, 'r0') | |
94 R1 = Reg8Op(1, 'r1') | |
95 R2 = Reg8Op(2, 'r2') | |
96 R3 = Reg8Op(3, 'r3') | |
97 R4 = Reg8Op(4, 'r4') | |
98 R5 = Reg8Op(5, 'r5') | |
99 R6 = Reg8Op(6, 'r6') | |
100 R7 = Reg8Op(7, 'r7') | |
101 # Other registers: | |
102 # TODO | |
103 SP = ArmRegister(13, 'sp') | |
104 LR = ArmRegister(14, 'lr') | |
105 PC = ArmRegister(15, 'pc') | |
106 | |
107 registers = [R0, R1, R2, R3, R4, R5, R6, R7, SP, LR, PC] | |
108 | 25 |
109 | 26 |
110 class RegSpOp: | 27 class RegSpOp: |
111 @classmethod | 28 @classmethod |
112 def Create(cls, vop): | 29 def Create(cls, vop): |
134 def isRegOffset(regname, x, y): | 51 def isRegOffset(regname, x, y): |
135 if type(x) is ASymbol and type(y) is ANumber and x.name.upper() == regname: | 52 if type(x) is ASymbol and type(y) is ANumber and x.name.upper() == regname: |
136 return y.number | 53 return y.number |
137 elif type(y) is ASymbol and type(x) is ANumber and y.name.upper() == regname: | 54 elif type(y) is ASymbol and type(x) is ANumber and y.name.upper() == regname: |
138 return x.number | 55 return x.number |
139 | 56 |
140 | 57 |
141 class MemRegXRel: | 58 class MemRegXRel: |
142 def __init__(self, offset): | 59 def __init__(self, offset): |
143 assert offset % 4 == 0 | 60 assert offset % 4 == 0 |
144 self.offset = offset | 61 self.offset = offset |
245 | 162 |
246 def instruction(i): | 163 def instruction(i): |
247 allins.append(i) | 164 allins.append(i) |
248 return i | 165 return i |
249 | 166 |
250 | 167 add_rule(['dcd', 'imm32'], lambda rhs: Dcd(rhs[1])) |
251 @instruction | 168 |
252 class Dcd(ArmInstruction): | 169 class Dcd(ArmInstruction): |
253 mnemonic = 'dcd' | 170 mnemonic = 'dcd' |
254 operands = (Imm32,) | 171 operands = (Imm32,) |
255 def __init__(self, expr): | 172 def __init__(self, expr): |
256 if isinstance(expr, Imm32): | 173 if isinstance(expr, Imm32): |
460 return u16(h) | 377 return u16(h) |
461 | 378 |
462 def __repr__(self): | 379 def __repr__(self): |
463 return '{} {}, {}, {}'.format(self.mnemonic, self.rd, self.rn, self.imm3.imm) | 380 return '{} {}, {}, {}'.format(self.mnemonic, self.rd, self.rn, self.imm3.imm) |
464 | 381 |
382 | |
383 add_rule(['add', 'r8', ',', 'r8', ',', 'imm3'], lambda rhs: Add2(rhs[1], rhs[3], rhs[5])) | |
384 | |
465 @instruction | 385 @instruction |
466 class Add2(regregimm3_base): | 386 class Add2(regregimm3_base): |
467 """ add Rd, Rn, imm3 """ | 387 """ add Rd, Rn, imm3 """ |
468 mnemonic = 'add' | 388 mnemonic = 'add' |
469 opcode = 0b0001110 | 389 opcode = 0b0001110 |
487 @classmethod | 407 @classmethod |
488 def fromim(cls, im): | 408 def fromim(cls, im): |
489 return cls(im.dst[0], im.src[0], im.src[1]) | 409 return cls(im.dst[0], im.src[0], im.src[1]) |
490 | 410 |
491 def encode(self): | 411 def encode(self): |
492 at = ArmToken() | 412 at = ThumbToken() |
493 at.rd = self.rd.num | 413 at.rd = self.rd.num |
494 rn = self.rn.num | 414 rn = self.rn.num |
495 rm = self.rm.num | 415 rm = self.rm.num |
496 at[3:6] = rn | 416 at[3:6] = rn |
497 at[6:9] = rm | 417 at[6:9] = rm |
528 @classmethod | 448 @classmethod |
529 def fromim(cls, im): | 449 def fromim(cls, im): |
530 return cls(im.dst[0], im.src[0]) | 450 return cls(im.dst[0], im.src[0]) |
531 | 451 |
532 def encode(self): | 452 def encode(self): |
533 at = ArmToken() | 453 at = ThumbToken() |
534 at.rd = self.rd.num & 0x7 | 454 at.rd = self.rd.num & 0x7 |
535 D = (self.rd.num >> 3) & 0x1 | 455 D = (self.rd.num >> 3) & 0x1 |
536 Rm = self.rm.num | 456 Rm = self.rm.num |
537 opcode = 0b01000110 | 457 opcode = 0b01000110 |
538 at[8:16] = opcode | 458 at[8:16] = opcode |
557 def fromim(cls, im): | 477 def fromim(cls, im): |
558 assert im.src[1] is im.dst[0] | 478 assert im.src[1] is im.dst[0] |
559 return cls(im.src[0], im.dst[0]) | 479 return cls(im.src[0], im.dst[0]) |
560 | 480 |
561 def encode(self): | 481 def encode(self): |
562 at = ArmToken() | 482 at = ThumbToken() |
563 rn = self.rn.num | 483 rn = self.rn.num |
564 at.rd = self.rdm.num | 484 at.rd = self.rdm.num |
565 opcode = 0b0100001101 | 485 opcode = 0b0100001101 |
566 #h = (opcode << 6) | (rn << 3) | rdm | 486 #h = (opcode << 6) | (rn << 3) | rdm |
567 at[6:16] = opcode | 487 at[6:16] = opcode |
585 @classmethod | 505 @classmethod |
586 def fromim(cls, im): | 506 def fromim(cls, im): |
587 return cls(im.src[0], im.src[1]) | 507 return cls(im.src[0], im.src[1]) |
588 | 508 |
589 def encode(self): | 509 def encode(self): |
590 at = ArmToken() | 510 at = ThumbToken() |
591 at.rd = self.rdn.num | 511 at.rd = self.rdn.num |
592 rm = self.rm.num | 512 rm = self.rm.num |
593 at[3:6] = rm | 513 at[3:6] = rm |
594 at[6:16] = self.opcode | 514 at[6:16] = self.opcode |
595 return at.encode() | 515 return at.encode() |
772 raise NotImplementedError('not implemented for this register') | 692 raise NotImplementedError('not implemented for this register') |
773 h = (0x5a << 9) | (M << 8) | reg_list | 693 h = (0x5a << 9) | (M << 8) | reg_list |
774 return u16(h) | 694 return u16(h) |
775 | 695 |
776 | 696 |
697 add_rule(['pop', 'reg_list'], lambda rhs: Pop(rhs[1])) | |
698 | |
777 @instruction | 699 @instruction |
778 class Pop(ArmInstruction): | 700 class Pop(ArmInstruction): |
779 operands = (RegisterSet,) | 701 operands = (RegisterSet,) |
780 mnemonic = 'pop' | 702 mnemonic = 'pop' |
781 | 703 |