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