annotate python/ppci/target/arm/instructions.py @ 350:2b02bd286fe9

Fixed A9 hello worle
author Windel Bouwman
date Sat, 08 Mar 2014 16:29:03 +0100
parents 3bb7dcfe5529
children 899ae3aea803
rev   line source
342
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
1
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
2 from ..basetarget import Instruction
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
3 from ...bitfun import rotate_left
342
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
4
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
5 from .token import ArmToken
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
6 from .registers import R0, SP, ArmRegister
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
7
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
8
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
9 def encode_imm32(v):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
10 """ Bundle 32 bit value into 4 bits rotation and 8 bits value
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
11 """
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
12 for i in range(0, 16):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
13 v2 = rotate_left(v, i*2)
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
14 if (v2 & 0xFFFFFF00) == 0:
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
15 rotation = i
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
16 val = v2 & 0xFF
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
17 x = (rotation << 8) | val
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
18 return x
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
19 raise Exception("Invalid value {}".format(v))
342
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
20
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
21 # Instructions:
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
22
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
23 class ArmInstruction(Instruction):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
24 def __init__(self):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
25 self.token = ArmToken()
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
26
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
27
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
28 class Dcd(ArmInstruction):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
29 def __init__(self, v):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
30 super().__init__()
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
31 self.v = v
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
32
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
33 def encode(self):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
34 self.token[0:32] = self.v
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
35 return self.token.encode()
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
36
350
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
37 def __repr__(self):
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
38 return 'DCD {}'.format(hex(self.v))
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
39
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
40
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
41 def Mov(*args):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
42 if len(args) == 2:
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
43 if isinstance(args[1], int):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
44 return Mov1(*args)
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
45 elif isinstance(args[1], ArmRegister):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
46 return Mov2(*args)
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
47 raise Exception()
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
48
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
49
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
50 class Mov1(ArmInstruction):
342
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
51 """ Mov Rd, imm16 """
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
52 def __init__(self, reg, imm):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
53 super().__init__()
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
54 assert type(imm) is int
342
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
55 self.reg = reg
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
56 self.imm = imm
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
57
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
58 def encode(self):
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
59 self.token[0:12] = encode_imm32(self.imm)
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
60 self.token.Rd = self.reg.num
342
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
61 self.token[16:20] = 0
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
62 self.token[20] = 0 # Set flags
342
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
63 self.token[21:28] = 0b0011101
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
64 self.token.cond = AL
342
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
65 return self.token.encode()
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
66
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
67 def relocations(self):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
68 return []
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
69
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
70 def __repr__(self):
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
71 return 'Mov {}, {}'.format(self.reg, self.imm)
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
72
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
73
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
74 class Mov2(ArmInstruction):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
75 def __init__(self, rd, rm):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
76 super().__init__()
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
77 self.rd = rd
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
78 self.rm = rm
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
79
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
80 def encode(self):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
81 self.token[0:4] = self.rm.num
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
82 self.token[4:12] = 0
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
83 self.token[12:16] = self.rd.num
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
84 self.token[16:20] = 0
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
85 self.token.S = 0
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
86 self.token[21:28] = 0xD
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
87 self.token.cond = AL
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
88 return self.token.encode()
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
89
350
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
90 def __repr__(self):
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
91 return 'MOV {}, {}'.format(self.rd, self.rm)
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
92
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
93
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
94 def Add(*args):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
95 if len(args) == 3 and isinstance(args[0], ArmRegister) and \
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
96 isinstance(args[1], ArmRegister):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
97 if isinstance(args[2], ArmRegister):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
98 return Add1(args[0], args[1], args[2])
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
99 elif isinstance(args[2], int):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
100 return Add2(args[0], args[1], args[2])
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
101 raise Exception()
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
102
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
103 def Sub(*args):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
104 if len(args) == 3 and isinstance(args[0], ArmRegister) and \
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
105 isinstance(args[1], ArmRegister):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
106 if isinstance(args[2], ArmRegister):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
107 return Sub1(args[0], args[1], args[2])
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
108 elif isinstance(args[2], int):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
109 return Sub2(args[0], args[1], args[2])
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
110 raise Exception()
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
111
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
112 def Mul(*args):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
113 return Mul1(args[0], args[1], args[2])
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
114
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
115
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
116 class Mul(ArmInstruction):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
117 def __init__(self, rd, rn, rm):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
118 super().__init__()
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
119 self.rd = rd
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
120 self.rn = rn
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
121 self.rm = rm
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
122
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
123 def encode(self):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
124 self.token[0:4] = self.rn.num
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
125 self.token[4:8] = 0b1001
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
126 self.token[8:12] = self.rm.num
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
127 self.token[16:20] = self.rd.num
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
128 self.token.S = 0
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
129 self.token.cond = AL
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
130 return self.token.encode()
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
131
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
132
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
133 class OpRegRegReg(ArmInstruction):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
134 """ add rd, rn, rm """
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
135 def __init__(self, rd, rn, rm, shift=0):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
136 super().__init__()
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
137 self.rd = rd
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
138 self.rn = rn
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
139 self.rm = rm
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
140
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
141 def encode(self):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
142 self.token[0:4] = self.rm.num
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
143 self.token[4] = 0
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
144 self.token[5:7] = 0
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
145 self.token[7:12] = 0 # Shift
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
146 self.token.Rd = self.rd.num
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
147 self.token.Rn = self.rn.num
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
148 self.token.S = 0 # Set flags
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
149 self.token[21:28] = self.opcode
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
150 self.token.cond = 0xE # Always!
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
151 return self.token.encode()
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
152
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
153 def __repr__(self):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
154 return 'add {}, {}, {}'.format(self.rd, self.rn, self.rm)
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
155
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
156
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
157 class Add1(OpRegRegReg):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
158 opcode = 0b0000100
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
159
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
160
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
161 class Sub1(OpRegRegReg):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
162 opcode = 0b0000010
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
163
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
164
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
165 class Orr1(OpRegRegReg):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
166 opcode = 0b0001100
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
167
342
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
168
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
169 class OpRegRegImm(ArmInstruction):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
170 """ add rd, rn, imm12 """
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
171 def __init__(self, rd, rn, imm):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
172 super().__init__()
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
173 self.rd = rd
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
174 self.rn = rn
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
175 self.imm2 = encode_imm32(imm)
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
176 self.imm = imm
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
177
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
178 def encode(self):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
179 self.token[0:12] = self.imm2
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
180 self.token.Rd = self.rd.num
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
181 self.token.Rn = self.rn.num
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
182 self.token.S = 0 # Set flags
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
183 self.token[21:28] = self.opcode
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
184 self.token.cond = 0xE # Always!
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
185 return self.token.encode()
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
186
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
187 def __repr__(self):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
188 return 'add {}, {}, {}'.format(self.rd, self.rn, self.imm)
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
189
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
190
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
191 class Add2(OpRegRegImm):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
192 opcode = 0b0010100
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
193
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
194
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
195 class Sub2(OpRegRegImm):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
196 opcode = 0b0010010
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
197
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
198
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
199
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
200 # Branches:
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
201
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
202 class BranchBaseRoot(ArmInstruction):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
203 def __init__(self, target):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
204 super().__init__()
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
205 self.target = target
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
206
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
207 def encode(self):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
208 self.token.cond = self.cond
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
209 self.token[24:28] = self.opcode
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
210 return self.token.encode()
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
211
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
212 def relocations(self):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
213 return [(self.target, 'b_imm24')]
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
214
350
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
215 def __repr__(self):
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
216 mnemonic = self.__class__.__name__
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
217 return '{} {}'.format(mnemonic, self.target)
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
218
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
219
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
220 EQ, NE, CS, CC, MI, PL, VS, VC, HI, LS, GE, LT, GT, LE, AL = range(15)
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
221
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
222 class BranchBase(BranchBaseRoot):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
223 opcode = 0b1010
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
224
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
225 class BranchLinkBase(BranchBaseRoot):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
226 opcode = 0b1011
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
227
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
228 class Bl(BranchLinkBase):
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
229 cond = AL
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
230
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
231 class B(BranchBase):
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
232 cond = AL
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
233
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
234 class Beq(BranchBase):
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
235 cond = EQ
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
236
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
237 class Bgt(BranchBase):
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
238 cond = GT
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
239
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
240 class Ble(BranchBase):
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
241 cond = LE
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
242
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
243 class Blt(BranchBase):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
244 cond = LT
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
245
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
246
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
247 # Memory:
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
248
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
249 def reg_list_to_mask(reg_list):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
250 mask = 0
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
251 for reg in reg_list:
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
252 mask |= (1 << reg.num)
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
253 return mask
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
254
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
255
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
256 class Push(ArmInstruction):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
257 def __init__(self, register_set):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
258 super().__init__()
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
259 self.reg_list = register_set
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
260
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
261 def encode(self):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
262 self.token.cond = AL
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
263 self.token[16:28] = 0b100100101101
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
264 reg_list = 0
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
265 self.token[0:16] = reg_list_to_mask(self.reg_list)
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
266 return self.token.encode()
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
267
350
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
268 def __repr__(self):
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
269 return 'PUSH {}'.format(self.reg_list)
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
270
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
271
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
272 class Pop(ArmInstruction):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
273 def __init__(self, register_set):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
274 super().__init__()
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
275 self.reg_list = register_set
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
276
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
277 def encode(self):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
278 self.token.cond = AL
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
279 self.token[16:28] = 0b100010111101
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
280 self.token[0:16] = reg_list_to_mask(self.reg_list)
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
281 return self.token.encode()
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
282
350
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
283 def __repr__(self):
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
284 return 'POP {}'.format(self.reg_list)
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
285
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
286
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
287 def Ldr(*args):
350
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
288 """ Convenience function that creates the correct instruction """
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
289 if len(args) == 3:
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
290 if isinstance(args[1], ArmRegister):
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
291 return Ldr1(*args)
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
292 elif len(args) == 2:
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
293 if isinstance(args[1], ArmRegister):
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
294 return Ldr1(args[0], args[1], 0)
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
295 elif isinstance(args[1], str):
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
296 return Ldr3(*args)
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
297 raise Exception()
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
298
350
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
299
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
300 def Str(*args):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
301 if len(args) == 3 and isinstance(args[1], ArmRegister):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
302 return Str1(*args)
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
303 elif len(args) == 2 and isinstance(args[1], ArmRegister):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
304 return Str1(args[0], args[1], 0)
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
305 raise Exception()
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
306
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
307
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
308 class LdrStrBase(ArmInstruction):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
309 def __init__(self, rt, rn, offset):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
310 super().__init__()
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
311 self.rt = rt
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
312 self.rn = rn
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
313 self.offset = offset
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
314
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
315 def encode(self):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
316 self.token.cond = AL
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
317 self.token.Rn = self.rn.num
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
318 self.token[25:28] = self.opcode
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
319 self.token[20] = self.bit20
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
320 self.token[12:16] = self.rt.num
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
321 self.token[24] = 1 # Index
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
322 if self.offset >= 0:
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
323 self.token[23] = 1 # U == 1 'add'
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
324 self.token[0:12] = self.offset
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
325 else:
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
326 self.token[23] = 0
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
327 self.token[0:12] = -self.offset
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
328 return self.token.encode()
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
329
350
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
330 def __repr__(self):
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
331 return '{} {}, [{}, {}]'.format(self.mnemonic, self.rt, self.rn,
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
332 hex(self.offset))
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
333
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
334 class Str1(LdrStrBase):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
335 opcode = 0b010
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
336 bit20 = 0
350
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
337 mnemonic = 'STR'
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
338
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
339
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
340 class Ldr1(LdrStrBase):
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
341 opcode = 0b010
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
342 bit20 = 1
350
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
343 mnemonic = 'LDR'
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
344
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
345
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
346 class Ldr3(ArmInstruction):
350
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
347 """ Load PC relative constant value
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
348 LDR rt, label
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
349 encoding A1
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
350 """
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
351 def __init__(self, rt, label):
350
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
352 super().__init__()
346
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
353 self.rt = rt
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
354 self.label = label
3bb7dcfe5529 expanded arm target
Windel Bouwman
parents: 345
diff changeset
355
350
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
356 def __repr__(self):
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
357 return 'LDR {}, {}'.format(self.rt, self.label)
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
358
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
359 def relocations(self):
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
360 return [(self.label, 'ldr_imm12')]
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
361
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
362 def encode(self):
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
363 self.token.cond = AL
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
364 self.token[0:12] = 0 # Filled by linker
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
365 self.token[12:16] = self.rt.num
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
366 self.token[16:23] = 0b0011111
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
367 self.token[24:28] = 0b0101
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 346
diff changeset
368 return self.token.encode()