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