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