1 /* FR30 opcode support. -*- C -*-
2 Copyright 2011 Free Software Foundation, Inc.
4 Contributed by Red Hat Inc;
6 This file is part of the GNU Binutils.
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.
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.
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. */
23 /* This file is an addendum to fr30.cpu. Heavy use of C code isn't
24 appropriate in .cpu files, so it resides here. This especially applies
25 to assembly/disassembly where parsing/printing can be quite involved.
26 Such things aren't really part of the specification of the cpu, per se,
27 so .cpu files provide the general framework and .opc files handle the
28 nitty-gritty details as necessary.
30 Each section is delimited with start and end markers.
32 <arch>-opc.h additions use: "-- opc.h"
33 <arch>-opc.c additions use: "-- opc.c"
34 <arch>-asm.c additions use: "-- asm.c"
35 <arch>-dis.c additions use: "-- dis.c"
36 <arch>-ibd.h additions use: "-- ibd.h". */
40 /* ??? This can be improved upon. */
41 #undef CGEN_DIS_HASH_SIZE
42 #define CGEN_DIS_HASH_SIZE 16
44 #define CGEN_DIS_HASH(buffer, value) (((unsigned char *) (buffer))[0] >> 4)
49 /* Handle register lists for LDMx and STMx. */
52 parse_register_number (const char **strp)
56 if (**strp < '0' || **strp > '9')
57 return -1; /* Error. */
61 if (**strp >= '0' && **strp <= '9')
63 regno = regno * 10 + (**strp - '0');
71 parse_register_list (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
73 int opindex ATTRIBUTE_UNUSED,
74 unsigned long *valuep,
75 int high_low, /* 0 == high, 1 == low. */
76 int load_store) /* 0 == load, 1 == store. */
79 while (**strp && **strp != ')')
83 if (**strp != 'R' && **strp != 'r')
87 regno = parse_register_number (strp);
89 return _("Register number is not valid");
90 if (regno > 7 && !high_low)
91 return _("Register must be between r0 and r7");
92 if (regno < 8 && high_low)
93 return _("Register must be between r8 and r15");
98 if (load_store) /* Mask is reversed for store. */
99 *valuep |= 0x80 >> regno;
101 *valuep |= 1 << regno;
105 if (*(*strp + 1) == ')')
111 if (!*strp || **strp != ')')
112 return _("Register list is not valid");
118 parse_low_register_list_ld (CGEN_CPU_DESC cd,
121 unsigned long *valuep)
123 return parse_register_list (cd, strp, opindex, valuep,
124 0 /* Low. */, 0 /* Load. */);
128 parse_hi_register_list_ld (CGEN_CPU_DESC cd,
131 unsigned long *valuep)
133 return parse_register_list (cd, strp, opindex, valuep,
134 1 /* High. */, 0 /* Load. */);
138 parse_low_register_list_st (CGEN_CPU_DESC cd,
141 unsigned long *valuep)
143 return parse_register_list (cd, strp, opindex, valuep,
144 0 /* Low. */, 1 /* Store. */);
148 parse_hi_register_list_st (CGEN_CPU_DESC cd,
151 unsigned long *valuep)
153 return parse_register_list (cd, strp, opindex, valuep,
154 1 /* High. */, 1 /* Store. */);
161 print_register_list (void * dis_info,
164 int load_store) /* 0 == load, 1 == store. */
166 disassemble_info *info = dis_info;
178 (*info->fprintf_func) (info->stream, "r%li", reg_index + offset);
182 for (reg_index = 1; reg_index <= 7; ++reg_index)
191 (*info->fprintf_func) (info->stream, "%sr%li", comma, reg_index + offset);
198 print_hi_register_list_ld (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
201 unsigned int attrs ATTRIBUTE_UNUSED,
202 bfd_vma pc ATTRIBUTE_UNUSED,
203 int length ATTRIBUTE_UNUSED)
205 print_register_list (dis_info, value, 8, 0 /* Load. */);
209 print_low_register_list_ld (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
212 unsigned int attrs ATTRIBUTE_UNUSED,
213 bfd_vma pc ATTRIBUTE_UNUSED,
214 int length ATTRIBUTE_UNUSED)
216 print_register_list (dis_info, value, 0, 0 /* Load. */);
220 print_hi_register_list_st (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
223 unsigned int attrs ATTRIBUTE_UNUSED,
224 bfd_vma pc ATTRIBUTE_UNUSED,
225 int length ATTRIBUTE_UNUSED)
227 print_register_list (dis_info, value, 8, 1 /* Store. */);
231 print_low_register_list_st (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
234 unsigned int attrs ATTRIBUTE_UNUSED,
235 bfd_vma pc ATTRIBUTE_UNUSED,
236 int length ATTRIBUTE_UNUSED)
238 print_register_list (dis_info, value, 0, 1 /* Store. */);
242 print_m4 (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
245 unsigned int attrs ATTRIBUTE_UNUSED,
246 bfd_vma pc ATTRIBUTE_UNUSED,
247 int length ATTRIBUTE_UNUSED)
249 disassemble_info *info = (disassemble_info *) dis_info;
251 (*info->fprintf_func) (info->stream, "%ld", value);