OSDN Git Service

From 2001-03-01 Tom Rix <trix@redhat.com>:
[pf3gnuchains/pf3gnuchains3x.git] / cgen / fr30.opc
1 /* FR30 opcode support.  -*- C -*-
2    Copyright (C) 2000 Red Hat, Inc.
3    This file is part of CGEN.  */
4
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.
11
12    Each section is delimited with start and end markers.
13
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"
19 */
20 \f
21 /* -- opc.h */
22
23 /* ??? This can be improved upon.  */
24 #undef CGEN_DIS_HASH_SIZE
25 #define CGEN_DIS_HASH_SIZE 16
26 #undef CGEN_DIS_HASH
27 #define CGEN_DIS_HASH(buffer, value) (((unsigned char *) (buffer))[0] >> 4)
28
29 /* -- */
30 \f
31 /* -- asm.c */
32 /* Handle register lists for LDMx and STMx  */
33
34 static int
35 parse_register_number (strp)
36      const char **strp;
37 {
38   int regno;
39   if (**strp < '0' || **strp > '9')
40     return -1; /* error */
41   regno = **strp - '0';
42   ++*strp;
43
44   if (**strp >= '0' && **strp <= '9')
45     {
46       regno = regno * 10 + (**strp - '0');
47       ++*strp;
48     }
49
50   return regno;
51 }
52
53 static const char *
54 parse_register_list (cd, strp, opindex, valuep, high_low, load_store)
55      CGEN_CPU_DESC cd;
56      const char **strp;
57      int opindex;
58      unsigned long *valuep;
59      int high_low;   /* 0 == high, 1 == low */
60      int load_store; /* 0 == load, 1 == store */
61 {
62   int regno;
63   *valuep = 0;
64   while (**strp && **strp != ')')
65     {
66       if (**strp != 'R' && **strp != 'r')
67         break;
68       ++*strp;
69
70       regno = parse_register_number (strp);
71       if (regno == -1)
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";
77
78       if (high_low)
79         regno -= 8;
80
81       if (load_store) /* mask is reversed for store */
82         *valuep |= 0x80 >> regno;
83       else
84         *valuep |= 1 << regno;
85
86       if (**strp == ',')
87         {
88           if (*(*strp + 1) == ')')
89             break;
90           ++*strp;
91         }
92     }
93
94   if (!*strp || **strp != ')')
95     return "Register list is not valid";
96
97   return NULL;
98 }
99
100 static const char *
101 parse_low_register_list_ld (cd, strp, opindex, valuep)
102      CGEN_CPU_DESC cd;
103      const char **strp;
104      int opindex;
105      unsigned long *valuep;
106 {
107   return parse_register_list (cd, strp, opindex, valuep, 0/*low*/, 0/*load*/);
108 }
109
110 static const char *
111 parse_hi_register_list_ld (cd, strp, opindex, valuep)
112      CGEN_CPU_DESC cd;
113      const char **strp;
114      int opindex;
115      unsigned long *valuep;
116 {
117   return parse_register_list (cd, strp, opindex, valuep, 1/*high*/, 0/*load*/);
118 }
119
120 static const char *
121 parse_low_register_list_st (cd, strp, opindex, valuep)
122      CGEN_CPU_DESC cd;
123      const char **strp;
124      int opindex;
125      unsigned long *valuep;
126 {
127   return parse_register_list (cd, strp, opindex, valuep, 0/*low*/, 1/*store*/);
128 }
129
130 static const char *
131 parse_hi_register_list_st (cd, strp, opindex, valuep)
132      CGEN_CPU_DESC cd;
133      const char **strp;
134      int opindex;
135      unsigned long *valuep;
136 {
137   return parse_register_list (cd, strp, opindex, valuep, 1/*high*/, 1/*store*/);
138 }
139
140 /* -- */
141
142 /* -- dis.c */
143
144 static void
145 print_register_list (dis_info, value, offset, load_store)
146      PTR dis_info;
147      long value;
148      long offset;
149      int load_store; /* 0 == load, 1 == store */
150 {
151   disassemble_info *info = dis_info;
152   int mask;
153   int index = 0;
154   char* comma = "";
155
156   if (load_store)
157     mask = 0x80;
158   else
159     mask = 1;
160
161   if (value & mask)
162     {
163       (*info->fprintf_func) (info->stream, "r%i", index + offset);
164       comma = ",";
165     }
166     
167   for (index = 1; index <= 7; ++index)
168     {
169       if (load_store)
170         mask >>= 1;
171       else
172         mask <<= 1;
173
174       if (value & mask)
175         {
176           (*info->fprintf_func) (info->stream, "%sr%i", comma, index + offset);
177           comma = ",";
178         }
179     }
180 }
181
182 static void
183 print_hi_register_list_ld (cd, dis_info, value, attrs, pc, length)
184      CGEN_CPU_DESC cd;
185      PTR dis_info;
186      long value;
187      unsigned int attrs;
188      bfd_vma pc;
189      int length;
190 {
191   print_register_list (dis_info, value, 8, 0/*load*/);
192 }
193
194 static void
195 print_low_register_list_ld (cd, dis_info, value, attrs, pc, length)
196      CGEN_CPU_DESC cd;
197      PTR dis_info;
198      long value;
199      unsigned int attrs;
200      bfd_vma pc;
201      int length;
202 {
203   print_register_list (dis_info, value, 0, 0/*load*/);
204 }
205
206 static void
207 print_hi_register_list_st (cd, dis_info, value, attrs, pc, length)
208      CGEN_CPU_DESC cd;
209      PTR dis_info;
210      long value;
211      unsigned int attrs;
212      bfd_vma pc;
213      int length;
214 {
215   print_register_list (dis_info, value, 8, 1/*store*/);
216 }
217
218 static void
219 print_low_register_list_st (cd, dis_info, value, attrs, pc, length)
220      CGEN_CPU_DESC cd;
221      PTR dis_info;
222      long value;
223      unsigned int attrs;
224      bfd_vma pc;
225      int length;
226 {
227   print_register_list (dis_info, value, 0, 1/*store*/);
228 }
229
230 static void
231 print_m4 (cd, dis_info, value, attrs, pc, length)
232      CGEN_CPU_DESC cd;
233      PTR dis_info;
234      long value;
235      unsigned int attrs;
236      bfd_vma pc;
237      int length;
238 {
239   disassemble_info *info = (disassemble_info *) dis_info;
240   (*info->fprintf_func) (info->stream, "%ld", value);
241 }
242 /* -- */