1 1.1 christos /* tc-z8k.c -- Assemble code for the Zilog Z800n 2 1.10 christos Copyright (C) 1992-2025 Free Software Foundation, Inc. 3 1.1 christos 4 1.1 christos This file is part of GAS, the GNU Assembler. 5 1.1 christos 6 1.1 christos GAS is free software; you can redistribute it and/or modify 7 1.1 christos it under the terms of the GNU General Public License as published by 8 1.1 christos the Free Software Foundation; either version 3, or (at your option) 9 1.1 christos any later version. 10 1.1 christos 11 1.1 christos GAS is distributed in the hope that it will be useful, 12 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 1.1 christos GNU General Public License for more details. 15 1.1 christos 16 1.1 christos You should have received a copy of the GNU General Public License 17 1.1 christos along with GAS; see the file COPYING. If not, write to the Free 18 1.1 christos Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 19 1.1 christos 02110-1301, USA. */ 20 1.1 christos 21 1.1 christos /* Written By Steve Chamberlain <sac (at) cygnus.com>. */ 22 1.1 christos 23 1.1 christos #include "as.h" 24 1.1 christos #include "safe-ctype.h" 25 1.1 christos #define DEFINE_TABLE 26 1.1 christos #include "opcodes/z8k-opc.h" 27 1.1 christos 28 1.1 christos const char comment_chars[] = "!"; 29 1.1 christos const char line_comment_chars[] = "#"; 30 1.1 christos const char line_separator_chars[] = ";"; 31 1.1 christos 32 1.1 christos extern int machine; 33 1.1 christos extern int coff_flags; 34 1.1 christos int segmented_mode; 35 1.1 christos 36 1.3 christos /* This is non-zero if target was set from the command line. 37 1.3 christos If non-zero, 1 means Z8002 (non-segmented), 2 means Z8001 (segmented). */ 38 1.1 christos static int z8k_target_from_cmdline; 39 1.1 christos 40 1.1 christos static void 41 1.1 christos s_segm (int segm) 42 1.1 christos { 43 1.1 christos if (segm) 44 1.1 christos { 45 1.1 christos segmented_mode = 1; 46 1.1 christos bfd_set_arch_mach (stdoutput, TARGET_ARCH, bfd_mach_z8001); 47 1.1 christos } 48 1.1 christos else 49 1.1 christos { 50 1.1 christos segmented_mode = 0; 51 1.1 christos bfd_set_arch_mach (stdoutput, TARGET_ARCH, bfd_mach_z8002); 52 1.1 christos } 53 1.1 christos } 54 1.1 christos 55 1.1 christos static void 56 1.1 christos even (int ignore ATTRIBUTE_UNUSED) 57 1.1 christos { 58 1.1 christos frag_align (1, 0, 0); 59 1.1 christos record_alignment (now_seg, 1); 60 1.1 christos } 61 1.1 christos 62 1.1 christos static int 63 1.1 christos tohex (int c) 64 1.1 christos { 65 1.1 christos if (ISDIGIT (c)) 66 1.1 christos return c - '0'; 67 1.1 christos if (ISLOWER (c)) 68 1.1 christos return c - 'a' + 10; 69 1.1 christos return c - 'A' + 10; 70 1.1 christos } 71 1.1 christos 72 1.1 christos static void 73 1.1 christos sval (int ignore ATTRIBUTE_UNUSED) 74 1.1 christos { 75 1.1 christos SKIP_WHITESPACE (); 76 1.1 christos if (*input_line_pointer == '\'') 77 1.1 christos { 78 1.1 christos int c; 79 1.1 christos input_line_pointer++; 80 1.1 christos c = *input_line_pointer++; 81 1.1 christos while (c != '\'') 82 1.1 christos { 83 1.1 christos if (c == '%') 84 1.1 christos { 85 1.1 christos c = (tohex (input_line_pointer[0]) << 4) 86 1.1 christos | tohex (input_line_pointer[1]); 87 1.1 christos input_line_pointer += 2; 88 1.1 christos } 89 1.1 christos FRAG_APPEND_1_CHAR (c); 90 1.1 christos c = *input_line_pointer++; 91 1.1 christos } 92 1.1 christos demand_empty_rest_of_line (); 93 1.1 christos } 94 1.1 christos } 95 1.1 christos 96 1.1 christos /* This table describes all the machine specific pseudo-ops the assembler 97 1.1 christos has to support. The fields are: 98 1.1 christos pseudo-op name without dot 99 1.1 christos function to call to execute this pseudo-op 100 1.1 christos Integer arg to pass to the function 101 1.1 christos */ 102 1.1 christos 103 1.1 christos const pseudo_typeS md_pseudo_table[] = { 104 1.1 christos {"int" , cons , 2}, 105 1.1 christos {"data.b" , cons , 1}, 106 1.1 christos {"data.w" , cons , 2}, 107 1.1 christos {"data.l" , cons , 4}, 108 1.1 christos {"form" , listing_psize , 0}, 109 1.1 christos {"heading", listing_title , 0}, 110 1.1 christos {"import" , s_ignore , 0}, 111 1.1 christos {"page" , listing_eject , 0}, 112 1.1 christos {"program", s_ignore , 0}, 113 1.1 christos {"z8001" , s_segm , 1}, 114 1.1 christos {"z8002" , s_segm , 0}, 115 1.1 christos 116 1.1 christos {"segm" , s_segm , 1}, 117 1.1 christos {"unsegm" , s_segm , 0}, 118 1.1 christos {"unseg" , s_segm , 0}, 119 1.8 christos {"name" , s_file , 0}, 120 1.1 christos {"global" , s_globl , 0}, 121 1.1 christos {"wval" , cons , 2}, 122 1.1 christos {"lval" , cons , 4}, 123 1.1 christos {"bval" , cons , 1}, 124 1.1 christos {"sval" , sval , 0}, 125 1.1 christos {"rsect" , obj_coff_section, 0}, 126 1.1 christos {"sect" , obj_coff_section, 0}, 127 1.1 christos {"block" , s_space , 0}, 128 1.1 christos {"even" , even , 0}, 129 1.1 christos {0 , 0 , 0} 130 1.1 christos }; 131 1.1 christos 132 1.1 christos const char EXP_CHARS[] = "eE"; 133 1.1 christos 134 1.1 christos /* Chars that mean this number is a floating point constant. 135 1.1 christos As in 0f12.456 136 1.1 christos or 0d1.2345e12 */ 137 1.1 christos const char FLT_CHARS[] = "rRsSfFdDxXpP"; 138 1.1 christos 139 1.1 christos /* Opcode mnemonics. */ 140 1.8 christos static htab_t opcode_hash_control; 141 1.1 christos 142 1.1 christos void 143 1.1 christos md_begin (void) 144 1.1 christos { 145 1.1 christos const opcode_entry_type *opcode; 146 1.7 christos unsigned int idx = -1u; 147 1.1 christos 148 1.8 christos opcode_hash_control = str_htab_create (); 149 1.1 christos 150 1.1 christos for (opcode = z8k_table; opcode->name; opcode++) 151 1.1 christos { 152 1.1 christos /* Only enter unique codes into the table. */ 153 1.1 christos if (idx != opcode->idx) 154 1.8 christos str_hash_insert (opcode_hash_control, opcode->name, opcode, 0); 155 1.1 christos idx = opcode->idx; 156 1.1 christos } 157 1.1 christos 158 1.1 christos /* Default to z8002. */ 159 1.3 christos s_segm (z8k_target_from_cmdline ? z8k_target_from_cmdline - 1 : 0); 160 1.1 christos 161 1.1 christos /* Insert the pseudo ops, too. */ 162 1.1 christos for (idx = 0; md_pseudo_table[idx].poc_name; idx++) 163 1.1 christos { 164 1.1 christos opcode_entry_type *fake_opcode; 165 1.5 christos fake_opcode = XNEW (opcode_entry_type); 166 1.1 christos fake_opcode->name = md_pseudo_table[idx].poc_name; 167 1.10 christos fake_opcode->p = md_pseudo_table + idx; 168 1.1 christos fake_opcode->opcode = 250; 169 1.8 christos str_hash_insert (opcode_hash_control, fake_opcode->name, fake_opcode, 0); 170 1.1 christos } 171 1.1 christos } 172 1.1 christos 173 1.1 christos typedef struct z8k_op { 174 1.1 christos /* CLASS_REG_xxx. */ 175 1.1 christos int regsize; 176 1.1 christos 177 1.1 christos /* 0 .. 15. */ 178 1.1 christos unsigned int reg; 179 1.1 christos 180 1.1 christos int mode; 181 1.1 christos 182 1.1 christos /* Any other register associated with the mode. */ 183 1.1 christos unsigned int x_reg; 184 1.1 christos 185 1.1 christos /* Any expression. */ 186 1.1 christos expressionS exp; 187 1.1 christos } op_type; 188 1.1 christos 189 1.1 christos static expressionS *da_operand; 190 1.1 christos static expressionS *imm_operand; 191 1.1 christos 192 1.1 christos static int reg[16]; 193 1.1 christos static int the_cc; 194 1.1 christos static int the_ctrl; 195 1.1 christos static int the_flags; 196 1.1 christos static int the_interrupt; 197 1.1 christos 198 1.1 christos /* Determine register number. src points to the ascii number 199 1.1 christos (after "rl", "rh", "r", "rr", or "rq"). If a character 200 1.1 christos outside the set of {0,',',')','('} follows the number, 201 1.1 christos return NULL to indicate that it's not a valid register 202 1.1 christos number. */ 203 1.1 christos 204 1.1 christos static char * 205 1.1 christos whatreg (unsigned int *preg, char *src) 206 1.1 christos { 207 1.1 christos unsigned int new_reg; 208 1.1 christos 209 1.1 christos /* src[0] is already known to be a digit. */ 210 1.1 christos if (ISDIGIT (src[1])) 211 1.1 christos { 212 1.1 christos new_reg = (src[0] - '0') * 10 + src[1] - '0'; 213 1.1 christos src += 2; 214 1.1 christos } 215 1.1 christos else 216 1.1 christos { 217 1.1 christos new_reg = (src[0] - '0'); 218 1.1 christos src += 1; 219 1.1 christos } 220 1.1 christos 221 1.1 christos if (src[0] != 0 && src[0] != ',' && src[0] != '(' && src[0] != ')') 222 1.1 christos return NULL; 223 1.1 christos 224 1.1 christos *preg = new_reg; 225 1.1 christos return src; 226 1.1 christos } 227 1.1 christos 228 1.1 christos /* Parse operands 229 1.1 christos 230 1.1 christos rh0-rh7, rl0-rl7 231 1.1 christos r0-r15 232 1.1 christos rr0-rr14 233 1.1 christos rq0--rq12 234 1.1 christos WREG r0,r1,r2,r3,r4,r5,r6,r7,fp,sp 235 1.1 christos r0l,r0h,..r7l,r7h 236 1.1 christos @WREG 237 1.1 christos @WREG+ 238 1.1 christos @-WREG 239 1.1 christos #const 240 1.1 christos */ 241 1.1 christos 242 1.1 christos /* Try to parse a reg name. Return a pointer to the first character 243 1.1 christos in SRC after the reg name. */ 244 1.1 christos 245 1.1 christos static char * 246 1.1 christos parse_reg (char *src, int *mode, unsigned int *preg) 247 1.1 christos { 248 1.1 christos char *res = NULL; 249 1.1 christos char regno; 250 1.1 christos 251 1.1 christos /* Check for stack pointer "sp" alias. */ 252 1.1 christos if ((src[0] == 's' || src[0] == 'S') 253 1.1 christos && (src[1] == 'p' || src[1] == 'P') 254 1.1 christos && (src[2] == 0 || src[2] == ',')) 255 1.1 christos { 256 1.1 christos if (segmented_mode) 257 1.1 christos { 258 1.1 christos *mode = CLASS_REG_LONG; 259 1.1 christos *preg = 14; 260 1.1 christos } 261 1.1 christos else 262 1.1 christos { 263 1.1 christos *mode = CLASS_REG_WORD; 264 1.1 christos *preg = 15; 265 1.1 christos } 266 1.1 christos return src + 2; 267 1.1 christos } 268 1.1 christos 269 1.1 christos if (src[0] == 'r' || src[0] == 'R') 270 1.1 christos { 271 1.1 christos if (src[1] == 'r' || src[1] == 'R') 272 1.1 christos { 273 1.1 christos if (src[2] < '0' || src[2] > '9') 274 1.1 christos return NULL; /* Assume no register name but a label starting with 'rr'. */ 275 1.1 christos *mode = CLASS_REG_LONG; 276 1.1 christos res = whatreg (preg, src + 2); 277 1.1 christos if (res == NULL) 278 1.1 christos return NULL; /* Not a valid register name. */ 279 1.1 christos regno = *preg; 280 1.1 christos if (regno > 14) 281 1.1 christos as_bad (_("register rr%d out of range"), regno); 282 1.1 christos if (regno & 1) 283 1.1 christos as_bad (_("register rr%d does not exist"), regno); 284 1.1 christos } 285 1.1 christos else if (src[1] == 'h' || src[1] == 'H') 286 1.1 christos { 287 1.1 christos if (src[2] < '0' || src[2] > '9') 288 1.1 christos return NULL; /* Assume no register name but a label starting with 'rh'. */ 289 1.1 christos *mode = CLASS_REG_BYTE; 290 1.1 christos res = whatreg (preg, src + 2); 291 1.1 christos if (res == NULL) 292 1.1 christos return NULL; /* Not a valid register name. */ 293 1.1 christos regno = *preg; 294 1.1 christos if (regno > 7) 295 1.1 christos as_bad (_("register rh%d out of range"), regno); 296 1.1 christos } 297 1.1 christos else if (src[1] == 'l' || src[1] == 'L') 298 1.1 christos { 299 1.1 christos if (src[2] < '0' || src[2] > '9') 300 1.1 christos return NULL; /* Assume no register name but a label starting with 'rl'. */ 301 1.1 christos *mode = CLASS_REG_BYTE; 302 1.1 christos res = whatreg (preg, src + 2); 303 1.1 christos if (res == NULL) 304 1.1 christos return NULL; /* Not a valid register name. */ 305 1.1 christos regno = *preg; 306 1.1 christos if (regno > 7) 307 1.1 christos as_bad (_("register rl%d out of range"), regno); 308 1.1 christos *preg += 8; 309 1.1 christos } 310 1.1 christos else if (src[1] == 'q' || src[1] == 'Q') 311 1.1 christos { 312 1.1 christos if (src[2] < '0' || src[2] > '9') 313 1.1 christos return NULL; /* Assume no register name but a label starting with 'rq'. */ 314 1.1 christos *mode = CLASS_REG_QUAD; 315 1.1 christos res = whatreg (preg, src + 2); 316 1.1 christos if (res == NULL) 317 1.1 christos return NULL; /* Not a valid register name. */ 318 1.1 christos regno = *preg; 319 1.1 christos if (regno > 12) 320 1.1 christos as_bad (_("register rq%d out of range"), regno); 321 1.1 christos if (regno & 3) 322 1.1 christos as_bad (_("register rq%d does not exist"), regno); 323 1.1 christos } 324 1.1 christos else 325 1.1 christos { 326 1.1 christos if (src[1] < '0' || src[1] > '9') 327 1.1 christos return NULL; /* Assume no register name but a label starting with 'r'. */ 328 1.1 christos *mode = CLASS_REG_WORD; 329 1.1 christos res = whatreg (preg, src + 1); 330 1.1 christos if (res == NULL) 331 1.1 christos return NULL; /* Not a valid register name. */ 332 1.1 christos regno = *preg; 333 1.1 christos if (regno > 15) 334 1.1 christos as_bad (_("register r%d out of range"), regno); 335 1.1 christos } 336 1.1 christos } 337 1.1 christos return res; 338 1.1 christos } 339 1.1 christos 340 1.1 christos static char * 341 1.1 christos parse_exp (char *s, expressionS *op) 342 1.1 christos { 343 1.1 christos char *save = input_line_pointer; 344 1.1 christos char *new_pointer; 345 1.1 christos 346 1.1 christos input_line_pointer = s; 347 1.1 christos expression (op); 348 1.1 christos if (op->X_op == O_absent) 349 1.1 christos as_bad (_("missing operand")); 350 1.1 christos new_pointer = input_line_pointer; 351 1.1 christos input_line_pointer = save; 352 1.1 christos return new_pointer; 353 1.1 christos } 354 1.1 christos 355 1.1 christos /* The many forms of operand: 356 1.1 christos 357 1.1 christos <rb> 358 1.1 christos <r> 359 1.1 christos <rr> 360 1.1 christos <rq> 361 1.1 christos @r 362 1.1 christos #exp 363 1.1 christos exp 364 1.1 christos exp(r) 365 1.1 christos r(#exp) 366 1.1 christos r(r) 367 1.1 christos */ 368 1.1 christos 369 1.1 christos static char * 370 1.1 christos checkfor (char *ptr, char what) 371 1.1 christos { 372 1.1 christos if (*ptr == what) 373 1.1 christos ptr++; 374 1.1 christos else 375 1.1 christos as_bad (_("expected %c"), what); 376 1.1 christos 377 1.1 christos return ptr; 378 1.1 christos } 379 1.1 christos 380 1.1 christos /* Make sure the mode supplied is the size of a word. */ 381 1.1 christos 382 1.1 christos static void 383 1.5 christos regword (int mode, const char *string) 384 1.1 christos { 385 1.1 christos int ok; 386 1.1 christos 387 1.1 christos ok = CLASS_REG_WORD; 388 1.1 christos if (ok != mode) 389 1.1 christos { 390 1.1 christos as_bad (_("register is wrong size for a word %s"), string); 391 1.1 christos } 392 1.1 christos } 393 1.1 christos 394 1.1 christos /* Make sure the mode supplied is the size of an address. */ 395 1.1 christos 396 1.1 christos static void 397 1.5 christos regaddr (int mode, const char *string) 398 1.1 christos { 399 1.1 christos int ok; 400 1.1 christos 401 1.1 christos ok = segmented_mode ? CLASS_REG_LONG : CLASS_REG_WORD; 402 1.1 christos if (ok != mode) 403 1.1 christos { 404 1.1 christos as_bad (_("register is wrong size for address %s"), string); 405 1.1 christos } 406 1.1 christos } 407 1.1 christos 408 1.1 christos struct ctrl_names { 409 1.1 christos int value; 410 1.5 christos const char *name; 411 1.1 christos }; 412 1.1 christos 413 1.1 christos static struct ctrl_names ctrl_table[] = { 414 1.1 christos { 0x1, "flags" }, /* ldctlb only. */ 415 1.1 christos { 0x2, "fcw" }, /* ldctl only. Applies to all remaining control registers. */ 416 1.1 christos { 0x3, "refresh" }, 417 1.1 christos { 0x4, "psapseg" }, 418 1.1 christos { 0x5, "psapoff" }, 419 1.1 christos { 0x5, "psap" }, 420 1.1 christos { 0x6, "nspseg" }, 421 1.1 christos { 0x7, "nspoff" }, 422 1.1 christos { 0x7, "nsp" }, 423 1.1 christos { 0 , 0 } 424 1.1 christos }; 425 1.1 christos 426 1.1 christos static void 427 1.1 christos get_ctrl_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED) 428 1.1 christos { 429 1.1 christos char *src = *ptr; 430 1.1 christos int i, l; 431 1.1 christos 432 1.10 christos while (is_whitespace (*src)) 433 1.1 christos src++; 434 1.1 christos 435 1.1 christos mode->mode = CLASS_CTRL; 436 1.1 christos for (i = 0; ctrl_table[i].name; i++) 437 1.1 christos { 438 1.1 christos l = strlen (ctrl_table[i].name); 439 1.1 christos if (! strncasecmp (ctrl_table[i].name, src, l)) 440 1.1 christos { 441 1.1 christos the_ctrl = ctrl_table[i].value; 442 1.1 christos if (*(src + l) && *(src + l) != ',') 443 1.1 christos break; 444 1.1 christos *ptr = src + l; /* Valid control name found: "consume" it. */ 445 1.1 christos return; 446 1.1 christos } 447 1.1 christos } 448 1.1 christos the_ctrl = 0; 449 1.1 christos } 450 1.1 christos 451 1.1 christos struct flag_names { 452 1.1 christos int value; 453 1.5 christos const char *name; 454 1.1 christos }; 455 1.1 christos 456 1.1 christos static struct flag_names flag_table[] = { 457 1.1 christos { 0x1, "P" }, 458 1.1 christos { 0x1, "V" }, 459 1.1 christos { 0x2, "S" }, 460 1.1 christos { 0x4, "Z" }, 461 1.1 christos { 0x8, "C" }, 462 1.1 christos { 0x0, "+" }, 463 1.1 christos { 0x0, "," }, 464 1.1 christos { 0, 0 } 465 1.1 christos }; 466 1.1 christos 467 1.1 christos static void 468 1.1 christos get_flags_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED) 469 1.1 christos { 470 1.1 christos char *src = *ptr; 471 1.1 christos char c; 472 1.1 christos int i; 473 1.1 christos int j; 474 1.1 christos 475 1.10 christos while (is_whitespace (*src)) 476 1.1 christos src++; 477 1.1 christos 478 1.1 christos mode->mode = CLASS_FLAGS; 479 1.1 christos the_flags = 0; 480 1.1 christos for (j = 0; j <= 9; j++) 481 1.1 christos { 482 1.1 christos if (!src[j]) 483 1.1 christos goto done; 484 1.1 christos c = TOUPPER(src[j]); 485 1.1 christos for (i = 0; flag_table[i].name; i++) 486 1.1 christos { 487 1.1 christos if (flag_table[i].name[0] == c) 488 1.1 christos { 489 1.1 christos the_flags = the_flags | flag_table[i].value; 490 1.1 christos goto match; 491 1.1 christos } 492 1.1 christos } 493 1.1 christos goto done; 494 1.1 christos match: 495 1.1 christos ; 496 1.1 christos } 497 1.1 christos done: 498 1.1 christos *ptr = src + j; 499 1.1 christos } 500 1.1 christos 501 1.1 christos struct interrupt_names { 502 1.1 christos int value; 503 1.5 christos const char *name; 504 1.1 christos }; 505 1.1 christos 506 1.1 christos static struct interrupt_names intr_table[] = { 507 1.1 christos { 0x1, "nvi" }, 508 1.1 christos { 0x2, "vi" }, 509 1.1 christos { 0x3, "both" }, 510 1.1 christos { 0x3, "all" }, 511 1.1 christos { 0, 0 } 512 1.1 christos }; 513 1.1 christos 514 1.1 christos static void 515 1.1 christos get_interrupt_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED) 516 1.1 christos { 517 1.1 christos char *src = *ptr; 518 1.1 christos int i, l; 519 1.1 christos 520 1.10 christos while (is_whitespace (*src)) 521 1.1 christos src++; 522 1.1 christos 523 1.1 christos mode->mode = CLASS_IMM; 524 1.1 christos the_interrupt = 0; 525 1.1 christos 526 1.1 christos while (*src) 527 1.1 christos { 528 1.1 christos for (i = 0; intr_table[i].name; i++) 529 1.1 christos { 530 1.1 christos l = strlen (intr_table[i].name); 531 1.1 christos if (! strncasecmp (intr_table[i].name, src, l)) 532 1.1 christos { 533 1.1 christos the_interrupt |= intr_table[i].value; 534 1.1 christos if (*(src + l) && *(src + l) != ',') 535 1.1 christos { 536 1.1 christos *ptr = src + l; 537 1.1 christos invalid: 538 1.1 christos as_bad (_("unknown interrupt %s"), src); 539 1.10 christos while (! is_end_of_stmt (**ptr)) 540 1.1 christos (*ptr)++; /* Consume rest of line. */ 541 1.1 christos return; 542 1.1 christos } 543 1.1 christos src += l; 544 1.1 christos if (! *src) 545 1.1 christos { 546 1.1 christos *ptr = src; 547 1.1 christos return; 548 1.1 christos } 549 1.1 christos } 550 1.1 christos } 551 1.1 christos if (*src == ',') 552 1.1 christos src++; 553 1.1 christos else 554 1.1 christos { 555 1.1 christos *ptr = src; 556 1.1 christos goto invalid; 557 1.1 christos } 558 1.1 christos } 559 1.1 christos 560 1.1 christos /* No interrupt type specified, opcode won't do anything. */ 561 1.1 christos as_warn (_("opcode has no effect")); 562 1.1 christos the_interrupt = 0x0; 563 1.1 christos } 564 1.1 christos 565 1.1 christos struct cc_names { 566 1.1 christos int value; 567 1.5 christos const char *name; 568 1.1 christos }; 569 1.1 christos 570 1.1 christos static struct cc_names table[] = { 571 1.1 christos { 0x0, "f" }, 572 1.1 christos { 0x1, "lt" }, 573 1.1 christos { 0x2, "le" }, 574 1.1 christos { 0x3, "ule" }, 575 1.1 christos { 0x4, "ov/pe" }, 576 1.1 christos { 0x4, "ov" }, 577 1.1 christos { 0x4, "pe/ov" }, 578 1.1 christos { 0x4, "pe" }, 579 1.1 christos { 0x5, "mi" }, 580 1.1 christos { 0x6, "eq" }, 581 1.1 christos { 0x6, "z" }, 582 1.1 christos { 0x7, "c/ult" }, 583 1.1 christos { 0x7, "c" }, 584 1.1 christos { 0x7, "ult/c" }, 585 1.1 christos { 0x7, "ult" }, 586 1.1 christos { 0x8, "t" }, 587 1.1 christos { 0x9, "ge" }, 588 1.1 christos { 0xa, "gt" }, 589 1.1 christos { 0xb, "ugt" }, 590 1.1 christos { 0xc, "nov/po" }, 591 1.1 christos { 0xc, "nov" }, 592 1.1 christos { 0xc, "po/nov" }, 593 1.1 christos { 0xc, "po" }, 594 1.1 christos { 0xd, "pl" }, 595 1.1 christos { 0xe, "ne" }, 596 1.1 christos { 0xe, "nz" }, 597 1.1 christos { 0xf, "nc/uge" }, 598 1.1 christos { 0xf, "nc" }, 599 1.1 christos { 0xf, "uge/nc" }, 600 1.1 christos { 0xf, "uge" }, 601 1.1 christos { 0 , 0 } 602 1.1 christos }; 603 1.1 christos 604 1.1 christos static void 605 1.1 christos get_cc_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED) 606 1.1 christos { 607 1.1 christos char *src = *ptr; 608 1.1 christos int i, l; 609 1.1 christos 610 1.10 christos while (is_whitespace (*src)) 611 1.1 christos src++; 612 1.1 christos 613 1.1 christos mode->mode = CLASS_CC; 614 1.1 christos for (i = 0; table[i].name; i++) 615 1.1 christos { 616 1.1 christos l = strlen (table[i].name); 617 1.1 christos if (! strncasecmp (table[i].name, src, l)) 618 1.1 christos { 619 1.1 christos the_cc = table[i].value; 620 1.1 christos if (*(src + l) && *(src + l) != ',') 621 1.1 christos break; 622 1.1 christos *ptr = src + l; /* Valid cc found: "consume" it. */ 623 1.1 christos return; 624 1.1 christos } 625 1.1 christos } 626 1.1 christos the_cc = 0x8; /* Not recognizing the cc defaults to t. (Assuming no cc present.) */ 627 1.1 christos } 628 1.1 christos 629 1.1 christos static void 630 1.1 christos get_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED) 631 1.1 christos { 632 1.1 christos char *src = *ptr; 633 1.1 christos char *end; 634 1.1 christos 635 1.1 christos mode->mode = 0; 636 1.1 christos 637 1.10 christos while (is_whitespace (*src)) 638 1.1 christos src++; 639 1.1 christos if (*src == '#') 640 1.1 christos { 641 1.1 christos mode->mode = CLASS_IMM; 642 1.1 christos imm_operand = &(mode->exp); 643 1.1 christos src = parse_exp (src + 1, &(mode->exp)); 644 1.1 christos } 645 1.1 christos else if (*src == '@') 646 1.1 christos { 647 1.1 christos mode->mode = CLASS_IR; 648 1.1 christos src = parse_reg (src + 1, &mode->regsize, &mode->reg); 649 1.1 christos } 650 1.1 christos else 651 1.1 christos { 652 1.1 christos unsigned int regn; 653 1.1 christos 654 1.1 christos end = parse_reg (src, &mode->mode, ®n); 655 1.1 christos 656 1.1 christos if (end) 657 1.1 christos { 658 1.1 christos int nw; 659 1.1 christos unsigned int nr; 660 1.1 christos 661 1.1 christos src = end; 662 1.1 christos if (*src == '(') 663 1.1 christos { 664 1.1 christos src++; 665 1.1 christos end = parse_reg (src, &nw, &nr); 666 1.1 christos if (end) 667 1.1 christos { 668 1.1 christos /* Got Ra(Rb). */ 669 1.1 christos src = end; 670 1.1 christos 671 1.1 christos if (*src != ')') 672 1.1 christos as_bad (_("Missing ) in ra(rb)")); 673 1.1 christos else 674 1.1 christos src++; 675 1.1 christos 676 1.1 christos regaddr (mode->mode, "ra(rb) ra"); 677 1.1 christos mode->mode = CLASS_BX; 678 1.1 christos mode->reg = regn; 679 1.1 christos mode->x_reg = nr; 680 1.1 christos reg[ARG_RX] = nr; 681 1.1 christos } 682 1.1 christos else 683 1.1 christos { 684 1.1 christos /* Got Ra(disp). */ 685 1.1 christos if (*src == '#') 686 1.1 christos src++; 687 1.1 christos src = parse_exp (src, &(mode->exp)); 688 1.1 christos src = checkfor (src, ')'); 689 1.1 christos mode->mode = CLASS_BA; 690 1.1 christos mode->reg = regn; 691 1.1 christos mode->x_reg = 0; 692 1.1 christos imm_operand = &(mode->exp); 693 1.1 christos } 694 1.1 christos } 695 1.1 christos else 696 1.1 christos { 697 1.1 christos mode->reg = regn; 698 1.1 christos mode->x_reg = 0; 699 1.1 christos } 700 1.1 christos } 701 1.1 christos else 702 1.1 christos { 703 1.1 christos /* No initial reg. */ 704 1.1 christos src = parse_exp (src, &(mode->exp)); 705 1.1 christos if (*src == '(') 706 1.1 christos { 707 1.1 christos src++; 708 1.1 christos end = parse_reg (src, &(mode->mode), ®n); 709 1.1 christos regword (mode->mode, "addr(Ra) ra"); 710 1.1 christos mode->mode = CLASS_X; 711 1.1 christos mode->reg = regn; 712 1.1 christos mode->x_reg = 0; 713 1.1 christos da_operand = &(mode->exp); 714 1.1 christos src = checkfor (end, ')'); 715 1.1 christos } 716 1.1 christos else 717 1.1 christos { 718 1.1 christos /* Just an address. */ 719 1.1 christos mode->mode = CLASS_DA; 720 1.1 christos mode->reg = 0; 721 1.1 christos mode->x_reg = 0; 722 1.1 christos da_operand = &(mode->exp); 723 1.1 christos } 724 1.1 christos } 725 1.1 christos } 726 1.1 christos *ptr = src; 727 1.1 christos } 728 1.1 christos 729 1.1 christos static char * 730 1.1 christos get_operands (const opcode_entry_type *opcode, char *op_end, op_type *operand) 731 1.1 christos { 732 1.1 christos char *ptr = op_end; 733 1.1 christos char *savptr; 734 1.1 christos 735 1.1 christos switch (opcode->noperands) 736 1.1 christos { 737 1.1 christos case 0: 738 1.1 christos operand[0].mode = 0; 739 1.1 christos operand[1].mode = 0; 740 1.10 christos while (is_whitespace (*ptr)) 741 1.1 christos ptr++; 742 1.1 christos break; 743 1.1 christos 744 1.1 christos case 1: 745 1.1 christos if (opcode->arg_info[0] == CLASS_CC) 746 1.1 christos { 747 1.1 christos get_cc_operand (&ptr, operand + 0, 0); 748 1.10 christos while (is_whitespace (*ptr)) 749 1.1 christos ptr++; 750 1.10 christos if (! is_end_of_stmt (*ptr)) 751 1.1 christos { 752 1.1 christos as_bad (_("invalid condition code '%s'"), ptr); 753 1.10 christos while (! is_end_of_stmt (*ptr)) 754 1.1 christos ptr++; /* Consume rest of line. */ 755 1.1 christos } 756 1.1 christos } 757 1.1 christos else if (opcode->arg_info[0] == CLASS_FLAGS) 758 1.1 christos { 759 1.1 christos get_flags_operand (&ptr, operand + 0, 0); 760 1.10 christos while (is_whitespace (*ptr)) 761 1.1 christos ptr++; 762 1.10 christos if (! is_end_of_stmt (*ptr)) 763 1.1 christos { 764 1.1 christos as_bad (_("invalid flag '%s'"), ptr); 765 1.10 christos while (*ptr && ! is_end_of_stmt (*ptr)) 766 1.1 christos ptr++; /* Consume rest of line. */ 767 1.1 christos } 768 1.1 christos } 769 1.1 christos else if (opcode->arg_info[0] == (CLASS_IMM + (ARG_IMM2))) 770 1.1 christos get_interrupt_operand (&ptr, operand + 0, 0); 771 1.1 christos else 772 1.1 christos get_operand (&ptr, operand + 0, 0); 773 1.1 christos 774 1.1 christos operand[1].mode = 0; 775 1.1 christos break; 776 1.1 christos 777 1.1 christos case 2: 778 1.1 christos savptr = ptr; 779 1.1 christos if (opcode->arg_info[0] == CLASS_CC) 780 1.1 christos { 781 1.1 christos get_cc_operand (&ptr, operand + 0, 0); 782 1.10 christos while (is_whitespace (*ptr)) 783 1.1 christos ptr++; 784 1.1 christos if (*ptr != ',' && strchr (ptr + 1, ',')) 785 1.1 christos { 786 1.1 christos savptr = ptr; 787 1.1 christos while (*ptr != ',') 788 1.1 christos ptr++; 789 1.1 christos *ptr = 0; 790 1.1 christos ptr++; 791 1.1 christos as_bad (_("invalid condition code '%s'"), savptr); 792 1.1 christos } 793 1.1 christos } 794 1.1 christos else if (opcode->arg_info[0] == CLASS_CTRL) 795 1.1 christos { 796 1.1 christos get_ctrl_operand (&ptr, operand + 0, 0); 797 1.1 christos 798 1.1 christos if (the_ctrl == 0) 799 1.1 christos { 800 1.1 christos ptr = savptr; 801 1.1 christos get_operand (&ptr, operand + 0, 0); 802 1.1 christos 803 1.1 christos if (ptr == 0) 804 1.1 christos return NULL; 805 1.1 christos if (*ptr == ',') 806 1.1 christos ptr++; 807 1.1 christos get_ctrl_operand (&ptr, operand + 1, 1); 808 1.1 christos if (the_ctrl == 0) 809 1.1 christos return NULL; 810 1.1 christos return ptr; 811 1.1 christos } 812 1.1 christos } 813 1.1 christos else 814 1.1 christos get_operand (&ptr, operand + 0, 0); 815 1.1 christos 816 1.1 christos if (ptr == 0) 817 1.1 christos return NULL; 818 1.1 christos if (*ptr == ',') 819 1.1 christos ptr++; 820 1.1 christos get_operand (&ptr, operand + 1, 1); 821 1.1 christos break; 822 1.1 christos 823 1.1 christos case 3: 824 1.1 christos get_operand (&ptr, operand + 0, 0); 825 1.1 christos if (*ptr == ',') 826 1.1 christos ptr++; 827 1.1 christos get_operand (&ptr, operand + 1, 1); 828 1.1 christos if (*ptr == ',') 829 1.1 christos ptr++; 830 1.1 christos get_operand (&ptr, operand + 2, 2); 831 1.1 christos break; 832 1.1 christos 833 1.1 christos case 4: 834 1.1 christos get_operand (&ptr, operand + 0, 0); 835 1.1 christos if (*ptr == ',') 836 1.1 christos ptr++; 837 1.1 christos get_operand (&ptr, operand + 1, 1); 838 1.1 christos if (*ptr == ',') 839 1.1 christos ptr++; 840 1.1 christos get_operand (&ptr, operand + 2, 2); 841 1.1 christos if (*ptr == ',') 842 1.1 christos ptr++; 843 1.1 christos get_cc_operand (&ptr, operand + 3, 3); 844 1.1 christos break; 845 1.1 christos 846 1.1 christos default: 847 1.1 christos abort (); 848 1.1 christos } 849 1.1 christos 850 1.1 christos return ptr; 851 1.1 christos } 852 1.1 christos 853 1.1 christos /* Passed a pointer to a list of opcodes which use different 854 1.1 christos addressing modes. Return the opcode which matches the opcodes 855 1.1 christos provided. */ 856 1.1 christos 857 1.1 christos static opcode_entry_type * 858 1.1 christos get_specific (opcode_entry_type *opcode, op_type *operands) 859 1.1 christos { 860 1.1 christos opcode_entry_type *this_try = opcode; 861 1.1 christos int found = 0; 862 1.1 christos unsigned int noperands = opcode->noperands; 863 1.1 christos 864 1.7 christos unsigned int this_index = opcode->idx; 865 1.1 christos 866 1.1 christos while (this_index == opcode->idx && !found) 867 1.1 christos { 868 1.1 christos unsigned int i; 869 1.1 christos 870 1.1 christos this_try = opcode++; 871 1.1 christos for (i = 0; i < noperands; i++) 872 1.1 christos { 873 1.1 christos unsigned int mode = operands[i].mode; 874 1.1 christos 875 1.1 christos if (((mode & CLASS_MASK) == CLASS_IR) && ((this_try->arg_info[i] & CLASS_MASK) == CLASS_IRO)) 876 1.1 christos { 877 1.1 christos mode = operands[i].mode = (operands[i].mode & ~CLASS_MASK) | CLASS_IRO; 878 1.1 christos } 879 1.1 christos 880 1.1 christos if ((mode & CLASS_MASK) != (this_try->arg_info[i] & CLASS_MASK)) 881 1.1 christos { 882 1.1 christos /* It could be a pc rel operand, if this is a da mode 883 1.1 christos and we like disps, then insert it. */ 884 1.1 christos 885 1.1 christos if (mode == CLASS_DA && this_try->arg_info[i] == CLASS_DISP) 886 1.1 christos { 887 1.1 christos /* This is the case. */ 888 1.1 christos operands[i].mode = CLASS_DISP; 889 1.1 christos } 890 1.1 christos else if (mode == CLASS_BA && this_try->arg_info[i]) 891 1.1 christos { 892 1.1 christos /* Can't think of a way to turn what we've been 893 1.1 christos given into something that's OK. */ 894 1.1 christos goto fail; 895 1.1 christos } 896 1.1 christos else if (this_try->arg_info[i] & CLASS_PR) 897 1.1 christos { 898 1.1 christos if (mode == CLASS_REG_LONG && segmented_mode) 899 1.1 christos { 900 1.1 christos /* OK. */ 901 1.1 christos } 902 1.1 christos else if (mode == CLASS_REG_WORD && !segmented_mode) 903 1.1 christos { 904 1.1 christos /* OK. */ 905 1.1 christos } 906 1.1 christos else 907 1.1 christos goto fail; 908 1.1 christos } 909 1.1 christos else 910 1.1 christos goto fail; 911 1.1 christos } 912 1.1 christos switch (mode & CLASS_MASK) 913 1.1 christos { 914 1.1 christos default: 915 1.1 christos break; 916 1.1 christos case CLASS_IRO: 917 1.1 christos if (operands[i].regsize != CLASS_REG_WORD) 918 1.1 christos as_bad (_("invalid indirect register size")); 919 1.1 christos reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg; 920 1.1 christos break; 921 1.1 christos case CLASS_IR: 922 1.1 christos if ((segmented_mode && operands[i].regsize != CLASS_REG_LONG) 923 1.1 christos || (!segmented_mode && operands[i].regsize != CLASS_REG_WORD)) 924 1.1 christos as_bad (_("invalid indirect register size")); 925 1.1 christos reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg; 926 1.1 christos break; 927 1.1 christos case CLASS_X: 928 1.1 christos case CLASS_BA: 929 1.1 christos case CLASS_BX: 930 1.1 christos case CLASS_DISP: 931 1.1 christos case CLASS_REG: 932 1.1 christos case CLASS_REG_WORD: 933 1.1 christos case CLASS_REG_BYTE: 934 1.1 christos case CLASS_REG_QUAD: 935 1.1 christos case CLASS_REG_LONG: 936 1.1 christos case CLASS_REGN0: 937 1.1 christos reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg; 938 1.1 christos break; 939 1.1 christos case CLASS_CTRL: 940 1.1 christos if (this_try->opcode == OPC_ldctlb && the_ctrl != 1) 941 1.1 christos as_bad (_("invalid control register name")); 942 1.1 christos break; 943 1.1 christos } 944 1.1 christos } 945 1.1 christos 946 1.1 christos found = 1; 947 1.1 christos fail: 948 1.1 christos ; 949 1.1 christos } 950 1.1 christos if (found) 951 1.1 christos return this_try; 952 1.1 christos else 953 1.1 christos return 0; 954 1.1 christos } 955 1.1 christos 956 1.8 christos static unsigned char buffer[20]; 957 1.1 christos 958 1.1 christos static void 959 1.6 christos newfix (int ptr, bfd_reloc_code_real_type type, int size, expressionS *operand) 960 1.1 christos { 961 1.1 christos fixS *fixP; 962 1.1 christos 963 1.1 christos /* Size is in nibbles. */ 964 1.1 christos if (operand->X_add_symbol 965 1.1 christos || operand->X_op_symbol 966 1.1 christos || operand->X_add_number) 967 1.1 christos { 968 1.6 christos int is_pcrel; 969 1.1 christos switch(type) 970 1.1 christos { 971 1.1 christos case BFD_RELOC_8_PCREL: 972 1.1 christos case BFD_RELOC_Z8K_CALLR: 973 1.1 christos case BFD_RELOC_Z8K_DISP7: 974 1.1 christos is_pcrel = 1; 975 1.6 christos break; 976 1.6 christos default: 977 1.6 christos is_pcrel = 0; 978 1.6 christos break; 979 1.1 christos } 980 1.1 christos fixP = fix_new_exp (frag_now, ptr, size / 2, 981 1.1 christos operand, is_pcrel, type); 982 1.1 christos if (is_pcrel) 983 1.1 christos fixP->fx_no_overflow = 1; 984 1.1 christos } 985 1.1 christos } 986 1.1 christos 987 1.8 christos static unsigned char * 988 1.8 christos apply_fix (unsigned char *ptr, bfd_reloc_code_real_type type, 989 1.8 christos expressionS *operand, int size) 990 1.1 christos { 991 1.1 christos long n = operand->X_add_number; 992 1.1 christos 993 1.1 christos /* size is in nibbles. */ 994 1.1 christos 995 1.1 christos newfix ((ptr - buffer) / 2, type, size + 1, operand); 996 1.8 christos 997 1.8 christos if (type == BFD_RELOC_Z8K_DISP7) 998 1.1 christos { 999 1.8 christos /* 2 nibbles, but most significant bit is part of the opcode == 7 bits. */ 1000 1.8 christos *ptr++ = (n >> 4) & 7; 1001 1.1 christos *ptr++ = n >> 0; 1002 1.8 christos } 1003 1.8 christos else 1004 1.8 christos { 1005 1.8 christos switch (size) 1006 1.8 christos { 1007 1.8 christos case 8: /* 8 nibbles == 32 bits. */ 1008 1.8 christos *ptr++ = n >> 28; 1009 1.8 christos *ptr++ = n >> 24; 1010 1.8 christos *ptr++ = n >> 20; 1011 1.8 christos *ptr++ = n >> 16; 1012 1.8 christos /* Fall through. */ 1013 1.8 christos case 4: /* 4 nibbles == 16 bits. */ 1014 1.8 christos *ptr++ = n >> 12; 1015 1.8 christos *ptr++ = n >> 8; 1016 1.8 christos /* Fall through. */ 1017 1.8 christos case 2: 1018 1.8 christos *ptr++ = n >> 4; 1019 1.8 christos /* Fall through. */ 1020 1.8 christos case 1: 1021 1.8 christos *ptr++ = n >> 0; 1022 1.8 christos break; 1023 1.8 christos } 1024 1.1 christos } 1025 1.1 christos return ptr; 1026 1.1 christos } 1027 1.1 christos 1028 1.1 christos /* Now we know what sort of opcodes it is. Let's build the bytes. */ 1029 1.1 christos 1030 1.1 christos static void 1031 1.1 christos build_bytes (opcode_entry_type *this_try, struct z8k_op *operand ATTRIBUTE_UNUSED) 1032 1.1 christos { 1033 1.8 christos unsigned char *output_ptr = buffer; 1034 1.1 christos int c; 1035 1.1 christos int nibble; 1036 1.1 christos unsigned int *class_ptr; 1037 1.1 christos 1038 1.1 christos frag_wane (frag_now); 1039 1.1 christos frag_new (0); 1040 1.1 christos 1041 1.1 christos if (frag_room () < 8) 1042 1.1 christos frag_grow (8); /* Make room for maximum instruction size. */ 1043 1.1 christos 1044 1.1 christos memset (buffer, 0, sizeof (buffer)); 1045 1.1 christos class_ptr = this_try->byte_info; 1046 1.1 christos 1047 1.1 christos for (nibble = 0; (c = *class_ptr++); nibble++) 1048 1.1 christos { 1049 1.1 christos 1050 1.1 christos switch (c & CLASS_MASK) 1051 1.1 christos { 1052 1.1 christos default: 1053 1.1 christos abort (); 1054 1.1 christos 1055 1.1 christos case CLASS_ADDRESS: 1056 1.1 christos /* Direct address, we don't cope with the SS mode right now. */ 1057 1.1 christos if (segmented_mode) 1058 1.1 christos { 1059 1.1 christos /* da_operand->X_add_number |= 0x80000000; -- Now set at relocation time. */ 1060 1.1 christos output_ptr = apply_fix (output_ptr, BFD_RELOC_32, da_operand, 8); 1061 1.1 christos } 1062 1.1 christos else 1063 1.1 christos { 1064 1.1 christos output_ptr = apply_fix (output_ptr, BFD_RELOC_16, da_operand, 4); 1065 1.1 christos } 1066 1.1 christos da_operand = 0; 1067 1.1 christos break; 1068 1.1 christos case CLASS_DISP8: 1069 1.1 christos /* pc rel 8 bit */ 1070 1.1 christos output_ptr = apply_fix (output_ptr, BFD_RELOC_8_PCREL, da_operand, 2); 1071 1.1 christos da_operand = 0; 1072 1.1 christos break; 1073 1.1 christos 1074 1.1 christos case CLASS_0DISP7: 1075 1.1 christos /* pc rel 7 bit */ 1076 1.1 christos *output_ptr = 0; 1077 1.1 christos output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_DISP7, da_operand, 2); 1078 1.1 christos da_operand = 0; 1079 1.1 christos break; 1080 1.1 christos 1081 1.1 christos case CLASS_1DISP7: 1082 1.1 christos /* pc rel 7 bit */ 1083 1.1 christos *output_ptr = 0x80; 1084 1.1 christos output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_DISP7, da_operand, 2); 1085 1.1 christos output_ptr[-2] = 0x8; 1086 1.1 christos da_operand = 0; 1087 1.1 christos break; 1088 1.1 christos 1089 1.1 christos case CLASS_BIT_1OR2: 1090 1.1 christos *output_ptr = c & 0xf; 1091 1.1 christos if (imm_operand) 1092 1.1 christos { 1093 1.1 christos if (imm_operand->X_add_number == 2) 1094 1.1 christos *output_ptr |= 2; 1095 1.1 christos else if (imm_operand->X_add_number != 1) 1096 1.1 christos as_bad (_("immediate must be 1 or 2")); 1097 1.1 christos } 1098 1.1 christos else 1099 1.1 christos as_bad (_("immediate 1 or 2 expected")); 1100 1.1 christos output_ptr++; 1101 1.1 christos break; 1102 1.1 christos case CLASS_CC: 1103 1.1 christos *output_ptr++ = the_cc; 1104 1.1 christos break; 1105 1.1 christos case CLASS_0CCC: 1106 1.1 christos if (the_ctrl < 2 || the_ctrl > 7) 1107 1.1 christos as_bad (_("invalid control register name")); 1108 1.1 christos *output_ptr++ = the_ctrl; 1109 1.1 christos break; 1110 1.1 christos case CLASS_1CCC: 1111 1.1 christos if (the_ctrl < 2 || the_ctrl > 7) 1112 1.1 christos as_bad (_("invalid control register name")); 1113 1.1 christos *output_ptr++ = the_ctrl | 0x8; 1114 1.1 christos break; 1115 1.1 christos case CLASS_00II: 1116 1.1 christos *output_ptr++ = (~the_interrupt & 0x3); 1117 1.1 christos break; 1118 1.1 christos case CLASS_01II: 1119 1.1 christos *output_ptr++ = (~the_interrupt & 0x3) | 0x4; 1120 1.1 christos break; 1121 1.1 christos case CLASS_FLAGS: 1122 1.1 christos *output_ptr++ = the_flags; 1123 1.1 christos break; 1124 1.1 christos case CLASS_IGNORE: 1125 1.1 christos case CLASS_BIT: 1126 1.1 christos *output_ptr++ = c & 0xf; 1127 1.1 christos break; 1128 1.1 christos case CLASS_REGN0: 1129 1.1 christos if (reg[c & 0xf] == 0) 1130 1.1 christos as_bad (_("can't use R0 here")); 1131 1.1 christos /* Fall through. */ 1132 1.1 christos case CLASS_REG: 1133 1.1 christos case CLASS_REG_BYTE: 1134 1.1 christos case CLASS_REG_WORD: 1135 1.1 christos case CLASS_REG_LONG: 1136 1.1 christos case CLASS_REG_QUAD: 1137 1.6 christos /* Insert bit pattern of right reg. */ 1138 1.1 christos *output_ptr++ = reg[c & 0xf]; 1139 1.1 christos break; 1140 1.1 christos case CLASS_DISP: 1141 1.1 christos switch (c & ARG_MASK) 1142 1.1 christos { 1143 1.1 christos case ARG_DISP12: 1144 1.1 christos output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_CALLR, da_operand, 4); 1145 1.1 christos break; 1146 1.1 christos case ARG_DISP16: 1147 1.1 christos output_ptr = apply_fix (output_ptr, BFD_RELOC_16_PCREL, da_operand, 4); 1148 1.1 christos break; 1149 1.1 christos default: 1150 1.1 christos output_ptr = apply_fix (output_ptr, BFD_RELOC_16, da_operand, 4); 1151 1.1 christos } 1152 1.1 christos da_operand = 0; 1153 1.1 christos break; 1154 1.1 christos 1155 1.1 christos case CLASS_IMM: 1156 1.1 christos { 1157 1.1 christos switch (c & ARG_MASK) 1158 1.1 christos { 1159 1.1 christos case ARG_NIM4: 1160 1.1 christos if (imm_operand->X_add_number > 15) 1161 1.1 christos as_bad (_("immediate value out of range")); 1162 1.1 christos imm_operand->X_add_number = -imm_operand->X_add_number; 1163 1.1 christos output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_IMM4L, imm_operand, 1); 1164 1.1 christos break; 1165 1.1 christos /*case ARG_IMMNMINUS1: not used. */ 1166 1.1 christos case ARG_IMM4M1: 1167 1.1 christos imm_operand->X_add_number--; 1168 1.6 christos /* Fall through. */ 1169 1.1 christos case ARG_IMM4: 1170 1.1 christos if (imm_operand->X_add_number > 15) 1171 1.1 christos as_bad (_("immediate value out of range")); 1172 1.1 christos output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_IMM4L, imm_operand, 1); 1173 1.1 christos break; 1174 1.1 christos case ARG_NIM8: 1175 1.1 christos imm_operand->X_add_number = -imm_operand->X_add_number; 1176 1.6 christos /* Fall through. */ 1177 1.1 christos case ARG_IMM8: 1178 1.1 christos output_ptr = apply_fix (output_ptr, BFD_RELOC_8, imm_operand, 2); 1179 1.1 christos break; 1180 1.1 christos case ARG_IMM16: 1181 1.1 christos output_ptr = apply_fix (output_ptr, BFD_RELOC_16, imm_operand, 4); 1182 1.1 christos break; 1183 1.1 christos case ARG_IMM32: 1184 1.1 christos output_ptr = apply_fix (output_ptr, BFD_RELOC_32, imm_operand, 8); 1185 1.1 christos break; 1186 1.1 christos default: 1187 1.1 christos abort (); 1188 1.1 christos } 1189 1.1 christos } 1190 1.1 christos } 1191 1.1 christos } 1192 1.1 christos 1193 1.1 christos /* Copy from the nibble buffer into the frag. */ 1194 1.1 christos { 1195 1.1 christos int length = (output_ptr - buffer) / 2; 1196 1.8 christos unsigned char *src = buffer; 1197 1.8 christos unsigned char *fragp = (unsigned char *) frag_more (length); 1198 1.1 christos 1199 1.1 christos while (src < output_ptr) 1200 1.1 christos { 1201 1.8 christos *fragp = ((src[0] & 0xf) << 4) | (src[1] & 0xf); 1202 1.1 christos src += 2; 1203 1.1 christos fragp++; 1204 1.1 christos } 1205 1.1 christos } 1206 1.1 christos } 1207 1.1 christos 1208 1.1 christos /* This is the guts of the machine-dependent assembler. STR points to a 1209 1.1 christos machine dependent instruction. This function is supposed to emit 1210 1.1 christos the frags/bytes it assembles to. */ 1211 1.1 christos 1212 1.1 christos void 1213 1.1 christos md_assemble (char *str) 1214 1.1 christos { 1215 1.1 christos char c; 1216 1.1 christos char *op_start; 1217 1.1 christos char *op_end; 1218 1.1 christos struct z8k_op operand[4]; 1219 1.1 christos opcode_entry_type *opcode; 1220 1.1 christos 1221 1.1 christos /* Drop leading whitespace. */ 1222 1.10 christos while (is_whitespace (*str)) 1223 1.1 christos str++; 1224 1.1 christos 1225 1.1 christos /* Find the op code end. */ 1226 1.1 christos for (op_start = op_end = str; 1227 1.10 christos ! is_whitespace (*op_end) && ! is_end_of_stmt (*op_end); 1228 1.1 christos op_end++) 1229 1.1 christos ; 1230 1.1 christos 1231 1.1 christos if (op_end == op_start) 1232 1.1 christos { 1233 1.1 christos as_bad (_("can't find opcode ")); 1234 1.1 christos } 1235 1.1 christos c = *op_end; 1236 1.1 christos 1237 1.8 christos *op_end = 0; /* Zero-terminate op code string for str_hash_find() call. */ 1238 1.1 christos 1239 1.10 christos opcode = str_hash_find (opcode_hash_control, op_start); 1240 1.1 christos 1241 1.1 christos if (opcode == NULL) 1242 1.1 christos { 1243 1.1 christos as_bad (_("unknown opcode")); 1244 1.1 christos return; 1245 1.1 christos } 1246 1.1 christos 1247 1.1 christos *op_end = c; /* Restore original string. */ 1248 1.1 christos 1249 1.1 christos if (opcode->opcode == 250) 1250 1.1 christos { 1251 1.10 christos const pseudo_typeS *p; 1252 1.1 christos char oc; 1253 1.1 christos char *old = input_line_pointer; 1254 1.1 christos 1255 1.1 christos /* Was really a pseudo op. */ 1256 1.1 christos 1257 1.1 christos input_line_pointer = op_end; 1258 1.1 christos 1259 1.1 christos oc = *old; 1260 1.1 christos *old = '\n'; 1261 1.10 christos while (is_whitespace (*input_line_pointer)) 1262 1.1 christos input_line_pointer++; 1263 1.10 christos p = opcode->p; 1264 1.1 christos 1265 1.1 christos (p->poc_handler) (p->poc_val); 1266 1.1 christos input_line_pointer = old; 1267 1.1 christos *old = oc; 1268 1.1 christos } 1269 1.1 christos else 1270 1.1 christos { 1271 1.1 christos char *new_input_line_pointer; 1272 1.1 christos 1273 1.1 christos new_input_line_pointer = get_operands (opcode, op_end, operand); 1274 1.1 christos if (new_input_line_pointer) 1275 1.1 christos { 1276 1.1 christos input_line_pointer = new_input_line_pointer; 1277 1.1 christos opcode = get_specific (opcode, operand); 1278 1.1 christos } 1279 1.1 christos 1280 1.1 christos if (new_input_line_pointer == NULL || opcode == NULL) 1281 1.1 christos { 1282 1.1 christos /* Couldn't find an opcode which matched the operands. */ 1283 1.1 christos char *where = frag_more (2); 1284 1.1 christos 1285 1.1 christos where[0] = 0x0; 1286 1.1 christos where[1] = 0x0; 1287 1.1 christos 1288 1.1 christos as_bad (_("Can't find opcode to match operands")); 1289 1.1 christos return; 1290 1.1 christos } 1291 1.1 christos 1292 1.1 christos build_bytes (opcode, operand); 1293 1.1 christos } 1294 1.1 christos } 1295 1.1 christos 1296 1.1 christos /* We have no need to default values of symbols. */ 1297 1.1 christos 1298 1.1 christos symbolS * 1299 1.1 christos md_undefined_symbol (char *name ATTRIBUTE_UNUSED) 1300 1.1 christos { 1301 1.1 christos return 0; 1302 1.1 christos } 1303 1.1 christos 1304 1.1 christos /* Various routines to kill one day. */ 1305 1.1 christos 1306 1.5 christos const char * 1307 1.1 christos md_atof (int type, char *litP, int *sizeP) 1308 1.1 christos { 1309 1.8 christos return ieee_md_atof (type, litP, sizeP, true); 1310 1.1 christos } 1311 1.1 christos 1312 1.10 christos const char md_shortopts[] = "z:"; 1314 1.10 christos 1315 1.1 christos const struct option md_longopts[] = 1316 1.1 christos { 1317 1.1 christos #define OPTION_RELAX (OPTION_MD_BASE) 1318 1.1 christos {"linkrelax", no_argument, NULL, OPTION_RELAX}, 1319 1.1 christos {NULL, no_argument, NULL, 0} 1320 1.1 christos }; 1321 1.10 christos 1322 1.1 christos const size_t md_longopts_size = sizeof (md_longopts); 1323 1.1 christos 1324 1.5 christos int 1325 1.1 christos md_parse_option (int c, const char *arg) 1326 1.1 christos { 1327 1.1 christos switch (c) 1328 1.1 christos { 1329 1.1 christos case 'z': 1330 1.3 christos if (!strcmp (arg, "8001")) 1331 1.1 christos z8k_target_from_cmdline = 2; 1332 1.3 christos else if (!strcmp (arg, "8002")) 1333 1.1 christos z8k_target_from_cmdline = 1; 1334 1.1 christos else 1335 1.1 christos { 1336 1.1 christos as_bad (_("invalid architecture -z%s"), arg); 1337 1.1 christos return 0; 1338 1.1 christos } 1339 1.1 christos break; 1340 1.1 christos 1341 1.1 christos case OPTION_RELAX: 1342 1.1 christos linkrelax = 1; 1343 1.1 christos break; 1344 1.1 christos 1345 1.1 christos default: 1346 1.1 christos return 0; 1347 1.1 christos } 1348 1.1 christos 1349 1.1 christos return 1; 1350 1.1 christos } 1351 1.1 christos 1352 1.1 christos void 1353 1.1 christos md_show_usage (FILE *stream) 1354 1.1 christos { 1355 1.1 christos fprintf (stream, _("\ 1356 1.1 christos Z8K options:\n\ 1357 1.1 christos -z8001 generate segmented code\n\ 1358 1.1 christos -z8002 generate unsegmented code\n\ 1359 1.1 christos -linkrelax create linker relaxable code\n")); 1360 1.1 christos } 1361 1.1 christos 1362 1.1 christos void 1364 1.1 christos md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, 1365 1.1 christos segT sec ATTRIBUTE_UNUSED, 1366 1.1 christos fragS *fragP ATTRIBUTE_UNUSED) 1367 1.1 christos { 1368 1.1 christos printf (_("call to md_convert_frag\n")); 1369 1.1 christos abort (); 1370 1.1 christos } 1371 1.1 christos 1372 1.1 christos /* Generate a machine dependent reloc from a fixup. */ 1373 1.1 christos 1374 1.1 christos arelent* 1375 1.1 christos tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, 1376 1.1 christos fixS *fixp ATTRIBUTE_UNUSED) 1377 1.1 christos { 1378 1.10 christos arelent *reloc; 1379 1.10 christos 1380 1.1 christos reloc = notes_alloc (sizeof (arelent)); 1381 1.1 christos reloc->sym_ptr_ptr = notes_alloc (sizeof (asymbol *)); 1382 1.1 christos *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); 1383 1.1 christos reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; 1384 1.1 christos reloc->addend = fixp->fx_offset; 1385 1.1 christos reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); 1386 1.1 christos 1387 1.1 christos if (! reloc->howto) 1388 1.1 christos { 1389 1.1 christos as_bad_where (fixp->fx_file, fixp->fx_line, 1390 1.1 christos _("Cannot represent %s relocation in object file"), 1391 1.1 christos bfd_get_reloc_code_name (fixp->fx_r_type)); 1392 1.1 christos abort (); 1393 1.1 christos } 1394 1.1 christos return reloc; 1395 1.1 christos } 1396 1.1 christos 1397 1.1 christos valueT 1398 1.7 christos md_section_align (segT seg, valueT size) 1399 1.1 christos { 1400 1.1 christos int align = bfd_section_alignment (seg); 1401 1.1 christos valueT mask = ((valueT) 1 << align) - 1; 1402 1.1 christos 1403 1.1 christos return (size + mask) & ~mask; 1404 1.1 christos } 1405 1.1 christos 1406 1.1 christos /* Attempt to simplify or eliminate a fixup. To indicate that a fixup 1407 1.1 christos has been eliminated, set fix->fx_done. If fix->fx_addsy is non-NULL, 1408 1.1 christos we will have to generate a reloc entry. */ 1409 1.1 christos void 1410 1.10 christos md_apply_fix (fixS *fixP, valueT *valP, segT segment ATTRIBUTE_UNUSED) 1411 1.1 christos { 1412 1.1 christos offsetT val = *valP; 1413 1.1 christos char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; 1414 1.1 christos 1415 1.1 christos switch (fixP->fx_r_type) 1416 1.1 christos { 1417 1.1 christos case BFD_RELOC_Z8K_IMM4L: 1418 1.1 christos if (fixP->fx_addsy) 1419 1.1 christos { 1420 1.1 christos fixP->fx_no_overflow = 1; 1421 1.1 christos fixP->fx_done = 0; 1422 1.1 christos } 1423 1.1 christos else 1424 1.1 christos buf[0] = (buf[0] & 0xf0) | (val & 0xf); 1425 1.1 christos break; 1426 1.1 christos 1427 1.1 christos case BFD_RELOC_8: 1428 1.1 christos if (fixP->fx_addsy) 1429 1.1 christos { 1430 1.1 christos fixP->fx_no_overflow = 1; 1431 1.1 christos fixP->fx_done = 0; 1432 1.1 christos } 1433 1.1 christos else 1434 1.1 christos *buf++ = val; 1435 1.1 christos break; 1436 1.1 christos 1437 1.1 christos case BFD_RELOC_16: 1438 1.1 christos if (fixP->fx_addsy) 1439 1.1 christos { 1440 1.1 christos fixP->fx_no_overflow = 1; 1441 1.1 christos fixP->fx_done = 0; 1442 1.1 christos } 1443 1.1 christos else 1444 1.1 christos { 1445 1.1 christos *buf++ = (val >> 8); 1446 1.1 christos *buf++ = val; 1447 1.1 christos } 1448 1.1 christos break; 1449 1.1 christos 1450 1.1 christos case BFD_RELOC_32: 1451 1.1 christos if (fixP->fx_addsy) 1452 1.1 christos { 1453 1.1 christos fixP->fx_no_overflow = 1; 1454 1.1 christos fixP->fx_done = 0; 1455 1.1 christos } 1456 1.1 christos else 1457 1.1 christos { 1458 1.1 christos *buf++ = (val >> 24); 1459 1.1 christos *buf++ = (val >> 16); 1460 1.1 christos *buf++ = (val >> 8); 1461 1.1 christos *buf++ = val; 1462 1.1 christos } 1463 1.1 christos break; 1464 1.1 christos 1465 1.1 christos case BFD_RELOC_8_PCREL: 1466 1.1 christos if (fixP->fx_addsy) 1467 1.1 christos { 1468 1.1 christos fixP->fx_no_overflow = 1; 1469 1.1 christos fixP->fx_done = 0; 1470 1.1 christos } 1471 1.1 christos else 1472 1.1 christos { 1473 1.1 christos if (val & 1) 1474 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line, 1475 1.1 christos _("cannot branch to odd address")); 1476 1.1 christos val /= 2; 1477 1.1 christos if (val > 127 || val < -128) 1478 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line, 1479 1.1 christos _("relative jump out of range")); 1480 1.1 christos *buf++ = val; 1481 1.1 christos fixP->fx_no_overflow = 1; 1482 1.1 christos fixP->fx_done = 1; 1483 1.1 christos } 1484 1.1 christos break; 1485 1.1 christos 1486 1.1 christos case BFD_RELOC_16_PCREL: 1487 1.1 christos if (fixP->fx_addsy) 1488 1.1 christos { 1489 1.1 christos fixP->fx_no_overflow = 1; 1490 1.1 christos fixP->fx_done = 0; 1491 1.1 christos } 1492 1.1 christos else 1493 1.1 christos { 1494 1.1 christos val = val - fixP->fx_frag->fr_address + fixP->fx_where - fixP->fx_size; 1495 1.1 christos if (val > 32767 || val < -32768) 1496 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line, 1497 1.1 christos _("relative address out of range")); 1498 1.1 christos *buf++ = (val >> 8); 1499 1.1 christos *buf++ = val; 1500 1.1 christos fixP->fx_no_overflow = 1; 1501 1.1 christos fixP->fx_done = 1; 1502 1.1 christos } 1503 1.1 christos break; 1504 1.1 christos 1505 1.1 christos case BFD_RELOC_Z8K_CALLR: 1506 1.1 christos if (fixP->fx_addsy) 1507 1.1 christos { 1508 1.1 christos fixP->fx_no_overflow = 1; 1509 1.1 christos fixP->fx_done = 0; 1510 1.1 christos } 1511 1.1 christos else 1512 1.1 christos { 1513 1.1 christos if (val & 1) 1514 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line, 1515 1.1 christos _("cannot branch to odd address")); 1516 1.1 christos if (val > 4096 || val < -4095) 1517 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line, 1518 1.1 christos _("relative call out of range")); 1519 1.1 christos val = -val / 2; 1520 1.1 christos *buf = (*buf & 0xf0) | ((val >> 8) & 0xf); 1521 1.1 christos buf++; 1522 1.1 christos *buf++ = val & 0xff; 1523 1.1 christos fixP->fx_no_overflow = 1; 1524 1.1 christos fixP->fx_done = 1; 1525 1.1 christos } 1526 1.1 christos break; 1527 1.1 christos 1528 1.1 christos case BFD_RELOC_Z8K_DISP7: 1529 1.1 christos if (fixP->fx_addsy) 1530 1.1 christos { 1531 1.1 christos fixP->fx_no_overflow = 1; 1532 1.1 christos fixP->fx_done = 0; 1533 1.1 christos } 1534 1.1 christos else 1535 1.1 christos { 1536 1.1 christos if (val & 1) 1537 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line, 1538 1.1 christos _("cannot branch to odd address")); 1539 1.1 christos val /= 2; 1540 1.1 christos if (val > 0 || val < -127) 1541 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line, 1542 1.1 christos _("relative jump out of range")); 1543 1.1 christos *buf = (*buf & 0x80) | (-val & 0x7f); 1544 1.1 christos fixP->fx_no_overflow = 1; 1545 1.1 christos fixP->fx_done = 1; 1546 1.1 christos } 1547 1.1 christos break; 1548 1.1 christos 1549 1.1 christos default: 1550 1.1 christos printf(_("md_apply_fix: unknown r_type 0x%x\n"), fixP->fx_r_type); 1551 1.1 christos abort (); 1552 1.1 christos } 1553 1.1 christos 1554 1.1 christos if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0) 1555 1.1 christos fixP->fx_done = 1; 1556 1.1 christos } 1557 1.1 christos 1558 1.1 christos int 1559 1.1 christos md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED, 1560 1.1 christos segT segment_type ATTRIBUTE_UNUSED) 1561 1.1 christos { 1562 1.1 christos printf (_("call to md_estimate_size_before_relax\n")); 1563 1.1 christos abort (); 1564 1.1 christos } 1565 1.1 christos 1566 1.1 christos /* Put number into target byte order. */ 1567 1.1 christos 1568 1.1 christos void 1569 1.1 christos md_number_to_chars (char *ptr, valueT use, int nbytes) 1570 1.1 christos { 1571 1.1 christos number_to_chars_bigendian (ptr, use, nbytes); 1572 1.1 christos } 1573 1.1 christos 1574 1.1 christos /* On the Z8000, a PC-relative offset is relative to the address of the 1575 1.1 christos instruction plus its size. */ 1576 1.1 christos long 1577 1.1 christos md_pcrel_from (fixS *fixP) 1578 1.1 christos { 1579 1.1 christos return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address; 1580 1.1 christos } 1581 1.1 christos 1582 1.1 christos void 1583 1.1 christos tc_coff_symbol_emit_hook (symbolS *s ATTRIBUTE_UNUSED) 1584 { 1585 } 1586