1 1.1.1.3 christos /* tc-dlx.c -- Assemble for the DLX 2 1.1.1.11 christos Copyright (C) 2002-2026 Free Software Foundation, Inc. 3 1.1 skrll 4 1.1 skrll This file is part of GAS, the GNU Assembler. 5 1.1 skrll 6 1.1 skrll GAS is free software; you can redistribute it and/or modify 7 1.1 skrll it under the terms of the GNU General Public License as published by 8 1.1 skrll the Free Software Foundation; either version 3, or (at your option) 9 1.1 skrll any later version. 10 1.1 skrll 11 1.1 skrll GAS is distributed in the hope that it will be useful, 12 1.1 skrll but WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.1 skrll MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 1.1 skrll GNU General Public License for more details. 15 1.1 skrll 16 1.1 skrll You should have received a copy of the GNU General Public License 17 1.1 skrll along with GAS; see the file COPYING. If not, write to the Free 18 1.1 skrll Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 19 1.1 skrll 02110-1301, USA. */ 20 1.1 skrll 21 1.1 skrll /* Initially created by Kuang Hwa Lin, 3/20/2002. */ 22 1.1 skrll 23 1.1 skrll #include "as.h" 24 1.1.1.3 christos #include "safe-ctype.h" 25 1.1 skrll #include "tc-dlx.h" 26 1.1 skrll #include "opcode/dlx.h" 27 1.1.1.5 christos #include "elf/dlx.h" 28 1.1.1.5 christos #include "bfd/elf32-dlx.h" 29 1.1 skrll 30 1.1 skrll /* Make it easier to clone this machine desc into another one. */ 31 1.1 skrll #define machine_opcode dlx_opcode 32 1.1 skrll #define machine_opcodes dlx_opcodes 33 1.1 skrll #define machine_ip dlx_ip 34 1.1 skrll #define machine_it dlx_it 35 1.1 skrll 36 1.1 skrll #define NO_RELOC BFD_RELOC_NONE 37 1.1 skrll #define RELOC_DLX_REL26 BFD_RELOC_DLX_JMP26 38 1.1 skrll #define RELOC_DLX_16 BFD_RELOC_16 39 1.1 skrll #define RELOC_DLX_REL16 BFD_RELOC_16_PCREL_S2 40 1.1 skrll #define RELOC_DLX_HI16 BFD_RELOC_HI16_S 41 1.1 skrll #define RELOC_DLX_LO16 BFD_RELOC_LO16 42 1.1 skrll #define RELOC_DLX_VTINHERIT BFD_RELOC_VTABLE_INHERIT 43 1.1 skrll #define RELOC_DLX_VTENTRY BFD_RELOC_VTABLE_ENTRY 44 1.1 skrll 45 1.1 skrll /* handle of the OPCODE hash table */ 46 1.1.1.8 christos static htab_t op_hash = NULL; 47 1.1 skrll 48 1.1 skrll struct machine_it 49 1.1 skrll { 50 1.1 skrll char *error; 51 1.1 skrll unsigned long opcode; 52 1.1 skrll struct nlist *nlistp; 53 1.1 skrll expressionS exp; 54 1.1 skrll int pcrel; 55 1.1 skrll int size; 56 1.1 skrll int reloc_offset; /* Offset of reloc within insn. */ 57 1.1.1.5 christos bfd_reloc_code_real_type reloc; 58 1.1 skrll int HI; 59 1.1 skrll int LO; 60 1.1 skrll } 61 1.1 skrll the_insn; 62 1.1 skrll 63 1.1 skrll /* This array holds the chars that always start a comment. If the 64 1.1 skrll pre-processor is disabled, these aren't very useful. */ 65 1.1 skrll const char comment_chars[] = ";"; 66 1.1 skrll 67 1.1 skrll /* This array holds the chars that only start a comment at the beginning of 68 1.1 skrll a line. If the line seems to have the form '# 123 filename' 69 1.1 skrll .line and .file directives will appear in the pre-processed output. */ 70 1.1 skrll /* Note that input_file.c hand checks for '#' at the beginning of the 71 1.1 skrll first line of the input file. This is because the compiler outputs 72 1.1 skrll #NO_APP at the beginning of its output. */ 73 1.1 skrll /* Also note that comments like this one will always work. */ 74 1.1 skrll const char line_comment_chars[] = "#"; 75 1.1 skrll 76 1.1 skrll /* We needed an unused char for line separation to work around the 77 1.1 skrll lack of macros, using sed and such. */ 78 1.1 skrll const char line_separator_chars[] = "@"; 79 1.1 skrll 80 1.1 skrll /* Chars that can be used to separate mant from exp in floating point nums. */ 81 1.1 skrll const char EXP_CHARS[] = "eE"; 82 1.1 skrll 83 1.1 skrll /* Chars that mean this number is a floating point constant. 84 1.1 skrll As in 0f12.456 85 1.1 skrll or 0d1.2345e12. */ 86 1.1 skrll const char FLT_CHARS[] = "rRsSfFdDxXpP"; 87 1.1 skrll 88 1.1 skrll static void 89 1.1.1.5 christos insert_sreg (const char *regname, int regnum) 90 1.1 skrll { 91 1.1 skrll /* Must be large enough to hold the names of the special registers. */ 92 1.1 skrll char buf[80]; 93 1.1 skrll int i; 94 1.1 skrll 95 1.1.1.8 christos symbol_table_insert (symbol_new (regname, reg_section, 96 1.1.1.8 christos &zero_address_frag, regnum)); 97 1.1 skrll for (i = 0; regname[i]; i++) 98 1.1 skrll buf[i] = ISLOWER (regname[i]) ? TOUPPER (regname[i]) : regname[i]; 99 1.1 skrll buf[i] = '\0'; 100 1.1 skrll 101 1.1.1.8 christos symbol_table_insert (symbol_new (buf, reg_section, 102 1.1.1.8 christos &zero_address_frag, regnum)); 103 1.1 skrll } 104 1.1 skrll 105 1.1 skrll /* Install symbol definitions for assorted special registers. 106 1.1 skrll See MIPS Assembly Language Programmer's Guide page 1-4 */ 107 1.1 skrll 108 1.1 skrll static void 109 1.1 skrll define_some_regs (void) 110 1.1 skrll { 111 1.1 skrll /* Software representation. */ 112 1.1 skrll insert_sreg ("zero", 0); 113 1.1 skrll insert_sreg ("at", 1); 114 1.1 skrll insert_sreg ("v0", 2); 115 1.1 skrll insert_sreg ("v1", 3); 116 1.1 skrll insert_sreg ("a0", 4); 117 1.1 skrll insert_sreg ("a1", 5); 118 1.1 skrll insert_sreg ("a2", 6); 119 1.1 skrll insert_sreg ("a3", 7); 120 1.1 skrll insert_sreg ("t0", 8); 121 1.1 skrll insert_sreg ("t1", 9); 122 1.1 skrll insert_sreg ("t2", 10); 123 1.1 skrll insert_sreg ("t3", 11); 124 1.1 skrll insert_sreg ("t4", 12); 125 1.1 skrll insert_sreg ("t5", 13); 126 1.1 skrll insert_sreg ("t6", 14); 127 1.1 skrll insert_sreg ("t7", 15); 128 1.1 skrll insert_sreg ("s0", 16); 129 1.1 skrll insert_sreg ("s1", 17); 130 1.1 skrll insert_sreg ("s2", 18); 131 1.1 skrll insert_sreg ("s3", 19); 132 1.1 skrll insert_sreg ("s4", 20); 133 1.1 skrll insert_sreg ("s5", 21); 134 1.1 skrll insert_sreg ("s6", 22); 135 1.1 skrll insert_sreg ("s7", 23); 136 1.1 skrll insert_sreg ("t8", 24); 137 1.1 skrll insert_sreg ("t9", 25); 138 1.1 skrll insert_sreg ("k0", 26); 139 1.1 skrll insert_sreg ("k1", 27); 140 1.1 skrll insert_sreg ("gp", 28); 141 1.1 skrll insert_sreg ("sp", 29); 142 1.1 skrll insert_sreg ("fp", 30); 143 1.1 skrll insert_sreg ("ra", 31); 144 1.1 skrll /* Special registers. */ 145 1.1 skrll insert_sreg ("pc", 0); 146 1.1 skrll insert_sreg ("npc", 1); 147 1.1 skrll insert_sreg ("iad", 2); 148 1.1 skrll } 149 1.1 skrll 150 1.1 skrll /* Subroutine check the string to match an register. */ 151 1.1 skrll 152 1.1 skrll static int 153 1.1 skrll match_sft_register (char *name) 154 1.1 skrll { 155 1.1 skrll #define MAX_REG_NO 35 156 1.1 skrll /* Currently we have 35 software registers defined - 157 1.1 skrll we borrowed from MIPS. */ 158 1.1.1.5 christos static const char *soft_reg[] = 159 1.1 skrll { 160 1.1 skrll "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", 161 1.1 skrll "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", 162 1.1 skrll "s0", "s1", "s2", "s3", "s4", "s5", "s7", "k0", "k1", 163 1.1 skrll "gp", "sp", "fp", "ra", "pc", "npc", "iad", 164 1.1 skrll "EndofTab" /* End of the Table indicator */ 165 1.1 skrll }; 166 1.1 skrll char low_name[21], *ptr; 167 1.1 skrll int idx; 168 1.1 skrll 169 1.1 skrll for (ptr = name,idx = 0; *ptr != '\0'; ptr++) 170 1.1 skrll low_name[idx++] = TOLOWER (*ptr); 171 1.1 skrll 172 1.1 skrll low_name[idx] = '\0'; 173 1.1 skrll idx = 0; 174 1.1 skrll 175 1.1 skrll while (idx < MAX_REG_NO && strcmp (soft_reg[idx], & low_name [0])) 176 1.1 skrll idx += 1; 177 1.1 skrll 178 1.1 skrll return idx < MAX_REG_NO; 179 1.1 skrll } 180 1.1 skrll 181 1.1 skrll /* Subroutine check the string to match an register. */ 182 1.1 skrll 183 1.1 skrll static int 184 1.1 skrll is_ldst_registers (char *name) 185 1.1 skrll { 186 1.1 skrll char *ptr = name; 187 1.1 skrll 188 1.1 skrll /* The first character of the register name got to be either %, $, r of R. */ 189 1.1 skrll if ((ptr[0] == '%' || ptr[0] == '$' || ptr[0] == 'r' || ptr[0] == 'R') 190 1.1.1.10 christos && ISDIGIT (ptr[1])) 191 1.1 skrll return 1; 192 1.1 skrll 193 1.1 skrll /* Now check the software register representation. */ 194 1.1 skrll return match_sft_register (ptr); 195 1.1 skrll } 196 1.1 skrll 197 1.1 skrll /* Subroutine of s_proc so targets can choose a different default prefix. 198 1.1 skrll If DEFAULT_PREFIX is NULL, use the target's "leading char". */ 199 1.1 skrll 200 1.1 skrll static void 201 1.1 skrll s_proc (int end_p) 202 1.1 skrll { 203 1.1 skrll /* Record the current function so that we can issue an error message for 204 1.1 skrll misplaced .func,.endfunc, and also so that .endfunc needs no 205 1.1 skrll arguments. */ 206 1.1 skrll static char *current_name; 207 1.1 skrll static char *current_label; 208 1.1 skrll 209 1.1 skrll if (end_p) 210 1.1 skrll { 211 1.1 skrll if (current_name == NULL) 212 1.1 skrll { 213 1.1 skrll as_bad (_("missing .proc")); 214 1.1 skrll ignore_rest_of_line (); 215 1.1 skrll return; 216 1.1 skrll } 217 1.1 skrll 218 1.1 skrll current_name = current_label = NULL; 219 1.1 skrll SKIP_WHITESPACE (); 220 1.1.1.10 christos while (!is_end_of_stmt (*input_line_pointer)) 221 1.1 skrll input_line_pointer++; 222 1.1 skrll } 223 1.1 skrll else 224 1.1 skrll { 225 1.1 skrll char *name, *label; 226 1.1 skrll char delim1, delim2; 227 1.1 skrll 228 1.1 skrll if (current_name != NULL) 229 1.1 skrll { 230 1.1 skrll as_bad (_(".endfunc missing for previous .proc")); 231 1.1 skrll ignore_rest_of_line (); 232 1.1 skrll return; 233 1.1 skrll } 234 1.1 skrll 235 1.1.1.4 christos delim1 = get_symbol_name (&name); 236 1.1 skrll name = xstrdup (name); 237 1.1.1.10 christos restore_line_pointer (delim1); 238 1.1.1.10 christos SKIP_WHITESPACE (); 239 1.1 skrll 240 1.1 skrll if (*input_line_pointer != ',') 241 1.1 skrll { 242 1.1 skrll char leading_char = 0; 243 1.1 skrll 244 1.1 skrll leading_char = bfd_get_symbol_leading_char (stdoutput); 245 1.1 skrll /* Missing entry point, use function's name with the leading 246 1.1 skrll char prepended. */ 247 1.1 skrll if (leading_char) 248 1.1.1.3 christos { 249 1.1.1.3 christos unsigned len = strlen (name) + 1; 250 1.1.1.5 christos label = XNEWVEC (char, len + 1); 251 1.1.1.3 christos label[0] = leading_char; 252 1.1.1.3 christos memcpy (label + 1, name, len); 253 1.1.1.3 christos } 254 1.1 skrll else 255 1.1 skrll label = name; 256 1.1 skrll } 257 1.1 skrll else 258 1.1 skrll { 259 1.1 skrll ++input_line_pointer; 260 1.1 skrll SKIP_WHITESPACE (); 261 1.1.1.4 christos delim2 = get_symbol_name (&label); 262 1.1 skrll label = xstrdup (label); 263 1.1.1.4 christos (void) restore_line_pointer (delim2); 264 1.1 skrll } 265 1.1 skrll 266 1.1 skrll current_name = name; 267 1.1 skrll current_label = label; 268 1.1 skrll } 269 1.1 skrll demand_empty_rest_of_line (); 270 1.1 skrll } 271 1.1 skrll 272 1.1 skrll /* This function is called once, at assembler startup time. It should 273 1.1 skrll set up all the tables, etc., that the MD part of the assembler will 274 1.1 skrll need. */ 275 1.1 skrll 276 1.1 skrll void 277 1.1 skrll md_begin (void) 278 1.1 skrll { 279 1.1 skrll unsigned int i; 280 1.1 skrll 281 1.1 skrll /* Create a new hash table. */ 282 1.1.1.8 christos op_hash = str_htab_create (); 283 1.1 skrll 284 1.1 skrll /* Hash up all the opcodes for fast use later. */ 285 1.1 skrll for (i = 0; i < num_dlx_opcodes; i++) 286 1.1 skrll { 287 1.1 skrll const char *name = machine_opcodes[i].name; 288 1.1.1.8 christos if (str_hash_insert (op_hash, name, &machine_opcodes[i], 0) != NULL) 289 1.1.1.8 christos as_fatal (_("duplicate %s"), name); 290 1.1 skrll } 291 1.1 skrll 292 1.1 skrll define_some_regs (); 293 1.1 skrll } 294 1.1 skrll 295 1.1 skrll /* This function will check the opcode and return 1 if the opcode is one 296 1.1 skrll of the load/store instruction, and it will fix the operand string to 297 1.1 skrll the standard form so we can use the standard parse_operand routine. */ 298 1.1 skrll 299 1.1 skrll #define READ_OP 0x100 300 1.1 skrll #define WRITE_OP 0x200 301 1.1 skrll static char iBuf[81]; 302 1.1 skrll 303 1.1 skrll static char * 304 1.1 skrll dlx_parse_loadop (char * str) 305 1.1 skrll { 306 1.1 skrll char *ptr = str; 307 1.1 skrll int idx = 0; 308 1.1 skrll 309 1.1 skrll /* The last pair of ()/[] is the register, all other are the 310 1.1 skrll reloc displacement, and if there is a register then it ought 311 1.1 skrll to have a pair of ()/[] 312 1.1 skrll This is not necessarily true, what if the load instruction come 313 1.1 skrll without the register and with %hi/%lo modifier? */ 314 1.1 skrll for (idx = 0; idx < 72 && ptr[idx] != '\0'; idx++) 315 1.1 skrll ; 316 1.1 skrll 317 1.1 skrll if (idx == 72) 318 1.1 skrll { 319 1.1 skrll badoperand_load: 320 1.1 skrll as_bad (_("Bad operand for a load instruction: <%s>"), str); 321 1.1 skrll return NULL; 322 1.1 skrll } 323 1.1 skrll else 324 1.1 skrll { 325 1.1 skrll int i, pb = 0; 326 1.1 skrll int m2 = 0; 327 1.1 skrll char rs1[7], rd[7], endm, match = '0'; 328 1.1 skrll char imm[72]; 329 1.1 skrll 330 1.1 skrll idx -= 1; 331 1.1 skrll switch (str[idx]) 332 1.1 skrll { 333 1.1 skrll case ')': 334 1.1 skrll match = '('; 335 1.1 skrll endm = ')'; 336 1.1 skrll break; 337 1.1 skrll case ']': 338 1.1 skrll match = '['; 339 1.1 skrll endm = ']'; 340 1.1 skrll break; 341 1.1 skrll default: 342 1.1 skrll /* No register indicated, fill in zero. */ 343 1.1 skrll rs1[0] = 'r'; 344 1.1 skrll rs1[1] = '0'; 345 1.1 skrll rs1[2] = '\0'; 346 1.1 skrll match = 0; 347 1.1 skrll endm = 0; 348 1.1 skrll m2 = 1; 349 1.1 skrll } 350 1.1 skrll 351 1.1 skrll if (!m2) 352 1.1 skrll { 353 1.1 skrll /* Searching for (/[ which will match the ]/). */ 354 1.1 skrll for (pb = idx - 1; str[pb] != match; pb -= 1) 355 1.1 skrll /* Match can only be either '[' or '(', if it is 356 1.1 skrll '(' then this can be a normal expression, we'll treat 357 1.1 skrll it as an operand. */ 358 1.1 skrll if (str[pb] == endm || pb < (idx - 5)) 359 1.1 skrll goto load_no_rs1; 360 1.1 skrll pb += 1; 361 1.1 skrll 362 1.1 skrll for (i = 0; (pb + i) < idx; i++) 363 1.1 skrll rs1[i] = str[pb+i]; 364 1.1 skrll 365 1.1 skrll rs1[i] = '\0'; 366 1.1 skrll 367 1.1 skrll if (is_ldst_registers (& rs1[0])) 368 1.1 skrll /* Point to the last character of the imm. */ 369 1.1 skrll pb -= 1; 370 1.1 skrll else 371 1.1 skrll { 372 1.1 skrll load_no_rs1: 373 1.1 skrll if (match == '[') 374 1.1 skrll goto badoperand_load; 375 1.1 skrll /* No register indicated, fill in zero and restore the imm. */ 376 1.1 skrll rs1[0] = 'r'; 377 1.1 skrll rs1[1] = '0'; 378 1.1 skrll rs1[2] = '\0'; 379 1.1 skrll m2 = 1; 380 1.1 skrll } 381 1.1 skrll } 382 1.1 skrll 383 1.1 skrll /* Duplicate the first register. */ 384 1.1 skrll for (i = 0; i < 7 && str[i] != ','; i++) 385 1.1 skrll rd[i] = ptr[i]; 386 1.1 skrll 387 1.1 skrll if (str[i] != ',') 388 1.1 skrll goto badoperand_load; 389 1.1 skrll else 390 1.1 skrll rd[i] = '\0'; 391 1.1 skrll 392 1.1 skrll /* Copy the immd. */ 393 1.1 skrll if (m2) 394 1.1 skrll /* Put the '\0' back in. */ 395 1.1 skrll pb = idx + 1; 396 1.1 skrll 397 1.1 skrll for (i++, m2 = 0; i < pb; m2++,i++) 398 1.1 skrll imm[m2] = ptr[i]; 399 1.1 skrll 400 1.1 skrll imm[m2] = '\0'; 401 1.1 skrll 402 1.1 skrll /* Assemble the instruction to gas internal format. */ 403 1.1 skrll for (i = 0; rd[i] != '\0'; i++) 404 1.1 skrll iBuf[i] = rd[i]; 405 1.1 skrll 406 1.1 skrll iBuf[i++] = ','; 407 1.1 skrll 408 1.1 skrll for (pb = 0 ; rs1[pb] != '\0'; i++, pb++) 409 1.1 skrll iBuf[i] = rs1[pb]; 410 1.1 skrll 411 1.1 skrll iBuf[i++] = ','; 412 1.1 skrll 413 1.1 skrll for (pb = 0; imm[pb] != '\0'; i++, pb++) 414 1.1 skrll iBuf[i] = imm[pb]; 415 1.1 skrll 416 1.1 skrll iBuf[i] = '\0'; 417 1.1 skrll return iBuf; 418 1.1 skrll } 419 1.1 skrll } 420 1.1 skrll 421 1.1 skrll static char * 422 1.1 skrll dlx_parse_storeop (char * str) 423 1.1 skrll { 424 1.1 skrll char *ptr = str; 425 1.1 skrll int idx = 0; 426 1.1 skrll 427 1.1 skrll /* Search for the ','. */ 428 1.1 skrll for (idx = 0; idx < 72 && ptr[idx] != ','; idx++) 429 1.1 skrll ; 430 1.1 skrll 431 1.1 skrll if (idx == 72) 432 1.1 skrll { 433 1.1 skrll badoperand_store: 434 1.1 skrll as_bad (_("Bad operand for a store instruction: <%s>"), str); 435 1.1 skrll return NULL; 436 1.1 skrll } 437 1.1 skrll else 438 1.1 skrll { 439 1.1 skrll /* idx now points to the ','. */ 440 1.1 skrll int i, pb = 0; 441 1.1 skrll int comma = idx; 442 1.1 skrll int m2 = 0; 443 1.1 skrll char rs1[7], rd[7], endm, match = '0'; 444 1.1 skrll char imm[72]; 445 1.1 skrll 446 1.1 skrll /* Now parse the '(' and ')', and make idx point to ')'. */ 447 1.1 skrll idx -= 1; 448 1.1 skrll switch (str[idx]) 449 1.1 skrll { 450 1.1 skrll case ')': 451 1.1 skrll match = '('; 452 1.1 skrll endm = ')'; 453 1.1 skrll break; 454 1.1 skrll case ']': 455 1.1 skrll match = '['; 456 1.1 skrll endm = ']'; 457 1.1 skrll break; 458 1.1 skrll default: 459 1.1 skrll /* No register indicated, fill in zero. */ 460 1.1 skrll rs1[0] = 'r'; 461 1.1 skrll rs1[1] = '0'; 462 1.1 skrll rs1[2] = '\0'; 463 1.1 skrll match = 0; 464 1.1 skrll endm = 0; 465 1.1 skrll m2 = 1; 466 1.1 skrll } 467 1.1 skrll 468 1.1 skrll if (!m2) 469 1.1 skrll { 470 1.1 skrll /* Searching for (/[ which will match the ]/). */ 471 1.1 skrll for (pb = idx - 1; str[pb] != match; pb -= 1) 472 1.1 skrll if (pb < (idx - 5) || str[pb] == endm) 473 1.1 skrll goto store_no_rs1; 474 1.1 skrll pb += 1; 475 1.1 skrll 476 1.1 skrll for (i = 0; (pb + i) < idx; i++) 477 1.1 skrll rs1[i] = str[pb + i]; 478 1.1 skrll 479 1.1 skrll rs1[i] = '\0'; 480 1.1 skrll 481 1.1 skrll if (is_ldst_registers (& rs1[0])) 482 1.1 skrll /* Point to the last character of the imm. */ 483 1.1 skrll pb -= 1; 484 1.1 skrll else 485 1.1 skrll { 486 1.1 skrll store_no_rs1: 487 1.1 skrll if (match == '[') 488 1.1 skrll goto badoperand_store; 489 1.1 skrll 490 1.1 skrll /* No register indicated, fill in zero and restore the imm. */ 491 1.1 skrll rs1[0] = 'r'; 492 1.1 skrll rs1[1] = '0'; 493 1.1 skrll rs1[2] = '\0'; 494 1.1 skrll pb = comma; 495 1.1 skrll } 496 1.1 skrll } 497 1.1 skrll else 498 1.1 skrll /* No register was specified. */ 499 1.1 skrll pb = comma; 500 1.1 skrll 501 1.1 skrll /* Duplicate the first register. */ 502 1.1.1.10 christos for (i = comma + 1; is_whitespace (str[i]); i++) 503 1.1 skrll ; 504 1.1 skrll 505 1.1 skrll for (m2 = 0; (m2 < 7 && str[i] != '\0'); i++, m2++) 506 1.1 skrll { 507 1.1.1.10 christos if (!is_whitespace (str[i])) 508 1.1 skrll rd[m2] = str[i]; 509 1.1 skrll else 510 1.1 skrll goto badoperand_store; 511 1.1 skrll } 512 1.1 skrll 513 1.1 skrll if (str[i] != '\0') 514 1.1 skrll goto badoperand_store; 515 1.1 skrll else 516 1.1 skrll rd[m2] = '\0'; 517 1.1 skrll 518 1.1 skrll /* Copy the immd. */ 519 1.1 skrll for (i = 0; i < pb; i++) 520 1.1 skrll imm[i] = ptr[i]; 521 1.1 skrll 522 1.1 skrll imm[i] = '\0'; 523 1.1 skrll 524 1.1 skrll /* Assemble the instruction to gas internal format. */ 525 1.1 skrll for (i = 0; rd[i] != '\0'; i++) 526 1.1 skrll iBuf[i] = rd[i]; 527 1.1 skrll iBuf[i++] = ','; 528 1.1 skrll for (pb = 0 ; rs1[pb] != '\0'; i++, pb++) 529 1.1 skrll iBuf[i] = rs1[pb]; 530 1.1 skrll iBuf[i++] = ','; 531 1.1 skrll for (pb = 0; imm[pb] != '\0'; i++, pb++) 532 1.1 skrll iBuf[i] = imm[pb]; 533 1.1 skrll iBuf[i] = '\0'; 534 1.1 skrll return iBuf; 535 1.1 skrll } 536 1.1 skrll } 537 1.1 skrll 538 1.1 skrll static char * 539 1.1 skrll fix_ld_st_operand (unsigned long opcode, char* str) 540 1.1 skrll { 541 1.1 skrll /* Check the opcode. */ 542 1.1.1.10 christos switch (opcode) 543 1.1 skrll { 544 1.1 skrll case LBOP: 545 1.1 skrll case LBUOP: 546 1.1 skrll case LSBUOP: 547 1.1 skrll case LHOP: 548 1.1 skrll case LHUOP: 549 1.1 skrll case LSHUOP: 550 1.1 skrll case LWOP: 551 1.1 skrll case LSWOP: 552 1.1 skrll return dlx_parse_loadop (str); 553 1.1 skrll case SBOP: 554 1.1 skrll case SHOP: 555 1.1 skrll case SWOP: 556 1.1 skrll return dlx_parse_storeop (str); 557 1.1 skrll default: 558 1.1 skrll return str; 559 1.1 skrll } 560 1.1 skrll } 561 1.1 skrll 562 1.1 skrll static int 563 1.1 skrll hilo_modifier_ok (char *s) 564 1.1 skrll { 565 1.1 skrll char *ptr = s; 566 1.1 skrll int idx, count = 1; 567 1.1 skrll 568 1.1 skrll if (*ptr != '(') 569 1.1 skrll return 1; 570 1.1 skrll 571 1.1 skrll for (idx = 1; ptr[idx] != '\0' && ptr[idx] != '[' && idx < 73; idx += 1) 572 1.1 skrll { 573 1.1 skrll if (count == 0) 574 1.1 skrll return count; 575 1.1 skrll 576 1.1 skrll if (ptr[idx] == '(') 577 1.1 skrll count += 1; 578 1.1 skrll 579 1.1 skrll if (ptr[idx] == ')') 580 1.1 skrll count -= 1; 581 1.1 skrll } 582 1.1 skrll 583 1.1 skrll return (count == 0) ? 1:0; 584 1.1 skrll } 585 1.1 skrll 586 1.1 skrll static char * 587 1.1 skrll parse_operand (char *s, expressionS *operandp) 588 1.1 skrll { 589 1.1 skrll char *save = input_line_pointer; 590 1.1.1.2 christos char *new_pos; 591 1.1 skrll 592 1.1 skrll the_insn.HI = the_insn.LO = 0; 593 1.1 skrll 594 1.1 skrll /* Search for %hi and %lo, make a mark and skip it. */ 595 1.1.1.8 christos if (startswith (s, "%hi")) 596 1.1 skrll { 597 1.1 skrll s += 3; 598 1.1 skrll the_insn.HI = 1; 599 1.1 skrll } 600 1.1 skrll else 601 1.1 skrll { 602 1.1.1.8 christos if (startswith (s, "%lo")) 603 1.1 skrll { 604 1.1 skrll s += 3; 605 1.1 skrll the_insn.LO = 1; 606 1.1 skrll } 607 1.1 skrll else 608 1.1 skrll the_insn.LO = 0; 609 1.1 skrll } 610 1.1 skrll 611 1.1 skrll if (the_insn.HI || the_insn.LO) 612 1.1 skrll { 613 1.1 skrll if (!hilo_modifier_ok (s)) 614 1.1 skrll as_bad (_("Expression Error for operand modifier %%hi/%%lo\n")); 615 1.1 skrll } 616 1.1 skrll 617 1.1 skrll /* Check for the % and $ register representation */ 618 1.1 skrll if ((s[0] == '%' || s[0] == '$' || s[0] == 'r' || s[0] == 'R') 619 1.1.1.10 christos && ISDIGIT (s[1])) 620 1.1 skrll { 621 1.1 skrll /* We have a numeric register expression. No biggy. */ 622 1.1 skrll s += 1; 623 1.1 skrll input_line_pointer = s; 624 1.1 skrll (void) expression (operandp); 625 1.1 skrll if (operandp->X_op != O_constant 626 1.1 skrll || operandp->X_add_number > 31) 627 1.1 skrll as_bad (_("Invalid expression after %%%%\n")); 628 1.1 skrll operandp->X_op = O_register; 629 1.1 skrll } 630 1.1 skrll else 631 1.1 skrll { 632 1.1 skrll /* Normal operand parsing. */ 633 1.1 skrll input_line_pointer = s; 634 1.1 skrll (void) expression (operandp); 635 1.1.1.9 christos resolve_register (operandp); 636 1.1 skrll } 637 1.1 skrll 638 1.1.1.2 christos new_pos = input_line_pointer; 639 1.1 skrll input_line_pointer = save; 640 1.1.1.2 christos return new_pos; 641 1.1 skrll } 642 1.1 skrll 643 1.1 skrll /* Instruction parsing. Takes a string containing the opcode. 644 1.1 skrll Operands are at input_line_pointer. Output is in the_insn. 645 1.1 skrll Warnings or errors are generated. */ 646 1.1 skrll 647 1.1 skrll static void 648 1.1 skrll machine_ip (char *str) 649 1.1 skrll { 650 1.1 skrll char *s; 651 1.1 skrll const char *args; 652 1.1 skrll struct machine_opcode *insn; 653 1.1 skrll unsigned long opcode; 654 1.1 skrll expressionS the_operand; 655 1.1 skrll expressionS *operand = &the_operand; 656 1.1 skrll unsigned int reg, reg_shift = 0; 657 1.1 skrll 658 1.1.1.4 christos memset (&the_insn, '\0', sizeof (the_insn)); 659 1.1.1.4 christos the_insn.reloc = NO_RELOC; 660 1.1.1.4 christos 661 1.1 skrll /* Fixup the opcode string to all lower cases, and also 662 1.1 skrll allow numerical digits. */ 663 1.1 skrll s = str; 664 1.1 skrll 665 1.1 skrll if (ISALPHA (*s)) 666 1.1 skrll for (; ISALNUM (*s); ++s) 667 1.1 skrll if (ISUPPER (*s)) 668 1.1 skrll *s = TOLOWER (*s); 669 1.1 skrll 670 1.1 skrll switch (*s) 671 1.1 skrll { 672 1.1 skrll case '\0': 673 1.1 skrll break; 674 1.1 skrll 675 1.1 skrll default: 676 1.1.1.10 christos if (is_whitespace (*s)) 677 1.1.1.10 christos { 678 1.1.1.10 christos *s++ = '\0'; 679 1.1.1.10 christos break; 680 1.1.1.10 christos } 681 1.1 skrll as_bad (_("Unknown opcode: `%s'"), str); 682 1.1 skrll return; 683 1.1 skrll } 684 1.1 skrll 685 1.1.1.4 christos /* Hash the opcode, insn will have the string from opcode table. */ 686 1.1.1.10 christos if ((insn = str_hash_find (op_hash, str)) == NULL) 687 1.1 skrll { 688 1.1 skrll /* Handle the ret and return macro here. */ 689 1.1 skrll if ((strcmp (str, "ret") == 0) || (strcmp (str, "return") == 0)) 690 1.1.1.4 christos the_insn.opcode = JROP | 0x03e00000; /* 0x03e00000 = r31 << 21 */ 691 1.1 skrll else 692 1.1 skrll as_bad (_("Unknown opcode `%s'."), str); 693 1.1 skrll 694 1.1 skrll return; 695 1.1 skrll } 696 1.1 skrll 697 1.1 skrll opcode = insn->opcode; 698 1.1 skrll 699 1.1 skrll /* Set the sip reloc HI16 flag. */ 700 1.1 skrll if (!set_dlx_skip_hi16_flag (1)) 701 1.1 skrll as_bad (_("Can not set dlx_skip_hi16_flag")); 702 1.1 skrll 703 1.1 skrll /* Fix the operand string if it is one of load store instructions. */ 704 1.1 skrll s = fix_ld_st_operand (opcode, s); 705 1.1 skrll 706 1.1 skrll /* Build the opcode, checking as we go to make sure that the 707 1.1 skrll operands match. 708 1.1 skrll If an operand matches, we modify the_insn or opcode appropriately, 709 1.1 skrll and do a "continue". If an operand fails to match, we "break". */ 710 1.1 skrll if (insn->args[0] != '\0' && insn->args[0] != 'N') 711 1.1 skrll { 712 1.1 skrll /* Prime the pump. */ 713 1.1 skrll if (*s == '\0') 714 1.1 skrll { 715 1.1 skrll as_bad (_("Missing arguments for opcode <%s>."), str); 716 1.1 skrll return; 717 1.1 skrll } 718 1.1 skrll else 719 1.1 skrll s = parse_operand (s, operand); 720 1.1 skrll } 721 1.1 skrll else if (insn->args[0] == 'N') 722 1.1 skrll { 723 1.1 skrll /* Clean up the insn and done! */ 724 1.1 skrll the_insn.opcode = opcode; 725 1.1 skrll return; 726 1.1 skrll } 727 1.1 skrll 728 1.1 skrll /* Parse through the args (this is from opcode table), *s point to 729 1.1 skrll the current character of the instruction stream. */ 730 1.1 skrll for (args = insn->args;; ++args) 731 1.1 skrll { 732 1.1 skrll switch (*args) 733 1.1 skrll { 734 1.1 skrll /* End of Line. */ 735 1.1 skrll case '\0': 736 1.1 skrll /* End of args. */ 737 1.1 skrll if (*s == '\0') 738 1.1 skrll { 739 1.1 skrll /* We are truly done. */ 740 1.1 skrll the_insn.opcode = opcode; 741 1.1 skrll /* Clean up the HI and LO mark. */ 742 1.1 skrll the_insn.HI = 0; 743 1.1 skrll the_insn.LO = 0; 744 1.1 skrll return; 745 1.1 skrll } 746 1.1 skrll 747 1.1 skrll the_insn.HI = 0; 748 1.1 skrll the_insn.LO = 0; 749 1.1 skrll as_bad (_("Too many operands: %s"), s); 750 1.1 skrll break; 751 1.1 skrll 752 1.1 skrll /* ',' Args separator */ 753 1.1 skrll case ',': 754 1.1 skrll /* Must match a comma. */ 755 1.1 skrll if (*s++ == ',') 756 1.1 skrll { 757 1.1 skrll /* Parse next operand. */ 758 1.1 skrll s = parse_operand (s, operand); 759 1.1 skrll continue; 760 1.1 skrll } 761 1.1 skrll break; 762 1.1 skrll 763 1.1 skrll /* It can be a 'a' register or 'i' operand. */ 764 1.1 skrll case 'P': 765 1.1 skrll /* Macro move operand/reg. */ 766 1.1 skrll if (operand->X_op == O_register) 767 1.1 skrll { 768 1.1.1.6 christos /* It's a register. */ 769 1.1 skrll reg_shift = 21; 770 1.1 skrll goto general_reg; 771 1.1 skrll } 772 1.1.1.6 christos /* Fall through. */ 773 1.1 skrll 774 1.1 skrll /* The immediate 16 bits literal, bit 0-15. */ 775 1.1 skrll case 'i': 776 1.1 skrll /* offset, unsigned. */ 777 1.1 skrll case 'I': 778 1.1 skrll /* offset, signed. */ 779 1.1 skrll if (operand->X_op == O_constant) 780 1.1 skrll { 781 1.1 skrll if (the_insn.HI) 782 1.1 skrll operand->X_add_number >>= 16; 783 1.1 skrll 784 1.1 skrll opcode |= operand->X_add_number & 0xFFFF; 785 1.1 skrll 786 1.1 skrll if (the_insn.HI && the_insn.LO) 787 1.1 skrll as_bad (_("Both the_insn.HI and the_insn.LO are set : %s"), s); 788 1.1 skrll else 789 1.1 skrll { 790 1.1 skrll the_insn.HI = 0; 791 1.1 skrll the_insn.LO = 0; 792 1.1 skrll } 793 1.1 skrll continue; 794 1.1 skrll } 795 1.1 skrll 796 1.1.1.4 christos the_insn.reloc = (the_insn.HI) ? RELOC_DLX_HI16 797 1.1 skrll : (the_insn.LO ? RELOC_DLX_LO16 : RELOC_DLX_16); 798 1.1 skrll the_insn.reloc_offset = 2; 799 1.1 skrll the_insn.size = 2; 800 1.1 skrll the_insn.pcrel = 0; 801 1.1 skrll the_insn.exp = * operand; 802 1.1 skrll the_insn.HI = 0; 803 1.1 skrll the_insn.LO = 0; 804 1.1 skrll continue; 805 1.1 skrll 806 1.1 skrll case 'd': 807 1.1 skrll /* offset, signed. */ 808 1.1 skrll if (operand->X_op == O_constant) 809 1.1 skrll { 810 1.1 skrll opcode |= operand->X_add_number & 0xFFFF; 811 1.1 skrll continue; 812 1.1 skrll } 813 1.1 skrll the_insn.reloc = RELOC_DLX_REL16; 814 1.1 skrll the_insn.reloc_offset = 0; /* BIG-ENDIAN Byte 3 of insn. */ 815 1.1 skrll the_insn.size = 4; 816 1.1 skrll the_insn.pcrel = 1; 817 1.1 skrll the_insn.exp = *operand; 818 1.1 skrll continue; 819 1.1 skrll 820 1.1 skrll /* The immediate 26 bits literal, bit 0-25. */ 821 1.1 skrll case 'D': 822 1.1 skrll /* offset, signed. */ 823 1.1 skrll if (operand->X_op == O_constant) 824 1.1 skrll { 825 1.1 skrll opcode |= operand->X_add_number & 0x3FFFFFF; 826 1.1 skrll continue; 827 1.1 skrll } 828 1.1 skrll the_insn.reloc = RELOC_DLX_REL26; 829 1.1 skrll the_insn.reloc_offset = 0; /* BIG-ENDIAN Byte 3 of insn. */ 830 1.1 skrll the_insn.size = 4; 831 1.1 skrll the_insn.pcrel = 1; 832 1.1 skrll the_insn.exp = *operand; 833 1.1 skrll continue; 834 1.1 skrll 835 1.1 skrll /* Type 'a' Register. */ 836 1.1 skrll case 'a': 837 1.1 skrll /* A general register at bits 21-25, rs1. */ 838 1.1 skrll reg_shift = 21; 839 1.1 skrll goto general_reg; 840 1.1 skrll 841 1.1 skrll /* Type 'b' Register. */ 842 1.1 skrll case 'b': 843 1.1 skrll /* A general register at bits 16-20, rs2/rd. */ 844 1.1 skrll reg_shift = 16; 845 1.1 skrll goto general_reg; 846 1.1 skrll 847 1.1 skrll /* Type 'c' Register. */ 848 1.1 skrll case 'c': 849 1.1 skrll /* A general register at bits 11-15, rd. */ 850 1.1 skrll reg_shift = 11; 851 1.1 skrll 852 1.1 skrll general_reg: 853 1.1 skrll know (operand->X_add_symbol == 0); 854 1.1 skrll know (operand->X_op_symbol == 0); 855 1.1 skrll reg = operand->X_add_number; 856 1.1 skrll if (reg & 0xffffffe0) 857 1.1 skrll as_fatal (_("failed regnum sanity check.")); 858 1.1 skrll else 859 1.1 skrll /* Got the register, now figure out where it goes in the opcode. */ 860 1.1 skrll opcode |= reg << reg_shift; 861 1.1 skrll 862 1.1 skrll switch (*args) 863 1.1 skrll { 864 1.1 skrll case 'a': 865 1.1 skrll case 'b': 866 1.1 skrll case 'c': 867 1.1 skrll case 'P': 868 1.1 skrll continue; 869 1.1 skrll } 870 1.1 skrll as_fatal (_("failed general register sanity check.")); 871 1.1 skrll break; 872 1.1 skrll 873 1.1 skrll default: 874 1.1 skrll BAD_CASE (*args); 875 1.1 skrll } 876 1.1 skrll 877 1.1 skrll /* Types or values of args don't match. */ 878 1.1 skrll as_bad (_("Invalid operands")); 879 1.1 skrll return; 880 1.1 skrll } 881 1.1 skrll } 882 1.1 skrll 883 1.1 skrll /* Assemble a single instruction. Its label has already been handled 884 1.1 skrll by the generic front end. We just parse opcode and operands, and 885 1.1 skrll produce the bytes of data and relocation. */ 886 1.1 skrll 887 1.1 skrll void 888 1.1 skrll md_assemble (char *str) 889 1.1 skrll { 890 1.1 skrll char *toP; 891 1.1 skrll fixS *fixP; 892 1.1 skrll bit_fixS *bitP; 893 1.1 skrll 894 1.1 skrll know (str); 895 1.1 skrll machine_ip (str); 896 1.1 skrll toP = frag_more (4); 897 1.1.1.2 christos dwarf2_emit_insn (4); 898 1.1.1.2 christos 899 1.1 skrll /* Put out the opcode. */ 900 1.1 skrll md_number_to_chars (toP, the_insn.opcode, 4); 901 1.1 skrll 902 1.1 skrll /* Put out the symbol-dependent stuff. */ 903 1.1 skrll if (the_insn.reloc != NO_RELOC) 904 1.1 skrll { 905 1.1 skrll fixP = fix_new_exp (frag_now, 906 1.1 skrll (toP - frag_now->fr_literal + the_insn.reloc_offset), 907 1.1 skrll the_insn.size, & the_insn.exp, the_insn.pcrel, 908 1.1 skrll the_insn.reloc); 909 1.1 skrll 910 1.1 skrll /* Turn off complaints that the addend is 911 1.1 skrll too large for things like foo+100000@ha. */ 912 1.1 skrll switch (the_insn.reloc) 913 1.1 skrll { 914 1.1 skrll case RELOC_DLX_HI16: 915 1.1 skrll case RELOC_DLX_LO16: 916 1.1 skrll fixP->fx_no_overflow = 1; 917 1.1 skrll break; 918 1.1 skrll default: 919 1.1 skrll break; 920 1.1 skrll } 921 1.1 skrll 922 1.1 skrll switch (fixP->fx_r_type) 923 1.1 skrll { 924 1.1 skrll case RELOC_DLX_REL26: 925 1.1.1.5 christos bitP = XNEW (bit_fixS); 926 1.1 skrll bitP->fx_bit_size = 26; 927 1.1 skrll bitP->fx_bit_offset = 25; 928 1.1 skrll bitP->fx_bit_base = the_insn.opcode & 0xFC000000; 929 1.1 skrll bitP->fx_bit_base_adj = 0; 930 1.1 skrll bitP->fx_bit_max = 0; 931 1.1 skrll bitP->fx_bit_min = 0; 932 1.1 skrll bitP->fx_bit_add = 0x03FFFFFF; 933 1.1 skrll fixP->fx_bit_fixP = bitP; 934 1.1 skrll break; 935 1.1 skrll case RELOC_DLX_LO16: 936 1.1 skrll case RELOC_DLX_REL16: 937 1.1.1.5 christos bitP = XNEW (bit_fixS); 938 1.1 skrll bitP->fx_bit_size = 16; 939 1.1 skrll bitP->fx_bit_offset = 15; 940 1.1 skrll bitP->fx_bit_base = the_insn.opcode & 0xFFFF0000; 941 1.1 skrll bitP->fx_bit_base_adj = 0; 942 1.1 skrll bitP->fx_bit_max = 0; 943 1.1 skrll bitP->fx_bit_min = 0; 944 1.1 skrll bitP->fx_bit_add = 0x0000FFFF; 945 1.1 skrll fixP->fx_bit_fixP = bitP; 946 1.1 skrll break; 947 1.1 skrll case RELOC_DLX_HI16: 948 1.1.1.5 christos bitP = XNEW (bit_fixS); 949 1.1 skrll bitP->fx_bit_size = 16; 950 1.1 skrll bitP->fx_bit_offset = 15; 951 1.1 skrll bitP->fx_bit_base = the_insn.opcode & 0xFFFF0000; 952 1.1 skrll bitP->fx_bit_base_adj = 0; 953 1.1 skrll bitP->fx_bit_max = 0; 954 1.1 skrll bitP->fx_bit_min = 0; 955 1.1 skrll bitP->fx_bit_add = 0x0000FFFF; 956 1.1 skrll fixP->fx_bit_fixP = bitP; 957 1.1 skrll break; 958 1.1 skrll default: 959 1.1 skrll fixP->fx_bit_fixP = NULL; 960 1.1 skrll break; 961 1.1 skrll } 962 1.1 skrll } 963 1.1 skrll } 964 1.1 skrll 965 1.1 skrll /* This is identical to the md_atof in m68k.c. I think this is right, 966 1.1 skrll but I'm not sure. Dlx will not use it anyway, so I just leave it 967 1.1 skrll here for now. */ 968 1.1 skrll 969 1.1.1.5 christos const char * 970 1.1 skrll md_atof (int type, char *litP, int *sizeP) 971 1.1 skrll { 972 1.1.1.8 christos return ieee_md_atof (type, litP, sizeP, true); 973 1.1 skrll } 974 1.1 skrll 975 1.1 skrll /* Write out big-endian. */ 976 1.1 skrll void 977 1.1 skrll md_number_to_chars (char *buf, valueT val, int n) 978 1.1 skrll { 979 1.1 skrll number_to_chars_bigendian (buf, val, n); 980 1.1 skrll } 981 1.1 skrll 982 1.1.1.8 christos bool 983 1.1 skrll md_dlx_fix_adjustable (fixS *fixP) 984 1.1 skrll { 985 1.1 skrll /* We need the symbol name for the VTABLE entries. */ 986 1.1 skrll return (fixP->fx_r_type != BFD_RELOC_VTABLE_INHERIT 987 1.1 skrll && fixP->fx_r_type != BFD_RELOC_VTABLE_ENTRY); 988 1.1 skrll } 989 1.1 skrll 990 1.1 skrll void 991 1.1 skrll md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) 992 1.1 skrll { 993 1.1 skrll long val = *valP; 994 1.1 skrll char *place = fixP->fx_where + fixP->fx_frag->fr_literal; 995 1.1 skrll 996 1.1 skrll switch (fixP->fx_r_type) 997 1.1 skrll { 998 1.1 skrll case RELOC_DLX_LO16: 999 1.1 skrll case RELOC_DLX_REL16: 1000 1.1 skrll if (fixP->fx_bit_fixP != NULL) 1001 1.1 skrll { 1002 1.1 skrll val = (val & 0x0000FFFF) | fixP->fx_bit_fixP->fx_bit_base; 1003 1.1 skrll free (fixP->fx_bit_fixP); 1004 1.1 skrll fixP->fx_bit_fixP = NULL; 1005 1.1 skrll } 1006 1.1 skrll break; 1007 1.1 skrll 1008 1.1 skrll case RELOC_DLX_HI16: 1009 1.1 skrll if (fixP->fx_bit_fixP != NULL) 1010 1.1 skrll { 1011 1.1 skrll val = (val >> 16) | fixP->fx_bit_fixP->fx_bit_base; 1012 1.1 skrll free (fixP->fx_bit_fixP); 1013 1.1 skrll fixP->fx_bit_fixP = NULL; 1014 1.1 skrll } 1015 1.1 skrll break; 1016 1.1 skrll 1017 1.1 skrll case RELOC_DLX_REL26: 1018 1.1 skrll if (fixP->fx_bit_fixP != NULL) 1019 1.1 skrll { 1020 1.1 skrll val = (val & 0x03FFFFFF) | fixP->fx_bit_fixP->fx_bit_base; 1021 1.1 skrll free (fixP->fx_bit_fixP); 1022 1.1 skrll fixP->fx_bit_fixP = NULL; 1023 1.1 skrll } 1024 1.1 skrll break; 1025 1.1 skrll 1026 1.1 skrll case BFD_RELOC_VTABLE_INHERIT: 1027 1.1 skrll /* This borrowed from tc-ppc.c on a whim. */ 1028 1.1 skrll fixP->fx_done = 0; 1029 1.1 skrll if (fixP->fx_addsy 1030 1.1 skrll && !S_IS_DEFINED (fixP->fx_addsy) 1031 1.1 skrll && !S_IS_WEAK (fixP->fx_addsy)) 1032 1.1 skrll S_SET_WEAK (fixP->fx_addsy); 1033 1.1 skrll return; 1034 1.1 skrll 1035 1.1 skrll case BFD_RELOC_VTABLE_ENTRY: 1036 1.1 skrll fixP->fx_done = 0; 1037 1.1 skrll return; 1038 1.1 skrll 1039 1.1 skrll default: 1040 1.1 skrll break; 1041 1.1 skrll } 1042 1.1 skrll 1043 1.1 skrll number_to_chars_bigendian (place, val, fixP->fx_size); 1044 1.1 skrll if (fixP->fx_addsy == NULL) 1045 1.1 skrll fixP->fx_done = 1; 1046 1.1.1.7 christos if (fixP->fx_bit_fixP != NULL) 1047 1.1.1.7 christos fixP->fx_no_overflow = 1; 1048 1.1 skrll } 1049 1.1 skrll 1050 1.1.1.10 christos const char md_shortopts[] = ""; 1051 1.1 skrll 1052 1.1.1.10 christos const struct option md_longopts[] = 1053 1.1 skrll { 1054 1.1 skrll {NULL, no_argument, NULL, 0} 1055 1.1 skrll }; 1056 1.1 skrll 1057 1.1.1.10 christos const size_t md_longopts_size = sizeof (md_longopts); 1058 1.1 skrll 1059 1.1 skrll int 1060 1.1 skrll md_parse_option (int c ATTRIBUTE_UNUSED, 1061 1.1.1.5 christos const char *arg ATTRIBUTE_UNUSED) 1062 1.1 skrll { 1063 1.1 skrll return 0; 1064 1.1 skrll } 1065 1.1 skrll 1066 1.1 skrll void 1067 1.1 skrll md_show_usage (FILE *stream ATTRIBUTE_UNUSED) 1068 1.1 skrll { 1069 1.1 skrll } 1070 1.1 skrll 1071 1.1 skrll /* This is called when a line is unrecognized. */ 1072 1.1 skrll 1073 1.1 skrll int 1074 1.1 skrll dlx_unrecognized_line (int c) 1075 1.1 skrll { 1076 1.1 skrll int lab; 1077 1.1 skrll char *s; 1078 1.1 skrll 1079 1.1 skrll if (c != '$' || ! ISDIGIT ((unsigned char) input_line_pointer[0])) 1080 1.1 skrll return 0; 1081 1.1 skrll 1082 1.1 skrll s = input_line_pointer; 1083 1.1 skrll 1084 1.1 skrll lab = 0; 1085 1.1 skrll while (ISDIGIT ((unsigned char) *s)) 1086 1.1 skrll { 1087 1.1 skrll lab = lab * 10 + *s - '0'; 1088 1.1 skrll ++s; 1089 1.1 skrll } 1090 1.1 skrll 1091 1.1 skrll if (*s != ':') 1092 1.1 skrll /* Not a label definition. */ 1093 1.1 skrll return 0; 1094 1.1 skrll 1095 1.1 skrll if (dollar_label_defined (lab)) 1096 1.1 skrll { 1097 1.1 skrll as_bad (_("label \"$%d\" redefined"), lab); 1098 1.1 skrll return 0; 1099 1.1 skrll } 1100 1.1 skrll 1101 1.1 skrll define_dollar_label (lab); 1102 1.1 skrll colon (dollar_label_name (lab, 0)); 1103 1.1 skrll input_line_pointer = s + 1; 1104 1.1 skrll 1105 1.1 skrll return 1; 1106 1.1 skrll } 1107 1.1 skrll 1108 1.1 skrll /* Default the values of symbols known that should be "predefined". We 1109 1.1 skrll don't bother to predefine them unless you actually use one, since there 1110 1.1 skrll are a lot of them. */ 1111 1.1 skrll 1112 1.1 skrll symbolS * 1113 1.1 skrll md_undefined_symbol (char *name ATTRIBUTE_UNUSED) 1114 1.1 skrll { 1115 1.1 skrll return NULL; 1116 1.1 skrll } 1117 1.1 skrll 1118 1.1 skrll /* Parse an operand that is machine-specific, the function was called 1119 1.1 skrll in expr.c by operand() function, when everything failed before it 1120 1.1 skrll call a quit. */ 1121 1.1 skrll 1122 1.1 skrll void 1123 1.1 skrll md_operand (expressionS* expressionP) 1124 1.1 skrll { 1125 1.1 skrll /* Check for the #number representation */ 1126 1.1 skrll if (input_line_pointer[0] == '#' && 1127 1.1.1.10 christos ISDIGIT (input_line_pointer[1])) 1128 1.1 skrll { 1129 1.1 skrll /* We have a numeric number expression. No biggy. */ 1130 1.1 skrll input_line_pointer += 1; /* Skip # */ 1131 1.1 skrll 1132 1.1 skrll (void) expression (expressionP); 1133 1.1 skrll 1134 1.1 skrll if (expressionP->X_op != O_constant) 1135 1.1 skrll as_bad (_("Invalid expression after # number\n")); 1136 1.1 skrll } 1137 1.1 skrll 1138 1.1 skrll return; 1139 1.1 skrll } 1140 1.1 skrll 1141 1.1 skrll /* Round up a section size to the appropriate boundary. */ 1142 1.1 skrll 1143 1.1 skrll valueT 1144 1.1 skrll md_section_align (segT segment ATTRIBUTE_UNUSED, 1145 1.1 skrll valueT size) 1146 1.1 skrll { 1147 1.1 skrll /* Byte alignment is fine. */ 1148 1.1 skrll return size; 1149 1.1 skrll } 1150 1.1 skrll 1151 1.1 skrll /* Exactly what point is a PC-relative offset relative TO? 1152 1.1 skrll On the 29000, they're relative to the address of the instruction, 1153 1.1 skrll which we have set up as the address of the fixup too. */ 1154 1.1 skrll 1155 1.1 skrll long 1156 1.1 skrll md_pcrel_from (fixS* fixP) 1157 1.1 skrll { 1158 1.1 skrll return 4 + fixP->fx_where + fixP->fx_frag->fr_address; 1159 1.1 skrll } 1160 1.1 skrll 1161 1.1 skrll /* Translate internal representation of relocation info to BFD target 1162 1.1 skrll format. 1163 1.1 skrll FIXME: To what extent can we get all relevant targets to use this? 1164 1.1 skrll The above FIXME is from a29k, but I think it is also needed here. */ 1165 1.1 skrll 1166 1.1 skrll arelent * 1167 1.1 skrll tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, 1168 1.1 skrll fixS *fixP) 1169 1.1 skrll { 1170 1.1 skrll arelent * reloc; 1171 1.1 skrll 1172 1.1.1.10 christos reloc = notes_alloc (sizeof (arelent)); 1173 1.1.1.10 christos reloc->sym_ptr_ptr = notes_alloc (sizeof (asymbol *)); 1174 1.1.1.10 christos *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy); 1175 1.1 skrll 1176 1.1.1.10 christos reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type); 1177 1.1 skrll if (reloc->howto == NULL) 1178 1.1 skrll { 1179 1.1 skrll as_bad_where (fixP->fx_file, fixP->fx_line, 1180 1.1 skrll _("internal error: can't export reloc type %d (`%s')"), 1181 1.1 skrll fixP->fx_r_type, 1182 1.1 skrll bfd_get_reloc_code_name (fixP->fx_r_type)); 1183 1.1 skrll return NULL; 1184 1.1 skrll } 1185 1.1 skrll 1186 1.1.1.2 christos gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative); 1187 1.1 skrll 1188 1.1 skrll reloc->address = fixP->fx_frag->fr_address + fixP->fx_where; 1189 1.1 skrll 1190 1.1 skrll if (fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY) 1191 1.1 skrll reloc->address = fixP->fx_offset; 1192 1.1 skrll reloc->addend = 0; 1193 1.1 skrll 1194 1.1 skrll return reloc; 1195 1.1 skrll } 1196 1.1 skrll 1197 1.1 skrll const pseudo_typeS 1198 1.1 skrll dlx_pseudo_table[] = 1199 1.1 skrll { 1200 1.1 skrll /* Some additional ops that are used by gcc-dlx. */ 1201 1.1 skrll {"asciiz", stringer, 8 + 1}, 1202 1.1 skrll {"half", cons, 2}, 1203 1.1 skrll {"dword", cons, 8}, 1204 1.1 skrll {"word", cons, 4}, 1205 1.1 skrll {"proc", s_proc, 0}, 1206 1.1 skrll {"endproc", s_proc, 1}, 1207 1.1 skrll {NULL, NULL, 0} 1208 1.1 skrll }; 1209 1.1 skrll 1210 1.1 skrll void 1211 1.1 skrll dlx_pop_insert (void) 1212 1.1 skrll { 1213 1.1 skrll pop_insert (dlx_pseudo_table); 1214 1.1 skrll return ; 1215 1.1 skrll } 1216