]>
Commit | Line | Data |
---|---|---|
dc15e575 NC |
1 | /* IP2K opcode support. -*- C -*- |
2 | Copyright 2002, 2005, 2011 Free Software Foundation, Inc. | |
3 | ||
4 | Contributed by Red Hat Inc; | |
5 | ||
6 | This file is part of the GNU Binutils. | |
7 | ||
8 | This program is free software; you can redistribute it and/or modify | |
9 | it under the terms of the GNU General Public License as published by | |
10 | the Free Software Foundation; either version 3 of the License, or | |
11 | (at your option) any later version. | |
12 | ||
13 | This program is distributed in the hope that it will be useful, | |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | GNU General Public License for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License | |
19 | along with this program; if not, write to the Free Software | |
20 | Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, | |
21 | MA 02110-1301, USA. */ | |
22 | ||
23 | /* | |
24 | Each section is delimited with start and end markers. | |
25 | ||
26 | <arch>-opc.h additions use: "-- opc.h" | |
27 | <arch>-opc.c additions use: "-- opc.c" | |
28 | <arch>-asm.c additions use: "-- asm.c" | |
29 | <arch>-dis.c additions use: "-- dis.c" | |
30 | <arch>-ibd.h additions use: "-- ibd.h". */ | |
31 | \f | |
32 | /* -- opc.h */ | |
33 | ||
34 | /* Check applicability of instructions against machines. */ | |
35 | #define CGEN_VALIDATE_INSN_SUPPORTED | |
36 | ||
37 | /* Allows reason codes to be output when assembler errors occur. */ | |
38 | #define CGEN_VERBOSE_ASSEMBLER_ERRORS | |
39 | ||
40 | /* Override disassembly hashing - there are variable bits in the top | |
41 | byte of these instructions. */ | |
42 | #define CGEN_DIS_HASH_SIZE 8 | |
43 | #define CGEN_DIS_HASH(buf, value) \ | |
44 | (((* (unsigned char*) (buf)) >> 5) % CGEN_DIS_HASH_SIZE) | |
45 | ||
46 | #define CGEN_ASM_HASH_SIZE 127 | |
47 | #define CGEN_ASM_HASH(insn) ip2k_asm_hash (insn) | |
48 | ||
49 | extern unsigned int ip2k_asm_hash (const char *); | |
50 | extern int ip2k_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *); | |
51 | \f | |
52 | /* -- opc.c */ | |
53 | ||
54 | #include "safe-ctype.h" | |
55 | ||
56 | /* A better hash function for instruction mnemonics. */ | |
57 | unsigned int | |
58 | ip2k_asm_hash (const char* insn) | |
59 | { | |
60 | unsigned int hash; | |
61 | const char* m = insn; | |
62 | ||
63 | for (hash = 0; *m && ! ISSPACE (*m); m++) | |
64 | hash = (hash * 23) ^ (0x1F & TOLOWER (*m)); | |
65 | ||
66 | /* printf ("%s %d\n", insn, (hash % CGEN_ASM_HASH_SIZE)); */ | |
67 | ||
68 | return hash % CGEN_ASM_HASH_SIZE; | |
69 | } | |
70 | ||
71 | ||
72 | /* Special check to ensure that instruction exists for given machine. */ | |
73 | ||
74 | int | |
75 | ip2k_cgen_insn_supported (CGEN_CPU_DESC cd, const CGEN_INSN *insn) | |
76 | { | |
77 | int machs = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH); | |
78 | ||
79 | /* No mach attribute? Assume it's supported for all machs. */ | |
80 | if (machs == 0) | |
81 | return 1; | |
82 | ||
83 | return (machs & cd->machs) != 0; | |
84 | } | |
85 | ||
86 | \f | |
87 | /* -- asm.c */ | |
88 | ||
89 | static const char * | |
90 | parse_fr (CGEN_CPU_DESC cd, | |
91 | const char **strp, | |
92 | int opindex, | |
93 | unsigned long *valuep) | |
94 | { | |
95 | const char *errmsg; | |
96 | const char *old_strp; | |
97 | char *afteroffset; | |
98 | enum cgen_parse_operand_result result_type; | |
99 | bfd_vma value; | |
100 | extern CGEN_KEYWORD ip2k_cgen_opval_register_names; | |
101 | bfd_vma tempvalue; | |
102 | ||
103 | old_strp = *strp; | |
104 | afteroffset = NULL; | |
105 | ||
106 | /* Check here to see if you're about to try parsing a w as the first arg | |
107 | and return an error if you are. */ | |
108 | if ((strncmp (*strp, "w", 1) == 0) || (strncmp (*strp, "W", 1) == 0)) | |
109 | { | |
110 | (*strp)++; | |
111 | ||
112 | if ((strncmp (*strp, ",", 1) == 0) || ISSPACE (**strp)) | |
113 | { | |
114 | /* We've been passed a w. Return with an error message so that | |
115 | cgen will try the next parsing option. */ | |
116 | errmsg = _("W keyword invalid in FR operand slot."); | |
117 | return errmsg; | |
118 | } | |
119 | *strp = old_strp; | |
120 | } | |
121 | ||
122 | /* Attempt parse as register keyword. */ | |
123 | errmsg = cgen_parse_keyword (cd, strp, & ip2k_cgen_opval_register_names, | |
124 | (long *) valuep); | |
125 | if (*strp != NULL | |
126 | && errmsg == NULL) | |
127 | return errmsg; | |
128 | ||
129 | /* Attempt to parse for "(IP)". */ | |
130 | afteroffset = strstr (*strp, "(IP)"); | |
131 | ||
132 | if (afteroffset == NULL) | |
133 | /* Make sure it's not in lower case. */ | |
134 | afteroffset = strstr (*strp, "(ip)"); | |
135 | ||
136 | if (afteroffset != NULL) | |
137 | { | |
138 | if (afteroffset != *strp) | |
139 | { | |
140 | /* Invalid offset present. */ | |
141 | errmsg = _("offset(IP) is not a valid form"); | |
142 | return errmsg; | |
143 | } | |
144 | else | |
145 | { | |
146 | *strp += 4; | |
147 | *valuep = 0; | |
148 | errmsg = NULL; | |
149 | return errmsg; | |
150 | } | |
151 | } | |
152 | ||
153 | /* Attempt to parse for DP. ex: mov w, offset(DP) | |
154 | mov offset(DP),w */ | |
155 | ||
156 | /* Try parsing it as an address and see what comes back. */ | |
157 | afteroffset = strstr (*strp, "(DP)"); | |
158 | ||
159 | if (afteroffset == NULL) | |
160 | /* Maybe it's in lower case. */ | |
161 | afteroffset = strstr (*strp, "(dp)"); | |
162 | ||
163 | if (afteroffset != NULL) | |
164 | { | |
165 | if (afteroffset == *strp) | |
166 | { | |
167 | /* No offset present. Use 0 by default. */ | |
168 | tempvalue = 0; | |
169 | errmsg = NULL; | |
170 | } | |
171 | else | |
172 | errmsg = cgen_parse_address (cd, strp, opindex, | |
173 | BFD_RELOC_IP2K_FR_OFFSET, | |
174 | & result_type, & tempvalue); | |
175 | ||
176 | if (errmsg == NULL) | |
177 | { | |
178 | if (tempvalue <= 127) | |
179 | { | |
180 | /* Value is ok. Fix up the first 2 bits and return. */ | |
181 | *valuep = 0x0100 | tempvalue; | |
182 | *strp += 4; /* Skip over the (DP) in *strp. */ | |
183 | return errmsg; | |
184 | } | |
185 | else | |
186 | { | |
187 | /* Found something there in front of (DP) but it's out | |
188 | of range. */ | |
189 | errmsg = _("(DP) offset out of range."); | |
190 | return errmsg; | |
191 | } | |
192 | } | |
193 | } | |
194 | ||
195 | ||
196 | /* Attempt to parse for SP. ex: mov w, offset(SP) | |
197 | mov offset(SP), w. */ | |
198 | afteroffset = strstr (*strp, "(SP)"); | |
199 | ||
200 | if (afteroffset == NULL) | |
201 | /* Maybe it's in lower case. */ | |
202 | afteroffset = strstr (*strp, "(sp)"); | |
203 | ||
204 | if (afteroffset != NULL) | |
205 | { | |
206 | if (afteroffset == *strp) | |
207 | { | |
208 | /* No offset present. Use 0 by default. */ | |
209 | tempvalue = 0; | |
210 | errmsg = NULL; | |
211 | } | |
212 | else | |
213 | errmsg = cgen_parse_address (cd, strp, opindex, | |
214 | BFD_RELOC_IP2K_FR_OFFSET, | |
215 | & result_type, & tempvalue); | |
216 | ||
217 | if (errmsg == NULL) | |
218 | { | |
219 | if (tempvalue <= 127) | |
220 | { | |
221 | /* Value is ok. Fix up the first 2 bits and return. */ | |
222 | *valuep = 0x0180 | tempvalue; | |
223 | *strp += 4; /* Skip over the (SP) in *strp. */ | |
224 | return errmsg; | |
225 | } | |
226 | else | |
227 | { | |
228 | /* Found something there in front of (SP) but it's out | |
229 | of range. */ | |
230 | errmsg = _("(SP) offset out of range."); | |
231 | return errmsg; | |
232 | } | |
233 | } | |
234 | } | |
235 | ||
236 | /* Attempt to parse as an address. */ | |
237 | *strp = old_strp; | |
238 | errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_IP2K_FR9, | |
239 | & result_type, & value); | |
240 | if (errmsg == NULL) | |
241 | { | |
242 | *valuep = value; | |
243 | ||
244 | /* If a parenthesis is found, warn about invalid form. */ | |
245 | if (**strp == '(') | |
246 | errmsg = _("illegal use of parentheses"); | |
247 | ||
248 | /* If a numeric value is specified, ensure that it is between | |
249 | 1 and 255. */ | |
250 | else if (result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) | |
251 | { | |
252 | if (value < 0x1 || value > 0xff) | |
253 | errmsg = _("operand out of range (not between 1 and 255)"); | |
254 | } | |
255 | } | |
256 | return errmsg; | |
257 | } | |
258 | ||
259 | static const char * | |
260 | parse_addr16 (CGEN_CPU_DESC cd, | |
261 | const char **strp, | |
262 | int opindex, | |
263 | unsigned long *valuep) | |
264 | { | |
265 | const char *errmsg; | |
266 | enum cgen_parse_operand_result result_type; | |
267 | bfd_reloc_code_real_type code = BFD_RELOC_NONE; | |
268 | bfd_vma value; | |
269 | ||
270 | if (opindex == (CGEN_OPERAND_TYPE) IP2K_OPERAND_ADDR16H) | |
271 | code = BFD_RELOC_IP2K_HI8DATA; | |
272 | else if (opindex == (CGEN_OPERAND_TYPE) IP2K_OPERAND_ADDR16L) | |
273 | code = BFD_RELOC_IP2K_LO8DATA; | |
274 | else | |
275 | { | |
276 | /* Something is very wrong. opindex has to be one of the above. */ | |
277 | errmsg = _("parse_addr16: invalid opindex."); | |
278 | return errmsg; | |
279 | } | |
280 | ||
281 | errmsg = cgen_parse_address (cd, strp, opindex, code, | |
282 | & result_type, & value); | |
283 | if (errmsg == NULL) | |
284 | { | |
285 | /* We either have a relocation or a number now. */ | |
286 | if (result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) | |
287 | { | |
288 | /* We got a number back. */ | |
289 | if (code == BFD_RELOC_IP2K_HI8DATA) | |
290 | value >>= 8; | |
291 | else | |
292 | /* code = BFD_RELOC_IP2K_LOW8DATA. */ | |
293 | value &= 0x00FF; | |
294 | } | |
295 | *valuep = value; | |
296 | } | |
297 | ||
298 | return errmsg; | |
299 | } | |
300 | ||
301 | static const char * | |
302 | parse_addr16_cjp (CGEN_CPU_DESC cd, | |
303 | const char **strp, | |
304 | int opindex, | |
305 | unsigned long *valuep) | |
306 | { | |
307 | const char *errmsg; | |
308 | enum cgen_parse_operand_result result_type; | |
309 | bfd_reloc_code_real_type code = BFD_RELOC_NONE; | |
310 | bfd_vma value; | |
311 | ||
312 | if (opindex == (CGEN_OPERAND_TYPE) IP2K_OPERAND_ADDR16CJP) | |
313 | code = BFD_RELOC_IP2K_ADDR16CJP; | |
314 | else if (opindex == (CGEN_OPERAND_TYPE) IP2K_OPERAND_ADDR16P) | |
315 | code = BFD_RELOC_IP2K_PAGE3; | |
316 | ||
317 | errmsg = cgen_parse_address (cd, strp, opindex, code, | |
318 | & result_type, & value); | |
319 | if (errmsg == NULL) | |
320 | { | |
321 | if (result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) | |
322 | { | |
323 | if ((value & 0x1) == 0) /* If the address is even .... */ | |
324 | { | |
325 | if (opindex == (CGEN_OPERAND_TYPE) IP2K_OPERAND_ADDR16CJP) | |
326 | *valuep = (value >> 1) & 0x1FFF; /* Should mask be 1FFF? */ | |
327 | else if (opindex == (CGEN_OPERAND_TYPE) IP2K_OPERAND_ADDR16P) | |
328 | *valuep = (value >> 14) & 0x7; | |
329 | } | |
330 | else | |
331 | errmsg = _("Byte address required. - must be even."); | |
332 | } | |
333 | else if (result_type == CGEN_PARSE_OPERAND_RESULT_QUEUED) | |
334 | { | |
335 | /* This will happen for things like (s2-s1) where s2 and s1 | |
336 | are labels. */ | |
337 | *valuep = value; | |
338 | } | |
339 | else | |
340 | errmsg = _("cgen_parse_address returned a symbol. Literal required."); | |
341 | } | |
342 | return errmsg; | |
343 | } | |
344 | ||
345 | static const char * | |
346 | parse_lit8 (CGEN_CPU_DESC cd, | |
347 | const char **strp, | |
348 | int opindex, | |
349 | long *valuep) | |
350 | { | |
351 | const char *errmsg; | |
352 | enum cgen_parse_operand_result result_type; | |
353 | bfd_reloc_code_real_type code = BFD_RELOC_NONE; | |
354 | bfd_vma value; | |
355 | ||
356 | /* Parse %OP relocating operators. */ | |
357 | if (strncmp (*strp, "%bank", 5) == 0) | |
358 | { | |
359 | *strp += 5; | |
360 | code = BFD_RELOC_IP2K_BANK; | |
361 | } | |
362 | else if (strncmp (*strp, "%lo8data", 8) == 0) | |
363 | { | |
364 | *strp += 8; | |
365 | code = BFD_RELOC_IP2K_LO8DATA; | |
366 | } | |
367 | else if (strncmp (*strp, "%hi8data", 8) == 0) | |
368 | { | |
369 | *strp += 8; | |
370 | code = BFD_RELOC_IP2K_HI8DATA; | |
371 | } | |
372 | else if (strncmp (*strp, "%ex8data", 8) == 0) | |
373 | { | |
374 | *strp += 8; | |
375 | code = BFD_RELOC_IP2K_EX8DATA; | |
376 | } | |
377 | else if (strncmp (*strp, "%lo8insn", 8) == 0) | |
378 | { | |
379 | *strp += 8; | |
380 | code = BFD_RELOC_IP2K_LO8INSN; | |
381 | } | |
382 | else if (strncmp (*strp, "%hi8insn", 8) == 0) | |
383 | { | |
384 | *strp += 8; | |
385 | code = BFD_RELOC_IP2K_HI8INSN; | |
386 | } | |
387 | ||
388 | /* Parse %op operand. */ | |
389 | if (code != BFD_RELOC_NONE) | |
390 | { | |
391 | errmsg = cgen_parse_address (cd, strp, opindex, code, | |
392 | & result_type, & value); | |
393 | if ((errmsg == NULL) && | |
394 | (result_type != CGEN_PARSE_OPERAND_RESULT_QUEUED)) | |
395 | errmsg = _("percent-operator operand is not a symbol"); | |
396 | ||
397 | *valuep = value; | |
398 | } | |
399 | /* Parse as a number. */ | |
400 | else | |
401 | { | |
402 | errmsg = cgen_parse_signed_integer (cd, strp, opindex, valuep); | |
403 | ||
404 | /* Truncate to eight bits to accept both signed and unsigned input. */ | |
405 | if (errmsg == NULL) | |
406 | *valuep &= 0xFF; | |
407 | } | |
408 | ||
409 | return errmsg; | |
410 | } | |
411 | ||
412 | static const char * | |
413 | parse_bit3 (CGEN_CPU_DESC cd, | |
414 | const char **strp, | |
415 | int opindex, | |
416 | unsigned long *valuep) | |
417 | { | |
418 | const char *errmsg; | |
419 | char mode = 0; | |
420 | long count = 0; | |
421 | unsigned long value; | |
422 | ||
423 | if (strncmp (*strp, "%bit", 4) == 0) | |
424 | { | |
425 | *strp += 4; | |
426 | mode = 1; | |
427 | } | |
428 | else if (strncmp (*strp, "%msbbit", 7) == 0) | |
429 | { | |
430 | *strp += 7; | |
431 | mode = 1; | |
432 | } | |
433 | else if (strncmp (*strp, "%lsbbit", 7) == 0) | |
434 | { | |
435 | *strp += 7; | |
436 | mode = 2; | |
437 | } | |
438 | ||
439 | errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep); | |
440 | if (errmsg) | |
441 | return errmsg; | |
442 | ||
443 | if (mode) | |
444 | { | |
445 | value = * valuep; | |
446 | if (value == 0) | |
447 | { | |
448 | errmsg = _("Attempt to find bit index of 0"); | |
449 | return errmsg; | |
450 | } | |
451 | ||
452 | if (mode == 1) | |
453 | { | |
454 | count = 31; | |
455 | while ((value & 0x80000000) == 0) | |
456 | { | |
457 | count--; | |
458 | value <<= 1; | |
459 | } | |
460 | } | |
461 | else if (mode == 2) | |
462 | { | |
463 | count = 0; | |
464 | while ((value & 0x00000001) == 0) | |
465 | { | |
466 | count++; | |
467 | value >>= 1; | |
468 | } | |
469 | } | |
470 | ||
471 | *valuep = count; | |
472 | } | |
473 | ||
474 | return errmsg; | |
475 | } | |
476 | ||
477 | /* -- dis.c */ | |
478 | ||
479 | static void | |
480 | print_fr (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, | |
481 | void * dis_info, | |
482 | long value, | |
483 | unsigned int attrs ATTRIBUTE_UNUSED, | |
484 | bfd_vma pc ATTRIBUTE_UNUSED, | |
485 | int length ATTRIBUTE_UNUSED) | |
486 | { | |
487 | disassemble_info *info = (disassemble_info *) dis_info; | |
488 | const CGEN_KEYWORD_ENTRY *ke; | |
489 | extern CGEN_KEYWORD ip2k_cgen_opval_register_names; | |
490 | long offsettest; | |
491 | long offsetvalue; | |
492 | ||
493 | if (value == 0) /* This is (IP). */ | |
494 | { | |
495 | (*info->fprintf_func) (info->stream, "%s", "(IP)"); | |
496 | return; | |
497 | } | |
498 | ||
499 | offsettest = value >> 7; | |
500 | offsetvalue = value & 0x7F; | |
501 | ||
502 | /* Check to see if first two bits are 10 -> (DP). */ | |
503 | if (offsettest == 2) | |
504 | { | |
505 | if (offsetvalue == 0) | |
506 | (*info->fprintf_func) (info->stream, "%s","(DP)"); | |
507 | else | |
508 | (*info->fprintf_func) (info->stream, "$%lx%s", offsetvalue, "(DP)"); | |
509 | return; | |
510 | } | |
511 | ||
512 | /* Check to see if first two bits are 11 -> (SP). */ | |
513 | if (offsettest == 3) | |
514 | { | |
515 | if (offsetvalue == 0) | |
516 | (*info->fprintf_func) (info->stream, "%s", "(SP)"); | |
517 | else | |
518 | (*info->fprintf_func) (info->stream, "$%lx%s", offsetvalue,"(SP)"); | |
519 | return; | |
520 | } | |
521 | ||
522 | /* Attempt to print as a register keyword. */ | |
523 | ke = cgen_keyword_lookup_value (& ip2k_cgen_opval_register_names, value); | |
524 | ||
525 | if (ke != NULL) | |
526 | (*info->fprintf_func) (info->stream, "%s", ke->name); | |
527 | else | |
528 | /* Print as an address literal. */ | |
529 | (*info->fprintf_func) (info->stream, "$%02lx", value); | |
530 | } | |
531 | ||
532 | static void | |
533 | print_dollarhex (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, | |
534 | void * dis_info, | |
535 | long value, | |
536 | unsigned int attrs ATTRIBUTE_UNUSED, | |
537 | bfd_vma pc ATTRIBUTE_UNUSED, | |
538 | int length ATTRIBUTE_UNUSED) | |
539 | { | |
540 | disassemble_info *info = (disassemble_info *) dis_info; | |
541 | ||
542 | (*info->fprintf_func) (info->stream, "$%lx", value); | |
543 | } | |
544 | ||
545 | static void | |
546 | print_dollarhex8 (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, | |
547 | void * dis_info, | |
548 | long value, | |
549 | unsigned int attrs ATTRIBUTE_UNUSED, | |
550 | bfd_vma pc ATTRIBUTE_UNUSED, | |
551 | int length ATTRIBUTE_UNUSED) | |
552 | { | |
553 | disassemble_info *info = (disassemble_info *) dis_info; | |
554 | ||
555 | (*info->fprintf_func) (info->stream, "$%02lx", value); | |
556 | } | |
557 | ||
558 | static void | |
559 | print_dollarhex_addr16h (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, | |
560 | void * dis_info, | |
561 | long value, | |
562 | unsigned int attrs ATTRIBUTE_UNUSED, | |
563 | bfd_vma pc ATTRIBUTE_UNUSED, | |
564 | int length ATTRIBUTE_UNUSED) | |
565 | { | |
566 | disassemble_info *info = (disassemble_info *) dis_info; | |
567 | ||
568 | /* This is a loadh instruction. Shift the value to the left | |
569 | by 8 bits so that disassembled code will reassemble properly. */ | |
570 | value = ((value << 8) & 0xFF00); | |
571 | ||
572 | (*info->fprintf_func) (info->stream, "$%04lx", value); | |
573 | } | |
574 | ||
575 | static void | |
576 | print_dollarhex_addr16l (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, | |
577 | void * dis_info, | |
578 | long value, | |
579 | unsigned int attrs ATTRIBUTE_UNUSED, | |
580 | bfd_vma pc ATTRIBUTE_UNUSED, | |
581 | int length ATTRIBUTE_UNUSED) | |
582 | { | |
583 | disassemble_info *info = (disassemble_info *) dis_info; | |
584 | ||
585 | (*info->fprintf_func) (info->stream, "$%04lx", value); | |
586 | } | |
587 | ||
588 | static void | |
589 | print_dollarhex_p (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, | |
590 | void * dis_info, | |
591 | long value, | |
592 | unsigned int attrs ATTRIBUTE_UNUSED, | |
593 | bfd_vma pc ATTRIBUTE_UNUSED, | |
594 | int length ATTRIBUTE_UNUSED) | |
595 | { | |
596 | disassemble_info *info = (disassemble_info *) dis_info; | |
597 | ||
598 | value = ((value << 14) & 0x1C000); | |
599 | ;value = (value & 0x1FFFF); | |
600 | (*info->fprintf_func) (info->stream, "$%05lx", value); | |
601 | } | |
602 | ||
603 | static void | |
604 | print_dollarhex_cj (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, | |
605 | void * dis_info, | |
606 | long value, | |
607 | unsigned int attrs ATTRIBUTE_UNUSED, | |
608 | bfd_vma pc ATTRIBUTE_UNUSED, | |
609 | int length ATTRIBUTE_UNUSED) | |
610 | { | |
611 | disassemble_info *info = (disassemble_info *) dis_info; | |
612 | ||
613 | value = ((value << 1) & 0x1FFFF); | |
614 | (*info->fprintf_func) (info->stream, "$%05lx", value); | |
615 | } | |
616 | ||
617 | static void | |
618 | print_decimal (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, | |
619 | void * dis_info, | |
620 | long value, | |
621 | unsigned int attrs ATTRIBUTE_UNUSED, | |
622 | bfd_vma pc ATTRIBUTE_UNUSED, | |
623 | int length ATTRIBUTE_UNUSED) | |
624 | { | |
625 | disassemble_info *info = (disassemble_info *) dis_info; | |
626 | ||
627 | (*info->fprintf_func) (info->stream, "%ld", value); | |
628 | } | |
629 | ||
630 | ||
631 | ||
632 | /* -- */ | |
633 |