target: fix mem2array/array2mem
[openocd.git] / src / target / nds32_disassembler.c
blobd859e0c6aadf30108afed3d33d253b3dc4ec85ad
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 ***************************************************************************/
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
25 #include <helper/log.h>
26 #include <target/target.h>
27 #include "nds32_disassembler.h"
29 static const int enable4_bits[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
31 int nds32_read_opcode(struct nds32 *nds32, uint32_t address, uint32_t *value)
33 struct target *target = nds32->target;
34 uint8_t value_buf[4];
36 if (!target_was_examined(target)) {
37 LOG_ERROR("Target not examined yet");
38 return ERROR_FAIL;
41 int retval = target_read_buffer(target, address, 4, value_buf);
43 if (retval == ERROR_OK) {
44 /* instructions are always big-endian */
45 *value = be_to_h_u32(value_buf);
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);
56 return retval;
59 static int nds32_parse_type_0(uint32_t opcode, int32_t *imm)
61 *imm = opcode & 0x1FFFFFF;
63 return ERROR_OK;
66 static int nds32_parse_type_1(uint32_t opcode, uint8_t *rt, int32_t *imm)
68 *rt = (opcode >> 20) & 0x1F;
69 *imm = opcode & 0xFFFFF;
71 return ERROR_OK;
74 static int nds32_parse_type_2(uint32_t opcode, uint8_t *rt, uint8_t *ra, int32_t *imm)
76 *rt = (opcode >> 20) & 0x1F;
77 *ra = (opcode >> 15) & 0x1F;
78 *imm = opcode & 0x7FFF;
80 return ERROR_OK;
83 static int nds32_parse_type_3(uint32_t opcode, uint8_t *rt, uint8_t *ra,
84 uint8_t *rb, int32_t *imm)
86 *rt = (opcode >> 20) & 0x1F;
87 *ra = (opcode >> 15) & 0x1F;
88 *rb = (opcode >> 10) & 0x1F;
89 *imm = opcode & 0x3FF;
91 return ERROR_OK;
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)
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;
103 return ERROR_OK;
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)
111 uint8_t opc_6;
113 opc_6 = instruction->info.opc_6;
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;
218 return ERROR_OK;
221 static int nds32_parse_group_1_insn(struct nds32 *nds32, uint32_t opcode,
222 uint32_t address, struct nds32_instruction *instruction)
224 uint8_t opc_6;
226 opc_6 = instruction->info.opc_6;
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;
331 return ERROR_OK;
334 static int nds32_parse_group_2_insn(struct nds32 *nds32, uint32_t opcode,
335 uint32_t address, struct nds32_instruction *instruction)
337 uint8_t opc_6;
339 opc_6 = instruction->info.opc_6;
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);
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);
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;
465 return ERROR_OK;
468 static int nds32_parse_mem(struct nds32 *nds32, uint32_t opcode, uint32_t address,
469 struct nds32_instruction *instruction)
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;
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;
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;
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;
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;
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;
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;
900 return ERROR_OK;
903 static int nds32_calculate_lsmw_access_range(struct nds32 *nds32,
904 struct nds32_instruction *instruction)
906 uint8_t ba;
907 uint8_t id;
908 uint8_t enable4;
910 enable4 = (instruction->info.imm >> 6) & 0xF;
911 ba = (instruction->info.imm >> 4) & 0x1;
912 id = (instruction->info.imm >> 3) & 0x1;
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;
923 } else {
924 nds32_get_mapped_reg(nds32, instruction->info.ra, &(instruction->access_start));
925 instruction->access_end = instruction->access_start - 4;
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]);
938 return ERROR_OK;
941 static int nds32_parse_lsmw(struct nds32 *nds32, uint32_t opcode, uint32_t address,
942 struct nds32_instruction *instruction)
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;
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;
1052 return ERROR_OK;
1055 static int nds32_parse_hwgp(struct nds32 *nds32, uint32_t opcode, uint32_t address,
1056 struct nds32_instruction *instruction)
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);
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;
1138 return ERROR_OK;
1141 static int nds32_parse_sbgp(struct nds32 *nds32, uint32_t opcode, uint32_t address,
1142 struct nds32_instruction *instruction)
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;
1177 return ERROR_OK;
1180 static int nds32_parse_group_3_insn(struct nds32 *nds32, uint32_t opcode, uint32_t address,
1181 struct nds32_instruction *instruction)
1183 uint8_t opc_6;
1185 opc_6 = instruction->info.opc_6;
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;
1209 return ERROR_OK;
1212 static int nds32_parse_alu_1(uint32_t opcode, uint32_t address,
1213 struct nds32_instruction *instruction)
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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;
1738 return ERROR_OK;
1741 static int nds32_parse_alu_2(uint32_t opcode, uint32_t address,
1742 struct nds32_instruction *instruction)
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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;
2152 return ERROR_OK;
2155 static int nds32_parse_group_4_insn(struct nds32 *nds32, uint32_t opcode,
2156 uint32_t address, struct nds32_instruction *instruction)
2158 uint8_t opc_6;
2160 opc_6 = instruction->info.opc_6;
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);
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);
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;
2267 break;
2268 case 6: { /* BR1 */
2269 int32_t imm;
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);
2298 break;
2299 case 7: { /* BR2 */
2300 int32_t imm;
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;
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;
2397 return ERROR_OK;
2400 static int nds32_parse_group_5_insn(struct nds32 *nds32, uint32_t opcode,
2401 uint32_t address, struct nds32_instruction *instruction)
2403 uint8_t opc_6;
2405 opc_6 = instruction->info.opc_6;
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;
2498 return ERROR_OK;
2501 static int nds32_parse_group_6_insn(struct nds32 *nds32, uint32_t opcode,
2502 uint32_t address, struct nds32_instruction *instruction)
2504 uint8_t opc_6;
2506 opc_6 = instruction->info.opc_6;
2508 switch (opc_6 & 0x7) {
2509 case 2: { /* MISC */
2510 int32_t imm;
2511 uint8_t sub_opc;
2513 nds32_parse_type_0(opcode, &imm);
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;
2661 break;
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;
2672 return ERROR_OK;
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,
2687 static uint8_t nds32_extract_field_8u(uint16_t opcode, uint32_t start, uint32_t length)
2689 if (0 < length && length < 9)
2690 return (opcode >> start) & field_mask[length];
2692 return 0;
2695 static int nds32_parse_group_0_insn_16(struct nds32 *nds32, uint16_t opcode,
2696 uint32_t address, struct nds32_instruction *instruction)
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);
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);
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);
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;
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);
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);
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;
2920 return ERROR_OK;
2923 static int nds32_parse_group_1_insn_16(struct nds32 *nds32, uint16_t opcode,
2924 uint32_t address, struct nds32_instruction *instruction)
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);
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;
3137 return ERROR_OK;
3140 static int nds32_parse_group_2_insn_16(struct nds32 *nds32, uint16_t opcode,
3141 uint32_t address, struct nds32_instruction *instruction)
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);
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;
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);
3251 break;
3254 return ERROR_OK;
3257 static int nds32_parse_group_3_insn_16(struct nds32 *nds32, uint16_t opcode,
3258 uint32_t address, struct nds32_instruction *instruction)
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;
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);
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);
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;
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);
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 */
3402 uint8_t re;
3403 uint8_t gpr_count;
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);
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;
3419 instruction->info.rd = re;
3420 /* GPRs list: R6 ~ Re and fp, gp, lp */
3421 gpr_count = 3 + (re - 5);
3423 nds32_get_mapped_reg(nds32, R31,
3424 &(instruction->access_end));
3425 instruction->access_start =
3426 instruction->access_end - (gpr_count * 4);
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);
3436 break;
3437 case 1: /* POP25 */
3439 uint8_t re;
3440 uint8_t gpr_count;
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);
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;
3456 instruction->info.rd = re;
3457 /* GPRs list: R6 ~ Re and fp, gp, lp */
3458 gpr_count = 3 + (re - 5);
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);
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);
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;
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;
3545 break;
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;
3557 return ERROR_OK;
3560 int nds32_evaluate_opcode(struct nds32 *nds32, uint32_t opcode, uint32_t address,
3561 struct nds32_instruction *instruction)
3563 int retval = ERROR_OK;
3565 /* clear fields, to avoid confusion */
3566 memset(instruction, 0, sizeof(struct nds32_instruction));
3568 if (opcode >> 31) {
3569 /* 16 bits instruction */
3570 instruction->instruction_size = 2;
3571 opcode = (opcode >> 16) & 0xFFFF;
3572 instruction->opcode = opcode;
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;
3595 } else {
3596 /* 32 bits instruction */
3597 instruction->instruction_size = 4;
3598 instruction->opcode = opcode;
3600 uint8_t opc_6;
3601 opc_6 = opcode >> 25;
3602 instruction->info.opc_6 = opc_6;
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;
3636 return retval;