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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.20.1/] [gas/] [config/] [tc-msp430.c] - Blame information for rev 413

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 205 julius
/* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
2
 
3
  Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009
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_start;
682
  char *op_end;
683
  int size = 0;
684
 
685
  /* Drop leading whitespace.  */
686
  from = skip_space (from);
687
  *to = 0;
688
 
689
  /* Find the op code end.  */
690
  for (op_start = op_end = from; *op_end != 0 && is_part_of_name (*op_end);)
691
    {
692
      to[size++] = *op_end++;
693
      if (size + 1 >= limit)
694
        break;
695
    }
696
 
697
  to[size] = 0;
698
  return op_end;
699
}
700
 
701
#define OPTION_MMCU 'm'
702
#define OPTION_RELAX 'Q'
703
#define OPTION_POLYMORPHS 'P'
704
 
705
static void
706
msp430_set_arch (int dummy ATTRIBUTE_UNUSED)
707
{
708
  char *str = (char *) alloca (32);     /* 32 for good measure.  */
709
 
710
  input_line_pointer = extract_word (input_line_pointer, str, 32);
711
 
712
  md_parse_option (OPTION_MMCU, str);
713
  bfd_set_arch_mach (stdoutput, TARGET_ARCH, msp430_mcu->mach);
714
}
715
 
716
static void
717
show_mcu_list (FILE * stream)
718
{
719
  int i;
720
 
721
  fprintf (stream, _("Known MCU names:\n"));
722
 
723
  for (i = 0; mcu_types[i].name; i++)
724
    fprintf (stream, _("\t %s\n"), mcu_types[i].name);
725
 
726
  fprintf (stream, "\n");
727
}
728
 
729
int
730
md_parse_option (int c, char * arg)
731
{
732
  int i;
733
 
734
  switch (c)
735
    {
736
    case OPTION_MMCU:
737
      for (i = 0; mcu_types[i].name; ++i)
738
        if (strcmp (mcu_types[i].name, arg) == 0)
739
          break;
740
 
741
      if (!mcu_types[i].name)
742
        {
743
          show_mcu_list (stderr);
744
          as_fatal (_("unknown MCU: %s\n"), arg);
745
        }
746
 
747
      if (msp430_mcu == &default_mcu || msp430_mcu->mach == mcu_types[i].mach)
748
        msp430_mcu = &mcu_types[i];
749
      else
750
        as_fatal (_("redefinition of mcu type %s' to %s'"),
751
                  msp430_mcu->name, mcu_types[i].name);
752
      return 1;
753
      break;
754
 
755
    case OPTION_RELAX:
756
      msp430_enable_relax = 1;
757
      return 1;
758
      break;
759
 
760
    case OPTION_POLYMORPHS:
761
      msp430_enable_polys = 1;
762
      return 1;
763
      break;
764
    }
765
 
766
  return 0;
767
}
768
 
769
 
770
const pseudo_typeS md_pseudo_table[] =
771
{
772
  {"arch", msp430_set_arch, 0},
773
  {"profiler", msp430_profiler, 0},
774
  {NULL, NULL, 0}
775
};
776
 
777
const char *md_shortopts = "m:";
778
 
779
struct option md_longopts[] =
780
{
781
  {"mmcu", required_argument, NULL, OPTION_MMCU},
782
  {"mP", no_argument, NULL, OPTION_POLYMORPHS},
783
  {"mQ", no_argument, NULL, OPTION_RELAX},
784
  {NULL, no_argument, NULL, 0}
785
};
786
 
787
size_t md_longopts_size = sizeof (md_longopts);
788
 
789
void
790
md_show_usage (FILE * stream)
791
{
792
  fprintf (stream,
793
           _("MSP430 options:\n"
794
             "  -mmcu=[msp430-name] select microcontroller type\n"
795
             "                  msp430x110  msp430x112\n"
796
             "                  msp430x1101 msp430x1111\n"
797
             "                  msp430x1121 msp430x1122 msp430x1132\n"
798
             "                  msp430x122  msp430x123\n"
799
             "                  msp430x1222 msp430x1232\n"
800
             "                  msp430x133  msp430x135\n"
801
             "                  msp430x1331 msp430x1351\n"
802
             "                  msp430x147  msp430x148  msp430x149\n"
803
             "                  msp430x155  msp430x156  msp430x157\n"
804
             "                  msp430x167  msp430x168  msp430x169\n"
805
             "                  msp430x1610 msp430x1611 msp430x1612\n"
806
             "                  msp430x311  msp430x312  msp430x313  msp430x314  msp430x315\n"
807
             "                  msp430x323  msp430x325\n"
808
             "                  msp430x336  msp430x337\n"
809
             "                  msp430x412  msp430x413  msp430x415  msp430x417\n"
810
             "                  msp430xE423 msp430xE425 msp430E427\n"
811
             "                  msp430xW423 msp430xW425 msp430W427\n"
812
             "                  msp430xG437 msp430xG438 msp430G439\n"
813
             "                  msp430x435  msp430x436  msp430x437\n"
814
             "                  msp430x447  msp430x448  msp430x449\n"));
815
  fprintf (stream,
816
           _("  -mQ - enable relaxation at assembly time. DANGEROUS!\n"
817
             "  -mP - enable polymorph instructions\n"));
818
 
819
  show_mcu_list (stream);
820
}
821
 
822
symbolS *
823
md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
824
{
825
  return 0;
826
}
827
 
828
static char *
829
extract_cmd (char * from, char * to, int limit)
830
{
831
  int size = 0;
832
 
833
  while (*from && ! ISSPACE (*from) && *from != '.' && limit > size)
834
    {
835
      *(to + size) = *from;
836
      from++;
837
      size++;
838
    }
839
 
840
  *(to + size) = 0;
841
 
842
  return from;
843
}
844
 
845
char *
846
md_atof (int type, char * litP, int * sizeP)
847
{
848
  return ieee_md_atof (type, litP, sizeP, FALSE);
849
}
850
 
851
void
852
md_begin (void)
853
{
854
  struct msp430_opcode_s * opcode;
855
  msp430_hash = hash_new ();
856
 
857
  for (opcode = msp430_opcodes; opcode->name; opcode++)
858
    hash_insert (msp430_hash, opcode->name, (char *) opcode);
859
 
860
  bfd_set_arch_mach (stdoutput, TARGET_ARCH, msp430_mcu->mach);
861
}
862
 
863
static int
864
check_reg (char * t)
865
{
866
  /* If this is a reg numb, str 't' must be a number from 0 - 15.  */
867
 
868
  if (strlen (t) > 2 && *(t + 2) != '+')
869
    return 1;
870
 
871
  while (*t)
872
    {
873
      if ((*t < '0' || *t > '9') && *t != '+')
874
        break;
875
      t++;
876
    }
877
 
878
  if (*t)
879
    return 1;
880
 
881
  return 0;
882
}
883
 
884
 
885
static int
886
msp430_srcoperand (struct msp430_operand_s * op,
887
                   char * l, int bin, int * imm_op)
888
{
889
  char *__tl = l;
890
 
891
  /* Check if an immediate #VALUE.  The hash sign should be only at the beginning!  */
892
  if (*l == '#')
893
    {
894
      char *h = l;
895
      int vshift = -1;
896
      int rval = 0;
897
 
898
      /* Check if there is:
899
         llo(x) - least significant 16 bits, x &= 0xffff
900
         lhi(x) - x = (x >> 16) & 0xffff,
901
         hlo(x) - x = (x >> 32) & 0xffff,
902
         hhi(x) - x = (x >> 48) & 0xffff
903
         The value _MUST_ be constant expression: #hlo(1231231231).  */
904
 
905
      *imm_op = 1;
906
 
907
      if (strncasecmp (h, "#llo(", 5) == 0)
908
        {
909
          vshift = 0;
910
          rval = 3;
911
        }
912
      else if (strncasecmp (h, "#lhi(", 5) == 0)
913
        {
914
          vshift = 1;
915
          rval = 3;
916
        }
917
      else if (strncasecmp (h, "#hlo(", 5) == 0)
918
        {
919
          vshift = 2;
920
          rval = 3;
921
        }
922
      else if (strncasecmp (h, "#hhi(", 5) == 0)
923
        {
924
          vshift = 3;
925
          rval = 3;
926
        }
927
      else if (strncasecmp (h, "#lo(", 4) == 0)
928
        {
929
          vshift = 0;
930
          rval = 2;
931
        }
932
      else if (strncasecmp (h, "#hi(", 4) == 0)
933
        {
934
          vshift = 1;
935
          rval = 2;
936
        }
937
 
938
      op->reg = 0;               /* Reg PC.  */
939
      op->am = 3;
940
      op->ol = 1;               /* Immediate  will follow an instruction.  */
941
      __tl = h + 1 + rval;
942
      op->mode = OP_EXP;
943
 
944
      parse_exp (__tl, &(op->exp));
945
      if (op->exp.X_op == O_constant)
946
        {
947
          int x = op->exp.X_add_number;
948
 
949
          if (vshift == 0)
950
            {
951
              x = x & 0xffff;
952
              op->exp.X_add_number = x;
953
            }
954
          else if (vshift == 1)
955
            {
956
              x = (x >> 16) & 0xffff;
957
              op->exp.X_add_number = x;
958
            }
959
          else if (vshift > 1)
960
            {
961
              if (x < 0)
962
                op->exp.X_add_number = -1;
963
              else
964
                op->exp.X_add_number = 0;        /* Nothing left.  */
965
              x = op->exp.X_add_number;
966
            }
967
 
968
          if (op->exp.X_add_number > 65535 || op->exp.X_add_number < -32768)
969
            {
970
              as_bad (_("value %d out of range. Use #lo() or #hi()"), x);
971
              return 1;
972
            }
973
 
974
          /* Now check constants.  */
975
          /* Substitute register mode with a constant generator if applicable.  */
976
 
977
          x = (short) x;        /* Extend sign.  */
978
 
979
          if (x == 0)
980
            {
981
              op->reg = 3;
982
              op->am = 0;
983
              op->ol = 0;
984
              op->mode = OP_REG;
985
            }
986
          else if (x == 1)
987
            {
988
              op->reg = 3;
989
              op->am = 1;
990
              op->ol = 0;
991
              op->mode = OP_REG;
992
            }
993
          else if (x == 2)
994
            {
995
              op->reg = 3;
996
              op->am = 2;
997
              op->ol = 0;
998
              op->mode = OP_REG;
999
            }
1000
          else if (x == -1)
1001
            {
1002
              op->reg = 3;
1003
              op->am = 3;
1004
              op->ol = 0;
1005
              op->mode = OP_REG;
1006
            }
1007
          else if (x == 4)
1008
            {
1009
#ifdef PUSH_1X_WORKAROUND
1010
              if (bin == 0x1200)
1011
                {
1012
                  /* Remove warning as confusing.
1013
                     as_warn (_("Hardware push bug workaround")); */
1014
                }
1015
              else
1016
#endif
1017
                {
1018
                  op->reg = 2;
1019
                  op->am = 2;
1020
                  op->ol = 0;
1021
                  op->mode = OP_REG;
1022
                }
1023
            }
1024
          else if (x == 8)
1025
            {
1026
#ifdef PUSH_1X_WORKAROUND
1027
              if (bin == 0x1200)
1028
                {
1029
                  /* Remove warning as confusing.
1030
                     as_warn (_("Hardware push bug workaround")); */
1031
                }
1032
              else
1033
#endif
1034
                {
1035
                  op->reg = 2;
1036
                  op->am = 3;
1037
                  op->ol = 0;
1038
                  op->mode = OP_REG;
1039
                }
1040
            }
1041
        }
1042
      else if (op->exp.X_op == O_symbol)
1043
        {
1044
          op->mode = OP_EXP;
1045
        }
1046
      else if (op->exp.X_op == O_big)
1047
        {
1048
          short x;
1049
          if (vshift != -1)
1050
            {
1051
              op->exp.X_op = O_constant;
1052
              op->exp.X_add_number = 0xffff & generic_bignum[vshift];
1053
              x = op->exp.X_add_number;
1054
            }
1055
          else
1056
            {
1057
              as_bad (_
1058
                      ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "),
1059
                      l);
1060
              return 1;
1061
            }
1062
 
1063
          if (x == 0)
1064
            {
1065
              op->reg = 3;
1066
              op->am = 0;
1067
              op->ol = 0;
1068
              op->mode = OP_REG;
1069
            }
1070
          else if (x == 1)
1071
            {
1072
              op->reg = 3;
1073
              op->am = 1;
1074
              op->ol = 0;
1075
              op->mode = OP_REG;
1076
            }
1077
          else if (x == 2)
1078
            {
1079
              op->reg = 3;
1080
              op->am = 2;
1081
              op->ol = 0;
1082
              op->mode = OP_REG;
1083
            }
1084
          else if (x == -1)
1085
            {
1086
              op->reg = 3;
1087
              op->am = 3;
1088
              op->ol = 0;
1089
              op->mode = OP_REG;
1090
            }
1091
          else if (x == 4)
1092
            {
1093
              op->reg = 2;
1094
              op->am = 2;
1095
              op->ol = 0;
1096
              op->mode = OP_REG;
1097
            }
1098
          else if (x == 8)
1099
            {
1100
              op->reg = 2;
1101
              op->am = 3;
1102
              op->ol = 0;
1103
              op->mode = OP_REG;
1104
            }
1105
        }
1106
      /* Redundant (yet) check.  */
1107
      else if (op->exp.X_op == O_register)
1108
        as_bad
1109
          (_("Registers cannot be used within immediate expression [%s]"), l);
1110
      else
1111
        as_bad (_("unknown operand %s"), l);
1112
 
1113
      return 0;
1114
    }
1115
 
1116
  /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25).  */
1117
  if (*l == '&')
1118
    {
1119
      char *h = l;
1120
 
1121
      op->reg = 2;              /* reg 2 in absolute addr mode.  */
1122
      op->am = 1;               /* mode As == 01 bin.  */
1123
      op->ol = 1;               /* Immediate value followed by instruction.  */
1124
      __tl = h + 1;
1125
      parse_exp (__tl, &(op->exp));
1126
      op->mode = OP_EXP;
1127
      if (op->exp.X_op == O_constant)
1128
        {
1129
          int x = op->exp.X_add_number;
1130
 
1131
          if (x > 65535 || x < -32768)
1132
            {
1133
              as_bad (_("value out of range: %d"), x);
1134
              return 1;
1135
            }
1136
        }
1137
      else if (op->exp.X_op == O_symbol)
1138
        ;
1139
      else
1140
        {
1141
          /* Redundant (yet) check.  */
1142
          if (op->exp.X_op == O_register)
1143
            as_bad
1144
              (_("Registers cannot be used within absolute expression [%s]"), l);
1145
          else
1146
            as_bad (_("unknown expression in operand %s"), l);
1147
          return 1;
1148
        }
1149
      return 0;
1150
    }
1151
 
1152
  /* Check if indirect register mode @Rn / postincrement @Rn+.  */
1153
  if (*l == '@')
1154
    {
1155
      char *t = l;
1156
      char *m = strchr (l, '+');
1157
 
1158
      if (t != l)
1159
        {
1160
          as_bad (_("unknown addressing mode %s"), l);
1161
          return 1;
1162
        }
1163
 
1164
      t++;
1165
      if (*t != 'r' && *t != 'R')
1166
        {
1167
          as_bad (_("unknown addressing mode %s"), l);
1168
          return 1;
1169
        }
1170
 
1171
      t++;      /* Points to the reg value.  */
1172
 
1173
      if (check_reg (t))
1174
        {
1175
          as_bad (_("Bad register name r%s"), t);
1176
          return 1;
1177
        }
1178
 
1179
      op->mode = OP_REG;
1180
      op->am = m ? 3 : 2;
1181
      op->ol = 0;
1182
      if (m)
1183
        *m = 0;                  /* strip '+' */
1184
      op->reg = atoi (t);
1185
      if (op->reg < 0 || op->reg > 15)
1186
        {
1187
          as_bad (_("MSP430 does not have %d registers"), op->reg);
1188
          return 1;
1189
        }
1190
 
1191
      return 0;
1192
    }
1193
 
1194
  /* Check if register indexed X(Rn).  */
1195
  do
1196
    {
1197
      char *h = strrchr (l, '(');
1198
      char *m = strrchr (l, ')');
1199
      char *t;
1200
 
1201
      *imm_op = 1;
1202
 
1203
      if (!h)
1204
        break;
1205
      if (!m)
1206
        {
1207
          as_bad (_("')' required"));
1208
          return 1;
1209
        }
1210
 
1211
      t = h;
1212
      op->am = 1;
1213
      op->ol = 1;
1214
      /* Extract a register.  */
1215
      t++;      /* Advance pointer.  */
1216
 
1217
      if (*t != 'r' && *t != 'R')
1218
        {
1219
          as_bad (_
1220
                  ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
1221
                  l);
1222
          return 1;
1223
        }
1224
      t++;
1225
 
1226
      op->reg = *t - '0';
1227
      if (op->reg > 9 || op->reg < 0)
1228
        {
1229
          as_bad (_("unknown operator (r%s substituted as a register name"),
1230
                  t);
1231
          return 1;
1232
        }
1233
      t++;
1234
      if (*t != ')')
1235
        {
1236
          op->reg = op->reg * 10;
1237
          op->reg += *t - '0';
1238
 
1239
          if (op->reg > 15)
1240
            {
1241
              as_bad (_("unknown operator %s"), l);
1242
              return 1;
1243
            }
1244
          if (op->reg == 2)
1245
            {
1246
              as_bad (_("r2 should not be used in indexed addressing mode"));
1247
              return 1;
1248
            }
1249
 
1250
          if (*(t + 1) != ')')
1251
            {
1252
              as_bad (_("unknown operator %s"), l);
1253
              return 1;
1254
            }
1255
        }
1256
 
1257
      /* Extract constant.  */
1258
      __tl = l;
1259
      *h = 0;
1260
      op->mode = OP_EXP;
1261
      parse_exp (__tl, &(op->exp));
1262
      if (op->exp.X_op == O_constant)
1263
        {
1264
          int x = op->exp.X_add_number;
1265
 
1266
          if (x > 65535 || x < -32768)
1267
            {
1268
              as_bad (_("value out of range: %d"), x);
1269
              return 1;
1270
            }
1271
 
1272
          if (x == 0)
1273
            {
1274
              op->mode = OP_REG;
1275
              op->am = 2;
1276
              op->ol = 0;
1277
              return 0;
1278
            }
1279
        }
1280
      else if (op->exp.X_op == O_symbol)
1281
        ;
1282
      else
1283
        {
1284
          /* Redundant (yet) check.  */
1285
          if (op->exp.X_op == O_register)
1286
            as_bad
1287
              (_("Registers cannot be used as a prefix of indexed expression [%s]"), l);
1288
          else
1289
            as_bad (_("unknown expression in operand %s"), l);
1290
          return 1;
1291
        }
1292
 
1293
      return 0;
1294
    }
1295
  while (0);
1296
 
1297
  /* Register mode 'mov r1,r2'.  */
1298
  do
1299
    {
1300
      char *t = l;
1301
 
1302
      /* Operand should be a register.  */
1303
      if (*t == 'r' || *t == 'R')
1304
        {
1305
          int x = atoi (t + 1);
1306
 
1307
          if (check_reg (t + 1))
1308
            break;
1309
 
1310
          if (x < 0 || x > 15)
1311
            break;              /* Symbolic mode.  */
1312
 
1313
          op->mode = OP_REG;
1314
          op->am = 0;
1315
          op->ol = 0;
1316
          op->reg = x;
1317
          return 0;
1318
        }
1319
    }
1320
  while (0);
1321
 
1322
  /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'.  */
1323
  do
1324
    {
1325
      op->mode = OP_EXP;
1326
      op->reg = 0;               /* PC relative... be careful.  */
1327
      op->am = 1;
1328
      op->ol = 1;
1329
      __tl = l;
1330
      parse_exp (__tl, &(op->exp));
1331
      return 0;
1332
    }
1333
  while (0);
1334
 
1335
  /* Unreachable.  */
1336
  as_bad (_("unknown addressing mode for operand %s"), l);
1337
  return 1;
1338
}
1339
 
1340
 
1341
static int
1342
msp430_dstoperand (struct msp430_operand_s * op, char * l, int bin)
1343
{
1344
  int dummy;
1345
  int ret = msp430_srcoperand (op, l, bin, & dummy);
1346
 
1347
  if (ret)
1348
    return ret;
1349
 
1350
  if (op->am == 2)
1351
    {
1352
      char *__tl = "0";
1353
 
1354
      op->mode = OP_EXP;
1355
      op->am = 1;
1356
      op->ol = 1;
1357
      parse_exp (__tl, &(op->exp));
1358
 
1359
      if (op->exp.X_op != O_constant || op->exp.X_add_number != 0)
1360
        {
1361
          as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
1362
                  op->reg, op->reg);
1363
          return 1;
1364
        }
1365
      return 0;
1366
    }
1367
 
1368
  if (op->am > 1)
1369
    {
1370
      as_bad (_
1371
              ("this addressing mode is not applicable for destination operand"));
1372
      return 1;
1373
    }
1374
  return 0;
1375
}
1376
 
1377
 
1378
/* Parse instruction operands.
1379
   Return binary opcode.  */
1380
 
1381
static unsigned int
1382
msp430_operands (struct msp430_opcode_s * opcode, char * line)
1383
{
1384
  int bin = opcode->bin_opcode; /* Opcode mask.  */
1385
  int __is = 0;
1386
  char l1[MAX_OP_LEN], l2[MAX_OP_LEN];
1387
  char *frag;
1388
  int where;
1389
  struct msp430_operand_s op1, op2;
1390
  int res = 0;
1391
  static short ZEROS = 0;
1392
  int byte_op, imm_op;
1393
 
1394
  /* Opcode is the one from opcodes table
1395
     line contains something like
1396
     [.w] @r2+, 5(R1)
1397
     or
1398
     .b @r2+, 5(R1).  */
1399
 
1400
  /* Check if byte or word operation.  */
1401
  if (*line == '.' && TOLOWER (*(line + 1)) == 'b')
1402
    {
1403
      bin |= BYTE_OPERATION;
1404
      byte_op = 1;
1405
    }
1406
  else
1407
    byte_op = 0;
1408
 
1409
  /* skip .[bwBW].  */
1410
  while (! ISSPACE (*line) && *line)
1411
    line++;
1412
 
1413
  if (opcode->insn_opnumb && (!*line || *line == '\n'))
1414
    {
1415
      as_bad (_("instruction %s requires %d operand(s)"),
1416
              opcode->name, opcode->insn_opnumb);
1417
      return 0;
1418
    }
1419
 
1420
  memset (l1, 0, sizeof (l1));
1421
  memset (l2, 0, sizeof (l2));
1422
  memset (&op1, 0, sizeof (op1));
1423
  memset (&op2, 0, sizeof (op2));
1424
 
1425
  imm_op = 0;
1426
 
1427
  switch (opcode->fmt)
1428
    {
1429
    case 0:                      /* Emulated.  */
1430
      switch (opcode->insn_opnumb)
1431
        {
1432
        case 0:
1433
          /* Set/clear bits instructions.  */
1434
          __is = 2;
1435
          frag = frag_more (__is);
1436
          bfd_putl16 ((bfd_vma) bin, frag);
1437
          dwarf2_emit_insn (__is);
1438
          break;
1439
        case 1:
1440
          /* Something which works with destination operand.  */
1441
          line = extract_operand (line, l1, sizeof (l1));
1442
          res = msp430_dstoperand (&op1, l1, opcode->bin_opcode);
1443
          if (res)
1444
            break;
1445
 
1446
          bin |= (op1.reg | (op1.am << 7));
1447
          __is = 1 + op1.ol;
1448
          frag = frag_more (2 * __is);
1449
          where = frag - frag_now->fr_literal;
1450
          bfd_putl16 ((bfd_vma) bin, frag);
1451
          dwarf2_emit_insn (2 * __is);
1452
 
1453
          if (op1.mode == OP_EXP)
1454
            {
1455
              where += 2;
1456
              bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1457
 
1458
              if (op1.reg)
1459
                fix_new_exp (frag_now, where, 2,
1460
                             &(op1.exp), FALSE, CHECK_RELOC_MSP430);
1461
              else
1462
                fix_new_exp (frag_now, where, 2,
1463
                             &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1464
            }
1465
          break;
1466
 
1467
        case 2:
1468
          {
1469
            /* Shift instruction.  */
1470
            line = extract_operand (line, l1, sizeof (l1));
1471
            strncpy (l2, l1, sizeof (l2));
1472
            l2[sizeof (l2) - 1] = '\0';
1473
            res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
1474
            res += msp430_dstoperand (&op2, l2, opcode->bin_opcode);
1475
 
1476
            if (res)
1477
              break;    /* An error occurred.  All warnings were done before.  */
1478
 
1479
            bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
1480
 
1481
            __is = 1 + op1.ol + op2.ol; /* insn size in words.  */
1482
            frag = frag_more (2 * __is);
1483
            where = frag - frag_now->fr_literal;
1484
            bfd_putl16 ((bfd_vma) bin, frag);
1485
            dwarf2_emit_insn (2 * __is);
1486
 
1487
            if (op1.mode == OP_EXP)
1488
              {
1489
                where += 2;     /* Advance 'where' as we do not know _where_.  */
1490
                bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1491
 
1492
                if (op1.reg || (op1.reg == 0 && op1.am == 3))    /* Not PC relative.  */
1493
                  fix_new_exp (frag_now, where, 2,
1494
                               &(op1.exp), FALSE, CHECK_RELOC_MSP430);
1495
                else
1496
                  fix_new_exp (frag_now, where, 2,
1497
                               &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1498
              }
1499
 
1500
            if (op2.mode == OP_EXP)
1501
              {
1502
                imm_op = 0;
1503
                bfd_putl16 ((bfd_vma) ZEROS, frag + 2 + ((__is == 3) ? 2 : 0));
1504
 
1505
                if (op2.reg)    /* Not PC relative.  */
1506
                  fix_new_exp (frag_now, where + 2, 2,
1507
                               &(op2.exp), FALSE, CHECK_RELOC_MSP430);
1508
                else
1509
                  fix_new_exp (frag_now, where + 2, 2,
1510
                               &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1511
              }
1512
            break;
1513
          }
1514
        case 3:
1515
          /* Branch instruction => mov dst, r0.  */
1516
          line = extract_operand (line, l1, sizeof (l1));
1517
 
1518
          res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
1519
          if (res)
1520
            break;
1521
 
1522
          byte_op = 0;
1523
          imm_op = 0;
1524
 
1525
          bin |= ((op1.reg << 8) | (op1.am << 4));
1526
          __is = 1 + op1.ol;
1527
          frag = frag_more (2 * __is);
1528
          where = frag - frag_now->fr_literal;
1529
          bfd_putl16 ((bfd_vma) bin, frag);
1530
          dwarf2_emit_insn (2 * __is);
1531
 
1532
          if (op1.mode == OP_EXP)
1533
            {
1534
              where += 2;
1535
              bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1536
 
1537
              if (op1.reg || (op1.reg == 0 && op1.am == 3))
1538
                fix_new_exp (frag_now, where, 2,
1539
                             &(op1.exp), FALSE, CHECK_RELOC_MSP430);
1540
              else
1541
                fix_new_exp (frag_now, where, 2,
1542
                             &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1543
            }
1544
          break;
1545
        }
1546
      break;
1547
 
1548
    case 1:                     /* Format 1, double operand.  */
1549
      line = extract_operand (line, l1, sizeof (l1));
1550
      line = extract_operand (line, l2, sizeof (l2));
1551
      res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
1552
      res += msp430_dstoperand (&op2, l2, opcode->bin_opcode);
1553
 
1554
      if (res)
1555
        break;                  /* Error occurred.  All warnings were done before.  */
1556
 
1557
      bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
1558
 
1559
      __is = 1 + op1.ol + op2.ol;       /* insn size in words.  */
1560
      frag = frag_more (2 * __is);
1561
      where = frag - frag_now->fr_literal;
1562
      bfd_putl16 ((bfd_vma) bin, frag);
1563
      dwarf2_emit_insn (2 * __is);
1564
 
1565
      if (op1.mode == OP_EXP)
1566
        {
1567
          where += 2;           /* Advance where as we do not know _where_.  */
1568
          bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1569
 
1570
          if (op1.reg || (op1.reg == 0 && op1.am == 3))  /* Not PC relative.  */
1571
            fix_new_exp (frag_now, where, 2,
1572
                         &(op1.exp), FALSE, CHECK_RELOC_MSP430);
1573
          else
1574
            fix_new_exp (frag_now, where, 2,
1575
                         &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1576
        }
1577
 
1578
      if (op2.mode == OP_EXP)
1579
        {
1580
          imm_op = 0;
1581
          bfd_putl16 ((bfd_vma) ZEROS, frag + 2 + ((__is == 3) ? 2 : 0));
1582
 
1583
          if (op2.reg)          /* Not PC relative.  */
1584
            fix_new_exp (frag_now, where + 2, 2,
1585
                         &(op2.exp), FALSE, CHECK_RELOC_MSP430);
1586
          else
1587
            fix_new_exp (frag_now, where + 2, 2,
1588
                         &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1589
        }
1590
      break;
1591
 
1592
    case 2:                     /* Single-operand mostly instr.  */
1593
      if (opcode->insn_opnumb == 0)
1594
        {
1595
          /* reti instruction.  */
1596
          frag = frag_more (2);
1597
          bfd_putl16 ((bfd_vma) bin, frag);
1598
          dwarf2_emit_insn (2);
1599
          break;
1600
        }
1601
 
1602
      line = extract_operand (line, l1, sizeof (l1));
1603
      res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
1604
      if (res)
1605
        break;          /* Error in operand.  */
1606
 
1607
      bin |= op1.reg | (op1.am << 4);
1608
      __is = 1 + op1.ol;
1609
      frag = frag_more (2 * __is);
1610
      where = frag - frag_now->fr_literal;
1611
      bfd_putl16 ((bfd_vma) bin, frag);
1612
      dwarf2_emit_insn (2 * __is);
1613
 
1614
      if (op1.mode == OP_EXP)
1615
        {
1616
          bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1617
 
1618
          if (op1.reg || (op1.reg == 0 && op1.am == 3))  /* Not PC relative.  */
1619
            fix_new_exp (frag_now, where + 2, 2,
1620
                         &(op1.exp), FALSE, CHECK_RELOC_MSP430);
1621
          else
1622
            fix_new_exp (frag_now, where + 2, 2,
1623
                         &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1624
        }
1625
      break;
1626
 
1627
    case 3:                     /* Conditional jumps instructions.  */
1628
      line = extract_operand (line, l1, sizeof (l1));
1629
      /* l1 is a label.  */
1630
      if (l1[0])
1631
        {
1632
          char *m = l1;
1633
          expressionS exp;
1634
 
1635
          if (*m == '$')
1636
            m++;
1637
 
1638
          parse_exp (m, &exp);
1639
          frag = frag_more (2); /* Instr size is 1 word.  */
1640
 
1641
          /* In order to handle something like:
1642
 
1643
             and #0x8000, r5
1644
             tst r5
1645
             jz   4     ;       skip next 4 bytes
1646
             inv r5
1647
             inc r5
1648
             nop        ;       will jump here if r5 positive or zero
1649
 
1650
             jCOND      -n      ;assumes jump n bytes backward:
1651
 
1652
             mov r5,r6
1653
             jmp -2
1654
 
1655
             is equal to:
1656
             lab:
1657
             mov r5,r6
1658
             jmp lab
1659
 
1660
             jCOND      $n      ; jump from PC in either direction.  */
1661
 
1662
          if (exp.X_op == O_constant)
1663
            {
1664
              int x = exp.X_add_number;
1665
 
1666
              if (x & 1)
1667
                {
1668
                  as_warn (_("Even number required. Rounded to %d"), x + 1);
1669
                  x++;
1670
                }
1671
 
1672
              if ((*l1 == '$' && x > 0) || x < 0)
1673
                x -= 2;
1674
 
1675
              x >>= 1;
1676
 
1677
              if (x > 512 || x < -511)
1678
                {
1679
                  as_bad (_("Wrong displacement  %d"), x << 1);
1680
                  break;
1681
                }
1682
 
1683
              bin |= x & 0x3ff;
1684
              bfd_putl16 ((bfd_vma) bin, frag);
1685
            }
1686
          else if (exp.X_op == O_symbol && *l1 != '$')
1687
            {
1688
              where = frag - frag_now->fr_literal;
1689
              fix_new_exp (frag_now, where, 2,
1690
                           &exp, TRUE, BFD_RELOC_MSP430_10_PCREL);
1691
 
1692
              bfd_putl16 ((bfd_vma) bin, frag);
1693
            }
1694
          else if (*l1 == '$')
1695
            {
1696
              as_bad (_("instruction requires label sans '$'"));
1697
            }
1698
          else
1699
            {
1700
              as_bad (_
1701
                      ("instruction requires label or value in range -511:512"));
1702
            }
1703
          dwarf2_emit_insn (2 * __is);
1704
          break;
1705
        }
1706
      else
1707
        {
1708
          as_bad (_("instruction requires label"));
1709
          break;
1710
        }
1711
      break;
1712
 
1713
    case 4:     /* Extended jumps.  */
1714
      if (!msp430_enable_polys)
1715
        {
1716
          as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
1717
          break;
1718
        }
1719
 
1720
      line = extract_operand (line, l1, sizeof (l1));
1721
      if (l1[0])
1722
        {
1723
          char *m = l1;
1724
          expressionS exp;
1725
 
1726
          /* Ignore absolute addressing. make it PC relative anyway.  */
1727
          if (*m == '#' || *m == '$')
1728
            m++;
1729
 
1730
          parse_exp (m, & exp);
1731
          if (exp.X_op == O_symbol)
1732
            {
1733
              /* Relaxation required.  */
1734
              struct rcodes_s rc = msp430_rcodes[opcode->insn_opnumb];
1735
 
1736
              /* The parameter to dwarf2_emit_insn is actually the offset to the start
1737
                 of the insn from the fix piece of instruction that was emitted.
1738
                 Since next fragments may have variable size we tie debug info
1739
                 to the beginning of the instruction. */
1740
              frag = frag_more (8);
1741
              dwarf2_emit_insn (0);
1742
              bfd_putl16 ((bfd_vma) rc.sop, frag);
1743
              frag = frag_variant (rs_machine_dependent, 8, 2,
1744
                                   ENCODE_RELAX (rc.lpos, STATE_BITS10), /* Wild guess.  */
1745
                                   exp.X_add_symbol,
1746
                                   0,    /* Offset is zero if jump dist less than 1K.  */
1747
                                   (char *) frag);
1748
              break;
1749
            }
1750
        }
1751
 
1752
      as_bad (_("instruction requires label"));
1753
      break;
1754
 
1755
    case 5:     /* Emulated extended branches.  */
1756
      if (!msp430_enable_polys)
1757
        {
1758
          as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
1759
          break;
1760
        }
1761
      line = extract_operand (line, l1, sizeof (l1));
1762
      if (l1[0])
1763
        {
1764
          char * m = l1;
1765
          expressionS exp;
1766
 
1767
          /* Ignore absolute addressing. make it PC relative anyway.  */
1768
          if (*m == '#' || *m == '$')
1769
            m++;
1770
 
1771
          parse_exp (m, & exp);
1772
          if (exp.X_op == O_symbol)
1773
            {
1774
              /* Relaxation required.  */
1775
              struct hcodes_s hc = msp430_hcodes[opcode->insn_opnumb];
1776
 
1777
              frag = frag_more (8);
1778
              dwarf2_emit_insn (0);
1779
              bfd_putl16 ((bfd_vma) hc.op0, frag);
1780
              bfd_putl16 ((bfd_vma) hc.op1, frag+2);
1781
 
1782
              frag = frag_variant (rs_machine_dependent, 8, 2,
1783
                                   ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10), /* Wild guess.  */
1784
                                   exp.X_add_symbol,
1785
                                   0,    /* Offset is zero if jump dist less than 1K.  */
1786
                                   (char *) frag);
1787
              break;
1788
            }
1789
        }
1790
 
1791
      as_bad (_("instruction requires label"));
1792
      break;
1793
 
1794
    default:
1795
      as_bad (_("Illegal instruction or not implemented opcode."));
1796
    }
1797
 
1798
  input_line_pointer = line;
1799
  return 0;
1800
}
1801
 
1802
void
1803
md_assemble (char * str)
1804
{
1805
  struct msp430_opcode_s * opcode;
1806
  char cmd[32];
1807
  unsigned int i = 0;
1808
 
1809
  str = skip_space (str);       /* Skip leading spaces.  */
1810
  str = extract_cmd (str, cmd, sizeof (cmd));
1811
 
1812
  while (cmd[i] && i < sizeof (cmd))
1813
    {
1814
      char a = TOLOWER (cmd[i]);
1815
      cmd[i] = a;
1816
      i++;
1817
    }
1818
 
1819
  if (!cmd[0])
1820
    {
1821
      as_bad (_("can't find opcode "));
1822
      return;
1823
    }
1824
 
1825
  opcode = (struct msp430_opcode_s *) hash_find (msp430_hash, cmd);
1826
 
1827
  if (opcode == NULL)
1828
    {
1829
      as_bad (_("unknown opcode `%s'"), cmd);
1830
      return;
1831
    }
1832
 
1833
  {
1834
    char *__t = input_line_pointer;
1835
 
1836
    msp430_operands (opcode, str);
1837
    input_line_pointer = __t;
1838
  }
1839
}
1840
 
1841
/* GAS will call this function for each section at the end of the assembly,
1842
   to permit the CPU backend to adjust the alignment of a section.  */
1843
 
1844
valueT
1845
md_section_align (asection * seg, valueT addr)
1846
{
1847
  int align = bfd_get_section_alignment (stdoutput, seg);
1848
 
1849
  return ((addr + (1 << align) - 1) & (-1 << align));
1850
}
1851
 
1852
/* If you define this macro, it should return the offset between the
1853
   address of a PC relative fixup and the position from which the PC
1854
   relative adjustment should be made.  On many processors, the base
1855
   of a PC relative instruction is the next instruction, so this
1856
   macro would return the length of an instruction.  */
1857
 
1858
long
1859
md_pcrel_from_section (fixS * fixp, segT sec)
1860
{
1861
  if (fixp->fx_addsy != (symbolS *) NULL
1862
      && (!S_IS_DEFINED (fixp->fx_addsy)
1863
          || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
1864
    return 0;
1865
 
1866
  return fixp->fx_frag->fr_address + fixp->fx_where;
1867
}
1868
 
1869
/* Replaces standard TC_FORCE_RELOCATION_LOCAL.
1870
   Now it handles the situation when relocations
1871
   have to be passed to linker. */
1872
int
1873
msp430_force_relocation_local(fixS *fixp)
1874
{
1875
  if (msp430_enable_polys
1876
        && !msp430_enable_relax)
1877
    return 1;
1878
  else
1879
    return (!fixp->fx_pcrel
1880
            || generic_force_reloc(fixp));
1881
}
1882
 
1883
 
1884
/* GAS will call this for each fixup.  It should store the correct
1885
   value in the object file.  */
1886
void
1887
md_apply_fix (fixS * fixp, valueT * valuep, segT seg)
1888
{
1889
  unsigned char * where;
1890
  unsigned long insn;
1891
  long value;
1892
 
1893
  if (fixp->fx_addsy == (symbolS *) NULL)
1894
    {
1895
      value = *valuep;
1896
      fixp->fx_done = 1;
1897
    }
1898
  else if (fixp->fx_pcrel)
1899
    {
1900
      segT s = S_GET_SEGMENT (fixp->fx_addsy);
1901
 
1902
      if (fixp->fx_addsy && (s == seg || s == absolute_section))
1903
        {
1904
          /* FIXME: We can appear here only in case if we perform a pc
1905
             relative jump to the label which is i) global, ii) locally
1906
             defined or this is a jump to an absolute symbol.
1907
             If this is an absolute symbol -- everything is OK.
1908
             If this is a global label, we've got a symbol value defined
1909
             twice:
1910
               1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
1911
                  from this section start
1912
               2. *valuep will contain the real offset from jump insn to the
1913
                  label
1914
             So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
1915
             will be incorrect. Therefore remove s_get_value.  */
1916
          value = /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep;
1917
          fixp->fx_done = 1;
1918
        }
1919
      else
1920
        value = *valuep;
1921
    }
1922
  else
1923
    {
1924
      value = fixp->fx_offset;
1925
 
1926
      if (fixp->fx_subsy != (symbolS *) NULL)
1927
        {
1928
          if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
1929
            {
1930
              value -= S_GET_VALUE (fixp->fx_subsy);
1931
              fixp->fx_done = 1;
1932
            }
1933
          else
1934
            {
1935
              /* We don't actually support subtracting a symbol.  */
1936
              as_bad_where (fixp->fx_file, fixp->fx_line,
1937
                            _("expression too complex"));
1938
            }
1939
        }
1940
    }
1941
 
1942
  fixp->fx_no_overflow = 1;
1943
 
1944
  /* if polymorphs are enabled and relax disabled.
1945
     do not kill any relocs and pass them to linker. */
1946
  if (msp430_enable_polys
1947
      && !msp430_enable_relax)
1948
    {
1949
      if (!fixp->fx_addsy || (fixp->fx_addsy
1950
          && S_GET_SEGMENT (fixp->fx_addsy) == absolute_section))
1951
        fixp->fx_done = 1;      /* It is ok to kill 'abs' reloc.  */
1952
      else
1953
        fixp->fx_done = 0;
1954
    }
1955
 
1956
  if (fixp->fx_done)
1957
    {
1958
      /* Fetch the instruction, insert the fully resolved operand
1959
         value, and stuff the instruction back again.  */
1960
 
1961
      where = (unsigned char *) fixp->fx_frag->fr_literal + fixp->fx_where;
1962
 
1963
      insn = bfd_getl16 (where);
1964
 
1965
      switch (fixp->fx_r_type)
1966
        {
1967
        case BFD_RELOC_MSP430_10_PCREL:
1968
          if (value & 1)
1969
            as_bad_where (fixp->fx_file, fixp->fx_line,
1970
                          _("odd address operand: %ld"), value);
1971
 
1972
          /* Jumps are in words.  */
1973
          value >>= 1;
1974
          --value;              /* Correct PC.  */
1975
 
1976
          if (value < -512 || value > 511)
1977
            as_bad_where (fixp->fx_file, fixp->fx_line,
1978
                          _("operand out of range: %ld"), value);
1979
 
1980
          value &= 0x3ff;       /* get rid of extended sign */
1981
          bfd_putl16 ((bfd_vma) (value | insn), where);
1982
          break;
1983
 
1984
        case BFD_RELOC_MSP430_RL_PCREL:
1985
        case BFD_RELOC_MSP430_16_PCREL:
1986
          if (value & 1)
1987
            as_bad_where (fixp->fx_file, fixp->fx_line,
1988
                          _("odd address operand: %ld"), value);
1989
 
1990
          /* Nothing to be corrected here.  */
1991
          if (value < -32768 || value > 65536)
1992
            as_bad_where (fixp->fx_file, fixp->fx_line,
1993
                          _("operand out of range: %ld"), value);
1994
 
1995
          value &= 0xffff;      /* Get rid of extended sign.  */
1996
          bfd_putl16 ((bfd_vma) value, where);
1997
          break;
1998
 
1999
        case BFD_RELOC_MSP430_16_PCREL_BYTE:
2000
          /* Nothing to be corrected here.  */
2001
          if (value < -32768 || value > 65536)
2002
            as_bad_where (fixp->fx_file, fixp->fx_line,
2003
                          _("operand out of range: %ld"), value);
2004
 
2005
          value &= 0xffff;      /* Get rid of extended sign.  */
2006
          bfd_putl16 ((bfd_vma) value, where);
2007
          break;
2008
 
2009
        case BFD_RELOC_32:
2010
          bfd_putl16 ((bfd_vma) value, where);
2011
          break;
2012
 
2013
        case BFD_RELOC_MSP430_16:
2014
        case BFD_RELOC_16:
2015
        case BFD_RELOC_MSP430_16_BYTE:
2016
          value &= 0xffff;
2017
          bfd_putl16 ((bfd_vma) value, where);
2018
          break;
2019
 
2020
        default:
2021
          as_fatal (_("line %d: unknown relocation type: 0x%x"),
2022
                    fixp->fx_line, fixp->fx_r_type);
2023
          break;
2024
        }
2025
    }
2026
  else
2027
    {
2028
      fixp->fx_addnumber = value;
2029
    }
2030
}
2031
 
2032
/* GAS will call this to generate a reloc, passing the resulting reloc
2033
   to `bfd_install_relocation'.  This currently works poorly, as
2034
   `bfd_install_relocation' often does the wrong thing, and instances of
2035
   `tc_gen_reloc' have been written to work around the problems, which
2036
   in turns makes it difficult to fix `bfd_install_relocation'.  */
2037
 
2038
/* If while processing a fixup, a reloc really needs to be created
2039
   then it is done here.  */
2040
 
2041
arelent *
2042
tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
2043
{
2044
  arelent * reloc;
2045
 
2046
  reloc = xmalloc (sizeof (arelent));
2047
 
2048
  reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
2049
  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2050
 
2051
  reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
2052
  reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
2053
  if (reloc->howto == (reloc_howto_type *) NULL)
2054
    {
2055
      as_bad_where (fixp->fx_file, fixp->fx_line,
2056
                    _("reloc %d not supported by object file format"),
2057
                    (int) fixp->fx_r_type);
2058
      return NULL;
2059
    }
2060
 
2061
  if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
2062
      || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
2063
    reloc->address = fixp->fx_offset;
2064
 
2065
  reloc->addend = fixp->fx_offset;
2066
 
2067
  return reloc;
2068
}
2069
 
2070
int
2071
md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
2072
                               asection * segment_type ATTRIBUTE_UNUSED)
2073
{
2074
  if (fragP->fr_symbol && S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
2075
    {
2076
      /* This is a jump -> pcrel mode. Nothing to do much here.
2077
         Return value == 2.  */
2078
      fragP->fr_subtype =
2079
          ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_BITS10);
2080
    }
2081
  else if (fragP->fr_symbol)
2082
    {
2083
      /* Its got a segment, but its not ours.   Even if fr_symbol is in
2084
         an absolute segment, we don't know a displacement until we link
2085
         object files. So it will always be long. This also applies to
2086
         labels in a subsegment of current. Liker may relax it to short
2087
         jump later. Return value == 8.  */
2088
      fragP->fr_subtype =
2089
          ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_WORD);
2090
    }
2091
  else
2092
    {
2093
      /* We know the abs value. may be it is a jump to fixed address.
2094
         Impossible in our case, cause all constants already handled. */
2095
      fragP->fr_subtype =
2096
          ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_UNDEF);
2097
    }
2098
 
2099
  return md_relax_table[fragP->fr_subtype].rlx_length;
2100
}
2101
 
2102
void
2103
md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
2104
                 asection * sec ATTRIBUTE_UNUSED,
2105
                 fragS * fragP)
2106
{
2107
  char * where = 0;
2108
  int rela = -1;
2109
  int i;
2110
  struct rcodes_s * cc = NULL;
2111
  struct hcodes_s * hc = NULL;
2112
 
2113
  switch (fragP->fr_subtype)
2114
    {
2115
    case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_BITS10):
2116
    case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_BITS10):
2117
    case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_BITS10):
2118
      /* We do not have to convert anything here.
2119
         Just apply a fix.  */
2120
      rela = BFD_RELOC_MSP430_10_PCREL;
2121
      break;
2122
 
2123
    case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_WORD):
2124
    case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_UNDEF):
2125
      /* Convert uncond branch jmp lab -> br lab.  */
2126
      cc = & msp430_rcodes[7];
2127
      where = fragP->fr_literal + fragP->fr_fix;
2128
      bfd_putl16 (cc->lop0, where);
2129
      rela = BFD_RELOC_MSP430_RL_PCREL;
2130
      fragP->fr_fix += 2;
2131
      break;
2132
 
2133
    case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_WORD):
2134
    case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_UNDEF):
2135
      {
2136
        /* Other simple branches.  */
2137
        int insn = bfd_getl16 (fragP->fr_opcode);
2138
 
2139
        insn &= 0xffff;
2140
        /* Find actual instruction.  */
2141
        for (i = 0; i < 7 && !cc; i++)
2142
          if (msp430_rcodes[i].sop == insn)
2143
            cc = & msp430_rcodes[i];
2144
        if (!cc || !cc->name)
2145
          as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
2146
                    __FUNCTION__, (long) insn);
2147
        where = fragP->fr_literal + fragP->fr_fix;
2148
        bfd_putl16 (cc->lop0, where);
2149
        bfd_putl16 (cc->lop1, where + 2);
2150
        rela = BFD_RELOC_MSP430_RL_PCREL;
2151
        fragP->fr_fix += 4;
2152
      }
2153
      break;
2154
 
2155
    case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_WORD):
2156
    case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_UNDEF):
2157
      cc = & msp430_rcodes[6];
2158
      where = fragP->fr_literal + fragP->fr_fix;
2159
      bfd_putl16 (cc->lop0, where);
2160
      bfd_putl16 (cc->lop1, where + 2);
2161
      bfd_putl16 (cc->lop2, where + 4);
2162
      rela = BFD_RELOC_MSP430_RL_PCREL;
2163
      fragP->fr_fix += 6;
2164
      break;
2165
 
2166
    case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10):
2167
      {
2168
        int insn = bfd_getl16 (fragP->fr_opcode + 2);
2169
 
2170
        insn &= 0xffff;
2171
        for (i = 0; i < 4 && !hc; i++)
2172
          if (msp430_hcodes[i].op1 == insn)
2173
            hc = &msp430_hcodes[i];
2174
        if (!hc || !hc->name)
2175
          as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
2176
              __FUNCTION__, (long) insn);
2177
        rela = BFD_RELOC_MSP430_10_PCREL;
2178
        /* Apply a fix for a first label if necessary.
2179
           another fix will be applied to the next word of insn anyway.  */
2180
        if (hc->tlab == 2)
2181
          fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2182
              fragP->fr_offset, TRUE, rela);
2183
        fragP->fr_fix += 2;
2184
      }
2185
 
2186
      break;
2187
 
2188
    case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_WORD):
2189
    case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_UNDEF):
2190
      {
2191
        int insn = bfd_getl16 (fragP->fr_opcode + 2);
2192
 
2193
        insn &= 0xffff;
2194
        for (i = 0; i < 4 && !hc; i++)
2195
          if (msp430_hcodes[i].op1 == insn)
2196
            hc = & msp430_hcodes[i];
2197
        if (!hc || !hc->name)
2198
          as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
2199
              __FUNCTION__, (long) insn);
2200
        rela = BFD_RELOC_MSP430_RL_PCREL;
2201
        where = fragP->fr_literal + fragP->fr_fix;
2202
        bfd_putl16 (hc->lop0, where);
2203
        bfd_putl16 (hc->lop1, where + 2);
2204
        bfd_putl16 (hc->lop2, where + 4);
2205
        fragP->fr_fix += 6;
2206
      }
2207
      break;
2208
 
2209
    default:
2210
      as_fatal (_("internal inconsistency problem in %s:  %lx"),
2211
                __FUNCTION__, (long) fragP->fr_subtype);
2212
      break;
2213
    }
2214
 
2215
  /* Now apply fix.  */
2216
  fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2217
           fragP->fr_offset, TRUE, rela);
2218
  /* Just fixed 2 bytes.  */
2219
  fragP->fr_fix += 2;
2220
}
2221
 
2222
/* Relax fragment. Mostly stolen from hc11 and mcore
2223
   which arches I think I know.  */
2224
 
2225
long
2226
msp430_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS * fragP,
2227
                   long stretch ATTRIBUTE_UNUSED)
2228
{
2229
  long growth;
2230
  offsetT aim = 0;
2231
  symbolS *symbolP;
2232
  const relax_typeS *this_type;
2233
  const relax_typeS *start_type;
2234
  relax_substateT next_state;
2235
  relax_substateT this_state;
2236
  const relax_typeS *table = md_relax_table;
2237
 
2238
  /* Nothing to be done if the frag has already max size.  */
2239
  if (RELAX_STATE (fragP->fr_subtype) == STATE_UNDEF
2240
      || RELAX_STATE (fragP->fr_subtype) == STATE_WORD)
2241
    return 0;
2242
 
2243
  if (RELAX_STATE (fragP->fr_subtype) == STATE_BITS10)
2244
    {
2245
      symbolP = fragP->fr_symbol;
2246
      if (symbol_resolved_p (symbolP))
2247
        as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
2248
                  __FUNCTION__);
2249
      /* We know the offset. calculate a distance.  */
2250
      aim = S_GET_VALUE (symbolP) - fragP->fr_address - fragP->fr_fix;
2251
    }
2252
 
2253
  if (!msp430_enable_relax)
2254
    {
2255
      /* Relaxation is not enabled. So, make all jump as long ones
2256
         by setting 'aim' to quite high value. */
2257
      aim = 0x7fff;
2258
    }
2259
 
2260
  this_state = fragP->fr_subtype;
2261
  start_type = this_type = table + this_state;
2262
 
2263
  if (aim < 0)
2264
    {
2265
      /* Look backwards.  */
2266
      for (next_state = this_type->rlx_more; next_state;)
2267
        if (aim >= this_type->rlx_backward || !this_type->rlx_backward)
2268
          next_state = 0;
2269
        else
2270
          {
2271
            /* Grow to next state.  */
2272
            this_state = next_state;
2273
            this_type = table + this_state;
2274
            next_state = this_type->rlx_more;
2275
          }
2276
    }
2277
  else
2278
    {
2279
      /* Look forwards.  */
2280
      for (next_state = this_type->rlx_more; next_state;)
2281
        if (aim <= this_type->rlx_forward || !this_type->rlx_forward)
2282
          next_state = 0;
2283
        else
2284
          {
2285
            /* Grow to next state.  */
2286
            this_state = next_state;
2287
            this_type = table + this_state;
2288
            next_state = this_type->rlx_more;
2289
          }
2290
    }
2291
 
2292
  growth = this_type->rlx_length - start_type->rlx_length;
2293
  if (growth != 0)
2294
    fragP->fr_subtype = this_state;
2295
  return growth;
2296
}

powered by: WebSVN 2.1.0

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