LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2014 The Go Authors. All rights reserved. | 1 // Copyright 2014 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package armasm | 5 package armasm |
6 | 6 |
7 import ( | 7 import ( |
8 "encoding/binary" | 8 "encoding/binary" |
9 "fmt" | 9 "fmt" |
10 ) | 10 ) |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 // _pm_ means ± (usually keyed by the U bit). | 122 // _pm_ means ± (usually keyed by the U bit). |
123 // The _W suffix indicates a general addressing mode based on the P and W bits. | 123 // The _W suffix indicates a general addressing mode based on the P and W bits. |
124 // The _offset and _postindex suffixes force the given addressing mode. | 124 // The _offset and _postindex suffixes force the given addressing mode. |
125 // The rest should be somewhat self-explanatory, at least given | 125 // The rest should be somewhat self-explanatory, at least given |
126 // the decodeArg function. | 126 // the decodeArg function. |
127 type instArg uint8 | 127 type instArg uint8 |
128 | 128 |
129 const ( | 129 const ( |
130 _ instArg = iota | 130 _ instArg = iota |
131 arg_APSR | 131 arg_APSR |
| 132 arg_FPSCR |
| 133 arg_Dn_half |
132 arg_R1_0 | 134 arg_R1_0 |
133 arg_R1_12 | 135 arg_R1_12 |
134 arg_R2_0 | 136 arg_R2_0 |
135 arg_R2_12 | 137 arg_R2_12 |
136 arg_R_0 | 138 arg_R_0 |
137 arg_R_12 | 139 arg_R_12 |
| 140 arg_R_12_nzcv |
138 arg_R_16 | 141 arg_R_16 |
139 arg_R_16_WB | 142 arg_R_16_WB |
140 arg_R_8 | 143 arg_R_8 |
141 arg_R_rotate | 144 arg_R_rotate |
142 arg_R_shift_R | 145 arg_R_shift_R |
143 arg_R_shift_imm | 146 arg_R_shift_imm |
144 arg_SP | 147 arg_SP |
| 148 arg_Sd |
| 149 arg_Sd_Dd |
| 150 arg_Dd_Sd |
| 151 arg_Sm |
| 152 arg_Sm_Dm |
| 153 arg_Sn |
| 154 arg_Sn_Dn |
145 arg_const | 155 arg_const |
146 arg_endian | 156 arg_endian |
| 157 arg_fbits |
| 158 arg_fp_0 |
147 arg_imm24 | 159 arg_imm24 |
148 arg_imm5 | 160 arg_imm5 |
149 arg_imm5_32 | 161 arg_imm5_32 |
150 arg_imm5_nz | 162 arg_imm5_nz |
151 arg_imm_12at8_4at0 | 163 arg_imm_12at8_4at0 |
152 arg_imm_4at16_12at0 | 164 arg_imm_4at16_12at0 |
| 165 arg_imm_vfp |
153 arg_label24 | 166 arg_label24 |
154 arg_label24H | 167 arg_label24H |
155 arg_label_m_12 | 168 arg_label_m_12 |
156 arg_label_p_12 | 169 arg_label_p_12 |
157 arg_label_pm_12 | 170 arg_label_pm_12 |
158 arg_label_pm_4_4 | 171 arg_label_pm_4_4 |
159 arg_lsb_width | 172 arg_lsb_width |
160 arg_mem_R | 173 arg_mem_R |
161 arg_mem_R_pm_R_W | 174 arg_mem_R_pm_R_W |
162 arg_mem_R_pm_R_postindex | 175 arg_mem_R_pm_R_postindex |
163 arg_mem_R_pm_R_shift_imm_W | 176 arg_mem_R_pm_R_shift_imm_W |
164 arg_mem_R_pm_R_shift_imm_offset | 177 arg_mem_R_pm_R_shift_imm_offset |
165 arg_mem_R_pm_R_shift_imm_postindex | 178 arg_mem_R_pm_R_shift_imm_postindex |
166 arg_mem_R_pm_imm12_W | 179 arg_mem_R_pm_imm12_W |
167 arg_mem_R_pm_imm12_offset | 180 arg_mem_R_pm_imm12_offset |
168 arg_mem_R_pm_imm12_postindex | 181 arg_mem_R_pm_imm12_postindex |
169 arg_mem_R_pm_imm8_W | 182 arg_mem_R_pm_imm8_W |
170 arg_mem_R_pm_imm8_postindex | 183 arg_mem_R_pm_imm8_postindex |
| 184 arg_mem_R_pm_imm8at0_offset |
171 arg_option | 185 arg_option |
172 arg_registers | 186 arg_registers |
173 arg_registers1 | 187 arg_registers1 |
174 arg_registers2 | 188 arg_registers2 |
175 arg_satimm4 | 189 arg_satimm4 |
176 arg_satimm5 | 190 arg_satimm5 |
177 arg_satimm4m1 | 191 arg_satimm4m1 |
178 arg_satimm5m1 | 192 arg_satimm5m1 |
179 arg_widthm1 | 193 arg_widthm1 |
180 ) | 194 ) |
181 | 195 |
182 // decodeArg decodes the arg described by aop from the instruction bits x. | 196 // decodeArg decodes the arg described by aop from the instruction bits x. |
183 // It returns nil if x cannot be decoded according to aop. | 197 // It returns nil if x cannot be decoded according to aop. |
184 func decodeArg(aop instArg, x uint32) Arg { | 198 func decodeArg(aop instArg, x uint32) Arg { |
185 switch aop { | 199 switch aop { |
186 default: | 200 default: |
187 return nil | 201 return nil |
188 | 202 |
189 case arg_APSR: | 203 case arg_APSR: |
190 return APSR | 204 return APSR |
| 205 case arg_FPSCR: |
| 206 return FPSCR |
191 | 207 |
192 case arg_R_0: | 208 case arg_R_0: |
193 return Reg(x & (1<<4 - 1)) | 209 return Reg(x & (1<<4 - 1)) |
194 case arg_R_8: | 210 case arg_R_8: |
195 return Reg((x >> 8) & (1<<4 - 1)) | 211 return Reg((x >> 8) & (1<<4 - 1)) |
196 case arg_R_12: | 212 case arg_R_12: |
197 return Reg((x >> 12) & (1<<4 - 1)) | 213 return Reg((x >> 12) & (1<<4 - 1)) |
198 case arg_R_16: | 214 case arg_R_16: |
199 return Reg((x >> 16) & (1<<4 - 1)) | 215 return Reg((x >> 16) & (1<<4 - 1)) |
200 | 216 |
| 217 case arg_R_12_nzcv: |
| 218 r := Reg((x >> 12) & (1<<4 - 1)) |
| 219 if r == R15 { |
| 220 return APSR_nzcv |
| 221 } |
| 222 return r |
| 223 |
201 case arg_R_16_WB: | 224 case arg_R_16_WB: |
202 mode := AddrLDM | 225 mode := AddrLDM |
203 if (x>>21)&1 != 0 { | 226 if (x>>21)&1 != 0 { |
204 mode = AddrLDM_WB | 227 mode = AddrLDM_WB |
205 } | 228 } |
206 return Mem{Base: Reg((x >> 16) & (1<<4 - 1)), Mode: mode} | 229 return Mem{Base: Reg((x >> 16) & (1<<4 - 1)), Mode: mode} |
207 | 230 |
208 case arg_R_rotate: | 231 case arg_R_rotate: |
209 Rm := Reg(x & (1<<4 - 1)) | 232 Rm := Reg(x & (1<<4 - 1)) |
210 typ, count := decodeShift(x) | 233 typ, count := decodeShift(x) |
(...skipping 22 matching lines...) Expand all Loading... |
233 case arg_R1_12: | 256 case arg_R1_12: |
234 return Reg(((x >> 12) & (1<<4 - 1))) | 257 return Reg(((x >> 12) & (1<<4 - 1))) |
235 case arg_R2_0: | 258 case arg_R2_0: |
236 return Reg((x & (1<<4 - 1)) | 1) | 259 return Reg((x & (1<<4 - 1)) | 1) |
237 case arg_R2_12: | 260 case arg_R2_12: |
238 return Reg(((x >> 12) & (1<<4 - 1)) | 1) | 261 return Reg(((x >> 12) & (1<<4 - 1)) | 1) |
239 | 262 |
240 case arg_SP: | 263 case arg_SP: |
241 return SP | 264 return SP |
242 | 265 |
| 266 case arg_Sd_Dd: |
| 267 v := (x >> 12) & (1<<4 - 1) |
| 268 vx := (x >> 22) & 1 |
| 269 sz := (x >> 8) & 1 |
| 270 if sz != 0 { |
| 271 return D0 + Reg(vx<<4+v) |
| 272 } else { |
| 273 return S0 + Reg(v<<1+vx) |
| 274 } |
| 275 |
| 276 case arg_Dd_Sd: |
| 277 return decodeArg(arg_Sd_Dd, x^(1<<8)) |
| 278 |
| 279 case arg_Sd: |
| 280 v := (x >> 12) & (1<<4 - 1) |
| 281 vx := (x >> 22) & 1 |
| 282 return S0 + Reg(v<<1+vx) |
| 283 |
| 284 case arg_Sm_Dm: |
| 285 v := (x >> 0) & (1<<4 - 1) |
| 286 vx := (x >> 5) & 1 |
| 287 sz := (x >> 8) & 1 |
| 288 if sz != 0 { |
| 289 return D0 + Reg(vx<<4+v) |
| 290 } else { |
| 291 return S0 + Reg(v<<1+vx) |
| 292 } |
| 293 |
| 294 case arg_Sm: |
| 295 v := (x >> 0) & (1<<4 - 1) |
| 296 vx := (x >> 5) & 1 |
| 297 return S0 + Reg(v<<1+vx) |
| 298 |
| 299 case arg_Dn_half: |
| 300 v := (x >> 16) & (1<<4 - 1) |
| 301 vx := (x >> 7) & 1 |
| 302 return RegX{D0 + Reg(vx<<4+v), int((x >> 21) & 1)} |
| 303 |
| 304 case arg_Sn_Dn: |
| 305 v := (x >> 16) & (1<<4 - 1) |
| 306 vx := (x >> 7) & 1 |
| 307 sz := (x >> 8) & 1 |
| 308 if sz != 0 { |
| 309 return D0 + Reg(vx<<4+v) |
| 310 } else { |
| 311 return S0 + Reg(v<<1+vx) |
| 312 } |
| 313 |
| 314 case arg_Sn: |
| 315 v := (x >> 16) & (1<<4 - 1) |
| 316 vx := (x >> 7) & 1 |
| 317 return S0 + Reg(v<<1+vx) |
| 318 |
243 case arg_const: | 319 case arg_const: |
244 v := x & (1<<8 - 1) | 320 v := x & (1<<8 - 1) |
245 rot := (x >> 8) & (1<<4 - 1) * 2 | 321 rot := (x >> 8) & (1<<4 - 1) * 2 |
246 if rot > 0 && v&3 == 0 { | 322 if rot > 0 && v&3 == 0 { |
247 // could rotate less | 323 // could rotate less |
248 return ImmAlt{uint8(v), uint8(rot)} | 324 return ImmAlt{uint8(v), uint8(rot)} |
249 } | 325 } |
250 if rot >= 24 && ((v<<(32-rot))&0xFF)>>(32-rot) == v { | 326 if rot >= 24 && ((v<<(32-rot))&0xFF)>>(32-rot) == v { |
251 // could wrap around to rot==0. | 327 // could wrap around to rot==0. |
252 return ImmAlt{uint8(v), uint8(rot)} | 328 return ImmAlt{uint8(v), uint8(rot)} |
253 } | 329 } |
254 return Imm(v>>rot | v<<(32-rot)) | 330 return Imm(v>>rot | v<<(32-rot)) |
255 | 331 |
256 case arg_endian: | 332 case arg_endian: |
257 return Endian((x >> 9) & 1) | 333 return Endian((x >> 9) & 1) |
258 | 334 |
| 335 case arg_fbits: |
| 336 return Imm((16 << ((x >> 7) & 1)) - ((x&(1<<4-1))<<1 | (x>>5)&1)
) |
| 337 |
| 338 case arg_fp_0: |
| 339 return Imm(0) |
| 340 |
259 case arg_imm24: | 341 case arg_imm24: |
260 return Imm(x & (1<<24 - 1)) | 342 return Imm(x & (1<<24 - 1)) |
261 | 343 |
262 case arg_imm5: | 344 case arg_imm5: |
263 return Imm((x >> 7) & (1<<5 - 1)) | 345 return Imm((x >> 7) & (1<<5 - 1)) |
264 | 346 |
265 case arg_imm5_32: | 347 case arg_imm5_32: |
266 x = (x >> 7) & (1<<5 - 1) | 348 x = (x >> 7) & (1<<5 - 1) |
267 if x == 0 { | 349 if x == 0 { |
268 x = 32 | 350 x = 32 |
269 } | 351 } |
270 return Imm(x) | 352 return Imm(x) |
271 | 353 |
272 case arg_imm5_nz: | 354 case arg_imm5_nz: |
273 x = (x >> 7) & (1<<5 - 1) | 355 x = (x >> 7) & (1<<5 - 1) |
274 if x == 0 { | 356 if x == 0 { |
275 return nil | 357 return nil |
276 } | 358 } |
277 return Imm(x) | 359 return Imm(x) |
278 | 360 |
279 case arg_imm_4at16_12at0: | 361 case arg_imm_4at16_12at0: |
280 return Imm((x>>16)&(1<<4-1)<<12 | x&(1<<12-1)) | 362 return Imm((x>>16)&(1<<4-1)<<12 | x&(1<<12-1)) |
281 | 363 |
282 case arg_imm_12at8_4at0: | 364 case arg_imm_12at8_4at0: |
283 return Imm((x>>8)&(1<<12-1)<<4 | x&(1<<4-1)) | 365 return Imm((x>>8)&(1<<12-1)<<4 | x&(1<<4-1)) |
| 366 |
| 367 case arg_imm_vfp: |
| 368 x = (x>>16)&(1<<4-1)<<4 | x&(1<<4-1) |
| 369 return Imm(x) |
284 | 370 |
285 case arg_label24: | 371 case arg_label24: |
286 imm := (x & (1<<24 - 1)) << 2 | 372 imm := (x & (1<<24 - 1)) << 2 |
287 return PCRel(int32(imm<<6) >> 6) | 373 return PCRel(int32(imm<<6) >> 6) |
288 | 374 |
289 case arg_label24H: | 375 case arg_label24H: |
290 h := (x >> 24) & 1 | 376 h := (x >> 24) & 1 |
291 imm := (x&(1<<24-1))<<2 | h<<1 | 377 imm := (x&(1<<24-1))<<2 | h<<1 |
292 return PCRel(int32(imm<<6) >> 6) | 378 return PCRel(int32(imm<<6) >> 6) |
293 | 379 |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
404 return nil | 490 return nil |
405 } | 491 } |
406 sign := int8(+1) | 492 sign := int8(+1) |
407 if u == 0 { | 493 if u == 0 { |
408 sign = -1 | 494 sign = -1 |
409 } | 495 } |
410 imm := int16((x>>8)&(1<<4-1)<<4 | x&(1<<4-1)) | 496 imm := int16((x>>8)&(1<<4-1)<<4 | x&(1<<4-1)) |
411 mode := AddrMode(uint8(p<<1) | uint8(w^1)) | 497 mode := AddrMode(uint8(p<<1) | uint8(w^1)) |
412 return Mem{Base: Rn, Mode: mode, Offset: int16(sign) * imm} | 498 return Mem{Base: Rn, Mode: mode, Offset: int16(sign) * imm} |
413 | 499 |
| 500 case arg_mem_R_pm_imm8at0_offset: |
| 501 Rn := Reg((x >> 16) & (1<<4 - 1)) |
| 502 u := (x >> 23) & 1 |
| 503 sign := int8(+1) |
| 504 if u == 0 { |
| 505 sign = -1 |
| 506 } |
| 507 imm := int16(x&(1<<8-1)) << 2 |
| 508 return Mem{Base: Rn, Mode: AddrOffset, Offset: int16(sign) * imm
} |
| 509 |
414 case arg_option: | 510 case arg_option: |
415 return Imm(x & (1<<4 - 1)) | 511 return Imm(x & (1<<4 - 1)) |
416 | 512 |
417 case arg_registers: | 513 case arg_registers: |
418 return RegList(x & (1<<16 - 1)) | 514 return RegList(x & (1<<16 - 1)) |
419 | 515 |
420 case arg_registers2: | 516 case arg_registers2: |
421 x &= 1<<16 - 1 | 517 x &= 1<<16 - 1 |
422 n := 0 | 518 n := 0 |
423 for i := 0; i < 16; i++ { | 519 for i := 0; i < 16; i++ { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
462 count = 32 | 558 count = 32 |
463 } | 559 } |
464 case RotateRight: | 560 case RotateRight: |
465 if count == 0 { | 561 if count == 0 { |
466 typ = RotateRightExt | 562 typ = RotateRightExt |
467 count = 1 | 563 count = 1 |
468 } | 564 } |
469 } | 565 } |
470 return typ, uint8(count) | 566 return typ, uint8(count) |
471 } | 567 } |
LEFT | RIGHT |