1 1.1 christos /* tc-msp430.c -- Assembler code for the Texas Instruments MSP430 2 1.1 christos 3 1.10 christos Copyright (C) 2002-2025 Free Software Foundation, Inc. 4 1.1 christos Contributed by Dmitry Diky <diwil (at) mail.ru> 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 <limits.h> 25 1.1 christos #include "subsegs.h" 26 1.1 christos #include "opcode/msp430.h" 27 1.1 christos #include "safe-ctype.h" 28 1.1 christos #include "dwarf2dbg.h" 29 1.3 christos #include "elf/msp430.h" 30 1.3 christos #include "libiberty.h" 31 1.1 christos 32 1.1 christos /* We will disable polymorphs by default because it is dangerous. 33 1.1 christos The potential problem here is the following: assume we got the 34 1.1 christos following code: 35 1.1 christos 36 1.1 christos jump .l1 37 1.1 christos nop 38 1.1 christos jump subroutine ; external symbol 39 1.1 christos .l1: 40 1.1 christos nop 41 1.1 christos ret 42 1.3 christos 43 1.1 christos In case of assembly time relaxation we'll get: 44 1.1 christos 0: jmp .l1 <.text +0x08> (reloc deleted) 45 1.1 christos 2: nop 46 1.1 christos 4: br subroutine 47 1.1 christos .l1: 48 1.1 christos 8: nop 49 1.1 christos 10: ret 50 1.1 christos 51 1.1 christos If the 'subroutine' is within +-1024 bytes range then linker 52 1.1 christos will produce: 53 1.1 christos 0: jmp .text +0x08 54 1.1 christos 2: nop 55 1.1 christos 4: jmp subroutine 56 1.1 christos .l1: 57 1.1 christos 6: nop 58 1.1 christos 8: ret ; 'jmp .text +0x08' will land here. WRONG!!! 59 1.1 christos 60 1.1 christos The workaround is the following: 61 1.1 christos 1. Declare global var enable_polymorphs which set to 1 via option -mp. 62 1.1 christos 2. Declare global var enable_relax which set to 1 via option -mQ. 63 1.1 christos 64 1.1 christos If polymorphs are enabled, and relax isn't, treat all jumps as long jumps, 65 1.1 christos do not delete any relocs and leave them for linker. 66 1.3 christos 67 1.1 christos If relax is enabled, relax at assembly time and kill relocs as necessary. */ 68 1.1 christos 69 1.1 christos int msp430_enable_relax; 70 1.1 christos int msp430_enable_polys; 71 1.1 christos 72 1.1 christos /* GCC uses the some condition codes which we'll 73 1.1 christos implement as new polymorph instructions. 74 1.3 christos 75 1.1 christos COND EXPL SHORT JUMP LONG JUMP 76 1.1 christos =============================================== 77 1.1 christos eq == jeq jne +4; br lab 78 1.1 christos ne != jne jeq +4; br lab 79 1.1 christos 80 1.1 christos ltn honours no-overflow flag 81 1.1 christos ltn < jn jn +2; jmp +4; br lab 82 1.1 christos 83 1.3 christos lt < jl jge +4; br lab 84 1.1 christos ltu < jlo lhs +4; br lab 85 1.1 christos le <= see below 86 1.1 christos leu <= see below 87 1.1 christos 88 1.1 christos gt > see below 89 1.1 christos gtu > see below 90 1.1 christos ge >= jge jl +4; br lab 91 1.1 christos geu >= jhs jlo +4; br lab 92 1.1 christos =============================================== 93 1.1 christos 94 1.1 christos Therefore, new opcodes are (BranchEQ -> beq; and so on...) 95 1.1 christos beq,bne,blt,bltn,bltu,bge,bgeu 96 1.3 christos 'u' means unsigned compares 97 1.3 christos 98 1.1 christos Also, we add 'jump' instruction: 99 1.1 christos jump UNCOND -> jmp br lab 100 1.1 christos 101 1.1 christos They will have fmt == 4, and insn_opnumb == number of instruction. */ 102 1.1 christos 103 1.3 christos struct rcodes_s 104 1.1 christos { 105 1.5 christos const char * name; 106 1.1 christos int index; /* Corresponding insn_opnumb. */ 107 1.1 christos int sop; /* Opcode if jump length is short. */ 108 1.1 christos long lpos; /* Label position. */ 109 1.1 christos long lop0; /* Opcode 1 _word_ (16 bits). */ 110 1.1 christos long lop1; /* Opcode second word. */ 111 1.1 christos long lop2; /* Opcode third word. */ 112 1.1 christos }; 113 1.1 christos 114 1.1 christos #define MSP430_RLC(n,i,sop,o1) \ 115 1.1 christos {#n, i, sop, 2, (o1 + 2), 0x4010, 0} 116 1.1 christos 117 1.3 christos static struct rcodes_s msp430_rcodes[] = 118 1.1 christos { 119 1.1 christos MSP430_RLC (beq, 0, 0x2400, 0x2000), 120 1.1 christos MSP430_RLC (bne, 1, 0x2000, 0x2400), 121 1.1 christos MSP430_RLC (blt, 2, 0x3800, 0x3400), 122 1.1 christos MSP430_RLC (bltu, 3, 0x2800, 0x2c00), 123 1.1 christos MSP430_RLC (bge, 4, 0x3400, 0x3800), 124 1.1 christos MSP430_RLC (bgeu, 5, 0x2c00, 0x2800), 125 1.1 christos {"bltn", 6, 0x3000, 3, 0x3000 + 1, 0x3c00 + 2,0x4010}, 126 1.1 christos {"jump", 7, 0x3c00, 1, 0x4010, 0, 0}, 127 1.1 christos {0,0,0,0,0,0,0} 128 1.1 christos }; 129 1.3 christos 130 1.3 christos #undef MSP430_RLC 131 1.3 christos #define MSP430_RLC(n,i,sop,o1) \ 132 1.3 christos {#n, i, sop, 2, (o1 + 2), 0x0030, 0} 133 1.3 christos 134 1.3 christos static struct rcodes_s msp430x_rcodes[] = 135 1.3 christos { 136 1.3 christos MSP430_RLC (beq, 0, 0x2400, 0x2000), 137 1.3 christos MSP430_RLC (bne, 1, 0x2000, 0x2400), 138 1.3 christos MSP430_RLC (blt, 2, 0x3800, 0x3400), 139 1.3 christos MSP430_RLC (bltu, 3, 0x2800, 0x2c00), 140 1.3 christos MSP430_RLC (bge, 4, 0x3400, 0x3800), 141 1.3 christos MSP430_RLC (bgeu, 5, 0x2c00, 0x2800), 142 1.3 christos {"bltn", 6, 0x3000, 3, 0x0030 + 1, 0x3c00 + 2, 0x3000}, 143 1.3 christos {"jump", 7, 0x3c00, 1, 0x0030, 0, 0}, 144 1.3 christos {0,0,0,0,0,0,0} 145 1.3 christos }; 146 1.1 christos #undef MSP430_RLC 147 1.1 christos 148 1.3 christos /* More difficult than above and they have format 5. 149 1.1 christos 150 1.1 christos COND EXPL SHORT LONG 151 1.1 christos ================================================================= 152 1.1 christos gt > jeq +2; jge label jeq +6; jl +4; br label 153 1.1 christos gtu > jeq +2; jhs label jeq +6; jlo +4; br label 154 1.1 christos leu <= jeq label; jlo label jeq +2; jhs +4; br label 155 1.1 christos le <= jeq label; jl label jeq +2; jge +4; br label 156 1.1 christos ================================================================= */ 157 1.1 christos 158 1.3 christos struct hcodes_s 159 1.1 christos { 160 1.5 christos const char * name; 161 1.1 christos int index; /* Corresponding insn_opnumb. */ 162 1.1 christos int tlab; /* Number of labels in short mode. */ 163 1.1 christos int op0; /* Opcode for first word of short jump. */ 164 1.1 christos int op1; /* Opcode for second word of short jump. */ 165 1.1 christos int lop0; /* Opcodes for long jump mode. */ 166 1.1 christos int lop1; 167 1.1 christos int lop2; 168 1.1 christos }; 169 1.1 christos 170 1.3 christos static struct hcodes_s msp430_hcodes[] = 171 1.1 christos { 172 1.1 christos {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x4010 }, 173 1.1 christos {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x4010 }, 174 1.1 christos {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x4010 }, 175 1.1 christos {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x4010 }, 176 1.1 christos {0,0,0,0,0,0,0,0} 177 1.1 christos }; 178 1.1 christos 179 1.3 christos static struct hcodes_s msp430x_hcodes[] = 180 1.3 christos { 181 1.3 christos {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x0030 }, 182 1.3 christos {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x0030 }, 183 1.3 christos {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x0030 }, 184 1.3 christos {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x0030 }, 185 1.3 christos {0,0,0,0,0,0,0,0} 186 1.3 christos }; 187 1.3 christos 188 1.1 christos const char comment_chars[] = ";"; 189 1.1 christos const char line_comment_chars[] = "#"; 190 1.1 christos const char line_separator_chars[] = "{"; 191 1.1 christos const char EXP_CHARS[] = "eE"; 192 1.1 christos const char FLT_CHARS[] = "dD"; 193 1.1 christos 194 1.1 christos /* Handle long expressions. */ 195 1.1 christos extern LITTLENUM_TYPE generic_bignum[]; 196 1.1 christos 197 1.8 christos static htab_t msp430_hash; 198 1.1 christos 199 1.1 christos /* Relaxations. */ 200 1.1 christos #define STATE_UNCOND_BRANCH 1 /* jump */ 201 1.1 christos #define STATE_NOOV_BRANCH 3 /* bltn */ 202 1.1 christos #define STATE_SIMPLE_BRANCH 2 /* bne, beq, etc... */ 203 1.1 christos #define STATE_EMUL_BRANCH 4 204 1.1 christos 205 1.1 christos #define CNRL 2 206 1.1 christos #define CUBL 4 207 1.1 christos #define CNOL 8 208 1.1 christos #define CSBL 6 209 1.1 christos #define CEBL 4 210 1.1 christos 211 1.1 christos /* Length. */ 212 1.7 christos #define STATE_BITS10 1 /* Wild guess. short jump. */ 213 1.7 christos #define STATE_WORD 2 /* 2 bytes pc rel. addr. more. */ 214 1.7 christos #define STATE_UNDEF 3 /* Cannot handle this yet. convert to word mode. */ 215 1.1 christos 216 1.1 christos #define ENCODE_RELAX(what,length) (((what) << 2) + (length)) 217 1.1 christos #define RELAX_STATE(s) ((s) & 3) 218 1.1 christos #define RELAX_LEN(s) ((s) >> 2) 219 1.1 christos #define RELAX_NEXT(a,b) ENCODE_RELAX (a, b + 1) 220 1.1 christos 221 1.1 christos relax_typeS md_relax_table[] = 222 1.1 christos { 223 1.1 christos /* Unused. */ 224 1.1 christos {1, 1, 0, 0}, 225 1.1 christos {1, 1, 0, 0}, 226 1.1 christos {1, 1, 0, 0}, 227 1.1 christos {1, 1, 0, 0}, 228 1.1 christos 229 1.1 christos /* Unconditional jump. */ 230 1.1 christos {1, 1, 8, 5}, 231 1.1 christos {1024, -1024, CNRL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_BITS10)}, /* state 10 bits displ */ 232 1.1 christos {0, 0, CUBL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_WORD)}, /* state word */ 233 1.1 christos {1, 1, CUBL, 0}, /* state undef */ 234 1.1 christos 235 1.1 christos /* Simple branches. */ 236 1.1 christos {0, 0, 8, 9}, 237 1.1 christos {1024, -1024, CNRL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_BITS10)}, /* state 10 bits displ */ 238 1.1 christos {0, 0, CSBL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_WORD)}, /* state word */ 239 1.1 christos {1, 1, CSBL, 0}, 240 1.1 christos 241 1.1 christos /* blt no overflow branch. */ 242 1.1 christos {1, 1, 8, 13}, 243 1.1 christos {1024, -1024, CNRL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_BITS10)}, /* state 10 bits displ */ 244 1.1 christos {0, 0, CNOL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_WORD)}, /* state word */ 245 1.1 christos {1, 1, CNOL, 0}, 246 1.1 christos 247 1.1 christos /* Emulated branches. */ 248 1.1 christos {1, 1, 8, 17}, 249 1.1 christos {1020, -1020, CEBL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_BITS10)}, /* state 10 bits displ */ 250 1.1 christos {0, 0, CNOL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_WORD)}, /* state word */ 251 1.1 christos {1, 1, CNOL, 0} 252 1.1 christos }; 253 1.1 christos 254 1.1 christos 255 1.3 christos #define MAX_OP_LEN 4096 256 1.1 christos 257 1.3 christos typedef enum msp_isa 258 1.1 christos { 259 1.3 christos MSP_ISA_430, 260 1.3 christos MSP_ISA_430X, 261 1.3 christos MSP_ISA_430Xv2 262 1.3 christos } msp_isa; 263 1.1 christos 264 1.3 christos static enum msp_isa selected_isa = MSP_ISA_430Xv2; 265 1.1 christos 266 1.8 christos static inline bool 267 1.3 christos target_is_430x (void) 268 1.3 christos { 269 1.3 christos return selected_isa >= MSP_ISA_430X; 270 1.3 christos } 271 1.1 christos 272 1.8 christos static inline bool 273 1.3 christos target_is_430xv2 (void) 274 1.3 christos { 275 1.3 christos return selected_isa == MSP_ISA_430Xv2; 276 1.3 christos } 277 1.1 christos 278 1.7 christos /* Generate an absolute 16-bit relocation, for 430 (!extended_op) instructions 279 1.7 christos only. 280 1.7 christos For the 430X we generate a 430 relocation only for the case where part of an 281 1.7 christos expression is being extracted (e.g. #hi(EXP), #lo(EXP). Otherwise generate 282 1.7 christos a 430X relocation. 283 1.3 christos For the 430 we generate a relocation without assembler range checking 284 1.7 christos if we are handling an immediate value or a byte-width instruction. */ 285 1.3 christos 286 1.3 christos #undef CHECK_RELOC_MSP430 287 1.3 christos #define CHECK_RELOC_MSP430(OP) \ 288 1.3 christos (target_is_430x () \ 289 1.7 christos ? ((OP).expp == MSP_EXPP_ALL \ 290 1.7 christos ? BFD_RELOC_MSP430X_ABS16 \ 291 1.7 christos : ((OP).vshift == 1 \ 292 1.7 christos ? BFD_RELOC_MSP430_ABS_HI16 : BFD_RELOC_16)) \ 293 1.3 christos : ((imm_op || byte_op) \ 294 1.3 christos ? BFD_RELOC_MSP430_16_BYTE : BFD_RELOC_MSP430_16)) 295 1.3 christos 296 1.3 christos /* Generate a 16-bit pc-relative relocation. 297 1.6 christos For the 430X we generate a relocation without linker range checking. 298 1.3 christos For the 430 we generate a relocation without assembler range checking 299 1.3 christos if we are handling an immediate value or a byte-width instruction. */ 300 1.3 christos #undef CHECK_RELOC_MSP430_PCREL 301 1.3 christos #define CHECK_RELOC_MSP430_PCREL \ 302 1.3 christos (target_is_430x () \ 303 1.3 christos ? BFD_RELOC_MSP430X_PCR16 \ 304 1.3 christos : (imm_op || byte_op) \ 305 1.3 christos ? BFD_RELOC_MSP430_16_PCREL_BYTE : BFD_RELOC_MSP430_16_PCREL) 306 1.1 christos 307 1.1 christos /* Profiling capability: 308 1.1 christos It is a performance hit to use gcc's profiling approach for this tiny target. 309 1.1 christos Even more -- jtag hardware facility does not perform any profiling functions. 310 1.1 christos However we've got gdb's built-in simulator where we can do anything. 311 1.1 christos Therefore my suggestion is: 312 1.1 christos 313 1.1 christos We define new section ".profiler" which holds all profiling information. 314 1.1 christos We define new pseudo operation .profiler which will instruct assembler to 315 1.1 christos add new profile entry to the object file. Profile should take place at the 316 1.1 christos present address. 317 1.1 christos 318 1.1 christos Pseudo-op format: 319 1.1 christos 320 1.1 christos .profiler flags,function_to_profile [, cycle_corrector, extra] 321 1.1 christos 322 1.1 christos where 'flags' is a combination of the following chars: 323 1.1 christos s - function Start 324 1.1 christos x - function eXit 325 1.1 christos i - function is in Init section 326 1.1 christos f - function is in Fini section 327 1.1 christos l - Library call 328 1.1 christos c - libC standard call 329 1.1 christos d - stack value Demand (saved at run-time in simulator) 330 1.1 christos I - Interrupt service routine 331 1.1 christos P - Prologue start 332 1.1 christos p - Prologue end 333 1.1 christos E - Epilogue start 334 1.1 christos e - Epilogue end 335 1.1 christos j - long Jump/ sjlj unwind 336 1.1 christos a - an Arbitrary code fragment 337 1.1 christos t - exTra parameter saved (constant value like frame size) 338 1.1 christos '""' optional: "sil" == sil 339 1.1 christos 340 1.1 christos function_to_profile - function's address 341 1.1 christos cycle_corrector - a value which should be added to the cycle 342 1.1 christos counter, zero if omitted 343 1.1 christos extra - some extra parameter, zero if omitted. 344 1.1 christos 345 1.1 christos For example: 346 1.1 christos ------------------------------ 347 1.1 christos .global fxx 348 1.1 christos .type fxx,@function 349 1.1 christos fxx: 350 1.1 christos .LFrameOffset_fxx=0x08 351 1.1 christos .profiler "scdP", fxx ; function entry. 352 1.1 christos ; we also demand stack value to be displayed 353 1.1 christos push r11 354 1.1 christos push r10 355 1.1 christos push r9 356 1.1 christos push r8 357 1.1 christos .profiler "cdp",fxx,0, .LFrameOffset_fxx ; check stack value at this point 358 1.1 christos ; (this is a prologue end) 359 1.1 christos ; note, that spare var filled with the frame size 360 1.1 christos mov r15,r8 361 1.1 christos .... 362 1.1 christos .profiler cdE,fxx ; check stack 363 1.1 christos pop r8 364 1.1 christos pop r9 365 1.1 christos pop r10 366 1.1 christos pop r11 367 1.1 christos .profiler xcde,fxx,3 ; exit adds 3 to the cycle counter 368 1.1 christos ret ; cause 'ret' insn takes 3 cycles 369 1.1 christos ------------------------------- 370 1.1 christos 371 1.1 christos This profiling approach does not produce any overhead and 372 1.1 christos absolutely harmless. 373 1.1 christos So, even profiled code can be uploaded to the MCU. */ 374 1.1 christos #define MSP430_PROFILER_FLAG_ENTRY 1 /* s */ 375 1.1 christos #define MSP430_PROFILER_FLAG_EXIT 2 /* x */ 376 1.1 christos #define MSP430_PROFILER_FLAG_INITSECT 4 /* i */ 377 1.1 christos #define MSP430_PROFILER_FLAG_FINISECT 8 /* f */ 378 1.1 christos #define MSP430_PROFILER_FLAG_LIBCALL 0x10 /* l */ 379 1.1 christos #define MSP430_PROFILER_FLAG_STDCALL 0x20 /* c */ 380 1.1 christos #define MSP430_PROFILER_FLAG_STACKDMD 0x40 /* d */ 381 1.1 christos #define MSP430_PROFILER_FLAG_ISR 0x80 /* I */ 382 1.1 christos #define MSP430_PROFILER_FLAG_PROLSTART 0x100 /* P */ 383 1.1 christos #define MSP430_PROFILER_FLAG_PROLEND 0x200 /* p */ 384 1.1 christos #define MSP430_PROFILER_FLAG_EPISTART 0x400 /* E */ 385 1.1 christos #define MSP430_PROFILER_FLAG_EPIEND 0x800 /* e */ 386 1.1 christos #define MSP430_PROFILER_FLAG_JUMP 0x1000 /* j */ 387 1.1 christos #define MSP430_PROFILER_FLAG_FRAGMENT 0x2000 /* a */ 388 1.1 christos #define MSP430_PROFILER_FLAG_EXTRA 0x4000 /* t */ 389 1.1 christos #define MSP430_PROFILER_FLAG_notyet 0x8000 /* ? */ 390 1.1 christos 391 1.1 christos static int 392 1.1 christos pow2value (int y) 393 1.1 christos { 394 1.1 christos int n = 0; 395 1.1 christos unsigned int x; 396 1.1 christos 397 1.1 christos x = y; 398 1.1 christos 399 1.1 christos if (!x) 400 1.1 christos return 1; 401 1.1 christos 402 1.1 christos for (; x; x = x >> 1) 403 1.1 christos if (x & 1) 404 1.1 christos n++; 405 1.1 christos 406 1.1 christos return n == 1; 407 1.1 christos } 408 1.1 christos 409 1.1 christos /* Parse ordinary expression. */ 410 1.1 christos 411 1.1 christos static char * 412 1.1 christos parse_exp (char * s, expressionS * op) 413 1.1 christos { 414 1.1 christos input_line_pointer = s; 415 1.1 christos expression (op); 416 1.1 christos if (op->X_op == O_absent) 417 1.1 christos as_bad (_("missing operand")); 418 1.9 christos else 419 1.9 christos resolve_register (op); 420 1.7 christos 421 1.6 christos /* Our caller is likely to check that the entire expression was parsed. 422 1.6 christos If we have found a hex constant with an 'h' suffix, ilp will be left 423 1.6 christos pointing at the 'h', so skip it here. */ 424 1.6 christos if (input_line_pointer != NULL 425 1.6 christos && op->X_op == O_constant 426 1.6 christos && (*input_line_pointer == 'h' || *input_line_pointer == 'H')) 427 1.6 christos ++ input_line_pointer; 428 1.1 christos return input_line_pointer; 429 1.1 christos } 430 1.1 christos 431 1.1 christos 432 1.1 christos /* Delete spaces from s: X ( r 1 2) => X(r12). */ 433 1.1 christos 434 1.1 christos static void 435 1.1 christos del_spaces (char * s) 436 1.1 christos { 437 1.1 christos while (*s) 438 1.1 christos { 439 1.10 christos if (is_whitespace (*s)) 440 1.1 christos { 441 1.1 christos char *m = s + 1; 442 1.1 christos 443 1.10 christos while (is_whitespace (*m) && *m) 444 1.1 christos m++; 445 1.1 christos memmove (s, m, strlen (m) + 1); 446 1.1 christos } 447 1.1 christos else 448 1.1 christos s++; 449 1.1 christos } 450 1.1 christos } 451 1.1 christos 452 1.1 christos static inline char * 453 1.1 christos skip_space (char * s) 454 1.1 christos { 455 1.10 christos while (is_whitespace (*s)) 456 1.1 christos ++s; 457 1.1 christos return s; 458 1.1 christos } 459 1.1 christos 460 1.1 christos /* Extract one word from FROM and copy it to TO. Delimiters are ",;\n" */ 461 1.1 christos 462 1.1 christos static char * 463 1.1 christos extract_operand (char * from, char * to, int limit) 464 1.1 christos { 465 1.1 christos int size = 0; 466 1.1 christos 467 1.1 christos /* Drop leading whitespace. */ 468 1.1 christos from = skip_space (from); 469 1.1 christos 470 1.1 christos while (size < limit && *from) 471 1.1 christos { 472 1.1 christos *(to + size) = *from; 473 1.1 christos if (*from == ',' || *from == ';' || *from == '\n') 474 1.1 christos break; 475 1.1 christos from++; 476 1.1 christos size++; 477 1.1 christos } 478 1.1 christos 479 1.1 christos *(to + size) = 0; 480 1.1 christos del_spaces (to); 481 1.1 christos 482 1.1 christos from++; 483 1.1 christos 484 1.1 christos return from; 485 1.1 christos } 486 1.1 christos 487 1.1 christos static void 488 1.1 christos msp430_profiler (int dummy ATTRIBUTE_UNUSED) 489 1.1 christos { 490 1.1 christos char buffer[1024]; 491 1.1 christos char f[32]; 492 1.1 christos char * str = buffer; 493 1.1 christos char * flags = f; 494 1.1 christos int p_flags = 0; 495 1.1 christos char * halt; 496 1.1 christos int ops = 0; 497 1.1 christos int left; 498 1.1 christos char * s; 499 1.1 christos segT seg; 500 1.1 christos int subseg; 501 1.1 christos char * end = 0; 502 1.1 christos expressionS exp; 503 1.1 christos expressionS exp1; 504 1.1 christos 505 1.1 christos s = input_line_pointer; 506 1.1 christos end = input_line_pointer; 507 1.1 christos 508 1.1 christos while (*end && *end != '\n') 509 1.1 christos end++; 510 1.1 christos 511 1.1 christos while (*s && *s != '\n') 512 1.1 christos { 513 1.1 christos if (*s == ',') 514 1.1 christos ops++; 515 1.1 christos s++; 516 1.1 christos } 517 1.1 christos 518 1.1 christos left = 3 - ops; 519 1.1 christos 520 1.1 christos if (ops < 1) 521 1.1 christos { 522 1.1 christos as_bad (_(".profiler pseudo requires at least two operands.")); 523 1.1 christos input_line_pointer = end; 524 1.1 christos return; 525 1.1 christos } 526 1.1 christos 527 1.1 christos input_line_pointer = extract_operand (input_line_pointer, flags, 32); 528 1.1 christos 529 1.1 christos while (*flags) 530 1.1 christos { 531 1.1 christos switch (*flags) 532 1.1 christos { 533 1.1 christos case '"': 534 1.1 christos break; 535 1.1 christos case 'a': 536 1.1 christos p_flags |= MSP430_PROFILER_FLAG_FRAGMENT; 537 1.1 christos break; 538 1.1 christos case 'j': 539 1.1 christos p_flags |= MSP430_PROFILER_FLAG_JUMP; 540 1.1 christos break; 541 1.1 christos case 'P': 542 1.1 christos p_flags |= MSP430_PROFILER_FLAG_PROLSTART; 543 1.1 christos break; 544 1.1 christos case 'p': 545 1.1 christos p_flags |= MSP430_PROFILER_FLAG_PROLEND; 546 1.1 christos break; 547 1.1 christos case 'E': 548 1.1 christos p_flags |= MSP430_PROFILER_FLAG_EPISTART; 549 1.1 christos break; 550 1.1 christos case 'e': 551 1.1 christos p_flags |= MSP430_PROFILER_FLAG_EPIEND; 552 1.1 christos break; 553 1.1 christos case 's': 554 1.1 christos p_flags |= MSP430_PROFILER_FLAG_ENTRY; 555 1.1 christos break; 556 1.1 christos case 'x': 557 1.1 christos p_flags |= MSP430_PROFILER_FLAG_EXIT; 558 1.1 christos break; 559 1.1 christos case 'i': 560 1.1 christos p_flags |= MSP430_PROFILER_FLAG_INITSECT; 561 1.1 christos break; 562 1.1 christos case 'f': 563 1.1 christos p_flags |= MSP430_PROFILER_FLAG_FINISECT; 564 1.1 christos break; 565 1.1 christos case 'l': 566 1.1 christos p_flags |= MSP430_PROFILER_FLAG_LIBCALL; 567 1.1 christos break; 568 1.1 christos case 'c': 569 1.1 christos p_flags |= MSP430_PROFILER_FLAG_STDCALL; 570 1.1 christos break; 571 1.1 christos case 'd': 572 1.1 christos p_flags |= MSP430_PROFILER_FLAG_STACKDMD; 573 1.1 christos break; 574 1.1 christos case 'I': 575 1.1 christos p_flags |= MSP430_PROFILER_FLAG_ISR; 576 1.1 christos break; 577 1.1 christos case 't': 578 1.1 christos p_flags |= MSP430_PROFILER_FLAG_EXTRA; 579 1.1 christos break; 580 1.1 christos default: 581 1.1 christos as_warn (_("unknown profiling flag - ignored.")); 582 1.1 christos break; 583 1.1 christos } 584 1.1 christos flags++; 585 1.1 christos } 586 1.1 christos 587 1.1 christos if (p_flags 588 1.1 christos && ( ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_ENTRY 589 1.1 christos | MSP430_PROFILER_FLAG_EXIT)) 590 1.1 christos || ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_PROLSTART 591 1.1 christos | MSP430_PROFILER_FLAG_PROLEND 592 1.1 christos | MSP430_PROFILER_FLAG_EPISTART 593 1.1 christos | MSP430_PROFILER_FLAG_EPIEND)) 594 1.1 christos || ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_INITSECT 595 1.1 christos | MSP430_PROFILER_FLAG_FINISECT)))) 596 1.1 christos { 597 1.1 christos as_bad (_("ambiguous flags combination - '.profiler' directive ignored.")); 598 1.1 christos input_line_pointer = end; 599 1.1 christos return; 600 1.1 christos } 601 1.1 christos 602 1.1 christos /* Generate temp symbol which denotes current location. */ 603 1.1 christos if (now_seg == absolute_section) /* Paranoia ? */ 604 1.1 christos { 605 1.1 christos exp1.X_op = O_constant; 606 1.1 christos exp1.X_add_number = abs_section_offset; 607 1.1 christos as_warn (_("profiling in absolute section?")); 608 1.1 christos } 609 1.1 christos else 610 1.1 christos { 611 1.1 christos exp1.X_op = O_symbol; 612 1.1 christos exp1.X_add_symbol = symbol_temp_new_now (); 613 1.1 christos exp1.X_add_number = 0; 614 1.1 christos } 615 1.1 christos 616 1.1 christos /* Generate a symbol which holds flags value. */ 617 1.1 christos exp.X_op = O_constant; 618 1.1 christos exp.X_add_number = p_flags; 619 1.1 christos 620 1.1 christos /* Save current section. */ 621 1.1 christos seg = now_seg; 622 1.1 christos subseg = now_subseg; 623 1.1 christos 624 1.1 christos /* Now go to .profiler section. */ 625 1.9 christos obj_elf_change_section (".profiler", SHT_PROGBITS, 0, 0, 0, false); 626 1.1 christos 627 1.1 christos /* Save flags. */ 628 1.1 christos emit_expr (& exp, 2); 629 1.1 christos 630 1.1 christos /* Save label value. */ 631 1.1 christos emit_expr (& exp1, 2); 632 1.1 christos 633 1.1 christos while (ops--) 634 1.1 christos { 635 1.1 christos /* Now get profiling info. */ 636 1.1 christos halt = extract_operand (input_line_pointer, str, 1024); 637 1.1 christos /* Process like ".word xxx" directive. */ 638 1.6 christos (void) parse_exp (str, & exp); 639 1.1 christos emit_expr (& exp, 2); 640 1.1 christos input_line_pointer = halt; 641 1.1 christos } 642 1.1 christos 643 1.1 christos /* Fill the rest with zeros. */ 644 1.1 christos exp.X_op = O_constant; 645 1.1 christos exp.X_add_number = 0; 646 1.1 christos while (left--) 647 1.1 christos emit_expr (& exp, 2); 648 1.1 christos 649 1.1 christos /* Return to current section. */ 650 1.1 christos subseg_set (seg, subseg); 651 1.1 christos } 652 1.1 christos 653 1.1 christos static char * 654 1.1 christos extract_word (char * from, char * to, int limit) 655 1.1 christos { 656 1.1 christos char *op_end; 657 1.1 christos int size = 0; 658 1.1 christos 659 1.1 christos /* Drop leading whitespace. */ 660 1.1 christos from = skip_space (from); 661 1.1 christos *to = 0; 662 1.1 christos 663 1.1 christos /* Find the op code end. */ 664 1.1 christos for (op_end = from; *op_end != 0 && is_part_of_name (*op_end);) 665 1.1 christos { 666 1.1 christos to[size++] = *op_end++; 667 1.1 christos if (size + 1 >= limit) 668 1.1 christos break; 669 1.1 christos } 670 1.1 christos 671 1.1 christos to[size] = 0; 672 1.1 christos return op_end; 673 1.1 christos } 674 1.1 christos 675 1.1 christos #define OPTION_MMCU 'm' 676 1.1 christos #define OPTION_RELAX 'Q' 677 1.1 christos #define OPTION_POLYMORPHS 'P' 678 1.3 christos #define OPTION_LARGE 'l' 679 1.8 christos static bool large_model = false; 680 1.3 christos #define OPTION_NO_INTR_NOPS 'N' 681 1.3 christos #define OPTION_INTR_NOPS 'n' 682 1.8 christos static bool gen_interrupt_nops = false; 683 1.3 christos #define OPTION_WARN_INTR_NOPS 'y' 684 1.3 christos #define OPTION_NO_WARN_INTR_NOPS 'Y' 685 1.8 christos static bool warn_interrupt_nops = true; 686 1.7 christos #define OPTION_UNKNOWN_INTR_NOPS 'u' 687 1.7 christos #define OPTION_NO_UNKNOWN_INTR_NOPS 'U' 688 1.8 christos static bool do_unknown_interrupt_nops = true; 689 1.3 christos #define OPTION_MCPU 'c' 690 1.6 christos #define OPTION_DATA_REGION 'r' 691 1.8 christos static bool upper_data_region_in_use = false; 692 1.7 christos /* The default is to use the lower region only. */ 693 1.8 christos static bool lower_data_region_only = true; 694 1.8 christos 695 1.8 christos /* Deprecated option, silently ignore it for compatibility with GCC <= 10. */ 696 1.8 christos #define OPTION_MOVE_DATA 'd' 697 1.3 christos 698 1.3 christos enum 699 1.3 christos { 700 1.3 christos OPTION_SILICON_ERRATA = OPTION_MD_BASE, 701 1.3 christos OPTION_SILICON_ERRATA_WARN, 702 1.5 christos }; 703 1.3 christos 704 1.3 christos static unsigned int silicon_errata_fix = 0; 705 1.3 christos static unsigned int silicon_errata_warn = 0; 706 1.3 christos #define SILICON_ERRATA_CPU4 (1 << 0) 707 1.3 christos #define SILICON_ERRATA_CPU8 (1 << 1) 708 1.3 christos #define SILICON_ERRATA_CPU11 (1 << 2) 709 1.3 christos #define SILICON_ERRATA_CPU12 (1 << 3) 710 1.3 christos #define SILICON_ERRATA_CPU13 (1 << 4) 711 1.3 christos #define SILICON_ERRATA_CPU19 (1 << 5) 712 1.1 christos 713 1.1 christos static void 714 1.3 christos msp430_set_arch (int option) 715 1.1 christos { 716 1.5 christos char str[32]; /* 32 for good measure. */ 717 1.1 christos 718 1.1 christos input_line_pointer = extract_word (input_line_pointer, str, 32); 719 1.1 christos 720 1.3 christos md_parse_option (option, str); 721 1.3 christos bfd_set_arch_mach (stdoutput, TARGET_ARCH, 722 1.3 christos target_is_430x () ? bfd_mach_msp430x : bfd_mach_msp11); 723 1.1 christos } 724 1.1 christos 725 1.3 christos /* This is a copy of the same data structure found in gcc/config/msp430/msp430.c 726 1.3 christos Keep these two structures in sync. 727 1.6 christos The data in this structure has been extracted from version 1.194 of the 728 1.6 christos devices.csv file released by TI in September 2016. */ 729 1.3 christos 730 1.3 christos struct msp430_mcu_data 731 1.1 christos { 732 1.3 christos const char * name; 733 1.3 christos unsigned int revision; /* 0=> MSP430, 1=>MSP430X, 2=> MSP430Xv2. */ 734 1.3 christos unsigned int hwmpy; /* 0=>none, 1=>16-bit, 2=>16-bit w/sign extend, 4=>32-bit, 8=> 32-bit (5xx). */ 735 1.1 christos } 736 1.3 christos msp430_mcu_data [] = 737 1.3 christos { 738 1.3 christos { "cc430f5123",2,8 }, 739 1.3 christos { "cc430f5125",2,8 }, 740 1.3 christos { "cc430f5133",2,8 }, 741 1.3 christos { "cc430f5135",2,8 }, 742 1.3 christos { "cc430f5137",2,8 }, 743 1.3 christos { "cc430f5143",2,8 }, 744 1.3 christos { "cc430f5145",2,8 }, 745 1.3 christos { "cc430f5147",2,8 }, 746 1.3 christos { "cc430f6125",2,8 }, 747 1.3 christos { "cc430f6126",2,8 }, 748 1.3 christos { "cc430f6127",2,8 }, 749 1.3 christos { "cc430f6135",2,8 }, 750 1.3 christos { "cc430f6137",2,8 }, 751 1.3 christos { "cc430f6143",2,8 }, 752 1.3 christos { "cc430f6145",2,8 }, 753 1.3 christos { "cc430f6147",2,8 }, 754 1.3 christos { "msp430afe221",0,2 }, 755 1.3 christos { "msp430afe222",0,2 }, 756 1.3 christos { "msp430afe223",0,2 }, 757 1.3 christos { "msp430afe231",0,2 }, 758 1.3 christos { "msp430afe232",0,2 }, 759 1.3 christos { "msp430afe233",0,2 }, 760 1.3 christos { "msp430afe251",0,2 }, 761 1.3 christos { "msp430afe252",0,2 }, 762 1.3 christos { "msp430afe253",0,2 }, 763 1.3 christos { "msp430bt5190",2,8 }, 764 1.3 christos { "msp430c091",0,0 }, 765 1.3 christos { "msp430c092",0,0 }, 766 1.3 christos { "msp430c111",0,0 }, 767 1.3 christos { "msp430c1111",0,0 }, 768 1.3 christos { "msp430c112",0,0 }, 769 1.3 christos { "msp430c1121",0,0 }, 770 1.3 christos { "msp430c1331",0,0 }, 771 1.3 christos { "msp430c1351",0,0 }, 772 1.3 christos { "msp430c311s",0,0 }, 773 1.3 christos { "msp430c312",0,0 }, 774 1.3 christos { "msp430c313",0,0 }, 775 1.3 christos { "msp430c314",0,0 }, 776 1.3 christos { "msp430c315",0,0 }, 777 1.3 christos { "msp430c323",0,0 }, 778 1.3 christos { "msp430c325",0,0 }, 779 1.3 christos { "msp430c336",0,1 }, 780 1.3 christos { "msp430c337",0,1 }, 781 1.3 christos { "msp430c412",0,0 }, 782 1.3 christos { "msp430c413",0,0 }, 783 1.3 christos { "msp430cg4616",1,1 }, 784 1.3 christos { "msp430cg4617",1,1 }, 785 1.3 christos { "msp430cg4618",1,1 }, 786 1.3 christos { "msp430cg4619",1,1 }, 787 1.3 christos { "msp430e112",0,0 }, 788 1.3 christos { "msp430e313",0,0 }, 789 1.3 christos { "msp430e315",0,0 }, 790 1.3 christos { "msp430e325",0,0 }, 791 1.3 christos { "msp430e337",0,1 }, 792 1.3 christos { "msp430f110",0,0 }, 793 1.3 christos { "msp430f1101",0,0 }, 794 1.3 christos { "msp430f1101a",0,0 }, 795 1.3 christos { "msp430f1111",0,0 }, 796 1.3 christos { "msp430f1111a",0,0 }, 797 1.3 christos { "msp430f112",0,0 }, 798 1.3 christos { "msp430f1121",0,0 }, 799 1.3 christos { "msp430f1121a",0,0 }, 800 1.3 christos { "msp430f1122",0,0 }, 801 1.3 christos { "msp430f1132",0,0 }, 802 1.3 christos { "msp430f122",0,0 }, 803 1.3 christos { "msp430f1222",0,0 }, 804 1.3 christos { "msp430f123",0,0 }, 805 1.3 christos { "msp430f1232",0,0 }, 806 1.3 christos { "msp430f133",0,0 }, 807 1.3 christos { "msp430f135",0,0 }, 808 1.3 christos { "msp430f147",0,1 }, 809 1.3 christos { "msp430f1471",0,1 }, 810 1.3 christos { "msp430f148",0,1 }, 811 1.3 christos { "msp430f1481",0,1 }, 812 1.3 christos { "msp430f149",0,1 }, 813 1.3 christos { "msp430f1491",0,1 }, 814 1.3 christos { "msp430f155",0,0 }, 815 1.3 christos { "msp430f156",0,0 }, 816 1.3 christos { "msp430f157",0,0 }, 817 1.3 christos { "msp430f1610",0,1 }, 818 1.3 christos { "msp430f1611",0,1 }, 819 1.3 christos { "msp430f1612",0,1 }, 820 1.3 christos { "msp430f167",0,1 }, 821 1.3 christos { "msp430f168",0,1 }, 822 1.3 christos { "msp430f169",0,1 }, 823 1.3 christos { "msp430f2001",0,0 }, 824 1.3 christos { "msp430f2002",0,0 }, 825 1.3 christos { "msp430f2003",0,0 }, 826 1.3 christos { "msp430f2011",0,0 }, 827 1.3 christos { "msp430f2012",0,0 }, 828 1.3 christos { "msp430f2013",0,0 }, 829 1.3 christos { "msp430f2101",0,0 }, 830 1.3 christos { "msp430f2111",0,0 }, 831 1.3 christos { "msp430f2112",0,0 }, 832 1.3 christos { "msp430f2121",0,0 }, 833 1.3 christos { "msp430f2122",0,0 }, 834 1.3 christos { "msp430f2131",0,0 }, 835 1.3 christos { "msp430f2132",0,0 }, 836 1.3 christos { "msp430f2232",0,0 }, 837 1.3 christos { "msp430f2234",0,0 }, 838 1.3 christos { "msp430f2252",0,0 }, 839 1.3 christos { "msp430f2254",0,0 }, 840 1.3 christos { "msp430f2272",0,0 }, 841 1.3 christos { "msp430f2274",0,0 }, 842 1.3 christos { "msp430f233",0,2 }, 843 1.3 christos { "msp430f2330",0,2 }, 844 1.3 christos { "msp430f235",0,2 }, 845 1.3 christos { "msp430f2350",0,2 }, 846 1.3 christos { "msp430f2370",0,2 }, 847 1.3 christos { "msp430f2410",0,2 }, 848 1.3 christos { "msp430f2416",1,2 }, 849 1.3 christos { "msp430f2417",1,2 }, 850 1.3 christos { "msp430f2418",1,2 }, 851 1.3 christos { "msp430f2419",1,2 }, 852 1.3 christos { "msp430f247",0,2 }, 853 1.3 christos { "msp430f2471",0,2 }, 854 1.3 christos { "msp430f248",0,2 }, 855 1.3 christos { "msp430f2481",0,2 }, 856 1.3 christos { "msp430f249",0,2 }, 857 1.3 christos { "msp430f2491",0,2 }, 858 1.3 christos { "msp430f2616",1,2 }, 859 1.3 christos { "msp430f2617",1,2 }, 860 1.3 christos { "msp430f2618",1,2 }, 861 1.3 christos { "msp430f2619",1,2 }, 862 1.3 christos { "msp430f412",0,0 }, 863 1.3 christos { "msp430f413",0,0 }, 864 1.3 christos { "msp430f4132",0,0 }, 865 1.3 christos { "msp430f415",0,0 }, 866 1.3 christos { "msp430f4152",0,0 }, 867 1.3 christos { "msp430f417",0,0 }, 868 1.3 christos { "msp430f423",0,1 }, 869 1.3 christos { "msp430f423a",0,1 }, 870 1.3 christos { "msp430f425",0,1 }, 871 1.3 christos { "msp430f4250",0,0 }, 872 1.3 christos { "msp430f425a",0,1 }, 873 1.3 christos { "msp430f4260",0,0 }, 874 1.3 christos { "msp430f427",0,1 }, 875 1.3 christos { "msp430f4270",0,0 }, 876 1.3 christos { "msp430f427a",0,1 }, 877 1.3 christos { "msp430f435",0,0 }, 878 1.3 christos { "msp430f4351",0,0 }, 879 1.3 christos { "msp430f436",0,0 }, 880 1.3 christos { "msp430f4361",0,0 }, 881 1.3 christos { "msp430f437",0,0 }, 882 1.3 christos { "msp430f4371",0,0 }, 883 1.3 christos { "msp430f438",0,0 }, 884 1.3 christos { "msp430f439",0,0 }, 885 1.3 christos { "msp430f447",0,1 }, 886 1.3 christos { "msp430f448",0,1 }, 887 1.3 christos { "msp430f4481",0,1 }, 888 1.3 christos { "msp430f449",0,1 }, 889 1.3 christos { "msp430f4491",0,1 }, 890 1.3 christos { "msp430f4616",1,1 }, 891 1.3 christos { "msp430f46161",1,1 }, 892 1.3 christos { "msp430f4617",1,1 }, 893 1.3 christos { "msp430f46171",1,1 }, 894 1.3 christos { "msp430f4618",1,1 }, 895 1.3 christos { "msp430f46181",1,1 }, 896 1.3 christos { "msp430f4619",1,1 }, 897 1.3 christos { "msp430f46191",1,1 }, 898 1.3 christos { "msp430f47126",1,4 }, 899 1.3 christos { "msp430f47127",1,4 }, 900 1.3 christos { "msp430f47163",1,4 }, 901 1.3 christos { "msp430f47166",1,4 }, 902 1.3 christos { "msp430f47167",1,4 }, 903 1.3 christos { "msp430f47173",1,4 }, 904 1.3 christos { "msp430f47176",1,4 }, 905 1.3 christos { "msp430f47177",1,4 }, 906 1.3 christos { "msp430f47183",1,4 }, 907 1.3 christos { "msp430f47186",1,4 }, 908 1.3 christos { "msp430f47187",1,4 }, 909 1.3 christos { "msp430f47193",1,4 }, 910 1.3 christos { "msp430f47196",1,4 }, 911 1.3 christos { "msp430f47197",1,4 }, 912 1.3 christos { "msp430f477",0,0 }, 913 1.3 christos { "msp430f478",0,0 }, 914 1.3 christos { "msp430f4783",0,4 }, 915 1.3 christos { "msp430f4784",0,4 }, 916 1.3 christos { "msp430f479",0,0 }, 917 1.3 christos { "msp430f4793",0,4 }, 918 1.3 christos { "msp430f4794",0,4 }, 919 1.3 christos { "msp430f5131",2,8 }, 920 1.3 christos { "msp430f5132",2,8 }, 921 1.3 christos { "msp430f5151",2,8 }, 922 1.3 christos { "msp430f5152",2,8 }, 923 1.3 christos { "msp430f5171",2,8 }, 924 1.3 christos { "msp430f5172",2,8 }, 925 1.3 christos { "msp430f5212",2,8 }, 926 1.3 christos { "msp430f5213",2,8 }, 927 1.3 christos { "msp430f5214",2,8 }, 928 1.3 christos { "msp430f5217",2,8 }, 929 1.3 christos { "msp430f5218",2,8 }, 930 1.3 christos { "msp430f5219",2,8 }, 931 1.3 christos { "msp430f5222",2,8 }, 932 1.3 christos { "msp430f5223",2,8 }, 933 1.3 christos { "msp430f5224",2,8 }, 934 1.3 christos { "msp430f5227",2,8 }, 935 1.3 christos { "msp430f5228",2,8 }, 936 1.3 christos { "msp430f5229",2,8 }, 937 1.3 christos { "msp430f5232",2,8 }, 938 1.3 christos { "msp430f5234",2,8 }, 939 1.3 christos { "msp430f5237",2,8 }, 940 1.3 christos { "msp430f5239",2,8 }, 941 1.3 christos { "msp430f5242",2,8 }, 942 1.3 christos { "msp430f5244",2,8 }, 943 1.3 christos { "msp430f5247",2,8 }, 944 1.3 christos { "msp430f5249",2,8 }, 945 1.3 christos { "msp430f5252",2,8 }, 946 1.3 christos { "msp430f5253",2,8 }, 947 1.3 christos { "msp430f5254",2,8 }, 948 1.3 christos { "msp430f5255",2,8 }, 949 1.3 christos { "msp430f5256",2,8 }, 950 1.3 christos { "msp430f5257",2,8 }, 951 1.3 christos { "msp430f5258",2,8 }, 952 1.3 christos { "msp430f5259",2,8 }, 953 1.3 christos { "msp430f5304",2,8 }, 954 1.3 christos { "msp430f5308",2,8 }, 955 1.3 christos { "msp430f5309",2,8 }, 956 1.3 christos { "msp430f5310",2,8 }, 957 1.3 christos { "msp430f5324",2,8 }, 958 1.3 christos { "msp430f5325",2,8 }, 959 1.3 christos { "msp430f5326",2,8 }, 960 1.3 christos { "msp430f5327",2,8 }, 961 1.3 christos { "msp430f5328",2,8 }, 962 1.3 christos { "msp430f5329",2,8 }, 963 1.3 christos { "msp430f5333",2,8 }, 964 1.3 christos { "msp430f5335",2,8 }, 965 1.3 christos { "msp430f5336",2,8 }, 966 1.3 christos { "msp430f5338",2,8 }, 967 1.3 christos { "msp430f5340",2,8 }, 968 1.3 christos { "msp430f5341",2,8 }, 969 1.3 christos { "msp430f5342",2,8 }, 970 1.3 christos { "msp430f5358",2,8 }, 971 1.3 christos { "msp430f5359",2,8 }, 972 1.3 christos { "msp430f5418",2,8 }, 973 1.3 christos { "msp430f5418a",2,8 }, 974 1.3 christos { "msp430f5419",2,8 }, 975 1.3 christos { "msp430f5419a",2,8 }, 976 1.3 christos { "msp430f5435",2,8 }, 977 1.3 christos { "msp430f5435a",2,8 }, 978 1.3 christos { "msp430f5436",2,8 }, 979 1.3 christos { "msp430f5436a",2,8 }, 980 1.3 christos { "msp430f5437",2,8 }, 981 1.3 christos { "msp430f5437a",2,8 }, 982 1.3 christos { "msp430f5438",2,8 }, 983 1.3 christos { "msp430f5438a",2,8 }, 984 1.3 christos { "msp430f5500",2,8 }, 985 1.3 christos { "msp430f5501",2,8 }, 986 1.3 christos { "msp430f5502",2,8 }, 987 1.3 christos { "msp430f5503",2,8 }, 988 1.3 christos { "msp430f5504",2,8 }, 989 1.3 christos { "msp430f5505",2,8 }, 990 1.3 christos { "msp430f5506",2,8 }, 991 1.3 christos { "msp430f5507",2,8 }, 992 1.3 christos { "msp430f5508",2,8 }, 993 1.3 christos { "msp430f5509",2,8 }, 994 1.3 christos { "msp430f5510",2,8 }, 995 1.3 christos { "msp430f5513",2,8 }, 996 1.3 christos { "msp430f5514",2,8 }, 997 1.3 christos { "msp430f5515",2,8 }, 998 1.3 christos { "msp430f5517",2,8 }, 999 1.3 christos { "msp430f5519",2,8 }, 1000 1.3 christos { "msp430f5521",2,8 }, 1001 1.3 christos { "msp430f5522",2,8 }, 1002 1.3 christos { "msp430f5524",2,8 }, 1003 1.3 christos { "msp430f5525",2,8 }, 1004 1.3 christos { "msp430f5526",2,8 }, 1005 1.3 christos { "msp430f5527",2,8 }, 1006 1.3 christos { "msp430f5528",2,8 }, 1007 1.3 christos { "msp430f5529",2,8 }, 1008 1.3 christos { "msp430f5630",2,8 }, 1009 1.3 christos { "msp430f5631",2,8 }, 1010 1.3 christos { "msp430f5632",2,8 }, 1011 1.3 christos { "msp430f5633",2,8 }, 1012 1.3 christos { "msp430f5634",2,8 }, 1013 1.3 christos { "msp430f5635",2,8 }, 1014 1.3 christos { "msp430f5636",2,8 }, 1015 1.3 christos { "msp430f5637",2,8 }, 1016 1.3 christos { "msp430f5638",2,8 }, 1017 1.3 christos { "msp430f5658",2,8 }, 1018 1.3 christos { "msp430f5659",2,8 }, 1019 1.3 christos { "msp430f5xx_6xxgeneric",2,8 }, 1020 1.3 christos { "msp430f6433",2,8 }, 1021 1.3 christos { "msp430f6435",2,8 }, 1022 1.3 christos { "msp430f6436",2,8 }, 1023 1.3 christos { "msp430f6438",2,8 }, 1024 1.3 christos { "msp430f6458",2,8 }, 1025 1.3 christos { "msp430f6459",2,8 }, 1026 1.3 christos { "msp430f6630",2,8 }, 1027 1.3 christos { "msp430f6631",2,8 }, 1028 1.3 christos { "msp430f6632",2,8 }, 1029 1.3 christos { "msp430f6633",2,8 }, 1030 1.3 christos { "msp430f6634",2,8 }, 1031 1.3 christos { "msp430f6635",2,8 }, 1032 1.3 christos { "msp430f6636",2,8 }, 1033 1.3 christos { "msp430f6637",2,8 }, 1034 1.3 christos { "msp430f6638",2,8 }, 1035 1.3 christos { "msp430f6658",2,8 }, 1036 1.3 christos { "msp430f6659",2,8 }, 1037 1.3 christos { "msp430f6720",2,8 }, 1038 1.3 christos { "msp430f6720a",2,8 }, 1039 1.3 christos { "msp430f6721",2,8 }, 1040 1.3 christos { "msp430f6721a",2,8 }, 1041 1.3 christos { "msp430f6723",2,8 }, 1042 1.3 christos { "msp430f6723a",2,8 }, 1043 1.3 christos { "msp430f6724",2,8 }, 1044 1.3 christos { "msp430f6724a",2,8 }, 1045 1.3 christos { "msp430f6725",2,8 }, 1046 1.3 christos { "msp430f6725a",2,8 }, 1047 1.3 christos { "msp430f6726",2,8 }, 1048 1.3 christos { "msp430f6726a",2,8 }, 1049 1.3 christos { "msp430f6730",2,8 }, 1050 1.3 christos { "msp430f6730a",2,8 }, 1051 1.3 christos { "msp430f6731",2,8 }, 1052 1.3 christos { "msp430f6731a",2,8 }, 1053 1.3 christos { "msp430f6733",2,8 }, 1054 1.3 christos { "msp430f6733a",2,8 }, 1055 1.3 christos { "msp430f6734",2,8 }, 1056 1.3 christos { "msp430f6734a",2,8 }, 1057 1.3 christos { "msp430f6735",2,8 }, 1058 1.3 christos { "msp430f6735a",2,8 }, 1059 1.3 christos { "msp430f6736",2,8 }, 1060 1.3 christos { "msp430f6736a",2,8 }, 1061 1.3 christos { "msp430f6745",2,8 }, 1062 1.3 christos { "msp430f67451",2,8 }, 1063 1.3 christos { "msp430f67451a",2,8 }, 1064 1.3 christos { "msp430f6745a",2,8 }, 1065 1.3 christos { "msp430f6746",2,8 }, 1066 1.3 christos { "msp430f67461",2,8 }, 1067 1.3 christos { "msp430f67461a",2,8 }, 1068 1.3 christos { "msp430f6746a",2,8 }, 1069 1.3 christos { "msp430f6747",2,8 }, 1070 1.3 christos { "msp430f67471",2,8 }, 1071 1.3 christos { "msp430f67471a",2,8 }, 1072 1.3 christos { "msp430f6747a",2,8 }, 1073 1.3 christos { "msp430f6748",2,8 }, 1074 1.3 christos { "msp430f67481",2,8 }, 1075 1.3 christos { "msp430f67481a",2,8 }, 1076 1.3 christos { "msp430f6748a",2,8 }, 1077 1.3 christos { "msp430f6749",2,8 }, 1078 1.3 christos { "msp430f67491",2,8 }, 1079 1.3 christos { "msp430f67491a",2,8 }, 1080 1.3 christos { "msp430f6749a",2,8 }, 1081 1.3 christos { "msp430f67621",2,8 }, 1082 1.3 christos { "msp430f67621a",2,8 }, 1083 1.3 christos { "msp430f67641",2,8 }, 1084 1.3 christos { "msp430f67641a",2,8 }, 1085 1.3 christos { "msp430f6765",2,8 }, 1086 1.3 christos { "msp430f67651",2,8 }, 1087 1.3 christos { "msp430f67651a",2,8 }, 1088 1.3 christos { "msp430f6765a",2,8 }, 1089 1.3 christos { "msp430f6766",2,8 }, 1090 1.3 christos { "msp430f67661",2,8 }, 1091 1.3 christos { "msp430f67661a",2,8 }, 1092 1.3 christos { "msp430f6766a",2,8 }, 1093 1.3 christos { "msp430f6767",2,8 }, 1094 1.3 christos { "msp430f67671",2,8 }, 1095 1.3 christos { "msp430f67671a",2,8 }, 1096 1.3 christos { "msp430f6767a",2,8 }, 1097 1.3 christos { "msp430f6768",2,8 }, 1098 1.3 christos { "msp430f67681",2,8 }, 1099 1.3 christos { "msp430f67681a",2,8 }, 1100 1.3 christos { "msp430f6768a",2,8 }, 1101 1.3 christos { "msp430f6769",2,8 }, 1102 1.3 christos { "msp430f67691",2,8 }, 1103 1.3 christos { "msp430f67691a",2,8 }, 1104 1.3 christos { "msp430f6769a",2,8 }, 1105 1.3 christos { "msp430f6775",2,8 }, 1106 1.3 christos { "msp430f67751",2,8 }, 1107 1.3 christos { "msp430f67751a",2,8 }, 1108 1.3 christos { "msp430f6775a",2,8 }, 1109 1.3 christos { "msp430f6776",2,8 }, 1110 1.3 christos { "msp430f67761",2,8 }, 1111 1.3 christos { "msp430f67761a",2,8 }, 1112 1.3 christos { "msp430f6776a",2,8 }, 1113 1.3 christos { "msp430f6777",2,8 }, 1114 1.3 christos { "msp430f67771",2,8 }, 1115 1.3 christos { "msp430f67771a",2,8 }, 1116 1.3 christos { "msp430f6777a",2,8 }, 1117 1.3 christos { "msp430f6778",2,8 }, 1118 1.3 christos { "msp430f67781",2,8 }, 1119 1.3 christos { "msp430f67781a",2,8 }, 1120 1.3 christos { "msp430f6778a",2,8 }, 1121 1.3 christos { "msp430f6779",2,8 }, 1122 1.3 christos { "msp430f67791",2,8 }, 1123 1.3 christos { "msp430f67791a",2,8 }, 1124 1.3 christos { "msp430f6779a",2,8 }, 1125 1.3 christos { "msp430fe423",0,0 }, 1126 1.3 christos { "msp430fe4232",0,0 }, 1127 1.3 christos { "msp430fe423a",0,0 }, 1128 1.3 christos { "msp430fe4242",0,0 }, 1129 1.3 christos { "msp430fe425",0,0 }, 1130 1.3 christos { "msp430fe4252",0,0 }, 1131 1.3 christos { "msp430fe425a",0,0 }, 1132 1.3 christos { "msp430fe427",0,0 }, 1133 1.3 christos { "msp430fe4272",0,0 }, 1134 1.3 christos { "msp430fe427a",0,0 }, 1135 1.3 christos { "msp430fg4250",0,0 }, 1136 1.3 christos { "msp430fg4260",0,0 }, 1137 1.3 christos { "msp430fg4270",0,0 }, 1138 1.3 christos { "msp430fg437",0,0 }, 1139 1.3 christos { "msp430fg438",0,0 }, 1140 1.3 christos { "msp430fg439",0,0 }, 1141 1.3 christos { "msp430fg4616",1,1 }, 1142 1.3 christos { "msp430fg4617",1,1 }, 1143 1.3 christos { "msp430fg4618",1,1 }, 1144 1.3 christos { "msp430fg4619",1,1 }, 1145 1.3 christos { "msp430fg477",0,0 }, 1146 1.3 christos { "msp430fg478",0,0 }, 1147 1.3 christos { "msp430fg479",0,0 }, 1148 1.3 christos { "msp430fg6425",2,8 }, 1149 1.3 christos { "msp430fg6426",2,8 }, 1150 1.3 christos { "msp430fg6625",2,8 }, 1151 1.3 christos { "msp430fg6626",2,8 }, 1152 1.3 christos { "msp430fr2032",2,0 }, 1153 1.3 christos { "msp430fr2033",2,0 }, 1154 1.6 christos { "msp430fr2110",2,0 }, 1155 1.6 christos { "msp430fr2111",2,0 }, 1156 1.5 christos { "msp430fr2310",2,0 }, 1157 1.5 christos { "msp430fr2311",2,0 }, 1158 1.3 christos { "msp430fr2433",2,8 }, 1159 1.5 christos { "msp430fr2532",2,8 }, 1160 1.5 christos { "msp430fr2533",2,8 }, 1161 1.5 christos { "msp430fr2632",2,8 }, 1162 1.5 christos { "msp430fr2633",2,8 }, 1163 1.3 christos { "msp430fr2xx_4xxgeneric",2,8 }, 1164 1.3 christos { "msp430fr4131",2,0 }, 1165 1.3 christos { "msp430fr4132",2,0 }, 1166 1.3 christos { "msp430fr4133",2,0 }, 1167 1.3 christos { "msp430fr5720",2,8 }, 1168 1.3 christos { "msp430fr5721",2,8 }, 1169 1.3 christos { "msp430fr5722",2,8 }, 1170 1.3 christos { "msp430fr5723",2,8 }, 1171 1.3 christos { "msp430fr5724",2,8 }, 1172 1.3 christos { "msp430fr5725",2,8 }, 1173 1.3 christos { "msp430fr5726",2,8 }, 1174 1.3 christos { "msp430fr5727",2,8 }, 1175 1.3 christos { "msp430fr5728",2,8 }, 1176 1.3 christos { "msp430fr5729",2,8 }, 1177 1.3 christos { "msp430fr5730",2,8 }, 1178 1.3 christos { "msp430fr5731",2,8 }, 1179 1.3 christos { "msp430fr5732",2,8 }, 1180 1.3 christos { "msp430fr5733",2,8 }, 1181 1.3 christos { "msp430fr5734",2,8 }, 1182 1.3 christos { "msp430fr5735",2,8 }, 1183 1.3 christos { "msp430fr5736",2,8 }, 1184 1.3 christos { "msp430fr5737",2,8 }, 1185 1.3 christos { "msp430fr5738",2,8 }, 1186 1.3 christos { "msp430fr5739",2,8 }, 1187 1.3 christos { "msp430fr57xxgeneric",2,8 }, 1188 1.3 christos { "msp430fr5847",2,8 }, 1189 1.3 christos { "msp430fr58471",2,8 }, 1190 1.3 christos { "msp430fr5848",2,8 }, 1191 1.3 christos { "msp430fr5849",2,8 }, 1192 1.3 christos { "msp430fr5857",2,8 }, 1193 1.3 christos { "msp430fr5858",2,8 }, 1194 1.3 christos { "msp430fr5859",2,8 }, 1195 1.3 christos { "msp430fr5867",2,8 }, 1196 1.3 christos { "msp430fr58671",2,8 }, 1197 1.3 christos { "msp430fr5868",2,8 }, 1198 1.3 christos { "msp430fr5869",2,8 }, 1199 1.3 christos { "msp430fr5870",2,8 }, 1200 1.3 christos { "msp430fr5872",2,8 }, 1201 1.3 christos { "msp430fr58721",2,8 }, 1202 1.3 christos { "msp430fr5887",2,8 }, 1203 1.3 christos { "msp430fr5888",2,8 }, 1204 1.3 christos { "msp430fr5889",2,8 }, 1205 1.3 christos { "msp430fr58891",2,8 }, 1206 1.3 christos { "msp430fr5922",2,8 }, 1207 1.3 christos { "msp430fr59221",2,8 }, 1208 1.3 christos { "msp430fr5947",2,8 }, 1209 1.3 christos { "msp430fr59471",2,8 }, 1210 1.3 christos { "msp430fr5948",2,8 }, 1211 1.3 christos { "msp430fr5949",2,8 }, 1212 1.3 christos { "msp430fr5957",2,8 }, 1213 1.3 christos { "msp430fr5958",2,8 }, 1214 1.3 christos { "msp430fr5959",2,8 }, 1215 1.5 christos { "msp430fr5962",2,8 }, 1216 1.5 christos { "msp430fr5964",2,8 }, 1217 1.3 christos { "msp430fr5967",2,8 }, 1218 1.3 christos { "msp430fr5968",2,8 }, 1219 1.3 christos { "msp430fr5969",2,8 }, 1220 1.3 christos { "msp430fr59691",2,8 }, 1221 1.3 christos { "msp430fr5970",2,8 }, 1222 1.3 christos { "msp430fr5972",2,8 }, 1223 1.3 christos { "msp430fr59721",2,8 }, 1224 1.3 christos { "msp430fr5986",2,8 }, 1225 1.3 christos { "msp430fr5987",2,8 }, 1226 1.3 christos { "msp430fr5988",2,8 }, 1227 1.3 christos { "msp430fr5989",2,8 }, 1228 1.3 christos { "msp430fr59891",2,8 }, 1229 1.5 christos { "msp430fr5992",2,8 }, 1230 1.5 christos { "msp430fr5994",2,8 }, 1231 1.6 christos { "msp430fr59941",2,8 }, 1232 1.3 christos { "msp430fr5xx_6xxgeneric",2,8 }, 1233 1.3 christos { "msp430fr6820",2,8 }, 1234 1.3 christos { "msp430fr6822",2,8 }, 1235 1.3 christos { "msp430fr68221",2,8 }, 1236 1.3 christos { "msp430fr6870",2,8 }, 1237 1.3 christos { "msp430fr6872",2,8 }, 1238 1.3 christos { "msp430fr68721",2,8 }, 1239 1.3 christos { "msp430fr6877",2,8 }, 1240 1.3 christos { "msp430fr6879",2,8 }, 1241 1.3 christos { "msp430fr68791",2,8 }, 1242 1.3 christos { "msp430fr6887",2,8 }, 1243 1.3 christos { "msp430fr6888",2,8 }, 1244 1.3 christos { "msp430fr6889",2,8 }, 1245 1.3 christos { "msp430fr68891",2,8 }, 1246 1.3 christos { "msp430fr6920",2,8 }, 1247 1.3 christos { "msp430fr6922",2,8 }, 1248 1.3 christos { "msp430fr69221",2,8 }, 1249 1.3 christos { "msp430fr6927",2,8 }, 1250 1.3 christos { "msp430fr69271",2,8 }, 1251 1.3 christos { "msp430fr6928",2,8 }, 1252 1.3 christos { "msp430fr6970",2,8 }, 1253 1.3 christos { "msp430fr6972",2,8 }, 1254 1.3 christos { "msp430fr69721",2,8 }, 1255 1.3 christos { "msp430fr6977",2,8 }, 1256 1.3 christos { "msp430fr6979",2,8 }, 1257 1.3 christos { "msp430fr69791",2,8 }, 1258 1.3 christos { "msp430fr6987",2,8 }, 1259 1.3 christos { "msp430fr6988",2,8 }, 1260 1.3 christos { "msp430fr6989",2,8 }, 1261 1.3 christos { "msp430fr69891",2,8 }, 1262 1.3 christos { "msp430fw423",0,0 }, 1263 1.3 christos { "msp430fw425",0,0 }, 1264 1.3 christos { "msp430fw427",0,0 }, 1265 1.3 christos { "msp430fw428",0,0 }, 1266 1.3 christos { "msp430fw429",0,0 }, 1267 1.3 christos { "msp430g2001",0,0 }, 1268 1.3 christos { "msp430g2101",0,0 }, 1269 1.3 christos { "msp430g2102",0,0 }, 1270 1.3 christos { "msp430g2111",0,0 }, 1271 1.3 christos { "msp430g2112",0,0 }, 1272 1.3 christos { "msp430g2113",0,0 }, 1273 1.3 christos { "msp430g2121",0,0 }, 1274 1.3 christos { "msp430g2131",0,0 }, 1275 1.3 christos { "msp430g2132",0,0 }, 1276 1.3 christos { "msp430g2152",0,0 }, 1277 1.3 christos { "msp430g2153",0,0 }, 1278 1.3 christos { "msp430g2201",0,0 }, 1279 1.3 christos { "msp430g2202",0,0 }, 1280 1.3 christos { "msp430g2203",0,0 }, 1281 1.3 christos { "msp430g2210",0,0 }, 1282 1.3 christos { "msp430g2211",0,0 }, 1283 1.3 christos { "msp430g2212",0,0 }, 1284 1.3 christos { "msp430g2213",0,0 }, 1285 1.3 christos { "msp430g2221",0,0 }, 1286 1.3 christos { "msp430g2230",0,0 }, 1287 1.3 christos { "msp430g2231",0,0 }, 1288 1.3 christos { "msp430g2232",0,0 }, 1289 1.3 christos { "msp430g2233",0,0 }, 1290 1.3 christos { "msp430g2252",0,0 }, 1291 1.3 christos { "msp430g2253",0,0 }, 1292 1.3 christos { "msp430g2302",0,0 }, 1293 1.3 christos { "msp430g2303",0,0 }, 1294 1.3 christos { "msp430g2312",0,0 }, 1295 1.3 christos { "msp430g2313",0,0 }, 1296 1.3 christos { "msp430g2332",0,0 }, 1297 1.3 christos { "msp430g2333",0,0 }, 1298 1.3 christos { "msp430g2352",0,0 }, 1299 1.3 christos { "msp430g2353",0,0 }, 1300 1.3 christos { "msp430g2402",0,0 }, 1301 1.3 christos { "msp430g2403",0,0 }, 1302 1.3 christos { "msp430g2412",0,0 }, 1303 1.3 christos { "msp430g2413",0,0 }, 1304 1.3 christos { "msp430g2432",0,0 }, 1305 1.3 christos { "msp430g2433",0,0 }, 1306 1.3 christos { "msp430g2444",0,0 }, 1307 1.3 christos { "msp430g2452",0,0 }, 1308 1.3 christos { "msp430g2453",0,0 }, 1309 1.3 christos { "msp430g2513",0,0 }, 1310 1.3 christos { "msp430g2533",0,0 }, 1311 1.3 christos { "msp430g2544",0,0 }, 1312 1.3 christos { "msp430g2553",0,0 }, 1313 1.3 christos { "msp430g2744",0,0 }, 1314 1.3 christos { "msp430g2755",0,0 }, 1315 1.3 christos { "msp430g2855",0,0 }, 1316 1.3 christos { "msp430g2955",0,0 }, 1317 1.3 christos { "msp430i2020",0,2 }, 1318 1.3 christos { "msp430i2021",0,2 }, 1319 1.3 christos { "msp430i2030",0,2 }, 1320 1.3 christos { "msp430i2031",0,2 }, 1321 1.3 christos { "msp430i2040",0,2 }, 1322 1.3 christos { "msp430i2041",0,2 }, 1323 1.3 christos { "msp430i2xxgeneric",0,2 }, 1324 1.3 christos { "msp430l092",0,0 }, 1325 1.3 christos { "msp430p112",0,0 }, 1326 1.3 christos { "msp430p313",0,0 }, 1327 1.3 christos { "msp430p315",0,0 }, 1328 1.3 christos { "msp430p315s",0,0 }, 1329 1.3 christos { "msp430p325",0,0 }, 1330 1.3 christos { "msp430p337",0,1 }, 1331 1.3 christos { "msp430sl5438a",2,8 }, 1332 1.3 christos { "msp430tch5e",0,0 }, 1333 1.3 christos { "msp430xgeneric",2,8 }, 1334 1.3 christos { "rf430f5144",2,8 }, 1335 1.3 christos { "rf430f5155",2,8 }, 1336 1.3 christos { "rf430f5175",2,8 }, 1337 1.3 christos { "rf430frl152h",0,0 }, 1338 1.3 christos { "rf430frl152h_rom",0,0 }, 1339 1.3 christos { "rf430frl153h",0,0 }, 1340 1.3 christos { "rf430frl153h_rom",0,0 }, 1341 1.3 christos { "rf430frl154h",0,0 }, 1342 1.3 christos { "rf430frl154h_rom",0,0 } 1343 1.3 christos }; 1344 1.1 christos 1345 1.1 christos int 1346 1.5 christos md_parse_option (int c, const char * arg) 1347 1.1 christos { 1348 1.1 christos switch (c) 1349 1.1 christos { 1350 1.3 christos case OPTION_SILICON_ERRATA: 1351 1.3 christos case OPTION_SILICON_ERRATA_WARN: 1352 1.3 christos { 1353 1.3 christos signed int i; 1354 1.3 christos const struct 1355 1.3 christos { 1356 1.5 christos const char * name; 1357 1.3 christos unsigned int length; 1358 1.3 christos unsigned int bitfield; 1359 1.3 christos } erratas[] = 1360 1.3 christos { 1361 1.3 christos { STRING_COMMA_LEN ("cpu4"), SILICON_ERRATA_CPU4 }, 1362 1.3 christos { STRING_COMMA_LEN ("cpu8"), SILICON_ERRATA_CPU8 }, 1363 1.3 christos { STRING_COMMA_LEN ("cpu11"), SILICON_ERRATA_CPU11 }, 1364 1.3 christos { STRING_COMMA_LEN ("cpu12"), SILICON_ERRATA_CPU12 }, 1365 1.3 christos { STRING_COMMA_LEN ("cpu13"), SILICON_ERRATA_CPU13 }, 1366 1.3 christos { STRING_COMMA_LEN ("cpu19"), SILICON_ERRATA_CPU19 }, 1367 1.3 christos }; 1368 1.3 christos 1369 1.3 christos do 1370 1.3 christos { 1371 1.3 christos for (i = ARRAY_SIZE (erratas); i--;) 1372 1.3 christos if (strncasecmp (arg, erratas[i].name, erratas[i].length) == 0) 1373 1.3 christos { 1374 1.3 christos if (c == OPTION_SILICON_ERRATA) 1375 1.3 christos silicon_errata_fix |= erratas[i].bitfield; 1376 1.3 christos else 1377 1.3 christos silicon_errata_warn |= erratas[i].bitfield; 1378 1.3 christos arg += erratas[i].length; 1379 1.3 christos break; 1380 1.3 christos } 1381 1.3 christos if (i < 0) 1382 1.3 christos { 1383 1.3 christos as_warn (_("Unrecognised CPU errata name starting here: %s"), arg); 1384 1.3 christos break; 1385 1.3 christos } 1386 1.3 christos if (*arg == 0) 1387 1.3 christos break; 1388 1.3 christos if (*arg != ',') 1389 1.3 christos as_warn (_("Expecting comma after CPU errata name, not: %s"), arg); 1390 1.3 christos else 1391 1.3 christos arg ++; 1392 1.3 christos } 1393 1.3 christos while (*arg != 0); 1394 1.3 christos } 1395 1.3 christos return 1; 1396 1.3 christos 1397 1.1 christos case OPTION_MMCU: 1398 1.3 christos if (arg == NULL) 1399 1.3 christos as_fatal (_("MCU option requires a name\n")); 1400 1.1 christos 1401 1.3 christos if (strcasecmp ("msp430", arg) == 0) 1402 1.3 christos selected_isa = MSP_ISA_430; 1403 1.3 christos else if (strcasecmp ("msp430xv2", arg) == 0) 1404 1.3 christos selected_isa = MSP_ISA_430Xv2; 1405 1.3 christos else if (strcasecmp ("msp430x", arg) == 0) 1406 1.3 christos selected_isa = MSP_ISA_430X; 1407 1.3 christos else 1408 1.1 christos { 1409 1.3 christos int i; 1410 1.3 christos 1411 1.3 christos for (i = ARRAY_SIZE (msp430_mcu_data); i--;) 1412 1.3 christos if (strcasecmp (msp430_mcu_data[i].name, arg) == 0) 1413 1.3 christos { 1414 1.3 christos switch (msp430_mcu_data[i].revision) 1415 1.3 christos { 1416 1.3 christos case 0: selected_isa = MSP_ISA_430; break; 1417 1.3 christos case 1: selected_isa = MSP_ISA_430X; break; 1418 1.3 christos case 2: selected_isa = MSP_ISA_430Xv2; break; 1419 1.3 christos } 1420 1.3 christos break; 1421 1.3 christos } 1422 1.1 christos } 1423 1.3 christos /* It is not an error if we do not match the MCU name. */ 1424 1.3 christos return 1; 1425 1.1 christos 1426 1.3 christos case OPTION_MCPU: 1427 1.3 christos if (strcmp (arg, "430") == 0 1428 1.3 christos || strcasecmp (arg, "msp430") == 0) 1429 1.3 christos selected_isa = MSP_ISA_430; 1430 1.3 christos else if (strcasecmp (arg, "430x") == 0 1431 1.3 christos || strcasecmp (arg, "msp430x") == 0) 1432 1.3 christos selected_isa = MSP_ISA_430X; 1433 1.3 christos else if (strcasecmp (arg, "430xv2") == 0 1434 1.3 christos || strcasecmp (arg, "msp430xv2") == 0) 1435 1.3 christos selected_isa = MSP_ISA_430Xv2; 1436 1.1 christos else 1437 1.3 christos as_fatal (_("unrecognised argument to -mcpu option '%s'"), arg); 1438 1.1 christos return 1; 1439 1.3 christos 1440 1.1 christos case OPTION_RELAX: 1441 1.3 christos msp430_enable_relax = 1; 1442 1.1 christos return 1; 1443 1.3 christos 1444 1.1 christos case OPTION_POLYMORPHS: 1445 1.1 christos msp430_enable_polys = 1; 1446 1.1 christos return 1; 1447 1.3 christos 1448 1.3 christos case OPTION_LARGE: 1449 1.8 christos large_model = true; 1450 1.3 christos return 1; 1451 1.3 christos 1452 1.3 christos case OPTION_NO_INTR_NOPS: 1453 1.8 christos gen_interrupt_nops = false; 1454 1.3 christos return 1; 1455 1.3 christos case OPTION_INTR_NOPS: 1456 1.8 christos gen_interrupt_nops = true; 1457 1.3 christos return 1; 1458 1.3 christos 1459 1.3 christos case OPTION_WARN_INTR_NOPS: 1460 1.8 christos warn_interrupt_nops = true; 1461 1.3 christos return 1; 1462 1.3 christos case OPTION_NO_WARN_INTR_NOPS: 1463 1.8 christos warn_interrupt_nops = false; 1464 1.3 christos return 1; 1465 1.3 christos 1466 1.7 christos case OPTION_UNKNOWN_INTR_NOPS: 1467 1.8 christos do_unknown_interrupt_nops = true; 1468 1.7 christos return 1; 1469 1.7 christos case OPTION_NO_UNKNOWN_INTR_NOPS: 1470 1.8 christos do_unknown_interrupt_nops = false; 1471 1.7 christos return 1; 1472 1.7 christos 1473 1.3 christos case OPTION_MOVE_DATA: 1474 1.8 christos /* Silently ignored. */ 1475 1.3 christos return 1; 1476 1.6 christos 1477 1.6 christos case OPTION_DATA_REGION: 1478 1.6 christos if (strcmp (arg, "upper") == 0 1479 1.6 christos || strcmp (arg, "either") == 0) 1480 1.8 christos upper_data_region_in_use = true; 1481 1.7 christos if (strcmp (arg, "upper") == 0 1482 1.7 christos || strcmp (arg, "either") == 0 1483 1.7 christos /* With data-region=none, the compiler has generated code assuming 1484 1.7 christos data could be in the upper region, but nothing has been explicitly 1485 1.7 christos placed there. */ 1486 1.7 christos || strcmp (arg, "none") == 0) 1487 1.8 christos lower_data_region_only = false; 1488 1.6 christos return 1; 1489 1.1 christos } 1490 1.1 christos 1491 1.1 christos return 0; 1492 1.1 christos } 1493 1.1 christos 1494 1.3 christos /* The intention here is to have the mere presence of these sections 1495 1.3 christos cause the object to have a reference to a well-known symbol. This 1496 1.3 christos reference pulls in the bits of the runtime (crt0) that initialize 1497 1.3 christos these sections. Thus, for example, the startup code to call 1498 1.3 christos memset() to initialize .bss will only be linked in when there is a 1499 1.3 christos non-empty .bss section. Otherwise, the call would exist but have a 1500 1.3 christos zero length parameter, which is a waste of memory and cycles. 1501 1.3 christos 1502 1.3 christos The code which initializes these sections should have a global 1503 1.3 christos label for these symbols, and should be marked with KEEP() in the 1504 1.3 christos linker script. */ 1505 1.3 christos 1506 1.3 christos static void 1507 1.3 christos msp430_make_init_symbols (const char * name) 1508 1.3 christos { 1509 1.8 christos if (startswith (name, ".bss") 1510 1.8 christos || startswith (name, ".lower.bss") 1511 1.8 christos || startswith (name, ".either.bss") 1512 1.8 christos || startswith (name, ".gnu.linkonce.b.")) 1513 1.3 christos (void) symbol_find_or_make ("__crt0_init_bss"); 1514 1.3 christos 1515 1.8 christos if (startswith (name, ".data") 1516 1.8 christos || startswith (name, ".lower.data") 1517 1.8 christos || startswith (name, ".either.data") 1518 1.8 christos || startswith (name, ".gnu.linkonce.d.")) 1519 1.3 christos (void) symbol_find_or_make ("__crt0_movedata"); 1520 1.3 christos /* Note - data assigned to the .either.data section may end up being 1521 1.3 christos placed in the .upper.data section if the .lower.data section is 1522 1.6 christos full. Hence the need to define the crt0 symbol. 1523 1.6 christos The linker may create upper or either data sections, even when none exist 1524 1.6 christos at the moment, so use the value of the data-region flag to determine if 1525 1.6 christos the symbol is needed. */ 1526 1.8 christos if (startswith (name, ".either.data") 1527 1.8 christos || startswith (name, ".upper.data") 1528 1.6 christos || upper_data_region_in_use) 1529 1.3 christos (void) symbol_find_or_make ("__crt0_move_highdata"); 1530 1.3 christos 1531 1.3 christos /* See note about .either.data above. */ 1532 1.8 christos if (startswith (name, ".upper.bss") 1533 1.8 christos || startswith (name, ".either.bss") 1534 1.6 christos || upper_data_region_in_use) 1535 1.3 christos (void) symbol_find_or_make ("__crt0_init_highbss"); 1536 1.7 christos 1537 1.7 christos /* The following symbols are for the crt0 functions that run through 1538 1.7 christos the different .*_array sections and call the functions placed there. 1539 1.7 christos - init_array stores global static C++ constructors to run before main. 1540 1.7 christos - preinit_array is not expected to ever be used for MSP430. 1541 1.7 christos GCC only places initialization functions for runtime "sanitizers" 1542 1.7 christos (i.e. {a,l,t,u}san) and "virtual table verification" in preinit_array. 1543 1.7 christos - fini_array stores global static C++ destructors to run after calling 1544 1.7 christos exit() or returning from main. 1545 1.7 christos __crt0_run_array is required to actually call the functions in the above 1546 1.7 christos arrays. */ 1547 1.8 christos if (startswith (name, ".init_array")) 1548 1.7 christos { 1549 1.7 christos (void) symbol_find_or_make ("__crt0_run_init_array"); 1550 1.7 christos (void) symbol_find_or_make ("__crt0_run_array"); 1551 1.7 christos } 1552 1.8 christos else if (startswith (name, ".preinit_array")) 1553 1.7 christos { 1554 1.7 christos (void) symbol_find_or_make ("__crt0_run_preinit_array"); 1555 1.7 christos (void) symbol_find_or_make ("__crt0_run_array"); 1556 1.7 christos } 1557 1.8 christos else if (startswith (name, ".fini_array")) 1558 1.7 christos { 1559 1.7 christos (void) symbol_find_or_make ("__crt0_run_fini_array"); 1560 1.7 christos (void) symbol_find_or_make ("__crt0_run_array"); 1561 1.7 christos } 1562 1.3 christos } 1563 1.3 christos 1564 1.3 christos static void 1565 1.3 christos msp430_section (int arg) 1566 1.3 christos { 1567 1.3 christos char * saved_ilp = input_line_pointer; 1568 1.5 christos const char * name = obj_elf_section_name (); 1569 1.3 christos 1570 1.3 christos msp430_make_init_symbols (name); 1571 1.3 christos 1572 1.3 christos input_line_pointer = saved_ilp; 1573 1.3 christos obj_elf_section (arg); 1574 1.3 christos } 1575 1.3 christos 1576 1.3 christos void 1577 1.3 christos msp430_frob_section (asection *sec) 1578 1.3 christos { 1579 1.3 christos const char *name = sec->name; 1580 1.3 christos 1581 1.3 christos if (sec->size == 0) 1582 1.3 christos return; 1583 1.3 christos 1584 1.3 christos msp430_make_init_symbols (name); 1585 1.3 christos } 1586 1.3 christos 1587 1.3 christos static void 1588 1.3 christos msp430_lcomm (int ignore ATTRIBUTE_UNUSED) 1589 1.3 christos { 1590 1.3 christos symbolS *symbolP = s_comm_internal (0, s_lcomm_internal); 1591 1.3 christos 1592 1.3 christos if (symbolP) 1593 1.3 christos symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT; 1594 1.3 christos (void) symbol_find_or_make ("__crt0_init_bss"); 1595 1.3 christos } 1596 1.3 christos 1597 1.3 christos static void 1598 1.3 christos msp430_comm (int needs_align) 1599 1.3 christos { 1600 1.3 christos s_comm_internal (needs_align, elf_common_parse); 1601 1.3 christos (void) symbol_find_or_make ("__crt0_init_bss"); 1602 1.3 christos } 1603 1.3 christos 1604 1.3 christos static void 1605 1.3 christos msp430_refsym (int arg ATTRIBUTE_UNUSED) 1606 1.3 christos { 1607 1.3 christos char sym_name[1024]; 1608 1.3 christos input_line_pointer = extract_word (input_line_pointer, sym_name, 1024); 1609 1.3 christos 1610 1.3 christos (void) symbol_find_or_make (sym_name); 1611 1.3 christos } 1612 1.1 christos 1613 1.7 christos /* Handle a .mspabi_attribute or .gnu_attribute directive. 1614 1.7 christos attr_type is 0 for .mspabi_attribute or 1 for .gnu_attribute. 1615 1.7 christos This is only used for validating the attributes in the assembly file against 1616 1.7 christos the options gas has been invoked with. If the attributes and options are 1617 1.7 christos compatible then we add the attributes to the assembly file in 1618 1.9 christos msp430_md_finish. */ 1619 1.7 christos static void 1620 1.7 christos msp430_object_attribute (int attr_type) 1621 1.7 christos { 1622 1.7 christos char tag_name_s[32]; 1623 1.7 christos char tag_value_s[32]; 1624 1.7 christos int tag_name, tag_value; 1625 1.7 christos /* First operand is the tag name, second is the tag value e.g. 1626 1.7 christos ".mspabi_attribute 4, 2". */ 1627 1.7 christos input_line_pointer = extract_operand (input_line_pointer, tag_name_s, 32); 1628 1.7 christos input_line_pointer = extract_operand (input_line_pointer, tag_value_s, 32); 1629 1.7 christos tag_name = atoi (tag_name_s); 1630 1.7 christos tag_value = atoi (tag_value_s); 1631 1.7 christos /* If the attribute directive is present, the tag_value should never be set 1632 1.7 christos to 0. */ 1633 1.7 christos if (tag_name == 0 || tag_value == 0) 1634 1.7 christos as_bad (_("bad arguments \"%s\" and/or \"%s\" in %s directive"), 1635 1.7 christos tag_name_s, tag_value_s, (attr_type ? ".gnu_attribute" 1636 1.7 christos : ".mspabi_attribute")); 1637 1.7 christos else if (attr_type == 0) 1638 1.7 christos /* Handle .mspabi_attribute. */ 1639 1.7 christos switch (tag_name) 1640 1.7 christos { 1641 1.7 christos case OFBA_MSPABI_Tag_ISA: 1642 1.7 christos switch (tag_value) 1643 1.7 christos { 1644 1.7 christos case OFBA_MSPABI_Val_ISA_MSP430: 1645 1.7 christos if (target_is_430x ()) 1646 1.7 christos as_bad (_("file was compiled for the 430 ISA but the %s ISA is " 1647 1.7 christos "selected"), (target_is_430xv2 () ? "430X" : "430Xv2")); 1648 1.7 christos break; 1649 1.7 christos case OFBA_MSPABI_Val_ISA_MSP430X: 1650 1.7 christos if (!target_is_430x ()) 1651 1.7 christos as_bad (_("file was compiled for the 430X ISA but the 430 ISA is " 1652 1.7 christos "selected")); 1653 1.7 christos break; 1654 1.7 christos default: 1655 1.7 christos as_bad (_("unknown MSPABI build attribute value '%d' for " 1656 1.7 christos "OFBA_MSPABI_Tag_ISA(%d) in .mspabi_attribute directive"), 1657 1.7 christos tag_value, OFBA_MSPABI_Tag_ISA); 1658 1.7 christos break; 1659 1.7 christos } 1660 1.7 christos break; 1661 1.7 christos case OFBA_MSPABI_Tag_Code_Model: 1662 1.7 christos /* Fall through. */ 1663 1.7 christos case OFBA_MSPABI_Tag_Data_Model: 1664 1.7 christos /* FIXME: Might we want to set the memory model to large if the assembly 1665 1.7 christos file has the large model attribute, but -ml has not been passed? */ 1666 1.7 christos switch (tag_value) 1667 1.7 christos { 1668 1.7 christos case OFBA_MSPABI_Val_Code_Model_SMALL: 1669 1.7 christos if (large_model) 1670 1.7 christos as_bad (_("file was compiled for the small memory model, but the " 1671 1.7 christos "large memory model is selected")); 1672 1.7 christos break; 1673 1.7 christos case OFBA_MSPABI_Val_Code_Model_LARGE: 1674 1.7 christos if (!large_model) 1675 1.7 christos as_bad (_("file was compiled for the large memory model, " 1676 1.7 christos "but the small memory model is selected")); 1677 1.7 christos break; 1678 1.7 christos default: 1679 1.7 christos as_bad (_("unknown MSPABI build attribute value '%d' for %s(%d) " 1680 1.7 christos "in .mspabi_attribute directive"), tag_value, 1681 1.7 christos (tag_name == OFBA_MSPABI_Tag_Code_Model 1682 1.7 christos ? "OFBA_MSPABI_Tag_Code_Model" 1683 1.7 christos : "OFBA_MSPABI_Tag_Data_Model"), 1684 1.7 christos (tag_name == OFBA_MSPABI_Tag_Code_Model 1685 1.7 christos ? OFBA_MSPABI_Tag_Code_Model 1686 1.7 christos : OFBA_MSPABI_Tag_Data_Model)); 1687 1.7 christos break; 1688 1.7 christos } 1689 1.7 christos break; 1690 1.7 christos default: 1691 1.7 christos as_bad (_("unknown MSPABI build attribute tag '%d' in " 1692 1.7 christos ".mspabi_attribute directive"), tag_name); 1693 1.7 christos break; 1694 1.7 christos } 1695 1.7 christos else if (attr_type == 1) 1696 1.7 christos /* Handle .gnu_attribute. */ 1697 1.7 christos switch (tag_name) 1698 1.7 christos { 1699 1.7 christos case Tag_GNU_MSP430_Data_Region: 1700 1.7 christos /* This attribute is only applicable in the large memory model. */ 1701 1.7 christos if (!large_model) 1702 1.7 christos break; 1703 1.7 christos switch (tag_value) 1704 1.7 christos { 1705 1.7 christos case Val_GNU_MSP430_Data_Region_Lower: 1706 1.7 christos if (!lower_data_region_only) 1707 1.7 christos as_bad (_("file was compiled assuming all data will be in the " 1708 1.7 christos "lower memory region, but the upper region is in use")); 1709 1.7 christos break; 1710 1.7 christos case Val_GNU_MSP430_Data_Region_Any: 1711 1.7 christos if (lower_data_region_only) 1712 1.7 christos as_bad (_("file was compiled assuming data could be in the upper " 1713 1.7 christos "memory region, but the lower data region is " 1714 1.7 christos "exclusively in use")); 1715 1.7 christos break; 1716 1.7 christos default: 1717 1.7 christos as_bad (_("unknown GNU build attribute value '%d' for " 1718 1.7 christos "Tag_GNU_MSP430_Data_Region(%d) in .gnu_attribute " 1719 1.7 christos "directive"), tag_value, Tag_GNU_MSP430_Data_Region); 1720 1.7 christos } 1721 1.7 christos } 1722 1.7 christos else 1723 1.7 christos as_bad (_("internal: unexpected argument '%d' to msp430_object_attribute"), 1724 1.7 christos attr_type); 1725 1.7 christos } 1726 1.7 christos 1727 1.1 christos const pseudo_typeS md_pseudo_table[] = 1728 1.1 christos { 1729 1.3 christos {"arch", msp430_set_arch, OPTION_MMCU}, 1730 1.3 christos {"cpu", msp430_set_arch, OPTION_MCPU}, 1731 1.1 christos {"profiler", msp430_profiler, 0}, 1732 1.3 christos {"section", msp430_section, 0}, 1733 1.3 christos {"section.s", msp430_section, 0}, 1734 1.3 christos {"sect", msp430_section, 0}, 1735 1.3 christos {"sect.s", msp430_section, 0}, 1736 1.3 christos {"pushsection", msp430_section, 1}, 1737 1.3 christos {"refsym", msp430_refsym, 0}, 1738 1.3 christos {"comm", msp430_comm, 0}, 1739 1.3 christos {"lcomm", msp430_lcomm, 0}, 1740 1.7 christos {"mspabi_attribute", msp430_object_attribute, 0}, 1741 1.7 christos {"gnu_attribute", msp430_object_attribute, 1}, 1742 1.1 christos {NULL, NULL, 0} 1743 1.1 christos }; 1744 1.1 christos 1745 1.10 christos const char md_shortopts[] = "mm:,mP,mQ,ml,mN,mn,my,mY,mu,mU"; 1746 1.1 christos 1747 1.10 christos const struct option md_longopts[] = 1748 1.1 christos { 1749 1.3 christos {"msilicon-errata", required_argument, NULL, OPTION_SILICON_ERRATA}, 1750 1.3 christos {"msilicon-errata-warn", required_argument, NULL, OPTION_SILICON_ERRATA_WARN}, 1751 1.1 christos {"mmcu", required_argument, NULL, OPTION_MMCU}, 1752 1.3 christos {"mcpu", required_argument, NULL, OPTION_MCPU}, 1753 1.1 christos {"mP", no_argument, NULL, OPTION_POLYMORPHS}, 1754 1.1 christos {"mQ", no_argument, NULL, OPTION_RELAX}, 1755 1.3 christos {"ml", no_argument, NULL, OPTION_LARGE}, 1756 1.3 christos {"mN", no_argument, NULL, OPTION_NO_INTR_NOPS}, 1757 1.3 christos {"mn", no_argument, NULL, OPTION_INTR_NOPS}, 1758 1.3 christos {"mY", no_argument, NULL, OPTION_NO_WARN_INTR_NOPS}, 1759 1.3 christos {"my", no_argument, NULL, OPTION_WARN_INTR_NOPS}, 1760 1.7 christos {"mu", no_argument, NULL, OPTION_UNKNOWN_INTR_NOPS}, 1761 1.7 christos {"mU", no_argument, NULL, OPTION_NO_UNKNOWN_INTR_NOPS}, 1762 1.3 christos {"md", no_argument, NULL, OPTION_MOVE_DATA}, 1763 1.6 christos {"mdata-region", required_argument, NULL, OPTION_DATA_REGION}, 1764 1.1 christos {NULL, no_argument, NULL, 0} 1765 1.1 christos }; 1766 1.1 christos 1767 1.10 christos const size_t md_longopts_size = sizeof (md_longopts); 1768 1.1 christos 1769 1.1 christos void 1770 1.1 christos md_show_usage (FILE * stream) 1771 1.1 christos { 1772 1.1 christos fprintf (stream, 1773 1.1 christos _("MSP430 options:\n" 1774 1.3 christos " -mmcu=<msp430-name> - select microcontroller type\n" 1775 1.3 christos " -mcpu={430|430x|430xv2} - select microcontroller architecture\n")); 1776 1.3 christos fprintf (stream, 1777 1.3 christos _(" -msilicon-errata=<name>[,<name>...] - enable fixups for silicon errata\n" 1778 1.3 christos " -msilicon-errata-warn=<name>[,<name>...] - warn when a fixup might be needed\n" 1779 1.3 christos " supported errata names: cpu4, cpu8, cpu11, cpu12, cpu13, cpu19\n")); 1780 1.1 christos fprintf (stream, 1781 1.1 christos _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n" 1782 1.1 christos " -mP - enable polymorph instructions\n")); 1783 1.3 christos fprintf (stream, 1784 1.3 christos _(" -ml - enable large code model\n")); 1785 1.3 christos fprintf (stream, 1786 1.3 christos _(" -mN - do not insert NOPs after changing interrupts (default)\n")); 1787 1.3 christos fprintf (stream, 1788 1.3 christos _(" -mn - insert a NOP after changing interrupts\n")); 1789 1.3 christos fprintf (stream, 1790 1.3 christos _(" -mY - do not warn about missing NOPs after changing interrupts\n")); 1791 1.3 christos fprintf (stream, 1792 1.3 christos _(" -my - warn about missing NOPs after changing interrupts (default)\n")); 1793 1.3 christos fprintf (stream, 1794 1.7 christos _(" -mU - for an instruction which changes interrupt state, but where it is not\n" 1795 1.7 christos " known how the state is changed, do not warn/insert NOPs\n")); 1796 1.7 christos fprintf (stream, 1797 1.7 christos _(" -mu - for an instruction which changes interrupt state, but where it is not\n" 1798 1.7 christos " known how the state is changed, warn/insert NOPs (default)\n" 1799 1.7 christos " -mn and/or -my are required for this to have any effect\n")); 1800 1.7 christos fprintf (stream, 1801 1.6 christos _(" -mdata-region={none|lower|upper|either} - select region data will be\n" 1802 1.6 christos " placed in.\n")); 1803 1.1 christos } 1804 1.1 christos 1805 1.1 christos symbolS * 1806 1.1 christos md_undefined_symbol (char * name ATTRIBUTE_UNUSED) 1807 1.1 christos { 1808 1.3 christos return NULL; 1809 1.1 christos } 1810 1.1 christos 1811 1.1 christos static char * 1812 1.1 christos extract_cmd (char * from, char * to, int limit) 1813 1.1 christos { 1814 1.1 christos int size = 0; 1815 1.1 christos 1816 1.10 christos while (*from && ! is_whitespace (*from) && *from != '.' && limit > size) 1817 1.1 christos { 1818 1.1 christos *(to + size) = *from; 1819 1.1 christos from++; 1820 1.1 christos size++; 1821 1.1 christos } 1822 1.1 christos 1823 1.1 christos *(to + size) = 0; 1824 1.1 christos 1825 1.1 christos return from; 1826 1.1 christos } 1827 1.1 christos 1828 1.5 christos const char * 1829 1.1 christos md_atof (int type, char * litP, int * sizeP) 1830 1.1 christos { 1831 1.8 christos return ieee_md_atof (type, litP, sizeP, false); 1832 1.1 christos } 1833 1.1 christos 1834 1.1 christos void 1835 1.1 christos md_begin (void) 1836 1.1 christos { 1837 1.1 christos struct msp430_opcode_s * opcode; 1838 1.8 christos msp430_hash = str_htab_create (); 1839 1.1 christos 1840 1.1 christos for (opcode = msp430_opcodes; opcode->name; opcode++) 1841 1.8 christos str_hash_insert (msp430_hash, opcode->name, opcode, 0); 1842 1.1 christos 1843 1.3 christos bfd_set_arch_mach (stdoutput, TARGET_ARCH, 1844 1.3 christos target_is_430x () ? bfd_mach_msp430x : bfd_mach_msp11); 1845 1.5 christos 1846 1.5 christos /* Set linkrelax here to avoid fixups in most sections. */ 1847 1.5 christos linkrelax = 1; 1848 1.1 christos } 1849 1.1 christos 1850 1.8 christos static inline bool 1851 1.7 christos is_regname_end (char c) 1852 1.7 christos { 1853 1.7 christos return (c == 0 || ! ISALNUM (c)); 1854 1.7 christos } 1855 1.7 christos 1856 1.3 christos /* Returns the register number equivalent to the string T. 1857 1.3 christos Returns -1 if there is no such register. 1858 1.3 christos Skips a leading 'r' or 'R' character if there is one. 1859 1.3 christos Handles the register aliases PC and SP. */ 1860 1.3 christos 1861 1.3 christos static signed int 1862 1.1 christos check_reg (char * t) 1863 1.1 christos { 1864 1.7 christos char * endt; 1865 1.7 christos signed long int val; 1866 1.3 christos 1867 1.7 christos if (t == NULL || t[0] == 0) 1868 1.3 christos return -1; 1869 1.3 christos 1870 1.3 christos if (*t == 'r' || *t == 'R') 1871 1.3 christos ++t; 1872 1.1 christos 1873 1.7 christos if (strncasecmp (t, "pc", 2) == 0 && is_regname_end (t[2])) 1874 1.3 christos return 0; 1875 1.3 christos 1876 1.7 christos if (strncasecmp (t, "sp", 2) == 0 && is_regname_end (t[2])) 1877 1.1 christos return 1; 1878 1.1 christos 1879 1.7 christos if (strncasecmp (t, "sr", 2) == 0 && is_regname_end (t[2])) 1880 1.3 christos return 2; 1881 1.3 christos 1882 1.7 christos if (*t == '0' && is_regname_end (t[1])) 1883 1.3 christos return 0; 1884 1.3 christos 1885 1.7 christos val = strtol (t, & endt, 0); 1886 1.1 christos 1887 1.3 christos if (val < 1 || val > 15) 1888 1.3 christos return -1; 1889 1.1 christos 1890 1.7 christos if (is_regname_end (*endt)) 1891 1.7 christos return val; 1892 1.7 christos 1893 1.7 christos return -1; 1894 1.1 christos } 1895 1.1 christos 1896 1.1 christos static int 1897 1.1 christos msp430_srcoperand (struct msp430_operand_s * op, 1898 1.3 christos char * l, 1899 1.3 christos int bin, 1900 1.8 christos bool * imm_op, 1901 1.8 christos bool allow_20bit_values, 1902 1.8 christos bool constants_allowed) 1903 1.1 christos { 1904 1.6 christos char * end; 1905 1.1 christos char *__tl = l; 1906 1.1 christos 1907 1.1 christos /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */ 1908 1.1 christos if (*l == '#') 1909 1.1 christos { 1910 1.1 christos char *h = l; 1911 1.1 christos int vshift = -1; 1912 1.1 christos int rval = 0; 1913 1.7 christos /* Use all parts of the constant expression by default. */ 1914 1.7 christos enum msp430_expp_e expp = MSP_EXPP_ALL; 1915 1.1 christos 1916 1.1 christos /* Check if there is: 1917 1.1 christos llo(x) - least significant 16 bits, x &= 0xffff 1918 1.1 christos lhi(x) - x = (x >> 16) & 0xffff, 1919 1.1 christos hlo(x) - x = (x >> 32) & 0xffff, 1920 1.1 christos hhi(x) - x = (x >> 48) & 0xffff 1921 1.7 christos The value _MUST_ be an immediate expression: #hlo(1231231231). */ 1922 1.1 christos 1923 1.8 christos *imm_op = true; 1924 1.1 christos 1925 1.1 christos if (strncasecmp (h, "#llo(", 5) == 0) 1926 1.1 christos { 1927 1.1 christos vshift = 0; 1928 1.1 christos rval = 3; 1929 1.7 christos expp = MSP_EXPP_LLO; 1930 1.1 christos } 1931 1.1 christos else if (strncasecmp (h, "#lhi(", 5) == 0) 1932 1.1 christos { 1933 1.1 christos vshift = 1; 1934 1.1 christos rval = 3; 1935 1.7 christos expp = MSP_EXPP_LHI; 1936 1.1 christos } 1937 1.1 christos else if (strncasecmp (h, "#hlo(", 5) == 0) 1938 1.1 christos { 1939 1.1 christos vshift = 2; 1940 1.1 christos rval = 3; 1941 1.7 christos expp = MSP_EXPP_HLO; 1942 1.1 christos } 1943 1.1 christos else if (strncasecmp (h, "#hhi(", 5) == 0) 1944 1.1 christos { 1945 1.1 christos vshift = 3; 1946 1.1 christos rval = 3; 1947 1.7 christos expp = MSP_EXPP_HHI; 1948 1.1 christos } 1949 1.1 christos else if (strncasecmp (h, "#lo(", 4) == 0) 1950 1.1 christos { 1951 1.1 christos vshift = 0; 1952 1.1 christos rval = 2; 1953 1.7 christos expp = MSP_EXPP_LO; 1954 1.1 christos } 1955 1.1 christos else if (strncasecmp (h, "#hi(", 4) == 0) 1956 1.1 christos { 1957 1.1 christos vshift = 1; 1958 1.1 christos rval = 2; 1959 1.7 christos expp = MSP_EXPP_HI; 1960 1.1 christos } 1961 1.1 christos 1962 1.1 christos op->reg = 0; /* Reg PC. */ 1963 1.1 christos op->am = 3; 1964 1.3 christos op->ol = 1; /* Immediate will follow an instruction. */ 1965 1.1 christos __tl = h + 1 + rval; 1966 1.1 christos op->mode = OP_EXP; 1967 1.3 christos op->vshift = vshift; 1968 1.7 christos op->expp = expp; 1969 1.1 christos 1970 1.6 christos end = parse_exp (__tl, &(op->exp)); 1971 1.6 christos if (end != NULL && *end != 0 && *end != ')' ) 1972 1.6 christos { 1973 1.6 christos as_bad (_("extra characters '%s' at end of immediate expression '%s'"), end, l); 1974 1.6 christos return 1; 1975 1.6 christos } 1976 1.1 christos if (op->exp.X_op == O_constant) 1977 1.1 christos { 1978 1.1 christos int x = op->exp.X_add_number; 1979 1.1 christos 1980 1.1 christos if (vshift == 0) 1981 1.1 christos { 1982 1.1 christos x = x & 0xffff; 1983 1.1 christos op->exp.X_add_number = x; 1984 1.1 christos } 1985 1.1 christos else if (vshift == 1) 1986 1.1 christos { 1987 1.1 christos x = (x >> 16) & 0xffff; 1988 1.1 christos op->exp.X_add_number = x; 1989 1.3 christos op->vshift = 0; 1990 1.1 christos } 1991 1.1 christos else if (vshift > 1) 1992 1.1 christos { 1993 1.1 christos if (x < 0) 1994 1.1 christos op->exp.X_add_number = -1; 1995 1.1 christos else 1996 1.1 christos op->exp.X_add_number = 0; /* Nothing left. */ 1997 1.1 christos x = op->exp.X_add_number; 1998 1.3 christos op->vshift = 0; 1999 1.1 christos } 2000 1.1 christos 2001 1.3 christos if (allow_20bit_values) 2002 1.3 christos { 2003 1.3 christos if (op->exp.X_add_number > 0xfffff || op->exp.X_add_number < -524288) 2004 1.3 christos { 2005 1.3 christos as_bad (_("value 0x%x out of extended range."), x); 2006 1.3 christos return 1; 2007 1.3 christos } 2008 1.3 christos } 2009 1.3 christos else if (op->exp.X_add_number > 65535 || op->exp.X_add_number < -32768) 2010 1.1 christos { 2011 1.1 christos as_bad (_("value %d out of range. Use #lo() or #hi()"), x); 2012 1.1 christos return 1; 2013 1.1 christos } 2014 1.1 christos 2015 1.1 christos /* Now check constants. */ 2016 1.1 christos /* Substitute register mode with a constant generator if applicable. */ 2017 1.1 christos 2018 1.3 christos if (!allow_20bit_values) 2019 1.3 christos x = (short) x; /* Extend sign. */ 2020 1.1 christos 2021 1.3 christos if (! constants_allowed) 2022 1.3 christos ; 2023 1.3 christos else if (x == 0) 2024 1.1 christos { 2025 1.1 christos op->reg = 3; 2026 1.1 christos op->am = 0; 2027 1.1 christos op->ol = 0; 2028 1.1 christos op->mode = OP_REG; 2029 1.1 christos } 2030 1.1 christos else if (x == 1) 2031 1.1 christos { 2032 1.1 christos op->reg = 3; 2033 1.1 christos op->am = 1; 2034 1.1 christos op->ol = 0; 2035 1.1 christos op->mode = OP_REG; 2036 1.1 christos } 2037 1.1 christos else if (x == 2) 2038 1.1 christos { 2039 1.1 christos op->reg = 3; 2040 1.1 christos op->am = 2; 2041 1.1 christos op->ol = 0; 2042 1.1 christos op->mode = OP_REG; 2043 1.1 christos } 2044 1.1 christos else if (x == -1) 2045 1.1 christos { 2046 1.1 christos op->reg = 3; 2047 1.1 christos op->am = 3; 2048 1.1 christos op->ol = 0; 2049 1.1 christos op->mode = OP_REG; 2050 1.1 christos } 2051 1.1 christos else if (x == 4) 2052 1.1 christos { 2053 1.3 christos if (bin == 0x1200 && ! target_is_430x ()) 2054 1.1 christos { 2055 1.3 christos /* CPU4: The shorter form of PUSH #4 is not supported on MSP430. */ 2056 1.3 christos if (silicon_errata_warn & SILICON_ERRATA_CPU4) 2057 1.3 christos as_warn (_("cpu4: not converting PUSH #4 to shorter form")); 2058 1.3 christos /* No need to check silicon_errata_fixes - this fix is always implemented. */ 2059 1.1 christos } 2060 1.1 christos else 2061 1.1 christos { 2062 1.1 christos op->reg = 2; 2063 1.1 christos op->am = 2; 2064 1.1 christos op->ol = 0; 2065 1.1 christos op->mode = OP_REG; 2066 1.1 christos } 2067 1.1 christos } 2068 1.1 christos else if (x == 8) 2069 1.1 christos { 2070 1.3 christos if (bin == 0x1200 && ! target_is_430x ()) 2071 1.1 christos { 2072 1.3 christos /* CPU4: The shorter form of PUSH #8 is not supported on MSP430. */ 2073 1.3 christos if (silicon_errata_warn & SILICON_ERRATA_CPU4) 2074 1.3 christos as_warn (_("cpu4: not converting PUSH #8 to shorter form")); 2075 1.1 christos } 2076 1.1 christos else 2077 1.1 christos { 2078 1.1 christos op->reg = 2; 2079 1.1 christos op->am = 3; 2080 1.1 christos op->ol = 0; 2081 1.1 christos op->mode = OP_REG; 2082 1.1 christos } 2083 1.1 christos } 2084 1.1 christos } 2085 1.1 christos else if (op->exp.X_op == O_symbol) 2086 1.1 christos { 2087 1.3 christos if (vshift > 1) 2088 1.3 christos as_bad (_("error: unsupported #foo() directive used on symbol")); 2089 1.1 christos op->mode = OP_EXP; 2090 1.1 christos } 2091 1.1 christos else if (op->exp.X_op == O_big) 2092 1.1 christos { 2093 1.1 christos short x; 2094 1.3 christos 2095 1.1 christos if (vshift != -1) 2096 1.1 christos { 2097 1.1 christos op->exp.X_op = O_constant; 2098 1.1 christos op->exp.X_add_number = 0xffff & generic_bignum[vshift]; 2099 1.1 christos x = op->exp.X_add_number; 2100 1.3 christos op->vshift = 0; 2101 1.1 christos } 2102 1.1 christos else 2103 1.1 christos { 2104 1.1 christos as_bad (_ 2105 1.6 christos ("unknown expression in operand %s. Use #llo(), #lhi(), #hlo() or #hhi()"), 2106 1.1 christos l); 2107 1.1 christos return 1; 2108 1.1 christos } 2109 1.1 christos 2110 1.1 christos if (x == 0) 2111 1.1 christos { 2112 1.1 christos op->reg = 3; 2113 1.1 christos op->am = 0; 2114 1.1 christos op->ol = 0; 2115 1.1 christos op->mode = OP_REG; 2116 1.1 christos } 2117 1.1 christos else if (x == 1) 2118 1.1 christos { 2119 1.1 christos op->reg = 3; 2120 1.1 christos op->am = 1; 2121 1.1 christos op->ol = 0; 2122 1.1 christos op->mode = OP_REG; 2123 1.1 christos } 2124 1.1 christos else if (x == 2) 2125 1.1 christos { 2126 1.1 christos op->reg = 3; 2127 1.1 christos op->am = 2; 2128 1.1 christos op->ol = 0; 2129 1.1 christos op->mode = OP_REG; 2130 1.1 christos } 2131 1.1 christos else if (x == -1) 2132 1.1 christos { 2133 1.1 christos op->reg = 3; 2134 1.1 christos op->am = 3; 2135 1.1 christos op->ol = 0; 2136 1.1 christos op->mode = OP_REG; 2137 1.1 christos } 2138 1.1 christos else if (x == 4) 2139 1.1 christos { 2140 1.1 christos op->reg = 2; 2141 1.1 christos op->am = 2; 2142 1.1 christos op->ol = 0; 2143 1.1 christos op->mode = OP_REG; 2144 1.1 christos } 2145 1.1 christos else if (x == 8) 2146 1.1 christos { 2147 1.1 christos op->reg = 2; 2148 1.1 christos op->am = 3; 2149 1.1 christos op->ol = 0; 2150 1.1 christos op->mode = OP_REG; 2151 1.1 christos } 2152 1.1 christos } 2153 1.1 christos /* Redundant (yet) check. */ 2154 1.1 christos else if (op->exp.X_op == O_register) 2155 1.1 christos as_bad 2156 1.1 christos (_("Registers cannot be used within immediate expression [%s]"), l); 2157 1.1 christos else 2158 1.1 christos as_bad (_("unknown operand %s"), l); 2159 1.1 christos 2160 1.1 christos return 0; 2161 1.1 christos } 2162 1.1 christos 2163 1.1 christos /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */ 2164 1.1 christos if (*l == '&') 2165 1.1 christos { 2166 1.1 christos char *h = l; 2167 1.1 christos 2168 1.7 christos op->reg = 2; /* Reg 2 in absolute addr mode. */ 2169 1.7 christos op->am = 1; /* Mode As == 01 bin. */ 2170 1.1 christos op->ol = 1; /* Immediate value followed by instruction. */ 2171 1.1 christos __tl = h + 1; 2172 1.6 christos end = parse_exp (__tl, &(op->exp)); 2173 1.6 christos if (end != NULL && *end != 0) 2174 1.6 christos { 2175 1.6 christos as_bad (_("extra characters '%s' at the end of absolute operand '%s'"), end, l); 2176 1.6 christos return 1; 2177 1.6 christos } 2178 1.1 christos op->mode = OP_EXP; 2179 1.3 christos op->vshift = 0; 2180 1.7 christos op->expp = MSP_EXPP_ALL; 2181 1.1 christos if (op->exp.X_op == O_constant) 2182 1.1 christos { 2183 1.1 christos int x = op->exp.X_add_number; 2184 1.1 christos 2185 1.3 christos if (allow_20bit_values) 2186 1.1 christos { 2187 1.3 christos if (x > 0xfffff || x < -(0x7ffff)) 2188 1.3 christos { 2189 1.3 christos as_bad (_("value 0x%x out of extended range."), x); 2190 1.3 christos return 1; 2191 1.3 christos } 2192 1.3 christos } 2193 1.3 christos else if (x > 65535 || x < -32768) 2194 1.3 christos { 2195 1.3 christos as_bad (_("value out of range: 0x%x"), x); 2196 1.1 christos return 1; 2197 1.1 christos } 2198 1.1 christos } 2199 1.1 christos else if (op->exp.X_op == O_symbol) 2200 1.1 christos ; 2201 1.1 christos else 2202 1.1 christos { 2203 1.1 christos /* Redundant (yet) check. */ 2204 1.1 christos if (op->exp.X_op == O_register) 2205 1.1 christos as_bad 2206 1.1 christos (_("Registers cannot be used within absolute expression [%s]"), l); 2207 1.1 christos else 2208 1.1 christos as_bad (_("unknown expression in operand %s"), l); 2209 1.1 christos return 1; 2210 1.1 christos } 2211 1.1 christos return 0; 2212 1.1 christos } 2213 1.1 christos 2214 1.1 christos /* Check if indirect register mode @Rn / postincrement @Rn+. */ 2215 1.1 christos if (*l == '@') 2216 1.1 christos { 2217 1.1 christos char *t = l; 2218 1.1 christos char *m = strchr (l, '+'); 2219 1.1 christos 2220 1.1 christos if (t != l) 2221 1.1 christos { 2222 1.1 christos as_bad (_("unknown addressing mode %s"), l); 2223 1.1 christos return 1; 2224 1.1 christos } 2225 1.1 christos 2226 1.1 christos t++; 2227 1.1 christos 2228 1.3 christos if ((op->reg = check_reg (t)) == -1) 2229 1.1 christos { 2230 1.3 christos as_bad (_("Bad register name %s"), t); 2231 1.1 christos return 1; 2232 1.1 christos } 2233 1.1 christos 2234 1.1 christos op->mode = OP_REG; 2235 1.1 christos op->am = m ? 3 : 2; 2236 1.1 christos op->ol = 0; 2237 1.3 christos 2238 1.3 christos /* PC cannot be used in indirect addressing. */ 2239 1.3 christos if (target_is_430xv2 () && op->reg == 0) 2240 1.1 christos { 2241 1.3 christos as_bad (_("cannot use indirect addressing with the PC")); 2242 1.1 christos return 1; 2243 1.1 christos } 2244 1.1 christos 2245 1.1 christos return 0; 2246 1.1 christos } 2247 1.1 christos 2248 1.1 christos /* Check if register indexed X(Rn). */ 2249 1.1 christos do 2250 1.1 christos { 2251 1.1 christos char *h = strrchr (l, '('); 2252 1.1 christos char *m = strrchr (l, ')'); 2253 1.1 christos char *t; 2254 1.1 christos 2255 1.8 christos *imm_op = true; 2256 1.1 christos 2257 1.1 christos if (!h) 2258 1.1 christos break; 2259 1.1 christos if (!m) 2260 1.1 christos { 2261 1.1 christos as_bad (_("')' required")); 2262 1.1 christos return 1; 2263 1.1 christos } 2264 1.1 christos 2265 1.1 christos t = h; 2266 1.1 christos op->am = 1; 2267 1.1 christos op->ol = 1; 2268 1.3 christos 2269 1.1 christos /* Extract a register. */ 2270 1.3 christos if ((op->reg = check_reg (t + 1)) == -1) 2271 1.1 christos { 2272 1.1 christos as_bad (_ 2273 1.1 christos ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"), 2274 1.1 christos l); 2275 1.1 christos return 1; 2276 1.1 christos } 2277 1.1 christos 2278 1.3 christos if (op->reg == 2) 2279 1.1 christos { 2280 1.3 christos as_bad (_("r2 should not be used in indexed addressing mode")); 2281 1.1 christos return 1; 2282 1.1 christos } 2283 1.1 christos 2284 1.1 christos /* Extract constant. */ 2285 1.1 christos __tl = l; 2286 1.1 christos *h = 0; 2287 1.1 christos op->mode = OP_EXP; 2288 1.3 christos op->vshift = 0; 2289 1.7 christos op->expp = MSP_EXPP_ALL; 2290 1.6 christos end = parse_exp (__tl, &(op->exp)); 2291 1.6 christos if (end != NULL && *end != 0) 2292 1.6 christos { 2293 1.6 christos as_bad (_("extra characters '%s' at end of operand '%s'"), end, l); 2294 1.6 christos return 1; 2295 1.6 christos } 2296 1.1 christos if (op->exp.X_op == O_constant) 2297 1.1 christos { 2298 1.1 christos int x = op->exp.X_add_number; 2299 1.1 christos 2300 1.3 christos if (allow_20bit_values) 2301 1.3 christos { 2302 1.3 christos if (x > 0xfffff || x < - (0x7ffff)) 2303 1.3 christos { 2304 1.3 christos as_bad (_("value 0x%x out of extended range."), x); 2305 1.3 christos return 1; 2306 1.3 christos } 2307 1.3 christos } 2308 1.3 christos else if (x > 65535 || x < -32768) 2309 1.1 christos { 2310 1.3 christos as_bad (_("value out of range: 0x%x"), x); 2311 1.1 christos return 1; 2312 1.1 christos } 2313 1.1 christos 2314 1.1 christos if (x == 0) 2315 1.1 christos { 2316 1.1 christos op->mode = OP_REG; 2317 1.1 christos op->am = 2; 2318 1.1 christos op->ol = 0; 2319 1.1 christos return 0; 2320 1.1 christos } 2321 1.3 christos 2322 1.3 christos if (op->reg == 1 && (x & 1)) 2323 1.3 christos { 2324 1.3 christos if (silicon_errata_fix & SILICON_ERRATA_CPU8) 2325 1.3 christos as_bad (_("CPU8: Stack pointer accessed with an odd offset")); 2326 1.3 christos else if (silicon_errata_warn & SILICON_ERRATA_CPU8) 2327 1.3 christos as_warn (_("CPU8: Stack pointer accessed with an odd offset")); 2328 1.3 christos } 2329 1.1 christos } 2330 1.1 christos else if (op->exp.X_op == O_symbol) 2331 1.1 christos ; 2332 1.1 christos else 2333 1.1 christos { 2334 1.1 christos /* Redundant (yet) check. */ 2335 1.1 christos if (op->exp.X_op == O_register) 2336 1.1 christos as_bad 2337 1.1 christos (_("Registers cannot be used as a prefix of indexed expression [%s]"), l); 2338 1.1 christos else 2339 1.1 christos as_bad (_("unknown expression in operand %s"), l); 2340 1.1 christos return 1; 2341 1.1 christos } 2342 1.1 christos 2343 1.1 christos return 0; 2344 1.1 christos } 2345 1.1 christos while (0); 2346 1.1 christos 2347 1.3 christos /* Possibly register mode 'mov r1,r2'. */ 2348 1.3 christos if ((op->reg = check_reg (l)) != -1) 2349 1.1 christos { 2350 1.3 christos op->mode = OP_REG; 2351 1.3 christos op->am = 0; 2352 1.3 christos op->ol = 0; 2353 1.3 christos return 0; 2354 1.1 christos } 2355 1.1 christos 2356 1.1 christos /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */ 2357 1.6 christos op->mode = OP_EXP; 2358 1.6 christos op->reg = 0; /* PC relative... be careful. */ 2359 1.6 christos /* An expression starting with a minus sign is a constant, not an address. */ 2360 1.6 christos op->am = (*l == '-' ? 3 : 1); 2361 1.6 christos op->ol = 1; 2362 1.6 christos op->vshift = 0; 2363 1.7 christos op->expp = MSP_EXPP_ALL; 2364 1.6 christos __tl = l; 2365 1.6 christos end = parse_exp (__tl, &(op->exp)); 2366 1.6 christos if (end != NULL && * end != 0) 2367 1.1 christos { 2368 1.6 christos as_bad (_("extra characters '%s' at end of operand '%s'"), end, l); 2369 1.6 christos return 1; 2370 1.1 christos } 2371 1.6 christos return 0; 2372 1.1 christos } 2373 1.1 christos 2374 1.1 christos 2375 1.1 christos static int 2376 1.3 christos msp430_dstoperand (struct msp430_operand_s * op, 2377 1.3 christos char * l, 2378 1.3 christos int bin, 2379 1.8 christos bool allow_20bit_values, 2380 1.8 christos bool constants_allowed) 2381 1.1 christos { 2382 1.8 christos bool dummy; 2383 1.3 christos int ret = msp430_srcoperand (op, l, bin, & dummy, 2384 1.3 christos allow_20bit_values, 2385 1.3 christos constants_allowed); 2386 1.1 christos 2387 1.1 christos if (ret) 2388 1.1 christos return ret; 2389 1.1 christos 2390 1.1 christos if (op->am == 2) 2391 1.1 christos { 2392 1.5 christos char *__tl = (char *) "0"; 2393 1.1 christos 2394 1.1 christos op->mode = OP_EXP; 2395 1.1 christos op->am = 1; 2396 1.1 christos op->ol = 1; 2397 1.3 christos op->vshift = 0; 2398 1.7 christos op->expp = MSP_EXPP_ALL; 2399 1.6 christos (void) parse_exp (__tl, &(op->exp)); 2400 1.1 christos 2401 1.1 christos if (op->exp.X_op != O_constant || op->exp.X_add_number != 0) 2402 1.1 christos { 2403 1.1 christos as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"), 2404 1.1 christos op->reg, op->reg); 2405 1.1 christos return 1; 2406 1.1 christos } 2407 1.1 christos return 0; 2408 1.1 christos } 2409 1.1 christos 2410 1.1 christos if (op->am > 1) 2411 1.1 christos { 2412 1.1 christos as_bad (_ 2413 1.1 christos ("this addressing mode is not applicable for destination operand")); 2414 1.1 christos return 1; 2415 1.1 christos } 2416 1.1 christos return 0; 2417 1.1 christos } 2418 1.1 christos 2419 1.3 christos /* Attempt to encode a MOVA instruction with the given operands. 2420 1.3 christos Returns the length of the encoded instruction if successful 2421 1.3 christos or 0 upon failure. If the encoding fails, an error message 2422 1.3 christos will be returned if a pointer is provided. */ 2423 1.1 christos 2424 1.3 christos static int 2425 1.8 christos try_encode_mova (bool imm_op, 2426 1.3 christos int bin, 2427 1.3 christos struct msp430_operand_s * op1, 2428 1.3 christos struct msp430_operand_s * op2, 2429 1.3 christos const char ** error_message_return) 2430 1.1 christos { 2431 1.3 christos short ZEROS = 0; 2432 1.1 christos char *frag; 2433 1.1 christos int where; 2434 1.1 christos 2435 1.3 christos /* Only a restricted subset of the normal MSP430 addressing modes 2436 1.3 christos are supported here, so check for the ones that are allowed. */ 2437 1.3 christos if (imm_op) 2438 1.1 christos { 2439 1.3 christos if (op1->mode == OP_EXP) 2440 1.1 christos { 2441 1.3 christos if (op2->mode != OP_REG) 2442 1.3 christos { 2443 1.3 christos if (error_message_return != NULL) 2444 1.3 christos * error_message_return = _("expected register as second argument of %s"); 2445 1.3 christos return 0; 2446 1.3 christos } 2447 1.1 christos 2448 1.3 christos if (op1->am == 3) 2449 1.3 christos { 2450 1.3 christos /* MOVA #imm20, Rdst. */ 2451 1.3 christos bin |= 0x80 | op2->reg; 2452 1.3 christos frag = frag_more (4); 2453 1.3 christos where = frag - frag_now->fr_literal; 2454 1.3 christos if (op1->exp.X_op == O_constant) 2455 1.3 christos { 2456 1.3 christos bin |= ((op1->exp.X_add_number >> 16) & 0xf) << 8; 2457 1.10 christos bfd_putl16 (bin, frag); 2458 1.3 christos bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2); 2459 1.3 christos } 2460 1.3 christos else 2461 1.3 christos { 2462 1.10 christos bfd_putl16 (bin, frag); 2463 1.8 christos fix_new_exp (frag_now, where, 4, &(op1->exp), false, 2464 1.3 christos BFD_RELOC_MSP430X_ABS20_ADR_SRC); 2465 1.10 christos bfd_putl16 (ZEROS, frag + 2); 2466 1.3 christos } 2467 1.1 christos 2468 1.3 christos return 4; 2469 1.3 christos } 2470 1.3 christos else if (op1->am == 1) 2471 1.1 christos { 2472 1.3 christos /* MOVA z16(Rsrc), Rdst. */ 2473 1.3 christos bin |= 0x30 | (op1->reg << 8) | op2->reg; 2474 1.3 christos frag = frag_more (4); 2475 1.3 christos where = frag - frag_now->fr_literal; 2476 1.10 christos bfd_putl16 (bin, frag); 2477 1.3 christos if (op1->exp.X_op == O_constant) 2478 1.3 christos { 2479 1.3 christos if (op1->exp.X_add_number > 0xffff 2480 1.3 christos || op1->exp.X_add_number < -(0x7fff)) 2481 1.3 christos { 2482 1.3 christos if (error_message_return != NULL) 2483 1.3 christos * error_message_return = _("index value too big for %s"); 2484 1.3 christos return 0; 2485 1.3 christos } 2486 1.3 christos bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2); 2487 1.3 christos } 2488 1.1 christos else 2489 1.3 christos { 2490 1.10 christos bfd_putl16 (ZEROS, frag + 2); 2491 1.8 christos fix_new_exp (frag_now, where + 2, 2, &(op1->exp), false, 2492 1.3 christos op1->reg == 0 ? 2493 1.3 christos BFD_RELOC_MSP430X_PCR16 : 2494 1.3 christos BFD_RELOC_MSP430X_ABS16); 2495 1.3 christos } 2496 1.3 christos return 4; 2497 1.1 christos } 2498 1.3 christos 2499 1.3 christos if (error_message_return != NULL) 2500 1.3 christos * error_message_return = _("unexpected addressing mode for %s"); 2501 1.3 christos return 0; 2502 1.3 christos } 2503 1.3 christos else if (op1->am == 0) 2504 1.3 christos { 2505 1.3 christos /* MOVA Rsrc, ... */ 2506 1.3 christos if (op2->mode == OP_REG) 2507 1.3 christos { 2508 1.3 christos bin |= 0xc0 | (op1->reg << 8) | op2->reg; 2509 1.3 christos frag = frag_more (2); 2510 1.3 christos where = frag - frag_now->fr_literal; 2511 1.10 christos bfd_putl16 (bin, frag); 2512 1.3 christos return 2; 2513 1.3 christos } 2514 1.3 christos else if (op2->am == 1) 2515 1.3 christos { 2516 1.3 christos if (op2->reg == 2) 2517 1.3 christos { 2518 1.3 christos /* MOVA Rsrc, &abs20. */ 2519 1.3 christos bin |= 0x60 | (op1->reg << 8); 2520 1.3 christos frag = frag_more (4); 2521 1.3 christos where = frag - frag_now->fr_literal; 2522 1.3 christos if (op2->exp.X_op == O_constant) 2523 1.3 christos { 2524 1.3 christos bin |= (op2->exp.X_add_number >> 16) & 0xf; 2525 1.10 christos bfd_putl16 (bin, frag); 2526 1.3 christos bfd_putl16 (op2->exp.X_add_number & 0xffff, frag + 2); 2527 1.3 christos } 2528 1.3 christos else 2529 1.3 christos { 2530 1.10 christos bfd_putl16 (bin, frag); 2531 1.10 christos bfd_putl16 (ZEROS, frag + 2); 2532 1.8 christos fix_new_exp (frag_now, where, 4, &(op2->exp), false, 2533 1.3 christos BFD_RELOC_MSP430X_ABS20_ADR_DST); 2534 1.3 christos } 2535 1.3 christos return 4; 2536 1.3 christos } 2537 1.3 christos 2538 1.3 christos /* MOVA Rsrc, z16(Rdst). */ 2539 1.3 christos bin |= 0x70 | (op1->reg << 8) | op2->reg; 2540 1.3 christos frag = frag_more (4); 2541 1.3 christos where = frag - frag_now->fr_literal; 2542 1.10 christos bfd_putl16 (bin, frag); 2543 1.3 christos if (op2->exp.X_op == O_constant) 2544 1.3 christos { 2545 1.3 christos if (op2->exp.X_add_number > 0xffff 2546 1.3 christos || op2->exp.X_add_number < -(0x7fff)) 2547 1.3 christos { 2548 1.3 christos if (error_message_return != NULL) 2549 1.3 christos * error_message_return = _("index value too big for %s"); 2550 1.3 christos return 0; 2551 1.3 christos } 2552 1.3 christos bfd_putl16 (op2->exp.X_add_number & 0xffff, frag + 2); 2553 1.3 christos } 2554 1.3 christos else 2555 1.3 christos { 2556 1.10 christos bfd_putl16 (ZEROS, frag + 2); 2557 1.8 christos fix_new_exp (frag_now, where + 2, 2, &(op2->exp), false, 2558 1.3 christos op2->reg == 0 ? 2559 1.3 christos BFD_RELOC_MSP430X_PCR16 : 2560 1.3 christos BFD_RELOC_MSP430X_ABS16); 2561 1.3 christos } 2562 1.3 christos return 4; 2563 1.3 christos } 2564 1.3 christos 2565 1.3 christos if (error_message_return != NULL) 2566 1.3 christos * error_message_return = _("unexpected addressing mode for %s"); 2567 1.3 christos return 0; 2568 1.3 christos } 2569 1.3 christos } 2570 1.3 christos 2571 1.8 christos /* imm_op == false. */ 2572 1.3 christos 2573 1.3 christos if (op1->reg == 2 && op1->am == 1 && op1->mode == OP_EXP) 2574 1.3 christos { 2575 1.3 christos /* MOVA &abs20, Rdst. */ 2576 1.3 christos if (op2->mode != OP_REG) 2577 1.3 christos { 2578 1.3 christos if (error_message_return != NULL) 2579 1.3 christos * error_message_return = _("expected register as second argument of %s"); 2580 1.3 christos return 0; 2581 1.3 christos } 2582 1.3 christos 2583 1.3 christos if (op2->reg == 2 || op2->reg == 3) 2584 1.3 christos { 2585 1.3 christos if (error_message_return != NULL) 2586 1.3 christos * error_message_return = _("constant generator destination register found in %s"); 2587 1.3 christos return 0; 2588 1.3 christos } 2589 1.3 christos 2590 1.3 christos bin |= 0x20 | op2->reg; 2591 1.3 christos frag = frag_more (4); 2592 1.3 christos where = frag - frag_now->fr_literal; 2593 1.3 christos if (op1->exp.X_op == O_constant) 2594 1.3 christos { 2595 1.3 christos bin |= ((op1->exp.X_add_number >> 16) & 0xf) << 8; 2596 1.10 christos bfd_putl16 (bin, frag); 2597 1.3 christos bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2); 2598 1.3 christos } 2599 1.3 christos else 2600 1.3 christos { 2601 1.10 christos bfd_putl16 (bin, frag); 2602 1.10 christos bfd_putl16 (ZEROS, frag + 2); 2603 1.8 christos fix_new_exp (frag_now, where, 4, &(op1->exp), false, 2604 1.3 christos BFD_RELOC_MSP430X_ABS20_ADR_SRC); 2605 1.3 christos } 2606 1.3 christos return 4; 2607 1.3 christos } 2608 1.3 christos else if (op1->mode == OP_REG) 2609 1.3 christos { 2610 1.3 christos if (op1->am == 3) 2611 1.3 christos { 2612 1.3 christos /* MOVA @Rsrc+, Rdst. */ 2613 1.3 christos if (op2->mode != OP_REG) 2614 1.3 christos { 2615 1.3 christos if (error_message_return != NULL) 2616 1.3 christos * error_message_return = _("expected register as second argument of %s"); 2617 1.3 christos return 0; 2618 1.3 christos } 2619 1.3 christos 2620 1.3 christos if (op2->reg == 2 || op2->reg == 3) 2621 1.3 christos { 2622 1.3 christos if (error_message_return != NULL) 2623 1.3 christos * error_message_return = _("constant generator destination register found in %s"); 2624 1.3 christos return 0; 2625 1.3 christos } 2626 1.3 christos 2627 1.3 christos if (op1->reg == 2 || op1->reg == 3) 2628 1.3 christos { 2629 1.3 christos if (error_message_return != NULL) 2630 1.3 christos * error_message_return = _("constant generator source register found in %s"); 2631 1.3 christos return 0; 2632 1.3 christos } 2633 1.3 christos 2634 1.3 christos bin |= 0x10 | (op1->reg << 8) | op2->reg; 2635 1.3 christos frag = frag_more (2); 2636 1.3 christos where = frag - frag_now->fr_literal; 2637 1.10 christos bfd_putl16 (bin, frag); 2638 1.3 christos return 2; 2639 1.3 christos } 2640 1.3 christos else if (op1->am == 2) 2641 1.3 christos { 2642 1.3 christos /* MOVA @Rsrc,Rdst */ 2643 1.3 christos if (op2->mode != OP_REG) 2644 1.3 christos { 2645 1.3 christos if (error_message_return != NULL) 2646 1.3 christos * error_message_return = _("expected register as second argument of %s"); 2647 1.3 christos return 0; 2648 1.3 christos } 2649 1.3 christos 2650 1.3 christos if (op2->reg == 2 || op2->reg == 3) 2651 1.3 christos { 2652 1.3 christos if (error_message_return != NULL) 2653 1.3 christos * error_message_return = _("constant generator destination register found in %s"); 2654 1.3 christos return 0; 2655 1.3 christos } 2656 1.3 christos 2657 1.3 christos if (op1->reg == 2 || op1->reg == 3) 2658 1.3 christos { 2659 1.3 christos if (error_message_return != NULL) 2660 1.3 christos * error_message_return = _("constant generator source register found in %s"); 2661 1.3 christos return 0; 2662 1.3 christos } 2663 1.3 christos 2664 1.3 christos bin |= (op1->reg << 8) | op2->reg; 2665 1.3 christos frag = frag_more (2); 2666 1.3 christos where = frag - frag_now->fr_literal; 2667 1.10 christos bfd_putl16 (bin, frag); 2668 1.3 christos return 2; 2669 1.3 christos } 2670 1.3 christos } 2671 1.3 christos 2672 1.3 christos if (error_message_return != NULL) 2673 1.3 christos * error_message_return = _("unexpected addressing mode for %s"); 2674 1.3 christos 2675 1.3 christos return 0; 2676 1.3 christos } 2677 1.3 christos 2678 1.3 christos #define NOP_CHECK_INTERRUPT (1 << 0) 2679 1.3 christos #define NOP_CHECK_CPU12 (1 << 1) 2680 1.3 christos #define NOP_CHECK_CPU19 (1 << 2) 2681 1.3 christos 2682 1.3 christos static signed int check_for_nop = 0; 2683 1.3 christos 2684 1.3 christos #define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0) 2685 1.3 christos 2686 1.7 christos /* is_{e,d}int only check the explicit enabling/disabling of interrupts. 2687 1.7 christos For MOV insns, more sophisticated processing is needed to determine if they 2688 1.7 christos result in enabling/disabling interrupts. */ 2689 1.7 christos #define is_dint(OPCODE, BIN) ((strcmp (OPCODE, "dint") == 0) \ 2690 1.7 christos || ((strcmp (OPCODE, "bic") == 0) \ 2691 1.7 christos && BIN == 0xc232) \ 2692 1.7 christos || ((strcmp (OPCODE, "clr") == 0) \ 2693 1.7 christos && BIN == 0x4302)) 2694 1.7 christos 2695 1.7 christos #define is_eint(OPCODE, BIN) ((strcmp (OPCODE, "eint") == 0) \ 2696 1.7 christos || ((strcmp (OPCODE, "bis") == 0) \ 2697 1.7 christos && BIN == 0xd232)) 2698 1.7 christos 2699 1.7 christos const char * const INSERT_NOP_BEFORE_EINT = "NOP inserted here, before an interrupt enable instruction"; 2700 1.7 christos const char * const INSERT_NOP_AFTER_DINT = "NOP inserted here, after an interrupt disable instruction"; 2701 1.7 christos const char * const INSERT_NOP_AFTER_EINT = "NOP inserted here, after an interrupt enable instruction"; 2702 1.7 christos const char * const INSERT_NOP_BEFORE_UNKNOWN = "NOP inserted here, before this interrupt state change"; 2703 1.7 christos const char * const INSERT_NOP_AFTER_UNKNOWN ="NOP inserted here, after the instruction that changed interrupt state"; 2704 1.7 christos const char * const INSERT_NOP_AT_EOF = "NOP inserted after the interrupt state change at the end of the file"; 2705 1.7 christos 2706 1.7 christos const char * const WARN_NOP_BEFORE_EINT = "a NOP might be needed here, before an interrupt enable instruction"; 2707 1.7 christos const char * const WARN_NOP_AFTER_DINT = "a NOP might be needed here, after an interrupt disable instruction"; 2708 1.7 christos const char * const WARN_NOP_AFTER_EINT = "a NOP might be needed here, after an interrupt enable instruction"; 2709 1.7 christos const char * const WARN_NOP_BEFORE_UNKNOWN = "a NOP might be needed here, before this interrupt state change"; 2710 1.7 christos const char * const WARN_NOP_AFTER_UNKNOWN = "a NOP might also be needed here, after the instruction that changed interrupt state"; 2711 1.7 christos const char * const WARN_NOP_AT_EOF = "a NOP might be needed after the interrupt state change at the end of the file"; 2712 1.7 christos 2713 1.7 christos static void 2714 1.7 christos gen_nop (void) 2715 1.7 christos { 2716 1.7 christos char *frag; 2717 1.7 christos frag = frag_more (2); 2718 1.10 christos bfd_putl16 (0x4303 /* NOP */, frag); 2719 1.7 christos dwarf2_emit_insn (2); 2720 1.7 christos } 2721 1.7 christos 2722 1.7 christos /* Insert/inform about adding a NOP if this insn enables interrupts. */ 2723 1.7 christos 2724 1.7 christos static void 2725 1.8 christos warn_eint_nop (bool prev_insn_is_nop, bool prev_insn_is_dint) 2726 1.7 christos { 2727 1.7 christos if (prev_insn_is_nop 2728 1.7 christos /* If the last insn was a DINT, we will have already warned that a NOP is 2729 1.7 christos required after it. */ 2730 1.7 christos || prev_insn_is_dint 2731 1.7 christos /* 430 ISA does not require a NOP before EINT. */ 2732 1.7 christos || (! target_is_430x ())) 2733 1.7 christos return; 2734 1.7 christos 2735 1.7 christos if (gen_interrupt_nops) 2736 1.7 christos { 2737 1.7 christos gen_nop (); 2738 1.7 christos if (warn_interrupt_nops) 2739 1.7 christos as_warn (_(INSERT_NOP_BEFORE_EINT)); 2740 1.7 christos } 2741 1.7 christos else if (warn_interrupt_nops) 2742 1.7 christos as_warn (_(WARN_NOP_BEFORE_EINT)); 2743 1.7 christos } 2744 1.7 christos 2745 1.7 christos /* Use when unsure what effect the insn will have on the interrupt status, 2746 1.7 christos to insert/warn about adding a NOP before the current insn. */ 2747 1.7 christos 2748 1.7 christos static void 2749 1.8 christos warn_unsure_interrupt (bool prev_insn_is_nop, 2750 1.8 christos bool prev_insn_is_dint) 2751 1.7 christos { 2752 1.7 christos if (prev_insn_is_nop 2753 1.7 christos /* If the last insn was a DINT, we will have already warned that a NOP is 2754 1.7 christos required after it. */ 2755 1.7 christos || prev_insn_is_dint 2756 1.7 christos /* 430 ISA does not require a NOP before EINT or DINT. */ 2757 1.7 christos || (! target_is_430x ())) 2758 1.7 christos return; 2759 1.7 christos 2760 1.7 christos if (gen_interrupt_nops) 2761 1.7 christos { 2762 1.7 christos gen_nop (); 2763 1.7 christos if (warn_interrupt_nops) 2764 1.7 christos as_warn (_(INSERT_NOP_BEFORE_UNKNOWN)); 2765 1.7 christos } 2766 1.7 christos else if (warn_interrupt_nops) 2767 1.7 christos as_warn (_(WARN_NOP_BEFORE_UNKNOWN)); 2768 1.7 christos } 2769 1.7 christos 2770 1.3 christos /* Parse instruction operands. 2771 1.3 christos Return binary opcode. */ 2772 1.3 christos 2773 1.3 christos static unsigned int 2774 1.3 christos msp430_operands (struct msp430_opcode_s * opcode, char * line) 2775 1.3 christos { 2776 1.3 christos int bin = opcode->bin_opcode; /* Opcode mask. */ 2777 1.3 christos int insn_length = 0; 2778 1.3 christos char l1[MAX_OP_LEN], l2[MAX_OP_LEN]; 2779 1.3 christos char *frag; 2780 1.6 christos char *end; 2781 1.3 christos int where; 2782 1.3 christos struct msp430_operand_s op1, op2; 2783 1.3 christos int res = 0; 2784 1.3 christos static short ZEROS = 0; 2785 1.8 christos bool byte_op, imm_op; 2786 1.3 christos int op_length = 0; 2787 1.3 christos int fmt; 2788 1.3 christos int extended = 0x1800; 2789 1.8 christos bool extended_op = false; 2790 1.8 christos bool addr_op; 2791 1.3 christos const char * error_message; 2792 1.3 christos static signed int repeat_count = 0; 2793 1.8 christos static bool prev_insn_is_nop = false; 2794 1.8 christos static bool prev_insn_is_dint = false; 2795 1.8 christos static bool prev_insn_is_eint = false; 2796 1.7 christos /* We might decide before the end of the function that the current insn is 2797 1.7 christos equivalent to DINT/EINT. */ 2798 1.8 christos bool this_insn_is_dint = false; 2799 1.8 christos bool this_insn_is_eint = false; 2800 1.8 christos bool fix_emitted; 2801 1.3 christos 2802 1.3 christos /* Opcode is the one from opcodes table 2803 1.3 christos line contains something like 2804 1.3 christos [.w] @r2+, 5(R1) 2805 1.3 christos or 2806 1.3 christos .b @r2+, 5(R1). */ 2807 1.3 christos 2808 1.8 christos byte_op = false; 2809 1.8 christos addr_op = false; 2810 1.3 christos if (*line == '.') 2811 1.3 christos { 2812 1.8 christos bool check = false; 2813 1.3 christos ++ line; 2814 1.3 christos 2815 1.3 christos switch (TOLOWER (* line)) 2816 1.3 christos { 2817 1.3 christos case 'b': 2818 1.3 christos /* Byte operation. */ 2819 1.3 christos bin |= BYTE_OPERATION; 2820 1.8 christos byte_op = true; 2821 1.8 christos check = true; 2822 1.3 christos break; 2823 1.3 christos 2824 1.3 christos case 'a': 2825 1.3 christos /* "Address" ops work on 20-bit values. */ 2826 1.8 christos addr_op = true; 2827 1.3 christos bin |= BYTE_OPERATION; 2828 1.8 christos check = true; 2829 1.3 christos break; 2830 1.3 christos 2831 1.3 christos case 'w': 2832 1.3 christos /* Word operation - this is the default. */ 2833 1.8 christos check = true; 2834 1.3 christos break; 2835 1.3 christos 2836 1.3 christos default: 2837 1.10 christos if (is_whitespace (*line) || is_end_of_stmt(*line)) 2838 1.10 christos { 2839 1.10 christos as_warn (_("no size modifier after period, .w assumed")); 2840 1.10 christos break; 2841 1.10 christos } 2842 1.3 christos as_bad (_("unrecognised instruction size modifier .%c"), 2843 1.3 christos * line); 2844 1.3 christos return 0; 2845 1.3 christos } 2846 1.3 christos 2847 1.3 christos if (check) 2848 1.3 christos { 2849 1.3 christos ++ line; 2850 1.3 christos 2851 1.3 christos } 2852 1.3 christos } 2853 1.3 christos 2854 1.10 christos if (*line && ! is_whitespace (*line)) 2855 1.3 christos { 2856 1.3 christos as_bad (_("junk found after instruction: %s.%s"), 2857 1.3 christos opcode->name, line); 2858 1.3 christos return 0; 2859 1.3 christos } 2860 1.3 christos 2861 1.3 christos /* Catch the case where the programmer has used a ".a" size modifier on an 2862 1.3 christos instruction that does not support it. Look for an alternative extended 2863 1.3 christos instruction that has the same name without the period. Eg: "add.a" 2864 1.3 christos becomes "adda". Although this not an officially supported way of 2865 1.6 christos specifying instruction aliases other MSP430 assemblers allow it. So we 2866 1.3 christos support it for compatibility purposes. */ 2867 1.3 christos if (addr_op && opcode->fmt >= 0) 2868 1.3 christos { 2869 1.5 christos const char * old_name = opcode->name; 2870 1.3 christos char real_name[32]; 2871 1.3 christos 2872 1.3 christos sprintf (real_name, "%sa", old_name); 2873 1.8 christos opcode = str_hash_find (msp430_hash, real_name); 2874 1.3 christos if (opcode == NULL) 2875 1.3 christos { 2876 1.3 christos as_bad (_("instruction %s.a does not exist"), old_name); 2877 1.3 christos return 0; 2878 1.3 christos } 2879 1.3 christos #if 0 /* Enable for debugging. */ 2880 1.3 christos as_warn ("treating %s.a as %s", old_name, real_name); 2881 1.3 christos #endif 2882 1.8 christos addr_op = false; 2883 1.3 christos bin = opcode->bin_opcode; 2884 1.3 christos } 2885 1.3 christos 2886 1.3 christos if (opcode->fmt != -1 2887 1.3 christos && opcode->insn_opnumb 2888 1.3 christos && (!*line || *line == '\n')) 2889 1.3 christos { 2890 1.6 christos as_bad (ngettext ("instruction %s requires %d operand", 2891 1.6 christos "instruction %s requires %d operands", 2892 1.6 christos opcode->insn_opnumb), 2893 1.3 christos opcode->name, opcode->insn_opnumb); 2894 1.3 christos return 0; 2895 1.3 christos } 2896 1.3 christos 2897 1.3 christos memset (l1, 0, sizeof (l1)); 2898 1.3 christos memset (l2, 0, sizeof (l2)); 2899 1.3 christos memset (&op1, 0, sizeof (op1)); 2900 1.3 christos memset (&op2, 0, sizeof (op2)); 2901 1.3 christos 2902 1.8 christos imm_op = false; 2903 1.3 christos 2904 1.3 christos if ((fmt = opcode->fmt) < 0) 2905 1.3 christos { 2906 1.3 christos if (! target_is_430x ()) 2907 1.3 christos { 2908 1.3 christos as_bad (_("instruction %s requires MSP430X mcu"), 2909 1.3 christos opcode->name); 2910 1.3 christos return 0; 2911 1.3 christos } 2912 1.3 christos 2913 1.3 christos fmt = (-fmt) - 1; 2914 1.8 christos extended_op = true; 2915 1.3 christos } 2916 1.3 christos 2917 1.3 christos if (repeat_count) 2918 1.3 christos { 2919 1.3 christos /* If requested set the extended instruction repeat count. */ 2920 1.3 christos if (extended_op) 2921 1.3 christos { 2922 1.3 christos if (repeat_count > 0) 2923 1.3 christos extended |= (repeat_count - 1); 2924 1.3 christos else 2925 1.3 christos extended |= (1 << 7) | (- repeat_count); 2926 1.3 christos } 2927 1.3 christos else 2928 1.3 christos as_bad (_("unable to repeat %s insn"), opcode->name); 2929 1.3 christos 2930 1.3 christos repeat_count = 0; 2931 1.3 christos } 2932 1.3 christos 2933 1.7 christos /* The previous instruction set this flag if it wants to check if this insn 2934 1.7 christos is a NOP. */ 2935 1.3 christos if (check_for_nop) 2936 1.3 christos { 2937 1.3 christos if (! is_opcode ("nop")) 2938 1.3 christos { 2939 1.3 christos do 2940 1.3 christos { 2941 1.3 christos switch (check_for_nop & - check_for_nop) 2942 1.3 christos { 2943 1.3 christos case NOP_CHECK_INTERRUPT: 2944 1.7 christos /* NOP_CHECK_INTERRUPT rules: 2945 1.7 christos 1. 430 and 430x ISA require a NOP after DINT. 2946 1.7 christos 2. Only the 430x ISA requires NOP before EINT (this has 2947 1.7 christos been dealt with in the previous call to this function). 2948 1.7 christos 3. Only the 430x ISA requires NOP after every EINT. 2949 1.7 christos CPU42 errata. */ 2950 1.7 christos if (gen_interrupt_nops || warn_interrupt_nops) 2951 1.3 christos { 2952 1.7 christos if (prev_insn_is_dint) 2953 1.7 christos { 2954 1.7 christos if (gen_interrupt_nops) 2955 1.7 christos { 2956 1.7 christos gen_nop (); 2957 1.7 christos if (warn_interrupt_nops) 2958 1.7 christos as_warn (_(INSERT_NOP_AFTER_DINT)); 2959 1.7 christos } 2960 1.7 christos else 2961 1.7 christos as_warn (_(WARN_NOP_AFTER_DINT)); 2962 1.7 christos } 2963 1.7 christos else if (prev_insn_is_eint) 2964 1.7 christos { 2965 1.7 christos if (gen_interrupt_nops) 2966 1.7 christos { 2967 1.7 christos gen_nop (); 2968 1.7 christos if (warn_interrupt_nops) 2969 1.7 christos as_warn (_(INSERT_NOP_AFTER_EINT)); 2970 1.7 christos } 2971 1.7 christos else 2972 1.7 christos as_warn (_(WARN_NOP_AFTER_EINT)); 2973 1.7 christos } 2974 1.7 christos /* If we get here it's because the last instruction was 2975 1.7 christos determined to either disable or enable interrupts, but 2976 1.7 christos we're not sure which. 2977 1.7 christos We have no information yet about what effect the 2978 1.7 christos current instruction has on interrupts, that has to be 2979 1.7 christos sorted out later. 2980 1.7 christos The last insn may have required a NOP after it, so we 2981 1.7 christos deal with that now. */ 2982 1.3 christos else 2983 1.7 christos { 2984 1.7 christos if (gen_interrupt_nops) 2985 1.7 christos { 2986 1.7 christos gen_nop (); 2987 1.7 christos if (warn_interrupt_nops) 2988 1.7 christos as_warn (_(INSERT_NOP_AFTER_UNKNOWN)); 2989 1.7 christos } 2990 1.7 christos else 2991 1.7 christos /* warn_unsure_interrupt was called on the previous 2992 1.7 christos insn. */ 2993 1.7 christos as_warn (_(WARN_NOP_AFTER_UNKNOWN)); 2994 1.7 christos } 2995 1.3 christos } 2996 1.3 christos break; 2997 1.3 christos 2998 1.3 christos case NOP_CHECK_CPU12: 2999 1.3 christos if (silicon_errata_warn & SILICON_ERRATA_CPU12) 3000 1.6 christos as_warn (_("CPU12: CMP/BIT with PC destination ignores next instruction")); 3001 1.3 christos 3002 1.3 christos if (silicon_errata_fix & SILICON_ERRATA_CPU12) 3003 1.7 christos gen_nop (); 3004 1.3 christos break; 3005 1.3 christos 3006 1.3 christos case NOP_CHECK_CPU19: 3007 1.3 christos if (silicon_errata_warn & SILICON_ERRATA_CPU19) 3008 1.3 christos as_warn (_("CPU19: Instruction setting CPUOFF must be followed by a NOP")); 3009 1.3 christos 3010 1.3 christos if (silicon_errata_fix & SILICON_ERRATA_CPU19) 3011 1.7 christos gen_nop (); 3012 1.3 christos break; 3013 1.3 christos 3014 1.3 christos default: 3015 1.3 christos as_bad (_("internal error: unknown nop check state")); 3016 1.3 christos break; 3017 1.3 christos } 3018 1.3 christos check_for_nop &= ~ (check_for_nop & - check_for_nop); 3019 1.3 christos } 3020 1.3 christos while (check_for_nop); 3021 1.3 christos } 3022 1.3 christos check_for_nop = 0; 3023 1.3 christos } 3024 1.3 christos 3025 1.3 christos switch (fmt) 3026 1.3 christos { 3027 1.7 christos case 0: 3028 1.7 christos /* Emulated. */ 3029 1.3 christos switch (opcode->insn_opnumb) 3030 1.3 christos { 3031 1.3 christos case 0: 3032 1.5 christos if (is_opcode ("eint")) 3033 1.7 christos warn_eint_nop (prev_insn_is_nop, prev_insn_is_dint); 3034 1.3 christos 3035 1.3 christos /* Set/clear bits instructions. */ 3036 1.3 christos if (extended_op) 3037 1.3 christos { 3038 1.3 christos if (!addr_op) 3039 1.3 christos extended |= BYTE_OPERATION; 3040 1.3 christos 3041 1.3 christos /* Emit the extension word. */ 3042 1.3 christos insn_length += 2; 3043 1.3 christos frag = frag_more (2); 3044 1.3 christos bfd_putl16 (extended, frag); 3045 1.3 christos } 3046 1.3 christos 3047 1.3 christos insn_length += 2; 3048 1.3 christos frag = frag_more (2); 3049 1.10 christos bfd_putl16 (bin, frag); 3050 1.3 christos dwarf2_emit_insn (insn_length); 3051 1.3 christos break; 3052 1.3 christos 3053 1.3 christos case 1: 3054 1.3 christos /* Something which works with destination operand. */ 3055 1.3 christos line = extract_operand (line, l1, sizeof (l1)); 3056 1.8 christos res = msp430_dstoperand (&op1, l1, opcode->bin_opcode, extended_op, true); 3057 1.3 christos if (res) 3058 1.3 christos break; 3059 1.3 christos 3060 1.3 christos bin |= (op1.reg | (op1.am << 7)); 3061 1.3 christos 3062 1.3 christos /* If the PC is the destination... */ 3063 1.3 christos if (op1.am == 0 && op1.reg == 0 3064 1.3 christos /* ... and the opcode alters the SR. */ 3065 1.3 christos && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov") 3066 1.3 christos || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx"))) 3067 1.3 christos { 3068 1.3 christos if (silicon_errata_fix & SILICON_ERRATA_CPU11) 3069 1.6 christos as_bad (_("CPU11: PC is destination of SR altering instruction")); 3070 1.3 christos else if (silicon_errata_warn & SILICON_ERRATA_CPU11) 3071 1.6 christos as_warn (_("CPU11: PC is destination of SR altering instruction")); 3072 1.3 christos } 3073 1.3 christos 3074 1.3 christos /* If the status register is the destination... */ 3075 1.3 christos if (op1.am == 0 && op1.reg == 2 3076 1.3 christos /* ... and the opcode alters the SR. */ 3077 1.3 christos && (is_opcode ("adc") || is_opcode ("dec") || is_opcode ("decd") 3078 1.3 christos || is_opcode ("inc") || is_opcode ("incd") || is_opcode ("inv") 3079 1.3 christos || is_opcode ("sbc") || is_opcode ("sxt") 3080 1.3 christos || is_opcode ("adcx") || is_opcode ("decx") || is_opcode ("decdx") 3081 1.3 christos || is_opcode ("incx") || is_opcode ("incdx") || is_opcode ("invx") 3082 1.3 christos || is_opcode ("sbcx") 3083 1.3 christos )) 3084 1.3 christos { 3085 1.3 christos if (silicon_errata_fix & SILICON_ERRATA_CPU13) 3086 1.6 christos as_bad (_("CPU13: SR is destination of SR altering instruction")); 3087 1.3 christos else if (silicon_errata_warn & SILICON_ERRATA_CPU13) 3088 1.6 christos as_warn (_("CPU13: SR is destination of SR altering instruction")); 3089 1.3 christos } 3090 1.3 christos 3091 1.3 christos /* Compute the entire instruction length, in bytes. */ 3092 1.3 christos op_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2); 3093 1.3 christos insn_length += op_length; 3094 1.3 christos frag = frag_more (op_length); 3095 1.3 christos where = frag - frag_now->fr_literal; 3096 1.3 christos 3097 1.3 christos if (extended_op) 3098 1.3 christos { 3099 1.3 christos if (!addr_op) 3100 1.3 christos extended |= BYTE_OPERATION; 3101 1.3 christos 3102 1.3 christos if (op1.ol != 0 && ((extended & 0xf) != 0)) 3103 1.3 christos { 3104 1.3 christos as_bad (_("repeat instruction used with non-register mode instruction")); 3105 1.3 christos extended &= ~ 0xf; 3106 1.3 christos } 3107 1.3 christos 3108 1.3 christos if (op1.mode == OP_EXP) 3109 1.3 christos { 3110 1.3 christos if (op1.exp.X_op == O_constant) 3111 1.3 christos extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7; 3112 1.3 christos 3113 1.3 christos else if (op1.reg || op1.am == 3) /* Not PC relative. */ 3114 1.8 christos fix_new_exp (frag_now, where, 6, &(op1.exp), false, 3115 1.3 christos BFD_RELOC_MSP430X_ABS20_EXT_SRC); 3116 1.3 christos else 3117 1.8 christos fix_new_exp (frag_now, where, 6, &(op1.exp), false, 3118 1.3 christos BFD_RELOC_MSP430X_PCR20_EXT_SRC); 3119 1.3 christos } 3120 1.3 christos 3121 1.3 christos /* Emit the extension word. */ 3122 1.3 christos bfd_putl16 (extended, frag); 3123 1.3 christos frag += 2; 3124 1.3 christos where += 2; 3125 1.3 christos } 3126 1.3 christos 3127 1.10 christos bfd_putl16 (bin, frag); 3128 1.3 christos frag += 2; 3129 1.3 christos where += 2; 3130 1.3 christos 3131 1.3 christos if (op1.mode == OP_EXP) 3132 1.3 christos { 3133 1.3 christos if (op1.exp.X_op == O_constant) 3134 1.3 christos { 3135 1.3 christos bfd_putl16 (op1.exp.X_add_number & 0xffff, frag); 3136 1.3 christos } 3137 1.3 christos else 3138 1.3 christos { 3139 1.10 christos bfd_putl16 (ZEROS, frag); 3140 1.3 christos 3141 1.3 christos if (!extended_op) 3142 1.3 christos { 3143 1.3 christos if (op1.reg) 3144 1.3 christos fix_new_exp (frag_now, where, 2, 3145 1.8 christos &(op1.exp), false, CHECK_RELOC_MSP430 (op1)); 3146 1.3 christos else 3147 1.3 christos fix_new_exp (frag_now, where, 2, 3148 1.8 christos &(op1.exp), true, CHECK_RELOC_MSP430_PCREL); 3149 1.3 christos } 3150 1.3 christos } 3151 1.3 christos } 3152 1.3 christos 3153 1.3 christos dwarf2_emit_insn (insn_length); 3154 1.3 christos break; 3155 1.1 christos 3156 1.1 christos case 2: 3157 1.3 christos /* Shift instruction. */ 3158 1.3 christos line = extract_operand (line, l1, sizeof (l1)); 3159 1.3 christos strncpy (l2, l1, sizeof (l2)); 3160 1.3 christos l2[sizeof (l2) - 1] = '\0'; 3161 1.8 christos res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, true); 3162 1.8 christos res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, extended_op, true); 3163 1.3 christos 3164 1.3 christos if (res) 3165 1.3 christos break; /* An error occurred. All warnings were done before. */ 3166 1.3 christos 3167 1.3 christos insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2) + (op2.ol * 2); 3168 1.3 christos frag = frag_more (insn_length); 3169 1.3 christos where = frag - frag_now->fr_literal; 3170 1.3 christos 3171 1.3 christos if (target_is_430xv2 () 3172 1.3 christos && op1.mode == OP_REG 3173 1.3 christos && op1.reg == 0 3174 1.3 christos && (is_opcode ("rlax") 3175 1.3 christos || is_opcode ("rlcx") 3176 1.3 christos || is_opcode ("rla") 3177 1.3 christos || is_opcode ("rlc"))) 3178 1.3 christos { 3179 1.3 christos as_bad (_("%s: attempt to rotate the PC register"), opcode->name); 3180 1.3 christos break; 3181 1.3 christos } 3182 1.3 christos 3183 1.3 christos /* If the status register is the destination... */ 3184 1.3 christos if (op1.am == 0 && op1.reg == 2 3185 1.3 christos /* ... and the opcode alters the SR. */ 3186 1.3 christos && (is_opcode ("rla") || is_opcode ("rlc") 3187 1.3 christos || is_opcode ("rlax") || is_opcode ("rlcx") 3188 1.7 christos || is_opcode ("sxt") || is_opcode ("sxtx") 3189 1.7 christos || is_opcode ("swpb") 3190 1.3 christos )) 3191 1.3 christos { 3192 1.3 christos if (silicon_errata_fix & SILICON_ERRATA_CPU13) 3193 1.6 christos as_bad (_("CPU13: SR is destination of SR altering instruction")); 3194 1.3 christos else if (silicon_errata_warn & SILICON_ERRATA_CPU13) 3195 1.6 christos as_warn (_("CPU13: SR is destination of SR altering instruction")); 3196 1.3 christos } 3197 1.3 christos 3198 1.3 christos if (extended_op) 3199 1.3 christos { 3200 1.3 christos if (!addr_op) 3201 1.3 christos extended |= BYTE_OPERATION; 3202 1.3 christos 3203 1.3 christos if ((op1.ol != 0 || op2.ol != 0) && ((extended & 0xf) != 0)) 3204 1.3 christos { 3205 1.3 christos as_bad (_("repeat instruction used with non-register mode instruction")); 3206 1.3 christos extended &= ~ 0xf; 3207 1.3 christos } 3208 1.3 christos 3209 1.3 christos if (op1.mode == OP_EXP) 3210 1.3 christos { 3211 1.3 christos if (op1.exp.X_op == O_constant) 3212 1.3 christos extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7; 3213 1.3 christos 3214 1.3 christos else if (op1.reg || op1.am == 3) /* Not PC relative. */ 3215 1.8 christos fix_new_exp (frag_now, where, 6, &(op1.exp), false, 3216 1.3 christos BFD_RELOC_MSP430X_ABS20_EXT_SRC); 3217 1.3 christos else 3218 1.8 christos fix_new_exp (frag_now, where, 6, &(op1.exp), false, 3219 1.3 christos BFD_RELOC_MSP430X_PCR20_EXT_SRC); 3220 1.3 christos } 3221 1.3 christos 3222 1.3 christos if (op2.mode == OP_EXP) 3223 1.3 christos { 3224 1.3 christos if (op2.exp.X_op == O_constant) 3225 1.3 christos extended |= (op2.exp.X_add_number >> 16) & 0xf; 3226 1.3 christos 3227 1.3 christos else if (op1.mode == OP_EXP) 3228 1.8 christos fix_new_exp (frag_now, where, 8, &(op2.exp), false, 3229 1.3 christos op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_ODST 3230 1.3 christos : BFD_RELOC_MSP430X_PCR20_EXT_ODST); 3231 1.3 christos else 3232 1.8 christos fix_new_exp (frag_now, where, 6, &(op2.exp), false, 3233 1.3 christos op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_DST 3234 1.3 christos : BFD_RELOC_MSP430X_PCR20_EXT_DST); 3235 1.3 christos } 3236 1.3 christos 3237 1.3 christos /* Emit the extension word. */ 3238 1.3 christos bfd_putl16 (extended, frag); 3239 1.3 christos frag += 2; 3240 1.3 christos where += 2; 3241 1.3 christos } 3242 1.3 christos 3243 1.3 christos bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7)); 3244 1.10 christos bfd_putl16 (bin, frag); 3245 1.3 christos frag += 2; 3246 1.3 christos where += 2; 3247 1.3 christos 3248 1.3 christos if (op1.mode == OP_EXP) 3249 1.3 christos { 3250 1.3 christos if (op1.exp.X_op == O_constant) 3251 1.3 christos { 3252 1.3 christos bfd_putl16 (op1.exp.X_add_number & 0xffff, frag); 3253 1.3 christos } 3254 1.3 christos else 3255 1.3 christos { 3256 1.10 christos bfd_putl16 (ZEROS, frag); 3257 1.3 christos 3258 1.3 christos if (!extended_op) 3259 1.3 christos { 3260 1.3 christos if (op1.reg || op1.am == 3) /* Not PC relative. */ 3261 1.3 christos fix_new_exp (frag_now, where, 2, 3262 1.8 christos &(op1.exp), false, CHECK_RELOC_MSP430 (op1)); 3263 1.3 christos else 3264 1.3 christos fix_new_exp (frag_now, where, 2, 3265 1.8 christos &(op1.exp), true, CHECK_RELOC_MSP430_PCREL); 3266 1.3 christos } 3267 1.3 christos } 3268 1.3 christos frag += 2; 3269 1.3 christos where += 2; 3270 1.3 christos } 3271 1.3 christos 3272 1.3 christos if (op2.mode == OP_EXP) 3273 1.3 christos { 3274 1.3 christos if (op2.exp.X_op == O_constant) 3275 1.3 christos { 3276 1.3 christos bfd_putl16 (op2.exp.X_add_number & 0xffff, frag); 3277 1.3 christos } 3278 1.3 christos else 3279 1.3 christos { 3280 1.10 christos bfd_putl16 (ZEROS, frag); 3281 1.3 christos 3282 1.3 christos if (!extended_op) 3283 1.3 christos { 3284 1.3 christos if (op2.reg) /* Not PC relative. */ 3285 1.3 christos fix_new_exp (frag_now, where, 2, 3286 1.8 christos &(op2.exp), false, CHECK_RELOC_MSP430 (op2)); 3287 1.3 christos else 3288 1.3 christos fix_new_exp (frag_now, where, 2, 3289 1.8 christos &(op2.exp), true, CHECK_RELOC_MSP430_PCREL); 3290 1.3 christos } 3291 1.3 christos } 3292 1.3 christos } 3293 1.3 christos 3294 1.3 christos dwarf2_emit_insn (insn_length); 3295 1.3 christos break; 3296 1.3 christos 3297 1.3 christos case 3: 3298 1.3 christos /* Branch instruction => mov dst, r0. */ 3299 1.3 christos if (extended_op) 3300 1.3 christos { 3301 1.3 christos as_bad ("Internal error: state 0/3 not coded for extended instructions"); 3302 1.3 christos break; 3303 1.3 christos } 3304 1.3 christos 3305 1.3 christos line = extract_operand (line, l1, sizeof (l1)); 3306 1.8 christos res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, false); 3307 1.3 christos if (res) 3308 1.3 christos break; 3309 1.3 christos 3310 1.8 christos byte_op = false; 3311 1.8 christos imm_op = false; 3312 1.3 christos bin |= ((op1.reg << 8) | (op1.am << 4)); 3313 1.3 christos op_length = 2 + 2 * op1.ol; 3314 1.3 christos frag = frag_more (op_length); 3315 1.3 christos where = frag - frag_now->fr_literal; 3316 1.10 christos bfd_putl16 (bin, frag); 3317 1.3 christos 3318 1.3 christos if (op1.mode == OP_EXP) 3319 1.3 christos { 3320 1.3 christos if (op1.exp.X_op == O_constant) 3321 1.3 christos { 3322 1.3 christos bfd_putl16 (op1.exp.X_add_number & 0xffff, frag + 2); 3323 1.3 christos } 3324 1.3 christos else 3325 1.3 christos { 3326 1.3 christos where += 2; 3327 1.3 christos 3328 1.10 christos bfd_putl16 (ZEROS, frag + 2); 3329 1.3 christos 3330 1.3 christos if (op1.reg || op1.am == 3) 3331 1.3 christos fix_new_exp (frag_now, where, 2, 3332 1.8 christos &(op1.exp), false, CHECK_RELOC_MSP430 (op1)); 3333 1.3 christos else 3334 1.3 christos fix_new_exp (frag_now, where, 2, 3335 1.8 christos &(op1.exp), true, CHECK_RELOC_MSP430_PCREL); 3336 1.3 christos } 3337 1.3 christos } 3338 1.3 christos 3339 1.3 christos dwarf2_emit_insn (insn_length + op_length); 3340 1.3 christos break; 3341 1.3 christos 3342 1.3 christos case 4: 3343 1.3 christos /* CALLA instructions. */ 3344 1.8 christos fix_emitted = false; 3345 1.3 christos 3346 1.3 christos line = extract_operand (line, l1, sizeof (l1)); 3347 1.8 christos imm_op = false; 3348 1.3 christos 3349 1.3 christos res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, 3350 1.8 christos extended_op, false); 3351 1.3 christos if (res) 3352 1.3 christos break; 3353 1.3 christos 3354 1.8 christos byte_op = false; 3355 1.3 christos 3356 1.3 christos op_length = 2 + 2 * op1.ol; 3357 1.3 christos frag = frag_more (op_length); 3358 1.3 christos where = frag - frag_now->fr_literal; 3359 1.3 christos 3360 1.3 christos if (imm_op) 3361 1.3 christos { 3362 1.3 christos if (op1.am == 3) 3363 1.3 christos { 3364 1.3 christos bin |= 0xb0; 3365 1.3 christos 3366 1.8 christos fix_new_exp (frag_now, where, 4, &(op1.exp), false, 3367 1.3 christos BFD_RELOC_MSP430X_ABS20_ADR_DST); 3368 1.8 christos fix_emitted = true; 3369 1.3 christos } 3370 1.3 christos else if (op1.am == 1) 3371 1.3 christos { 3372 1.3 christos if (op1.reg == 0) 3373 1.3 christos { 3374 1.3 christos bin |= 0x90; 3375 1.3 christos 3376 1.8 christos fix_new_exp (frag_now, where, 4, &(op1.exp), false, 3377 1.3 christos BFD_RELOC_MSP430X_PCR20_CALL); 3378 1.8 christos fix_emitted = true; 3379 1.3 christos } 3380 1.3 christos else 3381 1.3 christos bin |= 0x50 | op1.reg; 3382 1.3 christos } 3383 1.3 christos else if (op1.am == 0) 3384 1.3 christos bin |= 0x40 | op1.reg; 3385 1.3 christos } 3386 1.3 christos else if (op1.am == 1) 3387 1.3 christos { 3388 1.3 christos bin |= 0x80; 3389 1.3 christos 3390 1.8 christos fix_new_exp (frag_now, where, 4, &(op1.exp), false, 3391 1.3 christos BFD_RELOC_MSP430X_ABS20_ADR_DST); 3392 1.8 christos fix_emitted = true; 3393 1.3 christos } 3394 1.3 christos else if (op1.am == 2) 3395 1.3 christos bin |= 0x60 | op1.reg; 3396 1.3 christos else if (op1.am == 3) 3397 1.3 christos bin |= 0x70 | op1.reg; 3398 1.3 christos 3399 1.10 christos bfd_putl16 (bin, frag); 3400 1.3 christos 3401 1.3 christos if (op1.mode == OP_EXP) 3402 1.3 christos { 3403 1.3 christos if (op1.ol != 1) 3404 1.3 christos { 3405 1.3 christos as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1.ol); 3406 1.3 christos break; 3407 1.3 christos } 3408 1.3 christos 3409 1.10 christos bfd_putl16 (ZEROS, frag + 2); 3410 1.3 christos 3411 1.3 christos if (! fix_emitted) 3412 1.3 christos fix_new_exp (frag_now, where + 2, 2, 3413 1.8 christos &(op1.exp), false, BFD_RELOC_16); 3414 1.3 christos } 3415 1.3 christos 3416 1.3 christos dwarf2_emit_insn (insn_length + op_length); 3417 1.3 christos break; 3418 1.3 christos 3419 1.3 christos case 5: 3420 1.1 christos { 3421 1.3 christos int n; 3422 1.3 christos int reg; 3423 1.3 christos 3424 1.3 christos /* [POP|PUSH]M[.A] #N, Rd */ 3425 1.1 christos line = extract_operand (line, l1, sizeof (l1)); 3426 1.3 christos line = extract_operand (line, l2, sizeof (l2)); 3427 1.1 christos 3428 1.3 christos if (*l1 != '#') 3429 1.3 christos { 3430 1.3 christos as_bad (_("expected #n as first argument of %s"), opcode->name); 3431 1.3 christos break; 3432 1.3 christos } 3433 1.6 christos end = parse_exp (l1 + 1, &(op1.exp)); 3434 1.6 christos if (end != NULL && *end != 0) 3435 1.6 christos { 3436 1.6 christos as_bad (_("extra characters '%s' at end of constant expression '%s'"), end, l1); 3437 1.6 christos break; 3438 1.6 christos } 3439 1.3 christos if (op1.exp.X_op != O_constant) 3440 1.3 christos { 3441 1.6 christos as_bad (_("expected constant expression as first argument of %s"), 3442 1.3 christos opcode->name); 3443 1.3 christos break; 3444 1.3 christos } 3445 1.1 christos 3446 1.3 christos if ((reg = check_reg (l2)) == -1) 3447 1.3 christos { 3448 1.3 christos as_bad (_("expected register as second argument of %s"), 3449 1.3 christos opcode->name); 3450 1.3 christos break; 3451 1.3 christos } 3452 1.1 christos 3453 1.3 christos op_length = 2; 3454 1.3 christos frag = frag_more (op_length); 3455 1.1 christos where = frag - frag_now->fr_literal; 3456 1.3 christos bin = opcode->bin_opcode; 3457 1.3 christos if (! addr_op) 3458 1.3 christos bin |= 0x100; 3459 1.3 christos n = op1.exp.X_add_number; 3460 1.3 christos bin |= (n - 1) << 4; 3461 1.3 christos if (is_opcode ("pushm")) 3462 1.3 christos bin |= reg; 3463 1.3 christos else 3464 1.3 christos { 3465 1.3 christos if (reg - n + 1 < 0) 3466 1.3 christos { 3467 1.3 christos as_bad (_("Too many registers popped")); 3468 1.3 christos break; 3469 1.3 christos } 3470 1.3 christos 3471 1.3 christos /* CPU21 errata: cannot use POPM to restore the SR register. */ 3472 1.3 christos if (target_is_430xv2 () 3473 1.3 christos && (reg - n + 1 < 3) 3474 1.3 christos && reg >= 2 3475 1.3 christos && is_opcode ("popm")) 3476 1.3 christos { 3477 1.3 christos as_bad (_("Cannot use POPM to restore the SR register")); 3478 1.3 christos break; 3479 1.3 christos } 3480 1.3 christos 3481 1.3 christos bin |= (reg - n + 1); 3482 1.3 christos } 3483 1.3 christos 3484 1.10 christos bfd_putl16 (bin, frag); 3485 1.3 christos dwarf2_emit_insn (op_length); 3486 1.3 christos break; 3487 1.3 christos } 3488 1.3 christos 3489 1.3 christos case 6: 3490 1.3 christos { 3491 1.3 christos int n; 3492 1.3 christos int reg; 3493 1.3 christos 3494 1.3 christos /* Bit rotation instructions. RRCM, RRAM, RRUM, RLAM. */ 3495 1.3 christos if (extended & 0xff) 3496 1.3 christos { 3497 1.3 christos as_bad (_("repeat count cannot be used with %s"), opcode->name); 3498 1.3 christos break; 3499 1.3 christos } 3500 1.3 christos 3501 1.3 christos line = extract_operand (line, l1, sizeof (l1)); 3502 1.3 christos line = extract_operand (line, l2, sizeof (l2)); 3503 1.3 christos 3504 1.3 christos if (*l1 != '#') 3505 1.3 christos { 3506 1.3 christos as_bad (_("expected #n as first argument of %s"), opcode->name); 3507 1.3 christos break; 3508 1.3 christos } 3509 1.6 christos end = parse_exp (l1 + 1, &(op1.exp)); 3510 1.6 christos if (end != NULL && *end != 0) 3511 1.6 christos { 3512 1.6 christos as_bad (_("extra characters '%s' at end of operand '%s'"), end, l1); 3513 1.6 christos break; 3514 1.6 christos } 3515 1.3 christos if (op1.exp.X_op != O_constant) 3516 1.3 christos { 3517 1.6 christos as_bad (_("expected constant expression as first argument of %s"), 3518 1.3 christos opcode->name); 3519 1.3 christos break; 3520 1.3 christos } 3521 1.3 christos n = op1.exp.X_add_number; 3522 1.3 christos if (n > 4 || n < 1) 3523 1.3 christos { 3524 1.3 christos as_bad (_("expected first argument of %s to be in the range 1-4"), 3525 1.3 christos opcode->name); 3526 1.3 christos break; 3527 1.3 christos } 3528 1.3 christos 3529 1.3 christos if ((reg = check_reg (l2)) == -1) 3530 1.3 christos { 3531 1.3 christos as_bad (_("expected register as second argument of %s"), 3532 1.3 christos opcode->name); 3533 1.3 christos break; 3534 1.3 christos } 3535 1.3 christos 3536 1.3 christos if (target_is_430xv2 () && reg == 0) 3537 1.3 christos { 3538 1.3 christos as_bad (_("%s: attempt to rotate the PC register"), opcode->name); 3539 1.3 christos break; 3540 1.3 christos } 3541 1.3 christos 3542 1.3 christos op_length = 2; 3543 1.3 christos frag = frag_more (op_length); 3544 1.3 christos where = frag - frag_now->fr_literal; 3545 1.3 christos 3546 1.3 christos bin = opcode->bin_opcode; 3547 1.3 christos if (! addr_op) 3548 1.3 christos bin |= 0x10; 3549 1.3 christos bin |= (n - 1) << 10; 3550 1.3 christos bin |= reg; 3551 1.3 christos 3552 1.10 christos bfd_putl16 (bin, frag); 3553 1.3 christos dwarf2_emit_insn (op_length); 3554 1.3 christos break; 3555 1.3 christos } 3556 1.3 christos 3557 1.3 christos case 8: 3558 1.3 christos { 3559 1.8 christos bool need_reloc = false; 3560 1.3 christos int n; 3561 1.3 christos int reg; 3562 1.3 christos 3563 1.3 christos /* ADDA, CMPA and SUBA address instructions. */ 3564 1.3 christos if (extended & 0xff) 3565 1.3 christos { 3566 1.3 christos as_bad (_("repeat count cannot be used with %s"), opcode->name); 3567 1.3 christos break; 3568 1.1 christos } 3569 1.1 christos 3570 1.3 christos line = extract_operand (line, l1, sizeof (l1)); 3571 1.3 christos line = extract_operand (line, l2, sizeof (l2)); 3572 1.3 christos 3573 1.3 christos bin = opcode->bin_opcode; 3574 1.3 christos 3575 1.3 christos if (*l1 == '#') 3576 1.1 christos { 3577 1.6 christos end = parse_exp (l1 + 1, &(op1.exp)); 3578 1.6 christos if (end != NULL && *end != 0) 3579 1.6 christos { 3580 1.6 christos as_bad (_("extra characters '%s' at end of operand '%s'"), end, l1); 3581 1.6 christos break; 3582 1.6 christos } 3583 1.1 christos 3584 1.3 christos if (op1.exp.X_op == O_constant) 3585 1.3 christos { 3586 1.3 christos n = op1.exp.X_add_number; 3587 1.10 christos /* Strictly speaking the positive value test should be for "n > 0x7ffff" 3588 1.10 christos but traditionally when specifying immediates as hex values any valid 3589 1.10 christos bit pattern is allowed. Hence "suba #0xfffff, r6" is allowed, and so 3590 1.10 christos the positive value test has to be "n > 0xfffff". 3591 1.10 christos FIXME: We could pre-parse the expression to find out if it starts with 3592 1.10 christos 0x and only then allow positive values > 0x7fffff. */ 3593 1.10 christos if (n > 0xfffff || n < -0x80000) 3594 1.3 christos { 3595 1.3 christos as_bad (_("expected value of first argument of %s to fit into 20-bits"), 3596 1.3 christos opcode->name); 3597 1.3 christos break; 3598 1.3 christos } 3599 1.3 christos 3600 1.3 christos bin |= ((n >> 16) & 0xf) << 8; 3601 1.3 christos } 3602 1.1 christos else 3603 1.3 christos { 3604 1.3 christos n = 0; 3605 1.8 christos need_reloc = true; 3606 1.3 christos } 3607 1.3 christos 3608 1.3 christos op_length = 4; 3609 1.3 christos } 3610 1.3 christos else 3611 1.3 christos { 3612 1.3 christos if ((n = check_reg (l1)) == -1) 3613 1.3 christos { 3614 1.3 christos as_bad (_("expected register name or constant as first argument of %s"), 3615 1.3 christos opcode->name); 3616 1.3 christos break; 3617 1.3 christos } 3618 1.3 christos 3619 1.3 christos bin |= (n << 8) | (1 << 6); 3620 1.3 christos op_length = 2; 3621 1.1 christos } 3622 1.3 christos 3623 1.3 christos if ((reg = check_reg (l2)) == -1) 3624 1.3 christos { 3625 1.3 christos as_bad (_("expected register as second argument of %s"), 3626 1.3 christos opcode->name); 3627 1.3 christos break; 3628 1.3 christos } 3629 1.3 christos 3630 1.3 christos frag = frag_more (op_length); 3631 1.3 christos where = frag - frag_now->fr_literal; 3632 1.3 christos bin |= reg; 3633 1.3 christos if (need_reloc) 3634 1.8 christos fix_new_exp (frag_now, where, 4, &(op1.exp), false, 3635 1.3 christos BFD_RELOC_MSP430X_ABS20_ADR_SRC); 3636 1.3 christos 3637 1.10 christos bfd_putl16 (bin, frag); 3638 1.3 christos if (op_length == 4) 3639 1.10 christos bfd_putl16 (n & 0xffff, frag + 2); 3640 1.3 christos dwarf2_emit_insn (op_length); 3641 1.1 christos break; 3642 1.1 christos } 3643 1.1 christos 3644 1.3 christos case 9: /* MOVA, BRA, RETA. */ 3645 1.8 christos imm_op = false; 3646 1.3 christos bin = opcode->bin_opcode; 3647 1.3 christos 3648 1.3 christos if (is_opcode ("reta")) 3649 1.3 christos { 3650 1.3 christos /* The RETA instruction does not take any arguments. 3651 1.3 christos The implicit first argument is @SP+. 3652 1.3 christos The implicit second argument is PC. */ 3653 1.3 christos op1.mode = OP_REG; 3654 1.3 christos op1.am = 3; 3655 1.3 christos op1.reg = 1; 3656 1.3 christos 3657 1.3 christos op2.mode = OP_REG; 3658 1.3 christos op2.reg = 0; 3659 1.3 christos } 3660 1.3 christos else 3661 1.3 christos { 3662 1.3 christos line = extract_operand (line, l1, sizeof (l1)); 3663 1.3 christos res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, 3664 1.8 christos &imm_op, extended_op, false); 3665 1.3 christos 3666 1.3 christos if (is_opcode ("bra")) 3667 1.3 christos { 3668 1.3 christos /* This is the BRA synthetic instruction. 3669 1.3 christos The second argument is always PC. */ 3670 1.3 christos op2.mode = OP_REG; 3671 1.3 christos op2.reg = 0; 3672 1.3 christos } 3673 1.3 christos else 3674 1.3 christos { 3675 1.3 christos line = extract_operand (line, l2, sizeof (l2)); 3676 1.3 christos res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, 3677 1.8 christos extended_op, true); 3678 1.3 christos } 3679 1.3 christos 3680 1.3 christos if (res) 3681 1.3 christos break; /* Error occurred. All warnings were done before. */ 3682 1.3 christos } 3683 1.1 christos 3684 1.3 christos /* Only a restricted subset of the normal MSP430 addressing modes 3685 1.3 christos are supported here, so check for the ones that are allowed. */ 3686 1.3 christos if ((op_length = try_encode_mova (imm_op, bin, & op1, & op2, 3687 1.3 christos & error_message)) == 0) 3688 1.3 christos { 3689 1.3 christos as_bad (error_message, opcode->name); 3690 1.3 christos break; 3691 1.3 christos } 3692 1.3 christos dwarf2_emit_insn (op_length); 3693 1.3 christos break; 3694 1.1 christos 3695 1.3 christos case 10: /* RPT */ 3696 1.3 christos line = extract_operand (line, l1, sizeof l1); 3697 1.3 christos /* The RPT instruction only accepted immediates and registers. */ 3698 1.3 christos if (*l1 == '#') 3699 1.3 christos { 3700 1.6 christos end = parse_exp (l1 + 1, &(op1.exp)); 3701 1.6 christos if (end != NULL && *end != 0) 3702 1.6 christos { 3703 1.6 christos as_bad (_("extra characters '%s' at end of operand '%s'"), end, l1); 3704 1.6 christos break; 3705 1.6 christos } 3706 1.3 christos if (op1.exp.X_op != O_constant) 3707 1.3 christos { 3708 1.3 christos as_bad (_("expected constant value as argument to RPT")); 3709 1.3 christos break; 3710 1.3 christos } 3711 1.3 christos if (op1.exp.X_add_number < 1 3712 1.3 christos || op1.exp.X_add_number > (1 << 4)) 3713 1.3 christos { 3714 1.3 christos as_bad (_("expected constant in the range 2..16")); 3715 1.3 christos break; 3716 1.3 christos } 3717 1.1 christos 3718 1.3 christos /* We silently accept and ignore a repeat count of 1. */ 3719 1.3 christos if (op1.exp.X_add_number > 1) 3720 1.3 christos repeat_count = op1.exp.X_add_number; 3721 1.3 christos } 3722 1.3 christos else 3723 1.1 christos { 3724 1.3 christos int reg; 3725 1.1 christos 3726 1.3 christos if ((reg = check_reg (l1)) != -1) 3727 1.3 christos { 3728 1.3 christos if (reg == 0) 3729 1.3 christos as_warn (_("PC used as an argument to RPT")); 3730 1.3 christos else 3731 1.3 christos repeat_count = - reg; 3732 1.3 christos } 3733 1.1 christos else 3734 1.3 christos { 3735 1.3 christos as_bad (_("expected constant or register name as argument to RPT insn")); 3736 1.3 christos break; 3737 1.3 christos } 3738 1.1 christos } 3739 1.1 christos break; 3740 1.3 christos 3741 1.3 christos default: 3742 1.6 christos as_bad (_("Illegal emulated instruction")); 3743 1.3 christos break; 3744 1.1 christos } 3745 1.1 christos break; 3746 1.1 christos 3747 1.7 christos /* FIXME: Emit warning when dest reg SR(R2) is addressed with .B or .A. 3748 1.7 christos From f5 ref man 6.3.3: 3749 1.7 christos The 16-bit Status Register (SR, also called R2), used as a source or 3750 1.7 christos destination register, can only be used in register mode addressed 3751 1.7 christos with word instructions. */ 3752 1.7 christos 3753 1.1 christos case 1: /* Format 1, double operand. */ 3754 1.1 christos line = extract_operand (line, l1, sizeof (l1)); 3755 1.1 christos line = extract_operand (line, l2, sizeof (l2)); 3756 1.8 christos res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, true); 3757 1.8 christos res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, extended_op, true); 3758 1.1 christos 3759 1.1 christos if (res) 3760 1.1 christos break; /* Error occurred. All warnings were done before. */ 3761 1.1 christos 3762 1.3 christos if (extended_op 3763 1.3 christos && is_opcode ("movx") 3764 1.3 christos && addr_op 3765 1.3 christos && msp430_enable_relax) 3766 1.3 christos { 3767 1.3 christos /* This is the MOVX.A instruction. See if we can convert 3768 1.3 christos it into the MOVA instruction instead. This saves 2 bytes. */ 3769 1.3 christos if ((op_length = try_encode_mova (imm_op, 0x0000, & op1, & op2, 3770 1.3 christos NULL)) != 0) 3771 1.3 christos { 3772 1.3 christos dwarf2_emit_insn (op_length); 3773 1.3 christos break; 3774 1.3 christos } 3775 1.3 christos } 3776 1.3 christos 3777 1.1 christos bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7)); 3778 1.1 christos 3779 1.3 christos /* If the PC is the destination... */ 3780 1.3 christos if (op2.am == 0 && op2.reg == 0 3781 1.3 christos /* ... and the opcode alters the SR. */ 3782 1.3 christos && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov") 3783 1.3 christos || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx"))) 3784 1.3 christos { 3785 1.3 christos if (silicon_errata_fix & SILICON_ERRATA_CPU11) 3786 1.6 christos as_bad (_("CPU11: PC is destination of SR altering instruction")); 3787 1.3 christos else if (silicon_errata_warn & SILICON_ERRATA_CPU11) 3788 1.6 christos as_warn (_("CPU11: PC is destination of SR altering instruction")); 3789 1.3 christos } 3790 1.3 christos 3791 1.3 christos /* If the status register is the destination... */ 3792 1.3 christos if (op2.am == 0 && op2.reg == 2 3793 1.3 christos /* ... and the opcode alters the SR. */ 3794 1.3 christos && (is_opcode ("add") || is_opcode ("addc") || is_opcode ("and") 3795 1.3 christos || is_opcode ("dadd") || is_opcode ("sub") || is_opcode ("subc") 3796 1.3 christos || is_opcode ("xor") 3797 1.3 christos || is_opcode ("addx") || is_opcode ("addcx") || is_opcode ("andx") 3798 1.3 christos || is_opcode ("daddx") || is_opcode ("subx") || is_opcode ("subcx") 3799 1.3 christos || is_opcode ("xorx") 3800 1.3 christos )) 3801 1.3 christos { 3802 1.3 christos if (silicon_errata_fix & SILICON_ERRATA_CPU13) 3803 1.6 christos as_bad (_("CPU13: SR is destination of SR altering instruction")); 3804 1.3 christos else if (silicon_errata_warn & SILICON_ERRATA_CPU13) 3805 1.6 christos as_warn (_("CPU13: SR is destination of SR altering instruction")); 3806 1.3 christos } 3807 1.3 christos 3808 1.7 christos /* Chain these checks for SR manipulations so we can warn if they are not 3809 1.7 christos caught. */ 3810 1.3 christos if (((is_opcode ("bis") && bin == 0xd032) 3811 1.3 christos || (is_opcode ("mov") && bin == 0x4032) 3812 1.3 christos || (is_opcode ("xor") && bin == 0xe032)) 3813 1.3 christos && op1.mode == OP_EXP 3814 1.3 christos && op1.exp.X_op == O_constant 3815 1.3 christos && (op1.exp.X_add_number & 0x10) == 0x10) 3816 1.3 christos check_for_nop |= NOP_CHECK_CPU19; 3817 1.7 christos else if ((is_opcode ("mov") && op2.mode == OP_REG && op2.reg == 2)) 3818 1.7 christos { 3819 1.7 christos /* Any MOV with the SR as the destination either enables or disables 3820 1.7 christos interrupts. */ 3821 1.7 christos if (op1.mode == OP_EXP 3822 1.7 christos && op1.exp.X_op == O_constant) 3823 1.7 christos { 3824 1.7 christos if ((op1.exp.X_add_number & 0x8) == 0x8) 3825 1.7 christos { 3826 1.7 christos /* The GIE bit is being set. */ 3827 1.7 christos warn_eint_nop (prev_insn_is_nop, prev_insn_is_dint); 3828 1.8 christos this_insn_is_eint = true; 3829 1.7 christos } 3830 1.7 christos else 3831 1.7 christos /* The GIE bit is being cleared. */ 3832 1.8 christos this_insn_is_dint = true; 3833 1.7 christos } 3834 1.7 christos /* If an immediate value which is covered by the constant generator 3835 1.7 christos is the src, then op1 will have been changed to either R2 or R3 by 3836 1.7 christos this point. 3837 1.7 christos The only constants covered by CG1 and CG2, which have bit 3 set 3838 1.7 christos and therefore would enable interrupts when writing to the SR, are 3839 1.7 christos R2 with addresing mode 0b11 and R3 with 0b11. 3840 1.7 christos The addressing mode is in bits 5:4 of the binary opcode. */ 3841 1.7 christos else if (op1.mode == OP_REG 3842 1.7 christos && (op1.reg == 2 || op1.reg == 3) 3843 1.7 christos && (bin & 0x30) == 0x30) 3844 1.7 christos { 3845 1.7 christos warn_eint_nop (prev_insn_is_nop, prev_insn_is_dint); 3846 1.8 christos this_insn_is_eint = true; 3847 1.7 christos } 3848 1.7 christos /* Any other use of the constant generator with destination R2, will 3849 1.7 christos disable interrupts. */ 3850 1.7 christos else if (op1.mode == OP_REG 3851 1.7 christos && (op1.reg == 2 || op1.reg == 3)) 3852 1.8 christos this_insn_is_dint = true; 3853 1.7 christos else if (do_unknown_interrupt_nops) 3854 1.7 christos { 3855 1.7 christos /* FIXME: Couldn't work out whether the insn is enabling or 3856 1.7 christos disabling interrupts, so for safety need to treat it as both 3857 1.7 christos a DINT and EINT. */ 3858 1.7 christos warn_unsure_interrupt (prev_insn_is_nop, prev_insn_is_dint); 3859 1.7 christos check_for_nop |= NOP_CHECK_INTERRUPT; 3860 1.7 christos } 3861 1.7 christos } 3862 1.7 christos else if (is_eint (opcode->name, bin)) 3863 1.7 christos warn_eint_nop (prev_insn_is_nop, prev_insn_is_dint); 3864 1.7 christos else if ((bin & 0x32) == 0x32) 3865 1.7 christos { 3866 1.7 christos /* Double-operand insn with the As==0b11 and Rdst==0x2 will result in 3867 1.7 christos * an interrupt state change if a write happens. */ 3868 1.7 christos /* FIXME: How strict to be here? */ 3869 1.7 christos ; 3870 1.7 christos } 3871 1.3 christos 3872 1.3 christos /* Compute the entire length of the instruction in bytes. */ 3873 1.3 christos op_length = (extended_op ? 2 : 0) /* The extension word. */ 3874 1.3 christos + 2 /* The opcode */ 3875 1.3 christos + (2 * op1.ol) /* The first operand. */ 3876 1.3 christos + (2 * op2.ol); /* The second operand. */ 3877 1.3 christos 3878 1.3 christos insn_length += op_length; 3879 1.3 christos frag = frag_more (op_length); 3880 1.1 christos where = frag - frag_now->fr_literal; 3881 1.3 christos 3882 1.3 christos if (extended_op) 3883 1.3 christos { 3884 1.3 christos if (!addr_op) 3885 1.3 christos extended |= BYTE_OPERATION; 3886 1.3 christos 3887 1.3 christos if ((op1.ol != 0 || op2.ol != 0) && ((extended & 0xf) != 0)) 3888 1.3 christos { 3889 1.3 christos as_bad (_("repeat instruction used with non-register mode instruction")); 3890 1.3 christos extended &= ~ 0xf; 3891 1.3 christos } 3892 1.3 christos 3893 1.3 christos /* If necessary, emit a reloc to update the extension word. */ 3894 1.3 christos if (op1.mode == OP_EXP) 3895 1.3 christos { 3896 1.3 christos if (op1.exp.X_op == O_constant) 3897 1.3 christos extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7; 3898 1.3 christos 3899 1.3 christos else if (op1.reg || op1.am == 3) /* Not PC relative. */ 3900 1.8 christos fix_new_exp (frag_now, where, 6, &(op1.exp), false, 3901 1.3 christos BFD_RELOC_MSP430X_ABS20_EXT_SRC); 3902 1.3 christos else 3903 1.8 christos fix_new_exp (frag_now, where, 6, &(op1.exp), false, 3904 1.3 christos BFD_RELOC_MSP430X_PCR20_EXT_SRC); 3905 1.3 christos } 3906 1.3 christos 3907 1.3 christos if (op2.mode == OP_EXP) 3908 1.3 christos { 3909 1.3 christos if (op2.exp.X_op == O_constant) 3910 1.3 christos extended |= (op2.exp.X_add_number >> 16) & 0xf; 3911 1.3 christos 3912 1.3 christos else if (op1.mode == OP_EXP) 3913 1.8 christos fix_new_exp (frag_now, where, 8, &(op2.exp), false, 3914 1.3 christos op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_ODST 3915 1.3 christos : BFD_RELOC_MSP430X_PCR20_EXT_ODST); 3916 1.3 christos 3917 1.3 christos else 3918 1.8 christos fix_new_exp (frag_now, where, 6, &(op2.exp), false, 3919 1.3 christos op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_DST 3920 1.3 christos : BFD_RELOC_MSP430X_PCR20_EXT_DST); 3921 1.3 christos } 3922 1.3 christos 3923 1.3 christos /* Emit the extension word. */ 3924 1.3 christos bfd_putl16 (extended, frag); 3925 1.3 christos where += 2; 3926 1.3 christos frag += 2; 3927 1.3 christos } 3928 1.3 christos 3929 1.10 christos bfd_putl16 (bin, frag); 3930 1.3 christos where += 2; 3931 1.3 christos frag += 2; 3932 1.1 christos 3933 1.1 christos if (op1.mode == OP_EXP) 3934 1.1 christos { 3935 1.3 christos if (op1.exp.X_op == O_constant) 3936 1.3 christos { 3937 1.3 christos bfd_putl16 (op1.exp.X_add_number & 0xffff, frag); 3938 1.3 christos } 3939 1.3 christos else 3940 1.3 christos { 3941 1.10 christos bfd_putl16 (ZEROS, frag); 3942 1.3 christos 3943 1.3 christos if (!extended_op) 3944 1.3 christos { 3945 1.3 christos if (op1.reg || op1.am == 3) /* Not PC relative. */ 3946 1.3 christos fix_new_exp (frag_now, where, 2, 3947 1.8 christos &(op1.exp), false, CHECK_RELOC_MSP430 (op1)); 3948 1.3 christos else 3949 1.3 christos fix_new_exp (frag_now, where, 2, 3950 1.8 christos &(op1.exp), true, CHECK_RELOC_MSP430_PCREL); 3951 1.3 christos } 3952 1.3 christos } 3953 1.1 christos 3954 1.3 christos where += 2; 3955 1.3 christos frag += 2; 3956 1.1 christos } 3957 1.1 christos 3958 1.1 christos if (op2.mode == OP_EXP) 3959 1.1 christos { 3960 1.3 christos if (op2.exp.X_op == O_constant) 3961 1.3 christos { 3962 1.3 christos bfd_putl16 (op2.exp.X_add_number & 0xffff, frag); 3963 1.3 christos } 3964 1.3 christos else 3965 1.3 christos { 3966 1.10 christos bfd_putl16 (ZEROS, frag); 3967 1.1 christos 3968 1.3 christos if (!extended_op) 3969 1.3 christos { 3970 1.3 christos if (op2.reg) /* Not PC relative. */ 3971 1.3 christos fix_new_exp (frag_now, where, 2, 3972 1.8 christos &(op2.exp), false, CHECK_RELOC_MSP430 (op2)); 3973 1.3 christos else 3974 1.3 christos fix_new_exp (frag_now, where, 2, 3975 1.8 christos &(op2.exp), true, CHECK_RELOC_MSP430_PCREL); 3976 1.3 christos } 3977 1.3 christos } 3978 1.1 christos } 3979 1.3 christos 3980 1.3 christos dwarf2_emit_insn (insn_length); 3981 1.3 christos 3982 1.3 christos /* If the PC is the destination... */ 3983 1.3 christos if (op2.am == 0 && op2.reg == 0 3984 1.3 christos /* ... but the opcode does not alter the destination. */ 3985 1.3 christos && (is_opcode ("cmp") || is_opcode ("bit") || is_opcode ("cmpx"))) 3986 1.3 christos check_for_nop |= NOP_CHECK_CPU12; 3987 1.1 christos break; 3988 1.1 christos 3989 1.1 christos case 2: /* Single-operand mostly instr. */ 3990 1.1 christos if (opcode->insn_opnumb == 0) 3991 1.1 christos { 3992 1.1 christos /* reti instruction. */ 3993 1.3 christos insn_length += 2; 3994 1.1 christos frag = frag_more (2); 3995 1.10 christos bfd_putl16 (bin, frag); 3996 1.3 christos dwarf2_emit_insn (insn_length); 3997 1.1 christos break; 3998 1.1 christos } 3999 1.1 christos 4000 1.1 christos line = extract_operand (line, l1, sizeof (l1)); 4001 1.3 christos res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, 4002 1.8 christos &imm_op, extended_op, true); 4003 1.1 christos if (res) 4004 1.1 christos break; /* Error in operand. */ 4005 1.1 christos 4006 1.3 christos if (target_is_430xv2 () 4007 1.3 christos && op1.mode == OP_REG 4008 1.3 christos && op1.reg == 0 4009 1.3 christos && (is_opcode ("rrax") 4010 1.3 christos || is_opcode ("rrcx") 4011 1.3 christos || is_opcode ("rra") 4012 1.3 christos || is_opcode ("rrc"))) 4013 1.3 christos { 4014 1.3 christos as_bad (_("%s: attempt to rotate the PC register"), opcode->name); 4015 1.3 christos break; 4016 1.3 christos } 4017 1.3 christos 4018 1.3 christos /* If the status register is the destination... */ 4019 1.3 christos if (op1.am == 0 && op1.reg == 2 4020 1.3 christos /* ... and the opcode alters the SR. */ 4021 1.3 christos && (is_opcode ("rra") || is_opcode ("rrc") || is_opcode ("sxt"))) 4022 1.3 christos { 4023 1.3 christos if (silicon_errata_fix & SILICON_ERRATA_CPU13) 4024 1.6 christos as_bad (_("CPU13: SR is destination of SR altering instruction")); 4025 1.3 christos else if (silicon_errata_warn & SILICON_ERRATA_CPU13) 4026 1.6 christos as_warn (_("CPU13: SR is destination of SR altering instruction")); 4027 1.3 christos } 4028 1.3 christos 4029 1.3 christos insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2); 4030 1.3 christos frag = frag_more (insn_length); 4031 1.3 christos where = frag - frag_now->fr_literal; 4032 1.3 christos 4033 1.3 christos if (extended_op) 4034 1.3 christos { 4035 1.3 christos if (is_opcode ("swpbx") || is_opcode ("sxtx")) 4036 1.3 christos { 4037 1.3 christos /* These two instructions use a special 4038 1.3 christos encoding of the A/L and B/W bits. */ 4039 1.3 christos bin &= ~ BYTE_OPERATION; 4040 1.3 christos 4041 1.3 christos if (byte_op) 4042 1.3 christos { 4043 1.3 christos as_bad (_("%s instruction does not accept a .b suffix"), 4044 1.3 christos opcode->name); 4045 1.3 christos break; 4046 1.3 christos } 4047 1.3 christos else if (! addr_op) 4048 1.3 christos extended |= BYTE_OPERATION; 4049 1.3 christos } 4050 1.3 christos else if (! addr_op) 4051 1.3 christos extended |= BYTE_OPERATION; 4052 1.3 christos 4053 1.5 christos if (is_opcode ("rrux")) 4054 1.5 christos extended |= IGNORE_CARRY_BIT; 4055 1.5 christos 4056 1.3 christos if (op1.ol != 0 && ((extended & 0xf) != 0)) 4057 1.3 christos { 4058 1.3 christos as_bad (_("repeat instruction used with non-register mode instruction")); 4059 1.3 christos extended &= ~ 0xf; 4060 1.3 christos } 4061 1.3 christos 4062 1.3 christos if (op1.mode == OP_EXP) 4063 1.3 christos { 4064 1.3 christos if (op1.exp.X_op == O_constant) 4065 1.3 christos extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7; 4066 1.3 christos 4067 1.3 christos else if (op1.reg || op1.am == 3) /* Not PC relative. */ 4068 1.8 christos fix_new_exp (frag_now, where, 6, &(op1.exp), false, 4069 1.3 christos BFD_RELOC_MSP430X_ABS20_EXT_SRC); 4070 1.3 christos else 4071 1.8 christos fix_new_exp (frag_now, where, 6, &(op1.exp), false, 4072 1.3 christos BFD_RELOC_MSP430X_PCR20_EXT_SRC); 4073 1.3 christos } 4074 1.3 christos 4075 1.3 christos /* Emit the extension word. */ 4076 1.3 christos bfd_putl16 (extended, frag); 4077 1.3 christos frag += 2; 4078 1.3 christos where += 2; 4079 1.3 christos } 4080 1.3 christos 4081 1.1 christos bin |= op1.reg | (op1.am << 4); 4082 1.10 christos bfd_putl16 (bin, frag); 4083 1.3 christos frag += 2; 4084 1.3 christos where += 2; 4085 1.1 christos 4086 1.1 christos if (op1.mode == OP_EXP) 4087 1.1 christos { 4088 1.3 christos if (op1.exp.X_op == O_constant) 4089 1.3 christos { 4090 1.3 christos bfd_putl16 (op1.exp.X_add_number & 0xffff, frag); 4091 1.3 christos } 4092 1.3 christos else 4093 1.3 christos { 4094 1.10 christos bfd_putl16 (ZEROS, frag); 4095 1.1 christos 4096 1.3 christos if (!extended_op) 4097 1.3 christos { 4098 1.3 christos if (op1.reg || op1.am == 3) /* Not PC relative. */ 4099 1.3 christos fix_new_exp (frag_now, where, 2, 4100 1.8 christos &(op1.exp), false, CHECK_RELOC_MSP430 (op1)); 4101 1.3 christos else 4102 1.3 christos fix_new_exp (frag_now, where, 2, 4103 1.8 christos &(op1.exp), true, CHECK_RELOC_MSP430_PCREL); 4104 1.3 christos } 4105 1.3 christos } 4106 1.1 christos } 4107 1.3 christos 4108 1.3 christos dwarf2_emit_insn (insn_length); 4109 1.1 christos break; 4110 1.1 christos 4111 1.1 christos case 3: /* Conditional jumps instructions. */ 4112 1.1 christos line = extract_operand (line, l1, sizeof (l1)); 4113 1.1 christos /* l1 is a label. */ 4114 1.1 christos if (l1[0]) 4115 1.1 christos { 4116 1.1 christos char *m = l1; 4117 1.1 christos expressionS exp; 4118 1.1 christos 4119 1.1 christos if (*m == '$') 4120 1.1 christos m++; 4121 1.1 christos 4122 1.6 christos end = parse_exp (m, &exp); 4123 1.6 christos if (end != NULL && *end != 0) 4124 1.6 christos { 4125 1.6 christos as_bad (_("extra characters '%s' at end of operand '%s'"), end, l1); 4126 1.6 christos break; 4127 1.6 christos } 4128 1.1 christos 4129 1.1 christos /* In order to handle something like: 4130 1.1 christos 4131 1.1 christos and #0x8000, r5 4132 1.1 christos tst r5 4133 1.1 christos jz 4 ; skip next 4 bytes 4134 1.1 christos inv r5 4135 1.1 christos inc r5 4136 1.1 christos nop ; will jump here if r5 positive or zero 4137 1.1 christos 4138 1.1 christos jCOND -n ;assumes jump n bytes backward: 4139 1.1 christos 4140 1.1 christos mov r5,r6 4141 1.1 christos jmp -2 4142 1.1 christos 4143 1.1 christos is equal to: 4144 1.1 christos lab: 4145 1.1 christos mov r5,r6 4146 1.1 christos jmp lab 4147 1.1 christos 4148 1.1 christos jCOND $n ; jump from PC in either direction. */ 4149 1.1 christos 4150 1.1 christos if (exp.X_op == O_constant) 4151 1.1 christos { 4152 1.1 christos int x = exp.X_add_number; 4153 1.1 christos 4154 1.1 christos if (x & 1) 4155 1.1 christos { 4156 1.1 christos as_warn (_("Even number required. Rounded to %d"), x + 1); 4157 1.1 christos x++; 4158 1.1 christos } 4159 1.1 christos 4160 1.1 christos if ((*l1 == '$' && x > 0) || x < 0) 4161 1.1 christos x -= 2; 4162 1.1 christos 4163 1.1 christos x >>= 1; 4164 1.1 christos 4165 1.1 christos if (x > 512 || x < -511) 4166 1.1 christos { 4167 1.6 christos as_bad (_("Wrong displacement %d"), x << 1); 4168 1.1 christos break; 4169 1.1 christos } 4170 1.1 christos 4171 1.3 christos insn_length += 2; 4172 1.3 christos frag = frag_more (2); /* Instr size is 1 word. */ 4173 1.3 christos 4174 1.1 christos bin |= x & 0x3ff; 4175 1.10 christos bfd_putl16 (bin, frag); 4176 1.1 christos } 4177 1.1 christos else if (exp.X_op == O_symbol && *l1 != '$') 4178 1.1 christos { 4179 1.3 christos insn_length += 2; 4180 1.3 christos frag = frag_more (2); /* Instr size is 1 word. */ 4181 1.1 christos where = frag - frag_now->fr_literal; 4182 1.1 christos fix_new_exp (frag_now, where, 2, 4183 1.8 christos &exp, true, BFD_RELOC_MSP430_10_PCREL); 4184 1.1 christos 4185 1.10 christos bfd_putl16 (bin, frag); 4186 1.1 christos } 4187 1.1 christos else if (*l1 == '$') 4188 1.1 christos { 4189 1.1 christos as_bad (_("instruction requires label sans '$'")); 4190 1.1 christos } 4191 1.1 christos else 4192 1.3 christos as_bad (_ 4193 1.3 christos ("instruction requires label or value in range -511:512")); 4194 1.3 christos dwarf2_emit_insn (insn_length); 4195 1.1 christos break; 4196 1.1 christos } 4197 1.1 christos else 4198 1.1 christos { 4199 1.1 christos as_bad (_("instruction requires label")); 4200 1.1 christos break; 4201 1.1 christos } 4202 1.1 christos break; 4203 1.1 christos 4204 1.1 christos case 4: /* Extended jumps. */ 4205 1.1 christos if (!msp430_enable_polys) 4206 1.1 christos { 4207 1.1 christos as_bad (_("polymorphs are not enabled. Use -mP option to enable.")); 4208 1.1 christos break; 4209 1.1 christos } 4210 1.3 christos 4211 1.1 christos line = extract_operand (line, l1, sizeof (l1)); 4212 1.1 christos if (l1[0]) 4213 1.1 christos { 4214 1.1 christos char *m = l1; 4215 1.1 christos expressionS exp; 4216 1.1 christos 4217 1.1 christos /* Ignore absolute addressing. make it PC relative anyway. */ 4218 1.1 christos if (*m == '#' || *m == '$') 4219 1.1 christos m++; 4220 1.1 christos 4221 1.6 christos end = parse_exp (m, & exp); 4222 1.6 christos if (end != NULL && *end != 0) 4223 1.6 christos { 4224 1.6 christos as_bad (_("extra characters '%s' at end of operand '%s'"), end, l1); 4225 1.6 christos break; 4226 1.6 christos } 4227 1.1 christos if (exp.X_op == O_symbol) 4228 1.1 christos { 4229 1.1 christos /* Relaxation required. */ 4230 1.1 christos struct rcodes_s rc = msp430_rcodes[opcode->insn_opnumb]; 4231 1.1 christos 4232 1.3 christos if (target_is_430x ()) 4233 1.3 christos rc = msp430x_rcodes[opcode->insn_opnumb]; 4234 1.3 christos 4235 1.3 christos /* The parameter to dwarf2_emit_insn is actually the offset to 4236 1.3 christos the start of the insn from the fix piece of instruction that 4237 1.3 christos was emitted. Since next fragments may have variable size we 4238 1.3 christos tie debug info to the beginning of the instruction. */ 4239 1.3 christos insn_length += 8; 4240 1.1 christos frag = frag_more (8); 4241 1.1 christos dwarf2_emit_insn (0); 4242 1.10 christos bfd_putl16 (rc.sop, frag); 4243 1.1 christos frag = frag_variant (rs_machine_dependent, 8, 2, 4244 1.3 christos /* Wild guess. */ 4245 1.3 christos ENCODE_RELAX (rc.lpos, STATE_BITS10), 4246 1.1 christos exp.X_add_symbol, 4247 1.1 christos 0, /* Offset is zero if jump dist less than 1K. */ 4248 1.1 christos (char *) frag); 4249 1.1 christos break; 4250 1.1 christos } 4251 1.1 christos } 4252 1.1 christos 4253 1.1 christos as_bad (_("instruction requires label")); 4254 1.1 christos break; 4255 1.1 christos 4256 1.1 christos case 5: /* Emulated extended branches. */ 4257 1.1 christos if (!msp430_enable_polys) 4258 1.1 christos { 4259 1.1 christos as_bad (_("polymorphs are not enabled. Use -mP option to enable.")); 4260 1.1 christos break; 4261 1.1 christos } 4262 1.1 christos line = extract_operand (line, l1, sizeof (l1)); 4263 1.1 christos if (l1[0]) 4264 1.1 christos { 4265 1.1 christos char * m = l1; 4266 1.1 christos expressionS exp; 4267 1.1 christos 4268 1.1 christos /* Ignore absolute addressing. make it PC relative anyway. */ 4269 1.1 christos if (*m == '#' || *m == '$') 4270 1.1 christos m++; 4271 1.1 christos 4272 1.6 christos end = parse_exp (m, & exp); 4273 1.6 christos if (end != NULL && *end != 0) 4274 1.6 christos { 4275 1.6 christos as_bad (_("extra characters '%s' at end of operand '%s'"), end, l1); 4276 1.6 christos break; 4277 1.6 christos } 4278 1.1 christos if (exp.X_op == O_symbol) 4279 1.1 christos { 4280 1.1 christos /* Relaxation required. */ 4281 1.1 christos struct hcodes_s hc = msp430_hcodes[opcode->insn_opnumb]; 4282 1.1 christos 4283 1.3 christos if (target_is_430x ()) 4284 1.3 christos hc = msp430x_hcodes[opcode->insn_opnumb]; 4285 1.3 christos 4286 1.3 christos insn_length += 8; 4287 1.1 christos frag = frag_more (8); 4288 1.1 christos dwarf2_emit_insn (0); 4289 1.10 christos bfd_putl16 (hc.op0, frag); 4290 1.10 christos bfd_putl16 (hc.op1, frag + 2); 4291 1.1 christos 4292 1.1 christos frag = frag_variant (rs_machine_dependent, 8, 2, 4293 1.1 christos ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10), /* Wild guess. */ 4294 1.1 christos exp.X_add_symbol, 4295 1.1 christos 0, /* Offset is zero if jump dist less than 1K. */ 4296 1.1 christos (char *) frag); 4297 1.1 christos break; 4298 1.1 christos } 4299 1.1 christos } 4300 1.1 christos 4301 1.1 christos as_bad (_("instruction requires label")); 4302 1.1 christos break; 4303 1.1 christos 4304 1.1 christos default: 4305 1.1 christos as_bad (_("Illegal instruction or not implemented opcode.")); 4306 1.1 christos } 4307 1.1 christos 4308 1.7 christos if (is_opcode ("nop")) 4309 1.7 christos { 4310 1.8 christos prev_insn_is_nop = true; 4311 1.8 christos prev_insn_is_dint = false; 4312 1.8 christos prev_insn_is_eint = false; 4313 1.7 christos } 4314 1.7 christos else if (this_insn_is_dint || is_dint (opcode->name, bin)) 4315 1.7 christos { 4316 1.8 christos prev_insn_is_dint = true; 4317 1.8 christos prev_insn_is_eint = false; 4318 1.8 christos prev_insn_is_nop = false; 4319 1.7 christos check_for_nop |= NOP_CHECK_INTERRUPT; 4320 1.7 christos } 4321 1.7 christos /* NOP is not needed after EINT for 430 ISA. */ 4322 1.7 christos else if (target_is_430x () && (this_insn_is_eint || is_eint (opcode->name, bin))) 4323 1.7 christos { 4324 1.8 christos prev_insn_is_eint = true; 4325 1.8 christos prev_insn_is_nop = false; 4326 1.8 christos prev_insn_is_dint = false; 4327 1.7 christos check_for_nop |= NOP_CHECK_INTERRUPT; 4328 1.7 christos } 4329 1.7 christos else 4330 1.7 christos { 4331 1.8 christos prev_insn_is_nop = false; 4332 1.8 christos prev_insn_is_dint = false; 4333 1.8 christos prev_insn_is_eint = false; 4334 1.7 christos } 4335 1.7 christos 4336 1.1 christos input_line_pointer = line; 4337 1.1 christos return 0; 4338 1.1 christos } 4339 1.1 christos 4340 1.1 christos void 4341 1.1 christos md_assemble (char * str) 4342 1.1 christos { 4343 1.1 christos struct msp430_opcode_s * opcode; 4344 1.1 christos char cmd[32]; 4345 1.1 christos unsigned int i = 0; 4346 1.1 christos 4347 1.1 christos str = skip_space (str); /* Skip leading spaces. */ 4348 1.3 christos str = extract_cmd (str, cmd, sizeof (cmd) - 1); 4349 1.1 christos 4350 1.3 christos while (cmd[i]) 4351 1.1 christos { 4352 1.1 christos char a = TOLOWER (cmd[i]); 4353 1.1 christos cmd[i] = a; 4354 1.1 christos i++; 4355 1.1 christos } 4356 1.1 christos 4357 1.1 christos if (!cmd[0]) 4358 1.1 christos { 4359 1.6 christos as_bad (_("can't find opcode")); 4360 1.1 christos return; 4361 1.1 christos } 4362 1.1 christos 4363 1.10 christos opcode = str_hash_find (msp430_hash, cmd); 4364 1.1 christos 4365 1.1 christos if (opcode == NULL) 4366 1.1 christos { 4367 1.1 christos as_bad (_("unknown opcode `%s'"), cmd); 4368 1.1 christos return; 4369 1.1 christos } 4370 1.1 christos 4371 1.1 christos { 4372 1.1 christos char *__t = input_line_pointer; 4373 1.1 christos 4374 1.1 christos msp430_operands (opcode, str); 4375 1.1 christos input_line_pointer = __t; 4376 1.1 christos } 4377 1.1 christos } 4378 1.1 christos 4379 1.1 christos /* GAS will call this function for each section at the end of the assembly, 4380 1.1 christos to permit the CPU backend to adjust the alignment of a section. */ 4381 1.1 christos 4382 1.1 christos valueT 4383 1.1 christos md_section_align (asection * seg, valueT addr) 4384 1.1 christos { 4385 1.7 christos int align = bfd_section_alignment (seg); 4386 1.1 christos 4387 1.10 christos return (addr + ((valueT) 1 << align) - 1) & -((valueT) 1 << align); 4388 1.1 christos } 4389 1.1 christos 4390 1.1 christos /* If you define this macro, it should return the offset between the 4391 1.1 christos address of a PC relative fixup and the position from which the PC 4392 1.1 christos relative adjustment should be made. On many processors, the base 4393 1.1 christos of a PC relative instruction is the next instruction, so this 4394 1.1 christos macro would return the length of an instruction. */ 4395 1.1 christos 4396 1.1 christos long 4397 1.1 christos md_pcrel_from_section (fixS * fixp, segT sec) 4398 1.1 christos { 4399 1.10 christos if (fixp->fx_addsy != NULL 4400 1.1 christos && (!S_IS_DEFINED (fixp->fx_addsy) 4401 1.1 christos || (S_GET_SEGMENT (fixp->fx_addsy) != sec))) 4402 1.1 christos return 0; 4403 1.1 christos 4404 1.1 christos return fixp->fx_frag->fr_address + fixp->fx_where; 4405 1.1 christos } 4406 1.1 christos 4407 1.6 christos /* Addition to the standard TC_FORCE_RELOCATION_LOCAL. 4408 1.1 christos Now it handles the situation when relocations 4409 1.3 christos have to be passed to linker. */ 4410 1.1 christos int 4411 1.3 christos msp430_force_relocation_local (fixS *fixp) 4412 1.1 christos { 4413 1.3 christos if (fixp->fx_r_type == BFD_RELOC_MSP430_10_PCREL) 4414 1.3 christos return 1; 4415 1.3 christos if (fixp->fx_pcrel) 4416 1.3 christos return 1; 4417 1.1 christos if (msp430_enable_polys 4418 1.1 christos && !msp430_enable_relax) 4419 1.1 christos return 1; 4420 1.3 christos 4421 1.6 christos return 0; 4422 1.1 christos } 4423 1.1 christos 4424 1.1 christos 4425 1.1 christos /* GAS will call this for each fixup. It should store the correct 4426 1.1 christos value in the object file. */ 4427 1.1 christos void 4428 1.1 christos md_apply_fix (fixS * fixp, valueT * valuep, segT seg) 4429 1.1 christos { 4430 1.1 christos unsigned char * where; 4431 1.1 christos unsigned long insn; 4432 1.1 christos long value; 4433 1.1 christos 4434 1.10 christos if (fixp->fx_addsy == NULL) 4435 1.1 christos { 4436 1.1 christos value = *valuep; 4437 1.1 christos fixp->fx_done = 1; 4438 1.1 christos } 4439 1.1 christos else if (fixp->fx_pcrel) 4440 1.1 christos { 4441 1.1 christos segT s = S_GET_SEGMENT (fixp->fx_addsy); 4442 1.1 christos 4443 1.1 christos if (fixp->fx_addsy && (s == seg || s == absolute_section)) 4444 1.1 christos { 4445 1.1 christos /* FIXME: We can appear here only in case if we perform a pc 4446 1.1 christos relative jump to the label which is i) global, ii) locally 4447 1.1 christos defined or this is a jump to an absolute symbol. 4448 1.1 christos If this is an absolute symbol -- everything is OK. 4449 1.1 christos If this is a global label, we've got a symbol value defined 4450 1.1 christos twice: 4451 1.1 christos 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset 4452 1.1 christos from this section start 4453 1.1 christos 2. *valuep will contain the real offset from jump insn to the 4454 1.1 christos label 4455 1.1 christos So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep); 4456 1.1 christos will be incorrect. Therefore remove s_get_value. */ 4457 1.1 christos value = /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep; 4458 1.1 christos fixp->fx_done = 1; 4459 1.1 christos } 4460 1.1 christos else 4461 1.1 christos value = *valuep; 4462 1.1 christos } 4463 1.1 christos else 4464 1.1 christos { 4465 1.1 christos value = fixp->fx_offset; 4466 1.1 christos 4467 1.10 christos if (fixp->fx_subsy != NULL) 4468 1.1 christos { 4469 1.1 christos if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section) 4470 1.1 christos { 4471 1.1 christos value -= S_GET_VALUE (fixp->fx_subsy); 4472 1.1 christos fixp->fx_done = 1; 4473 1.1 christos } 4474 1.1 christos } 4475 1.1 christos } 4476 1.1 christos 4477 1.1 christos fixp->fx_no_overflow = 1; 4478 1.1 christos 4479 1.3 christos /* If polymorphs are enabled and relax disabled. 4480 1.3 christos do not kill any relocs and pass them to linker. */ 4481 1.3 christos if (msp430_enable_polys 4482 1.1 christos && !msp430_enable_relax) 4483 1.1 christos { 4484 1.3 christos if (!fixp->fx_addsy 4485 1.3 christos || S_GET_SEGMENT (fixp->fx_addsy) == absolute_section) 4486 1.1 christos fixp->fx_done = 1; /* It is ok to kill 'abs' reloc. */ 4487 1.1 christos else 4488 1.1 christos fixp->fx_done = 0; 4489 1.1 christos } 4490 1.1 christos 4491 1.1 christos if (fixp->fx_done) 4492 1.1 christos { 4493 1.1 christos /* Fetch the instruction, insert the fully resolved operand 4494 1.1 christos value, and stuff the instruction back again. */ 4495 1.1 christos where = (unsigned char *) fixp->fx_frag->fr_literal + fixp->fx_where; 4496 1.1 christos 4497 1.1 christos insn = bfd_getl16 (where); 4498 1.1 christos 4499 1.1 christos switch (fixp->fx_r_type) 4500 1.1 christos { 4501 1.1 christos case BFD_RELOC_MSP430_10_PCREL: 4502 1.1 christos if (value & 1) 4503 1.1 christos as_bad_where (fixp->fx_file, fixp->fx_line, 4504 1.1 christos _("odd address operand: %ld"), value); 4505 1.1 christos 4506 1.1 christos /* Jumps are in words. */ 4507 1.1 christos value >>= 1; 4508 1.1 christos --value; /* Correct PC. */ 4509 1.1 christos 4510 1.1 christos if (value < -512 || value > 511) 4511 1.1 christos as_bad_where (fixp->fx_file, fixp->fx_line, 4512 1.1 christos _("operand out of range: %ld"), value); 4513 1.1 christos 4514 1.1 christos value &= 0x3ff; /* get rid of extended sign */ 4515 1.10 christos bfd_putl16 (value | insn, where); 4516 1.1 christos break; 4517 1.1 christos 4518 1.3 christos case BFD_RELOC_MSP430X_PCR16: 4519 1.1 christos case BFD_RELOC_MSP430_RL_PCREL: 4520 1.1 christos case BFD_RELOC_MSP430_16_PCREL: 4521 1.1 christos if (value & 1) 4522 1.1 christos as_bad_where (fixp->fx_file, fixp->fx_line, 4523 1.1 christos _("odd address operand: %ld"), value); 4524 1.3 christos /* Fall through. */ 4525 1.1 christos 4526 1.3 christos case BFD_RELOC_MSP430_16_PCREL_BYTE: 4527 1.1 christos /* Nothing to be corrected here. */ 4528 1.1 christos if (value < -32768 || value > 65536) 4529 1.1 christos as_bad_where (fixp->fx_file, fixp->fx_line, 4530 1.1 christos _("operand out of range: %ld"), value); 4531 1.3 christos /* Fall through. */ 4532 1.1 christos 4533 1.3 christos case BFD_RELOC_MSP430X_ABS16: 4534 1.3 christos case BFD_RELOC_MSP430_16: 4535 1.3 christos case BFD_RELOC_16: 4536 1.3 christos case BFD_RELOC_MSP430_16_BYTE: 4537 1.1 christos value &= 0xffff; /* Get rid of extended sign. */ 4538 1.10 christos bfd_putl16 (value, where); 4539 1.1 christos break; 4540 1.1 christos 4541 1.3 christos case BFD_RELOC_MSP430_ABS_HI16: 4542 1.3 christos value >>= 16; 4543 1.1 christos value &= 0xffff; /* Get rid of extended sign. */ 4544 1.10 christos bfd_putl16 (value, where); 4545 1.1 christos break; 4546 1.1 christos 4547 1.1 christos case BFD_RELOC_32: 4548 1.10 christos bfd_putl32 (value, where); 4549 1.1 christos break; 4550 1.1 christos 4551 1.3 christos case BFD_RELOC_MSP430_ABS8: 4552 1.3 christos case BFD_RELOC_8: 4553 1.10 christos bfd_put_8 (NULL, value, where); 4554 1.3 christos break; 4555 1.3 christos 4556 1.3 christos case BFD_RELOC_MSP430X_ABS20_EXT_SRC: 4557 1.3 christos case BFD_RELOC_MSP430X_PCR20_EXT_SRC: 4558 1.10 christos bfd_putl16 (value & 0xffff, where + 4); 4559 1.3 christos value >>= 16; 4560 1.10 christos bfd_putl16 (((value & 0xf) << 7) | insn, where); 4561 1.3 christos break; 4562 1.3 christos 4563 1.3 christos case BFD_RELOC_MSP430X_ABS20_ADR_SRC: 4564 1.10 christos bfd_putl16 (value & 0xffff, where + 2); 4565 1.3 christos value >>= 16; 4566 1.10 christos bfd_putl16 (((value & 0xf) << 8) | insn, where); 4567 1.3 christos break; 4568 1.3 christos 4569 1.3 christos case BFD_RELOC_MSP430X_ABS20_EXT_ODST: 4570 1.10 christos bfd_putl16 (value & 0xffff, where + 6); 4571 1.3 christos value >>= 16; 4572 1.10 christos bfd_putl16 ((value & 0xf) | insn, where); 4573 1.3 christos break; 4574 1.3 christos 4575 1.3 christos case BFD_RELOC_MSP430X_PCR20_CALL: 4576 1.10 christos bfd_putl16 (value & 0xffff, where + 2); 4577 1.3 christos value >>= 16; 4578 1.10 christos bfd_putl16 ((value & 0xf) | insn, where); 4579 1.3 christos break; 4580 1.3 christos 4581 1.3 christos case BFD_RELOC_MSP430X_ABS20_EXT_DST: 4582 1.3 christos case BFD_RELOC_MSP430X_PCR20_EXT_DST: 4583 1.10 christos bfd_putl16 (value & 0xffff, where + 4); 4584 1.3 christos value >>= 16; 4585 1.10 christos bfd_putl16 ((value & 0xf) | insn, where); 4586 1.3 christos break; 4587 1.3 christos 4588 1.3 christos case BFD_RELOC_MSP430X_PCR20_EXT_ODST: 4589 1.10 christos bfd_putl16 (value & 0xffff, where + 6); 4590 1.3 christos value >>= 16; 4591 1.10 christos bfd_putl16 ((value & 0xf) | insn, where); 4592 1.3 christos break; 4593 1.3 christos 4594 1.3 christos case BFD_RELOC_MSP430X_ABS20_ADR_DST: 4595 1.10 christos bfd_putl16 (value & 0xffff, where + 2); 4596 1.3 christos value >>= 16; 4597 1.10 christos bfd_putl16 ((value & 0xf) | insn, where); 4598 1.1 christos break; 4599 1.1 christos 4600 1.1 christos default: 4601 1.1 christos as_fatal (_("line %d: unknown relocation type: 0x%x"), 4602 1.1 christos fixp->fx_line, fixp->fx_r_type); 4603 1.1 christos break; 4604 1.1 christos } 4605 1.1 christos } 4606 1.1 christos else 4607 1.1 christos { 4608 1.1 christos fixp->fx_addnumber = value; 4609 1.1 christos } 4610 1.1 christos } 4611 1.1 christos 4612 1.8 christos static bool 4613 1.3 christos S_IS_GAS_LOCAL (symbolS * s) 4614 1.3 christos { 4615 1.3 christos const char * name; 4616 1.3 christos unsigned int len; 4617 1.3 christos 4618 1.3 christos if (s == NULL) 4619 1.8 christos return false; 4620 1.3 christos name = S_GET_NAME (s); 4621 1.3 christos len = strlen (name) - 1; 4622 1.3 christos 4623 1.3 christos return name[len] == 1 || name[len] == 2; 4624 1.3 christos } 4625 1.3 christos 4626 1.1 christos /* GAS will call this to generate a reloc, passing the resulting reloc 4627 1.1 christos to `bfd_install_relocation'. This currently works poorly, as 4628 1.1 christos `bfd_install_relocation' often does the wrong thing, and instances of 4629 1.1 christos `tc_gen_reloc' have been written to work around the problems, which 4630 1.1 christos in turns makes it difficult to fix `bfd_install_relocation'. */ 4631 1.1 christos 4632 1.1 christos /* If while processing a fixup, a reloc really needs to be created 4633 1.1 christos then it is done here. */ 4634 1.1 christos 4635 1.3 christos arelent ** 4636 1.10 christos tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp) 4637 1.1 christos { 4638 1.10 christos static arelent *no_relocs = NULL; 4639 1.10 christos static arelent *relocs[MAX_RELOC_EXPANSION + 1]; 4640 1.3 christos arelent *reloc; 4641 1.1 christos 4642 1.10 christos reloc = notes_alloc (sizeof (arelent)); 4643 1.1 christos reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; 4644 1.1 christos reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); 4645 1.3 christos 4646 1.10 christos if (reloc->howto == NULL) 4647 1.1 christos { 4648 1.1 christos as_bad_where (fixp->fx_file, fixp->fx_line, 4649 1.1 christos _("reloc %d not supported by object file format"), 4650 1.1 christos (int) fixp->fx_r_type); 4651 1.10 christos return &no_relocs; 4652 1.3 christos } 4653 1.3 christos 4654 1.3 christos relocs[0] = reloc; 4655 1.3 christos relocs[1] = NULL; 4656 1.3 christos 4657 1.3 christos if (fixp->fx_subsy 4658 1.3 christos && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section) 4659 1.3 christos { 4660 1.3 christos fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy); 4661 1.3 christos fixp->fx_subsy = NULL; 4662 1.3 christos } 4663 1.3 christos 4664 1.3 christos if (fixp->fx_addsy && fixp->fx_subsy) 4665 1.3 christos { 4666 1.3 christos asection *asec, *ssec; 4667 1.3 christos 4668 1.3 christos asec = S_GET_SEGMENT (fixp->fx_addsy); 4669 1.3 christos ssec = S_GET_SEGMENT (fixp->fx_subsy); 4670 1.3 christos 4671 1.3 christos /* If we have a difference between two different, non-absolute symbols 4672 1.3 christos we must generate two relocs (one for each symbol) and allow the 4673 1.3 christos linker to resolve them - relaxation may change the distances between 4674 1.3 christos symbols, even local symbols defined in the same section. 4675 1.3 christos 4676 1.3 christos Unfortunately we cannot do this with assembler generated local labels 4677 1.3 christos because there can be multiple incarnations of the same label, with 4678 1.3 christos exactly the same name, in any given section and the linker will have 4679 1.3 christos no way to identify the correct one. Instead we just have to hope 4680 1.6 christos that no relaxation will occur between the local label and the other 4681 1.3 christos symbol in the expression. 4682 1.3 christos 4683 1.3 christos Similarly we have to compute differences between symbols in the .eh_frame 4684 1.3 christos section as the linker is not smart enough to apply relocations there 4685 1.3 christos before attempting to process it. */ 4686 1.3 christos if ((ssec != absolute_section || asec != absolute_section) 4687 1.3 christos && (fixp->fx_addsy != fixp->fx_subsy) 4688 1.3 christos && strcmp (ssec->name, ".eh_frame") != 0 4689 1.3 christos && ! S_IS_GAS_LOCAL (fixp->fx_addsy) 4690 1.3 christos && ! S_IS_GAS_LOCAL (fixp->fx_subsy)) 4691 1.3 christos { 4692 1.10 christos arelent *reloc2 = notes_alloc (sizeof (arelent)); 4693 1.3 christos 4694 1.3 christos relocs[0] = reloc2; 4695 1.3 christos relocs[1] = reloc; 4696 1.3 christos 4697 1.3 christos reloc2->address = reloc->address; 4698 1.3 christos reloc2->howto = bfd_reloc_type_lookup (stdoutput, 4699 1.3 christos BFD_RELOC_MSP430_SYM_DIFF); 4700 1.3 christos reloc2->addend = - S_GET_VALUE (fixp->fx_subsy); 4701 1.3 christos 4702 1.3 christos if (ssec == absolute_section) 4703 1.10 christos reloc2->sym_ptr_ptr = &bfd_abs_section_ptr->symbol; 4704 1.3 christos else 4705 1.3 christos { 4706 1.10 christos reloc2->sym_ptr_ptr = notes_alloc (sizeof (asymbol *)); 4707 1.3 christos *reloc2->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy); 4708 1.3 christos } 4709 1.3 christos 4710 1.3 christos reloc->addend = fixp->fx_offset; 4711 1.3 christos if (asec == absolute_section) 4712 1.3 christos { 4713 1.3 christos reloc->addend += S_GET_VALUE (fixp->fx_addsy); 4714 1.10 christos reloc->sym_ptr_ptr = &bfd_abs_section_ptr->symbol; 4715 1.3 christos } 4716 1.3 christos else 4717 1.3 christos { 4718 1.10 christos reloc->sym_ptr_ptr = notes_alloc (sizeof (asymbol *)); 4719 1.3 christos *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); 4720 1.3 christos } 4721 1.3 christos 4722 1.3 christos fixp->fx_pcrel = 0; 4723 1.3 christos fixp->fx_done = 1; 4724 1.3 christos return relocs; 4725 1.3 christos } 4726 1.3 christos else 4727 1.3 christos { 4728 1.3 christos char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal; 4729 1.3 christos 4730 1.3 christos reloc->addend = (S_GET_VALUE (fixp->fx_addsy) 4731 1.3 christos - S_GET_VALUE (fixp->fx_subsy) + fixp->fx_offset); 4732 1.3 christos 4733 1.3 christos switch (fixp->fx_r_type) 4734 1.3 christos { 4735 1.3 christos case BFD_RELOC_8: 4736 1.3 christos md_number_to_chars (fixpos, reloc->addend, 1); 4737 1.3 christos break; 4738 1.3 christos 4739 1.3 christos case BFD_RELOC_16: 4740 1.3 christos md_number_to_chars (fixpos, reloc->addend, 2); 4741 1.3 christos break; 4742 1.3 christos 4743 1.3 christos case BFD_RELOC_24: 4744 1.3 christos md_number_to_chars (fixpos, reloc->addend, 3); 4745 1.3 christos break; 4746 1.3 christos 4747 1.3 christos case BFD_RELOC_32: 4748 1.3 christos md_number_to_chars (fixpos, reloc->addend, 4); 4749 1.3 christos break; 4750 1.3 christos 4751 1.3 christos default: 4752 1.10 christos reloc->sym_ptr_ptr = &bfd_abs_section_ptr->symbol; 4753 1.3 christos return relocs; 4754 1.3 christos } 4755 1.3 christos 4756 1.10 christos return &no_relocs; 4757 1.3 christos } 4758 1.1 christos } 4759 1.3 christos else 4760 1.3 christos { 4761 1.3 christos #if 0 4762 1.3 christos if (fixp->fx_r_type == BFD_RELOC_MSP430X_ABS16 4763 1.3 christos && S_GET_SEGMENT (fixp->fx_addsy) == absolute_section) 4764 1.3 christos { 4765 1.3 christos bfd_vma amount = S_GET_VALUE (fixp->fx_addsy); 4766 1.3 christos char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal; 4767 1.1 christos 4768 1.3 christos md_number_to_chars (fixpos, amount, 2); 4769 1.10 christos return &no_relocs; 4770 1.3 christos } 4771 1.3 christos #endif 4772 1.10 christos reloc->sym_ptr_ptr = notes_alloc (sizeof (asymbol *)); 4773 1.3 christos *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); 4774 1.3 christos reloc->addend = fixp->fx_offset; 4775 1.1 christos 4776 1.3 christos if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT 4777 1.3 christos || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY) 4778 1.3 christos reloc->address = fixp->fx_offset; 4779 1.3 christos } 4780 1.1 christos 4781 1.3 christos return relocs; 4782 1.1 christos } 4783 1.1 christos 4784 1.1 christos int 4785 1.1 christos md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, 4786 1.1 christos asection * segment_type ATTRIBUTE_UNUSED) 4787 1.1 christos { 4788 1.1 christos if (fragP->fr_symbol && S_GET_SEGMENT (fragP->fr_symbol) == segment_type) 4789 1.1 christos { 4790 1.1 christos /* This is a jump -> pcrel mode. Nothing to do much here. 4791 1.1 christos Return value == 2. */ 4792 1.1 christos fragP->fr_subtype = 4793 1.1 christos ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_BITS10); 4794 1.1 christos } 4795 1.1 christos else if (fragP->fr_symbol) 4796 1.1 christos { 4797 1.6 christos /* It's got a segment, but it's not ours. Even if fr_symbol is in 4798 1.1 christos an absolute segment, we don't know a displacement until we link 4799 1.1 christos object files. So it will always be long. This also applies to 4800 1.1 christos labels in a subsegment of current. Liker may relax it to short 4801 1.1 christos jump later. Return value == 8. */ 4802 1.1 christos fragP->fr_subtype = 4803 1.1 christos ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_WORD); 4804 1.1 christos } 4805 1.1 christos else 4806 1.1 christos { 4807 1.1 christos /* We know the abs value. may be it is a jump to fixed address. 4808 1.1 christos Impossible in our case, cause all constants already handled. */ 4809 1.1 christos fragP->fr_subtype = 4810 1.1 christos ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_UNDEF); 4811 1.1 christos } 4812 1.1 christos 4813 1.1 christos return md_relax_table[fragP->fr_subtype].rlx_length; 4814 1.1 christos } 4815 1.1 christos 4816 1.1 christos void 4817 1.1 christos md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, 4818 1.1 christos asection * sec ATTRIBUTE_UNUSED, 4819 1.1 christos fragS * fragP) 4820 1.1 christos { 4821 1.1 christos char * where = 0; 4822 1.1 christos int rela = -1; 4823 1.1 christos int i; 4824 1.1 christos struct rcodes_s * cc = NULL; 4825 1.1 christos struct hcodes_s * hc = NULL; 4826 1.1 christos 4827 1.1 christos switch (fragP->fr_subtype) 4828 1.1 christos { 4829 1.1 christos case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_BITS10): 4830 1.1 christos case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_BITS10): 4831 1.1 christos case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_BITS10): 4832 1.1 christos /* We do not have to convert anything here. 4833 1.1 christos Just apply a fix. */ 4834 1.1 christos rela = BFD_RELOC_MSP430_10_PCREL; 4835 1.1 christos break; 4836 1.1 christos 4837 1.1 christos case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_WORD): 4838 1.1 christos case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_UNDEF): 4839 1.1 christos /* Convert uncond branch jmp lab -> br lab. */ 4840 1.3 christos if (target_is_430x ()) 4841 1.3 christos cc = msp430x_rcodes + 7; 4842 1.3 christos else 4843 1.3 christos cc = msp430_rcodes + 7; 4844 1.1 christos where = fragP->fr_literal + fragP->fr_fix; 4845 1.1 christos bfd_putl16 (cc->lop0, where); 4846 1.1 christos rela = BFD_RELOC_MSP430_RL_PCREL; 4847 1.1 christos fragP->fr_fix += 2; 4848 1.1 christos break; 4849 1.1 christos 4850 1.1 christos case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_WORD): 4851 1.1 christos case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_UNDEF): 4852 1.1 christos { 4853 1.1 christos /* Other simple branches. */ 4854 1.1 christos int insn = bfd_getl16 (fragP->fr_opcode); 4855 1.1 christos 4856 1.1 christos insn &= 0xffff; 4857 1.1 christos /* Find actual instruction. */ 4858 1.3 christos if (target_is_430x ()) 4859 1.3 christos { 4860 1.3 christos for (i = 0; i < 7 && !cc; i++) 4861 1.3 christos if (msp430x_rcodes[i].sop == insn) 4862 1.3 christos cc = msp430x_rcodes + i; 4863 1.3 christos } 4864 1.3 christos else 4865 1.3 christos { 4866 1.3 christos for (i = 0; i < 7 && !cc; i++) 4867 1.3 christos if (msp430_rcodes[i].sop == insn) 4868 1.3 christos cc = & msp430_rcodes[i]; 4869 1.3 christos } 4870 1.3 christos 4871 1.1 christos if (!cc || !cc->name) 4872 1.1 christos as_fatal (_("internal inconsistency problem in %s: insn %04lx"), 4873 1.9 christos __func__, (long) insn); 4874 1.1 christos where = fragP->fr_literal + fragP->fr_fix; 4875 1.1 christos bfd_putl16 (cc->lop0, where); 4876 1.1 christos bfd_putl16 (cc->lop1, where + 2); 4877 1.1 christos rela = BFD_RELOC_MSP430_RL_PCREL; 4878 1.1 christos fragP->fr_fix += 4; 4879 1.1 christos } 4880 1.1 christos break; 4881 1.1 christos 4882 1.1 christos case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_WORD): 4883 1.1 christos case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_UNDEF): 4884 1.3 christos if (target_is_430x ()) 4885 1.3 christos cc = msp430x_rcodes + 6; 4886 1.3 christos else 4887 1.3 christos cc = msp430_rcodes + 6; 4888 1.1 christos where = fragP->fr_literal + fragP->fr_fix; 4889 1.1 christos bfd_putl16 (cc->lop0, where); 4890 1.1 christos bfd_putl16 (cc->lop1, where + 2); 4891 1.1 christos bfd_putl16 (cc->lop2, where + 4); 4892 1.1 christos rela = BFD_RELOC_MSP430_RL_PCREL; 4893 1.1 christos fragP->fr_fix += 6; 4894 1.1 christos break; 4895 1.1 christos 4896 1.1 christos case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10): 4897 1.1 christos { 4898 1.1 christos int insn = bfd_getl16 (fragP->fr_opcode + 2); 4899 1.1 christos 4900 1.1 christos insn &= 0xffff; 4901 1.3 christos if (target_is_430x ()) 4902 1.3 christos { 4903 1.3 christos for (i = 0; i < 4 && !hc; i++) 4904 1.3 christos if (msp430x_hcodes[i].op1 == insn) 4905 1.3 christos hc = msp430x_hcodes + i; 4906 1.3 christos } 4907 1.3 christos else 4908 1.3 christos { 4909 1.3 christos for (i = 0; i < 4 && !hc; i++) 4910 1.3 christos if (msp430_hcodes[i].op1 == insn) 4911 1.3 christos hc = &msp430_hcodes[i]; 4912 1.3 christos } 4913 1.1 christos if (!hc || !hc->name) 4914 1.1 christos as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"), 4915 1.9 christos __func__, (long) insn); 4916 1.1 christos rela = BFD_RELOC_MSP430_10_PCREL; 4917 1.1 christos /* Apply a fix for a first label if necessary. 4918 1.1 christos another fix will be applied to the next word of insn anyway. */ 4919 1.1 christos if (hc->tlab == 2) 4920 1.1 christos fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, 4921 1.8 christos fragP->fr_offset, true, rela); 4922 1.1 christos fragP->fr_fix += 2; 4923 1.1 christos } 4924 1.1 christos 4925 1.1 christos break; 4926 1.1 christos 4927 1.1 christos case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_WORD): 4928 1.1 christos case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_UNDEF): 4929 1.1 christos { 4930 1.1 christos int insn = bfd_getl16 (fragP->fr_opcode + 2); 4931 1.1 christos 4932 1.1 christos insn &= 0xffff; 4933 1.3 christos if (target_is_430x ()) 4934 1.3 christos { 4935 1.3 christos for (i = 0; i < 4 && !hc; i++) 4936 1.3 christos if (msp430x_hcodes[i].op1 == insn) 4937 1.3 christos hc = msp430x_hcodes + i; 4938 1.3 christos } 4939 1.3 christos else 4940 1.3 christos { 4941 1.3 christos for (i = 0; i < 4 && !hc; i++) 4942 1.3 christos if (msp430_hcodes[i].op1 == insn) 4943 1.3 christos hc = & msp430_hcodes[i]; 4944 1.3 christos } 4945 1.1 christos if (!hc || !hc->name) 4946 1.1 christos as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"), 4947 1.9 christos __func__, (long) insn); 4948 1.1 christos rela = BFD_RELOC_MSP430_RL_PCREL; 4949 1.1 christos where = fragP->fr_literal + fragP->fr_fix; 4950 1.1 christos bfd_putl16 (hc->lop0, where); 4951 1.1 christos bfd_putl16 (hc->lop1, where + 2); 4952 1.1 christos bfd_putl16 (hc->lop2, where + 4); 4953 1.1 christos fragP->fr_fix += 6; 4954 1.1 christos } 4955 1.1 christos break; 4956 1.1 christos 4957 1.1 christos default: 4958 1.6 christos as_fatal (_("internal inconsistency problem in %s: %lx"), 4959 1.9 christos __func__, (long) fragP->fr_subtype); 4960 1.1 christos break; 4961 1.1 christos } 4962 1.1 christos 4963 1.1 christos /* Now apply fix. */ 4964 1.1 christos fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, 4965 1.8 christos fragP->fr_offset, true, rela); 4966 1.1 christos /* Just fixed 2 bytes. */ 4967 1.1 christos fragP->fr_fix += 2; 4968 1.1 christos } 4969 1.1 christos 4970 1.1 christos /* Relax fragment. Mostly stolen from hc11 and mcore 4971 1.1 christos which arches I think I know. */ 4972 1.1 christos 4973 1.1 christos long 4974 1.1 christos msp430_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS * fragP, 4975 1.1 christos long stretch ATTRIBUTE_UNUSED) 4976 1.1 christos { 4977 1.1 christos long growth; 4978 1.1 christos offsetT aim = 0; 4979 1.1 christos symbolS *symbolP; 4980 1.1 christos const relax_typeS *this_type; 4981 1.1 christos const relax_typeS *start_type; 4982 1.1 christos relax_substateT next_state; 4983 1.1 christos relax_substateT this_state; 4984 1.1 christos const relax_typeS *table = md_relax_table; 4985 1.1 christos 4986 1.1 christos /* Nothing to be done if the frag has already max size. */ 4987 1.1 christos if (RELAX_STATE (fragP->fr_subtype) == STATE_UNDEF 4988 1.1 christos || RELAX_STATE (fragP->fr_subtype) == STATE_WORD) 4989 1.1 christos return 0; 4990 1.1 christos 4991 1.1 christos if (RELAX_STATE (fragP->fr_subtype) == STATE_BITS10) 4992 1.1 christos { 4993 1.1 christos symbolP = fragP->fr_symbol; 4994 1.1 christos if (symbol_resolved_p (symbolP)) 4995 1.1 christos as_fatal (_("internal inconsistency problem in %s: resolved symbol"), 4996 1.9 christos __func__); 4997 1.1 christos /* We know the offset. calculate a distance. */ 4998 1.1 christos aim = S_GET_VALUE (symbolP) - fragP->fr_address - fragP->fr_fix; 4999 1.1 christos } 5000 1.1 christos 5001 1.1 christos if (!msp430_enable_relax) 5002 1.1 christos { 5003 1.1 christos /* Relaxation is not enabled. So, make all jump as long ones 5004 1.3 christos by setting 'aim' to quite high value. */ 5005 1.1 christos aim = 0x7fff; 5006 1.1 christos } 5007 1.3 christos 5008 1.1 christos this_state = fragP->fr_subtype; 5009 1.1 christos start_type = this_type = table + this_state; 5010 1.1 christos 5011 1.1 christos if (aim < 0) 5012 1.1 christos { 5013 1.1 christos /* Look backwards. */ 5014 1.1 christos for (next_state = this_type->rlx_more; next_state;) 5015 1.1 christos if (aim >= this_type->rlx_backward || !this_type->rlx_backward) 5016 1.1 christos next_state = 0; 5017 1.1 christos else 5018 1.1 christos { 5019 1.1 christos /* Grow to next state. */ 5020 1.1 christos this_state = next_state; 5021 1.1 christos this_type = table + this_state; 5022 1.1 christos next_state = this_type->rlx_more; 5023 1.1 christos } 5024 1.1 christos } 5025 1.1 christos else 5026 1.1 christos { 5027 1.1 christos /* Look forwards. */ 5028 1.1 christos for (next_state = this_type->rlx_more; next_state;) 5029 1.1 christos if (aim <= this_type->rlx_forward || !this_type->rlx_forward) 5030 1.1 christos next_state = 0; 5031 1.1 christos else 5032 1.1 christos { 5033 1.1 christos /* Grow to next state. */ 5034 1.1 christos this_state = next_state; 5035 1.1 christos this_type = table + this_state; 5036 1.1 christos next_state = this_type->rlx_more; 5037 1.1 christos } 5038 1.1 christos } 5039 1.1 christos 5040 1.1 christos growth = this_type->rlx_length - start_type->rlx_length; 5041 1.1 christos if (growth != 0) 5042 1.1 christos fragP->fr_subtype = this_state; 5043 1.1 christos return growth; 5044 1.1 christos } 5045 1.3 christos 5046 1.3 christos /* Return FALSE if the fixup in fixp should be left alone and not 5047 1.3 christos adjusted. We return FALSE here so that linker relaxation will 5048 1.3 christos work. */ 5049 1.3 christos 5050 1.8 christos bool 5051 1.3 christos msp430_fix_adjustable (struct fix *fixp ATTRIBUTE_UNUSED) 5052 1.3 christos { 5053 1.3 christos /* If the symbol is in a non-code section then it should be OK. */ 5054 1.3 christos if (fixp->fx_addsy 5055 1.3 christos && ((S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_CODE) == 0)) 5056 1.8 christos return true; 5057 1.3 christos 5058 1.8 christos return false; 5059 1.3 christos } 5060 1.3 christos 5061 1.8 christos /* Scan uleb128 subtraction expressions and insert fixups for them. 5062 1.8 christos e.g., .uleb128 .L1 - .L0 5063 1.8 christos Because relaxation may change the value of the subtraction, we 5064 1.8 christos must resolve them at link-time. */ 5065 1.8 christos 5066 1.8 christos static void 5067 1.8 christos msp430_insert_uleb128_fixes (bfd *abfd ATTRIBUTE_UNUSED, 5068 1.8 christos asection *sec, void *xxx ATTRIBUTE_UNUSED) 5069 1.8 christos { 5070 1.8 christos segment_info_type *seginfo = seg_info (sec); 5071 1.8 christos struct frag *fragP; 5072 1.8 christos 5073 1.8 christos subseg_set (sec, 0); 5074 1.8 christos 5075 1.8 christos for (fragP = seginfo->frchainP->frch_root; 5076 1.8 christos fragP; fragP = fragP->fr_next) 5077 1.8 christos { 5078 1.8 christos expressionS *exp, *exp_dup; 5079 1.8 christos 5080 1.8 christos if (fragP->fr_type != rs_leb128 || fragP->fr_symbol == NULL) 5081 1.8 christos continue; 5082 1.3 christos 5083 1.8 christos exp = symbol_get_value_expression (fragP->fr_symbol); 5084 1.8 christos 5085 1.8 christos if (exp->X_op != O_subtract) 5086 1.8 christos continue; 5087 1.8 christos 5088 1.8 christos /* FIXME: Skip for .sleb128. */ 5089 1.8 christos if (fragP->fr_subtype != 0) 5090 1.8 christos continue; 5091 1.8 christos 5092 1.8 christos exp_dup = xmemdup (exp, sizeof (*exp), sizeof (*exp)); 5093 1.8 christos exp_dup->X_op = O_symbol; 5094 1.8 christos exp_dup->X_op_symbol = NULL; 5095 1.8 christos 5096 1.8 christos /* Emit the SUB relocation first, since the SET relocation will write out 5097 1.8 christos the final value. */ 5098 1.8 christos exp_dup->X_add_symbol = exp->X_op_symbol; 5099 1.8 christos fix_new_exp (fragP, fragP->fr_fix, 0, 5100 1.8 christos exp_dup, 0, BFD_RELOC_MSP430_SUB_ULEB128); 5101 1.8 christos 5102 1.8 christos exp_dup->X_add_symbol = exp->X_add_symbol; 5103 1.8 christos /* Insert relocations to resolve the subtraction at link-time. */ 5104 1.8 christos fix_new_exp (fragP, fragP->fr_fix, 0, 5105 1.8 christos exp_dup, 0, BFD_RELOC_MSP430_SET_ULEB128); 5106 1.8 christos 5107 1.8 christos } 5108 1.8 christos } 5109 1.8 christos 5110 1.8 christos /* Called after all assembly has been done. */ 5111 1.3 christos void 5112 1.9 christos msp430_md_finish (void) 5113 1.3 christos { 5114 1.3 christos if (check_for_nop) 5115 1.7 christos { 5116 1.7 christos if (gen_interrupt_nops) 5117 1.7 christos { 5118 1.7 christos gen_nop (); 5119 1.7 christos if (warn_interrupt_nops) 5120 1.7 christos as_warn (INSERT_NOP_AT_EOF); 5121 1.7 christos } 5122 1.7 christos else if (warn_interrupt_nops) 5123 1.7 christos as_warn (_(WARN_NOP_AT_EOF)); 5124 1.7 christos } 5125 1.3 christos 5126 1.8 christos /* Insert relocations for uleb128 directives, so the values can be recomputed 5127 1.8 christos at link time. */ 5128 1.8 christos bfd_map_over_sections (stdoutput, msp430_insert_uleb128_fixes, NULL); 5129 1.8 christos 5130 1.7 christos /* We have already emitted an error if any of the following attributes 5131 1.7 christos disagree with the attributes in the input assembly file. See 5132 1.7 christos msp430_object_attribute. */ 5133 1.9 christos if (!bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_ISA, 5134 1.9 christos target_is_430x () 5135 1.9 christos ? OFBA_MSPABI_Val_ISA_MSP430X 5136 1.9 christos : OFBA_MSPABI_Val_ISA_MSP430) 5137 1.9 christos || !bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Code_Model, 5138 1.9 christos large_model 5139 1.9 christos ? OFBA_MSPABI_Val_Code_Model_LARGE 5140 1.9 christos : OFBA_MSPABI_Val_Code_Model_SMALL) 5141 1.9 christos || !bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Data_Model, 5142 1.9 christos large_model 5143 1.9 christos ? OFBA_MSPABI_Val_Code_Model_LARGE 5144 1.9 christos : OFBA_MSPABI_Val_Code_Model_SMALL) 5145 1.7 christos /* The data region GNU attribute is ignored for the small memory model. */ 5146 1.9 christos || (large_model 5147 1.9 christos && !bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_GNU, 5148 1.9 christos Tag_GNU_MSP430_Data_Region, 5149 1.9 christos lower_data_region_only 5150 1.9 christos ? Val_GNU_MSP430_Data_Region_Lower 5151 1.9 christos : Val_GNU_MSP430_Data_Region_Any))) 5152 1.9 christos as_fatal (_("error adding attribute: %s"), 5153 1.9 christos bfd_errmsg (bfd_get_error ())); 5154 1.3 christos } 5155 1.3 christos 5156 1.3 christos /* Returns FALSE if there is a msp430 specific reason why the 5157 1.3 christos subtraction of two same-section symbols cannot be computed by 5158 1.3 christos the assembler. */ 5159 1.3 christos 5160 1.8 christos bool 5161 1.3 christos msp430_allow_local_subtract (expressionS * left, 5162 1.3 christos expressionS * right, 5163 1.3 christos segT section) 5164 1.3 christos { 5165 1.3 christos /* If the symbols are not in a code section then they are OK. */ 5166 1.3 christos if ((section->flags & SEC_CODE) == 0) 5167 1.8 christos return true; 5168 1.3 christos 5169 1.3 christos if (S_IS_GAS_LOCAL (left->X_add_symbol) || S_IS_GAS_LOCAL (right->X_add_symbol)) 5170 1.8 christos return true; 5171 1.3 christos 5172 1.3 christos if (left->X_add_symbol == right->X_add_symbol) 5173 1.8 christos return true; 5174 1.3 christos 5175 1.3 christos /* We have to assume that there may be instructions between the 5176 1.3 christos two symbols and that relaxation may increase the distance between 5177 1.3 christos them. */ 5178 1.8 christos return false; 5179 1.3 christos } 5180