1 /* FR30 opcode support. -*- C -*-
2 Copyright (C) 2000, 2001, 2005 Red Hat, Inc.
3 This file is part of CGEN. */
5 /* This file is an addendum to fr30.cpu. Heavy use of C code isn't
6 appropriate in .cpu files, so it resides here. This especially applies
7 to assembly/disassembly where parsing/printing can be quite involved.
8 Such things aren't really part of the specification of the cpu, per se,
9 so .cpu files provide the general framework and .opc files handle the
10 nitty-gritty details as necessary.
12 Each section is delimited with start and end markers.
14 <arch>-opc.h additions use: "-- opc.h"
15 <arch>-opc.c additions use: "-- opc.c"
16 <arch>-asm.c additions use: "-- asm.c"
17 <arch>-dis.c additions use: "-- dis.c"
18 <arch>-ibd.h additions use: "-- ibd.h". */
22 /* ??? This can be improved upon. */
23 #undef CGEN_DIS_HASH_SIZE
24 #define CGEN_DIS_HASH_SIZE 16
26 #define CGEN_DIS_HASH(buffer, value) (((unsigned char *) (buffer))[0] >> 4)
31 /* Handle register lists for LDMx and STMx. */
34 parse_register_number (const char **strp)
38 if (**strp < '0' || **strp > '9')
39 return -1; /* Error. */
43 if (**strp >= '0' && **strp <= '9')
45 regno = regno * 10 + (**strp - '0');
53 parse_register_list (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
55 int opindex ATTRIBUTE_UNUSED,
56 unsigned long *valuep,
57 int high_low, /* 0 == high, 1 == low. */
58 int load_store) /* 0 == load, 1 == store. */
61 while (**strp && **strp != ')')
65 if (**strp != 'R' && **strp != 'r')
69 regno = parse_register_number (strp);
71 return _("Register number is not valid");
72 if (regno > 7 && !high_low)
73 return _("Register must be between r0 and r7");
74 if (regno < 8 && high_low)
75 return _("Register must be between r8 and r15");
80 if (load_store) /* Mask is reversed for store. */
81 *valuep |= 0x80 >> regno;
83 *valuep |= 1 << regno;
87 if (*(*strp + 1) == ')')
93 if (!*strp || **strp != ')')
94 return _("Register list is not valid");
100 parse_low_register_list_ld (CGEN_CPU_DESC cd,
103 unsigned long *valuep)
105 return parse_register_list (cd, strp, opindex, valuep,
106 0 /* Low. */, 0 /* Load. */);
110 parse_hi_register_list_ld (CGEN_CPU_DESC cd,
113 unsigned long *valuep)
115 return parse_register_list (cd, strp, opindex, valuep,
116 1 /* High. */, 0 /* Load. */);
120 parse_low_register_list_st (CGEN_CPU_DESC cd,
123 unsigned long *valuep)
125 return parse_register_list (cd, strp, opindex, valuep,
126 0 /* Low. */, 1 /* Store. */);
130 parse_hi_register_list_st (CGEN_CPU_DESC cd,
133 unsigned long *valuep)
135 return parse_register_list (cd, strp, opindex, valuep,
136 1 /* High. */, 1 /* Store. */);
143 print_register_list (void * dis_info,
146 int load_store) /* 0 == load, 1 == store. */
148 disassemble_info *info = dis_info;
160 (*info->fprintf_func) (info->stream, "r%li", reg_index + offset);
164 for (reg_index = 1; reg_index <= 7; ++reg_index)
173 (*info->fprintf_func) (info->stream, "%sr%li", comma, reg_index + offset);
180 print_hi_register_list_ld (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
183 unsigned int attrs ATTRIBUTE_UNUSED,
184 bfd_vma pc ATTRIBUTE_UNUSED,
185 int length ATTRIBUTE_UNUSED)
187 print_register_list (dis_info, value, 8, 0 /* Load. */);
191 print_low_register_list_ld (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
194 unsigned int attrs ATTRIBUTE_UNUSED,
195 bfd_vma pc ATTRIBUTE_UNUSED,
196 int length ATTRIBUTE_UNUSED)
198 print_register_list (dis_info, value, 0, 0 /* Load. */);
202 print_hi_register_list_st (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
205 unsigned int attrs ATTRIBUTE_UNUSED,
206 bfd_vma pc ATTRIBUTE_UNUSED,
207 int length ATTRIBUTE_UNUSED)
209 print_register_list (dis_info, value, 8, 1 /* Store. */);
213 print_low_register_list_st (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
216 unsigned int attrs ATTRIBUTE_UNUSED,
217 bfd_vma pc ATTRIBUTE_UNUSED,
218 int length ATTRIBUTE_UNUSED)
220 print_register_list (dis_info, value, 0, 1 /* Store. */);
224 print_m4 (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
227 unsigned int attrs ATTRIBUTE_UNUSED,
228 bfd_vma pc ATTRIBUTE_UNUSED,
229 int length ATTRIBUTE_UNUSED)
231 disassemble_info *info = (disassemble_info *) dis_info;
233 (*info->fprintf_func) (info->stream, "%ld", value);