1 // This should be compiled as ARM code.
2 
3 #include <stdio.h>
4 #include <malloc.h>
5 
6 typedef unsigned int UInt;
7 
do_ldrt_A1_imm_132(unsigned char * p)8 __attribute__((noinline)) UInt do_ldrt_A1_imm_132 ( unsigned char* p )
9 {
10   UInt res;
11   __asm__ __volatile__(
12   // Twice do ldrt for testing post-indexed.
13      "mov r5, %1 ; ldrt r6, [r5], #+132 ; ldrt r6, [r5], #132 ; mov %0, r6"
14       : "=r"(res) : "r"(p) : "r5", "r6"
15   );
16   return res;
17 }
18 
do_ldrt_A2_imm_132(unsigned char * p)19 __attribute__((noinline)) UInt do_ldrt_A2_imm_132 ( unsigned char* p )
20 {
21   UInt res;
22   __asm__ __volatile__(
23   // Twice ldrt for testing post-indexed.
24      "mov r5, %1 ; mov r6, #33; ldrt r7, [r5], +r6, lsl #2 ; ldrt r7, [r5], +r6, lsl #2 ; mov %0, r7"
25       : "=r"(res) : "r"(p) : "r5", "r6", "r7"
26   );
27   return res;
28 }
29 
do_ldrbt_A1_imm_2(unsigned char * val)30 __attribute__((noinline)) UInt do_ldrbt_A1_imm_2 (unsigned char* val)
31 {
32   UInt res;
33   __asm__ __volatile__(
34   // Twice ldrbt for testing post-indexed.
35      "mov r4, %1 ; ldrbt r5, [r4], #+2; ldrbt r5, [r4], #+2; mov %0, r5"
36      : "=r"(res) : "r"(val) : "r4", "r5"
37   );
38   return res;
39 }
40 
do_ldrbt_A2_imm_2(unsigned char * val)41 __attribute__((noinline)) UInt do_ldrbt_A2_imm_2 (unsigned char* val)
42 {
43   UInt res;
44   __asm__ __volatile__(
45   // Twice ldrbt for testing post-indexed.
46      "mov r4, %1 ; mov r5, #4; ldrbt r6, [r4], +r5, lsr #2 ; ldrbt r6, [r4], +r5, lsr #2; mov %0, r6"
47      : "=r"(res) : "r"(val) : "r4", "r5", "r6"
48   );
49   return res;
50 }
51 
do_ldrht_A1_imm_m2(unsigned char * val)52 __attribute__((noinline)) UInt do_ldrht_A1_imm_m2 (unsigned char* val)
53 {
54   UInt res;
55   __asm__ __volatile__(
56   // Twice ldrht for testing post-indexed.
57      "mov r4, %1 ; ldrht r5, [r4], #-2 ; ldrht r5, [r4], #-2 ; mov %0, r5"
58      : "=r"(res) : "r"(val) : "r4", "r5"
59   );
60   return res;
61 }
62 
do_ldrht_A2_imm_m2(unsigned char * val)63 __attribute__((noinline)) UInt do_ldrht_A2_imm_m2 (unsigned char* val)
64 {
65   UInt res;
66   __asm__ __volatile__(
67   // Twice ldrht for testing post-indexed.
68      "mov r4, %1 ; mov r5, #2 ; ldrht r6, [r4], -r5 ; ldrht r6, [r4], -r5 ; mov %0, r6"
69      : "=r"(res) : "r"(val) : "r4", "r5", "r6"
70   );
71   return res;
72 }
73 
do_ldrsht_A1_imm_m2(unsigned char * val)74 __attribute__((noinline)) UInt do_ldrsht_A1_imm_m2 (unsigned char* val)
75 {
76   UInt res;
77   __asm__ __volatile__(
78   // Twice ldrsht for testing post-indexed.
79      "mov r4, %1 ; ldrsht r5, [r4], #-2 ; ldrsht r5, [r4], #-2 ; mov %0, r5"
80      : "=r"(res) : "r"(val) : "r4", "r5"
81   );
82   return res;
83 }
84 
do_ldrsht_A2_imm_1(unsigned char * val)85 __attribute__((noinline)) UInt do_ldrsht_A2_imm_1 (unsigned char* val)
86 {
87   UInt res;
88   __asm__ __volatile__(
89   // Twice ldrsht for testing post-indexed.
90      "mov r4, %1 ; mov r5, #1 ; ldrsht r6, [r4], r5 ; ldrsht r6, [r4], r5 ; mov %0, r6"
91      : "=r"(res) : "r"(val) : "r4", "r5", "r6"
92   );
93   return res;
94 }
95 
do_ldrsbt_A1_imm_1(unsigned char * val)96 __attribute__((noinline)) UInt do_ldrsbt_A1_imm_1 (unsigned char* val)
97 {
98   UInt res;
99   __asm__ __volatile__(
100   // Twice ldrsbt for testing post-indexed.
101      "mov r4, %1 ; ldrsbt r5, [r4], #1 ; ldrsbt r5, [r4], #1 ; mov %0, r5"
102      : "=r"(res) : "r"(val) : "r4", "r5"
103   );
104   return res;
105 }
106 
do_ldrsbt_A2_imm_1(unsigned char * val)107 __attribute__((noinline)) UInt do_ldrsbt_A2_imm_1 (unsigned char* val)
108 {
109   UInt res;
110   __asm__ __volatile__(
111   // Twice ldrsbt for testing post-indexed.
112      "mov r4, %1 ; mov r5, #1 ; ldrsbt r6, [r4], r5 ; ldrsbt r6, [r4], r5 ; mov %0, r6"
113      : "=r"(res) : "r"(val) : "r4", "r5", "r6"
114   );
115   return res;
116 }
117 
do_strbt_A1_imm_1(unsigned char * val)118 __attribute__((noinline)) void do_strbt_A1_imm_1 (unsigned char* val)
119 {
120   __asm__ __volatile__(
121   // Twice strbt for testing post-indexed.
122      "mov r4, %0 ; mov r5, #0xCD ; strbt r5, [r4], #1 ; strbt r5, [r4], #1"
123      : : "r"(val) : "r4", "r5"
124   );
125 }
126 
do_strbt_A2_imm_1(unsigned char * val)127 __attribute__((noinline)) void do_strbt_A2_imm_1 (unsigned char* val)
128 {
129   __asm__ __volatile__(
130   // Twice strbt for testing post-indexed.
131      "mov r4, %0 ; mov r5, #1 ; mov r6, #0xCD ; strbt r6, [r4], r5, LSL #1 ; strbt r6, [r4], r5"
132      : : "r"(val) : "r4", "r5", "r6"
133   );
134 }
135 
do_strht_A1_imm_1(unsigned char * val)136 __attribute__((noinline)) void do_strht_A1_imm_1 (unsigned char* val)
137 {
138   __asm__ __volatile__(
139   // Twice strht for testing post-indexed.
140      "mov r4, %0 ; ldr r5, =0xABCD ; strht r5, [r4], #1 ; strht r5, [r4], #1"
141      : : "r"(val) : "r4", "r5"
142   );
143 }
144 
do_strht_A2_imm_1(unsigned char * val)145 __attribute__((noinline)) void do_strht_A2_imm_1 (unsigned char* val)
146 {
147   __asm__ __volatile__(
148   // Twice strht for testing post-indexed.
149      "mov r4, %0 ; mov r5, #1 ; ldr r6, =0xDCBA ; strht r6, [r4], r5  ; strht r6, [r4], r5"
150      : : "r"(val) : "r4", "r5", "r6"
151   );
152 }
153 
do_strt_A1_imm_4(unsigned char * val)154 __attribute__((noinline)) void do_strt_A1_imm_4 (unsigned char* val)
155 {
156   __asm__ __volatile__(
157   // Twice strt for testing post-indexed.
158      "mov r4, %0 ; ldr r5, =0xABCDEFFF ; strt r5, [r4], #4  ; ldr r5, =0x01234567 ; strt r5, [r4], #0"
159      : : "r"(val) : "r4", "r5"
160   );
161 }
162 
do_strt_A2_imm_4(unsigned char * val)163 __attribute__((noinline)) void do_strt_A2_imm_4 (unsigned char* val)
164 {
165   __asm__ __volatile__(
166   // Twice strt for testing post-indexed.
167      "mov r4, %0 ; mov r5, #2 ; ldr r6, =0xFFFEDCBA ; strt r6, [r4], -r5, LSL #1  ; mov r5, #0 ; ldr r6, =0x76543210 ; strt r6, [r4], +r5"
168      : : "r"(val) : "r4", "r5", "r6"
169   );
170 }
171 
main(void)172 int main ( void )
173 {
174   UInt i;
175   unsigned char* b = malloc(256);
176   for (i = 0; i < 256; i++) b[i] = (unsigned char)i;
177   UInt r = do_ldrt_A1_imm_132(b);
178   free(b);
179   printf("result is 0x%08x (should be 0x%08x)\n", r, 0x87868584);
180 
181   UInt j;
182   unsigned char* c = malloc(256);
183   for (j = 0; j < 256; j++) c[j] = (unsigned char)j;
184   UInt k = do_ldrt_A2_imm_132(c);
185   free(c);
186   printf("result is 0x%08x (should be 0x%08x)\n", k, 0x87868584);
187 
188   UInt val_ldrbt = (200 << 0) | (150 << 8) | (137 << 16) | (10 << 24);
189   printf("result is %u (should be %u)\n", do_ldrbt_A1_imm_2((unsigned char*)&val_ldrbt), 137);
190 
191   UInt val_ldrbt_A2 = (200 << 0) | (150 << 8) | (137 << 16) | (10 << 24);
192   printf("result is %u (should be %u)\n", do_ldrbt_A2_imm_2((unsigned char*)&val_ldrbt_A2), 150);
193 
194   UInt val_ldrht_A1 = (0xC8 << 0) | (0xF6 << 8) | (0xBB << 16) | (0x0A << 24);
195   printf("result is %u (should be %u)\n", do_ldrht_A1_imm_m2((unsigned char*)&val_ldrht_A1 + 2), 0x0000F6C8);
196 
197   UInt val_ldrht_A2 = (0xC8 << 0) | (0xF7 << 8) | (0xBB << 16) | (0x0A << 24);
198   printf("result is %u (should be %u)\n", do_ldrht_A2_imm_m2((unsigned char*)&val_ldrht_A2 + 2), 0x0000F7C8);
199 
200   UInt val_ldrsht_A1 = (0x08 << 0) | (0xFC << 8) | (0x0B << 16) | (0x0A << 24);
201   printf("result is %u (should be %u)\n", do_ldrsht_A1_imm_m2((unsigned char*)&val_ldrsht_A1 + 2), 0xFFFFFC08);
202 
203   UInt val_ldrsht_A2 = (0xC8 << 0) | (0x0B << 8) | (0xFB << 16) | (0x0A << 24);
204   printf("result is %u (should be %u)\n", do_ldrsht_A2_imm_1((unsigned char*)&val_ldrsht_A2), 0xFFFFFB0B);
205 
206   UInt val_ldrsbt_A1 = (0xC8 << 0) | (0xF0 << 8) | (0xCD << 16) | (0x0A << 24);
207   printf("result is %u (should be %u)\n", do_ldrsbt_A1_imm_1((unsigned char*)&val_ldrsbt_A1), 0xFFFFFFF0);
208 
209   UInt val_ldrsbt_A2 = (0xC8 << 0) | (0xF0 << 8) | (0xFD << 16) | (0x0A << 24);
210   printf("result is %u (should be %u)\n", do_ldrsbt_A2_imm_1((unsigned char*)&val_ldrsbt_A2 + 1), 0xFFFFFFFD);
211 
212   UInt val_strbt_A1 = (0xC8 << 0) | (0xF0 << 8) | (0xFD << 16) | (0x0A << 24);
213   do_strbt_A1_imm_1((unsigned char*)&val_strbt_A1);
214   printf("result is %u (should be %u)\n", val_strbt_A1, 0x0AFDCDCD);
215 
216   UInt val_strbt_A2 = (0xC8 << 0) | (0xF0 << 8) | (0xFD << 16) | (0x0A << 24);
217   do_strbt_A2_imm_1((unsigned char*)&val_strbt_A2);
218   printf("result is %u (should be %u)\n", val_strbt_A2, 0x0ACDF0CD);
219 
220   UInt val_strht_A1 = 0xFFFFFFFF;
221   do_strht_A1_imm_1((unsigned char*)&val_strht_A1);
222   printf("result is %u (should be %u)\n", val_strht_A1, 0xFFABCDCD);
223 
224   UInt val_strht_A2 = 0xFFFFFFFF;
225   do_strht_A2_imm_1((unsigned char*)&val_strht_A2);
226   printf("result is %u (should be %u)\n", val_strht_A2, 0xFFDCBABA);
227 
228   UInt val_strt_A1[2] = {0xFFFFFFFF, 0xFFFFFFFF};
229   do_strt_A1_imm_4((unsigned char*)&val_strt_A1[0]);
230   printf("result is %u %u (should be %u %u)\n", val_strt_A1[0], val_strt_A1[1], 0xABCDEFFF, 0x01234567);
231 
232   UInt val_strt_A2[2] = {0xFFFFFFFF, 0xFFFFFFFF};
233   do_strt_A2_imm_4((unsigned char*)&val_strt_A2[1]);
234   printf("result is %u %u (should be %u %u)\n", val_strt_A2[0], val_strt_A2[1], 0x76543210, 0xFFFEDCBA);
235 
236   return 0;
237 }
238