2012-11-09 Nick Clifton <nickc@redhat.com>
[deliverable/binutils-gdb.git] / gas / config / tc-crx.c
CommitLineData
1fe1f39c 1/* tc-crx.c -- Assembler code for the CRX CPU core.
1f42f8b3 2 Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012
87975d2a 3 Free Software Foundation, Inc.
1fe1f39c
NC
4
5 Contributed by Tomer Levi, NSC, Israel.
6 Originally written for GAS 2.12 by Tomer Levi, NSC, Israel.
7 Updates, BFDizing, GNUifying and ELF support by Tomer Levi.
8
9 This file is part of GAS, the GNU Assembler.
10
11 GAS is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
ec2655a6 13 the Free Software Foundation; either version 3, or (at your option)
1fe1f39c
NC
14 any later version.
15
16 GAS is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with GAS; see the file COPYING. If not, write to the
4b4da160
NC
23 Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
24 MA 02110-1301, USA. */
1fe1f39c
NC
25
26#include "as.h"
1f42f8b3 27#include "bfd_stdint.h"
1fe1f39c
NC
28#include "safe-ctype.h"
29#include "dwarf2dbg.h"
30#include "opcode/crx.h"
31#include "elf/crx.h"
32
1fe1f39c 33/* Word is considered here as a 16-bit unsigned short int. */
1fe1f39c
NC
34#define WORD_SHIFT 16
35
36/* Register is 4-bit size. */
37#define REG_SIZE 4
38
39/* Maximum size of a single instruction (in words). */
40#define INSN_MAX_SIZE 3
41
42/* Maximum bits which may be set in a `mask16' operand. */
43#define MAX_REGS_IN_MASK16 8
44
1fe1f39c
NC
45/* Utility macros for string comparison. */
46#define streq(a, b) (strcmp (a, b) == 0)
47#define strneq(a, b, c) (strncmp (a, b, c) == 0)
48
023d1155 49/* Assign a number NUM, shifted by SHIFT bytes, into a location
1fe1f39c
NC
50 pointed by index BYTE of array 'output_opcode'. */
51#define CRX_PRINT(BYTE, NUM, SHIFT) output_opcode[BYTE] |= (NUM << SHIFT)
52
023d1155
TL
53/* Operand errors. */
54typedef enum
55 {
56 OP_LEGAL = 0, /* Legal operand. */
57 OP_OUT_OF_RANGE, /* Operand not within permitted range. */
58 OP_NOT_EVEN, /* Operand is Odd number, should be even. */
59 OP_ILLEGAL_DISPU4, /* Operand is not within DISPU4 range. */
60 OP_ILLEGAL_CST4, /* Operand is not within CST4 range. */
61 OP_NOT_UPPER_64KB /* Operand is not within the upper 64KB
62 (0xFFFF0000-0xFFFFFFFF). */
63 }
64op_err;
65
1fe1f39c
NC
66/* Opcode mnemonics hash table. */
67static struct hash_control *crx_inst_hash;
68/* CRX registers hash table. */
69static struct hash_control *reg_hash;
70/* CRX coprocessor registers hash table. */
71static struct hash_control *copreg_hash;
72/* Current instruction we're assembling. */
73const inst *instruction;
74
023d1155
TL
75/* Global variables. */
76
77/* Array to hold an instruction encoding. */
1fe1f39c 78long output_opcode[2];
023d1155 79
1fe1f39c
NC
80/* Nonzero means a relocatable symbol. */
81int relocatable;
023d1155 82
1fe1f39c
NC
83/* A copy of the original instruction (used in error messages). */
84char ins_parse[MAX_INST_LEN];
023d1155
TL
85
86/* The current processed argument number. */
82d6ee2a 87int cur_arg_num;
1fe1f39c
NC
88
89/* Generic assembler global variables which must be defined by all targets. */
90
91/* Characters which always start a comment. */
92const char comment_chars[] = "#";
93
94/* Characters which start a comment at the beginning of a line. */
95const char line_comment_chars[] = "#";
96
97/* This array holds machine specific line separator characters. */
98const char line_separator_chars[] = ";";
99
100/* Chars that can be used to separate mant from exp in floating point nums. */
101const char EXP_CHARS[] = "eE";
102
103/* Chars that mean this number is a floating point constant as in 0f12.456 */
104const char FLT_CHARS[] = "f'";
105
106/* Target-specific multicharacter options, not const-declared at usage. */
107const char *md_shortopts = "";
42851540
NC
108struct option md_longopts[] =
109{
1fe1f39c
NC
110 {NULL, no_argument, NULL, 0}
111};
112size_t md_longopts_size = sizeof (md_longopts);
113
114/* This table describes all the machine specific pseudo-ops
115 the assembler has to support. The fields are:
116 *** Pseudo-op name without dot.
117 *** Function to call to execute this pseudo-op.
118 *** Integer arg to pass to the function. */
119
120const pseudo_typeS md_pseudo_table[] =
121{
122 /* In CRX machine, align is in bytes (not a ptwo boundary). */
123 {"align", s_align_bytes, 0},
124 {0, 0, 0}
125};
126
023d1155 127/* CRX relaxation table. */
1fe1f39c
NC
128const relax_typeS md_relax_table[] =
129{
130 /* bCC */
131 {0xfa, -0x100, 2, 1}, /* 8 */
132 {0xfffe, -0x10000, 4, 2}, /* 16 */
133 {0xfffffffe, -0xfffffffe, 6, 0}, /* 32 */
134
135 /* bal */
136 {0xfffe, -0x10000, 4, 4}, /* 16 */
137 {0xfffffffe, -0xfffffffe, 6, 0}, /* 32 */
138
30c62922 139 /* cmpbr/bcop */
1fe1f39c
NC
140 {0xfe, -0x100, 4, 6}, /* 8 */
141 {0xfffffe, -0x1000000, 6, 0} /* 24 */
142};
143
023d1155 144static void reset_vars (char *);
1fe1f39c
NC
145static reg get_register (char *);
146static copreg get_copregister (char *);
023d1155
TL
147static argtype get_optype (operand_type);
148static int get_opbits (operand_type);
149static int get_opflags (operand_type);
1fe1f39c 150static int get_number_of_operands (void);
82d6ee2a 151static void parse_operand (char *, ins *);
87975d2a
AM
152static int gettrap (const char *);
153static void handle_LoadStor (const char *);
154static int get_cinv_parameters (const char *);
023d1155
TL
155static long getconstant (long, int);
156static op_err check_range (long *, int, unsigned int, int);
1fe1f39c
NC
157static int getreg_image (reg);
158static void parse_operands (ins *, char *);
159static void parse_insn (ins *, char *);
160static void print_operand (int, int, argument *);
161static void print_constant (int, int, argument *);
162static int exponent2scale (int);
1fe1f39c 163static void mask_reg (int, unsigned short *);
023d1155 164static void process_label_constant (char *, ins *);
82d6ee2a 165static void set_operand (char *, ins *);
1fe1f39c
NC
166static char * preprocess_reglist (char *, int *);
167static int assemble_insn (char *, ins *);
168static void print_insn (ins *);
023d1155
TL
169static void warn_if_needed (ins *);
170static int adjust_if_needed (ins *);
1fe1f39c
NC
171
172/* Return the bit size for a given operand. */
173
174static int
023d1155 175get_opbits (operand_type op)
1fe1f39c
NC
176{
177 if (op < MAX_OPRD)
178 return crx_optab[op].bit_size;
179 else
180 return 0;
181}
182
183/* Return the argument type of a given operand. */
184
185static argtype
023d1155 186get_optype (operand_type op)
1fe1f39c
NC
187{
188 if (op < MAX_OPRD)
189 return crx_optab[op].arg_type;
190 else
191 return nullargs;
192}
193
9bb1ebc2
TL
194/* Return the flags of a given operand. */
195
196static int
023d1155 197get_opflags (operand_type op)
9bb1ebc2
TL
198{
199 if (op < MAX_OPRD)
200 return crx_optab[op].flags;
201 else
202 return 0;
203}
204
1fe1f39c
NC
205/* Get the core processor register 'reg_name'. */
206
207static reg
208get_register (char *reg_name)
209{
91d6fa6a 210 const reg_entry *rreg;
1fe1f39c 211
91d6fa6a 212 rreg = (const reg_entry *) hash_find (reg_hash, reg_name);
1fe1f39c 213
91d6fa6a
NC
214 if (rreg != NULL)
215 return rreg->value.reg_val;
1fe1f39c
NC
216 else
217 return nullregister;
218}
219
220/* Get the coprocessor register 'copreg_name'. */
221
222static copreg
223get_copregister (char *copreg_name)
224{
91d6fa6a 225 const reg_entry *coreg;
1fe1f39c 226
91d6fa6a 227 coreg = (const reg_entry *) hash_find (copreg_hash, copreg_name);
1fe1f39c 228
91d6fa6a
NC
229 if (coreg != NULL)
230 return coreg->value.copreg_val;
1fe1f39c
NC
231 else
232 return nullcopregister;
233}
234
1fe1f39c
NC
235/* Round up a section size to the appropriate boundary. */
236
237valueT
238md_section_align (segT seg, valueT val)
239{
240 /* Round .text section to a multiple of 2. */
241 if (seg == text_section)
242 return (val + 1) & ~1;
243 return val;
244}
245
246/* Parse an operand that is machine-specific (remove '*'). */
247
248void
249md_operand (expressionS * exp)
250{
251 char c = *input_line_pointer;
252
253 switch (c)
254 {
255 case '*':
256 input_line_pointer++;
257 expression (exp);
258 break;
259 default:
260 break;
261 }
262}
263
264/* Reset global variables before parsing a new instruction. */
265
266static void
023d1155 267reset_vars (char *op)
1fe1f39c 268{
023d1155 269 cur_arg_num = relocatable = 0;
42851540 270 memset (& output_opcode, '\0', sizeof (output_opcode));
1fe1f39c 271
1fe1f39c 272 /* Save a copy of the original OP (used in error messages). */
6c5cf62c
NC
273 strncpy (ins_parse, op, sizeof ins_parse - 1);
274 ins_parse [sizeof ins_parse - 1] = 0;
1fe1f39c
NC
275}
276
670ec21d
NC
277/* This macro decides whether a particular reloc is an entry in a
278 switch table. It is used when relaxing, because the linker needs
279 to know about all such entries so that it can adjust them if
280 necessary. */
281
282#define SWITCH_TABLE(fix) \
283 ( (fix)->fx_addsy != NULL \
284 && (fix)->fx_subsy != NULL \
285 && S_GET_SEGMENT ((fix)->fx_addsy) == \
286 S_GET_SEGMENT ((fix)->fx_subsy) \
287 && S_GET_SEGMENT (fix->fx_addsy) != undefined_section \
288 && ( (fix)->fx_r_type == BFD_RELOC_CRX_NUM8 \
289 || (fix)->fx_r_type == BFD_RELOC_CRX_NUM16 \
290 || (fix)->fx_r_type == BFD_RELOC_CRX_NUM32))
291
292/* See whether we need to force a relocation into the output file.
293 This is used to force out switch and PC relative relocations when
294 relaxing. */
295
296int
297crx_force_relocation (fixS *fix)
298{
299 if (generic_force_reloc (fix) || SWITCH_TABLE (fix))
300 return 1;
301
302 return 0;
303}
304
1fe1f39c
NC
305/* Generate a relocation entry for a fixup. */
306
307arelent *
308tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS * fixP)
309{
310 arelent * reloc;
311
312 reloc = xmalloc (sizeof (arelent));
42851540 313 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
1fe1f39c
NC
314 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
315 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
316 reloc->addend = fixP->fx_offset;
317
318 if (fixP->fx_subsy != NULL)
670ec21d
NC
319 {
320 if (SWITCH_TABLE (fixP))
321 {
322 /* Keep the current difference in the addend. */
323 reloc->addend = (S_GET_VALUE (fixP->fx_addsy)
324 - S_GET_VALUE (fixP->fx_subsy) + fixP->fx_offset);
42851540 325
670ec21d
NC
326 switch (fixP->fx_r_type)
327 {
328 case BFD_RELOC_CRX_NUM8:
329 fixP->fx_r_type = BFD_RELOC_CRX_SWITCH8;
330 break;
331 case BFD_RELOC_CRX_NUM16:
332 fixP->fx_r_type = BFD_RELOC_CRX_SWITCH16;
333 break;
334 case BFD_RELOC_CRX_NUM32:
335 fixP->fx_r_type = BFD_RELOC_CRX_SWITCH32;
336 break;
337 default:
338 abort ();
339 break;
340 }
341 }
342 else
343 {
344 /* We only resolve difference expressions in the same section. */
345 as_bad_where (fixP->fx_file, fixP->fx_line,
346 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
347 fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "0",
348 segment_name (fixP->fx_addsy
349 ? S_GET_SEGMENT (fixP->fx_addsy)
350 : absolute_section),
351 S_GET_NAME (fixP->fx_subsy),
352 segment_name (S_GET_SEGMENT (fixP->fx_addsy)));
353 }
354 }
1fe1f39c 355
9c2799c2 356 gas_assert ((int) fixP->fx_r_type > 0);
1fe1f39c
NC
357 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
358
359 if (reloc->howto == (reloc_howto_type *) NULL)
360 {
361 as_bad_where (fixP->fx_file, fixP->fx_line,
362 _("internal error: reloc %d (`%s') not supported by object file format"),
363 fixP->fx_r_type,
364 bfd_get_reloc_code_name (fixP->fx_r_type));
365 return NULL;
366 }
9c2799c2 367 gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
1fe1f39c
NC
368
369 return reloc;
370}
371
372/* Prepare machine-dependent frags for relaxation. */
373
374int
375md_estimate_size_before_relax (fragS *fragp, asection *seg)
376{
377 /* If symbol is undefined or located in a different section,
378 select the largest supported relocation. */
379 relax_substateT subtype;
380 relax_substateT rlx_state[] = {0, 2,
381 3, 4,
382 5, 6};
383
384 for (subtype = 0; subtype < ARRAY_SIZE (rlx_state); subtype += 2)
385 {
386 if (fragp->fr_subtype == rlx_state[subtype]
387 && (!S_IS_DEFINED (fragp->fr_symbol)
388 || seg != S_GET_SEGMENT (fragp->fr_symbol)))
389 {
390 fragp->fr_subtype = rlx_state[subtype + 1];
391 break;
392 }
393 }
394
395 if (fragp->fr_subtype >= ARRAY_SIZE (md_relax_table))
396 abort ();
397
398 return md_relax_table[fragp->fr_subtype].rlx_length;
399}
400
401void
402md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, fragS *fragP)
403{
404 /* 'opcode' points to the start of the instruction, whether
405 we need to change the instruction's fixed encoding. */
406 char *opcode = fragP->fr_literal + fragP->fr_fix;
407 bfd_reloc_code_real_type reloc;
408
409 subseg_change (sec, 0);
410
411 switch (fragP->fr_subtype)
412 {
413 case 0:
414 reloc = BFD_RELOC_CRX_REL8;
415 break;
416 case 1:
417 *opcode = 0x7e;
418 reloc = BFD_RELOC_CRX_REL16;
419 break;
420 case 2:
421 *opcode = 0x7f;
422 reloc = BFD_RELOC_CRX_REL32;
423 break;
424 case 3:
425 reloc = BFD_RELOC_CRX_REL16;
426 break;
427 case 4:
428 *++opcode = 0x31;
429 reloc = BFD_RELOC_CRX_REL32;
430 break;
431 case 5:
432 reloc = BFD_RELOC_CRX_REL8_CMP;
433 break;
434 case 6:
435 *++opcode = 0x31;
436 reloc = BFD_RELOC_CRX_REL24;
437 break;
438 default:
439 abort ();
440 break;
441 }
442
443 fix_new (fragP, fragP->fr_fix,
444 bfd_get_reloc_size (bfd_reloc_type_lookup (stdoutput, reloc)),
445 fragP->fr_symbol, fragP->fr_offset, 1, reloc);
446 fragP->fr_var = 0;
447 fragP->fr_fix += md_relax_table[fragP->fr_subtype].rlx_length;
448}
449
450/* Process machine-dependent command line options. Called once for
451 each option on the command line that the machine-independent part of
452 GAS does not understand. */
453
454int
455md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
456{
457 return 0;
458}
459
460/* Machine-dependent usage-output. */
461
462void
463md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
464{
465 return;
466}
467
1fe1f39c
NC
468char *
469md_atof (int type, char *litP, int *sizeP)
470{
499ac353 471 return ieee_md_atof (type, litP, sizeP, target_big_endian);
1fe1f39c
NC
472}
473
474/* Apply a fixS (fixup of an instruction or data that we didn't have
475 enough info to complete immediately) to the data in a frag.
476 Since linkrelax is nonzero and TC_LINKRELAX_FIXUP is defined to disable
477 relaxation of debug sections, this function is called only when
478 fixuping relocations of debug sections. */
479
480void
55cf6793 481md_apply_fix (fixS *fixP, valueT *valP, segT seg)
1fe1f39c
NC
482{
483 valueT val = * valP;
484 char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
485 fixP->fx_offset = 0;
486
487 switch (fixP->fx_r_type)
488 {
489 case BFD_RELOC_CRX_NUM8:
490 bfd_put_8 (stdoutput, (unsigned char) val, buf);
491 break;
492 case BFD_RELOC_CRX_NUM16:
493 bfd_put_16 (stdoutput, val, buf);
494 break;
495 case BFD_RELOC_CRX_NUM32:
496 bfd_put_32 (stdoutput, val, buf);
497 break;
498 default:
499 /* We shouldn't ever get here because linkrelax is nonzero. */
500 abort ();
501 break;
502 }
503
504 fixP->fx_done = 0;
505
506 if (fixP->fx_addsy == NULL
507 && fixP->fx_pcrel == 0)
508 fixP->fx_done = 1;
509
510 if (fixP->fx_pcrel == 1
511 && fixP->fx_addsy != NULL
512 && S_GET_SEGMENT (fixP->fx_addsy) == seg)
513 fixP->fx_done = 1;
514}
515
516/* The location from which a PC relative jump should be calculated,
517 given a PC relative reloc. */
518
519long
520md_pcrel_from (fixS *fixp)
521{
522 return fixp->fx_frag->fr_address + fixp->fx_where;
523}
524
525/* This function is called once, at assembler startup time. This should
526 set up all the tables, etc that the MD part of the assembler needs. */
527
528void
529md_begin (void)
530{
531 const char *hashret = NULL;
532 int i = 0;
533
534 /* Set up a hash table for the instructions. */
9bb1ebc2 535 if ((crx_inst_hash = hash_new ()) == NULL)
1fe1f39c 536 as_fatal (_("Virtual memory exhausted"));
9bb1ebc2 537
1fe1f39c
NC
538 while (crx_instruction[i].mnemonic != NULL)
539 {
540 const char *mnemonic = crx_instruction[i].mnemonic;
541
542 hashret = hash_insert (crx_inst_hash, mnemonic,
5a49b8ac 543 (void *) &crx_instruction[i]);
1fe1f39c
NC
544
545 if (hashret != NULL && *hashret != '\0')
546 as_fatal (_("Can't hash `%s': %s\n"), crx_instruction[i].mnemonic,
547 *hashret == 0 ? _("(unknown reason)") : hashret);
548
549 /* Insert unique names into hash table. The CRX instruction set
550 has many identical opcode names that have different opcodes based
551 on the operands. This hash table then provides a quick index to
552 the first opcode with a particular name in the opcode table. */
553 do
554 {
555 ++i;
556 }
557 while (crx_instruction[i].mnemonic != NULL
558 && streq (crx_instruction[i].mnemonic, mnemonic));
559 }
560
561 /* Initialize reg_hash hash table. */
9bb1ebc2
TL
562 if ((reg_hash = hash_new ()) == NULL)
563 as_fatal (_("Virtual memory exhausted"));
1fe1f39c
NC
564
565 {
566 const reg_entry *regtab;
567
568 for (regtab = crx_regtab;
569 regtab < (crx_regtab + NUMREGS); regtab++)
570 {
5a49b8ac 571 hashret = hash_insert (reg_hash, regtab->name, (void *) regtab);
1fe1f39c
NC
572 if (hashret)
573 as_fatal (_("Internal Error: Can't hash %s: %s"),
574 regtab->name,
575 hashret);
576 }
577 }
578
579 /* Initialize copreg_hash hash table. */
9bb1ebc2
TL
580 if ((copreg_hash = hash_new ()) == NULL)
581 as_fatal (_("Virtual memory exhausted"));
1fe1f39c
NC
582
583 {
584 const reg_entry *copregtab;
585
586 for (copregtab = crx_copregtab; copregtab < (crx_copregtab + NUMCOPREGS);
587 copregtab++)
588 {
5a49b8ac
AM
589 hashret = hash_insert (copreg_hash, copregtab->name,
590 (void *) copregtab);
1fe1f39c
NC
591 if (hashret)
592 as_fatal (_("Internal Error: Can't hash %s: %s"),
593 copregtab->name,
594 hashret);
595 }
596 }
597 /* Set linkrelax here to avoid fixups in most sections. */
598 linkrelax = 1;
599}
600
023d1155
TL
601/* Process constants (immediate/absolute)
602 and labels (jump targets/Memory locations). */
1fe1f39c
NC
603
604static void
82d6ee2a 605process_label_constant (char *str, ins * crx_ins)
1fe1f39c 606{
023d1155 607 char *saved_input_line_pointer;
82d6ee2a
TL
608 argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument. */
609
023d1155 610 saved_input_line_pointer = input_line_pointer;
1fe1f39c
NC
611 input_line_pointer = str;
612
613 expression (&crx_ins->exp);
023d1155 614
1fe1f39c
NC
615 switch (crx_ins->exp.X_op)
616 {
42851540
NC
617 case O_big:
618 case O_absent:
619 /* Missing or bad expr becomes absolute 0. */
620 as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
621 str);
622 crx_ins->exp.X_op = O_constant;
623 crx_ins->exp.X_add_number = 0;
624 crx_ins->exp.X_add_symbol = (symbolS *) 0;
625 crx_ins->exp.X_op_symbol = (symbolS *) 0;
023d1155 626 /* Fall through. */
42851540 627
1fe1f39c 628 case O_constant:
023d1155
TL
629 cur_arg->X_op = O_constant;
630 cur_arg->constant = crx_ins->exp.X_add_number;
1fe1f39c
NC
631 break;
632
633 case O_symbol:
634 case O_subtract:
023d1155
TL
635 case O_add:
636 cur_arg->X_op = O_symbol;
42851540 637 crx_ins->rtype = BFD_RELOC_NONE;
1fe1f39c
NC
638 relocatable = 1;
639
82d6ee2a 640 switch (cur_arg->type)
1fe1f39c
NC
641 {
642 case arg_cr:
1fe1f39c
NC
643 if (IS_INSN_TYPE (LD_STOR_INS_INC))
644 crx_ins->rtype = BFD_RELOC_CRX_REGREL12;
645 else if (IS_INSN_TYPE (CSTBIT_INS)
646 || IS_INSN_TYPE (STOR_IMM_INS))
1fe1f39c
NC
647 crx_ins->rtype = BFD_RELOC_CRX_REGREL28;
648 else
1fe1f39c 649 crx_ins->rtype = BFD_RELOC_CRX_REGREL32;
023d1155
TL
650 break;
651
82d6ee2a 652 case arg_idxr:
1fe1f39c
NC
653 crx_ins->rtype = BFD_RELOC_CRX_REGREL22;
654 break;
023d1155 655
1fe1f39c 656 case arg_c:
1fe1f39c
NC
657 if (IS_INSN_MNEMONIC ("bal") || IS_INSN_TYPE (DCR_BRANCH_INS))
658 crx_ins->rtype = BFD_RELOC_CRX_REL16;
659 else if (IS_INSN_TYPE (BRANCH_INS))
9bb1ebc2 660 crx_ins->rtype = BFD_RELOC_CRX_REL8;
1fe1f39c
NC
661 else if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (STOR_IMM_INS)
662 || IS_INSN_TYPE (CSTBIT_INS))
663 crx_ins->rtype = BFD_RELOC_CRX_ABS32;
664 else if (IS_INSN_TYPE (BRANCH_NEQ_INS))
665 crx_ins->rtype = BFD_RELOC_CRX_REL4;
30c62922 666 else if (IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
9bb1ebc2 667 crx_ins->rtype = BFD_RELOC_CRX_REL8_CMP;
1fe1f39c 668 break;
023d1155 669
1fe1f39c 670 case arg_ic:
1fe1f39c
NC
671 if (IS_INSN_TYPE (ARITH_INS))
672 crx_ins->rtype = BFD_RELOC_CRX_IMM32;
673 else if (IS_INSN_TYPE (ARITH_BYTE_INS))
674 crx_ins->rtype = BFD_RELOC_CRX_IMM16;
675 break;
676 default:
677 break;
678 }
1fe1f39c
NC
679 break;
680
681 default:
023d1155 682 cur_arg->X_op = crx_ins->exp.X_op;
1fe1f39c
NC
683 break;
684 }
685
023d1155
TL
686 input_line_pointer = saved_input_line_pointer;
687 return;
1fe1f39c
NC
688}
689
690/* Get the values of the scale to be encoded -
691 used for the scaled index mode of addressing. */
692
693static int
694exponent2scale (int val)
695{
696 int exponent;
697
698 /* If 'val' is 0, the following 'for' will be an endless loop. */
699 if (val == 0)
700 return 0;
701
702 for (exponent = 0; (val != 1); val >>= 1, exponent++)
703 ;
704
705 return exponent;
706}
707
82d6ee2a
TL
708/* Parsing different types of operands
709 -> constants Immediate/Absolute/Relative numbers
710 -> Labels Relocatable symbols
711 -> (rbase) Register base
712 -> disp(rbase) Register relative
713 -> disp(rbase)+ Post-increment mode
714 -> disp(rbase,ridx,scl) Register index mode */
1fe1f39c
NC
715
716static void
82d6ee2a 717set_operand (char *operand, ins * crx_ins)
1fe1f39c 718{
82d6ee2a
TL
719 char *operandS; /* Pointer to start of sub-opearand. */
720 char *operandE; /* Pointer to end of sub-opearand. */
721 expressionS scale;
722 int scale_val;
723 char *input_save, c;
724 argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument. */
1fe1f39c 725
82d6ee2a
TL
726 /* Initialize pointers. */
727 operandS = operandE = operand;
728
729 switch (cur_arg->type)
1fe1f39c 730 {
82d6ee2a
TL
731 case arg_sc: /* Case *+0x18. */
732 case arg_ic: /* Case $0x18. */
733 operandS++;
734 case arg_c: /* Case 0x18. */
735 /* Set constant. */
aea44f62 736 process_label_constant (operandS, crx_ins);
82d6ee2a
TL
737
738 if (cur_arg->type != arg_ic)
739 cur_arg->type = arg_c;
740 break;
741
742 case arg_icr: /* Case $0x18(r1). */
743 operandS++;
744 case arg_cr: /* Case 0x18(r1). */
745 /* Set displacement constant. */
746 while (*operandE != '(')
747 operandE++;
748 *operandE = '\0';
aea44f62 749 process_label_constant (operandS, crx_ins);
82d6ee2a
TL
750 operandS = operandE;
751 case arg_rbase: /* Case (r1). */
752 operandS++;
753 /* Set register base. */
754 while (*operandE != ')')
755 operandE++;
756 *operandE = '\0';
757 if ((cur_arg->r = get_register (operandS)) == nullregister)
1fe1f39c 758 as_bad (_("Illegal register `%s' in Instruction `%s'"),
82d6ee2a 759 operandS, ins_parse);
1fe1f39c 760
82d6ee2a
TL
761 if (cur_arg->type != arg_rbase)
762 cur_arg->type = arg_cr;
763 break;
1fe1f39c 764
82d6ee2a
TL
765 case arg_idxr:
766 /* Set displacement constant. */
767 while (*operandE != '(')
768 operandE++;
769 *operandE = '\0';
770 process_label_constant (operandS, crx_ins);
771 operandS = ++operandE;
772
773 /* Set register base. */
774 while ((*operandE != ',') && (! ISSPACE (*operandE)))
775 operandE++;
776 *operandE++ = '\0';
777 if ((cur_arg->r = get_register (operandS)) == nullregister)
1fe1f39c 778 as_bad (_("Illegal register `%s' in Instruction `%s'"),
82d6ee2a
TL
779 operandS, ins_parse);
780
781 /* Skip leading white space. */
782 while (ISSPACE (*operandE))
783 operandE++;
784 operandS = operandE;
1fe1f39c 785
82d6ee2a
TL
786 /* Set register index. */
787 while ((*operandE != ')') && (*operandE != ','))
788 operandE++;
789 c = *operandE;
790 *operandE++ = '\0';
1fe1f39c 791
82d6ee2a
TL
792 if ((cur_arg->i_r = get_register (operandS)) == nullregister)
793 as_bad (_("Illegal register `%s' in Instruction `%s'"),
794 operandS, ins_parse);
795
796 /* Skip leading white space. */
797 while (ISSPACE (*operandE))
798 operandE++;
799 operandS = operandE;
800
801 /* Set the scale. */
802 if (c == ')')
803 cur_arg->scale = 0;
1fe1f39c
NC
804 else
805 {
82d6ee2a
TL
806 while (*operandE != ')')
807 operandE++;
808 *operandE = '\0';
1fe1f39c 809
82d6ee2a
TL
810 /* Preprocess the scale string. */
811 input_save = input_line_pointer;
812 input_line_pointer = operandS;
813 expression (&scale);
814 input_line_pointer = input_save;
1fe1f39c 815
82d6ee2a 816 scale_val = scale.X_add_number;
1fe1f39c 817
82d6ee2a
TL
818 /* Check if the scale value is legal. */
819 if (scale_val != 1 && scale_val != 2
820 && scale_val != 4 && scale_val != 8)
821 as_bad (_("Illegal Scale - `%d'"), scale_val);
1fe1f39c 822
82d6ee2a 823 cur_arg->scale = exponent2scale (scale_val);
1fe1f39c
NC
824 }
825 break;
82d6ee2a 826
1fe1f39c
NC
827 default:
828 break;
829 }
830}
831
82d6ee2a
TL
832/* Parse a single operand.
833 operand - Current operand to parse.
834 crx_ins - Current assembled instruction. */
1fe1f39c
NC
835
836static void
82d6ee2a 837parse_operand (char *operand, ins * crx_ins)
1fe1f39c 838{
82d6ee2a
TL
839 int ret_val;
840 argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument. */
1fe1f39c 841
82d6ee2a
TL
842 /* Initialize the type to NULL before parsing. */
843 cur_arg->type = nullargs;
1fe1f39c 844
82d6ee2a
TL
845 /* Check whether this is a general processor register. */
846 if ((ret_val = get_register (operand)) != nullregister)
1fe1f39c 847 {
82d6ee2a
TL
848 cur_arg->type = arg_r;
849 cur_arg->r = ret_val;
023d1155
TL
850 cur_arg->X_op = O_register;
851 return;
1fe1f39c 852 }
1fe1f39c 853
82d6ee2a
TL
854 /* Check whether this is a core [special] coprocessor register. */
855 if ((ret_val = get_copregister (operand)) != nullcopregister)
856 {
857 cur_arg->type = arg_copr;
858 if (ret_val >= cs0)
859 cur_arg->type = arg_copsr;
860 cur_arg->cr = ret_val;
023d1155
TL
861 cur_arg->X_op = O_register;
862 return;
82d6ee2a 863 }
1fe1f39c 864
82d6ee2a 865 /* Deal with special characters. */
1fe1f39c
NC
866 switch (operand[0])
867 {
1fe1f39c
NC
868 case '$':
869 if (strchr (operand, '(') != NULL)
82d6ee2a 870 cur_arg->type = arg_icr;
1fe1f39c 871 else
82d6ee2a
TL
872 cur_arg->type = arg_ic;
873 goto set_params;
1fe1f39c
NC
874 break;
875
1fe1f39c 876 case '*':
82d6ee2a
TL
877 cur_arg->type = arg_sc;
878 goto set_params;
1fe1f39c 879 break;
82d6ee2a
TL
880
881 case '(':
882 cur_arg->type = arg_rbase;
883 goto set_params;
1fe1f39c 884 break;
82d6ee2a 885
1fe1f39c 886 default:
82d6ee2a
TL
887 break;
888 }
889
890 if (strchr (operand, '(') != NULL)
891 {
892 if (strchr (operand, ',') != NULL
893 && (strchr (operand, ',') > strchr (operand, '(')))
894 cur_arg->type = arg_idxr;
1fe1f39c 895 else
82d6ee2a
TL
896 cur_arg->type = arg_cr;
897 }
898 else
899 cur_arg->type = arg_c;
900 goto set_params;
901
902/* Parse an operand according to its type. */
903set_params:
904 cur_arg->constant = 0;
905 set_operand (operand, crx_ins);
1fe1f39c
NC
906}
907
82d6ee2a
TL
908/* Parse the various operands. Each operand is then analyzed to fillup
909 the fields in the crx_ins data structure. */
1fe1f39c
NC
910
911static void
912parse_operands (ins * crx_ins, char *operands)
913{
914 char *operandS; /* Operands string. */
915 char *operandH, *operandT; /* Single operand head/tail pointers. */
916 int allocated = 0; /* Indicates a new operands string was allocated. */
917 char *operand[MAX_OPERANDS]; /* Separating the operands. */
918 int op_num = 0; /* Current operand number we are parsing. */
919 int bracket_flag = 0; /* Indicates a bracket '(' was found. */
920 int sq_bracket_flag = 0; /* Indicates a square bracket '[' was found. */
921
922 /* Preprocess the list of registers, if necessary. */
923 operandS = operandH = operandT = (INST_HAS_REG_LIST) ?
924 preprocess_reglist (operands, &allocated) : operands;
925
926 while (*operandT != '\0')
927 {
928 if (*operandT == ',' && bracket_flag != 1 && sq_bracket_flag != 1)
929 {
930 *operandT++ = '\0';
931 operand[op_num++] = strdup (operandH);
932 operandH = operandT;
933 continue;
934 }
935
936 if (*operandT == ' ')
937 as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse);
938
939 if (*operandT == '(')
940 bracket_flag = 1;
941 else if (*operandT == '[')
942 sq_bracket_flag = 1;
943
944 if (*operandT == ')')
945 {
946 if (bracket_flag)
947 bracket_flag = 0;
948 else
949 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
950 }
951 else if (*operandT == ']')
952 {
953 if (sq_bracket_flag)
954 sq_bracket_flag = 0;
955 else
956 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
957 }
958
959 if (bracket_flag == 1 && *operandT == ')')
960 bracket_flag = 0;
961 else if (sq_bracket_flag == 1 && *operandT == ']')
962 sq_bracket_flag = 0;
963
964 operandT++;
965 }
966
967 /* Adding the last operand. */
968 operand[op_num++] = strdup (operandH);
969 crx_ins->nargs = op_num;
970
971 /* Verifying correct syntax of operands (all brackets should be closed). */
972 if (bracket_flag || sq_bracket_flag)
973 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
974
82d6ee2a 975 /* Now we parse each operand separately. */
1fe1f39c
NC
976 for (op_num = 0; op_num < crx_ins->nargs; op_num++)
977 {
82d6ee2a
TL
978 cur_arg_num = op_num;
979 parse_operand (operand[op_num], crx_ins);
1fe1f39c
NC
980 free (operand[op_num]);
981 }
982
983 if (allocated)
984 free (operandS);
985}
986
987/* Get the trap index in dispatch table, given its name.
988 This routine is used by assembling the 'excp' instruction. */
989
990static int
87975d2a 991gettrap (const char *s)
1fe1f39c
NC
992{
993 const trap_entry *trap;
994
995 for (trap = crx_traps; trap < (crx_traps + NUMTRAPS); trap++)
42851540 996 if (strcasecmp (trap->name, s) == 0)
1fe1f39c
NC
997 return trap->entry;
998
999 as_bad (_("Unknown exception: `%s'"), s);
1000 return 0;
1001}
1002
64995a6b
TL
1003/* Post-Increment instructions, as well as Store-Immediate instructions, are a
1004 sub-group within load/stor instruction groups.
1005 Therefore, when parsing a Post-Increment/Store-Immediate insn, we have to
1006 advance the instruction pointer to the start of that sub-group (that is, up
1007 to the first instruction of that type).
1008 Otherwise, the insn will be mistakenly identified as of type LD_STOR_INS. */
1fe1f39c
NC
1009
1010static void
87975d2a 1011handle_LoadStor (const char *operands)
1fe1f39c 1012{
9bb1ebc2
TL
1013 /* Post-Increment instructions precede Store-Immediate instructions in
1014 CRX instruction table, hence they are handled before.
1015 This synchronization should be kept. */
64995a6b 1016
1fe1f39c 1017 /* Assuming Post-Increment insn has the following format :
64995a6b
TL
1018 'MNEMONIC DISP(REG)+, REG' (e.g. 'loadw 12(r5)+, r6').
1019 LD_STOR_INS_INC are the only store insns containing a plus sign (+). */
1fe1f39c 1020 if (strstr (operands, ")+") != NULL)
9bb1ebc2
TL
1021 {
1022 while (! IS_INSN_TYPE (LD_STOR_INS_INC))
1023 instruction++;
1024 return;
1025 }
1026
1027 /* Assuming Store-Immediate insn has the following format :
1028 'MNEMONIC $DISP, ...' (e.g. 'storb $1, 12(r5)').
1029 STOR_IMM_INS are the only store insns containing a dollar sign ($). */
1030 if (strstr (operands, "$") != NULL)
1031 while (! IS_INSN_TYPE (STOR_IMM_INS))
1fe1f39c
NC
1032 instruction++;
1033}
1034
1035/* Top level module where instruction parsing starts.
1036 crx_ins - data structure holds some information.
1037 operands - holds the operands part of the whole instruction. */
1038
1039static void
1040parse_insn (ins *insn, char *operands)
1041{
023d1155
TL
1042 int i;
1043
1044 /* Handle instructions with no operands. */
1045 for (i = 0; no_op_insn[i] != NULL; i++)
1046 {
1047 if (streq (no_op_insn[i], instruction->mnemonic))
1048 {
1049 insn->nargs = 0;
1050 return;
1051 }
1052 }
1053
1054 /* Handle 'excp'/'cinv' instructions. */
1fe1f39c
NC
1055 if (IS_INSN_MNEMONIC ("excp") || IS_INSN_MNEMONIC ("cinv"))
1056 {
1057 insn->nargs = 1;
1058 insn->arg[0].type = arg_ic;
1fe1f39c
NC
1059 insn->arg[0].constant = IS_INSN_MNEMONIC ("excp") ?
1060 gettrap (operands) : get_cinv_parameters (operands);
023d1155 1061 insn->arg[0].X_op = O_constant;
1fe1f39c
NC
1062 return;
1063 }
1064
e3c52c53 1065 /* Handle load/stor unique instructions before parsing. */
64995a6b
TL
1066 if (IS_INSN_TYPE (LD_STOR_INS))
1067 handle_LoadStor (operands);
1fe1f39c
NC
1068
1069 if (operands != NULL)
1070 parse_operands (insn, operands);
1071}
1072
1073/* Cinv instruction requires special handling. */
1074
1075static int
87975d2a 1076get_cinv_parameters (const char *operand)
1fe1f39c 1077{
87975d2a 1078 const char *p = operand;
48c9f030 1079 int d_used = 0, i_used = 0, u_used = 0, b_used = 0;
1fe1f39c
NC
1080
1081 while (*++p != ']')
1082 {
1083 if (*p == ',' || *p == ' ')
1084 continue;
1085
1086 if (*p == 'd')
1087 d_used = 1;
1088 else if (*p == 'i')
1089 i_used = 1;
1090 else if (*p == 'u')
1091 u_used = 1;
48c9f030
NC
1092 else if (*p == 'b')
1093 b_used = 1;
1fe1f39c
NC
1094 else
1095 as_bad (_("Illegal `cinv' parameter: `%c'"), *p);
1096 }
1097
48c9f030
NC
1098 return ((b_used ? 8 : 0)
1099 + (d_used ? 4 : 0)
1fe1f39c
NC
1100 + (i_used ? 2 : 0)
1101 + (u_used ? 1 : 0));
1102}
1103
1104/* Retrieve the opcode image of a given register.
1105 If the register is illegal for the current instruction,
1106 issue an error. */
1107
1108static int
1109getreg_image (reg r)
1110{
91d6fa6a 1111 const reg_entry *rreg;
1fe1f39c 1112 char *reg_name;
9bb1ebc2 1113 int is_procreg = 0; /* Nonzero means argument should be processor reg. */
1fe1f39c 1114
82d6ee2a
TL
1115 if (((IS_INSN_MNEMONIC ("mtpr")) && (cur_arg_num == 1))
1116 || ((IS_INSN_MNEMONIC ("mfpr")) && (cur_arg_num == 0)) )
9bb1ebc2 1117 is_procreg = 1;
1fe1f39c
NC
1118
1119 /* Check whether the register is in registers table. */
1120 if (r < MAX_REG)
91d6fa6a 1121 rreg = &crx_regtab[r];
1fe1f39c 1122 /* Check whether the register is in coprocessor registers table. */
87975d2a 1123 else if (r < (int) MAX_COPREG)
91d6fa6a 1124 rreg = &crx_copregtab[r-MAX_REG];
1fe1f39c
NC
1125 /* Register not found. */
1126 else
1127 {
1128 as_bad (_("Unknown register: `%d'"), r);
1129 return 0;
1130 }
1131
91d6fa6a 1132 reg_name = rreg->name;
1fe1f39c
NC
1133
1134/* Issue a error message when register is illegal. */
1135#define IMAGE_ERR \
1136 as_bad (_("Illegal register (`%s') in Instruction: `%s'"), \
1137 reg_name, ins_parse); \
1138 break;
1139
91d6fa6a 1140 switch (rreg->type)
1fe1f39c
NC
1141 {
1142 case CRX_U_REGTYPE:
9bb1ebc2 1143 if (is_procreg || (instruction->flags & USER_REG))
91d6fa6a 1144 return rreg->image;
9bb1ebc2
TL
1145 else
1146 IMAGE_ERR;
1147
1fe1f39c 1148 case CRX_CFG_REGTYPE:
9bb1ebc2 1149 if (is_procreg)
91d6fa6a 1150 return rreg->image;
1fe1f39c
NC
1151 else
1152 IMAGE_ERR;
1153
1154 case CRX_R_REGTYPE:
9bb1ebc2 1155 if (! is_procreg)
91d6fa6a 1156 return rreg->image;
1fe1f39c
NC
1157 else
1158 IMAGE_ERR;
1159
9bb1ebc2
TL
1160 case CRX_C_REGTYPE:
1161 case CRX_CS_REGTYPE:
91d6fa6a 1162 return rreg->image;
9bb1ebc2
TL
1163 break;
1164
1fe1f39c
NC
1165 default:
1166 IMAGE_ERR;
1167 }
1168
1169 return 0;
1170}
1171
023d1155 1172/* Routine used to represent integer X using NBITS bits. */
1fe1f39c 1173
023d1155
TL
1174static long
1175getconstant (long x, int nbits)
1fe1f39c 1176{
1f42f8b3 1177 return x & ((((1U << (nbits - 1)) - 1) << 1) | 1);
1fe1f39c
NC
1178}
1179
1180/* Print a constant value to 'output_opcode':
1181 ARG holds the operand's type and value.
1182 SHIFT represents the location of the operand to be print into.
1183 NBITS determines the size (in bits) of the constant. */
1184
1185static void
1186print_constant (int nbits, int shift, argument *arg)
1187{
1188 unsigned long mask = 0;
1189
1190 long constant = getconstant (arg->constant, nbits);
1191
1192 switch (nbits)
1193 {
1194 case 32:
1195 case 28:
1196 case 24:
1197 case 22:
1198 /* mask the upper part of the constant, that is, the bits
1199 going to the lowest byte of output_opcode[0].
1200 The upper part of output_opcode[1] is always filled,
1201 therefore it is always masked with 0xFFFF. */
1202 mask = (1 << (nbits - 16)) - 1;
1203 /* Divide the constant between two consecutive words :
1204 0 1 2 3
1205 +---------+---------+---------+---------+
1206 | | X X X X | X X X X | |
1207 +---------+---------+---------+---------+
1208 output_opcode[0] output_opcode[1] */
1209
1210 CRX_PRINT (0, (constant >> WORD_SHIFT) & mask, 0);
1211 CRX_PRINT (1, (constant & 0xFFFF), WORD_SHIFT);
1212 break;
1213
1214 case 16:
1215 case 12:
1216 /* Special case - in arg_cr, the SHIFT represents the location
1217 of the REGISTER, not the constant, which is itself not shifted. */
1218 if (arg->type == arg_cr)
1219 {
1220 CRX_PRINT (0, constant, 0);
1221 break;
1222 }
1223
9bb1ebc2
TL
1224 /* When instruction size is 3 and 'shift' is 16, a 16-bit constant is
1225 always filling the upper part of output_opcode[1]. If we mistakenly
1226 write it to output_opcode[0], the constant prefix (that is, 'match')
708587a4 1227 will be overridden.
9bb1ebc2
TL
1228 0 1 2 3
1229 +---------+---------+---------+---------+
1230 | 'match' | | X X X X | |
1231 +---------+---------+---------+---------+
1232 output_opcode[0] output_opcode[1] */
1233
1234 if ((instruction->size > 2) && (shift == WORD_SHIFT))
1fe1f39c
NC
1235 CRX_PRINT (1, constant, WORD_SHIFT);
1236 else
1237 CRX_PRINT (0, constant, shift);
1238 break;
1239
1240 default:
1241 CRX_PRINT (0, constant, shift);
1242 break;
1243 }
1244}
1245
1246/* Print an operand to 'output_opcode', which later on will be
1247 printed to the object file:
1248 ARG holds the operand's type, size and value.
1249 SHIFT represents the printing location of operand.
1250 NBITS determines the size (in bits) of a constant operand. */
1251
1252static void
1253print_operand (int nbits, int shift, argument *arg)
1254{
1255 switch (arg->type)
1256 {
1257 case arg_r:
1258 CRX_PRINT (0, getreg_image (arg->r), shift);
1259 break;
1260
1261 case arg_copr:
1262 if (arg->cr < c0 || arg->cr > c15)
1263 as_bad (_("Illegal Co-processor register in Instruction `%s' "),
1264 ins_parse);
1265 CRX_PRINT (0, getreg_image (arg->cr), shift);
1266 break;
1267
1268 case arg_copsr:
1269 if (arg->cr < cs0 || arg->cr > cs15)
1270 as_bad (_("Illegal Co-processor special register in Instruction `%s' "),
1271 ins_parse);
1272 CRX_PRINT (0, getreg_image (arg->cr), shift);
1273 break;
1274
82d6ee2a 1275 case arg_idxr:
1fe1f39c
NC
1276 /* 16 12 8 6 0
1277 +--------------------------------+
9bb1ebc2 1278 | r_base | r_idx | scl| disp |
1fe1f39c
NC
1279 +--------------------------------+ */
1280 CRX_PRINT (0, getreg_image (arg->r), 12);
1281 CRX_PRINT (0, getreg_image (arg->i_r), 8);
1282 CRX_PRINT (0, arg->scale, 6);
82d6ee2a
TL
1283 case arg_ic:
1284 case arg_c:
1fe1f39c
NC
1285 print_constant (nbits, shift, arg);
1286 break;
1287
1288 case arg_rbase:
1289 CRX_PRINT (0, getreg_image (arg->r), shift);
1290 break;
1291
1292 case arg_cr:
1293 /* case base_cst4. */
023d1155
TL
1294 if (instruction->flags & DISPU4MAP)
1295 print_constant (nbits, shift + REG_SIZE, arg);
1fe1f39c 1296 else
9bb1ebc2 1297 /* rbase_disps<NN> and other such cases. */
1fe1f39c
NC
1298 print_constant (nbits, shift, arg);
1299 /* Add the register argument to the output_opcode. */
1300 CRX_PRINT (0, getreg_image (arg->r), shift);
1301 break;
1302
1fe1f39c
NC
1303 default:
1304 break;
1305 }
1306}
1307
1308/* Retrieve the number of operands for the current assembled instruction. */
1309
1310static int
1311get_number_of_operands (void)
1312{
1313 int i;
1314
1315 for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
1316 ;
1317 return i;
1318}
1319
023d1155
TL
1320/* Verify that the number NUM can be represented in BITS bits (that is,
1321 within its permitted range), based on the instruction's FLAGS.
1322 If UPDATE is nonzero, update the value of NUM if necessary.
1323 Return OP_LEGAL upon success, actual error type upon failure. */
1324
1325static op_err
1326check_range (long *num, int bits, int unsigned flags, int update)
1327{
1f42f8b3 1328 uint32_t max;
023d1155
TL
1329 int retval = OP_LEGAL;
1330 int bin;
1f42f8b3
AM
1331 uint32_t upper_64kb = 0xffff0000;
1332 uint32_t value = *num;
023d1155
TL
1333
1334 /* Verify operand value is even. */
1335 if (flags & OP_EVEN)
1336 {
1337 if (value % 2)
1338 return OP_NOT_EVEN;
1339 }
1340
1341 if (flags & OP_UPPER_64KB)
1342 {
1343 /* Check if value is to be mapped to upper 64 KB memory area. */
1344 if ((value & upper_64kb) == upper_64kb)
1345 {
1346 value -= upper_64kb;
1347 if (update)
1348 *num = value;
1349 }
1350 else
1351 return OP_NOT_UPPER_64KB;
1352 }
1353
1354 if (flags & OP_SHIFT)
1355 {
1f42f8b3
AM
1356 /* All OP_SHIFT args are also OP_SIGNED, so we want to keep the
1357 sign. However, right shift of a signed type with a negative
1358 value is implementation defined. See ISO C 6.5.7. So we use
1359 an unsigned type and sign extend afterwards. */
023d1155 1360 value >>= 1;
805e800d 1361 value = (value ^ 0x40000000) - 0x40000000;
023d1155
TL
1362 if (update)
1363 *num = value;
1364 }
1365 else if (flags & OP_SHIFT_DEC)
1366 {
1367 value = (value >> 1) - 1;
1368 if (update)
1369 *num = value;
1370 }
1371
1372 if (flags & OP_ESC)
1373 {
1374 /* 0x7e and 0x7f are reserved escape sequences of dispe9. */
1375 if (value == 0x7e || value == 0x7f)
1376 return OP_OUT_OF_RANGE;
1377 }
1378
1379 if (flags & OP_DISPU4)
1380 {
1381 int is_dispu4 = 0;
1382
1f42f8b3
AM
1383 uint32_t mul = (instruction->flags & DISPUB4 ? 1
1384 : instruction->flags & DISPUW4 ? 2
1385 : instruction->flags & DISPUD4 ? 4
1386 : 0);
023d1155
TL
1387
1388 for (bin = 0; bin < cst4_maps; bin++)
1389 {
1f42f8b3 1390 if (value == mul * bin)
023d1155
TL
1391 {
1392 is_dispu4 = 1;
1393 if (update)
1394 *num = bin;
1395 break;
1396 }
1397 }
1398 if (!is_dispu4)
1399 retval = OP_ILLEGAL_DISPU4;
1400 }
1401 else if (flags & OP_CST4)
1402 {
1403 int is_cst4 = 0;
1404
1405 for (bin = 0; bin < cst4_maps; bin++)
1406 {
805e800d 1407 if (value == (uint32_t) cst4_map[bin])
023d1155
TL
1408 {
1409 is_cst4 = 1;
1410 if (update)
1411 *num = bin;
1412 break;
1413 }
1414 }
1415 if (!is_cst4)
1416 retval = OP_ILLEGAL_CST4;
1417 }
1418 else if (flags & OP_SIGNED)
1419 {
1f42f8b3
AM
1420 max = 1;
1421 max = max << (bits - 1);
1422 value += max;
1423 max = ((max - 1) << 1) | 1;
1424 if (value > max)
023d1155
TL
1425 retval = OP_OUT_OF_RANGE;
1426 }
1427 else if (flags & OP_UNSIGNED)
1428 {
1f42f8b3
AM
1429 max = 1;
1430 max = max << (bits - 1);
1431 max = ((max - 1) << 1) | 1;
1432 if (value > max)
023d1155
TL
1433 retval = OP_OUT_OF_RANGE;
1434 }
1435 return retval;
1436}
1437
1438/* Assemble a single instruction:
1439 INSN is already parsed (that is, all operand values and types are set).
1440 For instruction to be assembled, we need to find an appropriate template in
1441 the instruction table, meeting the following conditions:
1442 1: Has the same number of operands.
1443 2: Has the same operand types.
1444 3: Each operand size is sufficient to represent the instruction's values.
1fe1f39c
NC
1445 Returns 1 upon success, 0 upon failure. */
1446
1447static int
1448assemble_insn (char *mnemonic, ins *insn)
1449{
023d1155
TL
1450 /* Type of each operand in the current template. */
1451 argtype cur_type[MAX_OPERANDS];
1452 /* Size (in bits) of each operand in the current template. */
1453 unsigned int cur_size[MAX_OPERANDS];
1454 /* Flags of each operand in the current template. */
1455 unsigned int cur_flags[MAX_OPERANDS];
9bb1ebc2 1456 /* Instruction type to match. */
82d6ee2a 1457 unsigned int ins_type;
023d1155 1458 /* Boolean flag to mark whether a match was found. */
1fe1f39c 1459 int match = 0;
023d1155
TL
1460 int i;
1461 /* Nonzero if an instruction with same number of operands was found. */
1462 int found_same_number_of_operands = 0;
1463 /* Nonzero if an instruction with same argument types was found. */
1464 int found_same_argument_types = 0;
1465 /* Nonzero if a constant was found within the required range. */
1466 int found_const_within_range = 0;
1467 /* Argument number of an operand with invalid type. */
1468 int invalid_optype = -1;
1469 /* Argument number of an operand with invalid constant value. */
1470 int invalid_const = -1;
1471 /* Operand error (used for issuing various constant error messages). */
1472 op_err op_error, const_err = OP_LEGAL;
1473
1474/* Retrieve data (based on FUNC) for each operand of a given instruction. */
1475#define GET_CURRENT_DATA(FUNC, ARRAY) \
1476 for (i = 0; i < insn->nargs; i++) \
1477 ARRAY[i] = FUNC (instruction->operands[i].op_type)
1478
1479#define GET_CURRENT_TYPE GET_CURRENT_DATA(get_optype, cur_type)
1480#define GET_CURRENT_SIZE GET_CURRENT_DATA(get_opbits, cur_size)
1481#define GET_CURRENT_FLAGS GET_CURRENT_DATA(get_opflags, cur_flags)
1482
1483 /* Instruction has no operands -> only copy the constant opcode. */
1fe1f39c
NC
1484 if (insn->nargs == 0)
1485 {
1486 output_opcode[0] = BIN (instruction->match, instruction->match_bits);
1487 return 1;
1488 }
1489
9bb1ebc2
TL
1490 /* In some case, same mnemonic can appear with different instruction types.
1491 For example, 'storb' is supported with 3 different types :
1492 LD_STOR_INS, LD_STOR_INS_INC, STOR_IMM_INS.
1493 We assume that when reaching this point, the instruction type was
1494 pre-determined. We need to make sure that the type stays the same
1495 during a search for matching instruction. */
1496 ins_type = CRX_INS_TYPE(instruction->flags);
1497
023d1155
TL
1498 while (/* Check that match is still not found. */
1499 match != 1
1fe1f39c
NC
1500 /* Check we didn't get to end of table. */
1501 && instruction->mnemonic != NULL
1502 /* Check that the actual mnemonic is still available. */
9bb1ebc2
TL
1503 && IS_INSN_MNEMONIC (mnemonic)
1504 /* Check that the instruction type wasn't changed. */
1505 && IS_INSN_TYPE(ins_type))
1fe1f39c 1506 {
023d1155
TL
1507 /* Check whether number of arguments is legal. */
1508 if (get_number_of_operands () != insn->nargs)
1509 goto next_insn;
1510 found_same_number_of_operands = 1;
1511
1512 /* Initialize arrays with data of each operand in current template. */
1513 GET_CURRENT_TYPE;
1514 GET_CURRENT_SIZE;
1515 GET_CURRENT_FLAGS;
1516
1517 /* Check for type compatibility. */
1fe1f39c
NC
1518 for (i = 0; i < insn->nargs; i++)
1519 {
023d1155 1520 if (cur_type[i] != insn->arg[i].type)
e92c9d66 1521 {
023d1155
TL
1522 if (invalid_optype == -1)
1523 invalid_optype = i + 1;
1524 goto next_insn;
e92c9d66
TL
1525 }
1526 }
023d1155 1527 found_same_argument_types = 1;
e92c9d66 1528
023d1155
TL
1529 for (i = 0; i < insn->nargs; i++)
1530 {
1531 /* Reverse the operand indices for certain opcodes:
1532 Index 0 -->> 1
1533 Index 1 -->> 0
1534 Other index -->> stays the same. */
1535 int j = instruction->flags & REVERSE_MATCH ?
1536 i == 0 ? 1 :
1537 i == 1 ? 0 : i :
1538 i;
1539
1540 /* Only check range - don't update the constant's value, since the
1541 current instruction may not be the last we try to match.
1542 The constant's value will be updated later, right before printing
1543 it to the object file. */
1544 if ((insn->arg[j].X_op == O_constant)
1545 && (op_error = check_range (&insn->arg[j].constant, cur_size[j],
1546 cur_flags[j], 0)))
1547 {
1548 if (invalid_const == -1)
1549 {
1550 invalid_const = j + 1;
1551 const_err = op_error;
1552 }
1553 goto next_insn;
1554 }
1555 /* For symbols, we make sure the relocation size (which was already
1556 determined) is sufficient. */
1557 else if ((insn->arg[j].X_op == O_symbol)
1558 && ((bfd_reloc_type_lookup (stdoutput, insn->rtype))->bitsize
1559 > cur_size[j]))
1560 goto next_insn;
1561 }
1562 found_const_within_range = 1;
1fe1f39c 1563
023d1155
TL
1564 /* If we got till here -> Full match is found. */
1565 match = 1;
1566 break;
1fe1f39c 1567
023d1155
TL
1568/* Try again with next instruction. */
1569next_insn:
1570 instruction++;
1fe1f39c
NC
1571 }
1572
023d1155 1573 if (!match)
1fe1f39c 1574 {
023d1155
TL
1575 /* We haven't found a match - instruction can't be assembled. */
1576 if (!found_same_number_of_operands)
1577 as_bad (_("Incorrect number of operands"));
1578 else if (!found_same_argument_types)
1579 as_bad (_("Illegal type of operand (arg %d)"), invalid_optype);
1580 else if (!found_const_within_range)
1581 {
1582 switch (const_err)
e3c52c53 1583 {
023d1155
TL
1584 case OP_OUT_OF_RANGE:
1585 as_bad (_("Operand out of range (arg %d)"), invalid_const);
1586 break;
1587 case OP_NOT_EVEN:
1588 as_bad (_("Operand has odd displacement (arg %d)"), invalid_const);
1589 break;
1590 case OP_ILLEGAL_DISPU4:
1591 as_bad (_("Invalid DISPU4 operand value (arg %d)"), invalid_const);
1592 break;
1593 case OP_ILLEGAL_CST4:
1594 as_bad (_("Invalid CST4 operand value (arg %d)"), invalid_const);
1595 break;
1596 case OP_NOT_UPPER_64KB:
1597 as_bad (_("Operand value is not within upper 64 KB (arg %d)"),
1598 invalid_const);
1599 break;
1600 default:
1601 as_bad (_("Illegal operand (arg %d)"), invalid_const);
1602 break;
e3c52c53 1603 }
023d1155
TL
1604 }
1605
1606 return 0;
1607 }
1608 else
1609 /* Full match - print the encoding to output file. */
1610 {
1611 /* Make further checkings (such that couldn't be made earlier).
1612 Warn the user if necessary. */
1613 warn_if_needed (insn);
1614
1615 /* Check whether we need to adjust the instruction pointer. */
1616 if (adjust_if_needed (insn))
1617 /* If instruction pointer was adjusted, we need to update
1618 the size of the current template operands. */
1619 GET_CURRENT_SIZE;
9bb1ebc2 1620
023d1155 1621 for (i = 0; i < insn->nargs; i++)
9bb1ebc2 1622 {
023d1155
TL
1623 int j = instruction->flags & REVERSE_MATCH ?
1624 i == 0 ? 1 :
1625 i == 1 ? 0 : i :
1626 i;
1627
1628 /* This time, update constant value before printing it. */
1629 if ((insn->arg[j].X_op == O_constant)
1630 && (check_range (&insn->arg[j].constant, cur_size[j],
1631 cur_flags[j], 1) != OP_LEGAL))
1632 as_fatal (_("Illegal operand (arg %d)"), j+1);
9bb1ebc2
TL
1633 }
1634
023d1155
TL
1635 /* First, copy the instruction's opcode. */
1636 output_opcode[0] = BIN (instruction->match, instruction->match_bits);
9bb1ebc2 1637
023d1155 1638 for (i = 0; i < insn->nargs; i++)
1fe1f39c 1639 {
023d1155
TL
1640 cur_arg_num = i;
1641 print_operand (cur_size[i], instruction->operands[i].shift,
1642 &insn->arg[i]);
1643 }
1644 }
9bb1ebc2 1645
023d1155
TL
1646 return 1;
1647}
9bb1ebc2 1648
023d1155
TL
1649/* Bunch of error checkings.
1650 The checks are made after a matching instruction was found. */
9bb1ebc2 1651
023d1155
TL
1652void
1653warn_if_needed (ins *insn)
1654{
1655 /* If the post-increment address mode is used and the load/store
1656 source register is the same as rbase, the result of the
1657 instruction is undefined. */
1658 if (IS_INSN_TYPE (LD_STOR_INS_INC))
1659 {
1660 /* Enough to verify that one of the arguments is a simple reg. */
1661 if ((insn->arg[0].type == arg_r) || (insn->arg[1].type == arg_r))
1662 if (insn->arg[0].r == insn->arg[1].r)
1663 as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
1664 insn->arg[0].r);
1665 }
9bb1ebc2 1666
023d1155
TL
1667 /* Some instruction assume the stack pointer as rptr operand.
1668 Issue an error when the register to be loaded is also SP. */
1669 if (instruction->flags & NO_SP)
1670 {
1671 if (getreg_image (insn->arg[0].r) == getreg_image (sp))
1672 as_bad (_("`%s' has undefined result"), ins_parse);
1673 }
1fe1f39c 1674
023d1155
TL
1675 /* If the rptr register is specified as one of the registers to be loaded,
1676 the final contents of rptr are undefined. Thus, we issue an error. */
1677 if (instruction->flags & NO_RPTR)
1678 {
1679 if ((1 << getreg_image (insn->arg[0].r)) & insn->arg[1].constant)
1680 as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
1681 getreg_image (insn->arg[0].r));
1682 }
1683}
1fe1f39c 1684
023d1155
TL
1685/* In some cases, we need to adjust the instruction pointer although a
1686 match was already found. Here, we gather all these cases.
1687 Returns 1 if instruction pointer was adjusted, otherwise 0. */
1fe1f39c 1688
023d1155
TL
1689int
1690adjust_if_needed (ins *insn)
1691{
1692 int ret_value = 0;
1693
1694 /* Special check for 'addub $0, r0' instruction -
1695 The opcode '0000 0000 0000 0000' is not allowed. */
1696 if (IS_INSN_MNEMONIC ("addub"))
1697 {
1698 if ((instruction->operands[0].op_type == cst4)
1699 && instruction->operands[1].op_type == regr)
1fe1f39c 1700 {
023d1155
TL
1701 if (insn->arg[0].constant == 0 && insn->arg[1].r == r0)
1702 {
1703 instruction++;
1704 ret_value = 1;
1705 }
1fe1f39c
NC
1706 }
1707 }
1708
023d1155
TL
1709 /* Optimization: Omit a zero displacement in bit operations,
1710 saving 2-byte encoding space (e.g., 'cbitw $8, 0(r1)'). */
1711 if (IS_INSN_TYPE (CSTBIT_INS))
1712 {
1713 if ((instruction->operands[1].op_type == rbase_disps12)
1714 && (insn->arg[1].X_op == O_constant)
1715 && (insn->arg[1].constant == 0))
1716 {
1717 instruction--;
1718 ret_value = 1;
1719 }
1720 }
1721
1722 return ret_value;
1fe1f39c
NC
1723}
1724
1725/* Set the appropriate bit for register 'r' in 'mask'.
1726 This indicates that this register is loaded or stored by
1727 the instruction. */
1728
1729static void
1730mask_reg (int r, unsigned short int *mask)
1731{
1732 if ((reg)r > (reg)sp)
1733 {
1734 as_bad (_("Invalid Register in Register List"));
1735 return;
1736 }
1737
1738 *mask |= (1 << r);
1739}
1740
1741/* Preprocess register list - create a 16-bit mask with one bit for each
1742 of the 16 general purpose registers. If a bit is set, it indicates
1743 that this register is loaded or stored by the instruction. */
1744
1745static char *
1746preprocess_reglist (char *param, int *allocated)
1747{
1748 char reg_name[MAX_REGNAME_LEN]; /* Current parsed register name. */
1749 char *regP; /* Pointer to 'reg_name' string. */
1750 int reg_counter = 0; /* Count number of parsed registers. */
1751 unsigned short int mask = 0; /* Mask for 16 general purpose registers. */
1752 char *new_param; /* New created operands string. */
1753 char *paramP = param; /* Pointer to original opearands string. */
1754 char maskstring[10]; /* Array to print the mask as a string. */
9bb1ebc2 1755 int hi_found = 0, lo_found = 0; /* Boolean flags for hi/lo registers. */
1fe1f39c
NC
1756 reg r;
1757 copreg cr;
1758
1759 /* If 'param' is already in form of a number, no need to preprocess. */
1760 if (strchr (paramP, '{') == NULL)
1761 return param;
1762
1763 /* Verifying correct syntax of operand. */
1764 if (strchr (paramP, '}') == NULL)
1765 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1766
1767 while (*paramP++ != '{');
1768
1769 new_param = (char *)xcalloc (MAX_INST_LEN, sizeof (char));
1770 *allocated = 1;
1771 strncpy (new_param, param, paramP - param - 1);
1772
1773 while (*paramP != '}')
1774 {
1775 regP = paramP;
1776 memset (&reg_name, '\0', sizeof (reg_name));
1777
1778 while (ISALNUM (*paramP))
1779 paramP++;
1780
1781 strncpy (reg_name, regP, paramP - regP);
1782
48c9f030 1783 /* Coprocessor register c<N>. */
1fe1f39c
NC
1784 if (IS_INSN_TYPE (COP_REG_INS))
1785 {
9bb1ebc2
TL
1786 if (((cr = get_copregister (reg_name)) == nullcopregister)
1787 || (crx_copregtab[cr-MAX_REG].type != CRX_C_REGTYPE))
1788 as_fatal (_("Illegal register `%s' in cop-register list"), reg_name);
1fe1f39c
NC
1789 mask_reg (getreg_image (cr - c0), &mask);
1790 }
48c9f030
NC
1791 /* Coprocessor Special register cs<N>. */
1792 else if (IS_INSN_TYPE (COPS_REG_INS))
1793 {
9bb1ebc2
TL
1794 if (((cr = get_copregister (reg_name)) == nullcopregister)
1795 || (crx_copregtab[cr-MAX_REG].type != CRX_CS_REGTYPE))
1796 as_fatal (_("Illegal register `%s' in cop-special-register list"),
48c9f030
NC
1797 reg_name);
1798 mask_reg (getreg_image (cr - cs0), &mask);
1799 }
9bb1ebc2
TL
1800 /* User register u<N>. */
1801 else if (instruction->flags & USER_REG)
1802 {
1803 if (streq(reg_name, "uhi"))
1804 {
1805 hi_found = 1;
1806 goto next_inst;
1807 }
1808 else if (streq(reg_name, "ulo"))
1809 {
1810 lo_found = 1;
1811 goto next_inst;
1812 }
1813 else if (((r = get_register (reg_name)) == nullregister)
1814 || (crx_regtab[r].type != CRX_U_REGTYPE))
1815 as_fatal (_("Illegal register `%s' in user register list"), reg_name);
1816
1817 mask_reg (getreg_image (r - u0), &mask);
1818 }
48c9f030 1819 /* General purpose register r<N>. */
1fe1f39c
NC
1820 else
1821 {
9bb1ebc2
TL
1822 if (streq(reg_name, "hi"))
1823 {
1824 hi_found = 1;
1825 goto next_inst;
1826 }
1827 else if (streq(reg_name, "lo"))
1828 {
1829 lo_found = 1;
1830 goto next_inst;
1831 }
1832 else if (((r = get_register (reg_name)) == nullregister)
1833 || (crx_regtab[r].type != CRX_R_REGTYPE))
1834 as_fatal (_("Illegal register `%s' in register list"), reg_name);
1835
1836 mask_reg (getreg_image (r - r0), &mask);
1fe1f39c
NC
1837 }
1838
1839 if (++reg_counter > MAX_REGS_IN_MASK16)
1840 as_bad (_("Maximum %d bits may be set in `mask16' operand"),
1841 MAX_REGS_IN_MASK16);
1842
9bb1ebc2 1843next_inst:
1fe1f39c
NC
1844 while (!ISALNUM (*paramP) && *paramP != '}')
1845 paramP++;
1846 }
1847
1848 if (*++paramP != '\0')
1849 as_warn (_("rest of line ignored; first ignored character is `%c'"),
1850 *paramP);
1851
9bb1ebc2
TL
1852 switch (hi_found + lo_found)
1853 {
1854 case 0:
1855 /* At least one register should be specified. */
1856 if (mask == 0)
1857 as_bad (_("Illegal `mask16' operand, operation is undefined - `%s'"),
1858 ins_parse);
1859 break;
1860
1861 case 1:
1862 /* HI can't be specified without LO (and vise-versa). */
1863 as_bad (_("HI/LO registers should be specified together"));
1864 break;
1865
1866 case 2:
1867 /* HI/LO registers mustn't be masked with additional registers. */
1868 if (mask != 0)
1869 as_bad (_("HI/LO registers should be specified without additional registers"));
1870
1871 default:
1872 break;
1873 }
1fe1f39c
NC
1874
1875 sprintf (maskstring, "$0x%x", mask);
1876 strcat (new_param, maskstring);
1877 return new_param;
1878}
1879
1880/* Print the instruction.
1881 Handle also cases where the instruction is relaxable/relocatable. */
1882
1883void
1884print_insn (ins *insn)
1885{
1886 unsigned int i, j, insn_size;
1887 char *this_frag;
1888 unsigned short words[4];
aea44f62 1889 int addr_mod;
1fe1f39c
NC
1890
1891 /* Arrange the insn encodings in a WORD size array. */
1892 for (i = 0, j = 0; i < 2; i++)
1893 {
1894 words[j++] = (output_opcode[i] >> 16) & 0xFFFF;
1895 words[j++] = output_opcode[i] & 0xFFFF;
1896 }
1897
1898 /* Handle relaxtion. */
1899 if ((instruction->flags & RELAXABLE) && relocatable)
1900 {
1901 int relax_subtype;
1902
1903 /* Write the maximal instruction size supported. */
1904 insn_size = INSN_MAX_SIZE;
1905
1906 /* bCC */
1907 if (IS_INSN_TYPE (BRANCH_INS))
1908 relax_subtype = 0;
1909 /* bal */
1910 else if (IS_INSN_TYPE (DCR_BRANCH_INS) || IS_INSN_MNEMONIC ("bal"))
1911 relax_subtype = 3;
30c62922
TL
1912 /* cmpbr/bcop */
1913 else if (IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
1fe1f39c
NC
1914 relax_subtype = 5;
1915 else
1916 abort ();
1917
1918 this_frag = frag_var (rs_machine_dependent, insn_size * 2,
1919 4, relax_subtype,
1920 insn->exp.X_add_symbol,
1921 insn->exp.X_add_number,
1922 0);
1923 }
1924 else
1925 {
1926 insn_size = instruction->size;
1927 this_frag = frag_more (insn_size * 2);
1928
1929 /* Handle relocation. */
1930 if ((relocatable) && (insn->rtype != BFD_RELOC_NONE))
1931 {
1932 reloc_howto_type *reloc_howto;
1933 int size;
1934
1935 reloc_howto = bfd_reloc_type_lookup (stdoutput, insn->rtype);
1936
1937 if (!reloc_howto)
1938 abort ();
1939
1940 size = bfd_get_reloc_size (reloc_howto);
1941
1942 if (size < 1 || size > 4)
1943 abort ();
1944
1945 fix_new_exp (frag_now, this_frag - frag_now->fr_literal,
1946 size, &insn->exp, reloc_howto->pc_relative,
1947 insn->rtype);
1948 }
1949 }
1950
aea44f62
TL
1951 /* Verify a 2-byte code alignment. */
1952 addr_mod = frag_now_fix () & 1;
1953 if (frag_now->has_code && frag_now->insn_addr != addr_mod)
1954 as_bad (_("instruction address is not a multiple of 2"));
1955 frag_now->insn_addr = addr_mod;
1956 frag_now->has_code = 1;
1957
1fe1f39c
NC
1958 /* Write the instruction encoding to frag. */
1959 for (i = 0; i < insn_size; i++)
1960 {
1961 md_number_to_chars (this_frag, (valueT) words[i], 2);
1962 this_frag += 2;
1963 }
1964}
1965
1966/* This is the guts of the machine-dependent assembler. OP points to a
1967 machine dependent instruction. This function is supposed to emit
1968 the frags/bytes it assembles to. */
1969
1970void
1971md_assemble (char *op)
1972{
1973 ins crx_ins;
1974 char *param;
1975 char c;
1976
1977 /* Reset global variables for a new instruction. */
023d1155 1978 reset_vars (op);
1fe1f39c
NC
1979
1980 /* Strip the mnemonic. */
1981 for (param = op; *param != 0 && !ISSPACE (*param); param++)
1982 ;
1983 c = *param;
1984 *param++ = '\0';
1985
1986 /* Find the instruction. */
1987 instruction = (const inst *) hash_find (crx_inst_hash, op);
1988 if (instruction == NULL)
1989 {
1990 as_bad (_("Unknown opcode: `%s'"), op);
87975d2a 1991 param[-1] = c;
1fe1f39c
NC
1992 return;
1993 }
1994
1995 /* Tie dwarf2 debug info to the address at the start of the insn. */
1996 dwarf2_emit_insn (0);
1997
023d1155
TL
1998 /* Parse the instruction's operands. */
1999 parse_insn (&crx_ins, param);
1fe1f39c 2000
023d1155 2001 /* Assemble the instruction - return upon failure. */
1fe1f39c 2002 if (assemble_insn (op, &crx_ins) == 0)
87975d2a
AM
2003 {
2004 param[-1] = c;
2005 return;
2006 }
1fe1f39c
NC
2007
2008 /* Print the instruction. */
87975d2a 2009 param[-1] = c;
1fe1f39c
NC
2010 print_insn (&crx_ins);
2011}
This page took 0.676582 seconds and 4 git commands to generate.