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