Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(25)

Delta Between Two Patch Sets: armasm/decode.go

Issue 104770047: code review 104770047: armasm: add VFP, golden testdata (Closed)
Left Patch Set: Created 10 years, 10 months ago
Right Patch Set: diff -r 08f5d599cb70 https://code.google.com/p/rsc.arm/ Created 10 years, 10 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Right: Side by side diff | Download
« no previous file with change/comment | « arm.csv ('k') | armasm/decode_test.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(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
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
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
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
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 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b