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