1
/* Fujitsu FRV opcode support, for GNU Binutils. -*- C -*-
3
Copyright 2000, 2001, 2003, 2004, 2005, 2007, 2009
4
Free Software Foundation, Inc.
6
Contributed by Red Hat Inc; developed under contract from Fujitsu.
8
This file is part of the GNU Binutils.
10
This program is free software; you can redistribute it and/or modify
11
it under the terms of the GNU General Public License as published by
12
the Free Software Foundation; either version 3 of the License, or
13
(at your option) any later version.
15
This program is distributed in the hope that it will be useful,
16
but WITHOUT ANY WARRANTY; without even the implied warranty of
17
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
GNU General Public License for more details.
20
You should have received a copy of the GNU General Public License
21
along with this program; if not, write to the Free Software
22
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
23
MA 02110-1301, USA. */
26
/* This file is an addendum to frv.cpu. Heavy use of C code isn't
27
appropriate in .cpu files, so it resides here. This especially applies
28
to assembly/disassembly where parsing/printing can be quite involved.
29
Such things aren't really part of the specification of the cpu, per se,
30
so .cpu files provide the general framework and .opc files handle the
31
nitty-gritty details as necessary.
33
Each section is delimited with start and end markers.
35
<arch>-opc.h additions use: "-- opc.h"
36
<arch>-opc.c additions use: "-- opc.c"
37
<arch>-asm.c additions use: "-- asm.c"
38
<arch>-dis.c additions use: "-- dis.c"
39
<arch>-ibd.h additions use: "-- ibd.h". */
43
#undef CGEN_DIS_HASH_SIZE
44
#define CGEN_DIS_HASH_SIZE 128
46
#define CGEN_DIS_HASH(buffer, value) (((value) >> 18) & 127)
48
/* Allows reason codes to be output when assembler errors occur. */
49
#define CGEN_VERBOSE_ASSEMBLER_ERRORS
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
55
typedef CGEN_ATTR_VALUE_ENUM_TYPE VLIW_COMBO[FRV_VLIW_SIZE];
60
int constraint_violation;
62
unsigned long elf_flags;
63
CGEN_ATTR_VALUE_ENUM_TYPE * unit_mapping;
64
VLIW_COMBO * current_vliw;
65
CGEN_ATTR_VALUE_ENUM_TYPE major[FRV_VLIW_SIZE];
66
const CGEN_INSN * insn[FRV_VLIW_SIZE];
69
int frv_is_branch_major (CGEN_ATTR_VALUE_ENUM_TYPE, unsigned long);
70
int frv_is_float_major (CGEN_ATTR_VALUE_ENUM_TYPE, unsigned long);
71
int frv_is_media_major (CGEN_ATTR_VALUE_ENUM_TYPE, unsigned long);
72
int frv_is_branch_insn (const CGEN_INSN *);
73
int frv_is_float_insn (const CGEN_INSN *);
74
int frv_is_media_insn (const CGEN_INSN *);
75
void frv_vliw_reset (FRV_VLIW *, unsigned long, unsigned long);
76
int frv_vliw_add_insn (FRV_VLIW *, const CGEN_INSN *);
84
/* DEBUG appears below as argument of OP macro. */
87
/* Returns TRUE if {MAJOR,MACH} is a major branch of the FRV
91
frv_is_branch_major (CGEN_ATTR_VALUE_ENUM_TYPE major, unsigned long mach)
96
if (major >= FR400_MAJOR_B_1 && major <= FR400_MAJOR_B_6)
100
if (major >= FR450_MAJOR_B_1 && major <= FR450_MAJOR_B_6)
104
if (major >= FR500_MAJOR_B_1 && major <= FR500_MAJOR_B_6)
112
/* Returns TRUE if {MAJOR,MACH} supports floating point insns. */
115
frv_is_float_major (CGEN_ATTR_VALUE_ENUM_TYPE major, unsigned long mach)
123
if (major >= FR500_MAJOR_F_1 && major <= FR500_MAJOR_F_8)
131
/* Returns TRUE if {MAJOR,MACH} supports media insns. */
134
frv_is_media_major (CGEN_ATTR_VALUE_ENUM_TYPE major, unsigned long mach)
139
if (major >= FR400_MAJOR_M_1 && major <= FR400_MAJOR_M_2)
143
if (major >= FR450_MAJOR_M_1 && major <= FR450_MAJOR_M_6)
147
if (major >= FR500_MAJOR_M_1 && major <= FR500_MAJOR_M_8)
156
frv_is_branch_insn (const CGEN_INSN *insn)
158
if (frv_is_branch_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR400_MAJOR),
161
if (frv_is_branch_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR450_MAJOR),
164
if (frv_is_branch_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR500_MAJOR),
172
frv_is_float_insn (const CGEN_INSN *insn)
174
if (frv_is_float_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR400_MAJOR),
177
if (frv_is_float_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR450_MAJOR),
180
if (frv_is_float_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR500_MAJOR),
188
frv_is_media_insn (const CGEN_INSN *insn)
190
if (frv_is_media_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR400_MAJOR),
193
if (frv_is_media_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR450_MAJOR),
196
if (frv_is_media_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR500_MAJOR),
203
/* This table represents the allowable packing for vliw insns for the fr400.
204
The fr400 has only 2 vliw slots. Represent this by not allowing any insns
206
Subsets of any given row are also allowed. */
207
static VLIW_COMBO fr400_allowed_vliw[] =
209
/* slot0 slot1 slot2 slot3 */
210
{ UNIT_I0, UNIT_I1, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO },
211
{ UNIT_I0, UNIT_FM0, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO },
212
{ UNIT_I0, UNIT_B0, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO },
213
{ UNIT_FM0, UNIT_FM1, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO },
214
{ UNIT_FM0, UNIT_B0, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO },
215
{ UNIT_B0, UNIT_NIL, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO },
216
{ UNIT_C, UNIT_NIL, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO },
217
{ UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO }
220
/* This table represents the allowable packing for vliw insns for the fr500.
221
The fr500 has only 4 vliw slots. Represent this by not allowing any insns
223
Subsets of any given row are also allowed. */
224
static VLIW_COMBO fr500_allowed_vliw[] =
226
/* slot0 slot1 slot2 slot3 */
227
{ UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1 PAD_VLIW_COMBO },
228
{ UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_B0 PAD_VLIW_COMBO },
229
{ UNIT_I0, UNIT_FM0, UNIT_FM1, UNIT_B0 PAD_VLIW_COMBO },
230
{ UNIT_I0, UNIT_FM0, UNIT_B0, UNIT_B1 PAD_VLIW_COMBO },
231
{ UNIT_I0, UNIT_I1, UNIT_B0, UNIT_B1 PAD_VLIW_COMBO },
232
{ UNIT_I0, UNIT_B0, UNIT_B1, UNIT_NIL PAD_VLIW_COMBO },
233
{ UNIT_FM0, UNIT_FM1, UNIT_B0, UNIT_B1 PAD_VLIW_COMBO },
234
{ UNIT_FM0, UNIT_B0, UNIT_B1, UNIT_NIL PAD_VLIW_COMBO },
235
{ UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO },
236
{ UNIT_C, UNIT_NIL, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO },
237
{ UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO }
240
/* This table represents the allowable packing for vliw insns for the fr550.
241
Subsets of any given row are also allowed. */
242
static VLIW_COMBO fr550_allowed_vliw[] =
244
/* slot0 slot1 slot2 slot3 slot4 slot5 slot6 slot7 */
245
{ UNIT_I0, UNIT_I1, UNIT_I2, UNIT_I3, UNIT_B0, UNIT_B1 , UNIT_NIL, UNIT_NIL },
246
{ UNIT_I0, UNIT_I1, UNIT_I2, UNIT_B0, UNIT_B1 , UNIT_NIL, UNIT_NIL, UNIT_NIL },
247
{ UNIT_I0, UNIT_I1, UNIT_B0, UNIT_B1 , UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL },
248
{ UNIT_I0, UNIT_B0, UNIT_B1 , UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL },
249
{ UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1, UNIT_I2, UNIT_FM2, UNIT_I3, UNIT_FM3 },
250
{ UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1, UNIT_I2, UNIT_FM2, UNIT_I3, UNIT_B0 },
251
{ UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1, UNIT_I2, UNIT_FM2, UNIT_FM3, UNIT_B0 },
252
{ UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1, UNIT_I2, UNIT_FM2, UNIT_B0, UNIT_B1 },
253
{ UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1, UNIT_I2, UNIT_I3, UNIT_B0, UNIT_B1 },
254
{ UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1, UNIT_I2, UNIT_B0, UNIT_B1, UNIT_NIL },
255
{ UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1, UNIT_FM2, UNIT_FM3, UNIT_B0, UNIT_B1 },
256
{ UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1, UNIT_FM2, UNIT_FM3, UNIT_B0, UNIT_B1 },
257
{ UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1, UNIT_FM2, UNIT_B0, UNIT_B1, UNIT_NIL },
258
{ UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1, UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL },
259
{ UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_I2, UNIT_I3, UNIT_B0, UNIT_B1, UNIT_NIL },
260
{ UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_I2, UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL },
261
{ UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL, UNIT_NIL },
262
{ UNIT_I0, UNIT_FM0, UNIT_FM1, UNIT_FM2, UNIT_FM3, UNIT_B0, UNIT_B1, UNIT_NIL },
263
{ UNIT_I0, UNIT_FM0, UNIT_FM1, UNIT_FM2, UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL },
264
{ UNIT_I0, UNIT_FM0, UNIT_FM1, UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL, UNIT_NIL },
265
{ UNIT_I0, UNIT_FM0, UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL },
266
{ UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL },
267
{ UNIT_C, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL },
268
{ UNIT_FM0, UNIT_FM1, UNIT_FM2, UNIT_FM3, UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL },
269
{ UNIT_FM0, UNIT_FM1, UNIT_FM2, UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL, UNIT_NIL },
270
{ UNIT_FM0, UNIT_FM1, UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL },
271
{ UNIT_FM0, UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL },
272
{ UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL }
275
/* Some insns are assigned specialized implementation units which map to
276
different actual implementation units on different machines. These
277
tables perform that mapping. */
278
static CGEN_ATTR_VALUE_ENUM_TYPE fr400_unit_mapping[] =
280
/* unit in insn actual unit */
285
/* I2 */ UNIT_NIL, /* no I2 or I3 unit */
287
/* IALL */ UNIT_I01, /* only I0 and I1 units */
290
/* FM01 */ UNIT_FM01,
291
/* FM2 */ UNIT_NIL, /* no F2 or M2 units */
292
/* FM3 */ UNIT_NIL, /* no F3 or M3 units */
293
/* FMALL */ UNIT_FM01,/* Only F0,F1,M0,M1 units */
294
/* FMLOW */ UNIT_FM0, /* Only F0,M0 units */
295
/* B0 */ UNIT_B0, /* branches only in B0 unit. */
299
/* MULT-DIV */ UNIT_I0, /* multiply and divide only in I0 unit. */
300
/* IACC */ UNIT_I01, /* iacc multiply in I0 or I1 unit. */
301
/* LOAD */ UNIT_I0, /* load only in I0 unit. */
302
/* STORE */ UNIT_I0, /* store only in I0 unit. */
303
/* SCAN */ UNIT_I0, /* scan only in I0 unit. */
304
/* DCPL */ UNIT_C, /* dcpl only in C unit. */
305
/* MDUALACC */ UNIT_FM0, /* media dual acc insn only in FM0 unit. */
306
/* MDCUTSSI */ UNIT_FM0, /* mdcutssi only in FM0 unit. */
307
/* MCLRACC-1*/ UNIT_FM0 /* mclracc,A==1 insn only in FM0 unit. */
310
/* Some insns are assigned specialized implementation units which map to
311
different actual implementation units on different machines. These
312
tables perform that mapping. */
313
static CGEN_ATTR_VALUE_ENUM_TYPE fr450_unit_mapping[] =
315
/* unit in insn actual unit */
320
/* I2 */ UNIT_NIL, /* no I2 or I3 unit */
322
/* IALL */ UNIT_I01, /* only I0 and I1 units */
325
/* FM01 */ UNIT_FM01,
326
/* FM2 */ UNIT_NIL, /* no F2 or M2 units */
327
/* FM3 */ UNIT_NIL, /* no F3 or M3 units */
328
/* FMALL */ UNIT_FM01,/* Only F0,F1,M0,M1 units */
329
/* FMLOW */ UNIT_FM0, /* Only F0,M0 units */
330
/* B0 */ UNIT_B0, /* branches only in B0 unit. */
334
/* MULT-DIV */ UNIT_I0, /* multiply and divide only in I0 unit. */
335
/* IACC */ UNIT_I01, /* iacc multiply in I0 or I1 unit. */
336
/* LOAD */ UNIT_I0, /* load only in I0 unit. */
337
/* STORE */ UNIT_I0, /* store only in I0 unit. */
338
/* SCAN */ UNIT_I0, /* scan only in I0 unit. */
339
/* DCPL */ UNIT_I0, /* dcpl only in I0 unit. */
340
/* MDUALACC */ UNIT_FM0, /* media dual acc insn only in FM0 unit. */
341
/* MDCUTSSI */ UNIT_FM01, /* mdcutssi in FM0 or FM1. */
342
/* MCLRACC-1*/ UNIT_FM0 /* mclracc,A==1 insn only in FM0 unit. */
345
static CGEN_ATTR_VALUE_ENUM_TYPE fr500_unit_mapping[] =
347
/* unit in insn actual unit */
352
/* I2 */ UNIT_NIL, /* no I2 or I3 unit */
354
/* IALL */ UNIT_I01, /* only I0 and I1 units */
357
/* FM01 */ UNIT_FM01,
358
/* FM2 */ UNIT_NIL, /* no F2 or M2 units */
359
/* FM3 */ UNIT_NIL, /* no F3 or M2 units */
360
/* FMALL */ UNIT_FM01,/* Only F0,F1,M0,M1 units */
361
/* FMLOW */ UNIT_FM0, /* Only F0,M0 units */
366
/* MULT-DIV */ UNIT_I01, /* multiply and divide in I0 or I1 unit. */
367
/* IACC */ UNIT_NIL, /* iacc multiply not implemented */
368
/* LOAD */ UNIT_I01, /* load in I0 or I1 unit. */
369
/* STORE */ UNIT_I0, /* store only in I0 unit. */
370
/* SCAN */ UNIT_I01, /* scan in I0 or I1 unit. */
371
/* DCPL */ UNIT_C, /* dcpl only in C unit. */
372
/* MDUALACC */ UNIT_FM0, /* media dual acc insn only in FM0 unit. */
373
/* MDCUTSSI */ UNIT_FM0, /* mdcutssi only in FM0 unit. */
374
/* MCLRACC-1*/ UNIT_FM01 /* mclracc,A==1 in FM0 or FM1 unit. */
377
static CGEN_ATTR_VALUE_ENUM_TYPE fr550_unit_mapping[] =
379
/* unit in insn actual unit */
386
/* IALL */ UNIT_IALL,
389
/* FM01 */ UNIT_FM01,
392
/* FMALL */ UNIT_FMALL,
393
/* FMLOW */ UNIT_FM01, /* Only F0,F1,M0,M1 units */
398
/* MULT-DIV */ UNIT_I01, /* multiply and divide in I0 or I1 unit. */
399
/* IACC */ UNIT_NIL, /* iacc multiply not implemented. */
400
/* LOAD */ UNIT_I01, /* load in I0 or I1 unit. */
401
/* STORE */ UNIT_I01, /* store in I0 or I1 unit. */
402
/* SCAN */ UNIT_IALL, /* scan in any integer unit. */
403
/* DCPL */ UNIT_I0, /* dcpl only in I0 unit. */
404
/* MDUALACC */ UNIT_FMALL,/* media dual acc insn in all media units */
405
/* MDCUTSSI */ UNIT_FM01, /* mdcutssi in FM0 or FM1 unit. */
406
/* MCLRACC-1*/ UNIT_FM01 /* mclracc,A==1 in FM0 or FM1 unit. */
410
frv_vliw_reset (FRV_VLIW *vliw, unsigned long mach, unsigned long elf_flags)
413
vliw->constraint_violation = 0;
415
vliw->elf_flags = elf_flags;
420
vliw->current_vliw = fr400_allowed_vliw;
421
vliw->unit_mapping = fr400_unit_mapping;
424
vliw->current_vliw = fr400_allowed_vliw;
425
vliw->unit_mapping = fr450_unit_mapping;
428
vliw->current_vliw = fr550_allowed_vliw;
429
vliw->unit_mapping = fr550_unit_mapping;
432
vliw->current_vliw = fr500_allowed_vliw;
433
vliw->unit_mapping = fr500_unit_mapping;
438
/* Return TRUE if unit1 is a match for unit2.
439
Unit1 comes from the insn's UNIT attribute. unit2 comes from one of the
440
*_allowed_vliw tables above. */
442
match_unit (FRV_VLIW *vliw,
443
CGEN_ATTR_VALUE_ENUM_TYPE unit1, CGEN_ATTR_VALUE_ENUM_TYPE unit2)
445
/* Map any specialized implementation units to actual ones. */
446
unit1 = vliw->unit_mapping[unit1];
458
/* The 01 versions of these units are within 2 enums of the 0 or 1
460
if (unit1 - unit2 <= 2)
465
/* The ALL versions of these units are within 5 enums of the 0, 1, 2 or 3
467
if (unit1 - unit2 <= 5)
477
/* Return TRUE if the vliws match, FALSE otherwise. */
480
match_vliw (VLIW_COMBO *vliw1, VLIW_COMBO *vliw2, int vliw_size)
484
for (i = 0; i < vliw_size; ++i)
485
if ((*vliw1)[i] != (*vliw2)[i])
491
/* Find the next vliw vliw in the table that can accomodate the new insn.
492
If one is found then return it. Otherwise return NULL. */
495
add_next_to_vliw (FRV_VLIW *vliw, CGEN_ATTR_VALUE_ENUM_TYPE unit)
497
int next = vliw->next_slot;
498
VLIW_COMBO *current = vliw->current_vliw;
499
VLIW_COMBO *potential;
503
fprintf (stderr, "frv-opc.c line %d: bad vliw->next_slot value.\n",
505
abort (); /* Should never happen. */
508
/* The table is sorted by units allowed within slots, so vliws with
509
identical starting sequences are together. */
513
if (match_unit (vliw, unit, (*potential)[next]))
517
while (match_vliw (potential, current, next));
522
/* Look for the given major insn type in the given vliw.
523
Returns TRUE if found, FALSE otherwise. */
526
find_major_in_vliw (FRV_VLIW *vliw, CGEN_ATTR_VALUE_ENUM_TYPE major)
530
for (i = 0; i < vliw->next_slot; ++i)
531
if (vliw->major[i] == major)
537
/* Check for constraints between the insns in the vliw due to major insn
541
fr400_check_insn_major_constraints (FRV_VLIW *vliw, CGEN_ATTR_VALUE_ENUM_TYPE major)
543
/* In the cpu file, all media insns are represented as being allowed in
544
both media units. This makes it easier since this is the case for fr500.
545
Catch the invalid combinations here. Insns of major class FR400_MAJOR_M_2
546
cannot coexist with any other media insn in a vliw. */
549
case FR400_MAJOR_M_2:
550
return ! find_major_in_vliw (vliw, FR400_MAJOR_M_1)
551
&& ! find_major_in_vliw (vliw, FR400_MAJOR_M_2);
552
case FR400_MAJOR_M_1:
553
return ! find_major_in_vliw (vliw, FR400_MAJOR_M_2);
561
fr450_check_insn_major_constraints (FRV_VLIW *vliw, CGEN_ATTR_VALUE_ENUM_TYPE major)
563
CGEN_ATTR_VALUE_ENUM_TYPE other_major;
565
/* Our caller guarantees there's at least one other instruction. */
566
other_major = CGEN_INSN_ATTR_VALUE (vliw->insn[0], CGEN_INSN_FR450_MAJOR);
568
/* (M4, M5) and (M4, M6) are allowed. */
569
if (other_major == FR450_MAJOR_M_4)
570
if (major == FR450_MAJOR_M_5 || major == FR450_MAJOR_M_6)
573
/* Otherwise, instructions in even-numbered media categories cannot be
574
executed in parallel with other media instructions. */
577
case FR450_MAJOR_M_2:
578
case FR450_MAJOR_M_4:
579
case FR450_MAJOR_M_6:
580
return !(other_major >= FR450_MAJOR_M_1
581
&& other_major <= FR450_MAJOR_M_6);
583
case FR450_MAJOR_M_1:
584
case FR450_MAJOR_M_3:
585
case FR450_MAJOR_M_5:
586
return !(other_major == FR450_MAJOR_M_2
587
|| other_major == FR450_MAJOR_M_4
588
|| other_major == FR450_MAJOR_M_6);
596
find_unit_in_vliw (FRV_VLIW *vliw, CGEN_ATTR_VALUE_ENUM_TYPE unit)
600
for (i = 0; i < vliw->next_slot; ++i)
601
if (CGEN_INSN_ATTR_VALUE (vliw->insn[i], CGEN_INSN_UNIT) == unit)
604
return FALSE; /* Not found. */
608
find_major_in_slot (FRV_VLIW *vliw,
609
CGEN_ATTR_VALUE_ENUM_TYPE major,
610
CGEN_ATTR_VALUE_ENUM_TYPE slot)
614
for (i = 0; i < vliw->next_slot; ++i)
615
if (vliw->major[i] == major && (*vliw->current_vliw)[i] == slot)
622
fr550_find_media_in_vliw (FRV_VLIW *vliw)
626
for (i = 0; i < vliw->next_slot; ++i)
628
if (vliw->major[i] < FR550_MAJOR_M_1 || vliw->major[i] > FR550_MAJOR_M_5)
631
/* Found a media insn, however, MNOP and MCLRACC don't count. */
632
if (CGEN_INSN_NUM (vliw->insn[i]) == FRV_INSN_MNOP
633
|| CGEN_INSN_NUM (vliw->insn[i]) == FRV_INSN_MCLRACC_0
634
|| CGEN_INSN_NUM (vliw->insn[i]) == FRV_INSN_MCLRACC_1)
637
return TRUE; /* Found one. */
644
fr550_find_float_in_vliw (FRV_VLIW *vliw)
648
for (i = 0; i < vliw->next_slot; ++i)
650
if (vliw->major[i] < FR550_MAJOR_F_1 || vliw->major[i] > FR550_MAJOR_F_4)
653
/* Found a floating point insn, however, FNOP doesn't count. */
654
if (CGEN_INSN_NUM (vliw->insn[i]) == FRV_INSN_FNOP)
657
return TRUE; /* Found one. */
664
fr550_check_insn_major_constraints (FRV_VLIW *vliw,
665
CGEN_ATTR_VALUE_ENUM_TYPE major,
666
const CGEN_INSN *insn)
668
CGEN_ATTR_VALUE_ENUM_TYPE unit;
669
CGEN_ATTR_VALUE_ENUM_TYPE slot = (*vliw->current_vliw)[vliw->next_slot];
673
/* If it's a store, then there must be another store in I1 */
674
unit = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_UNIT);
675
if (unit == UNIT_STORE)
676
return find_unit_in_vliw (vliw, UNIT_STORE);
680
/* Floating point insns other than FNOP in slot f2 or f3 cannot coexist
682
if (major >= FR550_MAJOR_F_1 && major <= FR550_MAJOR_F_4
683
&& CGEN_INSN_NUM (insn) != FRV_INSN_FNOP)
684
return ! fr550_find_media_in_vliw (vliw);
685
/* Media insns other than MNOP in slot m2 or m3 cannot coexist with
686
floating point insns. */
687
if (major >= FR550_MAJOR_M_1 && major <= FR550_MAJOR_M_5
688
&& CGEN_INSN_NUM (insn) != FRV_INSN_MNOP)
689
return ! fr550_find_float_in_vliw (vliw);
690
/* F-2 in slot f2 or f3 cannot coexist with F-2 or F-4 in slot f1 or f2
692
if (major == FR550_MAJOR_F_2)
693
return ! find_major_in_slot (vliw, FR550_MAJOR_F_2,
694
slot - (UNIT_FM2 - UNIT_FM0))
695
&& ! find_major_in_slot (vliw, FR550_MAJOR_F_4,
696
slot - (UNIT_FM2 - UNIT_FM0));
697
/* M-2 or M-5 in slot m2 or m3 cannot coexist with M-2 in slot m1 or m2
699
if (major == FR550_MAJOR_M_2 || major == FR550_MAJOR_M_5)
700
return ! find_major_in_slot (vliw, FR550_MAJOR_M_2,
701
slot - (UNIT_FM2 - UNIT_FM0));
702
/* M-4 in slot m2 or m3 cannot coexist with M-4 in slot m1 or m2
704
if (major == FR550_MAJOR_M_4)
705
return ! find_major_in_slot (vliw, FR550_MAJOR_M_4,
706
slot - (UNIT_FM2 - UNIT_FM0));
711
return TRUE; /* All OK. */
715
fr500_check_insn_major_constraints (FRV_VLIW *vliw, CGEN_ATTR_VALUE_ENUM_TYPE major)
717
/* TODO: A table might be faster for some of the more complex instances
721
case FR500_MAJOR_I_1:
722
case FR500_MAJOR_I_4:
723
case FR500_MAJOR_I_5:
724
case FR500_MAJOR_I_6:
725
case FR500_MAJOR_B_1:
726
case FR500_MAJOR_B_2:
727
case FR500_MAJOR_B_3:
728
case FR500_MAJOR_B_4:
729
case FR500_MAJOR_B_5:
730
case FR500_MAJOR_B_6:
731
case FR500_MAJOR_F_4:
732
case FR500_MAJOR_F_8:
733
case FR500_MAJOR_M_8:
734
return TRUE; /* OK */
735
case FR500_MAJOR_I_2:
736
/* Cannot coexist with I-3 insn. */
737
return ! find_major_in_vliw (vliw, FR500_MAJOR_I_3);
738
case FR500_MAJOR_I_3:
739
/* Cannot coexist with I-2 insn. */
740
return ! find_major_in_vliw (vliw, FR500_MAJOR_I_2);
741
case FR500_MAJOR_F_1:
742
case FR500_MAJOR_F_2:
743
/* Cannot coexist with F-5, F-6, or M-7 insn. */
744
return ! find_major_in_vliw (vliw, FR500_MAJOR_F_5)
745
&& ! find_major_in_vliw (vliw, FR500_MAJOR_F_6)
746
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
747
case FR500_MAJOR_F_3:
748
/* Cannot coexist with F-7, or M-7 insn. */
749
return ! find_major_in_vliw (vliw, FR500_MAJOR_F_7)
750
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
751
case FR500_MAJOR_F_5:
752
/* Cannot coexist with F-1, F-2, F-6, F-7, or M-7 insn. */
753
return ! find_major_in_vliw (vliw, FR500_MAJOR_F_1)
754
&& ! find_major_in_vliw (vliw, FR500_MAJOR_F_2)
755
&& ! find_major_in_vliw (vliw, FR500_MAJOR_F_6)
756
&& ! find_major_in_vliw (vliw, FR500_MAJOR_F_7)
757
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
758
case FR500_MAJOR_F_6:
759
/* Cannot coexist with F-1, F-2, F-5, F-6, or M-7 insn. */
760
return ! find_major_in_vliw (vliw, FR500_MAJOR_F_1)
761
&& ! find_major_in_vliw (vliw, FR500_MAJOR_F_2)
762
&& ! find_major_in_vliw (vliw, FR500_MAJOR_F_5)
763
&& ! find_major_in_vliw (vliw, FR500_MAJOR_F_6)
764
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
765
case FR500_MAJOR_F_7:
766
/* Cannot coexist with F-3, F-5, F-7, or M-7 insn. */
767
return ! find_major_in_vliw (vliw, FR500_MAJOR_F_3)
768
&& ! find_major_in_vliw (vliw, FR500_MAJOR_F_5)
769
&& ! find_major_in_vliw (vliw, FR500_MAJOR_F_7)
770
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
771
case FR500_MAJOR_M_1:
772
/* Cannot coexist with M-7 insn. */
773
return ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
774
case FR500_MAJOR_M_2:
775
case FR500_MAJOR_M_3:
776
/* Cannot coexist with M-5, M-6 or M-7 insn. */
777
return ! find_major_in_vliw (vliw, FR500_MAJOR_M_5)
778
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_6)
779
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
780
case FR500_MAJOR_M_4:
781
/* Cannot coexist with M-6 insn. */
782
return ! find_major_in_vliw (vliw, FR500_MAJOR_M_6);
783
case FR500_MAJOR_M_5:
784
/* Cannot coexist with M-2, M-3, M-5, M-6 or M-7 insn. */
785
return ! find_major_in_vliw (vliw, FR500_MAJOR_M_2)
786
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_3)
787
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_5)
788
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_6)
789
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
790
case FR500_MAJOR_M_6:
791
/* Cannot coexist with M-2, M-3, M-4, M-5, M-6 or M-7 insn. */
792
return ! find_major_in_vliw (vliw, FR500_MAJOR_M_2)
793
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_3)
794
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_4)
795
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_5)
796
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_6)
797
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
798
case FR500_MAJOR_M_7:
799
/* Cannot coexist with M-1, M-2, M-3, M-5, M-6 or M-7 insn. */
800
return ! find_major_in_vliw (vliw, FR500_MAJOR_M_1)
801
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_2)
802
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_3)
803
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_5)
804
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_6)
805
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_7)
806
&& ! find_major_in_vliw (vliw, FR500_MAJOR_F_1)
807
&& ! find_major_in_vliw (vliw, FR500_MAJOR_F_2)
808
&& ! find_major_in_vliw (vliw, FR500_MAJOR_F_3)
809
&& ! find_major_in_vliw (vliw, FR500_MAJOR_F_5)
810
&& ! find_major_in_vliw (vliw, FR500_MAJOR_F_6)
811
&& ! find_major_in_vliw (vliw, FR500_MAJOR_F_7);
813
fprintf (stderr, "frv-opc.c, line %d: bad major code, aborting.\n",
822
check_insn_major_constraints (FRV_VLIW *vliw,
823
CGEN_ATTR_VALUE_ENUM_TYPE major,
824
const CGEN_INSN *insn)
829
return fr400_check_insn_major_constraints (vliw, major);
832
return fr450_check_insn_major_constraints (vliw, major);
835
return fr550_check_insn_major_constraints (vliw, major, insn);
838
return fr500_check_insn_major_constraints (vliw, major);
842
/* Add in insn to the VLIW vliw if possible.
843
Return 0 if successful, non-zero otherwise. */
846
frv_vliw_add_insn (FRV_VLIW *vliw, const CGEN_INSN *insn)
849
CGEN_ATTR_VALUE_ENUM_TYPE major;
850
CGEN_ATTR_VALUE_ENUM_TYPE unit;
851
VLIW_COMBO *new_vliw;
853
if (vliw->constraint_violation || CGEN_INSN_INVALID_P (insn))
856
slot_index = vliw->next_slot;
857
if (slot_index >= FRV_VLIW_SIZE)
860
unit = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_UNIT);
861
if (unit == UNIT_NIL)
863
fprintf (stderr, "frv-opc.c line %d: bad insn unit.\n",
865
abort (); /* No UNIT specified for this insn in frv.cpu. */
871
major = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR400_MAJOR);
874
major = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR450_MAJOR);
877
major = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR550_MAJOR);
880
major = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR500_MAJOR);
886
/* Any insn can be added to slot 0. */
887
while (! match_unit (vliw, unit, (*vliw->current_vliw)[0]))
888
++vliw->current_vliw;
889
vliw->major[0] = major;
890
vliw->insn[0] = insn;
895
/* If there are already insns in the vliw(s) check to see that
896
this one can be added. Do this by finding an allowable vliw
897
combination that can accept the new insn. */
898
if (! (vliw->elf_flags & EF_FRV_NOPACK))
900
new_vliw = add_next_to_vliw (vliw, unit);
901
if (new_vliw && check_insn_major_constraints (vliw, major, insn))
903
vliw->current_vliw = new_vliw;
904
vliw->major[slot_index] = major;
905
vliw->insn[slot_index] = insn;
910
/* The frv machine supports all packing conbinations. If we fail,
911
to add the insn, then it could not be handled as if it was the fr500.
912
Just return as if it was handled ok. */
913
if (vliw->mach == bfd_mach_frv)
917
vliw->constraint_violation = 1;
922
spr_valid (long regno)
924
if (regno < 0) return FALSE;
925
if (regno <= 4095) return TRUE;
931
inline static const char *
932
parse_symbolic_address (CGEN_CPU_DESC cd,
936
enum cgen_parse_operand_result *resultp,
939
enum cgen_parse_operand_result result_type;
940
const char *errmsg = (* cd->parse_operand_fn)
941
(cd, CGEN_PARSE_OPERAND_SYMBOLIC, strp, opindex, opinfo,
942
&result_type, valuep);
945
&& result_type != CGEN_PARSE_OPERAND_RESULT_QUEUED)
946
return "symbolic expression required";
949
*resultp = result_type;
955
parse_ldd_annotation (CGEN_CPU_DESC cd,
958
unsigned long *valuep)
961
enum cgen_parse_operand_result result_type;
964
if (**strp == '#' || **strp == '%')
966
if (strncasecmp (*strp + 1, "tlsdesc(", 8) == 0)
969
errmsg = parse_symbolic_address (cd, strp, opindex,
970
BFD_RELOC_FRV_TLSDESC_RELAX,
971
&result_type, &value);
973
return "missing ')'";
982
while (**strp == ' ' || **strp == '\t')
986
return "missing `@'";
994
parse_call_annotation (CGEN_CPU_DESC cd,
997
unsigned long *valuep)
1000
enum cgen_parse_operand_result result_type;
1003
if (**strp == '#' || **strp == '%')
1005
if (strncasecmp (*strp + 1, "gettlsoff(", 10) == 0)
1008
errmsg = parse_symbolic_address (cd, strp, opindex,
1009
BFD_RELOC_FRV_GETTLSOFF_RELAX,
1010
&result_type, &value);
1012
return "missing ')'";
1021
while (**strp == ' ' || **strp == '\t')
1025
return "missing `@'";
1033
parse_ld_annotation (CGEN_CPU_DESC cd,
1036
unsigned long *valuep)
1039
enum cgen_parse_operand_result result_type;
1042
if (**strp == '#' || **strp == '%')
1044
if (strncasecmp (*strp + 1, "tlsoff(", 7) == 0)
1047
errmsg = parse_symbolic_address (cd, strp, opindex,
1048
BFD_RELOC_FRV_TLSOFF_RELAX,
1049
&result_type, &value);
1051
return "missing ')'";
1060
while (**strp == ' ' || **strp == '\t')
1064
return "missing `@'";
1072
parse_ulo16 (CGEN_CPU_DESC cd,
1075
unsigned long *valuep)
1078
enum cgen_parse_operand_result result_type;
1081
if (**strp == '#' || **strp == '%')
1083
if (strncasecmp (*strp + 1, "lo(", 3) == 0)
1086
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16,
1087
& result_type, & value);
1089
return "missing `)'";
1092
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
1097
if (strncasecmp (*strp + 1, "gprello(", 8) == 0)
1100
errmsg = parse_symbolic_address (cd, strp, opindex,
1101
BFD_RELOC_FRV_GPRELLO,
1102
& result_type, & value);
1104
return "missing ')'";
1109
else if (strncasecmp (*strp + 1, "gotlo(", 6) == 0)
1112
errmsg = parse_symbolic_address (cd, strp, opindex,
1113
BFD_RELOC_FRV_GOTLO,
1114
& result_type, & value);
1116
return "missing ')'";
1121
else if (strncasecmp (*strp + 1, "gotfuncdesclo(", 14) == 0)
1124
errmsg = parse_symbolic_address (cd, strp, opindex,
1125
BFD_RELOC_FRV_FUNCDESC_GOTLO,
1126
& result_type, & value);
1128
return "missing ')'";
1133
else if (strncasecmp (*strp + 1, "gotofflo(", 9) == 0)
1136
errmsg = parse_symbolic_address (cd, strp, opindex,
1137
BFD_RELOC_FRV_GOTOFFLO,
1138
& result_type, & value);
1140
return "missing ')'";
1145
else if (strncasecmp (*strp + 1, "gotofffuncdesclo(", 17) == 0)
1148
errmsg = parse_symbolic_address (cd, strp, opindex,
1149
BFD_RELOC_FRV_FUNCDESC_GOTOFFLO,
1150
& result_type, & value);
1152
return "missing ')'";
1157
else if (strncasecmp (*strp + 1, "gottlsdesclo(", 13) == 0)
1160
errmsg = parse_symbolic_address (cd, strp, opindex,
1161
BFD_RELOC_FRV_GOTTLSDESCLO,
1162
& result_type, & value);
1164
return "missing ')'";
1169
else if (strncasecmp (*strp + 1, "tlsmofflo(", 10) == 0)
1172
errmsg = parse_symbolic_address (cd, strp, opindex,
1173
BFD_RELOC_FRV_TLSMOFFLO,
1174
& result_type, & value);
1176
return "missing ')'";
1181
else if (strncasecmp (*strp + 1, "gottlsofflo(", 12) == 0)
1184
errmsg = parse_symbolic_address (cd, strp, opindex,
1185
BFD_RELOC_FRV_GOTTLSOFFLO,
1186
& result_type, & value);
1188
return "missing ')'";
1194
return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
1198
parse_uslo16 (CGEN_CPU_DESC cd,
1201
signed long *valuep)
1204
enum cgen_parse_operand_result result_type;
1207
if (**strp == '#' || **strp == '%')
1209
if (strncasecmp (*strp + 1, "lo(", 3) == 0)
1212
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16,
1213
& result_type, & value);
1215
return "missing `)'";
1218
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
1223
else if (strncasecmp (*strp + 1, "gprello(", 8) == 0)
1226
errmsg = parse_symbolic_address (cd, strp, opindex,
1227
BFD_RELOC_FRV_GPRELLO,
1228
& result_type, & value);
1230
return "missing ')'";
1235
else if (strncasecmp (*strp + 1, "gotlo(", 6) == 0)
1238
errmsg = parse_symbolic_address (cd, strp, opindex,
1239
BFD_RELOC_FRV_GOTLO,
1240
& result_type, & value);
1242
return "missing ')'";
1247
else if (strncasecmp (*strp + 1, "gotfuncdesclo(", 14) == 0)
1250
errmsg = parse_symbolic_address (cd, strp, opindex,
1251
BFD_RELOC_FRV_FUNCDESC_GOTLO,
1252
& result_type, & value);
1254
return "missing ')'";
1259
else if (strncasecmp (*strp + 1, "gotofflo(", 9) == 0)
1262
errmsg = parse_symbolic_address (cd, strp, opindex,
1263
BFD_RELOC_FRV_GOTOFFLO,
1264
& result_type, & value);
1266
return "missing ')'";
1271
else if (strncasecmp (*strp + 1, "gotofffuncdesclo(", 17) == 0)
1274
errmsg = parse_symbolic_address (cd, strp, opindex,
1275
BFD_RELOC_FRV_FUNCDESC_GOTOFFLO,
1276
& result_type, & value);
1278
return "missing ')'";
1283
else if (strncasecmp (*strp + 1, "gottlsdesclo(", 13) == 0)
1286
errmsg = parse_symbolic_address (cd, strp, opindex,
1287
BFD_RELOC_FRV_GOTTLSDESCLO,
1288
& result_type, & value);
1290
return "missing ')'";
1295
else if (strncasecmp (*strp + 1, "tlsmofflo(", 10) == 0)
1298
errmsg = parse_symbolic_address (cd, strp, opindex,
1299
BFD_RELOC_FRV_TLSMOFFLO,
1300
& result_type, & value);
1302
return "missing ')'";
1307
else if (strncasecmp (*strp + 1, "gottlsofflo(", 12) == 0)
1310
errmsg = parse_symbolic_address (cd, strp, opindex,
1311
BFD_RELOC_FRV_GOTTLSOFFLO,
1312
& result_type, & value);
1314
return "missing ')'";
1320
return cgen_parse_signed_integer (cd, strp, opindex, valuep);
1324
parse_uhi16 (CGEN_CPU_DESC cd,
1327
unsigned long *valuep)
1330
enum cgen_parse_operand_result result_type;
1333
if (**strp == '#' || **strp == '%')
1335
if (strncasecmp (*strp + 1, "hi(", 3) == 0)
1338
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_HI16,
1339
& result_type, & value);
1341
return "missing `)'";
1344
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
1346
/* If value is wider than 32 bits then be
1347
careful about how we extract bits 16-31. */
1348
if (sizeof (value) > 4)
1349
value &= (((bfd_vma)1 << 16) << 16) - 1;
1356
else if (strncasecmp (*strp + 1, "gprelhi(", 8) == 0)
1359
errmsg = parse_symbolic_address (cd, strp, opindex,
1360
BFD_RELOC_FRV_GPRELHI,
1361
& result_type, & value);
1363
return "missing ')'";
1368
else if (strncasecmp (*strp + 1, "gothi(", 6) == 0)
1371
errmsg = parse_symbolic_address (cd, strp, opindex,
1372
BFD_RELOC_FRV_GOTHI,
1373
& result_type, & value);
1375
return "missing ')'";
1380
else if (strncasecmp (*strp + 1, "gotfuncdeschi(", 14) == 0)
1383
errmsg = parse_symbolic_address (cd, strp, opindex,
1384
BFD_RELOC_FRV_FUNCDESC_GOTHI,
1385
& result_type, & value);
1387
return "missing ')'";
1392
else if (strncasecmp (*strp + 1, "gotoffhi(", 9) == 0)
1395
errmsg = parse_symbolic_address (cd, strp, opindex,
1396
BFD_RELOC_FRV_GOTOFFHI,
1397
& result_type, & value);
1399
return "missing ')'";
1404
else if (strncasecmp (*strp + 1, "gotofffuncdeschi(", 17) == 0)
1407
errmsg = parse_symbolic_address (cd, strp, opindex,
1408
BFD_RELOC_FRV_FUNCDESC_GOTOFFHI,
1409
& result_type, & value);
1411
return "missing ')'";
1416
else if (strncasecmp (*strp + 1, "gottlsdeschi(", 13) == 0)
1419
errmsg = parse_symbolic_address (cd, strp, opindex,
1420
BFD_RELOC_FRV_GOTTLSDESCHI,
1421
&result_type, &value);
1423
return "missing ')'";
1428
else if (strncasecmp (*strp + 1, "tlsmoffhi(", 10) == 0)
1431
errmsg = parse_symbolic_address (cd, strp, opindex,
1432
BFD_RELOC_FRV_TLSMOFFHI,
1433
& result_type, & value);
1435
return "missing ')'";
1440
else if (strncasecmp (*strp + 1, "gottlsoffhi(", 12) == 0)
1443
errmsg = parse_symbolic_address (cd, strp, opindex,
1444
BFD_RELOC_FRV_GOTTLSOFFHI,
1445
& result_type, & value);
1447
return "missing ')'";
1453
return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
1457
parse_register_number (const char **strp)
1461
if (**strp < '0' || **strp > '9')
1462
return -1; /* error */
1464
regno = **strp - '0';
1465
for (++*strp; **strp >= '0' && **strp <= '9'; ++*strp)
1466
regno = regno * 10 + (**strp - '0');
1472
parse_spr (CGEN_CPU_DESC cd,
1474
CGEN_KEYWORD * table,
1477
const char *save_strp;
1480
/* Check for spr index notation. */
1481
if (strncasecmp (*strp, "spr[", 4) == 0)
1484
regno = parse_register_number (strp);
1486
return _("missing `]'");
1488
if (! spr_valid (regno))
1489
return _("Special purpose register number is out of range");
1495
regno = parse_register_number (strp);
1498
if (! spr_valid (regno))
1499
return _("Special purpose register number is out of range");
1505
return cgen_parse_keyword (cd, strp, table, valuep);
1509
parse_d12 (CGEN_CPU_DESC cd,
1515
enum cgen_parse_operand_result result_type;
1518
/* Check for small data reference. */
1519
if (**strp == '#' || **strp == '%')
1521
if (strncasecmp (*strp + 1, "gprel12(", 8) == 0)
1524
errmsg = parse_symbolic_address (cd, strp, opindex,
1525
BFD_RELOC_FRV_GPREL12,
1526
& result_type, & value);
1528
return "missing `)'";
1533
else if (strncasecmp (*strp + 1, "got12(", 6) == 0)
1536
errmsg = parse_symbolic_address (cd, strp, opindex,
1537
BFD_RELOC_FRV_GOT12,
1538
& result_type, & value);
1540
return "missing ')'";
1545
else if (strncasecmp (*strp + 1, "gotfuncdesc12(", 14) == 0)
1548
errmsg = parse_symbolic_address (cd, strp, opindex,
1549
BFD_RELOC_FRV_FUNCDESC_GOT12,
1550
& result_type, & value);
1552
return "missing ')'";
1557
else if (strncasecmp (*strp + 1, "gotoff12(", 9) == 0)
1560
errmsg = parse_symbolic_address (cd, strp, opindex,
1561
BFD_RELOC_FRV_GOTOFF12,
1562
& result_type, & value);
1564
return "missing ')'";
1569
else if (strncasecmp (*strp + 1, "gotofffuncdesc12(", 17) == 0)
1572
errmsg = parse_symbolic_address (cd, strp, opindex,
1573
BFD_RELOC_FRV_FUNCDESC_GOTOFF12,
1574
& result_type, & value);
1576
return "missing ')'";
1581
else if (strncasecmp (*strp + 1, "gottlsdesc12(", 13) == 0)
1584
errmsg = parse_symbolic_address (cd, strp, opindex,
1585
BFD_RELOC_FRV_GOTTLSDESC12,
1586
& result_type, & value);
1588
return "missing ')'";
1593
else if (strncasecmp (*strp + 1, "tlsmoff12(", 10) == 0)
1596
errmsg = parse_symbolic_address (cd, strp, opindex,
1597
BFD_RELOC_FRV_TLSMOFF12,
1598
& result_type, & value);
1600
return "missing ')'";
1605
else if (strncasecmp (*strp + 1, "gottlsoff12(", 12) == 0)
1608
errmsg = parse_symbolic_address (cd, strp, opindex,
1609
BFD_RELOC_FRV_GOTTLSOFF12,
1610
& result_type, & value);
1612
return "missing ')'";
1618
return cgen_parse_signed_integer (cd, strp, opindex, valuep);
1622
parse_s12 (CGEN_CPU_DESC cd,
1628
enum cgen_parse_operand_result result_type;
1631
/* Check for small data reference. */
1632
if (**strp == '#' || **strp == '%')
1634
if (strncasecmp (*strp + 1, "gprel12(", 8) == 0)
1637
errmsg = parse_symbolic_address (cd, strp, opindex,
1638
BFD_RELOC_FRV_GPREL12,
1639
& result_type, & value);
1641
return "missing `)'";
1646
else if (strncasecmp (*strp + 1, "got12(", 6) == 0)
1649
errmsg = parse_symbolic_address (cd, strp, opindex,
1650
BFD_RELOC_FRV_GOT12,
1651
& result_type, & value);
1653
return "missing ')'";
1658
else if (strncasecmp (*strp + 1, "gotfuncdesc12(", 14) == 0)
1661
errmsg = parse_symbolic_address (cd, strp, opindex,
1662
BFD_RELOC_FRV_FUNCDESC_GOT12,
1663
& result_type, & value);
1665
return "missing ')'";
1670
else if (strncasecmp (*strp + 1, "gotoff12(", 9) == 0)
1673
errmsg = parse_symbolic_address (cd, strp, opindex,
1674
BFD_RELOC_FRV_GOTOFF12,
1675
& result_type, & value);
1677
return "missing ')'";
1682
else if (strncasecmp (*strp + 1, "gotofffuncdesc12(", 17) == 0)
1685
errmsg = parse_symbolic_address (cd, strp, opindex,
1686
BFD_RELOC_FRV_FUNCDESC_GOTOFF12,
1687
& result_type, & value);
1689
return "missing ')'";
1694
else if (strncasecmp (*strp + 1, "gottlsdesc12(", 13) == 0)
1697
errmsg = parse_symbolic_address (cd, strp, opindex,
1698
BFD_RELOC_FRV_GOTTLSDESC12,
1699
& result_type, & value);
1701
return "missing ')'";
1706
else if (strncasecmp (*strp + 1, "tlsmoff12(", 10) == 0)
1709
errmsg = parse_symbolic_address (cd, strp, opindex,
1710
BFD_RELOC_FRV_TLSMOFF12,
1711
& result_type, & value);
1713
return "missing ')'";
1718
else if (strncasecmp (*strp + 1, "gottlsoff12(", 12) == 0)
1721
errmsg = parse_symbolic_address (cd, strp, opindex,
1722
BFD_RELOC_FRV_GOTTLSOFF12,
1723
& result_type, & value);
1725
return "missing ')'";
1734
return cgen_parse_signed_integer (cd, strp, opindex, valuep);
1738
parse_u12 (CGEN_CPU_DESC cd,
1744
enum cgen_parse_operand_result result_type;
1747
/* Check for small data reference. */
1748
if ((**strp == '#' || **strp == '%')
1749
&& strncasecmp (*strp + 1, "gprel12(", 8) == 0)
1752
errmsg = parse_symbolic_address (cd, strp, opindex,
1753
BFD_RELOC_FRV_GPRELU12,
1754
& result_type, & value);
1756
return "missing `)'";
1765
return cgen_parse_signed_integer (cd, strp, opindex, valuep);
1770
parse_A (CGEN_CPU_DESC cd,
1773
unsigned long *valuep,
1781
errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
1786
return _("Value of A operand must be 0 or 1");
1792
parse_A0 (CGEN_CPU_DESC cd,
1795
unsigned long *valuep)
1797
return parse_A (cd, strp, opindex, valuep, 0);
1801
parse_A1 (CGEN_CPU_DESC cd,
1804
unsigned long *valuep)
1806
return parse_A (cd, strp, opindex, valuep, 1);
1810
parse_even_register (CGEN_CPU_DESC cd,
1812
CGEN_KEYWORD * tableP,
1815
const char * errmsg;
1816
const char * saved_star_strP = * strP;
1818
errmsg = cgen_parse_keyword (cd, strP, tableP, valueP);
1820
if (errmsg == NULL && ((* valueP) & 1))
1822
errmsg = _("register number must be even");
1823
* strP = saved_star_strP;
1830
parse_call_label (CGEN_CPU_DESC cd,
1834
enum cgen_parse_operand_result *resultp,
1840
/* Check for small data reference. */
1841
if (opinfo == 0 && (**strp == '#' || **strp == '%'))
1843
if (strncasecmp (*strp + 1, "gettlsoff(", 10) == 0)
1846
errmsg = parse_symbolic_address (cd, strp, opindex,
1847
BFD_RELOC_FRV_GETTLSOFF,
1850
return _("missing `)'");
1857
return cgen_parse_address (cd, strp, opindex, opinfo, resultp, valuep);
1864
print_at (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1866
long reloc_ann ATTRIBUTE_UNUSED,
1867
long value ATTRIBUTE_UNUSED,
1868
bfd_vma pc ATTRIBUTE_UNUSED,
1869
int length ATTRIBUTE_UNUSED)
1871
disassemble_info *info = (disassemble_info *) dis_info;
1873
(*info->fprintf_func) (info->stream, "@");
1877
print_spr (CGEN_CPU_DESC cd,
1879
CGEN_KEYWORD *names,
1883
/* Use the register index format for any unnamed registers. */
1884
if (cgen_keyword_lookup_value (names, regno) == NULL)
1886
disassemble_info *info = (disassemble_info *) dis_info;
1887
(*info->fprintf_func) (info->stream, "spr[%ld]", regno);
1890
print_keyword (cd, dis_info, names, regno, attrs);
1894
print_hi (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1897
unsigned int attrs ATTRIBUTE_UNUSED,
1898
bfd_vma pc ATTRIBUTE_UNUSED,
1899
int length ATTRIBUTE_UNUSED)
1901
disassemble_info *info = (disassemble_info *) dis_info;
1903
(*info->fprintf_func) (info->stream, value ? "0x%lx" : "hi(0x%lx)", value);
1907
print_lo (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1910
unsigned int attrs ATTRIBUTE_UNUSED,
1911
bfd_vma pc ATTRIBUTE_UNUSED,
1912
int length ATTRIBUTE_UNUSED)
1914
disassemble_info *info = (disassemble_info *) dis_info;
1916
(*info->fprintf_func) (info->stream, "0x%lx", value);
1918
(*info->fprintf_func) (info->stream, "lo(0x%lx)", value);