annotate python/ppci/target/arm/instructions.py @ 345:b4882ff0ed06

Added more arm isa tests
author Windel Bouwman
date Sun, 02 Mar 2014 17:12:08 +0100
parents 86b02c98a717
children 3bb7dcfe5529
rev   line source
342
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
1
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
2
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
3 from ..basetarget import Instruction
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 # Helpers:
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
9
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
10 def rotate_right(v, n):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
11 """ bit-wise Rotate right n times """
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
12 mask = (2**n) - 1
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
13 mask_bits = v & mask
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
14 return (v >> n) | (mask_bits << (32 - n))
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
15
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
16 def rotate_left(v, n):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
17 assert n >= 0
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
18 assert n < 32
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
19 return rotate_right(v, 32 - n)
342
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
20
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
21 masks = [rotate_right(0xFF, i * 2) for i in range(16)]
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
22 #0x000000FF,
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
23 #0xC000007F,
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
24 #0xF000000F,
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
25 #0xFC000003,
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
26 #0xFF000000, # 4
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
27
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
28 assert masks[4] == 0xFF000000, hex(masks[4])
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
29
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
30 def encode_imm32(v):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
31 """ Bundle 32 bit value into 4 bits rotation and 8 bits value
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
32 """
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
33 for i in range(0, 16):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
34 v2 = rotate_left(v, i*2)
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
35 if (v2 & 0xFFFFFF00) == 0:
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
36 rotation = i
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
37 val = v2 & 0xFF
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
38 x = (rotation << 8) | val
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
39 return x
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
40 raise Exception("Invalid value {}".format(v))
342
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
41
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
42 # Instructions:
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
43
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
44 class ArmInstruction(Instruction):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
45 def __init__(self):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
46 self.token = ArmToken()
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
47
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
48
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
49 class Mov(ArmInstruction):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
50 """ Mov Rd, imm16 """
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
51 def __init__(self, reg, imm):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
52 super().__init__()
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
53 self.reg = reg
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
54 self.imm = imm
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
55
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
56 def encode(self):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
57 self.token[0:12] = self.imm
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
58 self.token.Rd = self.reg.num
342
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
59 self.token[16:20] = 0
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
60 self.token[20] = 0
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
61 self.token[21:28] = 0b0011101
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
62 self.token.cond = 0xE # Always!
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
63 return self.token.encode()
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
64
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
65 def relocations(self):
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
66 return []
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
67
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
68 def __repr__(self):
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
69 return 'Mov {}, {}'.format(self.reg, self.imm)
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
70
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
71
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
72 def Add(*args):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
73 if len(args) == 3 and isinstance(args[0], ArmRegister) and \
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
74 isinstance(args[1], ArmRegister):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
75 if isinstance(args[2], ArmRegister):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
76 return Add1(args[0], args[1], args[2])
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
77 elif isinstance(args[2], int):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
78 return Add2(args[0], args[1], args[2])
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
79 raise Exception()
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
80
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
81 def Sub(*args):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
82 if len(args) == 3 and isinstance(args[0], ArmRegister) and \
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
83 isinstance(args[1], ArmRegister):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
84 if isinstance(args[2], ArmRegister):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
85 return Sub1(args[0], args[1], args[2])
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
86 elif isinstance(args[2], int):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
87 return Sub2(args[0], args[1], args[2])
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
88 raise Exception()
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
89
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
90 class OpRegRegReg(ArmInstruction):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
91 """ add rd, rn, rm """
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
92 def __init__(self, rd, rn, rm, shift=0):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
93 super().__init__()
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
94 self.rd = rd
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
95 self.rn = rn
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
96 self.rm = rm
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
97
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
98 def encode(self):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
99 self.token[0:4] = self.rm.num
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
100 self.token[4] = 0
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
101 self.token[5:7] = 0
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
102 self.token[7:12] = 0 # Shift
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
103 self.token.Rd = self.rd.num
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
104 self.token.Rn = self.rn.num
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
105 self.token.S = 0 # Set flags
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
106 self.token[21:28] = self.opcode
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
107 self.token.cond = 0xE # Always!
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
108 return self.token.encode()
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
109
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
110 def __repr__(self):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
111 return 'add {}, {}, {}'.format(self.rd, self.rn, self.rm)
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
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
114 class Add1(OpRegRegReg):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
115 opcode = 0b0000100
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
116
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
117
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
118 class Sub1(OpRegRegReg):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
119 opcode = 0b0000010
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
120
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 class Orr1(OpRegRegReg):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
123 opcode = 0b0001100
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
124
342
86b02c98a717 Moved target directory
Windel Bouwman
parents:
diff changeset
125
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
126 class OpRegRegImm(ArmInstruction):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
127 """ add rd, rn, imm12 """
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
128 def __init__(self, rd, rn, imm):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
129 super().__init__()
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
130 self.rd = rd
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
131 self.rn = rn
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
132 self.imm2 = encode_imm32(imm)
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
133 self.imm = imm
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
134
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
135 def encode(self):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
136 self.token[0:12] = self.imm2
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
137 self.token.Rd = self.rd.num
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
138 self.token.Rn = self.rn.num
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
139 self.token.S = 0 # Set flags
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
140 self.token[21:28] = self.opcode
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
141 self.token.cond = 0xE # Always!
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
142 return self.token.encode()
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
143
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
144 def __repr__(self):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
145 return 'add {}, {}, {}'.format(self.rd, self.rn, self.imm)
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
146
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
147
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
148 class Add2(OpRegRegImm):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
149 opcode = 0b0010100
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
150
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
151
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
152 class Sub2(OpRegRegImm):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
153 opcode = 0b0010010
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
154
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 # Branches:
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
158
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
159 class BranchBaseRoot(ArmInstruction):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
160 def __init__(self, target):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
161 super().__init__()
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
162 self.target = target
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 def encode(self):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
165 self.token.cond = self.cond
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
166 self.token[24:28] = self.opcode
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
167 return self.token.encode()
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
168
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
169 def relocations(self):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
170 return [(self.target, 'b_imm24')]
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
171
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
172
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
173 class BranchBase(BranchBaseRoot):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
174 opcode = 0b1010
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
175
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
176 class BranchLinkBase(BranchBaseRoot):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
177 opcode = 0b1011
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
178
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
179 class Bl(BranchLinkBase):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
180 cond = 0xE
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
181
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
182 class B(BranchBase):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
183 cond = 0xE
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
184
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
185 class Beq(BranchBase):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
186 cond = 0x0
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
187
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
188 class Bgt(BranchBase):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
189 cond = 0xC
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 Ble(BranchBase):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 342
diff changeset
192 cond = 0xD
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