remove d30v sanitization
[deliverable/binutils-gdb.git] / opcodes / m32r-asm.c
CommitLineData
9c03036a
DE
1/* Assembler interface for targets using CGEN. -*- C -*-
2 CGEN: Cpu tools GENerator
3
fbc8134d 4THIS FILE IS USED TO GENERATE m32r-asm.c.
9c03036a 5
0bf55db8 6Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
9c03036a
DE
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
fbc8134d
DE
21along with this program; if not, write to the Free Software Foundation, Inc.,
2259 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
9c03036a 23
23cf992f 24#include "sysdep.h"
9c03036a
DE
25#include <ctype.h>
26#include <stdio.h>
27#include "ansidecl.h"
28#include "bfd.h"
0bf55db8 29#include "symcat.h"
9c03036a 30#include "m32r-opc.h"
cbc6c9b2 31#include "opintl.h"
9c03036a
DE
32
33/* ??? The layout of this stuff is still work in progress.
34 For speed in assembly/disassembly, we use inline functions. That of course
35 will only work for GCC. When this stuff is finished, we can decide whether
36 to keep the inline functions (and only get the performance increase when
37 compiled with GCC), or switch to macros, or use something else.
38*/
39
1294c286
DE
40static const char * insert_normal
41 PARAMS ((long, unsigned int, int, int, int, char *));
23cf992f
NC
42static const char * parse_insn_normal
43 PARAMS ((const CGEN_INSN *, const char **, CGEN_FIELDS *));
0bf55db8 44static const char * insert_insn_normal
fbc8134d 45 PARAMS ((const CGEN_INSN *, CGEN_FIELDS *, cgen_insn_t *, bfd_vma));
9c03036a 46\f
1294c286
DE
47/* -- assembler routines inserted here */
48/* -- asm.c */
9c03036a 49
1294c286 50/* Handle '#' prefixes (i.e. skip over them). */
9c03036a 51
0bf55db8 52static const char *
1294c286
DE
53parse_hash (strp, opindex, valuep)
54 const char **strp;
55 int opindex;
56 unsigned long *valuep;
9c03036a 57{
1294c286
DE
58 if (**strp == '#')
59 ++*strp;
0bf55db8 60 return NULL;
9c03036a 61}
853713a7
DE
62
63/* Handle shigh(), high(). */
64
65static const char *
1294c286 66parse_hi16 (strp, opindex, valuep)
853713a7
DE
67 const char **strp;
68 int opindex;
853713a7
DE
69 unsigned long *valuep;
70{
71 const char *errmsg;
72 enum cgen_parse_operand_result result_type;
73
853713a7
DE
74 if (**strp == '#')
75 ++*strp;
76
cbc6c9b2 77 if (strncasecmp (*strp, "high(", 5) == 0)
853713a7
DE
78 {
79 *strp += 5;
80 errmsg = cgen_parse_address (strp, opindex, BFD_RELOC_M32R_HI16_ULO,
81 &result_type, valuep);
82 if (**strp != ')')
83 return "missing `)'";
84 ++*strp;
85 if (errmsg == NULL
86 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
87 *valuep >>= 16;
88 return errmsg;
89 }
cbc6c9b2 90 else if (strncasecmp (*strp, "shigh(", 6) == 0)
853713a7
DE
91 {
92 *strp += 6;
93 errmsg = cgen_parse_address (strp, opindex, BFD_RELOC_M32R_HI16_SLO,
94 &result_type, valuep);
95 if (**strp != ')')
96 return "missing `)'";
97 ++*strp;
98 if (errmsg == NULL
99 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
100 *valuep = (*valuep >> 16) + ((*valuep) & 0x8000 ? 1 : 0);
101 return errmsg;
102 }
103
0bf55db8 104 return cgen_parse_unsigned_integer (strp, opindex, valuep);
853713a7
DE
105}
106
107/* Handle low() in a signed context. Also handle sda().
108 The signedness of the value doesn't matter to low(), but this also
109 handles the case where low() isn't present. */
110
111static const char *
1294c286 112parse_slo16 (strp, opindex, valuep)
853713a7
DE
113 const char **strp;
114 int opindex;
853713a7
DE
115 long *valuep;
116{
117 const char *errmsg;
118 enum cgen_parse_operand_result result_type;
119
853713a7
DE
120 if (**strp == '#')
121 ++*strp;
122
cbc6c9b2 123 if (strncasecmp (*strp, "low(", 4) == 0)
853713a7
DE
124 {
125 *strp += 4;
126 errmsg = cgen_parse_address (strp, opindex, BFD_RELOC_M32R_LO16,
127 &result_type, valuep);
128 if (**strp != ')')
129 return "missing `)'";
130 ++*strp;
0bf55db8
DE
131 if (errmsg == NULL
132 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
133 *valuep &= 0xffff;
853713a7
DE
134 return errmsg;
135 }
136
cbc6c9b2 137 if (strncasecmp (*strp, "sda(", 4) == 0)
853713a7
DE
138 {
139 *strp += 4;
140 errmsg = cgen_parse_address (strp, opindex, BFD_RELOC_M32R_SDA16, NULL, valuep);
141 if (**strp != ')')
142 return "missing `)'";
143 ++*strp;
144 return errmsg;
145 }
146
0bf55db8 147 return cgen_parse_signed_integer (strp, opindex, valuep);
853713a7
DE
148}
149
150/* Handle low() in an unsigned context.
151 The signedness of the value doesn't matter to low(), but this also
152 handles the case where low() isn't present. */
153
154static const char *
1294c286 155parse_ulo16 (strp, opindex, valuep)
853713a7
DE
156 const char **strp;
157 int opindex;
853713a7
DE
158 unsigned long *valuep;
159{
160 const char *errmsg;
161 enum cgen_parse_operand_result result_type;
162
853713a7
DE
163 if (**strp == '#')
164 ++*strp;
165
cbc6c9b2 166 if (strncasecmp (*strp, "low(", 4) == 0)
853713a7
DE
167 {
168 *strp += 4;
169 errmsg = cgen_parse_address (strp, opindex, BFD_RELOC_M32R_LO16,
170 &result_type, valuep);
171 if (**strp != ')')
172 return "missing `)'";
173 ++*strp;
0bf55db8
DE
174 if (errmsg == NULL
175 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
176 *valuep &= 0xffff;
853713a7
DE
177 return errmsg;
178 }
179
0bf55db8 180 return cgen_parse_unsigned_integer (strp, opindex, valuep);
853713a7
DE
181}
182
183/* -- */
184
185/* Main entry point for operand parsing.
186
187 This function is basically just a big switch statement. Earlier versions
188 used tables to look up the function to use, but
189 - if the table contains both assembler and disassembler functions then
190 the disassembler contains much of the assembler and vice-versa,
191 - there's a lot of inlining possibilities as things grow,
192 - using a switch statement avoids the function call overhead.
193
194 This function could be moved into `parse_insn_normal', but keeping it
195 separate makes clear the interface between `parse_insn_normal' and each of
196 the handlers.
197*/
198
0bf55db8 199const char *
853713a7
DE
200m32r_cgen_parse_operand (opindex, strp, fields)
201 int opindex;
202 const char ** strp;
203 CGEN_FIELDS * fields;
204{
205 const char * errmsg;
206
207 switch (opindex)
208 {
209 case M32R_OPERAND_SR :
210 errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_gr, & fields->f_r2);
211 break;
212 case M32R_OPERAND_DR :
213 errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_gr, & fields->f_r1);
214 break;
215 case M32R_OPERAND_SRC1 :
216 errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_gr, & fields->f_r1);
217 break;
218 case M32R_OPERAND_SRC2 :
219 errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_gr, & fields->f_r2);
220 break;
221 case M32R_OPERAND_SCR :
222 errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_cr, & fields->f_r2);
223 break;
224 case M32R_OPERAND_DCR :
225 errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_cr, & fields->f_r1);
226 break;
227 case M32R_OPERAND_SIMM8 :
0bf55db8 228 errmsg = cgen_parse_signed_integer (strp, M32R_OPERAND_SIMM8, &fields->f_simm8);
853713a7
DE
229 break;
230 case M32R_OPERAND_SIMM16 :
0bf55db8 231 errmsg = cgen_parse_signed_integer (strp, M32R_OPERAND_SIMM16, &fields->f_simm16);
853713a7
DE
232 break;
233 case M32R_OPERAND_UIMM4 :
0bf55db8 234 errmsg = cgen_parse_unsigned_integer (strp, M32R_OPERAND_UIMM4, &fields->f_uimm4);
853713a7
DE
235 break;
236 case M32R_OPERAND_UIMM5 :
0bf55db8 237 errmsg = cgen_parse_unsigned_integer (strp, M32R_OPERAND_UIMM5, &fields->f_uimm5);
853713a7
DE
238 break;
239 case M32R_OPERAND_UIMM16 :
0bf55db8 240 errmsg = cgen_parse_unsigned_integer (strp, M32R_OPERAND_UIMM16, &fields->f_uimm16);
853713a7 241 break;
ab0bd049
DE
242/* start-sanitize-m32rx */
243 case M32R_OPERAND_IMM1 :
0bf55db8 244 errmsg = cgen_parse_unsigned_integer (strp, M32R_OPERAND_IMM1, &fields->f_imm1);
ab0bd049
DE
245 break;
246/* end-sanitize-m32rx */
247/* start-sanitize-m32rx */
248 case M32R_OPERAND_ACCD :
249 errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_accums, & fields->f_accd);
250 break;
251/* end-sanitize-m32rx */
252/* start-sanitize-m32rx */
253 case M32R_OPERAND_ACCS :
254 errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_accums, & fields->f_accs);
255 break;
256/* end-sanitize-m32rx */
257/* start-sanitize-m32rx */
258 case M32R_OPERAND_ACC :
259 errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_accums, & fields->f_acc);
260 break;
261/* end-sanitize-m32rx */
1294c286
DE
262 case M32R_OPERAND_HASH :
263 errmsg = parse_hash (strp, M32R_OPERAND_HASH, &fields->f_nil);
264 break;
853713a7 265 case M32R_OPERAND_HI16 :
1294c286 266 errmsg = parse_hi16 (strp, M32R_OPERAND_HI16, &fields->f_hi16);
853713a7
DE
267 break;
268 case M32R_OPERAND_SLO16 :
1294c286 269 errmsg = parse_slo16 (strp, M32R_OPERAND_SLO16, &fields->f_simm16);
853713a7
DE
270 break;
271 case M32R_OPERAND_ULO16 :
1294c286 272 errmsg = parse_ulo16 (strp, M32R_OPERAND_ULO16, &fields->f_uimm16);
853713a7
DE
273 break;
274 case M32R_OPERAND_UIMM24 :
0bf55db8 275 errmsg = cgen_parse_address (strp, M32R_OPERAND_UIMM24, 0, NULL, & fields->f_uimm24);
853713a7
DE
276 break;
277 case M32R_OPERAND_DISP8 :
0bf55db8 278 errmsg = cgen_parse_address (strp, M32R_OPERAND_DISP8, 0, NULL, & fields->f_disp8);
853713a7
DE
279 break;
280 case M32R_OPERAND_DISP16 :
0bf55db8 281 errmsg = cgen_parse_address (strp, M32R_OPERAND_DISP16, 0, NULL, & fields->f_disp16);
853713a7
DE
282 break;
283 case M32R_OPERAND_DISP24 :
0bf55db8 284 errmsg = cgen_parse_address (strp, M32R_OPERAND_DISP24, 0, NULL, & fields->f_disp24);
853713a7
DE
285 break;
286
287 default :
cbc6c9b2
DE
288 /* xgettext:c-format */
289 fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
853713a7
DE
290 abort ();
291 }
292
293 return errmsg;
294}
295
296/* Main entry point for operand insertion.
297
298 This function is basically just a big switch statement. Earlier versions
299 used tables to look up the function to use, but
300 - if the table contains both assembler and disassembler functions then
301 the disassembler contains much of the assembler and vice-versa,
302 - there's a lot of inlining possibilities as things grow,
303 - using a switch statement avoids the function call overhead.
304
305 This function could be moved into `parse_insn_normal', but keeping it
306 separate makes clear the interface between `parse_insn_normal' and each of
307 the handlers. It's also needed by GAS to insert operands that couldn't be
308 resolved during parsing.
309*/
310
0bf55db8 311const char *
fbc8134d 312m32r_cgen_insert_operand (opindex, fields, buffer, pc)
5d07b6cf 313 int opindex;
853713a7 314 CGEN_FIELDS * fields;
0bf55db8 315 char * buffer;
fbc8134d 316 bfd_vma pc;
853713a7 317{
0bf55db8 318 const char * errmsg;
853713a7
DE
319
320 switch (opindex)
321 {
322 case M32R_OPERAND_SR :
1294c286 323 errmsg = insert_normal (fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
853713a7
DE
324 break;
325 case M32R_OPERAND_DR :
1294c286 326 errmsg = insert_normal (fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
853713a7
DE
327 break;
328 case M32R_OPERAND_SRC1 :
1294c286 329 errmsg = insert_normal (fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
853713a7
DE
330 break;
331 case M32R_OPERAND_SRC2 :
1294c286 332 errmsg = insert_normal (fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
853713a7
DE
333 break;
334 case M32R_OPERAND_SCR :
1294c286 335 errmsg = insert_normal (fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
853713a7
DE
336 break;
337 case M32R_OPERAND_DCR :
1294c286 338 errmsg = insert_normal (fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
853713a7
DE
339 break;
340 case M32R_OPERAND_SIMM8 :
1294c286 341 errmsg = insert_normal (fields->f_simm8, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 8, 8, CGEN_FIELDS_BITSIZE (fields), buffer);
853713a7
DE
342 break;
343 case M32R_OPERAND_SIMM16 :
1294c286 344 errmsg = insert_normal (fields->f_simm16, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 16, 16, CGEN_FIELDS_BITSIZE (fields), buffer);
853713a7
DE
345 break;
346 case M32R_OPERAND_UIMM4 :
1294c286 347 errmsg = insert_normal (fields->f_uimm4, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
853713a7
DE
348 break;
349 case M32R_OPERAND_UIMM5 :
1294c286 350 errmsg = insert_normal (fields->f_uimm5, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 11, 5, CGEN_FIELDS_BITSIZE (fields), buffer);
853713a7
DE
351 break;
352 case M32R_OPERAND_UIMM16 :
1294c286 353 errmsg = insert_normal (fields->f_uimm16, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, CGEN_FIELDS_BITSIZE (fields), buffer);
853713a7 354 break;
ab0bd049
DE
355/* start-sanitize-m32rx */
356 case M32R_OPERAND_IMM1 :
0bf55db8 357 {
fbc8134d
DE
358 long value = fields->f_imm1;
359 value = ((value) - (1));
1294c286 360 errmsg = insert_normal (value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 15, 1, CGEN_FIELDS_BITSIZE (fields), buffer);
0bf55db8 361 }
ab0bd049
DE
362 break;
363/* end-sanitize-m32rx */
364/* start-sanitize-m32rx */
365 case M32R_OPERAND_ACCD :
1294c286 366 errmsg = insert_normal (fields->f_accd, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 2, CGEN_FIELDS_BITSIZE (fields), buffer);
ab0bd049
DE
367 break;
368/* end-sanitize-m32rx */
369/* start-sanitize-m32rx */
370 case M32R_OPERAND_ACCS :
1294c286 371 errmsg = insert_normal (fields->f_accs, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 2, CGEN_FIELDS_BITSIZE (fields), buffer);
ab0bd049
DE
372 break;
373/* end-sanitize-m32rx */
374/* start-sanitize-m32rx */
375 case M32R_OPERAND_ACC :
1294c286 376 errmsg = insert_normal (fields->f_acc, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 1, CGEN_FIELDS_BITSIZE (fields), buffer);
ab0bd049
DE
377 break;
378/* end-sanitize-m32rx */
1294c286
DE
379 case M32R_OPERAND_HASH :
380 errmsg = insert_normal (fields->f_nil, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
381 break;
853713a7 382 case M32R_OPERAND_HI16 :
1294c286 383 errmsg = insert_normal (fields->f_hi16, 0|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, CGEN_FIELDS_BITSIZE (fields), buffer);
853713a7
DE
384 break;
385 case M32R_OPERAND_SLO16 :
1294c286 386 errmsg = insert_normal (fields->f_simm16, 0, 16, 16, CGEN_FIELDS_BITSIZE (fields), buffer);
853713a7
DE
387 break;
388 case M32R_OPERAND_ULO16 :
1294c286 389 errmsg = insert_normal (fields->f_uimm16, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, CGEN_FIELDS_BITSIZE (fields), buffer);
853713a7
DE
390 break;
391 case M32R_OPERAND_UIMM24 :
1294c286 392 errmsg = insert_normal (fields->f_uimm24, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_ABS_ADDR)|(1<<CGEN_OPERAND_UNSIGNED), 8, 24, CGEN_FIELDS_BITSIZE (fields), buffer);
853713a7
DE
393 break;
394 case M32R_OPERAND_DISP8 :
0bf55db8 395 {
fbc8134d 396 long value = fields->f_disp8;
b00ea55c 397 value = ((int) (((value) - (((pc) & (-4))))) >> (2));
1294c286 398 errmsg = insert_normal (value, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 8, 8, CGEN_FIELDS_BITSIZE (fields), buffer);
0bf55db8 399 }
853713a7
DE
400 break;
401 case M32R_OPERAND_DISP16 :
0bf55db8 402 {
fbc8134d 403 long value = fields->f_disp16;
b00ea55c 404 value = ((int) (((value) - (pc))) >> (2));
1294c286 405 errmsg = insert_normal (value, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 16, 16, CGEN_FIELDS_BITSIZE (fields), buffer);
0bf55db8 406 }
853713a7
DE
407 break;
408 case M32R_OPERAND_DISP24 :
0bf55db8 409 {
fbc8134d 410 long value = fields->f_disp24;
b00ea55c 411 value = ((int) (((value) - (pc))) >> (2));
1294c286 412 errmsg = insert_normal (value, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 8, 24, CGEN_FIELDS_BITSIZE (fields), buffer);
0bf55db8 413 }
853713a7
DE
414 break;
415
416 default :
cbc6c9b2
DE
417 /* xgettext:c-format */
418 fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
853713a7
DE
419 opindex);
420 abort ();
421 }
422
423 return errmsg;
424}
425
426cgen_parse_fn * m32r_cgen_parse_handlers[] =
5d07b6cf
DE
427{
428 0, /* default */
853713a7
DE
429 parse_insn_normal,
430};
431
432cgen_insert_fn * m32r_cgen_insert_handlers[] =
5d07b6cf
DE
433{
434 0, /* default */
853713a7
DE
435 insert_insn_normal,
436};
437
438void
439m32r_cgen_init_asm (mach, endian)
440 int mach;
441 enum cgen_endian endian;
442{
443 m32r_cgen_init_tables (mach);
1294c286 444 cgen_set_cpu (& m32r_cgen_opcode_table, mach, endian);
853713a7
DE
445 cgen_asm_init ();
446}
447
1294c286
DE
448\f
449/* Default insertion routine.
450
451 ATTRS is a mask of the boolean attributes.
452 LENGTH is the length of VALUE in bits.
453 TOTAL_LENGTH is the total length of the insn (currently 8,16,32).
454
455 The result is an error message or NULL if success. */
456
457/* ??? This duplicates functionality with bfd's howto table and
458 bfd_install_relocation. */
459/* ??? For architectures where insns can be representable as ints,
460 store insn in `field' struct and add registers, etc. while parsing? */
461
462static const char *
463insert_normal (value, attrs, start, length, total_length, buffer)
464 long value;
465 unsigned int attrs;
466 int start;
467 int length;
468 int total_length;
469 char * buffer;
470{
471 bfd_vma x;
472 static char buf[100];
cbc6c9b2
DE
473 /* Written this way to avoid undefined behaviour.
474 Yes, `long' will be bfd_vma but not yet. */
475 long mask = (((1L << (length - 1)) - 1) << 1) | 1;
476
477 /* If LENGTH is zero, this operand doesn't contribute to the value. */
478 if (length == 0)
479 return NULL;
1294c286
DE
480
481 /* Ensure VALUE will fit. */
cbc6c9b2 482 if ((attrs & CGEN_ATTR_MASK (CGEN_OPERAND_UNSIGNED)) != 0)
1294c286 483 {
cbc6c9b2 484 unsigned long max = mask;
1294c286
DE
485 if ((unsigned long) value > max)
486 {
cbc6c9b2
DE
487 /* xgettext:c-format */
488 sprintf (buf, _("operand out of range (%lu not between 0 and %lu)"),
489 value, max);
1294c286
DE
490 return buf;
491 }
492 }
493 else
494 {
cbc6c9b2
DE
495 long min = - (1L << (length - 1));
496 long max = (1L << (length - 1)) - 1;
1294c286
DE
497 if (value < min || value > max)
498 {
cbc6c9b2
DE
499 sprintf
500 /* xgettext:c-format */
501 (buf, _("operand out of range (%ld not between %ld and %ld)"),
502 value, min, max);
1294c286
DE
503 return buf;
504 }
505 }
506
507#if 0 /*def CGEN_INT_INSN*/
cbc6c9b2 508 *buffer |= (value & mask) << (total_length - (start + length));
1294c286
DE
509#else
510 switch (total_length)
511 {
512 case 8:
513 x = * (unsigned char *) buffer;
514 break;
515 case 16:
516 if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
517 x = bfd_getb16 (buffer);
518 else
519 x = bfd_getl16 (buffer);
520 break;
521 case 32:
522 if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
523 x = bfd_getb32 (buffer);
524 else
525 x = bfd_getl32 (buffer);
526 break;
527 default :
528 abort ();
529 }
530
cbc6c9b2 531 x |= (value & mask) << (total_length - (start + length));
1294c286
DE
532
533 switch (total_length)
534 {
535 case 8:
536 * buffer = value;
537 break;
538 case 16:
539 if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
540 bfd_putb16 (x, buffer);
541 else
542 bfd_putl16 (x, buffer);
543 break;
544 case 32:
545 if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
546 bfd_putb32 (x, buffer);
547 else
548 bfd_putl32 (x, buffer);
549 break;
550 default :
551 abort ();
552 }
553#endif
554
555 return NULL;
556}
9c03036a
DE
557\f
558/* Default insn parser.
559
560 The syntax string is scanned and operands are parsed and stored in FIELDS.
561 Relocs are queued as we go via other callbacks.
562
563 ??? Note that this is currently an all-or-nothing parser. If we fail to
564 parse the instruction, we return 0 and the caller will start over from
565 the beginning. Backtracking will be necessary in parsing subexpressions,
566 but that can be handled there. Not handling backtracking here may get
567 expensive in the case of the m68k. Deal with later.
568
569 Returns NULL for success, an error message for failure.
570*/
571
572static const char *
573parse_insn_normal (insn, strp, fields)
0bf55db8
DE
574 const CGEN_INSN * insn;
575 const char ** strp;
576 CGEN_FIELDS * fields;
9c03036a 577{
0bf55db8
DE
578 const CGEN_SYNTAX * syntax = CGEN_INSN_SYNTAX (insn);
579 const char * str = *strp;
580 const char * errmsg;
581 const char * p;
853713a7 582 const unsigned char * syn;
9c03036a 583#ifdef CGEN_MNEMONIC_OPERANDS
fbc8134d 584 /* FIXME: wip */
0bf55db8 585 int past_opcode_p;
9c03036a
DE
586#endif
587
23cf992f
NC
588 /* For now we assume the mnemonic is first (there are no leading operands).
589 We can parse it without needing to set up operand parsing. */
590 p = CGEN_INSN_MNEMONIC (insn);
853713a7
DE
591 while (* p && * p == * str)
592 ++ p, ++ str;
cbc6c9b2 593
853713a7 594 if (* p || (* str && !isspace (* str)))
cbc6c9b2 595 return _("unrecognized instruction");
9c03036a
DE
596
597 CGEN_INIT_PARSE ();
a394e326 598 cgen_init_parse_operand ();
9c03036a
DE
599#ifdef CGEN_MNEMONIC_OPERANDS
600 past_opcode_p = 0;
601#endif
602
603 /* We don't check for (*str != '\0') here because we want to parse
604 any trailing fake arguments in the syntax string. */
23cf992f 605 syn = CGEN_SYNTAX_STRING (CGEN_INSN_SYNTAX (insn));
0bf55db8 606
23cf992f 607 /* Mnemonics come first for now, ensure valid string. */
853713a7 608 if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
23cf992f 609 abort ();
0bf55db8 610
23cf992f 611 ++syn;
0bf55db8 612
853713a7 613 while (* syn != 0)
9c03036a
DE
614 {
615 /* Non operand chars must match exactly. */
853713a7 616 if (CGEN_SYNTAX_CHAR_P (* syn))
9c03036a 617 {
853713a7 618 if (*str == CGEN_SYNTAX_CHAR (* syn))
9c03036a
DE
619 {
620#ifdef CGEN_MNEMONIC_OPERANDS
853713a7 621 if (* syn == ' ')
9c03036a
DE
622 past_opcode_p = 1;
623#endif
853713a7
DE
624 ++ syn;
625 ++ str;
9c03036a
DE
626 }
627 else
628 {
629 /* Syntax char didn't match. Can't be this insn. */
0bf55db8
DE
630 /* FIXME: would like to return something like
631 "expected char `c'" */
cbc6c9b2 632 return _("syntax error");
9c03036a
DE
633 }
634 continue;
635 }
636
637 /* We have an operand of some sort. */
638 errmsg = m32r_cgen_parse_operand (CGEN_SYNTAX_FIELD (*syn),
639 &str, fields);
640 if (errmsg)
641 return errmsg;
642
643 /* Done with this operand, continue with next one. */
853713a7 644 ++ syn;
9c03036a
DE
645 }
646
647 /* If we're at the end of the syntax string, we're done. */
853713a7 648 if (* syn == '\0')
9c03036a
DE
649 {
650 /* FIXME: For the moment we assume a valid `str' can only contain
651 blanks now. IE: We needn't try again with a longer version of
652 the insn and it is assumed that longer versions of insns appear
653 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
853713a7
DE
654 while (isspace (* str))
655 ++ str;
9c03036a 656
853713a7 657 if (* str != '\0')
cbc6c9b2 658 return _("junk at end of line"); /* FIXME: would like to include `str' */
9c03036a
DE
659
660 return NULL;
661 }
662
663 /* We couldn't parse it. */
664 return "unrecognized instruction";
665}
666
667/* Default insn builder (insert handler).
0bf55db8
DE
668 The instruction is recorded in target byte order.
669 The result is an error message or NULL if success. */
670/* FIXME: change buffer to char *? */
9c03036a 671
0bf55db8 672static const char *
fbc8134d 673insert_insn_normal (insn, fields, buffer, pc)
0bf55db8
DE
674 const CGEN_INSN * insn;
675 CGEN_FIELDS * fields;
676 cgen_insn_t * buffer;
fbc8134d 677 bfd_vma pc;
9c03036a 678{
0bf55db8
DE
679 const CGEN_SYNTAX * syntax = CGEN_INSN_SYNTAX (insn);
680 bfd_vma value;
853713a7 681 const unsigned char * syn;
9c03036a
DE
682
683 CGEN_INIT_INSERT ();
23cf992f 684 value = CGEN_INSN_VALUE (insn);
9c03036a
DE
685
686 /* If we're recording insns as numbers (rather than a string of bytes),
687 target byte order handling is deferred until later. */
688#undef min
689#define min(a,b) ((a) < (b) ? (a) : (b))
690#if 0 /*def CGEN_INT_INSN*/
691 *buffer = value;
692#else
693 switch (min (CGEN_BASE_INSN_BITSIZE, CGEN_FIELDS_BITSIZE (fields)))
694 {
695 case 8:
853713a7 696 * buffer = value;
9c03036a
DE
697 break;
698 case 16:
699 if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
700 bfd_putb16 (value, (char *) buffer);
701 else
702 bfd_putl16 (value, (char *) buffer);
703 break;
704 case 32:
705 if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
706 bfd_putb32 (value, (char *) buffer);
707 else
708 bfd_putl32 (value, (char *) buffer);
709 break;
710 default:
711 abort ();
712 }
713#endif
714
715 /* ??? Rather than scanning the syntax string again, we could store
716 in `fields' a null terminated list of the fields that are present. */
717
853713a7 718 for (syn = CGEN_SYNTAX_STRING (syntax); * syn != '\0'; ++ syn)
9c03036a 719 {
0bf55db8
DE
720 const char *errmsg;
721
853713a7 722 if (CGEN_SYNTAX_CHAR_P (* syn))
9c03036a
DE
723 continue;
724
0bf55db8 725 errmsg = m32r_cgen_insert_operand (CGEN_SYNTAX_FIELD (*syn), fields,
fbc8134d 726 (char *) buffer, pc);
0bf55db8
DE
727 if (errmsg)
728 return errmsg;
9c03036a 729 }
0bf55db8
DE
730
731 return NULL;
9c03036a
DE
732}
733\f
734/* Main entry point.
735 This routine is called for each instruction to be assembled.
736 STR points to the insn to be assembled.
737 We assume all necessary tables have been initialized.
1294c286
DE
738 The assembled instruction, less any fixups, is stored in buf.
739 [??? What byte order?]
9c03036a
DE
740 The result is a pointer to the insn's entry in the opcode table,
741 or NULL if an error occured (an error message will have already been
1294c286
DE
742 printed).
743
744 Note that when processing (non-alias) macro-insns,
745 this function recurses. */
9c03036a 746
23cf992f 747const CGEN_INSN *
5b3b8cb0 748m32r_cgen_assemble_insn (str, fields, buf, errmsg)
0bf55db8 749 const char * str;
853713a7
DE
750 CGEN_FIELDS * fields;
751 cgen_insn_t * buf;
0bf55db8 752 char ** errmsg;
9c03036a 753{
0bf55db8 754 const char * start;
853713a7 755 CGEN_INSN_LIST * ilist;
9c03036a
DE
756
757 /* Skip leading white space. */
853713a7
DE
758 while (isspace (* str))
759 ++ str;
9c03036a
DE
760
761 /* The instructions are stored in hashed lists.
762 Get the first in the list. */
763 ilist = CGEN_ASM_LOOKUP_INSN (str);
764
765 /* Keep looking until we find a match. */
766
767 start = str;
768 for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
769 {
23cf992f 770 const CGEN_INSN *insn = ilist->insn;
9c03036a
DE
771
772#if 0 /* not needed as unsupported opcodes shouldn't be in the hash lists */
773 /* Is this insn supported by the selected cpu? */
774 if (! m32r_cgen_insn_supported (insn))
775 continue;
776#endif
777
9c03036a
DE
778 /* If the RELAX attribute is set, this is an insn that shouldn't be
779 chosen immediately. Instead, it is used during assembler/linker
780 relaxation if possible. */
781 if (CGEN_INSN_ATTR (insn, CGEN_INSN_RELAX) != 0)
782 continue;
9c03036a
DE
783
784 str = start;
785
786 /* Record a default length for the insn. This will get set to the
787 correct value while parsing. */
788 /* FIXME: wip */
789 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
790
853713a7 791 if (! CGEN_PARSE_FN (insn) (insn, & str, fields))
9c03036a 792 {
fbc8134d
DE
793 /* ??? 0 is passed for `pc' */
794 if (CGEN_INSERT_FN (insn) (insn, fields, buf, (bfd_vma) 0) != NULL)
0bf55db8 795 continue;
9c03036a
DE
796 /* It is up to the caller to actually output the insn and any
797 queued relocs. */
798 return insn;
799 }
800
801 /* Try the next entry. */
802 }
803
5b3b8cb0
DE
804 /* FIXME: We can return a better error message than this.
805 Need to track why it failed and pick the right one. */
806 {
807 static char errbuf[100];
cbc6c9b2
DE
808 if (strlen (start) > 50)
809 /* xgettext:c-format */
810 sprintf (errbuf, _("bad instruction `%.50s...'"), start);
811 else
812 /* xgettext:c-format */
813 sprintf (errbuf, _("bad instruction `%.50s'"), start);
814
5b3b8cb0
DE
815 *errmsg = errbuf;
816 return NULL;
817 }
9c03036a
DE
818}
819\f
5b3b8cb0
DE
820#if 0 /* This calls back to GAS which we can't do without care. */
821
9c03036a 822/* Record each member of OPVALS in the assembler's symbol table.
5b3b8cb0
DE
823 This lets GAS parse registers for us.
824 ??? Interesting idea but not currently used. */
9c03036a 825
23cf992f
NC
826/* Record each member of OPVALS in the assembler's symbol table.
827 FIXME: Not currently used. */
828
9c03036a
DE
829void
830m32r_cgen_asm_hash_keywords (opvals)
853713a7 831 CGEN_KEYWORD * opvals;
9c03036a 832{
23cf992f 833 CGEN_KEYWORD_SEARCH search = cgen_keyword_search_init (opvals, NULL);
853713a7 834 const CGEN_KEYWORD_ENTRY * ke;
9c03036a 835
853713a7 836 while ((ke = cgen_keyword_search_next (& search)) != NULL)
9c03036a
DE
837 {
838#if 0 /* Unnecessary, should be done in the search routine. */
839 if (! m32r_cgen_opval_supported (ke))
840 continue;
841#endif
842 cgen_asm_record_register (ke->name, ke->value);
843 }
844}
5b3b8cb0
DE
845
846#endif /* 0 */
This page took 0.100353 seconds and 4 git commands to generate.