1 /* tc-msp430.c -- Assembler code for the Texas Instruments MSP430 2 3 Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 4 Contributed by Dmitry Diky <diwil@mail.ru> 5 6 This file is part of GAS, the GNU Assembler. 7 8 GAS is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2, or (at your option) 11 any later version. 12 13 GAS is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with GAS; see the file COPYING. If not, write to 20 the Free Software Foundation, 51 Franklin Street - Fifth Floor, 21 Boston, MA 02110-1301, USA. */ 22 23 #include <stdio.h> 24 #include <string.h> 25 #include <stdlib.h> 26 #include <limits.h> 27 28 #define PUSH_1X_WORKAROUND 29 #include "as.h" 30 #include "subsegs.h" 31 #include "opcode/msp430.h" 32 #include "safe-ctype.h" 33 #include "dwarf2dbg.h" 34 35 /* 36 We will disable polymorphs by default because it is dangerous. 37 The potencial problem here is the following: assume we got the 38 following code: 39 40 jump .l1 41 nop 42 jump subroutine ; external symbol 43 .l1: 44 nop 45 ret 46 47 In case of assembly time relaxation we'll get: 48 0: jmp .l1 <.text +0x08> (reloc deleted) 49 2: nop 50 4: br subroutine 51 .l1: 52 8: nop 53 10: ret 54 55 If the 'subroutine' wiys thin +-1024 bytes range then linker 56 will produce 57 0: jmp .text +0x08 58 2: nop 59 4: jmp subroutine 60 .l1: 61 6: nop 62 8: ret ; 'jmp .text +0x08' will land here. WRONG!!! 63 64 65 The workaround is the following: 66 1. Declare global var enable_polymorphs which set to 1 via option -mP. 67 2. Declare global var enable_relax which set to 1 via option -mQ. 68 69 If polymorphs are enabled, and relax isn't, treat all jumps as long jumps, 70 do not delete any relocs and leave them for linker. 71 72 If relax is enabled, relax at assembly time and kill relocs as necessary. 73 */ 74 75 int msp430_enable_relax; 76 int msp430_enable_polys; 77 78 /* GCC uses the some condition codes which we'll 79 implement as new polymorph instructions. 80 81 COND EXPL SHORT JUMP LONG JUMP 82 =============================================== 83 eq == jeq jne +4; br lab 84 ne != jne jeq +4; br lab 85 86 ltn honours no-overflow flag 87 ltn < jn jn +2; jmp +4; br lab 88 89 lt < jl jge +4; br lab 90 ltu < jlo lhs +4; br lab 91 le <= see below 92 leu <= see below 93 94 gt > see below 95 gtu > see below 96 ge >= jge jl +4; br lab 97 geu >= jhs jlo +4; br lab 98 =============================================== 99 100 Therefore, new opcodes are (BranchEQ -> beq; and so on...) 101 beq,bne,blt,bltn,bltu,bge,bgeu 102 'u' means unsigned compares 103 104 Also, we add 'jump' instruction: 105 jump UNCOND -> jmp br lab 106 107 They will have fmt == 4, and insn_opnumb == number of instruction. */ 108 109 struct rcodes_s 110 { 111 char * name; 112 int index; /* Corresponding insn_opnumb. */ 113 int sop; /* Opcode if jump length is short. */ 114 long lpos; /* Label position. */ 115 long lop0; /* Opcode 1 _word_ (16 bits). */ 116 long lop1; /* Opcode second word. */ 117 long lop2; /* Opcode third word. */ 118 }; 119 120 #define MSP430_RLC(n,i,sop,o1) \ 121 {#n, i, sop, 2, (o1 + 2), 0x4010, 0} 122 123 static struct rcodes_s msp430_rcodes[] = 124 { 125 MSP430_RLC (beq, 0, 0x2400, 0x2000), 126 MSP430_RLC (bne, 1, 0x2000, 0x2400), 127 MSP430_RLC (blt, 2, 0x3800, 0x3400), 128 MSP430_RLC (bltu, 3, 0x2800, 0x2c00), 129 MSP430_RLC (bge, 4, 0x3400, 0x3800), 130 MSP430_RLC (bgeu, 5, 0x2c00, 0x2800), 131 {"bltn", 6, 0x3000, 3, 0x3000 + 1, 0x3c00 + 2,0x4010}, 132 {"jump", 7, 0x3c00, 1, 0x4010, 0, 0}, 133 {0,0,0,0,0,0,0} 134 }; 135 #undef MSP430_RLC 136 137 138 /* More difficult than above and they have format 5. 139 140 COND EXPL SHORT LONG 141 ================================================================= 142 gt > jeq +2; jge label jeq +6; jl +4; br label 143 gtu > jeq +2; jhs label jeq +6; jlo +4; br label 144 leu <= jeq label; jlo label jeq +2; jhs +4; br label 145 le <= jeq label; jl label jeq +2; jge +4; br label 146 ================================================================= */ 147 148 struct hcodes_s 149 { 150 char * name; 151 int index; /* Corresponding insn_opnumb. */ 152 int tlab; /* Number of labels in short mode. */ 153 int op0; /* Opcode for first word of short jump. */ 154 int op1; /* Opcode for second word of short jump. */ 155 int lop0; /* Opcodes for long jump mode. */ 156 int lop1; 157 int lop2; 158 }; 159 160 static struct hcodes_s msp430_hcodes[] = 161 { 162 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x4010 }, 163 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x4010 }, 164 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x4010 }, 165 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x4010 }, 166 {0,0,0,0,0,0,0,0} 167 }; 168 169 const char comment_chars[] = ";"; 170 const char line_comment_chars[] = "#"; 171 const char line_separator_chars[] = ""; 172 const char EXP_CHARS[] = "eE"; 173 const char FLT_CHARS[] = "dD"; 174 175 /* Handle long expressions. */ 176 extern LITTLENUM_TYPE generic_bignum[]; 177 178 static struct hash_control *msp430_hash; 179 180 /* Relaxations. */ 181 #define STATE_UNCOND_BRANCH 1 /* jump */ 182 #define STATE_NOOV_BRANCH 3 /* bltn */ 183 #define STATE_SIMPLE_BRANCH 2 /* bne, beq, etc... */ 184 #define STATE_EMUL_BRANCH 4 185 186 #define CNRL 2 187 #define CUBL 4 188 #define CNOL 8 189 #define CSBL 6 190 #define CEBL 4 191 192 /* Length. */ 193 #define STATE_BITS10 1 /* wild guess. short jump */ 194 #define STATE_WORD 2 /* 2 bytes pc rel. addr. more */ 195 #define STATE_UNDEF 3 /* cannot handle this yet. convert to word mode */ 196 197 #define ENCODE_RELAX(what,length) (((what) << 2) + (length)) 198 #define RELAX_STATE(s) ((s) & 3) 199 #define RELAX_LEN(s) ((s) >> 2) 200 #define RELAX_NEXT(a,b) ENCODE_RELAX (a, b + 1) 201 202 relax_typeS md_relax_table[] = 203 { 204 /* Unused. */ 205 {1, 1, 0, 0}, 206 {1, 1, 0, 0}, 207 {1, 1, 0, 0}, 208 {1, 1, 0, 0}, 209 210 /* Unconditional jump. */ 211 {1, 1, 8, 5}, 212 {1024, -1024, CNRL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_BITS10)}, /* state 10 bits displ */ 213 {0, 0, CUBL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_WORD)}, /* state word */ 214 {1, 1, CUBL, 0}, /* state undef */ 215 216 /* Simple branches. */ 217 {0, 0, 8, 9}, 218 {1024, -1024, CNRL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_BITS10)}, /* state 10 bits displ */ 219 {0, 0, CSBL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_WORD)}, /* state word */ 220 {1, 1, CSBL, 0}, 221 222 /* blt no overflow branch. */ 223 {1, 1, 8, 13}, 224 {1024, -1024, CNRL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_BITS10)}, /* state 10 bits displ */ 225 {0, 0, CNOL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_WORD)}, /* state word */ 226 {1, 1, CNOL, 0}, 227 228 /* Emulated branches. */ 229 {1, 1, 8, 17}, 230 {1020, -1020, CEBL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_BITS10)}, /* state 10 bits displ */ 231 {0, 0, CNOL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_WORD)}, /* state word */ 232 {1, 1, CNOL, 0} 233 }; 234 235 236 #define MAX_OP_LEN 256 237 238 struct mcu_type_s 239 { 240 char * name; 241 int isa; 242 int mach; 243 }; 244 245 #define MSP430_ISA_11 11 246 #define MSP430_ISA_110 110 247 #define MSP430_ISA_12 12 248 #define MSP430_ISA_13 13 249 #define MSP430_ISA_14 14 250 #define MSP430_ISA_15 15 251 #define MSP430_ISA_16 16 252 #define MSP430_ISA_21 21 253 #define MSP430_ISA_31 31 254 #define MSP430_ISA_32 32 255 #define MSP430_ISA_33 33 256 #define MSP430_ISA_41 41 257 #define MSP430_ISA_42 42 258 #define MSP430_ISA_43 43 259 #define MSP430_ISA_44 44 260 261 #define CHECK_RELOC_MSP430 ((imm_op || byte_op)?BFD_RELOC_MSP430_16_BYTE:BFD_RELOC_MSP430_16) 262 #define CHECK_RELOC_MSP430_PCREL ((imm_op || byte_op)?BFD_RELOC_MSP430_16_PCREL_BYTE:BFD_RELOC_MSP430_16_PCREL) 263 264 static struct mcu_type_s mcu_types[] = 265 { 266 {"msp1", MSP430_ISA_11, bfd_mach_msp11}, 267 {"msp2", MSP430_ISA_14, bfd_mach_msp14}, 268 {"msp430x110", MSP430_ISA_11, bfd_mach_msp11}, 269 {"msp430x112", MSP430_ISA_11, bfd_mach_msp11}, 270 {"msp430x1101", MSP430_ISA_110, bfd_mach_msp110}, 271 {"msp430x1111", MSP430_ISA_110, bfd_mach_msp110}, 272 {"msp430x1121", MSP430_ISA_110, bfd_mach_msp110}, 273 {"msp430x1122", MSP430_ISA_11, bfd_mach_msp110}, 274 {"msp430x1132", MSP430_ISA_11, bfd_mach_msp110}, 275 276 {"msp430x122", MSP430_ISA_12, bfd_mach_msp12}, 277 {"msp430x123", MSP430_ISA_12, bfd_mach_msp12}, 278 {"msp430x1222", MSP430_ISA_12, bfd_mach_msp12}, 279 {"msp430x1232", MSP430_ISA_12, bfd_mach_msp12}, 280 281 {"msp430x133", MSP430_ISA_13, bfd_mach_msp13}, 282 {"msp430x135", MSP430_ISA_13, bfd_mach_msp13}, 283 {"msp430x1331", MSP430_ISA_13, bfd_mach_msp13}, 284 {"msp430x1351", MSP430_ISA_13, bfd_mach_msp13}, 285 {"msp430x147", MSP430_ISA_14, bfd_mach_msp14}, 286 {"msp430x148", MSP430_ISA_14, bfd_mach_msp14}, 287 {"msp430x149", MSP430_ISA_14, bfd_mach_msp14}, 288 289 {"msp430x155", MSP430_ISA_15, bfd_mach_msp15}, 290 {"msp430x156", MSP430_ISA_15, bfd_mach_msp15}, 291 {"msp430x157", MSP430_ISA_15, bfd_mach_msp15}, 292 {"msp430x167", MSP430_ISA_16, bfd_mach_msp16}, 293 {"msp430x168", MSP430_ISA_16, bfd_mach_msp16}, 294 {"msp430x169", MSP430_ISA_16, bfd_mach_msp16}, 295 {"msp430x1610", MSP430_ISA_16, bfd_mach_msp16}, 296 {"msp430x1611", MSP430_ISA_16, bfd_mach_msp16}, 297 {"msp430x1612", MSP430_ISA_16, bfd_mach_msp16}, 298 299 {"msp430x2101", MSP430_ISA_21, bfd_mach_msp21}, 300 {"msp430x2111", MSP430_ISA_21, bfd_mach_msp21}, 301 {"msp430x2121", MSP430_ISA_21, bfd_mach_msp21}, 302 {"msp430x2131", MSP430_ISA_21, bfd_mach_msp21}, 303 304 {"msp430x311", MSP430_ISA_31, bfd_mach_msp31}, 305 {"msp430x312", MSP430_ISA_31, bfd_mach_msp31}, 306 {"msp430x313", MSP430_ISA_31, bfd_mach_msp31}, 307 {"msp430x314", MSP430_ISA_31, bfd_mach_msp31}, 308 {"msp430x315", MSP430_ISA_31, bfd_mach_msp31}, 309 {"msp430x323", MSP430_ISA_32, bfd_mach_msp32}, 310 {"msp430x325", MSP430_ISA_32, bfd_mach_msp32}, 311 {"msp430x336", MSP430_ISA_33, bfd_mach_msp33}, 312 {"msp430x337", MSP430_ISA_33, bfd_mach_msp33}, 313 314 {"msp430x412", MSP430_ISA_41, bfd_mach_msp41}, 315 {"msp430x413", MSP430_ISA_41, bfd_mach_msp41}, 316 {"msp430x415", MSP430_ISA_41, bfd_mach_msp41}, 317 {"msp430x417", MSP430_ISA_41, bfd_mach_msp41}, 318 319 {"msp430xE423", MSP430_ISA_42, bfd_mach_msp42}, 320 {"msp430xE425", MSP430_ISA_42, bfd_mach_msp42}, 321 {"msp430xE427", MSP430_ISA_42, bfd_mach_msp42}, 322 323 {"msp430xW423", MSP430_ISA_42, bfd_mach_msp42}, 324 {"msp430xW425", MSP430_ISA_42, bfd_mach_msp42}, 325 {"msp430xW427", MSP430_ISA_42, bfd_mach_msp42}, 326 327 {"msp430xG437", MSP430_ISA_43, bfd_mach_msp43}, 328 {"msp430xG438", MSP430_ISA_43, bfd_mach_msp43}, 329 {"msp430xG439", MSP430_ISA_43, bfd_mach_msp43}, 330 331 {"msp430x435", MSP430_ISA_43, bfd_mach_msp43}, 332 {"msp430x436", MSP430_ISA_43, bfd_mach_msp43}, 333 {"msp430x437", MSP430_ISA_43, bfd_mach_msp43}, 334 {"msp430x447", MSP430_ISA_44, bfd_mach_msp44}, 335 {"msp430x448", MSP430_ISA_44, bfd_mach_msp44}, 336 {"msp430x449", MSP430_ISA_44, bfd_mach_msp44}, 337 338 {NULL, 0, 0} 339 }; 340 341 342 static struct mcu_type_s default_mcu = 343 { "msp430x11", MSP430_ISA_11, bfd_mach_msp11 }; 344 345 static struct mcu_type_s * msp430_mcu = & default_mcu; 346 347 /* Profiling capability: 348 It is a performance hit to use gcc's profiling approach for this tiny target. 349 Even more -- jtag hardware facility does not perform any profiling functions. 350 However we've got gdb's built-in simulator where we can do anything. 351 Therefore my suggestion is: 352 353 We define new section ".profiler" which holds all profiling information. 354 We define new pseudo operation .profiler which will instruct assembler to 355 add new profile entry to the object file. Profile should take place at the 356 present address. 357 358 Pseudo-op format: 359 360 .profiler flags,function_to_profile [, cycle_corrector, extra] 361 362 where 'flags' is a combination of the following chars: 363 s - function Start 364 x - function eXit 365 i - function is in Init section 366 f - function is in Fini section 367 l - Library call 368 c - libC standard call 369 d - stack value Demand (saved at run-time in simulator) 370 I - Interrupt service routine 371 P - Prologue start 372 p - Prologue end 373 E - Epilogue start 374 e - Epilogue end 375 j - long Jump/ sjlj unwind 376 a - an Arbitrary code fragment 377 t - exTra parameter saved (constant value like frame size) 378 '""' optional: "sil" == sil 379 380 function_to_profile - function's address 381 cycle_corrector - a value which should be added to the cycle 382 counter, zero if omitted 383 extra - some extra parameter, zero if omitted. 384 385 For example: 386 ------------------------------ 387 .global fxx 388 .type fxx,@function 389 fxx: 390 .LFrameOffset_fxx=0x08 391 .profiler "scdP", fxx ; function entry. 392 ; we also demand stack value to be displayed 393 push r11 394 push r10 395 push r9 396 push r8 397 .profiler "cdp",fxx,0, .LFrameOffset_fxx ; check stack value at this point 398 ; (this is a prologue end) 399 ; note, that spare var filled with the farme size 400 mov r15,r8 401 .... 402 .profiler cdE,fxx ; check stack 403 pop r8 404 pop r9 405 pop r10 406 pop r11 407 .profiler xcde,fxx,3 ; exit adds 3 to the cycle counter 408 ret ; cause 'ret' insn takes 3 cycles 409 ------------------------------- 410 411 This profiling approach does not produce any overhead and 412 absolutely harmless. 413 So, even profiled code can be uploaded to the MCU. */ 414 #define MSP430_PROFILER_FLAG_ENTRY 1 /* s */ 415 #define MSP430_PROFILER_FLAG_EXIT 2 /* x */ 416 #define MSP430_PROFILER_FLAG_INITSECT 4 /* i */ 417 #define MSP430_PROFILER_FLAG_FINISECT 8 /* f */ 418 #define MSP430_PROFILER_FLAG_LIBCALL 0x10 /* l */ 419 #define MSP430_PROFILER_FLAG_STDCALL 0x20 /* c */ 420 #define MSP430_PROFILER_FLAG_STACKDMD 0x40 /* d */ 421 #define MSP430_PROFILER_FLAG_ISR 0x80 /* I */ 422 #define MSP430_PROFILER_FLAG_PROLSTART 0x100 /* P */ 423 #define MSP430_PROFILER_FLAG_PROLEND 0x200 /* p */ 424 #define MSP430_PROFILER_FLAG_EPISTART 0x400 /* E */ 425 #define MSP430_PROFILER_FLAG_EPIEND 0x800 /* e */ 426 #define MSP430_PROFILER_FLAG_JUMP 0x1000 /* j */ 427 #define MSP430_PROFILER_FLAG_FRAGMENT 0x2000 /* a */ 428 #define MSP430_PROFILER_FLAG_EXTRA 0x4000 /* t */ 429 #define MSP430_PROFILER_FLAG_notyet 0x8000 /* ? */ 430 431 static int 432 pow2value (int y) 433 { 434 int n = 0; 435 unsigned int x; 436 437 x = y; 438 439 if (!x) 440 return 1; 441 442 for (; x; x = x >> 1) 443 if (x & 1) 444 n++; 445 446 return n == 1; 447 } 448 449 /* Parse ordinary expression. */ 450 451 static char * 452 parse_exp (char * s, expressionS * op) 453 { 454 input_line_pointer = s; 455 expression (op); 456 if (op->X_op == O_absent) 457 as_bad (_("missing operand")); 458 return input_line_pointer; 459 } 460 461 462 /* Delete spaces from s: X ( r 1 2) => X(r12). */ 463 464 static void 465 del_spaces (char * s) 466 { 467 while (*s) 468 { 469 if (ISSPACE (*s)) 470 { 471 char *m = s + 1; 472 473 while (ISSPACE (*m) && *m) 474 m++; 475 memmove (s, m, strlen (m) + 1); 476 } 477 else 478 s++; 479 } 480 } 481 482 static inline char * 483 skip_space (char * s) 484 { 485 while (ISSPACE (*s)) 486 ++s; 487 return s; 488 } 489 490 /* Extract one word from FROM and copy it to TO. Delimeters are ",;\n" */ 491 492 static char * 493 extract_operand (char * from, char * to, int limit) 494 { 495 int size = 0; 496 497 /* Drop leading whitespace. */ 498 from = skip_space (from); 499 500 while (size < limit && *from) 501 { 502 *(to + size) = *from; 503 if (*from == ',' || *from == ';' || *from == '\n') 504 break; 505 from++; 506 size++; 507 } 508 509 *(to + size) = 0; 510 del_spaces (to); 511 512 from++; 513 514 return from; 515 } 516 517 static void 518 msp430_profiler (int dummy ATTRIBUTE_UNUSED) 519 { 520 char buffer[1024]; 521 char f[32]; 522 char * str = buffer; 523 char * flags = f; 524 int p_flags = 0; 525 char * halt; 526 int ops = 0; 527 int left; 528 char * s; 529 segT seg; 530 int subseg; 531 char * end = 0; 532 expressionS exp; 533 expressionS exp1; 534 535 s = input_line_pointer; 536 end = input_line_pointer; 537 538 while (*end && *end != '\n') 539 end++; 540 541 while (*s && *s != '\n') 542 { 543 if (*s == ',') 544 ops++; 545 s++; 546 } 547 548 left = 3 - ops; 549 550 if (ops < 1) 551 { 552 as_bad (_(".profiler pseudo requires at least two operands.")); 553 input_line_pointer = end; 554 return; 555 } 556 557 input_line_pointer = extract_operand (input_line_pointer, flags, 32); 558 559 while (*flags) 560 { 561 switch (*flags) 562 { 563 case '"': 564 break; 565 case 'a': 566 p_flags |= MSP430_PROFILER_FLAG_FRAGMENT; 567 break; 568 case 'j': 569 p_flags |= MSP430_PROFILER_FLAG_JUMP; 570 break; 571 case 'P': 572 p_flags |= MSP430_PROFILER_FLAG_PROLSTART; 573 break; 574 case 'p': 575 p_flags |= MSP430_PROFILER_FLAG_PROLEND; 576 break; 577 case 'E': 578 p_flags |= MSP430_PROFILER_FLAG_EPISTART; 579 break; 580 case 'e': 581 p_flags |= MSP430_PROFILER_FLAG_EPIEND; 582 break; 583 case 's': 584 p_flags |= MSP430_PROFILER_FLAG_ENTRY; 585 break; 586 case 'x': 587 p_flags |= MSP430_PROFILER_FLAG_EXIT; 588 break; 589 case 'i': 590 p_flags |= MSP430_PROFILER_FLAG_INITSECT; 591 break; 592 case 'f': 593 p_flags |= MSP430_PROFILER_FLAG_FINISECT; 594 break; 595 case 'l': 596 p_flags |= MSP430_PROFILER_FLAG_LIBCALL; 597 break; 598 case 'c': 599 p_flags |= MSP430_PROFILER_FLAG_STDCALL; 600 break; 601 case 'd': 602 p_flags |= MSP430_PROFILER_FLAG_STACKDMD; 603 break; 604 case 'I': 605 p_flags |= MSP430_PROFILER_FLAG_ISR; 606 break; 607 case 't': 608 p_flags |= MSP430_PROFILER_FLAG_EXTRA; 609 break; 610 default: 611 as_warn (_("unknown profiling flag - ignored.")); 612 break; 613 } 614 flags++; 615 } 616 617 if (p_flags 618 && ( ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_ENTRY 619 | MSP430_PROFILER_FLAG_EXIT)) 620 || ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_PROLSTART 621 | MSP430_PROFILER_FLAG_PROLEND 622 | MSP430_PROFILER_FLAG_EPISTART 623 | MSP430_PROFILER_FLAG_EPIEND)) 624 || ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_INITSECT 625 | MSP430_PROFILER_FLAG_FINISECT)))) 626 { 627 as_bad (_("ambigious flags combination - '.profiler' directive ignored.")); 628 input_line_pointer = end; 629 return; 630 } 631 632 /* Generate temp symbol which denotes current location. */ 633 if (now_seg == absolute_section) /* Paranoja ? */ 634 { 635 exp1.X_op = O_constant; 636 exp1.X_add_number = abs_section_offset; 637 as_warn (_("profiling in absolute section? Hm...")); 638 } 639 else 640 { 641 exp1.X_op = O_symbol; 642 exp1.X_add_symbol = symbol_temp_new_now (); 643 exp1.X_add_number = 0; 644 } 645 646 /* Generate a symbol which holds flags value. */ 647 exp.X_op = O_constant; 648 exp.X_add_number = p_flags; 649 650 /* Save current section. */ 651 seg = now_seg; 652 subseg = now_subseg; 653 654 /* Now go to .profiler section. */ 655 obj_elf_change_section (".profiler", SHT_PROGBITS, 0, 0, 0, 0, 0); 656 657 /* Save flags. */ 658 emit_expr (& exp, 2); 659 660 /* Save label value. */ 661 emit_expr (& exp1, 2); 662 663 while (ops--) 664 { 665 /* Now get profiling info. */ 666 halt = extract_operand (input_line_pointer, str, 1024); 667 /* Process like ".word xxx" directive. */ 668 parse_exp (str, & exp); 669 emit_expr (& exp, 2); 670 input_line_pointer = halt; 671 } 672 673 /* Fill the rest with zeros. */ 674 exp.X_op = O_constant; 675 exp.X_add_number = 0; 676 while (left--) 677 emit_expr (& exp, 2); 678 679 /* Return to current section. */ 680 subseg_set (seg, subseg); 681 } 682 683 static char * 684 extract_word (char * from, char * to, int limit) 685 { 686 char *op_start; 687 char *op_end; 688 int size = 0; 689 690 /* Drop leading whitespace. */ 691 from = skip_space (from); 692 *to = 0; 693 694 /* Find the op code end. */ 695 for (op_start = op_end = from; *op_end != 0 && is_part_of_name (*op_end);) 696 { 697 to[size++] = *op_end++; 698 if (size + 1 >= limit) 699 break; 700 } 701 702 to[size] = 0; 703 return op_end; 704 } 705 706 #define OPTION_MMCU 'm' 707 #define OPTION_RELAX 'Q' 708 #define OPTION_POLYMORPHS 'P' 709 710 static void 711 msp430_set_arch (int dummy ATTRIBUTE_UNUSED) 712 { 713 char *str = (char *) alloca (32); /* 32 for good measure. */ 714 715 input_line_pointer = extract_word (input_line_pointer, str, 32); 716 717 md_parse_option (OPTION_MMCU, str); 718 bfd_set_arch_mach (stdoutput, TARGET_ARCH, msp430_mcu->mach); 719 } 720 721 static void 722 show_mcu_list (FILE * stream) 723 { 724 int i; 725 726 fprintf (stream, _("Known MCU names:\n")); 727 728 for (i = 0; mcu_types[i].name; i++) 729 fprintf (stream, _("\t %s\n"), mcu_types[i].name); 730 731 fprintf (stream, "\n"); 732 } 733 734 int 735 md_parse_option (int c, char * arg) 736 { 737 int i; 738 739 switch (c) 740 { 741 case OPTION_MMCU: 742 for (i = 0; mcu_types[i].name; ++i) 743 if (strcmp (mcu_types[i].name, arg) == 0) 744 break; 745 746 if (!mcu_types[i].name) 747 { 748 show_mcu_list (stderr); 749 as_fatal (_("unknown MCU: %s\n"), arg); 750 } 751 752 if (msp430_mcu == &default_mcu || msp430_mcu->mach == mcu_types[i].mach) 753 msp430_mcu = &mcu_types[i]; 754 else 755 as_fatal (_("redefinition of mcu type %s' to %s'"), 756 msp430_mcu->name, mcu_types[i].name); 757 return 1; 758 break; 759 760 case OPTION_RELAX: 761 msp430_enable_relax = 1; 762 return 1; 763 break; 764 765 case OPTION_POLYMORPHS: 766 msp430_enable_polys = 1; 767 return 1; 768 break; 769 } 770 771 return 0; 772 } 773 774 775 const pseudo_typeS md_pseudo_table[] = 776 { 777 {"arch", msp430_set_arch, 0}, 778 {"profiler", msp430_profiler, 0}, 779 {NULL, NULL, 0} 780 }; 781 782 const char *md_shortopts = "m:"; 783 784 struct option md_longopts[] = 785 { 786 {"mmcu", required_argument, NULL, OPTION_MMCU}, 787 {"mP", no_argument, NULL, OPTION_POLYMORPHS}, 788 {"mQ", no_argument, NULL, OPTION_RELAX}, 789 {NULL, no_argument, NULL, 0} 790 }; 791 792 size_t md_longopts_size = sizeof (md_longopts); 793 794 void 795 md_show_usage (FILE * stream) 796 { 797 fprintf (stream, 798 _("MSP430 options:\n" 799 " -mmcu=[msp430-name] select microcontroller type\n" 800 " msp430x110 msp430x112\n" 801 " msp430x1101 msp430x1111\n" 802 " msp430x1121 msp430x1122 msp430x1132\n" 803 " msp430x122 msp430x123\n" 804 " msp430x1222 msp430x1232\n" 805 " msp430x133 msp430x135\n" 806 " msp430x1331 msp430x1351\n" 807 " msp430x147 msp430x148 msp430x149\n" 808 " msp430x155 msp430x156 msp430x157\n" 809 " msp430x167 msp430x168 msp430x169\n" 810 " msp430x1610 msp430x1611 msp430x1612\n" 811 " msp430x311 msp430x312 msp430x313 msp430x314 msp430x315\n" 812 " msp430x323 msp430x325\n" 813 " msp430x336 msp430x337\n" 814 " msp430x412 msp430x413 msp430x415 msp430x417\n" 815 " msp430xE423 msp430xE425 msp430E427\n" 816 " msp430xW423 msp430xW425 msp430W427\n" 817 " msp430xG437 msp430xG438 msp430G439\n" 818 " msp430x435 msp430x436 msp430x437\n" 819 " msp430x447 msp430x448 msp430x449\n")); 820 fprintf (stream, 821 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n" 822 " -mP - enable polymorph instructions\n")); 823 824 show_mcu_list (stream); 825 } 826 827 symbolS * 828 md_undefined_symbol (char * name ATTRIBUTE_UNUSED) 829 { 830 return 0; 831 } 832 833 static char * 834 extract_cmd (char * from, char * to, int limit) 835 { 836 int size = 0; 837 838 while (*from && ! ISSPACE (*from) && *from != '.' && limit > size) 839 { 840 *(to + size) = *from; 841 from++; 842 size++; 843 } 844 845 *(to + size) = 0; 846 847 return from; 848 } 849 850 /* Turn a string in input_line_pointer into a floating point constant 851 of type TYPE, and store the appropriate bytes in *LITP. The number 852 of LITTLENUMS emitted is stored in *SIZEP. An error message is 853 returned, or NULL on OK. */ 854 855 char * 856 md_atof (int type, char * litP, int * sizeP) 857 { 858 int prec; 859 LITTLENUM_TYPE words[4]; 860 LITTLENUM_TYPE *wordP; 861 char *t; 862 863 switch (type) 864 { 865 case 'f': 866 prec = 2; 867 break; 868 case 'd': 869 prec = 4; 870 break; 871 default: 872 *sizeP = 0; 873 return _("bad call to md_atof"); 874 } 875 876 t = atof_ieee (input_line_pointer, type, words); 877 if (t) 878 input_line_pointer = t; 879 880 *sizeP = prec * sizeof (LITTLENUM_TYPE); 881 882 /* This loop outputs the LITTLENUMs in REVERSE order. */ 883 for (wordP = words + prec - 1; prec--;) 884 { 885 md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE)); 886 litP += sizeof (LITTLENUM_TYPE); 887 } 888 889 return NULL; 890 } 891 892 void 893 md_begin (void) 894 { 895 struct msp430_opcode_s * opcode; 896 msp430_hash = hash_new (); 897 898 for (opcode = msp430_opcodes; opcode->name; opcode++) 899 hash_insert (msp430_hash, opcode->name, (char *) opcode); 900 901 bfd_set_arch_mach (stdoutput, TARGET_ARCH, msp430_mcu->mach); 902 } 903 904 static int 905 check_reg (char * t) 906 { 907 /* If this is a reg numb, str 't' must be a number from 0 - 15. */ 908 909 if (strlen (t) > 2 && *(t + 2) != '+') 910 return 1; 911 912 while (*t) 913 { 914 if ((*t < '0' || *t > '9') && *t != '+') 915 break; 916 t++; 917 } 918 919 if (*t) 920 return 1; 921 922 return 0; 923 } 924 925 926 static int 927 msp430_srcoperand (struct msp430_operand_s * op, 928 char * l, int bin, int * imm_op) 929 { 930 char *__tl = l; 931 932 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */ 933 if (*l == '#') 934 { 935 char *h = l; 936 int vshift = -1; 937 int rval = 0; 938 939 /* Check if there is: 940 llo(x) - least significant 16 bits, x &= 0xffff 941 lhi(x) - x = (x >> 16) & 0xffff, 942 hlo(x) - x = (x >> 32) & 0xffff, 943 hhi(x) - x = (x >> 48) & 0xffff 944 The value _MUST_ be constant expression: #hlo(1231231231). */ 945 946 *imm_op = 1; 947 948 if (strncasecmp (h, "#llo(", 5) == 0) 949 { 950 vshift = 0; 951 rval = 3; 952 } 953 else if (strncasecmp (h, "#lhi(", 5) == 0) 954 { 955 vshift = 1; 956 rval = 3; 957 } 958 else if (strncasecmp (h, "#hlo(", 5) == 0) 959 { 960 vshift = 2; 961 rval = 3; 962 } 963 else if (strncasecmp (h, "#hhi(", 5) == 0) 964 { 965 vshift = 3; 966 rval = 3; 967 } 968 else if (strncasecmp (h, "#lo(", 4) == 0) 969 { 970 vshift = 0; 971 rval = 2; 972 } 973 else if (strncasecmp (h, "#hi(", 4) == 0) 974 { 975 vshift = 1; 976 rval = 2; 977 } 978 979 op->reg = 0; /* Reg PC. */ 980 op->am = 3; 981 op->ol = 1; /* Immediate will follow an instruction. */ 982 __tl = h + 1 + rval; 983 op->mode = OP_EXP; 984 985 parse_exp (__tl, &(op->exp)); 986 if (op->exp.X_op == O_constant) 987 { 988 int x = op->exp.X_add_number; 989 990 if (vshift == 0) 991 { 992 x = x & 0xffff; 993 op->exp.X_add_number = x; 994 } 995 else if (vshift == 1) 996 { 997 x = (x >> 16) & 0xffff; 998 op->exp.X_add_number = x; 999 } 1000 else if (vshift > 1) 1001 { 1002 if (x < 0) 1003 op->exp.X_add_number = -1; 1004 else 1005 op->exp.X_add_number = 0; /* Nothing left. */ 1006 x = op->exp.X_add_number; 1007 } 1008 1009 if (op->exp.X_add_number > 65535 || op->exp.X_add_number < -32768) 1010 { 1011 as_bad (_("value %d out of range. Use #lo() or #hi()"), x); 1012 return 1; 1013 } 1014 1015 /* Now check constants. */ 1016 /* Substitute register mode with a constant generator if applicable. */ 1017 1018 x = (short) x; /* Extend sign. */ 1019 1020 if (x == 0) 1021 { 1022 op->reg = 3; 1023 op->am = 0; 1024 op->ol = 0; 1025 op->mode = OP_REG; 1026 } 1027 else if (x == 1) 1028 { 1029 op->reg = 3; 1030 op->am = 1; 1031 op->ol = 0; 1032 op->mode = OP_REG; 1033 } 1034 else if (x == 2) 1035 { 1036 op->reg = 3; 1037 op->am = 2; 1038 op->ol = 0; 1039 op->mode = OP_REG; 1040 } 1041 else if (x == -1) 1042 { 1043 op->reg = 3; 1044 op->am = 3; 1045 op->ol = 0; 1046 op->mode = OP_REG; 1047 } 1048 else if (x == 4) 1049 { 1050 #ifdef PUSH_1X_WORKAROUND 1051 if (bin == 0x1200) 1052 { 1053 /* Remove warning as confusing. 1054 as_warn(_("Hardware push bug workaround")); */ 1055 } 1056 else 1057 #endif 1058 { 1059 op->reg = 2; 1060 op->am = 2; 1061 op->ol = 0; 1062 op->mode = OP_REG; 1063 } 1064 } 1065 else if (x == 8) 1066 { 1067 #ifdef PUSH_1X_WORKAROUND 1068 if (bin == 0x1200) 1069 { 1070 /* Remove warning as confusing. 1071 as_warn(_("Hardware push bug workaround")); */ 1072 } 1073 else 1074 #endif 1075 { 1076 op->reg = 2; 1077 op->am = 3; 1078 op->ol = 0; 1079 op->mode = OP_REG; 1080 } 1081 } 1082 } 1083 else if (op->exp.X_op == O_symbol) 1084 { 1085 op->mode = OP_EXP; 1086 } 1087 else if (op->exp.X_op == O_big) 1088 { 1089 short x; 1090 if (vshift != -1) 1091 { 1092 op->exp.X_op = O_constant; 1093 op->exp.X_add_number = 0xffff & generic_bignum[vshift]; 1094 x = op->exp.X_add_number; 1095 } 1096 else 1097 { 1098 as_bad (_ 1099 ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "), 1100 l); 1101 return 1; 1102 } 1103 1104 if (x == 0) 1105 { 1106 op->reg = 3; 1107 op->am = 0; 1108 op->ol = 0; 1109 op->mode = OP_REG; 1110 } 1111 else if (x == 1) 1112 { 1113 op->reg = 3; 1114 op->am = 1; 1115 op->ol = 0; 1116 op->mode = OP_REG; 1117 } 1118 else if (x == 2) 1119 { 1120 op->reg = 3; 1121 op->am = 2; 1122 op->ol = 0; 1123 op->mode = OP_REG; 1124 } 1125 else if (x == -1) 1126 { 1127 op->reg = 3; 1128 op->am = 3; 1129 op->ol = 0; 1130 op->mode = OP_REG; 1131 } 1132 else if (x == 4) 1133 { 1134 op->reg = 2; 1135 op->am = 2; 1136 op->ol = 0; 1137 op->mode = OP_REG; 1138 } 1139 else if (x == 8) 1140 { 1141 op->reg = 2; 1142 op->am = 3; 1143 op->ol = 0; 1144 op->mode = OP_REG; 1145 } 1146 } 1147 /* Redudant (yet) check. */ 1148 else if (op->exp.X_op == O_register) 1149 as_bad 1150 (_("Registers cannot be used within immediate expression [%s]"), l); 1151 else 1152 as_bad (_("unknown operand %s"), l); 1153 1154 return 0; 1155 } 1156 1157 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */ 1158 if (*l == '&') 1159 { 1160 char *h = l; 1161 1162 op->reg = 2; /* reg 2 in absolute addr mode. */ 1163 op->am = 1; /* mode As == 01 bin. */ 1164 op->ol = 1; /* Immediate value followed by instruction. */ 1165 __tl = h + 1; 1166 parse_exp (__tl, &(op->exp)); 1167 op->mode = OP_EXP; 1168 if (op->exp.X_op == O_constant) 1169 { 1170 int x = op->exp.X_add_number; 1171 1172 if (x > 65535 || x < -32768) 1173 { 1174 as_bad (_("value out of range: %d"), x); 1175 return 1; 1176 } 1177 } 1178 else if (op->exp.X_op == O_symbol) 1179 ; 1180 else 1181 { 1182 /* Redudant (yet) check. */ 1183 if (op->exp.X_op == O_register) 1184 as_bad 1185 (_("Registers cannot be used within absolute expression [%s]"), l); 1186 else 1187 as_bad (_("unknown expression in operand %s"), l); 1188 return 1; 1189 } 1190 return 0; 1191 } 1192 1193 /* Check if indirect register mode @Rn / postincrement @Rn+. */ 1194 if (*l == '@') 1195 { 1196 char *t = l; 1197 char *m = strchr (l, '+'); 1198 1199 if (t != l) 1200 { 1201 as_bad (_("unknown addressing mode %s"), l); 1202 return 1; 1203 } 1204 1205 t++; 1206 if (*t != 'r' && *t != 'R') 1207 { 1208 as_bad (_("unknown addressing mode %s"), l); 1209 return 1; 1210 } 1211 1212 t++; /* Points to the reg value. */ 1213 1214 if (check_reg (t)) 1215 { 1216 as_bad (_("Bad register name r%s"), t); 1217 return 1; 1218 } 1219 1220 op->mode = OP_REG; 1221 op->am = m ? 3 : 2; 1222 op->ol = 0; 1223 if (m) 1224 *m = 0; /* strip '+' */ 1225 op->reg = atoi (t); 1226 if (op->reg < 0 || op->reg > 15) 1227 { 1228 as_bad (_("MSP430 does not have %d registers"), op->reg); 1229 return 1; 1230 } 1231 1232 return 0; 1233 } 1234 1235 /* Check if register indexed X(Rn). */ 1236 do 1237 { 1238 char *h = strrchr (l, '('); 1239 char *m = strrchr (l, ')'); 1240 char *t; 1241 1242 *imm_op = 1; 1243 1244 if (!h) 1245 break; 1246 if (!m) 1247 { 1248 as_bad (_("')' required")); 1249 return 1; 1250 } 1251 1252 t = h; 1253 op->am = 1; 1254 op->ol = 1; 1255 /* Extract a register. */ 1256 t++; /* Advance pointer. */ 1257 1258 if (*t != 'r' && *t != 'R') 1259 { 1260 as_bad (_ 1261 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"), 1262 l); 1263 return 1; 1264 } 1265 t++; 1266 1267 op->reg = *t - '0'; 1268 if (op->reg > 9 || op->reg < 0) 1269 { 1270 as_bad (_("unknown operator (r%s substituded as a register name"), 1271 t); 1272 return 1; 1273 } 1274 t++; 1275 if (*t != ')') 1276 { 1277 op->reg = op->reg * 10; 1278 op->reg += *t - '0'; 1279 1280 if (op->reg > 15) 1281 { 1282 as_bad (_("unknown operator %s"), l); 1283 return 1; 1284 } 1285 if (op->reg == 2) 1286 { 1287 as_bad (_("r2 should not be used in indexed addressing mode")); 1288 return 1; 1289 } 1290 1291 if (*(t + 1) != ')') 1292 { 1293 as_bad (_("unknown operator %s"), l); 1294 return 1; 1295 } 1296 } 1297 1298 /* Extract constant. */ 1299 __tl = l; 1300 *h = 0; 1301 op->mode = OP_EXP; 1302 parse_exp (__tl, &(op->exp)); 1303 if (op->exp.X_op == O_constant) 1304 { 1305 int x = op->exp.X_add_number; 1306 1307 if (x > 65535 || x < -32768) 1308 { 1309 as_bad (_("value out of range: %d"), x); 1310 return 1; 1311 } 1312 1313 if (x == 0) 1314 { 1315 op->mode = OP_REG; 1316 op->am = 2; 1317 op->ol = 0; 1318 return 0; 1319 } 1320 } 1321 else if (op->exp.X_op == O_symbol) 1322 ; 1323 else 1324 { 1325 /* Redudant (yet) check. */ 1326 if (op->exp.X_op == O_register) 1327 as_bad 1328 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l); 1329 else 1330 as_bad (_("unknown expression in operand %s"), l); 1331 return 1; 1332 } 1333 1334 return 0; 1335 } 1336 while (0); 1337 1338 /* Register mode 'mov r1,r2'. */ 1339 do 1340 { 1341 char *t = l; 1342 1343 /* Operand should be a register. */ 1344 if (*t == 'r' || *t == 'R') 1345 { 1346 int x = atoi (t + 1); 1347 1348 if (check_reg (t + 1)) 1349 break; 1350 1351 if (x < 0 || x > 15) 1352 break; /* Symbolic mode. */ 1353 1354 op->mode = OP_REG; 1355 op->am = 0; 1356 op->ol = 0; 1357 op->reg = x; 1358 return 0; 1359 } 1360 } 1361 while (0); 1362 1363 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */ 1364 do 1365 { 1366 op->mode = OP_EXP; 1367 op->reg = 0; /* PC relative... be careful. */ 1368 op->am = 1; 1369 op->ol = 1; 1370 __tl = l; 1371 parse_exp (__tl, &(op->exp)); 1372 return 0; 1373 } 1374 while (0); 1375 1376 /* Unreachable. */ 1377 as_bad (_("unknown addressing mode for operand %s"), l); 1378 return 1; 1379 } 1380 1381 1382 static int 1383 msp430_dstoperand (struct msp430_operand_s * op, char * l, int bin) 1384 { 1385 int dummy; 1386 int ret = msp430_srcoperand (op, l, bin, & dummy); 1387 1388 if (ret) 1389 return ret; 1390 1391 if (op->am == 2) 1392 { 1393 char *__tl = "0"; 1394 1395 op->mode = OP_EXP; 1396 op->am = 1; 1397 op->ol = 1; 1398 parse_exp (__tl, &(op->exp)); 1399 1400 if (op->exp.X_op != O_constant || op->exp.X_add_number != 0) 1401 { 1402 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"), 1403 op->reg, op->reg); 1404 return 1; 1405 } 1406 return 0; 1407 } 1408 1409 if (op->am > 1) 1410 { 1411 as_bad (_ 1412 ("this addressing mode is not applicable for destination operand")); 1413 return 1; 1414 } 1415 return 0; 1416 } 1417 1418 1419 /* Parse instruction operands. 1420 Return binary opcode. */ 1421 1422 static unsigned int 1423 msp430_operands (struct msp430_opcode_s * opcode, char * line) 1424 { 1425 int bin = opcode->bin_opcode; /* Opcode mask. */ 1426 int __is = 0; 1427 char l1[MAX_OP_LEN], l2[MAX_OP_LEN]; 1428 char *frag; 1429 int where; 1430 struct msp430_operand_s op1, op2; 1431 int res = 0; 1432 static short ZEROS = 0; 1433 int byte_op, imm_op; 1434 1435 /* Opcode is the one from opcodes table 1436 line contains something like 1437 [.w] @r2+, 5(R1) 1438 or 1439 .b @r2+, 5(R1). */ 1440 1441 /* Check if byte or word operation. */ 1442 if (*line == '.' && TOLOWER (*(line + 1)) == 'b') 1443 { 1444 bin |= BYTE_OPERATION; 1445 byte_op = 1; 1446 } 1447 else 1448 byte_op = 0; 1449 1450 /* skip .[bwBW]. */ 1451 while (! ISSPACE (*line) && *line) 1452 line++; 1453 1454 if (opcode->insn_opnumb && (!*line || *line == '\n')) 1455 { 1456 as_bad (_("instruction %s requires %d operand(s)"), 1457 opcode->name, opcode->insn_opnumb); 1458 return 0; 1459 } 1460 1461 memset (l1, 0, sizeof (l1)); 1462 memset (l2, 0, sizeof (l2)); 1463 memset (&op1, 0, sizeof (op1)); 1464 memset (&op2, 0, sizeof (op2)); 1465 1466 imm_op = 0; 1467 1468 switch (opcode->fmt) 1469 { 1470 case 0: /* Emulated. */ 1471 switch (opcode->insn_opnumb) 1472 { 1473 case 0: 1474 /* Set/clear bits instructions. */ 1475 __is = 2; 1476 frag = frag_more (__is); 1477 bfd_putl16 ((bfd_vma) bin, frag); 1478 dwarf2_emit_insn (__is); 1479 break; 1480 case 1: 1481 /* Something which works with destination operand. */ 1482 line = extract_operand (line, l1, sizeof (l1)); 1483 res = msp430_dstoperand (&op1, l1, opcode->bin_opcode); 1484 if (res) 1485 break; 1486 1487 bin |= (op1.reg | (op1.am << 7)); 1488 __is = 1 + op1.ol; 1489 frag = frag_more (2 * __is); 1490 where = frag - frag_now->fr_literal; 1491 bfd_putl16 ((bfd_vma) bin, frag); 1492 dwarf2_emit_insn (2 * __is); 1493 1494 if (op1.mode == OP_EXP) 1495 { 1496 where += 2; 1497 bfd_putl16 ((bfd_vma) ZEROS, frag + 2); 1498 1499 if (op1.reg) 1500 fix_new_exp (frag_now, where, 2, 1501 &(op1.exp), FALSE, CHECK_RELOC_MSP430); 1502 else 1503 fix_new_exp (frag_now, where, 2, 1504 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL); 1505 } 1506 break; 1507 1508 case 2: 1509 { 1510 /* Shift instruction. */ 1511 line = extract_operand (line, l1, sizeof (l1)); 1512 strncpy (l2, l1, sizeof (l2)); 1513 l2[sizeof (l2) - 1] = '\0'; 1514 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op); 1515 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode); 1516 1517 if (res) 1518 break; /* An error occurred. All warnings were done before. */ 1519 1520 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7)); 1521 1522 __is = 1 + op1.ol + op2.ol; /* insn size in words. */ 1523 frag = frag_more (2 * __is); 1524 where = frag - frag_now->fr_literal; 1525 bfd_putl16 ((bfd_vma) bin, frag); 1526 dwarf2_emit_insn (2 * __is); 1527 1528 if (op1.mode == OP_EXP) 1529 { 1530 where += 2; /* Advance 'where' as we do not know _where_. */ 1531 bfd_putl16 ((bfd_vma) ZEROS, frag + 2); 1532 1533 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */ 1534 fix_new_exp (frag_now, where, 2, 1535 &(op1.exp), FALSE, CHECK_RELOC_MSP430); 1536 else 1537 fix_new_exp (frag_now, where, 2, 1538 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL); 1539 } 1540 1541 if (op2.mode == OP_EXP) 1542 { 1543 imm_op = 0; 1544 bfd_putl16 ((bfd_vma) ZEROS, frag + 2 + ((__is == 3) ? 2 : 0)); 1545 1546 if (op2.reg) /* Not PC relative. */ 1547 fix_new_exp (frag_now, where + 2, 2, 1548 &(op2.exp), FALSE, CHECK_RELOC_MSP430); 1549 else 1550 fix_new_exp (frag_now, where + 2, 2, 1551 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL); 1552 } 1553 break; 1554 } 1555 case 3: 1556 /* Branch instruction => mov dst, r0. */ 1557 line = extract_operand (line, l1, sizeof (l1)); 1558 1559 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op); 1560 if (res) 1561 break; 1562 1563 byte_op = 0; 1564 imm_op = 0; 1565 1566 bin |= ((op1.reg << 8) | (op1.am << 4)); 1567 __is = 1 + op1.ol; 1568 frag = frag_more (2 * __is); 1569 where = frag - frag_now->fr_literal; 1570 bfd_putl16 ((bfd_vma) bin, frag); 1571 dwarf2_emit_insn (2 * __is); 1572 1573 if (op1.mode == OP_EXP) 1574 { 1575 where += 2; 1576 bfd_putl16 ((bfd_vma) ZEROS, frag + 2); 1577 1578 if (op1.reg || (op1.reg == 0 && op1.am == 3)) 1579 fix_new_exp (frag_now, where, 2, 1580 &(op1.exp), FALSE, CHECK_RELOC_MSP430); 1581 else 1582 fix_new_exp (frag_now, where, 2, 1583 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL); 1584 } 1585 break; 1586 } 1587 break; 1588 1589 case 1: /* Format 1, double operand. */ 1590 line = extract_operand (line, l1, sizeof (l1)); 1591 line = extract_operand (line, l2, sizeof (l2)); 1592 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op); 1593 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode); 1594 1595 if (res) 1596 break; /* Error occurred. All warnings were done before. */ 1597 1598 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7)); 1599 1600 __is = 1 + op1.ol + op2.ol; /* insn size in words. */ 1601 frag = frag_more (2 * __is); 1602 where = frag - frag_now->fr_literal; 1603 bfd_putl16 ((bfd_vma) bin, frag); 1604 dwarf2_emit_insn (2 * __is); 1605 1606 if (op1.mode == OP_EXP) 1607 { 1608 where += 2; /* Advance where as we do not know _where_. */ 1609 bfd_putl16 ((bfd_vma) ZEROS, frag + 2); 1610 1611 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */ 1612 fix_new_exp (frag_now, where, 2, 1613 &(op1.exp), FALSE, CHECK_RELOC_MSP430); 1614 else 1615 fix_new_exp (frag_now, where, 2, 1616 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL); 1617 } 1618 1619 if (op2.mode == OP_EXP) 1620 { 1621 imm_op = 0; 1622 bfd_putl16 ((bfd_vma) ZEROS, frag + 2 + ((__is == 3) ? 2 : 0)); 1623 1624 if (op2.reg) /* Not PC relative. */ 1625 fix_new_exp (frag_now, where + 2, 2, 1626 &(op2.exp), FALSE, CHECK_RELOC_MSP430); 1627 else 1628 fix_new_exp (frag_now, where + 2, 2, 1629 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL); 1630 } 1631 break; 1632 1633 case 2: /* Single-operand mostly instr. */ 1634 if (opcode->insn_opnumb == 0) 1635 { 1636 /* reti instruction. */ 1637 frag = frag_more (2); 1638 bfd_putl16 ((bfd_vma) bin, frag); 1639 dwarf2_emit_insn (2); 1640 break; 1641 } 1642 1643 line = extract_operand (line, l1, sizeof (l1)); 1644 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op); 1645 if (res) 1646 break; /* Error in operand. */ 1647 1648 bin |= op1.reg | (op1.am << 4); 1649 __is = 1 + op1.ol; 1650 frag = frag_more (2 * __is); 1651 where = frag - frag_now->fr_literal; 1652 bfd_putl16 ((bfd_vma) bin, frag); 1653 dwarf2_emit_insn (2 * __is); 1654 1655 if (op1.mode == OP_EXP) 1656 { 1657 bfd_putl16 ((bfd_vma) ZEROS, frag + 2); 1658 1659 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */ 1660 fix_new_exp (frag_now, where + 2, 2, 1661 &(op1.exp), FALSE, CHECK_RELOC_MSP430); 1662 else 1663 fix_new_exp (frag_now, where + 2, 2, 1664 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL); 1665 } 1666 break; 1667 1668 case 3: /* Conditional jumps instructions. */ 1669 line = extract_operand (line, l1, sizeof (l1)); 1670 /* l1 is a label. */ 1671 if (l1[0]) 1672 { 1673 char *m = l1; 1674 expressionS exp; 1675 1676 if (*m == '$') 1677 m++; 1678 1679 parse_exp (m, &exp); 1680 frag = frag_more (2); /* Instr size is 1 word. */ 1681 1682 /* In order to handle something like: 1683 1684 and #0x8000, r5 1685 tst r5 1686 jz 4 ; skip next 4 bytes 1687 inv r5 1688 inc r5 1689 nop ; will jump here if r5 positive or zero 1690 1691 jCOND -n ;assumes jump n bytes backward: 1692 1693 mov r5,r6 1694 jmp -2 1695 1696 is equal to: 1697 lab: 1698 mov r5,r6 1699 jmp lab 1700 1701 jCOND $n ; jump from PC in either direction. */ 1702 1703 if (exp.X_op == O_constant) 1704 { 1705 int x = exp.X_add_number; 1706 1707 if (x & 1) 1708 { 1709 as_warn (_("Even number required. Rounded to %d"), x + 1); 1710 x++; 1711 } 1712 1713 if ((*l1 == '$' && x > 0) || x < 0) 1714 x -= 2; 1715 1716 x >>= 1; 1717 1718 if (x > 512 || x < -511) 1719 { 1720 as_bad (_("Wrong displacement %d"), x << 1); 1721 break; 1722 } 1723 1724 bin |= x & 0x3ff; 1725 bfd_putl16 ((bfd_vma) bin, frag); 1726 } 1727 else if (exp.X_op == O_symbol && *l1 != '$') 1728 { 1729 where = frag - frag_now->fr_literal; 1730 fix_new_exp (frag_now, where, 2, 1731 &exp, TRUE, BFD_RELOC_MSP430_10_PCREL); 1732 1733 bfd_putl16 ((bfd_vma) bin, frag); 1734 } 1735 else if (*l1 == '$') 1736 { 1737 as_bad (_("instruction requires label sans '$'")); 1738 } 1739 else 1740 { 1741 as_bad (_ 1742 ("instruction requires label or value in range -511:512")); 1743 } 1744 dwarf2_emit_insn (2 * __is); 1745 break; 1746 } 1747 else 1748 { 1749 as_bad (_("instruction requires label")); 1750 break; 1751 } 1752 break; 1753 1754 case 4: /* Extended jumps. */ 1755 if (!msp430_enable_polys) 1756 { 1757 as_bad(_("polymorphs are not enabled. Use -mP option to enable.")); 1758 break; 1759 } 1760 1761 line = extract_operand (line, l1, sizeof (l1)); 1762 if (l1[0]) 1763 { 1764 char *m = l1; 1765 expressionS exp; 1766 1767 /* Ignore absolute addressing. make it PC relative anyway. */ 1768 if (*m == '#' || *m == '$') 1769 m++; 1770 1771 parse_exp (m, & exp); 1772 if (exp.X_op == O_symbol) 1773 { 1774 /* Relaxation required. */ 1775 struct rcodes_s rc = msp430_rcodes[opcode->insn_opnumb]; 1776 1777 /* The parameter to dwarf2_emit_insn is actually the offset to the start 1778 of the insn from the fix piece of instruction that was emitted. 1779 Since next fragments may have variable size we tie debug info 1780 to the beginning of the instruction. */ 1781 frag = frag_more (8); 1782 dwarf2_emit_insn (0); 1783 bfd_putl16 ((bfd_vma) rc.sop, frag); 1784 frag = frag_variant (rs_machine_dependent, 8, 2, 1785 ENCODE_RELAX (rc.lpos, STATE_BITS10), /* Wild guess. */ 1786 exp.X_add_symbol, 1787 0, /* Offset is zero if jump dist less than 1K. */ 1788 (char *) frag); 1789 break; 1790 } 1791 } 1792 1793 as_bad (_("instruction requires label")); 1794 break; 1795 1796 case 5: /* Emulated extended branches. */ 1797 if (!msp430_enable_polys) 1798 { 1799 as_bad(_("polymorphs are not enabled. Use -mP option to enable.")); 1800 break; 1801 } 1802 line = extract_operand (line, l1, sizeof (l1)); 1803 if (l1[0]) 1804 { 1805 char * m = l1; 1806 expressionS exp; 1807 1808 /* Ignore absolute addressing. make it PC relative anyway. */ 1809 if (*m == '#' || *m == '$') 1810 m++; 1811 1812 parse_exp (m, & exp); 1813 if (exp.X_op == O_symbol) 1814 { 1815 /* Relaxation required. */ 1816 struct hcodes_s hc = msp430_hcodes[opcode->insn_opnumb]; 1817 1818 frag = frag_more (8); 1819 dwarf2_emit_insn (0); 1820 bfd_putl16 ((bfd_vma) hc.op0, frag); 1821 bfd_putl16 ((bfd_vma) hc.op1, frag+2); 1822 1823 frag = frag_variant (rs_machine_dependent, 8, 2, 1824 ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10), /* Wild guess. */ 1825 exp.X_add_symbol, 1826 0, /* Offset is zero if jump dist less than 1K. */ 1827 (char *) frag); 1828 break; 1829 } 1830 } 1831 1832 as_bad (_("instruction requires label")); 1833 break; 1834 1835 default: 1836 as_bad (_("Ilegal instruction or not implmented opcode.")); 1837 } 1838 1839 input_line_pointer = line; 1840 return 0; 1841 } 1842 1843 void 1844 md_assemble (char * str) 1845 { 1846 struct msp430_opcode_s * opcode; 1847 char cmd[32]; 1848 unsigned int i = 0; 1849 1850 str = skip_space (str); /* Skip leading spaces. */ 1851 str = extract_cmd (str, cmd, sizeof (cmd)); 1852 1853 while (cmd[i] && i < sizeof (cmd)) 1854 { 1855 char a = TOLOWER (cmd[i]); 1856 cmd[i] = a; 1857 i++; 1858 } 1859 1860 if (!cmd[0]) 1861 { 1862 as_bad (_("can't find opcode ")); 1863 return; 1864 } 1865 1866 opcode = (struct msp430_opcode_s *) hash_find (msp430_hash, cmd); 1867 1868 if (opcode == NULL) 1869 { 1870 as_bad (_("unknown opcode `%s'"), cmd); 1871 return; 1872 } 1873 1874 { 1875 char *__t = input_line_pointer; 1876 1877 msp430_operands (opcode, str); 1878 input_line_pointer = __t; 1879 } 1880 } 1881 1882 /* GAS will call this function for each section at the end of the assembly, 1883 to permit the CPU backend to adjust the alignment of a section. */ 1884 1885 valueT 1886 md_section_align (asection * seg, valueT addr) 1887 { 1888 int align = bfd_get_section_alignment (stdoutput, seg); 1889 1890 return ((addr + (1 << align) - 1) & (-1 << align)); 1891 } 1892 1893 /* If you define this macro, it should return the offset between the 1894 address of a PC relative fixup and the position from which the PC 1895 relative adjustment should be made. On many processors, the base 1896 of a PC relative instruction is the next instruction, so this 1897 macro would return the length of an instruction. */ 1898 1899 long 1900 md_pcrel_from_section (fixS * fixp, segT sec) 1901 { 1902 if (fixp->fx_addsy != (symbolS *) NULL 1903 && (!S_IS_DEFINED (fixp->fx_addsy) 1904 || (S_GET_SEGMENT (fixp->fx_addsy) != sec))) 1905 return 0; 1906 1907 return fixp->fx_frag->fr_address + fixp->fx_where; 1908 } 1909 1910 /* Replaces standard TC_FORCE_RELOCATION_LOCAL. 1911 Now it handles the situation when relocations 1912 have to be passed to linker. */ 1913 int 1914 msp430_force_relocation_local(fixS *fixp) 1915 { 1916 if (msp430_enable_polys 1917 && !msp430_enable_relax) 1918 return 1; 1919 else 1920 return (!fixp->fx_pcrel 1921 || fixp->fx_plt 1922 || generic_force_reloc(fixp)); 1923 } 1924 1925 1926 /* GAS will call this for each fixup. It should store the correct 1927 value in the object file. */ 1928 void 1929 md_apply_fix (fixS * fixp, valueT * valuep, segT seg) 1930 { 1931 unsigned char * where; 1932 unsigned long insn; 1933 long value; 1934 1935 if (fixp->fx_addsy == (symbolS *) NULL) 1936 { 1937 value = *valuep; 1938 fixp->fx_done = 1; 1939 } 1940 else if (fixp->fx_pcrel) 1941 { 1942 segT s = S_GET_SEGMENT (fixp->fx_addsy); 1943 1944 if (fixp->fx_addsy && (s == seg || s == absolute_section)) 1945 { 1946 /* FIXME: We can appear here only in case if we perform a pc 1947 relative jump to the label which is i) global, ii) locally 1948 defined or this is a jump to an absolute symbol. 1949 If this is an absolute symbol -- everything is OK. 1950 If this is a global label, we've got a symbol value defined 1951 twice: 1952 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset 1953 from this section start 1954 2. *valuep will contain the real offset from jump insn to the 1955 label 1956 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep); 1957 will be incorrect. Therefore remove s_get_value. */ 1958 value = /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep; 1959 fixp->fx_done = 1; 1960 } 1961 else 1962 value = *valuep; 1963 } 1964 else 1965 { 1966 value = fixp->fx_offset; 1967 1968 if (fixp->fx_subsy != (symbolS *) NULL) 1969 { 1970 if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section) 1971 { 1972 value -= S_GET_VALUE (fixp->fx_subsy); 1973 fixp->fx_done = 1; 1974 } 1975 else 1976 { 1977 /* We don't actually support subtracting a symbol. */ 1978 as_bad_where (fixp->fx_file, fixp->fx_line, 1979 _("expression too complex")); 1980 } 1981 } 1982 } 1983 1984 fixp->fx_no_overflow = 1; 1985 1986 /* if polymorphs are enabled and relax disabled. 1987 do not kill any relocs and pass them to linker. */ 1988 if (msp430_enable_polys 1989 && !msp430_enable_relax) 1990 { 1991 if (!fixp->fx_addsy || (fixp->fx_addsy 1992 && S_GET_SEGMENT (fixp->fx_addsy) == absolute_section)) 1993 fixp->fx_done = 1; /* it is ok to kill 'abs' reloc */ 1994 else 1995 fixp->fx_done = 0; 1996 } 1997 1998 if (fixp->fx_done) 1999 { 2000 /* Fetch the instruction, insert the fully resolved operand 2001 value, and stuff the instruction back again. */ 2002 2003 where = (unsigned char *) fixp->fx_frag->fr_literal + fixp->fx_where; 2004 2005 insn = bfd_getl16 (where); 2006 2007 switch (fixp->fx_r_type) 2008 { 2009 case BFD_RELOC_MSP430_10_PCREL: 2010 if (value & 1) 2011 as_bad_where (fixp->fx_file, fixp->fx_line, 2012 _("odd address operand: %ld"), value); 2013 2014 /* Jumps are in words. */ 2015 value >>= 1; 2016 --value; /* Correct PC. */ 2017 2018 if (value < -512 || value > 511) 2019 as_bad_where (fixp->fx_file, fixp->fx_line, 2020 _("operand out of range: %ld"), value); 2021 2022 value &= 0x3ff; /* get rid of extended sign */ 2023 bfd_putl16 ((bfd_vma) (value | insn), where); 2024 break; 2025 2026 case BFD_RELOC_MSP430_RL_PCREL: 2027 case BFD_RELOC_MSP430_16_PCREL: 2028 if (value & 1) 2029 as_bad_where (fixp->fx_file, fixp->fx_line, 2030 _("odd address operand: %ld"), value); 2031 2032 /* Nothing to be corrected here. */ 2033 if (value < -32768 || value > 65536) 2034 as_bad_where (fixp->fx_file, fixp->fx_line, 2035 _("operand out of range: %ld"), value); 2036 2037 value &= 0xffff; /* Get rid of extended sign. */ 2038 bfd_putl16 ((bfd_vma) value, where); 2039 break; 2040 2041 case BFD_RELOC_MSP430_16_PCREL_BYTE: 2042 /* Nothing to be corrected here. */ 2043 if (value < -32768 || value > 65536) 2044 as_bad_where (fixp->fx_file, fixp->fx_line, 2045 _("operand out of range: %ld"), value); 2046 2047 value &= 0xffff; /* Get rid of extended sign. */ 2048 bfd_putl16 ((bfd_vma) value, where); 2049 break; 2050 2051 case BFD_RELOC_32: 2052 bfd_putl16 ((bfd_vma) value, where); 2053 break; 2054 2055 case BFD_RELOC_MSP430_16: 2056 case BFD_RELOC_16: 2057 case BFD_RELOC_MSP430_16_BYTE: 2058 value &= 0xffff; 2059 bfd_putl16 ((bfd_vma) value, where); 2060 break; 2061 2062 default: 2063 as_fatal (_("line %d: unknown relocation type: 0x%x"), 2064 fixp->fx_line, fixp->fx_r_type); 2065 break; 2066 } 2067 } 2068 else 2069 { 2070 fixp->fx_addnumber = value; 2071 } 2072 } 2073 2074 /* GAS will call this to generate a reloc, passing the resulting reloc 2075 to `bfd_install_relocation'. This currently works poorly, as 2076 `bfd_install_relocation' often does the wrong thing, and instances of 2077 `tc_gen_reloc' have been written to work around the problems, which 2078 in turns makes it difficult to fix `bfd_install_relocation'. */ 2079 2080 /* If while processing a fixup, a reloc really needs to be created 2081 then it is done here. */ 2082 2083 arelent * 2084 tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp) 2085 { 2086 arelent * reloc; 2087 2088 reloc = xmalloc (sizeof (arelent)); 2089 2090 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *)); 2091 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); 2092 2093 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; 2094 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); 2095 if (reloc->howto == (reloc_howto_type *) NULL) 2096 { 2097 as_bad_where (fixp->fx_file, fixp->fx_line, 2098 _("reloc %d not supported by object file format"), 2099 (int) fixp->fx_r_type); 2100 return NULL; 2101 } 2102 2103 if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT 2104 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY) 2105 reloc->address = fixp->fx_offset; 2106 2107 reloc->addend = fixp->fx_offset; 2108 2109 return reloc; 2110 } 2111 2112 int 2113 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, 2114 asection * segment_type ATTRIBUTE_UNUSED) 2115 { 2116 if (fragP->fr_symbol && S_GET_SEGMENT (fragP->fr_symbol) == segment_type) 2117 { 2118 /* This is a jump -> pcrel mode. Nothing to do much here. 2119 Return value == 2. */ 2120 fragP->fr_subtype = 2121 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_BITS10); 2122 } 2123 else if (fragP->fr_symbol) 2124 { 2125 /* Its got a segment, but its not ours. Even if fr_symbol is in 2126 an absolute segment, we dont know a displacement until we link 2127 object files. So it will always be long. This also applies to 2128 labels in a subsegment of current. Liker may relax it to short 2129 jump later. Return value == 8. */ 2130 fragP->fr_subtype = 2131 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_WORD); 2132 } 2133 else 2134 { 2135 /* We know the abs value. may be it is a jump to fixed address. 2136 Impossible in our case, cause all constants already handeled. */ 2137 fragP->fr_subtype = 2138 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_UNDEF); 2139 } 2140 2141 return md_relax_table[fragP->fr_subtype].rlx_length; 2142 } 2143 2144 void 2145 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, 2146 asection * sec ATTRIBUTE_UNUSED, 2147 fragS * fragP) 2148 { 2149 char * where = 0; 2150 int rela = -1; 2151 int i; 2152 struct rcodes_s * cc = NULL; 2153 struct hcodes_s * hc = NULL; 2154 2155 switch (fragP->fr_subtype) 2156 { 2157 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_BITS10): 2158 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_BITS10): 2159 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_BITS10): 2160 /* We do not have to convert anything here. 2161 Just apply a fix. */ 2162 rela = BFD_RELOC_MSP430_10_PCREL; 2163 break; 2164 2165 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_WORD): 2166 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_UNDEF): 2167 /* Convert uncond branch jmp lab -> br lab. */ 2168 cc = & msp430_rcodes[7]; 2169 where = fragP->fr_literal + fragP->fr_fix; 2170 bfd_putl16 (cc->lop0, where); 2171 rela = BFD_RELOC_MSP430_RL_PCREL; 2172 fragP->fr_fix += 2; 2173 break; 2174 2175 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_WORD): 2176 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_UNDEF): 2177 { 2178 /* Other simple branches. */ 2179 int insn = bfd_getl16 (fragP->fr_opcode); 2180 2181 insn &= 0xffff; 2182 /* Find actual instruction. */ 2183 for (i = 0; i < 7 && !cc; i++) 2184 if (msp430_rcodes[i].sop == insn) 2185 cc = & msp430_rcodes[i]; 2186 if (!cc || !cc->name) 2187 as_fatal (_("internal inconsistency problem in %s: insn %04lx"), 2188 __FUNCTION__, (long) insn); 2189 where = fragP->fr_literal + fragP->fr_fix; 2190 bfd_putl16 (cc->lop0, where); 2191 bfd_putl16 (cc->lop1, where + 2); 2192 rela = BFD_RELOC_MSP430_RL_PCREL; 2193 fragP->fr_fix += 4; 2194 } 2195 break; 2196 2197 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_WORD): 2198 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_UNDEF): 2199 cc = & msp430_rcodes[6]; 2200 where = fragP->fr_literal + fragP->fr_fix; 2201 bfd_putl16 (cc->lop0, where); 2202 bfd_putl16 (cc->lop1, where + 2); 2203 bfd_putl16 (cc->lop2, where + 4); 2204 rela = BFD_RELOC_MSP430_RL_PCREL; 2205 fragP->fr_fix += 6; 2206 break; 2207 2208 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10): 2209 { 2210 int insn = bfd_getl16 (fragP->fr_opcode + 2); 2211 2212 insn &= 0xffff; 2213 for (i = 0; i < 4 && !hc; i++) 2214 if (msp430_hcodes[i].op1 == insn) 2215 hc = &msp430_hcodes[i]; 2216 if (!hc || !hc->name) 2217 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"), 2218 __FUNCTION__, (long) insn); 2219 rela = BFD_RELOC_MSP430_10_PCREL; 2220 /* Apply a fix for a first label if necessary. 2221 another fix will be applied to the next word of insn anyway. */ 2222 if (hc->tlab == 2) 2223 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, 2224 fragP->fr_offset, TRUE, rela); 2225 fragP->fr_fix += 2; 2226 } 2227 2228 break; 2229 2230 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_WORD): 2231 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_UNDEF): 2232 { 2233 int insn = bfd_getl16 (fragP->fr_opcode + 2); 2234 2235 insn &= 0xffff; 2236 for (i = 0; i < 4 && !hc; i++) 2237 if (msp430_hcodes[i].op1 == insn) 2238 hc = & msp430_hcodes[i]; 2239 if (!hc || !hc->name) 2240 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"), 2241 __FUNCTION__, (long) insn); 2242 rela = BFD_RELOC_MSP430_RL_PCREL; 2243 where = fragP->fr_literal + fragP->fr_fix; 2244 bfd_putl16 (hc->lop0, where); 2245 bfd_putl16 (hc->lop1, where + 2); 2246 bfd_putl16 (hc->lop2, where + 4); 2247 fragP->fr_fix += 6; 2248 } 2249 break; 2250 2251 default: 2252 as_fatal (_("internal inconsistency problem in %s: %lx"), 2253 __FUNCTION__, (long) fragP->fr_subtype); 2254 break; 2255 } 2256 2257 /* Now apply fix. */ 2258 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, 2259 fragP->fr_offset, TRUE, rela); 2260 /* Just fixed 2 bytes. */ 2261 fragP->fr_fix += 2; 2262 } 2263 2264 /* Relax fragment. Mostly stolen from hc11 and mcore 2265 which arches I think I know. */ 2266 2267 long 2268 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS * fragP, 2269 long stretch ATTRIBUTE_UNUSED) 2270 { 2271 long growth; 2272 offsetT aim = 0; 2273 symbolS *symbolP; 2274 const relax_typeS *this_type; 2275 const relax_typeS *start_type; 2276 relax_substateT next_state; 2277 relax_substateT this_state; 2278 const relax_typeS *table = md_relax_table; 2279 2280 /* Nothing to be done if the frag has already max size. */ 2281 if (RELAX_STATE (fragP->fr_subtype) == STATE_UNDEF 2282 || RELAX_STATE (fragP->fr_subtype) == STATE_WORD) 2283 return 0; 2284 2285 if (RELAX_STATE (fragP->fr_subtype) == STATE_BITS10) 2286 { 2287 symbolP = fragP->fr_symbol; 2288 if (symbol_resolved_p (symbolP)) 2289 as_fatal (_("internal inconsistency problem in %s: resolved symbol"), 2290 __FUNCTION__); 2291 /* We know the offset. calculate a distance. */ 2292 aim = S_GET_VALUE (symbolP) - fragP->fr_address - fragP->fr_fix; 2293 } 2294 2295 if (!msp430_enable_relax) 2296 { 2297 /* Relaxation is not enabled. So, make all jump as long ones 2298 by setting 'aim' to quite high value. */ 2299 aim = 0x7fff; 2300 } 2301 2302 this_state = fragP->fr_subtype; 2303 start_type = this_type = table + this_state; 2304 2305 if (aim < 0) 2306 { 2307 /* Look backwards. */ 2308 for (next_state = this_type->rlx_more; next_state;) 2309 if (aim >= this_type->rlx_backward || !this_type->rlx_backward) 2310 next_state = 0; 2311 else 2312 { 2313 /* Grow to next state. */ 2314 this_state = next_state; 2315 this_type = table + this_state; 2316 next_state = this_type->rlx_more; 2317 } 2318 } 2319 else 2320 { 2321 /* Look forwards. */ 2322 for (next_state = this_type->rlx_more; next_state;) 2323 if (aim <= this_type->rlx_forward || !this_type->rlx_forward) 2324 next_state = 0; 2325 else 2326 { 2327 /* Grow to next state. */ 2328 this_state = next_state; 2329 this_type = table + this_state; 2330 next_state = this_type->rlx_more; 2331 } 2332 } 2333 2334 growth = this_type->rlx_length - start_type->rlx_length; 2335 if (growth != 0) 2336 fragP->fr_subtype = this_state; 2337 return growth; 2338 } 2339