1 /* Assembler interface for targets using CGEN. -*- C -*-
2 CGEN: Cpu tools GENerator
4 THIS FILE IS USED TO GENERATE fr30-asm.c.
6 Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
8 This file is part of the GNU Binutils and GDB, the GNU debugger.
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 2, or (at your option)
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 Foundation, Inc.,
22 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
34 #define min(a,b) ((a) < (b) ? (a) : (b))
36 #define max(a,b) ((a) > (b) ? (a) : (b))
40 #define INLINE __inline__
45 /* Used by the ifield rtx function. */
46 #define FLD(f) (fields->f)
48 static const char * insert_normal
49 PARAMS ((CGEN_OPCODE_DESC
, long, unsigned int, unsigned int, unsigned int,
50 unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR
));
51 static const char * parse_insn_normal
52 PARAMS ((CGEN_OPCODE_DESC
, const CGEN_INSN
*,
53 const char **, CGEN_FIELDS
*));
54 static const char * insert_insn_normal
55 PARAMS ((CGEN_OPCODE_DESC
, const CGEN_INSN
*,
56 CGEN_FIELDS
*, CGEN_INSN_BYTES_PTR
, bfd_vma
));
58 /* -- assembler routines inserted here */
60 /* Handle register lists for LDMx and STMx */
63 parse_low_register_list (od
, strp
, opindex
, valuep
)
67 unsigned long *valuep
;
70 while (**strp
&& **strp
!= ')')
76 return "Register list is not valid";
82 parse_hi_register_list (od
, strp
, opindex
, valuep
)
86 unsigned long *valuep
;
88 return parse_low_register_list (od
, strp
, opindex
, valuep
);
93 /* Main entry point for operand parsing.
95 This function is basically just a big switch statement. Earlier versions
96 used tables to look up the function to use, but
97 - if the table contains both assembler and disassembler functions then
98 the disassembler contains much of the assembler and vice-versa,
99 - there's a lot of inlining possibilities as things grow,
100 - using a switch statement avoids the function call overhead.
102 This function could be moved into `parse_insn_normal', but keeping it
103 separate makes clear the interface between `parse_insn_normal' and each of
108 fr30_cgen_parse_operand (od
, opindex
, strp
, fields
)
112 CGEN_FIELDS
* fields
;
118 case FR30_OPERAND_RI
:
119 errmsg
= cgen_parse_keyword (od
, strp
, & fr30_cgen_opval_h_gr
, & fields
->f_Ri
);
121 case FR30_OPERAND_RJ
:
122 errmsg
= cgen_parse_keyword (od
, strp
, & fr30_cgen_opval_h_gr
, & fields
->f_Rj
);
124 case FR30_OPERAND_RIC
:
125 errmsg
= cgen_parse_keyword (od
, strp
, & fr30_cgen_opval_h_gr
, & fields
->f_Ric
);
127 case FR30_OPERAND_RJC
:
128 errmsg
= cgen_parse_keyword (od
, strp
, & fr30_cgen_opval_h_gr
, & fields
->f_Rjc
);
130 case FR30_OPERAND_CRI
:
131 errmsg
= cgen_parse_keyword (od
, strp
, & fr30_cgen_opval_h_cr
, & fields
->f_CRi
);
133 case FR30_OPERAND_CRJ
:
134 errmsg
= cgen_parse_keyword (od
, strp
, & fr30_cgen_opval_h_cr
, & fields
->f_CRj
);
136 case FR30_OPERAND_RS1
:
137 errmsg
= cgen_parse_keyword (od
, strp
, & fr30_cgen_opval_h_dr
, & fields
->f_Rs1
);
139 case FR30_OPERAND_RS2
:
140 errmsg
= cgen_parse_keyword (od
, strp
, & fr30_cgen_opval_h_dr
, & fields
->f_Rs2
);
142 case FR30_OPERAND_R13
:
143 errmsg
= cgen_parse_keyword (od
, strp
, & fr30_cgen_opval_h_r13
, & fields
->f_nil
);
145 case FR30_OPERAND_R14
:
146 errmsg
= cgen_parse_keyword (od
, strp
, & fr30_cgen_opval_h_r14
, & fields
->f_nil
);
148 case FR30_OPERAND_R15
:
149 errmsg
= cgen_parse_keyword (od
, strp
, & fr30_cgen_opval_h_r15
, & fields
->f_nil
);
151 case FR30_OPERAND_PS
:
152 errmsg
= cgen_parse_keyword (od
, strp
, & fr30_cgen_opval_h_ps
, & fields
->f_nil
);
154 case FR30_OPERAND_U4
:
155 errmsg
= cgen_parse_unsigned_integer (od
, strp
, FR30_OPERAND_U4
, &fields
->f_u4
);
157 case FR30_OPERAND_U4C
:
158 errmsg
= cgen_parse_unsigned_integer (od
, strp
, FR30_OPERAND_U4C
, &fields
->f_u4c
);
160 case FR30_OPERAND_U8
:
161 errmsg
= cgen_parse_unsigned_integer (od
, strp
, FR30_OPERAND_U8
, &fields
->f_u8
);
163 case FR30_OPERAND_I8
:
164 errmsg
= cgen_parse_unsigned_integer (od
, strp
, FR30_OPERAND_I8
, &fields
->f_i8
);
166 case FR30_OPERAND_UDISP6
:
167 errmsg
= cgen_parse_unsigned_integer (od
, strp
, FR30_OPERAND_UDISP6
, &fields
->f_udisp6
);
169 case FR30_OPERAND_DISP8
:
170 errmsg
= cgen_parse_signed_integer (od
, strp
, FR30_OPERAND_DISP8
, &fields
->f_disp8
);
172 case FR30_OPERAND_DISP9
:
173 errmsg
= cgen_parse_signed_integer (od
, strp
, FR30_OPERAND_DISP9
, &fields
->f_disp9
);
175 case FR30_OPERAND_DISP10
:
176 errmsg
= cgen_parse_signed_integer (od
, strp
, FR30_OPERAND_DISP10
, &fields
->f_disp10
);
178 case FR30_OPERAND_S10
:
179 errmsg
= cgen_parse_signed_integer (od
, strp
, FR30_OPERAND_S10
, &fields
->f_s10
);
181 case FR30_OPERAND_U10
:
182 errmsg
= cgen_parse_unsigned_integer (od
, strp
, FR30_OPERAND_U10
, &fields
->f_u10
);
184 case FR30_OPERAND_I32
:
185 errmsg
= cgen_parse_unsigned_integer (od
, strp
, FR30_OPERAND_I32
, &fields
->f_i32
);
187 case FR30_OPERAND_M4
:
188 errmsg
= cgen_parse_signed_integer (od
, strp
, FR30_OPERAND_M4
, &fields
->f_m4
);
190 case FR30_OPERAND_I20
:
191 errmsg
= cgen_parse_unsigned_integer (od
, strp
, FR30_OPERAND_I20
, &fields
->f_i20
);
193 case FR30_OPERAND_DIR8
:
194 errmsg
= cgen_parse_unsigned_integer (od
, strp
, FR30_OPERAND_DIR8
, &fields
->f_dir8
);
196 case FR30_OPERAND_DIR9
:
197 errmsg
= cgen_parse_unsigned_integer (od
, strp
, FR30_OPERAND_DIR9
, &fields
->f_dir9
);
199 case FR30_OPERAND_DIR10
:
200 errmsg
= cgen_parse_unsigned_integer (od
, strp
, FR30_OPERAND_DIR10
, &fields
->f_dir10
);
202 case FR30_OPERAND_LABEL9
:
205 errmsg
= cgen_parse_address (od
, strp
, FR30_OPERAND_LABEL9
, 0, NULL
, & value
);
206 fields
->f_rel9
= value
;
209 case FR30_OPERAND_LABEL12
:
212 errmsg
= cgen_parse_address (od
, strp
, FR30_OPERAND_LABEL12
, 0, NULL
, & value
);
213 fields
->f_rel12
= value
;
216 case FR30_OPERAND_REGLIST_LOW
:
217 errmsg
= parse_low_register_list (od
, strp
, FR30_OPERAND_REGLIST_LOW
, &fields
->f_reglist_low
);
219 case FR30_OPERAND_REGLIST_HI
:
220 errmsg
= parse_hi_register_list (od
, strp
, FR30_OPERAND_REGLIST_HI
, &fields
->f_reglist_hi
);
222 case FR30_OPERAND_CC
:
223 errmsg
= cgen_parse_unsigned_integer (od
, strp
, FR30_OPERAND_CC
, &fields
->f_cc
);
225 case FR30_OPERAND_CCC
:
226 errmsg
= cgen_parse_unsigned_integer (od
, strp
, FR30_OPERAND_CCC
, &fields
->f_ccc
);
230 /* xgettext:c-format */
231 fprintf (stderr
, _("Unrecognized field %d while parsing.\n"), opindex
);
238 /* Main entry point for operand insertion.
240 This function is basically just a big switch statement. Earlier versions
241 used tables to look up the function to use, but
242 - if the table contains both assembler and disassembler functions then
243 the disassembler contains much of the assembler and vice-versa,
244 - there's a lot of inlining possibilities as things grow,
245 - using a switch statement avoids the function call overhead.
247 This function could be moved into `parse_insn_normal', but keeping it
248 separate makes clear the interface between `parse_insn_normal' and each of
249 the handlers. It's also needed by GAS to insert operands that couldn't be
250 resolved during parsing.
254 fr30_cgen_insert_operand (od
, opindex
, fields
, buffer
, pc
)
257 CGEN_FIELDS
* fields
;
258 CGEN_INSN_BYTES_PTR buffer
;
262 unsigned int total_length
= CGEN_FIELDS_BITSIZE (fields
);
266 case FR30_OPERAND_RI
:
267 errmsg
= insert_normal (od
, fields
->f_Ri
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 0, 12, 4, 16, total_length
, buffer
);
269 case FR30_OPERAND_RJ
:
270 errmsg
= insert_normal (od
, fields
->f_Rj
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 0, 8, 4, 16, total_length
, buffer
);
272 case FR30_OPERAND_RIC
:
273 errmsg
= insert_normal (od
, fields
->f_Ric
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 16, 12, 4, 16, total_length
, buffer
);
275 case FR30_OPERAND_RJC
:
276 errmsg
= insert_normal (od
, fields
->f_Rjc
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 16, 8, 4, 16, total_length
, buffer
);
278 case FR30_OPERAND_CRI
:
279 errmsg
= insert_normal (od
, fields
->f_CRi
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 16, 12, 4, 16, total_length
, buffer
);
281 case FR30_OPERAND_CRJ
:
282 errmsg
= insert_normal (od
, fields
->f_CRj
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 16, 8, 4, 16, total_length
, buffer
);
284 case FR30_OPERAND_RS1
:
285 errmsg
= insert_normal (od
, fields
->f_Rs1
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 0, 8, 4, 16, total_length
, buffer
);
287 case FR30_OPERAND_RS2
:
288 errmsg
= insert_normal (od
, fields
->f_Rs2
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 0, 12, 4, 16, total_length
, buffer
);
290 case FR30_OPERAND_R13
:
291 errmsg
= insert_normal (od
, fields
->f_nil
, 0, 0, 0, 0, 0, total_length
, buffer
);
293 case FR30_OPERAND_R14
:
294 errmsg
= insert_normal (od
, fields
->f_nil
, 0, 0, 0, 0, 0, total_length
, buffer
);
296 case FR30_OPERAND_R15
:
297 errmsg
= insert_normal (od
, fields
->f_nil
, 0, 0, 0, 0, 0, total_length
, buffer
);
299 case FR30_OPERAND_PS
:
300 errmsg
= insert_normal (od
, fields
->f_nil
, 0, 0, 0, 0, 0, total_length
, buffer
);
302 case FR30_OPERAND_U4
:
303 errmsg
= insert_normal (od
, fields
->f_u4
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), 0, 8, 4, 16, total_length
, buffer
);
305 case FR30_OPERAND_U4C
:
306 errmsg
= insert_normal (od
, fields
->f_u4c
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), 0, 12, 4, 16, total_length
, buffer
);
308 case FR30_OPERAND_U8
:
309 errmsg
= insert_normal (od
, fields
->f_u8
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), 0, 8, 8, 16, total_length
, buffer
);
311 case FR30_OPERAND_I8
:
312 errmsg
= insert_normal (od
, fields
->f_i8
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), 0, 4, 8, 16, total_length
, buffer
);
314 case FR30_OPERAND_UDISP6
:
316 long value
= fields
->f_udisp6
;
317 value
= ((unsigned int) (value
) >> (2));
318 errmsg
= insert_normal (od
, value
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), 0, 8, 4, 16, total_length
, buffer
);
321 case FR30_OPERAND_DISP8
:
322 errmsg
= insert_normal (od
, fields
->f_disp8
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_SIGNED
), 0, 4, 8, 16, total_length
, buffer
);
324 case FR30_OPERAND_DISP9
:
326 long value
= fields
->f_disp9
;
327 value
= ((int) (value
) >> (1));
328 errmsg
= insert_normal (od
, value
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_SIGNED
), 0, 4, 8, 16, total_length
, buffer
);
331 case FR30_OPERAND_DISP10
:
333 long value
= fields
->f_disp10
;
334 value
= ((int) (value
) >> (2));
335 errmsg
= insert_normal (od
, value
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_SIGNED
), 0, 4, 8, 16, total_length
, buffer
);
338 case FR30_OPERAND_S10
:
340 long value
= fields
->f_s10
;
341 value
= ((int) (value
) >> (2));
342 errmsg
= insert_normal (od
, value
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_SIGNED
), 0, 8, 8, 16, total_length
, buffer
);
345 case FR30_OPERAND_U10
:
347 long value
= fields
->f_u10
;
348 value
= ((unsigned int) (value
) >> (2));
349 errmsg
= insert_normal (od
, value
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), 0, 8, 8, 16, total_length
, buffer
);
352 case FR30_OPERAND_I32
:
353 errmsg
= insert_normal (od
, fields
->f_i32
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_SIGN_OPT
)|(1<<CGEN_OPERAND_UNSIGNED
), 16, 0, 32, 32, total_length
, buffer
);
355 case FR30_OPERAND_M4
:
357 long value
= fields
->f_m4
;
358 value
= ((value
) & (15));
359 errmsg
= insert_normal (od
, value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 0, 8, 4, 16, total_length
, buffer
);
362 case FR30_OPERAND_I20
:
365 FLD (f_i20_4
) = ((unsigned int) (FLD (f_i20
)) >> (16));
366 FLD (f_i20_16
) = ((FLD (f_i20
)) & (65535));
368 errmsg
= insert_normal (od
, fields
->f_i20_4
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
)|(1<<CGEN_OPERAND_VIRTUAL
), 0, 8, 4, 16, total_length
, buffer
);
371 errmsg
= insert_normal (od
, fields
->f_i20_16
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
)|(1<<CGEN_OPERAND_VIRTUAL
), 16, 0, 16, 16, total_length
, buffer
);
376 case FR30_OPERAND_DIR8
:
377 errmsg
= insert_normal (od
, fields
->f_dir8
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 0, 8, 8, 16, total_length
, buffer
);
379 case FR30_OPERAND_DIR9
:
381 long value
= fields
->f_dir9
;
382 value
= ((unsigned int) (value
) >> (1));
383 errmsg
= insert_normal (od
, value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 0, 8, 8, 16, total_length
, buffer
);
386 case FR30_OPERAND_DIR10
:
388 long value
= fields
->f_dir10
;
389 value
= ((unsigned int) (value
) >> (2));
390 errmsg
= insert_normal (od
, value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 0, 8, 8, 16, total_length
, buffer
);
393 case FR30_OPERAND_LABEL9
:
395 long value
= fields
->f_rel9
;
396 value
= ((int) (((value
) - (((pc
) + (2))))) >> (1));
397 errmsg
= insert_normal (od
, value
, 0|(1<<CGEN_OPERAND_PCREL_ADDR
)|(1<<CGEN_OPERAND_SIGNED
), 0, 8, 8, 16, total_length
, buffer
);
400 case FR30_OPERAND_LABEL12
:
402 long value
= fields
->f_rel12
;
403 value
= ((int) (((value
) - (((pc
) + (2))))) >> (1));
404 errmsg
= insert_normal (od
, value
, 0|(1<<CGEN_OPERAND_PCREL_ADDR
)|(1<<CGEN_OPERAND_SIGNED
), 0, 5, 11, 16, total_length
, buffer
);
407 case FR30_OPERAND_REGLIST_LOW
:
408 errmsg
= insert_normal (od
, fields
->f_reglist_low
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 0, 8, 8, 16, total_length
, buffer
);
410 case FR30_OPERAND_REGLIST_HI
:
411 errmsg
= insert_normal (od
, fields
->f_reglist_hi
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 0, 8, 8, 16, total_length
, buffer
);
413 case FR30_OPERAND_CC
:
414 errmsg
= insert_normal (od
, fields
->f_cc
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 0, 4, 4, 16, total_length
, buffer
);
416 case FR30_OPERAND_CCC
:
417 errmsg
= insert_normal (od
, fields
->f_ccc
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), 16, 0, 8, 16, total_length
, buffer
);
421 /* xgettext:c-format */
422 fprintf (stderr
, _("Unrecognized field %d while building insn.\n"),
430 cgen_parse_fn
* const fr30_cgen_parse_handlers
[] =
436 cgen_insert_fn
* const fr30_cgen_insert_handlers
[] =
443 fr30_cgen_init_asm (od
)
449 #if ! CGEN_INT_INSN_P
451 /* Subroutine of insert_normal. */
454 insert_1 (od
, value
, start
, length
, word_length
, bufp
)
457 int start
,length
,word_length
;
460 unsigned long x
,mask
;
462 int big_p
= CGEN_OPCODE_INSN_ENDIAN (od
) == CGEN_ENDIAN_BIG
;
471 x
= bfd_getb16 (bufp
);
473 x
= bfd_getl16 (bufp
);
476 /* ??? This may need reworking as these cases don't necessarily
477 want the first byte and the last two bytes handled like this. */
479 x
= (bufp
[0] << 16) | bfd_getb16 (bufp
+ 1);
481 x
= bfd_getl16 (bufp
) | (bufp
[2] << 16);
485 x
= bfd_getb32 (bufp
);
487 x
= bfd_getl32 (bufp
);
493 /* Written this way to avoid undefined behaviour. */
494 mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
495 if (CGEN_INSN_LSB0_P
)
496 shift
= (start
+ 1) - length
;
498 shift
= (word_length
- (start
+ length
));
499 x
= (x
& ~(mask
<< shift
)) | ((value
& mask
) << shift
);
508 bfd_putb16 (x
, bufp
);
510 bfd_putl16 (x
, bufp
);
513 /* ??? This may need reworking as these cases don't necessarily
514 want the first byte and the last two bytes handled like this. */
518 bfd_putb16 (x
, bufp
+ 1);
522 bfd_putl16 (x
, bufp
);
528 bfd_putb32 (x
, bufp
);
530 bfd_putl32 (x
, bufp
);
537 #endif /* ! CGEN_INT_INSN_P */
539 /* Default insertion routine.
541 ATTRS is a mask of the boolean attributes.
542 WORD_OFFSET is the offset in bits from the start of the insn of the value.
543 WORD_LENGTH is the length of the word in bits in which the value resides.
544 START is the starting bit number in the word, architecture origin.
545 LENGTH is the length of VALUE in bits.
546 TOTAL_LENGTH is the total length of the insn in bits.
548 The result is an error message or NULL if success. */
550 /* ??? This duplicates functionality with bfd's howto table and
551 bfd_install_relocation. */
552 /* ??? This doesn't handle bfd_vma's. Create another function when
556 insert_normal (od
, value
, attrs
, word_offset
, start
, length
, word_length
,
557 total_length
, buffer
)
561 unsigned int word_offset
, start
, length
, word_length
, total_length
;
562 CGEN_INSN_BYTES_PTR buffer
;
564 static char errbuf
[100];
565 /* Written this way to avoid undefined behaviour. */
566 unsigned long mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
568 /* If LENGTH is zero, this operand doesn't contribute to the value. */
576 if (word_length
> 32)
579 /* For architectures with insns smaller than the insn-base-bitsize,
580 word_length may be too big. */
581 #if CGEN_MIN_INSN_BITSIZE < CGEN_BASE_INSN_BITSIZE
583 && word_length
> total_length
)
584 word_length
= total_length
;
587 /* Ensure VALUE will fit. */
588 if ((attrs
& CGEN_ATTR_MASK (CGEN_OPERAND_UNSIGNED
)) != 0)
590 unsigned long maxval
= mask
;
591 if ((unsigned long) value
> maxval
)
593 /* xgettext:c-format */
595 _("operand out of range (%lu not between 0 and %lu)"),
602 long minval
= - (1L << (length
- 1));
603 long maxval
= (1L << (length
- 1)) - 1;
604 if (value
< minval
|| value
> maxval
)
607 /* xgettext:c-format */
608 (errbuf
, _("operand out of range (%ld not between %ld and %ld)"),
609 value
, minval
, maxval
);
619 if (CGEN_INSN_LSB0_P
)
620 shift
= (start
+ 1) - length
;
622 shift
= word_length
- (start
+ length
);
623 *buffer
= (*buffer
& ~(mask
<< shift
)) | ((value
& mask
) << shift
);
626 #else /* ! CGEN_INT_INSN_P */
629 unsigned char *bufp
= (unsigned char *) buffer
+ word_offset
/ 8;
631 insert_1 (od
, value
, start
, length
, word_length
, bufp
);
634 #endif /* ! CGEN_INT_INSN_P */
639 /* Default insn parser.
641 The syntax string is scanned and operands are parsed and stored in FIELDS.
642 Relocs are queued as we go via other callbacks.
644 ??? Note that this is currently an all-or-nothing parser. If we fail to
645 parse the instruction, we return 0 and the caller will start over from
646 the beginning. Backtracking will be necessary in parsing subexpressions,
647 but that can be handled there. Not handling backtracking here may get
648 expensive in the case of the m68k. Deal with later.
650 Returns NULL for success, an error message for failure.
654 parse_insn_normal (od
, insn
, strp
, fields
)
656 const CGEN_INSN
* insn
;
658 CGEN_FIELDS
* fields
;
660 const CGEN_SYNTAX
* syntax
= CGEN_INSN_SYNTAX (insn
);
661 const char * str
= *strp
;
664 const unsigned char * syn
;
665 #ifdef CGEN_MNEMONIC_OPERANDS
670 /* For now we assume the mnemonic is first (there are no leading operands).
671 We can parse it without needing to set up operand parsing.
672 GAS's input scrubber will ensure mnemonics are lowercase, but we may
673 not be called from GAS. */
674 p
= CGEN_INSN_MNEMONIC (insn
);
675 while (*p
&& tolower (*p
) == tolower (*str
))
678 if (* p
|| (* str
&& !isspace (* str
)))
679 return _("unrecognized instruction");
681 CGEN_INIT_PARSE (od
);
682 cgen_init_parse_operand (od
);
683 #ifdef CGEN_MNEMONIC_OPERANDS
687 /* We don't check for (*str != '\0') here because we want to parse
688 any trailing fake arguments in the syntax string. */
689 syn
= CGEN_SYNTAX_STRING (syntax
);
691 /* Mnemonics come first for now, ensure valid string. */
692 if (! CGEN_SYNTAX_MNEMONIC_P (* syn
))
699 /* Non operand chars must match exactly. */
700 if (CGEN_SYNTAX_CHAR_P (* syn
))
702 if (*str
== CGEN_SYNTAX_CHAR (* syn
))
704 #ifdef CGEN_MNEMONIC_OPERANDS
713 /* Syntax char didn't match. Can't be this insn. */
714 /* FIXME: would like to return something like
715 "expected char `c'" */
716 return _("syntax error");
721 /* We have an operand of some sort. */
722 errmsg
= fr30_cgen_parse_operand (od
, CGEN_SYNTAX_FIELD (*syn
),
727 /* Done with this operand, continue with next one. */
731 /* If we're at the end of the syntax string, we're done. */
734 /* FIXME: For the moment we assume a valid `str' can only contain
735 blanks now. IE: We needn't try again with a longer version of
736 the insn and it is assumed that longer versions of insns appear
737 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
738 while (isspace (* str
))
742 return _("junk at end of line"); /* FIXME: would like to include `str' */
747 /* We couldn't parse it. */
748 return _("unrecognized instruction");
751 /* Default insn builder (insert handler).
752 The instruction is recorded in CGEN_INT_INSN_P byte order
753 (meaning that if CGEN_INT_INSN_P BUFFER is an int * and thus the value is
754 recorded in host byte order, otherwise BUFFER is an array of bytes and the
755 value is recorded in target byte order).
756 The result is an error message or NULL if success. */
759 insert_insn_normal (od
, insn
, fields
, buffer
, pc
)
761 const CGEN_INSN
* insn
;
762 CGEN_FIELDS
* fields
;
763 CGEN_INSN_BYTES_PTR buffer
;
766 const CGEN_SYNTAX
* syntax
= CGEN_INSN_SYNTAX (insn
);
768 const unsigned char * syn
;
770 CGEN_INIT_INSERT (od
);
771 value
= CGEN_INSN_BASE_VALUE (insn
);
773 /* If we're recording insns as numbers (rather than a string of bytes),
774 target byte order handling is deferred until later. */
782 cgen_put_insn_value (od
, buffer
, min (CGEN_BASE_INSN_BITSIZE
,
783 CGEN_FIELDS_BITSIZE (fields
)),
786 #endif /* ! CGEN_INT_INSN_P */
788 /* ??? It would be better to scan the format's fields.
789 Still need to be able to insert a value based on the operand though;
790 e.g. storing a branch displacement that got resolved later.
791 Needs more thought first. */
793 for (syn
= CGEN_SYNTAX_STRING (syntax
); * syn
!= '\0'; ++ syn
)
797 if (CGEN_SYNTAX_CHAR_P (* syn
))
800 errmsg
= fr30_cgen_insert_operand (od
, CGEN_SYNTAX_FIELD (*syn
),
810 This routine is called for each instruction to be assembled.
811 STR points to the insn to be assembled.
812 We assume all necessary tables have been initialized.
813 The assembled instruction, less any fixups, is stored in BUF.
814 Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
815 still needs to be converted to target byte order, otherwise BUF is an array
816 of bytes in target byte order.
817 The result is a pointer to the insn's entry in the opcode table,
818 or NULL if an error occured (an error message will have already been
821 Note that when processing (non-alias) macro-insns,
822 this function recurses. */
825 fr30_cgen_assemble_insn (od
, str
, fields
, buf
, errmsg
)
828 CGEN_FIELDS
* fields
;
829 CGEN_INSN_BYTES_PTR buf
;
833 CGEN_INSN_LIST
* ilist
;
835 /* Skip leading white space. */
836 while (isspace (* str
))
839 /* The instructions are stored in hashed lists.
840 Get the first in the list. */
841 ilist
= CGEN_ASM_LOOKUP_INSN (od
, str
);
843 /* Keep looking until we find a match. */
846 for ( ; ilist
!= NULL
; ilist
= CGEN_ASM_NEXT_INSN (ilist
))
848 const CGEN_INSN
*insn
= ilist
->insn
;
850 #if 0 /* not needed as unsupported opcodes shouldn't be in the hash lists */
851 /* Is this insn supported by the selected cpu? */
852 if (! fr30_cgen_insn_supported (od
, insn
))
856 /* If the RELAX attribute is set, this is an insn that shouldn't be
857 chosen immediately. Instead, it is used during assembler/linker
858 relaxation if possible. */
859 if (CGEN_INSN_ATTR (insn
, CGEN_INSN_RELAX
) != 0)
864 /* Allow parse/insert handlers to obtain length of insn. */
865 CGEN_FIELDS_BITSIZE (fields
) = CGEN_INSN_BITSIZE (insn
);
867 if (! CGEN_PARSE_FN (insn
) (od
, insn
, & str
, fields
))
869 /* ??? 0 is passed for `pc' */
870 if (CGEN_INSERT_FN (insn
) (od
, insn
, fields
, buf
, (bfd_vma
) 0) != NULL
)
872 /* It is up to the caller to actually output the insn and any
877 /* Try the next entry. */
880 /* FIXME: We can return a better error message than this.
881 Need to track why it failed and pick the right one. */
883 static char errbuf
[100];
884 if (strlen (start
) > 50)
885 /* xgettext:c-format */
886 sprintf (errbuf
, _("bad instruction `%.50s...'"), start
);
888 /* xgettext:c-format */
889 sprintf (errbuf
, _("bad instruction `%.50s'"), start
);
896 #if 0 /* This calls back to GAS which we can't do without care. */
898 /* Record each member of OPVALS in the assembler's symbol table.
899 This lets GAS parse registers for us.
900 ??? Interesting idea but not currently used. */
902 /* Record each member of OPVALS in the assembler's symbol table.
903 FIXME: Not currently used. */
906 fr30_cgen_asm_hash_keywords (od
, opvals
)
908 CGEN_KEYWORD
* opvals
;
910 CGEN_KEYWORD_SEARCH search
= cgen_keyword_search_init (opvals
, NULL
);
911 const CGEN_KEYWORD_ENTRY
* ke
;
913 while ((ke
= cgen_keyword_search_next (& search
)) != NULL
)
915 #if 0 /* Unnecessary, should be done in the search routine. */
916 if (! fr30_cgen_opval_supported (ke
))
919 cgen_asm_record_register (od
, ke
->name
, ke
->value
);