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