nds32: add new target type nds32_v2, nds32_v3, nds32_v3m
[openocd.git] / src / target / nds32_disassembler.c
1 /***************************************************************************
2 * Copyright (C) 2013 Andes Technology *
3 * Hsiangkai Wang <hkwang@andestech.com> *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
19 ***************************************************************************/
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <helper/log.h>
26 #include <target/target.h>
27 #include "nds32_disassembler.h"
28
29 static const int enable4_bits[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
30
31 int nds32_read_opcode(struct nds32 *nds32, uint32_t address, uint32_t *value)
32 {
33 struct target *target = nds32->target;
34 uint8_t value_buf[4];
35
36 if (!target_was_examined(target)) {
37 LOG_ERROR("Target not examined yet");
38 return ERROR_FAIL;
39 }
40
41 int retval = target_read_buffer(target, address, 4, value_buf);
42
43 if (retval == ERROR_OK) {
44 /* instructions are always big-endian */
45 *value = be_to_h_u32(value_buf);
46
47 LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8" PRIx32 "",
48 address,
49 *value);
50 } else {
51 *value = 0x0;
52 LOG_DEBUG("address: 0x%8.8" PRIx32 " failed",
53 address);
54 }
55
56 return retval;
57 }
58
59 static int nds32_parse_type_0(uint32_t opcode, int32_t *imm)
60 {
61 *imm = opcode & 0x1FFFFFF;
62
63 return ERROR_OK;
64 }
65
66 static int nds32_parse_type_1(uint32_t opcode, uint8_t *rt, int32_t *imm)
67 {
68 *rt = (opcode >> 20) & 0x1F;
69 *imm = opcode & 0xFFFFF;
70
71 return ERROR_OK;
72 }
73
74 static int nds32_parse_type_2(uint32_t opcode, uint8_t *rt, uint8_t *ra, int32_t *imm)
75 {
76 *rt = (opcode >> 20) & 0x1F;
77 *ra = (opcode >> 15) & 0x1F;
78 *imm = opcode & 0x7FFF;
79
80 return ERROR_OK;
81 }
82
83 static int nds32_parse_type_3(uint32_t opcode, uint8_t *rt, uint8_t *ra,
84 uint8_t *rb, int32_t *imm)
85 {
86 *rt = (opcode >> 20) & 0x1F;
87 *ra = (opcode >> 15) & 0x1F;
88 *rb = (opcode >> 10) & 0x1F;
89 *imm = opcode & 0x3FF;
90
91 return ERROR_OK;
92 }
93
94 static int nds32_parse_type_4(uint32_t opcode, uint8_t *rt, uint8_t *ra,
95 uint8_t *rb, uint8_t *rd, uint8_t *sub_opc)
96 {
97 *rt = (opcode >> 20) & 0x1F;
98 *ra = (opcode >> 15) & 0x1F;
99 *rb = (opcode >> 10) & 0x1F;
100 *rd = (opcode >> 5) & 0x1F;
101 *sub_opc = opcode & 0x1F;
102
103 return ERROR_OK;
104 }
105
106 /* LBI, LHI, LWI, LBI.bi, LHI.bi, LWI.bi */
107 static int nds32_parse_group_0_insn(struct nds32 *nds32, uint32_t opcode,
108 uint32_t address,
109 struct nds32_instruction *instruction)
110 {
111 uint8_t opc_6;
112
113 opc_6 = instruction->info.opc_6;
114
115 switch (opc_6 & 0x7) {
116 case 0: /* LBI */
117 nds32_parse_type_2(opcode, &(instruction->info.rt),
118 &(instruction->info.ra), &(instruction->info.imm));
119 instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */
120 instruction->type = NDS32_INSN_LOAD_STORE;
121 nds32_get_mapped_reg(nds32, instruction->info.ra,
122 &(instruction->access_start));
123 instruction->access_start += instruction->info.imm;
124 instruction->access_end = instruction->access_start + 1;
125 snprintf(instruction->text,
126 128,
127 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLBI\t$r%d,[$r%d+#%d]",
128 address,
129 opcode, instruction->info.rt, instruction->info.ra,
130 instruction->info.imm);
131 break;
132 case 1: /* LHI */
133 nds32_parse_type_2(opcode, &(instruction->info.rt),
134 &(instruction->info.ra), &(instruction->info.imm));
135 instruction->info.imm = (instruction->info.imm << 17) >> 16; /* sign-extend */
136 instruction->type = NDS32_INSN_LOAD_STORE;
137 nds32_get_mapped_reg(nds32, instruction->info.ra,
138 &(instruction->access_start));
139 instruction->access_start += instruction->info.imm;
140 instruction->access_end = instruction->access_start + 2;
141 snprintf(instruction->text,
142 128,
143 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLHI\t$r%d,[$r%d+#%d]",
144 address,
145 opcode, instruction->info.rt, instruction->info.ra,
146 instruction->info.imm);
147 break;
148 case 2: /* LWI */
149 nds32_parse_type_2(opcode, &(instruction->info.rt),
150 &(instruction->info.ra), &(instruction->info.imm));
151 instruction->info.imm = (instruction->info.imm << 17) >> 15; /* sign-extend */
152 instruction->type = NDS32_INSN_LOAD_STORE;
153 nds32_get_mapped_reg(nds32, instruction->info.ra,
154 &(instruction->access_start));
155 instruction->access_start += instruction->info.imm;
156 instruction->access_end = instruction->access_start + 4;
157 snprintf(instruction->text,
158 128,
159 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLWI\t$r%d,[$r%d+#%d]",
160 address,
161 opcode, instruction->info.rt, instruction->info.ra,
162 instruction->info.imm);
163 break;
164 case 4: /* LBI.bi */
165 nds32_parse_type_2(opcode, &(instruction->info.rt),
166 &(instruction->info.ra), &(instruction->info.imm));
167 instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */
168 instruction->type = NDS32_INSN_LOAD_STORE;
169 nds32_get_mapped_reg(nds32, instruction->info.ra,
170 &(instruction->access_start));
171 instruction->access_end = instruction->access_start + 1;
172 snprintf(instruction->text,
173 128,
174 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLBI.bi\t$r%d,[$r%d],#%d",
175 address,
176 opcode, instruction->info.rt, instruction->info.ra,
177 instruction->info.imm);
178 break;
179 case 5: /* LHI.bi */
180 nds32_parse_type_2(opcode, &(instruction->info.rt),
181 &(instruction->info.ra), &(instruction->info.imm));
182 instruction->info.imm = (instruction->info.imm << 17) >> 16; /* sign-extend */
183 instruction->type = NDS32_INSN_LOAD_STORE;
184 nds32_get_mapped_reg(nds32, instruction->info.ra,
185 &(instruction->access_start));
186 instruction->access_end = instruction->access_start + 2;
187 snprintf(instruction->text,
188 128,
189 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLHI.bi\t$r%d,[$r%d],#%d",
190 address,
191 opcode, instruction->info.rt, instruction->info.ra,
192 instruction->info.imm);
193 break;
194 case 6: /* LWI.bi */
195 nds32_parse_type_2(opcode, &(instruction->info.rt),
196 &(instruction->info.ra), &(instruction->info.imm));
197 instruction->info.imm = (instruction->info.imm << 17) >> 15; /* sign-extend */
198 instruction->type = NDS32_INSN_LOAD_STORE;
199 nds32_get_mapped_reg(nds32, instruction->info.ra,
200 &(instruction->access_start));
201 instruction->access_end = instruction->access_start + 4;
202 snprintf(instruction->text,
203 128,
204 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLWI.bi\t$r%d,[$r%d],#%d",
205 address,
206 opcode, instruction->info.rt, instruction->info.ra,
207 instruction->info.imm);
208 break;
209 default:
210 snprintf(instruction->text,
211 128,
212 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
213 address,
214 opcode);
215 return ERROR_FAIL;
216 }
217
218 return ERROR_OK;
219 }
220
221 static int nds32_parse_group_1_insn(struct nds32 *nds32, uint32_t opcode,
222 uint32_t address, struct nds32_instruction *instruction)
223 {
224 uint8_t opc_6;
225
226 opc_6 = instruction->info.opc_6;
227
228 switch (opc_6 & 0x7) {
229 case 0: /* SBI */
230 nds32_parse_type_2(opcode, &(instruction->info.rt),
231 &(instruction->info.ra), &(instruction->info.imm));
232 instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */
233 instruction->type = NDS32_INSN_LOAD_STORE;
234 nds32_get_mapped_reg(nds32, instruction->info.ra,
235 &(instruction->access_start));
236 instruction->access_start += instruction->info.imm;
237 instruction->access_end = instruction->access_start + 1;
238 snprintf(instruction->text,
239 128,
240 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSBI\t$r%d,[$r%d+#%d]",
241 address,
242 opcode, instruction->info.rt, instruction->info.ra,
243 instruction->info.imm);
244 break;
245 case 1: /* SHI */
246 nds32_parse_type_2(opcode, &(instruction->info.rt),
247 &(instruction->info.ra), &(instruction->info.imm));
248 instruction->info.imm = (instruction->info.imm << 17) >> 16; /* sign-extend */
249 instruction->type = NDS32_INSN_LOAD_STORE;
250 nds32_get_mapped_reg(nds32, instruction->info.ra,
251 &(instruction->access_start));
252 instruction->access_start += instruction->info.imm;
253 instruction->access_end = instruction->access_start + 2;
254 snprintf(instruction->text,
255 128,
256 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSHI\t$r%d,[$r%d+#%d]",
257 address,
258 opcode, instruction->info.rt, instruction->info.ra,
259 instruction->info.imm);
260 break;
261 case 2: /* SWI */
262 nds32_parse_type_2(opcode, &(instruction->info.rt),
263 &(instruction->info.ra), &(instruction->info.imm));
264 instruction->info.imm = (instruction->info.imm << 17) >> 15; /* sign-extend */
265 instruction->type = NDS32_INSN_LOAD_STORE;
266 nds32_get_mapped_reg(nds32, instruction->info.ra,
267 &(instruction->access_start));
268 instruction->access_start += instruction->info.imm;
269 instruction->access_end = instruction->access_start + 4;
270 snprintf(instruction->text,
271 128,
272 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSWI\t$r%d,[$r%d+#%d]",
273 address,
274 opcode, instruction->info.rt, instruction->info.ra,
275 instruction->info.imm);
276 break;
277 case 4: /* SBI.bi */
278 nds32_parse_type_2(opcode, &(instruction->info.rt),
279 &(instruction->info.ra), &(instruction->info.imm));
280 instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */
281 instruction->type = NDS32_INSN_LOAD_STORE;
282 nds32_get_mapped_reg(nds32, instruction->info.ra,
283 &(instruction->access_start));
284 instruction->access_end = instruction->access_start + 1;
285 snprintf(instruction->text,
286 128,
287 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSBI.bi\t$r%d,[$r%d],#%d",
288 address,
289 opcode, instruction->info.rt, instruction->info.ra,
290 instruction->info.imm);
291 break;
292 case 5: /* SHI.bi */
293 nds32_parse_type_2(opcode, &(instruction->info.rt),
294 &(instruction->info.ra), &(instruction->info.imm));
295 instruction->info.imm = (instruction->info.imm << 17) >> 16; /* sign-extend */
296 instruction->type = NDS32_INSN_LOAD_STORE;
297 nds32_get_mapped_reg(nds32, instruction->info.ra,
298 &(instruction->access_start));
299 instruction->access_end = instruction->access_start + 2;
300 snprintf(instruction->text,
301 128,
302 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSHI.bi\t$r%d,[$r%d],#%d",
303 address,
304 opcode, instruction->info.rt, instruction->info.ra,
305 instruction->info.imm);
306 break;
307 case 6: /* SWI.bi */
308 nds32_parse_type_2(opcode, &(instruction->info.rt),
309 &(instruction->info.ra), &(instruction->info.imm));
310 instruction->info.imm = (instruction->info.imm << 17) >> 15; /* sign-extend */
311 instruction->type = NDS32_INSN_LOAD_STORE;
312 nds32_get_mapped_reg(nds32, instruction->info.ra,
313 &(instruction->access_start));
314 instruction->access_end = instruction->access_start + 4;
315 snprintf(instruction->text,
316 128,
317 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSWI.bi\t$r%d,[$r%d],#%d",
318 address,
319 opcode, instruction->info.rt, instruction->info.ra,
320 instruction->info.imm);
321 break;
322 default:
323 snprintf(instruction->text,
324 128,
325 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
326 address,
327 opcode);
328 return ERROR_FAIL;
329 }
330
331 return ERROR_OK;
332 }
333
334 static int nds32_parse_group_2_insn(struct nds32 *nds32, uint32_t opcode,
335 uint32_t address, struct nds32_instruction *instruction)
336 {
337 uint8_t opc_6;
338
339 opc_6 = instruction->info.opc_6;
340
341 switch (opc_6 & 0x7) {
342 case 0: /* LBSI */
343 nds32_parse_type_2(opcode, &(instruction->info.rt),
344 &(instruction->info.ra), &(instruction->info.imm));
345 instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */
346 instruction->type = NDS32_INSN_LOAD_STORE;
347 nds32_get_mapped_reg(nds32, instruction->info.ra,
348 &(instruction->access_start));
349 instruction->access_start += instruction->info.imm;
350 instruction->access_end = instruction->access_start + 1;
351 snprintf(instruction->text,
352 128,
353 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLBSI\t$r%d,[$r%d+#%d]",
354 address,
355 opcode, instruction->info.rt, instruction->info.ra,
356 instruction->info.imm);
357 break;
358 case 1: /* LHSI */
359 nds32_parse_type_2(opcode, &(instruction->info.rt),
360 &(instruction->info.ra), &(instruction->info.imm));
361 instruction->info.imm = (instruction->info.imm << 17) >> 16; /* sign-extend */
362 instruction->type = NDS32_INSN_LOAD_STORE;
363 nds32_get_mapped_reg(nds32, instruction->info.ra,
364 &(instruction->access_start));
365 instruction->access_start += instruction->info.imm;
366 instruction->access_end = instruction->access_start + 2;
367 snprintf(instruction->text,
368 128,
369 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLHSI\t$r%d,[$r%d+#%d]",
370 address,
371 opcode, instruction->info.rt, instruction->info.ra,
372 instruction->info.imm);
373 break;
374 case 3: { /* DPREFI */
375 uint8_t sub_type;
376 nds32_parse_type_2(opcode, &sub_type, &(instruction->info.ra),
377 &(instruction->info.imm));
378 instruction->info.sub_opc = sub_type & 0xF;
379 instruction->type = NDS32_INSN_MISC;
380 if (sub_type & 0x10) { /* DPREFI.d */
381 /* sign-extend */
382 instruction->info.imm = (instruction->info.imm << 17) >> 14;
383 snprintf(instruction->text,
384 128,
385 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tDPREFI.d\t%d,[$r%d+#%d]",
386 address,
387 opcode, instruction->info.sub_opc,
388 instruction->info.ra, instruction->info.imm);
389 } else { /* DPREFI.w */
390 /* sign-extend */
391 instruction->info.imm = (instruction->info.imm << 17) >> 15;
392 snprintf(instruction->text,
393 128,
394 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tDPREFI.w\t%d,[$r%d+#%d]",
395 address,
396 opcode, instruction->info.sub_opc,
397 instruction->info.ra, instruction->info.imm);
398 }
399 }
400 break;
401 case 4: /* LBSI.bi */
402 nds32_parse_type_2(opcode, &(instruction->info.rt),
403 &(instruction->info.ra), &(instruction->info.imm));
404 instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */
405 instruction->type = NDS32_INSN_LOAD_STORE;
406 nds32_get_mapped_reg(nds32, instruction->info.ra,
407 &(instruction->access_start));
408 instruction->access_end = instruction->access_start + 1;
409 snprintf(instruction->text,
410 128,
411 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLBSI.bi\t$r%d,[$r%d],#%d",
412 address,
413 opcode, instruction->info.rt, instruction->info.ra,
414 instruction->info.imm);
415 break;
416 case 5: /* LHSI.bi */
417 nds32_parse_type_2(opcode, &(instruction->info.rt),
418 &(instruction->info.ra), &(instruction->info.imm));
419 instruction->info.imm = (instruction->info.imm << 17) >> 16; /* sign-extend */
420 instruction->type = NDS32_INSN_LOAD_STORE;
421 nds32_get_mapped_reg(nds32, instruction->info.ra,
422 &(instruction->access_start));
423 instruction->access_end = instruction->access_start + 2;
424 snprintf(instruction->text,
425 128,
426 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLHSI.bi\t$r%d,[$r%d],#%d",
427 address,
428 opcode, instruction->info.rt, instruction->info.ra,
429 instruction->info.imm);
430 break;
431 case 6: /* LBGP */
432 nds32_parse_type_1(opcode, &(instruction->info.rt), &(instruction->info.imm));
433 instruction->type = NDS32_INSN_LOAD_STORE;
434 if ((instruction->info.imm >> 19) & 0x1) { /* LBSI.gp */
435 instruction->info.imm = (instruction->info.imm << 13) >> 13;
436 nds32_get_mapped_reg(nds32, R29, &(instruction->access_start));
437 instruction->access_start += instruction->info.imm;
438 instruction->access_end = instruction->access_start + 1;
439 snprintf(instruction->text,
440 128,
441 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLBSI.gp\t$r%d,[#%d]",
442 address,
443 opcode, instruction->info.rt, instruction->info.imm);
444 } else { /* LBI.gp */
445 instruction->info.imm = (instruction->info.imm << 13) >> 13;
446 nds32_get_mapped_reg(nds32, R29, &(instruction->access_start));
447 instruction->access_start += instruction->info.imm;
448 instruction->access_end = instruction->access_start + 1;
449 snprintf(instruction->text,
450 128,
451 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLBI.gp\t$r%d,[#%d]",
452 address,
453 opcode, instruction->info.rt, instruction->info.imm);
454 }
455 break;
456 default:
457 snprintf(instruction->text,
458 128,
459 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
460 address,
461 opcode);
462 return ERROR_FAIL;
463 }
464
465 return ERROR_OK;
466 }
467
468 static int nds32_parse_mem(struct nds32 *nds32, uint32_t opcode, uint32_t address,
469 struct nds32_instruction *instruction)
470 {
471 uint32_t sub_opcode = opcode & 0x3F;
472 uint32_t val_ra, val_rb;
473 switch (sub_opcode >> 3) {
474 case 0:
475 switch (sub_opcode & 0x7) {
476 case 0: /* LB */
477 nds32_parse_type_3(opcode, &(instruction->info.rt),
478 &(instruction->info.ra), \
479 &(instruction->info.rb), &(instruction->info.imm));
480 instruction->type = NDS32_INSN_LOAD_STORE;
481 nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra);
482 nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb);
483 instruction->access_start = val_ra +
484 (val_rb << ((instruction->info.imm >> 8) & 0x3));
485 instruction->access_end = instruction->access_start + 1;
486 snprintf(instruction->text,
487 128,
488 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLB\t$r%d,[$r%d+($r%d<<%d)]",
489 address,
490 opcode, instruction->info.rt, instruction->info.ra,
491 instruction->info.rb,
492 (instruction->info.imm >> 8) & 0x3);
493 break;
494 case 1: /* LH */
495 nds32_parse_type_3(opcode, &(instruction->info.rt),
496 &(instruction->info.ra),
497 &(instruction->info.rb), &(instruction->info.imm));
498 instruction->type = NDS32_INSN_LOAD_STORE;
499 nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra);
500 nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb);
501 instruction->access_start = val_ra +
502 (val_rb << ((instruction->info.imm >> 8) & 0x3));
503 instruction->access_end = instruction->access_start + 2;
504 snprintf(instruction->text,
505 128,
506 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLH\t$r%d,[$r%d+($r%d<<%d)]",
507 address,
508 opcode, instruction->info.rt, instruction->info.ra,
509 instruction->info.rb,
510 (instruction->info.imm >> 8) & 0x3);
511 break;
512 case 2: /* LW */
513 nds32_parse_type_3(opcode, &(instruction->info.rt),
514 &(instruction->info.ra),
515 &(instruction->info.rb), &(instruction->info.imm));
516 instruction->type = NDS32_INSN_LOAD_STORE;
517 nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra);
518 nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb);
519 instruction->access_start = val_ra +
520 (val_rb << ((instruction->info.imm >> 8) & 0x3));
521 instruction->access_end = instruction->access_start + 4;
522 snprintf(instruction->text,
523 128,
524 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLW\t$r%d,[$r%d+($r%d<<%d)]",
525 address,
526 opcode, instruction->info.rt, instruction->info.ra,
527 instruction->info.rb,
528 (instruction->info.imm >> 8) & 0x3);
529 break;
530 case 4: /* LB.bi */
531 nds32_parse_type_3(opcode, &(instruction->info.rt),
532 &(instruction->info.ra),
533 &(instruction->info.rb), &(instruction->info.imm));
534 instruction->type = NDS32_INSN_LOAD_STORE;
535 nds32_get_mapped_reg(nds32, instruction->info.ra,
536 &(instruction->access_start));
537 instruction->access_end = instruction->access_start + 1;
538 snprintf(instruction->text,
539 128,
540 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLB.bi\t$r%d,[$r%d],($r%d<<%d)",
541 address,
542 opcode, instruction->info.rt,
543 instruction->info.ra, instruction->info.rb,
544 (instruction->info.imm >> 8) & 0x3);
545 break;
546 case 5: /* LH.bi */
547 nds32_parse_type_3(opcode, &(instruction->info.rt),
548 &(instruction->info.ra),
549 &(instruction->info.rb), &(instruction->info.imm));
550 instruction->type = NDS32_INSN_LOAD_STORE;
551 nds32_get_mapped_reg(nds32, instruction->info.ra,
552 &(instruction->access_start));
553 instruction->access_end = instruction->access_start + 2;
554 snprintf(instruction->text,
555 128,
556 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLH.bi\t$r%d,[$r%d],($r%d<<%d)",
557 address,
558 opcode, instruction->info.rt, instruction->info.ra,
559 instruction->info.rb,
560 (instruction->info.imm >> 8) & 0x3);
561 break;
562 case 6: /* LW.bi */
563 nds32_parse_type_3(opcode, &(instruction->info.rt),
564 &(instruction->info.ra),
565 &(instruction->info.rb), &(instruction->info.imm));
566 instruction->type = NDS32_INSN_LOAD_STORE;
567 nds32_get_mapped_reg(nds32, instruction->info.ra,
568 &(instruction->access_start));
569 instruction->access_end = instruction->access_start + 4;
570 snprintf(instruction->text,
571 128,
572 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLW.bi\t$r%d,[$r%d],($r%d<<%d)",
573 address,
574 opcode, instruction->info.rt, instruction->info.ra,
575 instruction->info.rb,
576 (instruction->info.imm >> 8) & 0x3);
577 break;
578 }
579 break;
580 case 1:
581 switch (sub_opcode & 0x7) {
582 case 0: /* SB */
583 nds32_parse_type_3(opcode, &(instruction->info.rt),
584 &(instruction->info.ra),
585 &(instruction->info.rb), &(instruction->info.imm));
586 instruction->type = NDS32_INSN_LOAD_STORE;
587 nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra);
588 nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb);
589 instruction->access_start = val_ra +
590 (val_rb << ((instruction->info.imm >> 8) & 0x3));
591 instruction->access_end = instruction->access_start + 1;
592 snprintf(instruction->text,
593 128,
594 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSB\t$r%d,[$r%d+($r%d<<%d)]",
595 address,
596 opcode, instruction->info.rt,
597 instruction->info.ra, instruction->info.rb,
598 (instruction->info.imm >> 8) & 0x3);
599 break;
600 case 1: /* SH */
601 nds32_parse_type_3(opcode, &(instruction->info.rt),
602 &(instruction->info.ra),
603 &(instruction->info.rb), &(instruction->info.imm));
604 instruction->type = NDS32_INSN_LOAD_STORE;
605 nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra);
606 nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb);
607 instruction->access_start = val_ra +
608 (val_rb << ((instruction->info.imm >> 8) & 0x3));
609 instruction->access_end = instruction->access_start + 2;
610 snprintf(instruction->text,
611 128,
612 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSH\t$r%d,[$r%d+($r%d<<%d)]",
613 address,
614 opcode, instruction->info.rt, instruction->info.ra,
615 instruction->info.rb,
616 (instruction->info.imm >> 8) & 0x3);
617 break;
618 case 2: /* SW */
619 nds32_parse_type_3(opcode, &(instruction->info.rt),
620 &(instruction->info.ra),
621 &(instruction->info.rb), &(instruction->info.imm));
622 instruction->type = NDS32_INSN_LOAD_STORE;
623 nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra);
624 nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb);
625 instruction->access_start = val_ra +
626 (val_rb << ((instruction->info.imm >> 8) & 0x3));
627 instruction->access_end = instruction->access_start + 4;
628 snprintf(instruction->text,
629 128,
630 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSW\t$r%d,[$r%d+($r%d<<%d)]",
631 address,
632 opcode, instruction->info.rt,
633 instruction->info.ra, instruction->info.rb,
634 (instruction->info.imm >> 8) & 0x3);
635 break;
636 case 4: /* SB.bi */
637 nds32_parse_type_3(opcode, &(instruction->info.rt),
638 &(instruction->info.ra),
639 &(instruction->info.rb), &(instruction->info.imm));
640 instruction->type = NDS32_INSN_LOAD_STORE;
641 nds32_get_mapped_reg(nds32, instruction->info.ra,
642 &(instruction->access_start));
643 instruction->access_end = instruction->access_start + 1;
644 snprintf(instruction->text,
645 128,
646 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSB.bi\t$r%d,[$r%d],($r%d<<%d)",
647 address,
648 opcode, instruction->info.rt, instruction->info.ra,
649 instruction->info.rb,
650 (instruction->info.imm >> 8) & 0x3);
651 break;
652 case 5: /* SH.bi */
653 nds32_parse_type_3(opcode, &(instruction->info.rt),
654 &(instruction->info.ra),
655 &(instruction->info.rb), &(instruction->info.imm));
656 instruction->type = NDS32_INSN_LOAD_STORE;
657 nds32_get_mapped_reg(nds32, instruction->info.ra,
658 &(instruction->access_start));
659 instruction->access_end = instruction->access_start + 2;
660 snprintf(instruction->text,
661 128,
662 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSH.bi\t$r%d,[$r%d],($r%d<<%d)",
663 address,
664 opcode, instruction->info.rt, instruction->info.ra,
665 instruction->info.rb,
666 (instruction->info.imm >> 8) & 0x3);
667 break;
668 case 6: /* SW.bi */
669 nds32_parse_type_3(opcode, &(instruction->info.rt),
670 &(instruction->info.ra),
671 &(instruction->info.rb), &(instruction->info.imm));
672 instruction->type = NDS32_INSN_LOAD_STORE;
673 nds32_get_mapped_reg(nds32, instruction->info.ra,
674 &(instruction->access_start));
675 instruction->access_end = instruction->access_start + 4;
676 snprintf(instruction->text,
677 128,
678 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSW.bi\t$r%d,[$r%d],($r%d<<%d)",
679 address,
680 opcode, instruction->info.rt, instruction->info.ra,
681 instruction->info.rb,
682 (instruction->info.imm >> 8) & 0x3);
683 break;
684 }
685 break;
686 case 2:
687 switch (sub_opcode & 0x7) {
688 case 0: /* LBS */
689 nds32_parse_type_3(opcode, &(instruction->info.rt),
690 &(instruction->info.ra),
691 &(instruction->info.rb), &(instruction->info.imm));
692 instruction->type = NDS32_INSN_LOAD_STORE;
693 nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra);
694 nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb);
695 instruction->access_start = val_ra +
696 (val_rb << ((instruction->info.imm >> 8) & 0x3));
697 instruction->access_end = instruction->access_start + 1;
698 snprintf(instruction->text,
699 128,
700 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLBS\t$r%d,[$r%d+($r%d<<%d)]",
701 address,
702 opcode, instruction->info.rt,
703 instruction->info.ra, instruction->info.rb,
704 (instruction->info.imm >> 8) & 0x3);
705 break;
706 case 1: /* LHS */
707 nds32_parse_type_3(opcode, &(instruction->info.rt),
708 &(instruction->info.ra),
709 &(instruction->info.rb), &(instruction->info.imm));
710 instruction->type = NDS32_INSN_LOAD_STORE;
711 nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra);
712 nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb);
713 instruction->access_start = val_ra +
714 (val_rb << ((instruction->info.imm >> 8) & 0x3));
715 instruction->access_end = instruction->access_start + 2;
716 snprintf(instruction->text,
717 128,
718 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLHS\t$r%d,[$r%d+($r%d<<%d)]",
719 address,
720 opcode, instruction->info.rt, instruction->info.ra,
721 instruction->info.rb,
722 (instruction->info.imm >> 8) & 0x3);
723 break;
724 case 3: /* DPREF */
725 nds32_parse_type_3(opcode, &(instruction->info.sub_opc),
726 &(instruction->info.ra),
727 &(instruction->info.rb), &(instruction->info.imm));
728 instruction->type = NDS32_INSN_MISC;
729 snprintf(instruction->text,
730 128,
731 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tDPREF\t#%d,[$r%d+($r%d<<#%d)]",
732 address,
733 opcode, instruction->info.sub_opc,
734 instruction->info.ra, instruction->info.rb,
735 (instruction->info.imm >> 8) & 0x3);
736 break;
737 case 4: /* LBS.bi */
738 nds32_parse_type_3(opcode, &(instruction->info.rt),
739 &(instruction->info.ra),
740 &(instruction->info.rb), &(instruction->info.imm));
741 instruction->type = NDS32_INSN_LOAD_STORE;
742 nds32_get_mapped_reg(nds32, instruction->info.ra,
743 &(instruction->access_start));
744 instruction->access_end = instruction->access_start + 1;
745 snprintf(instruction->text,
746 128,
747 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLBS.bi\t$r%d,[$r%d],($r%d<<%d)",
748 address,
749 opcode, instruction->info.rt, instruction->info.ra,
750 instruction->info.rb,
751 (instruction->info.imm >> 8) & 0x3);
752 break;
753 case 5: /* LHS.bi */
754 nds32_parse_type_3(opcode, &(instruction->info.rt),
755 &(instruction->info.ra),
756 &(instruction->info.rb), &(instruction->info.imm));
757 instruction->type = NDS32_INSN_LOAD_STORE;
758 nds32_get_mapped_reg(nds32, instruction->info.ra,
759 &(instruction->access_start));
760 instruction->access_end = instruction->access_start + 2;
761 snprintf(instruction->text,
762 128,
763 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLHS.bi\t$r%d,[$r%d],($r%d<<%d)",
764 address,
765 opcode, instruction->info.rt, instruction->info.ra,
766 instruction->info.rb,
767 (instruction->info.imm >> 8) & 0x3);
768 break;
769 }
770 break;
771 case 3:
772 switch (sub_opcode & 0x7) {
773 case 0: /* LLW */
774 nds32_parse_type_3(opcode, &(instruction->info.rt),
775 &(instruction->info.ra),
776 &(instruction->info.rb), &(instruction->info.imm));
777 instruction->type = NDS32_INSN_LOAD_STORE;
778 nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra);
779 nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb);
780 instruction->access_start = val_ra +
781 (val_rb << ((instruction->info.imm >> 8) & 0x3));
782 instruction->access_end = instruction->access_start + 4;
783 snprintf(instruction->text,
784 128,
785 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLLW\t$r%d,[$r%d+($r%d<<%d)]",
786 address,
787 opcode, instruction->info.rt, instruction->info.ra,
788 instruction->info.rb,
789 (instruction->info.imm >> 8) & 0x3);
790 break;
791 case 1: /* SCW */
792 nds32_parse_type_3(opcode, &(instruction->info.rt),
793 &(instruction->info.ra),
794 &(instruction->info.rb), &(instruction->info.imm));
795 instruction->type = NDS32_INSN_LOAD_STORE;
796 nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra);
797 nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb);
798 instruction->access_start = val_ra +
799 (val_rb << ((instruction->info.imm >> 8) & 0x3));
800 instruction->access_end = instruction->access_start + 4;
801 snprintf(instruction->text,
802 128,
803 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSCW\t$r%d,[$r%d+($r%d<<%d)]",
804 address,
805 opcode, instruction->info.rt, instruction->info.ra,
806 instruction->info.rb,
807 (instruction->info.imm >> 8) & 0x3);
808 break;
809 }
810 break;
811 case 4:
812 switch (sub_opcode & 0x7) {
813 case 0: /* LBUP */
814 nds32_parse_type_3(opcode, &(instruction->info.rt),
815 &(instruction->info.ra),
816 &(instruction->info.rb), &(instruction->info.imm));
817 instruction->type = NDS32_INSN_LOAD_STORE;
818 nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra);
819 nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb);
820 instruction->access_start = val_ra +
821 (val_rb << ((instruction->info.imm >> 8) & 0x3));
822 instruction->access_end = instruction->access_start + 1;
823 snprintf(instruction->text,
824 128,
825 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLBUP\t$r%d,[$r%d+($r%d<<%d)]",
826 address,
827 opcode, instruction->info.rt, instruction->info.ra,
828 instruction->info.rb,
829 (instruction->info.imm >> 8) & 0x3);
830 break;
831 case 2: /* LWUP */
832 nds32_parse_type_3(opcode, &(instruction->info.rt),
833 &(instruction->info.ra),
834 &(instruction->info.rb), &(instruction->info.imm));
835 instruction->type = NDS32_INSN_LOAD_STORE;
836 nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra);
837 nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb);
838 instruction->access_start = val_ra +
839 (val_rb << ((instruction->info.imm >> 8) & 0x3));
840 instruction->access_end = instruction->access_start + 4;
841 snprintf(instruction->text,
842 128,
843 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLWUP\t$r%d,[$r%d+($r%d<<%d)]",
844 address,
845 opcode, instruction->info.rt, instruction->info.ra,
846 instruction->info.rb,
847 (instruction->info.imm >> 8) & 0x3);
848 break;
849 }
850 break;
851 case 5:
852 switch (sub_opcode & 0x7) {
853 case 0: /* SBUP */
854 nds32_parse_type_3(opcode, &(instruction->info.rt),
855 &(instruction->info.ra),
856 &(instruction->info.rb), &(instruction->info.imm));
857 instruction->type = NDS32_INSN_LOAD_STORE;
858 nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra);
859 nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb);
860 instruction->access_start = val_ra +
861 (val_rb << ((instruction->info.imm >> 8) & 0x3));
862 instruction->access_end = instruction->access_start + 1;
863 snprintf(instruction->text,
864 128,
865 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSBUP\t$r%d,[$r%d+($r%d<<%d)]",
866 address,
867 opcode, instruction->info.rt, instruction->info.ra,
868 instruction->info.rb,
869 (instruction->info.imm >> 8) & 0x3);
870 break;
871 case 2: /* SWUP */
872 nds32_parse_type_3(opcode, &(instruction->info.rt),
873 &(instruction->info.ra),
874 &(instruction->info.rb), &(instruction->info.imm));
875 instruction->type = NDS32_INSN_LOAD_STORE;
876 nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra);
877 nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb);
878 instruction->access_start = val_ra +
879 (val_rb << ((instruction->info.imm >> 8) & 0x3));
880 instruction->access_end = instruction->access_start + 4;
881 snprintf(instruction->text,
882 128,
883 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSWUP\t$r%d,[$r%d+($r%d<<%d)]",
884 address,
885 opcode, instruction->info.rt, instruction->info.ra,
886 instruction->info.rb,
887 (instruction->info.imm >> 8) & 0x3);
888 break;
889 }
890 break;
891 default:
892 snprintf(instruction->text,
893 128,
894 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
895 address,
896 opcode);
897 return ERROR_FAIL;
898 }
899
900 return ERROR_OK;
901 }
902
903 static int nds32_calculate_lsmw_access_range(struct nds32 *nds32,
904 struct nds32_instruction *instruction)
905 {
906 uint8_t ba;
907 uint8_t id;
908 uint8_t enable4;
909
910 enable4 = (instruction->info.imm >> 6) & 0xF;
911 ba = (instruction->info.imm >> 4) & 0x1;
912 id = (instruction->info.imm >> 3) & 0x1;
913
914 if (ba) {
915 nds32_get_mapped_reg(nds32, instruction->info.ra, &(instruction->access_start));
916 if (id) { /* decrease */
917 /* access_end is the (last_element+1), so no need to minus 4 */
918 /* instruction->access_end -= 4; */
919 instruction->access_end = instruction->access_start;
920 } else { /* increase */
921 instruction->access_start += 4;
922 }
923 } else {
924 nds32_get_mapped_reg(nds32, instruction->info.ra, &(instruction->access_start));
925 instruction->access_end = instruction->access_start - 4;
926 }
927
928 if (id) { /* decrease */
929 instruction->access_start = instruction->access_end -
930 4 * (instruction->info.rd - instruction->info.rb + 1);
931 instruction->access_start -= (4 * enable4_bits[enable4]);
932 } else { /* increase */
933 instruction->access_end = instruction->access_start +
934 4 * (instruction->info.rd - instruction->info.rb + 1);
935 instruction->access_end += (4 * enable4_bits[enable4]);
936 }
937
938 return ERROR_OK;
939 }
940
941 static int nds32_parse_lsmw(struct nds32 *nds32, uint32_t opcode, uint32_t address,
942 struct nds32_instruction *instruction)
943 {
944 if (opcode & 0x20) { /* SMW, SMWA, SMWZB */
945 switch (opcode & 0x3) {
946 /* TODO */
947 case 0: /* SMW */
948 /* use rd as re */
949 nds32_parse_type_3(opcode, &(instruction->info.rb),
950 &(instruction->info.ra),
951 &(instruction->info.rd), &(instruction->info.imm));
952 instruction->type = NDS32_INSN_LOAD_STORE;
953 nds32_calculate_lsmw_access_range(nds32, instruction);
954 snprintf(instruction->text,
955 128,
956 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMW\t$r%d,[$r%d],$r%d,%d",
957 address,
958 opcode, instruction->info.rb, instruction->info.ra,
959 instruction->info.rd,
960 (instruction->info.imm >> 6) & 0xF);
961 break;
962 case 1: /* SMWA */
963 nds32_parse_type_3(opcode, &(instruction->info.rb),
964 &(instruction->info.ra),
965 &(instruction->info.rd), &(instruction->info.imm));
966 instruction->type = NDS32_INSN_LOAD_STORE;
967 nds32_calculate_lsmw_access_range(nds32, instruction);
968 snprintf(instruction->text,
969 128,
970 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMWA\t$r%d,[$r%d],$r%d,%d",
971 address,
972 opcode, instruction->info.rb, instruction->info.ra,
973 instruction->info.rd,
974 (instruction->info.imm >> 6) & 0xF);
975 break;
976 case 2: /* SMWZB */
977 nds32_parse_type_3(opcode, &(instruction->info.rb),
978 &(instruction->info.ra),
979 &(instruction->info.rd), &(instruction->info.imm));
980 instruction->type = NDS32_INSN_LOAD_STORE;
981 /* TODO: calculate access_start/access_end */
982 snprintf(instruction->text,
983 128,
984 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMWZB\t$r%d,[$r%d],$r%d,%d",
985 address,
986 opcode, instruction->info.rb, instruction->info.ra,
987 instruction->info.rd,
988 (instruction->info.imm >> 6) & 0xF);
989 break;
990 default:
991 snprintf(instruction->text,
992 128,
993 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
994 address,
995 opcode);
996 return ERROR_FAIL;
997 }
998 } else { /* LMW, LMWA, LMWZB */
999 switch (opcode & 0x3) {
1000 case 0: /* LMW */
1001 nds32_parse_type_3(opcode, &(instruction->info.rb),
1002 &(instruction->info.ra),
1003 &(instruction->info.rd), &(instruction->info.imm));
1004 instruction->type = NDS32_INSN_LOAD_STORE;
1005 nds32_calculate_lsmw_access_range(nds32, instruction);
1006 snprintf(instruction->text,
1007 128,
1008 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLMW\t$r%d,[$r%d],$r%d,%d",
1009 address,
1010 opcode, instruction->info.rb, instruction->info.ra,
1011 instruction->info.rd,
1012 (instruction->info.imm >> 6) & 0xF);
1013 break;
1014 case 1: /* LMWA */
1015 nds32_parse_type_3(opcode, &(instruction->info.rb),
1016 &(instruction->info.ra),
1017 &(instruction->info.rd), &(instruction->info.imm));
1018 instruction->type = NDS32_INSN_LOAD_STORE;
1019 nds32_calculate_lsmw_access_range(nds32, instruction);
1020 snprintf(instruction->text,
1021 128,
1022 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLMWA\t$r%d,[$r%d],$r%d,%d",
1023 address,
1024 opcode, instruction->info.rb, instruction->info.ra,
1025 instruction->info.rd,
1026 (instruction->info.imm >> 6) & 0xF);
1027 break;
1028 case 2: /* LMWZB */
1029 nds32_parse_type_3(opcode, &(instruction->info.rb),
1030 &(instruction->info.ra),
1031 &(instruction->info.rd), &(instruction->info.imm));
1032 instruction->type = NDS32_INSN_LOAD_STORE;
1033 /* TODO: calculate access_start/access_end */
1034 snprintf(instruction->text,
1035 128,
1036 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLMWZB\t$r%d,[$r%d],$r%d,%d",
1037 address,
1038 opcode, instruction->info.rb, instruction->info.ra,
1039 instruction->info.rd,
1040 (instruction->info.imm >> 6) & 0xF);
1041 break;
1042 default:
1043 snprintf(instruction->text,
1044 128,
1045 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
1046 address,
1047 opcode);
1048 return ERROR_FAIL;
1049 }
1050 }
1051
1052 return ERROR_OK;
1053 }
1054
1055 static int nds32_parse_hwgp(struct nds32 *nds32, uint32_t opcode, uint32_t address,
1056 struct nds32_instruction *instruction)
1057 {
1058 switch ((opcode >> 18) & 0x3) {
1059 case 0: /* LHI.gp */
1060 nds32_parse_type_1(opcode, &(instruction->info.rt), &(instruction->info.imm));
1061 instruction->info.imm = (instruction->info.imm << 14) >> 13; /* sign-extend */
1062 instruction->type = NDS32_INSN_LOAD_STORE;
1063 nds32_get_mapped_reg(nds32, R29, &(instruction->access_start));
1064 instruction->access_start += instruction->info.imm;
1065 instruction->access_end = instruction->access_start + 2;
1066 snprintf(instruction->text,
1067 128,
1068 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLHI.gp\t$r%d,[#%d]",
1069 address,
1070 opcode, instruction->info.rt, instruction->info.imm);
1071 break;
1072 case 1: /* LHSI.gp */
1073 nds32_parse_type_1(opcode, &(instruction->info.rt), &(instruction->info.imm));
1074 instruction->info.imm = (instruction->info.imm << 14) >> 13; /* sign-extend */
1075 instruction->type = NDS32_INSN_LOAD_STORE;
1076 nds32_get_mapped_reg(nds32, R29, &(instruction->access_start));
1077 instruction->access_start += instruction->info.imm;
1078 instruction->access_end = instruction->access_start + 2;
1079 snprintf(instruction->text,
1080 128,
1081 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLHSI.gp\t$r%d,[#%d]",
1082 address,
1083 opcode, instruction->info.rt, instruction->info.imm);
1084 break;
1085 case 2: /* SHI.gp */
1086 nds32_parse_type_1(opcode, &(instruction->info.rt), &(instruction->info.imm));
1087 instruction->info.imm = (instruction->info.imm << 14) >> 13; /* sign-extend */
1088 instruction->type = NDS32_INSN_LOAD_STORE;
1089 nds32_get_mapped_reg(nds32, R29, &(instruction->access_start));
1090 instruction->access_start += instruction->info.imm;
1091 instruction->access_end = instruction->access_start + 2;
1092 snprintf(instruction->text,
1093 128,
1094 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSHI.gp\t$r%d,[#%d]",
1095 address,
1096 opcode, instruction->info.rt, instruction->info.imm);
1097 break;
1098 case 3:
1099 instruction->type = NDS32_INSN_LOAD_STORE;
1100 if ((opcode >> 17) & 0x1) { /* SWI.gp */
1101 nds32_parse_type_1(opcode, &(instruction->info.rt),
1102 &(instruction->info.imm));
1103 /* sign-extend */
1104 instruction->info.imm = (instruction->info.imm << 15) >> 13;
1105 nds32_get_mapped_reg(nds32, R29, &(instruction->access_start));
1106 instruction->access_start += instruction->info.imm;
1107 instruction->access_end = instruction->access_start + 4;
1108 snprintf(instruction->text,
1109 128,
1110 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSWI.gp\t$r%d,[#%d]",
1111 address,
1112 opcode, instruction->info.rt, instruction->info.imm);
1113 } else { /* LWI.gp */
1114 nds32_parse_type_1(opcode, &(instruction->info.rt),
1115 &(instruction->info.imm));
1116 /* sign-extend */
1117 instruction->info.imm = (instruction->info.imm << 15) >> 13;
1118 nds32_get_mapped_reg(nds32, R29, &(instruction->access_start));
1119 instruction->access_start += instruction->info.imm;
1120 instruction->access_end = instruction->access_start + 4;
1121 snprintf(instruction->text,
1122 128,
1123 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tLWI.gp\t$r%d,[#%d]",
1124 address,
1125 opcode, instruction->info.rt, instruction->info.imm);
1126 }
1127
1128 break;
1129 default:
1130 snprintf(instruction->text,
1131 128,
1132 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
1133 address,
1134 opcode);
1135 return ERROR_FAIL;
1136 }
1137
1138 return ERROR_OK;
1139 }
1140
1141 static int nds32_parse_sbgp(struct nds32 *nds32, uint32_t opcode, uint32_t address,
1142 struct nds32_instruction *instruction)
1143 {
1144 switch ((opcode >> 19) & 0x1) {
1145 case 0: /* SBI.gp */
1146 nds32_parse_type_1(opcode, &(instruction->info.rt), &(instruction->info.imm));
1147 instruction->info.imm = (instruction->info.imm << 13) >> 13; /* sign-extend */
1148 instruction->type = NDS32_INSN_LOAD_STORE;
1149 nds32_get_mapped_reg(nds32, R29, &(instruction->access_start));
1150 instruction->access_start += instruction->info.imm;
1151 instruction->access_end = instruction->access_start + 1;
1152 snprintf(instruction->text,
1153 128,
1154 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSBI.gp\t$r%d,[#%d]",
1155 address,
1156 opcode, instruction->info.rt, instruction->info.imm);
1157 break;
1158 case 1: /* ADDI.gp */
1159 nds32_parse_type_1(opcode, &(instruction->info.rt), &(instruction->info.imm));
1160 instruction->info.imm = (instruction->info.imm << 13) >> 13; /* sign-extend */
1161 instruction->type = NDS32_INSN_DATA_PROC;
1162 snprintf(instruction->text,
1163 128,
1164 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tADDI.gp\t$r%d,#%d",
1165 address,
1166 opcode, instruction->info.rt, instruction->info.imm);
1167 break;
1168 default:
1169 snprintf(instruction->text,
1170 128,
1171 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
1172 address,
1173 opcode);
1174 return ERROR_FAIL;
1175 }
1176
1177 return ERROR_OK;
1178 }
1179
1180 static int nds32_parse_group_3_insn(struct nds32 *nds32, uint32_t opcode, uint32_t address,
1181 struct nds32_instruction *instruction)
1182 {
1183 uint8_t opc_6;
1184
1185 opc_6 = instruction->info.opc_6;
1186
1187 switch (opc_6 & 0x7) {
1188 case 4: /* MEM */
1189 nds32_parse_mem(nds32, opcode, address, instruction);
1190 break;
1191 case 5: /* LSMW */
1192 nds32_parse_lsmw(nds32, opcode, address, instruction);
1193 break;
1194 case 6: /* HWGP */
1195 nds32_parse_hwgp(nds32, opcode, address, instruction);
1196 break;
1197 case 7: /* SBGP */
1198 nds32_parse_sbgp(nds32, opcode, address, instruction);
1199 break;
1200 default:
1201 snprintf(instruction->text,
1202 128,
1203 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
1204 address,
1205 opcode);
1206 return ERROR_FAIL;
1207 }
1208
1209 return ERROR_OK;
1210 }
1211
1212 static int nds32_parse_alu_1(uint32_t opcode, uint32_t address,
1213 struct nds32_instruction *instruction)
1214 {
1215 switch (opcode & 0x1F) {
1216 case 0: /* ADD */
1217 nds32_parse_type_3(opcode, &(instruction->info.rt), &(instruction->info.ra),
1218 &(instruction->info.rb), &(instruction->info.imm));
1219 instruction->type = NDS32_INSN_DATA_PROC;
1220 instruction->info.imm = (instruction->info.imm >> 5) & 0x1F;
1221 if (instruction->info.imm)
1222 snprintf(instruction->text,
1223 128,
1224 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tADD_SLLI\t$r%d,$r%d,$r%d,%d",
1225 address,
1226 opcode, instruction->info.rt, instruction->info.ra,
1227 instruction->info.rb,
1228 instruction->info.imm);
1229 else
1230 snprintf(instruction->text,
1231 128,
1232 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tADD\t$r%d,$r%d,$r%d",
1233 address,
1234 opcode, instruction->info.rt, instruction->info.ra,
1235 instruction->info.rb);
1236 break;
1237 case 1: /* SUB */
1238 nds32_parse_type_3(opcode, &(instruction->info.rt),
1239 &(instruction->info.ra),
1240 &(instruction->info.rb), &(instruction->info.imm));
1241 instruction->type = NDS32_INSN_DATA_PROC;
1242 instruction->info.imm = (instruction->info.imm >> 5) & 0x1F;
1243 if (instruction->info.imm)
1244 snprintf(instruction->text,
1245 128,
1246 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSUB_SLLI\t$r%d,$r%d,$r%d,%d",
1247 address,
1248 opcode, instruction->info.rt, instruction->info.ra,
1249 instruction->info.rb,
1250 instruction->info.imm);
1251 else
1252 snprintf(instruction->text,
1253 128,
1254 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSUB\t$r%d,$r%d,$r%d",
1255 address,
1256 opcode, instruction->info.rt, instruction->info.ra,
1257 instruction->info.rb);
1258 break;
1259 case 2: /* AND */
1260 nds32_parse_type_3(opcode, &(instruction->info.rt),
1261 &(instruction->info.ra),
1262 &(instruction->info.rb), &(instruction->info.imm));
1263 instruction->type = NDS32_INSN_DATA_PROC;
1264 instruction->info.imm = (instruction->info.imm >> 5) & 0x1F;
1265 if (instruction->info.imm)
1266 snprintf(instruction->text,
1267 128,
1268 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tAND_SLLI\t$r%d,$r%d,$r%d,%d",
1269 address,
1270 opcode, instruction->info.rt, instruction->info.ra,
1271 instruction->info.rb,
1272 instruction->info.imm);
1273 else
1274 snprintf(instruction->text,
1275 128,
1276 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tAND\t$r%d,$r%d,$r%d",
1277 address,
1278 opcode, instruction->info.rt, instruction->info.ra,
1279 instruction->info.rb);
1280 break;
1281 case 3: /* XOR */
1282 nds32_parse_type_3(opcode, &(instruction->info.rt),
1283 &(instruction->info.ra),
1284 &(instruction->info.rb), &(instruction->info.imm));
1285 instruction->type = NDS32_INSN_DATA_PROC;
1286 instruction->info.imm = (instruction->info.imm >> 5) & 0x1F;
1287 if (instruction->info.imm)
1288 snprintf(instruction->text,
1289 128,
1290 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tXOR_SLLI\t$r%d,$r%d,$r%d,%d",
1291 address,
1292 opcode, instruction->info.rt, instruction->info.ra,
1293 instruction->info.rb,
1294 instruction->info.imm);
1295 else
1296 snprintf(instruction->text,
1297 128,
1298 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tXOR\t$r%d,$r%d,$r%d",
1299 address,
1300 opcode, instruction->info.rt, instruction->info.ra,
1301 instruction->info.rb);
1302 break;
1303 case 4: /* OR */
1304 nds32_parse_type_3(opcode, &(instruction->info.rt),
1305 &(instruction->info.ra),
1306 &(instruction->info.rb), &(instruction->info.imm));
1307 instruction->type = NDS32_INSN_DATA_PROC;
1308 instruction->info.imm = (instruction->info.imm >> 5) & 0x1F;
1309 if (instruction->info.imm)
1310 snprintf(instruction->text,
1311 128,
1312 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tOR_SLLI\t$r%d,$r%d,$r%d,%d",
1313 address,
1314 opcode, instruction->info.rt, instruction->info.ra,
1315 instruction->info.rb,
1316 instruction->info.imm);
1317 else
1318 snprintf(instruction->text,
1319 128,
1320 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tOR\t$r%d,$r%d,$r%d",
1321 address,
1322 opcode, instruction->info.rt, instruction->info.ra,
1323 instruction->info.rb);
1324 break;
1325 case 5: /* NOR */
1326 nds32_parse_type_3(opcode, &(instruction->info.rt),
1327 &(instruction->info.ra),
1328 &(instruction->info.rb), &(instruction->info.imm));
1329 instruction->type = NDS32_INSN_DATA_PROC;
1330 snprintf(instruction->text,
1331 128,
1332 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tNOR\t$r%d,$r%d,$r%d",
1333 address,
1334 opcode, instruction->info.rt, instruction->info.ra,
1335 instruction->info.rb);
1336 break;
1337 case 6: /* SLT */
1338 nds32_parse_type_3(opcode, &(instruction->info.rt),
1339 &(instruction->info.ra),
1340 &(instruction->info.rb), &(instruction->info.imm));
1341 instruction->type = NDS32_INSN_DATA_PROC;
1342 snprintf(instruction->text,
1343 128,
1344 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSLT\t$r%d,$r%d,$r%d",
1345 address,
1346 opcode, instruction->info.rt, instruction->info.ra,
1347 instruction->info.rb);
1348 break;
1349 case 7: /* SLTS */
1350 nds32_parse_type_3(opcode, &(instruction->info.rt),
1351 &(instruction->info.ra),
1352 &(instruction->info.rb), &(instruction->info.imm));
1353 instruction->type = NDS32_INSN_DATA_PROC;
1354 snprintf(instruction->text,
1355 128,
1356 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSLTS\t$r%d,$r%d,$r%d",
1357 address,
1358 opcode, instruction->info.rt, instruction->info.ra,
1359 instruction->info.rb);
1360 break;
1361 case 8: { /* SLLI */
1362 uint8_t imm;
1363 int32_t sub_op;
1364 nds32_parse_type_3(opcode, &(instruction->info.rt),
1365 &(instruction->info.ra),
1366 &imm, &sub_op);
1367 instruction->info.imm = imm;
1368 instruction->type = NDS32_INSN_DATA_PROC;
1369 snprintf(instruction->text,
1370 128,
1371 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSLLI\t$r%d,$r%d,#%d",
1372 address,
1373 opcode, instruction->info.rt, instruction->info.ra,
1374 instruction->info.imm);
1375 }
1376 break;
1377 case 9: { /* SRLI */
1378 uint8_t imm;
1379 int32_t sub_op;
1380 nds32_parse_type_3(opcode, &(instruction->info.rt),
1381 &(instruction->info.ra),
1382 &imm, &sub_op);
1383 instruction->info.imm = imm;
1384 instruction->type = NDS32_INSN_DATA_PROC;
1385 snprintf(instruction->text,
1386 128,
1387 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSRLI\t$r%d,$r%d,#%d",
1388 address,
1389 opcode, instruction->info.rt, instruction->info.ra,
1390 instruction->info.imm);
1391 }
1392 break;
1393 case 10: { /* SRAI */
1394 uint8_t imm;
1395 int32_t sub_op;
1396 nds32_parse_type_3(opcode, &(instruction->info.rt),
1397 &(instruction->info.ra),
1398 &imm, &sub_op);
1399 instruction->info.imm = imm;
1400 instruction->type = NDS32_INSN_DATA_PROC;
1401 snprintf(instruction->text,
1402 128,
1403 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSRAI\t$r%d,$r%d,#%d",
1404 address,
1405 opcode, instruction->info.rt, instruction->info.ra,
1406 instruction->info.imm);
1407 }
1408 break;
1409 case 11: { /* ROTRI */
1410 uint8_t imm;
1411 int32_t sub_op;
1412 nds32_parse_type_3(opcode, &(instruction->info.rt),
1413 &(instruction->info.ra),
1414 &imm, &sub_op);
1415 instruction->info.imm = imm;
1416 instruction->type = NDS32_INSN_DATA_PROC;
1417 snprintf(instruction->text,
1418 128,
1419 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tROTRI\t$r%d,$r%d,#%d",
1420 address,
1421 opcode, instruction->info.rt, instruction->info.ra,
1422 instruction->info.imm);
1423 }
1424 break;
1425 case 12: { /* SLL */
1426 nds32_parse_type_3(opcode, &(instruction->info.rt),
1427 &(instruction->info.ra),
1428 &(instruction->info.rb), &(instruction->info.imm));
1429 instruction->type = NDS32_INSN_DATA_PROC;
1430 snprintf(instruction->text,
1431 128,
1432 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSLL\t$r%d,$r%d,$r%d",
1433 address,
1434 opcode, instruction->info.rt, instruction->info.ra,
1435 instruction->info.rb);
1436 }
1437 break;
1438 case 13: { /* SRL */
1439 nds32_parse_type_3(opcode, &(instruction->info.rt),
1440 &(instruction->info.ra),
1441 &(instruction->info.rb), &(instruction->info.imm));
1442 instruction->type = NDS32_INSN_DATA_PROC;
1443 snprintf(instruction->text,
1444 128,
1445 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSRL\t$r%d,$r%d,$r%d",
1446 address,
1447 opcode, instruction->info.rt, instruction->info.ra,
1448 instruction->info.rb);
1449 }
1450 break;
1451 case 14: { /* SRA */
1452 nds32_parse_type_3(opcode, &(instruction->info.rt),
1453 &(instruction->info.ra),
1454 &(instruction->info.rb), &(instruction->info.imm));
1455 instruction->type = NDS32_INSN_DATA_PROC;
1456 snprintf(instruction->text,
1457 128,
1458 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSRA\t$r%d,$r%d,$r%d",
1459 address,
1460 opcode, instruction->info.rt, instruction->info.ra,
1461 instruction->info.rb);
1462 }
1463 break;
1464 case 15: { /* ROTR */
1465 nds32_parse_type_3(opcode, &(instruction->info.rt),
1466 &(instruction->info.ra),
1467 &(instruction->info.rb), &(instruction->info.imm));
1468 instruction->type = NDS32_INSN_DATA_PROC;
1469 snprintf(instruction->text,
1470 128,
1471 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tROTR\t$r%d,$r%d,$r%d",
1472 address,
1473 opcode, instruction->info.rt, instruction->info.ra,
1474 instruction->info.rb);
1475 }
1476 break;
1477 case 16: { /* SEB */
1478 nds32_parse_type_2(opcode, &(instruction->info.rt),
1479 &(instruction->info.ra),
1480 &(instruction->info.imm));
1481 instruction->type = NDS32_INSN_DATA_PROC;
1482 snprintf(instruction->text,
1483 128,
1484 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSEB\t$r%d,$r%d",
1485 address,
1486 opcode, instruction->info.rt, instruction->info.ra);
1487 }
1488 break;
1489 case 17: { /* SEH */
1490 nds32_parse_type_2(opcode, &(instruction->info.rt),
1491 &(instruction->info.ra),
1492 &(instruction->info.imm));
1493 instruction->type = NDS32_INSN_DATA_PROC;
1494 snprintf(instruction->text,
1495 128,
1496 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSEH\t$r%d,$r%d",
1497 address,
1498 opcode, instruction->info.rt, instruction->info.ra);
1499 }
1500 break;
1501 case 18: /* BITC */
1502 nds32_parse_type_3(opcode, &(instruction->info.rt),
1503 &(instruction->info.ra),
1504 &(instruction->info.rb), &(instruction->info.imm));
1505 instruction->type = NDS32_INSN_DATA_PROC;
1506 snprintf(instruction->text,
1507 128,
1508 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBITC\t$r%d,$r%d,$r%d",
1509 address,
1510 opcode, instruction->info.rt, instruction->info.ra,
1511 instruction->info.rb);
1512 break;
1513 case 19: { /* ZEH */
1514 nds32_parse_type_2(opcode, &(instruction->info.rt),
1515 &(instruction->info.ra),
1516 &(instruction->info.imm));
1517 instruction->type = NDS32_INSN_DATA_PROC;
1518 snprintf(instruction->text,
1519 128,
1520 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tZEH\t$r%d,$r%d",
1521 address,
1522 opcode, instruction->info.rt, instruction->info.ra);
1523 }
1524 break;
1525 case 20: { /* WSBH */
1526 nds32_parse_type_2(opcode, &(instruction->info.rt),
1527 &(instruction->info.ra),
1528 &(instruction->info.imm));
1529 instruction->type = NDS32_INSN_DATA_PROC;
1530 snprintf(instruction->text,
1531 128,
1532 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tWSBH\t$r%d,$r%d",
1533 address,
1534 opcode, instruction->info.rt, instruction->info.ra);
1535 }
1536 break;
1537 case 21: /* OR_SRLI */
1538 nds32_parse_type_3(opcode, &(instruction->info.rt),
1539 &(instruction->info.ra),
1540 &(instruction->info.rb), &(instruction->info.imm));
1541 instruction->type = NDS32_INSN_DATA_PROC;
1542 instruction->info.imm = (instruction->info.imm >> 5) & 0x1F;
1543 if (instruction->info.imm)
1544 snprintf(instruction->text,
1545 128,
1546 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tOR_SRLI\t$r%d,$r%d,$r%d,%d",
1547 address,
1548 opcode, instruction->info.rt, instruction->info.ra,
1549 instruction->info.rb,
1550 instruction->info.imm);
1551 else
1552 snprintf(instruction->text,
1553 128,
1554 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tOR\t$r%d,$r%d,$r%d",
1555 address,
1556 opcode, instruction->info.rt, instruction->info.ra,
1557 instruction->info.rb);
1558 break;
1559 case 22: { /* DIVSR */
1560 nds32_parse_type_4(opcode, &(instruction->info.rt),
1561 &(instruction->info.ra),
1562 &(instruction->info.rb), &(instruction->info.rd),
1563 &(instruction->info.sub_opc));
1564 instruction->type = NDS32_INSN_DATA_PROC;
1565 snprintf(instruction->text,
1566 128,
1567 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tDIVSR\t$r%d,$r%d,$r%d,$r%d",
1568 address,
1569 opcode, instruction->info.rt, instruction->info.ra,
1570 instruction->info.rb,
1571 instruction->info.rd);
1572 }
1573 break;
1574 case 23: { /* DIVR */
1575 nds32_parse_type_4(opcode, &(instruction->info.rt),
1576 &(instruction->info.ra),
1577 &(instruction->info.rb), &(instruction->info.rd),
1578 &(instruction->info.sub_opc));
1579 instruction->type = NDS32_INSN_DATA_PROC;
1580 snprintf(instruction->text,
1581 128,
1582 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tDIVR\t$r%d,$r%d,$r%d,$r%d",
1583 address,
1584 opcode, instruction->info.rt, instruction->info.ra,
1585 instruction->info.rb,
1586 instruction->info.rd);
1587 }
1588 break;
1589 case 24: { /* SVA */
1590 nds32_parse_type_3(opcode, &(instruction->info.rt),
1591 &(instruction->info.ra),
1592 &(instruction->info.rb), &(instruction->info.imm));
1593 instruction->type = NDS32_INSN_DATA_PROC;
1594 snprintf(instruction->text,
1595 128,
1596 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSVA\t$r%d,$r%d,$r%d",
1597 address,
1598 opcode, instruction->info.rt, instruction->info.ra,
1599 instruction->info.rb);
1600 }
1601 break;
1602 case 25: { /* SVS */
1603 nds32_parse_type_3(opcode, &(instruction->info.rt),
1604 &(instruction->info.ra),
1605 &(instruction->info.rb), &(instruction->info.imm));
1606 instruction->type = NDS32_INSN_DATA_PROC;
1607 snprintf(instruction->text,
1608 128,
1609 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSVS\t$r%d,$r%d,$r%d",
1610 address,
1611 opcode, instruction->info.rt, instruction->info.ra,
1612 instruction->info.rb);
1613 }
1614 break;
1615 case 26: { /* CMOVZ */
1616 nds32_parse_type_3(opcode, &(instruction->info.rt),
1617 &(instruction->info.ra),
1618 &(instruction->info.rb), &(instruction->info.imm));
1619 instruction->type = NDS32_INSN_MISC;
1620 snprintf(instruction->text,
1621 128,
1622 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tCMOVZ\t$r%d,$r%d,$r%d",
1623 address,
1624 opcode, instruction->info.rt, instruction->info.ra,
1625 instruction->info.rb);
1626 }
1627 break;
1628 case 27: { /* CMOVN */
1629 nds32_parse_type_3(opcode, &(instruction->info.rt),
1630 &(instruction->info.ra),
1631 &(instruction->info.rb), &(instruction->info.imm));
1632 instruction->type = NDS32_INSN_MISC;
1633 snprintf(instruction->text,
1634 128,
1635 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tCMOVN\t$r%d,$r%d,$r%d",
1636 address,
1637 opcode, instruction->info.rt, instruction->info.ra,
1638 instruction->info.rb);
1639 }
1640 break;
1641 case 28: /* ADD_SRLI */
1642 nds32_parse_type_3(opcode, &(instruction->info.rt),
1643 &(instruction->info.ra),
1644 &(instruction->info.rb), &(instruction->info.imm));
1645 instruction->type = NDS32_INSN_DATA_PROC;
1646 instruction->info.imm = (instruction->info.imm >> 5) & 0x1F;
1647 if (instruction->info.imm)
1648 snprintf(instruction->text,
1649 128,
1650 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tADD_SRLI\t$r%d,$r%d,$r%d,%d",
1651 address,
1652 opcode, instruction->info.rt, instruction->info.ra,
1653 instruction->info.rb,
1654 instruction->info.imm);
1655 else
1656 snprintf(instruction->text,
1657 128,
1658 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tADD\t$r%d,$r%d,$r%d",
1659 address,
1660 opcode, instruction->info.rt, instruction->info.ra,
1661 instruction->info.rb);
1662 break;
1663 case 29: /* SUB_SRLI */
1664 nds32_parse_type_3(opcode, &(instruction->info.rt),
1665 &(instruction->info.ra),
1666 &(instruction->info.rb), &(instruction->info.imm));
1667 instruction->type = NDS32_INSN_DATA_PROC;
1668 instruction->info.imm = (instruction->info.imm >> 5) & 0x1F;
1669 if (instruction->info.imm)
1670 snprintf(instruction->text,
1671 128,
1672 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSUB_SRLI\t$r%d,$r%d,$r%d,%d",
1673 address,
1674 opcode, instruction->info.rt, instruction->info.ra,
1675 instruction->info.rb,
1676 instruction->info.imm);
1677 else
1678 snprintf(instruction->text,
1679 128,
1680 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSUB\t$r%d,$r%d,$r%d",
1681 address,
1682 opcode, instruction->info.rt, instruction->info.ra,
1683 instruction->info.rb);
1684 break;
1685 case 30: /* AND_SRLI */
1686 nds32_parse_type_3(opcode, &(instruction->info.rt),
1687 &(instruction->info.ra),
1688 &(instruction->info.rb), &(instruction->info.imm));
1689 instruction->type = NDS32_INSN_DATA_PROC;
1690 instruction->info.imm = (instruction->info.imm >> 5) & 0x1F;
1691 if (instruction->info.imm)
1692 snprintf(instruction->text,
1693 128,
1694 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tAND_SRLI\t$r%d,$r%d,$r%d,%d",
1695 address,
1696 opcode, instruction->info.rt, instruction->info.ra,
1697 instruction->info.rb,
1698 instruction->info.imm);
1699 else
1700 snprintf(instruction->text,
1701 128,
1702 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tAND\t$r%d,$r%d,$r%d",
1703 address,
1704 opcode, instruction->info.rt, instruction->info.ra,
1705 instruction->info.rb);
1706 break;
1707 case 31: /* XOR_SRLI */
1708 nds32_parse_type_3(opcode, &(instruction->info.rt),
1709 &(instruction->info.ra),
1710 &(instruction->info.rb), &(instruction->info.imm));
1711 instruction->type = NDS32_INSN_DATA_PROC;
1712 instruction->info.imm = (instruction->info.imm >> 5) & 0x1F;
1713 if (instruction->info.imm)
1714 snprintf(instruction->text,
1715 128,
1716 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tXOR_SRLI\t$r%d,$r%d,$r%d,%d",
1717 address,
1718 opcode, instruction->info.rt, instruction->info.ra,
1719 instruction->info.rb,
1720 instruction->info.imm);
1721 else
1722 snprintf(instruction->text,
1723 128,
1724 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tXOR\t$r%d,$r%d,$r%d",
1725 address,
1726 opcode, instruction->info.rt, instruction->info.ra,
1727 instruction->info.rb);
1728 break;
1729 default:
1730 snprintf(instruction->text,
1731 128,
1732 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
1733 address,
1734 opcode);
1735 return ERROR_FAIL;
1736 }
1737
1738 return ERROR_OK;
1739 }
1740
1741 static int nds32_parse_alu_2(uint32_t opcode, uint32_t address,
1742 struct nds32_instruction *instruction)
1743 {
1744 switch (opcode & 0x3F) {
1745 case 0: /* MAX */
1746 nds32_parse_type_3(opcode, &(instruction->info.rt),
1747 &(instruction->info.ra),
1748 &(instruction->info.rb), &(instruction->info.imm));
1749 instruction->type = NDS32_INSN_DATA_PROC;
1750 snprintf(instruction->text,
1751 128,
1752 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMAX\t$r%d,$r%d,$r%d",
1753 address,
1754 opcode, instruction->info.rt, instruction->info.ra,
1755 instruction->info.rb);
1756 break;
1757 case 1: /* MIN */
1758 nds32_parse_type_3(opcode, &(instruction->info.rt),
1759 &(instruction->info.ra),
1760 &(instruction->info.rb), &(instruction->info.imm));
1761 instruction->type = NDS32_INSN_DATA_PROC;
1762 snprintf(instruction->text,
1763 128,
1764 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMIN\t$r%d,$r%d,$r%d",
1765 address,
1766 opcode, instruction->info.rt, instruction->info.ra,
1767 instruction->info.rb);
1768 break;
1769 case 2: /* AVE */
1770 nds32_parse_type_3(opcode, &(instruction->info.rt),
1771 &(instruction->info.ra),
1772 &(instruction->info.rb), &(instruction->info.imm));
1773 instruction->type = NDS32_INSN_DATA_PROC;
1774 snprintf(instruction->text,
1775 128,
1776 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tAVE\t$r%d,$r%d,$r%d",
1777 address,
1778 opcode, instruction->info.rt, instruction->info.ra,
1779 instruction->info.rb);
1780 break;
1781 case 3: /* ABS */
1782 nds32_parse_type_2(opcode, &(instruction->info.rt),
1783 &(instruction->info.ra),
1784 &(instruction->info.imm));
1785 instruction->type = NDS32_INSN_DATA_PROC;
1786 snprintf(instruction->text,
1787 128,
1788 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tAVE\t$r%d,$r%d",
1789 address,
1790 opcode, instruction->info.rt, instruction->info.ra);
1791 break;
1792 case 4: { /* CLIPS */
1793 uint8_t imm;
1794 nds32_parse_type_3(opcode, &(instruction->info.rt),
1795 &(instruction->info.ra),
1796 &imm, &(instruction->info.imm));
1797 instruction->info.imm = imm;
1798 instruction->type = NDS32_INSN_DATA_PROC;
1799 snprintf(instruction->text,
1800 128,
1801 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tCLIPS\t$r%d,$r%d,#%d",
1802 address,
1803 opcode, instruction->info.rt, instruction->info.ra,
1804 instruction->info.imm);
1805 }
1806 break;
1807 case 5: { /* CLIP */
1808 uint8_t imm;
1809 nds32_parse_type_3(opcode, &(instruction->info.rt),
1810 &(instruction->info.ra),
1811 &imm, &(instruction->info.imm));
1812 instruction->info.imm = imm;
1813 instruction->type = NDS32_INSN_DATA_PROC;
1814 snprintf(instruction->text,
1815 128,
1816 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tCLIP\t$r%d,$r%d,#%d",
1817 address,
1818 opcode, instruction->info.rt, instruction->info.ra,
1819 instruction->info.imm);
1820 }
1821 break;
1822 case 6: /* CLO */
1823 nds32_parse_type_2(opcode, &(instruction->info.rt),
1824 &(instruction->info.ra),
1825 &(instruction->info.imm));
1826 instruction->type = NDS32_INSN_DATA_PROC;
1827 snprintf(instruction->text,
1828 128,
1829 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tCLO\t$r%d,$r%d",
1830 address,
1831 opcode, instruction->info.rt, instruction->info.ra);
1832 break;
1833 case 7: /* CLZ */
1834 nds32_parse_type_2(opcode, &(instruction->info.rt),
1835 &(instruction->info.ra),
1836 &(instruction->info.imm));
1837 instruction->type = NDS32_INSN_DATA_PROC;
1838 snprintf(instruction->text,
1839 128,
1840 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tCLZ\t$r%d,$r%d",
1841 address,
1842 opcode, instruction->info.rt, instruction->info.ra);
1843 break;
1844 case 8: { /* BSET */
1845 uint8_t imm;
1846 nds32_parse_type_3(opcode, &(instruction->info.rt),
1847 &(instruction->info.ra),
1848 &imm, &(instruction->info.imm));
1849 instruction->info.imm = imm;
1850 instruction->type = NDS32_INSN_DATA_PROC;
1851 snprintf(instruction->text,
1852 128,
1853 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBSET\t$r%d,$r%d,#%d",
1854 address,
1855 opcode, instruction->info.rt, instruction->info.ra,
1856 instruction->info.imm);
1857 }
1858 break;
1859 case 9: { /* BCLR */
1860 uint8_t imm;
1861 nds32_parse_type_3(opcode, &(instruction->info.rt),
1862 &(instruction->info.ra),
1863 &imm, &(instruction->info.imm));
1864 instruction->info.imm = imm;
1865 instruction->type = NDS32_INSN_DATA_PROC;
1866 snprintf(instruction->text,
1867 128,
1868 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBCLR\t$r%d,$r%d,#%d",
1869 address,
1870 opcode, instruction->info.rt, instruction->info.ra,
1871 instruction->info.imm);
1872 }
1873 break;
1874 case 10: { /* BTGL */
1875 uint8_t imm;
1876 nds32_parse_type_3(opcode, &(instruction->info.rt),
1877 &(instruction->info.ra),
1878 &imm, &(instruction->info.imm));
1879 instruction->info.imm = imm;
1880 instruction->type = NDS32_INSN_DATA_PROC;
1881 snprintf(instruction->text,
1882 128,
1883 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBTGL\t$r%d,$r%d,#%d",
1884 address,
1885 opcode, instruction->info.rt, instruction->info.ra,
1886 instruction->info.imm);
1887 }
1888 break;
1889 case 11: { /* BTST */
1890 uint8_t imm;
1891 nds32_parse_type_3(opcode, &(instruction->info.rt),
1892 &(instruction->info.ra),
1893 &imm, &(instruction->info.imm));
1894 instruction->info.imm = imm;
1895 instruction->type = NDS32_INSN_DATA_PROC;
1896 snprintf(instruction->text,
1897 128,
1898 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBTST\t$r%d,$r%d,#%d",
1899 address,
1900 opcode, instruction->info.rt, instruction->info.ra,
1901 instruction->info.imm);
1902 }
1903 break;
1904 case 12: /* BSE */
1905 nds32_parse_type_3(opcode, &(instruction->info.rt),
1906 &(instruction->info.ra),
1907 &(instruction->info.rb), &(instruction->info.imm));
1908 instruction->type = NDS32_INSN_DATA_PROC;
1909 snprintf(instruction->text,
1910 128,
1911 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBSE\t$r%d,$r%d,$r%d",
1912 address,
1913 opcode, instruction->info.rt, instruction->info.ra,
1914 instruction->info.rb);
1915 break;
1916 case 13: /* BSP */
1917 nds32_parse_type_3(opcode, &(instruction->info.rt),
1918 &(instruction->info.ra),
1919 &(instruction->info.rb), &(instruction->info.imm));
1920 instruction->type = NDS32_INSN_DATA_PROC;
1921 snprintf(instruction->text,
1922 128,
1923 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBSP\t$r%d,$r%d,$r%d",
1924 address,
1925 opcode, instruction->info.rt, instruction->info.ra,
1926 instruction->info.rb);
1927 break;
1928 case 14: /* FFB */
1929 nds32_parse_type_3(opcode, &(instruction->info.rt),
1930 &(instruction->info.ra),
1931 &(instruction->info.rb), &(instruction->info.imm));
1932 instruction->type = NDS32_INSN_DATA_PROC;
1933 snprintf(instruction->text,
1934 128,
1935 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tFFB\t$r%d,$r%d,$r%d",
1936 address,
1937 opcode, instruction->info.rt, instruction->info.ra,
1938 instruction->info.rb);
1939 break;
1940 case 15: /* FFMISM */
1941 nds32_parse_type_3(opcode, &(instruction->info.rt),
1942 &(instruction->info.ra),
1943 &(instruction->info.rb), &(instruction->info.imm));
1944 instruction->type = NDS32_INSN_DATA_PROC;
1945 snprintf(instruction->text,
1946 128,
1947 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tFFMISM\t$r%d,$r%d,$r%d",
1948 address,
1949 opcode, instruction->info.rt, instruction->info.ra,
1950 instruction->info.rb);
1951 break;
1952 case 23: /* FFZMISM */
1953 nds32_parse_type_3(opcode, &(instruction->info.rt),
1954 &(instruction->info.ra),
1955 &(instruction->info.rb), &(instruction->info.imm));
1956 instruction->type = NDS32_INSN_DATA_PROC;
1957 snprintf(instruction->text,
1958 128,
1959 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tFFZMISM\t$r%d,$r%d,$r%d",
1960 address,
1961 opcode, instruction->info.rt, instruction->info.ra,
1962 instruction->info.rb);
1963 break;
1964 case 32: /* MFUSR */
1965 nds32_parse_type_1(opcode, &(instruction->info.rt),
1966 &(instruction->info.imm));
1967 instruction->type = NDS32_INSN_RESOURCE_ACCESS;
1968 snprintf(instruction->text,
1969 128,
1970 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMFUSR\t$r%d,#%d",
1971 address,
1972 opcode, instruction->info.rt,
1973 (instruction->info.imm >> 10) & 0x3FF);
1974 break;
1975 case 33: /* MTUSR */
1976 nds32_parse_type_1(opcode, &(instruction->info.rt),
1977 &(instruction->info.imm));
1978 instruction->type = NDS32_INSN_RESOURCE_ACCESS;
1979 snprintf(instruction->text,
1980 128,
1981 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMTUSR\t$r%d,#%d",
1982 address,
1983 opcode, instruction->info.rt,
1984 (instruction->info.imm >> 10) & 0x3FF);
1985 break;
1986 case 36: /* MUL */
1987 nds32_parse_type_3(opcode, &(instruction->info.rt),
1988 &(instruction->info.ra),
1989 &(instruction->info.rb), &(instruction->info.imm));
1990 instruction->type = NDS32_INSN_DATA_PROC;
1991 snprintf(instruction->text,
1992 128,
1993 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMUL\t$r%d,$r%d,$r%d",
1994 address,
1995 opcode, instruction->info.rt, instruction->info.ra,
1996 instruction->info.rb);
1997 break;
1998 case 40: { /* MULTS64 */
1999 uint8_t dt_val;
2000 nds32_parse_type_3(opcode, &dt_val,
2001 &(instruction->info.ra),
2002 &(instruction->info.rb), &(instruction->info.imm));
2003 instruction->type = NDS32_INSN_DATA_PROC;
2004 snprintf(instruction->text,
2005 128,
2006 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMULTS64\t$D%d,$r%d,$r%d",
2007 address,
2008 opcode, (dt_val >> 1) & 0x1, instruction->info.ra,
2009 instruction->info.rb);
2010 }
2011 break;
2012 case 41: { /* MULT64 */
2013 uint8_t dt_val;
2014 nds32_parse_type_3(opcode, &dt_val,
2015 &(instruction->info.ra),
2016 &(instruction->info.rb), &(instruction->info.imm));
2017 instruction->type = NDS32_INSN_DATA_PROC;
2018 snprintf(instruction->text,
2019 128,
2020 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMULT64\t$D%d,$r%d,$r%d",
2021 address,
2022 opcode, (dt_val >> 1) & 0x1, instruction->info.ra,
2023 instruction->info.rb);
2024 }
2025 break;
2026 case 42: { /* MADDS64 */
2027 uint8_t dt_val;
2028 nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra),
2029 &(instruction->info.rb), &(instruction->info.imm));
2030 instruction->type = NDS32_INSN_DATA_PROC;
2031 snprintf(instruction->text,
2032 128,
2033 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMADDS64\t$D%d,$r%d,$r%d",
2034 address,
2035 opcode, (dt_val >> 1) & 0x1, instruction->info.ra,
2036 instruction->info.rb);
2037 }
2038 break;
2039 case 43: { /* MADD64 */
2040 uint8_t dt_val;
2041 nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra),
2042 &(instruction->info.rb), &(instruction->info.imm));
2043 instruction->type = NDS32_INSN_DATA_PROC;
2044 snprintf(instruction->text,
2045 128,
2046 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMADD64\t$D%d,$r%d,$r%d",
2047 address,
2048 opcode, (dt_val >> 1) & 0x1, instruction->info.ra,
2049 instruction->info.rb);
2050 }
2051 break;
2052 case 44: { /* MSUBS64 */
2053 uint8_t dt_val;
2054 nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra),
2055 &(instruction->info.rb), &(instruction->info.imm));
2056 instruction->type = NDS32_INSN_DATA_PROC;
2057 snprintf(instruction->text,
2058 128,
2059 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMSUBS64\t$D%d,$r%d,$r%d",
2060 address,
2061 opcode, (dt_val >> 1) & 0x1, instruction->info.ra,
2062 instruction->info.rb);
2063 }
2064 break;
2065 case 45: { /* MSUB64 */
2066 uint8_t dt_val;
2067 nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra),
2068 &(instruction->info.rb), &(instruction->info.imm));
2069 instruction->type = NDS32_INSN_DATA_PROC;
2070 snprintf(instruction->text,
2071 128,
2072 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMSUB64\t$D%d,$r%d,$r%d",
2073 address,
2074 opcode, (dt_val >> 1) & 0x1, instruction->info.ra,
2075 instruction->info.rb);
2076 }
2077 break;
2078 case 46: { /* DIVS */
2079 uint8_t dt_val;
2080 nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra),
2081 &(instruction->info.rb), &(instruction->info.imm));
2082 instruction->type = NDS32_INSN_DATA_PROC;
2083 snprintf(instruction->text,
2084 128,
2085 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tDIVS\t$D%d,$r%d,$r%d",
2086 address,
2087 opcode, (dt_val >> 1) & 0x1, instruction->info.ra,
2088 instruction->info.rb);
2089 }
2090 break;
2091 case 47: { /* DIV */
2092 uint8_t dt_val;
2093 nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra),
2094 &(instruction->info.rb), &(instruction->info.imm));
2095 instruction->type = NDS32_INSN_DATA_PROC;
2096 snprintf(instruction->text,
2097 128,
2098 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tDIV\t$D%d,$r%d,$r%d",
2099 address,
2100 opcode, (dt_val >> 1) & 0x1, instruction->info.ra,
2101 instruction->info.rb);
2102 }
2103 break;
2104 case 49: { /* MULT32 */
2105 uint8_t dt_val;
2106 nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra),
2107 &(instruction->info.rb), &(instruction->info.imm));
2108 instruction->type = NDS32_INSN_DATA_PROC;
2109 snprintf(instruction->text,
2110 128,
2111 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMULT32\t$D%d,$r%d,$r%d",
2112 address,
2113 opcode, (dt_val >> 1) & 0x1, instruction->info.ra,
2114 instruction->info.rb);
2115 }
2116 break;
2117 case 51: { /* MADD32 */
2118 uint8_t dt_val;
2119 nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra),
2120 &(instruction->info.rb), &(instruction->info.imm));
2121 instruction->type = NDS32_INSN_DATA_PROC;
2122 snprintf(instruction->text,
2123 128,
2124 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMADD32\t$D%d,$r%d,$r%d",
2125 address,
2126 opcode, (dt_val >> 1) & 0x1, instruction->info.ra,
2127 instruction->info.rb);
2128 }
2129 break;
2130 case 53: { /* MSUB32 */
2131 uint8_t dt_val;
2132 nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra),
2133 &(instruction->info.rb), &(instruction->info.imm));
2134 instruction->type = NDS32_INSN_DATA_PROC;
2135 snprintf(instruction->text,
2136 128,
2137 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMSUB32\t$D%d,$r%d,$r%d",
2138 address,
2139 opcode, (dt_val >> 1) & 0x1, instruction->info.ra,
2140 instruction->info.rb);
2141 }
2142 break;
2143 default:
2144 snprintf(instruction->text,
2145 128,
2146 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
2147 address,
2148 opcode);
2149 return ERROR_FAIL;
2150 }
2151
2152 return ERROR_OK;
2153 }
2154
2155 static int nds32_parse_group_4_insn(struct nds32 *nds32, uint32_t opcode,
2156 uint32_t address, struct nds32_instruction *instruction)
2157 {
2158 uint8_t opc_6;
2159
2160 opc_6 = instruction->info.opc_6;
2161
2162 switch (opc_6 & 0x7) {
2163 case 0: /* ALU_1 */
2164 nds32_parse_alu_1(opcode, address, instruction);
2165 break;
2166 case 1: /* ALU_2 */
2167 nds32_parse_alu_2(opcode, address, instruction);
2168 break;
2169 case 2: /* MOVI */
2170 nds32_parse_type_1(opcode, &(instruction->info.rt),
2171 &(instruction->info.imm));
2172 /* sign-extend */
2173 instruction->info.imm = (instruction->info.imm << 12) >> 12;
2174 instruction->type = NDS32_INSN_DATA_PROC;
2175 snprintf(instruction->text,
2176 128,
2177 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMOVI\t$r%d,#%d",
2178 address,
2179 opcode, instruction->info.rt, instruction->info.imm);
2180 break;
2181 case 3: /* SETHI */
2182 nds32_parse_type_1(opcode, &(instruction->info.rt),
2183 &(instruction->info.imm));
2184 instruction->type = NDS32_INSN_DATA_PROC;
2185 snprintf(instruction->text,
2186 128,
2187 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSETHI\t$r%d,0x%8.8" PRIx32,
2188 address,
2189 opcode, instruction->info.rt, instruction->info.imm);
2190 break;
2191 case 4: /* JI */
2192 nds32_parse_type_0(opcode, &(instruction->info.imm));
2193 /* sign-extend */
2194 instruction->info.imm = (instruction->info.imm << 8) >> 8;
2195 instruction->type = NDS32_INSN_JUMP_BRANCH;
2196 if ((instruction->info.imm >> 24) & 0x1) { /* JAL */
2197 snprintf(instruction->text,
2198 128,
2199 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tJAL\t#%d",
2200 address,
2201 opcode, instruction->info.imm);
2202 } else { /* J */
2203 snprintf(instruction->text,
2204 128,
2205 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tJ\t#%d",
2206 address,
2207 opcode, instruction->info.imm);
2208 }
2209 break;
2210 case 5: { /* JREG */
2211 int32_t imm;
2212 nds32_parse_type_0(opcode, &imm);
2213 instruction->info.rb = (imm >> 10) & 0x1F;
2214 instruction->type = NDS32_INSN_JUMP_BRANCH;
2215 switch (imm & 0x1F) {
2216 /* TODO */
2217 case 0: /* JR */
2218 if (imm & 0x20) { /* RET */
2219 snprintf(instruction->text,
2220 128,
2221 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tRET\t$r%d",
2222 address,
2223 opcode, instruction->info.rb);
2224 } else { /* JR */
2225 snprintf(instruction->text,
2226 128,
2227 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tJR\t$r%d",
2228 address,
2229 opcode, instruction->info.rb);
2230 }
2231 break;
2232 case 1: /* JRAL */
2233 instruction->info.rt = (imm >> 20) & 0x1F;
2234 snprintf(instruction->text,
2235 128,
2236 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tJRAL\t$r%d,$r%d",
2237 address,
2238 opcode, instruction->info.rt, instruction->info.rb);
2239 break;
2240 case 2: /* JRNEZ */
2241 snprintf(instruction->text,
2242 128,
2243 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tJRNEZ\t$r%d",
2244 address,
2245 opcode, instruction->info.rb);
2246 break;
2247 case 3: /* JRALNEZ */
2248 instruction->info.rt = (imm >> 20) & 0x1F;
2249 if (instruction->info.rt == R30)
2250 snprintf(instruction->text,
2251 128,
2252 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tJRALNEZ\t$r%d",
2253 address,
2254 opcode, instruction->info.rb);
2255 else
2256 snprintf(instruction->text,
2257 128,
2258 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
2259 "\tJRALNEZ\t$r%d,$r%d",
2260 address,
2261 opcode,
2262 instruction->info.rt,
2263 instruction->info.rb);
2264 break;
2265 }
2266 }
2267 break;
2268 case 6: { /* BR1 */
2269 int32_t imm;
2270
2271 nds32_parse_type_0(opcode, &imm);
2272 instruction->type = NDS32_INSN_JUMP_BRANCH;
2273 if ((imm >> 14) & 0x1) { /* BNE */
2274 nds32_parse_type_2(opcode, &(instruction->info.rt),
2275 &(instruction->info.ra), &(instruction->info.imm));
2276 /* sign-extend */
2277 instruction->info.imm = (instruction->info.imm << 18) >> 18;
2278 snprintf(instruction->text,
2279 128,
2280 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBNE\t$r%d,$r%d,#%d",
2281 address,
2282 opcode, instruction->info.rt, instruction->info.ra,
2283 instruction->info.imm);
2284 } else { /* BEQ */
2285 nds32_parse_type_2(opcode, &(instruction->info.rt),
2286 &(instruction->info.ra), &(instruction->info.imm));
2287 /* sign-extend */
2288 instruction->info.imm = (instruction->info.imm << 18) >> 18;
2289 snprintf(instruction->text,
2290 128,
2291 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBEQ\t$r%d,$r%d,#%d",
2292 address,
2293 opcode, instruction->info.rt,
2294 instruction->info.ra,
2295 instruction->info.imm);
2296 }
2297 }
2298 break;
2299 case 7: { /* BR2 */
2300 int32_t imm;
2301
2302 nds32_parse_type_0(opcode, &imm);
2303 instruction->type = NDS32_INSN_JUMP_BRANCH;
2304 switch ((imm >> 16) & 0xF) {
2305 case 2: /* BEQZ */
2306 nds32_parse_type_1(opcode, &(instruction->info.rt),
2307 &(instruction->info.imm));
2308 instruction->info.imm = (instruction->info.imm << 16) >> 16;
2309 snprintf(instruction->text,
2310 128,
2311 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBEQZ\t$r%d,#%d",
2312 address,
2313 opcode, instruction->info.rt, instruction->info.imm);
2314 break;
2315 case 3: /* BNEZ */
2316 nds32_parse_type_1(opcode, &(instruction->info.rt),
2317 &(instruction->info.imm));
2318 instruction->info.imm = (instruction->info.imm << 16) >> 16;
2319 snprintf(instruction->text,
2320 128,
2321 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBNEZ\t$r%d,#%d",
2322 address,
2323 opcode, instruction->info.rt, instruction->info.imm);
2324 break;
2325 case 4: /* BGEZ */
2326 nds32_parse_type_1(opcode, &(instruction->info.rt),
2327 &(instruction->info.imm));
2328 instruction->info.imm = (instruction->info.imm << 16) >> 16;
2329 snprintf(instruction->text,
2330 128,
2331 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBGEZ\t$r%d,#%d",
2332 address,
2333 opcode, instruction->info.rt, instruction->info.imm);
2334 break;
2335 case 5: /* BLTZ */
2336 nds32_parse_type_1(opcode, &(instruction->info.rt),
2337 &(instruction->info.imm));
2338 instruction->info.imm = (instruction->info.imm << 16) >> 16;
2339 snprintf(instruction->text,
2340 128,
2341 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBLTZ\t$r%d,#%d",
2342 address,
2343 opcode, instruction->info.rt, instruction->info.imm);
2344 break;
2345 case 6: /* BGTZ */
2346 nds32_parse_type_1(opcode, &(instruction->info.rt),
2347 &(instruction->info.imm));
2348 instruction->info.imm = (instruction->info.imm << 16) >> 16;
2349 snprintf(instruction->text,
2350 128,
2351 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBGTZ\t$r%d,#%d",
2352 address,
2353 opcode, instruction->info.rt, instruction->info.imm);
2354 break;
2355 case 7: /* BLEZ */
2356 nds32_parse_type_1(opcode, &(instruction->info.rt),
2357 &(instruction->info.imm));
2358 instruction->info.imm = (instruction->info.imm << 16) >> 16;
2359 snprintf(instruction->text,
2360 128,
2361 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBLEZ\t$r%d,#%d",
2362 address,
2363 opcode, instruction->info.rt, instruction->info.imm);
2364 break;
2365 case 12: /* BGEZAL */
2366 nds32_parse_type_1(opcode, &(instruction->info.rt),
2367 &(instruction->info.imm));
2368 instruction->info.imm = (instruction->info.imm << 16) >> 16;
2369 snprintf(instruction->text,
2370 128,
2371 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBGEZAL\t$r%d,#%d",
2372 address,
2373 opcode, instruction->info.rt, instruction->info.imm);
2374 break;
2375 case 13: /* BLTZAL */
2376 nds32_parse_type_1(opcode, &(instruction->info.rt),
2377 &(instruction->info.imm));
2378 instruction->info.imm = (instruction->info.imm << 16) >> 16;
2379 snprintf(instruction->text,
2380 128,
2381 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBLTZAL\t$r%d,#%d",
2382 address,
2383 opcode, instruction->info.rt, instruction->info.imm);
2384 break;
2385 }
2386 }
2387 break;
2388 default:
2389 snprintf(instruction->text,
2390 128,
2391 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
2392 address,
2393 opcode);
2394 return ERROR_FAIL;
2395 }
2396
2397 return ERROR_OK;
2398 }
2399
2400 static int nds32_parse_group_5_insn(struct nds32 *nds32, uint32_t opcode,
2401 uint32_t address, struct nds32_instruction *instruction)
2402 {
2403 uint8_t opc_6;
2404
2405 opc_6 = instruction->info.opc_6;
2406
2407 switch (opc_6 & 0x7) {
2408 case 0: /* ADDI */
2409 nds32_parse_type_2(opcode, &(instruction->info.rt),
2410 &(instruction->info.ra), &(instruction->info.imm));
2411 instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */
2412 instruction->type = NDS32_INSN_DATA_PROC;
2413 snprintf(instruction->text,
2414 128,
2415 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tADDI\t$r%d,$r%d,#%d",
2416 address,
2417 opcode, instruction->info.rt, instruction->info.ra,
2418 instruction->info.imm);
2419 break;
2420 case 1: /* SUBRI */
2421 nds32_parse_type_2(opcode, &(instruction->info.rt),
2422 &(instruction->info.ra), &(instruction->info.imm));
2423 instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */
2424 instruction->type = NDS32_INSN_DATA_PROC;
2425 snprintf(instruction->text,
2426 128,
2427 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSUBRI\t$r%d,$r%d,#%d",
2428 address,
2429 opcode, instruction->info.rt, instruction->info.ra,
2430 instruction->info.imm);
2431 break;
2432 case 2: /* ANDI */
2433 nds32_parse_type_2(opcode, &(instruction->info.rt),
2434 &(instruction->info.ra), &(instruction->info.imm));
2435 instruction->type = NDS32_INSN_DATA_PROC;
2436 snprintf(instruction->text,
2437 128,
2438 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tANDI\t$r%d,$r%d,#%d",
2439 address,
2440 opcode, instruction->info.rt, instruction->info.ra,
2441 instruction->info.imm);
2442 break;
2443 case 3: /* XORI */
2444 nds32_parse_type_2(opcode, &(instruction->info.rt),
2445 &(instruction->info.ra), &(instruction->info.imm));
2446 instruction->type = NDS32_INSN_DATA_PROC;
2447 snprintf(instruction->text,
2448 128,
2449 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tXORI\t$r%d,$r%d,#%d",
2450 address,
2451 opcode, instruction->info.rt, instruction->info.ra,
2452 instruction->info.imm);
2453 break;
2454 case 4: /* ORI */
2455 nds32_parse_type_2(opcode, &(instruction->info.rt),
2456 &(instruction->info.ra), &(instruction->info.imm));
2457 instruction->type = NDS32_INSN_DATA_PROC;
2458 snprintf(instruction->text,
2459 128,
2460 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tORI\t$r%d,$r%d,0x%8.8" PRIx32,
2461 address,
2462 opcode, instruction->info.rt, instruction->info.ra,
2463 instruction->info.imm);
2464 break;
2465 case 6: /* SLTI */
2466 nds32_parse_type_2(opcode, &(instruction->info.rt),
2467 &(instruction->info.ra), &(instruction->info.imm));
2468 instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */
2469 instruction->type = NDS32_INSN_DATA_PROC;
2470 snprintf(instruction->text,
2471 128,
2472 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSLTI\t$r%d,$r%d,#%d",
2473 address,
2474 opcode, instruction->info.rt, instruction->info.ra,
2475 instruction->info.imm);
2476 break;
2477 case 7: /* SLTSI */
2478 nds32_parse_type_2(opcode, &(instruction->info.rt),
2479 &(instruction->info.ra), &(instruction->info.imm));
2480 instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */
2481 instruction->type = NDS32_INSN_DATA_PROC;
2482 snprintf(instruction->text,
2483 128,
2484 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSLTSI\t$r%d,$r%d,#%d",
2485 address,
2486 opcode, instruction->info.rt, instruction->info.ra,
2487 instruction->info.imm);
2488 break;
2489 default:
2490 snprintf(instruction->text,
2491 128,
2492 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
2493 address,
2494 opcode);
2495 return ERROR_FAIL;
2496 }
2497
2498 return ERROR_OK;
2499 }
2500
2501 static int nds32_parse_group_6_insn(struct nds32 *nds32, uint32_t opcode,
2502 uint32_t address, struct nds32_instruction *instruction)
2503 {
2504 uint8_t opc_6;
2505
2506 opc_6 = instruction->info.opc_6;
2507
2508 switch (opc_6 & 0x7) {
2509 case 2: { /* MISC */
2510 int32_t imm;
2511 uint8_t sub_opc;
2512
2513 nds32_parse_type_0(opcode, &imm);
2514
2515 sub_opc = imm & 0x1F;
2516 switch (sub_opc) {
2517 case 0: /* STANDBY */
2518 instruction->type = NDS32_INSN_MISC;
2519 snprintf(instruction->text,
2520 128,
2521 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSTANDBY\t#%d",
2522 address,
2523 opcode, (opcode >> 5) & 0x3);
2524 break;
2525 case 1: /* CCTL */
2526 /* TODO */
2527 nds32_parse_type_2(opcode, &(instruction->info.rt),
2528 &(instruction->info.ra), &(instruction->info.imm));
2529 instruction->type = NDS32_INSN_MISC;
2530 snprintf(instruction->text,
2531 128,
2532 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tCCTL",
2533 address,
2534 opcode);
2535 break;
2536 case 2: /* MFSR */
2537 nds32_parse_type_1(opcode, &(instruction->info.rt),
2538 &(instruction->info.imm));
2539 instruction->type = NDS32_INSN_RESOURCE_ACCESS;
2540 snprintf(instruction->text,
2541 128,
2542 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMFSR\t$r%d,#%d",
2543 address,
2544 opcode, instruction->info.rt,
2545 (instruction->info.imm >> 10) & 0x3FF);
2546 break;
2547 case 3: /* MTSR */
2548 nds32_parse_type_1(opcode, &(instruction->info.ra),
2549 &(instruction->info.imm));
2550 instruction->type = NDS32_INSN_RESOURCE_ACCESS;
2551 snprintf(instruction->text,
2552 128,
2553 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMTSR\t$r%d,#%d",
2554 address,
2555 opcode, instruction->info.ra,
2556 (instruction->info.imm >> 10) & 0x3FF);
2557 break;
2558 case 4: /* IRET */
2559 instruction->type = NDS32_INSN_MISC;
2560 snprintf(instruction->text,
2561 128,
2562 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tIRET",
2563 address,
2564 opcode);
2565 break;
2566 case 5: /* TRAP */
2567 instruction->type = NDS32_INSN_MISC;
2568 snprintf(instruction->text,
2569 128,
2570 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tTRAP\t#%d",
2571 address,
2572 opcode, (imm >> 5) & 0x7FFF);
2573 break;
2574 case 6: /* TEQZ */
2575 nds32_parse_type_1(opcode, &(instruction->info.ra),
2576 &(instruction->info.imm));
2577 instruction->type = NDS32_INSN_MISC;
2578 snprintf(instruction->text,
2579 128,
2580 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tTEQZ\t$r%d,#%d",
2581 address,
2582 opcode, instruction->info.ra,
2583 (instruction->info.imm >> 5) & 0x7FFF);
2584 break;
2585 case 7: /* TNEZ */
2586 nds32_parse_type_1(opcode, &(instruction->info.ra),
2587 &(instruction->info.imm));
2588 instruction->type = NDS32_INSN_MISC;
2589 snprintf(instruction->text,
2590 128,
2591 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tTNEZ\t$r%d,#%d",
2592 address,
2593 opcode, instruction->info.ra,
2594 (instruction->info.imm >> 5) & 0x7FFF);
2595 break;
2596 case 8: /* DSB */
2597 instruction->type = NDS32_INSN_MISC;
2598 snprintf(instruction->text,
2599 128,
2600 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tDSB",
2601 address,
2602 opcode);
2603 break;
2604 case 9: /* ISB */
2605 instruction->type = NDS32_INSN_MISC;
2606 snprintf(instruction->text,
2607 128,
2608 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tISB",
2609 address,
2610 opcode);
2611 break;
2612 case 10: /* BREAK */
2613 instruction->type = NDS32_INSN_MISC;
2614 instruction->info.sub_opc = imm & 0x1F;
2615 instruction->info.imm = (imm >> 5) & 0x7FFF;
2616 snprintf(instruction->text,
2617 128,
2618 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBREAK\t#%d",
2619 address,
2620 opcode, instruction->info.imm);
2621 break;
2622 case 11: /* SYSCALL */
2623 instruction->type = NDS32_INSN_MISC;
2624 snprintf(instruction->text,
2625 128,
2626 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSYSCALL\t#%d",
2627 address,
2628 opcode, (imm >> 5) & 0x7FFF);
2629 break;
2630 case 12: /* MSYNC */
2631 instruction->type = NDS32_INSN_MISC;
2632 snprintf(instruction->text,
2633 128,
2634 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMSYNC\t#%d",
2635 address,
2636 opcode, (imm >> 5) & 0x7);
2637 break;
2638 case 13: /* ISYNC */
2639 nds32_parse_type_1(opcode, &(instruction->info.ra),
2640 &(instruction->info.imm));
2641 instruction->type = NDS32_INSN_MISC;
2642 snprintf(instruction->text,
2643 128,
2644 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tISYNC\t$r%d",
2645 address,
2646 opcode, instruction->info.ra);
2647 break;
2648 case 14: /* TLBOP */
2649 /* TODO */
2650 nds32_parse_type_2(opcode, &(instruction->info.rt),
2651 &(instruction->info.ra), &(instruction->info.imm));
2652 instruction->type = NDS32_INSN_RESOURCE_ACCESS;
2653 snprintf(instruction->text,
2654 128,
2655 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tTLBOP",
2656 address,
2657 opcode);
2658 break;
2659 }
2660
2661 break;
2662 }
2663 default:
2664 snprintf(instruction->text,
2665 128,
2666 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
2667 address,
2668 opcode);
2669 return ERROR_FAIL;
2670 }
2671
2672 return ERROR_OK;
2673 }
2674
2675 static uint32_t field_mask[9] = {
2676 0x0,
2677 0x1,
2678 0x3,
2679 0x7,
2680 0xF,
2681 0x1F,
2682 0x3F,
2683 0x7F,
2684 0xFF,
2685 };
2686
2687 static uint8_t nds32_extract_field_8u(uint16_t opcode, uint32_t start, uint32_t length)
2688 {
2689 if (0 < length && length < 9)
2690 return (opcode >> start) & field_mask[length];
2691
2692 return 0;
2693 }
2694
2695 static int nds32_parse_group_0_insn_16(struct nds32 *nds32, uint16_t opcode,
2696 uint32_t address, struct nds32_instruction *instruction)
2697 {
2698 switch ((opcode >> 10) & 0x7) {
2699 case 0: /* MOV55 */
2700 instruction->info.rt = nds32_extract_field_8u(opcode, 5, 5);
2701 instruction->info.ra = nds32_extract_field_8u(opcode, 0, 5);
2702 instruction->type = NDS32_INSN_MISC;
2703 snprintf(instruction->text,
2704 128,
2705 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tMOV55\t$r%d,$r%d",
2706 address,
2707 opcode, instruction->info.rt, instruction->info.ra);
2708 break;
2709 case 1: /* MOVI55 */
2710 instruction->info.rt = nds32_extract_field_8u(opcode, 5, 5);
2711 instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5);
2712 instruction->info.imm = (instruction->info.imm << 27) >> 27;
2713 instruction->type = NDS32_INSN_MISC;
2714 snprintf(instruction->text,
2715 128,
2716 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tMOVI55\t$r%d,#%d",
2717 address,
2718 opcode, instruction->info.rt, instruction->info.imm);
2719 break;
2720 case 2: /* ADD45, SUB45 */
2721 instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4);
2722 instruction->info.rb = nds32_extract_field_8u(opcode, 0, 5);
2723 instruction->type = NDS32_INSN_DATA_PROC;
2724 if (nds32_extract_field_8u(opcode, 9, 1) == 0) { /* ADD45 */
2725 snprintf(instruction->text,
2726 128,
2727 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tADD45\t$r%d,$r%d",
2728 address,
2729 opcode, instruction->info.rt, instruction->info.rb);
2730 } else { /* SUB45 */
2731 snprintf(instruction->text,
2732 128,
2733 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tSUB45\t$r%d,$r%d",
2734 address,
2735 opcode, instruction->info.rt, instruction->info.rb);
2736 }
2737
2738 break;
2739 case 3: /* ADDI45, SUBI45 */
2740 instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4);
2741 instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5);
2742 instruction->type = NDS32_INSN_DATA_PROC;
2743 if (nds32_extract_field_8u(opcode, 9, 1) == 0) { /* ADDI45 */
2744 snprintf(instruction->text,
2745 128,
2746 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tADDI45\t$r%d,#%d",
2747 address,
2748 opcode, instruction->info.rt, instruction->info.imm);
2749 } else { /* SUBI45 */
2750 snprintf(instruction->text,
2751 128,
2752 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tSUBI45\t$r%d,#%d",
2753 address,
2754 opcode, instruction->info.rt, instruction->info.imm);
2755 }
2756 break;
2757 case 4: /* SRAI45, SRLI45 */
2758 instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4);
2759 instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5);
2760 instruction->type = NDS32_INSN_DATA_PROC;
2761 if (nds32_extract_field_8u(opcode, 9, 1) == 0) { /* SRAI45 */
2762 snprintf(instruction->text,
2763 128,
2764 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tSRAI45\t$r%d,#%d",
2765 address,
2766 opcode, instruction->info.rt, instruction->info.imm);
2767 } else { /* SRLI45 */
2768 if ((instruction->info.rt == 0) && (instruction->info.imm == 0)) {
2769 snprintf(instruction->text,
2770 128,
2771 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tNOP",
2772 address,
2773 opcode);
2774 } else {
2775 snprintf(instruction->text,
2776 128,
2777 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tSRLI45\t$r%d,#%d",
2778 address,
2779 opcode, instruction->info.rt, instruction->info.imm);
2780 }
2781 }
2782 break;
2783 case 5:
2784 instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3);
2785 instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3);
2786 instruction->type = NDS32_INSN_DATA_PROC;
2787 if (nds32_extract_field_8u(opcode, 9, 1) == 0) { /* SLLI333 */
2788 instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3);
2789 snprintf(instruction->text,
2790 128,
2791 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tSLLI333\t$r%d,$r%d,#%d",
2792 address,
2793 opcode, instruction->info.rt, instruction->info.ra,
2794 instruction->info.imm);
2795 } else {
2796 instruction->info.sub_opc = nds32_extract_field_8u(opcode, 0, 3);
2797 switch (instruction->info.sub_opc) {
2798 case 0: /* ZEB33 */
2799 snprintf(instruction->text,
2800 128,
2801 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tZEB33\t$r%d,$r%d",
2802 address,
2803 opcode, instruction->info.rt, instruction->info.ra);
2804 break;
2805 case 1: /* ZEH33 */
2806 snprintf(instruction->text,
2807 128,
2808 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tZEH33\t$r%d,$r%d",
2809 address,
2810 opcode, instruction->info.rt, instruction->info.ra);
2811 break;
2812 case 2: /* SEB33 */
2813 snprintf(instruction->text,
2814 128,
2815 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tSEB33\t$r%d,$r%d",
2816 address,
2817 opcode, instruction->info.rt, instruction->info.ra);
2818 break;
2819 case 3: /* SEH33 */
2820 snprintf(instruction->text,
2821 128,
2822 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tSEH33\t$r%d,$r%d",
2823 address,
2824 opcode, instruction->info.rt, instruction->info.ra);
2825 break;
2826 case 4: /* XLSB33 */
2827 snprintf(instruction->text,
2828 128,
2829 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tXLSB33\t$r%d,$r%d",
2830 address,
2831 opcode, instruction->info.rt, instruction->info.ra);
2832 break;
2833 case 5: /* XLLB33 */
2834 snprintf(instruction->text,
2835 128,
2836 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tXLLB33\t$r%d,$r%d",
2837 address,
2838 opcode, instruction->info.rt, instruction->info.ra);
2839 break;
2840 case 6: /* BMSKI33 */
2841 instruction->info.ra = 0;
2842 instruction->info.imm = nds32_extract_field_8u(opcode, 3, 3);
2843 snprintf(instruction->text,
2844 128,
2845 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tBMSKI33\t$r%d,$r%d",
2846 address,
2847 opcode, instruction->info.rt, instruction->info.imm);
2848 break;
2849 case 7: /* FEXTI33 */
2850 instruction->info.ra = 0;
2851 instruction->info.imm = nds32_extract_field_8u(opcode, 3, 3);
2852 snprintf(instruction->text,
2853 128,
2854 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tFEXTI33\t$r%d,$r%d",
2855 address,
2856 opcode, instruction->info.rt, instruction->info.imm);
2857 break;
2858 default:
2859 snprintf(instruction->text,
2860 128,
2861 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
2862 "\tUNDEFINED INSTRUCTION",
2863 address,
2864 opcode);
2865 return ERROR_FAIL;
2866 }
2867 }
2868 break;
2869 case 6: /* ADD333, SUB333 */
2870 instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3);
2871 instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3);
2872 instruction->info.rb = nds32_extract_field_8u(opcode, 0, 3);
2873 instruction->type = NDS32_INSN_DATA_PROC;
2874 if (nds32_extract_field_8u(opcode, 9, 1) == 0) { /* ADD333 */
2875 snprintf(instruction->text,
2876 128,
2877 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tADD333\t$r%d,$r%d,$r%d",
2878 address,
2879 opcode, instruction->info.rt, instruction->info.ra,
2880 instruction->info.rb);
2881 } else { /* SUB333 */
2882 snprintf(instruction->text,
2883 128,
2884 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tSUB333\t$r%d,$r%d,$r%d",
2885 address,
2886 opcode, instruction->info.rt, instruction->info.ra,
2887 instruction->info.rb);
2888 }
2889 break;
2890 case 7: /* ADDI333, SUBI333 */
2891 instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3);
2892 instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3);
2893 instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3);
2894 instruction->type = NDS32_INSN_DATA_PROC;
2895 if (nds32_extract_field_8u(opcode, 9, 1) == 0) { /* ADDI333 */
2896 snprintf(instruction->text,
2897 128,
2898 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tADDI333\t$r%d,$r%d,#%d",
2899 address,
2900 opcode, instruction->info.rt, instruction->info.ra,
2901 instruction->info.imm);
2902 } else { /* SUBI333 */
2903 snprintf(instruction->text,
2904 128,
2905 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tSUBI333\t$r%d,$r%d,#%d",
2906 address,
2907 opcode, instruction->info.rt, instruction->info.ra,
2908 instruction->info.imm);
2909 }
2910 break;
2911 default:
2912 snprintf(instruction->text,
2913 128,
2914 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
2915 address,
2916 opcode);
2917 return ERROR_FAIL;
2918 }
2919
2920 return ERROR_OK;
2921 }
2922
2923 static int nds32_parse_group_1_insn_16(struct nds32 *nds32, uint16_t opcode,
2924 uint32_t address, struct nds32_instruction *instruction)
2925 {
2926 switch ((opcode >> 9) & 0xF) {
2927 case 0: /* LWI333 */
2928 instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3);
2929 instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3);
2930 instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3) << 2;
2931 instruction->type = NDS32_INSN_LOAD_STORE;
2932 nds32_get_mapped_reg(nds32, instruction->info.ra,
2933 &(instruction->access_start));
2934 instruction->access_start += instruction->info.imm;
2935 instruction->access_end = instruction->access_start + 4;
2936 snprintf(instruction->text,
2937 128,
2938 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tLWI333\t$r%d,[$r%d+(#%d)]",
2939 address,
2940 opcode, instruction->info.rt, instruction->info.ra,
2941 instruction->info.imm);
2942 break;
2943 case 1: /* LWI333.BI */
2944 instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3);
2945 instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3);
2946 instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3);
2947 instruction->type = NDS32_INSN_LOAD_STORE;
2948 nds32_get_mapped_reg(nds32, instruction->info.ra,
2949 &(instruction->access_start));
2950 instruction->access_end = instruction->access_start + 4;
2951 snprintf(instruction->text,
2952 128,
2953 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tLWI333.BI\t$r%d,[$r%d],#%d",
2954 address,
2955 opcode, instruction->info.rt, instruction->info.ra,
2956 instruction->info.imm << 2);
2957 break;
2958 case 2: /* LHI333 */
2959 instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3);
2960 instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3);
2961 instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3) << 1;
2962 instruction->type = NDS32_INSN_LOAD_STORE;
2963 nds32_get_mapped_reg(nds32, instruction->info.ra,
2964 &(instruction->access_start));
2965 instruction->access_start += instruction->info.imm;
2966 instruction->access_end = instruction->access_start + 2;
2967 snprintf(instruction->text,
2968 128,
2969 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tLHI333\t$r%d,[$r%d+(#%d)]",
2970 address,
2971 opcode, instruction->info.rt, instruction->info.ra,
2972 instruction->info.imm);
2973 break;
2974 case 3: /* LBI333 */
2975 instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3);
2976 instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3);
2977 instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3);
2978 instruction->type = NDS32_INSN_LOAD_STORE;
2979 nds32_get_mapped_reg(nds32, instruction->info.ra,
2980 &(instruction->access_start));
2981 instruction->access_start += instruction->info.imm;
2982 instruction->access_end = instruction->access_start + 1;
2983 snprintf(instruction->text,
2984 128,
2985 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tLBI333\t$r%d,[$r%d+(#%d)]",
2986 address,
2987 opcode, instruction->info.rt, instruction->info.ra,
2988 instruction->info.imm);
2989 break;
2990 case 4: /* SWI333 */
2991 instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3);
2992 instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3);
2993 instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3) << 2;
2994 instruction->type = NDS32_INSN_LOAD_STORE;
2995 nds32_get_mapped_reg(nds32, instruction->info.ra,
2996 &(instruction->access_start));
2997 instruction->access_start += instruction->info.imm;
2998 instruction->access_end = instruction->access_start + 4;
2999 snprintf(instruction->text,
3000 128,
3001 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tSWI333\t$r%d,[$r%d+(#%d)]",
3002 address,
3003 opcode, instruction->info.rt, instruction->info.ra,
3004 instruction->info.imm);
3005 break;
3006 case 5: /* SWI333.BI */
3007 instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3);
3008 instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3);
3009 instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3) << 2;
3010 instruction->type = NDS32_INSN_LOAD_STORE;
3011 nds32_get_mapped_reg(nds32, instruction->info.ra,
3012 &(instruction->access_start));
3013 instruction->access_end = instruction->access_start + 4;
3014 snprintf(instruction->text,
3015 128,
3016 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tSWI333.BI\t$r%d,[$r%d],#%d",
3017 address,
3018 opcode, instruction->info.rt, instruction->info.ra,
3019 instruction->info.imm);
3020 break;
3021 case 6: /* SHI333 */
3022 instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3);
3023 instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3);
3024 instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3) << 1;
3025 instruction->type = NDS32_INSN_LOAD_STORE;
3026 nds32_get_mapped_reg(nds32, instruction->info.ra,
3027 &(instruction->access_start));
3028 instruction->access_start += instruction->info.imm;
3029 instruction->access_end = instruction->access_start + 2;
3030 snprintf(instruction->text,
3031 128,
3032 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tSHI333\t$r%d,[$r%d+(#%d)]",
3033 address,
3034 opcode, instruction->info.rt, instruction->info.ra,
3035 instruction->info.imm);
3036 break;
3037 case 7: /* SBI333 */
3038 instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3);
3039 instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3);
3040 instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3);
3041 instruction->type = NDS32_INSN_LOAD_STORE;
3042 nds32_get_mapped_reg(nds32, instruction->info.ra,
3043 &(instruction->access_start));
3044 instruction->access_start += instruction->info.imm;
3045 instruction->access_end = instruction->access_start + 1;
3046 snprintf(instruction->text,
3047 128,
3048 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tSHI333\t$r%d,[$r%d+(#%d)]",
3049 address,
3050 opcode, instruction->info.rt, instruction->info.ra,
3051 instruction->info.imm);
3052 break;
3053 case 8: /* ADDRI36.SP */
3054 instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3);
3055 instruction->info.imm = nds32_extract_field_8u(opcode, 0, 6) << 2;
3056 instruction->type = NDS32_INSN_DATA_PROC;
3057 snprintf(instruction->text,
3058 128,
3059 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tADDRI36.SP\t$r%d,#%d",
3060 address,
3061 opcode, instruction->info.rt, instruction->info.imm);
3062 break;
3063 case 9: /* LWI45.FE */
3064 instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4);
3065 instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5);
3066 instruction->info.imm -= 32;
3067 instruction->info.imm <<= 2;
3068 instruction->type = NDS32_INSN_LOAD_STORE;
3069 nds32_get_mapped_reg(nds32, R8, &(instruction->access_start));
3070 instruction->access_start += instruction->info.imm;
3071 instruction->access_end = instruction->access_start + 4;
3072 snprintf(instruction->text,
3073 128,
3074 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tLWI45.FE\t$r%d,[#%d]",
3075 address,
3076 opcode, instruction->info.rt, instruction->info.imm);
3077 break;
3078 case 10: /* LWI450 */
3079 instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4);
3080 instruction->info.ra = nds32_extract_field_8u(opcode, 0, 5);
3081 instruction->type = NDS32_INSN_LOAD_STORE;
3082 nds32_get_mapped_reg(nds32, instruction->info.ra,
3083 &(instruction->access_start));
3084 instruction->access_end = instruction->access_start + 4;
3085 snprintf(instruction->text,
3086 128,
3087 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tLWI450\t$r%d,$r%d",
3088 address,
3089 opcode, instruction->info.rt, instruction->info.ra);
3090 break;
3091 case 11: /* SWI450 */
3092 instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4);
3093 instruction->info.ra = nds32_extract_field_8u(opcode, 0, 5);
3094 instruction->type = NDS32_INSN_LOAD_STORE;
3095 nds32_get_mapped_reg(nds32, instruction->info.ra,
3096 &(instruction->access_start));
3097 instruction->access_end = instruction->access_start + 4;
3098 snprintf(instruction->text,
3099 128,
3100 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tSWI450\t$r%d,$r%d",
3101 address,
3102 opcode, instruction->info.rt, instruction->info.ra);
3103 break;
3104 case 12:
3105 case 13:
3106 case 14:
3107 case 15: /* LWI37, SWI37 */
3108 instruction->info.rt = nds32_extract_field_8u(opcode, 8, 3);
3109 instruction->info.imm = nds32_extract_field_8u(opcode, 0, 7) << 2;
3110 instruction->type = NDS32_INSN_LOAD_STORE;
3111 nds32_get_mapped_reg(nds32, R28, &(instruction->access_start));
3112 instruction->access_start += instruction->info.imm;
3113 instruction->access_end = instruction->access_start + 4;
3114 if (nds32_extract_field_8u(opcode, 7, 1) == 0) { /* LWI37 */
3115 snprintf(instruction->text,
3116 128,
3117 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tLWI37\t$r%d,[fp+#%d]",
3118 address,
3119 opcode, instruction->info.rt, instruction->info.imm);
3120 } else { /* SWI37 */
3121 snprintf(instruction->text,
3122 128,
3123 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tSWI37\t$r%d,[fp+#%d]",
3124 address,
3125 opcode, instruction->info.rt, instruction->info.imm);
3126 }
3127 break;
3128 default: /* ERROR */
3129 snprintf(instruction->text,
3130 128,
3131 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
3132 address,
3133 opcode);
3134 return ERROR_FAIL;
3135 }
3136
3137 return ERROR_OK;
3138 }
3139
3140 static int nds32_parse_group_2_insn_16(struct nds32 *nds32, uint16_t opcode,
3141 uint32_t address, struct nds32_instruction *instruction)
3142 {
3143 switch ((opcode >> 11) & 0x3) {
3144 case 0: /* BEQZ38 */
3145 instruction->info.rt = nds32_extract_field_8u(opcode, 8, 3);
3146 instruction->info.imm = nds32_extract_field_8u(opcode, 0, 8);
3147 instruction->info.imm = (instruction->info.imm << 24) >> 24;
3148 instruction->type = NDS32_INSN_JUMP_BRANCH;
3149 snprintf(instruction->text,
3150 128,
3151 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tBEQZ38\t$r%d,#%d",
3152 address,
3153 opcode, instruction->info.rt, instruction->info.imm);
3154 break;
3155 case 1: /* BNEZ38 */
3156 instruction->info.rt = nds32_extract_field_8u(opcode, 8, 3);
3157 instruction->info.imm = nds32_extract_field_8u(opcode, 0, 8);
3158 instruction->info.imm = (instruction->info.imm << 24) >> 24;
3159 instruction->type = NDS32_INSN_JUMP_BRANCH;
3160 snprintf(instruction->text,
3161 128,
3162 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tBNEZ38\t$r%d,#%d",
3163 address,
3164 opcode, instruction->info.rt, instruction->info.imm);
3165 break;
3166 case 2: /* BEQS38,J8 */
3167 instruction->info.rt = nds32_extract_field_8u(opcode, 8, 3);
3168 instruction->info.imm = nds32_extract_field_8u(opcode, 0, 8);
3169 instruction->info.imm = (instruction->info.imm << 24) >> 24;
3170 instruction->type = NDS32_INSN_JUMP_BRANCH;
3171 if (instruction->info.rt == 5) { /* J8 */
3172 snprintf(instruction->text,
3173 128,
3174 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tJ8\t#%d",
3175 address,
3176 opcode, instruction->info.imm);
3177 } else { /* BEQS38 */
3178 snprintf(instruction->text,
3179 128,
3180 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tBEQS38\t$r%d,#%d",
3181 address,
3182 opcode, instruction->info.rt, instruction->info.imm);
3183 }
3184 break;
3185 case 3: /* BNES38, JR5, RET5, JRAL5 */
3186 instruction->info.rt = nds32_extract_field_8u(opcode, 8, 3);
3187 instruction->info.imm = nds32_extract_field_8u(opcode, 0, 8);
3188 instruction->info.imm = (instruction->info.imm << 24) >> 24;
3189 instruction->type = NDS32_INSN_JUMP_BRANCH;
3190 if (instruction->info.rt == 5) {
3191 instruction->info.imm = 0;
3192 instruction->info.rb = nds32_extract_field_8u(opcode, 0, 5);
3193 switch (nds32_extract_field_8u(opcode, 5, 3)) {
3194 case 0: /* JR5 */
3195 snprintf(instruction->text,
3196 128,
3197 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tJR5\t$r%d",
3198 address,
3199 opcode, instruction->info.rb);
3200 break;
3201 case 1: /* JRAL5 */
3202 snprintf(instruction->text,
3203 128,
3204 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tJRAL5\t$r%d",
3205 address,
3206 opcode, instruction->info.rb);
3207 break;
3208 case 2: /* EX9.IT */
3209 instruction->info.rb = 0;
3210 instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5);
3211 /* TODO: implement real instruction semantics */
3212 snprintf(instruction->text,
3213 128,
3214 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tEX9.IT\t#%d",
3215 address,
3216 opcode, instruction->info.imm);
3217 break;
3218 case 4: /* RET5 */
3219 snprintf(instruction->text,
3220 128,
3221 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tRET5\t$r%d",
3222 address,
3223 opcode, instruction->info.rb);
3224 break;
3225 case 5: /* ADD5.PC */
3226 instruction->info.rt = 0;
3227 instruction->info.rt = nds32_extract_field_8u(opcode, 0, 5);
3228 instruction->type = NDS32_INSN_DATA_PROC;
3229 snprintf(instruction->text,
3230 128,
3231 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tADD5.PC\t$r%d",
3232 address,
3233 opcode, instruction->info.rt);
3234 break;
3235 default:
3236 snprintf(instruction->text,
3237 128,
3238 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
3239 "\tUNDEFINED INSTRUCTION",
3240 address,
3241 opcode);
3242 return ERROR_FAIL;
3243 }
3244 } else { /* BNES38 */
3245 snprintf(instruction->text,
3246 128,
3247 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tBNES38\t$r%d,#%d",
3248 address,
3249 opcode, instruction->info.rt, instruction->info.imm);
3250 }
3251 break;
3252 }
3253
3254 return ERROR_OK;
3255 }
3256
3257 static int nds32_parse_group_3_insn_16(struct nds32 *nds32, uint16_t opcode,
3258 uint32_t address, struct nds32_instruction *instruction)
3259 {
3260 switch ((opcode >> 11) & 0x3) {
3261 case 0:
3262 switch ((opcode >> 9) & 0x3) {
3263 case 0: /* SLTS45 */
3264 instruction->info.ra = nds32_extract_field_8u(opcode, 5, 4);
3265 instruction->info.rb = nds32_extract_field_8u(opcode, 0, 5);
3266 instruction->type = NDS32_INSN_DATA_PROC;
3267 snprintf(instruction->text,
3268 128,
3269 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tSLTS45\t$r%d,$r%d",
3270 address,
3271 opcode, instruction->info.ra, instruction->info.rb);
3272 break;
3273 case 1: /* SLT45 */
3274 instruction->info.ra = nds32_extract_field_8u(opcode, 5, 4);
3275 instruction->info.rb = nds32_extract_field_8u(opcode, 0, 5);
3276 instruction->type = NDS32_INSN_DATA_PROC;
3277 snprintf(instruction->text,
3278 128,
3279 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tSLT45\t$r%d,$r%d",
3280 address,
3281 opcode, instruction->info.ra, instruction->info.rb);
3282 break;
3283 case 2: /* SLTSI45 */
3284 instruction->info.ra = nds32_extract_field_8u(opcode, 5, 4);
3285 instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5);
3286 instruction->type = NDS32_INSN_DATA_PROC;
3287 snprintf(instruction->text,
3288 128,
3289 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tSLTSI45\t$r%d,#%d",
3290 address,
3291 opcode, instruction->info.ra, instruction->info.imm);
3292 break;
3293 case 3: /* SLTI45 */
3294 instruction->info.ra = nds32_extract_field_8u(opcode, 5, 4);
3295 instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5);
3296 instruction->type = NDS32_INSN_DATA_PROC;
3297 snprintf(instruction->text,
3298 128,
3299 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tSLTI45\t$r%d,#%d",
3300 address,
3301 opcode, instruction->info.ra, instruction->info.imm);
3302 break;
3303 }
3304 break;
3305 case 1:
3306 switch ((opcode >> 9) & 0x3) {
3307 case 0:
3308 instruction->info.imm = nds32_extract_field_8u(opcode, 0, 8);
3309 instruction->info.imm = (instruction->info.imm << 24) >> 24;
3310 instruction->type = NDS32_INSN_JUMP_BRANCH;
3311 if (nds32_extract_field_8u(opcode, 8, 1) == 0) { /* BEQZS8 */
3312 snprintf(instruction->text,
3313 128,
3314 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tBEQZS8\t#%d",
3315 address,
3316 opcode, instruction->info.imm);
3317 } else { /* BNEZS8 */
3318 snprintf(instruction->text,
3319 128,
3320 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tBNEZS8\t#%d",
3321 address,
3322 opcode, instruction->info.imm);
3323 }
3324 break;
3325 case 1: /* BREAK16 */
3326 if (((opcode >> 5) & 0xF) == 0) {
3327 instruction->type = NDS32_INSN_MISC;
3328 snprintf(instruction->text,
3329 128,
3330 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tBREAK16\t#%d",
3331 address,
3332 opcode, opcode & 0x1F);
3333 } else { /* EX9.IT */
3334 instruction->type = NDS32_INSN_MISC;
3335 /* TODO: implement real instruction semantics */
3336 snprintf(instruction->text,
3337 128,
3338 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tEX9.IT\t#%d",
3339 address,
3340 opcode, opcode & 0x1FF);
3341 }
3342 break;
3343 case 2: /* ADDI10S */
3344 case 3:
3345 instruction->info.imm = opcode & 0x3FF;
3346 instruction->info.imm = (instruction->info.imm << 22) >> 22;
3347 instruction->type = NDS32_INSN_DATA_PROC;
3348 snprintf(instruction->text,
3349 128,
3350 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tADDI10.SP\t#%d",
3351 address,
3352 opcode, instruction->info.imm);
3353 break;
3354 }
3355 break;
3356 case 2:
3357 instruction->info.rt = nds32_extract_field_8u(opcode, 8, 3);
3358 instruction->info.imm = nds32_extract_field_8u(opcode, 0, 7) << 2;
3359 instruction->type = NDS32_INSN_LOAD_STORE;
3360 nds32_get_mapped_reg(nds32, R31, &(instruction->access_start));
3361 instruction->access_start += instruction->info.imm;
3362 instruction->access_end = instruction->access_start + 4;
3363 if (nds32_extract_field_8u(opcode, 7, 1) == 0) { /* LWI37.SP */
3364 snprintf(instruction->text,
3365 128,
3366 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tLWI37.SP\t$r%d,[+#%d]",
3367 address,
3368 opcode, instruction->info.rt, instruction->info.imm);
3369 } else { /* SWI37.SP */
3370 snprintf(instruction->text,
3371 128,
3372 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tSWI37.SP\t$r%d,[+#%d]",
3373 address,
3374 opcode, instruction->info.rt, instruction->info.imm);
3375 }
3376 break;
3377 case 3:
3378 switch ((opcode >> 9) & 0x3) {
3379 case 0: /* IFCALL9 */
3380 instruction->info.imm = opcode & 0x1FF;
3381 instruction->type = NDS32_INSN_JUMP_BRANCH;
3382 snprintf(instruction->text,
3383 128,
3384 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tIFCALL9\t#%d",
3385 address,
3386 opcode, instruction->info.imm);
3387 break;
3388 case 1: /* MOVPI45 */
3389 instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5) + 16;
3390 instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4);
3391 instruction->type = NDS32_INSN_MISC;
3392 snprintf(instruction->text,
3393 128,
3394 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32 "\t\tMOVPI45\t$r%d,#%d",
3395 address,
3396 opcode, instruction->info.rt, instruction->info.imm);
3397 break;
3398 case 2: /* PUSH25, POP25, MOVD44 */
3399 switch ((opcode >> 7) & 0x3) {
3400 case 0: /* PUSH25 */
3401 {
3402 uint8_t re;
3403 uint8_t gpr_count;
3404
3405 instruction->type = NDS32_INSN_LOAD_STORE;
3406 instruction->info.imm =
3407 nds32_extract_field_8u(opcode, 0, 5) << 3;
3408 re = nds32_extract_field_8u(opcode, 5, 2);
3409
3410 if (re == 0)
3411 re = 6;
3412 else if (re == 1)
3413 re = 8;
3414 else if (re == 2)
3415 re = 10;
3416 else if (re == 3)
3417 re = 14;
3418
3419 instruction->info.rd = re;
3420 /* GPRs list: R6 ~ Re and fp, gp, lp */
3421 gpr_count = 3 + (re - 5);
3422
3423 nds32_get_mapped_reg(nds32, R31,
3424 &(instruction->access_end));
3425 instruction->access_start =
3426 instruction->access_end - (gpr_count * 4);
3427
3428 snprintf(instruction->text,
3429 128,
3430 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32
3431 "\t\tPUSH25\t$r%d,#%d",
3432 address,
3433 opcode, instruction->info.rd,
3434 instruction->info.imm);
3435 }
3436 break;
3437 case 1: /* POP25 */
3438 {
3439 uint8_t re;
3440 uint8_t gpr_count;
3441
3442 instruction->type = NDS32_INSN_LOAD_STORE;
3443 instruction->info.imm =
3444 nds32_extract_field_8u(opcode, 0, 5) << 3;
3445 re = nds32_extract_field_8u(opcode, 5, 2);
3446
3447 if (re == 0)
3448 re = 6;
3449 else if (re == 1)
3450 re = 8;
3451 else if (re == 2)
3452 re = 10;
3453 else if (re == 3)
3454 re = 14;
3455
3456 instruction->info.rd = re;
3457 /* GPRs list: R6 ~ Re and fp, gp, lp */
3458 gpr_count = 3 + (re - 5);
3459
3460 nds32_get_mapped_reg(nds32, R31,
3461 &(instruction->access_start));
3462 instruction->access_start += instruction->info.imm;
3463 instruction->access_end =
3464 instruction->access_start + (gpr_count * 4);
3465
3466 snprintf(instruction->text,
3467 128,
3468 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32
3469 "\t\tPOP25\t$r%d,#%d",
3470 address,
3471 opcode, instruction->info.rd,
3472 instruction->info.imm);
3473 }
3474 break;
3475 case 2: /* MOVD44 */
3476 case 3:
3477 instruction->info.ra =
3478 nds32_extract_field_8u(opcode, 0, 4) * 2;
3479 instruction->info.rt =
3480 nds32_extract_field_8u(opcode, 4, 4) * 2;
3481 instruction->type = NDS32_INSN_MISC;
3482 snprintf(instruction->text,
3483 128,
3484 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32
3485 "\t\tMOVD44\t$r%d,$r%d",
3486 address,
3487 opcode, instruction->info.rt, instruction->info.ra);
3488 break;
3489 }
3490 break;
3491 case 3: /* NEG33, NOT33, MUL33, XOR33, AND33, OR33 */
3492 instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3);
3493 instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3);
3494 instruction->type = NDS32_INSN_DATA_PROC;
3495 switch (opcode & 0x7) {
3496 case 2: /* NEG33 */
3497 snprintf(instruction->text,
3498 128,
3499 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32
3500 "\t\tNEG33\t$r%d,$r%d",
3501 address,
3502 opcode, instruction->info.rt, instruction->info.ra);
3503 break;
3504 case 3: /* NOT33 */
3505 snprintf(instruction->text,
3506 128,
3507 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32
3508 "\t\tNOT33\t$r%d,$r%d",
3509 address,
3510 opcode, instruction->info.rt, instruction->info.ra);
3511 break;
3512 case 4: /* MUL33 */
3513 snprintf(instruction->text,
3514 128,
3515 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32
3516 "\t\tMUL33\t$r%d,$r%d",
3517 address,
3518 opcode, instruction->info.rt, instruction->info.ra);
3519 break;
3520 case 5: /* XOR33 */
3521 snprintf(instruction->text,
3522 128,
3523 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32
3524 "\t\tXOR33\t$r%d,$r%d",
3525 address,
3526 opcode, instruction->info.rt, instruction->info.ra);
3527 break;
3528 case 6: /* AND33 */
3529 snprintf(instruction->text,
3530 128,
3531 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32
3532 "\t\tAND33\t$r%d,$r%d",
3533 address,
3534 opcode, instruction->info.rt, instruction->info.ra);
3535 break;
3536 case 7: /* OR33 */
3537 snprintf(instruction->text,
3538 128,
3539 "0x%8.8" PRIx32 "\t0x%4.4" PRIx32
3540 "\t\tOR33\t$r%d,$r%d",
3541 address,
3542 opcode, instruction->info.rt, instruction->info.ra);
3543 break;
3544 }
3545 break;
3546 }
3547 break;
3548 default:
3549 snprintf(instruction->text,
3550 128,
3551 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
3552 address,
3553 opcode);
3554 return ERROR_FAIL;
3555 }
3556
3557 return ERROR_OK;
3558 }
3559
3560 int nds32_evaluate_opcode(struct nds32 *nds32, uint32_t opcode, uint32_t address,
3561 struct nds32_instruction *instruction)
3562 {
3563 int retval = ERROR_OK;
3564
3565 /* clear fields, to avoid confusion */
3566 memset(instruction, 0, sizeof(struct nds32_instruction));
3567
3568 if (opcode >> 31) {
3569 /* 16 bits instruction */
3570 instruction->instruction_size = 2;
3571 opcode = (opcode >> 16) & 0xFFFF;
3572 instruction->opcode = opcode;
3573
3574 switch ((opcode >> 13) & 0x3) {
3575 case 0:
3576 retval = nds32_parse_group_0_insn_16(nds32, opcode, address, instruction);
3577 break;
3578 case 1:
3579 retval = nds32_parse_group_1_insn_16(nds32, opcode, address, instruction);
3580 break;
3581 case 2:
3582 retval = nds32_parse_group_2_insn_16(nds32, opcode, address, instruction);
3583 break;
3584 case 3:
3585 retval = nds32_parse_group_3_insn_16(nds32, opcode, address, instruction);
3586 break;
3587 default:
3588 snprintf(instruction->text,
3589 128,
3590 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
3591 address,
3592 opcode);
3593 return ERROR_FAIL;
3594 }
3595 } else {
3596 /* 32 bits instruction */
3597 instruction->instruction_size = 4;
3598 instruction->opcode = opcode;
3599
3600 uint8_t opc_6;
3601 opc_6 = opcode >> 25;
3602 instruction->info.opc_6 = opc_6;
3603
3604 switch ((opc_6 >> 3) & 0x7) {
3605 case 0: /* LBI, LHI, LWI, LBI.bi, LHI.bi, LWI.bi */
3606 retval = nds32_parse_group_0_insn(nds32, opcode, address, instruction);
3607 break;
3608 case 1: /* SBI, SHI, SWI, SBI.bi, SHI.bi, SWI.bi */
3609 retval = nds32_parse_group_1_insn(nds32, opcode, address, instruction);
3610 break;
3611 case 2: /* LBSI, LHSI, DPREFI, LBSI.bi, LHSI.bi, LBGP */
3612 retval = nds32_parse_group_2_insn(nds32, opcode, address, instruction);
3613 break;
3614 case 3: /* MEM, LSMW, HWGP, SBGP */
3615 retval = nds32_parse_group_3_insn(nds32, opcode, address, instruction);
3616 break;
3617 case 4: /* ALU_1, ALU_2, MOVI, SETHI, JI, JREG, BR1, BR2 */
3618 retval = nds32_parse_group_4_insn(nds32, opcode, address, instruction);
3619 break;
3620 case 5: /* ADDI, SUBRI, ANDI, XORI, ORI, SLTI, SLTSI */
3621 retval = nds32_parse_group_5_insn(nds32, opcode, address, instruction);
3622 break;
3623 case 6: /* MISC */
3624 retval = nds32_parse_group_6_insn(nds32, opcode, address, instruction);
3625 break;
3626 default: /* ERROR */
3627 snprintf(instruction->text,
3628 128,
3629 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
3630 address,
3631 opcode);
3632 return ERROR_FAIL;
3633 }
3634 }
3635
3636 return retval;
3637 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)