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