* cgen-asm.in (insert_normal): Use CGEN_BOOL_ATTR.
[binutils-gdb.git] / opcodes / fr30-asm.c
1 /* Assembler interface for targets using CGEN. -*- C -*-
2 CGEN: Cpu tools GENerator
3
4 THIS FILE IS USED TO GENERATE fr30-asm.c.
5
6 Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
7
8 This file is part of the GNU Binutils and GDB, the GNU debugger.
9
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)
13 any later version.
14
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.
19
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. */
23
24 #include "sysdep.h"
25 #include <ctype.h>
26 #include <stdio.h>
27 #include "ansidecl.h"
28 #include "bfd.h"
29 #include "symcat.h"
30 #include "fr30-opc.h"
31 #include "opintl.h"
32
33 #undef min
34 #define min(a,b) ((a) < (b) ? (a) : (b))
35 #undef max
36 #define max(a,b) ((a) > (b) ? (a) : (b))
37
38 #undef INLINE
39 #ifdef __GNUC__
40 #define INLINE __inline__
41 #else
42 #define INLINE
43 #endif
44
45 /* Used by the ifield rtx function. */
46 #define FLD(f) (fields->f)
47
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));
57 \f
58 /* -- assembler routines inserted here */
59 /* -- asm.c */
60 /* Handle register lists for LDMx and STMx */
61
62 static int
63 parse_register_number (strp)
64 const char **strp;
65 {
66 int regno;
67 if (**strp < '0' || **strp > '9')
68 return -1; /* error */
69 regno = **strp - '0';
70 ++*strp;
71
72 if (**strp >= '0' && **strp <= '9')
73 {
74 regno = regno * 10 + (**strp - '0');
75 ++*strp;
76 }
77
78 return regno;
79 }
80
81 static const char *
82 parse_register_list (od, strp, opindex, valuep, high_low, load_store)
83 CGEN_OPCODE_DESC od;
84 const char **strp;
85 int opindex;
86 unsigned long *valuep;
87 int high_low; /* 0 == high, 1 == low */
88 int load_store; /* 0 == load, 1 == store */
89 {
90 int regno;
91 *valuep = 0;
92 while (**strp && **strp != ')')
93 {
94 if (**strp != 'R' && **strp != 'r')
95 break;
96 ++*strp;
97
98 regno = parse_register_number (strp);
99 if (regno == -1)
100 return "Register number is not valid";
101 if (regno > 7 && !high_low)
102 return "Register must be between r0 and r7";
103 if (regno < 8 && high_low)
104 return "Register must be between r8 and r15";
105
106 if (high_low)
107 regno -= 8;
108
109 if (load_store) /* mask is reversed for store */
110 *valuep |= 0x80 >> regno;
111 else
112 *valuep |= 1 << regno;
113
114 if (**strp == ',')
115 {
116 if (*(*strp + 1) == ')')
117 break;
118 ++*strp;
119 }
120 }
121
122 if (!*strp || **strp != ')')
123 return "Register list is not valid";
124
125 return NULL;
126 }
127
128 static const char *
129 parse_low_register_list_ld (od, strp, opindex, valuep)
130 CGEN_OPCODE_DESC od;
131 const char **strp;
132 int opindex;
133 unsigned long *valuep;
134 {
135 return parse_register_list (od, strp, opindex, valuep, 0/*low*/, 0/*load*/);
136 }
137
138 static const char *
139 parse_hi_register_list_ld (od, strp, opindex, valuep)
140 CGEN_OPCODE_DESC od;
141 const char **strp;
142 int opindex;
143 unsigned long *valuep;
144 {
145 return parse_register_list (od, strp, opindex, valuep, 1/*high*/, 0/*load*/);
146 }
147
148 static const char *
149 parse_low_register_list_st (od, strp, opindex, valuep)
150 CGEN_OPCODE_DESC od;
151 const char **strp;
152 int opindex;
153 unsigned long *valuep;
154 {
155 return parse_register_list (od, strp, opindex, valuep, 0/*low*/, 1/*store*/);
156 }
157
158 static const char *
159 parse_hi_register_list_st (od, strp, opindex, valuep)
160 CGEN_OPCODE_DESC od;
161 const char **strp;
162 int opindex;
163 unsigned long *valuep;
164 {
165 return parse_register_list (od, strp, opindex, valuep, 1/*high*/, 1/*store*/);
166 }
167
168 /* -- */
169
170 /* Main entry point for operand parsing.
171
172 This function is basically just a big switch statement. Earlier versions
173 used tables to look up the function to use, but
174 - if the table contains both assembler and disassembler functions then
175 the disassembler contains much of the assembler and vice-versa,
176 - there's a lot of inlining possibilities as things grow,
177 - using a switch statement avoids the function call overhead.
178
179 This function could be moved into `parse_insn_normal', but keeping it
180 separate makes clear the interface between `parse_insn_normal' and each of
181 the handlers.
182 */
183
184 const char *
185 fr30_cgen_parse_operand (od, opindex, strp, fields)
186 CGEN_OPCODE_DESC od;
187 int opindex;
188 const char ** strp;
189 CGEN_FIELDS * fields;
190 {
191 const char * errmsg;
192
193 switch (opindex)
194 {
195 case FR30_OPERAND_RI :
196 errmsg = cgen_parse_keyword (od, strp, & fr30_cgen_opval_h_gr, & fields->f_Ri);
197 break;
198 case FR30_OPERAND_RJ :
199 errmsg = cgen_parse_keyword (od, strp, & fr30_cgen_opval_h_gr, & fields->f_Rj);
200 break;
201 case FR30_OPERAND_RIC :
202 errmsg = cgen_parse_keyword (od, strp, & fr30_cgen_opval_h_gr, & fields->f_Ric);
203 break;
204 case FR30_OPERAND_RJC :
205 errmsg = cgen_parse_keyword (od, strp, & fr30_cgen_opval_h_gr, & fields->f_Rjc);
206 break;
207 case FR30_OPERAND_CRI :
208 errmsg = cgen_parse_keyword (od, strp, & fr30_cgen_opval_h_cr, & fields->f_CRi);
209 break;
210 case FR30_OPERAND_CRJ :
211 errmsg = cgen_parse_keyword (od, strp, & fr30_cgen_opval_h_cr, & fields->f_CRj);
212 break;
213 case FR30_OPERAND_RS1 :
214 errmsg = cgen_parse_keyword (od, strp, & fr30_cgen_opval_h_dr, & fields->f_Rs1);
215 break;
216 case FR30_OPERAND_RS2 :
217 errmsg = cgen_parse_keyword (od, strp, & fr30_cgen_opval_h_dr, & fields->f_Rs2);
218 break;
219 case FR30_OPERAND_R13 :
220 errmsg = cgen_parse_keyword (od, strp, & fr30_cgen_opval_h_r13, & fields->f_nil);
221 break;
222 case FR30_OPERAND_R14 :
223 errmsg = cgen_parse_keyword (od, strp, & fr30_cgen_opval_h_r14, & fields->f_nil);
224 break;
225 case FR30_OPERAND_R15 :
226 errmsg = cgen_parse_keyword (od, strp, & fr30_cgen_opval_h_r15, & fields->f_nil);
227 break;
228 case FR30_OPERAND_PS :
229 errmsg = cgen_parse_keyword (od, strp, & fr30_cgen_opval_h_ps, & fields->f_nil);
230 break;
231 case FR30_OPERAND_U4 :
232 errmsg = cgen_parse_unsigned_integer (od, strp, FR30_OPERAND_U4, &fields->f_u4);
233 break;
234 case FR30_OPERAND_U4C :
235 errmsg = cgen_parse_unsigned_integer (od, strp, FR30_OPERAND_U4C, &fields->f_u4c);
236 break;
237 case FR30_OPERAND_U8 :
238 errmsg = cgen_parse_unsigned_integer (od, strp, FR30_OPERAND_U8, &fields->f_u8);
239 break;
240 case FR30_OPERAND_I8 :
241 errmsg = cgen_parse_unsigned_integer (od, strp, FR30_OPERAND_I8, &fields->f_i8);
242 break;
243 case FR30_OPERAND_UDISP6 :
244 errmsg = cgen_parse_unsigned_integer (od, strp, FR30_OPERAND_UDISP6, &fields->f_udisp6);
245 break;
246 case FR30_OPERAND_DISP8 :
247 errmsg = cgen_parse_signed_integer (od, strp, FR30_OPERAND_DISP8, &fields->f_disp8);
248 break;
249 case FR30_OPERAND_DISP9 :
250 errmsg = cgen_parse_signed_integer (od, strp, FR30_OPERAND_DISP9, &fields->f_disp9);
251 break;
252 case FR30_OPERAND_DISP10 :
253 errmsg = cgen_parse_signed_integer (od, strp, FR30_OPERAND_DISP10, &fields->f_disp10);
254 break;
255 case FR30_OPERAND_S10 :
256 errmsg = cgen_parse_signed_integer (od, strp, FR30_OPERAND_S10, &fields->f_s10);
257 break;
258 case FR30_OPERAND_U10 :
259 errmsg = cgen_parse_unsigned_integer (od, strp, FR30_OPERAND_U10, &fields->f_u10);
260 break;
261 case FR30_OPERAND_I32 :
262 errmsg = cgen_parse_unsigned_integer (od, strp, FR30_OPERAND_I32, &fields->f_i32);
263 break;
264 case FR30_OPERAND_M4 :
265 errmsg = cgen_parse_signed_integer (od, strp, FR30_OPERAND_M4, &fields->f_m4);
266 break;
267 case FR30_OPERAND_I20 :
268 errmsg = cgen_parse_unsigned_integer (od, strp, FR30_OPERAND_I20, &fields->f_i20);
269 break;
270 case FR30_OPERAND_DIR8 :
271 errmsg = cgen_parse_unsigned_integer (od, strp, FR30_OPERAND_DIR8, &fields->f_dir8);
272 break;
273 case FR30_OPERAND_DIR9 :
274 errmsg = cgen_parse_unsigned_integer (od, strp, FR30_OPERAND_DIR9, &fields->f_dir9);
275 break;
276 case FR30_OPERAND_DIR10 :
277 errmsg = cgen_parse_unsigned_integer (od, strp, FR30_OPERAND_DIR10, &fields->f_dir10);
278 break;
279 case FR30_OPERAND_LABEL9 :
280 {
281 bfd_vma value;
282 errmsg = cgen_parse_address (od, strp, FR30_OPERAND_LABEL9, 0, NULL, & value);
283 fields->f_rel9 = value;
284 }
285 break;
286 case FR30_OPERAND_LABEL12 :
287 {
288 bfd_vma value;
289 errmsg = cgen_parse_address (od, strp, FR30_OPERAND_LABEL12, 0, NULL, & value);
290 fields->f_rel12 = value;
291 }
292 break;
293 case FR30_OPERAND_REGLIST_LOW_LD :
294 errmsg = parse_low_register_list_ld (od, strp, FR30_OPERAND_REGLIST_LOW_LD, &fields->f_reglist_low_ld);
295 break;
296 case FR30_OPERAND_REGLIST_HI_LD :
297 errmsg = parse_hi_register_list_ld (od, strp, FR30_OPERAND_REGLIST_HI_LD, &fields->f_reglist_hi_ld);
298 break;
299 case FR30_OPERAND_REGLIST_LOW_ST :
300 errmsg = parse_low_register_list_st (od, strp, FR30_OPERAND_REGLIST_LOW_ST, &fields->f_reglist_low_st);
301 break;
302 case FR30_OPERAND_REGLIST_HI_ST :
303 errmsg = parse_hi_register_list_st (od, strp, FR30_OPERAND_REGLIST_HI_ST, &fields->f_reglist_hi_st);
304 break;
305 case FR30_OPERAND_CC :
306 errmsg = cgen_parse_unsigned_integer (od, strp, FR30_OPERAND_CC, &fields->f_cc);
307 break;
308 case FR30_OPERAND_CCC :
309 errmsg = cgen_parse_unsigned_integer (od, strp, FR30_OPERAND_CCC, &fields->f_ccc);
310 break;
311
312 default :
313 /* xgettext:c-format */
314 fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
315 abort ();
316 }
317
318 return errmsg;
319 }
320
321 /* Main entry point for operand insertion.
322
323 This function is basically just a big switch statement. Earlier versions
324 used tables to look up the function to use, but
325 - if the table contains both assembler and disassembler functions then
326 the disassembler contains much of the assembler and vice-versa,
327 - there's a lot of inlining possibilities as things grow,
328 - using a switch statement avoids the function call overhead.
329
330 This function could be moved into `parse_insn_normal', but keeping it
331 separate makes clear the interface between `parse_insn_normal' and each of
332 the handlers. It's also needed by GAS to insert operands that couldn't be
333 resolved during parsing.
334 */
335
336 const char *
337 fr30_cgen_insert_operand (od, opindex, fields, buffer, pc)
338 CGEN_OPCODE_DESC od;
339 int opindex;
340 CGEN_FIELDS * fields;
341 CGEN_INSN_BYTES_PTR buffer;
342 bfd_vma pc;
343 {
344 const char * errmsg;
345 unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
346
347 switch (opindex)
348 {
349 case FR30_OPERAND_RI :
350 errmsg = insert_normal (od, fields->f_Ri, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 4, 16, total_length, buffer);
351 break;
352 case FR30_OPERAND_RJ :
353 errmsg = insert_normal (od, fields->f_Rj, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 4, 16, total_length, buffer);
354 break;
355 case FR30_OPERAND_RIC :
356 errmsg = insert_normal (od, fields->f_Ric, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 12, 4, 16, total_length, buffer);
357 break;
358 case FR30_OPERAND_RJC :
359 errmsg = insert_normal (od, fields->f_Rjc, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 8, 4, 16, total_length, buffer);
360 break;
361 case FR30_OPERAND_CRI :
362 errmsg = insert_normal (od, fields->f_CRi, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 12, 4, 16, total_length, buffer);
363 break;
364 case FR30_OPERAND_CRJ :
365 errmsg = insert_normal (od, fields->f_CRj, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 8, 4, 16, total_length, buffer);
366 break;
367 case FR30_OPERAND_RS1 :
368 errmsg = insert_normal (od, fields->f_Rs1, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 4, 16, total_length, buffer);
369 break;
370 case FR30_OPERAND_RS2 :
371 errmsg = insert_normal (od, fields->f_Rs2, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 4, 16, total_length, buffer);
372 break;
373 case FR30_OPERAND_R13 :
374 errmsg = insert_normal (od, fields->f_nil, 0, 0, 0, 0, 0, total_length, buffer);
375 break;
376 case FR30_OPERAND_R14 :
377 errmsg = insert_normal (od, fields->f_nil, 0, 0, 0, 0, 0, total_length, buffer);
378 break;
379 case FR30_OPERAND_R15 :
380 errmsg = insert_normal (od, fields->f_nil, 0, 0, 0, 0, 0, total_length, buffer);
381 break;
382 case FR30_OPERAND_PS :
383 errmsg = insert_normal (od, fields->f_nil, 0, 0, 0, 0, 0, total_length, buffer);
384 break;
385 case FR30_OPERAND_U4 :
386 errmsg = insert_normal (od, fields->f_u4, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 4, 16, total_length, buffer);
387 break;
388 case FR30_OPERAND_U4C :
389 errmsg = insert_normal (od, fields->f_u4c, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 4, 16, total_length, buffer);
390 break;
391 case FR30_OPERAND_U8 :
392 errmsg = insert_normal (od, fields->f_u8, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, buffer);
393 break;
394 case FR30_OPERAND_I8 :
395 errmsg = insert_normal (od, fields->f_i8, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 4, 8, 16, total_length, buffer);
396 break;
397 case FR30_OPERAND_UDISP6 :
398 {
399 long value = fields->f_udisp6;
400 value = ((unsigned int) (value) >> (2));
401 errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 4, 16, total_length, buffer);
402 }
403 break;
404 case FR30_OPERAND_DISP8 :
405 errmsg = insert_normal (od, fields->f_disp8, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 0, 4, 8, 16, total_length, buffer);
406 break;
407 case FR30_OPERAND_DISP9 :
408 {
409 long value = fields->f_disp9;
410 value = ((int) (value) >> (1));
411 errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 0, 4, 8, 16, total_length, buffer);
412 }
413 break;
414 case FR30_OPERAND_DISP10 :
415 {
416 long value = fields->f_disp10;
417 value = ((int) (value) >> (2));
418 errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 0, 4, 8, 16, total_length, buffer);
419 }
420 break;
421 case FR30_OPERAND_S10 :
422 {
423 long value = fields->f_s10;
424 value = ((int) (value) >> (2));
425 errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 0, 8, 8, 16, total_length, buffer);
426 }
427 break;
428 case FR30_OPERAND_U10 :
429 {
430 long value = fields->f_u10;
431 value = ((unsigned int) (value) >> (2));
432 errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, buffer);
433 }
434 break;
435 case FR30_OPERAND_I32 :
436 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);
437 break;
438 case FR30_OPERAND_M4 :
439 {
440 long value = fields->f_m4;
441 value = ((value) & (15));
442 errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 4, 16, total_length, buffer);
443 }
444 break;
445 case FR30_OPERAND_I20 :
446 {
447 do {
448 FLD (f_i20_4) = ((unsigned int) (FLD (f_i20)) >> (16));
449 FLD (f_i20_16) = ((FLD (f_i20)) & (65535));
450 } while (0);
451 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);
452 if (errmsg)
453 break;
454 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);
455 if (errmsg)
456 break;
457 }
458 break;
459 case FR30_OPERAND_DIR8 :
460 errmsg = insert_normal (od, fields->f_dir8, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, buffer);
461 break;
462 case FR30_OPERAND_DIR9 :
463 {
464 long value = fields->f_dir9;
465 value = ((unsigned int) (value) >> (1));
466 errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, buffer);
467 }
468 break;
469 case FR30_OPERAND_DIR10 :
470 {
471 long value = fields->f_dir10;
472 value = ((unsigned int) (value) >> (2));
473 errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, buffer);
474 }
475 break;
476 case FR30_OPERAND_LABEL9 :
477 {
478 long value = fields->f_rel9;
479 value = ((int) (((value) - (((pc) + (2))))) >> (1));
480 errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_PCREL_ADDR), 0, 8, 8, 16, total_length, buffer);
481 }
482 break;
483 case FR30_OPERAND_LABEL12 :
484 {
485 long value = fields->f_rel12;
486 value = ((int) (((value) - (((pc) + (2))))) >> (1));
487 errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_PCREL_ADDR), 0, 5, 11, 16, total_length, buffer);
488 }
489 break;
490 case FR30_OPERAND_REGLIST_LOW_LD :
491 errmsg = insert_normal (od, fields->f_reglist_low_ld, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, buffer);
492 break;
493 case FR30_OPERAND_REGLIST_HI_LD :
494 errmsg = insert_normal (od, fields->f_reglist_hi_ld, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, buffer);
495 break;
496 case FR30_OPERAND_REGLIST_LOW_ST :
497 errmsg = insert_normal (od, fields->f_reglist_low_st, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, buffer);
498 break;
499 case FR30_OPERAND_REGLIST_HI_ST :
500 errmsg = insert_normal (od, fields->f_reglist_hi_st, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, buffer);
501 break;
502 case FR30_OPERAND_CC :
503 errmsg = insert_normal (od, fields->f_cc, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 4, 4, 16, total_length, buffer);
504 break;
505 case FR30_OPERAND_CCC :
506 errmsg = insert_normal (od, fields->f_ccc, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 16, 0, 8, 16, total_length, buffer);
507 break;
508
509 default :
510 /* xgettext:c-format */
511 fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
512 opindex);
513 abort ();
514 }
515
516 return errmsg;
517 }
518
519 cgen_parse_fn * const fr30_cgen_parse_handlers[] =
520 {
521 0, /* default */
522 parse_insn_normal,
523 };
524
525 cgen_insert_fn * const fr30_cgen_insert_handlers[] =
526 {
527 0, /* default */
528 insert_insn_normal,
529 };
530
531 void
532 fr30_cgen_init_asm (od)
533 CGEN_OPCODE_DESC od;
534 {
535 }
536
537 \f
538 #if ! CGEN_INT_INSN_P
539
540 /* Subroutine of insert_normal. */
541
542 static INLINE void
543 insert_1 (od, value, start, length, word_length, bufp)
544 CGEN_OPCODE_DESC od;
545 unsigned long value;
546 int start,length,word_length;
547 unsigned char *bufp;
548 {
549 unsigned long x,mask;
550 int shift;
551 int big_p = CGEN_OPCODE_INSN_ENDIAN (od) == CGEN_ENDIAN_BIG;
552
553 switch (word_length)
554 {
555 case 8:
556 x = *bufp;
557 break;
558 case 16:
559 if (big_p)
560 x = bfd_getb16 (bufp);
561 else
562 x = bfd_getl16 (bufp);
563 break;
564 case 24:
565 /* ??? This may need reworking as these cases don't necessarily
566 want the first byte and the last two bytes handled like this. */
567 if (big_p)
568 x = (bufp[0] << 16) | bfd_getb16 (bufp + 1);
569 else
570 x = bfd_getl16 (bufp) | (bufp[2] << 16);
571 break;
572 case 32:
573 if (big_p)
574 x = bfd_getb32 (bufp);
575 else
576 x = bfd_getl32 (bufp);
577 break;
578 default :
579 abort ();
580 }
581
582 /* Written this way to avoid undefined behaviour. */
583 mask = (((1L << (length - 1)) - 1) << 1) | 1;
584 if (CGEN_INSN_LSB0_P)
585 shift = (start + 1) - length;
586 else
587 shift = (word_length - (start + length));
588 x = (x & ~(mask << shift)) | ((value & mask) << shift);
589
590 switch (word_length)
591 {
592 case 8:
593 *bufp = x;
594 break;
595 case 16:
596 if (big_p)
597 bfd_putb16 (x, bufp);
598 else
599 bfd_putl16 (x, bufp);
600 break;
601 case 24:
602 /* ??? This may need reworking as these cases don't necessarily
603 want the first byte and the last two bytes handled like this. */
604 if (big_p)
605 {
606 bufp[0] = x >> 16;
607 bfd_putb16 (x, bufp + 1);
608 }
609 else
610 {
611 bfd_putl16 (x, bufp);
612 bufp[2] = x >> 16;
613 }
614 break;
615 case 32:
616 if (big_p)
617 bfd_putb32 (x, bufp);
618 else
619 bfd_putl32 (x, bufp);
620 break;
621 default :
622 abort ();
623 }
624 }
625
626 #endif /* ! CGEN_INT_INSN_P */
627
628 /* Default insertion routine.
629
630 ATTRS is a mask of the boolean attributes.
631 WORD_OFFSET is the offset in bits from the start of the insn of the value.
632 WORD_LENGTH is the length of the word in bits in which the value resides.
633 START is the starting bit number in the word, architecture origin.
634 LENGTH is the length of VALUE in bits.
635 TOTAL_LENGTH is the total length of the insn in bits.
636
637 The result is an error message or NULL if success. */
638
639 /* ??? This duplicates functionality with bfd's howto table and
640 bfd_install_relocation. */
641 /* ??? This doesn't handle bfd_vma's. Create another function when
642 necessary. */
643
644 static const char *
645 insert_normal (od, value, attrs, word_offset, start, length, word_length,
646 total_length, buffer)
647 CGEN_OPCODE_DESC od;
648 long value;
649 unsigned int attrs;
650 unsigned int word_offset, start, length, word_length, total_length;
651 CGEN_INSN_BYTES_PTR buffer;
652 {
653 static char errbuf[100];
654 /* Written this way to avoid undefined behaviour. */
655 unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
656
657 /* If LENGTH is zero, this operand doesn't contribute to the value. */
658 if (length == 0)
659 return NULL;
660
661 if (CGEN_INT_INSN_P
662 && word_offset != 0)
663 abort ();
664
665 if (word_length > 32)
666 abort ();
667
668 /* For architectures with insns smaller than the insn-base-bitsize,
669 word_length may be too big. */
670 #if CGEN_MIN_INSN_BITSIZE < CGEN_BASE_INSN_BITSIZE
671 if (word_offset == 0
672 && word_length > total_length)
673 word_length = total_length;
674 #endif
675
676 /* Ensure VALUE will fit. */
677 if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_UNSIGNED))
678 {
679 unsigned long maxval = mask;
680 if ((unsigned long) value > maxval)
681 {
682 /* xgettext:c-format */
683 sprintf (errbuf,
684 _("operand out of range (%lu not between 0 and %lu)"),
685 value, maxval);
686 return errbuf;
687 }
688 }
689 else
690 {
691 long minval = - (1L << (length - 1));
692 long maxval = (1L << (length - 1)) - 1;
693 if (value < minval || value > maxval)
694 {
695 sprintf
696 /* xgettext:c-format */
697 (errbuf, _("operand out of range (%ld not between %ld and %ld)"),
698 value, minval, maxval);
699 return errbuf;
700 }
701 }
702
703 #if CGEN_INT_INSN_P
704
705 {
706 int shift;
707
708 if (CGEN_INSN_LSB0_P)
709 shift = (start + 1) - length;
710 else
711 shift = word_length - (start + length);
712 *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
713 }
714
715 #else /* ! CGEN_INT_INSN_P */
716
717 {
718 unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
719
720 insert_1 (od, value, start, length, word_length, bufp);
721 }
722
723 #endif /* ! CGEN_INT_INSN_P */
724
725 return NULL;
726 }
727 \f
728 /* Default insn parser.
729
730 The syntax string is scanned and operands are parsed and stored in FIELDS.
731 Relocs are queued as we go via other callbacks.
732
733 ??? Note that this is currently an all-or-nothing parser. If we fail to
734 parse the instruction, we return 0 and the caller will start over from
735 the beginning. Backtracking will be necessary in parsing subexpressions,
736 but that can be handled there. Not handling backtracking here may get
737 expensive in the case of the m68k. Deal with later.
738
739 Returns NULL for success, an error message for failure.
740 */
741
742 static const char *
743 parse_insn_normal (od, insn, strp, fields)
744 CGEN_OPCODE_DESC od;
745 const CGEN_INSN * insn;
746 const char ** strp;
747 CGEN_FIELDS * fields;
748 {
749 const CGEN_SYNTAX * syntax = CGEN_INSN_SYNTAX (insn);
750 const char * str = *strp;
751 const char * errmsg;
752 const char * p;
753 const unsigned char * syn;
754 #ifdef CGEN_MNEMONIC_OPERANDS
755 /* FIXME: wip */
756 int past_opcode_p;
757 #endif
758
759 /* For now we assume the mnemonic is first (there are no leading operands).
760 We can parse it without needing to set up operand parsing.
761 GAS's input scrubber will ensure mnemonics are lowercase, but we may
762 not be called from GAS. */
763 p = CGEN_INSN_MNEMONIC (insn);
764 while (*p && tolower (*p) == tolower (*str))
765 ++p, ++str;
766
767 if (* p || (* str && !isspace (* str)))
768 return _("unrecognized instruction");
769
770 CGEN_INIT_PARSE (od);
771 cgen_init_parse_operand (od);
772 #ifdef CGEN_MNEMONIC_OPERANDS
773 past_opcode_p = 0;
774 #endif
775
776 /* We don't check for (*str != '\0') here because we want to parse
777 any trailing fake arguments in the syntax string. */
778 syn = CGEN_SYNTAX_STRING (syntax);
779
780 /* Mnemonics come first for now, ensure valid string. */
781 if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
782 abort ();
783
784 ++syn;
785
786 while (* syn != 0)
787 {
788 /* Non operand chars must match exactly. */
789 if (CGEN_SYNTAX_CHAR_P (* syn))
790 {
791 if (*str == CGEN_SYNTAX_CHAR (* syn))
792 {
793 #ifdef CGEN_MNEMONIC_OPERANDS
794 if (* syn == ' ')
795 past_opcode_p = 1;
796 #endif
797 ++ syn;
798 ++ str;
799 }
800 else
801 {
802 /* Syntax char didn't match. Can't be this insn. */
803 /* FIXME: would like to return something like
804 "expected char `c'" */
805 return _("syntax error");
806 }
807 continue;
808 }
809
810 /* We have an operand of some sort. */
811 errmsg = fr30_cgen_parse_operand (od, CGEN_SYNTAX_FIELD (*syn),
812 &str, fields);
813 if (errmsg)
814 return errmsg;
815
816 /* Done with this operand, continue with next one. */
817 ++ syn;
818 }
819
820 /* If we're at the end of the syntax string, we're done. */
821 if (* syn == '\0')
822 {
823 /* FIXME: For the moment we assume a valid `str' can only contain
824 blanks now. IE: We needn't try again with a longer version of
825 the insn and it is assumed that longer versions of insns appear
826 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
827 while (isspace (* str))
828 ++ str;
829
830 if (* str != '\0')
831 return _("junk at end of line"); /* FIXME: would like to include `str' */
832
833 return NULL;
834 }
835
836 /* We couldn't parse it. */
837 return _("unrecognized instruction");
838 }
839
840 /* Default insn builder (insert handler).
841 The instruction is recorded in CGEN_INT_INSN_P byte order
842 (meaning that if CGEN_INT_INSN_P BUFFER is an int * and thus the value is
843 recorded in host byte order, otherwise BUFFER is an array of bytes and the
844 value is recorded in target byte order).
845 The result is an error message or NULL if success. */
846
847 static const char *
848 insert_insn_normal (od, insn, fields, buffer, pc)
849 CGEN_OPCODE_DESC od;
850 const CGEN_INSN * insn;
851 CGEN_FIELDS * fields;
852 CGEN_INSN_BYTES_PTR buffer;
853 bfd_vma pc;
854 {
855 const CGEN_SYNTAX * syntax = CGEN_INSN_SYNTAX (insn);
856 unsigned long value;
857 const unsigned char * syn;
858
859 CGEN_INIT_INSERT (od);
860 value = CGEN_INSN_BASE_VALUE (insn);
861
862 /* If we're recording insns as numbers (rather than a string of bytes),
863 target byte order handling is deferred until later. */
864
865 #if CGEN_INT_INSN_P
866
867 *buffer = value;
868
869 #else
870
871 cgen_put_insn_value (od, buffer, min (CGEN_BASE_INSN_BITSIZE,
872 CGEN_FIELDS_BITSIZE (fields)),
873 value);
874
875 #endif /* ! CGEN_INT_INSN_P */
876
877 /* ??? It would be better to scan the format's fields.
878 Still need to be able to insert a value based on the operand though;
879 e.g. storing a branch displacement that got resolved later.
880 Needs more thought first. */
881
882 for (syn = CGEN_SYNTAX_STRING (syntax); * syn != '\0'; ++ syn)
883 {
884 const char *errmsg;
885
886 if (CGEN_SYNTAX_CHAR_P (* syn))
887 continue;
888
889 errmsg = fr30_cgen_insert_operand (od, CGEN_SYNTAX_FIELD (*syn),
890 fields, buffer, pc);
891 if (errmsg)
892 return errmsg;
893 }
894
895 return NULL;
896 }
897 \f
898 /* Main entry point.
899 This routine is called for each instruction to be assembled.
900 STR points to the insn to be assembled.
901 We assume all necessary tables have been initialized.
902 The assembled instruction, less any fixups, is stored in BUF.
903 Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
904 still needs to be converted to target byte order, otherwise BUF is an array
905 of bytes in target byte order.
906 The result is a pointer to the insn's entry in the opcode table,
907 or NULL if an error occured (an error message will have already been
908 printed).
909
910 Note that when processing (non-alias) macro-insns,
911 this function recurses. */
912
913 const CGEN_INSN *
914 fr30_cgen_assemble_insn (od, str, fields, buf, errmsg)
915 CGEN_OPCODE_DESC od;
916 const char * str;
917 CGEN_FIELDS * fields;
918 CGEN_INSN_BYTES_PTR buf;
919 char ** errmsg;
920 {
921 const char * start;
922 CGEN_INSN_LIST * ilist;
923
924 /* Skip leading white space. */
925 while (isspace (* str))
926 ++ str;
927
928 /* The instructions are stored in hashed lists.
929 Get the first in the list. */
930 ilist = CGEN_ASM_LOOKUP_INSN (od, str);
931
932 /* Keep looking until we find a match. */
933
934 start = str;
935 for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
936 {
937 const CGEN_INSN *insn = ilist->insn;
938
939 #if 0 /* not needed as unsupported opcodes shouldn't be in the hash lists */
940 /* Is this insn supported by the selected cpu? */
941 if (! fr30_cgen_insn_supported (od, insn))
942 continue;
943 #endif
944
945 /* If the RELAX attribute is set, this is an insn that shouldn't be
946 chosen immediately. Instead, it is used during assembler/linker
947 relaxation if possible. */
948 if (CGEN_INSN_ATTR (insn, CGEN_INSN_RELAX) != 0)
949 continue;
950
951 str = start;
952
953 /* Allow parse/insert handlers to obtain length of insn. */
954 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
955
956 if (! CGEN_PARSE_FN (insn) (od, insn, & str, fields))
957 {
958 /* ??? 0 is passed for `pc' */
959 if (CGEN_INSERT_FN (insn) (od, insn, fields, buf, (bfd_vma) 0) != NULL)
960 continue;
961 /* It is up to the caller to actually output the insn and any
962 queued relocs. */
963 return insn;
964 }
965
966 /* Try the next entry. */
967 }
968
969 /* FIXME: We can return a better error message than this.
970 Need to track why it failed and pick the right one. */
971 {
972 static char errbuf[100];
973 if (strlen (start) > 50)
974 /* xgettext:c-format */
975 sprintf (errbuf, _("bad instruction `%.50s...'"), start);
976 else
977 /* xgettext:c-format */
978 sprintf (errbuf, _("bad instruction `%.50s'"), start);
979
980 *errmsg = errbuf;
981 return NULL;
982 }
983 }
984 \f
985 #if 0 /* This calls back to GAS which we can't do without care. */
986
987 /* Record each member of OPVALS in the assembler's symbol table.
988 This lets GAS parse registers for us.
989 ??? Interesting idea but not currently used. */
990
991 /* Record each member of OPVALS in the assembler's symbol table.
992 FIXME: Not currently used. */
993
994 void
995 fr30_cgen_asm_hash_keywords (od, opvals)
996 CGEN_OPCODE_DESC od;
997 CGEN_KEYWORD * opvals;
998 {
999 CGEN_KEYWORD_SEARCH search = cgen_keyword_search_init (opvals, NULL);
1000 const CGEN_KEYWORD_ENTRY * ke;
1001
1002 while ((ke = cgen_keyword_search_next (& search)) != NULL)
1003 {
1004 #if 0 /* Unnecessary, should be done in the search routine. */
1005 if (! fr30_cgen_opval_supported (ke))
1006 continue;
1007 #endif
1008 cgen_asm_record_register (od, ke->name, ke->value);
1009 }
1010 }
1011
1012 #endif /* 0 */