or1k.opc revision 1.2 1 1.1 matt /* OpenRISC 1000 opcode support. -*- C -*-
2 1.1 matt Copyright 2000-2014 Free Software Foundation, Inc.
3 1.1 matt
4 1.1 matt Originally ontributed for OR32 by Red Hat Inc;
5 1.1 matt
6 1.1 matt This file is part of the GNU Binutils.
7 1.1 matt
8 1.1 matt This program is free software; you can redistribute it and/or modify
9 1.1 matt it under the terms of the GNU General Public License as published by
10 1.1 matt the Free Software Foundation; either version 3 of the License, or
11 1.1 matt (at your option) any later version.
12 1.1 matt
13 1.1 matt This program is distributed in the hope that it will be useful,
14 1.1 matt but WITHOUT ANY WARRANTY; without even the implied warranty of
15 1.1 matt MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 1.1 matt GNU General Public License for more details.
17 1.1 matt
18 1.1 matt You should have received a copy of the GNU General Public License
19 1.1 matt along with this program; if not, see <http://www.gnu.org/licenses/>. */
20 1.1 matt
21 1.1 matt /* This file is an addendum to or1k.cpu. Heavy use of C code isn't
22 1.1 matt appropriate in .cpu files, so it resides here. This especially applies
23 1.1 matt to assembly/disassembly where parsing/printing can be quite involved.
24 1.1 matt Such things aren't really part of the specification of the cpu, per se,
25 1.1 matt so .cpu files provide the general framework and .opc files handle the
26 1.1 matt nitty-gritty details as necessary.
27 1.1 matt
28 1.1 matt Each section is delimited with start and end markers.
29 1.1 matt
30 1.1 matt <arch>-opc.h additions use: "-- opc.h"
31 1.1 matt <arch>-opc.c additions use: "-- opc.c"
32 1.1 matt <arch>-asm.c additions use: "-- asm.c"
33 1.1 matt <arch>-dis.c additions use: "-- dis.c"
34 1.1 matt <arch>-ibd.h additions use: "-- ibd.h" */
35 1.1 matt
36 1.1 matt /* -- opc.h */
37 1.1 matt
38 1.1 matt #undef CGEN_DIS_HASH_SIZE
39 1.1 matt #define CGEN_DIS_HASH_SIZE 256
40 1.1 matt #undef CGEN_DIS_HASH
41 1.1 matt #define CGEN_DIS_HASH(buffer, value) (((unsigned char *) (buffer))[0] >> 2)
42 1.1 matt
43 1.2 christos /* Check applicability of instructions against machines. */
44 1.2 christos #define CGEN_VALIDATE_INSN_SUPPORTED
45 1.2 christos
46 1.2 christos extern int or1k_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *);
47 1.2 christos
48 1.1 matt /* -- */
49 1.1 matt
50 1.1 matt /* -- opc.c */
51 1.2 christos
52 1.2 christos /* Special check to ensure that instruction exists for given machine. */
53 1.2 christos
54 1.2 christos int
55 1.2 christos or1k_cgen_insn_supported (CGEN_CPU_DESC cd, const CGEN_INSN *insn)
56 1.2 christos {
57 1.2 christos int machs = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH);
58 1.2 christos
59 1.2 christos /* No mach attribute? Assume it's supported for all machs. */
60 1.2 christos if (machs == 0)
61 1.2 christos return 1;
62 1.2 christos
63 1.2 christos return ((machs & cd->machs) != 0);
64 1.2 christos }
65 1.2 christos
66 1.1 matt /* -- */
67 1.1 matt
68 1.1 matt /* -- asm.c */
69 1.1 matt
70 1.1 matt static const char * MISSING_CLOSING_PARENTHESIS = N_("missing `)'");
71 1.2 christos static const char * INVALID_STORE_RELOC = N_("relocation invalid for store");
72 1.2 christos static const char * INVALID_RELOC_TYPE = N_("internal relocation type invalid");
73 1.1 matt
74 1.1 matt #define CGEN_VERBOSE_ASSEMBLER_ERRORS
75 1.1 matt
76 1.1 matt static const char *
77 1.1 matt parse_disp26 (CGEN_CPU_DESC cd,
78 1.1 matt const char ** strp,
79 1.1 matt int opindex,
80 1.2 christos int opinfo ATTRIBUTE_UNUSED,
81 1.1 matt enum cgen_parse_operand_result * resultp,
82 1.1 matt bfd_vma * valuep)
83 1.1 matt {
84 1.2 christos const char *str = *strp;
85 1.1 matt const char *errmsg = NULL;
86 1.2 christos bfd_reloc_code_real_type reloc = BFD_RELOC_OR1K_REL_26;
87 1.1 matt
88 1.2 christos if (strncasecmp (str, "plta(", 5) == 0)
89 1.2 christos {
90 1.2 christos *strp = str + 5;
91 1.2 christos reloc = BFD_RELOC_OR1K_PLTA26;
92 1.2 christos }
93 1.2 christos else if (strncasecmp (str, "plt(", 4) == 0)
94 1.1 matt {
95 1.2 christos *strp = str + 4;
96 1.2 christos reloc = BFD_RELOC_OR1K_PLT26;
97 1.1 matt }
98 1.1 matt
99 1.2 christos errmsg = cgen_parse_address (cd, strp, opindex, reloc, resultp, valuep);
100 1.1 matt
101 1.2 christos if (reloc != BFD_RELOC_OR1K_REL_26)
102 1.1 matt {
103 1.1 matt if (**strp != ')')
104 1.1 matt errmsg = MISSING_CLOSING_PARENTHESIS;
105 1.2 christos else
106 1.2 christos ++*strp;
107 1.1 matt }
108 1.1 matt
109 1.2 christos return errmsg;
110 1.2 christos }
111 1.1 matt
112 1.2 christos static const char *
113 1.2 christos parse_disp21 (CGEN_CPU_DESC cd,
114 1.2 christos const char ** strp,
115 1.2 christos int opindex,
116 1.2 christos int opinfo ATTRIBUTE_UNUSED,
117 1.2 christos enum cgen_parse_operand_result * resultp,
118 1.2 christos bfd_vma * valuep)
119 1.2 christos {
120 1.2 christos const char *str = *strp;
121 1.2 christos const char *errmsg = NULL;
122 1.2 christos bfd_reloc_code_real_type reloc = BFD_RELOC_OR1K_PCREL_PG21;
123 1.1 matt
124 1.2 christos if (strncasecmp (str, "got(", 4) == 0)
125 1.2 christos {
126 1.2 christos *strp = str + 4;
127 1.2 christos reloc = BFD_RELOC_OR1K_GOT_PG21;
128 1.1 matt }
129 1.2 christos else if (strncasecmp (str, "tlsgd(", 6) == 0)
130 1.1 matt {
131 1.2 christos *strp = str + 6;
132 1.2 christos reloc = BFD_RELOC_OR1K_TLS_GD_PG21;
133 1.1 matt }
134 1.2 christos else if (strncasecmp (str, "tlsldm(", 7) == 0)
135 1.1 matt {
136 1.2 christos *strp = str + 7;
137 1.2 christos reloc = BFD_RELOC_OR1K_TLS_LDM_PG21;
138 1.1 matt }
139 1.2 christos else if (strncasecmp (str, "gottp(", 6) == 0)
140 1.1 matt {
141 1.2 christos *strp = str + 6;
142 1.2 christos reloc = BFD_RELOC_OR1K_TLS_IE_PG21;
143 1.1 matt }
144 1.1 matt
145 1.2 christos errmsg = cgen_parse_address (cd, strp, opindex, reloc, resultp, valuep);
146 1.1 matt
147 1.2 christos if (reloc != BFD_RELOC_OR1K_PCREL_PG21)
148 1.1 matt {
149 1.1 matt if (**strp != ')')
150 1.2 christos errmsg = MISSING_CLOSING_PARENTHESIS;
151 1.2 christos else
152 1.2 christos ++*strp;
153 1.1 matt }
154 1.1 matt
155 1.2 christos return errmsg;
156 1.2 christos }
157 1.1 matt
158 1.2 christos enum or1k_rclass
159 1.2 christos {
160 1.2 christos RCLASS_DIRECT = 0,
161 1.2 christos RCLASS_GOT = 1,
162 1.2 christos RCLASS_GOTPC = 2,
163 1.2 christos RCLASS_GOTOFF = 3,
164 1.2 christos RCLASS_TLSGD = 4,
165 1.2 christos RCLASS_TLSLDM = 5,
166 1.2 christos RCLASS_DTPOFF = 6,
167 1.2 christos RCLASS_GOTTPOFF = 7,
168 1.2 christos RCLASS_TPOFF = 8,
169 1.2 christos };
170 1.1 matt
171 1.2 christos enum or1k_rtype
172 1.2 christos {
173 1.2 christos RTYPE_LO = 0,
174 1.2 christos RTYPE_SLO = 1,
175 1.2 christos RTYPE_PO = 2,
176 1.2 christos RTYPE_SPO = 3,
177 1.2 christos RTYPE_HI = 4,
178 1.2 christos RTYPE_AHI = 5,
179 1.2 christos };
180 1.2 christos
181 1.2 christos #define RCLASS_SHIFT 3
182 1.2 christos #define RTYPE_MASK 7
183 1.2 christos
184 1.2 christos static const bfd_reloc_code_real_type or1k_imm16_relocs[][6] = {
185 1.2 christos { BFD_RELOC_LO16,
186 1.2 christos BFD_RELOC_OR1K_SLO16,
187 1.2 christos BFD_RELOC_OR1K_LO13,
188 1.2 christos BFD_RELOC_OR1K_SLO13,
189 1.2 christos BFD_RELOC_HI16,
190 1.2 christos BFD_RELOC_HI16_S, },
191 1.2 christos { BFD_RELOC_OR1K_GOT16,
192 1.2 christos BFD_RELOC_UNUSED,
193 1.2 christos BFD_RELOC_OR1K_GOT_LO13,
194 1.2 christos BFD_RELOC_UNUSED,
195 1.2 christos BFD_RELOC_UNUSED,
196 1.2 christos BFD_RELOC_UNUSED },
197 1.2 christos { BFD_RELOC_OR1K_GOTPC_LO16,
198 1.2 christos BFD_RELOC_UNUSED,
199 1.2 christos BFD_RELOC_UNUSED,
200 1.2 christos BFD_RELOC_UNUSED,
201 1.2 christos BFD_RELOC_OR1K_GOTPC_HI16,
202 1.2 christos BFD_RELOC_UNUSED },
203 1.2 christos { BFD_RELOC_LO16_GOTOFF,
204 1.2 christos BFD_RELOC_OR1K_GOTOFF_SLO16,
205 1.2 christos BFD_RELOC_UNUSED,
206 1.2 christos BFD_RELOC_UNUSED,
207 1.2 christos BFD_RELOC_HI16_GOTOFF,
208 1.2 christos BFD_RELOC_HI16_S_GOTOFF },
209 1.2 christos { BFD_RELOC_OR1K_TLS_GD_LO16,
210 1.2 christos BFD_RELOC_UNUSED,
211 1.2 christos BFD_RELOC_OR1K_TLS_GD_LO13,
212 1.2 christos BFD_RELOC_UNUSED,
213 1.2 christos BFD_RELOC_OR1K_TLS_GD_HI16,
214 1.2 christos BFD_RELOC_UNUSED },
215 1.2 christos { BFD_RELOC_OR1K_TLS_LDM_LO16,
216 1.2 christos BFD_RELOC_UNUSED,
217 1.2 christos BFD_RELOC_OR1K_TLS_LDM_LO13,
218 1.2 christos BFD_RELOC_UNUSED,
219 1.2 christos BFD_RELOC_OR1K_TLS_LDM_HI16,
220 1.2 christos BFD_RELOC_UNUSED },
221 1.2 christos { BFD_RELOC_OR1K_TLS_LDO_LO16,
222 1.2 christos BFD_RELOC_UNUSED,
223 1.2 christos BFD_RELOC_UNUSED,
224 1.2 christos BFD_RELOC_UNUSED,
225 1.2 christos BFD_RELOC_OR1K_TLS_LDO_HI16,
226 1.2 christos BFD_RELOC_UNUSED },
227 1.2 christos { BFD_RELOC_OR1K_TLS_IE_LO16,
228 1.2 christos BFD_RELOC_UNUSED,
229 1.2 christos BFD_RELOC_OR1K_TLS_IE_LO13,
230 1.2 christos BFD_RELOC_UNUSED,
231 1.2 christos BFD_RELOC_OR1K_TLS_IE_HI16,
232 1.2 christos BFD_RELOC_OR1K_TLS_IE_AHI16 },
233 1.2 christos { BFD_RELOC_OR1K_TLS_LE_LO16,
234 1.2 christos BFD_RELOC_OR1K_TLS_LE_SLO16,
235 1.2 christos BFD_RELOC_UNUSED,
236 1.2 christos BFD_RELOC_UNUSED,
237 1.2 christos BFD_RELOC_OR1K_TLS_LE_HI16,
238 1.2 christos BFD_RELOC_OR1K_TLS_LE_AHI16 },
239 1.2 christos };
240 1.1 matt
241 1.2 christos static int
242 1.2 christos parse_reloc (const char **strp)
243 1.2 christos {
244 1.2 christos const char *str = *strp;
245 1.2 christos enum or1k_rclass cls = RCLASS_DIRECT;
246 1.2 christos enum or1k_rtype typ;
247 1.2 christos
248 1.2 christos if (strncasecmp (str, "got(", 4) == 0)
249 1.2 christos {
250 1.2 christos *strp = str + 4;
251 1.2 christos return (RCLASS_GOT << RCLASS_SHIFT) | RTYPE_LO;
252 1.2 christos }
253 1.2 christos if (strncasecmp (str, "gotpo(", 6) == 0)
254 1.2 christos {
255 1.2 christos *strp = str + 6;
256 1.2 christos return (RCLASS_GOT << RCLASS_SHIFT) | RTYPE_PO;
257 1.2 christos }
258 1.2 christos if (strncasecmp (str, "gottppo(", 8) == 0)
259 1.2 christos {
260 1.2 christos *strp = str + 8;
261 1.2 christos return (RCLASS_GOTTPOFF << RCLASS_SHIFT) | RTYPE_PO;
262 1.2 christos }
263 1.2 christos
264 1.2 christos if (strncasecmp (str, "gotpc", 5) == 0)
265 1.2 christos {
266 1.2 christos str += 5;
267 1.2 christos cls = RCLASS_GOTPC;
268 1.2 christos }
269 1.2 christos else if (strncasecmp (str, "gotoff", 6) == 0)
270 1.2 christos {
271 1.2 christos str += 6;
272 1.2 christos cls = RCLASS_GOTOFF;
273 1.2 christos }
274 1.2 christos else if (strncasecmp (str, "tlsgd", 5) == 0)
275 1.2 christos {
276 1.2 christos str += 5;
277 1.2 christos cls = RCLASS_TLSGD;
278 1.2 christos }
279 1.2 christos else if (strncasecmp (str, "tlsldm", 6) == 0)
280 1.2 christos {
281 1.2 christos str += 6;
282 1.2 christos cls = RCLASS_TLSLDM;
283 1.2 christos }
284 1.2 christos else if (strncasecmp (str, "dtpoff", 6) == 0)
285 1.2 christos {
286 1.2 christos str += 6;
287 1.2 christos cls = RCLASS_DTPOFF;
288 1.2 christos }
289 1.2 christos else if (strncasecmp (str, "gottpoff", 8) == 0)
290 1.2 christos {
291 1.2 christos str += 8;
292 1.2 christos cls = RCLASS_GOTTPOFF;
293 1.2 christos }
294 1.2 christos else if (strncasecmp (str, "tpoff", 5) == 0)
295 1.2 christos {
296 1.2 christos str += 5;
297 1.2 christos cls = RCLASS_TPOFF;
298 1.2 christos }
299 1.2 christos
300 1.2 christos if (strncasecmp (str, "hi(", 3) == 0)
301 1.2 christos {
302 1.2 christos str += 3;
303 1.2 christos typ = RTYPE_HI;
304 1.2 christos }
305 1.2 christos else if (strncasecmp (str, "lo(", 3) == 0)
306 1.2 christos {
307 1.2 christos str += 3;
308 1.2 christos typ = RTYPE_LO;
309 1.2 christos }
310 1.2 christos else if (strncasecmp (str, "ha(", 3) == 0)
311 1.2 christos {
312 1.2 christos str += 3;
313 1.2 christos typ = RTYPE_AHI;
314 1.2 christos }
315 1.2 christos else if (strncasecmp (str, "po(", 3) == 0 && cls != RCLASS_GOTTPOFF)
316 1.2 christos {
317 1.2 christos str += 3;
318 1.2 christos typ = RTYPE_PO;
319 1.2 christos }
320 1.2 christos else
321 1.2 christos return -1;
322 1.1 matt
323 1.2 christos *strp = str;
324 1.2 christos return (cls << RCLASS_SHIFT) | typ;
325 1.2 christos }
326 1.1 matt
327 1.2 christos static const char *
328 1.2 christos parse_imm16 (CGEN_CPU_DESC cd, const char **strp, int opindex,
329 1.2 christos long *valuep, int splitp)
330 1.2 christos {
331 1.2 christos const char *errmsg;
332 1.2 christos enum cgen_parse_operand_result result_type;
333 1.2 christos bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
334 1.2 christos enum or1k_rtype reloc_type;
335 1.2 christos int reloc_code;
336 1.2 christos bfd_vma ret;
337 1.1 matt
338 1.2 christos if (**strp == '#')
339 1.2 christos ++*strp;
340 1.1 matt
341 1.2 christos reloc_code = parse_reloc (strp);
342 1.2 christos reloc_type = reloc_code & RTYPE_MASK;
343 1.2 christos if (reloc_code >= 0)
344 1.1 matt {
345 1.2 christos enum or1k_rclass reloc_class = reloc_code >> RCLASS_SHIFT;
346 1.2 christos if (splitp)
347 1.2 christos {
348 1.2 christos if ((reloc_type == RTYPE_LO || reloc_type == RTYPE_PO)
349 1.2 christos && reloc_class != RCLASS_GOT)
350 1.2 christos /* If split we or up the type to RTYPE_SLO or RTYPE_SPO. */
351 1.2 christos reloc_type |= 1;
352 1.2 christos else
353 1.2 christos return INVALID_STORE_RELOC;
354 1.2 christos }
355 1.2 christos reloc = or1k_imm16_relocs[reloc_class][reloc_type];
356 1.1 matt }
357 1.1 matt
358 1.2 christos if (reloc != BFD_RELOC_UNUSED)
359 1.1 matt {
360 1.1 matt bfd_vma value;
361 1.1 matt
362 1.2 christos errmsg = cgen_parse_address (cd, strp, opindex, reloc,
363 1.1 matt &result_type, &value);
364 1.1 matt if (**strp != ')')
365 1.2 christos errmsg = MISSING_CLOSING_PARENTHESIS;
366 1.1 matt ++*strp;
367 1.1 matt
368 1.2 christos ret = value;
369 1.1 matt
370 1.2 christos if (errmsg == NULL && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
371 1.2 christos switch (reloc_type)
372 1.2 christos {
373 1.2 christos case RTYPE_AHI:
374 1.2 christos ret += 0x8000;
375 1.2 christos /* FALLTHRU */
376 1.2 christos case RTYPE_HI:
377 1.2 christos ret >>= 16;
378 1.2 christos /* FALLTHRU */
379 1.2 christos case RTYPE_LO:
380 1.2 christos case RTYPE_SLO:
381 1.2 christos ret &= 0xffff;
382 1.2 christos ret = (ret ^ 0x8000) - 0x8000;
383 1.2 christos break;
384 1.2 christos case RTYPE_PO:
385 1.2 christos case RTYPE_SPO:
386 1.2 christos ret &= 0x1fff;
387 1.2 christos break;
388 1.2 christos default:
389 1.2 christos errmsg = INVALID_RELOC_TYPE;
390 1.2 christos }
391 1.1 matt }
392 1.1 matt else
393 1.1 matt {
394 1.1 matt long value;
395 1.1 matt errmsg = cgen_parse_signed_integer (cd, strp, opindex, &value);
396 1.1 matt ret = value;
397 1.1 matt }
398 1.1 matt
399 1.1 matt if (errmsg == NULL)
400 1.1 matt *valuep = ret;
401 1.1 matt
402 1.1 matt return errmsg;
403 1.1 matt }
404 1.1 matt
405 1.1 matt static const char *
406 1.2 christos parse_simm16 (CGEN_CPU_DESC cd, const char **strp, int opindex, long *valuep)
407 1.1 matt {
408 1.2 christos return parse_imm16(cd, strp, opindex, (long *) valuep, 0);
409 1.2 christos }
410 1.2 christos
411 1.2 christos static const char *
412 1.2 christos parse_simm16_split (CGEN_CPU_DESC cd, const char **strp, int opindex,
413 1.2 christos long *valuep)
414 1.2 christos {
415 1.2 christos return parse_imm16(cd, strp, opindex, (long *) valuep, 1);
416 1.2 christos }
417 1.1 matt
418 1.2 christos static const char *
419 1.2 christos parse_uimm16 (CGEN_CPU_DESC cd, const char **strp, int opindex,
420 1.2 christos unsigned long *valuep)
421 1.2 christos {
422 1.2 christos const char *errmsg = parse_imm16(cd, strp, opindex, (long *) valuep, 0);
423 1.1 matt if (errmsg == NULL)
424 1.1 matt *valuep &= 0xffff;
425 1.1 matt return errmsg;
426 1.1 matt }
427 1.1 matt
428 1.2 christos static const char *
429 1.2 christos parse_uimm16_split (CGEN_CPU_DESC cd, const char **strp, int opindex,
430 1.2 christos unsigned long *valuep)
431 1.2 christos {
432 1.2 christos const char *errmsg = parse_imm16(cd, strp, opindex, (long *) valuep, 1);
433 1.2 christos if (errmsg == NULL)
434 1.2 christos *valuep &= 0xffff;
435 1.2 christos return errmsg;
436 1.2 christos }
437 1.2 christos
438 1.2 christos /* Parse register pairs with syntax rA,rB to a flag + rA value. */
439 1.2 christos
440 1.2 christos static const char *
441 1.2 christos parse_regpair (CGEN_CPU_DESC cd, const char **strp,
442 1.2 christos int opindex ATTRIBUTE_UNUSED, unsigned long *valuep)
443 1.2 christos {
444 1.2 christos long reg1_index;
445 1.2 christos long reg2_index;
446 1.2 christos const char *errmsg;
447 1.2 christos
448 1.2 christos /* The first part should just be a register. */
449 1.2 christos errmsg = cgen_parse_keyword (cd, strp, &or1k_cgen_opval_h_gpr,
450 1.2 christos ®1_index);
451 1.2 christos
452 1.2 christos /* If that worked skip the comma separator. */
453 1.2 christos if (errmsg == NULL)
454 1.2 christos {
455 1.2 christos if (**strp == ',')
456 1.2 christos ++*strp;
457 1.2 christos else
458 1.2 christos errmsg = "Unexpected character, expected ','";
459 1.2 christos }
460 1.2 christos
461 1.2 christos /* If that worked the next part is just another register. */
462 1.2 christos if (errmsg == NULL)
463 1.2 christos errmsg = cgen_parse_keyword (cd, strp, &or1k_cgen_opval_h_gpr,
464 1.2 christos ®2_index);
465 1.2 christos
466 1.2 christos /* Validate the register pair is valid and create the output value. */
467 1.2 christos if (errmsg == NULL)
468 1.2 christos {
469 1.2 christos int regoffset = reg2_index - reg1_index;
470 1.2 christos
471 1.2 christos if (regoffset == 1 || regoffset == 2)
472 1.2 christos {
473 1.2 christos unsigned short offsetmask;
474 1.2 christos unsigned short value;
475 1.2 christos
476 1.2 christos offsetmask = ((regoffset == 2 ? 1 : 0) << 5);
477 1.2 christos value = offsetmask | reg1_index;
478 1.2 christos
479 1.2 christos *valuep = value;
480 1.2 christos }
481 1.2 christos else
482 1.2 christos errmsg = "Invalid register pair, offset not 1 or 2.";
483 1.2 christos }
484 1.2 christos
485 1.2 christos return errmsg;
486 1.2 christos }
487 1.2 christos
488 1.2 christos /* -- */
489 1.2 christos
490 1.2 christos /* -- dis.c */
491 1.2 christos
492 1.2 christos static void
493 1.2 christos print_regpair (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
494 1.2 christos void * dis_info,
495 1.2 christos long value,
496 1.2 christos unsigned int attrs ATTRIBUTE_UNUSED,
497 1.2 christos bfd_vma pc ATTRIBUTE_UNUSED,
498 1.2 christos int length ATTRIBUTE_UNUSED)
499 1.2 christos {
500 1.2 christos disassemble_info *info = dis_info;
501 1.2 christos char reg1_index;
502 1.2 christos char reg2_index;
503 1.2 christos
504 1.2 christos reg1_index = value & 0x1f;
505 1.2 christos reg2_index = reg1_index + ((value & (1 << 5)) ? 2 : 1);
506 1.2 christos
507 1.2 christos (*info->fprintf_func) (info->stream, "r%d,r%d", reg1_index, reg2_index);
508 1.2 christos }
509 1.2 christos
510 1.1 matt /* -- */
511 1.1 matt
512 1.1 matt /* -- ibd.h */
513 1.1 matt
514 1.1 matt /* -- */
515