opcodes/
[deliverable/binutils-gdb.git] / gas / config / tc-crx.c
CommitLineData
1fe1f39c 1/* tc-crx.c -- Assembler code for the CRX CPU core.
ec2655a6 2 Copyright 2004, 2007 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{
208 const reg_entry *reg;
209
210 reg = (const reg_entry *) hash_find (reg_hash, reg_name);
211
212 if (reg != NULL)
213 return reg->value.reg_val;
214 else
215 return nullregister;
216}
217
218/* Get the coprocessor register 'copreg_name'. */
219
220static copreg
221get_copregister (char *copreg_name)
222{
223 const reg_entry *copreg;
224
225 copreg = (const reg_entry *) hash_find (copreg_hash, copreg_name);
226
227 if (copreg != NULL)
228 return copreg->value.copreg_val;
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
NC
353
354 assert ((int) fixP->fx_r_type > 0);
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 }
365 assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
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
466/* Turn a string in input_line_pointer into a floating point constant
467 of type TYPE, and store the appropriate bytes in *LITP. The number
468 of LITTLENUMS emitted is stored in *SIZEP. An error message is
469 returned, or NULL on OK. */
470
471char *
472md_atof (int type, char *litP, int *sizeP)
473{
474 int prec;
475 LITTLENUM_TYPE words[4];
476 char *t;
477 int i;
478
479 switch (type)
480 {
481 case 'f':
482 prec = 2;
483 break;
484
485 case 'd':
486 prec = 4;
487 break;
488
489 default:
490 *sizeP = 0;
491 return _("bad call to md_atof");
492 }
493
494 t = atof_ieee (input_line_pointer, type, words);
495 if (t)
496 input_line_pointer = t;
497
498 *sizeP = prec * 2;
499
500 if (! target_big_endian)
501 {
502 for (i = prec - 1; i >= 0; i--)
503 {
504 md_number_to_chars (litP, (valueT) words[i], 2);
505 litP += 2;
506 }
507 }
508 else
509 {
510 for (i = 0; i < prec; i++)
511 {
512 md_number_to_chars (litP, (valueT) words[i], 2);
513 litP += 2;
514 }
515 }
516
517 return NULL;
518}
519
520/* Apply a fixS (fixup of an instruction or data that we didn't have
521 enough info to complete immediately) to the data in a frag.
522 Since linkrelax is nonzero and TC_LINKRELAX_FIXUP is defined to disable
523 relaxation of debug sections, this function is called only when
524 fixuping relocations of debug sections. */
525
526void
55cf6793 527md_apply_fix (fixS *fixP, valueT *valP, segT seg)
1fe1f39c
NC
528{
529 valueT val = * valP;
530 char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
531 fixP->fx_offset = 0;
532
533 switch (fixP->fx_r_type)
534 {
535 case BFD_RELOC_CRX_NUM8:
536 bfd_put_8 (stdoutput, (unsigned char) val, buf);
537 break;
538 case BFD_RELOC_CRX_NUM16:
539 bfd_put_16 (stdoutput, val, buf);
540 break;
541 case BFD_RELOC_CRX_NUM32:
542 bfd_put_32 (stdoutput, val, buf);
543 break;
544 default:
545 /* We shouldn't ever get here because linkrelax is nonzero. */
546 abort ();
547 break;
548 }
549
550 fixP->fx_done = 0;
551
552 if (fixP->fx_addsy == NULL
553 && fixP->fx_pcrel == 0)
554 fixP->fx_done = 1;
555
556 if (fixP->fx_pcrel == 1
557 && fixP->fx_addsy != NULL
558 && S_GET_SEGMENT (fixP->fx_addsy) == seg)
559 fixP->fx_done = 1;
560}
561
562/* The location from which a PC relative jump should be calculated,
563 given a PC relative reloc. */
564
565long
566md_pcrel_from (fixS *fixp)
567{
568 return fixp->fx_frag->fr_address + fixp->fx_where;
569}
570
571/* This function is called once, at assembler startup time. This should
572 set up all the tables, etc that the MD part of the assembler needs. */
573
574void
575md_begin (void)
576{
577 const char *hashret = NULL;
578 int i = 0;
579
580 /* Set up a hash table for the instructions. */
9bb1ebc2 581 if ((crx_inst_hash = hash_new ()) == NULL)
1fe1f39c 582 as_fatal (_("Virtual memory exhausted"));
9bb1ebc2 583
1fe1f39c
NC
584 while (crx_instruction[i].mnemonic != NULL)
585 {
586 const char *mnemonic = crx_instruction[i].mnemonic;
587
588 hashret = hash_insert (crx_inst_hash, mnemonic,
589 (PTR) &crx_instruction[i]);
590
591 if (hashret != NULL && *hashret != '\0')
592 as_fatal (_("Can't hash `%s': %s\n"), crx_instruction[i].mnemonic,
593 *hashret == 0 ? _("(unknown reason)") : hashret);
594
595 /* Insert unique names into hash table. The CRX instruction set
596 has many identical opcode names that have different opcodes based
597 on the operands. This hash table then provides a quick index to
598 the first opcode with a particular name in the opcode table. */
599 do
600 {
601 ++i;
602 }
603 while (crx_instruction[i].mnemonic != NULL
604 && streq (crx_instruction[i].mnemonic, mnemonic));
605 }
606
607 /* Initialize reg_hash hash table. */
9bb1ebc2
TL
608 if ((reg_hash = hash_new ()) == NULL)
609 as_fatal (_("Virtual memory exhausted"));
1fe1f39c
NC
610
611 {
612 const reg_entry *regtab;
613
614 for (regtab = crx_regtab;
615 regtab < (crx_regtab + NUMREGS); regtab++)
616 {
617 hashret = hash_insert (reg_hash, regtab->name, (PTR) regtab);
618 if (hashret)
619 as_fatal (_("Internal Error: Can't hash %s: %s"),
620 regtab->name,
621 hashret);
622 }
623 }
624
625 /* Initialize copreg_hash hash table. */
9bb1ebc2
TL
626 if ((copreg_hash = hash_new ()) == NULL)
627 as_fatal (_("Virtual memory exhausted"));
1fe1f39c
NC
628
629 {
630 const reg_entry *copregtab;
631
632 for (copregtab = crx_copregtab; copregtab < (crx_copregtab + NUMCOPREGS);
633 copregtab++)
634 {
635 hashret = hash_insert (copreg_hash, copregtab->name, (PTR) copregtab);
636 if (hashret)
637 as_fatal (_("Internal Error: Can't hash %s: %s"),
638 copregtab->name,
639 hashret);
640 }
641 }
642 /* Set linkrelax here to avoid fixups in most sections. */
643 linkrelax = 1;
644}
645
023d1155
TL
646/* Process constants (immediate/absolute)
647 and labels (jump targets/Memory locations). */
1fe1f39c
NC
648
649static void
82d6ee2a 650process_label_constant (char *str, ins * crx_ins)
1fe1f39c 651{
023d1155 652 char *saved_input_line_pointer;
82d6ee2a
TL
653 argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument. */
654
023d1155 655 saved_input_line_pointer = input_line_pointer;
1fe1f39c
NC
656 input_line_pointer = str;
657
658 expression (&crx_ins->exp);
023d1155 659
1fe1f39c
NC
660 switch (crx_ins->exp.X_op)
661 {
42851540
NC
662 case O_big:
663 case O_absent:
664 /* Missing or bad expr becomes absolute 0. */
665 as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
666 str);
667 crx_ins->exp.X_op = O_constant;
668 crx_ins->exp.X_add_number = 0;
669 crx_ins->exp.X_add_symbol = (symbolS *) 0;
670 crx_ins->exp.X_op_symbol = (symbolS *) 0;
023d1155 671 /* Fall through. */
42851540 672
1fe1f39c 673 case O_constant:
023d1155
TL
674 cur_arg->X_op = O_constant;
675 cur_arg->constant = crx_ins->exp.X_add_number;
1fe1f39c
NC
676 break;
677
678 case O_symbol:
679 case O_subtract:
023d1155
TL
680 case O_add:
681 cur_arg->X_op = O_symbol;
42851540 682 crx_ins->rtype = BFD_RELOC_NONE;
1fe1f39c
NC
683 relocatable = 1;
684
82d6ee2a 685 switch (cur_arg->type)
1fe1f39c
NC
686 {
687 case arg_cr:
1fe1f39c
NC
688 if (IS_INSN_TYPE (LD_STOR_INS_INC))
689 crx_ins->rtype = BFD_RELOC_CRX_REGREL12;
690 else if (IS_INSN_TYPE (CSTBIT_INS)
691 || IS_INSN_TYPE (STOR_IMM_INS))
1fe1f39c
NC
692 crx_ins->rtype = BFD_RELOC_CRX_REGREL28;
693 else
1fe1f39c 694 crx_ins->rtype = BFD_RELOC_CRX_REGREL32;
023d1155
TL
695 break;
696
82d6ee2a 697 case arg_idxr:
1fe1f39c
NC
698 crx_ins->rtype = BFD_RELOC_CRX_REGREL22;
699 break;
023d1155 700
1fe1f39c 701 case arg_c:
1fe1f39c
NC
702 if (IS_INSN_MNEMONIC ("bal") || IS_INSN_TYPE (DCR_BRANCH_INS))
703 crx_ins->rtype = BFD_RELOC_CRX_REL16;
704 else if (IS_INSN_TYPE (BRANCH_INS))
9bb1ebc2 705 crx_ins->rtype = BFD_RELOC_CRX_REL8;
1fe1f39c
NC
706 else if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (STOR_IMM_INS)
707 || IS_INSN_TYPE (CSTBIT_INS))
708 crx_ins->rtype = BFD_RELOC_CRX_ABS32;
709 else if (IS_INSN_TYPE (BRANCH_NEQ_INS))
710 crx_ins->rtype = BFD_RELOC_CRX_REL4;
30c62922 711 else if (IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
9bb1ebc2 712 crx_ins->rtype = BFD_RELOC_CRX_REL8_CMP;
1fe1f39c 713 break;
023d1155 714
1fe1f39c 715 case arg_ic:
1fe1f39c
NC
716 if (IS_INSN_TYPE (ARITH_INS))
717 crx_ins->rtype = BFD_RELOC_CRX_IMM32;
718 else if (IS_INSN_TYPE (ARITH_BYTE_INS))
719 crx_ins->rtype = BFD_RELOC_CRX_IMM16;
720 break;
721 default:
722 break;
723 }
1fe1f39c
NC
724 break;
725
726 default:
023d1155 727 cur_arg->X_op = crx_ins->exp.X_op;
1fe1f39c
NC
728 break;
729 }
730
023d1155
TL
731 input_line_pointer = saved_input_line_pointer;
732 return;
1fe1f39c
NC
733}
734
735/* Get the values of the scale to be encoded -
736 used for the scaled index mode of addressing. */
737
738static int
739exponent2scale (int val)
740{
741 int exponent;
742
743 /* If 'val' is 0, the following 'for' will be an endless loop. */
744 if (val == 0)
745 return 0;
746
747 for (exponent = 0; (val != 1); val >>= 1, exponent++)
748 ;
749
750 return exponent;
751}
752
82d6ee2a
TL
753/* Parsing different types of operands
754 -> constants Immediate/Absolute/Relative numbers
755 -> Labels Relocatable symbols
756 -> (rbase) Register base
757 -> disp(rbase) Register relative
758 -> disp(rbase)+ Post-increment mode
759 -> disp(rbase,ridx,scl) Register index mode */
1fe1f39c
NC
760
761static void
82d6ee2a 762set_operand (char *operand, ins * crx_ins)
1fe1f39c 763{
82d6ee2a
TL
764 char *operandS; /* Pointer to start of sub-opearand. */
765 char *operandE; /* Pointer to end of sub-opearand. */
766 expressionS scale;
767 int scale_val;
768 char *input_save, c;
769 argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument. */
1fe1f39c 770
82d6ee2a
TL
771 /* Initialize pointers. */
772 operandS = operandE = operand;
773
774 switch (cur_arg->type)
1fe1f39c 775 {
82d6ee2a
TL
776 case arg_sc: /* Case *+0x18. */
777 case arg_ic: /* Case $0x18. */
778 operandS++;
779 case arg_c: /* Case 0x18. */
780 /* Set constant. */
aea44f62 781 process_label_constant (operandS, crx_ins);
82d6ee2a
TL
782
783 if (cur_arg->type != arg_ic)
784 cur_arg->type = arg_c;
785 break;
786
787 case arg_icr: /* Case $0x18(r1). */
788 operandS++;
789 case arg_cr: /* Case 0x18(r1). */
790 /* Set displacement constant. */
791 while (*operandE != '(')
792 operandE++;
793 *operandE = '\0';
aea44f62 794 process_label_constant (operandS, crx_ins);
82d6ee2a
TL
795 operandS = operandE;
796 case arg_rbase: /* Case (r1). */
797 operandS++;
798 /* Set register base. */
799 while (*operandE != ')')
800 operandE++;
801 *operandE = '\0';
802 if ((cur_arg->r = get_register (operandS)) == nullregister)
1fe1f39c 803 as_bad (_("Illegal register `%s' in Instruction `%s'"),
82d6ee2a 804 operandS, ins_parse);
1fe1f39c 805
82d6ee2a
TL
806 if (cur_arg->type != arg_rbase)
807 cur_arg->type = arg_cr;
808 break;
1fe1f39c 809
82d6ee2a
TL
810 case arg_idxr:
811 /* Set displacement constant. */
812 while (*operandE != '(')
813 operandE++;
814 *operandE = '\0';
815 process_label_constant (operandS, crx_ins);
816 operandS = ++operandE;
817
818 /* Set register base. */
819 while ((*operandE != ',') && (! ISSPACE (*operandE)))
820 operandE++;
821 *operandE++ = '\0';
822 if ((cur_arg->r = get_register (operandS)) == nullregister)
1fe1f39c 823 as_bad (_("Illegal register `%s' in Instruction `%s'"),
82d6ee2a
TL
824 operandS, ins_parse);
825
826 /* Skip leading white space. */
827 while (ISSPACE (*operandE))
828 operandE++;
829 operandS = operandE;
1fe1f39c 830
82d6ee2a
TL
831 /* Set register index. */
832 while ((*operandE != ')') && (*operandE != ','))
833 operandE++;
834 c = *operandE;
835 *operandE++ = '\0';
1fe1f39c 836
82d6ee2a
TL
837 if ((cur_arg->i_r = get_register (operandS)) == nullregister)
838 as_bad (_("Illegal register `%s' in Instruction `%s'"),
839 operandS, ins_parse);
840
841 /* Skip leading white space. */
842 while (ISSPACE (*operandE))
843 operandE++;
844 operandS = operandE;
845
846 /* Set the scale. */
847 if (c == ')')
848 cur_arg->scale = 0;
1fe1f39c
NC
849 else
850 {
82d6ee2a
TL
851 while (*operandE != ')')
852 operandE++;
853 *operandE = '\0';
1fe1f39c 854
82d6ee2a
TL
855 /* Preprocess the scale string. */
856 input_save = input_line_pointer;
857 input_line_pointer = operandS;
858 expression (&scale);
859 input_line_pointer = input_save;
1fe1f39c 860
82d6ee2a 861 scale_val = scale.X_add_number;
1fe1f39c 862
82d6ee2a
TL
863 /* Check if the scale value is legal. */
864 if (scale_val != 1 && scale_val != 2
865 && scale_val != 4 && scale_val != 8)
866 as_bad (_("Illegal Scale - `%d'"), scale_val);
1fe1f39c 867
82d6ee2a 868 cur_arg->scale = exponent2scale (scale_val);
1fe1f39c
NC
869 }
870 break;
82d6ee2a 871
1fe1f39c
NC
872 default:
873 break;
874 }
875}
876
82d6ee2a
TL
877/* Parse a single operand.
878 operand - Current operand to parse.
879 crx_ins - Current assembled instruction. */
1fe1f39c
NC
880
881static void
82d6ee2a 882parse_operand (char *operand, ins * crx_ins)
1fe1f39c 883{
82d6ee2a
TL
884 int ret_val;
885 argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument. */
1fe1f39c 886
82d6ee2a
TL
887 /* Initialize the type to NULL before parsing. */
888 cur_arg->type = nullargs;
1fe1f39c 889
82d6ee2a
TL
890 /* Check whether this is a general processor register. */
891 if ((ret_val = get_register (operand)) != nullregister)
1fe1f39c 892 {
82d6ee2a
TL
893 cur_arg->type = arg_r;
894 cur_arg->r = ret_val;
023d1155
TL
895 cur_arg->X_op = O_register;
896 return;
1fe1f39c 897 }
1fe1f39c 898
82d6ee2a
TL
899 /* Check whether this is a core [special] coprocessor register. */
900 if ((ret_val = get_copregister (operand)) != nullcopregister)
901 {
902 cur_arg->type = arg_copr;
903 if (ret_val >= cs0)
904 cur_arg->type = arg_copsr;
905 cur_arg->cr = ret_val;
023d1155
TL
906 cur_arg->X_op = O_register;
907 return;
82d6ee2a 908 }
1fe1f39c 909
82d6ee2a 910 /* Deal with special characters. */
1fe1f39c
NC
911 switch (operand[0])
912 {
1fe1f39c
NC
913 case '$':
914 if (strchr (operand, '(') != NULL)
82d6ee2a 915 cur_arg->type = arg_icr;
1fe1f39c 916 else
82d6ee2a
TL
917 cur_arg->type = arg_ic;
918 goto set_params;
1fe1f39c
NC
919 break;
920
1fe1f39c 921 case '*':
82d6ee2a
TL
922 cur_arg->type = arg_sc;
923 goto set_params;
1fe1f39c 924 break;
82d6ee2a
TL
925
926 case '(':
927 cur_arg->type = arg_rbase;
928 goto set_params;
1fe1f39c 929 break;
82d6ee2a 930
1fe1f39c 931 default:
82d6ee2a
TL
932 break;
933 }
934
935 if (strchr (operand, '(') != NULL)
936 {
937 if (strchr (operand, ',') != NULL
938 && (strchr (operand, ',') > strchr (operand, '(')))
939 cur_arg->type = arg_idxr;
1fe1f39c 940 else
82d6ee2a
TL
941 cur_arg->type = arg_cr;
942 }
943 else
944 cur_arg->type = arg_c;
945 goto set_params;
946
947/* Parse an operand according to its type. */
948set_params:
949 cur_arg->constant = 0;
950 set_operand (operand, crx_ins);
1fe1f39c
NC
951}
952
82d6ee2a
TL
953/* Parse the various operands. Each operand is then analyzed to fillup
954 the fields in the crx_ins data structure. */
1fe1f39c
NC
955
956static void
957parse_operands (ins * crx_ins, char *operands)
958{
959 char *operandS; /* Operands string. */
960 char *operandH, *operandT; /* Single operand head/tail pointers. */
961 int allocated = 0; /* Indicates a new operands string was allocated. */
962 char *operand[MAX_OPERANDS]; /* Separating the operands. */
963 int op_num = 0; /* Current operand number we are parsing. */
964 int bracket_flag = 0; /* Indicates a bracket '(' was found. */
965 int sq_bracket_flag = 0; /* Indicates a square bracket '[' was found. */
966
967 /* Preprocess the list of registers, if necessary. */
968 operandS = operandH = operandT = (INST_HAS_REG_LIST) ?
969 preprocess_reglist (operands, &allocated) : operands;
970
971 while (*operandT != '\0')
972 {
973 if (*operandT == ',' && bracket_flag != 1 && sq_bracket_flag != 1)
974 {
975 *operandT++ = '\0';
976 operand[op_num++] = strdup (operandH);
977 operandH = operandT;
978 continue;
979 }
980
981 if (*operandT == ' ')
982 as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse);
983
984 if (*operandT == '(')
985 bracket_flag = 1;
986 else if (*operandT == '[')
987 sq_bracket_flag = 1;
988
989 if (*operandT == ')')
990 {
991 if (bracket_flag)
992 bracket_flag = 0;
993 else
994 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
995 }
996 else if (*operandT == ']')
997 {
998 if (sq_bracket_flag)
999 sq_bracket_flag = 0;
1000 else
1001 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1002 }
1003
1004 if (bracket_flag == 1 && *operandT == ')')
1005 bracket_flag = 0;
1006 else if (sq_bracket_flag == 1 && *operandT == ']')
1007 sq_bracket_flag = 0;
1008
1009 operandT++;
1010 }
1011
1012 /* Adding the last operand. */
1013 operand[op_num++] = strdup (operandH);
1014 crx_ins->nargs = op_num;
1015
1016 /* Verifying correct syntax of operands (all brackets should be closed). */
1017 if (bracket_flag || sq_bracket_flag)
1018 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1019
82d6ee2a 1020 /* Now we parse each operand separately. */
1fe1f39c
NC
1021 for (op_num = 0; op_num < crx_ins->nargs; op_num++)
1022 {
82d6ee2a
TL
1023 cur_arg_num = op_num;
1024 parse_operand (operand[op_num], crx_ins);
1fe1f39c
NC
1025 free (operand[op_num]);
1026 }
1027
1028 if (allocated)
1029 free (operandS);
1030}
1031
1032/* Get the trap index in dispatch table, given its name.
1033 This routine is used by assembling the 'excp' instruction. */
1034
1035static int
1036gettrap (char *s)
1037{
1038 const trap_entry *trap;
1039
1040 for (trap = crx_traps; trap < (crx_traps + NUMTRAPS); trap++)
42851540 1041 if (strcasecmp (trap->name, s) == 0)
1fe1f39c
NC
1042 return trap->entry;
1043
1044 as_bad (_("Unknown exception: `%s'"), s);
1045 return 0;
1046}
1047
64995a6b
TL
1048/* Post-Increment instructions, as well as Store-Immediate instructions, are a
1049 sub-group within load/stor instruction groups.
1050 Therefore, when parsing a Post-Increment/Store-Immediate insn, we have to
1051 advance the instruction pointer to the start of that sub-group (that is, up
1052 to the first instruction of that type).
1053 Otherwise, the insn will be mistakenly identified as of type LD_STOR_INS. */
1fe1f39c
NC
1054
1055static void
64995a6b 1056handle_LoadStor (char *operands)
1fe1f39c 1057{
9bb1ebc2
TL
1058 /* Post-Increment instructions precede Store-Immediate instructions in
1059 CRX instruction table, hence they are handled before.
1060 This synchronization should be kept. */
64995a6b 1061
1fe1f39c 1062 /* Assuming Post-Increment insn has the following format :
64995a6b
TL
1063 'MNEMONIC DISP(REG)+, REG' (e.g. 'loadw 12(r5)+, r6').
1064 LD_STOR_INS_INC are the only store insns containing a plus sign (+). */
1fe1f39c 1065 if (strstr (operands, ")+") != NULL)
9bb1ebc2
TL
1066 {
1067 while (! IS_INSN_TYPE (LD_STOR_INS_INC))
1068 instruction++;
1069 return;
1070 }
1071
1072 /* Assuming Store-Immediate insn has the following format :
1073 'MNEMONIC $DISP, ...' (e.g. 'storb $1, 12(r5)').
1074 STOR_IMM_INS are the only store insns containing a dollar sign ($). */
1075 if (strstr (operands, "$") != NULL)
1076 while (! IS_INSN_TYPE (STOR_IMM_INS))
1fe1f39c
NC
1077 instruction++;
1078}
1079
1080/* Top level module where instruction parsing starts.
1081 crx_ins - data structure holds some information.
1082 operands - holds the operands part of the whole instruction. */
1083
1084static void
1085parse_insn (ins *insn, char *operands)
1086{
023d1155
TL
1087 int i;
1088
1089 /* Handle instructions with no operands. */
1090 for (i = 0; no_op_insn[i] != NULL; i++)
1091 {
1092 if (streq (no_op_insn[i], instruction->mnemonic))
1093 {
1094 insn->nargs = 0;
1095 return;
1096 }
1097 }
1098
1099 /* Handle 'excp'/'cinv' instructions. */
1fe1f39c
NC
1100 if (IS_INSN_MNEMONIC ("excp") || IS_INSN_MNEMONIC ("cinv"))
1101 {
1102 insn->nargs = 1;
1103 insn->arg[0].type = arg_ic;
1fe1f39c
NC
1104 insn->arg[0].constant = IS_INSN_MNEMONIC ("excp") ?
1105 gettrap (operands) : get_cinv_parameters (operands);
023d1155 1106 insn->arg[0].X_op = O_constant;
1fe1f39c
NC
1107 return;
1108 }
1109
e3c52c53 1110 /* Handle load/stor unique instructions before parsing. */
64995a6b
TL
1111 if (IS_INSN_TYPE (LD_STOR_INS))
1112 handle_LoadStor (operands);
1fe1f39c
NC
1113
1114 if (operands != NULL)
1115 parse_operands (insn, operands);
1116}
1117
1118/* Cinv instruction requires special handling. */
1119
1120static int
1121get_cinv_parameters (char * operand)
1122{
1123 char *p = operand;
48c9f030 1124 int d_used = 0, i_used = 0, u_used = 0, b_used = 0;
1fe1f39c
NC
1125
1126 while (*++p != ']')
1127 {
1128 if (*p == ',' || *p == ' ')
1129 continue;
1130
1131 if (*p == 'd')
1132 d_used = 1;
1133 else if (*p == 'i')
1134 i_used = 1;
1135 else if (*p == 'u')
1136 u_used = 1;
48c9f030
NC
1137 else if (*p == 'b')
1138 b_used = 1;
1fe1f39c
NC
1139 else
1140 as_bad (_("Illegal `cinv' parameter: `%c'"), *p);
1141 }
1142
48c9f030
NC
1143 return ((b_used ? 8 : 0)
1144 + (d_used ? 4 : 0)
1fe1f39c
NC
1145 + (i_used ? 2 : 0)
1146 + (u_used ? 1 : 0));
1147}
1148
1149/* Retrieve the opcode image of a given register.
1150 If the register is illegal for the current instruction,
1151 issue an error. */
1152
1153static int
1154getreg_image (reg r)
1155{
1156 const reg_entry *reg;
1157 char *reg_name;
9bb1ebc2 1158 int is_procreg = 0; /* Nonzero means argument should be processor reg. */
1fe1f39c 1159
82d6ee2a
TL
1160 if (((IS_INSN_MNEMONIC ("mtpr")) && (cur_arg_num == 1))
1161 || ((IS_INSN_MNEMONIC ("mfpr")) && (cur_arg_num == 0)) )
9bb1ebc2 1162 is_procreg = 1;
1fe1f39c
NC
1163
1164 /* Check whether the register is in registers table. */
1165 if (r < MAX_REG)
1166 reg = &crx_regtab[r];
1167 /* Check whether the register is in coprocessor registers table. */
1168 else if (r < MAX_COPREG)
1169 reg = &crx_copregtab[r-MAX_REG];
1170 /* Register not found. */
1171 else
1172 {
1173 as_bad (_("Unknown register: `%d'"), r);
1174 return 0;
1175 }
1176
1177 reg_name = reg->name;
1178
1179/* Issue a error message when register is illegal. */
1180#define IMAGE_ERR \
1181 as_bad (_("Illegal register (`%s') in Instruction: `%s'"), \
1182 reg_name, ins_parse); \
1183 break;
1184
1185 switch (reg->type)
1186 {
1187 case CRX_U_REGTYPE:
9bb1ebc2
TL
1188 if (is_procreg || (instruction->flags & USER_REG))
1189 return reg->image;
1190 else
1191 IMAGE_ERR;
1192
1fe1f39c 1193 case CRX_CFG_REGTYPE:
9bb1ebc2 1194 if (is_procreg)
1fe1f39c
NC
1195 return reg->image;
1196 else
1197 IMAGE_ERR;
1198
1199 case CRX_R_REGTYPE:
9bb1ebc2 1200 if (! is_procreg)
1fe1f39c
NC
1201 return reg->image;
1202 else
1203 IMAGE_ERR;
1204
9bb1ebc2
TL
1205 case CRX_C_REGTYPE:
1206 case CRX_CS_REGTYPE:
3ad3f5ad 1207 return reg->image;
9bb1ebc2
TL
1208 break;
1209
1fe1f39c
NC
1210 default:
1211 IMAGE_ERR;
1212 }
1213
1214 return 0;
1215}
1216
023d1155 1217/* Routine used to represent integer X using NBITS bits. */
1fe1f39c 1218
023d1155
TL
1219static long
1220getconstant (long x, int nbits)
1fe1f39c 1221{
1fe1f39c
NC
1222 /* The following expression avoids overflow if
1223 'nbits' is the number of bits in 'bfd_vma'. */
1224 return (x & ((((1 << (nbits - 1)) - 1) << 1) | 1));
1225}
1226
1227/* Print a constant value to 'output_opcode':
1228 ARG holds the operand's type and value.
1229 SHIFT represents the location of the operand to be print into.
1230 NBITS determines the size (in bits) of the constant. */
1231
1232static void
1233print_constant (int nbits, int shift, argument *arg)
1234{
1235 unsigned long mask = 0;
1236
1237 long constant = getconstant (arg->constant, nbits);
1238
1239 switch (nbits)
1240 {
1241 case 32:
1242 case 28:
1243 case 24:
1244 case 22:
1245 /* mask the upper part of the constant, that is, the bits
1246 going to the lowest byte of output_opcode[0].
1247 The upper part of output_opcode[1] is always filled,
1248 therefore it is always masked with 0xFFFF. */
1249 mask = (1 << (nbits - 16)) - 1;
1250 /* Divide the constant between two consecutive words :
1251 0 1 2 3
1252 +---------+---------+---------+---------+
1253 | | X X X X | X X X X | |
1254 +---------+---------+---------+---------+
1255 output_opcode[0] output_opcode[1] */
1256
1257 CRX_PRINT (0, (constant >> WORD_SHIFT) & mask, 0);
1258 CRX_PRINT (1, (constant & 0xFFFF), WORD_SHIFT);
1259 break;
1260
1261 case 16:
1262 case 12:
1263 /* Special case - in arg_cr, the SHIFT represents the location
1264 of the REGISTER, not the constant, which is itself not shifted. */
1265 if (arg->type == arg_cr)
1266 {
1267 CRX_PRINT (0, constant, 0);
1268 break;
1269 }
1270
9bb1ebc2
TL
1271 /* When instruction size is 3 and 'shift' is 16, a 16-bit constant is
1272 always filling the upper part of output_opcode[1]. If we mistakenly
1273 write it to output_opcode[0], the constant prefix (that is, 'match')
708587a4 1274 will be overridden.
9bb1ebc2
TL
1275 0 1 2 3
1276 +---------+---------+---------+---------+
1277 | 'match' | | X X X X | |
1278 +---------+---------+---------+---------+
1279 output_opcode[0] output_opcode[1] */
1280
1281 if ((instruction->size > 2) && (shift == WORD_SHIFT))
1fe1f39c
NC
1282 CRX_PRINT (1, constant, WORD_SHIFT);
1283 else
1284 CRX_PRINT (0, constant, shift);
1285 break;
1286
1287 default:
1288 CRX_PRINT (0, constant, shift);
1289 break;
1290 }
1291}
1292
1293/* Print an operand to 'output_opcode', which later on will be
1294 printed to the object file:
1295 ARG holds the operand's type, size and value.
1296 SHIFT represents the printing location of operand.
1297 NBITS determines the size (in bits) of a constant operand. */
1298
1299static void
1300print_operand (int nbits, int shift, argument *arg)
1301{
1302 switch (arg->type)
1303 {
1304 case arg_r:
1305 CRX_PRINT (0, getreg_image (arg->r), shift);
1306 break;
1307
1308 case arg_copr:
1309 if (arg->cr < c0 || arg->cr > c15)
1310 as_bad (_("Illegal Co-processor register in Instruction `%s' "),
1311 ins_parse);
1312 CRX_PRINT (0, getreg_image (arg->cr), shift);
1313 break;
1314
1315 case arg_copsr:
1316 if (arg->cr < cs0 || arg->cr > cs15)
1317 as_bad (_("Illegal Co-processor special register in Instruction `%s' "),
1318 ins_parse);
1319 CRX_PRINT (0, getreg_image (arg->cr), shift);
1320 break;
1321
82d6ee2a 1322 case arg_idxr:
1fe1f39c
NC
1323 /* 16 12 8 6 0
1324 +--------------------------------+
9bb1ebc2 1325 | r_base | r_idx | scl| disp |
1fe1f39c
NC
1326 +--------------------------------+ */
1327 CRX_PRINT (0, getreg_image (arg->r), 12);
1328 CRX_PRINT (0, getreg_image (arg->i_r), 8);
1329 CRX_PRINT (0, arg->scale, 6);
82d6ee2a
TL
1330 case arg_ic:
1331 case arg_c:
1fe1f39c
NC
1332 print_constant (nbits, shift, arg);
1333 break;
1334
1335 case arg_rbase:
1336 CRX_PRINT (0, getreg_image (arg->r), shift);
1337 break;
1338
1339 case arg_cr:
1340 /* case base_cst4. */
023d1155
TL
1341 if (instruction->flags & DISPU4MAP)
1342 print_constant (nbits, shift + REG_SIZE, arg);
1fe1f39c 1343 else
9bb1ebc2 1344 /* rbase_disps<NN> and other such cases. */
1fe1f39c
NC
1345 print_constant (nbits, shift, arg);
1346 /* Add the register argument to the output_opcode. */
1347 CRX_PRINT (0, getreg_image (arg->r), shift);
1348 break;
1349
1fe1f39c
NC
1350 default:
1351 break;
1352 }
1353}
1354
1355/* Retrieve the number of operands for the current assembled instruction. */
1356
1357static int
1358get_number_of_operands (void)
1359{
1360 int i;
1361
1362 for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
1363 ;
1364 return i;
1365}
1366
023d1155
TL
1367/* Verify that the number NUM can be represented in BITS bits (that is,
1368 within its permitted range), based on the instruction's FLAGS.
1369 If UPDATE is nonzero, update the value of NUM if necessary.
1370 Return OP_LEGAL upon success, actual error type upon failure. */
1371
1372static op_err
1373check_range (long *num, int bits, int unsigned flags, int update)
1374{
1375 long min, max;
1376 int retval = OP_LEGAL;
1377 int bin;
1378 long upper_64kb = 0xFFFF0000;
1379 long value = *num;
1380
70e45ad9
NC
1381 /* For hosts witah longs bigger than 32-bits make sure that the top
1382 bits of a 32-bit negative value read in by the parser are set,
1383 so that the correct comparisons are made. */
1384 if (value & 0x80000000)
1385 value |= (-1L << 31);
1386
023d1155
TL
1387 /* Verify operand value is even. */
1388 if (flags & OP_EVEN)
1389 {
1390 if (value % 2)
1391 return OP_NOT_EVEN;
1392 }
1393
1394 if (flags & OP_UPPER_64KB)
1395 {
1396 /* Check if value is to be mapped to upper 64 KB memory area. */
1397 if ((value & upper_64kb) == upper_64kb)
1398 {
1399 value -= upper_64kb;
1400 if (update)
1401 *num = value;
1402 }
1403 else
1404 return OP_NOT_UPPER_64KB;
1405 }
1406
1407 if (flags & OP_SHIFT)
1408 {
1409 value >>= 1;
1410 if (update)
1411 *num = value;
1412 }
1413 else if (flags & OP_SHIFT_DEC)
1414 {
1415 value = (value >> 1) - 1;
1416 if (update)
1417 *num = value;
1418 }
1419
1420 if (flags & OP_ESC)
1421 {
1422 /* 0x7e and 0x7f are reserved escape sequences of dispe9. */
1423 if (value == 0x7e || value == 0x7f)
1424 return OP_OUT_OF_RANGE;
1425 }
1426
1427 if (flags & OP_DISPU4)
1428 {
1429 int is_dispu4 = 0;
1430
1431 int mul = (instruction->flags & DISPUB4) ? 1
1432 : (instruction->flags & DISPUW4) ? 2
1433 : (instruction->flags & DISPUD4) ? 4 : 0;
1434
1435 for (bin = 0; bin < cst4_maps; bin++)
1436 {
1437 if (value == (mul * bin))
1438 {
1439 is_dispu4 = 1;
1440 if (update)
1441 *num = bin;
1442 break;
1443 }
1444 }
1445 if (!is_dispu4)
1446 retval = OP_ILLEGAL_DISPU4;
1447 }
1448 else if (flags & OP_CST4)
1449 {
1450 int is_cst4 = 0;
1451
1452 for (bin = 0; bin < cst4_maps; bin++)
1453 {
1454 if (value == cst4_map[bin])
1455 {
1456 is_cst4 = 1;
1457 if (update)
1458 *num = bin;
1459 break;
1460 }
1461 }
1462 if (!is_cst4)
1463 retval = OP_ILLEGAL_CST4;
1464 }
1465 else if (flags & OP_SIGNED)
1466 {
1467 max = (1 << (bits - 1)) - 1;
1468 min = - (1 << (bits - 1));
1469 if ((value > max) || (value < min))
1470 retval = OP_OUT_OF_RANGE;
1471 }
1472 else if (flags & OP_UNSIGNED)
1473 {
1474 max = ((((1 << (bits - 1)) - 1) << 1) | 1);
1475 min = 0;
1476 if (((unsigned long) value > (unsigned long) max)
1477 || ((unsigned long) value < (unsigned long) min))
1478 retval = OP_OUT_OF_RANGE;
1479 }
1480 return retval;
1481}
1482
1483/* Assemble a single instruction:
1484 INSN is already parsed (that is, all operand values and types are set).
1485 For instruction to be assembled, we need to find an appropriate template in
1486 the instruction table, meeting the following conditions:
1487 1: Has the same number of operands.
1488 2: Has the same operand types.
1489 3: Each operand size is sufficient to represent the instruction's values.
1fe1f39c
NC
1490 Returns 1 upon success, 0 upon failure. */
1491
1492static int
1493assemble_insn (char *mnemonic, ins *insn)
1494{
023d1155
TL
1495 /* Type of each operand in the current template. */
1496 argtype cur_type[MAX_OPERANDS];
1497 /* Size (in bits) of each operand in the current template. */
1498 unsigned int cur_size[MAX_OPERANDS];
1499 /* Flags of each operand in the current template. */
1500 unsigned int cur_flags[MAX_OPERANDS];
9bb1ebc2 1501 /* Instruction type to match. */
82d6ee2a 1502 unsigned int ins_type;
023d1155 1503 /* Boolean flag to mark whether a match was found. */
1fe1f39c 1504 int match = 0;
023d1155
TL
1505 int i;
1506 /* Nonzero if an instruction with same number of operands was found. */
1507 int found_same_number_of_operands = 0;
1508 /* Nonzero if an instruction with same argument types was found. */
1509 int found_same_argument_types = 0;
1510 /* Nonzero if a constant was found within the required range. */
1511 int found_const_within_range = 0;
1512 /* Argument number of an operand with invalid type. */
1513 int invalid_optype = -1;
1514 /* Argument number of an operand with invalid constant value. */
1515 int invalid_const = -1;
1516 /* Operand error (used for issuing various constant error messages). */
1517 op_err op_error, const_err = OP_LEGAL;
1518
1519/* Retrieve data (based on FUNC) for each operand of a given instruction. */
1520#define GET_CURRENT_DATA(FUNC, ARRAY) \
1521 for (i = 0; i < insn->nargs; i++) \
1522 ARRAY[i] = FUNC (instruction->operands[i].op_type)
1523
1524#define GET_CURRENT_TYPE GET_CURRENT_DATA(get_optype, cur_type)
1525#define GET_CURRENT_SIZE GET_CURRENT_DATA(get_opbits, cur_size)
1526#define GET_CURRENT_FLAGS GET_CURRENT_DATA(get_opflags, cur_flags)
1527
1528 /* Instruction has no operands -> only copy the constant opcode. */
1fe1f39c
NC
1529 if (insn->nargs == 0)
1530 {
1531 output_opcode[0] = BIN (instruction->match, instruction->match_bits);
1532 return 1;
1533 }
1534
9bb1ebc2
TL
1535 /* In some case, same mnemonic can appear with different instruction types.
1536 For example, 'storb' is supported with 3 different types :
1537 LD_STOR_INS, LD_STOR_INS_INC, STOR_IMM_INS.
1538 We assume that when reaching this point, the instruction type was
1539 pre-determined. We need to make sure that the type stays the same
1540 during a search for matching instruction. */
1541 ins_type = CRX_INS_TYPE(instruction->flags);
1542
023d1155
TL
1543 while (/* Check that match is still not found. */
1544 match != 1
1fe1f39c
NC
1545 /* Check we didn't get to end of table. */
1546 && instruction->mnemonic != NULL
1547 /* Check that the actual mnemonic is still available. */
9bb1ebc2
TL
1548 && IS_INSN_MNEMONIC (mnemonic)
1549 /* Check that the instruction type wasn't changed. */
1550 && IS_INSN_TYPE(ins_type))
1fe1f39c 1551 {
023d1155
TL
1552 /* Check whether number of arguments is legal. */
1553 if (get_number_of_operands () != insn->nargs)
1554 goto next_insn;
1555 found_same_number_of_operands = 1;
1556
1557 /* Initialize arrays with data of each operand in current template. */
1558 GET_CURRENT_TYPE;
1559 GET_CURRENT_SIZE;
1560 GET_CURRENT_FLAGS;
1561
1562 /* Check for type compatibility. */
1fe1f39c
NC
1563 for (i = 0; i < insn->nargs; i++)
1564 {
023d1155 1565 if (cur_type[i] != insn->arg[i].type)
e92c9d66 1566 {
023d1155
TL
1567 if (invalid_optype == -1)
1568 invalid_optype = i + 1;
1569 goto next_insn;
e92c9d66
TL
1570 }
1571 }
023d1155 1572 found_same_argument_types = 1;
e92c9d66 1573
023d1155
TL
1574 for (i = 0; i < insn->nargs; i++)
1575 {
1576 /* Reverse the operand indices for certain opcodes:
1577 Index 0 -->> 1
1578 Index 1 -->> 0
1579 Other index -->> stays the same. */
1580 int j = instruction->flags & REVERSE_MATCH ?
1581 i == 0 ? 1 :
1582 i == 1 ? 0 : i :
1583 i;
1584
1585 /* Only check range - don't update the constant's value, since the
1586 current instruction may not be the last we try to match.
1587 The constant's value will be updated later, right before printing
1588 it to the object file. */
1589 if ((insn->arg[j].X_op == O_constant)
1590 && (op_error = check_range (&insn->arg[j].constant, cur_size[j],
1591 cur_flags[j], 0)))
1592 {
1593 if (invalid_const == -1)
1594 {
1595 invalid_const = j + 1;
1596 const_err = op_error;
1597 }
1598 goto next_insn;
1599 }
1600 /* For symbols, we make sure the relocation size (which was already
1601 determined) is sufficient. */
1602 else if ((insn->arg[j].X_op == O_symbol)
1603 && ((bfd_reloc_type_lookup (stdoutput, insn->rtype))->bitsize
1604 > cur_size[j]))
1605 goto next_insn;
1606 }
1607 found_const_within_range = 1;
1fe1f39c 1608
023d1155
TL
1609 /* If we got till here -> Full match is found. */
1610 match = 1;
1611 break;
1fe1f39c 1612
023d1155
TL
1613/* Try again with next instruction. */
1614next_insn:
1615 instruction++;
1fe1f39c
NC
1616 }
1617
023d1155 1618 if (!match)
1fe1f39c 1619 {
023d1155
TL
1620 /* We haven't found a match - instruction can't be assembled. */
1621 if (!found_same_number_of_operands)
1622 as_bad (_("Incorrect number of operands"));
1623 else if (!found_same_argument_types)
1624 as_bad (_("Illegal type of operand (arg %d)"), invalid_optype);
1625 else if (!found_const_within_range)
1626 {
1627 switch (const_err)
e3c52c53 1628 {
023d1155
TL
1629 case OP_OUT_OF_RANGE:
1630 as_bad (_("Operand out of range (arg %d)"), invalid_const);
1631 break;
1632 case OP_NOT_EVEN:
1633 as_bad (_("Operand has odd displacement (arg %d)"), invalid_const);
1634 break;
1635 case OP_ILLEGAL_DISPU4:
1636 as_bad (_("Invalid DISPU4 operand value (arg %d)"), invalid_const);
1637 break;
1638 case OP_ILLEGAL_CST4:
1639 as_bad (_("Invalid CST4 operand value (arg %d)"), invalid_const);
1640 break;
1641 case OP_NOT_UPPER_64KB:
1642 as_bad (_("Operand value is not within upper 64 KB (arg %d)"),
1643 invalid_const);
1644 break;
1645 default:
1646 as_bad (_("Illegal operand (arg %d)"), invalid_const);
1647 break;
e3c52c53 1648 }
023d1155
TL
1649 }
1650
1651 return 0;
1652 }
1653 else
1654 /* Full match - print the encoding to output file. */
1655 {
1656 /* Make further checkings (such that couldn't be made earlier).
1657 Warn the user if necessary. */
1658 warn_if_needed (insn);
1659
1660 /* Check whether we need to adjust the instruction pointer. */
1661 if (adjust_if_needed (insn))
1662 /* If instruction pointer was adjusted, we need to update
1663 the size of the current template operands. */
1664 GET_CURRENT_SIZE;
9bb1ebc2 1665
023d1155 1666 for (i = 0; i < insn->nargs; i++)
9bb1ebc2 1667 {
023d1155
TL
1668 int j = instruction->flags & REVERSE_MATCH ?
1669 i == 0 ? 1 :
1670 i == 1 ? 0 : i :
1671 i;
1672
1673 /* This time, update constant value before printing it. */
1674 if ((insn->arg[j].X_op == O_constant)
1675 && (check_range (&insn->arg[j].constant, cur_size[j],
1676 cur_flags[j], 1) != OP_LEGAL))
1677 as_fatal (_("Illegal operand (arg %d)"), j+1);
9bb1ebc2
TL
1678 }
1679
023d1155
TL
1680 /* First, copy the instruction's opcode. */
1681 output_opcode[0] = BIN (instruction->match, instruction->match_bits);
9bb1ebc2 1682
023d1155 1683 for (i = 0; i < insn->nargs; i++)
1fe1f39c 1684 {
023d1155
TL
1685 cur_arg_num = i;
1686 print_operand (cur_size[i], instruction->operands[i].shift,
1687 &insn->arg[i]);
1688 }
1689 }
9bb1ebc2 1690
023d1155
TL
1691 return 1;
1692}
9bb1ebc2 1693
023d1155
TL
1694/* Bunch of error checkings.
1695 The checks are made after a matching instruction was found. */
9bb1ebc2 1696
023d1155
TL
1697void
1698warn_if_needed (ins *insn)
1699{
1700 /* If the post-increment address mode is used and the load/store
1701 source register is the same as rbase, the result of the
1702 instruction is undefined. */
1703 if (IS_INSN_TYPE (LD_STOR_INS_INC))
1704 {
1705 /* Enough to verify that one of the arguments is a simple reg. */
1706 if ((insn->arg[0].type == arg_r) || (insn->arg[1].type == arg_r))
1707 if (insn->arg[0].r == insn->arg[1].r)
1708 as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
1709 insn->arg[0].r);
1710 }
9bb1ebc2 1711
023d1155
TL
1712 /* Some instruction assume the stack pointer as rptr operand.
1713 Issue an error when the register to be loaded is also SP. */
1714 if (instruction->flags & NO_SP)
1715 {
1716 if (getreg_image (insn->arg[0].r) == getreg_image (sp))
1717 as_bad (_("`%s' has undefined result"), ins_parse);
1718 }
1fe1f39c 1719
023d1155
TL
1720 /* If the rptr register is specified as one of the registers to be loaded,
1721 the final contents of rptr are undefined. Thus, we issue an error. */
1722 if (instruction->flags & NO_RPTR)
1723 {
1724 if ((1 << getreg_image (insn->arg[0].r)) & insn->arg[1].constant)
1725 as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
1726 getreg_image (insn->arg[0].r));
1727 }
1728}
1fe1f39c 1729
023d1155
TL
1730/* In some cases, we need to adjust the instruction pointer although a
1731 match was already found. Here, we gather all these cases.
1732 Returns 1 if instruction pointer was adjusted, otherwise 0. */
1fe1f39c 1733
023d1155
TL
1734int
1735adjust_if_needed (ins *insn)
1736{
1737 int ret_value = 0;
1738
1739 /* Special check for 'addub $0, r0' instruction -
1740 The opcode '0000 0000 0000 0000' is not allowed. */
1741 if (IS_INSN_MNEMONIC ("addub"))
1742 {
1743 if ((instruction->operands[0].op_type == cst4)
1744 && instruction->operands[1].op_type == regr)
1fe1f39c 1745 {
023d1155
TL
1746 if (insn->arg[0].constant == 0 && insn->arg[1].r == r0)
1747 {
1748 instruction++;
1749 ret_value = 1;
1750 }
1fe1f39c
NC
1751 }
1752 }
1753
023d1155
TL
1754 /* Optimization: Omit a zero displacement in bit operations,
1755 saving 2-byte encoding space (e.g., 'cbitw $8, 0(r1)'). */
1756 if (IS_INSN_TYPE (CSTBIT_INS))
1757 {
1758 if ((instruction->operands[1].op_type == rbase_disps12)
1759 && (insn->arg[1].X_op == O_constant)
1760 && (insn->arg[1].constant == 0))
1761 {
1762 instruction--;
1763 ret_value = 1;
1764 }
1765 }
1766
1767 return ret_value;
1fe1f39c
NC
1768}
1769
1770/* Set the appropriate bit for register 'r' in 'mask'.
1771 This indicates that this register is loaded or stored by
1772 the instruction. */
1773
1774static void
1775mask_reg (int r, unsigned short int *mask)
1776{
1777 if ((reg)r > (reg)sp)
1778 {
1779 as_bad (_("Invalid Register in Register List"));
1780 return;
1781 }
1782
1783 *mask |= (1 << r);
1784}
1785
1786/* Preprocess register list - create a 16-bit mask with one bit for each
1787 of the 16 general purpose registers. If a bit is set, it indicates
1788 that this register is loaded or stored by the instruction. */
1789
1790static char *
1791preprocess_reglist (char *param, int *allocated)
1792{
1793 char reg_name[MAX_REGNAME_LEN]; /* Current parsed register name. */
1794 char *regP; /* Pointer to 'reg_name' string. */
1795 int reg_counter = 0; /* Count number of parsed registers. */
1796 unsigned short int mask = 0; /* Mask for 16 general purpose registers. */
1797 char *new_param; /* New created operands string. */
1798 char *paramP = param; /* Pointer to original opearands string. */
1799 char maskstring[10]; /* Array to print the mask as a string. */
9bb1ebc2 1800 int hi_found = 0, lo_found = 0; /* Boolean flags for hi/lo registers. */
1fe1f39c
NC
1801 reg r;
1802 copreg cr;
1803
1804 /* If 'param' is already in form of a number, no need to preprocess. */
1805 if (strchr (paramP, '{') == NULL)
1806 return param;
1807
1808 /* Verifying correct syntax of operand. */
1809 if (strchr (paramP, '}') == NULL)
1810 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1811
1812 while (*paramP++ != '{');
1813
1814 new_param = (char *)xcalloc (MAX_INST_LEN, sizeof (char));
1815 *allocated = 1;
1816 strncpy (new_param, param, paramP - param - 1);
1817
1818 while (*paramP != '}')
1819 {
1820 regP = paramP;
1821 memset (&reg_name, '\0', sizeof (reg_name));
1822
1823 while (ISALNUM (*paramP))
1824 paramP++;
1825
1826 strncpy (reg_name, regP, paramP - regP);
1827
48c9f030 1828 /* Coprocessor register c<N>. */
1fe1f39c
NC
1829 if (IS_INSN_TYPE (COP_REG_INS))
1830 {
9bb1ebc2
TL
1831 if (((cr = get_copregister (reg_name)) == nullcopregister)
1832 || (crx_copregtab[cr-MAX_REG].type != CRX_C_REGTYPE))
1833 as_fatal (_("Illegal register `%s' in cop-register list"), reg_name);
1fe1f39c
NC
1834 mask_reg (getreg_image (cr - c0), &mask);
1835 }
48c9f030
NC
1836 /* Coprocessor Special register cs<N>. */
1837 else if (IS_INSN_TYPE (COPS_REG_INS))
1838 {
9bb1ebc2
TL
1839 if (((cr = get_copregister (reg_name)) == nullcopregister)
1840 || (crx_copregtab[cr-MAX_REG].type != CRX_CS_REGTYPE))
1841 as_fatal (_("Illegal register `%s' in cop-special-register list"),
48c9f030
NC
1842 reg_name);
1843 mask_reg (getreg_image (cr - cs0), &mask);
1844 }
9bb1ebc2
TL
1845 /* User register u<N>. */
1846 else if (instruction->flags & USER_REG)
1847 {
1848 if (streq(reg_name, "uhi"))
1849 {
1850 hi_found = 1;
1851 goto next_inst;
1852 }
1853 else if (streq(reg_name, "ulo"))
1854 {
1855 lo_found = 1;
1856 goto next_inst;
1857 }
1858 else if (((r = get_register (reg_name)) == nullregister)
1859 || (crx_regtab[r].type != CRX_U_REGTYPE))
1860 as_fatal (_("Illegal register `%s' in user register list"), reg_name);
1861
1862 mask_reg (getreg_image (r - u0), &mask);
1863 }
48c9f030 1864 /* General purpose register r<N>. */
1fe1f39c
NC
1865 else
1866 {
9bb1ebc2
TL
1867 if (streq(reg_name, "hi"))
1868 {
1869 hi_found = 1;
1870 goto next_inst;
1871 }
1872 else if (streq(reg_name, "lo"))
1873 {
1874 lo_found = 1;
1875 goto next_inst;
1876 }
1877 else if (((r = get_register (reg_name)) == nullregister)
1878 || (crx_regtab[r].type != CRX_R_REGTYPE))
1879 as_fatal (_("Illegal register `%s' in register list"), reg_name);
1880
1881 mask_reg (getreg_image (r - r0), &mask);
1fe1f39c
NC
1882 }
1883
1884 if (++reg_counter > MAX_REGS_IN_MASK16)
1885 as_bad (_("Maximum %d bits may be set in `mask16' operand"),
1886 MAX_REGS_IN_MASK16);
1887
9bb1ebc2 1888next_inst:
1fe1f39c
NC
1889 while (!ISALNUM (*paramP) && *paramP != '}')
1890 paramP++;
1891 }
1892
1893 if (*++paramP != '\0')
1894 as_warn (_("rest of line ignored; first ignored character is `%c'"),
1895 *paramP);
1896
9bb1ebc2
TL
1897 switch (hi_found + lo_found)
1898 {
1899 case 0:
1900 /* At least one register should be specified. */
1901 if (mask == 0)
1902 as_bad (_("Illegal `mask16' operand, operation is undefined - `%s'"),
1903 ins_parse);
1904 break;
1905
1906 case 1:
1907 /* HI can't be specified without LO (and vise-versa). */
1908 as_bad (_("HI/LO registers should be specified together"));
1909 break;
1910
1911 case 2:
1912 /* HI/LO registers mustn't be masked with additional registers. */
1913 if (mask != 0)
1914 as_bad (_("HI/LO registers should be specified without additional registers"));
1915
1916 default:
1917 break;
1918 }
1fe1f39c
NC
1919
1920 sprintf (maskstring, "$0x%x", mask);
1921 strcat (new_param, maskstring);
1922 return new_param;
1923}
1924
1925/* Print the instruction.
1926 Handle also cases where the instruction is relaxable/relocatable. */
1927
1928void
1929print_insn (ins *insn)
1930{
1931 unsigned int i, j, insn_size;
1932 char *this_frag;
1933 unsigned short words[4];
aea44f62 1934 int addr_mod;
1fe1f39c
NC
1935
1936 /* Arrange the insn encodings in a WORD size array. */
1937 for (i = 0, j = 0; i < 2; i++)
1938 {
1939 words[j++] = (output_opcode[i] >> 16) & 0xFFFF;
1940 words[j++] = output_opcode[i] & 0xFFFF;
1941 }
1942
1943 /* Handle relaxtion. */
1944 if ((instruction->flags & RELAXABLE) && relocatable)
1945 {
1946 int relax_subtype;
1947
1948 /* Write the maximal instruction size supported. */
1949 insn_size = INSN_MAX_SIZE;
1950
1951 /* bCC */
1952 if (IS_INSN_TYPE (BRANCH_INS))
1953 relax_subtype = 0;
1954 /* bal */
1955 else if (IS_INSN_TYPE (DCR_BRANCH_INS) || IS_INSN_MNEMONIC ("bal"))
1956 relax_subtype = 3;
30c62922
TL
1957 /* cmpbr/bcop */
1958 else if (IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
1fe1f39c
NC
1959 relax_subtype = 5;
1960 else
1961 abort ();
1962
1963 this_frag = frag_var (rs_machine_dependent, insn_size * 2,
1964 4, relax_subtype,
1965 insn->exp.X_add_symbol,
1966 insn->exp.X_add_number,
1967 0);
1968 }
1969 else
1970 {
1971 insn_size = instruction->size;
1972 this_frag = frag_more (insn_size * 2);
1973
1974 /* Handle relocation. */
1975 if ((relocatable) && (insn->rtype != BFD_RELOC_NONE))
1976 {
1977 reloc_howto_type *reloc_howto;
1978 int size;
1979
1980 reloc_howto = bfd_reloc_type_lookup (stdoutput, insn->rtype);
1981
1982 if (!reloc_howto)
1983 abort ();
1984
1985 size = bfd_get_reloc_size (reloc_howto);
1986
1987 if (size < 1 || size > 4)
1988 abort ();
1989
1990 fix_new_exp (frag_now, this_frag - frag_now->fr_literal,
1991 size, &insn->exp, reloc_howto->pc_relative,
1992 insn->rtype);
1993 }
1994 }
1995
aea44f62
TL
1996 /* Verify a 2-byte code alignment. */
1997 addr_mod = frag_now_fix () & 1;
1998 if (frag_now->has_code && frag_now->insn_addr != addr_mod)
1999 as_bad (_("instruction address is not a multiple of 2"));
2000 frag_now->insn_addr = addr_mod;
2001 frag_now->has_code = 1;
2002
1fe1f39c
NC
2003 /* Write the instruction encoding to frag. */
2004 for (i = 0; i < insn_size; i++)
2005 {
2006 md_number_to_chars (this_frag, (valueT) words[i], 2);
2007 this_frag += 2;
2008 }
2009}
2010
2011/* This is the guts of the machine-dependent assembler. OP points to a
2012 machine dependent instruction. This function is supposed to emit
2013 the frags/bytes it assembles to. */
2014
2015void
2016md_assemble (char *op)
2017{
2018 ins crx_ins;
2019 char *param;
2020 char c;
2021
2022 /* Reset global variables for a new instruction. */
023d1155 2023 reset_vars (op);
1fe1f39c
NC
2024
2025 /* Strip the mnemonic. */
2026 for (param = op; *param != 0 && !ISSPACE (*param); param++)
2027 ;
2028 c = *param;
2029 *param++ = '\0';
2030
2031 /* Find the instruction. */
2032 instruction = (const inst *) hash_find (crx_inst_hash, op);
2033 if (instruction == NULL)
2034 {
2035 as_bad (_("Unknown opcode: `%s'"), op);
2036 return;
2037 }
2038
2039 /* Tie dwarf2 debug info to the address at the start of the insn. */
2040 dwarf2_emit_insn (0);
2041
023d1155
TL
2042 /* Parse the instruction's operands. */
2043 parse_insn (&crx_ins, param);
1fe1f39c 2044
023d1155 2045 /* Assemble the instruction - return upon failure. */
1fe1f39c 2046 if (assemble_insn (op, &crx_ins) == 0)
023d1155 2047 return;
1fe1f39c
NC
2048
2049 /* Print the instruction. */
2050 print_insn (&crx_ins);
2051}
This page took 0.273468 seconds and 4 git commands to generate.