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