OSDN Git Service

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