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