1 1.1 christos /* tc-cr16.c -- Assembler code for the CR16 CPU core. 2 1.10 christos Copyright (C) 2007-2025 Free Software Foundation, Inc. 3 1.1 christos 4 1.1 christos Contributed by M R Swami Reddy <MR.Swami.Reddy (at) nsc.com> 5 1.1 christos 6 1.1 christos This file is part of GAS, the GNU Assembler. 7 1.1 christos 8 1.1 christos GAS is free software; you can redistribute it and/or modify 9 1.1 christos it under the terms of the GNU General Public License as published by 10 1.1 christos the Free Software Foundation; either version 3, or (at your option) 11 1.1 christos any later version. 12 1.1 christos 13 1.1 christos GAS is distributed in the hope that it will be useful, 14 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 15 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 1.1 christos GNU General Public License for more details. 17 1.1 christos 18 1.1 christos You should have received a copy of the GNU General Public License 19 1.1 christos along with GAS; see the file COPYING. If not, write to the 20 1.1 christos Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, 21 1.1 christos MA 02110-1301, USA. */ 22 1.1 christos 23 1.1 christos #include "as.h" 24 1.1 christos #include "safe-ctype.h" 25 1.1 christos #include "dwarf2dbg.h" 26 1.1 christos #include "opcode/cr16.h" 27 1.1 christos #include "elf/cr16.h" 28 1.1 christos 29 1.8 christos #include <limits.h> 30 1.8 christos #ifndef CHAR_BIT 31 1.8 christos #define CHAR_BIT 8 32 1.8 christos #endif 33 1.1 christos 34 1.1 christos /* Word is considered here as a 16-bit unsigned short int. */ 35 1.1 christos #define WORD_SHIFT 16 36 1.1 christos 37 1.1 christos /* Register is 2-byte size. */ 38 1.1 christos #define REG_SIZE 2 39 1.1 christos 40 1.1 christos /* Maximum size of a single instruction (in words). */ 41 1.1 christos #define INSN_MAX_SIZE 3 42 1.1 christos 43 1.1 christos /* Maximum bits which may be set in a `mask16' operand. */ 44 1.1 christos #define MAX_REGS_IN_MASK16 8 45 1.1 christos 46 1.1 christos /* Assign a number NUM, shifted by SHIFT bytes, into a location 47 1.1 christos pointed by index BYTE of array 'output_opcode'. */ 48 1.8 christos #define CR16_PRINT(BYTE, NUM, SHIFT) output_opcode[BYTE] |= (NUM) << (SHIFT) 49 1.1 christos 50 1.1 christos /* Operand errors. */ 51 1.1 christos typedef enum 52 1.1 christos { 53 1.1 christos OP_LEGAL = 0, /* Legal operand. */ 54 1.1 christos OP_OUT_OF_RANGE, /* Operand not within permitted range. */ 55 1.1 christos OP_NOT_EVEN /* Operand is Odd number, should be even. */ 56 1.1 christos } 57 1.1 christos op_err; 58 1.1 christos 59 1.1 christos /* Opcode mnemonics hash table. */ 60 1.8 christos static htab_t cr16_inst_hash; 61 1.1 christos /* CR16 registers hash table. */ 62 1.8 christos static htab_t reg_hash; 63 1.1 christos /* CR16 register pair hash table. */ 64 1.8 christos static htab_t regp_hash; 65 1.1 christos /* CR16 processor registers hash table. */ 66 1.8 christos static htab_t preg_hash; 67 1.1 christos /* CR16 processor registers 32 bit hash table. */ 68 1.8 christos static htab_t pregp_hash; 69 1.1 christos /* Current instruction we're assembling. */ 70 1.1 christos const inst *instruction; 71 1.1 christos 72 1.1 christos 73 1.1 christos static int code_label = 0; 74 1.1 christos 75 1.1 christos /* Global variables. */ 76 1.1 christos 77 1.1 christos /* Array to hold an instruction encoding. */ 78 1.1 christos long output_opcode[2]; 79 1.1 christos 80 1.1 christos /* Nonzero means a relocatable symbol. */ 81 1.1 christos int relocatable; 82 1.1 christos 83 1.1 christos /* A copy of the original instruction (used in error messages). */ 84 1.1 christos char ins_parse[MAX_INST_LEN]; 85 1.1 christos 86 1.1 christos /* The current processed argument number. */ 87 1.1 christos int cur_arg_num; 88 1.1 christos 89 1.1 christos /* Generic assembler global variables which must be defined by all targets. */ 90 1.1 christos 91 1.1 christos /* Characters which always start a comment. */ 92 1.1 christos const char comment_chars[] = "#"; 93 1.1 christos 94 1.1 christos /* Characters which start a comment at the beginning of a line. */ 95 1.1 christos const char line_comment_chars[] = "#"; 96 1.1 christos 97 1.1 christos /* This array holds machine specific line separator characters. */ 98 1.1 christos const char line_separator_chars[] = ";"; 99 1.1 christos 100 1.1 christos /* Chars that can be used to separate mant from exp in floating point nums. */ 101 1.1 christos const char EXP_CHARS[] = "eE"; 102 1.1 christos 103 1.1 christos /* Chars that mean this number is a floating point constant as in 0f12.456 */ 104 1.1 christos const char FLT_CHARS[] = "f'"; 105 1.1 christos 106 1.1 christos #ifdef OBJ_ELF 107 1.1 christos /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */ 108 1.1 christos symbolS * GOT_symbol; 109 1.1 christos #endif 110 1.1 christos 111 1.1 christos /* Target-specific multicharacter options, not const-declared at usage. */ 112 1.10 christos const char md_shortopts[] = ""; 113 1.10 christos const struct option md_longopts[] = 114 1.1 christos { 115 1.1 christos {NULL, no_argument, NULL, 0} 116 1.1 christos }; 117 1.10 christos const size_t md_longopts_size = sizeof (md_longopts); 118 1.1 christos 119 1.1 christos static void 120 1.1 christos l_cons (int nbytes) 121 1.1 christos { 122 1.1 christos int c; 123 1.1 christos expressionS exp; 124 1.1 christos 125 1.1 christos #ifdef md_flush_pending_output 126 1.8 christos md_flush_pending_output (); 127 1.1 christos #endif 128 1.1 christos 129 1.1 christos if (is_it_end_of_statement ()) 130 1.1 christos { 131 1.1 christos demand_empty_rest_of_line (); 132 1.1 christos return; 133 1.1 christos } 134 1.1 christos 135 1.1 christos #ifdef TC_ADDRESS_BYTES 136 1.1 christos if (nbytes == 0) 137 1.1 christos nbytes = TC_ADDRESS_BYTES (); 138 1.1 christos #endif 139 1.1 christos 140 1.1 christos #ifdef md_cons_align 141 1.1 christos md_cons_align (nbytes); 142 1.1 christos #endif 143 1.1 christos 144 1.1 christos c = 0; 145 1.1 christos do 146 1.1 christos { 147 1.1 christos unsigned int bits_available = BITS_PER_CHAR * nbytes; 148 1.1 christos char *hold = input_line_pointer; 149 1.1 christos 150 1.1 christos expression (&exp); 151 1.1 christos 152 1.1 christos if (*input_line_pointer == ':') 153 1.8 christos { 154 1.8 christos /* Bitfields. */ 155 1.8 christos long value = 0; 156 1.8 christos 157 1.8 christos for (;;) 158 1.8 christos { 159 1.8 christos unsigned long width; 160 1.8 christos 161 1.8 christos if (*input_line_pointer != ':') 162 1.8 christos { 163 1.8 christos input_line_pointer = hold; 164 1.8 christos break; 165 1.8 christos } 166 1.8 christos if (exp.X_op == O_absent) 167 1.8 christos { 168 1.8 christos as_warn (_("using a bit field width of zero")); 169 1.8 christos exp.X_add_number = 0; 170 1.8 christos exp.X_op = O_constant; 171 1.8 christos } 172 1.8 christos 173 1.8 christos if (exp.X_op != O_constant) 174 1.8 christos { 175 1.8 christos *input_line_pointer = '\0'; 176 1.8 christos as_bad (_("field width \"%s\" too complex for a bitfield"), 177 1.8 christos hold); 178 1.8 christos *input_line_pointer = ':'; 179 1.8 christos demand_empty_rest_of_line (); 180 1.8 christos return; 181 1.8 christos } 182 1.8 christos 183 1.8 christos if ((width = exp.X_add_number) > 184 1.8 christos (unsigned int)(BITS_PER_CHAR * nbytes)) 185 1.8 christos { 186 1.6 christos as_warn (ngettext ("field width %lu too big to fit in %d" 187 1.6 christos " byte: truncated to %d bits", 188 1.6 christos "field width %lu too big to fit in %d" 189 1.6 christos " bytes: truncated to %d bits", 190 1.6 christos nbytes), 191 1.6 christos width, nbytes, (BITS_PER_CHAR * nbytes)); 192 1.8 christos width = BITS_PER_CHAR * nbytes; 193 1.8 christos } 194 1.8 christos 195 1.8 christos if (width > bits_available) 196 1.8 christos { 197 1.8 christos /* FIXME-SOMEDAY: backing up and reparsing is wasteful. */ 198 1.8 christos input_line_pointer = hold; 199 1.8 christos exp.X_add_number = value; 200 1.8 christos break; 201 1.8 christos } 202 1.8 christos 203 1.8 christos /* Skip ':'. */ 204 1.8 christos hold = ++input_line_pointer; 205 1.8 christos 206 1.8 christos expression (&exp); 207 1.8 christos if (exp.X_op != O_constant) 208 1.8 christos { 209 1.8 christos char cache = *input_line_pointer; 210 1.8 christos 211 1.8 christos *input_line_pointer = '\0'; 212 1.8 christos as_bad (_("field value \"%s\" too complex for a bitfield"), 213 1.8 christos hold); 214 1.8 christos *input_line_pointer = cache; 215 1.8 christos demand_empty_rest_of_line (); 216 1.8 christos return; 217 1.8 christos } 218 1.8 christos 219 1.8 christos value |= ((~(-(1 << width)) & exp.X_add_number) 220 1.8 christos << ((BITS_PER_CHAR * nbytes) - bits_available)); 221 1.8 christos 222 1.8 christos if ((bits_available -= width) == 0 223 1.8 christos || is_it_end_of_statement () 224 1.8 christos || *input_line_pointer != ',') 225 1.8 christos break; 226 1.1 christos 227 1.8 christos hold = ++input_line_pointer; 228 1.8 christos expression (&exp); 229 1.8 christos } 230 1.1 christos 231 1.8 christos exp.X_add_number = value; 232 1.8 christos exp.X_op = O_constant; 233 1.8 christos exp.X_unsigned = 1; 234 1.8 christos } 235 1.1 christos 236 1.1 christos if ((*(input_line_pointer) == '@') && (*(input_line_pointer +1) == 'c')) 237 1.8 christos code_label = 1; 238 1.10 christos emit_expr (&exp, nbytes); 239 1.1 christos ++c; 240 1.1 christos if ((*(input_line_pointer) == '@') && (*(input_line_pointer +1) == 'c')) 241 1.8 christos { 242 1.8 christos input_line_pointer +=3; 243 1.8 christos break; 244 1.8 christos } 245 1.1 christos } 246 1.1 christos while ((*input_line_pointer++ == ',')); 247 1.1 christos 248 1.1 christos /* Put terminator back into stream. */ 249 1.1 christos input_line_pointer--; 250 1.1 christos 251 1.1 christos demand_empty_rest_of_line (); 252 1.1 christos } 253 1.1 christos 254 1.1 christos /* This table describes all the machine specific pseudo-ops 255 1.1 christos the assembler has to support. The fields are: 256 1.1 christos *** Pseudo-op name without dot. 257 1.1 christos *** Function to call to execute this pseudo-op. 258 1.1 christos *** Integer arg to pass to the function. */ 259 1.1 christos 260 1.1 christos const pseudo_typeS md_pseudo_table[] = 261 1.1 christos { 262 1.1 christos /* In CR16 machine, align is in bytes (not a ptwo boundary). */ 263 1.1 christos {"align", s_align_bytes, 0}, 264 1.1 christos {"long", l_cons, 4 }, 265 1.1 christos {"4byte", l_cons, 4 }, 266 1.1 christos {0, 0, 0} 267 1.1 christos }; 268 1.1 christos 269 1.1 christos /* CR16 relaxation table. */ 270 1.1 christos const relax_typeS md_relax_table[] = 271 1.1 christos { 272 1.1 christos /* bCC */ 273 1.1 christos {0x7f, -0x80, 2, 1}, /* 8 */ 274 1.1 christos {0xfffe, -0x10000, 4, 2}, /* 16 */ 275 1.1 christos {0xfffffe, -0x1000000, 6, 0}, /* 24 */ 276 1.1 christos }; 277 1.1 christos 278 1.1 christos /* Return the bit size for a given operand. */ 279 1.1 christos 280 1.1 christos static int 281 1.1 christos get_opbits (operand_type op) 282 1.1 christos { 283 1.1 christos if (op < MAX_OPRD) 284 1.1 christos return cr16_optab[op].bit_size; 285 1.1 christos 286 1.1 christos return 0; 287 1.1 christos } 288 1.1 christos 289 1.1 christos /* Return the argument type of a given operand. */ 290 1.1 christos 291 1.1 christos static argtype 292 1.1 christos get_optype (operand_type op) 293 1.1 christos { 294 1.1 christos if (op < MAX_OPRD) 295 1.1 christos return cr16_optab[op].arg_type; 296 1.1 christos else 297 1.1 christos return nullargs; 298 1.1 christos } 299 1.1 christos 300 1.1 christos /* Return the flags of a given operand. */ 301 1.1 christos 302 1.1 christos static int 303 1.1 christos get_opflags (operand_type op) 304 1.1 christos { 305 1.1 christos if (op < MAX_OPRD) 306 1.1 christos return cr16_optab[op].flags; 307 1.1 christos 308 1.1 christos return 0; 309 1.1 christos } 310 1.1 christos 311 1.1 christos /* Get the cc code. */ 312 1.1 christos 313 1.1 christos static int 314 1.1 christos get_cc (char *cc_name) 315 1.1 christos { 316 1.1 christos unsigned int i; 317 1.1 christos 318 1.1 christos for (i = 0; i < cr16_num_cc; i++) 319 1.1 christos if (strcmp (cc_name, cr16_b_cond_tab[i]) == 0) 320 1.1 christos return i; 321 1.1 christos 322 1.1 christos return -1; 323 1.1 christos } 324 1.1 christos 325 1.1 christos /* Get the core processor register 'reg_name'. */ 326 1.1 christos 327 1.1 christos static reg 328 1.1 christos get_register (char *reg_name) 329 1.1 christos { 330 1.1 christos const reg_entry *rreg; 331 1.1 christos 332 1.10 christos rreg = str_hash_find (reg_hash, reg_name); 333 1.1 christos 334 1.1 christos if (rreg != NULL) 335 1.1 christos return rreg->value.reg_val; 336 1.1 christos 337 1.1 christos return nullregister; 338 1.1 christos } 339 1.1 christos /* Get the core processor register-pair 'reg_name'. */ 340 1.1 christos 341 1.1 christos static reg 342 1.1 christos get_register_pair (char *reg_name) 343 1.1 christos { 344 1.1 christos const reg_entry *rreg; 345 1.1 christos char tmp_rp[16]="\0"; 346 1.1 christos 347 1.6 christos /* Add '(' and ')' to the reg pair, if it's not present. */ 348 1.3 christos if (reg_name[0] != '(') 349 1.1 christos { 350 1.1 christos tmp_rp[0] = '('; 351 1.1 christos strcat (tmp_rp, reg_name); 352 1.1 christos strcat (tmp_rp,")"); 353 1.10 christos rreg = str_hash_find (regp_hash, tmp_rp); 354 1.1 christos } 355 1.1 christos else 356 1.10 christos rreg = str_hash_find (regp_hash, reg_name); 357 1.1 christos 358 1.1 christos if (rreg != NULL) 359 1.1 christos return rreg->value.reg_val; 360 1.1 christos 361 1.1 christos return nullregister; 362 1.3 christos } 363 1.1 christos 364 1.1 christos /* Get the index register 'reg_name'. */ 365 1.1 christos 366 1.1 christos static reg 367 1.1 christos get_index_register (char *reg_name) 368 1.1 christos { 369 1.1 christos const reg_entry *rreg; 370 1.1 christos 371 1.10 christos rreg = str_hash_find (reg_hash, reg_name); 372 1.1 christos 373 1.1 christos if ((rreg != NULL) 374 1.1 christos && ((rreg->value.reg_val == 12) || (rreg->value.reg_val == 13))) 375 1.1 christos return rreg->value.reg_val; 376 1.1 christos 377 1.1 christos return nullregister; 378 1.1 christos } 379 1.1 christos /* Get the core processor index register-pair 'reg_name'. */ 380 1.1 christos 381 1.1 christos static reg 382 1.1 christos get_index_register_pair (char *reg_name) 383 1.1 christos { 384 1.1 christos const reg_entry *rreg; 385 1.1 christos 386 1.10 christos rreg = str_hash_find (regp_hash, reg_name); 387 1.1 christos 388 1.1 christos if (rreg != NULL) 389 1.1 christos { 390 1.1 christos if ((rreg->value.reg_val != 1) || (rreg->value.reg_val != 7) 391 1.8 christos || (rreg->value.reg_val != 9) || (rreg->value.reg_val > 10)) 392 1.8 christos return rreg->value.reg_val; 393 1.1 christos 394 1.1 christos as_bad (_("Unknown register pair - index relative mode: `%d'"), rreg->value.reg_val); 395 1.1 christos } 396 1.1 christos 397 1.1 christos return nullregister; 398 1.1 christos } 399 1.1 christos 400 1.1 christos /* Get the processor register 'preg_name'. */ 401 1.1 christos 402 1.1 christos static preg 403 1.1 christos get_pregister (char *preg_name) 404 1.1 christos { 405 1.1 christos const reg_entry *prreg; 406 1.1 christos 407 1.10 christos prreg = str_hash_find (preg_hash, preg_name); 408 1.1 christos 409 1.1 christos if (prreg != NULL) 410 1.1 christos return prreg->value.preg_val; 411 1.1 christos 412 1.1 christos return nullpregister; 413 1.1 christos } 414 1.1 christos 415 1.1 christos /* Get the processor register 'preg_name 32 bit'. */ 416 1.1 christos 417 1.1 christos static preg 418 1.1 christos get_pregisterp (char *preg_name) 419 1.1 christos { 420 1.1 christos const reg_entry *prreg; 421 1.1 christos 422 1.10 christos prreg = str_hash_find (pregp_hash, preg_name); 423 1.1 christos 424 1.1 christos if (prreg != NULL) 425 1.1 christos return prreg->value.preg_val; 426 1.1 christos 427 1.1 christos return nullpregister; 428 1.1 christos } 429 1.1 christos 430 1.1 christos 431 1.1 christos /* Round up a section size to the appropriate boundary. */ 432 1.1 christos 433 1.1 christos valueT 434 1.1 christos md_section_align (segT seg, valueT val) 435 1.1 christos { 436 1.1 christos /* Round .text section to a multiple of 2. */ 437 1.1 christos if (seg == text_section) 438 1.1 christos return (val + 1) & ~1; 439 1.1 christos return val; 440 1.1 christos } 441 1.1 christos 442 1.1 christos /* Parse an operand that is machine-specific (remove '*'). */ 443 1.1 christos 444 1.1 christos void 445 1.1 christos md_operand (expressionS * exp) 446 1.1 christos { 447 1.1 christos char c = *input_line_pointer; 448 1.1 christos 449 1.1 christos switch (c) 450 1.1 christos { 451 1.1 christos case '*': 452 1.1 christos input_line_pointer++; 453 1.1 christos expression (exp); 454 1.1 christos break; 455 1.1 christos default: 456 1.1 christos break; 457 1.1 christos } 458 1.1 christos } 459 1.1 christos 460 1.1 christos /* Reset global variables before parsing a new instruction. */ 461 1.1 christos 462 1.1 christos static void 463 1.1 christos reset_vars (char *op) 464 1.1 christos { 465 1.1 christos cur_arg_num = relocatable = 0; 466 1.1 christos memset (& output_opcode, '\0', sizeof (output_opcode)); 467 1.1 christos 468 1.1 christos /* Save a copy of the original OP (used in error messages). */ 469 1.1 christos strncpy (ins_parse, op, sizeof ins_parse - 1); 470 1.1 christos ins_parse [sizeof ins_parse - 1] = 0; 471 1.1 christos } 472 1.1 christos 473 1.1 christos /* This macro decides whether a particular reloc is an entry in a 474 1.1 christos switch table. It is used when relaxing, because the linker needs 475 1.1 christos to know about all such entries so that it can adjust them if 476 1.1 christos necessary. */ 477 1.1 christos 478 1.8 christos #define SWITCH_TABLE(fix) \ 479 1.8 christos ((fix)->fx_addsy != NULL \ 480 1.8 christos && (fix)->fx_subsy != NULL \ 481 1.8 christos && ((fix)->fx_r_type == BFD_RELOC_CR16_NUM8 \ 482 1.8 christos || (fix)->fx_r_type == BFD_RELOC_CR16_NUM16 \ 483 1.8 christos || (fix)->fx_r_type == BFD_RELOC_CR16_NUM32 \ 484 1.8 christos || (fix)->fx_r_type == BFD_RELOC_CR16_NUM32a) \ 485 1.8 christos && S_GET_SEGMENT ((fix)->fx_addsy) != undefined_section \ 486 1.8 christos && S_GET_SEGMENT ((fix)->fx_addsy) == S_GET_SEGMENT ((fix)->fx_subsy)) 487 1.1 christos 488 1.1 christos /* See whether we need to force a relocation into the output file. 489 1.1 christos This is used to force out switch and PC relative relocations when 490 1.1 christos relaxing. */ 491 1.1 christos 492 1.1 christos int 493 1.1 christos cr16_force_relocation (fixS *fix) 494 1.1 christos { 495 1.1 christos if (generic_force_reloc (fix) || SWITCH_TABLE (fix)) 496 1.1 christos return 1; 497 1.1 christos 498 1.1 christos return 0; 499 1.1 christos } 500 1.1 christos 501 1.1 christos /* Record a fixup for a cons expression. */ 502 1.1 christos 503 1.1 christos void 504 1.3 christos cr16_cons_fix_new (fragS *frag, int offset, int len, expressionS *exp, 505 1.3 christos bfd_reloc_code_real_type rtype) 506 1.1 christos { 507 1.1 christos switch (len) 508 1.1 christos { 509 1.1 christos default: rtype = BFD_RELOC_NONE; break; 510 1.1 christos case 1: rtype = BFD_RELOC_CR16_NUM8 ; break; 511 1.1 christos case 2: rtype = BFD_RELOC_CR16_NUM16; break; 512 1.1 christos case 4: 513 1.1 christos if (code_label) 514 1.8 christos { 515 1.8 christos rtype = BFD_RELOC_CR16_NUM32a; 516 1.8 christos code_label = 0; 517 1.8 christos } 518 1.1 christos else 519 1.8 christos rtype = BFD_RELOC_CR16_NUM32; 520 1.1 christos break; 521 1.1 christos } 522 1.1 christos 523 1.1 christos fix_new_exp (frag, offset, len, exp, 0, rtype); 524 1.1 christos } 525 1.1 christos 526 1.1 christos /* Generate a relocation entry for a fixup. */ 527 1.1 christos 528 1.1 christos arelent * 529 1.1 christos tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS * fixP) 530 1.1 christos { 531 1.1 christos arelent * reloc; 532 1.1 christos 533 1.1 christos /* If symbols are local and resolved, then no relocation needed. */ 534 1.3 christos if ( ((fixP->fx_addsy) 535 1.8 christos && (S_GET_SEGMENT (fixP->fx_addsy) == absolute_section)) 536 1.3 christos || ((fixP->fx_subsy) 537 1.1 christos && (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section))) 538 1.8 christos return NULL; 539 1.1 christos 540 1.10 christos reloc = notes_alloc (sizeof (arelent)); 541 1.10 christos reloc->sym_ptr_ptr = notes_alloc (sizeof (asymbol *)); 542 1.1 christos *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy); 543 1.1 christos reloc->address = fixP->fx_frag->fr_address + fixP->fx_where; 544 1.1 christos reloc->addend = fixP->fx_offset; 545 1.1 christos 546 1.1 christos if (fixP->fx_subsy != NULL) 547 1.1 christos { 548 1.1 christos if (SWITCH_TABLE (fixP)) 549 1.8 christos { 550 1.8 christos /* Keep the current difference in the addend. */ 551 1.8 christos reloc->addend = (S_GET_VALUE (fixP->fx_addsy) 552 1.8 christos - S_GET_VALUE (fixP->fx_subsy) + fixP->fx_offset); 553 1.8 christos 554 1.8 christos switch (fixP->fx_r_type) 555 1.8 christos { 556 1.8 christos case BFD_RELOC_CR16_NUM8: 557 1.8 christos fixP->fx_r_type = BFD_RELOC_CR16_SWITCH8; 558 1.8 christos break; 559 1.8 christos case BFD_RELOC_CR16_NUM16: 560 1.8 christos fixP->fx_r_type = BFD_RELOC_CR16_SWITCH16; 561 1.8 christos break; 562 1.8 christos case BFD_RELOC_CR16_NUM32: 563 1.8 christos fixP->fx_r_type = BFD_RELOC_CR16_SWITCH32; 564 1.8 christos break; 565 1.8 christos case BFD_RELOC_CR16_NUM32a: 566 1.8 christos fixP->fx_r_type = BFD_RELOC_CR16_NUM32a; 567 1.8 christos break; 568 1.8 christos default: 569 1.8 christos abort (); 570 1.8 christos break; 571 1.8 christos } 572 1.8 christos } 573 1.1 christos else 574 1.8 christos { 575 1.8 christos /* We only resolve difference expressions in the same section. */ 576 1.8 christos as_bad_subtract (fixP); 577 1.8 christos return NULL; 578 1.8 christos } 579 1.1 christos } 580 1.1 christos #ifdef OBJ_ELF 581 1.8 christos if ((fixP->fx_r_type == BFD_RELOC_CR16_GOT_REGREL20) 582 1.8 christos && GOT_symbol 583 1.8 christos && fixP->fx_addsy == GOT_symbol) 584 1.8 christos { 585 1.8 christos reloc->addend = fixP->fx_offset = reloc->address; 586 1.8 christos } 587 1.8 christos else if ((fixP->fx_r_type == BFD_RELOC_CR16_GOTC_REGREL20) 588 1.8 christos && GOT_symbol 589 1.1 christos && fixP->fx_addsy == GOT_symbol) 590 1.8 christos { 591 1.8 christos reloc->addend = fixP->fx_offset = reloc->address; 592 1.8 christos } 593 1.1 christos #endif 594 1.1 christos 595 1.1 christos gas_assert ((int) fixP->fx_r_type > 0); 596 1.1 christos reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type); 597 1.1 christos 598 1.1 christos if (reloc->howto == NULL) 599 1.1 christos { 600 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line, 601 1.8 christos _("internal error: reloc %d (`%s') not supported by object file format"), 602 1.8 christos fixP->fx_r_type, 603 1.8 christos bfd_get_reloc_code_name (fixP->fx_r_type)); 604 1.1 christos return NULL; 605 1.1 christos } 606 1.1 christos gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative); 607 1.1 christos 608 1.1 christos return reloc; 609 1.1 christos } 610 1.1 christos 611 1.1 christos /* Prepare machine-dependent frags for relaxation. */ 612 1.1 christos 613 1.1 christos int 614 1.1 christos md_estimate_size_before_relax (fragS *fragp, asection *seg) 615 1.1 christos { 616 1.1 christos /* If symbol is undefined or located in a different section, 617 1.1 christos select the largest supported relocation. */ 618 1.1 christos relax_substateT subtype; 619 1.1 christos relax_substateT rlx_state[] = {0, 2}; 620 1.1 christos 621 1.1 christos for (subtype = 0; subtype < ARRAY_SIZE (rlx_state); subtype += 2) 622 1.1 christos { 623 1.1 christos if (fragp->fr_subtype == rlx_state[subtype] 624 1.8 christos && (!S_IS_DEFINED (fragp->fr_symbol) 625 1.8 christos || seg != S_GET_SEGMENT (fragp->fr_symbol))) 626 1.8 christos { 627 1.8 christos fragp->fr_subtype = rlx_state[subtype + 1]; 628 1.8 christos break; 629 1.8 christos } 630 1.1 christos } 631 1.1 christos 632 1.1 christos if (fragp->fr_subtype >= ARRAY_SIZE (md_relax_table)) 633 1.1 christos abort (); 634 1.1 christos 635 1.1 christos return md_relax_table[fragp->fr_subtype].rlx_length; 636 1.1 christos } 637 1.1 christos 638 1.1 christos void 639 1.10 christos md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, 640 1.10 christos asection *sec ATTRIBUTE_UNUSED, 641 1.10 christos fragS *fragP) 642 1.1 christos { 643 1.1 christos /* 'opcode' points to the start of the instruction, whether 644 1.1 christos we need to change the instruction's fixed encoding. */ 645 1.8 christos char *opcode = &fragP->fr_literal[0] + fragP->fr_fix; 646 1.1 christos bfd_reloc_code_real_type reloc; 647 1.1 christos 648 1.1 christos switch (fragP->fr_subtype) 649 1.1 christos { 650 1.1 christos case 0: 651 1.1 christos reloc = BFD_RELOC_CR16_DISP8; 652 1.1 christos break; 653 1.1 christos case 1: 654 1.1 christos /* If the subtype is not changed due to :m operand qualifier, 655 1.8 christos then no need to update the opcode value. */ 656 1.1 christos if ((int)opcode[1] != 0x18) 657 1.8 christos { 658 1.8 christos opcode[0] = (opcode[0] & 0xf0); 659 1.8 christos opcode[1] = 0x18; 660 1.8 christos } 661 1.1 christos reloc = BFD_RELOC_CR16_DISP16; 662 1.1 christos break; 663 1.1 christos case 2: 664 1.1 christos /* If the subtype is not changed due to :l operand qualifier, 665 1.8 christos then no need to update the opcode value. */ 666 1.1 christos if ((int)opcode[1] != 0) 667 1.8 christos { 668 1.8 christos opcode[2] = opcode[0]; 669 1.8 christos opcode[0] = opcode[1]; 670 1.8 christos opcode[1] = 0x0; 671 1.8 christos } 672 1.1 christos reloc = BFD_RELOC_CR16_DISP24; 673 1.1 christos break; 674 1.1 christos default: 675 1.1 christos abort(); 676 1.1 christos } 677 1.1 christos 678 1.1 christos fix_new (fragP, fragP->fr_fix, 679 1.8 christos bfd_get_reloc_size (bfd_reloc_type_lookup (stdoutput, reloc)), 680 1.8 christos fragP->fr_symbol, fragP->fr_offset, 1, reloc); 681 1.1 christos fragP->fr_var = 0; 682 1.1 christos fragP->fr_fix += md_relax_table[fragP->fr_subtype].rlx_length; 683 1.1 christos } 684 1.1 christos 685 1.1 christos symbolS * 686 1.1 christos md_undefined_symbol (char *name) 687 1.1 christos { 688 1.1 christos if (*name == '_' && *(name + 1) == 'G' 689 1.1 christos && strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0) 690 1.8 christos { 691 1.8 christos if (!GOT_symbol) 692 1.8 christos { 693 1.8 christos if (symbol_find (name)) 694 1.8 christos as_bad (_("GOT already in symbol table")); 695 1.8 christos GOT_symbol = symbol_new (name, undefined_section, 696 1.8 christos &zero_address_frag, 0); 697 1.8 christos } 698 1.8 christos return GOT_symbol; 699 1.8 christos } 700 1.1 christos return 0; 701 1.1 christos } 702 1.1 christos 703 1.1 christos /* Process machine-dependent command line options. Called once for 704 1.1 christos each option on the command line that the machine-independent part of 705 1.1 christos GAS does not understand. */ 706 1.1 christos 707 1.1 christos int 708 1.5 christos md_parse_option (int c ATTRIBUTE_UNUSED, const char *arg ATTRIBUTE_UNUSED) 709 1.1 christos { 710 1.1 christos return 0; 711 1.1 christos } 712 1.1 christos 713 1.1 christos /* Machine-dependent usage-output. */ 714 1.1 christos 715 1.1 christos void 716 1.1 christos md_show_usage (FILE *stream ATTRIBUTE_UNUSED) 717 1.1 christos { 718 1.1 christos return; 719 1.1 christos } 720 1.1 christos 721 1.5 christos const char * 722 1.1 christos md_atof (int type, char *litP, int *sizeP) 723 1.1 christos { 724 1.1 christos return ieee_md_atof (type, litP, sizeP, target_big_endian); 725 1.1 christos } 726 1.1 christos 727 1.1 christos /* Apply a fixS (fixup of an instruction or data that we didn't have 728 1.1 christos enough info to complete immediately) to the data in a frag. 729 1.1 christos Since linkrelax is nonzero and TC_LINKRELAX_FIXUP is defined to disable 730 1.1 christos relaxation of debug sections, this function is called only when 731 1.1 christos fixuping relocations of debug sections. */ 732 1.1 christos 733 1.1 christos void 734 1.1 christos md_apply_fix (fixS *fixP, valueT *valP, segT seg) 735 1.1 christos { 736 1.1 christos valueT val = * valP; 737 1.1 christos 738 1.1 christos if (fixP->fx_addsy == NULL 739 1.1 christos && fixP->fx_pcrel == 0) 740 1.1 christos fixP->fx_done = 1; 741 1.1 christos else if (fixP->fx_pcrel == 1 742 1.1 christos && fixP->fx_addsy != NULL 743 1.1 christos && S_GET_SEGMENT (fixP->fx_addsy) == seg) 744 1.1 christos fixP->fx_done = 1; 745 1.1 christos else 746 1.1 christos fixP->fx_done = 0; 747 1.1 christos 748 1.1 christos if (fixP->fx_addsy != NULL && !fixP->fx_pcrel) 749 1.1 christos { 750 1.1 christos val = fixP->fx_offset; 751 1.1 christos fixP->fx_done = 1; 752 1.1 christos } 753 1.1 christos 754 1.1 christos if (fixP->fx_done) 755 1.1 christos { 756 1.1 christos char *buf = fixP->fx_frag->fr_literal + fixP->fx_where; 757 1.1 christos 758 1.1 christos fixP->fx_offset = 0; 759 1.1 christos 760 1.1 christos switch (fixP->fx_r_type) 761 1.1 christos { 762 1.1 christos case BFD_RELOC_CR16_NUM8: 763 1.10 christos bfd_put_8 (stdoutput, val, buf); 764 1.1 christos break; 765 1.1 christos case BFD_RELOC_CR16_NUM16: 766 1.1 christos bfd_put_16 (stdoutput, val, buf); 767 1.1 christos break; 768 1.1 christos case BFD_RELOC_CR16_NUM32: 769 1.1 christos bfd_put_32 (stdoutput, val, buf); 770 1.1 christos break; 771 1.1 christos case BFD_RELOC_CR16_NUM32a: 772 1.1 christos bfd_put_32 (stdoutput, val, buf); 773 1.1 christos break; 774 1.1 christos default: 775 1.1 christos /* We shouldn't ever get here because linkrelax is nonzero. */ 776 1.1 christos abort (); 777 1.1 christos break; 778 1.1 christos } 779 1.1 christos fixP->fx_done = 0; 780 1.1 christos } 781 1.1 christos else 782 1.1 christos fixP->fx_offset = * valP; 783 1.1 christos } 784 1.1 christos 785 1.1 christos /* The location from which a PC relative jump should be calculated, 786 1.1 christos given a PC relative reloc. */ 787 1.1 christos 788 1.1 christos long 789 1.1 christos md_pcrel_from (fixS *fixp) 790 1.1 christos { 791 1.1 christos return fixp->fx_frag->fr_address + fixp->fx_where; 792 1.1 christos } 793 1.1 christos 794 1.1 christos static void 795 1.8 christos initialise_reg_hash_table (htab_t *hash_table, 796 1.8 christos const reg_entry *register_table, 797 1.8 christos const unsigned int num_entries) 798 1.1 christos { 799 1.8 christos const reg_entry *rreg; 800 1.1 christos 801 1.8 christos *hash_table = str_htab_create (); 802 1.1 christos 803 1.1 christos for (rreg = register_table; 804 1.1 christos rreg < (register_table + num_entries); 805 1.1 christos rreg++) 806 1.8 christos if (str_hash_insert (*hash_table, rreg->name, rreg, 0) != NULL) 807 1.8 christos as_fatal (_("duplicate %s"), rreg->name); 808 1.1 christos } 809 1.1 christos 810 1.1 christos /* This function is called once, at assembler startup time. This should 811 1.1 christos set up all the tables, etc that the MD part of the assembler needs. */ 812 1.1 christos 813 1.1 christos void 814 1.1 christos md_begin (void) 815 1.1 christos { 816 1.1 christos int i = 0; 817 1.1 christos 818 1.1 christos /* Set up a hash table for the instructions. */ 819 1.8 christos cr16_inst_hash = str_htab_create (); 820 1.1 christos 821 1.1 christos while (cr16_instruction[i].mnemonic != NULL) 822 1.1 christos { 823 1.1 christos const char *mnemonic = cr16_instruction[i].mnemonic; 824 1.1 christos 825 1.8 christos if (str_hash_insert (cr16_inst_hash, mnemonic, cr16_instruction + i, 0)) 826 1.8 christos as_fatal (_("duplicate %s"), mnemonic); 827 1.1 christos 828 1.1 christos /* Insert unique names into hash table. The CR16 instruction set 829 1.8 christos has many identical opcode names that have different opcodes based 830 1.8 christos on the operands. This hash table then provides a quick index to 831 1.8 christos the first opcode with a particular name in the opcode table. */ 832 1.1 christos do 833 1.8 christos { 834 1.8 christos ++i; 835 1.8 christos } 836 1.1 christos while (cr16_instruction[i].mnemonic != NULL 837 1.8 christos && streq (cr16_instruction[i].mnemonic, mnemonic)); 838 1.1 christos } 839 1.1 christos 840 1.1 christos /* Initialize reg_hash hash table. */ 841 1.1 christos initialise_reg_hash_table (& reg_hash, cr16_regtab, NUMREGS); 842 1.1 christos /* Initialize regp_hash hash table. */ 843 1.1 christos initialise_reg_hash_table (& regp_hash, cr16_regptab, NUMREGPS); 844 1.1 christos /* Initialize preg_hash hash table. */ 845 1.1 christos initialise_reg_hash_table (& preg_hash, cr16_pregtab, NUMPREGS); 846 1.1 christos /* Initialize pregp_hash hash table. */ 847 1.1 christos initialise_reg_hash_table (& pregp_hash, cr16_pregptab, NUMPREGPS); 848 1.1 christos 849 1.1 christos /* Set linkrelax here to avoid fixups in most sections. */ 850 1.1 christos linkrelax = 1; 851 1.1 christos } 852 1.1 christos 853 1.1 christos /* Process constants (immediate/absolute) 854 1.1 christos and labels (jump targets/Memory locations). */ 855 1.1 christos 856 1.1 christos static void 857 1.1 christos process_label_constant (char *str, ins * cr16_ins) 858 1.1 christos { 859 1.1 christos char *saved_input_line_pointer; 860 1.1 christos int symbol_with_at = 0; 861 1.1 christos int symbol_with_s = 0; 862 1.1 christos int symbol_with_m = 0; 863 1.1 christos int symbol_with_l = 0; 864 1.1 christos int symbol_with_at_got = 0; 865 1.1 christos int symbol_with_at_gotc = 0; 866 1.1 christos argument *cur_arg = cr16_ins->arg + cur_arg_num; /* Current argument. */ 867 1.1 christos 868 1.1 christos saved_input_line_pointer = input_line_pointer; 869 1.1 christos input_line_pointer = str; 870 1.1 christos 871 1.1 christos expression (&cr16_ins->exp); 872 1.1 christos 873 1.1 christos switch (cr16_ins->exp.X_op) 874 1.1 christos { 875 1.1 christos case O_big: 876 1.1 christos case O_absent: 877 1.1 christos /* Missing or bad expr becomes absolute 0. */ 878 1.1 christos as_bad (_("missing or invalid displacement expression `%s' taken as 0"), 879 1.8 christos str); 880 1.1 christos cr16_ins->exp.X_op = O_constant; 881 1.1 christos cr16_ins->exp.X_add_number = 0; 882 1.1 christos cr16_ins->exp.X_add_symbol = NULL; 883 1.1 christos cr16_ins->exp.X_op_symbol = NULL; 884 1.1 christos /* Fall through. */ 885 1.1 christos 886 1.1 christos case O_constant: 887 1.1 christos cur_arg->X_op = O_constant; 888 1.1 christos cur_arg->constant = cr16_ins->exp.X_add_number; 889 1.1 christos break; 890 1.1 christos 891 1.1 christos case O_symbol: 892 1.1 christos case O_subtract: 893 1.1 christos case O_add: 894 1.1 christos cur_arg->X_op = O_symbol; 895 1.1 christos cur_arg->constant = cr16_ins->exp.X_add_number; 896 1.1 christos cr16_ins->exp.X_add_number = 0; 897 1.1 christos cr16_ins->rtype = BFD_RELOC_NONE; 898 1.1 christos relocatable = 1; 899 1.1 christos 900 1.8 christos if (startswith (input_line_pointer, "@c")) 901 1.8 christos symbol_with_at = 1; 902 1.1 christos 903 1.8 christos if (startswith (input_line_pointer, "@l") 904 1.8 christos || startswith (input_line_pointer, ":l")) 905 1.8 christos symbol_with_l = 1; 906 1.8 christos 907 1.8 christos if (startswith (input_line_pointer, "@m") 908 1.8 christos || startswith (input_line_pointer, ":m")) 909 1.8 christos symbol_with_m = 1; 910 1.8 christos 911 1.8 christos if (startswith (input_line_pointer, "@s") 912 1.8 christos || startswith (input_line_pointer, ":s")) 913 1.8 christos symbol_with_s = 1; 914 1.1 christos 915 1.8 christos if (startswith (input_line_pointer, "@cGOT") 916 1.8 christos || startswith (input_line_pointer, "@cgot")) 917 1.1 christos { 918 1.1 christos if (GOT_symbol == NULL) 919 1.8 christos GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME); 920 1.1 christos 921 1.8 christos symbol_with_at_gotc = 1; 922 1.1 christos } 923 1.8 christos else if (startswith (input_line_pointer, "@GOT") 924 1.8 christos || startswith (input_line_pointer, "@got")) 925 1.1 christos { 926 1.8 christos if ((startswith (input_line_pointer, "+")) 927 1.8 christos || (startswith (input_line_pointer, "-"))) 928 1.8 christos as_warn (_("GOT bad expression with %s."), input_line_pointer); 929 1.1 christos 930 1.1 christos if (GOT_symbol == NULL) 931 1.8 christos GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME); 932 1.1 christos 933 1.8 christos symbol_with_at_got = 1; 934 1.1 christos } 935 1.1 christos 936 1.1 christos switch (cur_arg->type) 937 1.8 christos { 938 1.8 christos case arg_cr: 939 1.8 christos if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS)) 940 1.8 christos { 941 1.1 christos if (symbol_with_at_got) 942 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20; 943 1.1 christos else if (symbol_with_at_gotc) 944 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20; 945 1.1 christos else if (cur_arg->size == 20) 946 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_REGREL20; 947 1.8 christos else 948 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_REGREL20a; 949 1.1 christos } 950 1.8 christos break; 951 1.8 christos 952 1.8 christos case arg_crp: 953 1.8 christos if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS)) 954 1.8 christos { 955 1.8 christos if (symbol_with_at_got) 956 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20; 957 1.8 christos else if (symbol_with_at_gotc) 958 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20; 959 1.8 christos } else { 960 1.8 christos switch (instruction->size) 961 1.8 christos { 962 1.8 christos case 1: 963 1.8 christos switch (cur_arg->size) 964 1.8 christos { 965 1.8 christos case 0: 966 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_REGREL0; 967 1.8 christos break; 968 1.8 christos case 4: 969 1.8 christos if (IS_INSN_MNEMONIC ("loadb") || IS_INSN_MNEMONIC ("storb")) 970 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_REGREL4; 971 1.8 christos else 972 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_REGREL4a; 973 1.8 christos break; 974 1.8 christos default: break; 975 1.8 christos } 976 1.8 christos break; 977 1.8 christos case 2: 978 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_REGREL16; 979 1.8 christos break; 980 1.8 christos case 3: 981 1.8 christos if (cur_arg->size == 20) 982 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_REGREL20; 983 1.8 christos else 984 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_REGREL20a; 985 1.8 christos break; 986 1.8 christos default: 987 1.8 christos break; 988 1.8 christos } 989 1.8 christos } 990 1.8 christos break; 991 1.1 christos 992 1.8 christos case arg_idxr: 993 1.8 christos if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS)) 994 1.1 christos { 995 1.1 christos if (symbol_with_at_got) 996 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20; 997 1.1 christos else if (symbol_with_at_gotc) 998 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20; 999 1.1 christos else 1000 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_REGREL20; 1001 1.1 christos } 1002 1.8 christos break; 1003 1.1 christos 1004 1.8 christos case arg_idxrp: 1005 1.8 christos if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS)) 1006 1.1 christos { 1007 1.8 christos if (symbol_with_at_got) 1008 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20; 1009 1.8 christos else if (symbol_with_at_gotc) 1010 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20; 1011 1.8 christos else { 1012 1.8 christos switch (instruction->size) 1013 1.8 christos { 1014 1.8 christos case 1: cr16_ins->rtype = BFD_RELOC_CR16_REGREL0; break; 1015 1.8 christos case 2: cr16_ins->rtype = BFD_RELOC_CR16_REGREL14; break; 1016 1.8 christos case 3: cr16_ins->rtype = BFD_RELOC_CR16_REGREL20; break; 1017 1.8 christos default: break; 1018 1.8 christos } 1019 1.8 christos } 1020 1.1 christos } 1021 1.8 christos break; 1022 1.1 christos 1023 1.8 christos case arg_c: 1024 1.8 christos if (IS_INSN_MNEMONIC ("bal")) 1025 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_DISP24; 1026 1.8 christos else if (IS_INSN_TYPE (BRANCH_INS)) 1027 1.8 christos { 1028 1.8 christos if (symbol_with_l) 1029 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_DISP24; 1030 1.8 christos else if (symbol_with_m) 1031 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_DISP16; 1032 1.8 christos else 1033 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_DISP8; 1034 1.8 christos } 1035 1.8 christos else if (IS_INSN_TYPE (STOR_IMM_INS) || IS_INSN_TYPE (LD_STOR_INS) 1036 1.8 christos || IS_INSN_TYPE (CSTBIT_INS)) 1037 1.8 christos { 1038 1.1 christos if (symbol_with_s) 1039 1.8 christos as_bad (_("operand %d: illegal use expression: `%s`"), cur_arg_num + 1, str); 1040 1.1 christos if (symbol_with_at_got) 1041 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20; 1042 1.1 christos else if (symbol_with_at_gotc) 1043 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20; 1044 1.1 christos else if (symbol_with_m) 1045 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_ABS20; 1046 1.8 christos else /* Default to (symbol_with_l) */ 1047 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_ABS24; 1048 1.8 christos } 1049 1.8 christos else if (IS_INSN_TYPE (BRANCH_NEQ_INS)) 1050 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_DISP4; 1051 1.8 christos break; 1052 1.8 christos 1053 1.8 christos case arg_ic: 1054 1.8 christos if (IS_INSN_TYPE (ARITH_INS)) 1055 1.8 christos { 1056 1.1 christos if (symbol_with_at_got) 1057 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20; 1058 1.1 christos else if (symbol_with_at_gotc) 1059 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20; 1060 1.1 christos else if (symbol_with_s) 1061 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_IMM4; 1062 1.8 christos else if (symbol_with_m) 1063 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_IMM20; 1064 1.8 christos else if (symbol_with_at) 1065 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_IMM32a; 1066 1.8 christos else /* Default to (symbol_with_l) */ 1067 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_IMM32; 1068 1.8 christos } 1069 1.8 christos else if (IS_INSN_TYPE (ARITH_BYTE_INS)) 1070 1.8 christos { 1071 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_IMM16; 1072 1.8 christos } 1073 1.8 christos break; 1074 1.8 christos default: 1075 1.8 christos break; 1076 1.8 christos } 1077 1.1 christos break; 1078 1.1 christos 1079 1.1 christos default: 1080 1.1 christos cur_arg->X_op = cr16_ins->exp.X_op; 1081 1.1 christos break; 1082 1.1 christos } 1083 1.1 christos 1084 1.1 christos input_line_pointer = saved_input_line_pointer; 1085 1.1 christos return; 1086 1.1 christos } 1087 1.1 christos 1088 1.1 christos /* Retrieve the opcode image of a given register. 1089 1.1 christos If the register is illegal for the current instruction, 1090 1.1 christos issue an error. */ 1091 1.1 christos 1092 1.1 christos static int 1093 1.1 christos getreg_image (reg r) 1094 1.1 christos { 1095 1.1 christos const reg_entry *rreg; 1096 1.1 christos char *reg_name; 1097 1.1 christos int is_procreg = 0; /* Nonzero means argument should be processor reg. */ 1098 1.1 christos 1099 1.1 christos /* Check whether the register is in registers table. */ 1100 1.1 christos if (r < MAX_REG) 1101 1.1 christos rreg = cr16_regtab + r; 1102 1.1 christos else /* Register not found. */ 1103 1.1 christos { 1104 1.1 christos as_bad (_("Unknown register: `%d'"), r); 1105 1.1 christos return 0; 1106 1.1 christos } 1107 1.1 christos 1108 1.1 christos reg_name = rreg->name; 1109 1.1 christos 1110 1.8 christos /* Issue a error message when register is illegal. */ 1111 1.8 christos #define IMAGE_ERR \ 1112 1.8 christos as_bad (_("Illegal register (`%s') in Instruction: `%s'"), \ 1113 1.6 christos reg_name, ins_parse); 1114 1.1 christos 1115 1.1 christos switch (rreg->type) 1116 1.1 christos { 1117 1.1 christos case CR16_R_REGTYPE: 1118 1.1 christos if (! is_procreg) 1119 1.8 christos return rreg->image; 1120 1.1 christos else 1121 1.8 christos IMAGE_ERR; 1122 1.6 christos break; 1123 1.1 christos 1124 1.1 christos case CR16_P_REGTYPE: 1125 1.1 christos return rreg->image; 1126 1.1 christos break; 1127 1.1 christos 1128 1.1 christos default: 1129 1.1 christos IMAGE_ERR; 1130 1.6 christos break; 1131 1.1 christos } 1132 1.1 christos 1133 1.1 christos return 0; 1134 1.1 christos } 1135 1.1 christos 1136 1.1 christos /* Parsing different types of operands 1137 1.1 christos -> constants Immediate/Absolute/Relative numbers 1138 1.1 christos -> Labels Relocatable symbols 1139 1.1 christos -> (reg pair base) Register pair base 1140 1.1 christos -> (rbase) Register base 1141 1.1 christos -> disp(rbase) Register relative 1142 1.1 christos -> [rinx]disp(reg pair) Register index with reg pair mode 1143 1.1 christos -> disp(rbase,ridx,scl) Register index mode. */ 1144 1.1 christos 1145 1.1 christos static void 1146 1.1 christos set_operand (char *operand, ins * cr16_ins) 1147 1.1 christos { 1148 1.6 christos char *operandS; /* Pointer to start of sub-operand. */ 1149 1.6 christos char *operandE; /* Pointer to end of sub-operand. */ 1150 1.1 christos 1151 1.1 christos argument *cur_arg = &cr16_ins->arg[cur_arg_num]; /* Current argument. */ 1152 1.1 christos 1153 1.1 christos /* Initialize pointers. */ 1154 1.1 christos operandS = operandE = operand; 1155 1.1 christos 1156 1.1 christos switch (cur_arg->type) 1157 1.1 christos { 1158 1.1 christos case arg_ic: /* Case $0x18. */ 1159 1.1 christos operandS++; 1160 1.6 christos /* Fall through. */ 1161 1.1 christos case arg_c: /* Case 0x18. */ 1162 1.1 christos /* Set constant. */ 1163 1.1 christos process_label_constant (operandS, cr16_ins); 1164 1.1 christos 1165 1.1 christos if (cur_arg->type != arg_ic) 1166 1.8 christos cur_arg->type = arg_c; 1167 1.1 christos break; 1168 1.1 christos 1169 1.1 christos case arg_icr: /* Case $0x18(r1). */ 1170 1.1 christos operandS++; 1171 1.1 christos case arg_cr: /* Case 0x18(r1). */ 1172 1.1 christos /* Set displacement constant. */ 1173 1.1 christos while (*operandE != '(') 1174 1.8 christos operandE++; 1175 1.1 christos *operandE = '\0'; 1176 1.1 christos process_label_constant (operandS, cr16_ins); 1177 1.1 christos operandS = operandE; 1178 1.6 christos /* Fall through. */ 1179 1.1 christos case arg_rbase: /* Case (r1) or (r1,r0). */ 1180 1.1 christos operandS++; 1181 1.1 christos /* Set register base. */ 1182 1.1 christos while (*operandE != ')') 1183 1.8 christos operandE++; 1184 1.1 christos *operandE = '\0'; 1185 1.1 christos if ((cur_arg->r = get_register (operandS)) == nullregister) 1186 1.8 christos as_bad (_("Illegal register `%s' in Instruction `%s'"), 1187 1.8 christos operandS, ins_parse); 1188 1.1 christos 1189 1.1 christos /* set the arg->rp, if reg is "r12" or "r13" or "14" or "15" */ 1190 1.1 christos if ((cur_arg->type != arg_rbase) 1191 1.8 christos && ((getreg_image (cur_arg->r) == 12) 1192 1.8 christos || (getreg_image (cur_arg->r) == 13) 1193 1.8 christos || (getreg_image (cur_arg->r) == 14) 1194 1.8 christos || (getreg_image (cur_arg->r) == 15))) 1195 1.8 christos { 1196 1.8 christos cur_arg->type = arg_crp; 1197 1.8 christos cur_arg->rp = cur_arg->r; 1198 1.8 christos } 1199 1.1 christos break; 1200 1.1 christos 1201 1.1 christos case arg_crp: /* Case 0x18(r1,r0). */ 1202 1.1 christos /* Set displacement constant. */ 1203 1.1 christos while (*operandE != '(') 1204 1.8 christos operandE++; 1205 1.1 christos *operandE = '\0'; 1206 1.1 christos process_label_constant (operandS, cr16_ins); 1207 1.1 christos operandS = operandE; 1208 1.1 christos operandS++; 1209 1.1 christos /* Set register pair base. */ 1210 1.1 christos while (*operandE != ')') 1211 1.8 christos operandE++; 1212 1.1 christos *operandE = '\0'; 1213 1.1 christos if ((cur_arg->rp = get_register_pair (operandS)) == nullregister) 1214 1.8 christos as_bad (_("Illegal register pair `%s' in Instruction `%s'"), 1215 1.8 christos operandS, ins_parse); 1216 1.1 christos break; 1217 1.1 christos 1218 1.1 christos case arg_idxr: 1219 1.1 christos /* Set register pair base. */ 1220 1.1 christos if ((strchr (operandS,'(') != NULL)) 1221 1.8 christos { 1222 1.10 christos while ((*operandE != '(') && (! is_whitespace (*operandE))) 1223 1.8 christos operandE++; 1224 1.8 christos if ((cur_arg->rp = get_index_register_pair (operandE)) == nullregister) 1225 1.8 christos as_bad (_("Illegal register pair `%s' in Instruction `%s'"), 1226 1.8 christos operandS, ins_parse); 1227 1.8 christos *operandE++ = '\0'; 1228 1.8 christos cur_arg->type = arg_idxrp; 1229 1.8 christos } 1230 1.1 christos else 1231 1.8 christos cur_arg->rp = -1; 1232 1.1 christos 1233 1.8 christos operandE = operandS; 1234 1.1 christos /* Set displacement constant. */ 1235 1.1 christos while (*operandE != ']') 1236 1.8 christos operandE++; 1237 1.1 christos process_label_constant (++operandE, cr16_ins); 1238 1.1 christos *operandE++ = '\0'; 1239 1.1 christos operandE = operandS; 1240 1.1 christos 1241 1.1 christos /* Set index register . */ 1242 1.1 christos operandS = strchr (operandE,'['); 1243 1.1 christos if (operandS != NULL) 1244 1.8 christos { /* Eliminate '[', detach from rest of operand. */ 1245 1.8 christos *operandS++ = '\0'; 1246 1.1 christos 1247 1.8 christos operandE = strchr (operandS, ']'); 1248 1.1 christos 1249 1.8 christos if (operandE == NULL) 1250 1.8 christos as_bad (_("unmatched '['")); 1251 1.8 christos else 1252 1.8 christos { /* Eliminate ']' and make sure it was the last thing 1253 1.8 christos in the string. */ 1254 1.8 christos *operandE = '\0'; 1255 1.8 christos if (*(operandE + 1) != '\0') 1256 1.8 christos as_bad (_("garbage after index spec ignored")); 1257 1.8 christos } 1258 1.8 christos } 1259 1.1 christos 1260 1.1 christos if ((cur_arg->i_r = get_index_register (operandS)) == nullregister) 1261 1.8 christos as_bad (_("Illegal register `%s' in Instruction `%s'"), 1262 1.8 christos operandS, ins_parse); 1263 1.1 christos *operandE = '\0'; 1264 1.1 christos *operandS = '\0'; 1265 1.1 christos break; 1266 1.1 christos 1267 1.1 christos default: 1268 1.1 christos break; 1269 1.1 christos } 1270 1.1 christos } 1271 1.1 christos 1272 1.1 christos /* Parse a single operand. 1273 1.1 christos operand - Current operand to parse. 1274 1.1 christos cr16_ins - Current assembled instruction. */ 1275 1.1 christos 1276 1.1 christos static void 1277 1.1 christos parse_operand (char *operand, ins * cr16_ins) 1278 1.1 christos { 1279 1.1 christos int ret_val; 1280 1.1 christos argument *cur_arg = cr16_ins->arg + cur_arg_num; /* Current argument. */ 1281 1.1 christos 1282 1.1 christos /* Initialize the type to NULL before parsing. */ 1283 1.1 christos cur_arg->type = nullargs; 1284 1.1 christos 1285 1.1 christos /* Check whether this is a condition code . */ 1286 1.1 christos if ((IS_INSN_MNEMONIC ("b")) && ((ret_val = get_cc (operand)) != -1)) 1287 1.1 christos { 1288 1.1 christos cur_arg->type = arg_cc; 1289 1.1 christos cur_arg->cc = ret_val; 1290 1.1 christos cur_arg->X_op = O_register; 1291 1.1 christos return; 1292 1.1 christos } 1293 1.1 christos 1294 1.1 christos /* Check whether this is a general processor register. */ 1295 1.1 christos if ((ret_val = get_register (operand)) != nullregister) 1296 1.1 christos { 1297 1.1 christos cur_arg->type = arg_r; 1298 1.1 christos cur_arg->r = ret_val; 1299 1.1 christos cur_arg->X_op = 0; 1300 1.1 christos return; 1301 1.1 christos } 1302 1.1 christos 1303 1.1 christos /* Check whether this is a general processor register pair. */ 1304 1.1 christos if ((operand[0] == '(') 1305 1.1 christos && ((ret_val = get_register_pair (operand)) != nullregister)) 1306 1.1 christos { 1307 1.1 christos cur_arg->type = arg_rp; 1308 1.1 christos cur_arg->rp = ret_val; 1309 1.1 christos cur_arg->X_op = O_register; 1310 1.1 christos return; 1311 1.1 christos } 1312 1.1 christos 1313 1.1 christos /* Check whether the operand is a processor register. 1314 1.1 christos For "lprd" and "sprd" instruction, only 32 bit 1315 1.1 christos processor registers used. */ 1316 1.1 christos if (!(IS_INSN_MNEMONIC ("lprd") || (IS_INSN_MNEMONIC ("sprd"))) 1317 1.1 christos && ((ret_val = get_pregister (operand)) != nullpregister)) 1318 1.1 christos { 1319 1.1 christos cur_arg->type = arg_pr; 1320 1.1 christos cur_arg->pr = ret_val; 1321 1.1 christos cur_arg->X_op = O_register; 1322 1.1 christos return; 1323 1.1 christos } 1324 1.1 christos 1325 1.1 christos /* Check whether this is a processor register - 32 bit. */ 1326 1.1 christos if ((ret_val = get_pregisterp (operand)) != nullpregister) 1327 1.1 christos { 1328 1.1 christos cur_arg->type = arg_prp; 1329 1.1 christos cur_arg->prp = ret_val; 1330 1.1 christos cur_arg->X_op = O_register; 1331 1.1 christos return; 1332 1.1 christos } 1333 1.1 christos 1334 1.1 christos /* Deal with special characters. */ 1335 1.1 christos switch (operand[0]) 1336 1.1 christos { 1337 1.1 christos case '$': 1338 1.1 christos if (strchr (operand, '(') != NULL) 1339 1.8 christos cur_arg->type = arg_icr; 1340 1.1 christos else 1341 1.8 christos cur_arg->type = arg_ic; 1342 1.1 christos goto set_params; 1343 1.1 christos break; 1344 1.1 christos 1345 1.1 christos case '(': 1346 1.1 christos cur_arg->type = arg_rbase; 1347 1.1 christos goto set_params; 1348 1.1 christos break; 1349 1.1 christos 1350 1.1 christos case '[': 1351 1.1 christos cur_arg->type = arg_idxr; 1352 1.1 christos goto set_params; 1353 1.1 christos break; 1354 1.1 christos 1355 1.1 christos default: 1356 1.1 christos break; 1357 1.1 christos } 1358 1.1 christos 1359 1.1 christos if (strchr (operand, '(') != NULL) 1360 1.1 christos { 1361 1.1 christos if (strchr (operand, ',') != NULL 1362 1.8 christos && (strchr (operand, ',') > strchr (operand, '('))) 1363 1.8 christos cur_arg->type = arg_crp; 1364 1.1 christos else 1365 1.8 christos cur_arg->type = arg_cr; 1366 1.1 christos } 1367 1.1 christos else 1368 1.1 christos cur_arg->type = arg_c; 1369 1.1 christos 1370 1.8 christos /* Parse an operand according to its type. */ 1371 1.1 christos set_params: 1372 1.1 christos cur_arg->constant = 0; 1373 1.1 christos set_operand (operand, cr16_ins); 1374 1.1 christos } 1375 1.1 christos 1376 1.1 christos /* Parse the various operands. Each operand is then analyzed to fillup 1377 1.1 christos the fields in the cr16_ins data structure. */ 1378 1.1 christos 1379 1.1 christos static void 1380 1.1 christos parse_operands (ins * cr16_ins, char *operands) 1381 1.1 christos { 1382 1.1 christos char *operandS; /* Operands string. */ 1383 1.1 christos char *operandH, *operandT; /* Single operand head/tail pointers. */ 1384 1.1 christos int allocated = 0; /* Indicates a new operands string was allocated.*/ 1385 1.1 christos char *operand[MAX_OPERANDS];/* Separating the operands. */ 1386 1.1 christos int op_num = 0; /* Current operand number we are parsing. */ 1387 1.1 christos int bracket_flag = 0; /* Indicates a bracket '(' was found. */ 1388 1.1 christos int sq_bracket_flag = 0; /* Indicates a square bracket '[' was found. */ 1389 1.1 christos 1390 1.1 christos /* Preprocess the list of registers, if necessary. */ 1391 1.1 christos operandS = operandH = operandT = operands; 1392 1.1 christos 1393 1.1 christos while (*operandT != '\0') 1394 1.1 christos { 1395 1.1 christos if (*operandT == ',' && bracket_flag != 1 && sq_bracket_flag != 1) 1396 1.8 christos { 1397 1.8 christos *operandT++ = '\0'; 1398 1.8 christos operand[op_num++] = strdup (operandH); 1399 1.8 christos operandH = operandT; 1400 1.8 christos continue; 1401 1.8 christos } 1402 1.1 christos 1403 1.10 christos if (is_whitespace (*operandT)) 1404 1.8 christos as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse); 1405 1.1 christos 1406 1.1 christos if (*operandT == '(') 1407 1.8 christos bracket_flag = 1; 1408 1.1 christos else if (*operandT == '[') 1409 1.8 christos sq_bracket_flag = 1; 1410 1.1 christos 1411 1.1 christos if (*operandT == ')') 1412 1.8 christos { 1413 1.8 christos if (bracket_flag) 1414 1.8 christos bracket_flag = 0; 1415 1.8 christos else 1416 1.8 christos as_fatal (_("Missing matching brackets : `%s'"), ins_parse); 1417 1.8 christos } 1418 1.1 christos else if (*operandT == ']') 1419 1.8 christos { 1420 1.8 christos if (sq_bracket_flag) 1421 1.8 christos sq_bracket_flag = 0; 1422 1.8 christos else 1423 1.8 christos as_fatal (_("Missing matching brackets : `%s'"), ins_parse); 1424 1.8 christos } 1425 1.1 christos 1426 1.1 christos if (bracket_flag == 1 && *operandT == ')') 1427 1.8 christos bracket_flag = 0; 1428 1.1 christos else if (sq_bracket_flag == 1 && *operandT == ']') 1429 1.8 christos sq_bracket_flag = 0; 1430 1.1 christos 1431 1.1 christos operandT++; 1432 1.1 christos } 1433 1.1 christos 1434 1.1 christos /* Adding the last operand. */ 1435 1.1 christos operand[op_num++] = strdup (operandH); 1436 1.1 christos cr16_ins->nargs = op_num; 1437 1.1 christos 1438 1.1 christos /* Verifying correct syntax of operands (all brackets should be closed). */ 1439 1.1 christos if (bracket_flag || sq_bracket_flag) 1440 1.1 christos as_fatal (_("Missing matching brackets : `%s'"), ins_parse); 1441 1.1 christos 1442 1.1 christos /* Now we parse each operand separately. */ 1443 1.1 christos for (op_num = 0; op_num < cr16_ins->nargs; op_num++) 1444 1.1 christos { 1445 1.1 christos cur_arg_num = op_num; 1446 1.1 christos parse_operand (operand[op_num], cr16_ins); 1447 1.1 christos free (operand[op_num]); 1448 1.1 christos } 1449 1.1 christos 1450 1.1 christos if (allocated) 1451 1.1 christos free (operandS); 1452 1.1 christos } 1453 1.1 christos 1454 1.1 christos /* Get the trap index in dispatch table, given its name. 1455 1.1 christos This routine is used by assembling the 'excp' instruction. */ 1456 1.1 christos 1457 1.1 christos static int 1458 1.1 christos gettrap (char *s) 1459 1.1 christos { 1460 1.1 christos const trap_entry *trap; 1461 1.1 christos 1462 1.1 christos for (trap = cr16_traps; trap < (cr16_traps + NUMTRAPS); trap++) 1463 1.1 christos if (strcasecmp (trap->name, s) == 0) 1464 1.1 christos return trap->entry; 1465 1.1 christos 1466 1.6 christos /* To make compatible with CR16 4.1 tools, the below 3-lines of 1467 1.1 christos * code added. Refer: Development Tracker item #123 */ 1468 1.1 christos for (trap = cr16_traps; trap < (cr16_traps + NUMTRAPS); trap++) 1469 1.1 christos if (trap->entry == (unsigned int) atoi (s)) 1470 1.1 christos return trap->entry; 1471 1.1 christos 1472 1.1 christos as_bad (_("Unknown exception: `%s'"), s); 1473 1.1 christos return 0; 1474 1.1 christos } 1475 1.1 christos 1476 1.1 christos /* Top level module where instruction parsing starts. 1477 1.1 christos cr16_ins - data structure holds some information. 1478 1.1 christos operands - holds the operands part of the whole instruction. */ 1479 1.1 christos 1480 1.1 christos static void 1481 1.1 christos parse_insn (ins *insn, char *operands) 1482 1.1 christos { 1483 1.1 christos int i; 1484 1.1 christos 1485 1.1 christos /* Handle instructions with no operands. */ 1486 1.1 christos for (i = 0; cr16_no_op_insn[i] != NULL; i++) 1487 1.1 christos { 1488 1.1 christos if (streq (cr16_no_op_insn[i], instruction->mnemonic)) 1489 1.1 christos { 1490 1.1 christos insn->nargs = 0; 1491 1.1 christos return; 1492 1.1 christos } 1493 1.1 christos } 1494 1.1 christos 1495 1.1 christos /* Handle 'excp' instructions. */ 1496 1.1 christos if (IS_INSN_MNEMONIC ("excp")) 1497 1.1 christos { 1498 1.1 christos insn->nargs = 1; 1499 1.1 christos insn->arg[0].type = arg_ic; 1500 1.1 christos insn->arg[0].constant = gettrap (operands); 1501 1.1 christos insn->arg[0].X_op = O_constant; 1502 1.1 christos return; 1503 1.1 christos } 1504 1.1 christos 1505 1.1 christos if (operands != NULL) 1506 1.1 christos parse_operands (insn, operands); 1507 1.1 christos } 1508 1.1 christos 1509 1.1 christos /* bCC instruction requires special handling. */ 1510 1.1 christos static char * 1511 1.1 christos get_b_cc (char * op) 1512 1.1 christos { 1513 1.1 christos unsigned int i; 1514 1.1 christos 1515 1.8 christos if (op[1] == 0 || (op[2] != 0 && op[3] != 0)) 1516 1.8 christos return NULL; 1517 1.1 christos 1518 1.1 christos for (i = 0; i < cr16_num_cc ; i++) 1519 1.8 christos if (streq (op + 1, cr16_b_cond_tab[i])) 1520 1.1 christos return (char *) cr16_b_cond_tab[i]; 1521 1.1 christos 1522 1.1 christos return NULL; 1523 1.1 christos } 1524 1.1 christos 1525 1.1 christos /* bCC instruction requires special handling. */ 1526 1.1 christos static int 1527 1.1 christos is_bcc_insn (char * op) 1528 1.1 christos { 1529 1.1 christos if (!(streq (op, "bal") || streq (op, "beq0b") || streq (op, "bnq0b") 1530 1.8 christos || streq (op, "beq0w") || streq (op, "bnq0w"))) 1531 1.1 christos if ((op[0] == 'b') && (get_b_cc (op) != NULL)) 1532 1.1 christos return 1; 1533 1.1 christos return 0; 1534 1.1 christos } 1535 1.1 christos 1536 1.1 christos /* Cinv instruction requires special handling. */ 1537 1.1 christos 1538 1.1 christos static void 1539 1.1 christos check_cinv_options (char * operand) 1540 1.1 christos { 1541 1.1 christos char *p = operand; 1542 1.1 christos 1543 1.1 christos while (*++p != ']') 1544 1.1 christos { 1545 1.1 christos switch (*p) 1546 1.1 christos { 1547 1.1 christos case ',': 1548 1.1 christos case 'i': 1549 1.1 christos case 'u': 1550 1.1 christos case 'd': 1551 1.1 christos break; 1552 1.1 christos default: 1553 1.10 christos if (is_whitespace (*p)) 1554 1.10 christos break; 1555 1.1 christos as_bad (_("Illegal `cinv' parameter: `%c'"), *p); 1556 1.1 christos } 1557 1.1 christos } 1558 1.1 christos } 1559 1.1 christos 1560 1.1 christos /* Retrieve the opcode image of a given register pair. 1561 1.1 christos If the register is illegal for the current instruction, 1562 1.1 christos issue an error. */ 1563 1.1 christos 1564 1.1 christos static int 1565 1.1 christos getregp_image (reg r) 1566 1.1 christos { 1567 1.1 christos const reg_entry *rreg; 1568 1.1 christos char *reg_name; 1569 1.1 christos 1570 1.1 christos /* Check whether the register is in registers table. */ 1571 1.1 christos if (r < MAX_REG) 1572 1.1 christos rreg = cr16_regptab + r; 1573 1.1 christos /* Register not found. */ 1574 1.1 christos else 1575 1.1 christos { 1576 1.1 christos as_bad (_("Unknown register pair: `%d'"), r); 1577 1.1 christos return 0; 1578 1.1 christos } 1579 1.1 christos 1580 1.1 christos reg_name = rreg->name; 1581 1.1 christos 1582 1.8 christos /* Issue a error message when register pair is illegal. */ 1583 1.8 christos #define RPAIR_IMAGE_ERR \ 1584 1.8 christos as_bad (_("Illegal register pair (`%s') in Instruction: `%s'"), \ 1585 1.8 christos reg_name, ins_parse); \ 1586 1.1 christos break; 1587 1.1 christos 1588 1.1 christos switch (rreg->type) 1589 1.1 christos { 1590 1.1 christos case CR16_RP_REGTYPE: 1591 1.1 christos return rreg->image; 1592 1.1 christos default: 1593 1.1 christos RPAIR_IMAGE_ERR; 1594 1.1 christos } 1595 1.1 christos 1596 1.1 christos return 0; 1597 1.1 christos } 1598 1.1 christos 1599 1.1 christos /* Retrieve the opcode image of a given index register pair. 1600 1.1 christos If the register is illegal for the current instruction, 1601 1.1 christos issue an error. */ 1602 1.1 christos 1603 1.1 christos static int 1604 1.1 christos getidxregp_image (reg r) 1605 1.1 christos { 1606 1.1 christos const reg_entry *rreg; 1607 1.1 christos char *reg_name; 1608 1.1 christos 1609 1.1 christos /* Check whether the register is in registers table. */ 1610 1.1 christos if (r < MAX_REG) 1611 1.1 christos rreg = cr16_regptab + r; 1612 1.1 christos /* Register not found. */ 1613 1.1 christos else 1614 1.1 christos { 1615 1.1 christos as_bad (_("Unknown register pair: `%d'"), r); 1616 1.1 christos return 0; 1617 1.1 christos } 1618 1.1 christos 1619 1.1 christos reg_name = rreg->name; 1620 1.1 christos 1621 1.8 christos /* Issue a error message when register pair is illegal. */ 1622 1.8 christos #define IDX_RPAIR_IMAGE_ERR \ 1623 1.1 christos as_bad (_("Illegal index register pair (`%s') in Instruction: `%s'"), \ 1624 1.8 christos reg_name, ins_parse); \ 1625 1.1 christos 1626 1.1 christos if (rreg->type == CR16_RP_REGTYPE) 1627 1.1 christos { 1628 1.1 christos switch (rreg->image) 1629 1.8 christos { 1630 1.8 christos case 0: return 0; break; 1631 1.8 christos case 2: return 1; break; 1632 1.8 christos case 4: return 2; break; 1633 1.8 christos case 6: return 3; break; 1634 1.8 christos case 8: return 4; break; 1635 1.8 christos case 10: return 5; break; 1636 1.8 christos case 3: return 6; break; 1637 1.8 christos case 5: return 7; break; 1638 1.8 christos default: 1639 1.8 christos break; 1640 1.8 christos } 1641 1.1 christos } 1642 1.1 christos 1643 1.1 christos IDX_RPAIR_IMAGE_ERR; 1644 1.1 christos return 0; 1645 1.1 christos } 1646 1.1 christos 1647 1.6 christos /* Retrieve the opcode image of a given processor register. 1648 1.1 christos If the register is illegal for the current instruction, 1649 1.1 christos issue an error. */ 1650 1.1 christos static int 1651 1.1 christos getprocreg_image (int r) 1652 1.1 christos { 1653 1.1 christos const reg_entry *rreg; 1654 1.1 christos char *reg_name; 1655 1.1 christos 1656 1.1 christos /* Check whether the register is in registers table. */ 1657 1.1 christos if (r >= MAX_REG && r < MAX_PREG) 1658 1.1 christos rreg = &cr16_pregtab[r - MAX_REG]; 1659 1.1 christos /* Register not found. */ 1660 1.1 christos else 1661 1.1 christos { 1662 1.1 christos as_bad (_("Unknown processor register : `%d'"), r); 1663 1.1 christos return 0; 1664 1.1 christos } 1665 1.1 christos 1666 1.1 christos reg_name = rreg->name; 1667 1.1 christos 1668 1.8 christos /* Issue a error message when register pair is illegal. */ 1669 1.8 christos #define PROCREG_IMAGE_ERR \ 1670 1.8 christos as_bad (_("Illegal processor register (`%s') in Instruction: `%s'"), \ 1671 1.8 christos reg_name, ins_parse); \ 1672 1.1 christos break; 1673 1.1 christos 1674 1.1 christos switch (rreg->type) 1675 1.1 christos { 1676 1.1 christos case CR16_P_REGTYPE: 1677 1.1 christos return rreg->image; 1678 1.1 christos default: 1679 1.1 christos PROCREG_IMAGE_ERR; 1680 1.1 christos } 1681 1.1 christos 1682 1.1 christos return 0; 1683 1.1 christos } 1684 1.1 christos 1685 1.6 christos /* Retrieve the opcode image of a given processor register. 1686 1.1 christos If the register is illegal for the current instruction, 1687 1.1 christos issue an error. */ 1688 1.1 christos static int 1689 1.1 christos getprocregp_image (int r) 1690 1.1 christos { 1691 1.1 christos const reg_entry *rreg; 1692 1.1 christos char *reg_name; 1693 1.1 christos int pregptab_disp = 0; 1694 1.1 christos 1695 1.1 christos /* Check whether the register is in registers table. */ 1696 1.1 christos if (r >= MAX_REG && r < MAX_PREG) 1697 1.1 christos { 1698 1.1 christos r = r - MAX_REG; 1699 1.1 christos switch (r) 1700 1.8 christos { 1701 1.8 christos case 4: pregptab_disp = 1; break; 1702 1.8 christos case 6: pregptab_disp = 2; break; 1703 1.8 christos case 8: 1704 1.8 christos case 9: 1705 1.8 christos case 10: 1706 1.8 christos pregptab_disp = 3; break; 1707 1.8 christos case 12: 1708 1.8 christos pregptab_disp = 4; break; 1709 1.8 christos case 14: 1710 1.8 christos pregptab_disp = 5; break; 1711 1.8 christos default: break; 1712 1.8 christos } 1713 1.1 christos rreg = &cr16_pregptab[r - pregptab_disp]; 1714 1.1 christos } 1715 1.1 christos /* Register not found. */ 1716 1.1 christos else 1717 1.1 christos { 1718 1.1 christos as_bad (_("Unknown processor register (32 bit) : `%d'"), r); 1719 1.1 christos return 0; 1720 1.1 christos } 1721 1.1 christos 1722 1.1 christos reg_name = rreg->name; 1723 1.1 christos 1724 1.8 christos /* Issue a error message when register pair is illegal. */ 1725 1.8 christos #define PROCREGP_IMAGE_ERR \ 1726 1.8 christos as_bad (_("Illegal 32 bit - processor register (`%s') in Instruction: `%s'"), \ 1727 1.8 christos reg_name, ins_parse); \ 1728 1.1 christos break; 1729 1.1 christos 1730 1.1 christos switch (rreg->type) 1731 1.1 christos { 1732 1.1 christos case CR16_P_REGTYPE: 1733 1.1 christos return rreg->image; 1734 1.1 christos default: 1735 1.1 christos PROCREGP_IMAGE_ERR; 1736 1.1 christos } 1737 1.1 christos 1738 1.1 christos return 0; 1739 1.1 christos } 1740 1.1 christos 1741 1.1 christos /* Routine used to represent integer X using NBITS bits. */ 1742 1.1 christos 1743 1.1 christos static long 1744 1.1 christos getconstant (long x, int nbits) 1745 1.1 christos { 1746 1.8 christos if ((unsigned) nbits >= sizeof (x) * CHAR_BIT) 1747 1.8 christos return x; 1748 1.8 christos return x & ((1UL << nbits) - 1); 1749 1.1 christos } 1750 1.1 christos 1751 1.1 christos /* Print a constant value to 'output_opcode': 1752 1.1 christos ARG holds the operand's type and value. 1753 1.1 christos SHIFT represents the location of the operand to be print into. 1754 1.1 christos NBITS determines the size (in bits) of the constant. */ 1755 1.1 christos 1756 1.1 christos static void 1757 1.1 christos print_constant (int nbits, int shift, argument *arg) 1758 1.1 christos { 1759 1.1 christos unsigned long mask = 0; 1760 1.8 christos unsigned long constant = getconstant (arg->constant, nbits); 1761 1.1 christos 1762 1.1 christos switch (nbits) 1763 1.1 christos { 1764 1.1 christos case 32: 1765 1.1 christos case 28: 1766 1.1 christos /* mask the upper part of the constant, that is, the bits 1767 1.8 christos going to the lowest byte of output_opcode[0]. 1768 1.8 christos The upper part of output_opcode[1] is always filled, 1769 1.8 christos therefore it is always masked with 0xFFFF. */ 1770 1.1 christos mask = (1 << (nbits - 16)) - 1; 1771 1.1 christos /* Divide the constant between two consecutive words : 1772 1.8 christos 0 1 2 3 1773 1.8 christos +---------+---------+---------+---------+ 1774 1.8 christos | | X X X X | x X x X | | 1775 1.8 christos +---------+---------+---------+---------+ 1776 1.8 christos output_opcode[0] output_opcode[1] */ 1777 1.1 christos 1778 1.1 christos CR16_PRINT (0, (constant >> WORD_SHIFT) & mask, 0); 1779 1.8 christos CR16_PRINT (1, constant & 0xFFFF, WORD_SHIFT); 1780 1.1 christos break; 1781 1.1 christos 1782 1.1 christos case 21: 1783 1.6 christos if ((nbits == 21) && (IS_INSN_TYPE (LD_STOR_INS))) 1784 1.6 christos nbits = 20; 1785 1.6 christos /* Fall through. */ 1786 1.1 christos case 24: 1787 1.1 christos case 22: 1788 1.1 christos case 20: 1789 1.1 christos /* mask the upper part of the constant, that is, the bits 1790 1.8 christos going to the lowest byte of output_opcode[0]. 1791 1.8 christos The upper part of output_opcode[1] is always filled, 1792 1.8 christos therefore it is always masked with 0xFFFF. */ 1793 1.1 christos mask = (1 << (nbits - 16)) - 1; 1794 1.1 christos /* Divide the constant between two consecutive words : 1795 1.8 christos 0 1 2 3 1796 1.8 christos +---------+---------+---------+---------+ 1797 1.8 christos | | X X X X | - X - X | | 1798 1.8 christos +---------+---------+---------+---------+ 1799 1.8 christos output_opcode[0] output_opcode[1] */ 1800 1.8 christos 1801 1.8 christos if (instruction->size > 2 && shift == WORD_SHIFT) 1802 1.8 christos { 1803 1.8 christos if (arg->type == arg_idxrp) 1804 1.8 christos { 1805 1.8 christos CR16_PRINT (0, ((constant >> WORD_SHIFT) & mask) << 8, 0); 1806 1.8 christos CR16_PRINT (1, constant & 0xFFFF, WORD_SHIFT); 1807 1.8 christos } 1808 1.8 christos else 1809 1.8 christos { 1810 1.8 christos CR16_PRINT (0, 1811 1.8 christos ((((constant >> WORD_SHIFT) & mask & 0xf) << 8) 1812 1.8 christos | (((constant >> WORD_SHIFT) & mask & 0xf0) >> 4)), 1813 1.8 christos 0); 1814 1.8 christos CR16_PRINT (1, constant & 0xFFFF, WORD_SHIFT); 1815 1.8 christos } 1816 1.8 christos } 1817 1.1 christos else 1818 1.8 christos CR16_PRINT (0, constant, shift); 1819 1.1 christos break; 1820 1.1 christos 1821 1.1 christos case 14: 1822 1.1 christos if (arg->type == arg_idxrp) 1823 1.8 christos { 1824 1.8 christos if (instruction->size == 2) 1825 1.8 christos { 1826 1.8 christos CR16_PRINT (0, (constant) & 0xf, shift); /* 0-3 bits. */ 1827 1.8 christos CR16_PRINT (0, (constant >> 4) & 0x3, shift + 20); /* 4-5 bits. */ 1828 1.8 christos CR16_PRINT (0, (constant >> 6) & 0x3, shift + 14); /* 6-7 bits. */ 1829 1.8 christos CR16_PRINT (0, (constant >> 8) & 0x3f, shift + 8); /* 8-13 bits. */ 1830 1.8 christos } 1831 1.8 christos else 1832 1.8 christos CR16_PRINT (0, constant, shift); 1833 1.8 christos } 1834 1.1 christos break; 1835 1.1 christos 1836 1.1 christos case 16: 1837 1.1 christos case 12: 1838 1.1 christos /* When instruction size is 3 and 'shift' is 16, a 16-bit constant is 1839 1.8 christos always filling the upper part of output_opcode[1]. If we mistakenly 1840 1.8 christos write it to output_opcode[0], the constant prefix (that is, 'match') 1841 1.8 christos will be overridden. 1842 1.8 christos 0 1 2 3 1843 1.8 christos +---------+---------+---------+---------+ 1844 1.8 christos | 'match' | | X X X X | | 1845 1.8 christos +---------+---------+---------+---------+ 1846 1.8 christos output_opcode[0] output_opcode[1] */ 1847 1.1 christos 1848 1.8 christos if (instruction->size > 2 && shift == WORD_SHIFT) 1849 1.8 christos CR16_PRINT (1, constant, WORD_SHIFT); 1850 1.1 christos else 1851 1.8 christos CR16_PRINT (0, constant, shift); 1852 1.1 christos break; 1853 1.1 christos 1854 1.1 christos case 8: 1855 1.8 christos CR16_PRINT (0, (constant / 2) & 0xf, shift); 1856 1.8 christos CR16_PRINT (0, (constant / 2) >> 4, shift + 8); 1857 1.1 christos break; 1858 1.1 christos 1859 1.1 christos default: 1860 1.8 christos CR16_PRINT (0, constant, shift); 1861 1.1 christos break; 1862 1.1 christos } 1863 1.1 christos } 1864 1.1 christos 1865 1.1 christos /* Print an operand to 'output_opcode', which later on will be 1866 1.1 christos printed to the object file: 1867 1.1 christos ARG holds the operand's type, size and value. 1868 1.1 christos SHIFT represents the printing location of operand. 1869 1.1 christos NBITS determines the size (in bits) of a constant operand. */ 1870 1.1 christos 1871 1.1 christos static void 1872 1.1 christos print_operand (int nbits, int shift, argument *arg) 1873 1.1 christos { 1874 1.1 christos switch (arg->type) 1875 1.1 christos { 1876 1.1 christos case arg_cc: 1877 1.1 christos CR16_PRINT (0, arg->cc, shift); 1878 1.1 christos break; 1879 1.1 christos 1880 1.1 christos case arg_r: 1881 1.1 christos CR16_PRINT (0, getreg_image (arg->r), shift); 1882 1.1 christos break; 1883 1.1 christos 1884 1.1 christos case arg_rp: 1885 1.1 christos CR16_PRINT (0, getregp_image (arg->rp), shift); 1886 1.1 christos break; 1887 1.1 christos 1888 1.1 christos case arg_pr: 1889 1.1 christos CR16_PRINT (0, getprocreg_image (arg->pr), shift); 1890 1.1 christos break; 1891 1.1 christos 1892 1.1 christos case arg_prp: 1893 1.1 christos CR16_PRINT (0, getprocregp_image (arg->prp), shift); 1894 1.1 christos break; 1895 1.1 christos 1896 1.1 christos case arg_idxrp: 1897 1.1 christos /* 16 12 8 6 0 1898 1.8 christos +-----------------------------+ 1899 1.8 christos | r_index | disp | rp_base | 1900 1.8 christos +-----------------------------+ */ 1901 1.1 christos 1902 1.1 christos if (instruction->size == 3) 1903 1.8 christos { 1904 1.8 christos CR16_PRINT (0, getidxregp_image (arg->rp), 0); 1905 1.8 christos CR16_PRINT (0, getreg_image (arg->i_r) & 1, 3); 1906 1.8 christos } 1907 1.1 christos else 1908 1.8 christos { 1909 1.8 christos CR16_PRINT (0, getidxregp_image (arg->rp), 16); 1910 1.8 christos CR16_PRINT (0, getreg_image (arg->i_r) & 1, 19); 1911 1.8 christos } 1912 1.1 christos print_constant (nbits, shift, arg); 1913 1.1 christos break; 1914 1.1 christos 1915 1.1 christos case arg_idxr: 1916 1.8 christos CR16_PRINT (0, getreg_image (arg->i_r) & 1, 1917 1.8 christos (IS_INSN_TYPE (CSTBIT_INS) 1918 1.8 christos && instruction->mnemonic[4] == 'b') ? 23 : 24); 1919 1.1 christos print_constant (nbits, shift, arg); 1920 1.1 christos break; 1921 1.1 christos 1922 1.1 christos case arg_ic: 1923 1.1 christos case arg_c: 1924 1.1 christos print_constant (nbits, shift, arg); 1925 1.1 christos break; 1926 1.1 christos 1927 1.1 christos case arg_rbase: 1928 1.1 christos CR16_PRINT (0, getreg_image (arg->r), shift); 1929 1.1 christos break; 1930 1.1 christos 1931 1.1 christos case arg_cr: 1932 1.8 christos print_constant (nbits, shift, arg); 1933 1.1 christos /* Add the register argument to the output_opcode. */ 1934 1.8 christos CR16_PRINT (0, getreg_image (arg->r), shift - 16); 1935 1.1 christos break; 1936 1.1 christos 1937 1.1 christos case arg_crp: 1938 1.8 christos print_constant (nbits, shift, arg); 1939 1.8 christos if ((IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS)) 1940 1.8 christos && instruction->size == 1) 1941 1.8 christos CR16_PRINT (0, getregp_image (arg->rp), 16); 1942 1.8 christos else if (instruction->size > 1) 1943 1.8 christos CR16_PRINT (0, getregp_image (arg->rp), (shift + 16) & 31); 1944 1.1 christos else 1945 1.8 christos CR16_PRINT (0, getregp_image (arg->rp), shift); 1946 1.1 christos break; 1947 1.1 christos 1948 1.1 christos default: 1949 1.1 christos break; 1950 1.1 christos } 1951 1.1 christos } 1952 1.1 christos 1953 1.1 christos /* Retrieve the number of operands for the current assembled instruction. */ 1954 1.1 christos 1955 1.1 christos static int 1956 1.1 christos get_number_of_operands (void) 1957 1.1 christos { 1958 1.1 christos int i; 1959 1.1 christos 1960 1.1 christos for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++) 1961 1.1 christos ; 1962 1.1 christos return i; 1963 1.1 christos } 1964 1.1 christos 1965 1.1 christos /* Verify that the number NUM can be represented in BITS bits (that is, 1966 1.1 christos within its permitted range), based on the instruction's FLAGS. 1967 1.1 christos If UPDATE is nonzero, update the value of NUM if necessary. 1968 1.1 christos Return OP_LEGAL upon success, actual error type upon failure. */ 1969 1.1 christos 1970 1.1 christos static op_err 1971 1.1 christos check_range (long *num, int bits, int unsigned flags, int update) 1972 1.1 christos { 1973 1.8 christos int32_t min, max; 1974 1.5 christos op_err retval = OP_LEGAL; 1975 1.8 christos int32_t value = *num; 1976 1.1 christos 1977 1.1 christos /* Verify operand value is even. */ 1978 1.1 christos if (flags & OP_EVEN) 1979 1.1 christos { 1980 1.1 christos if (value % 2) 1981 1.8 christos return OP_NOT_EVEN; 1982 1.1 christos } 1983 1.1 christos 1984 1.1 christos if (flags & OP_DEC) 1985 1.1 christos { 1986 1.1 christos value -= 1; 1987 1.1 christos if (update) 1988 1.8 christos *num = value; 1989 1.1 christos } 1990 1.1 christos 1991 1.1 christos if (flags & OP_SHIFT) 1992 1.1 christos { 1993 1.1 christos value >>= 1; 1994 1.1 christos if (update) 1995 1.8 christos *num = value; 1996 1.1 christos } 1997 1.1 christos else if (flags & OP_SHIFT_DEC) 1998 1.1 christos { 1999 1.1 christos value = (value >> 1) - 1; 2000 1.1 christos if (update) 2001 1.8 christos *num = value; 2002 1.1 christos } 2003 1.1 christos 2004 1.1 christos if (flags & OP_ABS20) 2005 1.1 christos { 2006 1.1 christos if (value > 0xEFFFF) 2007 1.8 christos return OP_OUT_OF_RANGE; 2008 1.1 christos } 2009 1.1 christos 2010 1.1 christos if (flags & OP_ESC) 2011 1.1 christos { 2012 1.1 christos if (value == 0xB || value == 0x9) 2013 1.8 christos return OP_OUT_OF_RANGE; 2014 1.1 christos else if (value == -1) 2015 1.8 christos { 2016 1.8 christos if (update) 2017 1.8 christos *num = 9; 2018 1.8 christos return retval; 2019 1.8 christos } 2020 1.1 christos } 2021 1.1 christos 2022 1.1 christos if (flags & OP_ESC1) 2023 1.1 christos { 2024 1.1 christos if (value > 13) 2025 1.8 christos return OP_OUT_OF_RANGE; 2026 1.1 christos } 2027 1.1 christos 2028 1.8 christos if (bits == 0) 2029 1.8 christos { 2030 1.8 christos if (value != 0) 2031 1.8 christos retval = OP_OUT_OF_RANGE; 2032 1.8 christos return retval; 2033 1.8 christos } 2034 1.8 christos 2035 1.8 christos if (flags & OP_SIGNED) 2036 1.8 christos { 2037 1.8 christos max = (1U << (bits - 1)) - 1; 2038 1.8 christos min = - (1U << (bits - 1)); 2039 1.8 christos if (value > max || value < min) 2040 1.8 christos retval = OP_OUT_OF_RANGE; 2041 1.8 christos } 2042 1.8 christos else if (flags & OP_UNSIGNED) 2043 1.8 christos { 2044 1.8 christos max = (1U << (bits - 1) << 1) - 1; 2045 1.8 christos if ((uint32_t) value > (uint32_t) max) 2046 1.8 christos retval = OP_OUT_OF_RANGE; 2047 1.8 christos } 2048 1.8 christos else if (flags & OP_NEG) 2049 1.8 christos { 2050 1.8 christos min = - ((1U << (bits - 1)) - 1); 2051 1.8 christos if (value < min) 2052 1.8 christos retval = OP_OUT_OF_RANGE; 2053 1.8 christos } 2054 1.8 christos return retval; 2055 1.1 christos } 2056 1.1 christos 2057 1.6 christos /* Bunch of error checking. 2058 1.1 christos The checks are made after a matching instruction was found. */ 2059 1.1 christos 2060 1.1 christos static void 2061 1.1 christos warn_if_needed (ins *insn) 2062 1.1 christos { 2063 1.1 christos /* If the post-increment address mode is used and the load/store 2064 1.1 christos source register is the same as rbase, the result of the 2065 1.1 christos instruction is undefined. */ 2066 1.1 christos if (IS_INSN_TYPE (LD_STOR_INS_INC)) 2067 1.1 christos { 2068 1.1 christos /* Enough to verify that one of the arguments is a simple reg. */ 2069 1.1 christos if ((insn->arg[0].type == arg_r) || (insn->arg[1].type == arg_r)) 2070 1.8 christos if (insn->arg[0].r == insn->arg[1].r) 2071 1.8 christos as_bad (_("Same src/dest register is used (`r%d'), " 2072 1.8 christos "result is undefined"), insn->arg[0].r); 2073 1.1 christos } 2074 1.1 christos 2075 1.1 christos if (IS_INSN_MNEMONIC ("pop") 2076 1.1 christos || IS_INSN_MNEMONIC ("push") 2077 1.1 christos || IS_INSN_MNEMONIC ("popret")) 2078 1.1 christos { 2079 1.1 christos unsigned int count = insn->arg[0].constant, reg_val; 2080 1.1 christos 2081 1.6 christos /* Check if count operand caused to save/retrieve the RA twice 2082 1.8 christos to generate warning message. */ 2083 1.8 christos if (insn->nargs > 2) 2084 1.8 christos { 2085 1.8 christos reg_val = getreg_image (insn->arg[1].r); 2086 1.8 christos 2087 1.8 christos if ( ((reg_val == 9) && (count > 7)) 2088 1.8 christos || ((reg_val == 10) && (count > 6)) 2089 1.8 christos || ((reg_val == 11) && (count > 5)) 2090 1.8 christos || ((reg_val == 12) && (count > 4)) 2091 1.8 christos || ((reg_val == 13) && (count > 2)) 2092 1.8 christos || ((reg_val == 14) && (count > 0))) 2093 1.8 christos as_warn (_("RA register is saved twice.")); 2094 1.8 christos 2095 1.8 christos /* Check if the third operand is "RA" or "ra" */ 2096 1.8 christos if (!(((insn->arg[2].r) == ra) || ((insn->arg[2].r) == RA))) 2097 1.8 christos as_bad (_("`%s' Illegal use of registers."), ins_parse); 2098 1.8 christos } 2099 1.1 christos 2100 1.1 christos if (insn->nargs > 1) 2101 1.8 christos { 2102 1.8 christos reg_val = getreg_image (insn->arg[1].r); 2103 1.1 christos 2104 1.8 christos /* If register is a register pair ie r12/r13/r14 in operand1, then 2105 1.8 christos the count constant should be validated. */ 2106 1.8 christos if (((reg_val == 11) && (count > 7)) 2107 1.8 christos || ((reg_val == 12) && (count > 6)) 2108 1.8 christos || ((reg_val == 13) && (count > 4)) 2109 1.8 christos || ((reg_val == 14) && (count > 2)) 2110 1.8 christos || ((reg_val == 15) && (count > 0))) 2111 1.8 christos as_bad (_("`%s' Illegal count-register combination."), ins_parse); 2112 1.8 christos } 2113 1.8 christos else 2114 1.8 christos { 2115 1.8 christos /* Check if the operand is "RA" or "ra" */ 2116 1.8 christos if (!(((insn->arg[0].r) == ra) || ((insn->arg[0].r) == RA))) 2117 1.8 christos as_bad (_("`%s' Illegal use of register."), ins_parse); 2118 1.8 christos } 2119 1.1 christos } 2120 1.1 christos 2121 1.1 christos /* Some instruction assume the stack pointer as rptr operand. 2122 1.1 christos Issue an error when the register to be loaded is also SP. */ 2123 1.1 christos if (instruction->flags & NO_SP) 2124 1.1 christos { 2125 1.1 christos if (getreg_image (insn->arg[1].r) == getreg_image (sp)) 2126 1.8 christos as_bad (_("`%s' has undefined result"), ins_parse); 2127 1.1 christos } 2128 1.1 christos 2129 1.1 christos /* If the rptr register is specified as one of the registers to be loaded, 2130 1.1 christos the final contents of rptr are undefined. Thus, we issue an error. */ 2131 1.1 christos if (instruction->flags & NO_RPTR) 2132 1.1 christos { 2133 1.1 christos if ((1 << getreg_image (insn->arg[0].r)) & insn->arg[1].constant) 2134 1.8 christos as_bad (_("Same src/dest register is used (`r%d'),result is undefined"), 2135 1.8 christos getreg_image (insn->arg[0].r)); 2136 1.1 christos } 2137 1.1 christos } 2138 1.1 christos 2139 1.1 christos /* In some cases, we need to adjust the instruction pointer although a 2140 1.1 christos match was already found. Here, we gather all these cases. 2141 1.1 christos Returns 1 if instruction pointer was adjusted, otherwise 0. */ 2142 1.1 christos 2143 1.1 christos static int 2144 1.1 christos adjust_if_needed (ins *insn ATTRIBUTE_UNUSED) 2145 1.1 christos { 2146 1.1 christos int ret_value = 0; 2147 1.1 christos 2148 1.1 christos if ((IS_INSN_TYPE (CSTBIT_INS)) || (IS_INSN_TYPE (LD_STOR_INS))) 2149 1.1 christos { 2150 1.1 christos if ((instruction->operands[0].op_type == abs24) 2151 1.8 christos && ((insn->arg[0].constant) > 0xF00000)) 2152 1.8 christos { 2153 1.8 christos insn->arg[0].constant &= 0xFFFFF; 2154 1.8 christos instruction--; 2155 1.8 christos ret_value = 1; 2156 1.8 christos } 2157 1.1 christos } 2158 1.1 christos 2159 1.1 christos return ret_value; 2160 1.1 christos } 2161 1.1 christos 2162 1.1 christos /* Assemble a single instruction: 2163 1.1 christos INSN is already parsed (that is, all operand values and types are set). 2164 1.1 christos For instruction to be assembled, we need to find an appropriate template in 2165 1.1 christos the instruction table, meeting the following conditions: 2166 1.1 christos 1: Has the same number of operands. 2167 1.1 christos 2: Has the same operand types. 2168 1.1 christos 3: Each operand size is sufficient to represent the instruction's values. 2169 1.1 christos Returns 1 upon success, 0 upon failure. */ 2170 1.1 christos 2171 1.1 christos static int 2172 1.5 christos assemble_insn (const char *mnemonic, ins *insn) 2173 1.1 christos { 2174 1.1 christos /* Type of each operand in the current template. */ 2175 1.1 christos argtype cur_type[MAX_OPERANDS]; 2176 1.1 christos /* Size (in bits) of each operand in the current template. */ 2177 1.1 christos unsigned int cur_size[MAX_OPERANDS]; 2178 1.1 christos /* Flags of each operand in the current template. */ 2179 1.1 christos unsigned int cur_flags[MAX_OPERANDS]; 2180 1.1 christos /* Instruction type to match. */ 2181 1.1 christos unsigned int ins_type; 2182 1.1 christos /* Boolean flag to mark whether a match was found. */ 2183 1.1 christos int match = 0; 2184 1.1 christos int i; 2185 1.1 christos /* Nonzero if an instruction with same number of operands was found. */ 2186 1.1 christos int found_same_number_of_operands = 0; 2187 1.1 christos /* Nonzero if an instruction with same argument types was found. */ 2188 1.1 christos int found_same_argument_types = 0; 2189 1.1 christos /* Nonzero if a constant was found within the required range. */ 2190 1.1 christos int found_const_within_range = 0; 2191 1.1 christos /* Argument number of an operand with invalid type. */ 2192 1.1 christos int invalid_optype = -1; 2193 1.1 christos /* Argument number of an operand with invalid constant value. */ 2194 1.1 christos int invalid_const = -1; 2195 1.1 christos /* Operand error (used for issuing various constant error messages). */ 2196 1.1 christos op_err op_error, const_err = OP_LEGAL; 2197 1.1 christos 2198 1.8 christos /* Retrieve data (based on FUNC) for each operand of a given instruction. */ 2199 1.8 christos #define GET_CURRENT_DATA(FUNC, ARRAY) \ 2200 1.8 christos for (i = 0; i < insn->nargs; i++) \ 2201 1.1 christos ARRAY[i] = FUNC (instruction->operands[i].op_type) 2202 1.1 christos 2203 1.1 christos #define GET_CURRENT_TYPE GET_CURRENT_DATA (get_optype, cur_type) 2204 1.1 christos #define GET_CURRENT_SIZE GET_CURRENT_DATA (get_opbits, cur_size) 2205 1.1 christos #define GET_CURRENT_FLAGS GET_CURRENT_DATA (get_opflags, cur_flags) 2206 1.1 christos 2207 1.1 christos /* Instruction has no operands -> only copy the constant opcode. */ 2208 1.1 christos if (insn->nargs == 0) 2209 1.1 christos { 2210 1.1 christos output_opcode[0] = BIN (instruction->match, instruction->match_bits); 2211 1.1 christos return 1; 2212 1.1 christos } 2213 1.1 christos 2214 1.1 christos /* In some case, same mnemonic can appear with different instruction types. 2215 1.1 christos For example, 'storb' is supported with 3 different types : 2216 1.1 christos LD_STOR_INS, LD_STOR_INS_INC, STOR_IMM_INS. 2217 1.1 christos We assume that when reaching this point, the instruction type was 2218 1.1 christos pre-determined. We need to make sure that the type stays the same 2219 1.1 christos during a search for matching instruction. */ 2220 1.1 christos ins_type = CR16_INS_TYPE (instruction->flags); 2221 1.1 christos 2222 1.1 christos while (/* Check that match is still not found. */ 2223 1.8 christos match != 1 2224 1.8 christos /* Check we didn't get to end of table. */ 2225 1.8 christos && instruction->mnemonic != NULL 2226 1.8 christos /* Check that the actual mnemonic is still available. */ 2227 1.8 christos && IS_INSN_MNEMONIC (mnemonic) 2228 1.8 christos /* Check that the instruction type wasn't changed. */ 2229 1.8 christos && IS_INSN_TYPE (ins_type)) 2230 1.1 christos { 2231 1.1 christos /* Check whether number of arguments is legal. */ 2232 1.1 christos if (get_number_of_operands () != insn->nargs) 2233 1.8 christos goto next_insn; 2234 1.1 christos found_same_number_of_operands = 1; 2235 1.1 christos 2236 1.1 christos /* Initialize arrays with data of each operand in current template. */ 2237 1.1 christos GET_CURRENT_TYPE; 2238 1.1 christos GET_CURRENT_SIZE; 2239 1.1 christos GET_CURRENT_FLAGS; 2240 1.1 christos 2241 1.1 christos /* Check for type compatibility. */ 2242 1.1 christos for (i = 0; i < insn->nargs; i++) 2243 1.8 christos { 2244 1.8 christos if (cur_type[i] != insn->arg[i].type) 2245 1.8 christos { 2246 1.8 christos if (invalid_optype == -1) 2247 1.8 christos invalid_optype = i + 1; 2248 1.8 christos goto next_insn; 2249 1.8 christos } 2250 1.8 christos } 2251 1.1 christos found_same_argument_types = 1; 2252 1.1 christos 2253 1.1 christos for (i = 0; i < insn->nargs; i++) 2254 1.8 christos { 2255 1.8 christos /* If 'bal' instruction size is '2' and reg operand is not 'ra' 2256 1.8 christos then goto next instruction. */ 2257 1.8 christos if (IS_INSN_MNEMONIC ("bal") && (i == 0) 2258 1.8 christos && (instruction->size == 2) && (insn->arg[i].rp != 14)) 2259 1.8 christos goto next_insn; 2260 1.8 christos 2261 1.8 christos /* If 'storb' instruction with 'sp' reg and 16-bit disp of 2262 1.8 christos * reg-pair, leads to undefined trap, so this should use 2263 1.8 christos * 20-bit disp of reg-pair. */ 2264 1.8 christos if (IS_INSN_MNEMONIC ("storb") && (instruction->size == 2) 2265 1.8 christos && (insn->arg[i].r == 15) && (insn->arg[i + 1].type == arg_crp)) 2266 1.8 christos goto next_insn; 2267 1.8 christos 2268 1.8 christos /* Only check range - don't update the constant's value, since the 2269 1.8 christos current instruction may not be the last we try to match. 2270 1.8 christos The constant's value will be updated later, right before printing 2271 1.8 christos it to the object file. */ 2272 1.8 christos if ((insn->arg[i].X_op == O_constant) 2273 1.8 christos && (op_error = check_range (&insn->arg[i].constant, cur_size[i], 2274 1.8 christos cur_flags[i], 0))) 2275 1.8 christos { 2276 1.8 christos if (invalid_const == -1) 2277 1.8 christos { 2278 1.8 christos invalid_const = i + 1; 2279 1.8 christos const_err = op_error; 2280 1.8 christos } 2281 1.8 christos goto next_insn; 2282 1.8 christos } 2283 1.8 christos /* For symbols, we make sure the relocation size (which was already 2284 1.8 christos determined) is sufficient. */ 2285 1.8 christos else if ((insn->arg[i].X_op == O_symbol) 2286 1.8 christos && ((bfd_reloc_type_lookup (stdoutput, insn->rtype))->bitsize 2287 1.8 christos > cur_size[i])) 2288 1.8 christos goto next_insn; 2289 1.8 christos } 2290 1.1 christos found_const_within_range = 1; 2291 1.1 christos 2292 1.1 christos /* If we got till here -> Full match is found. */ 2293 1.1 christos match = 1; 2294 1.1 christos break; 2295 1.1 christos 2296 1.8 christos /* Try again with next instruction. */ 2297 1.8 christos next_insn: 2298 1.1 christos instruction++; 2299 1.1 christos } 2300 1.1 christos 2301 1.1 christos if (!match) 2302 1.1 christos { 2303 1.1 christos /* We haven't found a match - instruction can't be assembled. */ 2304 1.1 christos if (!found_same_number_of_operands) 2305 1.8 christos as_bad (_("Incorrect number of operands")); 2306 1.1 christos else if (!found_same_argument_types) 2307 1.8 christos as_bad (_("Illegal type of operand (arg %d)"), invalid_optype); 2308 1.1 christos else if (!found_const_within_range) 2309 1.8 christos { 2310 1.8 christos switch (const_err) 2311 1.8 christos { 2312 1.8 christos case OP_OUT_OF_RANGE: 2313 1.8 christos as_bad (_("Operand out of range (arg %d)"), invalid_const); 2314 1.8 christos break; 2315 1.8 christos case OP_NOT_EVEN: 2316 1.8 christos as_bad (_("Operand has odd displacement (arg %d)"), invalid_const); 2317 1.8 christos break; 2318 1.8 christos default: 2319 1.8 christos as_bad (_("Illegal operand (arg %d)"), invalid_const); 2320 1.8 christos break; 2321 1.8 christos } 2322 1.8 christos } 2323 1.1 christos 2324 1.8 christos return 0; 2325 1.1 christos } 2326 1.1 christos else 2327 1.1 christos /* Full match - print the encoding to output file. */ 2328 1.1 christos { 2329 1.6 christos /* Make further checking (such that couldn't be made earlier). 2330 1.8 christos Warn the user if necessary. */ 2331 1.1 christos warn_if_needed (insn); 2332 1.1 christos 2333 1.1 christos /* Check whether we need to adjust the instruction pointer. */ 2334 1.1 christos if (adjust_if_needed (insn)) 2335 1.8 christos /* If instruction pointer was adjusted, we need to update 2336 1.8 christos the size of the current template operands. */ 2337 1.8 christos GET_CURRENT_SIZE; 2338 1.1 christos 2339 1.1 christos for (i = 0; i < insn->nargs; i++) 2340 1.8 christos { 2341 1.8 christos int j = instruction->flags & REVERSE_MATCH ? 2342 1.8 christos i == 0 ? 1 : 2343 1.8 christos i == 1 ? 0 : i : 2344 1.8 christos i; 2345 1.8 christos 2346 1.8 christos /* This time, update constant value before printing it. */ 2347 1.8 christos if ((insn->arg[j].X_op == O_constant) 2348 1.8 christos && (check_range (&insn->arg[j].constant, cur_size[j], 2349 1.8 christos cur_flags[j], 1) != OP_LEGAL)) 2350 1.8 christos as_fatal (_("Illegal operand (arg %d)"), j+1); 2351 1.8 christos } 2352 1.1 christos 2353 1.1 christos /* First, copy the instruction's opcode. */ 2354 1.1 christos output_opcode[0] = BIN (instruction->match, instruction->match_bits); 2355 1.1 christos 2356 1.1 christos for (i = 0; i < insn->nargs; i++) 2357 1.8 christos { 2358 1.8 christos /* For BAL (ra),disp17 instruction only. And also set the 2359 1.8 christos DISP24a relocation type. */ 2360 1.8 christos if (IS_INSN_MNEMONIC ("bal") && (instruction->size == 2) && i == 0) 2361 1.8 christos { 2362 1.8 christos insn->rtype = BFD_RELOC_CR16_DISP24a; 2363 1.8 christos continue; 2364 1.8 christos } 2365 1.8 christos cur_arg_num = i; 2366 1.8 christos print_operand (cur_size[i], instruction->operands[i].shift, 2367 1.8 christos &insn->arg[i]); 2368 1.8 christos } 2369 1.1 christos } 2370 1.1 christos 2371 1.1 christos return 1; 2372 1.1 christos } 2373 1.1 christos 2374 1.1 christos /* Print the instruction. 2375 1.1 christos Handle also cases where the instruction is relaxable/relocatable. */ 2376 1.1 christos 2377 1.1 christos static void 2378 1.1 christos print_insn (ins *insn) 2379 1.1 christos { 2380 1.1 christos unsigned int i, j, insn_size; 2381 1.1 christos char *this_frag; 2382 1.1 christos unsigned short words[4]; 2383 1.1 christos int addr_mod; 2384 1.1 christos 2385 1.1 christos /* Arrange the insn encodings in a WORD size array. */ 2386 1.1 christos for (i = 0, j = 0; i < 2; i++) 2387 1.1 christos { 2388 1.1 christos words[j++] = (output_opcode[i] >> 16) & 0xFFFF; 2389 1.1 christos words[j++] = output_opcode[i] & 0xFFFF; 2390 1.1 christos } 2391 1.1 christos 2392 1.8 christos /* Handle relocation. */ 2393 1.8 christos if ((instruction->flags & RELAXABLE) && relocatable) 2394 1.8 christos { 2395 1.8 christos int relax_subtype; 2396 1.8 christos /* Write the maximal instruction size supported. */ 2397 1.8 christos insn_size = INSN_MAX_SIZE; 2398 1.8 christos 2399 1.8 christos if (IS_INSN_TYPE (BRANCH_INS)) 2400 1.8 christos { 2401 1.8 christos switch (insn->rtype) 2402 1.8 christos { 2403 1.8 christos case BFD_RELOC_CR16_DISP24: 2404 1.8 christos relax_subtype = 2; 2405 1.8 christos break; 2406 1.8 christos case BFD_RELOC_CR16_DISP16: 2407 1.8 christos relax_subtype = 1; 2408 1.8 christos break; 2409 1.8 christos default: 2410 1.8 christos relax_subtype = 0; 2411 1.8 christos break; 2412 1.8 christos } 2413 1.8 christos } 2414 1.8 christos else 2415 1.8 christos abort (); 2416 1.8 christos 2417 1.8 christos this_frag = frag_var (rs_machine_dependent, insn_size *2, 2418 1.8 christos 4, relax_subtype, 2419 1.8 christos insn->exp.X_add_symbol, 2420 1.8 christos 0, 2421 1.8 christos 0); 2422 1.8 christos } 2423 1.8 christos else 2424 1.8 christos { 2425 1.8 christos insn_size = instruction->size; 2426 1.8 christos this_frag = frag_more (insn_size * 2); 2427 1.8 christos 2428 1.8 christos if ((relocatable) && (insn->rtype != BFD_RELOC_NONE)) 2429 1.8 christos { 2430 1.8 christos reloc_howto_type *reloc_howto; 2431 1.8 christos int size; 2432 1.8 christos 2433 1.8 christos reloc_howto = bfd_reloc_type_lookup (stdoutput, insn->rtype); 2434 1.8 christos 2435 1.8 christos if (!reloc_howto) 2436 1.8 christos abort (); 2437 1.8 christos 2438 1.8 christos size = bfd_get_reloc_size (reloc_howto); 2439 1.8 christos 2440 1.8 christos if (size < 1 || size > 4) 2441 1.8 christos abort (); 2442 1.8 christos 2443 1.8 christos fix_new_exp (frag_now, this_frag - frag_now->fr_literal, 2444 1.8 christos size, &insn->exp, reloc_howto->pc_relative, 2445 1.8 christos insn->rtype); 2446 1.8 christos } 2447 1.8 christos } 2448 1.1 christos 2449 1.1 christos /* Verify a 2-byte code alignment. */ 2450 1.1 christos addr_mod = frag_now_fix () & 1; 2451 1.1 christos if (frag_now->has_code && frag_now->insn_addr != addr_mod) 2452 1.1 christos as_bad (_("instruction address is not a multiple of 2")); 2453 1.1 christos frag_now->insn_addr = addr_mod; 2454 1.1 christos frag_now->has_code = 1; 2455 1.1 christos 2456 1.1 christos /* Write the instruction encoding to frag. */ 2457 1.1 christos for (i = 0; i < insn_size; i++) 2458 1.1 christos { 2459 1.10 christos md_number_to_chars (this_frag, words[i], 2); 2460 1.1 christos this_frag += 2; 2461 1.1 christos } 2462 1.1 christos } 2463 1.1 christos 2464 1.5 christos /* Actually assemble an instruction. */ 2465 1.5 christos 2466 1.5 christos static void 2467 1.5 christos cr16_assemble (const char *op, char *param) 2468 1.5 christos { 2469 1.5 christos ins cr16_ins; 2470 1.5 christos 2471 1.5 christos /* Find the instruction. */ 2472 1.10 christos instruction = str_hash_find (cr16_inst_hash, op); 2473 1.5 christos if (instruction == NULL) 2474 1.5 christos { 2475 1.5 christos as_bad (_("Unknown opcode: `%s'"), op); 2476 1.5 christos return; 2477 1.5 christos } 2478 1.5 christos 2479 1.5 christos /* Tie dwarf2 debug info to the address at the start of the insn. */ 2480 1.5 christos dwarf2_emit_insn (0); 2481 1.5 christos 2482 1.5 christos /* Parse the instruction's operands. */ 2483 1.5 christos parse_insn (&cr16_ins, param); 2484 1.5 christos 2485 1.5 christos /* Assemble the instruction - return upon failure. */ 2486 1.5 christos if (assemble_insn (op, &cr16_ins) == 0) 2487 1.5 christos return; 2488 1.5 christos 2489 1.5 christos /* Print the instruction. */ 2490 1.5 christos print_insn (&cr16_ins); 2491 1.5 christos } 2492 1.5 christos 2493 1.1 christos /* This is the guts of the machine-dependent assembler. OP points to a 2494 1.1 christos machine dependent instruction. This function is supposed to emit 2495 1.1 christos the frags/bytes it assembles to. */ 2496 1.1 christos 2497 1.1 christos void 2498 1.1 christos md_assemble (char *op) 2499 1.1 christos { 2500 1.1 christos ins cr16_ins; 2501 1.1 christos char *param, param1[32]; 2502 1.1 christos 2503 1.1 christos /* Reset global variables for a new instruction. */ 2504 1.1 christos reset_vars (op); 2505 1.1 christos 2506 1.1 christos /* Strip the mnemonic. */ 2507 1.10 christos for (param = op; *param != 0 && !is_whitespace (*param); param++) 2508 1.1 christos ; 2509 1.1 christos *param++ = '\0'; 2510 1.1 christos 2511 1.6 christos /* bCC instructions and adjust the mnemonic by adding extra white spaces. */ 2512 1.1 christos if (is_bcc_insn (op)) 2513 1.1 christos { 2514 1.1 christos strcpy (param1, get_b_cc (op)); 2515 1.1 christos strcat (param1,","); 2516 1.1 christos strcat (param1, param); 2517 1.10 christos param = param1; 2518 1.5 christos cr16_assemble ("b", param); 2519 1.5 christos return; 2520 1.1 christos } 2521 1.1 christos 2522 1.1 christos /* Checking the cinv options and adjust the mnemonic by removing the 2523 1.1 christos extra white spaces. */ 2524 1.1 christos if (streq ("cinv", op)) 2525 1.1 christos { 2526 1.8 christos /* Validate the cinv options. */ 2527 1.8 christos unsigned int op_len, param_len; 2528 1.1 christos check_cinv_options (param); 2529 1.8 christos op_len = strlen (op); 2530 1.8 christos param_len = strlen (param) + 1; 2531 1.8 christos memmove (op + op_len, param, param_len); 2532 1.1 christos } 2533 1.1 christos 2534 1.1 christos /* MAPPING - SHIFT INSN, if imm4/imm16 positive values 2535 1.1 christos lsh[b/w] imm4/imm6, reg ==> ashu[b/w] imm4/imm16, reg 2536 1.6 christos as CR16 core doesn't support lsh[b/w] right shift operations. */ 2537 1.1 christos if ((streq ("lshb", op) || streq ("lshw", op) || streq ("lshd", op)) 2538 1.1 christos && (param [0] == '$')) 2539 1.1 christos { 2540 1.1 christos strcpy (param1, param); 2541 1.1 christos /* Find the instruction. */ 2542 1.10 christos instruction = str_hash_find (cr16_inst_hash, op); 2543 1.8 christos parse_operands (&cr16_ins, param1); 2544 1.1 christos if (((&cr16_ins)->arg[0].type == arg_ic) 2545 1.8 christos && ((&cr16_ins)->arg[0].constant >= 0)) 2546 1.8 christos { 2547 1.8 christos if (streq ("lshb", op)) 2548 1.8 christos cr16_assemble ("ashub", param); 2549 1.8 christos else if (streq ("lshd", op)) 2550 1.8 christos cr16_assemble ("ashud", param); 2551 1.8 christos else 2552 1.8 christos cr16_assemble ("ashuw", param); 2553 1.8 christos return; 2554 1.8 christos } 2555 1.1 christos } 2556 1.1 christos 2557 1.5 christos cr16_assemble (op, param); 2558 1.1 christos } 2559