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