OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gas/] [config/] [tc-msp430.c] - Blame information for rev 16

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.