1 /* FR30 opcode support. -*- C -*-
2 Copyright (C) 2000 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"
23 /* ??? This can be improved upon. */
24 #undef CGEN_DIS_HASH_SIZE
25 #define CGEN_DIS_HASH_SIZE 16
27 #define CGEN_DIS_HASH(buffer, value) (((unsigned char *) (buffer))[0] >> 4)
32 /* Handle register lists for LDMx and STMx */
35 parse_register_number (strp)
39 if (**strp < '0' || **strp > '9')
40 return -1; /* error */
44 if (**strp >= '0' && **strp <= '9')
46 regno = regno * 10 + (**strp - '0');
54 parse_register_list (cd, strp, opindex, valuep, high_low, load_store)
58 unsigned long *valuep;
59 int high_low; /* 0 == high, 1 == low */
60 int load_store; /* 0 == load, 1 == store */
64 while (**strp && **strp != ')')
66 if (**strp != 'R' && **strp != 'r')
70 regno = parse_register_number (strp);
72 return "Register number is not valid";
73 if (regno > 7 && !high_low)
74 return "Register must be between r0 and r7";
75 if (regno < 8 && high_low)
76 return "Register must be between r8 and r15";
81 if (load_store) /* mask is reversed for store */
82 *valuep |= 0x80 >> regno;
84 *valuep |= 1 << regno;
88 if (*(*strp + 1) == ')')
94 if (!*strp || **strp != ')')
95 return "Register list is not valid";
101 parse_low_register_list_ld (cd, strp, opindex, valuep)
105 unsigned long *valuep;
107 return parse_register_list (cd, strp, opindex, valuep, 0/*low*/, 0/*load*/);
111 parse_hi_register_list_ld (cd, strp, opindex, valuep)
115 unsigned long *valuep;
117 return parse_register_list (cd, strp, opindex, valuep, 1/*high*/, 0/*load*/);
121 parse_low_register_list_st (cd, strp, opindex, valuep)
125 unsigned long *valuep;
127 return parse_register_list (cd, strp, opindex, valuep, 0/*low*/, 1/*store*/);
131 parse_hi_register_list_st (cd, strp, opindex, valuep)
135 unsigned long *valuep;
137 return parse_register_list (cd, strp, opindex, valuep, 1/*high*/, 1/*store*/);
145 print_register_list (dis_info, value, offset, load_store)
149 int load_store; /* 0 == load, 1 == store */
151 disassemble_info *info = dis_info;
163 (*info->fprintf_func) (info->stream, "r%i", index + offset);
167 for (index = 1; index <= 7; ++index)
176 (*info->fprintf_func) (info->stream, "%sr%i", comma, index + offset);
183 print_hi_register_list_ld (cd, dis_info, value, attrs, pc, length)
191 print_register_list (dis_info, value, 8, 0/*load*/);
195 print_low_register_list_ld (cd, dis_info, value, attrs, pc, length)
203 print_register_list (dis_info, value, 0, 0/*load*/);
207 print_hi_register_list_st (cd, dis_info, value, attrs, pc, length)
215 print_register_list (dis_info, value, 8, 1/*store*/);
219 print_low_register_list_st (cd, dis_info, value, attrs, pc, length)
227 print_register_list (dis_info, value, 0, 1/*store*/);
231 print_m4 (cd, dis_info, value, attrs, pc, length)
239 disassemble_info *info = (disassemble_info *) dis_info;
240 (*info->fprintf_func) (info->stream, "%ld", value);