3 typedef unsigned int u32;
\r
5 u32 arm_imm_find_nonzero(u32 imm, u32 start_bit)
\r
9 for(i = start_bit; i < 32; i += 2)
\r
11 if((imm >> i) & 0x03)
\r
18 u32 arm_disect_imm_32bit(u32 imm, u32 *stores, u32 *rotations)
\r
20 u32 store_count = 0;
\r
23 // Otherwise it'll return 0 things to store because it'll never
\r
32 // Find chunks of non-zero data at 2 bit alignments.
\r
35 left_shift = arm_imm_find_nonzero(imm, left_shift);
\r
37 if(left_shift == 32)
\r
39 // We've hit the end of the useful data.
\r
43 // Hit the end, it might wrap back around to the beginning.
\r
44 if(left_shift >= 24)
\r
46 // Make a mask for the residual bits. IE, if we have
\r
47 // 5 bits of data at the end we can wrap around to 3
\r
48 // bits of data in the beginning. Thus the first
\r
49 // thing, after being shifted left, has to be less
\r
50 // than 111b, 0x7, or (1 << 3) - 1.
\r
51 u32 top_bits = 32 - left_shift;
\r
52 u32 residual_bits = 8 - top_bits;
\r
53 u32 residual_mask = (1 << residual_bits) - 1;
\r
55 if((store_count > 1) && (left_shift > 24) &&
\r
56 ((stores[0] << (32 - rotations[0])) < residual_mask))
\r
58 // Then we can throw out the last bit and tack it on
\r
59 // to the first bit.
\r
60 u32 initial_bits = rotations[0];
\r
61 stores[0] = (stores[0] << (top_bits + (32 - rotations[0]))) |
\r
62 ((imm >> left_shift) & 0xFF);
\r
63 rotations[0] = top_bits;
\r
69 // There's nothing to wrap over to in the beginning
\r
70 stores[store_count] = (imm >> left_shift) & 0xFF;
\r
71 rotations[store_count] = (32 - left_shift) & 0x1F;
\r
72 return store_count + 1;
\r
77 stores[store_count] = (imm >> left_shift) & 0xFF;
\r
78 rotations[store_count] = (32 - left_shift) & 0x1F;
\r
85 #define ror(value, shift) \
\r
86 ((value) >> shift) | ((value) << (32 - shift)) \
\r
88 u32 arm_assemble_imm_32bit(u32 *stores, u32 *rotations, u32 store_count)
\r
90 u32 n = ror(stores[0], rotations[0]);
\r
92 printf("%x : %x\n", stores[0], rotations[0]);
\r
94 for(i = 1; i < store_count; i++)
\r
96 printf("%x : %x\n", stores[i], rotations[i]);
\r
97 n |= ror(stores[i], rotations[i]);
\r
104 int main(int argc, char *argv[])
\r
114 n = strtoul(argv[1], NULL, 16);
\r
115 store_count = arm_disect_imm_32bit(n, stores, rotations);
\r
116 n2 = arm_assemble_imm_32bit(stores, rotations, store_count);
\r
117 printf("%08x -> %08x (%d stores)\n", n, n2, store_count);
\r
123 store_count = arm_disect_imm_32bit(n, stores, rotations);
\r
124 n2 = arm_assemble_imm_32bit(stores, rotations, store_count);
\r
127 printf("Failure: %08x -/-> %08x\n", n, n2);
\r