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