202
|
1 from target import Register, Instruction, Target
|
|
2 from asmnodes import ASymbol, ANumber
|
|
3 from ppci import CompilerError
|
|
4 import struct, types
|
|
5
|
|
6 def u16(h):
|
|
7 return struct.pack('<H', h)
|
|
8
|
|
9 armtarget = Target('arm')
|
|
10
|
|
11 class ArmReg(Register):
|
|
12 def __init__(self, num, name):
|
|
13 super().__init__(name)
|
|
14 self.num = num
|
|
15
|
|
16 class ArmImm:
|
|
17 def __init__(self, i):
|
|
18 self.i = i
|
|
19
|
203
|
20 class RegOp:
|
|
21 def __init__(self, num):
|
|
22 assert num < 8
|
|
23 self.num = num
|
|
24
|
|
25 @classmethod
|
|
26 def Create(cls, vop):
|
|
27 if type(vop) is ASymbol:
|
|
28 name = vop.name
|
|
29 regs = {}
|
|
30 for r in armtarget.registers:
|
|
31 regs[r.name] = r
|
|
32 if name in regs:
|
|
33 r = regs[name]
|
|
34 return cls(r.num)
|
|
35
|
|
36 class Imm8:
|
|
37 def __init__(self, imm):
|
|
38 assert imm < 256
|
|
39 self.imm = imm
|
|
40
|
|
41 @classmethod
|
|
42 def Create(cls, vop):
|
|
43 if type(vop) is ANumber and vop.number < 256:
|
|
44 return cls(vop.number)
|
|
45
|
|
46 class Imm3:
|
|
47 def __init__(self, imm):
|
|
48 assert imm < 8
|
|
49 assert type(imm) is int
|
|
50 self.imm = imm
|
|
51
|
|
52 @classmethod
|
|
53 def Create(cls, vop):
|
|
54 if type(vop) is ANumber and vop.number < 8:
|
|
55 return cls(vop.number)
|
|
56
|
202
|
57 # 8 bit registers:
|
|
58 r4 = ArmReg(4, 'r4')
|
|
59 armtarget.registers.append(r4)
|
203
|
60 r5 = ArmReg(5, 'r5')
|
|
61 armtarget.registers.append(r5)
|
|
62 r6 = ArmReg(6, 'r6')
|
|
63 armtarget.registers.append(r6)
|
|
64 r7 = ArmReg(7, 'r7')
|
|
65 armtarget.registers.append(r7)
|
202
|
66
|
|
67 class ArmInstruction(Instruction):
|
|
68 pass
|
|
69
|
|
70 @armtarget.instruction
|
|
71 class ldr_ins(ArmInstruction):
|
|
72 mnemonic = 'ldr'
|
|
73 opcode = 1337
|
|
74
|
|
75
|
203
|
76 class Operand2:
|
|
77 def __init__(self, expr):
|
|
78 if type(expr) is ANumber:
|
|
79 pass
|
|
80 pass
|
|
81
|
202
|
82 @armtarget.instruction
|
|
83 class mov_ins(ArmInstruction):
|
|
84 """ mov Rd, imm8, move immediate value into register """
|
|
85 mnemonic = 'mov'
|
203
|
86 opcode = 4 # 00100 Rd(3) imm8
|
|
87 operands = (RegOp, Imm8)
|
|
88 def __init__(self, rd, imm):
|
|
89 self.imm = imm.imm
|
|
90 self.r = rd.num
|
202
|
91 def encode(self):
|
|
92 rd = self.r
|
|
93 opcode = self.opcode
|
|
94 imm8 = self.imm
|
|
95 h = (opcode << 11) | (rd << 8) | imm8
|
|
96 return u16(h)
|
|
97
|
203
|
98 @armtarget.instruction
|
|
99 class movregreg_ins(ArmInstruction):
|
|
100 """ mov Rd, Rm """
|
|
101 mnemonic = 'mov'
|
|
102 opcode = 8 # 01000 Rd(3) imm8
|
|
103 operands = (RegOp, RegOp)
|
|
104 def __init__(self, rd, rm):
|
|
105 self.rd = rd
|
|
106 self.rm = rm
|
|
107 def encode(self):
|
|
108 rd = self.rd.num
|
|
109 D = (rd & 0x8) >> 3
|
|
110 assert D < 2
|
|
111 rd = rd & 0x7
|
|
112 rm = self.rm.num
|
|
113 assert rm < 16
|
|
114 opcode = self.opcode
|
|
115 h = (opcode << 11) | (3 << 9) | (D << 7) | (rm << 3) | rd
|
|
116 return u16(h)
|
|
117
|
|
118 @armtarget.instruction
|
|
119 class addregregimm3_ins(ArmInstruction):
|
|
120 """ add Rd, Rn, imm3 """
|
|
121 mnemonic = 'add'
|
|
122 opcode = 3 # 00011
|
|
123 operands = (RegOp, RegOp, Imm3)
|
|
124 def __init__(self, rd, rn, imm3):
|
|
125 self.rd = rd
|
|
126 self.rn = rn
|
|
127 self.imm3 = imm3
|
|
128 def encode(self):
|
|
129 rd = self.rd.num
|
|
130 rn = self.rn.num
|
|
131 imm3 = self.imm3.imm
|
|
132 opcode = self.opcode
|
|
133 h = (opcode << 11) | (1 << 10) | (imm3 << 6) | (rn << 3) | rd
|
|
134 return u16(h)
|
|
135
|
|
136 @armtarget.instruction
|
|
137 class cmpregimm8_ins(ArmInstruction):
|
|
138 """ cmp Rn, imm8 """
|
|
139 mnemonic = 'cmp'
|
|
140 opcode = 5 # 00101
|
|
141 operands = (RegOp, Imm8)
|
|
142 def __init__(self, rn, imm):
|
|
143 self.rn = rn
|
|
144 self.imm = imm
|
|
145 def encode(self):
|
|
146 rn = self.rn.num
|
|
147 imm = self.imm.imm
|
|
148 opcode = self.opcode
|
|
149 h = (opcode << 11) | (rn << 8) | imm
|
|
150 return u16(h)
|
202
|
151
|
|
152 @armtarget.instruction
|
|
153 class yield_ins(ArmInstruction):
|
|
154 operands = ()
|
|
155 mnemonic = 'yield'
|
|
156 def encode(self):
|
|
157 return u16(0xbf10)
|
|
158
|