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