1 1.1 christos /* tc-m68hc11.c -- Assembler code for the Motorola 68HC11 & 68HC12. 2 1.10 christos Copyright (C) 1999-2025 Free Software Foundation, Inc. 3 1.1 christos Written by Stephane Carrez (stcarrez (at) nerim.fr) 4 1.1 christos XGATE and S12X added by James Murray (jsm (at) jsm-net.demon.co.uk) 5 1.1 christos 6 1.1 christos This file is part of GAS, the GNU Assembler. 7 1.1 christos 8 1.1 christos GAS is free software; you can redistribute it and/or modify 9 1.1 christos it under the terms of the GNU General Public License as published by 10 1.1 christos the Free Software Foundation; either version 3, or (at your option) 11 1.1 christos any later version. 12 1.1 christos 13 1.1 christos GAS is distributed in the hope that it will be useful, 14 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 15 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 1.1 christos GNU General Public License for more details. 17 1.1 christos 18 1.1 christos You should have received a copy of the GNU General Public License 19 1.1 christos along with GAS; see the file COPYING. If not, write to 20 1.1 christos the Free Software Foundation, 51 Franklin Street - Fifth Floor, 21 1.1 christos Boston, MA 02110-1301, USA. */ 22 1.1 christos 23 1.1 christos #include "as.h" 24 1.1 christos #include "safe-ctype.h" 25 1.1 christos #include "subsegs.h" 26 1.1 christos #include "opcode/m68hc11.h" 27 1.1 christos #include "dwarf2dbg.h" 28 1.1 christos #include "elf/m68hc11.h" 29 1.1 christos 30 1.1 christos const char comment_chars[] = ";!"; 31 1.1 christos const char line_comment_chars[] = "#*"; 32 1.1 christos const char line_separator_chars[] = ""; 33 1.1 christos 34 1.1 christos const char EXP_CHARS[] = "eE"; 35 1.1 christos const char FLT_CHARS[] = "dD"; 36 1.1 christos 37 1.1 christos #define STATE_CONDITIONAL_BRANCH (1) 38 1.1 christos #define STATE_PC_RELATIVE (2) 39 1.1 christos #define STATE_INDEXED_OFFSET (3) 40 1.1 christos #define STATE_INDEXED_PCREL (4) 41 1.1 christos #define STATE_XBCC_BRANCH (5) 42 1.1 christos #define STATE_CONDITIONAL_BRANCH_6812 (6) 43 1.1 christos 44 1.1 christos #define STATE_BYTE (0) 45 1.1 christos #define STATE_BITS5 (0) 46 1.1 christos #define STATE_WORD (1) 47 1.1 christos #define STATE_BITS9 (1) 48 1.1 christos #define STATE_LONG (2) 49 1.1 christos #define STATE_BITS16 (2) 50 1.1 christos #define STATE_UNDF (3) /* Symbol undefined in pass1 */ 51 1.1 christos 52 1.1 christos /* This macro has no side-effects. */ 53 1.1 christos #define ENCODE_RELAX(what,length) (((what) << 2) + (length)) 54 1.1 christos #define RELAX_STATE(s) ((s) >> 2) 55 1.1 christos #define RELAX_LENGTH(s) ((s) & 3) 56 1.1 christos 57 1.1 christos #define IS_OPCODE(C1,C2) (((C1) & 0x0FF) == ((C2) & 0x0FF)) 58 1.1 christos 59 1.1 christos /* This table describes how you change sizes for the various types of variable 60 1.1 christos size expressions. This version only supports two kinds. */ 61 1.1 christos 62 1.1 christos /* The fields are: 63 1.1 christos How far Forward this mode will reach. 64 1.1 christos How far Backward this mode will reach. 65 1.1 christos How many bytes this mode will add to the size of the frag. 66 1.1 christos Which mode to go to if the offset won't fit in this one. */ 67 1.1 christos 68 1.1 christos relax_typeS md_relax_table[] = 69 1.1 christos { 70 1.1 christos {1, 1, 0, 0}, /* First entries aren't used. */ 71 1.1 christos {1, 1, 0, 0}, /* For no good reason except. */ 72 1.1 christos {1, 1, 0, 0}, /* that the VAX doesn't either. */ 73 1.1 christos {1, 1, 0, 0}, 74 1.1 christos 75 1.1 christos /* Relax for bcc <L>. 76 1.1 christos These insns are translated into b!cc +3 jmp L. */ 77 1.1 christos {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD)}, 78 1.1 christos {0, 0, 3, 0}, 79 1.1 christos {1, 1, 0, 0}, 80 1.1 christos {1, 1, 0, 0}, 81 1.1 christos 82 1.1 christos /* Relax for bsr <L> and bra <L>. 83 1.1 christos These insns are translated into jsr and jmp. */ 84 1.1 christos {(127), (-128), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)}, 85 1.1 christos {0, 0, 1, 0}, 86 1.1 christos {1, 1, 0, 0}, 87 1.1 christos {1, 1, 0, 0}, 88 1.1 christos 89 1.1 christos /* Relax for indexed offset: 5-bits, 9-bits, 16-bits. */ 90 1.1 christos {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9)}, 91 1.1 christos {(255), (-256), 1, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16)}, 92 1.1 christos {0, 0, 2, 0}, 93 1.1 christos {1, 1, 0, 0}, 94 1.1 christos 95 1.1 christos /* Relax for PC relative offset: 5-bits, 9-bits, 16-bits. 96 1.1 christos For the 9-bit case, there will be a -1 correction to take into 97 1.1 christos account the new byte that's why the range is -255..256. */ 98 1.1 christos {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9)}, 99 1.1 christos {(256), (-255), 1, ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16)}, 100 1.1 christos {0, 0, 2, 0}, 101 1.1 christos {1, 1, 0, 0}, 102 1.1 christos 103 1.1 christos /* Relax for dbeq/ibeq/tbeq r,<L>: 104 1.1 christos These insns are translated into db!cc +3 jmp L. */ 105 1.1 christos {(255), (-256), 0, ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_WORD)}, 106 1.1 christos {0, 0, 3, 0}, 107 1.1 christos {1, 1, 0, 0}, 108 1.1 christos {1, 1, 0, 0}, 109 1.1 christos 110 1.1 christos /* Relax for bcc <L> on 68HC12. 111 1.1 christos These insns are translated into lbcc <L>. */ 112 1.1 christos {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_WORD)}, 113 1.1 christos {0, 0, 2, 0}, 114 1.1 christos {1, 1, 0, 0}, 115 1.1 christos {1, 1, 0, 0}, 116 1.1 christos 117 1.1 christos }; 118 1.1 christos 119 1.1 christos /* 68HC11 and 68HC12 registers. They are numbered according to the 68HC12. */ 120 1.1 christos typedef enum register_id 121 1.1 christos { 122 1.1 christos REG_NONE = -1, 123 1.1 christos REG_A = 0, 124 1.1 christos REG_B = 1, 125 1.1 christos REG_CCR = 2, 126 1.1 christos REG_D = 4, 127 1.1 christos REG_X = 5, 128 1.1 christos REG_Y = 6, 129 1.1 christos REG_SP = 7, 130 1.1 christos REG_PC = 8, 131 1.1 christos REG_R0 = 0, 132 1.1 christos REG_R1 = 1, 133 1.1 christos REG_R2 = 2, 134 1.1 christos REG_R3 = 3, 135 1.1 christos REG_R4 = 4, 136 1.1 christos REG_R5 = 5, 137 1.1 christos REG_R6 = 6, 138 1.1 christos REG_R7 = 7, 139 1.1 christos REG_SP_XG = 8, 140 1.1 christos REG_PC_XG = 9, 141 1.1 christos REG_CCR_XG = 10 142 1.1 christos } register_id; 143 1.1 christos 144 1.1 christos typedef struct operand 145 1.1 christos { 146 1.1 christos expressionS exp; 147 1.1 christos register_id reg1; 148 1.1 christos register_id reg2; 149 1.1 christos int mode; 150 1.1 christos } operand; 151 1.1 christos 152 1.1 christos struct m68hc11_opcode_def 153 1.1 christos { 154 1.1 christos long format; 155 1.1 christos int min_operands; 156 1.1 christos int max_operands; 157 1.1 christos int nb_modes; 158 1.1 christos int used; 159 1.1 christos struct m68hc11_opcode *opcode; 160 1.1 christos }; 161 1.1 christos 162 1.1 christos static struct m68hc11_opcode_def *m68hc11_opcode_defs = 0; 163 1.1 christos static int m68hc11_nb_opcode_defs = 0; 164 1.1 christos 165 1.1 christos typedef struct alias 166 1.1 christos { 167 1.1 christos const char *name; 168 1.1 christos const char *alias; 169 1.1 christos } alias; 170 1.1 christos 171 1.1 christos static alias alias_opcodes[] = 172 1.1 christos { 173 1.1 christos {"cpd", "cmpd"}, 174 1.1 christos {"cpx", "cmpx"}, 175 1.1 christos {"cpy", "cmpy"}, 176 1.1 christos {0, 0} 177 1.1 christos }; 178 1.1 christos 179 1.1 christos struct m9s12xg_opcode_def 180 1.1 christos { 181 1.1 christos long format; 182 1.1 christos int min_operands; 183 1.1 christos int max_operands; 184 1.1 christos int nb_modes; 185 1.1 christos int used; 186 1.1 christos struct m9s12xg_opcode *opcode; 187 1.1 christos }; 188 1.1 christos 189 1.1 christos /* Local functions. */ 190 1.1 christos static register_id reg_name_search (char *); 191 1.1 christos static register_id register_name (void); 192 1.1 christos static char *print_opcode_format (struct m68hc11_opcode *, int); 193 1.1 christos static char *skip_whites (char *); 194 1.1 christos static int check_range (long, int); 195 1.1 christos static void print_opcode_list (void); 196 1.1 christos static void get_default_target (void); 197 1.1 christos static void print_insn_format (char *); 198 1.1 christos static int get_operand (operand *, int, long); 199 1.1 christos static void fixup8 (expressionS *, int, int); 200 1.1 christos static void fixup16 (expressionS *, int, int); 201 1.1 christos static void fixup24 (expressionS *, int, int); 202 1.1 christos static void fixup8_xg (expressionS *, int, int); 203 1.1 christos static unsigned char convert_branch (unsigned char); 204 1.1 christos static char *m68hc11_new_insn (int); 205 1.1 christos static void build_dbranch_insn (struct m68hc11_opcode *, 206 1.1 christos operand *, int, int); 207 1.1 christos static int build_indexed_byte (operand *, int, int); 208 1.1 christos static int build_reg_mode (operand *, int); 209 1.1 christos 210 1.1 christos static struct m68hc11_opcode *find (struct m68hc11_opcode_def *, 211 1.1 christos operand *, int); 212 1.1 christos static struct m68hc11_opcode *find_opcode (struct m68hc11_opcode_def *, 213 1.1 christos operand *, int *); 214 1.1 christos static void build_jump_insn (struct m68hc11_opcode *, operand *, int, int); 215 1.1 christos static void build_insn_xg (struct m68hc11_opcode *, operand *, int); 216 1.1 christos static void build_insn (struct m68hc11_opcode *, operand *, int); 217 1.1 christos static int relaxable_symbol (symbolS *); 218 1.1 christos 219 1.1 christos /* Pseudo op to indicate a relax group. */ 220 1.1 christos static void s_m68hc11_relax (int); 221 1.1 christos 222 1.1 christos /* Pseudo op to control the ELF flags. */ 223 1.1 christos static void s_m68hc11_mode (int); 224 1.1 christos 225 1.1 christos /* Process directives specified via pseudo ops. */ 226 1.1 christos static void s_m68hc11_parse_pseudo_instruction (int); 227 1.1 christos 228 1.1 christos /* Mark the symbols with STO_M68HC12_FAR to indicate the functions 229 1.1 christos are using 'rtc' for returning. It is necessary to use 'call' 230 1.1 christos to invoke them. This is also used by the debugger to correctly 231 1.1 christos find the stack frame. */ 232 1.1 christos static void s_m68hc11_mark_symbol (int); 233 1.1 christos 234 1.1 christos /* Controls whether relative branches can be turned into long branches. 235 1.1 christos When the relative offset is too large, the insn are changed: 236 1.1 christos bra -> jmp 237 1.1 christos bsr -> jsr 238 1.1 christos bcc -> b!cc +3 239 1.1 christos jmp L 240 1.1 christos dbcc -> db!cc +3 241 1.1 christos jmp L 242 1.1 christos 243 1.6 christos Setting the flag forbids this. */ 244 1.1 christos static short flag_fixed_branches = 0; 245 1.1 christos 246 1.1 christos /* Force to use long jumps (absolute) instead of relative branches. */ 247 1.1 christos static short flag_force_long_jumps = 0; 248 1.1 christos 249 1.1 christos /* Change the direct addressing mode into an absolute addressing mode 250 1.1 christos when the insn does not support direct addressing. 251 1.1 christos For example, "clr *ZD0" is normally not possible and is changed 252 1.1 christos into "clr ZDO". */ 253 1.1 christos static short flag_strict_direct_addressing = 1; 254 1.1 christos 255 1.1 christos /* When an opcode has invalid operand, print out the syntax of the opcode 256 1.1 christos to stderr. */ 257 1.1 christos static short flag_print_insn_syntax = 0; 258 1.1 christos 259 1.1 christos /* Dumps the list of instructions with syntax and then exit: 260 1.1 christos 1 -> Only dumps the list (sorted by name) 261 1.1 christos 2 -> Generate an example (or test) that can be compiled. */ 262 1.1 christos static short flag_print_opcodes = 0; 263 1.1 christos 264 1.1 christos /* Opcode hash table. */ 265 1.8 christos static htab_t m68hc11_hash; 266 1.1 christos 267 1.1 christos /* Current cpu (either cpu6811 or cpu6812). This is determined automagically 268 1.1 christos by 'get_default_target' by looking at default BFD vector. This is overridden 269 1.1 christos with the -m<cpu> option. */ 270 1.1 christos static int current_architecture = 0; 271 1.1 christos 272 1.1 christos /* Default cpu determined by 'get_default_target'. */ 273 1.1 christos static const char *default_cpu; 274 1.1 christos 275 1.1 christos /* Number of opcodes in the sorted table (filtered by current cpu). */ 276 1.1 christos static int num_opcodes; 277 1.1 christos 278 1.1 christos /* The opcodes sorted by name and filtered by current cpu. */ 279 1.1 christos static struct m68hc11_opcode *m68hc11_sorted_opcodes; 280 1.1 christos 281 1.1 christos /* ELF flags to set in the output file header. */ 282 1.1 christos static int elf_flags = E_M68HC11_F64; 283 1.1 christos 284 1.1 christos /* These are the machine dependent pseudo-ops. These are included so 285 1.1 christos the assembler can work on the output from the SUN C compiler, which 286 1.1 christos generates these. */ 287 1.1 christos 288 1.1 christos /* This table describes all the machine specific pseudo-ops the assembler 289 1.1 christos has to support. The fields are: 290 1.1 christos pseudo-op name without dot 291 1.1 christos function to call to execute this pseudo-op 292 1.1 christos Integer arg to pass to the function. */ 293 1.1 christos const pseudo_typeS md_pseudo_table[] = 294 1.1 christos { 295 1.1 christos /* The following pseudo-ops are supported for MRI compatibility. */ 296 1.1 christos {"fcb", cons, 1}, 297 1.1 christos {"fdb", cons, 2}, 298 1.1 christos {"fqb", cons, 4}, 299 1.1 christos {"fcc", stringer, 8 + 1}, 300 1.1 christos {"rmb", s_space, 0}, 301 1.1 christos 302 1.1 christos /* Motorola ALIS. */ 303 1.1 christos {"xrefb", s_ignore, 0}, /* Same as xref */ 304 1.1 christos 305 1.1 christos /* Gcc driven relaxation. */ 306 1.1 christos {"relax", s_m68hc11_relax, 0}, 307 1.1 christos 308 1.1 christos /* .mode instruction (ala SH). */ 309 1.1 christos {"mode", s_m68hc11_mode, 0}, 310 1.1 christos 311 1.1 christos /* .far instruction. */ 312 1.1 christos {"far", s_m68hc11_mark_symbol, STO_M68HC12_FAR}, 313 1.1 christos 314 1.1 christos /* .interrupt instruction. */ 315 1.1 christos {"interrupt", s_m68hc11_mark_symbol, STO_M68HC12_INTERRUPT}, 316 1.1 christos 317 1.1 christos /* .nobankwarning instruction. */ 318 1.1 christos {"nobankwarning", s_m68hc11_parse_pseudo_instruction, E_M68HC11_NO_BANK_WARNING}, 319 1.1 christos 320 1.1 christos {0, 0, 0} 321 1.1 christos }; 322 1.1 christos 323 1.1 christos /* Options and initialization. */ 325 1.10 christos 326 1.1 christos const char md_shortopts[] = "Sm:"; 327 1.10 christos 328 1.1 christos const struct option md_longopts[] = 329 1.1 christos { 330 1.1 christos #define OPTION_FORCE_LONG_BRANCH (OPTION_MD_BASE) 331 1.6 christos {"force-long-branches", no_argument, NULL, OPTION_FORCE_LONG_BRANCH}, 332 1.1 christos {"force-long-branchs", no_argument, NULL, OPTION_FORCE_LONG_BRANCH}, /* Misspelled version kept for backwards compatibility. */ 333 1.1 christos 334 1.1 christos #define OPTION_SHORT_BRANCHES (OPTION_MD_BASE + 1) 335 1.6 christos {"short-branches", no_argument, NULL, OPTION_SHORT_BRANCHES}, 336 1.1 christos {"short-branchs", no_argument, NULL, OPTION_SHORT_BRANCHES}, /* Misspelled version kept for backwards compatibility. */ 337 1.1 christos 338 1.1 christos #define OPTION_STRICT_DIRECT_MODE (OPTION_MD_BASE + 2) 339 1.1 christos {"strict-direct-mode", no_argument, NULL, OPTION_STRICT_DIRECT_MODE}, 340 1.1 christos 341 1.1 christos #define OPTION_PRINT_INSN_SYNTAX (OPTION_MD_BASE + 3) 342 1.1 christos {"print-insn-syntax", no_argument, NULL, OPTION_PRINT_INSN_SYNTAX}, 343 1.1 christos 344 1.1 christos #define OPTION_PRINT_OPCODES (OPTION_MD_BASE + 4) 345 1.1 christos {"print-opcodes", no_argument, NULL, OPTION_PRINT_OPCODES}, 346 1.1 christos 347 1.1 christos #define OPTION_GENERATE_EXAMPLE (OPTION_MD_BASE + 5) 348 1.1 christos {"generate-example", no_argument, NULL, OPTION_GENERATE_EXAMPLE}, 349 1.1 christos 350 1.1 christos #define OPTION_MSHORT (OPTION_MD_BASE + 6) 351 1.1 christos {"mshort", no_argument, NULL, OPTION_MSHORT}, 352 1.1 christos 353 1.1 christos #define OPTION_MLONG (OPTION_MD_BASE + 7) 354 1.1 christos {"mlong", no_argument, NULL, OPTION_MLONG}, 355 1.1 christos 356 1.1 christos #define OPTION_MSHORT_DOUBLE (OPTION_MD_BASE + 8) 357 1.1 christos {"mshort-double", no_argument, NULL, OPTION_MSHORT_DOUBLE}, 358 1.1 christos 359 1.1 christos #define OPTION_MLONG_DOUBLE (OPTION_MD_BASE + 9) 360 1.1 christos {"mlong-double", no_argument, NULL, OPTION_MLONG_DOUBLE}, 361 1.1 christos 362 1.1 christos #define OPTION_XGATE_RAMOFFSET (OPTION_MD_BASE + 10) 363 1.1 christos {"xgate-ramoffset", no_argument, NULL, OPTION_XGATE_RAMOFFSET}, 364 1.1 christos 365 1.1 christos {NULL, no_argument, NULL, 0} 366 1.10 christos }; 367 1.1 christos const size_t md_longopts_size = sizeof (md_longopts); 368 1.1 christos 369 1.1 christos /* Get the target cpu for the assembler. This is based on the configure 370 1.1 christos options and on the -m68hc11/-m68hc12 option. If no option is specified, 371 1.1 christos we must get the default. */ 372 1.1 christos const char * 373 1.1 christos m68hc11_arch_format (void) 374 1.1 christos { 375 1.1 christos get_default_target (); 376 1.1 christos if (current_architecture & cpu6811) 377 1.1 christos return "elf32-m68hc11"; 378 1.1 christos else 379 1.1 christos return "elf32-m68hc12"; 380 1.1 christos } 381 1.1 christos 382 1.1 christos enum bfd_architecture 383 1.1 christos m68hc11_arch (void) 384 1.1 christos { 385 1.1 christos get_default_target (); 386 1.1 christos if (current_architecture & cpu6811) 387 1.1 christos return bfd_arch_m68hc11; 388 1.1 christos else 389 1.1 christos return bfd_arch_m68hc12; 390 1.1 christos } 391 1.1 christos 392 1.1 christos int 393 1.1 christos m68hc11_mach (void) 394 1.1 christos { 395 1.1 christos return 0; 396 1.1 christos } 397 1.1 christos 398 1.1 christos /* Listing header selected according to cpu. */ 399 1.1 christos const char * 400 1.1 christos m68hc11_listing_header (void) 401 1.1 christos { 402 1.1 christos if (current_architecture & cpu6811) 403 1.1 christos return "M68HC11 GAS "; 404 1.1 christos else if (current_architecture & cpuxgate) 405 1.1 christos return "XGATE GAS "; 406 1.1 christos else if (current_architecture & cpu9s12x) 407 1.1 christos return "S12X GAS "; 408 1.1 christos else 409 1.1 christos return "M68HC12 GAS "; 410 1.1 christos } 411 1.1 christos 412 1.1 christos void 413 1.1 christos md_show_usage (FILE *stream) 414 1.1 christos { 415 1.1 christos get_default_target (); 416 1.1 christos fprintf (stream, _("\ 417 1.1 christos Motorola 68HC11/68HC12/68HCS12 options:\n\ 418 1.1 christos -m68hc11 | -m68hc12 |\n\ 419 1.1 christos -m68hcs12 | -mm9s12x |\n\ 420 1.1 christos -mm9s12xg specify the processor [default %s]\n\ 421 1.1 christos -mshort use 16-bit int ABI (default)\n\ 422 1.1 christos -mlong use 32-bit int ABI\n\ 423 1.1 christos -mshort-double use 32-bit double ABI\n\ 424 1.1 christos -mlong-double use 64-bit double ABI (default)\n\ 425 1.1 christos --force-long-branches always turn relative branches into absolute ones\n\ 426 1.1 christos -S,--short-branches do not turn relative branches into absolute ones\n\ 427 1.1 christos when the offset is out of range\n\ 428 1.1 christos --strict-direct-mode do not turn the direct mode into extended mode\n\ 429 1.1 christos when the instruction does not support direct mode\n\ 430 1.1 christos --print-insn-syntax print the syntax of instruction in case of error\n\ 431 1.1 christos --print-opcodes print the list of instructions with syntax\n\ 432 1.1 christos --xgate-ramoffset offset ram addresses by 0xc000\n\ 433 1.1 christos --generate-example generate an example of each instruction\n\ 434 1.1 christos (used for testing)\n"), default_cpu); 435 1.1 christos 436 1.1 christos } 437 1.1 christos 438 1.1 christos /* Try to identify the default target based on the BFD library. */ 439 1.1 christos static void 440 1.1 christos get_default_target (void) 441 1.1 christos { 442 1.1 christos const bfd_target *target; 443 1.1 christos bfd abfd; 444 1.1 christos 445 1.1 christos if (current_architecture != 0) 446 1.1 christos return; 447 1.1 christos 448 1.1 christos default_cpu = "unknown"; 449 1.1 christos target = bfd_find_target (0, &abfd); 450 1.1 christos if (target && target->name) 451 1.1 christos { 452 1.1 christos if (strcmp (target->name, "elf32-m68hc12") == 0) 453 1.1 christos { 454 1.1 christos current_architecture = cpu6812; 455 1.1 christos default_cpu = "m68hc12"; 456 1.1 christos } 457 1.1 christos else if (strcmp (target->name, "elf32-m68hc11") == 0) 458 1.1 christos { 459 1.1 christos current_architecture = cpu6811; 460 1.1 christos default_cpu = "m68hc11"; 461 1.1 christos } 462 1.1 christos else 463 1.1 christos { 464 1.1 christos as_bad (_("Default target `%s' is not supported."), target->name); 465 1.1 christos } 466 1.1 christos } 467 1.1 christos } 468 1.1 christos 469 1.1 christos void 470 1.1 christos m68hc11_print_statistics (FILE *file) 471 1.1 christos { 472 1.1 christos int i; 473 1.1 christos struct m68hc11_opcode_def *opc; 474 1.8 christos 475 1.1 christos htab_print_statistics (file, "opcode table", m68hc11_hash); 476 1.1 christos 477 1.1 christos opc = m68hc11_opcode_defs; 478 1.1 christos if (opc == 0 || m68hc11_nb_opcode_defs == 0) 479 1.1 christos return; 480 1.1 christos 481 1.1 christos /* Dump the opcode statistics table. */ 482 1.1 christos fprintf (file, _("Name # Modes Min ops Max ops Modes mask # Used\n")); 483 1.1 christos for (i = 0; i < m68hc11_nb_opcode_defs; i++, opc++) 484 1.1 christos { 485 1.1 christos fprintf (file, "%-7.7s %5d %7d %7d 0x%08lx %7d\n", 486 1.1 christos opc->opcode->name, 487 1.1 christos opc->nb_modes, 488 1.1 christos opc->min_operands, opc->max_operands, opc->format, opc->used); 489 1.1 christos } 490 1.1 christos } 491 1.1 christos 492 1.5 christos int 493 1.1 christos md_parse_option (int c, const char *arg) 494 1.1 christos { 495 1.1 christos get_default_target (); 496 1.1 christos switch (c) 497 1.1 christos { 498 1.1 christos /* -S means keep external to 2 bit offset rather than 16 bit one. */ 499 1.1 christos case OPTION_SHORT_BRANCHES: 500 1.1 christos case 'S': 501 1.1 christos flag_fixed_branches = 1; 502 1.1 christos break; 503 1.1 christos 504 1.1 christos case OPTION_FORCE_LONG_BRANCH: 505 1.1 christos flag_force_long_jumps = 1; 506 1.1 christos break; 507 1.1 christos 508 1.1 christos case OPTION_PRINT_INSN_SYNTAX: 509 1.1 christos flag_print_insn_syntax = 1; 510 1.1 christos break; 511 1.1 christos 512 1.1 christos case OPTION_PRINT_OPCODES: 513 1.1 christos flag_print_opcodes = 1; 514 1.1 christos break; 515 1.1 christos 516 1.1 christos case OPTION_STRICT_DIRECT_MODE: 517 1.1 christos flag_strict_direct_addressing = 0; 518 1.1 christos break; 519 1.1 christos 520 1.1 christos case OPTION_GENERATE_EXAMPLE: 521 1.1 christos flag_print_opcodes = 2; 522 1.1 christos break; 523 1.1 christos 524 1.1 christos case OPTION_MSHORT: 525 1.1 christos elf_flags &= ~E_M68HC11_I32; 526 1.1 christos break; 527 1.1 christos 528 1.1 christos case OPTION_MLONG: 529 1.1 christos elf_flags |= E_M68HC11_I32; 530 1.1 christos break; 531 1.1 christos 532 1.1 christos case OPTION_MSHORT_DOUBLE: 533 1.1 christos elf_flags &= ~E_M68HC11_F64; 534 1.1 christos break; 535 1.1 christos 536 1.1 christos case OPTION_MLONG_DOUBLE: 537 1.1 christos elf_flags |= E_M68HC11_F64; 538 1.1 christos break; 539 1.1 christos 540 1.1 christos case OPTION_XGATE_RAMOFFSET: 541 1.1 christos elf_flags |= E_M68HC11_XGATE_RAMOFFSET; 542 1.1 christos break; 543 1.1 christos 544 1.1 christos case 'm': 545 1.1 christos if ((strcasecmp (arg, "68hc11") == 0) 546 1.1 christos || (strcasecmp (arg, "m68hc11") == 0)) 547 1.1 christos current_architecture = cpu6811; 548 1.1 christos else if ((strcasecmp (arg, "68hc12") == 0) 549 1.1 christos || (strcasecmp (arg, "m68hc12") == 0)) 550 1.1 christos current_architecture = cpu6812; 551 1.1 christos else if ((strcasecmp (arg, "68hcs12") == 0) 552 1.1 christos || (strcasecmp (arg, "m68hcs12") == 0)) 553 1.1 christos current_architecture = cpu6812 | cpu6812s; 554 1.1 christos else if (strcasecmp (arg, "m9s12x") == 0) 555 1.1 christos current_architecture = cpu6812 | cpu6812s | cpu9s12x; 556 1.1 christos else if ((strcasecmp (arg, "m9s12xg") == 0) 557 1.6 christos || (strcasecmp (arg, "xgate") == 0)) 558 1.1 christos /* xgate for backwards compatibility */ 559 1.1 christos current_architecture = cpuxgate; 560 1.1 christos else 561 1.1 christos as_bad (_("Option `%s' is not recognized."), arg); 562 1.1 christos break; 563 1.1 christos 564 1.1 christos default: 565 1.1 christos return 0; 566 1.1 christos } 567 1.1 christos 568 1.1 christos return 1; 569 1.1 christos } 570 1.1 christos 571 1.1 christos symbolS * 573 1.1 christos md_undefined_symbol (char *name ATTRIBUTE_UNUSED) 574 1.1 christos { 575 1.1 christos return 0; 576 1.5 christos } 577 1.1 christos 578 1.1 christos const char * 579 1.8 christos md_atof (int type, char *litP, int *sizeP) 580 1.1 christos { 581 1.1 christos return ieee_md_atof (type, litP, sizeP, true); 582 1.1 christos } 583 1.1 christos 584 1.1 christos valueT 585 1.7 christos md_section_align (asection *seg, valueT addr) 586 1.10 christos { 587 1.1 christos int align = bfd_section_alignment (seg); 588 1.1 christos return (addr + ((valueT) 1 << align) - 1) & -((valueT) 1 << align); 589 1.1 christos } 590 1.10 christos 591 1.1 christos static int 592 1.10 christos cmp_opcode (const void *p1, const void *p2) 593 1.10 christos { 594 1.1 christos const struct m68hc11_opcode *op1 = p1; 595 1.1 christos const struct m68hc11_opcode *op2 = p2; 596 1.1 christos return strcmp (op1->name, op2->name); 597 1.1 christos } 598 1.1 christos 599 1.1 christos #define IS_CALL_SYMBOL(MODE) \ 600 1.1 christos (((MODE) & (M6812_OP_PAGE|M6811_OP_IND16)) \ 601 1.1 christos == ((M6812_OP_PAGE|M6811_OP_IND16))) 602 1.1 christos 603 1.1 christos /* Initialize the assembler. Create the opcode hash table 604 1.1 christos (sorted on the names) with the M6811 opcode table 605 1.1 christos (from opcode library). */ 606 1.1 christos void 607 1.5 christos md_begin (void) 608 1.1 christos { 609 1.1 christos const char *prev_name = ""; 610 1.1 christos struct m68hc11_opcode *opcodes; 611 1.1 christos struct m68hc11_opcode_def *opc = 0; 612 1.1 christos int i, j; 613 1.1 christos 614 1.8 christos get_default_target (); 615 1.1 christos 616 1.1 christos m68hc11_hash = str_htab_create (); 617 1.5 christos 618 1.1 christos /* Get a writable copy of the opcode table and sort it on the names. */ 619 1.1 christos opcodes = XNEWVEC (struct m68hc11_opcode, m68hc11_num_opcodes); 620 1.1 christos m68hc11_sorted_opcodes = opcodes; 621 1.1 christos num_opcodes = 0; 622 1.1 christos for (i = 0; i < m68hc11_num_opcodes; i++) 623 1.1 christos { 624 1.1 christos if (m68hc11_opcodes[i].arch & current_architecture) 625 1.1 christos { 626 1.1 christos opcodes[num_opcodes] = m68hc11_opcodes[i]; 627 1.1 christos if (opcodes[num_opcodes].name[0] == 'b' 628 1.1 christos && opcodes[num_opcodes].format & M6811_OP_JUMP_REL 629 1.1 christos && !(opcodes[num_opcodes].format & M6811_OP_BITMASK)) 630 1.1 christos { 631 1.1 christos num_opcodes++; 632 1.1 christos opcodes[num_opcodes] = m68hc11_opcodes[i]; 633 1.1 christos } 634 1.1 christos num_opcodes++; 635 1.1 christos for (j = 0; alias_opcodes[j].name != 0; j++) 636 1.1 christos if (strcmp (m68hc11_opcodes[i].name, alias_opcodes[j].name) == 0) 637 1.1 christos { 638 1.1 christos opcodes[num_opcodes] = m68hc11_opcodes[i]; 639 1.1 christos opcodes[num_opcodes].name = alias_opcodes[j].alias; 640 1.1 christos num_opcodes++; 641 1.1 christos break; 642 1.1 christos } 643 1.10 christos } 644 1.1 christos } 645 1.5 christos qsort (opcodes, num_opcodes, sizeof (struct m68hc11_opcode), cmp_opcode); 646 1.9 christos 647 1.1 christos opc = XNEWVEC (struct m68hc11_opcode_def, num_opcodes); 648 1.1 christos m68hc11_opcode_defs = opc; 649 1.1 christos 650 1.1 christos /* Insert unique names into hash table. The M6811 instruction set 651 1.1 christos has several identical opcode names that have different opcodes based 652 1.1 christos on the operands. This hash table then provides a quick index to 653 1.1 christos the first opcode with a particular name in the opcode table. */ 654 1.1 christos for (i = 0; i < num_opcodes; i++, opcodes++) 655 1.1 christos { 656 1.1 christos int expect; 657 1.1 christos 658 1.9 christos if (strcmp (prev_name, opcodes->name)) 659 1.1 christos { 660 1.9 christos prev_name = opcodes->name; 661 1.9 christos opc++; 662 1.9 christos (opc - 1)->format = 0; 663 1.9 christos (opc - 1)->min_operands = 100; 664 1.9 christos (opc - 1)->max_operands = 0; 665 1.9 christos (opc - 1)->nb_modes = 0; 666 1.9 christos (opc - 1)->opcode = opcodes; 667 1.1 christos (opc - 1)->used = 0; 668 1.9 christos str_hash_insert (m68hc11_hash, opcodes->name, opc - 1, 0); 669 1.9 christos } 670 1.1 christos (opc - 1)->nb_modes++; 671 1.1 christos (opc - 1)->format |= opcodes->format; 672 1.1 christos 673 1.1 christos /* See how many operands this opcode needs. */ 674 1.1 christos expect = 0; 675 1.1 christos if (opcodes->arch == cpuxgate) 676 1.1 christos { 677 1.1 christos if (opcodes->format & (M68XG_OP_IMM3 | M68XG_OP_R | M68XG_OP_REL9 678 1.1 christos | M68XG_OP_REL10 )) 679 1.1 christos expect = 1; 680 1.1 christos else if (opcodes->format & (M68XG_OP_R_R | M68XG_OP_R_IMM4 681 1.1 christos | M68XG_OP_R_IMM8 | M68XG_OP_R_IMM8)) 682 1.1 christos expect = 2; 683 1.1 christos else if (opcodes->format & (M68XG_OP_R_R_R | M68XG_OP_R_R_OFFS5 684 1.1 christos | M68XG_OP_RD_RB_RI | M68XG_OP_RD_RB_RIp 685 1.1 christos | M68XG_OP_RD_RB_mRI)) 686 1.1 christos expect = 3; 687 1.1 christos } 688 1.1 christos else 689 1.1 christos { 690 1.1 christos if (opcodes->format & M6811_OP_MASK) 691 1.1 christos expect++; 692 1.1 christos if (opcodes->format & M6811_OP_BITMASK) 693 1.1 christos expect++; 694 1.1 christos if (opcodes->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16)) 695 1.1 christos expect++; 696 1.1 christos if (opcodes->format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2)) 697 1.1 christos expect++; 698 1.1 christos /* Special case for call instruction. */ 699 1.1 christos if ((opcodes->format & M6812_OP_PAGE) 700 1.1 christos && !(opcodes->format & M6811_OP_IND16)) 701 1.1 christos expect++; 702 1.9 christos } 703 1.9 christos 704 1.1 christos if (expect < (opc - 1)->min_operands) 705 1.1 christos (opc - 1)->min_operands = expect; 706 1.9 christos if (IS_CALL_SYMBOL (opcodes->format)) 707 1.9 christos expect++; 708 1.1 christos if (expect > (opc - 1)->max_operands) 709 1.1 christos (opc - 1)->max_operands = expect; 710 1.1 christos } 711 1.1 christos m68hc11_nb_opcode_defs = opc - m68hc11_opcode_defs; 712 1.1 christos 713 1.1 christos if (flag_print_opcodes) 714 1.1 christos { 715 1.1 christos print_opcode_list (); 716 1.1 christos exit (EXIT_SUCCESS); 717 1.1 christos } 718 1.1 christos } 719 1.1 christos 720 1.1 christos void 721 1.1 christos m68hc11_init_after_args (void) 722 1.1 christos { 723 1.1 christos } 724 1.1 christos 725 1.1 christos /* Builtin help. */ 727 1.1 christos 728 1.1 christos /* Return a string that represents the operand format for the instruction. 729 1.1 christos When example is true, this generates an example of operand. This is used 730 1.1 christos to give an example and also to generate a test. */ 731 1.1 christos 732 1.1 christos static char * 733 1.1 christos print_opcode_format (struct m68hc11_opcode *opcode, int example) 734 1.1 christos { 735 1.1 christos static char buf[128]; 736 1.1 christos int format = opcode->format; 737 1.1 christos char *p; 738 1.1 christos 739 1.1 christos p = buf; 740 1.1 christos buf[0] = 0; 741 1.1 christos 742 1.1 christos if (current_architecture == cpuxgate) 743 1.1 christos { 744 1.1 christos if (format & M68XG_OP_IMM3) 745 1.1 christos { 746 1.1 christos if (example) 747 1.1 christos sprintf (p, "#%d", rand () & 0x007); 748 1.1 christos else 749 1.1 christos strcpy (p, _("imm3")); 750 1.1 christos p = &p[strlen (p)]; 751 1.1 christos } 752 1.1 christos else if (format & M68XG_OP_R) 753 1.1 christos { 754 1.1 christos if (example) 755 1.1 christos sprintf (p, "R%d", rand () & 0x07); 756 1.1 christos else 757 1.1 christos strcpy (p, _("RD")); 758 1.1 christos p = &p[strlen (p)]; 759 1.1 christos } 760 1.1 christos else if (format & M68XG_OP_R_R) 761 1.1 christos { 762 1.1 christos if (example) 763 1.1 christos sprintf (p, "R%d,R%d", rand () & 0x07, rand () & 0x07); 764 1.1 christos else 765 1.1 christos strcpy (p, _("RD,RS")); 766 1.1 christos p = &p[strlen (p)]; 767 1.1 christos } 768 1.1 christos else if (format & M68XG_OP_R_IMM4) 769 1.1 christos { 770 1.1 christos if (example) 771 1.1 christos sprintf (p, "R%d,#%d", rand () & 0x07, rand () & 0x0f); 772 1.1 christos else 773 1.1 christos strcpy (p, _("RI, #imm4")); 774 1.1 christos p = &p[strlen (p)]; 775 1.1 christos } 776 1.1 christos else if (format & M68XG_OP_R_R_R) 777 1.1 christos { 778 1.1 christos if (example) 779 1.1 christos sprintf (p, "R%d,R%d,R%d", rand () & 0x07, rand () & 0x07, rand () & 0x07); 780 1.1 christos else 781 1.1 christos strcpy (p, "RD,RS1,RS2"); 782 1.1 christos p = &p[strlen (p)]; 783 1.1 christos } 784 1.1 christos else if (format & M68XG_OP_REL9) 785 1.1 christos { 786 1.1 christos if (example) 787 1.1 christos sprintf (p, "%d", rand () & 0x1FF); 788 1.1 christos else 789 1.1 christos strcpy (p, "<rel9>"); 790 1.1 christos p = &p[strlen (p)]; 791 1.1 christos } 792 1.1 christos else if (format & M68XG_OP_REL10) 793 1.1 christos { 794 1.1 christos if (example) 795 1.1 christos sprintf (p, "%d", rand () & 0x3FF); 796 1.1 christos else 797 1.1 christos strcpy (p, "<rel10>"); 798 1.1 christos p = &p[strlen (p)]; 799 1.1 christos } 800 1.1 christos else if (format & M68XG_OP_R_R_OFFS5) 801 1.1 christos { 802 1.1 christos if (example) 803 1.1 christos sprintf (p, "R%d, (R%d, #0x%x)", rand () & 0x07, rand () & 0x07, rand () & 0x1f); 804 1.1 christos else 805 1.1 christos strcpy (p, _("RD, (RI,#offs5)")); 806 1.1 christos p = &p[strlen (p)]; 807 1.1 christos } 808 1.1 christos else if (format & M68XG_OP_RD_RB_RI) 809 1.1 christos { 810 1.1 christos if (example) 811 1.1 christos sprintf (p, "R%d, (R%d, R%d)", rand () & 0x07, rand () & 0x07, rand () & 0x07); 812 1.1 christos else 813 1.1 christos strcpy (p, "RD, (RB, RI)"); 814 1.1 christos p = &p[strlen (p)]; 815 1.1 christos } 816 1.1 christos else if (format & M68XG_OP_RD_RB_RIp) 817 1.1 christos { 818 1.1 christos if (example) 819 1.1 christos sprintf (p, "R%d, (R%d, R%d+)", rand () & 0x07, rand () & 0x07, rand () & 0x07); 820 1.1 christos else 821 1.1 christos strcpy (p, "RD, (RB, RI+)"); 822 1.1 christos p = &p[strlen (p)]; 823 1.1 christos } 824 1.1 christos else if (format & M68XG_OP_RD_RB_mRI) 825 1.1 christos { 826 1.1 christos if (example) 827 1.1 christos sprintf (p, "R%d, (R%d, -R%d)", rand () & 0x07, rand () & 0x07, rand () & 0x07); 828 1.1 christos else 829 1.1 christos strcpy (p, "RD, (RB, -RI)"); 830 1.1 christos p = &p[strlen (p)]; 831 1.1 christos } 832 1.1 christos else if (format & M68XG_OP_R_IMM8) 833 1.1 christos { 834 1.1 christos if (example) 835 1.1 christos sprintf (p, "R%d, #0x%x", rand () & 0x07, rand () & 0xff); 836 1.1 christos else 837 1.1 christos strcpy (p, "RD, #imm8"); 838 1.1 christos p = &p[strlen (p)]; 839 1.1 christos } 840 1.1 christos else if (format & M68XG_OP_R_IMM16) 841 1.1 christos { 842 1.1 christos if (example) 843 1.1 christos sprintf (p, "R%d, #0x%x", rand () & 0x07, rand () & 0xffff); 844 1.1 christos else 845 1.1 christos strcpy (p, "RD, #imm16"); 846 1.1 christos p = &p[strlen (p)]; 847 1.1 christos } 848 1.1 christos } 849 1.1 christos else 850 1.1 christos { 851 1.1 christos 852 1.1 christos if (format & M6811_OP_IMM8) 853 1.1 christos { 854 1.1 christos if (example) 855 1.1 christos sprintf (p, "#%d", rand () & 0x0FF); 856 1.1 christos else 857 1.1 christos strcpy (p, _("#<imm8>")); 858 1.1 christos p = &p[strlen (p)]; 859 1.1 christos } 860 1.1 christos 861 1.1 christos if (format & M6811_OP_IMM16) 862 1.1 christos { 863 1.1 christos if (example) 864 1.1 christos sprintf (p, "#%d", rand () & 0x0FFFF); 865 1.1 christos else 866 1.1 christos strcpy (p, _("#<imm16>")); 867 1.1 christos p = &p[strlen (p)]; 868 1.1 christos } 869 1.1 christos 870 1.1 christos if (format & M6811_OP_IX) 871 1.1 christos { 872 1.1 christos if (example) 873 1.1 christos sprintf (p, "%d,X", rand () & 0x0FF); 874 1.1 christos else 875 1.1 christos strcpy (p, _("<imm8>,X")); 876 1.1 christos p = &p[strlen (p)]; 877 1.1 christos } 878 1.1 christos 879 1.1 christos if (format & M6811_OP_IY) 880 1.1 christos { 881 1.1 christos if (example) 882 1.1 christos sprintf (p, "%d,X", rand () & 0x0FF); 883 1.1 christos else 884 1.1 christos strcpy (p, _("<imm8>,X")); 885 1.1 christos p = &p[strlen (p)]; 886 1.1 christos } 887 1.1 christos 888 1.1 christos if (format & M6812_OP_IDX) 889 1.1 christos { 890 1.1 christos if (example) 891 1.1 christos sprintf (p, "%d,X", rand () & 0x0FF); 892 1.1 christos else 893 1.1 christos strcpy (p, "n,r"); 894 1.1 christos p = &p[strlen (p)]; 895 1.1 christos } 896 1.1 christos 897 1.1 christos if (format & M6812_OP_PAGE) 898 1.1 christos { 899 1.1 christos if (example) 900 1.1 christos sprintf (p, ", %d", rand () & 0x0FF); 901 1.1 christos else 902 1.1 christos strcpy (p, ", <page>"); 903 1.1 christos p = &p[strlen (p)]; 904 1.1 christos } 905 1.1 christos 906 1.1 christos if (format & M6811_OP_DIRECT) 907 1.1 christos { 908 1.1 christos if (example) 909 1.1 christos sprintf (p, "*Z%d", rand () & 0x0FF); 910 1.1 christos else 911 1.1 christos strcpy (p, _("*<abs8>")); 912 1.1 christos p = &p[strlen (p)]; 913 1.1 christos } 914 1.1 christos 915 1.1 christos if (format & M6811_OP_BITMASK) 916 1.1 christos { 917 1.1 christos if (buf[0]) 918 1.1 christos *p++ = ' '; 919 1.1 christos 920 1.1 christos if (example) 921 1.1 christos sprintf (p, "#$%02x", rand () & 0x0FF); 922 1.1 christos else 923 1.1 christos strcpy (p, _("#<mask>")); 924 1.1 christos 925 1.1 christos p = &p[strlen (p)]; 926 1.1 christos if (format & M6811_OP_JUMP_REL) 927 1.1 christos *p++ = ' '; 928 1.1 christos } 929 1.1 christos 930 1.1 christos if (format & M6811_OP_IND16) 931 1.1 christos { 932 1.1 christos if (example) 933 1.1 christos sprintf (p, _("symbol%d"), rand () & 0x0FF); 934 1.1 christos else 935 1.1 christos strcpy (p, _("<abs>")); 936 1.1 christos 937 1.1 christos p = &p[strlen (p)]; 938 1.1 christos } 939 1.1 christos 940 1.1 christos if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16)) 941 1.1 christos { 942 1.1 christos if (example) 943 1.1 christos { 944 1.1 christos if (format & M6811_OP_BITMASK) 945 1.1 christos { 946 1.1 christos sprintf (p, ".+%d", rand () & 0x7F); 947 1.1 christos } 948 1.1 christos else 949 1.1 christos { 950 1.1 christos sprintf (p, "L%d", rand () & 0x0FF); 951 1.1 christos } 952 1.1 christos } 953 1.1 christos else 954 1.1 christos strcpy (p, _("<label>")); 955 1.1 christos } 956 1.1 christos } 957 1.1 christos return buf; 958 1.1 christos } 959 1.1 christos 960 1.1 christos /* Prints the list of instructions with the possible operands. */ 961 1.1 christos static void 962 1.5 christos print_opcode_list (void) 963 1.1 christos { 964 1.1 christos int i; 965 1.1 christos const char *prev_name = ""; 966 1.1 christos struct m68hc11_opcode *opcodes; 967 1.1 christos int example = flag_print_opcodes == 2; 968 1.1 christos 969 1.1 christos if (example) 970 1.1 christos printf (_("# Example of `%s' instructions\n\t.sect .text\n_start:\n"), 971 1.1 christos default_cpu); 972 1.1 christos 973 1.1 christos opcodes = m68hc11_sorted_opcodes; 974 1.1 christos 975 1.1 christos /* Walk the list sorted on names (by md_begin). We only report 976 1.1 christos one instruction per line, and we collect the different operand 977 1.1 christos formats. */ 978 1.1 christos for (i = 0; i < num_opcodes; i++, opcodes++) 979 1.1 christos { 980 1.1 christos char *fmt = print_opcode_format (opcodes, example); 981 1.1 christos 982 1.1 christos if (example) 983 1.1 christos { 984 1.1 christos printf ("L%d:\t", i); 985 1.1 christos printf ("%s %s\n", opcodes->name, fmt); 986 1.1 christos } 987 1.1 christos else 988 1.1 christos { 989 1.1 christos if (strcmp (prev_name, opcodes->name)) 990 1.1 christos { 991 1.1 christos if (i > 0) 992 1.10 christos printf ("\n"); 993 1.1 christos 994 1.1 christos printf ("%-5.5s ", opcodes->name); 995 1.1 christos prev_name = opcodes->name; 996 1.1 christos } 997 1.1 christos if (fmt[0]) 998 1.1 christos printf (" [%s]", fmt); 999 1.1 christos } 1000 1.1 christos } 1001 1.1 christos printf ("\n"); 1002 1.1 christos } 1003 1.1 christos 1004 1.1 christos /* Print the instruction format. This operation is called when some 1005 1.1 christos instruction is not correct. Instruction format is printed as an 1006 1.1 christos error message. */ 1007 1.1 christos static void 1008 1.1 christos print_insn_format (char *name) 1009 1.1 christos { 1010 1.1 christos struct m68hc11_opcode_def *opc; 1011 1.10 christos struct m68hc11_opcode *opcode; 1012 1.1 christos char buf[128]; 1013 1.1 christos 1014 1.1 christos opc = str_hash_find (m68hc11_hash, name); 1015 1.1 christos if (opc == NULL) 1016 1.1 christos { 1017 1.1 christos as_bad (_("Instruction `%s' is not recognized."), name); 1018 1.1 christos return; 1019 1.1 christos } 1020 1.1 christos opcode = opc->opcode; 1021 1.1 christos 1022 1.1 christos as_bad (_("Instruction formats for `%s':"), name); 1023 1.1 christos do 1024 1.1 christos { 1025 1.1 christos char *fmt; 1026 1.1 christos 1027 1.1 christos fmt = print_opcode_format (opcode, 0); 1028 1.1 christos sprintf (buf, "\t%-5.5s %s", opcode->name, fmt); 1029 1.1 christos 1030 1.1 christos as_bad ("%s", buf); 1031 1.1 christos opcode++; 1032 1.1 christos } 1033 1.1 christos while (strcmp (opcode->name, name) == 0); 1034 1.1 christos } 1035 1.1 christos 1036 1.1 christos /* Analysis of 68HC11 and 68HC12 operands. */ 1038 1.1 christos 1039 1.1 christos /* reg_name_search() finds the register number given its name. 1040 1.1 christos Returns the register number or REG_NONE on failure. */ 1041 1.1 christos static register_id 1042 1.1 christos reg_name_search (char *name) 1043 1.1 christos { 1044 1.1 christos if (strcasecmp (name, "x") == 0 || strcasecmp (name, "ix") == 0) 1045 1.1 christos return REG_X; 1046 1.1 christos if (strcasecmp (name, "y") == 0 || strcasecmp (name, "iy") == 0) 1047 1.1 christos return REG_Y; 1048 1.1 christos if (strcasecmp (name, "a") == 0) 1049 1.1 christos return REG_A; 1050 1.1 christos if (strcasecmp (name, "b") == 0) 1051 1.1 christos return REG_B; 1052 1.1 christos if (strcasecmp (name, "d") == 0) 1053 1.1 christos return REG_D; 1054 1.1 christos if (strcasecmp (name, "sp") == 0) 1055 1.1 christos return REG_SP; 1056 1.1 christos if (strcasecmp (name, "pc") == 0) 1057 1.1 christos return REG_PC; 1058 1.1 christos if (strcasecmp (name, "ccr") == 0) 1059 1.1 christos return REG_CCR; 1060 1.1 christos /* XGATE */ 1061 1.1 christos if (strcasecmp (name, "r0") == 0) 1062 1.1 christos return REG_R0; 1063 1.1 christos if (strcasecmp (name, "r1") == 0) 1064 1.1 christos return REG_R1; 1065 1.1 christos if (strcasecmp (name, "r2") == 0) 1066 1.1 christos return REG_R2; 1067 1.1 christos if (strcasecmp (name, "r3") == 0) 1068 1.1 christos return REG_R3; 1069 1.1 christos if (strcasecmp (name, "r4") == 0) 1070 1.1 christos return REG_R4; 1071 1.1 christos if (strcasecmp (name, "r5") == 0) 1072 1.1 christos return REG_R5; 1073 1.1 christos if (strcasecmp (name, "r6") == 0) 1074 1.1 christos return REG_R6; 1075 1.1 christos if (strcasecmp (name, "r7") == 0) 1076 1.1 christos return REG_R7; 1077 1.1 christos if (strcasecmp (name, "sp") == 0) 1078 1.1 christos return REG_SP_XG; 1079 1.1 christos if (strcasecmp (name, "pc") == 0) 1080 1.1 christos return REG_PC_XG; 1081 1.1 christos if (strcasecmp (name, "ccr") == 0) 1082 1.1 christos return REG_CCR_XG; 1083 1.1 christos return REG_NONE; 1084 1.1 christos } 1085 1.10 christos 1086 1.1 christos static char * 1087 1.1 christos skip_whites (char *p) 1088 1.1 christos { 1089 1.1 christos while (is_whitespace (*p)) 1090 1.1 christos p++; 1091 1.1 christos 1092 1.1 christos return p; 1093 1.1 christos } 1094 1.1 christos 1095 1.1 christos /* Check the string at input_line_pointer 1096 1.1 christos to see if it is a valid register name. */ 1097 1.1 christos static register_id 1098 1.1 christos register_name (void) 1099 1.1 christos { 1100 1.1 christos register_id reg_number; 1101 1.1 christos char c, *p = input_line_pointer; 1102 1.1 christos 1103 1.1 christos if (!is_name_beginner (*p++)) 1104 1.1 christos return REG_NONE; 1105 1.1 christos 1106 1.1 christos while (is_part_of_name (*p++)) 1107 1.1 christos continue; 1108 1.1 christos 1109 1.1 christos c = *--p; 1110 1.1 christos if (c) 1111 1.1 christos *p++ = 0; 1112 1.1 christos 1113 1.1 christos /* Look to see if it's in the register table. */ 1114 1.1 christos reg_number = reg_name_search (input_line_pointer); 1115 1.1 christos if (reg_number != REG_NONE) 1116 1.1 christos { 1117 1.1 christos if (c) 1118 1.1 christos *--p = c; 1119 1.1 christos 1120 1.1 christos input_line_pointer = p; 1121 1.1 christos return reg_number; 1122 1.1 christos } 1123 1.1 christos if (c) 1124 1.1 christos *--p = c; 1125 1.1 christos 1126 1.1 christos return reg_number; 1127 1.1 christos } 1128 1.1 christos #define M6811_OP_CALL_ADDR 0x00800000 1129 1.1 christos #define M6811_OP_PAGE_ADDR 0x04000000 1130 1.1 christos 1131 1.1 christos /* Parse a string of operands and return an array of expressions. 1132 1.1 christos 1133 1.1 christos Operand mode[0] mode[1] exp[0] exp[1] 1134 1.1 christos #n M6811_OP_IMM16 - O_* 1135 1.1 christos *<exp> M6811_OP_DIRECT - O_* 1136 1.1 christos .{+-}<exp> M6811_OP_JUMP_REL - O_* 1137 1.1 christos <exp> M6811_OP_IND16 - O_* 1138 1.1 christos ,r N,r M6812_OP_IDX M6812_OP_REG O_constant O_register 1139 1.1 christos n,-r M6812_PRE_DEC M6812_OP_REG O_constant O_register 1140 1.1 christos n,+r M6812_PRE_INC " " 1141 1.1 christos n,r- M6812_POST_DEC " " 1142 1.1 christos n,r+ M6812_POST_INC " " 1143 1.1 christos A,r B,r D,r M6811_OP_REG M6812_OP_REG O_register O_register 1144 1.1 christos [D,r] M6811_OP_D_IDX M6812_OP_REG O_register O_register 1145 1.1 christos [n,r] M6811_OP_D_IDX_2 M6812_OP_REG O_constant O_register */ 1146 1.1 christos static int 1147 1.1 christos get_operand (operand *oper, int which, long opmode) 1148 1.1 christos { 1149 1.1 christos char *p = input_line_pointer; 1150 1.1 christos int mode; 1151 1.1 christos register_id reg; 1152 1.1 christos 1153 1.1 christos oper->exp.X_op = O_absent; 1154 1.1 christos oper->reg1 = REG_NONE; 1155 1.1 christos oper->reg2 = REG_NONE; 1156 1.1 christos mode = M6811_OP_NONE; 1157 1.1 christos 1158 1.1 christos p = skip_whites (p); 1159 1.1 christos 1160 1.1 christos if (*p == 0 || *p == '\n' || *p == '\r') 1161 1.1 christos { 1162 1.1 christos input_line_pointer = p; 1163 1.1 christos return 0; 1164 1.1 christos } 1165 1.1 christos 1166 1.1 christos if (*p == '*' && (opmode & (M6811_OP_DIRECT | M6811_OP_IND16))) 1167 1.1 christos { 1168 1.1 christos mode = M6811_OP_DIRECT; 1169 1.1 christos p++; 1170 1.1 christos } 1171 1.1 christos else if (*p == '#') 1172 1.1 christos { 1173 1.1 christos if (!(opmode & (M6811_OP_IMM8 | M6811_OP_IMM16 | M6811_OP_BITMASK))) 1174 1.1 christos { 1175 1.1 christos as_bad (_("Immediate operand is not allowed for operand %d."), 1176 1.1 christos which); 1177 1.1 christos return -1; 1178 1.8 christos } 1179 1.1 christos 1180 1.1 christos mode = M6811_OP_IMM16; 1181 1.1 christos p++; 1182 1.1 christos if (startswith (p, "%hi")) 1183 1.8 christos { 1184 1.1 christos p += 3; 1185 1.1 christos mode |= M6811_OP_HIGH_ADDR; 1186 1.1 christos } 1187 1.1 christos else if (startswith (p, "%lo")) 1188 1.1 christos { 1189 1.1 christos p += 3; 1190 1.8 christos mode |= M6811_OP_LOW_ADDR; 1191 1.1 christos } 1192 1.1 christos /* %page modifier is used to obtain only the page number 1193 1.1 christos of the address of a function. */ 1194 1.1 christos else if (startswith (p, "%page")) 1195 1.1 christos { 1196 1.1 christos p += 5; 1197 1.1 christos mode |= M6811_OP_PAGE_ADDR; 1198 1.1 christos } 1199 1.1 christos 1200 1.1 christos /* %addr modifier is used to obtain the physical address part 1201 1.8 christos of the function (16-bit). For 68HC12 the function will be 1202 1.1 christos mapped in the 16K window at 0x8000 and the value will be 1203 1.1 christos within that window (although the function address may not fit 1204 1.1 christos in 16-bit). See bfd/elf32-m68hc12.c for the translation. */ 1205 1.1 christos else if (startswith (p, "%addr")) 1206 1.1 christos { 1207 1.1 christos p += 5; 1208 1.1 christos mode |= M6811_OP_CALL_ADDR; 1209 1.1 christos } 1210 1.1 christos } 1211 1.1 christos else if (*p == '.' && (p[1] == '+' || p[1] == '-')) 1212 1.1 christos { 1213 1.1 christos p++; 1214 1.1 christos mode = M6811_OP_JUMP_REL; 1215 1.1 christos } 1216 1.1 christos else if (*p == '[') 1217 1.1 christos { 1218 1.1 christos if (current_architecture & cpu6811) 1219 1.1 christos as_bad (_("Indirect indexed addressing is not valid for 68HC11.")); 1220 1.1 christos 1221 1.1 christos p++; 1222 1.1 christos mode = M6812_OP_D_IDX; 1223 1.1 christos p = skip_whites (p); 1224 1.1 christos } 1225 1.1 christos else if (*p == ',') /* Special handling of ,x and ,y. */ 1226 1.1 christos { 1227 1.1 christos p++; 1228 1.1 christos input_line_pointer = p; 1229 1.1 christos 1230 1.1 christos reg = register_name (); 1231 1.1 christos if (reg != REG_NONE) 1232 1.1 christos { 1233 1.1 christos oper->reg1 = reg; 1234 1.1 christos oper->exp.X_op = O_constant; 1235 1.1 christos oper->exp.X_add_number = 0; 1236 1.1 christos oper->mode = M6812_OP_IDX; 1237 1.1 christos return 1; 1238 1.1 christos } 1239 1.8 christos as_bad (_("Spurious `,' or bad indirect register addressing mode.")); 1240 1.1 christos return -1; 1241 1.1 christos } 1242 1.1 christos /* Handle 68HC12 page specification in 'call foo,%page(bar)'. */ 1243 1.1 christos else if ((opmode & M6812_OP_PAGE) && startswith (p, "%page")) 1244 1.1 christos { 1245 1.1 christos p += 5; 1246 1.1 christos mode = M6811_OP_PAGE_ADDR | M6812_OP_PAGE | M6811_OP_IND16; 1247 1.1 christos } 1248 1.1 christos input_line_pointer = p; 1249 1.1 christos 1250 1.1 christos if (mode == M6811_OP_NONE || mode == M6812_OP_D_IDX) 1251 1.1 christos reg = register_name (); 1252 1.1 christos else 1253 1.1 christos reg = REG_NONE; 1254 1.1 christos 1255 1.1 christos if (reg != REG_NONE) 1256 1.1 christos { 1257 1.1 christos p = skip_whites (input_line_pointer); 1258 1.1 christos if (*p == ']' && mode == M6812_OP_D_IDX) 1259 1.1 christos { 1260 1.1 christos as_bad 1261 1.1 christos (_("Missing second register or offset for indexed-indirect mode.")); 1262 1.1 christos return -1; 1263 1.1 christos } 1264 1.1 christos 1265 1.1 christos oper->reg1 = reg; 1266 1.1 christos oper->mode = mode | M6812_OP_REG; 1267 1.1 christos if (*p != ',') 1268 1.1 christos { 1269 1.1 christos if (mode == M6812_OP_D_IDX) 1270 1.1 christos { 1271 1.1 christos as_bad (_("Missing second register for indexed-indirect mode.")); 1272 1.1 christos return -1; 1273 1.1 christos } 1274 1.1 christos return 1; 1275 1.1 christos } 1276 1.1 christos 1277 1.1 christos p++; 1278 1.1 christos input_line_pointer = p; 1279 1.1 christos reg = register_name (); 1280 1.1 christos if (reg != REG_NONE) 1281 1.1 christos { 1282 1.1 christos p = skip_whites (input_line_pointer); 1283 1.1 christos if (mode == M6812_OP_D_IDX) 1284 1.1 christos { 1285 1.1 christos if (*p != ']') 1286 1.1 christos { 1287 1.1 christos as_bad (_("Missing `]' to close indexed-indirect mode.")); 1288 1.1 christos return -1; 1289 1.1 christos } 1290 1.1 christos p++; 1291 1.1 christos oper->mode = M6812_OP_D_IDX; 1292 1.1 christos } 1293 1.1 christos input_line_pointer = p; 1294 1.1 christos 1295 1.1 christos oper->reg2 = reg; 1296 1.1 christos return 1; 1297 1.1 christos } 1298 1.1 christos return 1; 1299 1.1 christos } 1300 1.1 christos 1301 1.1 christos /* In MRI mode, isolate the operand because we can't distinguish 1302 1.1 christos operands from comments. */ 1303 1.1 christos if (flag_mri) 1304 1.10 christos { 1305 1.1 christos char c = 0; 1306 1.1 christos 1307 1.1 christos p = skip_whites (p); 1308 1.1 christos while (*p && !is_whitespace (*p)) 1309 1.1 christos p++; 1310 1.1 christos 1311 1.1 christos if (*p) 1312 1.1 christos { 1313 1.1 christos c = *p; 1314 1.1 christos *p = 0; 1315 1.1 christos } 1316 1.1 christos 1317 1.1 christos /* Parse as an expression. */ 1318 1.1 christos expression (&oper->exp); 1319 1.1 christos 1320 1.1 christos if (c) 1321 1.1 christos { 1322 1.1 christos *p = c; 1323 1.1 christos } 1324 1.1 christos } 1325 1.1 christos else 1326 1.1 christos { 1327 1.1 christos expression (&oper->exp); 1328 1.1 christos } 1329 1.1 christos 1330 1.1 christos if (oper->exp.X_op == O_illegal) 1331 1.1 christos { 1332 1.1 christos as_bad (_("Illegal operand.")); 1333 1.1 christos return -1; 1334 1.1 christos } 1335 1.1 christos else if (oper->exp.X_op == O_absent) 1336 1.1 christos { 1337 1.1 christos as_bad (_("Missing operand.")); 1338 1.1 christos return -1; 1339 1.1 christos } 1340 1.1 christos 1341 1.1 christos p = input_line_pointer; 1342 1.1 christos 1343 1.1 christos if (mode == M6811_OP_NONE || mode == M6811_OP_DIRECT 1344 1.1 christos || mode == M6812_OP_D_IDX) 1345 1.1 christos { 1346 1.1 christos p = skip_whites (input_line_pointer); 1347 1.1 christos 1348 1.1 christos if (*p == ',') 1349 1.1 christos { 1350 1.1 christos int possible_mode = M6811_OP_NONE; 1351 1.1 christos char *old_input_line; 1352 1.1 christos 1353 1.1 christos old_input_line = p; 1354 1.1 christos p++; 1355 1.1 christos 1356 1.1 christos /* 68HC12 pre increment or decrement. */ 1357 1.1 christos if (mode == M6811_OP_NONE) 1358 1.1 christos { 1359 1.1 christos if (*p == '-') 1360 1.1 christos { 1361 1.1 christos possible_mode = M6812_PRE_DEC; 1362 1.1 christos p++; 1363 1.1 christos } 1364 1.1 christos else if (*p == '+') 1365 1.1 christos { 1366 1.1 christos possible_mode = M6812_PRE_INC; 1367 1.1 christos p++; 1368 1.1 christos } 1369 1.1 christos p = skip_whites (p); 1370 1.1 christos } 1371 1.1 christos input_line_pointer = p; 1372 1.1 christos reg = register_name (); 1373 1.1 christos 1374 1.1 christos /* Backtrack if we have a valid constant expression and 1375 1.1 christos it does not correspond to the offset of the 68HC12 indexed 1376 1.1 christos addressing mode (as in N,x). */ 1377 1.1 christos if (reg == REG_NONE && mode == M6811_OP_NONE 1378 1.1 christos && possible_mode != M6811_OP_NONE) 1379 1.1 christos { 1380 1.1 christos oper->mode = M6811_OP_IND16 | M6811_OP_JUMP_REL; 1381 1.1 christos input_line_pointer = skip_whites (old_input_line); 1382 1.1 christos return 1; 1383 1.1 christos } 1384 1.1 christos 1385 1.1 christos if (possible_mode != M6811_OP_NONE) 1386 1.1 christos mode = possible_mode; 1387 1.1 christos 1388 1.1 christos if ((current_architecture & cpu6811) 1389 1.1 christos && possible_mode != M6811_OP_NONE) 1390 1.1 christos as_bad (_("Pre-increment mode is not valid for 68HC11")); 1391 1.1 christos /* Backtrack. */ 1392 1.1 christos if (which == 0 && opmode & M6812_OP_IDX_P2 1393 1.1 christos && reg != REG_X && reg != REG_Y 1394 1.1 christos && reg != REG_PC && reg != REG_SP) 1395 1.1 christos { 1396 1.1 christos reg = REG_NONE; 1397 1.1 christos input_line_pointer = p; 1398 1.1 christos } 1399 1.1 christos 1400 1.1 christos if (reg == REG_NONE && mode != M6811_OP_DIRECT 1401 1.1 christos && !(mode == M6811_OP_NONE && opmode & M6811_OP_IND16)) 1402 1.1 christos { 1403 1.1 christos as_bad (_("Wrong register in register indirect mode.")); 1404 1.1 christos return -1; 1405 1.1 christos } 1406 1.1 christos if (mode == M6812_OP_D_IDX) 1407 1.1 christos { 1408 1.1 christos p = skip_whites (input_line_pointer); 1409 1.1 christos if (*p++ != ']') 1410 1.1 christos { 1411 1.1 christos as_bad (_("Missing `]' to close register indirect operand.")); 1412 1.1 christos return -1; 1413 1.1 christos } 1414 1.1 christos input_line_pointer = p; 1415 1.1 christos oper->reg1 = reg; 1416 1.1 christos oper->mode = M6812_OP_D_IDX_2; 1417 1.1 christos return 1; 1418 1.1 christos } 1419 1.1 christos if (reg != REG_NONE) 1420 1.1 christos { 1421 1.1 christos oper->reg1 = reg; 1422 1.1 christos if (mode == M6811_OP_NONE) 1423 1.1 christos { 1424 1.1 christos p = input_line_pointer; 1425 1.1 christos if (*p == '-') 1426 1.1 christos { 1427 1.1 christos mode = M6812_POST_DEC; 1428 1.1 christos p++; 1429 1.1 christos if (current_architecture & cpu6811) 1430 1.1 christos as_bad 1431 1.1 christos (_("Post-decrement mode is not valid for 68HC11.")); 1432 1.1 christos } 1433 1.1 christos else if (*p == '+') 1434 1.1 christos { 1435 1.1 christos mode = M6812_POST_INC; 1436 1.1 christos p++; 1437 1.1 christos if (current_architecture & cpu6811) 1438 1.1 christos as_bad 1439 1.1 christos (_("Post-increment mode is not valid for 68HC11.")); 1440 1.1 christos } 1441 1.1 christos else 1442 1.1 christos mode = M6812_OP_IDX; 1443 1.1 christos 1444 1.1 christos input_line_pointer = p; 1445 1.1 christos } 1446 1.1 christos else 1447 1.1 christos mode |= M6812_OP_IDX; 1448 1.1 christos 1449 1.1 christos oper->mode = mode; 1450 1.1 christos return 1; 1451 1.1 christos } 1452 1.1 christos input_line_pointer = old_input_line; 1453 1.1 christos } 1454 1.1 christos 1455 1.1 christos if (mode == M6812_OP_D_IDX_2) 1456 1.1 christos { 1457 1.1 christos as_bad (_("Invalid indexed indirect mode.")); 1458 1.1 christos return -1; 1459 1.1 christos } 1460 1.1 christos } 1461 1.1 christos 1462 1.1 christos /* If the mode is not known until now, this is either a label 1463 1.1 christos or an indirect address. */ 1464 1.10 christos if (mode == M6811_OP_NONE) 1465 1.1 christos mode = M6811_OP_IND16 | M6811_OP_JUMP_REL; 1466 1.1 christos 1467 1.1 christos p = input_line_pointer; 1468 1.1 christos while (is_whitespace (*p)) 1469 1.1 christos p++; 1470 1.1 christos input_line_pointer = p; 1471 1.1 christos oper->mode = mode; 1472 1.1 christos 1473 1.1 christos return 1; 1474 1.1 christos } 1475 1.1 christos 1476 1.1 christos #define M6812_AUTO_INC_DEC (M6812_PRE_INC | M6812_PRE_DEC \ 1477 1.1 christos | M6812_POST_INC | M6812_POST_DEC) 1478 1.1 christos 1479 1.1 christos /* Checks that the number 'num' fits for a given mode. */ 1480 1.1 christos static int 1481 1.1 christos check_range (long num, int mode) 1482 1.1 christos { 1483 1.1 christos if (current_architecture == cpuxgate) 1484 1.1 christos { 1485 1.1 christos switch (mode) 1486 1.1 christos { 1487 1.1 christos case M68XG_OP_IMM3: 1488 1.1 christos return (num >= 0 && num <= 7) ? 1 : 0; 1489 1.1 christos 1490 1.1 christos case M68XG_OP_R_IMM4: 1491 1.1 christos return (num >= 0 && num <= 15) ? 1 : 0; 1492 1.1 christos 1493 1.1 christos case M68XG_OP_R_R_OFFS5: 1494 1.1 christos return (num >= 0 && num <= 31) ? 1 : 0; 1495 1.1 christos 1496 1.1 christos case M68XG_OP_R_IMM8: 1497 1.1 christos return (num >= 0 && num <= 255) ? 1 : 0; 1498 1.1 christos 1499 1.1 christos case M68XG_OP_R_IMM16: 1500 1.1 christos return (num >= 0 && num <= 65535) ? 1 : 0; 1501 1.1 christos 1502 1.1 christos case M68XG_OP_B_MARKER: 1503 1.1 christos return (num >= -512 && num <= 511) ? 1 : 0; 1504 1.1 christos 1505 1.1 christos case M68XG_OP_BRA_MARKER: 1506 1.1 christos return (num >= -1024 && num <= 1023) ? 1 : 0; 1507 1.1 christos 1508 1.1 christos default: 1509 1.1 christos return 0; 1510 1.1 christos } 1511 1.1 christos } 1512 1.1 christos else 1513 1.1 christos { 1514 1.1 christos /* Auto increment and decrement are ok for [-8..8] without 0. */ 1515 1.1 christos if (mode & M6812_AUTO_INC_DEC) 1516 1.1 christos return (num != 0 && num <= 8 && num >= -8); 1517 1.1 christos 1518 1.1 christos /* The 68HC12 supports 5, 9 and 16-bit offsets. */ 1519 1.1 christos if (mode & (M6812_INDEXED_IND | M6812_INDEXED | M6812_OP_IDX)) 1520 1.1 christos mode = M6811_OP_IND16; 1521 1.1 christos 1522 1.1 christos if (mode & M6812_OP_JUMP_REL16) 1523 1.1 christos mode = M6811_OP_IND16; 1524 1.1 christos 1525 1.1 christos mode &= ~M6811_OP_BRANCH; 1526 1.1 christos switch (mode) 1527 1.1 christos { 1528 1.1 christos case M6811_OP_IX: 1529 1.1 christos case M6811_OP_IY: 1530 1.1 christos case M6811_OP_DIRECT: 1531 1.1 christos return (num >= 0 && num <= 255) ? 1 : 0; 1532 1.1 christos 1533 1.1 christos case M6811_OP_BITMASK: 1534 1.1 christos case M6811_OP_IMM8: 1535 1.1 christos case M6812_OP_PAGE: 1536 1.1 christos return (((num & 0xFFFFFF00) == 0) || ((num & 0xFFFFFF00) == 0xFFFFFF00)) 1537 1.1 christos ? 1 : 0; 1538 1.1 christos 1539 1.1 christos case M6811_OP_JUMP_REL: 1540 1.1 christos return (num >= -128 && num <= 127) ? 1 : 0; 1541 1.1 christos 1542 1.1 christos case M6811_OP_IND16: 1543 1.1 christos case M6811_OP_IND16 | M6812_OP_PAGE: 1544 1.1 christos case M6811_OP_IMM16: 1545 1.1 christos return (((num & 0xFFFF0000) == 0) || ((num & 0xFFFF0000) == 0xFFFF0000)) 1546 1.1 christos ? 1 : 0; 1547 1.1 christos 1548 1.1 christos case M6812_OP_IBCC_MARKER: 1549 1.1 christos case M6812_OP_TBCC_MARKER: 1550 1.1 christos case M6812_OP_DBCC_MARKER: 1551 1.1 christos return (num >= -256 && num <= 255) ? 1 : 0; 1552 1.1 christos 1553 1.1 christos case M6812_OP_TRAP_ID: 1554 1.1 christos return ((num >= 0x30 && num <= 0x39) 1555 1.1 christos || (num >= 0x40 && num <= 0x0ff)) ? 1 : 0; 1556 1.1 christos 1557 1.1 christos default: 1558 1.1 christos return 0; 1559 1.1 christos } 1560 1.1 christos } 1561 1.1 christos } 1562 1.1 christos 1563 1.1 christos /* Gas fixup generation. */ 1565 1.1 christos 1566 1.1 christos /* Put a 1 byte expression described by 'oper'. If this expression contains 1567 1.1 christos unresolved symbols, generate an 8-bit fixup. */ 1568 1.1 christos static void 1569 1.1 christos fixup8 (expressionS *oper, int mode, int opmode) 1570 1.1 christos { 1571 1.1 christos char *f; 1572 1.1 christos 1573 1.1 christos f = frag_more (1); 1574 1.1 christos 1575 1.1 christos if (oper->X_op == O_constant) 1576 1.1 christos { 1577 1.9 christos if (mode & M6812_OP_TRAP_ID 1578 1.9 christos && !check_range (oper->X_add_number, M6812_OP_TRAP_ID)) 1579 1.1 christos { 1580 1.1 christos static char trap_id_warn_once = 0; 1581 1.1 christos 1582 1.1 christos as_bad (_("Trap id `%" PRId64 "' is out of range."), 1583 1.1 christos (int64_t) oper->X_add_number); 1584 1.1 christos if (trap_id_warn_once == 0) 1585 1.1 christos { 1586 1.1 christos trap_id_warn_once = 1; 1587 1.1 christos as_bad (_("Trap id must be within [0x30..0x39] or [0x40..0xff].")); 1588 1.1 christos } 1589 1.9 christos } 1590 1.9 christos 1591 1.1 christos if (!(mode & M6812_OP_TRAP_ID) 1592 1.1 christos && !check_range (oper->X_add_number, mode)) 1593 1.1 christos { 1594 1.1 christos as_bad (_("Operand out of 8-bit range: `%" PRId64 "'."), 1595 1.1 christos (int64_t) oper->X_add_number); 1596 1.1 christos } 1597 1.1 christos number_to_chars_bigendian (f, oper->X_add_number & 0x0FF, 1); 1598 1.1 christos } 1599 1.1 christos else if (oper->X_op != O_register) 1600 1.1 christos { 1601 1.3 christos if (mode & M6812_OP_TRAP_ID) 1602 1.8 christos as_bad (_("The trap id must be a constant.")); 1603 1.1 christos 1604 1.1 christos if (mode == M6811_OP_JUMP_REL) 1605 1.1 christos { 1606 1.1 christos fix_new_exp (frag_now, f - frag_now->fr_literal, 1, 1607 1.5 christos oper, true, BFD_RELOC_8_PCREL); 1608 1.1 christos } 1609 1.1 christos else 1610 1.1 christos { 1611 1.1 christos fixS *fixp; 1612 1.1 christos bfd_reloc_code_real_type reloc; 1613 1.1 christos 1614 1.1 christos /* Now create an 8-bit fixup. If there was some %hi, %lo 1615 1.1 christos or %page modifier, generate the reloc accordingly. */ 1616 1.1 christos if (opmode & M6811_OP_HIGH_ADDR) 1617 1.1 christos reloc = BFD_RELOC_M68HC11_HI8; 1618 1.1 christos else if (opmode & M6811_OP_LOW_ADDR) 1619 1.1 christos reloc = BFD_RELOC_M68HC11_LO8; 1620 1.1 christos else if (opmode & M6811_OP_PAGE_ADDR) 1621 1.8 christos reloc = BFD_RELOC_M68HC11_PAGE; 1622 1.1 christos else 1623 1.1 christos reloc = BFD_RELOC_8; 1624 1.1 christos 1625 1.1 christos fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1, 1626 1.1 christos oper, false, reloc); 1627 1.1 christos if (reloc != BFD_RELOC_8) 1628 1.1 christos fixp->fx_no_overflow = 1; 1629 1.1 christos } 1630 1.1 christos number_to_chars_bigendian (f, 0, 1); 1631 1.1 christos } 1632 1.1 christos else 1633 1.1 christos { 1634 1.1 christos as_fatal (_("Operand `%x' not recognized in fixup8."), oper->X_op); 1635 1.1 christos } 1636 1.1 christos } 1637 1.1 christos 1638 1.1 christos /* Put a 2 byte expression described by 'oper'. If this expression contains 1639 1.1 christos unresolved symbols, generate a 16-bit fixup. */ 1640 1.1 christos static void 1641 1.1 christos fixup16 (expressionS *oper, int mode, int opmode ATTRIBUTE_UNUSED) 1642 1.1 christos { 1643 1.1 christos char *f; 1644 1.1 christos 1645 1.1 christos f = frag_more (2); 1646 1.9 christos 1647 1.9 christos if (oper->X_op == O_constant) 1648 1.1 christos { 1649 1.1 christos if (!check_range (oper->X_add_number, mode)) 1650 1.1 christos { 1651 1.1 christos as_bad (_("Operand out of 16-bit range: `%" PRId64 "'."), 1652 1.1 christos (int64_t) oper->X_add_number); 1653 1.1 christos } 1654 1.5 christos number_to_chars_bigendian (f, oper->X_add_number & 0x0FFFF, 2); 1655 1.1 christos } 1656 1.1 christos else if (oper->X_op != O_register) 1657 1.1 christos { 1658 1.1 christos fixS *fixp; 1659 1.1 christos bfd_reloc_code_real_type reloc; 1660 1.1 christos 1661 1.1 christos if ((opmode & M6811_OP_CALL_ADDR) && (mode & M6811_OP_IMM16)) 1662 1.1 christos reloc = BFD_RELOC_M68HC11_LO16; 1663 1.1 christos else if (mode & M6812_OP_JUMP_REL16) 1664 1.1 christos reloc = BFD_RELOC_16_PCREL; 1665 1.1 christos else if (mode & M6812_OP_PAGE) 1666 1.1 christos reloc = BFD_RELOC_M68HC11_LO16; 1667 1.1 christos else 1668 1.1 christos reloc = BFD_RELOC_16; 1669 1.1 christos 1670 1.1 christos /* Now create a 16-bit fixup. */ 1671 1.3 christos fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 2, 1672 1.1 christos oper, 1673 1.1 christos reloc == BFD_RELOC_16_PCREL, 1674 1.1 christos reloc); 1675 1.1 christos number_to_chars_bigendian (f, 0, 2); 1676 1.1 christos 1677 1.1 christos if (reloc == BFD_RELOC_M68HC11_LO16) 1678 1.1 christos fixp->fx_no_overflow = 1; 1679 1.1 christos } 1680 1.1 christos else 1681 1.1 christos { 1682 1.1 christos as_fatal (_("Operand `%x' not recognized in fixup16."), oper->X_op); 1683 1.1 christos } 1684 1.1 christos } 1685 1.1 christos 1686 1.1 christos /* Put a 3 byte expression described by 'oper'. If this expression contains 1687 1.1 christos unresolved symbols, generate a 24-bit fixup. */ 1688 1.1 christos static void 1689 1.1 christos fixup24 (expressionS *oper, int mode, int opmode ATTRIBUTE_UNUSED) 1690 1.1 christos { 1691 1.1 christos char *f; 1692 1.1 christos 1693 1.1 christos f = frag_more (3); 1694 1.9 christos 1695 1.9 christos if (oper->X_op == O_constant) 1696 1.1 christos { 1697 1.1 christos if (!check_range (oper->X_add_number, mode)) 1698 1.1 christos { 1699 1.1 christos as_bad (_("Operand out of 16-bit range: `%" PRId64 "'."), 1700 1.1 christos (int64_t) oper->X_add_number); 1701 1.1 christos } 1702 1.1 christos number_to_chars_bigendian (f, oper->X_add_number & 0x0FFFFFF, 3); 1703 1.8 christos } 1704 1.1 christos else if (oper->X_op != O_register) 1705 1.1 christos { 1706 1.1 christos /* Now create a 24-bit fixup. */ 1707 1.1 christos fix_new_exp (frag_now, f - frag_now->fr_literal, 3, 1708 1.1 christos oper, false, BFD_RELOC_M68HC11_24); 1709 1.1 christos number_to_chars_bigendian (f, 0, 3); 1710 1.1 christos } 1711 1.1 christos else 1712 1.1 christos { 1713 1.6 christos as_fatal (_("Operand `%x' not recognized in fixup16."), oper->X_op); 1714 1.1 christos } 1715 1.1 christos } 1716 1.1 christos 1717 1.1 christos /* XGATE Put a 1 byte expression described by 'oper'. If this expression 1718 1.1 christos contains unresolved symbols, generate an 8-bit fixup. */ 1719 1.1 christos static void 1720 1.1 christos fixup8_xg (expressionS *oper, int mode, int opmode) 1721 1.1 christos { 1722 1.1 christos char *f; 1723 1.1 christos 1724 1.5 christos f = frag_more (1); 1725 1.1 christos 1726 1.1 christos if (oper->X_op == O_constant) 1727 1.1 christos { 1728 1.1 christos fixS *fixp; 1729 1.1 christos bfd_reloc_code_real_type reloc; 1730 1.1 christos 1731 1.1 christos if ((opmode & M6811_OP_HIGH_ADDR) || (opmode & M6811_OP_LOW_ADDR)) 1732 1.1 christos { 1733 1.1 christos if (opmode & M6811_OP_HIGH_ADDR) 1734 1.8 christos reloc = BFD_RELOC_M68HC11_HI8; 1735 1.1 christos else 1736 1.1 christos reloc = BFD_RELOC_M68HC11_LO8; 1737 1.1 christos 1738 1.1 christos fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1, 1739 1.1 christos oper, false, reloc); 1740 1.1 christos fixp->fx_no_overflow = 1; 1741 1.9 christos number_to_chars_bigendian (f, 0, 1); 1742 1.9 christos } 1743 1.1 christos else 1744 1.1 christos { 1745 1.1 christos if (!(check_range (oper->X_add_number, mode))) 1746 1.1 christos as_bad (_("Operand out of 8-bit range: `%" PRId64 "'."), 1747 1.1 christos (int64_t) oper->X_add_number); 1748 1.1 christos number_to_chars_bigendian (f, oper->X_add_number & 0x0FF, 1); 1749 1.1 christos } 1750 1.1 christos } 1751 1.1 christos else if (oper->X_op != O_register) 1752 1.3 christos { 1753 1.8 christos if (mode == M68XG_OP_REL9) 1754 1.1 christos { 1755 1.1 christos /* Future improvement: 1756 1.1 christos This fixup/reloc isn't adding on constants to symbols. */ 1757 1.1 christos fix_new_exp (frag_now, f - frag_now->fr_literal -1, 2, 1758 1.1 christos oper, true, BFD_RELOC_M68HC12_9_PCREL); 1759 1.3 christos } 1760 1.8 christos else if (mode == M68XG_OP_REL10) 1761 1.1 christos { 1762 1.1 christos /* Future improvement: 1763 1.1 christos This fixup/reloc isn't adding on constants to symbols. */ 1764 1.1 christos fix_new_exp (frag_now, f - frag_now->fr_literal -1, 2, 1765 1.5 christos oper, true, BFD_RELOC_M68HC12_10_PCREL); 1766 1.1 christos } 1767 1.1 christos else 1768 1.1 christos { 1769 1.1 christos fixS *fixp; 1770 1.1 christos bfd_reloc_code_real_type reloc; 1771 1.1 christos 1772 1.1 christos /* Now create an 8-bit fixup. If there was some %hi, %lo 1773 1.1 christos modifier, generate the reloc accordingly. */ 1774 1.1 christos if (opmode & M6811_OP_HIGH_ADDR) 1775 1.1 christos reloc = BFD_RELOC_M68HC11_HI8; 1776 1.1 christos else if (opmode & M6811_OP_LOW_ADDR) 1777 1.8 christos reloc = BFD_RELOC_M68HC11_LO8; 1778 1.1 christos else 1779 1.1 christos reloc = BFD_RELOC_8; 1780 1.1 christos 1781 1.1 christos fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1, 1782 1.1 christos oper, false, reloc); 1783 1.1 christos if (reloc != BFD_RELOC_8) 1784 1.1 christos fixp->fx_no_overflow = 1; 1785 1.1 christos } 1786 1.1 christos number_to_chars_bigendian (f, 0, 1); 1787 1.1 christos } 1788 1.1 christos else 1789 1.1 christos as_fatal (_("Operand `%x' not recognized in fixup8."), oper->X_op); 1790 1.1 christos } 1791 1.1 christos 1792 1.1 christos /* 68HC11 and 68HC12 code generation. */ 1794 1.1 christos 1795 1.1 christos /* Translate the short branch/bsr instruction into a long branch. */ 1796 1.1 christos 1797 1.1 christos static unsigned char 1798 1.1 christos convert_branch (unsigned char code) 1799 1.1 christos { 1800 1.1 christos if (IS_OPCODE (code, M6812_BSR)) 1801 1.1 christos return M6812_JSR; 1802 1.1 christos else if (IS_OPCODE (code, M6811_BSR)) 1803 1.1 christos return M6811_JSR; 1804 1.1 christos else if (IS_OPCODE (code, M6811_BRA)) 1805 1.1 christos return (current_architecture & cpu6812) ? M6812_JMP : M6811_JMP; 1806 1.1 christos else 1807 1.1 christos as_fatal (_("Unexpected branch conversion with `%x'"), code); 1808 1.1 christos 1809 1.1 christos /* Keep gcc happy. */ 1810 1.1 christos return M6811_JSR; 1811 1.1 christos } 1812 1.1 christos 1813 1.1 christos /* Start a new insn that contains at least 'size' bytes. Record the 1814 1.1 christos line information of that insn in the dwarf2 debug sections. */ 1815 1.1 christos static char * 1816 1.1 christos m68hc11_new_insn (int size) 1817 1.1 christos { 1818 1.1 christos char *f; 1819 1.1 christos 1820 1.1 christos f = frag_more (size); 1821 1.1 christos 1822 1.1 christos dwarf2_emit_insn (size); 1823 1.1 christos 1824 1.1 christos return f; 1825 1.1 christos } 1826 1.1 christos 1827 1.1 christos /* Builds a jump instruction (bra, bcc, bsr). */ 1828 1.1 christos static void 1829 1.1 christos build_jump_insn (struct m68hc11_opcode *opcode, operand operands[], 1830 1.1 christos int nb_operands, int jmp_mode) 1831 1.1 christos { 1832 1.1 christos unsigned char code; 1833 1.1 christos char *f; 1834 1.1 christos unsigned long n; 1835 1.1 christos 1836 1.1 christos /* The relative branch conversion is not supported for 1837 1.1 christos brclr and brset. */ 1838 1.1 christos gas_assert ((opcode->format & M6811_OP_BITMASK) == 0); 1839 1.1 christos gas_assert (nb_operands == 1); 1840 1.1 christos gas_assert (operands[0].reg1 == REG_NONE && operands[0].reg2 == REG_NONE); 1841 1.1 christos 1842 1.1 christos code = opcode->opcode; 1843 1.1 christos 1844 1.1 christos n = operands[0].exp.X_add_number; 1845 1.1 christos 1846 1.1 christos /* Turn into a long branch: 1847 1.1 christos - when force long branch option (and not for jbcc pseudos), 1848 1.1 christos - when jbcc and the constant is out of -128..127 range, 1849 1.1 christos - when branch optimization is allowed and branch out of range. */ 1850 1.1 christos if ((jmp_mode == 0 && flag_force_long_jumps) 1851 1.1 christos || (operands[0].exp.X_op == O_constant 1852 1.1 christos && (!check_range (n, opcode->format) && 1853 1.1 christos (jmp_mode == 1 || flag_fixed_branches == 0)))) 1854 1.1 christos { 1855 1.1 christos fix_new (frag_now, frag_now_fix (), 0, 1856 1.1 christos &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP); 1857 1.1 christos 1858 1.1 christos if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR) 1859 1.1 christos { 1860 1.1 christos code = convert_branch (code); 1861 1.1 christos 1862 1.1 christos f = m68hc11_new_insn (1); 1863 1.1 christos number_to_chars_bigendian (f, code, 1); 1864 1.1 christos } 1865 1.1 christos else if (current_architecture & cpu6812) 1866 1.1 christos { 1867 1.1 christos /* 68HC12: translate the bcc into a lbcc. */ 1868 1.1 christos f = m68hc11_new_insn (2); 1869 1.1 christos number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1); 1870 1.1 christos number_to_chars_bigendian (f + 1, code, 1); 1871 1.1 christos fixup16 (&operands[0].exp, M6812_OP_JUMP_REL16, 1872 1.1 christos M6812_OP_JUMP_REL16); 1873 1.1 christos return; 1874 1.1 christos } 1875 1.1 christos else 1876 1.1 christos { 1877 1.1 christos /* 68HC11: translate the bcc into b!cc +3; jmp <L>. */ 1878 1.1 christos f = m68hc11_new_insn (3); 1879 1.1 christos code ^= 1; 1880 1.1 christos number_to_chars_bigendian (f, code, 1); 1881 1.1 christos number_to_chars_bigendian (f + 1, 3, 1); 1882 1.1 christos number_to_chars_bigendian (f + 2, M6811_JMP, 1); 1883 1.1 christos } 1884 1.1 christos fixup16 (&operands[0].exp, M6811_OP_IND16, M6811_OP_IND16); 1885 1.1 christos return; 1886 1.1 christos } 1887 1.1 christos 1888 1.1 christos /* Branch with a constant that must fit in 8-bits. */ 1889 1.1 christos if (operands[0].exp.X_op == O_constant) 1890 1.1 christos { 1891 1.1 christos if (!check_range (n, opcode->format)) 1892 1.1 christos { 1893 1.1 christos as_bad (_("Operand out of range for a relative branch: `%ld'"), 1894 1.1 christos n); 1895 1.1 christos } 1896 1.1 christos else if (opcode->format & M6812_OP_JUMP_REL16) 1897 1.1 christos { 1898 1.1 christos f = m68hc11_new_insn (4); 1899 1.1 christos number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1); 1900 1.1 christos number_to_chars_bigendian (f + 1, code, 1); 1901 1.1 christos number_to_chars_bigendian (f + 2, n & 0x0ffff, 2); 1902 1.1 christos } 1903 1.1 christos else 1904 1.1 christos { 1905 1.1 christos f = m68hc11_new_insn (2); 1906 1.1 christos number_to_chars_bigendian (f, code, 1); 1907 1.1 christos number_to_chars_bigendian (f + 1, n & 0x0FF, 1); 1908 1.1 christos } 1909 1.1 christos } 1910 1.1 christos else if (opcode->format & M6812_OP_JUMP_REL16) 1911 1.1 christos { 1912 1.1 christos fix_new (frag_now, frag_now_fix (), 0, 1913 1.1 christos &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP); 1914 1.1 christos 1915 1.1 christos f = m68hc11_new_insn (2); 1916 1.1 christos number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1); 1917 1.1 christos number_to_chars_bigendian (f + 1, code, 1); 1918 1.1 christos fixup16 (&operands[0].exp, M6812_OP_JUMP_REL16, M6812_OP_JUMP_REL16); 1919 1.1 christos } 1920 1.1 christos else 1921 1.1 christos { 1922 1.1 christos char *op; 1923 1.1 christos 1924 1.1 christos fix_new (frag_now, frag_now_fix (), 0, 1925 1.1 christos &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP); 1926 1.1 christos 1927 1.1 christos /* Branch offset must fit in 8-bits, don't do some relax. */ 1928 1.1 christos if (jmp_mode == 0 && flag_fixed_branches) 1929 1.1 christos { 1930 1.1 christos op = m68hc11_new_insn (1); 1931 1.1 christos number_to_chars_bigendian (op, code, 1); 1932 1.1 christos fixup8 (&operands[0].exp, M6811_OP_JUMP_REL, M6811_OP_JUMP_REL); 1933 1.1 christos } 1934 1.1 christos 1935 1.1 christos /* bra/bsr made be changed into jmp/jsr. */ 1936 1.1 christos else if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR) 1937 1.10 christos { 1938 1.10 christos /* Allocate worst case storage. */ 1939 1.1 christos op = m68hc11_new_insn (3); 1940 1.1 christos number_to_chars_bigendian (op, code, 1); 1941 1.1 christos number_to_chars_bigendian (op + 1, 0, 1); 1942 1.1 christos frag_variant (rs_machine_dependent, 1, 1, 1943 1.1 christos ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF), 1944 1.1 christos operands[0].exp.X_add_symbol, n, op); 1945 1.1 christos } 1946 1.1 christos else if (current_architecture & cpu6812) 1947 1.10 christos { 1948 1.1 christos op = m68hc11_new_insn (2); 1949 1.1 christos number_to_chars_bigendian (op, code, 1); 1950 1.1 christos number_to_chars_bigendian (op + 1, 0, 1); 1951 1.1 christos frag_var (rs_machine_dependent, 2, 2, 1952 1.1 christos ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_UNDF), 1953 1.1 christos operands[0].exp.X_add_symbol, n, op); 1954 1.1 christos } 1955 1.1 christos else 1956 1.10 christos { 1957 1.1 christos op = m68hc11_new_insn (2); 1958 1.1 christos number_to_chars_bigendian (op, code, 1); 1959 1.1 christos number_to_chars_bigendian (op + 1, 0, 1); 1960 1.1 christos frag_var (rs_machine_dependent, 3, 3, 1961 1.1 christos ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF), 1962 1.1 christos operands[0].exp.X_add_symbol, n, op); 1963 1.1 christos } 1964 1.1 christos } 1965 1.1 christos } 1966 1.1 christos 1967 1.1 christos /* Builds a dbne/dbeq/tbne/tbeq instruction. */ 1968 1.1 christos static void 1969 1.1 christos build_dbranch_insn (struct m68hc11_opcode *opcode, operand operands[], 1970 1.1 christos int nb_operands, int jmp_mode) 1971 1.1 christos { 1972 1.1 christos unsigned char code; 1973 1.1 christos char *f; 1974 1.1 christos unsigned long n; 1975 1.1 christos 1976 1.1 christos /* The relative branch conversion is not supported for 1977 1.1 christos brclr and brset. */ 1978 1.1 christos gas_assert ((opcode->format & M6811_OP_BITMASK) == 0); 1979 1.1 christos gas_assert (nb_operands == 2); 1980 1.1 christos gas_assert (operands[0].reg1 != REG_NONE); 1981 1.1 christos 1982 1.1 christos code = opcode->opcode & 0x0FF; 1983 1.1 christos 1984 1.1 christos f = m68hc11_new_insn (1); 1985 1.1 christos number_to_chars_bigendian (f, code, 1); 1986 1.1 christos 1987 1.1 christos n = operands[1].exp.X_add_number; 1988 1.1 christos code = operands[0].reg1; 1989 1.1 christos 1990 1.1 christos if (operands[0].reg1 == REG_NONE || operands[0].reg1 == REG_CCR 1991 1.1 christos || operands[0].reg1 == REG_PC) 1992 1.1 christos as_bad (_("Invalid register for dbcc/tbcc instruction.")); 1993 1.1 christos 1994 1.1 christos if (opcode->format & M6812_OP_IBCC_MARKER) 1995 1.1 christos code |= 0x80; 1996 1.1 christos else if (opcode->format & M6812_OP_TBCC_MARKER) 1997 1.1 christos code |= 0x40; 1998 1.1 christos 1999 1.1 christos if (!(opcode->format & M6812_OP_EQ_MARKER)) 2000 1.1 christos code |= 0x20; 2001 1.1 christos 2002 1.1 christos /* Turn into a long branch: 2003 1.1 christos - when force long branch option (and not for jbcc pseudos), 2004 1.1 christos - when jdbcc and the constant is out of -256..255 range, 2005 1.1 christos - when branch optimization is allowed and branch out of range. */ 2006 1.1 christos if ((jmp_mode == 0 && flag_force_long_jumps) 2007 1.1 christos || (operands[1].exp.X_op == O_constant 2008 1.1 christos && (!check_range (n, M6812_OP_IBCC_MARKER) && 2009 1.1 christos (jmp_mode == 1 || flag_fixed_branches == 0)))) 2010 1.1 christos { 2011 1.1 christos f = frag_more (2); 2012 1.1 christos code ^= 0x20; 2013 1.1 christos number_to_chars_bigendian (f, code, 1); 2014 1.1 christos number_to_chars_bigendian (f + 1, M6812_JMP, 1); 2015 1.1 christos fixup16 (&operands[0].exp, M6811_OP_IND16, M6811_OP_IND16); 2016 1.1 christos return; 2017 1.1 christos } 2018 1.1 christos 2019 1.1 christos /* Branch with a constant that must fit in 9-bits. */ 2020 1.1 christos if (operands[1].exp.X_op == O_constant) 2021 1.1 christos { 2022 1.1 christos if (!check_range (n, M6812_OP_IBCC_MARKER)) 2023 1.1 christos { 2024 1.1 christos as_bad (_("Operand out of range for a relative branch: `%ld'"), 2025 1.1 christos n); 2026 1.1 christos } 2027 1.1 christos else 2028 1.1 christos { 2029 1.1 christos if ((long) n < 0) 2030 1.1 christos code |= 0x10; 2031 1.1 christos 2032 1.1 christos f = frag_more (2); 2033 1.1 christos number_to_chars_bigendian (f, code, 1); 2034 1.1 christos number_to_chars_bigendian (f + 1, n & 0x0FF, 1); 2035 1.1 christos } 2036 1.1 christos } 2037 1.1 christos else 2038 1.1 christos { 2039 1.1 christos /* Branch offset must fit in 8-bits, don't do some relax. */ 2040 1.1 christos if (jmp_mode == 0 && flag_fixed_branches) 2041 1.1 christos { 2042 1.1 christos fixup8 (&operands[0].exp, M6811_OP_JUMP_REL, M6811_OP_JUMP_REL); 2043 1.1 christos } 2044 1.1 christos 2045 1.1 christos else 2046 1.10 christos { 2047 1.1 christos f = frag_more (2); 2048 1.1 christos number_to_chars_bigendian (f, code, 1); 2049 1.1 christos number_to_chars_bigendian (f + 1, 0, 1); 2050 1.1 christos frag_var (rs_machine_dependent, 3, 3, 2051 1.1 christos ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_UNDF), 2052 1.1 christos operands[1].exp.X_add_symbol, n, f); 2053 1.1 christos } 2054 1.1 christos } 2055 1.1 christos } 2056 1.1 christos 2057 1.1 christos #define OP_EXTENDED (M6811_OP_PAGE2 | M6811_OP_PAGE3 | M6811_OP_PAGE4) 2058 1.1 christos 2059 1.1 christos /* Assemble the post index byte for 68HC12 extended addressing modes. */ 2060 1.1 christos 2061 1.1 christos static int 2062 1.1 christos build_indexed_byte (operand *op, int format ATTRIBUTE_UNUSED, int move_insn) 2063 1.1 christos { 2064 1.1 christos unsigned char byte = 0; 2065 1.1 christos char *f; 2066 1.1 christos int mode; 2067 1.1 christos long val; 2068 1.1 christos 2069 1.1 christos val = op->exp.X_add_number; 2070 1.1 christos mode = op->mode; 2071 1.1 christos if (mode & M6812_AUTO_INC_DEC) 2072 1.1 christos { 2073 1.1 christos byte = 0x20; 2074 1.1 christos if (mode & (M6812_POST_INC | M6812_POST_DEC)) 2075 1.1 christos byte |= 0x10; 2076 1.1 christos 2077 1.1 christos if (op->exp.X_op == O_constant) 2078 1.1 christos { 2079 1.1 christos if (!check_range (val, mode)) 2080 1.1 christos as_bad (_("Increment/decrement value is out of range: `%ld'."), 2081 1.1 christos val); 2082 1.1 christos 2083 1.1 christos if (mode & (M6812_POST_INC | M6812_PRE_INC)) 2084 1.1 christos byte |= (val - 1) & 0x07; 2085 1.1 christos else 2086 1.1 christos byte |= (8 - ((val) & 7)) | 0x8; 2087 1.1 christos } 2088 1.1 christos 2089 1.1 christos switch (op->reg1) 2090 1.1 christos { 2091 1.1 christos case REG_NONE: 2092 1.1 christos as_fatal (_("Expecting a register.")); 2093 1.1 christos 2094 1.1 christos case REG_X: 2095 1.1 christos byte |= 0; 2096 1.1 christos break; 2097 1.1 christos 2098 1.1 christos case REG_Y: 2099 1.1 christos byte |= 0x40; 2100 1.1 christos break; 2101 1.1 christos 2102 1.1 christos case REG_SP: 2103 1.1 christos byte |= 0x80; 2104 1.1 christos break; 2105 1.1 christos 2106 1.1 christos default: 2107 1.1 christos as_bad (_("Invalid register for post/pre increment.")); 2108 1.1 christos break; 2109 1.1 christos } 2110 1.1 christos 2111 1.1 christos f = frag_more (1); 2112 1.1 christos number_to_chars_bigendian (f, byte, 1); 2113 1.1 christos return 1; 2114 1.1 christos } 2115 1.1 christos 2116 1.1 christos if (mode & (M6812_OP_IDX | M6812_OP_D_IDX_2)) 2117 1.1 christos { 2118 1.1 christos switch (op->reg1) 2119 1.1 christos { 2120 1.1 christos case REG_X: 2121 1.1 christos byte = 0; 2122 1.1 christos break; 2123 1.1 christos 2124 1.1 christos case REG_Y: 2125 1.1 christos byte = 1; 2126 1.1 christos break; 2127 1.1 christos 2128 1.1 christos case REG_SP: 2129 1.1 christos byte = 2; 2130 1.1 christos break; 2131 1.1 christos 2132 1.1 christos case REG_PC: 2133 1.1 christos byte = 3; 2134 1.1 christos break; 2135 1.1 christos 2136 1.1 christos default: 2137 1.1 christos as_bad (_("Invalid register.")); 2138 1.1 christos break; 2139 1.1 christos } 2140 1.3 christos 2141 1.3 christos if (op->exp.X_op == O_constant) 2142 1.1 christos { 2143 1.1 christos if (!check_range (val, M6812_OP_IDX)) 2144 1.1 christos as_bad (_("Offset out of 16-bit range: %ld."), val); 2145 1.1 christos 2146 1.1 christos if (move_insn && !(val >= -16 && val <= 15) 2147 1.1 christos && ((!(mode & M6812_OP_IDX) && !(mode & M6812_OP_D_IDX_2)) 2148 1.1 christos || !(current_architecture & cpu9s12x))) 2149 1.1 christos { 2150 1.1 christos as_bad (_("Offset out of 5-bit range for movw/movb insn: %ld."), 2151 1.1 christos val); 2152 1.1 christos return -1; 2153 1.1 christos } 2154 1.1 christos 2155 1.1 christos if (val >= -16 && val <= 15 && !(mode & M6812_OP_D_IDX_2)) 2156 1.1 christos { 2157 1.1 christos byte = byte << 6; 2158 1.1 christos byte |= val & 0x1f; 2159 1.1 christos f = frag_more (1); 2160 1.1 christos number_to_chars_bigendian (f, byte, 1); 2161 1.1 christos return 1; 2162 1.1 christos } 2163 1.1 christos else if (val >= -256 && val <= 255 && !(mode & M6812_OP_D_IDX_2)) 2164 1.1 christos { 2165 1.1 christos byte = byte << 3; 2166 1.1 christos byte |= 0xe0; 2167 1.1 christos if (val < 0) 2168 1.1 christos byte |= 0x1; 2169 1.1 christos f = frag_more (2); 2170 1.1 christos number_to_chars_bigendian (f, byte, 1); 2171 1.1 christos number_to_chars_bigendian (f + 1, val & 0x0FF, 1); 2172 1.1 christos return 2; 2173 1.1 christos } 2174 1.1 christos else 2175 1.1 christos { 2176 1.1 christos byte = byte << 3; 2177 1.1 christos if (mode & M6812_OP_D_IDX_2) 2178 1.1 christos byte |= 0xe3; 2179 1.1 christos else 2180 1.1 christos byte |= 0xe2; 2181 1.1 christos 2182 1.1 christos f = frag_more (3); 2183 1.1 christos number_to_chars_bigendian (f, byte, 1); 2184 1.1 christos number_to_chars_bigendian (f + 1, val & 0x0FFFF, 2); 2185 1.1 christos return 3; 2186 1.1 christos } 2187 1.1 christos } 2188 1.1 christos 2189 1.1 christos if (mode & M6812_OP_D_IDX_2) 2190 1.1 christos { 2191 1.1 christos byte = (byte << 3) | 0xe3; 2192 1.1 christos f = frag_more (1); 2193 1.1 christos number_to_chars_bigendian (f, byte, 1); 2194 1.1 christos 2195 1.1 christos fixup16 (&op->exp, 0, 0); 2196 1.1 christos } 2197 1.1 christos else if (op->reg1 != REG_PC) 2198 1.1 christos { 2199 1.1 christos symbolS *sym; 2200 1.1 christos offsetT off; 2201 1.1 christos 2202 1.1 christos f = frag_more (1); 2203 1.1 christos number_to_chars_bigendian (f, byte, 1); 2204 1.1 christos sym = op->exp.X_add_symbol; 2205 1.1 christos off = op->exp.X_add_number; 2206 1.1 christos if (op->exp.X_op != O_symbol) 2207 1.1 christos { 2208 1.1 christos sym = make_expr_symbol (&op->exp); 2209 1.1 christos off = 0; 2210 1.1 christos } 2211 1.1 christos 2212 1.1 christos /* movb/movw cannot be relaxed. */ 2213 1.1 christos if (move_insn) 2214 1.1 christos { 2215 1.1 christos if ((mode & M6812_OP_IDX) && (current_architecture & cpu9s12x)) 2216 1.1 christos { 2217 1.1 christos /* Must treat as a 16bit relocate as size of final result is unknown. */ 2218 1.1 christos 2219 1.1 christos byte <<= 3; 2220 1.1 christos byte |= 0xe2; 2221 1.1 christos number_to_chars_bigendian (f, byte, 1); 2222 1.1 christos f = frag_more (2); 2223 1.1 christos fix_new (frag_now, f - frag_now->fr_literal, 2, 2224 1.1 christos sym, off, 0, BFD_RELOC_M68HC12_16B); 2225 1.1 christos return 1; 2226 1.1 christos } 2227 1.1 christos else 2228 1.1 christos { 2229 1.1 christos /* Non-S12X will fail at relocate stage if offset out of range. */ 2230 1.1 christos byte <<= 6; 2231 1.1 christos number_to_chars_bigendian (f, byte, 1); 2232 1.1 christos fix_new (frag_now, f - frag_now->fr_literal, 1, 2233 1.1 christos sym, off, 0, BFD_RELOC_M68HC12_5B); 2234 1.1 christos return 1; 2235 1.1 christos } 2236 1.1 christos } 2237 1.1 christos else 2238 1.1 christos { 2239 1.1 christos number_to_chars_bigendian (f, byte, 1); 2240 1.1 christos frag_var (rs_machine_dependent, 2, 2, 2241 1.1 christos ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF), 2242 1.1 christos sym, off, f); 2243 1.1 christos } 2244 1.1 christos } 2245 1.1 christos else 2246 1.1 christos { 2247 1.1 christos f = frag_more (1); 2248 1.1 christos 2249 1.1 christos /* movb/movw cannot be relaxed. */ 2250 1.1 christos if (move_insn) 2251 1.1 christos { 2252 1.1 christos byte <<= 6; 2253 1.1 christos number_to_chars_bigendian (f, byte, 1); 2254 1.1 christos fix_new (frag_now, f - frag_now->fr_literal, 1, 2255 1.1 christos op->exp.X_add_symbol, op->exp.X_add_number, 0, BFD_RELOC_M68HC12_5B); 2256 1.1 christos return 1; 2257 1.1 christos } 2258 1.1 christos else 2259 1.1 christos { 2260 1.1 christos number_to_chars_bigendian (f, byte, 1); 2261 1.1 christos frag_var (rs_machine_dependent, 2, 2, 2262 1.1 christos ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_UNDF), 2263 1.1 christos op->exp.X_add_symbol, 2264 1.1 christos op->exp.X_add_number, f); 2265 1.1 christos } 2266 1.1 christos } 2267 1.1 christos return 3; 2268 1.1 christos } 2269 1.1 christos 2270 1.1 christos if (mode & (M6812_OP_REG | M6812_OP_D_IDX)) 2271 1.1 christos { 2272 1.1 christos if (mode & M6812_OP_D_IDX) 2273 1.1 christos { 2274 1.1 christos if (op->reg1 != REG_D) 2275 1.1 christos as_bad (_("Expecting register D for indexed indirect mode.")); 2276 1.1 christos if ((move_insn) && (!(current_architecture & cpu9s12x))) 2277 1.1 christos as_bad (_("Indexed indirect mode is not allowed for movb/movw.")); 2278 1.1 christos 2279 1.1 christos byte = 0xE7; 2280 1.1 christos } 2281 1.1 christos else 2282 1.1 christos { 2283 1.1 christos switch (op->reg1) 2284 1.1 christos { 2285 1.1 christos case REG_A: 2286 1.1 christos byte = 0xE4; 2287 1.1 christos break; 2288 1.1 christos 2289 1.6 christos case REG_B: 2290 1.1 christos byte = 0xE5; 2291 1.1 christos break; 2292 1.1 christos 2293 1.1 christos default: 2294 1.1 christos as_bad (_("Invalid accumulator register.")); 2295 1.1 christos /* Fall through. */ 2296 1.1 christos 2297 1.1 christos case REG_D: 2298 1.1 christos byte = 0xE6; 2299 1.1 christos break; 2300 1.1 christos } 2301 1.1 christos } 2302 1.1 christos switch (op->reg2) 2303 1.1 christos { 2304 1.1 christos case REG_X: 2305 1.1 christos break; 2306 1.1 christos 2307 1.1 christos case REG_Y: 2308 1.1 christos byte |= (1 << 3); 2309 1.1 christos break; 2310 1.1 christos 2311 1.1 christos case REG_SP: 2312 1.1 christos byte |= (2 << 3); 2313 1.1 christos break; 2314 1.1 christos 2315 1.1 christos case REG_PC: 2316 1.1 christos byte |= (3 << 3); 2317 1.1 christos break; 2318 1.1 christos 2319 1.1 christos default: 2320 1.1 christos as_bad (_("Invalid indexed register.")); 2321 1.1 christos break; 2322 1.1 christos } 2323 1.1 christos f = frag_more (1); 2324 1.1 christos number_to_chars_bigendian (f, byte, 1); 2325 1.1 christos return 1; 2326 1.1 christos } 2327 1.1 christos 2328 1.1 christos fprintf (stderr, "mode = 0x%x\nop->reg1 = 0x%x\nop->reg2 = 0x%x\n", 2329 1.1 christos mode, op->reg1, op->reg2); 2330 1.1 christos as_fatal (_("Addressing mode not implemented yet.")); 2331 1.1 christos return 0; 2332 1.1 christos } 2333 1.1 christos 2334 1.1 christos /* Assemble the 68HC12 register mode byte. */ 2335 1.1 christos static int 2336 1.1 christos build_reg_mode (operand *op, int format) 2337 1.1 christos { 2338 1.1 christos unsigned char byte; 2339 1.1 christos char *f; 2340 1.1 christos 2341 1.1 christos if ((format & M6812_OP_SEX_MARKER) 2342 1.1 christos && (op->reg1 != REG_A) && (op->reg1 != REG_B) && (op->reg1 != REG_CCR) 2343 1.1 christos && (!(current_architecture & cpu9s12x))) 2344 1.1 christos as_bad (_("Invalid source register for this instruction, use 'tfr'.")); 2345 1.1 christos else if (op->reg1 == REG_NONE || op->reg1 == REG_PC) 2346 1.1 christos as_bad (_("Invalid source register.")); 2347 1.1 christos 2348 1.1 christos if (format & M6812_OP_SEX_MARKER 2349 1.1 christos && op->reg2 != REG_D 2350 1.1 christos && op->reg2 != REG_X && op->reg2 != REG_Y && op->reg2 != REG_SP) 2351 1.1 christos as_bad (_("Invalid destination register for this instruction, use 'tfr'.")); 2352 1.1 christos else if (op->reg2 == REG_NONE || op->reg2 == REG_PC) 2353 1.1 christos as_bad (_("Invalid destination register.")); 2354 1.1 christos 2355 1.1 christos byte = (op->reg1 << 4) | (op->reg2); 2356 1.1 christos if (format & M6812_OP_EXG_MARKER) 2357 1.1 christos byte |= 0x80; 2358 1.1 christos 2359 1.1 christos if ((format & M6812_OP_SEX_MARKER) 2360 1.1 christos && (op->reg1 == REG_D) && (current_architecture & cpu9s12x)) 2361 1.1 christos byte |= 0x08; 2362 1.1 christos 2363 1.1 christos f = frag_more (1); 2364 1.1 christos number_to_chars_bigendian (f, byte, 1); 2365 1.1 christos return 1; 2366 1.1 christos } 2367 1.1 christos 2368 1.1 christos /* build_insn_xg takes a pointer to the opcode entry in the opcode table, 2369 1.1 christos the array of operand expressions and builds the corresponding instruction. */ 2370 1.1 christos 2371 1.1 christos static void 2372 1.1 christos build_insn_xg (struct m68hc11_opcode *opcode, 2373 1.1 christos operand operands[], 2374 1.1 christos int nb_operands ATTRIBUTE_UNUSED) 2375 1.1 christos { 2376 1.1 christos char *f; 2377 1.1 christos long format; 2378 1.1 christos 2379 1.1 christos /* Put the page code instruction if there is one. */ 2380 1.1 christos format = opcode->format; 2381 1.1 christos 2382 1.1 christos if (!(operands[0].mode & (M6811_OP_LOW_ADDR | M6811_OP_HIGH_ADDR))) 2383 1.1 christos /* Need to retain those two modes, but clear for others. */ 2384 1.1 christos operands[0].mode = 0; 2385 1.1 christos 2386 1.1 christos if (format & M68XG_OP_R_IMM8) 2387 1.1 christos { 2388 1.1 christos /* These opcodes are byte followed by imm8. */ 2389 1.1 christos f = m68hc11_new_insn (1); 2390 1.1 christos number_to_chars_bigendian (f, opcode->opcode >> 8, 1); 2391 1.1 christos fixup8_xg (&operands[0].exp, format, operands[0].mode); 2392 1.1 christos } 2393 1.1 christos else if (format & M68XG_OP_R_IMM16) 2394 1.1 christos { 2395 1.1 christos fixS *fixp; 2396 1.1 christos /* These opcodes expand into two imm8 instructions. 2397 1.1 christos Emit as low:high as per the Freescale datasheet. 2398 1.1 christos The linker requires them to be adjacent to handle the upper byte. */ 2399 1.1 christos 2400 1.8 christos /* Build low byte. */ 2401 1.1 christos f = m68hc11_new_insn (1); 2402 1.1 christos number_to_chars_bigendian (f, opcode->opcode >> 8, 1); 2403 1.1 christos operands[0].mode = M6811_OP_LOW_ADDR; 2404 1.1 christos f = frag_more (1); 2405 1.1 christos fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1, 2406 1.1 christos &operands[0].exp, false, BFD_RELOC_M68HC12_LO8XG); 2407 1.1 christos fixp->fx_no_overflow = 1; 2408 1.1 christos number_to_chars_bigendian (f, 0, 1); 2409 1.1 christos 2410 1.8 christos /* Build high byte. */ 2411 1.1 christos f = m68hc11_new_insn (1); 2412 1.1 christos number_to_chars_bigendian (f, (opcode->opcode >> 8) | 0x08, 1); 2413 1.1 christos operands[0].mode = M6811_OP_HIGH_ADDR; 2414 1.1 christos f = frag_more (1); 2415 1.1 christos fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1, 2416 1.1 christos &operands[0].exp, false, BFD_RELOC_M68HC12_HI8XG); 2417 1.1 christos fixp->fx_no_overflow = 1; 2418 1.1 christos number_to_chars_bigendian (f, 0, 1); 2419 1.1 christos 2420 1.3 christos } 2421 1.1 christos else if (format & M68XG_OP_REL9) 2422 1.1 christos { 2423 1.1 christos f = m68hc11_new_insn (1); 2424 1.1 christos number_to_chars_bigendian (f, opcode->opcode >> 8, 1); /* High byte. */ 2425 1.1 christos fixup8_xg (&operands[0].exp, format, M68XG_OP_REL9); 2426 1.1 christos } 2427 1.1 christos else if (format & M68XG_OP_REL10) 2428 1.1 christos { 2429 1.1 christos f = m68hc11_new_insn (1); 2430 1.1 christos number_to_chars_bigendian (f, opcode->opcode >> 8, 1); /* High byte. */ 2431 1.1 christos fixup8_xg (&operands[0].exp, format, M68XG_OP_REL10); 2432 1.1 christos } 2433 1.1 christos else 2434 1.1 christos { 2435 1.1 christos f = m68hc11_new_insn (2); 2436 1.1 christos number_to_chars_bigendian (f, opcode->opcode, 2); 2437 1.1 christos } 2438 1.1 christos return; 2439 1.1 christos } 2440 1.1 christos 2441 1.1 christos /* build_insn takes a pointer to the opcode entry in the opcode table, 2442 1.1 christos the array of operand expressions and builds the corresponding instruction. 2443 1.1 christos This operation only deals with non relative jumps insn (need special 2444 1.1 christos handling). */ 2445 1.1 christos 2446 1.1 christos static void 2447 1.1 christos build_insn (struct m68hc11_opcode *opcode, 2448 1.1 christos operand operands[], 2449 1.1 christos int nb_operands ATTRIBUTE_UNUSED) 2450 1.1 christos { 2451 1.1 christos int i; 2452 1.1 christos char *f; 2453 1.1 christos long format; 2454 1.1 christos int move_insn = 0; 2455 1.1 christos 2456 1.1 christos /* Put the page code instruction if there is one. */ 2457 1.1 christos format = opcode->format; 2458 1.1 christos 2459 1.1 christos if (format & M6811_OP_BRANCH) 2460 1.1 christos fix_new (frag_now, frag_now_fix (), 0, 2461 1.1 christos &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP); 2462 1.1 christos 2463 1.1 christos if (format & OP_EXTENDED) 2464 1.1 christos { 2465 1.1 christos int page_code; 2466 1.1 christos 2467 1.1 christos f = m68hc11_new_insn (2); 2468 1.1 christos if (format & M6811_OP_PAGE2) 2469 1.1 christos page_code = M6811_OPCODE_PAGE2; 2470 1.1 christos else if (format & M6811_OP_PAGE3) 2471 1.1 christos page_code = M6811_OPCODE_PAGE3; 2472 1.1 christos else 2473 1.1 christos page_code = M6811_OPCODE_PAGE4; 2474 1.1 christos 2475 1.1 christos number_to_chars_bigendian (f, page_code, 1); 2476 1.1 christos f++; 2477 1.1 christos } 2478 1.1 christos else 2479 1.1 christos f = m68hc11_new_insn (1); 2480 1.1 christos 2481 1.1 christos number_to_chars_bigendian (f, opcode->opcode, 1); 2482 1.1 christos 2483 1.1 christos i = 0; 2484 1.1 christos 2485 1.1 christos /* The 68HC12 movb and movw instructions are special. We have to handle 2486 1.1 christos them in a special way. */ 2487 1.1 christos if (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2)) 2488 1.1 christos { 2489 1.1 christos move_insn = 1; 2490 1.1 christos if (format & M6812_OP_IDX) 2491 1.1 christos { 2492 1.1 christos build_indexed_byte (&operands[0], format, 1); 2493 1.1 christos i = 1; 2494 1.1 christos format &= ~M6812_OP_IDX; 2495 1.1 christos } 2496 1.1 christos if (format & M6812_OP_IDX_P2) 2497 1.1 christos { 2498 1.1 christos build_indexed_byte (&operands[1], format, 1); 2499 1.1 christos i = 0; 2500 1.1 christos format &= ~M6812_OP_IDX_P2; 2501 1.1 christos } 2502 1.1 christos } 2503 1.1 christos 2504 1.1 christos if (format & (M6811_OP_DIRECT | M6811_OP_IMM8)) 2505 1.1 christos { 2506 1.1 christos fixup8 (&operands[i].exp, 2507 1.1 christos format & (M6811_OP_DIRECT | M6811_OP_IMM8 | M6812_OP_TRAP_ID), 2508 1.1 christos operands[i].mode); 2509 1.1 christos i++; 2510 1.1 christos } 2511 1.1 christos else if (IS_CALL_SYMBOL (format) && nb_operands == 1) 2512 1.1 christos { 2513 1.1 christos format &= ~M6812_OP_PAGE; 2514 1.1 christos fixup24 (&operands[i].exp, format & M6811_OP_IND16, 2515 1.1 christos operands[i].mode); 2516 1.1 christos i++; 2517 1.1 christos } 2518 1.1 christos else if (format & (M6811_OP_IMM16 | M6811_OP_IND16)) 2519 1.1 christos { 2520 1.1 christos fixup16 (&operands[i].exp, 2521 1.1 christos format & (M6811_OP_IMM16 | M6811_OP_IND16 | M6812_OP_PAGE), 2522 1.1 christos operands[i].mode); 2523 1.1 christos i++; 2524 1.1 christos } 2525 1.1 christos else if (format & (M6811_OP_IX | M6811_OP_IY)) 2526 1.1 christos { 2527 1.1 christos if ((format & M6811_OP_IX) && (operands[0].reg1 != REG_X)) 2528 1.1 christos as_bad (_("Invalid indexed register, expecting register X.")); 2529 1.1 christos if ((format & M6811_OP_IY) && (operands[0].reg1 != REG_Y)) 2530 1.1 christos as_bad (_("Invalid indexed register, expecting register Y.")); 2531 1.1 christos 2532 1.1 christos fixup8 (&operands[0].exp, M6811_OP_IX, operands[0].mode); 2533 1.1 christos i = 1; 2534 1.1 christos } 2535 1.1 christos else if (format & 2536 1.1 christos (M6812_OP_IDX | M6812_OP_IDX_2 | M6812_OP_IDX_1 2537 1.1 christos | M6812_OP_D_IDX | M6812_OP_D_IDX_2)) 2538 1.1 christos { 2539 1.1 christos build_indexed_byte (&operands[i], format, move_insn); 2540 1.1 christos i++; 2541 1.1 christos } 2542 1.1 christos else if (format & M6812_OP_REG && current_architecture & cpu6812) 2543 1.1 christos { 2544 1.1 christos build_reg_mode (&operands[i], format); 2545 1.1 christos i++; 2546 1.1 christos } 2547 1.1 christos if (format & M6811_OP_BITMASK) 2548 1.1 christos { 2549 1.1 christos fixup8 (&operands[i].exp, M6811_OP_BITMASK, operands[i].mode); 2550 1.1 christos i++; 2551 1.1 christos } 2552 1.1 christos if (format & M6811_OP_JUMP_REL) 2553 1.1 christos { 2554 1.1 christos fixup8 (&operands[i].exp, M6811_OP_JUMP_REL, operands[i].mode); 2555 1.1 christos } 2556 1.1 christos else if (format & M6812_OP_IND16_P2) 2557 1.1 christos { 2558 1.1 christos fixup16 (&operands[1].exp, M6811_OP_IND16, operands[1].mode); 2559 1.1 christos } 2560 1.1 christos if (format & M6812_OP_PAGE) 2561 1.1 christos { 2562 1.1 christos fixup8 (&operands[i].exp, M6812_OP_PAGE, operands[i].mode); 2563 1.1 christos } 2564 1.1 christos } 2565 1.1 christos 2566 1.1 christos /* Opcode identification and operand analysis. */ 2568 1.1 christos 2569 1.1 christos /* find() gets a pointer to an entry in the opcode table. It must look at all 2570 1.1 christos opcodes with the same name and use the operands to choose the correct 2571 1.1 christos opcode. Returns the opcode pointer if there was a match and 0 if none. */ 2572 1.1 christos static struct m68hc11_opcode * 2573 1.1 christos find (struct m68hc11_opcode_def *opc, operand operands[], int nb_operands) 2574 1.1 christos { 2575 1.1 christos int i, match, pos; 2576 1.1 christos struct m68hc11_opcode *opcode; 2577 1.1 christos struct m68hc11_opcode *op_indirect; 2578 1.1 christos 2579 1.1 christos op_indirect = 0; 2580 1.1 christos opcode = opc->opcode; 2581 1.1 christos 2582 1.1 christos /* Now search the opcode table table for one with operands 2583 1.1 christos that matches what we've got. */ 2584 1.1 christos 2585 1.1 christos if (current_architecture & cpuxgate) 2586 1.1 christos { 2587 1.1 christos /* Many XGATE insns are simple enough that we get an exact match. */ 2588 1.1 christos for (pos = match = 0; match == 0 && pos < opc->nb_modes; pos++, opcode++) 2589 1.1 christos if (opcode->format == operands[nb_operands-1].mode) 2590 1.1 christos return opcode; 2591 1.1 christos 2592 1.1 christos return 0; 2593 1.1 christos } 2594 1.1 christos 2595 1.1 christos /* Non XGATE */ 2596 1.1 christos 2597 1.1 christos /* Now search the opcode table table for one with operands 2598 1.1 christos that matches what we've got. We're only done if the operands matched so 2599 1.1 christos far AND there are no more to check. */ 2600 1.1 christos for (pos = match = 0; match == 0 && pos < opc->nb_modes; pos++, opcode++) 2601 1.1 christos { 2602 1.1 christos int poss_indirect = 0; 2603 1.1 christos long format = opcode->format; 2604 1.1 christos int expect; 2605 1.1 christos 2606 1.1 christos expect = 0; 2607 1.1 christos if (opcode->format & M6811_OP_MASK) 2608 1.1 christos expect++; 2609 1.1 christos if (opcode->format & M6811_OP_BITMASK) 2610 1.1 christos expect++; 2611 1.1 christos if (opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16)) 2612 1.1 christos expect++; 2613 1.1 christos if (opcode->format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2)) 2614 1.1 christos expect++; 2615 1.1 christos if ((opcode->format & M6812_OP_PAGE) 2616 1.1 christos && (!IS_CALL_SYMBOL (opcode->format) || nb_operands == 2)) 2617 1.1 christos expect++; 2618 1.1 christos 2619 1.1 christos for (i = 0; expect == nb_operands && i < nb_operands; i++) 2620 1.1 christos { 2621 1.1 christos int mode = operands[i].mode; 2622 1.1 christos 2623 1.1 christos if (mode & M6811_OP_IMM16) 2624 1.1 christos { 2625 1.1 christos if (format & 2626 1.1 christos (M6811_OP_IMM8 | M6811_OP_IMM16 | M6811_OP_BITMASK)) 2627 1.1 christos continue; 2628 1.1 christos break; 2629 1.1 christos } 2630 1.1 christos if (mode == M6811_OP_DIRECT) 2631 1.1 christos { 2632 1.1 christos if (format & M6811_OP_DIRECT) 2633 1.1 christos continue; 2634 1.1 christos 2635 1.1 christos /* If the operand is a page 0 operand, remember a 2636 1.1 christos possible <abs-16> addressing mode. We mark 2637 1.1 christos this and continue to check other operands. */ 2638 1.1 christos if (format & M6811_OP_IND16 2639 1.1 christos && flag_strict_direct_addressing && op_indirect == 0) 2640 1.1 christos { 2641 1.1 christos poss_indirect = 1; 2642 1.1 christos continue; 2643 1.1 christos } 2644 1.1 christos break; 2645 1.1 christos } 2646 1.1 christos if (mode & M6811_OP_IND16) 2647 1.1 christos { 2648 1.1 christos if (i == 0 && (format & M6811_OP_IND16) != 0) 2649 1.1 christos continue; 2650 1.1 christos if (i != 0 && (format & M6812_OP_PAGE) != 0) 2651 1.1 christos continue; 2652 1.1 christos if (i != 0 && (format & M6812_OP_IND16_P2) != 0) 2653 1.1 christos continue; 2654 1.1 christos if (i == 0 && (format & M6811_OP_BITMASK)) 2655 1.1 christos break; 2656 1.1 christos } 2657 1.1 christos if (mode & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16)) 2658 1.1 christos { 2659 1.1 christos if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16)) 2660 1.1 christos continue; 2661 1.1 christos } 2662 1.1 christos if (mode & M6812_OP_REG) 2663 1.1 christos { 2664 1.1 christos if (i == 0 2665 1.1 christos && (format & M6812_OP_REG) 2666 1.1 christos && (operands[i].reg2 == REG_NONE)) 2667 1.1 christos continue; 2668 1.1 christos if (i == 0 2669 1.1 christos && (format & M6812_OP_REG) 2670 1.1 christos && (format & M6812_OP_REG_2) 2671 1.1 christos && (operands[i].reg2 != REG_NONE)) 2672 1.1 christos continue; 2673 1.1 christos if (i == 0 2674 1.1 christos && (format & M6812_OP_IDX) 2675 1.1 christos && (operands[i].reg2 != REG_NONE)) 2676 1.1 christos continue; 2677 1.1 christos if (i == 0 2678 1.1 christos && (format & M6812_OP_IDX) 2679 1.1 christos && (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))) 2680 1.1 christos continue; 2681 1.1 christos if (i == 1 2682 1.1 christos && (format & M6812_OP_IDX_P2)) 2683 1.1 christos continue; 2684 1.1 christos break; 2685 1.1 christos } 2686 1.1 christos if (mode & M6812_OP_IDX) 2687 1.1 christos { 2688 1.1 christos if (format & M6811_OP_IX && operands[i].reg1 == REG_X) 2689 1.1 christos continue; 2690 1.1 christos if (format & M6811_OP_IY && operands[i].reg1 == REG_Y) 2691 1.1 christos continue; 2692 1.1 christos if (i == 0 2693 1.1 christos && format & (M6812_OP_IDX | M6812_OP_IDX_1 | M6812_OP_IDX_2) 2694 1.1 christos && (operands[i].reg1 == REG_X 2695 1.1 christos || operands[i].reg1 == REG_Y 2696 1.1 christos || operands[i].reg1 == REG_SP 2697 1.1 christos || operands[i].reg1 == REG_PC)) 2698 1.1 christos continue; 2699 1.1 christos if (i == 1 && (format & M6812_OP_IDX_P2)) 2700 1.1 christos continue; 2701 1.1 christos } 2702 1.1 christos if (mode & format & (M6812_OP_D_IDX | M6812_OP_D_IDX_2)) 2703 1.1 christos { 2704 1.1 christos if (i == 0) 2705 1.1 christos continue; 2706 1.1 christos } 2707 1.1 christos if (mode & M6812_AUTO_INC_DEC) 2708 1.1 christos { 2709 1.1 christos if (i == 0 2710 1.1 christos && format & (M6812_OP_IDX | M6812_OP_IDX_1 | 2711 1.1 christos M6812_OP_IDX_2)) 2712 1.1 christos continue; 2713 1.1 christos if (i == 1 && format & M6812_OP_IDX_P2) 2714 1.1 christos continue; 2715 1.1 christos } 2716 1.1 christos break; 2717 1.1 christos } 2718 1.1 christos match = i == nb_operands; 2719 1.1 christos 2720 1.1 christos /* Operands are ok but an operand uses page 0 addressing mode 2721 1.1 christos while the insn supports abs-16 mode. Keep a reference to this 2722 1.1 christos insns in case there is no insn supporting page 0 addressing. */ 2723 1.1 christos if (match && poss_indirect) 2724 1.1 christos { 2725 1.1 christos op_indirect = opcode; 2726 1.1 christos match = 0; 2727 1.1 christos } 2728 1.1 christos if (match) 2729 1.1 christos break; 2730 1.1 christos } 2731 1.1 christos 2732 1.1 christos /* Page 0 addressing is used but not supported by any insn. 2733 1.1 christos If absolute addresses are supported, we use that insn. */ 2734 1.1 christos if (match == 0 && op_indirect) 2735 1.1 christos { 2736 1.1 christos opcode = op_indirect; 2737 1.1 christos match = 1; 2738 1.1 christos } 2739 1.1 christos 2740 1.1 christos return match ? opcode : 0; 2741 1.1 christos } 2742 1.1 christos 2743 1.1 christos /* Find the real opcode and its associated operands. We use a progressive 2744 1.1 christos approach here. On entry, 'opc' points to the first opcode in the 2745 1.1 christos table that matches the opcode name in the source line. We try to 2746 1.1 christos isolate an operand, find a possible match in the opcode table. 2747 1.1 christos We isolate another operand if no match were found. The table 'operands' 2748 1.1 christos is filled while operands are recognized. 2749 1.1 christos 2750 1.1 christos Returns the opcode pointer that matches the opcode name in the 2751 1.1 christos source line and the associated operands. */ 2752 1.1 christos static struct m68hc11_opcode * 2753 1.1 christos find_opcode (struct m68hc11_opcode_def *opc, operand operands[], 2754 1.1 christos int *nb_operands) 2755 1.1 christos { 2756 1.1 christos struct m68hc11_opcode *opcode; 2757 1.1 christos int i; 2758 1.1 christos 2759 1.1 christos if (opc->max_operands == 0) 2760 1.1 christos { 2761 1.1 christos *nb_operands = 0; 2762 1.1 christos return opc->opcode; 2763 1.1 christos } 2764 1.1 christos 2765 1.1 christos for (i = 0; i < opc->max_operands;) 2766 1.1 christos { 2767 1.1 christos int result; 2768 1.1 christos 2769 1.1 christos result = get_operand (&operands[i], i, opc->format); 2770 1.1 christos if (result <= 0) 2771 1.1 christos return 0; 2772 1.1 christos 2773 1.1 christos /* Special case where the bitmask of the bclr/brclr 2774 1.1 christos instructions is not introduced by #. 2775 1.1 christos Example: bclr 3,x $80. */ 2776 1.1 christos if (i == 1 && (opc->format & M6811_OP_BITMASK) 2777 1.1 christos && (operands[i].mode & M6811_OP_IND16)) 2778 1.1 christos { 2779 1.1 christos operands[i].mode = M6811_OP_IMM16; 2780 1.1 christos } 2781 1.1 christos 2782 1.1 christos i += result; 2783 1.1 christos *nb_operands = i; 2784 1.1 christos if (i >= opc->min_operands) 2785 1.1 christos { 2786 1.1 christos opcode = find (opc, operands, i); 2787 1.1 christos 2788 1.1 christos /* Another special case for 'call foo,page' instructions. 2789 1.1 christos Since we support 'call foo' and 'call foo,page' we must look 2790 1.1 christos if the optional page specification is present otherwise we will 2791 1.1 christos assemble immediately and treat the page spec as garbage. */ 2792 1.1 christos if (opcode && !(opcode->format & M6812_OP_PAGE)) 2793 1.1 christos return opcode; 2794 1.1 christos 2795 1.1 christos if (opcode && *input_line_pointer != ',') 2796 1.1 christos return opcode; 2797 1.1 christos } 2798 1.1 christos 2799 1.1 christos if (*input_line_pointer == ',') 2800 1.1 christos input_line_pointer++; 2801 1.1 christos } 2802 1.1 christos 2803 1.1 christos return 0; 2804 1.1 christos } 2805 1.1 christos 2806 1.1 christos #define M6812_XBCC_MARKER (M6812_OP_TBCC_MARKER \ 2807 1.1 christos | M6812_OP_DBCC_MARKER \ 2808 1.1 christos | M6812_OP_IBCC_MARKER) 2809 1.1 christos 2810 1.1 christos /* Gas line assembler entry point. */ 2812 1.1 christos 2813 1.1 christos /* This is the main entry point for the machine-dependent assembler. str 2814 1.1 christos points to a machine-dependent instruction. This function is supposed to 2815 1.10 christos emit the frags/bytes it assembles to. */ 2816 1.1 christos void 2817 1.1 christos md_assemble (char *str) 2818 1.1 christos { 2819 1.1 christos struct m68hc11_opcode_def *opc; 2820 1.1 christos struct m68hc11_opcode *opcode; 2821 1.1 christos 2822 1.1 christos struct m68hc11_opcode opcode_local; 2823 1.1 christos char *op_start, *op_end; 2824 1.1 christos char *save; 2825 1.10 christos char name[20]; 2826 1.1 christos int nlen = 0; 2827 1.1 christos operand operands[M6811_MAX_OPERANDS]; 2828 1.1 christos int nb_operands = 0; 2829 1.1 christos int branch_optimize = 0; 2830 1.10 christos int alias_id = -1; 2831 1.10 christos 2832 1.1 christos /* Drop leading whitespace. */ 2833 1.1 christos while (is_whitespace (*str)) 2834 1.1 christos str++; 2835 1.1 christos 2836 1.1 christos /* Find the opcode end and get the opcode in 'name'. The opcode is forced 2837 1.1 christos lower case (the opcode table only has lower case op-codes). */ 2838 1.1 christos for (op_start = op_end = str; 2839 1.1 christos !is_end_of_stmt (*op_end) && !is_whitespace (*op_end); 2840 1.1 christos op_end++) 2841 1.1 christos { 2842 1.1 christos name[nlen] = TOLOWER (op_start[nlen]); 2843 1.1 christos nlen++; 2844 1.1 christos if (nlen == sizeof (name) - 1) 2845 1.1 christos break; 2846 1.1 christos } 2847 1.1 christos name[nlen] = 0; 2848 1.1 christos 2849 1.1 christos if (nlen == 0) 2850 1.10 christos { 2851 1.1 christos as_bad (_("No instruction or missing opcode.")); 2852 1.1 christos return; 2853 1.1 christos } 2854 1.1 christos 2855 1.1 christos if (current_architecture == cpuxgate) 2856 1.1 christos { 2857 1.1 christos /* Find the opcode definition given its name. */ 2858 1.1 christos opc = str_hash_find (m68hc11_hash, name); 2859 1.1 christos if (opc == NULL) 2860 1.1 christos { 2861 1.1 christos as_bad (_("Opcode `%s' is not recognized."), name); 2862 1.1 christos return; 2863 1.1 christos } 2864 1.10 christos 2865 1.1 christos /* Grab a local copy. */ 2866 1.1 christos opcode_local.name = opc->opcode->name; 2867 1.1 christos /* These will be incomplete where multiple variants exist. */ 2868 1.1 christos opcode_local.opcode = opc->opcode->opcode; 2869 1.1 christos opcode_local.format = opc->opcode->format; 2870 1.1 christos 2871 1.1 christos save = input_line_pointer; 2872 1.1 christos input_line_pointer = op_end; 2873 1.1 christos 2874 1.1 christos if (opc->format == M68XG_OP_NONE) 2875 1.8 christos { 2876 1.1 christos /* No special handling required. */ 2877 1.1 christos opcode_local.format = M68XG_OP_NONE; 2878 1.1 christos build_insn_xg (opc->opcode, operands, 0); 2879 1.1 christos return; 2880 1.1 christos } 2881 1.1 christos 2882 1.1 christos /* Special handling of TFR. */ 2883 1.1 christos if (startswith (opc->opcode->name, "tfr")) 2884 1.1 christos { 2885 1.1 christos /* There must be two operands with a comma. */ 2886 1.1 christos input_line_pointer = skip_whites (input_line_pointer); 2887 1.1 christos operands[0].reg1 = register_name (); 2888 1.1 christos if (operands[0].reg1 == REG_NONE) 2889 1.1 christos { 2890 1.1 christos as_bad ("Invalid register\n"); 2891 1.1 christos return; 2892 1.1 christos } 2893 1.1 christos input_line_pointer = skip_whites (input_line_pointer); 2894 1.1 christos if (*input_line_pointer != ',') 2895 1.1 christos { 2896 1.1 christos as_bad ("Missing comma.\n"); 2897 1.1 christos return; 2898 1.1 christos } 2899 1.1 christos input_line_pointer++; 2900 1.1 christos input_line_pointer = skip_whites (input_line_pointer); 2901 1.1 christos operands[1].reg1 = register_name (); 2902 1.1 christos if (operands[1].reg1 == REG_NONE) 2903 1.1 christos { 2904 1.1 christos as_bad ("Invalid register\n"); 2905 1.1 christos return; 2906 1.1 christos } 2907 1.1 christos input_line_pointer = skip_whites (input_line_pointer); 2908 1.1 christos if (*input_line_pointer != '\n' && *input_line_pointer) 2909 1.1 christos { 2910 1.1 christos as_bad (_("Garbage at end of instruction: `%s'."), 2911 1.1 christos input_line_pointer); 2912 1.1 christos return; 2913 1.1 christos } 2914 1.1 christos if (operands[1].reg1 == REG_CCR) /* ,CCR */ 2915 1.1 christos opc->opcode->opcode = 0x00f8 | ( operands[0].reg1 << 8); 2916 1.1 christos else if (operands[0].reg1 == REG_CCR) /* CCR, */ 2917 1.1 christos opc->opcode->opcode = 0x00f9 | ( operands[1].reg1 << 8); 2918 1.1 christos else if (operands[1].reg1 == REG_PC) /* ,PC */ 2919 1.1 christos opc->opcode->opcode = 0x00fa | ( operands[0].reg1 << 8); 2920 1.1 christos else 2921 1.1 christos { 2922 1.1 christos as_bad ("Invalid operand to TFR\n"); 2923 1.1 christos return; 2924 1.1 christos } 2925 1.1 christos /* no special handling required */ 2926 1.1 christos opcode_local.format = M68XG_OP_NONE; 2927 1.1 christos opcode_local.opcode = opc->opcode->opcode; 2928 1.1 christos build_insn_xg (&opcode_local, operands, 0); 2929 1.1 christos return; 2930 1.1 christos } 2931 1.1 christos 2932 1.1 christos /* CSEM, SSEM */ 2933 1.1 christos if (opc->format & M68XG_OP_IMM3) 2934 1.1 christos { 2935 1.1 christos /* Either IMM3 or R */ 2936 1.1 christos input_line_pointer = skip_whites (input_line_pointer); 2937 1.1 christos if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r')) 2938 1.1 christos { 2939 1.1 christos operands[0].reg1 = register_name (); 2940 1.1 christos if (operands[0].reg1 == REG_NONE) 2941 1.1 christos { 2942 1.1 christos as_bad ("Invalid register\n"); 2943 1.1 christos return; 2944 1.1 christos } 2945 1.1 christos operands[0].mode = M68XG_OP_R; 2946 1.1 christos /* One opcode has multiple modes, so find right one. */ 2947 1.1 christos opcode = find (opc, operands, 1); 2948 1.1 christos if (opcode) 2949 1.3 christos { 2950 1.1 christos opcode_local.opcode = opcode->opcode 2951 1.1 christos | (operands[0].reg1 << 8); 2952 1.1 christos opcode_local.format = M68XG_OP_NONE; 2953 1.1 christos build_insn_xg (&opcode_local, operands, 1); 2954 1.1 christos } 2955 1.1 christos else 2956 1.1 christos as_bad ("No opcode found\n"); 2957 1.1 christos 2958 1.1 christos return; 2959 1.1 christos } 2960 1.1 christos else 2961 1.1 christos { 2962 1.1 christos if (*input_line_pointer == '#') 2963 1.1 christos input_line_pointer++; 2964 1.1 christos 2965 1.1 christos expression (&operands[0].exp); 2966 1.1 christos if (operands[0].exp.X_op == O_illegal) 2967 1.1 christos { 2968 1.1 christos as_bad (_("Illegal operand.")); 2969 1.1 christos return; 2970 1.1 christos } 2971 1.1 christos else if (operands[0].exp.X_op == O_absent) 2972 1.1 christos { 2973 1.3 christos as_bad (_("Missing operand.")); 2974 1.1 christos return; 2975 1.1 christos } 2976 1.1 christos 2977 1.1 christos if (check_range (operands[0].exp.X_add_number,M68XG_OP_IMM3)) 2978 1.1 christos { 2979 1.1 christos opcode_local.opcode |= (operands[0].exp.X_add_number); 2980 1.1 christos operands[0].mode = M68XG_OP_IMM3; 2981 1.1 christos 2982 1.1 christos opcode = find (opc, operands, 1); 2983 1.1 christos if (opcode) 2984 1.1 christos { 2985 1.1 christos opcode_local.opcode = opcode->opcode; 2986 1.1 christos opcode_local.opcode 2987 1.1 christos |= (operands[0].exp.X_add_number) << 8; 2988 1.1 christos opcode_local.format = M68XG_OP_NONE; 2989 1.1 christos build_insn_xg (&opcode_local, operands, 1); 2990 1.1 christos } 2991 1.1 christos else 2992 1.1 christos as_bad ("No opcode found\n"); 2993 1.1 christos 2994 1.1 christos return; 2995 1.1 christos } 2996 1.1 christos else 2997 1.8 christos { 2998 1.1 christos as_bad ("Number out of range for IMM3\n"); 2999 1.1 christos return; 3000 1.1 christos } 3001 1.1 christos } 3002 1.1 christos } 3003 1.1 christos 3004 1.1 christos /* Special handling of SIF. */ 3005 1.1 christos if (startswith (opc->opcode->name, "sif")) 3006 1.1 christos { 3007 1.1 christos /* Either OP_NONE or OP_RS. */ 3008 1.1 christos if (*input_line_pointer != '\n') 3009 1.1 christos input_line_pointer = skip_whites (input_line_pointer); 3010 1.1 christos 3011 1.1 christos if ((*input_line_pointer == '\n') || (*input_line_pointer == '\r') 3012 1.1 christos || (*input_line_pointer == '\0')) 3013 1.1 christos opc->opcode->opcode = 0x0300; 3014 1.1 christos else 3015 1.1 christos { 3016 1.1 christos operands[0].reg1 = register_name (); 3017 1.1 christos if (operands[0].reg1 == REG_NONE) 3018 1.1 christos { 3019 1.1 christos as_bad ("Invalid register\n"); 3020 1.1 christos return; 3021 1.1 christos } 3022 1.1 christos opcode_local.opcode = 0x00f7 | (operands[0].reg1 << 8); 3023 1.1 christos } 3024 1.1 christos opcode_local.format = M68XG_OP_NONE; 3025 1.1 christos build_insn_xg (&opcode_local, operands, 0); 3026 1.1 christos return; 3027 1.1 christos } 3028 1.1 christos 3029 1.1 christos /* SEX, PAR, JAL plus aliases NEG, TST, COM */ 3030 1.1 christos if (opc->format & M68XG_OP_R) 3031 1.1 christos { 3032 1.1 christos input_line_pointer = skip_whites (input_line_pointer); 3033 1.1 christos operands[0].reg1 = register_name (); 3034 1.1 christos if (operands[0].reg1 == REG_NONE) 3035 1.1 christos { 3036 1.1 christos as_bad ("Invalid register\n"); 3037 1.1 christos return; 3038 1.1 christos } 3039 1.1 christos if ((*input_line_pointer == '\n') || (*input_line_pointer == '\r') 3040 1.1 christos || (*input_line_pointer == '\0')) 3041 1.1 christos { 3042 1.8 christos /* Likely to be OP R. */ 3043 1.8 christos if (opc->format & M68XG_OP_R) 3044 1.1 christos { 3045 1.1 christos operands[0].mode = M68XG_OP_R; 3046 1.1 christos 3047 1.1 christos opcode = find (opc, operands, 1); 3048 1.8 christos if (opcode) 3049 1.1 christos { 3050 1.1 christos if ((startswith (opc->opcode->name, "com")) 3051 1.1 christos || (startswith (opc->opcode->name, "neg"))) 3052 1.1 christos /* Special case for com RD as alias for sub RD,R0,RS */ 3053 1.1 christos /* Special case for neg RD as alias for sub RD,R0,RS */ 3054 1.1 christos opcode_local.opcode = opcode->opcode 3055 1.1 christos | (operands[0].reg1 << 8) | (operands[0].reg1 << 2); 3056 1.1 christos else if (startswith (opc->opcode->name, "tst")) 3057 1.1 christos /* Special case for tst RS alias for sub R0, RS, R0 */ 3058 1.1 christos opcode_local.opcode = opcode->opcode 3059 1.1 christos | (operands[0].reg1 << 5); 3060 1.1 christos else 3061 1.1 christos opcode_local.opcode |= (operands[0].reg1 << 8); 3062 1.1 christos } 3063 1.1 christos opcode_local.format = M68XG_OP_NONE; 3064 1.1 christos build_insn_xg (&opcode_local, operands, 0); 3065 1.1 christos } 3066 1.1 christos else 3067 1.3 christos as_bad ("No valid mode found\n"); 3068 1.1 christos 3069 1.1 christos return; 3070 1.1 christos } 3071 1.1 christos } 3072 1.1 christos 3073 1.1 christos if (opc->format & (M68XG_OP_REL9 | M68XG_OP_REL10)) 3074 1.1 christos { 3075 1.1 christos opcode_local.format = opc->format; 3076 1.1 christos input_line_pointer = skip_whites (input_line_pointer); 3077 1.1 christos expression (&operands[0].exp); 3078 1.1 christos if (operands[0].exp.X_op == O_illegal) 3079 1.1 christos { 3080 1.1 christos as_bad (_("Illegal operand.")); 3081 1.1 christos return; 3082 1.1 christos } 3083 1.1 christos else if (operands[0].exp.X_op == O_absent) 3084 1.1 christos { 3085 1.1 christos as_bad (_("Missing operand.")); 3086 1.1 christos return; 3087 1.1 christos } 3088 1.1 christos opcode_local.opcode = opc->opcode->opcode; 3089 1.1 christos build_insn_xg (&opcode_local, operands, 1); 3090 1.1 christos return; 3091 1.1 christos } 3092 1.1 christos 3093 1.3 christos 3094 1.1 christos /* For other command formats, parse input line and determine the mode 3095 1.1 christos we are using as we go. */ 3096 1.1 christos 3097 1.1 christos input_line_pointer = skip_whites (input_line_pointer); 3098 1.3 christos if ((*input_line_pointer == '\n') || (*input_line_pointer == '\r') 3099 1.1 christos || (*input_line_pointer == '\0')) 3100 1.1 christos return; /* nothing left */ 3101 1.1 christos 3102 1.1 christos if (*input_line_pointer == '#') 3103 1.1 christos { 3104 1.1 christos as_bad ("No register specified before hash\n"); 3105 1.1 christos return; 3106 1.1 christos } 3107 1.1 christos 3108 1.1 christos /* first operand is expected to be a register */ 3109 1.1 christos if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r')) 3110 1.1 christos { 3111 1.1 christos operands[0].reg1 = register_name (); 3112 1.1 christos if (operands[0].reg1 == REG_NONE) 3113 1.1 christos { 3114 1.1 christos as_bad ("Invalid register\n"); 3115 1.1 christos return; 3116 1.1 christos } 3117 1.1 christos } 3118 1.1 christos 3119 1.1 christos input_line_pointer = skip_whites (input_line_pointer); 3120 1.1 christos if (*input_line_pointer != ',') 3121 1.1 christos { 3122 1.1 christos as_bad ("Missing operand\n"); 3123 1.1 christos return; 3124 1.1 christos } 3125 1.1 christos input_line_pointer++; 3126 1.1 christos input_line_pointer = skip_whites (input_line_pointer); 3127 1.1 christos 3128 1.1 christos if (*input_line_pointer == '#') 3129 1.1 christos { 3130 1.8 christos /* Some kind of immediate mode, check if this is possible. */ 3131 1.1 christos if (!(opc->format 3132 1.1 christos & (M68XG_OP_R_IMM8 | M68XG_OP_R_IMM16 | M68XG_OP_R_IMM4))) 3133 1.1 christos as_bad ("Invalid immediate mode for `%s'", opc->opcode->name); 3134 1.1 christos else 3135 1.8 christos { 3136 1.1 christos input_line_pointer++; 3137 1.1 christos input_line_pointer = skip_whites (input_line_pointer); 3138 1.1 christos if (startswith (input_line_pointer, "%hi")) 3139 1.1 christos { 3140 1.1 christos input_line_pointer += 3; 3141 1.1 christos operands[0].mode = M6811_OP_HIGH_ADDR; 3142 1.1 christos } 3143 1.1 christos else if (startswith (input_line_pointer, "%lo")) 3144 1.1 christos { 3145 1.1 christos input_line_pointer += 3; 3146 1.1 christos operands[0].mode = M6811_OP_LOW_ADDR; 3147 1.1 christos } 3148 1.1 christos else 3149 1.1 christos operands[0].mode = 0; 3150 1.1 christos 3151 1.1 christos expression (&operands[0].exp); 3152 1.1 christos if (operands[0].exp.X_op == O_illegal) 3153 1.1 christos { 3154 1.1 christos as_bad (_("Illegal operand.")); 3155 1.1 christos return; 3156 1.1 christos } 3157 1.1 christos else if (operands[0].exp.X_op == O_absent) 3158 1.1 christos { 3159 1.1 christos as_bad (_("Missing operand.")); 3160 1.1 christos return; 3161 1.1 christos } 3162 1.1 christos /* ok so far, can only be one mode */ 3163 1.1 christos opcode_local.format = opc->format 3164 1.1 christos & (M68XG_OP_R_IMM8 | M68XG_OP_R_IMM16 | M68XG_OP_R_IMM4); 3165 1.3 christos if (opcode_local.format & M68XG_OP_R_IMM4) 3166 1.1 christos { 3167 1.1 christos operands[0].mode = M68XG_OP_R_IMM4; 3168 1.1 christos /* same opcodes have multiple modes, so find right one */ 3169 1.1 christos opcode = find (opc, operands, 1); 3170 1.3 christos if (opcode) 3171 1.1 christos opcode_local.opcode = opcode->opcode 3172 1.1 christos | (operands[0].reg1 << 8); 3173 1.1 christos 3174 1.1 christos if (operands[0].exp.X_op != O_constant) 3175 1.1 christos as_bad ("Only constants supported at for IMM4 mode\n"); 3176 1.1 christos else 3177 1.1 christos { 3178 1.1 christos if (check_range 3179 1.1 christos (operands[0].exp.X_add_number,M68XG_OP_R_IMM4)) 3180 1.1 christos opcode_local.opcode 3181 1.1 christos |= (operands[0].exp.X_add_number << 4); 3182 1.1 christos else 3183 1.1 christos as_bad ("Number out of range for IMM4\n"); 3184 1.1 christos } 3185 1.1 christos opcode_local.format = M68XG_OP_NONE; 3186 1.1 christos } 3187 1.1 christos else if (opcode_local.format & M68XG_OP_R_IMM16) 3188 1.1 christos { 3189 1.1 christos operands[0].mode = M68XG_OP_R_IMM16; 3190 1.1 christos 3191 1.1 christos opcode = find (opc, operands, 1); 3192 1.1 christos if (opcode) 3193 1.1 christos { 3194 1.1 christos opcode_local.opcode = opcode->opcode 3195 1.1 christos | (operands[0].reg1 << 8); 3196 1.1 christos } 3197 1.1 christos } 3198 1.1 christos else 3199 1.1 christos { 3200 1.1 christos opcode_local.opcode = opc->opcode->opcode 3201 1.1 christos | (operands[0].reg1 << 8); 3202 1.1 christos } 3203 1.1 christos build_insn_xg (&opcode_local, operands, 1); 3204 1.1 christos } 3205 1.1 christos } 3206 1.1 christos else if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r')) 3207 1.1 christos { 3208 1.1 christos /* we've got as far as OP R, R */ 3209 1.1 christos operands[1].reg1 = register_name (); 3210 1.1 christos if (operands[1].reg1 == REG_NONE) 3211 1.1 christos { 3212 1.1 christos as_bad ("Invalid register\n"); 3213 1.1 christos return; 3214 1.1 christos } 3215 1.1 christos if ((*input_line_pointer == '\n') || (*input_line_pointer == '\r') 3216 1.1 christos || (*input_line_pointer == '\0')) 3217 1.1 christos { 3218 1.8 christos /* looks like OP_R_R */ 3219 1.8 christos if (opc->format & M68XG_OP_R_R) 3220 1.8 christos { 3221 1.1 christos operands[0].mode = M68XG_OP_R_R; 3222 1.1 christos /* same opcodes have multiple modes, so find right one */ 3223 1.1 christos opcode = find (opc, operands, 1); 3224 1.1 christos if (opcode) 3225 1.1 christos { 3226 1.3 christos if ((startswith (opc->opcode->name, "com")) 3227 1.1 christos || (startswith (opc->opcode->name, "mov")) 3228 1.1 christos || (startswith (opc->opcode->name, "neg"))) 3229 1.8 christos { 3230 1.8 christos /* Special cases for: 3231 1.1 christos com RD, RS alias for xnor RD,R0,RS 3232 1.1 christos mov RD, RS alias for or RD, R0, RS 3233 1.1 christos neg RD, RS alias for sub RD, R0, RS */ 3234 1.1 christos opcode_local.opcode = opcode->opcode 3235 1.3 christos | (operands[0].reg1 << 8) | (operands[1].reg1 << 2); 3236 1.1 christos } 3237 1.1 christos else if ((startswith (opc->opcode->name, "cmp")) 3238 1.1 christos || (startswith (opc->opcode->name, "cpc"))) 3239 1.1 christos { 3240 1.1 christos /* special cases for: 3241 1.1 christos cmp RS1, RS2 alias for sub R0, RS1, RS2 3242 1.1 christos cpc RS1, RS2 alias for sbc R0, RS1, RS2 */ 3243 1.1 christos opcode_local.opcode = opcode->opcode 3244 1.1 christos | (operands[0].reg1 << 5) | (operands[1].reg1 << 2); 3245 1.1 christos } 3246 1.1 christos else 3247 1.1 christos { 3248 1.1 christos opcode_local.opcode = opcode->opcode 3249 1.1 christos | (operands[0].reg1 << 8) | (operands[1].reg1 << 5); 3250 1.1 christos } 3251 1.1 christos opcode_local.format = M68XG_OP_NONE; 3252 1.1 christos build_insn_xg (&opcode_local, operands, 1); 3253 1.1 christos } 3254 1.1 christos } 3255 1.1 christos else 3256 1.1 christos { 3257 1.1 christos as_bad ("No valid mode found\n"); 3258 1.1 christos } 3259 1.1 christos } 3260 1.1 christos else 3261 1.1 christos { 3262 1.1 christos /* more data */ 3263 1.1 christos if (*input_line_pointer != ',') 3264 1.1 christos { 3265 1.1 christos as_bad (_("Missing operand.")); 3266 1.1 christos return; 3267 1.1 christos } 3268 1.1 christos input_line_pointer++; 3269 1.1 christos input_line_pointer = skip_whites (input_line_pointer); 3270 1.1 christos if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r')) 3271 1.1 christos { 3272 1.1 christos operands[2].reg1 = register_name (); 3273 1.1 christos if (operands[2].reg1 == REG_NONE) 3274 1.1 christos { 3275 1.1 christos as_bad ("Invalid register\n"); 3276 1.1 christos return; 3277 1.3 christos } 3278 1.1 christos if (opc->format & M68XG_OP_R_R_R) 3279 1.1 christos { 3280 1.1 christos operands[0].mode = M68XG_OP_R_R_R; 3281 1.1 christos 3282 1.1 christos opcode = find (opc, operands, 1); 3283 1.1 christos if (opcode) 3284 1.1 christos { 3285 1.1 christos opcode_local.opcode = opcode->opcode 3286 1.1 christos | (operands[0].reg1 << 8) | (operands[1].reg1 << 5) 3287 1.1 christos | (operands[2].reg1 << 2); 3288 1.1 christos opcode_local.format = M68XG_OP_NONE; 3289 1.1 christos build_insn_xg (&opcode_local, operands, 1); 3290 1.1 christos } 3291 1.1 christos } 3292 1.1 christos else 3293 1.1 christos { 3294 1.1 christos as_bad ("No valid mode found\n"); 3295 1.1 christos } 3296 1.1 christos } 3297 1.1 christos } 3298 1.1 christos } 3299 1.1 christos else if (*input_line_pointer == '(') /* Indexed modes */ 3300 1.1 christos { 3301 1.1 christos input_line_pointer++; 3302 1.1 christos input_line_pointer = skip_whites (input_line_pointer); 3303 1.1 christos if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r')) 3304 1.1 christos { 3305 1.1 christos /* we've got as far as OP R, (R */ 3306 1.1 christos operands[1].reg1 = register_name (); 3307 1.1 christos if (operands[1].reg1 == REG_NONE) 3308 1.1 christos { 3309 1.1 christos as_bad ("Invalid register\n"); 3310 1.1 christos return; 3311 1.1 christos } 3312 1.1 christos 3313 1.1 christos if ((*input_line_pointer == '\n') || (*input_line_pointer == '\r') 3314 1.3 christos || (*input_line_pointer == '\0')) 3315 1.1 christos { 3316 1.1 christos /* Looks like OP_R_R. */ 3317 1.1 christos as_bad (_("Missing operand.")); 3318 1.1 christos return; 3319 1.1 christos } 3320 1.1 christos 3321 1.1 christos input_line_pointer = skip_whites (input_line_pointer); 3322 1.1 christos 3323 1.1 christos if (*input_line_pointer != ',') 3324 1.1 christos { 3325 1.1 christos as_bad (_("Missing operand.")); 3326 1.1 christos return; 3327 1.1 christos } 3328 1.1 christos input_line_pointer++; 3329 1.1 christos input_line_pointer = skip_whites (input_line_pointer); 3330 1.1 christos 3331 1.1 christos if (*input_line_pointer == '#') 3332 1.1 christos { 3333 1.1 christos input_line_pointer++; 3334 1.1 christos input_line_pointer = skip_whites (input_line_pointer); 3335 1.1 christos expression (&operands[0].exp); 3336 1.1 christos if (operands[0].exp.X_op == O_illegal) 3337 1.1 christos { 3338 1.1 christos as_bad (_("Illegal operand.")); 3339 1.1 christos return; 3340 1.1 christos } 3341 1.1 christos else if (operands[0].exp.X_op == O_absent) 3342 1.1 christos { 3343 1.1 christos as_bad (_("Missing operand.")); 3344 1.1 christos return; 3345 1.1 christos } 3346 1.1 christos 3347 1.1 christos input_line_pointer = skip_whites (input_line_pointer); 3348 1.1 christos if (*input_line_pointer != ')') 3349 1.3 christos { 3350 1.1 christos as_bad ("Missing `)' to close register indirect operand."); 3351 1.1 christos return; 3352 1.1 christos } 3353 1.1 christos else 3354 1.1 christos { 3355 1.1 christos input_line_pointer++; 3356 1.1 christos } 3357 1.1 christos 3358 1.1 christos /* Ok so far, can only be one mode. */ 3359 1.1 christos opcode_local.format = M68XG_OP_R_R_OFFS5; 3360 1.1 christos operands[0].mode = M68XG_OP_R_R_OFFS5; 3361 1.1 christos 3362 1.1 christos opcode = find (opc, operands, 1); 3363 1.1 christos if (opcode) 3364 1.1 christos { 3365 1.1 christos opcode_local.opcode = opcode->opcode 3366 1.1 christos | (operands[0].reg1 << 8) | (operands[1].reg1 << 5); 3367 1.1 christos if (operands[0].exp.X_op != O_constant) 3368 1.1 christos { 3369 1.1 christos as_bad 3370 1.1 christos ("Only constants supported for indexed OFFS5 mode\n"); 3371 1.1 christos } 3372 1.1 christos else 3373 1.1 christos { 3374 1.1 christos if (check_range (operands[0].exp.X_add_number, 3375 1.1 christos M68XG_OP_R_R_OFFS5)) 3376 1.1 christos { 3377 1.1 christos opcode_local.opcode 3378 1.1 christos |= (operands[0].exp.X_add_number); 3379 1.1 christos opcode_local.format = M68XG_OP_NONE; 3380 1.1 christos build_insn_xg (&opcode_local, operands, 1); 3381 1.1 christos } 3382 1.1 christos else 3383 1.1 christos { 3384 1.1 christos as_bad ("Number out of range for OFFS5\n"); 3385 1.1 christos } 3386 1.1 christos } 3387 1.1 christos } 3388 1.1 christos } 3389 1.1 christos else 3390 1.1 christos { 3391 1.1 christos operands[0].mode = M68XG_OP_RD_RB_RI; 3392 1.1 christos 3393 1.1 christos if (*input_line_pointer == '-') 3394 1.1 christos { 3395 1.1 christos operands[0].mode = M68XG_OP_RD_RB_mRI; 3396 1.1 christos input_line_pointer++; 3397 1.1 christos } 3398 1.1 christos operands[2].reg1 = register_name (); 3399 1.1 christos if (operands[2].reg1 == REG_NONE) 3400 1.1 christos { 3401 1.1 christos as_bad ("Invalid register\n"); 3402 1.1 christos return; 3403 1.1 christos } 3404 1.1 christos 3405 1.1 christos if (*input_line_pointer == '+') 3406 1.1 christos { 3407 1.1 christos if (opcode_local.format == M68XG_OP_RD_RB_mRI) 3408 1.1 christos { 3409 1.1 christos as_bad (_("Illegal operand.")); 3410 1.1 christos return; 3411 1.1 christos } 3412 1.1 christos operands[0].mode = M68XG_OP_RD_RB_RIp; 3413 1.1 christos input_line_pointer++; 3414 1.1 christos } 3415 1.1 christos 3416 1.1 christos input_line_pointer = skip_whites (input_line_pointer); 3417 1.1 christos if (*input_line_pointer != ')') 3418 1.1 christos { 3419 1.1 christos as_bad 3420 1.1 christos ("Missing `)' to close register indirect operand."); 3421 1.1 christos return; 3422 1.1 christos } 3423 1.1 christos else 3424 1.1 christos { 3425 1.1 christos input_line_pointer++; 3426 1.1 christos } 3427 1.1 christos 3428 1.1 christos opcode = find (opc, operands, 1); 3429 1.1 christos if (opcode) 3430 1.1 christos { 3431 1.1 christos opcode_local.opcode = opcode->opcode 3432 1.10 christos | (operands[0].reg1 << 8) | (operands[1].reg1 << 5) 3433 1.1 christos | (operands[2].reg1 << 2); 3434 1.1 christos opcode_local.format = M68XG_OP_NONE; 3435 1.1 christos build_insn_xg (&opcode_local, operands, 1); 3436 1.1 christos } 3437 1.1 christos else 3438 1.1 christos { 3439 1.1 christos as_bad ("Failed to find opcode for %s %s\n", 3440 1.1 christos opc->opcode->name, op_end); 3441 1.1 christos } 3442 1.1 christos } 3443 1.1 christos } 3444 1.1 christos } 3445 1.1 christos else 3446 1.1 christos { 3447 1.10 christos as_bad (_("Failed to find a valid mode for `%s'."), 3448 1.1 christos opc->opcode->name); 3449 1.1 christos } 3450 1.1 christos 3451 1.1 christos if (opc->opcode && !flag_mri) 3452 1.1 christos { 3453 1.1 christos char *p = input_line_pointer; 3454 1.1 christos 3455 1.1 christos while (is_whitespace (*p) || *p == '\n' || *p == '\r') 3456 1.1 christos p++; 3457 1.1 christos 3458 1.1 christos if (*p != '\n' && *p) 3459 1.1 christos as_bad (_("Garbage at end of instruction: `%s'."), p); 3460 1.1 christos } 3461 1.1 christos 3462 1.1 christos input_line_pointer = save; 3463 1.1 christos 3464 1.1 christos /* Opcode is known but does not have valid operands. Print out the 3465 1.1 christos syntax for this opcode. */ 3466 1.1 christos if (opc->opcode == 0) 3467 1.1 christos { 3468 1.1 christos if (flag_print_insn_syntax) 3469 1.1 christos print_insn_format (name); 3470 1.1 christos 3471 1.10 christos as_bad (_("Invalid operand for `%s'"), name); 3472 1.1 christos return; 3473 1.1 christos } 3474 1.1 christos 3475 1.1 christos return; 3476 1.1 christos } 3477 1.1 christos 3478 1.1 christos /* Find the opcode definition given its name. */ 3479 1.10 christos opc = str_hash_find (m68hc11_hash, name); 3480 1.1 christos 3481 1.1 christos /* If it's not recognized, look for 'jbsr' and 'jbxx'. These are 3482 1.1 christos pseudo insns for relative branch. For these branches, we always 3483 1.1 christos optimize them (turned into absolute branches) even if --short-branches 3484 1.1 christos is given. */ 3485 1.1 christos if (opc == NULL && name[0] == 'j' && name[1] == 'b') 3486 1.1 christos { 3487 1.1 christos opc = str_hash_find (m68hc11_hash, &name[1]); 3488 1.1 christos if (opc 3489 1.1 christos && (!(opc->format & M6811_OP_JUMP_REL) 3490 1.1 christos || (opc->format & M6811_OP_BITMASK))) 3491 1.1 christos opc = 0; 3492 1.10 christos if (opc) 3493 1.1 christos branch_optimize = 1; 3494 1.10 christos } 3495 1.1 christos 3496 1.1 christos /* The following test should probably be removed. This does not conform 3497 1.1 christos to Motorola assembler specs. */ 3498 1.1 christos if (opc == NULL && flag_mri) 3499 1.10 christos { 3500 1.10 christos if (is_whitespace (*op_end)) 3501 1.1 christos { 3502 1.1 christos while (is_whitespace (*op_end)) 3503 1.1 christos op_end++; 3504 1.1 christos 3505 1.1 christos if (nlen < 19 3506 1.1 christos && (*op_end && 3507 1.1 christos (is_end_of_stmt (op_end[1]) 3508 1.1 christos || is_whitespace (op_end[1]) 3509 1.1 christos || !ISALNUM (op_end[1]))) 3510 1.10 christos && (*op_end == 'a' || *op_end == 'b' 3511 1.1 christos || *op_end == 'A' || *op_end == 'B' 3512 1.1 christos || *op_end == 'd' || *op_end == 'D' 3513 1.1 christos || *op_end == 'x' || *op_end == 'X' 3514 1.1 christos || *op_end == 'y' || *op_end == 'Y')) 3515 1.1 christos { 3516 1.1 christos name[nlen++] = TOLOWER (*op_end++); 3517 1.1 christos name[nlen] = 0; 3518 1.1 christos opc = str_hash_find (m68hc11_hash, name); 3519 1.1 christos } 3520 1.1 christos } 3521 1.1 christos } 3522 1.1 christos 3523 1.1 christos /* Identify a possible instruction alias. There are some on the 3524 1.1 christos 68HC12 to emulate a few 68HC11 instructions. */ 3525 1.1 christos if (opc == NULL && (current_architecture & cpu6812)) 3526 1.1 christos { 3527 1.1 christos int i; 3528 1.1 christos 3529 1.1 christos for (i = 0; i < m68hc12_num_alias; i++) 3530 1.1 christos if (strcmp (m68hc12_alias[i].name, name) == 0) 3531 1.1 christos { 3532 1.1 christos alias_id = i; 3533 1.1 christos break; 3534 1.10 christos } 3535 1.1 christos } 3536 1.1 christos if (opc == NULL && alias_id < 0) 3537 1.1 christos { 3538 1.1 christos as_bad (_("Opcode `%s' is not recognized."), name); 3539 1.1 christos return; 3540 1.1 christos } 3541 1.1 christos save = input_line_pointer; 3542 1.1 christos input_line_pointer = op_end; 3543 1.1 christos 3544 1.1 christos if (opc) 3545 1.1 christos { 3546 1.1 christos opc->used++; 3547 1.1 christos opcode = find_opcode (opc, operands, &nb_operands); 3548 1.10 christos } 3549 1.1 christos else 3550 1.1 christos opcode = 0; 3551 1.1 christos 3552 1.1 christos if ((opcode || alias_id >= 0) && !flag_mri) 3553 1.1 christos { 3554 1.1 christos char *p = input_line_pointer; 3555 1.1 christos 3556 1.1 christos while (is_whitespace (*p) || *p == '\n' || *p == '\r') 3557 1.1 christos p++; 3558 1.1 christos 3559 1.1 christos if (*p != '\n' && *p) 3560 1.1 christos as_bad (_("Garbage at end of instruction: `%s'."), p); 3561 1.1 christos } 3562 1.1 christos 3563 1.1 christos input_line_pointer = save; 3564 1.1 christos 3565 1.1 christos if (alias_id >= 0) 3566 1.1 christos { 3567 1.1 christos char *f = m68hc11_new_insn (m68hc12_alias[alias_id].size); 3568 1.1 christos 3569 1.1 christos number_to_chars_bigendian (f, m68hc12_alias[alias_id].code1, 1); 3570 1.1 christos if (m68hc12_alias[alias_id].size > 1) 3571 1.1 christos number_to_chars_bigendian (f + 1, m68hc12_alias[alias_id].code2, 1); 3572 1.1 christos 3573 1.1 christos return; 3574 1.1 christos } 3575 1.1 christos 3576 1.1 christos /* Opcode is known but does not have valid operands. Print out the 3577 1.1 christos syntax for this opcode. */ 3578 1.1 christos if (opcode == 0) 3579 1.1 christos { 3580 1.1 christos if (flag_print_insn_syntax) 3581 1.1 christos print_insn_format (name); 3582 1.1 christos 3583 1.1 christos if (((strcmp (name, "movb") == 0) || (strcmp (name, "movw") == 0)) 3584 1.1 christos && (current_architecture & cpu9s12x)) 3585 1.1 christos { 3586 1.1 christos char *f; 3587 1.1 christos int movb; 3588 1.1 christos if (strcmp (name, "movb") == 0) 3589 1.1 christos movb = 8; 3590 1.1 christos else 3591 1.1 christos movb = 0; 3592 1.1 christos 3593 1.1 christos /* The existing operand extract code fell over if these additional modes 3594 1.1 christos were enabled in m68hc11-opc.c. So they are commented there and 3595 1.1 christos decoded here instead. */ 3596 1.1 christos 3597 1.1 christos if (operands[1].mode & (M6812_OP_IDX | M6812_OP_IDX_1 3598 1.1 christos | M6812_OP_IDX_2 | M6812_OP_D_IDX | M6812_OP_D_IDX_2 | M6812_PRE_INC 3599 1.1 christos | M6812_PRE_DEC | M6812_POST_INC | M6812_POST_DEC )) 3600 1.1 christos { 3601 1.1 christos /* first check if valid mode then start building it up */ 3602 1.1 christos if (operands[0].mode & (M6811_OP_IMM8 | M6811_OP_IMM16 3603 1.1 christos | M6811_OP_IND16 | M6812_OP_IDX | M6812_OP_IDX_1 3604 1.1 christos | M6812_OP_IDX_2 | M6812_OP_D_IDX | M6812_OP_D_IDX_2)) 3605 1.1 christos { 3606 1.1 christos int opr16a; 3607 1.1 christos if (operands[1].mode & (M6811_OP_IND16)) 3608 1.1 christos opr16a = 3; 3609 1.1 christos else 3610 1.1 christos opr16a = 0; 3611 1.1 christos 3612 1.1 christos f = m68hc11_new_insn (2); 3613 1.1 christos 3614 1.1 christos if (operands[0].mode & (M6811_OP_IMM8 | M6811_OP_IMM16)) 3615 1.1 christos { 3616 1.1 christos number_to_chars_bigendian (f, 0x1800 + movb + opr16a, 2); 3617 1.1 christos build_indexed_byte (&operands[1], operands[1].mode, 1); 3618 1.1 christos if (movb) 3619 1.1 christos fixup8 (&operands[0].exp, M6811_OP_IMM8, 3620 1.1 christos operands[0].mode); 3621 1.1 christos else 3622 1.1 christos fixup16 (&operands[0].exp, M6811_OP_IMM16, 3623 1.1 christos operands[0].mode); 3624 1.1 christos 3625 1.1 christos return; 3626 1.1 christos } 3627 1.1 christos else if (operands[0].mode & M6811_OP_IND16) 3628 1.1 christos { 3629 1.1 christos number_to_chars_bigendian (f, 0x1801 + movb + opr16a, 2); 3630 1.1 christos build_indexed_byte (&operands[1], operands[1].mode, 1); 3631 1.1 christos fixup16 (&operands[0].exp, M6811_OP_IND16, operands[0].mode); 3632 1.1 christos return; 3633 1.1 christos } 3634 1.1 christos else 3635 1.1 christos { 3636 1.1 christos number_to_chars_bigendian (f, 0x1802 + movb + opr16a, 2); 3637 1.1 christos build_indexed_byte (&operands[0], operands[0].mode, 1); 3638 1.1 christos build_indexed_byte (&operands[1], operands[1].mode, 1); 3639 1.1 christos return; 3640 1.1 christos } 3641 1.1 christos } 3642 1.1 christos } 3643 1.1 christos else if (operands[1].mode & M6811_OP_IND16) 3644 1.1 christos { 3645 1.1 christos /* First check if this is valid mode, then start building it up. */ 3646 1.1 christos if (operands[0].mode & (M6811_OP_IMM8 | M6811_OP_IMM16 3647 1.1 christos | M6811_OP_IND16 | M6812_OP_IDX | M6812_OP_IDX_1 3648 1.1 christos | M6812_OP_IDX_2 | M6812_OP_D_IDX | M6812_OP_D_IDX_2)) 3649 1.1 christos { 3650 1.1 christos int opr16a; 3651 1.1 christos if (operands[1].mode & (M6811_OP_IND16)) 3652 1.1 christos opr16a = 3; 3653 1.1 christos else 3654 1.1 christos opr16a = 0; 3655 1.1 christos 3656 1.1 christos f = m68hc11_new_insn (2); 3657 1.1 christos 3658 1.1 christos /* The first two cases here should actually be covered by the 3659 1.1 christos normal operand code. */ 3660 1.1 christos if (operands[0].mode & (M6811_OP_IMM8 | M6811_OP_IMM16)) 3661 1.1 christos { 3662 1.1 christos number_to_chars_bigendian (f, 0x1800 + movb + opr16a, 2); 3663 1.1 christos if (movb) 3664 1.1 christos fixup8 (&operands[0].exp, M6811_OP_IMM8, operands[0].mode); 3665 1.1 christos else 3666 1.1 christos fixup16 (&operands[0].exp, M6811_OP_IMM16, operands[0].mode); 3667 1.1 christos 3668 1.1 christos fixup16 (&operands[0].exp, M6811_OP_IND16, operands[0].mode); 3669 1.1 christos return; 3670 1.1 christos } 3671 1.1 christos else if (operands[0].mode & M6811_OP_IND16) 3672 1.1 christos { 3673 1.1 christos number_to_chars_bigendian (f, 0x1801 + movb + opr16a, 2); 3674 1.1 christos build_indexed_byte (&operands[1], operands[1].mode, 1); 3675 1.1 christos fixup16 (&operands[0].exp, M6811_OP_IND16, operands[0].mode); 3676 1.1 christos return; 3677 1.1 christos } 3678 1.1 christos else 3679 1.1 christos { 3680 1.1 christos number_to_chars_bigendian (f, 0x1802 + movb + opr16a, 2); 3681 1.1 christos build_indexed_byte (&operands[0], operands[0].mode, 1); 3682 1.1 christos fixup16 (&operands[1].exp, M6811_OP_IND16, operands[1].mode); 3683 1.1 christos return; 3684 1.1 christos } 3685 1.1 christos } 3686 1.1 christos } 3687 1.1 christos 3688 1.1 christos as_bad (_("Invalid operand for `%s'"), name); 3689 1.1 christos return; 3690 1.1 christos 3691 1.1 christos } 3692 1.1 christos else 3693 1.1 christos { 3694 1.1 christos as_bad (_("Invalid operand for `%s'"), name); 3695 1.1 christos return; 3696 1.1 christos } 3697 1.1 christos } 3698 1.1 christos 3699 1.1 christos /* Treat dbeq/ibeq/tbeq instructions in a special way. The branch is 3700 1.1 christos relative and must be in the range -256..255 (9-bits). */ 3701 1.1 christos if ((opcode->format & M6812_XBCC_MARKER) 3702 1.1 christos && (opcode->format & M6811_OP_JUMP_REL)) 3703 1.1 christos build_dbranch_insn (opcode, operands, nb_operands, branch_optimize); 3704 1.1 christos 3705 1.1 christos /* Relative jumps instructions are taken care of separately. We have to make 3706 1.1 christos sure that the relative branch is within the range -128..127. If it's out 3707 1.1 christos of range, the instructions are changed into absolute instructions. 3708 1.1 christos This is not supported for the brset and brclr instructions. */ 3709 1.1 christos else if ((opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16)) 3710 1.1 christos && !(opcode->format & M6811_OP_BITMASK)) 3711 1.1 christos build_jump_insn (opcode, operands, nb_operands, branch_optimize); 3712 1.1 christos else 3713 1.1 christos build_insn (opcode, operands, nb_operands); 3714 1.1 christos } 3715 1.10 christos 3716 1.1 christos 3717 1.1 christos /* Pseudo op to control the ELF flags. */ 3719 1.1 christos static void 3720 1.1 christos s_m68hc11_mode (int x ATTRIBUTE_UNUSED) 3721 1.1 christos { 3722 1.1 christos char *name = input_line_pointer, ch; 3723 1.1 christos 3724 1.1 christos while (!is_end_of_stmt (*input_line_pointer)) 3725 1.1 christos input_line_pointer++; 3726 1.1 christos ch = *input_line_pointer; 3727 1.1 christos *input_line_pointer = '\0'; 3728 1.1 christos 3729 1.1 christos if (strcmp (name, "mshort") == 0) 3730 1.1 christos { 3731 1.1 christos elf_flags &= ~E_M68HC11_I32; 3732 1.1 christos } 3733 1.1 christos else if (strcmp (name, "mlong") == 0) 3734 1.1 christos { 3735 1.1 christos elf_flags |= E_M68HC11_I32; 3736 1.1 christos } 3737 1.1 christos else if (strcmp (name, "mshort-double") == 0) 3738 1.1 christos { 3739 1.1 christos elf_flags &= ~E_M68HC11_F64; 3740 1.1 christos } 3741 1.1 christos else if (strcmp (name, "mlong-double") == 0) 3742 1.1 christos { 3743 1.1 christos elf_flags |= E_M68HC11_F64; 3744 1.1 christos } 3745 1.1 christos else 3746 1.1 christos { 3747 1.1 christos as_warn (_("Invalid mode: %s\n"), name); 3748 1.1 christos } 3749 1.1 christos *input_line_pointer = ch; 3750 1.1 christos demand_empty_rest_of_line (); 3751 1.1 christos } 3752 1.1 christos 3753 1.1 christos /* Mark the symbols with STO_M68HC12_FAR to indicate the functions 3754 1.1 christos are using 'rtc' for returning. It is necessary to use 'call' 3755 1.1 christos to invoke them. This is also used by the debugger to correctly 3756 1.1 christos find the stack frame. */ 3757 1.1 christos static void 3758 1.1 christos s_m68hc11_mark_symbol (int mark) 3759 1.3 christos { 3760 1.1 christos char *name; 3761 1.3 christos int c; 3762 1.1 christos symbolS *symbolP; 3763 1.1 christos asymbol *bfdsym; 3764 1.1 christos elf_symbol_type *elfsym; 3765 1.1 christos 3766 1.8 christos do 3767 1.1 christos { 3768 1.1 christos c = get_symbol_name (&name); 3769 1.1 christos symbolP = symbol_find_or_make (name); 3770 1.1 christos (void) restore_line_pointer (c); 3771 1.1 christos 3772 1.1 christos SKIP_WHITESPACE (); 3773 1.1 christos 3774 1.1 christos bfdsym = symbol_get_bfdsym (symbolP); 3775 1.1 christos elfsym = elf_symbol_from (bfdsym); 3776 1.1 christos 3777 1.1 christos gas_assert (elfsym); 3778 1.1 christos 3779 1.1 christos /* Mark the symbol far (using rtc for function return). */ 3780 1.1 christos elfsym->internal_elf_sym.st_other |= mark; 3781 1.1 christos 3782 1.1 christos if (c == ',') 3783 1.1 christos { 3784 1.1 christos input_line_pointer ++; 3785 1.1 christos 3786 1.1 christos SKIP_WHITESPACE (); 3787 1.1 christos 3788 1.1 christos if (*input_line_pointer == '\n') 3789 1.1 christos c = '\n'; 3790 1.1 christos } 3791 1.1 christos } 3792 1.1 christos while (c == ','); 3793 1.1 christos 3794 1.1 christos demand_empty_rest_of_line (); 3795 1.1 christos } 3796 1.1 christos 3797 1.1 christos static void 3798 1.1 christos s_m68hc11_relax (int ignore ATTRIBUTE_UNUSED) 3799 1.1 christos { 3800 1.1 christos expressionS ex; 3801 1.1 christos 3802 1.1 christos expression (&ex); 3803 1.1 christos 3804 1.1 christos if (ex.X_op != O_symbol || ex.X_add_number != 0) 3805 1.1 christos { 3806 1.1 christos as_bad (_("bad .relax format")); 3807 1.1 christos ignore_rest_of_line (); 3808 1.1 christos return; 3809 1.1 christos } 3810 1.1 christos 3811 1.1 christos fix_new_exp (frag_now, frag_now_fix (), 0, &ex, 1, 3812 1.1 christos BFD_RELOC_M68HC11_RL_GROUP); 3813 1.1 christos 3814 1.1 christos demand_empty_rest_of_line (); 3815 1.1 christos } 3816 1.1 christos 3817 1.1 christos 3818 1.1 christos /* Relocation, relaxation and frag conversions. */ 3820 1.1 christos 3821 1.1 christos /* PC-relative offsets are relative to the start of the 3822 1.1 christos next instruction. That is, the address of the offset, plus its 3823 1.1 christos size, since the offset is always the last part of the insn. */ 3824 1.1 christos long 3825 1.1 christos md_pcrel_from (fixS *fixP) 3826 1.1 christos { 3827 1.1 christos if (fixP->fx_r_type == BFD_RELOC_M68HC11_RL_JUMP) 3828 1.1 christos return 0; 3829 1.1 christos 3830 1.10 christos return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address; 3831 1.10 christos } 3832 1.1 christos 3833 1.1 christos /* If while processing a fixup, a reloc really needs to be created 3834 1.1 christos then it is done here. */ 3835 1.1 christos arelent * 3836 1.1 christos tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) 3837 1.1 christos { 3838 1.10 christos arelent *reloc; 3839 1.1 christos 3840 1.1 christos reloc = notes_alloc (sizeof (arelent)); 3841 1.1 christos reloc->sym_ptr_ptr = notes_alloc (sizeof (asymbol *)); 3842 1.1 christos *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); 3843 1.1 christos reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; 3844 1.1 christos if (fixp->fx_r_type == 0) 3845 1.1 christos reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16); 3846 1.1 christos else 3847 1.1 christos reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); 3848 1.1 christos if (reloc->howto == NULL) 3849 1.1 christos { 3850 1.1 christos as_bad_where (fixp->fx_file, fixp->fx_line, 3851 1.1 christos _("Relocation %d is not supported by object file format."), 3852 1.1 christos (int) fixp->fx_r_type); 3853 1.1 christos return NULL; 3854 1.1 christos } 3855 1.1 christos 3856 1.1 christos /* Since we use Rel instead of Rela, encode the vtable entry to be 3857 1.1 christos used in the relocation's section offset. */ 3858 1.1 christos if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY) 3859 1.1 christos reloc->address = fixp->fx_offset; 3860 1.1 christos 3861 1.1 christos reloc->addend = 0; 3862 1.1 christos return reloc; 3863 1.1 christos } 3864 1.1 christos 3865 1.1 christos /* We need a port-specific relaxation function to cope with sym2 - sym1 3866 1.1 christos relative expressions with both symbols in the same segment (but not 3867 1.1 christos necessarily in the same frag as this insn), for example: 3868 1.1 christos ldab sym2-(sym1-2),pc 3869 1.1 christos sym1: 3870 1.1 christos The offset can be 5, 9 or 16 bits long. */ 3871 1.1 christos 3872 1.1 christos long 3873 1.1 christos m68hc11_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS *fragP, 3874 1.1 christos long stretch ATTRIBUTE_UNUSED) 3875 1.1 christos { 3876 1.6 christos long growth; 3877 1.1 christos offsetT aim = 0; 3878 1.1 christos symbolS *symbolP; 3879 1.1 christos const relax_typeS *this_type; 3880 1.1 christos const relax_typeS *start_type; 3881 1.1 christos relax_substateT next_state; 3882 1.1 christos relax_substateT this_state; 3883 1.1 christos const relax_typeS *table = TC_GENERIC_RELAX_TABLE; 3884 1.1 christos 3885 1.1 christos /* We only have to cope with frags as prepared by 3886 1.1 christos md_estimate_size_before_relax. The STATE_BITS16 case may get here 3887 1.1 christos because of the different reasons that it's not relaxable. */ 3888 1.1 christos switch (fragP->fr_subtype) 3889 1.1 christos { 3890 1.1 christos case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16): 3891 1.1 christos case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16): 3892 1.9 christos /* When we get to this state, the frag won't grow any more. */ 3893 1.1 christos return 0; 3894 1.1 christos 3895 1.1 christos case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS5): 3896 1.9 christos case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5): 3897 1.1 christos case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9): 3898 1.1 christos case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9): 3899 1.1 christos if (fragP->fr_symbol == NULL 3900 1.1 christos || S_GET_SEGMENT (fragP->fr_symbol) != absolute_section) 3901 1.1 christos as_fatal (_("internal inconsistency problem in %s: fr_symbol %lx"), 3902 1.9 christos __func__, (long) fragP->fr_symbol); 3903 1.1 christos symbolP = fragP->fr_symbol; 3904 1.1 christos if (symbol_resolved_p (symbolP)) 3905 1.1 christos as_fatal (_("internal inconsistency problem in %s: resolved symbol"), 3906 1.1 christos __func__); 3907 1.1 christos aim = S_GET_VALUE (symbolP); 3908 1.1 christos break; 3909 1.1 christos 3910 1.1 christos default: 3911 1.1 christos as_fatal (_("internal inconsistency problem in %s: fr_subtype %d"), 3912 1.1 christos __func__, fragP->fr_subtype); 3913 1.1 christos } 3914 1.1 christos 3915 1.1 christos /* The rest is stolen from relax_frag. There's no obvious way to 3916 1.1 christos share the code, but fortunately no requirement to keep in sync as 3917 1.1 christos long as fragP->fr_symbol does not have its segment changed. */ 3918 1.1 christos 3919 1.1 christos this_state = fragP->fr_subtype; 3920 1.1 christos start_type = this_type = table + this_state; 3921 1.1 christos 3922 1.1 christos if (aim < 0) 3923 1.1 christos { 3924 1.1 christos /* Look backwards. */ 3925 1.1 christos for (next_state = this_type->rlx_more; next_state;) 3926 1.1 christos if (aim >= this_type->rlx_backward) 3927 1.1 christos next_state = 0; 3928 1.1 christos else 3929 1.1 christos { 3930 1.1 christos /* Grow to next state. */ 3931 1.1 christos this_state = next_state; 3932 1.1 christos this_type = table + this_state; 3933 1.1 christos next_state = this_type->rlx_more; 3934 1.1 christos } 3935 1.1 christos } 3936 1.1 christos else 3937 1.1 christos { 3938 1.1 christos /* Look forwards. */ 3939 1.1 christos for (next_state = this_type->rlx_more; next_state;) 3940 1.1 christos if (aim <= this_type->rlx_forward) 3941 1.1 christos next_state = 0; 3942 1.1 christos else 3943 1.1 christos { 3944 1.1 christos /* Grow to next state. */ 3945 1.1 christos this_state = next_state; 3946 1.1 christos this_type = table + this_state; 3947 1.1 christos next_state = this_type->rlx_more; 3948 1.1 christos } 3949 1.1 christos } 3950 1.1 christos 3951 1.1 christos growth = this_type->rlx_length - start_type->rlx_length; 3952 1.1 christos if (growth != 0) 3953 1.1 christos fragP->fr_subtype = this_state; 3954 1.1 christos return growth; 3955 1.1 christos } 3956 1.3 christos 3957 1.1 christos void 3958 1.1 christos md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec ATTRIBUTE_UNUSED, 3959 1.1 christos fragS *fragP) 3960 1.1 christos { 3961 1.1 christos long value; 3962 1.1 christos long disp; 3963 1.1 christos char *buffer_address = fragP->fr_literal; 3964 1.1 christos 3965 1.1 christos /* Address in object code of the displacement. */ 3966 1.1 christos int object_address = fragP->fr_fix + fragP->fr_address; 3967 1.1 christos 3968 1.1 christos buffer_address += fragP->fr_fix; 3969 1.1 christos 3970 1.1 christos /* The displacement of the address, from current location. */ 3971 1.1 christos value = S_GET_VALUE (fragP->fr_symbol); 3972 1.1 christos disp = (value + fragP->fr_offset) - object_address; 3973 1.1 christos 3974 1.1 christos switch (fragP->fr_subtype) 3975 1.1 christos { 3976 1.1 christos case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE): 3977 1.1 christos fragP->fr_opcode[1] = disp; 3978 1.1 christos break; 3979 1.1 christos 3980 1.1 christos case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD): 3981 1.1 christos /* This relax is only for bsr and bra. */ 3982 1.1 christos gas_assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR) 3983 1.1 christos || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA) 3984 1.1 christos || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR)); 3985 1.1 christos 3986 1.1 christos fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]); 3987 1.1 christos 3988 1.1 christos fix_new (fragP, fragP->fr_fix - 1, 2, 3989 1.1 christos fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16); 3990 1.1 christos fragP->fr_fix += 1; 3991 1.1 christos break; 3992 1.1 christos 3993 1.1 christos case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE): 3994 1.1 christos case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_BYTE): 3995 1.1 christos fragP->fr_opcode[1] = disp; 3996 1.1 christos break; 3997 1.1 christos 3998 1.1 christos case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD): 3999 1.1 christos /* Invert branch. */ 4000 1.1 christos fragP->fr_opcode[0] ^= 1; 4001 1.1 christos fragP->fr_opcode[1] = 3; /* Branch offset. */ 4002 1.1 christos buffer_address[0] = M6811_JMP; 4003 1.3 christos fix_new (fragP, fragP->fr_fix + 1, 2, 4004 1.3 christos fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16); 4005 1.1 christos fragP->fr_fix += 3; 4006 1.1 christos break; 4007 1.1 christos 4008 1.1 christos case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_WORD): 4009 1.1 christos /* Translate branch into a long branch. */ 4010 1.1 christos fragP->fr_opcode[1] = fragP->fr_opcode[0]; 4011 1.1 christos fragP->fr_opcode[0] = M6811_OPCODE_PAGE2; 4012 1.1 christos 4013 1.1 christos fix_new (fragP, fragP->fr_fix, 2, 4014 1.1 christos fragP->fr_symbol, fragP->fr_offset, 1, 4015 1.1 christos BFD_RELOC_16_PCREL); 4016 1.1 christos fragP->fr_fix += 2; 4017 1.1 christos break; 4018 1.1 christos 4019 1.1 christos case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS5): 4020 1.1 christos if (fragP->fr_symbol != 0 4021 1.1 christos && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section) 4022 1.1 christos value = disp; 4023 1.1 christos /* fall through */ 4024 1.1 christos 4025 1.1 christos case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5): 4026 1.1 christos fragP->fr_opcode[0] = fragP->fr_opcode[0] << 6; 4027 1.1 christos fragP->fr_opcode[0] |= value & 0x1f; 4028 1.1 christos break; 4029 1.1 christos 4030 1.1 christos case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9): 4031 1.1 christos /* For a PC-relative offset, use the displacement with a -1 correction 4032 1.1 christos to take into account the additional byte of the insn. */ 4033 1.1 christos if (fragP->fr_symbol != 0 4034 1.1 christos && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section) 4035 1.1 christos value = disp - 1; 4036 1.1 christos /* fall through */ 4037 1.1 christos 4038 1.1 christos case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9): 4039 1.1 christos fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3); 4040 1.1 christos fragP->fr_opcode[0] |= 0xE0; 4041 1.1 christos fragP->fr_opcode[0] |= (value >> 8) & 1; 4042 1.1 christos fragP->fr_opcode[1] = value; 4043 1.1 christos fragP->fr_fix += 1; 4044 1.3 christos break; 4045 1.3 christos 4046 1.3 christos case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16): 4047 1.1 christos case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16): 4048 1.1 christos fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3); 4049 1.1 christos fragP->fr_opcode[0] |= 0xe2; 4050 1.1 christos if ((fragP->fr_opcode[0] & 0x0ff) == 0x0fa 4051 1.1 christos && fragP->fr_symbol != 0 4052 1.1 christos && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section) 4053 1.1 christos { 4054 1.1 christos fix_new (fragP, fragP->fr_fix, 2, 4055 1.1 christos fragP->fr_symbol, fragP->fr_offset, 4056 1.1 christos 1, BFD_RELOC_16_PCREL); 4057 1.1 christos } 4058 1.1 christos else 4059 1.1 christos { 4060 1.1 christos fix_new (fragP, fragP->fr_fix, 2, 4061 1.1 christos fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16); 4062 1.1 christos } 4063 1.1 christos fragP->fr_fix += 2; 4064 1.1 christos break; 4065 1.1 christos 4066 1.1 christos case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE): 4067 1.1 christos if (disp < 0) 4068 1.1 christos fragP->fr_opcode[0] |= 0x10; 4069 1.1 christos 4070 1.1 christos fragP->fr_opcode[1] = disp & 0x0FF; 4071 1.1 christos break; 4072 1.1 christos 4073 1.1 christos case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_WORD): 4074 1.1 christos /* Invert branch. */ 4075 1.1 christos fragP->fr_opcode[0] ^= 0x20; 4076 1.1 christos fragP->fr_opcode[1] = 3; /* Branch offset. */ 4077 1.1 christos buffer_address[0] = M6812_JMP; 4078 1.1 christos fix_new (fragP, fragP->fr_fix + 1, 2, 4079 1.1 christos fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16); 4080 1.1 christos fragP->fr_fix += 3; 4081 1.1 christos break; 4082 1.1 christos 4083 1.1 christos default: 4084 1.1 christos break; 4085 1.1 christos } 4086 1.1 christos } 4087 1.1 christos 4088 1.1 christos /* On an ELF system, we can't relax a weak symbol. The weak symbol 4089 1.1 christos can be overridden at final link time by a non weak symbol. We can 4090 1.1 christos relax externally visible symbol because there is no shared library 4091 1.1 christos and such symbol can't be overridden (unless they are weak). */ 4092 1.1 christos static int 4093 1.1 christos relaxable_symbol (symbolS *symbol) 4094 1.1 christos { 4095 1.1 christos return ! S_IS_WEAK (symbol); 4096 1.1 christos } 4097 1.1 christos 4098 1.1 christos /* Force truly undefined symbols to their maximum size, and generally set up 4099 1.1 christos the frag list to be relaxed. */ 4100 1.1 christos int 4101 1.1 christos md_estimate_size_before_relax (fragS *fragP, asection *segment) 4102 1.1 christos { 4103 1.1 christos if (RELAX_LENGTH (fragP->fr_subtype) == STATE_UNDF) 4104 1.1 christos { 4105 1.1 christos if (S_GET_SEGMENT (fragP->fr_symbol) != segment 4106 1.1 christos || !relaxable_symbol (fragP->fr_symbol) 4107 1.1 christos || (segment != absolute_section 4108 1.1 christos && RELAX_STATE (fragP->fr_subtype) == STATE_INDEXED_OFFSET)) 4109 1.1 christos { 4110 1.1 christos /* Non-relaxable cases. */ 4111 1.1 christos int old_fr_fix; 4112 1.1 christos char *buffer_address; 4113 1.1 christos 4114 1.1 christos old_fr_fix = fragP->fr_fix; 4115 1.1 christos buffer_address = fragP->fr_fix + fragP->fr_literal; 4116 1.1 christos 4117 1.1 christos switch (RELAX_STATE (fragP->fr_subtype)) 4118 1.1 christos { 4119 1.1 christos case STATE_PC_RELATIVE: 4120 1.1 christos 4121 1.1 christos /* This relax is only for bsr and bra. */ 4122 1.1 christos gas_assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR) 4123 1.1 christos || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA) 4124 1.1 christos || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR)); 4125 1.1 christos 4126 1.1 christos if (flag_fixed_branches) 4127 1.1 christos as_bad_where (fragP->fr_file, fragP->fr_line, 4128 1.1 christos _("bra or bsr with undefined symbol.")); 4129 1.1 christos 4130 1.1 christos /* The symbol is undefined or in a separate section. 4131 1.1 christos Turn bra into a jmp and bsr into a jsr. The insn 4132 1.1 christos becomes 3 bytes long (instead of 2). A fixup is 4133 1.1 christos necessary for the unresolved symbol address. */ 4134 1.1 christos fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]); 4135 1.1 christos 4136 1.1 christos fix_new (fragP, fragP->fr_fix - 1, 2, fragP->fr_symbol, 4137 1.1 christos fragP->fr_offset, 0, BFD_RELOC_16); 4138 1.1 christos fragP->fr_fix++; 4139 1.1 christos break; 4140 1.1 christos 4141 1.1 christos case STATE_CONDITIONAL_BRANCH: 4142 1.1 christos gas_assert (current_architecture & cpu6811); 4143 1.1 christos 4144 1.1 christos fragP->fr_opcode[0] ^= 1; /* Reverse sense of branch. */ 4145 1.1 christos fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */ 4146 1.1 christos 4147 1.1 christos /* Don't use fr_opcode[2] because this may be 4148 1.1 christos in a different frag. */ 4149 1.1 christos buffer_address[0] = M6811_JMP; 4150 1.1 christos 4151 1.1 christos fragP->fr_fix++; 4152 1.1 christos fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, 4153 1.1 christos fragP->fr_offset, 0, BFD_RELOC_16); 4154 1.1 christos fragP->fr_fix += 2; 4155 1.1 christos break; 4156 1.1 christos 4157 1.1 christos case STATE_INDEXED_OFFSET: 4158 1.1 christos gas_assert (current_architecture & cpu6812); 4159 1.1 christos 4160 1.1 christos if (fragP->fr_symbol 4161 1.1 christos && S_GET_SEGMENT (fragP->fr_symbol) == absolute_section) 4162 1.1 christos { 4163 1.1 christos fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_OFFSET, 4164 1.1 christos STATE_BITS5); 4165 1.1 christos /* Return the size of the variable part of the frag. */ 4166 1.1 christos return md_relax_table[fragP->fr_subtype].rlx_length; 4167 1.1 christos } 4168 1.1 christos else 4169 1.1 christos { 4170 1.1 christos /* Switch the indexed operation to 16-bit mode. */ 4171 1.1 christos fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3; 4172 1.1 christos fragP->fr_opcode[0] |= 0xe2; 4173 1.1 christos fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, 4174 1.1 christos fragP->fr_offset, 0, BFD_RELOC_16); 4175 1.1 christos fragP->fr_fix += 2; 4176 1.1 christos } 4177 1.1 christos break; 4178 1.1 christos 4179 1.1 christos case STATE_INDEXED_PCREL: 4180 1.1 christos gas_assert (current_architecture & cpu6812); 4181 1.1 christos 4182 1.1 christos if (fragP->fr_symbol 4183 1.1 christos && S_GET_SEGMENT (fragP->fr_symbol) == absolute_section) 4184 1.1 christos { 4185 1.1 christos fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_PCREL, 4186 1.1 christos STATE_BITS5); 4187 1.1 christos /* Return the size of the variable part of the frag. */ 4188 1.1 christos return md_relax_table[fragP->fr_subtype].rlx_length; 4189 1.1 christos } 4190 1.1 christos else 4191 1.1 christos { 4192 1.1 christos fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3; 4193 1.1 christos fragP->fr_opcode[0] |= 0xe2; 4194 1.1 christos fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, 4195 1.1 christos fragP->fr_offset, 1, BFD_RELOC_16_PCREL); 4196 1.1 christos fragP->fr_fix += 2; 4197 1.1 christos } 4198 1.1 christos break; 4199 1.1 christos 4200 1.1 christos case STATE_XBCC_BRANCH: 4201 1.1 christos gas_assert (current_architecture & cpu6812); 4202 1.1 christos 4203 1.1 christos fragP->fr_opcode[0] ^= 0x20; /* Reverse sense of branch. */ 4204 1.1 christos fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */ 4205 1.1 christos 4206 1.1 christos /* Don't use fr_opcode[2] because this may be 4207 1.1 christos in a different frag. */ 4208 1.1 christos buffer_address[0] = M6812_JMP; 4209 1.1 christos 4210 1.1 christos fragP->fr_fix++; 4211 1.1 christos fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, 4212 1.1 christos fragP->fr_offset, 0, BFD_RELOC_16); 4213 1.1 christos fragP->fr_fix += 2; 4214 1.1 christos break; 4215 1.1 christos 4216 1.1 christos case STATE_CONDITIONAL_BRANCH_6812: 4217 1.1 christos gas_assert (current_architecture & cpu6812); 4218 1.1 christos 4219 1.1 christos /* Translate into a lbcc branch. */ 4220 1.1 christos fragP->fr_opcode[1] = fragP->fr_opcode[0]; 4221 1.1 christos fragP->fr_opcode[0] = M6811_OPCODE_PAGE2; 4222 1.1 christos 4223 1.1 christos fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, 4224 1.1 christos fragP->fr_offset, 1, BFD_RELOC_16_PCREL); 4225 1.1 christos fragP->fr_fix += 2; 4226 1.1 christos break; 4227 1.1 christos 4228 1.1 christos default: 4229 1.1 christos as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype); 4230 1.1 christos } 4231 1.1 christos frag_wane (fragP); 4232 1.1 christos 4233 1.1 christos /* Return the growth in the fixed part of the frag. */ 4234 1.1 christos return fragP->fr_fix - old_fr_fix; 4235 1.1 christos } 4236 1.1 christos 4237 1.1 christos /* Relaxable cases. */ 4238 1.1 christos switch (RELAX_STATE (fragP->fr_subtype)) 4239 1.1 christos { 4240 1.1 christos case STATE_PC_RELATIVE: 4241 1.1 christos /* This relax is only for bsr and bra. */ 4242 1.1 christos gas_assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR) 4243 1.1 christos || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA) 4244 1.1 christos || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR)); 4245 1.1 christos 4246 1.1 christos fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE); 4247 1.1 christos break; 4248 1.1 christos 4249 1.1 christos case STATE_CONDITIONAL_BRANCH: 4250 1.1 christos gas_assert (current_architecture & cpu6811); 4251 1.1 christos 4252 1.1 christos fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, 4253 1.1 christos STATE_BYTE); 4254 1.1 christos break; 4255 1.1 christos 4256 1.1 christos case STATE_INDEXED_OFFSET: 4257 1.1 christos gas_assert (current_architecture & cpu6812); 4258 1.1 christos 4259 1.1 christos fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_OFFSET, 4260 1.1 christos STATE_BITS5); 4261 1.1 christos break; 4262 1.1 christos 4263 1.1 christos case STATE_INDEXED_PCREL: 4264 1.1 christos gas_assert (current_architecture & cpu6812); 4265 1.1 christos 4266 1.1 christos fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_PCREL, 4267 1.1 christos STATE_BITS5); 4268 1.1 christos break; 4269 1.1 christos 4270 1.1 christos case STATE_XBCC_BRANCH: 4271 1.1 christos gas_assert (current_architecture & cpu6812); 4272 1.1 christos 4273 1.1 christos fragP->fr_subtype = ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE); 4274 1.1 christos break; 4275 1.1 christos 4276 1.1 christos case STATE_CONDITIONAL_BRANCH_6812: 4277 1.1 christos gas_assert (current_architecture & cpu6812); 4278 1.1 christos 4279 1.1 christos fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, 4280 1.1 christos STATE_BYTE); 4281 1.1 christos break; 4282 1.1 christos } 4283 1.1 christos } 4284 1.1 christos 4285 1.1 christos if (fragP->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0])) 4286 1.1 christos as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype); 4287 1.1 christos 4288 1.1 christos /* Return the size of the variable part of the frag. */ 4289 1.1 christos return md_relax_table[fragP->fr_subtype].rlx_length; 4290 1.1 christos } 4291 1.1 christos 4292 1.1 christos /* See whether we need to force a relocation into the output file. */ 4293 1.1 christos int 4294 1.1 christos tc_m68hc11_force_relocation (fixS *fixP) 4295 1.1 christos { 4296 1.1 christos if (fixP->fx_r_type == BFD_RELOC_M68HC11_RL_GROUP) 4297 1.1 christos return 1; 4298 1.1 christos 4299 1.1 christos return generic_force_reloc (fixP); 4300 1.1 christos } 4301 1.1 christos 4302 1.1 christos /* Here we decide which fixups can be adjusted to make them relative 4303 1.1 christos to the beginning of the section instead of the symbol. Basically 4304 1.1 christos we need to make sure that the linker relaxation is done 4305 1.1 christos correctly, so in some cases we force the original symbol to be 4306 1.1 christos used. */ 4307 1.1 christos int 4308 1.1 christos tc_m68hc11_fix_adjustable (fixS *fixP) 4309 1.1 christos { 4310 1.1 christos switch (fixP->fx_r_type) 4311 1.1 christos { 4312 1.1 christos /* For the linker relaxation to work correctly, these relocs 4313 1.1 christos need to be on the symbol itself. */ 4314 1.1 christos case BFD_RELOC_16: 4315 1.1 christos case BFD_RELOC_M68HC11_RL_JUMP: 4316 1.1 christos case BFD_RELOC_M68HC11_RL_GROUP: 4317 1.1 christos case BFD_RELOC_VTABLE_INHERIT: 4318 1.1 christos case BFD_RELOC_VTABLE_ENTRY: 4319 1.1 christos case BFD_RELOC_32: 4320 1.1 christos 4321 1.1 christos /* The memory bank addressing translation also needs the original 4322 1.1 christos symbol. */ 4323 1.1 christos case BFD_RELOC_M68HC11_LO16: 4324 1.1 christos case BFD_RELOC_M68HC11_PAGE: 4325 1.1 christos case BFD_RELOC_M68HC11_24: 4326 1.1 christos return 0; 4327 1.1 christos 4328 1.1 christos default: 4329 1.10 christos return 1; 4330 1.1 christos } 4331 1.1 christos } 4332 1.1 christos 4333 1.10 christos void 4334 1.8 christos md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) 4335 1.1 christos { 4336 1.1 christos char *where; 4337 1.1 christos long value = * valP; 4338 1.1 christos 4339 1.1 christos if (fixP->fx_addsy == NULL) 4340 1.1 christos fixP->fx_done = 1; 4341 1.1 christos 4342 1.1 christos /* We don't actually support subtracting a symbol. */ 4343 1.1 christos if (fixP->fx_subsy != NULL) 4344 1.1 christos as_bad_subtract (fixP); 4345 1.1 christos 4346 1.1 christos /* Patch the instruction with the resolved operand. Elf relocation 4347 1.1 christos info will also be generated to take care of linker/loader fixups. 4348 1.1 christos The 68HC11 addresses only 64Kb, we are only concerned by 8 and 16-bit 4349 1.1 christos relocs. BFD_RELOC_8 is basically used for .page0 access (the linker 4350 1.10 christos will warn for overflows). BFD_RELOC_8_PCREL should not be generated 4351 1.1 christos because it's either resolved or turned out into non-relative insns (see 4352 1.1 christos relax table, bcc, bra, bsr transformations) 4353 1.1 christos 4354 1.1 christos The BFD_RELOC_32 is necessary for the support of --gstabs. */ 4355 1.10 christos where = fixP->fx_frag->fr_literal + fixP->fx_where; 4356 1.10 christos 4357 1.1 christos switch (fixP->fx_r_type) 4358 1.1 christos { 4359 1.1 christos case BFD_RELOC_32: 4360 1.1 christos bfd_putb32 (value, where); 4361 1.1 christos break; 4362 1.10 christos 4363 1.1 christos case BFD_RELOC_24: 4364 1.1 christos case BFD_RELOC_M68HC11_24: 4365 1.1 christos bfd_putb16 (value & 0x0ffff, where); 4366 1.1 christos where[2] = (value >> 16) & 0xff; 4367 1.1 christos break; 4368 1.1 christos 4369 1.1 christos case BFD_RELOC_16: 4370 1.1 christos case BFD_RELOC_16_PCREL: 4371 1.1 christos case BFD_RELOC_M68HC11_LO16: 4372 1.1 christos bfd_putb16 (value, where); 4373 1.1 christos if (value < -65537 || value > 65535) 4374 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line, 4375 1.1 christos _("Value out of 16-bit range.")); 4376 1.1 christos break; 4377 1.1 christos 4378 1.1 christos case BFD_RELOC_M68HC11_HI8: 4379 1.10 christos /* Caution, %hi(<symbol>+%ld) will generate incorrect code if %lo 4380 1.1 christos causes a carry. */ 4381 1.1 christos case BFD_RELOC_M68HC12_HI8XG: 4382 1.1 christos value = value >> 8; 4383 1.10 christos /* Fall through. */ 4384 1.1 christos 4385 1.1 christos case BFD_RELOC_M68HC12_LO8XG: 4386 1.1 christos case BFD_RELOC_M68HC11_LO8: 4387 1.1 christos case BFD_RELOC_8: 4388 1.1 christos case BFD_RELOC_M68HC11_PAGE: 4389 1.1 christos where[0] = value & 0xff; 4390 1.1 christos break; 4391 1.1 christos 4392 1.1 christos case BFD_RELOC_8_PCREL: 4393 1.10 christos where[0] = value & 0xff; 4394 1.10 christos 4395 1.1 christos if (value < -128 || value > 127) 4396 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line, 4397 1.1 christos _("Value %ld too large for 8-bit PC-relative branch."), 4398 1.1 christos value); 4399 1.1 christos break; 4400 1.1 christos 4401 1.1 christos /* These next two are for XGATE. */ 4402 1.10 christos case BFD_RELOC_M68HC12_9_PCREL: 4403 1.10 christos where[0] |= (value >> 9) & 0x01; 4404 1.1 christos where[1] = (value >> 1) & 0xff; 4405 1.1 christos if (value < -512 || value > 511) 4406 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line, 4407 1.1 christos _("Value %ld too large for 9-bit PC-relative branch."), 4408 1.1 christos value); 4409 1.1 christos break; 4410 1.1 christos 4411 1.1 christos case BFD_RELOC_M68HC12_10_PCREL: 4412 1.1 christos where[0] |= (value >> 9) & 0x03; 4413 1.1 christos where[1] = (value>> 1) & 0xff; 4414 1.1 christos if (value < -1024 || value > 1023) 4415 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line, 4416 1.1 christos _("Value %ld too large for 10-bit PC-relative branch."), 4417 1.1 christos value); 4418 1.1 christos 4419 1.1 christos break; 4420 1.1 christos 4421 1.1 christos case BFD_RELOC_M68HC11_3B: 4422 1.1 christos if (value <= 0 || value > 8) 4423 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line, 4424 1.1 christos _("Auto increment/decrement offset '%ld' is out of range."), 4425 1.1 christos value); 4426 1.1 christos if (where[0] & 0x8) 4427 1.1 christos value = 8 - value; 4428 1.1 christos else 4429 1.1 christos value--; 4430 1.1 christos 4431 1.3 christos where[0] = where[0] | (value & 0x07); 4432 1.1 christos break; 4433 1.1 christos 4434 1.1 christos case BFD_RELOC_M68HC12_5B: 4435 1.1 christos if (value < -16 || value > 15) 4436 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line, 4437 1.1 christos _("Offset out of 5-bit range for movw/movb insn: %ld"), 4438 1.1 christos value); 4439 1.1 christos if (value >= 0) 4440 1.1 christos where[0] |= value; 4441 1.1 christos else 4442 1.1 christos where[0] |= (0x10 | (16 + value)); 4443 1.3 christos break; 4444 1.1 christos 4445 1.1 christos case BFD_RELOC_M68HC12_9B: 4446 1.1 christos if (value < -256 || value > 255) 4447 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line, 4448 1.1 christos _("Offset out of 9-bit range for movw/movb insn: %ld"), 4449 1.1 christos value); 4450 1.1 christos /* sign bit already in xb postbyte */ 4451 1.1 christos if (value >= 0) 4452 1.1 christos where[1] = value; 4453 1.1 christos else 4454 1.1 christos where[1] = (256 + value); 4455 1.1 christos break; 4456 1.1 christos 4457 1.1 christos case BFD_RELOC_M68HC12_16B: 4458 1.1 christos if (value < -32768 || value > 32767) 4459 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line, 4460 1.1 christos _("Offset out of 16-bit range for movw/movb insn: %ld"), 4461 1.1 christos value); 4462 1.1 christos if (value < 0) 4463 1.1 christos value += 65536; 4464 1.1 christos 4465 1.1 christos where[0] = (value >> 8); 4466 1.1 christos where[1] = (value & 0xff); 4467 1.1 christos break; 4468 1.1 christos 4469 1.1 christos case BFD_RELOC_M68HC11_RL_JUMP: 4470 1.1 christos case BFD_RELOC_M68HC11_RL_GROUP: 4471 1.1 christos case BFD_RELOC_VTABLE_INHERIT: 4472 1.1 christos case BFD_RELOC_VTABLE_ENTRY: 4473 1.1 christos fixP->fx_done = 0; 4474 1.1 christos return; 4475 1.1 christos 4476 1.1 christos default: 4477 1.1 christos as_fatal (_("Line %d: unknown relocation type: 0x%x."), 4478 1.1 christos fixP->fx_line, fixP->fx_r_type); 4479 1.1 christos } 4480 1.1 christos } 4481 1.1 christos 4482 1.1 christos /* Set the ELF specific flags. */ 4483 1.1 christos void 4484 1.1 christos m68hc11_elf_final_processing (void) 4485 1.1 christos { 4486 1.1 christos if (current_architecture & cpu6812s) 4487 1.1 christos elf_flags |= EF_M68HCS12_MACH; 4488 1.1 christos elf_elfheader (stdoutput)->e_flags &= ~EF_M68HC11_ABI; 4489 1.1 christos elf_elfheader (stdoutput)->e_flags |= elf_flags; 4490 1.1 christos } 4491 1.1 christos 4492 1.1 christos /* Process directives specified via pseudo ops */ 4493 1.1 christos static void 4494 1.1 christos s_m68hc11_parse_pseudo_instruction (int pseudo_insn) 4495 { 4496 switch (pseudo_insn) 4497 { 4498 case E_M68HC11_NO_BANK_WARNING: 4499 elf_flags |= E_M68HC11_NO_BANK_WARNING; 4500 break; 4501 default: 4502 as_bad (_("Invalid directive")); 4503 } 4504 } 4505