Fix compile time warnings generated by gcc 4.0
[deliverable/binutils-gdb.git] / cpu / frv.opc
1 /* Fujitsu FRV opcode support, for GNU Binutils. -*- C -*-
2
3 Copyright 2000, 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
4
5 Contributed by Red Hat Inc; developed under contract from Fujitsu.
6
7 This file is part of the GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
23 */
24
25 /* This file is an addendum to frv.cpu. Heavy use of C code isn't
26 appropriate in .cpu files, so it resides here. This especially applies
27 to assembly/disassembly where parsing/printing can be quite involved.
28 Such things aren't really part of the specification of the cpu, per se,
29 so .cpu files provide the general framework and .opc files handle the
30 nitty-gritty details as necessary.
31
32 Each section is delimited with start and end markers.
33
34 <arch>-opc.h additions use: "-- opc.h"
35 <arch>-opc.c additions use: "-- opc.c"
36 <arch>-asm.c additions use: "-- asm.c"
37 <arch>-dis.c additions use: "-- dis.c"
38 <arch>-ibd.h additions use: "-- ibd.h"
39 */
40 \f
41 /* -- opc.h */
42
43 #undef CGEN_DIS_HASH_SIZE
44 #define CGEN_DIS_HASH_SIZE 128
45 #undef CGEN_DIS_HASH
46 #define CGEN_DIS_HASH(buffer, value) (((value) >> 18) & 127)
47
48 /* Allows reason codes to be output when assembler errors occur. */
49 #define CGEN_VERBOSE_ASSEMBLER_ERRORS
50
51 /* Vliw support. */
52 #define FRV_VLIW_SIZE 8 /* fr550 has largest vliw size of 8. */
53 #define PAD_VLIW_COMBO ,UNIT_NIL,UNIT_NIL,UNIT_NIL,UNIT_NIL
54 typedef CGEN_ATTR_VALUE_TYPE VLIW_COMBO[FRV_VLIW_SIZE];
55
56 typedef struct
57 {
58 int next_slot;
59 int constraint_violation;
60 unsigned long mach;
61 unsigned long elf_flags;
62 CGEN_ATTR_VALUE_TYPE *unit_mapping;
63 VLIW_COMBO *current_vliw;
64 CGEN_ATTR_VALUE_TYPE major[FRV_VLIW_SIZE];
65 const CGEN_INSN* insn[FRV_VLIW_SIZE];
66 } FRV_VLIW;
67
68 int frv_is_branch_major PARAMS ((CGEN_ATTR_VALUE_TYPE, unsigned long));
69 int frv_is_float_major PARAMS ((CGEN_ATTR_VALUE_TYPE, unsigned long));
70 int frv_is_media_major PARAMS ((CGEN_ATTR_VALUE_TYPE, unsigned long));
71 int frv_is_branch_insn PARAMS ((const CGEN_INSN *));
72 int frv_is_float_insn PARAMS ((const CGEN_INSN *));
73 int frv_is_media_insn PARAMS ((const CGEN_INSN *));
74 void frv_vliw_reset PARAMS ((FRV_VLIW *, unsigned long mach, unsigned long elf_flags));
75 int frv_vliw_add_insn PARAMS ((FRV_VLIW *, const CGEN_INSN *));
76 int spr_valid PARAMS ((long));
77 /* -- */
78 \f
79 /* -- opc.c */
80 #include "elf/frv.h"
81 #include <stdio.h>
82
83 static int match_unit
84 PARAMS ((FRV_VLIW *, CGEN_ATTR_VALUE_TYPE, CGEN_ATTR_VALUE_TYPE));
85 static int match_vliw
86 PARAMS ((VLIW_COMBO *, VLIW_COMBO *, int));
87 static VLIW_COMBO * add_next_to_vliw
88 PARAMS ((FRV_VLIW *, CGEN_ATTR_VALUE_TYPE));
89 static int find_major_in_vliw
90 PARAMS ((FRV_VLIW *, CGEN_ATTR_VALUE_TYPE));
91 static int fr400_check_insn_major_constraints
92 PARAMS ((FRV_VLIW *, CGEN_ATTR_VALUE_TYPE));
93 static int fr450_check_insn_major_constraints
94 PARAMS ((FRV_VLIW *, CGEN_ATTR_VALUE_TYPE));
95 static int fr500_check_insn_major_constraints
96 PARAMS ((FRV_VLIW *, CGEN_ATTR_VALUE_TYPE));
97 static int fr550_check_insn_major_constraints
98 PARAMS ((FRV_VLIW *, CGEN_ATTR_VALUE_TYPE, const CGEN_INSN *));
99 static int check_insn_major_constraints
100 PARAMS ((FRV_VLIW *, CGEN_ATTR_VALUE_TYPE, const CGEN_INSN *));
101
102 int
103 frv_is_branch_major (CGEN_ATTR_VALUE_TYPE major, unsigned long mach)
104 {
105 switch (mach)
106 {
107 case bfd_mach_fr400:
108 if (major >= FR400_MAJOR_B_1 && major <= FR400_MAJOR_B_6)
109 return 1; /* is a branch */
110 break;
111 case bfd_mach_fr450:
112 if (major >= FR450_MAJOR_B_1 && major <= FR450_MAJOR_B_6)
113 return 1; /* is a branch */
114 break;
115 default:
116 if (major >= FR500_MAJOR_B_1 && major <= FR500_MAJOR_B_6)
117 return 1; /* is a branch */
118 break;
119 }
120
121 return 0; /* not a branch */
122 }
123
124 int
125 frv_is_float_major (CGEN_ATTR_VALUE_TYPE major, unsigned long mach)
126 {
127 switch (mach)
128 {
129 case bfd_mach_fr400:
130 case bfd_mach_fr450:
131 return 0; /* No float insns */
132 default:
133 if (major >= FR500_MAJOR_F_1 && major <= FR500_MAJOR_F_8)
134 return 1; /* is a float insn */
135 break;
136 }
137
138 return 0; /* not a branch */
139 }
140
141 int
142 frv_is_media_major (CGEN_ATTR_VALUE_TYPE major, unsigned long mach)
143 {
144 switch (mach)
145 {
146 case bfd_mach_fr400:
147 if (major >= FR400_MAJOR_M_1 && major <= FR400_MAJOR_M_2)
148 return 1; /* is a media insn */
149 break;
150 case bfd_mach_fr450:
151 if (major >= FR450_MAJOR_M_1 && major <= FR450_MAJOR_M_6)
152 return 1; /* is a media insn */
153 break;
154 default:
155 if (major >= FR500_MAJOR_M_1 && major <= FR500_MAJOR_M_8)
156 return 1; /* is a media insn */
157 break;
158 }
159
160 return 0; /* not a branch */
161 }
162
163 int
164 frv_is_branch_insn (const CGEN_INSN *insn)
165 {
166 if (frv_is_branch_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR400_MAJOR),
167 bfd_mach_fr400))
168 return 1;
169 if (frv_is_branch_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR450_MAJOR),
170 bfd_mach_fr450))
171 return 1;
172 if (frv_is_branch_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR500_MAJOR),
173 bfd_mach_fr500))
174 return 1;
175
176 return 0;
177 }
178
179 int
180 frv_is_float_insn (const CGEN_INSN *insn)
181 {
182 if (frv_is_float_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR400_MAJOR),
183 bfd_mach_fr400))
184 return 1;
185 if (frv_is_float_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR450_MAJOR),
186 bfd_mach_fr450))
187 return 1;
188 if (frv_is_float_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR500_MAJOR),
189 bfd_mach_fr500))
190 return 1;
191
192 return 0;
193 }
194
195 int
196 frv_is_media_insn (const CGEN_INSN *insn)
197 {
198 if (frv_is_media_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR400_MAJOR),
199 bfd_mach_fr400))
200 return 1;
201 if (frv_is_media_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR450_MAJOR),
202 bfd_mach_fr450))
203 return 1;
204 if (frv_is_media_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR500_MAJOR),
205 bfd_mach_fr500))
206 return 1;
207
208 return 0;
209 }
210
211 /* This table represents the allowable packing for vliw insns for the fr400.
212 The fr400 has only 2 vliw slots. Represent this by not allowing any insns
213 in the extra slots.
214 Subsets of any given row are also allowed. */
215 static VLIW_COMBO fr400_allowed_vliw[] =
216 {
217 /* slot0 slot1 slot2 slot3 */
218 { UNIT_I0, UNIT_I1, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO },
219 { UNIT_I0, UNIT_FM0, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO },
220 { UNIT_I0, UNIT_B0, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO },
221 { UNIT_FM0, UNIT_FM1, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO },
222 { UNIT_FM0, UNIT_B0, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO },
223 { UNIT_B0, UNIT_NIL, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO },
224 { UNIT_C, UNIT_NIL, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO },
225 { UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO }
226 };
227
228 /* This table represents the allowable packing for vliw insns for the fr500.
229 The fr500 has only 4 vliw slots. Represent this by not allowing any insns
230 in the extra slots.
231 Subsets of any given row are also allowed. */
232 static VLIW_COMBO fr500_allowed_vliw[] =
233 {
234 /* slot0 slot1 slot2 slot3 */
235 { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1 PAD_VLIW_COMBO },
236 { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_B0 PAD_VLIW_COMBO },
237 { UNIT_I0, UNIT_FM0, UNIT_FM1, UNIT_B0 PAD_VLIW_COMBO },
238 { UNIT_I0, UNIT_FM0, UNIT_B0, UNIT_B1 PAD_VLIW_COMBO },
239 { UNIT_I0, UNIT_I1, UNIT_B0, UNIT_B1 PAD_VLIW_COMBO },
240 { UNIT_I0, UNIT_B0, UNIT_B1, UNIT_NIL PAD_VLIW_COMBO },
241 { UNIT_FM0, UNIT_FM1, UNIT_B0, UNIT_B1 PAD_VLIW_COMBO },
242 { UNIT_FM0, UNIT_B0, UNIT_B1, UNIT_NIL PAD_VLIW_COMBO },
243 { UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO },
244 { UNIT_C, UNIT_NIL, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO },
245 { UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO }
246 };
247
248 /* This table represents the allowable packing for vliw insns for the fr550.
249 Subsets of any given row are also allowed. */
250 static VLIW_COMBO fr550_allowed_vliw[] =
251 {
252 /* slot0 slot1 slot2 slot3 slot4 slot5 slot6 slot7 */
253 { UNIT_I0, UNIT_I1, UNIT_I2, UNIT_I3, UNIT_B0, UNIT_B1 , UNIT_NIL, UNIT_NIL },
254 { UNIT_I0, UNIT_I1, UNIT_I2, UNIT_B0, UNIT_B1 , UNIT_NIL, UNIT_NIL, UNIT_NIL },
255 { UNIT_I0, UNIT_I1, UNIT_B0, UNIT_B1 , UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL },
256 { UNIT_I0, UNIT_B0, UNIT_B1 , UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL },
257 { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1, UNIT_I2, UNIT_FM2, UNIT_I3, UNIT_FM3 },
258 { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1, UNIT_I2, UNIT_FM2, UNIT_I3, UNIT_B0 },
259 { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1, UNIT_I2, UNIT_FM2, UNIT_FM3, UNIT_B0 },
260 { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1, UNIT_I2, UNIT_FM2, UNIT_B0, UNIT_B1 },
261 { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1, UNIT_I2, UNIT_I3, UNIT_B0, UNIT_B1 },
262 { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1, UNIT_I2, UNIT_B0, UNIT_B1, UNIT_NIL },
263 { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1, UNIT_FM2, UNIT_FM3, UNIT_B0, UNIT_B1 },
264 { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1, UNIT_FM2, UNIT_FM3, UNIT_B0, UNIT_B1 },
265 { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1, UNIT_FM2, UNIT_B0, UNIT_B1, UNIT_NIL },
266 { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1, UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL },
267 { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_I2, UNIT_I3, UNIT_B0, UNIT_B1, UNIT_NIL },
268 { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_I2, UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL },
269 { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL, UNIT_NIL },
270 { UNIT_I0, UNIT_FM0, UNIT_FM1, UNIT_FM2, UNIT_FM3, UNIT_B0, UNIT_B1, UNIT_NIL },
271 { UNIT_I0, UNIT_FM0, UNIT_FM1, UNIT_FM2, UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL },
272 { UNIT_I0, UNIT_FM0, UNIT_FM1, UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL, UNIT_NIL },
273 { UNIT_I0, UNIT_FM0, UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL },
274 { UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL },
275 { UNIT_C, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL },
276 { UNIT_FM0, UNIT_FM1, UNIT_FM2, UNIT_FM3, UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL },
277 { UNIT_FM0, UNIT_FM1, UNIT_FM2, UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL, UNIT_NIL },
278 { UNIT_FM0, UNIT_FM1, UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL },
279 { UNIT_FM0, UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL },
280 { UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL }
281 };
282
283 /* Some insns are assigned specialized implementation units which map to
284 different actual implementation units on different machines. These
285 tables perform that mapping. */
286 static CGEN_ATTR_VALUE_TYPE fr400_unit_mapping[] =
287 {
288 /* unit in insn actual unit */
289 /* NIL */ UNIT_NIL,
290 /* I0 */ UNIT_I0,
291 /* I1 */ UNIT_I1,
292 /* I01 */ UNIT_I01,
293 /* I2 */ UNIT_NIL, /* no I2 or I3 unit */
294 /* I3 */ UNIT_NIL,
295 /* IALL */ UNIT_I01, /* only I0 and I1 units */
296 /* FM0 */ UNIT_FM0,
297 /* FM1 */ UNIT_FM1,
298 /* FM01 */ UNIT_FM01,
299 /* FM2 */ UNIT_NIL, /* no F2 or M2 units */
300 /* FM3 */ UNIT_NIL, /* no F3 or M3 units */
301 /* FMALL */ UNIT_FM01,/* Only F0,F1,M0,M1 units */
302 /* FMLOW */ UNIT_FM0, /* Only F0,M0 units */
303 /* B0 */ UNIT_B0, /* branches only in B0 unit. */
304 /* B1 */ UNIT_B0,
305 /* B01 */ UNIT_B0,
306 /* C */ UNIT_C,
307 /* MULT-DIV */ UNIT_I0, /* multiply and divide only in I0 unit. */
308 /* IACC */ UNIT_I01, /* iacc multiply in I0 or I1 unit. */
309 /* LOAD */ UNIT_I0, /* load only in I0 unit. */
310 /* STORE */ UNIT_I0, /* store only in I0 unit. */
311 /* SCAN */ UNIT_I0, /* scan only in I0 unit. */
312 /* DCPL */ UNIT_C, /* dcpl only in C unit. */
313 /* MDUALACC */ UNIT_FM0, /* media dual acc insn only in FM0 unit. */
314 /* MDCUTSSI */ UNIT_FM0, /* mdcutssi only in FM0 unit. */
315 /* MCLRACC-1*/ UNIT_FM0 /* mclracc,A==1 insn only in FM0 unit. */
316 };
317
318 /* Some insns are assigned specialized implementation units which map to
319 different actual implementation units on different machines. These
320 tables perform that mapping. */
321 static CGEN_ATTR_VALUE_TYPE fr450_unit_mapping[] =
322 {
323 /* unit in insn actual unit */
324 /* NIL */ UNIT_NIL,
325 /* I0 */ UNIT_I0,
326 /* I1 */ UNIT_I1,
327 /* I01 */ UNIT_I01,
328 /* I2 */ UNIT_NIL, /* no I2 or I3 unit */
329 /* I3 */ UNIT_NIL,
330 /* IALL */ UNIT_I01, /* only I0 and I1 units */
331 /* FM0 */ UNIT_FM0,
332 /* FM1 */ UNIT_FM1,
333 /* FM01 */ UNIT_FM01,
334 /* FM2 */ UNIT_NIL, /* no F2 or M2 units */
335 /* FM3 */ UNIT_NIL, /* no F3 or M3 units */
336 /* FMALL */ UNIT_FM01,/* Only F0,F1,M0,M1 units */
337 /* FMLOW */ UNIT_FM0, /* Only F0,M0 units */
338 /* B0 */ UNIT_B0, /* branches only in B0 unit. */
339 /* B1 */ UNIT_B0,
340 /* B01 */ UNIT_B0,
341 /* C */ UNIT_C,
342 /* MULT-DIV */ UNIT_I0, /* multiply and divide only in I0 unit. */
343 /* IACC */ UNIT_I01, /* iacc multiply in I0 or I1 unit. */
344 /* LOAD */ UNIT_I0, /* load only in I0 unit. */
345 /* STORE */ UNIT_I0, /* store only in I0 unit. */
346 /* SCAN */ UNIT_I0, /* scan only in I0 unit. */
347 /* DCPL */ UNIT_I0, /* dcpl only in I0 unit. */
348 /* MDUALACC */ UNIT_FM0, /* media dual acc insn only in FM0 unit. */
349 /* MDCUTSSI */ UNIT_FM01, /* mdcutssi in FM0 or FM1. */
350 /* MCLRACC-1*/ UNIT_FM0 /* mclracc,A==1 insn only in FM0 unit. */
351 };
352
353 static CGEN_ATTR_VALUE_TYPE fr500_unit_mapping[] =
354 {
355 /* unit in insn actual unit */
356 /* NIL */ UNIT_NIL,
357 /* I0 */ UNIT_I0,
358 /* I1 */ UNIT_I1,
359 /* I01 */ UNIT_I01,
360 /* I2 */ UNIT_NIL, /* no I2 or I3 unit */
361 /* I3 */ UNIT_NIL,
362 /* IALL */ UNIT_I01, /* only I0 and I1 units */
363 /* FM0 */ UNIT_FM0,
364 /* FM1 */ UNIT_FM1,
365 /* FM01 */ UNIT_FM01,
366 /* FM2 */ UNIT_NIL, /* no F2 or M2 units */
367 /* FM3 */ UNIT_NIL, /* no F3 or M2 units */
368 /* FMALL */ UNIT_FM01,/* Only F0,F1,M0,M1 units */
369 /* FMLOW */ UNIT_FM0, /* Only F0,M0 units */
370 /* B0 */ UNIT_B0,
371 /* B1 */ UNIT_B1,
372 /* B01 */ UNIT_B01,
373 /* C */ UNIT_C,
374 /* MULT-DIV */ UNIT_I01, /* multiply and divide in I0 or I1 unit. */
375 /* IACC */ UNIT_NIL, /* iacc multiply not implemented */
376 /* LOAD */ UNIT_I01, /* load in I0 or I1 unit. */
377 /* STORE */ UNIT_I0, /* store only in I0 unit. */
378 /* SCAN */ UNIT_I01, /* scan in I0 or I1 unit. */
379 /* DCPL */ UNIT_C, /* dcpl only in C unit. */
380 /* MDUALACC */ UNIT_FM0, /* media dual acc insn only in FM0 unit. */
381 /* MDCUTSSI */ UNIT_FM0, /* mdcutssi only in FM0 unit. */
382 /* MCLRACC-1*/ UNIT_FM01 /* mclracc,A==1 in FM0 or FM1 unit. */
383 };
384
385 static CGEN_ATTR_VALUE_TYPE fr550_unit_mapping[] =
386 {
387 /* unit in insn actual unit */
388 /* NIL */ UNIT_NIL,
389 /* I0 */ UNIT_I0,
390 /* I1 */ UNIT_I1,
391 /* I01 */ UNIT_I01,
392 /* I2 */ UNIT_I2,
393 /* I3 */ UNIT_I3,
394 /* IALL */ UNIT_IALL,
395 /* FM0 */ UNIT_FM0,
396 /* FM1 */ UNIT_FM1,
397 /* FM01 */ UNIT_FM01,
398 /* FM2 */ UNIT_FM2,
399 /* FM3 */ UNIT_FM3,
400 /* FMALL */ UNIT_FMALL,
401 /* FMLOW */ UNIT_FM01, /* Only F0,F1,M0,M1 units */
402 /* B0 */ UNIT_B0,
403 /* B1 */ UNIT_B1,
404 /* B01 */ UNIT_B01,
405 /* C */ UNIT_C,
406 /* MULT-DIV */ UNIT_I01, /* multiply and divide in I0 or I1 unit. */
407 /* IACC */ UNIT_NIL, /* iacc multiply not implemented. */
408 /* LOAD */ UNIT_I01, /* load in I0 or I1 unit. */
409 /* STORE */ UNIT_I01, /* store in I0 or I1 unit. */
410 /* SCAN */ UNIT_IALL, /* scan in any integer unit. */
411 /* DCPL */ UNIT_I0, /* dcpl only in I0 unit. */
412 /* MDUALACC */ UNIT_FMALL,/* media dual acc insn in all media units */
413 /* MDCUTSSI */ UNIT_FM01, /* mdcutssi in FM0 or FM1 unit. */
414 /* MCLRACC-1*/ UNIT_FM01 /* mclracc,A==1 in FM0 or FM1 unit. */
415 };
416
417 void
418 frv_vliw_reset (FRV_VLIW *vliw, unsigned long mach, unsigned long elf_flags)
419 {
420 vliw->next_slot = 0;
421 vliw->constraint_violation = 0;
422 vliw->mach = mach;
423 vliw->elf_flags = elf_flags;
424
425 switch (mach)
426 {
427 case bfd_mach_fr400:
428 vliw->current_vliw = fr400_allowed_vliw;
429 vliw->unit_mapping = fr400_unit_mapping;
430 break;
431 case bfd_mach_fr450:
432 vliw->current_vliw = fr400_allowed_vliw;
433 vliw->unit_mapping = fr450_unit_mapping;
434 break;
435 case bfd_mach_fr550:
436 vliw->current_vliw = fr550_allowed_vliw;
437 vliw->unit_mapping = fr550_unit_mapping;
438 break;
439 default:
440 vliw->current_vliw = fr500_allowed_vliw;
441 vliw->unit_mapping = fr500_unit_mapping;
442 break;
443 }
444 }
445
446 /* Return 1 if unit1 is a match for unit2.
447 Unit1 comes from the insn's UNIT attribute. unit2 comes from one of the
448 *_allowed_vliw tables above. */
449 static int
450 match_unit (FRV_VLIW *vliw,
451 CGEN_ATTR_VALUE_TYPE unit1, CGEN_ATTR_VALUE_TYPE unit2)
452 {
453 /* Map any specialized implementation units to actual ones. */
454 unit1 = vliw->unit_mapping[unit1];
455
456 if (unit1 == unit2)
457 return 1;
458 if (unit1 < unit2)
459 return 0;
460
461 switch (unit1)
462 {
463 case UNIT_I01:
464 case UNIT_FM01:
465 case UNIT_B01:
466 /* The 01 versions of these units are within 2 enums of the 0 or 1
467 versions. */
468 if (unit1 - unit2 <= 2)
469 return 1;
470 break;
471 case UNIT_IALL:
472 case UNIT_FMALL:
473 /* The ALL versions of these units are within 5 enums of the 0, 1, 2 or 3
474 versions. */
475 if (unit1 - unit2 <= 5)
476 return 1;
477 break;
478 default:
479 break;
480 }
481
482 return 0;
483 }
484
485 /* Return 1 if the vliws match, 0 otherwise. */
486
487 static int
488 match_vliw (VLIW_COMBO *vliw1, VLIW_COMBO *vliw2, int vliw_size)
489 {
490 int i;
491
492 for (i = 0; i < vliw_size; ++i)
493 {
494 if ((*vliw1)[i] != (*vliw2)[i])
495 return 0;
496 }
497
498 return 1;
499 }
500
501 /* Find the next vliw vliw in the table that can accomodate the new insn.
502 If one is found then return it. Otherwise return NULL. */
503
504 static VLIW_COMBO *
505 add_next_to_vliw (FRV_VLIW *vliw, CGEN_ATTR_VALUE_TYPE unit)
506 {
507 int next = vliw->next_slot;
508 VLIW_COMBO *current = vliw->current_vliw;
509 VLIW_COMBO *potential;
510
511 if (next <= 0)
512 {
513 fprintf (stderr, "frv-opc.c line %d: bad vliw->next_slot value.\n",
514 __LINE__);
515 abort (); /* Should never happen */
516 }
517
518 /* The table is sorted by units allowed within slots, so vliws with
519 identical starting sequences are together. */
520 potential = current;
521 do
522 {
523 if (match_unit (vliw, unit, (*potential)[next]))
524 return potential;
525 ++potential;
526 }
527 while (match_vliw (potential, current, next));
528
529 return NULL;
530 }
531
532 /* Look for the given major insn type in the given vliw. Return 1 if found,
533 return 0 otherwise. */
534
535 static int
536 find_major_in_vliw (FRV_VLIW *vliw, CGEN_ATTR_VALUE_TYPE major)
537 {
538 int i;
539
540 for (i = 0; i < vliw->next_slot; ++i)
541 if (vliw->major[i] == major)
542 return 1;
543
544 return 0;
545 }
546
547 /* Check for constraints between the insns in the vliw due to major insn
548 types. */
549
550 static int
551 fr400_check_insn_major_constraints (
552 FRV_VLIW *vliw, CGEN_ATTR_VALUE_TYPE major
553 )
554 {
555 /* In the cpu file, all media insns are represented as being allowed in
556 both media units. This makes it easier since this is the case for fr500.
557 Catch the invalid combinations here. Insns of major class FR400_MAJOR_M_2
558 cannot coexist with any other media insn in a vliw. */
559 switch (major)
560 {
561 case FR400_MAJOR_M_2:
562 return ! find_major_in_vliw (vliw, FR400_MAJOR_M_1)
563 && ! find_major_in_vliw (vliw, FR400_MAJOR_M_2);
564 case FR400_MAJOR_M_1:
565 return !find_major_in_vliw (vliw, FR400_MAJOR_M_2);
566 default:
567 break;
568 }
569 return 1;
570 }
571
572 static int
573 fr450_check_insn_major_constraints (
574 FRV_VLIW *vliw, CGEN_ATTR_VALUE_TYPE major
575 )
576 {
577 CGEN_ATTR_VALUE_TYPE other_major;
578
579 /* Our caller guarantees there's at least one other instruction. */
580 other_major = CGEN_INSN_ATTR_VALUE (vliw->insn[0], CGEN_INSN_FR450_MAJOR);
581
582 /* (M4, M5) and (M4, M6) are allowed. */
583 if (other_major == FR450_MAJOR_M_4)
584 if (major == FR450_MAJOR_M_5 || major == FR450_MAJOR_M_6)
585 return 1;
586
587 /* Otherwise, instructions in even-numbered media categories cannot be
588 executed in parallel with other media instructions. */
589 switch (major)
590 {
591 case FR450_MAJOR_M_2:
592 case FR450_MAJOR_M_4:
593 case FR450_MAJOR_M_6:
594 return !(other_major >= FR450_MAJOR_M_1
595 && other_major <= FR450_MAJOR_M_6);
596
597 case FR450_MAJOR_M_1:
598 case FR450_MAJOR_M_3:
599 case FR450_MAJOR_M_5:
600 return !(other_major == FR450_MAJOR_M_2
601 || other_major == FR450_MAJOR_M_4
602 || other_major == FR450_MAJOR_M_6);
603
604 default:
605 return 1;
606 }
607 }
608
609 static int
610 find_unit_in_vliw (
611 FRV_VLIW *vliw, CGEN_ATTR_VALUE_TYPE unit
612 )
613 {
614 int i;
615 for (i = 0; i < vliw->next_slot; ++i)
616 if (CGEN_INSN_ATTR_VALUE (vliw->insn[i], CGEN_INSN_UNIT) == unit)
617 return 1;
618
619 return 0; /* not found */
620 }
621
622 static int
623 find_major_in_slot (
624 FRV_VLIW *vliw, CGEN_ATTR_VALUE_TYPE major, CGEN_ATTR_VALUE_TYPE slot
625 )
626 {
627 int i;
628
629 for (i = 0; i < vliw->next_slot; ++i)
630 if (vliw->major[i] == major && (*vliw->current_vliw)[i] == slot)
631 return 1;
632
633 return 0;
634 }
635
636 static int
637 fr550_find_media_in_vliw (FRV_VLIW *vliw)
638 {
639 int i;
640
641 for (i = 0; i < vliw->next_slot; ++i)
642 {
643 if (vliw->major[i] < FR550_MAJOR_M_1 || vliw->major[i] > FR550_MAJOR_M_5)
644 continue;
645
646 /* Found a media insn, however, MNOP and MCLRACC don't count. */
647 if (CGEN_INSN_NUM (vliw->insn[i]) == FRV_INSN_MNOP
648 || CGEN_INSN_NUM (vliw->insn[i]) == FRV_INSN_MCLRACC_0
649 || CGEN_INSN_NUM (vliw->insn[i]) == FRV_INSN_MCLRACC_1)
650 continue;
651
652 return 1; /* found one */
653 }
654
655 return 0;
656 }
657
658 static int
659 fr550_find_float_in_vliw (FRV_VLIW *vliw)
660 {
661 int i;
662
663 for (i = 0; i < vliw->next_slot; ++i)
664 {
665 if (vliw->major[i] < FR550_MAJOR_F_1 || vliw->major[i] > FR550_MAJOR_F_4)
666 continue;
667
668 /* Found a floating point insn, however, FNOP doesn't count. */
669 if (CGEN_INSN_NUM (vliw->insn[i]) == FRV_INSN_FNOP)
670 continue;
671
672 return 1; /* found one */
673 }
674
675 return 0;
676 }
677
678 static int
679 fr550_check_insn_major_constraints (
680 FRV_VLIW *vliw, CGEN_ATTR_VALUE_TYPE major, const CGEN_INSN *insn
681 )
682 {
683 CGEN_ATTR_VALUE_TYPE unit;
684 CGEN_ATTR_VALUE_TYPE slot = (*vliw->current_vliw)[vliw->next_slot];
685 switch (slot)
686 {
687 case UNIT_I2:
688 /* If it's a store, then there must be another store in I1 */
689 unit = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_UNIT);
690 if (unit == UNIT_STORE)
691 return find_unit_in_vliw (vliw, UNIT_STORE);
692 break;
693 case UNIT_FM2:
694 case UNIT_FM3:
695 /* Floating point insns other than FNOP in slot f2 or f3 cannot coexist with
696 media insns. */
697 if (major >= FR550_MAJOR_F_1 && major <= FR550_MAJOR_F_4
698 && CGEN_INSN_NUM (insn) != FRV_INSN_FNOP)
699 return ! fr550_find_media_in_vliw (vliw);
700 /* Media insns other than MNOP in slot m2 or m3 cannot coexist with
701 floating point insns. */
702 if (major >= FR550_MAJOR_M_1 && major <= FR550_MAJOR_M_5
703 && CGEN_INSN_NUM (insn) != FRV_INSN_MNOP)
704 return ! fr550_find_float_in_vliw (vliw);
705 /* F-2 in slot f2 or f3 cannot coexist with F-2 or F-4 in slot f1 or f2
706 respectively.
707 */
708 if (major == FR550_MAJOR_F_2)
709 return ! find_major_in_slot (vliw, FR550_MAJOR_F_2, slot - (UNIT_FM2 - UNIT_FM0))
710 && ! find_major_in_slot (vliw, FR550_MAJOR_F_4, slot - (UNIT_FM2 - UNIT_FM0));
711 /* M-2 or M-5 in slot m2 or m3 cannot coexist with M-2 in slot m1 or m2
712 respectively. */
713 if (major == FR550_MAJOR_M_2 || major == FR550_MAJOR_M_5)
714 return ! find_major_in_slot (vliw, FR550_MAJOR_M_2, slot - (UNIT_FM2 - UNIT_FM0));
715 /* M-4 in slot m2 or m3 cannot coexist with M-4 in slot m1 or m2
716 respectively. */
717 if (major == FR550_MAJOR_M_4)
718 return ! find_major_in_slot (vliw, FR550_MAJOR_M_4, slot - (UNIT_FM2 - UNIT_FM0));
719 break;
720 default:
721 break;
722 }
723 return 1; /* all ok */
724 }
725
726 static int
727 fr500_check_insn_major_constraints (
728 FRV_VLIW *vliw, CGEN_ATTR_VALUE_TYPE major
729 )
730 {
731 /* TODO: A table might be faster for some of the more complex instances
732 here. */
733 switch (major)
734 {
735 case FR500_MAJOR_I_1:
736 case FR500_MAJOR_I_4:
737 case FR500_MAJOR_I_5:
738 case FR500_MAJOR_I_6:
739 case FR500_MAJOR_B_1:
740 case FR500_MAJOR_B_2:
741 case FR500_MAJOR_B_3:
742 case FR500_MAJOR_B_4:
743 case FR500_MAJOR_B_5:
744 case FR500_MAJOR_B_6:
745 case FR500_MAJOR_F_4:
746 case FR500_MAJOR_F_8:
747 case FR500_MAJOR_M_8:
748 return 1; /* OK */
749 case FR500_MAJOR_I_2:
750 /* Cannot coexist with I-3 insn. */
751 return ! find_major_in_vliw (vliw, FR500_MAJOR_I_3);
752 case FR500_MAJOR_I_3:
753 /* Cannot coexist with I-2 insn. */
754 return ! find_major_in_vliw (vliw, FR500_MAJOR_I_2);
755 case FR500_MAJOR_F_1:
756 case FR500_MAJOR_F_2:
757 /* Cannot coexist with F-5, F-6, or M-7 insn. */
758 return ! find_major_in_vliw (vliw, FR500_MAJOR_F_5)
759 && ! find_major_in_vliw (vliw, FR500_MAJOR_F_6)
760 && ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
761 case FR500_MAJOR_F_3:
762 /* Cannot coexist with F-7, or M-7 insn. */
763 return ! find_major_in_vliw (vliw, FR500_MAJOR_F_7)
764 && ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
765 case FR500_MAJOR_F_5:
766 /* Cannot coexist with F-1, F-2, F-6, F-7, or M-7 insn. */
767 return ! find_major_in_vliw (vliw, FR500_MAJOR_F_1)
768 && ! find_major_in_vliw (vliw, FR500_MAJOR_F_2)
769 && ! find_major_in_vliw (vliw, FR500_MAJOR_F_6)
770 && ! find_major_in_vliw (vliw, FR500_MAJOR_F_7)
771 && ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
772 case FR500_MAJOR_F_6:
773 /* Cannot coexist with F-1, F-2, F-5, F-6, or M-7 insn. */
774 return ! find_major_in_vliw (vliw, FR500_MAJOR_F_1)
775 && ! find_major_in_vliw (vliw, FR500_MAJOR_F_2)
776 && ! find_major_in_vliw (vliw, FR500_MAJOR_F_5)
777 && ! find_major_in_vliw (vliw, FR500_MAJOR_F_6)
778 && ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
779 case FR500_MAJOR_F_7:
780 /* Cannot coexist with F-3, F-5, F-7, or M-7 insn. */
781 return ! find_major_in_vliw (vliw, FR500_MAJOR_F_3)
782 && ! find_major_in_vliw (vliw, FR500_MAJOR_F_5)
783 && ! find_major_in_vliw (vliw, FR500_MAJOR_F_7)
784 && ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
785 case FR500_MAJOR_M_1:
786 /* Cannot coexist with M-7 insn. */
787 return ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
788 case FR500_MAJOR_M_2:
789 case FR500_MAJOR_M_3:
790 /* Cannot coexist with M-5, M-6 or M-7 insn. */
791 return ! find_major_in_vliw (vliw, FR500_MAJOR_M_5)
792 && ! find_major_in_vliw (vliw, FR500_MAJOR_M_6)
793 && ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
794 case FR500_MAJOR_M_4:
795 /* Cannot coexist with M-6 insn. */
796 return ! find_major_in_vliw (vliw, FR500_MAJOR_M_6);
797 case FR500_MAJOR_M_5:
798 /* Cannot coexist with M-2, M-3, M-5, M-6 or M-7 insn. */
799 return ! find_major_in_vliw (vliw, FR500_MAJOR_M_2)
800 && ! find_major_in_vliw (vliw, FR500_MAJOR_M_3)
801 && ! find_major_in_vliw (vliw, FR500_MAJOR_M_5)
802 && ! find_major_in_vliw (vliw, FR500_MAJOR_M_6)
803 && ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
804 case FR500_MAJOR_M_6:
805 /* Cannot coexist with M-2, M-3, M-4, M-5, M-6 or M-7 insn. */
806 return ! find_major_in_vliw (vliw, FR500_MAJOR_M_2)
807 && ! find_major_in_vliw (vliw, FR500_MAJOR_M_3)
808 && ! find_major_in_vliw (vliw, FR500_MAJOR_M_4)
809 && ! find_major_in_vliw (vliw, FR500_MAJOR_M_5)
810 && ! find_major_in_vliw (vliw, FR500_MAJOR_M_6)
811 && ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
812 case FR500_MAJOR_M_7:
813 /* Cannot coexist with M-1, M-2, M-3, M-5, M-6 or M-7 insn. */
814 return ! find_major_in_vliw (vliw, FR500_MAJOR_M_1)
815 && ! find_major_in_vliw (vliw, FR500_MAJOR_M_2)
816 && ! find_major_in_vliw (vliw, FR500_MAJOR_M_3)
817 && ! find_major_in_vliw (vliw, FR500_MAJOR_M_5)
818 && ! find_major_in_vliw (vliw, FR500_MAJOR_M_6)
819 && ! find_major_in_vliw (vliw, FR500_MAJOR_M_7)
820 && ! find_major_in_vliw (vliw, FR500_MAJOR_F_1)
821 && ! find_major_in_vliw (vliw, FR500_MAJOR_F_2)
822 && ! find_major_in_vliw (vliw, FR500_MAJOR_F_3)
823 && ! find_major_in_vliw (vliw, FR500_MAJOR_F_5)
824 && ! find_major_in_vliw (vliw, FR500_MAJOR_F_6)
825 && ! find_major_in_vliw (vliw, FR500_MAJOR_F_7);
826 default:
827 fprintf (stderr, "frv-opc.c, line %d: bad major code, aborting.\n",
828 __LINE__);
829 abort ();
830 break;
831 }
832 return 1;
833 }
834
835 static int
836 check_insn_major_constraints (
837 FRV_VLIW *vliw, CGEN_ATTR_VALUE_TYPE major, const CGEN_INSN *insn
838 )
839 {
840 int rc;
841 switch (vliw->mach)
842 {
843 case bfd_mach_fr400:
844 rc = fr400_check_insn_major_constraints (vliw, major);
845 break;
846 case bfd_mach_fr450:
847 rc = fr450_check_insn_major_constraints (vliw, major);
848 break;
849 case bfd_mach_fr550:
850 rc = fr550_check_insn_major_constraints (vliw, major, insn);
851 break;
852 default:
853 rc = fr500_check_insn_major_constraints (vliw, major);
854 break;
855 }
856 return rc;
857 }
858
859 /* Add in insn to the VLIW vliw if possible. Return 0 if successful,
860 non-zero otherwise. */
861 int
862 frv_vliw_add_insn (FRV_VLIW *vliw, const CGEN_INSN *insn)
863 {
864 int index;
865 CGEN_ATTR_VALUE_TYPE major;
866 CGEN_ATTR_VALUE_TYPE unit;
867 VLIW_COMBO *new_vliw;
868
869 if (vliw->constraint_violation || CGEN_INSN_INVALID_P (insn))
870 return 1;
871
872 index = vliw->next_slot;
873 if (index >= FRV_VLIW_SIZE)
874 return 1;
875
876 unit = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_UNIT);
877 if (unit == UNIT_NIL)
878 {
879 fprintf (stderr, "frv-opc.c line %d: bad insn unit.\n",
880 __LINE__);
881 abort (); /* no UNIT specified for this insn in frv.cpu */
882 }
883
884 switch (vliw->mach)
885 {
886 case bfd_mach_fr400:
887 major = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR400_MAJOR);
888 break;
889 case bfd_mach_fr450:
890 major = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR450_MAJOR);
891 break;
892 case bfd_mach_fr550:
893 major = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR550_MAJOR);
894 break;
895 default:
896 major = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR500_MAJOR);
897 break;
898 }
899
900 if (index <= 0)
901 {
902 /* Any insn can be added to slot 0. */
903 while (! match_unit (vliw, unit, (*vliw->current_vliw)[0]))
904 ++vliw->current_vliw;
905 vliw->major[0] = major;
906 vliw->insn[0] = insn;
907 vliw->next_slot = 1;
908 return 0;
909 }
910
911 /* If there are already insns in the vliw(s) check to see that
912 this one can be added. Do this by finding an allowable vliw
913 combination that can accept the new insn. */
914 if (! (vliw->elf_flags & EF_FRV_NOPACK))
915 {
916 new_vliw = add_next_to_vliw (vliw, unit);
917 if (new_vliw && check_insn_major_constraints (vliw, major, insn))
918 {
919 vliw->current_vliw = new_vliw;
920 vliw->major[index] = major;
921 vliw->insn[index] = insn;
922 vliw->next_slot++;
923 return 0;
924 }
925
926 /* The frv machine supports all packing conbinations. If we fail,
927 to add the insn, then it could not be handled as if it was the fr500.
928 Just return as if it was handled ok. */
929 if (vliw->mach == bfd_mach_frv)
930 return 0;
931 }
932
933 vliw->constraint_violation = 1;
934 return 1;
935 }
936
937 int
938 spr_valid (regno)
939 long regno;
940 {
941 if (regno < 0) return 0;
942 if (regno <= 4095) return 1;
943 return 0;
944 }
945 /* -- */
946 \f
947 /* -- asm.c */
948 static const char * parse_ulo16
949 PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
950 static const char * parse_uslo16
951 PARAMS ((CGEN_CPU_DESC, const char **, int, signed long *));
952 static const char * parse_uhi16
953 PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
954 static long parse_register_number
955 PARAMS ((const char **));
956 static const char * parse_spr
957 PARAMS ((CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *));
958 static const char * parse_d12
959 PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
960 static const char * parse_s12
961 PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
962 static const char * parse_u12
963 PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
964 static const char * parse_even_register
965 PARAMS ((CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *));
966 static const char * parse_A0
967 PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
968 static const char * parse_A1
969 PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
970 static const char * parse_A
971 PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *, long));
972
973 inline static const char *
974 parse_symbolic_address (CGEN_CPU_DESC cd,
975 const char **strp,
976 int opindex,
977 int opinfo,
978 enum cgen_parse_operand_result *resultp,
979 bfd_vma *valuep)
980 {
981 enum cgen_parse_operand_result result_type;
982 const char *errmsg = (* cd->parse_operand_fn)
983 (cd, CGEN_PARSE_OPERAND_SYMBOLIC, strp, opindex, opinfo,
984 &result_type, valuep);
985
986 if (errmsg == NULL
987 && result_type != CGEN_PARSE_OPERAND_RESULT_QUEUED)
988 return "symbolic expression required";
989
990 if (resultp)
991 *resultp = result_type;
992
993 return errmsg;
994 }
995
996 static const char *
997 parse_ldd_annotation (CGEN_CPU_DESC cd,
998 const char **strp,
999 int opindex,
1000 unsigned long *valuep)
1001 {
1002 const char *errmsg;
1003 enum cgen_parse_operand_result result_type;
1004 bfd_vma value;
1005
1006 if (**strp == '#' || **strp == '%')
1007 {
1008 if (strncasecmp (*strp + 1, "tlsdesc(", 8) == 0)
1009 {
1010 *strp += 9;
1011 errmsg = parse_symbolic_address (cd, strp, opindex,
1012 BFD_RELOC_FRV_TLSDESC_RELAX,
1013 &result_type, &value);
1014 if (**strp != ')')
1015 return "missing ')'";
1016 if (valuep)
1017 *valuep = value;
1018 ++*strp;
1019 if (errmsg)
1020 return errmsg;
1021 }
1022 }
1023
1024 while (**strp == ' ' || **strp == '\t')
1025 ++*strp;
1026
1027 if (**strp != '@')
1028 return "missing `@'";
1029
1030 ++*strp;
1031
1032 return NULL;
1033 }
1034
1035 static const char *
1036 parse_call_annotation (CGEN_CPU_DESC cd,
1037 const char **strp,
1038 int opindex,
1039 unsigned long *valuep)
1040 {
1041 const char *errmsg;
1042 enum cgen_parse_operand_result result_type;
1043 bfd_vma value;
1044
1045 if (**strp == '#' || **strp == '%')
1046 {
1047 if (strncasecmp (*strp + 1, "gettlsoff(", 10) == 0)
1048 {
1049 *strp += 11;
1050 errmsg = parse_symbolic_address (cd, strp, opindex,
1051 BFD_RELOC_FRV_GETTLSOFF_RELAX,
1052 &result_type, &value);
1053 if (**strp != ')')
1054 return "missing ')'";
1055 if (valuep)
1056 *valuep = value;
1057 ++*strp;
1058 if (errmsg)
1059 return errmsg;
1060 }
1061 }
1062
1063 while (**strp == ' ' || **strp == '\t')
1064 ++*strp;
1065
1066 if (**strp != '@')
1067 return "missing `@'";
1068
1069 ++*strp;
1070
1071 return NULL;
1072 }
1073
1074 static const char *
1075 parse_ld_annotation (CGEN_CPU_DESC cd,
1076 const char **strp,
1077 int opindex,
1078 unsigned long *valuep)
1079 {
1080 const char *errmsg;
1081 enum cgen_parse_operand_result result_type;
1082 bfd_vma value;
1083
1084 if (**strp == '#' || **strp == '%')
1085 {
1086 if (strncasecmp (*strp + 1, "tlsoff(", 7) == 0)
1087 {
1088 *strp += 8;
1089 errmsg = parse_symbolic_address (cd, strp, opindex,
1090 BFD_RELOC_FRV_TLSOFF_RELAX,
1091 &result_type, &value);
1092 if (**strp != ')')
1093 return "missing ')'";
1094 if (valuep)
1095 *valuep = value;
1096 ++*strp;
1097 if (errmsg)
1098 return errmsg;
1099 }
1100 }
1101
1102 while (**strp == ' ' || **strp == '\t')
1103 ++*strp;
1104
1105 if (**strp != '@')
1106 return "missing `@'";
1107
1108 ++*strp;
1109
1110 return NULL;
1111 }
1112
1113 static const char *
1114 parse_ulo16 (cd, strp, opindex, valuep)
1115 CGEN_CPU_DESC cd;
1116 const char **strp;
1117 int opindex;
1118 unsigned long *valuep;
1119 {
1120 const char *errmsg;
1121 enum cgen_parse_operand_result result_type;
1122 bfd_vma value;
1123
1124 if (**strp == '#' || **strp == '%')
1125 {
1126 if (strncasecmp (*strp + 1, "lo(", 3) == 0)
1127 {
1128 *strp += 4;
1129 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16,
1130 &result_type, &value);
1131 if (**strp != ')')
1132 return "missing `)'";
1133 ++*strp;
1134 if (errmsg == NULL
1135 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
1136 value &= 0xffff;
1137 *valuep = value;
1138 return errmsg;
1139 }
1140 if (strncasecmp (*strp + 1, "gprello(", 8) == 0)
1141 {
1142 *strp += 9;
1143 errmsg = parse_symbolic_address (cd, strp, opindex,
1144 BFD_RELOC_FRV_GPRELLO,
1145 &result_type, &value);
1146 if (**strp != ')')
1147 return "missing ')'";
1148 ++*strp;
1149 *valuep = value;
1150 return errmsg;
1151 }
1152 else if (strncasecmp (*strp + 1, "gotlo(", 6) == 0)
1153 {
1154 *strp += 7;
1155 errmsg = parse_symbolic_address (cd, strp, opindex,
1156 BFD_RELOC_FRV_GOTLO,
1157 &result_type, &value);
1158 if (**strp != ')')
1159 return "missing ')'";
1160 ++*strp;
1161 *valuep = value;
1162 return errmsg;
1163 }
1164 else if (strncasecmp (*strp + 1, "gotfuncdesclo(", 14) == 0)
1165 {
1166 *strp += 15;
1167 errmsg = parse_symbolic_address (cd, strp, opindex,
1168 BFD_RELOC_FRV_FUNCDESC_GOTLO,
1169 &result_type, &value);
1170 if (**strp != ')')
1171 return "missing ')'";
1172 ++*strp;
1173 *valuep = value;
1174 return errmsg;
1175 }
1176 else if (strncasecmp (*strp + 1, "gotofflo(", 9) == 0)
1177 {
1178 *strp += 10;
1179 errmsg = parse_symbolic_address (cd, strp, opindex,
1180 BFD_RELOC_FRV_GOTOFFLO,
1181 &result_type, &value);
1182 if (**strp != ')')
1183 return "missing ')'";
1184 ++*strp;
1185 *valuep = value;
1186 return errmsg;
1187 }
1188 else if (strncasecmp (*strp + 1, "gotofffuncdesclo(", 17) == 0)
1189 {
1190 *strp += 18;
1191 errmsg = parse_symbolic_address (cd, strp, opindex,
1192 BFD_RELOC_FRV_FUNCDESC_GOTOFFLO,
1193 &result_type, &value);
1194 if (**strp != ')')
1195 return "missing ')'";
1196 ++*strp;
1197 *valuep = value;
1198 return errmsg;
1199 }
1200 else if (strncasecmp (*strp + 1, "gottlsdesclo(", 13) == 0)
1201 {
1202 *strp += 14;
1203 errmsg = parse_symbolic_address (cd, strp, opindex,
1204 BFD_RELOC_FRV_GOTTLSDESCLO,
1205 &result_type, &value);
1206 if (**strp != ')')
1207 return "missing ')'";
1208 ++*strp;
1209 *valuep = value;
1210 return errmsg;
1211 }
1212 else if (strncasecmp (*strp + 1, "tlsmofflo(", 10) == 0)
1213 {
1214 *strp += 11;
1215 errmsg = parse_symbolic_address (cd, strp, opindex,
1216 BFD_RELOC_FRV_TLSMOFFLO,
1217 &result_type, &value);
1218 if (**strp != ')')
1219 return "missing ')'";
1220 ++*strp;
1221 *valuep = value;
1222 return errmsg;
1223 }
1224 else if (strncasecmp (*strp + 1, "gottlsofflo(", 12) == 0)
1225 {
1226 *strp += 13;
1227 errmsg = parse_symbolic_address (cd, strp, opindex,
1228 BFD_RELOC_FRV_GOTTLSOFFLO,
1229 &result_type, &value);
1230 if (**strp != ')')
1231 return "missing ')'";
1232 ++*strp;
1233 *valuep = value;
1234 return errmsg;
1235 }
1236 }
1237 return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
1238 }
1239
1240 static const char *
1241 parse_uslo16 (cd, strp, opindex, valuep)
1242 CGEN_CPU_DESC cd;
1243 const char **strp;
1244 int opindex;
1245 signed long *valuep;
1246 {
1247 const char *errmsg;
1248 enum cgen_parse_operand_result result_type;
1249 bfd_vma value;
1250
1251 if (**strp == '#' || **strp == '%')
1252 {
1253 if (strncasecmp (*strp + 1, "lo(", 3) == 0)
1254 {
1255 *strp += 4;
1256 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16,
1257 &result_type, &value);
1258 if (**strp != ')')
1259 return "missing `)'";
1260 ++*strp;
1261 if (errmsg == NULL
1262 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
1263 value &= 0xffff;
1264 *valuep = value;
1265 return errmsg;
1266 }
1267 else if (strncasecmp (*strp + 1, "gprello(", 8) == 0)
1268 {
1269 *strp += 9;
1270 errmsg = parse_symbolic_address (cd, strp, opindex,
1271 BFD_RELOC_FRV_GPRELLO,
1272 &result_type, &value);
1273 if (**strp != ')')
1274 return "missing ')'";
1275 ++*strp;
1276 *valuep = value;
1277 return errmsg;
1278 }
1279 else if (strncasecmp (*strp + 1, "gotlo(", 6) == 0)
1280 {
1281 *strp += 7;
1282 errmsg = parse_symbolic_address (cd, strp, opindex,
1283 BFD_RELOC_FRV_GOTLO,
1284 &result_type, &value);
1285 if (**strp != ')')
1286 return "missing ')'";
1287 ++*strp;
1288 *valuep = value;
1289 return errmsg;
1290 }
1291 else if (strncasecmp (*strp + 1, "gotfuncdesclo(", 14) == 0)
1292 {
1293 *strp += 15;
1294 errmsg = parse_symbolic_address (cd, strp, opindex,
1295 BFD_RELOC_FRV_FUNCDESC_GOTLO,
1296 &result_type, &value);
1297 if (**strp != ')')
1298 return "missing ')'";
1299 ++*strp;
1300 *valuep = value;
1301 return errmsg;
1302 }
1303 else if (strncasecmp (*strp + 1, "gotofflo(", 9) == 0)
1304 {
1305 *strp += 10;
1306 errmsg = parse_symbolic_address (cd, strp, opindex,
1307 BFD_RELOC_FRV_GOTOFFLO,
1308 &result_type, &value);
1309 if (**strp != ')')
1310 return "missing ')'";
1311 ++*strp;
1312 *valuep = value;
1313 return errmsg;
1314 }
1315 else if (strncasecmp (*strp + 1, "gotofffuncdesclo(", 17) == 0)
1316 {
1317 *strp += 18;
1318 errmsg = parse_symbolic_address (cd, strp, opindex,
1319 BFD_RELOC_FRV_FUNCDESC_GOTOFFLO,
1320 &result_type, &value);
1321 if (**strp != ')')
1322 return "missing ')'";
1323 ++*strp;
1324 *valuep = value;
1325 return errmsg;
1326 }
1327 else if (strncasecmp (*strp + 1, "gottlsdesclo(", 13) == 0)
1328 {
1329 *strp += 14;
1330 errmsg = parse_symbolic_address (cd, strp, opindex,
1331 BFD_RELOC_FRV_GOTTLSDESCLO,
1332 &result_type, &value);
1333 if (**strp != ')')
1334 return "missing ')'";
1335 ++*strp;
1336 *valuep = value;
1337 return errmsg;
1338 }
1339 else if (strncasecmp (*strp + 1, "tlsmofflo(", 10) == 0)
1340 {
1341 *strp += 11;
1342 errmsg = parse_symbolic_address (cd, strp, opindex,
1343 BFD_RELOC_FRV_TLSMOFFLO,
1344 &result_type, &value);
1345 if (**strp != ')')
1346 return "missing ')'";
1347 ++*strp;
1348 *valuep = value;
1349 return errmsg;
1350 }
1351 else if (strncasecmp (*strp + 1, "gottlsofflo(", 12) == 0)
1352 {
1353 *strp += 13;
1354 errmsg = parse_symbolic_address (cd, strp, opindex,
1355 BFD_RELOC_FRV_GOTTLSOFFLO,
1356 &result_type, &value);
1357 if (**strp != ')')
1358 return "missing ')'";
1359 ++*strp;
1360 *valuep = value;
1361 return errmsg;
1362 }
1363 }
1364 return cgen_parse_signed_integer (cd, strp, opindex, valuep);
1365 }
1366
1367 static const char *
1368 parse_uhi16 (cd, strp, opindex, valuep)
1369 CGEN_CPU_DESC cd;
1370 const char **strp;
1371 int opindex;
1372 unsigned long *valuep;
1373 {
1374 const char *errmsg;
1375 enum cgen_parse_operand_result result_type;
1376 bfd_vma value;
1377
1378 if (**strp == '#' || **strp == '%')
1379 {
1380 if (strncasecmp (*strp + 1, "hi(", 3) == 0)
1381 {
1382 *strp += 4;
1383 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_HI16,
1384 &result_type, &value);
1385 if (**strp != ')')
1386 return "missing `)'";
1387 ++*strp;
1388 if (errmsg == NULL
1389 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
1390 {
1391 /* If bfd_vma is wider than 32 bits, but we have a sign-
1392 or zero-extension, truncate it. */
1393 if (value >= - ((bfd_vma)1 << 31)
1394 || value <= ((bfd_vma)1 << 31) - (bfd_vma)1)
1395 value &= (((bfd_vma)1 << 16) << 16) - 1;
1396 value >>= 16;
1397 }
1398 *valuep = value;
1399 return errmsg;
1400 }
1401 else if (strncasecmp (*strp + 1, "gprelhi(", 8) == 0)
1402 {
1403 *strp += 9;
1404 errmsg = parse_symbolic_address (cd, strp, opindex,
1405 BFD_RELOC_FRV_GPRELHI,
1406 &result_type, &value);
1407 if (**strp != ')')
1408 return "missing ')'";
1409 ++*strp;
1410 *valuep = value;
1411 return errmsg;
1412 }
1413 else if (strncasecmp (*strp + 1, "gothi(", 6) == 0)
1414 {
1415 *strp += 7;
1416 errmsg = parse_symbolic_address (cd, strp, opindex,
1417 BFD_RELOC_FRV_GOTHI,
1418 &result_type, &value);
1419 if (**strp != ')')
1420 return "missing ')'";
1421 ++*strp;
1422 *valuep = value;
1423 return errmsg;
1424 }
1425 else if (strncasecmp (*strp + 1, "gotfuncdeschi(", 14) == 0)
1426 {
1427 *strp += 15;
1428 errmsg = parse_symbolic_address (cd, strp, opindex,
1429 BFD_RELOC_FRV_FUNCDESC_GOTHI,
1430 &result_type, &value);
1431 if (**strp != ')')
1432 return "missing ')'";
1433 ++*strp;
1434 *valuep = value;
1435 return errmsg;
1436 }
1437 else if (strncasecmp (*strp + 1, "gotoffhi(", 9) == 0)
1438 {
1439 *strp += 10;
1440 errmsg = parse_symbolic_address (cd, strp, opindex,
1441 BFD_RELOC_FRV_GOTOFFHI,
1442 &result_type, &value);
1443 if (**strp != ')')
1444 return "missing ')'";
1445 ++*strp;
1446 *valuep = value;
1447 return errmsg;
1448 }
1449 else if (strncasecmp (*strp + 1, "gotofffuncdeschi(", 17) == 0)
1450 {
1451 *strp += 18;
1452 errmsg = parse_symbolic_address (cd, strp, opindex,
1453 BFD_RELOC_FRV_FUNCDESC_GOTOFFHI,
1454 &result_type, &value);
1455 if (**strp != ')')
1456 return "missing ')'";
1457 ++*strp;
1458 *valuep = value;
1459 return errmsg;
1460 }
1461 else if (strncasecmp (*strp + 1, "gottlsdeschi(", 13) == 0)
1462 {
1463 *strp += 14;
1464 errmsg = parse_symbolic_address (cd, strp, opindex,
1465 BFD_RELOC_FRV_GOTTLSDESCHI,
1466 &result_type, &value);
1467 if (**strp != ')')
1468 return "missing ')'";
1469 ++*strp;
1470 *valuep = value;
1471 return errmsg;
1472 }
1473 else if (strncasecmp (*strp + 1, "tlsmoffhi(", 10) == 0)
1474 {
1475 *strp += 11;
1476 errmsg = parse_symbolic_address (cd, strp, opindex,
1477 BFD_RELOC_FRV_TLSMOFFHI,
1478 &result_type, &value);
1479 if (**strp != ')')
1480 return "missing ')'";
1481 ++*strp;
1482 *valuep = value;
1483 return errmsg;
1484 }
1485 else if (strncasecmp (*strp + 1, "gottlsoffhi(", 12) == 0)
1486 {
1487 *strp += 13;
1488 errmsg = parse_symbolic_address (cd, strp, opindex,
1489 BFD_RELOC_FRV_GOTTLSOFFHI,
1490 &result_type, &value);
1491 if (**strp != ')')
1492 return "missing ')'";
1493 ++*strp;
1494 *valuep = value;
1495 return errmsg;
1496 }
1497 }
1498 return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
1499 }
1500
1501 static long
1502 parse_register_number (strp)
1503 const char **strp;
1504 {
1505 int regno;
1506 if (**strp < '0' || **strp > '9')
1507 return -1; /* error */
1508
1509 regno = **strp - '0';
1510 for (++*strp; **strp >= '0' && **strp <= '9'; ++*strp)
1511 regno = regno * 10 + (**strp - '0');
1512
1513 return regno;
1514 }
1515
1516 static const char *
1517 parse_spr (cd, strp, table, valuep)
1518 CGEN_CPU_DESC cd;
1519 const char **strp;
1520 CGEN_KEYWORD * table;
1521 long *valuep;
1522 {
1523 const char *save_strp;
1524 long regno;
1525
1526 /* Check for spr index notation. */
1527 if (strncasecmp (*strp, "spr[", 4) == 0)
1528 {
1529 *strp += 4;
1530 regno = parse_register_number (strp);
1531 if (**strp != ']')
1532 return "missing `]'";
1533 ++*strp;
1534 if (! spr_valid (regno))
1535 return "Special purpose register number is out of range";
1536 *valuep = regno;
1537 return NULL;
1538 }
1539
1540 save_strp = *strp;
1541 regno = parse_register_number (strp);
1542 if (regno != -1)
1543 {
1544 if (! spr_valid (regno))
1545 return "Special purpose register number is out of range";
1546 *valuep = regno;
1547 return NULL;
1548 }
1549
1550 *strp = save_strp;
1551 return cgen_parse_keyword (cd, strp, table, valuep);
1552 }
1553
1554 static const char *
1555 parse_d12 (cd, strp, opindex, valuep)
1556 CGEN_CPU_DESC cd;
1557 const char **strp;
1558 int opindex;
1559 long *valuep;
1560 {
1561 const char *errmsg;
1562 enum cgen_parse_operand_result result_type;
1563 bfd_vma value;
1564
1565 /* Check for small data reference. */
1566 if (**strp == '#' || **strp == '%')
1567 {
1568 if (strncasecmp (*strp + 1, "gprel12(", 8) == 0)
1569 {
1570 *strp += 9;
1571 errmsg = parse_symbolic_address (cd, strp, opindex,
1572 BFD_RELOC_FRV_GPREL12,
1573 &result_type, &value);
1574 if (**strp != ')')
1575 return "missing `)'";
1576 ++*strp;
1577 *valuep = value;
1578 return errmsg;
1579 }
1580 else if (strncasecmp (*strp + 1, "got12(", 6) == 0)
1581 {
1582 *strp += 7;
1583 errmsg = parse_symbolic_address (cd, strp, opindex,
1584 BFD_RELOC_FRV_GOT12,
1585 &result_type, &value);
1586 if (**strp != ')')
1587 return "missing ')'";
1588 ++*strp;
1589 *valuep = value;
1590 return errmsg;
1591 }
1592 else if (strncasecmp (*strp + 1, "gotfuncdesc12(", 14) == 0)
1593 {
1594 *strp += 15;
1595 errmsg = parse_symbolic_address (cd, strp, opindex,
1596 BFD_RELOC_FRV_FUNCDESC_GOT12,
1597 &result_type, &value);
1598 if (**strp != ')')
1599 return "missing ')'";
1600 ++*strp;
1601 *valuep = value;
1602 return errmsg;
1603 }
1604 else if (strncasecmp (*strp + 1, "gotoff12(", 9) == 0)
1605 {
1606 *strp += 10;
1607 errmsg = parse_symbolic_address (cd, strp, opindex,
1608 BFD_RELOC_FRV_GOTOFF12,
1609 &result_type, &value);
1610 if (**strp != ')')
1611 return "missing ')'";
1612 ++*strp;
1613 *valuep = value;
1614 return errmsg;
1615 }
1616 else if (strncasecmp (*strp + 1, "gotofffuncdesc12(", 17) == 0)
1617 {
1618 *strp += 18;
1619 errmsg = parse_symbolic_address (cd, strp, opindex,
1620 BFD_RELOC_FRV_FUNCDESC_GOTOFF12,
1621 &result_type, &value);
1622 if (**strp != ')')
1623 return "missing ')'";
1624 ++*strp;
1625 *valuep = value;
1626 return errmsg;
1627 }
1628 else if (strncasecmp (*strp + 1, "gottlsdesc12(", 13) == 0)
1629 {
1630 *strp += 14;
1631 errmsg = parse_symbolic_address (cd, strp, opindex,
1632 BFD_RELOC_FRV_GOTTLSDESC12,
1633 &result_type, &value);
1634 if (**strp != ')')
1635 return "missing ')'";
1636 ++*strp;
1637 *valuep = value;
1638 return errmsg;
1639 }
1640 else if (strncasecmp (*strp + 1, "tlsmoff12(", 10) == 0)
1641 {
1642 *strp += 11;
1643 errmsg = parse_symbolic_address (cd, strp, opindex,
1644 BFD_RELOC_FRV_TLSMOFF12,
1645 &result_type, &value);
1646 if (**strp != ')')
1647 return "missing ')'";
1648 ++*strp;
1649 *valuep = value;
1650 return errmsg;
1651 }
1652 else if (strncasecmp (*strp + 1, "gottlsoff12(", 12) == 0)
1653 {
1654 *strp += 13;
1655 errmsg = parse_symbolic_address (cd, strp, opindex,
1656 BFD_RELOC_FRV_GOTTLSOFF12,
1657 &result_type, &value);
1658 if (**strp != ')')
1659 return "missing ')'";
1660 ++*strp;
1661 *valuep = value;
1662 return errmsg;
1663 }
1664 }
1665 return cgen_parse_signed_integer (cd, strp, opindex, valuep);
1666 }
1667
1668 static const char *
1669 parse_s12 (cd, strp, opindex, valuep)
1670 CGEN_CPU_DESC cd;
1671 const char **strp;
1672 int opindex;
1673 long *valuep;
1674 {
1675 const char *errmsg;
1676 enum cgen_parse_operand_result result_type;
1677 bfd_vma value;
1678
1679 /* Check for small data reference. */
1680 if (**strp == '#' || **strp == '%')
1681 {
1682 if (strncasecmp (*strp + 1, "gprel12(", 8) == 0)
1683 {
1684 *strp += 9;
1685 errmsg = parse_symbolic_address (cd, strp, opindex,
1686 BFD_RELOC_FRV_GPREL12,
1687 &result_type, &value);
1688 if (**strp != ')')
1689 return "missing `)'";
1690 ++*strp;
1691 *valuep = value;
1692 return errmsg;
1693 }
1694 else if (strncasecmp (*strp + 1, "got12(", 6) == 0)
1695 {
1696 *strp += 7;
1697 errmsg = parse_symbolic_address (cd, strp, opindex,
1698 BFD_RELOC_FRV_GOT12,
1699 &result_type, &value);
1700 if (**strp != ')')
1701 return "missing ')'";
1702 ++*strp;
1703 *valuep = value;
1704 return errmsg;
1705 }
1706 else if (strncasecmp (*strp + 1, "gotfuncdesc12(", 14) == 0)
1707 {
1708 *strp += 15;
1709 errmsg = parse_symbolic_address (cd, strp, opindex,
1710 BFD_RELOC_FRV_FUNCDESC_GOT12,
1711 &result_type, &value);
1712 if (**strp != ')')
1713 return "missing ')'";
1714 ++*strp;
1715 *valuep = value;
1716 return errmsg;
1717 }
1718 else if (strncasecmp (*strp + 1, "gotoff12(", 9) == 0)
1719 {
1720 *strp += 10;
1721 errmsg = parse_symbolic_address (cd, strp, opindex,
1722 BFD_RELOC_FRV_GOTOFF12,
1723 &result_type, &value);
1724 if (**strp != ')')
1725 return "missing ')'";
1726 ++*strp;
1727 *valuep = value;
1728 return errmsg;
1729 }
1730 else if (strncasecmp (*strp + 1, "gotofffuncdesc12(", 17) == 0)
1731 {
1732 *strp += 18;
1733 errmsg = parse_symbolic_address (cd, strp, opindex,
1734 BFD_RELOC_FRV_FUNCDESC_GOTOFF12,
1735 &result_type, &value);
1736 if (**strp != ')')
1737 return "missing ')'";
1738 ++*strp;
1739 *valuep = value;
1740 return errmsg;
1741 }
1742 else if (strncasecmp (*strp + 1, "gottlsdesc12(", 13) == 0)
1743 {
1744 *strp += 14;
1745 errmsg = parse_symbolic_address (cd, strp, opindex,
1746 BFD_RELOC_FRV_GOTTLSDESC12,
1747 &result_type, &value);
1748 if (**strp != ')')
1749 return "missing ')'";
1750 ++*strp;
1751 *valuep = value;
1752 return errmsg;
1753 }
1754 else if (strncasecmp (*strp + 1, "tlsmoff12(", 10) == 0)
1755 {
1756 *strp += 11;
1757 errmsg = parse_symbolic_address (cd, strp, opindex,
1758 BFD_RELOC_FRV_TLSMOFF12,
1759 &result_type, &value);
1760 if (**strp != ')')
1761 return "missing ')'";
1762 ++*strp;
1763 *valuep = value;
1764 return errmsg;
1765 }
1766 else if (strncasecmp (*strp + 1, "gottlsoff12(", 12) == 0)
1767 {
1768 *strp += 13;
1769 errmsg = parse_symbolic_address (cd, strp, opindex,
1770 BFD_RELOC_FRV_GOTTLSOFF12,
1771 &result_type, &value);
1772 if (**strp != ')')
1773 return "missing ')'";
1774 ++*strp;
1775 *valuep = value;
1776 return errmsg;
1777 }
1778 }
1779
1780 if (**strp == '#')
1781 ++*strp;
1782 return cgen_parse_signed_integer (cd, strp, opindex, valuep);
1783 }
1784
1785 static const char *
1786 parse_u12 (cd, strp, opindex, valuep)
1787 CGEN_CPU_DESC cd;
1788 const char **strp;
1789 int opindex;
1790 long *valuep;
1791 {
1792 const char *errmsg;
1793 enum cgen_parse_operand_result result_type;
1794 bfd_vma value;
1795
1796 /* Check for small data reference. */
1797 if ((**strp == '#' || **strp == '%')
1798 && strncasecmp (*strp + 1, "gprel12(", 8) == 0)
1799 {
1800 *strp += 9;
1801 errmsg = parse_symbolic_address (cd, strp, opindex,
1802 BFD_RELOC_FRV_GPRELU12,
1803 &result_type, &value);
1804 if (**strp != ')')
1805 return "missing `)'";
1806 ++*strp;
1807 *valuep = value;
1808 return errmsg;
1809 }
1810 else
1811 {
1812 if (**strp == '#')
1813 ++*strp;
1814 return cgen_parse_signed_integer (cd, strp, opindex, valuep);
1815 }
1816 }
1817
1818 static const char *
1819 parse_A (cd, strp, opindex, valuep, A)
1820 CGEN_CPU_DESC cd;
1821 const char **strp;
1822 int opindex;
1823 unsigned long *valuep;
1824 long A;
1825 {
1826 const char *errmsg;
1827
1828 if (**strp == '#')
1829 ++*strp;
1830
1831 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
1832 if (errmsg)
1833 return errmsg;
1834
1835 if (*valuep != A)
1836 return "Value of A operand must be 0 or 1";
1837
1838 return NULL;
1839 }
1840
1841 static const char *
1842 parse_A0 (cd, strp, opindex, valuep)
1843 CGEN_CPU_DESC cd;
1844 const char **strp;
1845 int opindex;
1846 unsigned long *valuep;
1847 {
1848 return parse_A (cd, strp, opindex, valuep, 0);
1849 }
1850
1851 static const char *
1852 parse_A1 (cd, strp, opindex, valuep)
1853 CGEN_CPU_DESC cd;
1854 const char **strp;
1855 int opindex;
1856 unsigned long *valuep;
1857 {
1858 return parse_A (cd, strp, opindex, valuep, 1);
1859 }
1860
1861 static const char *
1862 parse_even_register (cd, strP, tableP, valueP)
1863 CGEN_CPU_DESC cd;
1864 const char ** strP;
1865 CGEN_KEYWORD * tableP;
1866 long * valueP;
1867 {
1868 const char * errmsg;
1869 const char * saved_star_strP = * strP;
1870
1871 errmsg = cgen_parse_keyword (cd, strP, tableP, valueP);
1872
1873 if (errmsg == NULL && ((* valueP) & 1))
1874 {
1875 errmsg = _("register number must be even");
1876 * strP = saved_star_strP;
1877 }
1878
1879 return errmsg;
1880 }
1881
1882 static const char *
1883 parse_call_label (CGEN_CPU_DESC cd,
1884 const char **strp,
1885 int opindex,
1886 int opinfo,
1887 enum cgen_parse_operand_result *resultp,
1888 bfd_vma *valuep)
1889 {
1890 const char *errmsg;
1891 bfd_vma value;
1892
1893 /* Check for small data reference. */
1894 if (opinfo == 0 && (**strp == '#' || **strp == '%'))
1895 {
1896 if (strncasecmp (*strp + 1, "gettlsoff(", 10) == 0)
1897 {
1898 *strp += 11;
1899 errmsg = parse_symbolic_address (cd, strp, opindex,
1900 BFD_RELOC_FRV_GETTLSOFF,
1901 resultp, &value);
1902 if (**strp != ')')
1903 return "missing `)'";
1904 ++*strp;
1905 *valuep = value;
1906 return errmsg;
1907 }
1908 }
1909
1910 return cgen_parse_address (cd, strp, opindex, opinfo, resultp, valuep);
1911 }
1912
1913 /* -- */
1914 \f
1915 /* -- dis.c */
1916 static void print_spr
1917 PARAMS ((CGEN_CPU_DESC, PTR, CGEN_KEYWORD *, long, unsigned));
1918 static void print_hi
1919 PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int));
1920 static void print_lo
1921 PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int));
1922
1923 static void
1924 print_at (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1925 PTR dis_info,
1926 long reloc_ann ATTRIBUTE_UNUSED,
1927 long value ATTRIBUTE_UNUSED,
1928 bfd_vma pc ATTRIBUTE_UNUSED,
1929 int length ATTRIBUTE_UNUSED
1930 )
1931 {
1932 disassemble_info *info = (disassemble_info *) dis_info;
1933 (*info->fprintf_func) (info->stream, "@");
1934 }
1935
1936 static void
1937 print_spr (cd, dis_info, names, regno, attrs)
1938 CGEN_CPU_DESC cd;
1939 PTR dis_info;
1940 CGEN_KEYWORD *names;
1941 long regno;
1942 unsigned int attrs;
1943 {
1944 /* Use the register index format for any unnamed registers. */
1945 if (cgen_keyword_lookup_value (names, regno) == NULL)
1946 {
1947 disassemble_info *info = (disassemble_info *) dis_info;
1948 (*info->fprintf_func) (info->stream, "spr[%ld]", regno);
1949 }
1950 else
1951 print_keyword (cd, dis_info, names, regno, attrs);
1952 }
1953
1954 static void
1955 print_hi (cd, dis_info, value, attrs, pc, length)
1956 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
1957 PTR dis_info;
1958 long value;
1959 unsigned int attrs ATTRIBUTE_UNUSED;
1960 bfd_vma pc ATTRIBUTE_UNUSED;
1961 int length ATTRIBUTE_UNUSED;
1962 {
1963 disassemble_info *info = (disassemble_info *) dis_info;
1964 if (value)
1965 (*info->fprintf_func) (info->stream, "0x%lx", value);
1966 else
1967 (*info->fprintf_func) (info->stream, "hi(0x%lx)", value);
1968 }
1969
1970 static void
1971 print_lo (cd, dis_info, value, attrs, pc, length)
1972 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
1973 PTR dis_info;
1974 long value;
1975 unsigned int attrs ATTRIBUTE_UNUSED;
1976 bfd_vma pc ATTRIBUTE_UNUSED;
1977 int length ATTRIBUTE_UNUSED;
1978 {
1979 disassemble_info *info = (disassemble_info *) dis_info;
1980 if (value)
1981 (*info->fprintf_func) (info->stream, "0x%lx", value);
1982 else
1983 (*info->fprintf_func) (info->stream, "lo(0x%lx)", value);
1984 }
1985
1986 /* -- */
This page took 0.074834 seconds and 4 git commands to generate.