blob: 17caee1c92417542b0a14becb34e5727fb37e8a6 [file] [log] [blame]
Ashok Bhat658f89d2013-02-28 18:32:03 +00001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28#include <stdio.h>
29#include <inttypes.h>
30#include <string.h>
31
32int aarch64_disassemble(uint32_t code, char* instr);
33
34struct test_table_entry_t
35{
36 uint32_t code;
37 const char *instr;
38};
39static test_table_entry_t test_table [] =
40{
41 { 0x91000240, "add x0, x18, #0x0, lsl #0" },
42 { 0x9140041f, "add sp, x0, #0x1, lsl #12" },
43 { 0x917ffff2, "add x18, sp, #0xfff, lsl #12" },
44
45 { 0xd13ffe40, "sub x0, x18, #0xfff, lsl #0" },
46 { 0xd140001f, "sub sp, x0, #0x0, lsl #12" },
47 { 0xd14007f2, "sub x18, sp, #0x1, lsl #12" },
48
49 { 0x8b1e0200, "add x0, x16, x30, lsl #0" },
50 { 0x8b507fdf, "add xzr, x30, x16, lsr #31" },
51 { 0x8b8043f0, "add x16, xzr, x0, asr #16" },
52 { 0x8b5f401e, "add x30, x0, xzr, lsr #16" },
53
54
55 { 0x4b1e0200, "sub w0, w16, w30, lsl #0" },
56 { 0x4b507fdf, "sub wzr, w30, w16, lsr #31" },
57 { 0x4b8043f0, "sub w16, wzr, w0, asr #16" },
58 { 0x4b5f401e, "sub w30, w0, wzr, lsr #16" },
59
60 { 0x6b1e0200, "subs w0, w16, w30, lsl #0" },
61 { 0x6b507fdf, "subs wzr, w30, w16, lsr #31" },
62 { 0x6b8043f0, "subs w16, wzr, w0, asr #16" },
63 { 0x6b5f401e, "subs w30, w0, wzr, lsr #16" },
64
65 { 0x0a1e0200, "and w0, w16, w30, lsl #0" },
66 { 0x0a507fdf, "and wzr, w30, w16, lsr #31" },
67 { 0x0a8043f0, "and w16, wzr, w0, asr #16" },
68 { 0x0adf401e, "and w30, w0, wzr, ror #16" },
69
70 { 0x2a1e0200, "orr w0, w16, w30, lsl #0" },
71 { 0x2a507fdf, "orr wzr, w30, w16, lsr #31" },
72 { 0x2a8043f0, "orr w16, wzr, w0, asr #16" },
73 { 0x2adf401e, "orr w30, w0, wzr, ror #16" },
74
75 { 0x2a3e0200, "orn w0, w16, w30, lsl #0" },
76 { 0x2a707fdf, "orn wzr, w30, w16, lsr #31" },
77 { 0x2aa043f0, "orn w16, wzr, w0, asr #16" },
78 { 0x2aff401e, "orn w30, w0, wzr, ror #16" },
79
80 { 0x729fffe0, "movk w0, #0xffff, lsl #0" },
81 { 0x72a0000f, "movk w15, #0x0, lsl #16" },
82 { 0x7281fffe, "movk w30, #0xfff, lsl #0" },
83 { 0x72a0003f, "movk wzr, #0x1, lsl #16" },
84
85 { 0x529fffe0, "movz w0, #0xffff, lsl #0" },
86 { 0x52a0000f, "movz w15, #0x0, lsl #16" },
87 { 0x5281fffe, "movz w30, #0xfff, lsl #0" },
88 { 0x52a0003f, "movz wzr, #0x1, lsl #16" },
89
90 { 0xd29fffe0, "movz x0, #0xffff, lsl #0" },
91 { 0xd2a0000f, "movz x15, #0x0, lsl #16" },
92 { 0xd2c1fffe, "movz x30, #0xfff, lsl #32" },
93 { 0xd2e0003f, "movz xzr, #0x1, lsl #48" },
94
95 { 0x1a8003e0, "csel w0, wzr, w0, eq" },
96 { 0x1a831001, "csel w1, w0, w3, ne" },
97 { 0x1a9e2022, "csel w2, w1, w30, cs" },
98 { 0x1a8a3083, "csel w3, w4, w10, cc" },
99 { 0x1a8b40e4, "csel w4, w7, w11, mi" },
100 { 0x1a9b5105, "csel w5, w8, w27, pl" },
101 { 0x1a846167, "csel w7, w11, w4, vs" },
102 { 0x1a8671c8, "csel w8, w14, w6, vc" },
103 { 0x1a878289, "csel w9, w20, w7, hi" },
104 { 0x1a8c92aa, "csel w10, w21, w12, ls" },
105 { 0x1a8ea2ce, "csel w14, w22, w14, ge" },
106 { 0x1a9fb3b2, "csel w18, w29, wzr, lt" },
107 { 0x1a9fc3d8, "csel w24, w30, wzr, gt" },
108 { 0x1a82d17e, "csel w30, w11, w2, le" },
109 { 0x1a81e19f, "csel wzr, w12, w1, al" },
110
111 { 0x9a8003e0, "csel x0, xzr, x0, eq" },
112 { 0x9a831001, "csel x1, x0, x3, ne" },
113 { 0x9a9e2022, "csel x2, x1, x30, cs" },
114 { 0x9a8a3083, "csel x3, x4, x10, cc" },
115 { 0x9a8b40e4, "csel x4, x7, x11, mi" },
116 { 0x9a9b5105, "csel x5, x8, x27, pl" },
117 { 0x9a846167, "csel x7, x11, x4, vs" },
118 { 0x9a8671c8, "csel x8, x14, x6, vc" },
119 { 0x9a878289, "csel x9, x20, x7, hi" },
120 { 0x9a8c92aa, "csel x10, x21, x12, ls" },
121 { 0x9a8ea2ce, "csel x14, x22, x14, ge" },
122 { 0x9a9fb3b2, "csel x18, x29, xzr, lt" },
123 { 0x9a9fc3d8, "csel x24, x30, xzr, gt" },
124 { 0x9a82d17e, "csel x30, x11, x2, le" },
125 { 0x9a81e19f, "csel xzr, x12, x1, al" },
126
127 { 0x5a8003e0, "csinv w0, wzr, w0, eq" },
128 { 0x5a831001, "csinv w1, w0, w3, ne" },
129 { 0x5a9e2022, "csinv w2, w1, w30, cs" },
130 { 0x5a8a3083, "csinv w3, w4, w10, cc" },
131 { 0x5a8b40e4, "csinv w4, w7, w11, mi" },
132 { 0x5a9b5105, "csinv w5, w8, w27, pl" },
133 { 0x5a846167, "csinv w7, w11, w4, vs" },
134 { 0x5a8671c8, "csinv w8, w14, w6, vc" },
135 { 0x5a878289, "csinv w9, w20, w7, hi" },
136 { 0x5a8c92aa, "csinv w10, w21, w12, ls" },
137 { 0x5a8ea2ce, "csinv w14, w22, w14, ge" },
138 { 0x5a9fb3b2, "csinv w18, w29, wzr, lt" },
139 { 0x5a9fc3d8, "csinv w24, w30, wzr, gt" },
140 { 0x5a82d17e, "csinv w30, w11, w2, le" },
141 { 0x5a81e19f, "csinv wzr, w12, w1, al" },
142
143 { 0x1b1f3fc0, "madd w0, w30, wzr, w15" },
144 { 0x1b0079ef, "madd w15, w15, w0, w30" },
145 { 0x1b0f7ffe, "madd w30, wzr, w15, wzr" },
146 { 0x1b1e001f, "madd wzr, w0, w30, w0" },
147
148 { 0x9b3f3fc0, "smaddl x0, w30, wzr, x15" },
149 { 0x9b2079ef, "smaddl x15, w15, w0, x30" },
150 { 0x9b2f7ffe, "smaddl x30, wzr, w15, xzr" },
151 { 0x9b3e001f, "smaddl xzr, w0, w30, x0" },
152
153 { 0xd65f0000, "ret x0" },
154 { 0xd65f01e0, "ret x15" },
155 { 0xd65f03c0, "ret x30" },
156 { 0xd65f03e0, "ret xzr" },
157
158 { 0xb87f4be0, "ldr w0, [sp, wzr, uxtw #0]" },
159 { 0xb87ed80f, "ldr w15, [x0, w30, sxtw #2]" },
160 { 0xb86fc9fe, "ldr w30, [x15, w15, sxtw #0]" },
161 { 0xb8605bdf, "ldr wzr, [x30, w0, uxtw #2]" },
162 { 0xb87febe0, "ldr w0, [sp, xzr, sxtx #0]" },
163 { 0xb87e780f, "ldr w15, [x0, x30, lsl #2]" },
164 { 0xb86f69fe, "ldr w30, [x15, x15, lsl #0]" },
165 { 0xb860fbdf, "ldr wzr, [x30, x0, sxtx #2]" },
166
167 { 0xb83f4be0, "str w0, [sp, wzr, uxtw #0]" },
168 { 0xb83ed80f, "str w15, [x0, w30, sxtw #2]" },
169 { 0xb82fc9fe, "str w30, [x15, w15, sxtw #0]" },
170 { 0xb8205bdf, "str wzr, [x30, w0, uxtw #2]" },
171 { 0xb83febe0, "str w0, [sp, xzr, sxtx #0]" },
172 { 0xb83e780f, "str w15, [x0, x30, lsl #2]" },
173 { 0xb82f69fe, "str w30, [x15, x15, lsl #0]" },
174 { 0xb820fbdf, "str wzr, [x30, x0, sxtx #2]" },
175
176 { 0x787f4be0, "ldrh w0, [sp, wzr, uxtw #0]" },
177 { 0x787ed80f, "ldrh w15, [x0, w30, sxtw #1]" },
178 { 0x786fc9fe, "ldrh w30, [x15, w15, sxtw #0]" },
179 { 0x78605bdf, "ldrh wzr, [x30, w0, uxtw #1]" },
180 { 0x787febe0, "ldrh w0, [sp, xzr, sxtx #0]" },
181 { 0x787e780f, "ldrh w15, [x0, x30, lsl #1]" },
182 { 0x786f69fe, "ldrh w30, [x15, x15, lsl #0]" },
183 { 0x7860fbdf, "ldrh wzr, [x30, x0, sxtx #1]" },
184
185 { 0x783f4be0, "strh w0, [sp, wzr, uxtw #0]" },
186 { 0x783ed80f, "strh w15, [x0, w30, sxtw #1]" },
187 { 0x782fc9fe, "strh w30, [x15, w15, sxtw #0]" },
188 { 0x78205bdf, "strh wzr, [x30, w0, uxtw #1]" },
189 { 0x783febe0, "strh w0, [sp, xzr, sxtx #0]" },
190 { 0x783e780f, "strh w15, [x0, x30, lsl #1]" },
191 { 0x782f69fe, "strh w30, [x15, x15, lsl #0]" },
192 { 0x7820fbdf, "strh wzr, [x30, x0, sxtx #1]" },
193
194 { 0x387f5be0, "ldrb w0, [sp, wzr, uxtw #0]" },
195 { 0x387ec80f, "ldrb w15, [x0, w30, sxtw ]" },
196 { 0x386fd9fe, "ldrb w30, [x15, w15, sxtw #0]" },
197 { 0x38604bdf, "ldrb wzr, [x30, w0, uxtw ]" },
198 { 0x387ffbe0, "ldrb w0, [sp, xzr, sxtx #0]" },
199 { 0x387e780f, "ldrb w15, [x0, x30, lsl #0]" },
200 { 0x386f79fe, "ldrb w30, [x15, x15, lsl #0]" },
201 { 0x3860ebdf, "ldrb wzr, [x30, x0, sxtx ]" },
202
203 { 0x383f5be0, "strb w0, [sp, wzr, uxtw #0]" },
204 { 0x383ec80f, "strb w15, [x0, w30, sxtw ]" },
205 { 0x382fd9fe, "strb w30, [x15, w15, sxtw #0]" },
206 { 0x38204bdf, "strb wzr, [x30, w0, uxtw ]" },
207 { 0x383ffbe0, "strb w0, [sp, xzr, sxtx #0]" },
208 { 0x383e780f, "strb w15, [x0, x30, lsl #0]" },
209 { 0x382f79fe, "strb w30, [x15, x15, lsl #0]" },
210 { 0x3820ebdf, "strb wzr, [x30, x0, sxtx ]" },
211
212 { 0xf87f4be0, "ldr x0, [sp, wzr, uxtw #0]" },
213 { 0xf87ed80f, "ldr x15, [x0, w30, sxtw #3]" },
214 { 0xf86fc9fe, "ldr x30, [x15, w15, sxtw #0]" },
215 { 0xf8605bdf, "ldr xzr, [x30, w0, uxtw #3]" },
216 { 0xf87febe0, "ldr x0, [sp, xzr, sxtx #0]" },
217 { 0xf87e780f, "ldr x15, [x0, x30, lsl #3]" },
218 { 0xf86f69fe, "ldr x30, [x15, x15, lsl #0]" },
219 { 0xf860fbdf, "ldr xzr, [x30, x0, sxtx #3]" },
220
221 { 0xf83f4be0, "str x0, [sp, wzr, uxtw #0]" },
222 { 0xf83ed80f, "str x15, [x0, w30, sxtw #3]" },
223 { 0xf82fc9fe, "str x30, [x15, w15, sxtw #0]" },
224 { 0xf8205bdf, "str xzr, [x30, w0, uxtw #3]" },
225 { 0xf83febe0, "str x0, [sp, xzr, sxtx #0]" },
226 { 0xf83e780f, "str x15, [x0, x30, lsl #3]" },
227 { 0xf82f69fe, "str x30, [x15, x15, lsl #0]" },
228 { 0xf820fbdf, "str xzr, [x30, x0, sxtx #3]" },
229
230 { 0xb85007e0, "ldr w0, [sp], #-256" },
231 { 0xb840040f, "ldr w15, [x0], #0" },
232 { 0xb84015fe, "ldr w30, [x15], #1" },
233 { 0xb84ff7df, "ldr wzr, [x30], #255" },
234 { 0xb8100fe0, "str w0, [sp, #-256]!" },
235 { 0xb8000c0f, "str w15, [x0, #0]!" },
236 { 0xb8001dfe, "str w30, [x15, #1]!" },
237 { 0xb80fffdf, "str wzr, [x30, #255]!" },
238
239 { 0x13017be0, "sbfm w0, wzr, #1, #30" },
240 { 0x131e7fcf, "sbfm w15, w30, #30, #31" },
241 { 0x131f01fe, "sbfm w30, w15, #31, #0" },
242 { 0x1300041f, "sbfm wzr, w0, #0, #1" },
243
244 { 0x53017be0, "ubfm w0, wzr, #1, #30" },
245 { 0x531e7fcf, "ubfm w15, w30, #30, #31" },
246 { 0x531f01fe, "ubfm w30, w15, #31, #0" },
247 { 0x5300041f, "ubfm wzr, w0, #0, #1" },
248 { 0xd3417fe0, "ubfm x0, xzr, #1, #31" },
249 { 0xd35fffcf, "ubfm x15, x30, #31, #63" },
250 { 0xd35f01fe, "ubfm x30, x15, #31, #0" },
251 { 0xd340041f, "ubfm xzr, x0, #0, #1" },
252
253 { 0x139e7be0, "extr w0, wzr, w30, #30" },
254 { 0x138f7fcf, "extr w15, w30, w15, #31" },
255 { 0x138001fe, "extr w30, w15, w0, #0" },
256 { 0x139f041f, "extr wzr, w0, wzr, #1" },
257
258 { 0x54000020, "b.eq #.+4" },
259 { 0x54000201, "b.ne #.+64" },
260 { 0x54000802, "b.cs #.+256" },
261 { 0x54002003, "b.cc #.+1024" },
262 { 0x54008004, "b.mi #.+4096" },
263 { 0x54ffffe5, "b.pl #.-4" },
264 { 0x54ffff06, "b.vs #.-32" },
265 { 0x54fffc07, "b.vc #.-128" },
266 { 0x54fff008, "b.hi #.-512" },
267 { 0x54000049, "b.ls #.+8" },
268 { 0x5400006a, "b.ge #.+12" },
269 { 0x5400008b, "b.lt #.+16" },
270 { 0x54ffffcc, "b.gt #.-8" },
271 { 0x54ffffad, "b.le #.-12" },
272 { 0x54ffff8e, "b.al #.-16" },
273
274 { 0x8b2001e0, "add x0, x15, w0, uxtb #0" },
275 { 0x8b2f27cf, "add x15, x30, w15, uxth #1" },
276 { 0x8b3e4bfe, "add x30, sp, w30, uxtw #2" },
277 { 0x8b3f6c1f, "add sp, x0, xzr, uxtx #3" },
278 { 0x8b2091e0, "add x0, x15, w0, sxtb #4" },
279 { 0x8b2fa3cf, "add x15, x30, w15, sxth #0" },
280 { 0x8b3ec7fe, "add x30, sp, w30, sxtw #1" },
281 { 0x8b3fe81f, "add sp, x0, xzr, sxtx #2" },
282
283 { 0xcb2001e0, "sub x0, x15, w0, uxtb #0" },
284 { 0xcb2f27cf, "sub x15, x30, w15, uxth #1" },
285 { 0xcb3e4bfe, "sub x30, sp, w30, uxtw #2" },
286 { 0xcb3f6c1f, "sub sp, x0, xzr, uxtx #3" },
287 { 0xcb2091e0, "sub x0, x15, w0, sxtb #4" },
288 { 0xcb2fa3cf, "sub x15, x30, w15, sxth #0" },
289 { 0xcb3ec7fe, "sub x30, sp, w30, sxtw #1" },
290 { 0xcb3fe81f, "sub sp, x0, xzr, sxtx #2" }
291};
292
293int main()
294{
295 char instr[256];
296 uint32_t failed = 0;
297 for(uint32_t i = 0; i < sizeof(test_table)/sizeof(test_table_entry_t); ++i)
298 {
299 test_table_entry_t *test;
300 test = &test_table[i];
301 aarch64_disassemble(test->code, instr);
302 if(strcmp(instr, test->instr) != 0)
303 {
304 printf("Test Failed \n"
305 "Code : 0x%0x\n"
306 "Expected : %s\n"
307 "Actual : %s\n", test->code, test->instr, instr);
308 failed++;
309 }
310 }
311 if(failed == 0)
312 {
313 printf("All tests PASSED\n");
314 return 0;
315 }
316 else
317 {
318 printf("%d tests FAILED\n", failed);
319 return -1;
320 }
321}