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