gdb/gdbserver/
[deliverable/binutils-gdb.git] / gas / config / tc-msp430.c
CommitLineData
2469cfa2
NC
1/* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
2
13761a11 3 Copyright (C) 2002-2013 Free Software Foundation, Inc.
2469cfa2
NC
4 Contributed by Dmitry Diky <diwil@mail.ru>
5
6 This file is part of GAS, the GNU Assembler.
7
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
ec2655a6 10 the Free Software Foundation; either version 3, or (at your option)
2469cfa2
NC
11 any later version.
12
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to
4b4da160
NC
20 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
21 Boston, MA 02110-1301, USA. */
2469cfa2 22
df7b86aa 23#include "as.h"
2469cfa2 24#include <limits.h>
2469cfa2 25#define PUSH_1X_WORKAROUND
2469cfa2
NC
26#include "subsegs.h"
27#include "opcode/msp430.h"
28#include "safe-ctype.h"
2a9a06c1 29#include "dwarf2dbg.h"
13761a11 30#include "elf/msp430.h"
2469cfa2 31
79cf5950 32/* We will disable polymorphs by default because it is dangerous.
708587a4 33 The potential problem here is the following: assume we got the
77592908
DD
34 following code:
35
36 jump .l1
37 nop
38 jump subroutine ; external symbol
39 .l1:
40 nop
41 ret
13761a11 42
77592908
DD
43 In case of assembly time relaxation we'll get:
44 0: jmp .l1 <.text +0x08> (reloc deleted)
45 2: nop
46 4: br subroutine
47 .l1:
48 8: nop
49 10: ret
50
79cf5950
NC
51 If the 'subroutine' is within +-1024 bytes range then linker
52 will produce:
77592908
DD
53 0: jmp .text +0x08
54 2: nop
55 4: jmp subroutine
56 .l1:
57 6: nop
58 8: ret ; 'jmp .text +0x08' will land here. WRONG!!!
59
77592908 60 The workaround is the following:
79cf5950 61 1. Declare global var enable_polymorphs which set to 1 via option -mp.
77592908
DD
62 2. Declare global var enable_relax which set to 1 via option -mQ.
63
64 If polymorphs are enabled, and relax isn't, treat all jumps as long jumps,
65 do not delete any relocs and leave them for linker.
13761a11 66
79cf5950 67 If relax is enabled, relax at assembly time and kill relocs as necessary. */
77592908
DD
68
69int msp430_enable_relax;
70int msp430_enable_polys;
71
13761a11
NC
72/* Set linkrelax here to avoid fixups in most sections. */
73int linkrelax = 1;
74
f5c7edf4
AM
75/* GCC uses the some condition codes which we'll
76 implement as new polymorph instructions.
13761a11 77
f5c7edf4
AM
78 COND EXPL SHORT JUMP LONG JUMP
79 ===============================================
80 eq == jeq jne +4; br lab
81 ne != jne jeq +4; br lab
82
83 ltn honours no-overflow flag
84 ltn < jn jn +2; jmp +4; br lab
85
13761a11 86 lt < jl jge +4; br lab
f5c7edf4
AM
87 ltu < jlo lhs +4; br lab
88 le <= see below
89 leu <= see below
90
91 gt > see below
92 gtu > see below
93 ge >= jge jl +4; br lab
94 geu >= jhs jlo +4; br lab
95 ===============================================
96
97 Therefore, new opcodes are (BranchEQ -> beq; and so on...)
98 beq,bne,blt,bltn,bltu,bge,bgeu
13761a11
NC
99 'u' means unsigned compares
100
f5c7edf4
AM
101 Also, we add 'jump' instruction:
102 jump UNCOND -> jmp br lab
103
104 They will have fmt == 4, and insn_opnumb == number of instruction. */
105
13761a11 106struct rcodes_s
f5c7edf4
AM
107{
108 char * name;
109 int index; /* Corresponding insn_opnumb. */
110 int sop; /* Opcode if jump length is short. */
111 long lpos; /* Label position. */
112 long lop0; /* Opcode 1 _word_ (16 bits). */
113 long lop1; /* Opcode second word. */
114 long lop2; /* Opcode third word. */
115};
116
117#define MSP430_RLC(n,i,sop,o1) \
118 {#n, i, sop, 2, (o1 + 2), 0x4010, 0}
119
13761a11 120static struct rcodes_s msp430_rcodes[] =
f5c7edf4
AM
121{
122 MSP430_RLC (beq, 0, 0x2400, 0x2000),
123 MSP430_RLC (bne, 1, 0x2000, 0x2400),
124 MSP430_RLC (blt, 2, 0x3800, 0x3400),
125 MSP430_RLC (bltu, 3, 0x2800, 0x2c00),
126 MSP430_RLC (bge, 4, 0x3400, 0x3800),
127 MSP430_RLC (bgeu, 5, 0x2c00, 0x2800),
128 {"bltn", 6, 0x3000, 3, 0x3000 + 1, 0x3c00 + 2,0x4010},
129 {"jump", 7, 0x3c00, 1, 0x4010, 0, 0},
130 {0,0,0,0,0,0,0}
131};
f5c7edf4 132
13761a11
NC
133#undef MSP430_RLC
134#define MSP430_RLC(n,i,sop,o1) \
135 {#n, i, sop, 2, (o1 + 2), 0x0030, 0}
136
137static struct rcodes_s msp430x_rcodes[] =
138{
139 MSP430_RLC (beq, 0, 0x2400, 0x2000),
140 MSP430_RLC (bne, 1, 0x2000, 0x2400),
141 MSP430_RLC (blt, 2, 0x3800, 0x3400),
142 MSP430_RLC (bltu, 3, 0x2800, 0x2c00),
143 MSP430_RLC (bge, 4, 0x3400, 0x3800),
144 MSP430_RLC (bgeu, 5, 0x2c00, 0x2800),
145 {"bltn", 6, 0x3000, 3, 0x0030 + 1, 0x3c00 + 2, 0x3000},
146 {"jump", 7, 0x3c00, 1, 0x0030, 0, 0},
147 {0,0,0,0,0,0,0}
148};
149#undef MSP430_RLC
f5c7edf4
AM
150
151/* More difficult than above and they have format 5.
13761a11 152
f5c7edf4
AM
153 COND EXPL SHORT LONG
154 =================================================================
155 gt > jeq +2; jge label jeq +6; jl +4; br label
156 gtu > jeq +2; jhs label jeq +6; jlo +4; br label
157 leu <= jeq label; jlo label jeq +2; jhs +4; br label
158 le <= jeq label; jl label jeq +2; jge +4; br label
159 ================================================================= */
160
13761a11 161struct hcodes_s
f5c7edf4 162{
13761a11 163 char * name;
f5c7edf4
AM
164 int index; /* Corresponding insn_opnumb. */
165 int tlab; /* Number of labels in short mode. */
166 int op0; /* Opcode for first word of short jump. */
167 int op1; /* Opcode for second word of short jump. */
168 int lop0; /* Opcodes for long jump mode. */
169 int lop1;
170 int lop2;
171};
172
13761a11 173static struct hcodes_s msp430_hcodes[] =
f5c7edf4
AM
174{
175 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x4010 },
176 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x4010 },
177 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x4010 },
178 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x4010 },
179 {0,0,0,0,0,0,0,0}
180};
181
13761a11
NC
182static struct hcodes_s msp430x_hcodes[] =
183{
184 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x0030 },
185 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x0030 },
186 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x0030 },
187 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x0030 },
188 {0,0,0,0,0,0,0,0}
189};
190
2469cfa2
NC
191const char comment_chars[] = ";";
192const char line_comment_chars[] = "#";
870074dd 193const char line_separator_chars[] = "{";
2469cfa2
NC
194const char EXP_CHARS[] = "eE";
195const char FLT_CHARS[] = "dD";
196
197/* Handle long expressions. */
198extern LITTLENUM_TYPE generic_bignum[];
199
200static struct hash_control *msp430_hash;
201
b18c562e
NC
202/* Relaxations. */
203#define STATE_UNCOND_BRANCH 1 /* jump */
204#define STATE_NOOV_BRANCH 3 /* bltn */
205#define STATE_SIMPLE_BRANCH 2 /* bne, beq, etc... */
206#define STATE_EMUL_BRANCH 4
207
208#define CNRL 2
209#define CUBL 4
210#define CNOL 8
211#define CSBL 6
212#define CEBL 4
213
214/* Length. */
215#define STATE_BITS10 1 /* wild guess. short jump */
216#define STATE_WORD 2 /* 2 bytes pc rel. addr. more */
217#define STATE_UNDEF 3 /* cannot handle this yet. convert to word mode */
218
219#define ENCODE_RELAX(what,length) (((what) << 2) + (length))
220#define RELAX_STATE(s) ((s) & 3)
221#define RELAX_LEN(s) ((s) >> 2)
222#define RELAX_NEXT(a,b) ENCODE_RELAX (a, b + 1)
223
224relax_typeS md_relax_table[] =
225{
226 /* Unused. */
227 {1, 1, 0, 0},
228 {1, 1, 0, 0},
229 {1, 1, 0, 0},
230 {1, 1, 0, 0},
231
232 /* Unconditional jump. */
233 {1, 1, 8, 5},
234 {1024, -1024, CNRL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
235 {0, 0, CUBL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_WORD)}, /* state word */
236 {1, 1, CUBL, 0}, /* state undef */
237
238 /* Simple branches. */
239 {0, 0, 8, 9},
240 {1024, -1024, CNRL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
241 {0, 0, CSBL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_WORD)}, /* state word */
242 {1, 1, CSBL, 0},
243
244 /* blt no overflow branch. */
245 {1, 1, 8, 13},
246 {1024, -1024, CNRL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
247 {0, 0, CNOL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_WORD)}, /* state word */
248 {1, 1, CNOL, 0},
249
250 /* Emulated branches. */
251 {1, 1, 8, 17},
252 {1020, -1020, CEBL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
253 {0, 0, CNOL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_WORD)}, /* state word */
254 {1, 1, CNOL, 0}
255};
256
2469cfa2 257
8cd5b113 258#define MAX_OP_LEN 256
2469cfa2 259
638d3803
NC
260typedef enum msp_isa
261{
262 MSP_ISA_430,
263 MSP_ISA_430X,
264 MSP_ISA_430Xv2
265} msp_isa;
266
2469cfa2
NC
267struct mcu_type_s
268{
638d3803
NC
269 char * name;
270 msp_isa isa;
2469cfa2
NC
271};
272
638d3803
NC
273static struct mcu_type_s mcu_types[] =
274{
275 {"msp430afe221", MSP_ISA_430},
276 {"msp430afe222", MSP_ISA_430},
277 {"msp430afe223", MSP_ISA_430},
278 {"msp430afe231", MSP_ISA_430},
279 {"msp430afe232", MSP_ISA_430},
280 {"msp430afe233", MSP_ISA_430},
281 {"msp430afe251", MSP_ISA_430},
282 {"msp430afe252", MSP_ISA_430},
283 {"msp430afe253", MSP_ISA_430},
284 {"msp430c091", MSP_ISA_430},
285 {"msp430c092", MSP_ISA_430},
286 {"msp430c111", MSP_ISA_430},
287 {"msp430c1111", MSP_ISA_430},
288 {"msp430c112", MSP_ISA_430},
289 {"msp430c1121", MSP_ISA_430},
290 {"msp430e112", MSP_ISA_430},
291 {"msp430c1331", MSP_ISA_430},
292 {"msp430c1351", MSP_ISA_430},
293 {"msp430c311s", MSP_ISA_430},
294 {"msp430c312", MSP_ISA_430},
295 {"msp430c313", MSP_ISA_430},
296 {"msp430c314", MSP_ISA_430},
297 {"msp430c315", MSP_ISA_430},
298 {"msp430c323", MSP_ISA_430},
299 {"msp430c325", MSP_ISA_430},
300 {"msp430c336", MSP_ISA_430},
301 {"msp430c337", MSP_ISA_430},
302 {"msp430c412", MSP_ISA_430},
303 {"msp430c413", MSP_ISA_430},
304 {"msp430e313", MSP_ISA_430},
305 {"msp430e315", MSP_ISA_430},
306 {"msp430e325", MSP_ISA_430},
307 {"msp430e337", MSP_ISA_430},
308 {"msp430f110", MSP_ISA_430},
309 {"msp430f1101", MSP_ISA_430},
310 {"msp430f1101a", MSP_ISA_430},
311 {"msp430f1111", MSP_ISA_430},
312 {"msp430f1111a", MSP_ISA_430},
313 {"msp430f112", MSP_ISA_430},
314 {"msp430f1121", MSP_ISA_430},
315 {"msp430f1121a", MSP_ISA_430},
316 {"msp430f1122", MSP_ISA_430},
317 {"msp430f1132", MSP_ISA_430},
318 {"msp430f122", MSP_ISA_430},
319 {"msp430f1222", MSP_ISA_430},
320 {"msp430f123", MSP_ISA_430},
321 {"msp430f1232", MSP_ISA_430},
322 {"msp430f133", MSP_ISA_430},
323 {"msp430f135", MSP_ISA_430},
324 {"msp430f147", MSP_ISA_430},
325 {"msp430f1471", MSP_ISA_430},
326 {"msp430f148", MSP_ISA_430},
327 {"msp430f1481", MSP_ISA_430},
328 {"msp430f149", MSP_ISA_430},
329 {"msp430f1491", MSP_ISA_430},
330 {"msp430f155", MSP_ISA_430},
331 {"msp430f156", MSP_ISA_430},
332 {"msp430f157", MSP_ISA_430},
333 {"msp430f1610", MSP_ISA_430},
334 {"msp430f1611", MSP_ISA_430},
335 {"msp430f1612", MSP_ISA_430},
336 {"msp430f167", MSP_ISA_430},
337 {"msp430f168", MSP_ISA_430},
338 {"msp430f169", MSP_ISA_430},
339 {"msp430f2001", MSP_ISA_430},
340 {"msp430f2002", MSP_ISA_430},
341 {"msp430f2003", MSP_ISA_430},
342 {"msp430f2011", MSP_ISA_430},
343 {"msp430f2012", MSP_ISA_430},
344 {"msp430f2013", MSP_ISA_430},
345 {"msp430f2101", MSP_ISA_430},
346 {"msp430f2111", MSP_ISA_430},
347 {"msp430f2112", MSP_ISA_430},
348 {"msp430f2121", MSP_ISA_430},
349 {"msp430f2122", MSP_ISA_430},
350 {"msp430f2131", MSP_ISA_430},
351 {"msp430f2132", MSP_ISA_430},
352 {"msp430f2232", MSP_ISA_430},
353 {"msp430f2234", MSP_ISA_430},
354 {"msp430f2252", MSP_ISA_430},
355 {"msp430f2254", MSP_ISA_430},
356 {"msp430f2272", MSP_ISA_430},
357 {"msp430f2274", MSP_ISA_430},
358 {"msp430f233", MSP_ISA_430},
359 {"msp430f2330", MSP_ISA_430},
360 {"msp430f235", MSP_ISA_430},
361 {"msp430f2350", MSP_ISA_430},
362 {"msp430f2370", MSP_ISA_430},
363 {"msp430f2410", MSP_ISA_430},
364 {"msp430f247", MSP_ISA_430},
365 {"msp430f2471", MSP_ISA_430},
366 {"msp430f248", MSP_ISA_430},
367 {"msp430f2481", MSP_ISA_430},
368 {"msp430f249", MSP_ISA_430},
369 {"msp430f2491", MSP_ISA_430},
370 {"msp430f412", MSP_ISA_430},
371 {"msp430f413", MSP_ISA_430},
372 {"msp430f4132", MSP_ISA_430},
373 {"msp430f415", MSP_ISA_430},
374 {"msp430f4152", MSP_ISA_430},
375 {"msp430f417", MSP_ISA_430},
376 {"msp430f423", MSP_ISA_430},
377 {"msp430f423a", MSP_ISA_430},
378 {"msp430f425", MSP_ISA_430},
379 {"msp430f4250", MSP_ISA_430},
380 {"msp430f425a", MSP_ISA_430},
381 {"msp430f4260", MSP_ISA_430},
382 {"msp430f427", MSP_ISA_430},
383 {"msp430f4270", MSP_ISA_430},
384 {"msp430f427a", MSP_ISA_430},
385 {"msp430f435", MSP_ISA_430},
386 {"msp430f4351", MSP_ISA_430},
387 {"msp430f436", MSP_ISA_430},
388 {"msp430f4361", MSP_ISA_430},
389 {"msp430f437", MSP_ISA_430},
390 {"msp430f4371", MSP_ISA_430},
391 {"msp430f438", MSP_ISA_430},
392 {"msp430f439", MSP_ISA_430},
393 {"msp430f447", MSP_ISA_430},
394 {"msp430f448", MSP_ISA_430},
395 {"msp430f4481", MSP_ISA_430},
396 {"msp430f449", MSP_ISA_430},
397 {"msp430f4491", MSP_ISA_430},
398 {"msp430f477", MSP_ISA_430},
399 {"msp430f478", MSP_ISA_430},
400 {"msp430f4783", MSP_ISA_430},
401 {"msp430f4784", MSP_ISA_430},
402 {"msp430f479", MSP_ISA_430},
403 {"msp430f4793", MSP_ISA_430},
404 {"msp430f4794", MSP_ISA_430},
405 {"msp430fe423", MSP_ISA_430},
406 {"msp430fe4232", MSP_ISA_430},
407 {"msp430fe423a", MSP_ISA_430},
408 {"msp430fe4242", MSP_ISA_430},
409 {"msp430fe425", MSP_ISA_430},
410 {"msp430fe4252", MSP_ISA_430},
411 {"msp430fe425a", MSP_ISA_430},
412 {"msp430fe427", MSP_ISA_430},
413 {"msp430fe4272", MSP_ISA_430},
414 {"msp430fe427a", MSP_ISA_430},
415 {"msp430fg4250", MSP_ISA_430},
416 {"msp430fg4260", MSP_ISA_430},
417 {"msp430fg4270", MSP_ISA_430},
418 {"msp430fg437", MSP_ISA_430},
419 {"msp430fg438", MSP_ISA_430},
420 {"msp430fg439", MSP_ISA_430},
421 {"msp430fg477", MSP_ISA_430},
422 {"msp430fg478", MSP_ISA_430},
423 {"msp430fg479", MSP_ISA_430},
424 {"msp430fw423", MSP_ISA_430},
425 {"msp430fw425", MSP_ISA_430},
426 {"msp430fw427", MSP_ISA_430},
427 {"msp430fw428", MSP_ISA_430},
428 {"msp430fw429", MSP_ISA_430},
429 {"msp430g2001", MSP_ISA_430},
430 {"msp430g2101", MSP_ISA_430},
431 {"msp430g2102", MSP_ISA_430},
432 {"msp430g2111", MSP_ISA_430},
433 {"msp430g2112", MSP_ISA_430},
434 {"msp430g2113", MSP_ISA_430},
435 {"msp430g2121", MSP_ISA_430},
436 {"msp430g2131", MSP_ISA_430},
437 {"msp430g2132", MSP_ISA_430},
438 {"msp430g2152", MSP_ISA_430},
439 {"msp430g2153", MSP_ISA_430},
440 {"msp430g2201", MSP_ISA_430},
441 {"msp430g2202", MSP_ISA_430},
442 {"msp430g2203", MSP_ISA_430},
443 {"msp430g2210", MSP_ISA_430},
444 {"msp430g2211", MSP_ISA_430},
445 {"msp430g2212", MSP_ISA_430},
446 {"msp430g2213", MSP_ISA_430},
447 {"msp430g2221", MSP_ISA_430},
448 {"msp430g2230", MSP_ISA_430},
449 {"msp430g2231", MSP_ISA_430},
450 {"msp430g2232", MSP_ISA_430},
451 {"msp430g2233", MSP_ISA_430},
452 {"msp430g2252", MSP_ISA_430},
453 {"msp430g2253", MSP_ISA_430},
454 {"msp430g2302", MSP_ISA_430},
455 {"msp430g2303", MSP_ISA_430},
456 {"msp430g2312", MSP_ISA_430},
457 {"msp430g2313", MSP_ISA_430},
458 {"msp430g2332", MSP_ISA_430},
459 {"msp430g2333", MSP_ISA_430},
460 {"msp430g2352", MSP_ISA_430},
461 {"msp430g2353", MSP_ISA_430},
462 {"msp430g2402", MSP_ISA_430},
463 {"msp430g2403", MSP_ISA_430},
464 {"msp430g2412", MSP_ISA_430},
465 {"msp430g2413", MSP_ISA_430},
466 {"msp430g2432", MSP_ISA_430},
467 {"msp430g2433", MSP_ISA_430},
468 {"msp430g2444", MSP_ISA_430},
469 {"msp430g2452", MSP_ISA_430},
470 {"msp430g2453", MSP_ISA_430},
471 {"msp430g2513", MSP_ISA_430},
472 {"msp430g2533", MSP_ISA_430},
473 {"msp430g2544", MSP_ISA_430},
474 {"msp430g2553", MSP_ISA_430},
475 {"msp430g2744", MSP_ISA_430},
476 {"msp430g2755", MSP_ISA_430},
477 {"msp430g2855", MSP_ISA_430},
478 {"msp430g2955", MSP_ISA_430},
479 {"msp430l092", MSP_ISA_430},
480 {"msp430p112", MSP_ISA_430},
481 {"msp430p313", MSP_ISA_430},
482 {"msp430p315", MSP_ISA_430},
483 {"msp430p315s", MSP_ISA_430},
484 {"msp430p325", MSP_ISA_430},
485 {"msp430p337", MSP_ISA_430},
486 {"msp430tch5e", MSP_ISA_430},
487
488 {"msp430cg4616", MSP_ISA_430X},
489 {"msp430cg4617", MSP_ISA_430X},
490 {"msp430cg4618", MSP_ISA_430X},
491 {"msp430cg4619", MSP_ISA_430X},
492 {"msp430f2416", MSP_ISA_430X},
493 {"msp430f2417", MSP_ISA_430X},
494 {"msp430f2418", MSP_ISA_430X},
495 {"msp430f2419", MSP_ISA_430X},
496 {"msp430f2616", MSP_ISA_430X},
497 {"msp430f2617", MSP_ISA_430X},
498 {"msp430f2618", MSP_ISA_430X},
499 {"msp430f2619", MSP_ISA_430X},
500 {"msp430f47126", MSP_ISA_430X},
501 {"msp430f47127", MSP_ISA_430X},
502 {"msp430f47163", MSP_ISA_430X},
503 {"msp430f47173", MSP_ISA_430X},
504 {"msp430f47183", MSP_ISA_430X},
505 {"msp430f47193", MSP_ISA_430X},
506 {"msp430f47166", MSP_ISA_430X},
507 {"msp430f47176", MSP_ISA_430X},
508 {"msp430f47186", MSP_ISA_430X},
509 {"msp430f47196", MSP_ISA_430X},
510 {"msp430f47167", MSP_ISA_430X},
511 {"msp430f47177", MSP_ISA_430X},
512 {"msp430f47187", MSP_ISA_430X},
513 {"msp430f47197", MSP_ISA_430X},
514 {"msp430f46161", MSP_ISA_430X},
515 {"msp430f46171", MSP_ISA_430X},
516 {"msp430f46181", MSP_ISA_430X},
517 {"msp430f46191", MSP_ISA_430X},
518 {"msp430f4616", MSP_ISA_430X},
519 {"msp430f4617", MSP_ISA_430X},
520 {"msp430f4618", MSP_ISA_430X},
521 {"msp430f4619", MSP_ISA_430X},
522 {"msp430fg4616", MSP_ISA_430X},
523 {"msp430fg4617", MSP_ISA_430X},
524 {"msp430fg4618", MSP_ISA_430X},
525 {"msp430fg4619", MSP_ISA_430X},
526
527 {"msp430f5418", MSP_ISA_430Xv2},
528 {"msp430f5419", MSP_ISA_430Xv2},
529 {"msp430f5435", MSP_ISA_430Xv2},
530 {"msp430f5436", MSP_ISA_430Xv2},
531 {"msp430f5437", MSP_ISA_430Xv2},
532 {"msp430f5438", MSP_ISA_430Xv2},
533 {"msp430f5418a", MSP_ISA_430Xv2},
534 {"msp430f5419a", MSP_ISA_430Xv2},
535 {"msp430f5435a", MSP_ISA_430Xv2},
536 {"msp430f5436a", MSP_ISA_430Xv2},
537 {"msp430f5437a", MSP_ISA_430Xv2},
538 {"msp430f5438a", MSP_ISA_430Xv2},
539 {"msp430f5212", MSP_ISA_430Xv2},
540 {"msp430f5213", MSP_ISA_430Xv2},
541 {"msp430f5214", MSP_ISA_430Xv2},
542 {"msp430f5217", MSP_ISA_430Xv2},
543 {"msp430f5218", MSP_ISA_430Xv2},
544 {"msp430f5219", MSP_ISA_430Xv2},
545 {"msp430f5222", MSP_ISA_430Xv2},
546 {"msp430f5223", MSP_ISA_430Xv2},
547 {"msp430f5224", MSP_ISA_430Xv2},
548 {"msp430f5227", MSP_ISA_430Xv2},
549 {"msp430f5228", MSP_ISA_430Xv2},
550 {"msp430f5229", MSP_ISA_430Xv2},
551 {"msp430f5304", MSP_ISA_430Xv2},
552 {"msp430f5308", MSP_ISA_430Xv2},
553 {"msp430f5309", MSP_ISA_430Xv2},
554 {"msp430f5310", MSP_ISA_430Xv2},
555 {"msp430f5340", MSP_ISA_430Xv2},
556 {"msp430f5341", MSP_ISA_430Xv2},
557 {"msp430f5342", MSP_ISA_430Xv2},
558 {"msp430f5324", MSP_ISA_430Xv2},
559 {"msp430f5325", MSP_ISA_430Xv2},
560 {"msp430f5326", MSP_ISA_430Xv2},
561 {"msp430f5327", MSP_ISA_430Xv2},
562 {"msp430f5328", MSP_ISA_430Xv2},
563 {"msp430f5329", MSP_ISA_430Xv2},
564 {"msp430f5500", MSP_ISA_430Xv2},
565 {"msp430f5501", MSP_ISA_430Xv2},
566 {"msp430f5502", MSP_ISA_430Xv2},
567 {"msp430f5503", MSP_ISA_430Xv2},
568 {"msp430f5504", MSP_ISA_430Xv2},
569 {"msp430f5505", MSP_ISA_430Xv2},
570 {"msp430f5506", MSP_ISA_430Xv2},
571 {"msp430f5507", MSP_ISA_430Xv2},
572 {"msp430f5508", MSP_ISA_430Xv2},
573 {"msp430f5509", MSP_ISA_430Xv2},
574 {"msp430f5510", MSP_ISA_430Xv2},
575 {"msp430f5513", MSP_ISA_430Xv2},
576 {"msp430f5514", MSP_ISA_430Xv2},
577 {"msp430f5515", MSP_ISA_430Xv2},
578 {"msp430f5517", MSP_ISA_430Xv2},
579 {"msp430f5519", MSP_ISA_430Xv2},
580 {"msp430f5521", MSP_ISA_430Xv2},
581 {"msp430f5522", MSP_ISA_430Xv2},
582 {"msp430f5524", MSP_ISA_430Xv2},
583 {"msp430f5525", MSP_ISA_430Xv2},
584 {"msp430f5526", MSP_ISA_430Xv2},
585 {"msp430f5527", MSP_ISA_430Xv2},
586 {"msp430f5528", MSP_ISA_430Xv2},
587 {"msp430f5529", MSP_ISA_430Xv2},
588 {"cc430f5133", MSP_ISA_430Xv2},
589 {"cc430f5135", MSP_ISA_430Xv2},
590 {"cc430f5137", MSP_ISA_430Xv2},
591 {"cc430f6125", MSP_ISA_430Xv2},
592 {"cc430f6126", MSP_ISA_430Xv2},
593 {"cc430f6127", MSP_ISA_430Xv2},
594 {"cc430f6135", MSP_ISA_430Xv2},
595 {"cc430f6137", MSP_ISA_430Xv2},
596 {"cc430f5123", MSP_ISA_430Xv2},
597 {"cc430f5125", MSP_ISA_430Xv2},
598 {"cc430f5143", MSP_ISA_430Xv2},
599 {"cc430f5145", MSP_ISA_430Xv2},
600 {"cc430f5147", MSP_ISA_430Xv2},
601 {"cc430f6143", MSP_ISA_430Xv2},
602 {"cc430f6145", MSP_ISA_430Xv2},
603 {"cc430f6147", MSP_ISA_430Xv2},
604 {"msp430f5333", MSP_ISA_430Xv2},
605 {"msp430f5335", MSP_ISA_430Xv2},
606 {"msp430f5336", MSP_ISA_430Xv2},
607 {"msp430f5338", MSP_ISA_430Xv2},
608 {"msp430f5630", MSP_ISA_430Xv2},
609 {"msp430f5631", MSP_ISA_430Xv2},
610 {"msp430f5632", MSP_ISA_430Xv2},
611 {"msp430f5633", MSP_ISA_430Xv2},
612 {"msp430f5634", MSP_ISA_430Xv2},
613 {"msp430f5635", MSP_ISA_430Xv2},
614 {"msp430f5636", MSP_ISA_430Xv2},
615 {"msp430f5637", MSP_ISA_430Xv2},
616 {"msp430f5638", MSP_ISA_430Xv2},
617 {"msp430f6433", MSP_ISA_430Xv2},
618 {"msp430f6435", MSP_ISA_430Xv2},
619 {"msp430f6436", MSP_ISA_430Xv2},
620 {"msp430f6438", MSP_ISA_430Xv2},
621 {"msp430f6630", MSP_ISA_430Xv2},
622 {"msp430f6631", MSP_ISA_430Xv2},
623 {"msp430f6632", MSP_ISA_430Xv2},
624 {"msp430f6633", MSP_ISA_430Xv2},
625 {"msp430f6634", MSP_ISA_430Xv2},
626 {"msp430f6635", MSP_ISA_430Xv2},
627 {"msp430f6636", MSP_ISA_430Xv2},
628 {"msp430f6637", MSP_ISA_430Xv2},
629 {"msp430f6638", MSP_ISA_430Xv2},
630 {"msp430f5358", MSP_ISA_430Xv2},
631 {"msp430f5359", MSP_ISA_430Xv2},
632 {"msp430f5658", MSP_ISA_430Xv2},
633 {"msp430f5659", MSP_ISA_430Xv2},
634 {"msp430f6458", MSP_ISA_430Xv2},
635 {"msp430f6459", MSP_ISA_430Xv2},
636 {"msp430f6658", MSP_ISA_430Xv2},
637 {"msp430f6659", MSP_ISA_430Xv2},
638 {"msp430f5131", MSP_ISA_430Xv2},
639 {"msp430f5151", MSP_ISA_430Xv2},
640 {"msp430f5171", MSP_ISA_430Xv2},
641 {"msp430f5132", MSP_ISA_430Xv2},
642 {"msp430f5152", MSP_ISA_430Xv2},
643 {"msp430f5172", MSP_ISA_430Xv2},
644 {"msp430f6720", MSP_ISA_430Xv2},
645 {"msp430f6721", MSP_ISA_430Xv2},
646 {"msp430f6723", MSP_ISA_430Xv2},
647 {"msp430f6724", MSP_ISA_430Xv2},
648 {"msp430f6725", MSP_ISA_430Xv2},
649 {"msp430f6726", MSP_ISA_430Xv2},
650 {"msp430f6730", MSP_ISA_430Xv2},
651 {"msp430f6731", MSP_ISA_430Xv2},
652 {"msp430f6733", MSP_ISA_430Xv2},
653 {"msp430f6734", MSP_ISA_430Xv2},
654 {"msp430f6735", MSP_ISA_430Xv2},
655 {"msp430f6736", MSP_ISA_430Xv2},
656 {"msp430f67451", MSP_ISA_430Xv2},
657 {"msp430f67651", MSP_ISA_430Xv2},
658 {"msp430f67751", MSP_ISA_430Xv2},
659 {"msp430f67461", MSP_ISA_430Xv2},
660 {"msp430f67661", MSP_ISA_430Xv2},
661 {"msp430f67761", MSP_ISA_430Xv2},
662 {"msp430f67471", MSP_ISA_430Xv2},
663 {"msp430f67671", MSP_ISA_430Xv2},
664 {"msp430f67771", MSP_ISA_430Xv2},
665 {"msp430f67481", MSP_ISA_430Xv2},
666 {"msp430f67681", MSP_ISA_430Xv2},
667 {"msp430f67781", MSP_ISA_430Xv2},
668 {"msp430f67491", MSP_ISA_430Xv2},
669 {"msp430f67691", MSP_ISA_430Xv2},
670 {"msp430f67791", MSP_ISA_430Xv2},
671 {"msp430f6745", MSP_ISA_430Xv2},
672 {"msp430f6765", MSP_ISA_430Xv2},
673 {"msp430f6775", MSP_ISA_430Xv2},
674 {"msp430f6746", MSP_ISA_430Xv2},
675 {"msp430f6766", MSP_ISA_430Xv2},
676 {"msp430f6776", MSP_ISA_430Xv2},
677 {"msp430f6747", MSP_ISA_430Xv2},
678 {"msp430f6767", MSP_ISA_430Xv2},
679 {"msp430f6777", MSP_ISA_430Xv2},
680 {"msp430f6748", MSP_ISA_430Xv2},
681 {"msp430f6768", MSP_ISA_430Xv2},
682 {"msp430f6778", MSP_ISA_430Xv2},
683 {"msp430f6749", MSP_ISA_430Xv2},
684 {"msp430f6769", MSP_ISA_430Xv2},
685 {"msp430f6779", MSP_ISA_430Xv2},
686 {"msp430fr5720", MSP_ISA_430Xv2},
687 {"msp430fr5721", MSP_ISA_430Xv2},
688 {"msp430fr5722", MSP_ISA_430Xv2},
689 {"msp430fr5723", MSP_ISA_430Xv2},
690 {"msp430fr5724", MSP_ISA_430Xv2},
691 {"msp430fr5725", MSP_ISA_430Xv2},
692 {"msp430fr5726", MSP_ISA_430Xv2},
693 {"msp430fr5727", MSP_ISA_430Xv2},
694 {"msp430fr5728", MSP_ISA_430Xv2},
695 {"msp430fr5729", MSP_ISA_430Xv2},
696 {"msp430fr5730", MSP_ISA_430Xv2},
697 {"msp430fr5731", MSP_ISA_430Xv2},
698 {"msp430fr5732", MSP_ISA_430Xv2},
699 {"msp430fr5733", MSP_ISA_430Xv2},
700 {"msp430fr5734", MSP_ISA_430Xv2},
701 {"msp430fr5735", MSP_ISA_430Xv2},
702 {"msp430fr5736", MSP_ISA_430Xv2},
703 {"msp430fr5737", MSP_ISA_430Xv2},
704 {"msp430fr5738", MSP_ISA_430Xv2},
705 {"msp430fr5739", MSP_ISA_430Xv2},
706 {"msp430bt5190", MSP_ISA_430Xv2},
707 {"msp430fr5949", MSP_ISA_430Xv2},
708 {"msp430fr5969", MSP_ISA_430Xv2},
709 {"msp430sl5438a", MSP_ISA_430Xv2},
710
711 /* Generic names. */
712 {"msp430", MSP_ISA_430},
713 {"msp430X", MSP_ISA_430X},
714 {"msp430Xv2", MSP_ISA_430Xv2},
715
716 {NULL, 0}
717};
718
719static struct mcu_type_s default_mcu = { "msp430x11", MSP_ISA_430 };
720static struct mcu_type_s msp430x_mcu = { "msp430x", MSP_ISA_430X };
721static struct mcu_type_s msp430xv2_mcu = { "msp430xv2", MSP_ISA_430Xv2 };
722
723static struct mcu_type_s * msp430_mcu = & default_mcu;
724
725static inline bfd_boolean
726target_is_430x (void)
727{
728 return msp430_mcu->isa >= MSP_ISA_430X;
729}
730
731static inline bfd_boolean
732target_is_430xv2 (void)
733{
734 return msp430_mcu->isa == MSP_ISA_430Xv2;
735}
13761a11
NC
736
737/* Generate a 16-bit relocation.
738 For the 430X we generate a relocation without linkwer range checking
739 if the value is being used in an extended (ie 20-bit) instruction.
740 For the 430 we generate a relocation without assembler range checking
741 if we are handling an immediate value or a byte-width instruction. */
742#undef CHECK_RELOC_MSP430
743#define CHECK_RELOC_MSP430 \
638d3803 744 (target_is_430x () \
13761a11
NC
745 ? (extended_op ? BFD_RELOC_16 : BFD_RELOC_MSP430X_ABS16) \
746 : ((imm_op || byte_op) \
747 ? BFD_RELOC_MSP430_16_BYTE : BFD_RELOC_MSP430_16))
748
749/* Generate a 16-bit pc-relative relocation.
750 For the 430X we generate a relocation without linkwer range checking.
751 For the 430 we generate a relocation without assembler range checking
752 if we are handling an immediate value or a byte-width instruction. */
753#undef CHECK_RELOC_MSP430_PCREL
754#define CHECK_RELOC_MSP430_PCREL \
638d3803 755 (target_is_430x () \
13761a11
NC
756 ? BFD_RELOC_MSP430X_PCR16 \
757 : (imm_op || byte_op) \
758 ? BFD_RELOC_MSP430_16_PCREL_BYTE : BFD_RELOC_MSP430_16_PCREL)
2469cfa2 759
b18c562e
NC
760/* Profiling capability:
761 It is a performance hit to use gcc's profiling approach for this tiny target.
762 Even more -- jtag hardware facility does not perform any profiling functions.
763 However we've got gdb's built-in simulator where we can do anything.
764 Therefore my suggestion is:
765
766 We define new section ".profiler" which holds all profiling information.
767 We define new pseudo operation .profiler which will instruct assembler to
768 add new profile entry to the object file. Profile should take place at the
769 present address.
770
771 Pseudo-op format:
772
773 .profiler flags,function_to_profile [, cycle_corrector, extra]
774
775 where 'flags' is a combination of the following chars:
776 s - function Start
777 x - function eXit
778 i - function is in Init section
779 f - function is in Fini section
780 l - Library call
781 c - libC standard call
782 d - stack value Demand (saved at run-time in simulator)
783 I - Interrupt service routine
784 P - Prologue start
785 p - Prologue end
786 E - Epilogue start
787 e - Epilogue end
788 j - long Jump/ sjlj unwind
789 a - an Arbitrary code fragment
790 t - exTra parameter saved (constant value like frame size)
791 '""' optional: "sil" == sil
792
793 function_to_profile - function's address
794 cycle_corrector - a value which should be added to the cycle
795 counter, zero if omitted
796 extra - some extra parameter, zero if omitted.
797
798 For example:
799 ------------------------------
800 .global fxx
801 .type fxx,@function
802 fxx:
803 .LFrameOffset_fxx=0x08
804 .profiler "scdP", fxx ; function entry.
805 ; we also demand stack value to be displayed
806 push r11
807 push r10
808 push r9
809 push r8
810 .profiler "cdp",fxx,0, .LFrameOffset_fxx ; check stack value at this point
811 ; (this is a prologue end)
79cf5950 812 ; note, that spare var filled with the frame size
b18c562e
NC
813 mov r15,r8
814 ....
815 .profiler cdE,fxx ; check stack
816 pop r8
817 pop r9
818 pop r10
819 pop r11
820 .profiler xcde,fxx,3 ; exit adds 3 to the cycle counter
821 ret ; cause 'ret' insn takes 3 cycles
822 -------------------------------
823
824 This profiling approach does not produce any overhead and
825 absolutely harmless.
826 So, even profiled code can be uploaded to the MCU. */
827#define MSP430_PROFILER_FLAG_ENTRY 1 /* s */
828#define MSP430_PROFILER_FLAG_EXIT 2 /* x */
829#define MSP430_PROFILER_FLAG_INITSECT 4 /* i */
830#define MSP430_PROFILER_FLAG_FINISECT 8 /* f */
831#define MSP430_PROFILER_FLAG_LIBCALL 0x10 /* l */
832#define MSP430_PROFILER_FLAG_STDCALL 0x20 /* c */
833#define MSP430_PROFILER_FLAG_STACKDMD 0x40 /* d */
834#define MSP430_PROFILER_FLAG_ISR 0x80 /* I */
835#define MSP430_PROFILER_FLAG_PROLSTART 0x100 /* P */
836#define MSP430_PROFILER_FLAG_PROLEND 0x200 /* p */
837#define MSP430_PROFILER_FLAG_EPISTART 0x400 /* E */
838#define MSP430_PROFILER_FLAG_EPIEND 0x800 /* e */
839#define MSP430_PROFILER_FLAG_JUMP 0x1000 /* j */
840#define MSP430_PROFILER_FLAG_FRAGMENT 0x2000 /* a */
841#define MSP430_PROFILER_FLAG_EXTRA 0x4000 /* t */
842#define MSP430_PROFILER_FLAG_notyet 0x8000 /* ? */
2469cfa2 843
b18c562e
NC
844static int
845pow2value (int y)
2469cfa2 846{
b18c562e
NC
847 int n = 0;
848 unsigned int x;
2469cfa2 849
b18c562e 850 x = y;
2469cfa2 851
b18c562e
NC
852 if (!x)
853 return 1;
2469cfa2 854
b18c562e
NC
855 for (; x; x = x >> 1)
856 if (x & 1)
857 n++;
858
859 return n == 1;
860}
861
862/* Parse ordinary expression. */
863
864static char *
865parse_exp (char * s, expressionS * op)
2469cfa2 866{
b18c562e
NC
867 input_line_pointer = s;
868 expression (op);
869 if (op->X_op == O_absent)
870 as_bad (_("missing operand"));
871 return input_line_pointer;
872}
2469cfa2 873
b18c562e
NC
874
875/* Delete spaces from s: X ( r 1 2) => X(r12). */
2469cfa2
NC
876
877static void
b18c562e 878del_spaces (char * s)
2469cfa2 879{
b18c562e
NC
880 while (*s)
881 {
882 if (ISSPACE (*s))
883 {
884 char *m = s + 1;
2469cfa2 885
b18c562e
NC
886 while (ISSPACE (*m) && *m)
887 m++;
888 memmove (s, m, strlen (m) + 1);
889 }
890 else
891 s++;
892 }
893}
2469cfa2 894
b18c562e
NC
895static inline char *
896skip_space (char * s)
897{
898 while (ISSPACE (*s))
899 ++s;
900 return s;
901}
2469cfa2 902
708587a4 903/* Extract one word from FROM and copy it to TO. Delimiters are ",;\n" */
b18c562e
NC
904
905static char *
906extract_operand (char * from, char * to, int limit)
907{
908 int size = 0;
909
910 /* Drop leading whitespace. */
911 from = skip_space (from);
912
913 while (size < limit && *from)
914 {
915 *(to + size) = *from;
916 if (*from == ',' || *from == ';' || *from == '\n')
917 break;
918 from++;
919 size++;
920 }
921
922 *(to + size) = 0;
923 del_spaces (to);
924
925 from++;
926
927 return from;
2469cfa2
NC
928}
929
b18c562e
NC
930static void
931msp430_profiler (int dummy ATTRIBUTE_UNUSED)
2469cfa2 932{
b18c562e
NC
933 char buffer[1024];
934 char f[32];
935 char * str = buffer;
936 char * flags = f;
937 int p_flags = 0;
938 char * halt;
939 int ops = 0;
940 int left;
941 char * s;
942 segT seg;
943 int subseg;
944 char * end = 0;
945 expressionS exp;
946 expressionS exp1;
947
948 s = input_line_pointer;
949 end = input_line_pointer;
950
951 while (*end && *end != '\n')
952 end++;
953
954 while (*s && *s != '\n')
955 {
956 if (*s == ',')
957 ops++;
958 s++;
959 }
2469cfa2 960
b18c562e
NC
961 left = 3 - ops;
962
963 if (ops < 1)
964 {
965 as_bad (_(".profiler pseudo requires at least two operands."));
966 input_line_pointer = end;
967 return;
968 }
969
970 input_line_pointer = extract_operand (input_line_pointer, flags, 32);
971
972 while (*flags)
973 {
974 switch (*flags)
975 {
976 case '"':
977 break;
978 case 'a':
979 p_flags |= MSP430_PROFILER_FLAG_FRAGMENT;
980 break;
981 case 'j':
982 p_flags |= MSP430_PROFILER_FLAG_JUMP;
983 break;
984 case 'P':
985 p_flags |= MSP430_PROFILER_FLAG_PROLSTART;
986 break;
987 case 'p':
988 p_flags |= MSP430_PROFILER_FLAG_PROLEND;
989 break;
990 case 'E':
991 p_flags |= MSP430_PROFILER_FLAG_EPISTART;
992 break;
993 case 'e':
994 p_flags |= MSP430_PROFILER_FLAG_EPIEND;
995 break;
996 case 's':
997 p_flags |= MSP430_PROFILER_FLAG_ENTRY;
998 break;
999 case 'x':
1000 p_flags |= MSP430_PROFILER_FLAG_EXIT;
1001 break;
1002 case 'i':
1003 p_flags |= MSP430_PROFILER_FLAG_INITSECT;
1004 break;
1005 case 'f':
1006 p_flags |= MSP430_PROFILER_FLAG_FINISECT;
1007 break;
1008 case 'l':
1009 p_flags |= MSP430_PROFILER_FLAG_LIBCALL;
1010 break;
1011 case 'c':
1012 p_flags |= MSP430_PROFILER_FLAG_STDCALL;
1013 break;
1014 case 'd':
1015 p_flags |= MSP430_PROFILER_FLAG_STACKDMD;
1016 break;
1017 case 'I':
1018 p_flags |= MSP430_PROFILER_FLAG_ISR;
1019 break;
1020 case 't':
1021 p_flags |= MSP430_PROFILER_FLAG_EXTRA;
1022 break;
1023 default:
1024 as_warn (_("unknown profiling flag - ignored."));
1025 break;
1026 }
1027 flags++;
1028 }
1029
1030 if (p_flags
1031 && ( ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_ENTRY
1032 | MSP430_PROFILER_FLAG_EXIT))
1033 || ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_PROLSTART
1034 | MSP430_PROFILER_FLAG_PROLEND
1035 | MSP430_PROFILER_FLAG_EPISTART
1036 | MSP430_PROFILER_FLAG_EPIEND))
1037 || ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_INITSECT
1038 | MSP430_PROFILER_FLAG_FINISECT))))
1039 {
79cf5950 1040 as_bad (_("ambiguous flags combination - '.profiler' directive ignored."));
b18c562e
NC
1041 input_line_pointer = end;
1042 return;
1043 }
1044
1045 /* Generate temp symbol which denotes current location. */
79cf5950 1046 if (now_seg == absolute_section) /* Paranoia ? */
b18c562e
NC
1047 {
1048 exp1.X_op = O_constant;
1049 exp1.X_add_number = abs_section_offset;
79cf5950 1050 as_warn (_("profiling in absolute section?"));
b18c562e
NC
1051 }
1052 else
1053 {
1054 exp1.X_op = O_symbol;
1055 exp1.X_add_symbol = symbol_temp_new_now ();
1056 exp1.X_add_number = 0;
1057 }
1058
1059 /* Generate a symbol which holds flags value. */
1060 exp.X_op = O_constant;
1061 exp.X_add_number = p_flags;
1062
1063 /* Save current section. */
1064 seg = now_seg;
1065 subseg = now_subseg;
1066
1067 /* Now go to .profiler section. */
1068 obj_elf_change_section (".profiler", SHT_PROGBITS, 0, 0, 0, 0, 0);
1069
1070 /* Save flags. */
1071 emit_expr (& exp, 2);
1072
1073 /* Save label value. */
1074 emit_expr (& exp1, 2);
1075
1076 while (ops--)
1077 {
1078 /* Now get profiling info. */
1079 halt = extract_operand (input_line_pointer, str, 1024);
1080 /* Process like ".word xxx" directive. */
1081 parse_exp (str, & exp);
1082 emit_expr (& exp, 2);
1083 input_line_pointer = halt;
1084 }
1085
1086 /* Fill the rest with zeros. */
1087 exp.X_op = O_constant;
1088 exp.X_add_number = 0;
1089 while (left--)
1090 emit_expr (& exp, 2);
1091
1092 /* Return to current section. */
1093 subseg_set (seg, subseg);
2469cfa2
NC
1094}
1095
1096static char *
b18c562e 1097extract_word (char * from, char * to, int limit)
2469cfa2 1098{
2469cfa2
NC
1099 char *op_end;
1100 int size = 0;
1101
1102 /* Drop leading whitespace. */
1103 from = skip_space (from);
1104 *to = 0;
1105
1106 /* Find the op code end. */
87975d2a 1107 for (op_end = from; *op_end != 0 && is_part_of_name (*op_end);)
2469cfa2
NC
1108 {
1109 to[size++] = *op_end++;
1110 if (size + 1 >= limit)
1111 break;
1112 }
1113
1114 to[size] = 0;
1115 return op_end;
1116}
1117
b18c562e 1118#define OPTION_MMCU 'm'
77592908
DD
1119#define OPTION_RELAX 'Q'
1120#define OPTION_POLYMORPHS 'P'
13761a11
NC
1121#define OPTION_LARGE 'l'
1122static bfd_boolean large_model = FALSE;
1123#define OPTION_NO_INTR_NOPS 'N'
1124static bfd_boolean gen_interrupt_nops = TRUE;
638d3803 1125#define OPTION_MCPU 'c'
b18c562e 1126
2469cfa2 1127static void
638d3803 1128msp430_set_arch (int option)
2469cfa2
NC
1129{
1130 char *str = (char *) alloca (32); /* 32 for good measure. */
1131
1132 input_line_pointer = extract_word (input_line_pointer, str, 32);
1133
638d3803
NC
1134 md_parse_option (option, str);
1135 bfd_set_arch_mach (stdoutput, TARGET_ARCH,
1136 target_is_430x () ? bfd_mach_msp430x : bfd_mach_msp11);
2469cfa2
NC
1137}
1138
b18c562e
NC
1139static void
1140show_mcu_list (FILE * stream)
1141{
1142 int i;
1143
1144 fprintf (stream, _("Known MCU names:\n"));
1145
1146 for (i = 0; mcu_types[i].name; i++)
13761a11 1147 {
638d3803 1148 fprintf (stream, "%14.14s", mcu_types[i].name);
13761a11
NC
1149 if ((i % 6) == 5)
1150 fprintf (stream, "\n");
1151 }
b18c562e
NC
1152
1153 fprintf (stream, "\n");
1154}
1155
2469cfa2 1156int
b18c562e 1157md_parse_option (int c, char * arg)
2469cfa2
NC
1158{
1159 int i;
1160
1161 switch (c)
1162 {
1163 case OPTION_MMCU:
638d3803
NC
1164 if (arg == NULL)
1165 as_fatal (_("MCU option requires a name\n"));
1166
2469cfa2 1167 for (i = 0; mcu_types[i].name; ++i)
638d3803 1168 if (strcasecmp (mcu_types[i].name, arg) == 0)
2469cfa2
NC
1169 break;
1170
638d3803 1171 if (mcu_types[i].name == NULL)
2469cfa2
NC
1172 {
1173 show_mcu_list (stderr);
1174 as_fatal (_("unknown MCU: %s\n"), arg);
1175 }
1176
638d3803
NC
1177 /* Allow switching to the same or a lesser architecture. */
1178 if (msp430_mcu == &default_mcu || msp430_mcu->isa >= mcu_types[i].isa)
13761a11 1179 msp430_mcu = mcu_types + i;
2469cfa2 1180 else
638d3803 1181 as_fatal (_("redefinition of mcu type '%s' to '%s'"),
2469cfa2
NC
1182 msp430_mcu->name, mcu_types[i].name);
1183 return 1;
13761a11 1184
638d3803
NC
1185 case OPTION_MCPU:
1186 if (strcmp (arg, "430") == 0)
1187 msp430_mcu = & default_mcu;
1188 else if (strcmp (arg, "430x") == 0
1189 || strcmp (arg, "430X") == 0)
1190 msp430_mcu = & msp430x_mcu;
1191 else if (strcasecmp (arg, "430xv2") == 0)
1192 msp430_mcu = & msp430xv2_mcu;
1193 else
1194 as_fatal (_("unrecognised argument to -mcpu option '%s'"), arg);
1195
1196 return 1;
1197
77592908 1198 case OPTION_RELAX:
13761a11 1199 msp430_enable_relax = 1;
77592908 1200 return 1;
13761a11 1201
77592908
DD
1202 case OPTION_POLYMORPHS:
1203 msp430_enable_polys = 1;
1204 return 1;
13761a11
NC
1205
1206 case OPTION_LARGE:
1207 large_model = TRUE;
1208 return 1;
1209
1210 case OPTION_NO_INTR_NOPS:
1211 gen_interrupt_nops = FALSE;
1212 return 1;
2469cfa2
NC
1213 }
1214
1215 return 0;
1216}
1217
b18c562e 1218const pseudo_typeS md_pseudo_table[] =
2469cfa2 1219{
638d3803
NC
1220 {"arch", msp430_set_arch, OPTION_MMCU},
1221 {"cpu", msp430_set_arch, OPTION_MCPU},
b18c562e
NC
1222 {"profiler", msp430_profiler, 0},
1223 {NULL, NULL, 0}
1224};
2469cfa2 1225
638d3803 1226const char *md_shortopts = "mm:,mP,mQ,ml,mN";
2469cfa2 1227
b18c562e 1228struct option md_longopts[] =
2469cfa2 1229{
b18c562e 1230 {"mmcu", required_argument, NULL, OPTION_MMCU},
638d3803 1231 {"mcpu", required_argument, NULL, OPTION_MCPU},
77592908
DD
1232 {"mP", no_argument, NULL, OPTION_POLYMORPHS},
1233 {"mQ", no_argument, NULL, OPTION_RELAX},
13761a11
NC
1234 {"ml", no_argument, NULL, OPTION_LARGE},
1235 {"mN", no_argument, NULL, OPTION_NO_INTR_NOPS},
b18c562e
NC
1236 {NULL, no_argument, NULL, 0}
1237};
2469cfa2 1238
b18c562e 1239size_t md_longopts_size = sizeof (md_longopts);
2469cfa2 1240
b18c562e
NC
1241void
1242md_show_usage (FILE * stream)
2469cfa2 1243{
b18c562e
NC
1244 fprintf (stream,
1245 _("MSP430 options:\n"
638d3803
NC
1246 " -mmcu=<msp430-name> - select microcontroller type\n"
1247 " -mcpu={430|430x|430xv2} - select microcontroller architecture\n"));
77592908
DD
1248 fprintf (stream,
1249 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
1250 " -mP - enable polymorph instructions\n"));
13761a11
NC
1251 fprintf (stream,
1252 _(" -ml - enable large code model\n"));
1253 fprintf (stream,
1254 _(" -mN - disable generation of NOP after changing interrupts\n"));
2469cfa2 1255
b18c562e
NC
1256 show_mcu_list (stream);
1257}
2469cfa2 1258
b18c562e
NC
1259symbolS *
1260md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
1261{
13761a11 1262 return NULL;
2469cfa2
NC
1263}
1264
1265static char *
b18c562e 1266extract_cmd (char * from, char * to, int limit)
2469cfa2
NC
1267{
1268 int size = 0;
1269
1270 while (*from && ! ISSPACE (*from) && *from != '.' && limit > size)
1271 {
1272 *(to + size) = *from;
1273 from++;
1274 size++;
1275 }
1276
1277 *(to + size) = 0;
1278
1279 return from;
1280}
1281
2469cfa2 1282char *
b18c562e 1283md_atof (int type, char * litP, int * sizeP)
2469cfa2 1284{
499ac353 1285 return ieee_md_atof (type, litP, sizeP, FALSE);
2469cfa2
NC
1286}
1287
1288void
b18c562e 1289md_begin (void)
2469cfa2 1290{
b18c562e 1291 struct msp430_opcode_s * opcode;
2469cfa2
NC
1292 msp430_hash = hash_new ();
1293
1294 for (opcode = msp430_opcodes; opcode->name; opcode++)
1295 hash_insert (msp430_hash, opcode->name, (char *) opcode);
1296
638d3803
NC
1297 bfd_set_arch_mach (stdoutput, TARGET_ARCH,
1298 target_is_430x () ? bfd_mach_msp430x : bfd_mach_msp11);
2469cfa2
NC
1299}
1300
13761a11
NC
1301/* Returns the register number equivalent to the string T.
1302 Returns -1 if there is no such register.
1303 Skips a leading 'r' or 'R' character if there is one.
1304 Handles the register aliases PC and SP. */
1305
1306static signed int
b18c562e 1307check_reg (char * t)
2469cfa2 1308{
13761a11 1309 signed int val;
2469cfa2 1310
13761a11
NC
1311 if (t == NULL)
1312 return -1;
2469cfa2 1313
13761a11
NC
1314 if (*t == 'r' || *t == 'R')
1315 ++t;
1316
1317 if (strncasecmp (t, "pc", 2) == 0)
1318 return 0;
2469cfa2 1319
13761a11 1320 if (strncasecmp (t, "sp", 2) == 0)
b18c562e 1321 return 1;
2469cfa2 1322
13761a11
NC
1323 if (strncasecmp (t, "sr", 2) == 0)
1324 return 2;
1325
1326 if (*t == '0')
1327 return 0;
2469cfa2 1328
13761a11
NC
1329 val = atoi (t);
1330
1331 if (val < 1 || val > 15)
1332 return -1;
1333
1334 return val;
1335}
2469cfa2 1336
b18c562e
NC
1337static int
1338msp430_srcoperand (struct msp430_operand_s * op,
13761a11
NC
1339 char * l,
1340 int bin,
1341 int * imm_op,
1342 bfd_boolean allow_20bit_values,
1343 bfd_boolean constants_allowed)
2469cfa2 1344{
b18c562e 1345 char *__tl = l;
2469cfa2 1346
b18c562e
NC
1347 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
1348 if (*l == '#')
2469cfa2 1349 {
b18c562e
NC
1350 char *h = l;
1351 int vshift = -1;
1352 int rval = 0;
2469cfa2 1353
b18c562e
NC
1354 /* Check if there is:
1355 llo(x) - least significant 16 bits, x &= 0xffff
1356 lhi(x) - x = (x >> 16) & 0xffff,
1357 hlo(x) - x = (x >> 32) & 0xffff,
1358 hhi(x) - x = (x >> 48) & 0xffff
1359 The value _MUST_ be constant expression: #hlo(1231231231). */
2469cfa2 1360
b18c562e 1361 *imm_op = 1;
2469cfa2 1362
b18c562e
NC
1363 if (strncasecmp (h, "#llo(", 5) == 0)
1364 {
1365 vshift = 0;
1366 rval = 3;
1367 }
1368 else if (strncasecmp (h, "#lhi(", 5) == 0)
1369 {
1370 vshift = 1;
1371 rval = 3;
1372 }
1373 else if (strncasecmp (h, "#hlo(", 5) == 0)
1374 {
1375 vshift = 2;
1376 rval = 3;
1377 }
1378 else if (strncasecmp (h, "#hhi(", 5) == 0)
1379 {
1380 vshift = 3;
1381 rval = 3;
1382 }
1383 else if (strncasecmp (h, "#lo(", 4) == 0)
1384 {
1385 vshift = 0;
1386 rval = 2;
1387 }
1388 else if (strncasecmp (h, "#hi(", 4) == 0)
1389 {
1390 vshift = 1;
1391 rval = 2;
1392 }
2469cfa2 1393
b18c562e
NC
1394 op->reg = 0; /* Reg PC. */
1395 op->am = 3;
1396 op->ol = 1; /* Immediate will follow an instruction. */
1397 __tl = h + 1 + rval;
1398 op->mode = OP_EXP;
2469cfa2 1399
b18c562e
NC
1400 parse_exp (__tl, &(op->exp));
1401 if (op->exp.X_op == O_constant)
2469cfa2 1402 {
b18c562e 1403 int x = op->exp.X_add_number;
2469cfa2 1404
b18c562e 1405 if (vshift == 0)
2469cfa2 1406 {
b18c562e
NC
1407 x = x & 0xffff;
1408 op->exp.X_add_number = x;
1409 }
1410 else if (vshift == 1)
1411 {
1412 x = (x >> 16) & 0xffff;
1413 op->exp.X_add_number = x;
1414 }
1415 else if (vshift > 1)
1416 {
1417 if (x < 0)
1418 op->exp.X_add_number = -1;
2469cfa2 1419 else
b18c562e
NC
1420 op->exp.X_add_number = 0; /* Nothing left. */
1421 x = op->exp.X_add_number;
2469cfa2 1422 }
2469cfa2 1423
13761a11
NC
1424 if (allow_20bit_values)
1425 {
1426 if (op->exp.X_add_number > 0xfffff || op->exp.X_add_number < - (0x7ffff))
1427 {
1428 as_bad (_("value 0x%x out of extended range."), x);
1429 return 1;
1430 }
1431 }
1432 else if (op->exp.X_add_number > 65535 || op->exp.X_add_number < -32768)
b18c562e
NC
1433 {
1434 as_bad (_("value %d out of range. Use #lo() or #hi()"), x);
1435 return 1;
1436 }
2469cfa2 1437
b18c562e
NC
1438 /* Now check constants. */
1439 /* Substitute register mode with a constant generator if applicable. */
2469cfa2 1440
13761a11
NC
1441 if (!allow_20bit_values)
1442 x = (short) x; /* Extend sign. */
2469cfa2 1443
13761a11
NC
1444 if (! constants_allowed)
1445 ;
1446 else if (x == 0)
2469cfa2 1447 {
b18c562e
NC
1448 op->reg = 3;
1449 op->am = 0;
1450 op->ol = 0;
1451 op->mode = OP_REG;
1452 }
1453 else if (x == 1)
1454 {
1455 op->reg = 3;
1456 op->am = 1;
1457 op->ol = 0;
1458 op->mode = OP_REG;
1459 }
1460 else if (x == 2)
1461 {
1462 op->reg = 3;
1463 op->am = 2;
1464 op->ol = 0;
1465 op->mode = OP_REG;
1466 }
1467 else if (x == -1)
1468 {
1469 op->reg = 3;
1470 op->am = 3;
1471 op->ol = 0;
1472 op->mode = OP_REG;
1473 }
1474 else if (x == 4)
1475 {
1476#ifdef PUSH_1X_WORKAROUND
1477 if (bin == 0x1200)
1478 {
1479 /* Remove warning as confusing.
20203fb9 1480 as_warn (_("Hardware push bug workaround")); */
b18c562e
NC
1481 }
1482 else
1483#endif
1484 {
1485 op->reg = 2;
1486 op->am = 2;
1487 op->ol = 0;
1488 op->mode = OP_REG;
1489 }
1490 }
1491 else if (x == 8)
1492 {
1493#ifdef PUSH_1X_WORKAROUND
1494 if (bin == 0x1200)
1495 {
1496 /* Remove warning as confusing.
20203fb9 1497 as_warn (_("Hardware push bug workaround")); */
b18c562e
NC
1498 }
1499 else
1500#endif
1501 {
1502 op->reg = 2;
1503 op->am = 3;
1504 op->ol = 0;
1505 op->mode = OP_REG;
1506 }
2469cfa2 1507 }
2469cfa2 1508 }
b18c562e
NC
1509 else if (op->exp.X_op == O_symbol)
1510 {
1511 op->mode = OP_EXP;
1512 }
1513 else if (op->exp.X_op == O_big)
1514 {
1515 short x;
1516 if (vshift != -1)
1517 {
1518 op->exp.X_op = O_constant;
1519 op->exp.X_add_number = 0xffff & generic_bignum[vshift];
1520 x = op->exp.X_add_number;
1521 }
1522 else
1523 {
1524 as_bad (_
1525 ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "),
1526 l);
1527 return 1;
1528 }
2469cfa2 1529
b18c562e
NC
1530 if (x == 0)
1531 {
1532 op->reg = 3;
1533 op->am = 0;
1534 op->ol = 0;
1535 op->mode = OP_REG;
1536 }
1537 else if (x == 1)
1538 {
1539 op->reg = 3;
1540 op->am = 1;
1541 op->ol = 0;
1542 op->mode = OP_REG;
1543 }
1544 else if (x == 2)
1545 {
1546 op->reg = 3;
1547 op->am = 2;
1548 op->ol = 0;
1549 op->mode = OP_REG;
1550 }
1551 else if (x == -1)
1552 {
1553 op->reg = 3;
1554 op->am = 3;
1555 op->ol = 0;
1556 op->mode = OP_REG;
1557 }
1558 else if (x == 4)
1559 {
1560 op->reg = 2;
1561 op->am = 2;
1562 op->ol = 0;
1563 op->mode = OP_REG;
1564 }
1565 else if (x == 8)
1566 {
1567 op->reg = 2;
1568 op->am = 3;
1569 op->ol = 0;
1570 op->mode = OP_REG;
1571 }
1572 }
79cf5950 1573 /* Redundant (yet) check. */
b18c562e
NC
1574 else if (op->exp.X_op == O_register)
1575 as_bad
1576 (_("Registers cannot be used within immediate expression [%s]"), l);
1577 else
1578 as_bad (_("unknown operand %s"), l);
2469cfa2 1579
b18c562e
NC
1580 return 0;
1581 }
2469cfa2 1582
b18c562e
NC
1583 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
1584 if (*l == '&')
1585 {
1586 char *h = l;
2469cfa2 1587
b18c562e
NC
1588 op->reg = 2; /* reg 2 in absolute addr mode. */
1589 op->am = 1; /* mode As == 01 bin. */
1590 op->ol = 1; /* Immediate value followed by instruction. */
1591 __tl = h + 1;
1592 parse_exp (__tl, &(op->exp));
1593 op->mode = OP_EXP;
1594 if (op->exp.X_op == O_constant)
2469cfa2 1595 {
b18c562e 1596 int x = op->exp.X_add_number;
2469cfa2 1597
13761a11
NC
1598 if (allow_20bit_values)
1599 {
1600 if (x > 0xfffff || x < -(0x7ffff))
1601 {
1602 as_bad (_("value 0x%x out of extended range."), x);
1603 return 1;
1604 }
1605 }
1606 else if (x > 65535 || x < -32768)
b18c562e 1607 {
13761a11 1608 as_bad (_("value out of range: 0x%x"), x);
b18c562e
NC
1609 return 1;
1610 }
2469cfa2 1611 }
b18c562e
NC
1612 else if (op->exp.X_op == O_symbol)
1613 ;
1614 else
2469cfa2 1615 {
79cf5950 1616 /* Redundant (yet) check. */
b18c562e
NC
1617 if (op->exp.X_op == O_register)
1618 as_bad
1619 (_("Registers cannot be used within absolute expression [%s]"), l);
2469cfa2 1620 else
b18c562e
NC
1621 as_bad (_("unknown expression in operand %s"), l);
1622 return 1;
2469cfa2 1623 }
b18c562e
NC
1624 return 0;
1625 }
2469cfa2 1626
b18c562e
NC
1627 /* Check if indirect register mode @Rn / postincrement @Rn+. */
1628 if (*l == '@')
1629 {
1630 char *t = l;
1631 char *m = strchr (l, '+');
1632
1633 if (t != l)
2469cfa2 1634 {
b18c562e
NC
1635 as_bad (_("unknown addressing mode %s"), l);
1636 return 1;
2469cfa2
NC
1637 }
1638
b18c562e 1639 t++;
2469cfa2 1640
13761a11 1641 if ((op->reg = check_reg (t)) == -1)
2469cfa2 1642 {
13761a11 1643 as_bad (_("Bad register name %s"), t);
b18c562e 1644 return 1;
2469cfa2 1645 }
2469cfa2 1646
b18c562e
NC
1647 op->mode = OP_REG;
1648 op->am = m ? 3 : 2;
1649 op->ol = 0;
2469cfa2 1650
d1706f38
NC
1651 /* PC cannot be used in indirect addressing. */
1652 if (target_is_430xv2 () && op->reg == 0)
1653 {
1654 as_bad (_("cannot use indirect addressing with the PC"));
1655 return 1;
1656 }
b18c562e
NC
1657 return 0;
1658 }
2469cfa2 1659
b18c562e
NC
1660 /* Check if register indexed X(Rn). */
1661 do
1662 {
1663 char *h = strrchr (l, '(');
1664 char *m = strrchr (l, ')');
1665 char *t;
2469cfa2 1666
b18c562e 1667 *imm_op = 1;
2469cfa2 1668
b18c562e
NC
1669 if (!h)
1670 break;
1671 if (!m)
1672 {
1673 as_bad (_("')' required"));
1674 return 1;
1675 }
2469cfa2 1676
b18c562e
NC
1677 t = h;
1678 op->am = 1;
1679 op->ol = 1;
2469cfa2 1680
13761a11
NC
1681 /* Extract a register. */
1682 if ((op->reg = check_reg (t + 1)) == -1)
b18c562e
NC
1683 {
1684 as_bad (_
1685 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
1686 l);
1687 return 1;
1688 }
2469cfa2 1689
13761a11 1690 if (op->reg == 2)
b18c562e 1691 {
13761a11 1692 as_bad (_("r2 should not be used in indexed addressing mode"));
b18c562e
NC
1693 return 1;
1694 }
b18c562e
NC
1695
1696 /* Extract constant. */
1697 __tl = l;
1698 *h = 0;
1699 op->mode = OP_EXP;
1700 parse_exp (__tl, &(op->exp));
1701 if (op->exp.X_op == O_constant)
1702 {
1703 int x = op->exp.X_add_number;
1704
13761a11
NC
1705 if (allow_20bit_values)
1706 {
1707 if (x > 0xfffff || x < - (0x7ffff))
1708 {
1709 as_bad (_("value 0x%x out of extended range."), x);
1710 return 1;
1711 }
1712 }
1713 else if (x > 65535 || x < -32768)
2469cfa2 1714 {
13761a11 1715 as_bad (_("value out of range: 0x%x"), x);
b18c562e 1716 return 1;
2469cfa2 1717 }
b18c562e
NC
1718
1719 if (x == 0)
2469cfa2 1720 {
b18c562e
NC
1721 op->mode = OP_REG;
1722 op->am = 2;
1723 op->ol = 0;
1724 return 0;
2469cfa2
NC
1725 }
1726 }
b18c562e
NC
1727 else if (op->exp.X_op == O_symbol)
1728 ;
2469cfa2
NC
1729 else
1730 {
79cf5950 1731 /* Redundant (yet) check. */
b18c562e
NC
1732 if (op->exp.X_op == O_register)
1733 as_bad
1734 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l);
1735 else
1736 as_bad (_("unknown expression in operand %s"), l);
1737 return 1;
2469cfa2 1738 }
2469cfa2 1739
b18c562e 1740 return 0;
2469cfa2 1741 }
b18c562e 1742 while (0);
2469cfa2 1743
13761a11
NC
1744 /* Possibly register mode 'mov r1,r2'. */
1745 if ((op->reg = check_reg (l)) != -1)
b18c562e 1746 {
13761a11
NC
1747 op->mode = OP_REG;
1748 op->am = 0;
1749 op->ol = 0;
1750 return 0;
b18c562e 1751 }
b18c562e
NC
1752
1753 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
1754 do
1755 {
b18c562e
NC
1756 op->mode = OP_EXP;
1757 op->reg = 0; /* PC relative... be careful. */
13761a11
NC
1758 /* An expression starting with a minus sign is a constant, not an address. */
1759 op->am = (*l == '-' ? 3 : 1);
b18c562e
NC
1760 op->ol = 1;
1761 __tl = l;
1762 parse_exp (__tl, &(op->exp));
1763 return 0;
1764 }
1765 while (0);
1766
1767 /* Unreachable. */
1768 as_bad (_("unknown addressing mode for operand %s"), l);
1769 return 1;
2469cfa2
NC
1770}
1771
b18c562e 1772
2469cfa2 1773static int
13761a11
NC
1774msp430_dstoperand (struct msp430_operand_s * op,
1775 char * l,
1776 int bin,
1777 bfd_boolean allow_20bit_values,
1778 bfd_boolean constants_allowed)
2469cfa2
NC
1779{
1780 int dummy;
13761a11
NC
1781 int ret = msp430_srcoperand (op, l, bin, & dummy,
1782 allow_20bit_values,
1783 constants_allowed);
b18c562e 1784
2469cfa2
NC
1785 if (ret)
1786 return ret;
1787
1788 if (op->am == 2)
1789 {
1790 char *__tl = "0";
1791
1792 op->mode = OP_EXP;
1793 op->am = 1;
1794 op->ol = 1;
1795 parse_exp (__tl, &(op->exp));
b18c562e 1796
2469cfa2
NC
1797 if (op->exp.X_op != O_constant || op->exp.X_add_number != 0)
1798 {
1799 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
1800 op->reg, op->reg);
1801 return 1;
1802 }
1803 return 0;
1804 }
1805
1806 if (op->am > 1)
1807 {
1808 as_bad (_
1809 ("this addressing mode is not applicable for destination operand"));
1810 return 1;
1811 }
1812 return 0;
1813}
1814
1815
13761a11
NC
1816/* Attempt to encode a MOVA instruction with the given operands.
1817 Returns the length of the encoded instruction if successful
1818 or 0 upon failure. If the encoding fails, an error message
1819 will be returned if a pointer is provided. */
1820
1821static int
1822try_encode_mova (bfd_boolean imm_op,
1823 int bin,
1824 struct msp430_operand_s * op1,
1825 struct msp430_operand_s * op2,
1826 const char ** error_message_return)
1827{
1828 short ZEROS = 0;
1829 char *frag;
1830 int where;
1831
1832 /* Only a restricted subset of the normal MSP430 addressing modes
1833 are supported here, so check for the ones that are allowed. */
1834 if (imm_op)
1835 {
1836 if (op1->mode == OP_EXP)
1837 {
1838 if (op2->mode != OP_REG)
1839 {
1840 if (error_message_return != NULL)
1841 * error_message_return = _("expected register as second argument of %s");
1842 return 0;
1843 }
1844
1845 if (op1->am == 3)
1846 {
1847 /* MOVA #imm20, Rdst. */
1848 bin |= 0x80 | op2->reg;
1849 frag = frag_more (4);
1850 where = frag - frag_now->fr_literal;
1851 if (op1->exp.X_op == O_constant)
1852 {
1853 bin |= ((op1->exp.X_add_number >> 16) & 0xf) << 8;
1854 bfd_putl16 ((bfd_vma) bin, frag);
1855 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
1856 }
1857 else
1858 {
1859 bfd_putl16 ((bfd_vma) bin, frag);
1860 fix_new_exp (frag_now, where, 4, &(op1->exp), FALSE,
1861 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
1862 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1863 }
1864
1865 return 4;
1866 }
1867 else if (op1->am == 1)
1868 {
1869 /* MOVA z16(Rsrc), Rdst. */
1870 bin |= 0x30 | (op1->reg << 8) | op2->reg;
1871 frag = frag_more (4);
1872 where = frag - frag_now->fr_literal;
1873 bfd_putl16 ((bfd_vma) bin, frag);
1874 if (op1->exp.X_op == O_constant)
1875 {
1876 if (op1->exp.X_add_number > 0xffff
1877 || op1->exp.X_add_number < -(0x7fff))
1878 {
1879 if (error_message_return != NULL)
1880 * error_message_return = _("index value too big for %s");
1881 return 0;
1882 }
1883 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
1884 }
1885 else
1886 {
1887 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1888 fix_new_exp (frag_now, where + 2, 2, &(op1->exp), FALSE,
1889 op1->reg == 0 ?
1890 BFD_RELOC_MSP430X_PCR16 :
1891 BFD_RELOC_MSP430X_ABS16);
1892 }
1893 return 4;
1894 }
1895
1896 if (error_message_return != NULL)
1897 * error_message_return = _("unexpected addressing mode for %s");
1898 return 0;
1899 }
1900 else if (op1->am == 0)
1901 {
1902 /* MOVA Rsrc, ... */
1903 if (op2->mode == OP_REG)
1904 {
1905 bin |= 0xc0 | (op1->reg << 8) | op2->reg;
1906 frag = frag_more (2);
1907 where = frag - frag_now->fr_literal;
1908 bfd_putl16 ((bfd_vma) bin, frag);
1909 return 2;
1910 }
1911 else if (op2->am == 1)
1912 {
1913 if (op2->reg == 2)
1914 {
1915 /* MOVA Rsrc, &abs20. */
1916 bin |= 0x60 | (op1->reg << 8);
1917 frag = frag_more (4);
1918 where = frag - frag_now->fr_literal;
1919 if (op2->exp.X_op == O_constant)
1920 {
1921 bin |= (op2->exp.X_add_number >> 16) & 0xf;
1922 bfd_putl16 ((bfd_vma) bin, frag);
1923 bfd_putl16 (op2->exp.X_add_number & 0xffff, frag + 2);
1924 }
1925 else
1926 {
1927 bfd_putl16 ((bfd_vma) bin, frag);
1928 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1929 fix_new_exp (frag_now, where, 4, &(op2->exp), FALSE,
1930 BFD_RELOC_MSP430X_ABS20_ADR_DST);
1931 }
1932 return 4;
1933 }
1934
1935 /* MOVA Rsrc, z16(Rdst). */
1936 bin |= 0x70 | (op1->reg << 8) | op2->reg;
1937 frag = frag_more (4);
1938 where = frag - frag_now->fr_literal;
1939 bfd_putl16 ((bfd_vma) bin, frag);
1940 if (op2->exp.X_op == O_constant)
1941 {
1942 if (op2->exp.X_add_number > 0xffff
1943 || op2->exp.X_add_number < -(0x7fff))
1944 {
1945 if (error_message_return != NULL)
1946 * error_message_return = _("index value too big for %s");
1947 return 0;
1948 }
1949 bfd_putl16 (op2->exp.X_add_number & 0xffff, frag + 2);
1950 }
1951 else
1952 {
1953 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1954 fix_new_exp (frag_now, where + 2, 2, &(op2->exp), FALSE,
1955 op2->reg == 0 ?
1956 BFD_RELOC_MSP430X_PCR16 :
1957 BFD_RELOC_MSP430X_ABS16);
1958 }
1959 return 4;
1960 }
1961
1962 if (error_message_return != NULL)
1963 * error_message_return = _("unexpected addressing mode for %s");
1964 return 0;
1965 }
1966 }
1967
1968 /* imm_op == FALSE. */
1969
1970 if (op1->reg == 2 && op1->am == 1 && op1->mode == OP_EXP)
1971 {
1972 /* MOVA &abs20, Rdst. */
1973 if (op2->mode != OP_REG)
1974 {
1975 if (error_message_return != NULL)
1976 * error_message_return = _("expected register as second argument of %s");
1977 return 0;
1978 }
1979
1980 if (op2->reg == 2 || op2->reg == 3)
1981 {
1982 if (error_message_return != NULL)
1983 * error_message_return = _("constant generator destination register found in %s");
1984 return 0;
1985 }
1986
1987 bin |= 0x20 | op2->reg;
1988 frag = frag_more (4);
1989 where = frag - frag_now->fr_literal;
1990 if (op1->exp.X_op == O_constant)
1991 {
1992 bin |= ((op1->exp.X_add_number >> 16) & 0xf) << 8;
1993 bfd_putl16 ((bfd_vma) bin, frag);
1994 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
1995 }
1996 else
1997 {
1998 bfd_putl16 ((bfd_vma) bin, frag);
1999 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2000 fix_new_exp (frag_now, where, 4, &(op1->exp), FALSE,
2001 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
2002 }
2003 return 4;
2004 }
2005 else if (op1->mode == OP_REG)
2006 {
2007 if (op1->am == 3)
2008 {
2009 /* MOVA @Rsrc+, Rdst. */
2010 if (op2->mode != OP_REG)
2011 {
2012 if (error_message_return != NULL)
2013 * error_message_return = _("expected register as second argument of %s");
2014 return 0;
2015 }
2016
2017 if (op2->reg == 2 || op2->reg == 3)
2018 {
2019 if (error_message_return != NULL)
2020 * error_message_return = _("constant generator destination register found in %s");
2021 return 0;
2022 }
2023
2024 if (op1->reg == 2 || op1->reg == 3)
2025 {
2026 if (error_message_return != NULL)
2027 * error_message_return = _("constant generator source register found in %s");
2028 return 0;
2029 }
2030
2031 bin |= 0x10 | (op1->reg << 8) | op2->reg;
2032 frag = frag_more (2);
2033 where = frag - frag_now->fr_literal;
2034 bfd_putl16 ((bfd_vma) bin, frag);
2035 return 2;
2036 }
2037 else if (op1->am == 2)
2038 {
2039 /* MOVA @Rsrc,Rdst */
2040 if (op2->mode != OP_REG)
2041 {
2042 if (error_message_return != NULL)
2043 * error_message_return = _("expected register as second argument of %s");
2044 return 0;
2045 }
2046
2047 if (op2->reg == 2 || op2->reg == 3)
2048 {
2049 if (error_message_return != NULL)
2050 * error_message_return = _("constant generator destination register found in %s");
2051 return 0;
2052 }
2053
2054 if (op1->reg == 2 || op1->reg == 3)
2055 {
2056 if (error_message_return != NULL)
2057 * error_message_return = _("constant generator source register found in %s");
2058 return 0;
2059 }
2060
2061 bin |= (op1->reg << 8) | op2->reg;
2062 frag = frag_more (2);
2063 where = frag - frag_now->fr_literal;
2064 bfd_putl16 ((bfd_vma) bin, frag);
2065 return 2;
2066 }
2067 }
2068
2069 if (error_message_return != NULL)
2070 * error_message_return = _("unexpected addressing mode for %s");
2071
2072 return 0;
2073}
2074
638d3803
NC
2075#define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0)
2076
b18c562e
NC
2077/* Parse instruction operands.
2078 Return binary opcode. */
2079
2080static unsigned int
2081msp430_operands (struct msp430_opcode_s * opcode, char * line)
2469cfa2 2082{
b18c562e 2083 int bin = opcode->bin_opcode; /* Opcode mask. */
13761a11 2084 int insn_length = 0;
b18c562e
NC
2085 char l1[MAX_OP_LEN], l2[MAX_OP_LEN];
2086 char *frag;
2087 int where;
2088 struct msp430_operand_s op1, op2;
2089 int res = 0;
2090 static short ZEROS = 0;
2091 int byte_op, imm_op;
13761a11
NC
2092 int op_length = 0;
2093 int fmt;
2094 int extended = 0x1800;
2095 bfd_boolean extended_op = FALSE;
2096 bfd_boolean addr_op;
2097 const char * error_message;
2098 static signed int repeat_count = 0;
2099 bfd_boolean fix_emitted;
2469cfa2 2100
b18c562e
NC
2101 /* Opcode is the one from opcodes table
2102 line contains something like
2103 [.w] @r2+, 5(R1)
2104 or
2105 .b @r2+, 5(R1). */
2469cfa2 2106
b18c562e
NC
2107 /* Check if byte or word operation. */
2108 if (*line == '.' && TOLOWER (*(line + 1)) == 'b')
2469cfa2 2109 {
b18c562e
NC
2110 bin |= BYTE_OPERATION;
2111 byte_op = 1;
2469cfa2 2112 }
b18c562e
NC
2113 else
2114 byte_op = 0;
2469cfa2 2115
13761a11
NC
2116 /* "Address" ops work on 20-bit values. */
2117 if (*line == '.' && TOLOWER (*(line + 1)) == 'a')
2118 {
2119 addr_op = TRUE;
2120 bin |= BYTE_OPERATION;
2121 }
2122 else
2123 addr_op = FALSE;
2124
2125 /* skip .[aAbwBW]. */
b18c562e
NC
2126 while (! ISSPACE (*line) && *line)
2127 line++;
2469cfa2 2128
13761a11
NC
2129 if (opcode->fmt != -1
2130 && opcode->insn_opnumb
2131 && (!*line || *line == '\n'))
2469cfa2 2132 {
b18c562e
NC
2133 as_bad (_("instruction %s requires %d operand(s)"),
2134 opcode->name, opcode->insn_opnumb);
2135 return 0;
2136 }
2469cfa2 2137
b18c562e
NC
2138 memset (l1, 0, sizeof (l1));
2139 memset (l2, 0, sizeof (l2));
2140 memset (&op1, 0, sizeof (op1));
2141 memset (&op2, 0, sizeof (op2));
2469cfa2 2142
b18c562e 2143 imm_op = 0;
2469cfa2 2144
13761a11
NC
2145 if ((fmt = opcode->fmt) < 0)
2146 {
638d3803 2147 if (! target_is_430x ())
13761a11
NC
2148 {
2149 as_bad (_("instruction %s requires MSP430X mcu"),
2150 opcode->name);
2151 return 0;
2152 }
638d3803 2153
13761a11
NC
2154 fmt = (-fmt) - 1;
2155 extended_op = TRUE;
2156 }
2157
2158 if (repeat_count)
2159 {
2160 /* If requested set the extended instruction repeat count. */
2161 if (extended_op)
2162 {
2163 if (repeat_count > 0)
2164 extended |= (repeat_count - 1);
2165 else
2166 extended |= (1 << 7) | (- repeat_count);
2167 }
2168 else
2169 as_bad (_("unable to repeat %s insn"), opcode->name);
2170
2171 repeat_count = 0;
2172 }
2173
2174 switch (fmt)
b18c562e
NC
2175 {
2176 case 0: /* Emulated. */
2177 switch (opcode->insn_opnumb)
2469cfa2 2178 {
b18c562e
NC
2179 case 0:
2180 /* Set/clear bits instructions. */
13761a11
NC
2181 if (extended_op)
2182 {
2183 if (!addr_op)
2184 extended |= BYTE_OPERATION;
2185
2186 /* Emit the extension word. */
2187 insn_length += 2;
2188 frag = frag_more (insn_length);
2189 bfd_putl16 (extended, frag);
2190 }
638d3803 2191
13761a11
NC
2192 insn_length += 2;
2193 frag = frag_more (insn_length);
b18c562e 2194 bfd_putl16 ((bfd_vma) bin, frag);
13761a11
NC
2195
2196 if (gen_interrupt_nops
638d3803
NC
2197 && target_is_430xv2 ()
2198 && (is_opcode ("eint") || is_opcode ("dint")))
13761a11
NC
2199 {
2200 /* Emit a NOP following interrupt enable/disable.
2201 See 1.3.4.1 of the MSP430x5xx User Guide. */
2202 insn_length += 2;
2203 frag = frag_more (2);
2204 bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
2205 }
13761a11 2206 dwarf2_emit_insn (insn_length);
b18c562e 2207 break;
13761a11 2208
b18c562e
NC
2209 case 1:
2210 /* Something which works with destination operand. */
2211 line = extract_operand (line, l1, sizeof (l1));
13761a11 2212 res = msp430_dstoperand (&op1, l1, opcode->bin_opcode, extended_op, TRUE);
b18c562e
NC
2213 if (res)
2214 break;
2469cfa2 2215
13761a11
NC
2216 /* Compute the entire instruction length, in bytes. */
2217 insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
2218 frag = frag_more (insn_length);
b18c562e 2219 where = frag - frag_now->fr_literal;
638d3803 2220
13761a11 2221 if (extended_op)
2469cfa2 2222 {
13761a11
NC
2223 if (!addr_op)
2224 extended |= BYTE_OPERATION;
2225
2226 if (op1.ol != 0 && ((extended & 0xf) != 0))
2227 {
2228 as_bad (_("repeat instruction used with non-register mode instruction"));
2229 extended &= ~ 0xf;
2230 }
638d3803 2231
13761a11
NC
2232 if (op1.mode == OP_EXP)
2233 {
2234 if (op1.exp.X_op == O_constant)
2235 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
2236
2237 else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
2238 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2239 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
2240 else
2241 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2242 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
2243 }
638d3803 2244
13761a11
NC
2245 /* Emit the extension word. */
2246 bfd_putl16 (extended, frag);
2247 frag += 2;
2248 where += 2;
2249 }
2250
2251 bin |= (op1.reg | (op1.am << 7));
2252 bfd_putl16 ((bfd_vma) bin, frag);
2253 frag += 2;
2254 where += 2;
2255
2256 if (op1.mode == OP_EXP)
2257 {
2258 if (op1.exp.X_op == O_constant)
2259 {
2260 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
2261 }
2469cfa2 2262 else
13761a11
NC
2263 {
2264 bfd_putl16 ((bfd_vma) ZEROS, frag);
2265
2266 if (!extended_op)
2267 {
2268 if (op1.reg)
2269 fix_new_exp (frag_now, where, 2,
2270 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
2271 else
2272 fix_new_exp (frag_now, where, 2,
2273 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2274 }
2275 }
2276 }
2277
2278 if (gen_interrupt_nops
638d3803
NC
2279 && target_is_430xv2 ()
2280 && is_opcode ("clr")
13761a11
NC
2281 && bin == 0x4302 /* CLR R2*/)
2282 {
2283 /* Emit a NOP following interrupt enable/disable.
2284 See 1.3.4.1 of the MSP430x5xx User Guide. */
2285 insn_length += 2;
2286 frag = frag_more (2);
2287 bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
2469cfa2 2288 }
13761a11
NC
2289
2290 dwarf2_emit_insn (insn_length);
b18c562e 2291 break;
2469cfa2 2292
b18c562e 2293 case 2:
13761a11
NC
2294 /* Shift instruction. */
2295 line = extract_operand (line, l1, sizeof (l1));
2296 strncpy (l2, l1, sizeof (l2));
2297 l2[sizeof (l2) - 1] = '\0';
2298 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, TRUE);
2299 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, extended_op, TRUE);
2300
2301 if (res)
2302 break; /* An error occurred. All warnings were done before. */
2303
2304 insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2) + (op2.ol * 2);
2305 frag = frag_more (insn_length);
2306 where = frag - frag_now->fr_literal;
2307
d1706f38
NC
2308 if (target_is_430xv2 ()
2309 && op1.mode == OP_REG
638d3803
NC
2310 && op1.reg == 0
2311 && (is_opcode ("rlax")
2312 || is_opcode ("rlcx")
2313 || is_opcode ("rla")
2314 || is_opcode ("rlc")))
2315 {
2316 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
2317 return 0;
2318 }
2319
13761a11
NC
2320 if (extended_op)
2321 {
2322 if (!addr_op)
2323 extended |= BYTE_OPERATION;
2324
2325 if ((op1.ol != 0 || op2.ol != 0) && ((extended & 0xf) != 0))
2326 {
2327 as_bad (_("repeat instruction used with non-register mode instruction"));
2328 extended &= ~ 0xf;
2329 }
638d3803 2330
13761a11
NC
2331 if (op1.mode == OP_EXP)
2332 {
2333 if (op1.exp.X_op == O_constant)
2334 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
2335
2336 else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
2337 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2338 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
2339 else
2340 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2341 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
2342 }
2343
2344 if (op2.mode == OP_EXP)
2345 {
2346 if (op2.exp.X_op == O_constant)
2347 extended |= (op2.exp.X_add_number >> 16) & 0xf;
2348
2349 else if (op1.mode == OP_EXP)
2350 fix_new_exp (frag_now, where, 8, &(op2.exp), FALSE,
2351 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_ODST
2352 : BFD_RELOC_MSP430X_PCR20_EXT_ODST);
2353 else
2354 fix_new_exp (frag_now, where, 6, &(op2.exp), FALSE,
2355 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_DST
2356 : BFD_RELOC_MSP430X_PCR20_EXT_DST);
2357 }
2358
2359 /* Emit the extension word. */
2360 bfd_putl16 (extended, frag);
2361 frag += 2;
2362 where += 2;
2363 }
2364
2365 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
2366 bfd_putl16 ((bfd_vma) bin, frag);
2367 frag += 2;
2368 where += 2;
2369
2370 if (op1.mode == OP_EXP)
2371 {
2372 if (op1.exp.X_op == O_constant)
2373 {
2374 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
2375 }
2376 else
2377 {
2378 bfd_putl16 ((bfd_vma) ZEROS, frag);
2379
2380 if (!extended_op)
2381 {
2382 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
2383 fix_new_exp (frag_now, where, 2,
2384 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
2385 else
2386 fix_new_exp (frag_now, where, 2,
2387 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2388 }
2389 }
2390 frag += 2;
2391 where += 2;
2392 }
2393
2394 if (op2.mode == OP_EXP)
2395 {
2396 if (op2.exp.X_op == O_constant)
2397 {
2398 bfd_putl16 (op2.exp.X_add_number & 0xffff, frag);
2399 }
2400 else
2401 {
2402 bfd_putl16 ((bfd_vma) ZEROS, frag);
2403
2404 if (!extended_op)
2405 {
2406 if (op2.reg) /* Not PC relative. */
2407 fix_new_exp (frag_now, where, 2,
2408 &(op2.exp), FALSE, CHECK_RELOC_MSP430);
2409 else
2410 fix_new_exp (frag_now, where, 2,
2411 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2412 }
2413 }
2414 }
2415
2416 dwarf2_emit_insn (insn_length);
2417 break;
2418
2419 case 3:
2420 /* Branch instruction => mov dst, r0. */
2421 if (extended_op)
2422 {
2423 as_bad ("Internal error: state 0/3 not coded for extended instructions");
2424 return 0;
2425 }
2426
2427 line = extract_operand (line, l1, sizeof (l1));
2428 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, FALSE);
2429 if (res)
2430 break;
2431
2432 byte_op = 0;
2433 imm_op = 0;
2434 bin |= ((op1.reg << 8) | (op1.am << 4));
2435 op_length = 2 + 2 * op1.ol;
2436 frag = frag_more (op_length);
2437 where = frag - frag_now->fr_literal;
2438 bfd_putl16 ((bfd_vma) bin, frag);
2439
2440 if (op1.mode == OP_EXP)
2441 {
2442 if (op1.exp.X_op == O_constant)
2443 {
2444 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag + 2);
2445 }
2446 else
2447 {
2448 where += 2;
638d3803 2449
13761a11
NC
2450 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2451
2452 if (op1.reg || (op1.reg == 0 && op1.am == 3))
2453 fix_new_exp (frag_now, where, 2,
2454 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
2455 else
2456 fix_new_exp (frag_now, where, 2,
2457 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2458 }
2459 }
2460
2461 dwarf2_emit_insn (insn_length + op_length);
2462 break;
2463
2464 case 4:
2465 /* CALLA instructions. */
2466 fix_emitted = FALSE;
2467
2468 line = extract_operand (line, l1, sizeof (l1));
2469 imm_op = 0;
2470
2471 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op,
2472 extended_op, FALSE);
2473 if (res)
2474 break;
2475
2476 byte_op = 0;
2477
2478 op_length = 2 + 2 * op1.ol;
2479 frag = frag_more (op_length);
2480 where = frag - frag_now->fr_literal;
2481
2482 if (imm_op)
2483 {
2484 if (op1.am == 3)
2485 {
2486 bin |= 0xb0;
2487
2488 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2489 BFD_RELOC_MSP430X_ABS20_ADR_DST);
2490 fix_emitted = TRUE;
2491 }
2492 else if (op1.am == 1)
2493 {
2494 if (op1.reg == 0)
2495 {
2496 bin |= 0x90;
2497
2498 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2499 BFD_RELOC_MSP430X_PCR20_CALL);
2500 fix_emitted = TRUE;
2501 }
2502 else
2503 bin |= 0x50 | op1.reg;
2504 }
2505 else if (op1.am == 0)
2506 bin |= 0x40 | op1.reg;
2507 }
2508 else if (op1.am == 1)
2509 {
2510 bin |= 0x80;
2511
2512 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2513 BFD_RELOC_MSP430X_ABS20_ADR_DST);
2514 fix_emitted = TRUE;
2515 }
2516 else if (op1.am == 2)
2517 bin |= 0x60 | op1.reg;
2518 else if (op1.am == 3)
2519 bin |= 0x70 | op1.reg;
638d3803 2520
13761a11
NC
2521 bfd_putl16 ((bfd_vma) bin, frag);
2522
2523 if (op1.mode == OP_EXP)
2524 {
2525 if (op1.ol != 1)
2526 {
2527 as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1.ol);
2528 return 0;
2529 }
2530
2531 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2532
2533 if (! fix_emitted)
2534 fix_new_exp (frag_now, where + 2, 2,
2535 &(op1.exp), FALSE, BFD_RELOC_16);
2536 }
2537
2538 dwarf2_emit_insn (insn_length + op_length);
2539 break;
2540
2541 case 5:
b18c562e 2542 {
13761a11
NC
2543 int n;
2544 int reg;
2545
2546 /* [POP|PUSH]M[.A] #N, Rd */
b18c562e 2547 line = extract_operand (line, l1, sizeof (l1));
13761a11 2548 line = extract_operand (line, l2, sizeof (l2));
2469cfa2 2549
13761a11
NC
2550 if (*l1 != '#')
2551 {
638d3803 2552 as_bad (_("expected #n as first argument of %s"), opcode->name);
13761a11
NC
2553 return 0;
2554 }
2555 parse_exp (l1 + 1, &(op1.exp));
2556 if (op1.exp.X_op != O_constant)
2557 {
2558 as_bad (_("expected constant expression for first argument of %s"),
2559 opcode->name);
2560 return 0;
2561 }
2469cfa2 2562
13761a11
NC
2563 if ((reg = check_reg (l2)) == -1)
2564 {
2565 as_bad (_("expected register as second argument of %s"),
2566 opcode->name);
2567 return 0;
2568 }
2469cfa2 2569
13761a11
NC
2570 op_length = 2;
2571 frag = frag_more (op_length);
b18c562e 2572 where = frag - frag_now->fr_literal;
13761a11
NC
2573 bin = opcode->bin_opcode;
2574 if (! addr_op)
2575 bin |= 0x100;
2576 n = op1.exp.X_add_number;
2577 bin |= (n - 1) << 4;
638d3803 2578 if (is_opcode ("pushm"))
13761a11
NC
2579 bin |= reg;
2580 else
2581 {
2582 if (reg - n + 1 < 0)
2583 {
2584 as_bad (_("Too many registers popped"));
2585 return 0;
2586 }
638d3803 2587
d1706f38
NC
2588 /* CPU21 parts cannot use POPM to restore the SR register. */
2589 if (target_is_430xv2 ()
638d3803
NC
2590 && (reg - n + 1 < 3)
2591 && reg >= 2
2592 && is_opcode ("popm"))
2593 {
2594 as_bad (_("Cannot use POPM to restore the SR register"));
2595 return 0;
2596 }
2597
13761a11
NC
2598 bin |= (reg - n + 1);
2599 }
2600
b18c562e 2601 bfd_putl16 ((bfd_vma) bin, frag);
13761a11
NC
2602 dwarf2_emit_insn (op_length);
2603 break;
2604 }
2605
2606 case 6:
2607 {
2608 int n;
2609 int reg;
2610
2611 /* Bit rotation instructions. RRCM, RRAM, RRUM, RLAM. */
2612 if (extended & 0xff)
2613 {
2614 as_bad (_("repeat count cannot be used with %s"), opcode->name);
2615 return 0;
2616 }
2617
2618 line = extract_operand (line, l1, sizeof (l1));
2619 line = extract_operand (line, l2, sizeof (l2));
2620
2621 if (*l1 != '#')
2622 {
2623 as_bad (_("expected #n as first argument of %s"), opcode->name);
2624 return 0;
2625 }
2626 parse_exp (l1 + 1, &(op1.exp));
2627 if (op1.exp.X_op != O_constant)
2628 {
2629 as_bad (_("expected constant expression for first argument of %s"),
2630 opcode->name);
2631 return 0;
2632 }
2633 n = op1.exp.X_add_number;
2634 if (n > 4 || n < 1)
b18c562e 2635 {
13761a11
NC
2636 as_bad (_("expected first argument of %s to be in the range 1-4"),
2637 opcode->name);
2638 return 0;
2639 }
b18c562e 2640
13761a11
NC
2641 if ((reg = check_reg (l2)) == -1)
2642 {
2643 as_bad (_("expected register as second argument of %s"),
2644 opcode->name);
2645 return 0;
b18c562e
NC
2646 }
2647
d1706f38 2648 if (target_is_430xv2 () && reg == 0)
638d3803
NC
2649 {
2650 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
2651 return 0;
2652 }
2653
13761a11
NC
2654 op_length = 2;
2655 frag = frag_more (op_length);
2656 where = frag - frag_now->fr_literal;
2657
2658 bin = opcode->bin_opcode;
2659 if (! addr_op)
2660 bin |= 0x10;
2661 bin |= (n - 1) << 10;
2662 bin |= reg;
2663
2664 bfd_putl16 ((bfd_vma) bin, frag);
2665 dwarf2_emit_insn (op_length);
2666 break;
2667 }
2668
2669 case 7:
2670 {
2671 int reg;
2672
2673 /* RRUX: Synthetic unsigned right shift of a register by one bit. */
2674 if (extended & 0xff)
b18c562e 2675 {
13761a11
NC
2676 as_bad (_("repeat count cannot be used with %s"), opcode->name);
2677 return 0;
2678 }
b18c562e 2679
13761a11
NC
2680 line = extract_operand (line, l1, sizeof (l1));
2681 if ((reg = check_reg (l1)) == -1)
2682 {
2683 as_bad (_("expected register as argument of %s"),
2684 opcode->name);
2685 return 0;
2686 }
2687
d1706f38 2688 if (target_is_430xv2 () && reg == 0)
638d3803
NC
2689 {
2690 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
2691 return 0;
2692 }
2693
13761a11
NC
2694 if (byte_op)
2695 {
2696 /* Tricky - there is no single instruction that will do this.
2697 Encode as: RRA.B rN { BIC.B #0x80, rN */
2698 op_length = 6;
2699 frag = frag_more (op_length);
2700 where = frag - frag_now->fr_literal;
2701 bin = 0x1140 | reg;
2702 bfd_putl16 ((bfd_vma) bin, frag);
2703 dwarf2_emit_insn (2);
2704 bin = 0xc070 | reg;
2705 bfd_putl16 ((bfd_vma) bin, frag + 2);
2706 bin = 0x0080;
2707 bfd_putl16 ((bfd_vma) bin, frag + 4);
2708 dwarf2_emit_insn (4);
2709 }
2710 else
2711 {
2712 /* Encode as RRUM[.A] rN. */
2713 bin = opcode->bin_opcode;
2714 if (! addr_op)
2715 bin |= 0x10;
2716 bin |= reg;
2717 op_length = 2;
2718 frag = frag_more (op_length);
2719 where = frag - frag_now->fr_literal;
2720 bfd_putl16 ((bfd_vma) bin, frag);
2721 dwarf2_emit_insn (op_length);
638d3803 2722 }
b18c562e
NC
2723 break;
2724 }
b18c562e 2725
13761a11
NC
2726 case 8:
2727 {
2728 bfd_boolean need_reloc = FALSE;
2729 int n;
2730 int reg;
2731
2732 /* ADDA, CMPA and SUBA address instructions. */
2733 if (extended & 0xff)
2734 {
2735 as_bad (_("repeat count cannot be used with %s"), opcode->name);
2736 return 0;
2737 }
2738
2739 line = extract_operand (line, l1, sizeof (l1));
2740 line = extract_operand (line, l2, sizeof (l2));
2741
2742 bin = opcode->bin_opcode;
2743
2744 if (*l1 == '#')
2745 {
2746 parse_exp (l1 + 1, &(op1.exp));
2747
2748 if (op1.exp.X_op == O_constant)
2749 {
2750 n = op1.exp.X_add_number;
2751 if (n > 0xfffff || n < - (0x7ffff))
2752 {
2753 as_bad (_("expected value of first argument of %s to fit into 20-bits"),
2754 opcode->name);
2755 return 0;
2756 }
2757
2758 bin |= ((n >> 16) & 0xf) << 8;
2759 }
2760 else
2761 {
2762 n = 0;
2763 need_reloc = TRUE;
2764 }
2765
2766 op_length = 4;
2767 }
2768 else
2769 {
2770 if ((n = check_reg (l1)) == -1)
2771 {
2772 as_bad (_("expected register name or constant as first argument of %s"),
2773 opcode->name);
2774 return 0;
2775 }
2776
2777 bin |= (n << 8) | (1 << 6);
2778 op_length = 2;
2779 }
2780
2781 if ((reg = check_reg (l2)) == -1)
2782 {
2783 as_bad (_("expected register as second argument of %s"),
2784 opcode->name);
2785 return 0;
2786 }
2787
2788 frag = frag_more (op_length);
2789 where = frag - frag_now->fr_literal;
2790 bin |= reg;
2791 if (need_reloc)
2792 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2793 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
2794
2795 bfd_putl16 ((bfd_vma) bin, frag);
2796 if (op_length == 4)
2797 bfd_putl16 ((bfd_vma) (n & 0xffff), frag + 2);
2798 dwarf2_emit_insn (op_length);
b18c562e 2799 break;
13761a11 2800 }
638d3803 2801
13761a11 2802 case 9: /* MOVA, BRA, RETA. */
b18c562e 2803 imm_op = 0;
13761a11 2804 bin = opcode->bin_opcode;
b18c562e 2805
638d3803 2806 if (is_opcode ("reta"))
13761a11
NC
2807 {
2808 /* The RETA instruction does not take any arguments.
2809 The implicit first argument is @SP+.
2810 The implicit second argument is PC. */
2811 op1.mode = OP_REG;
2812 op1.am = 3;
2813 op1.reg = 1;
2814
2815 op2.mode = OP_REG;
2816 op2.reg = 0;
2817 }
2818 else
2819 {
2820 line = extract_operand (line, l1, sizeof (l1));
2821 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode,
2822 &imm_op, extended_op, FALSE);
b18c562e 2823
638d3803 2824 if (is_opcode ("bra"))
13761a11
NC
2825 {
2826 /* This is the BRA synthetic instruction.
2827 The second argument is always PC. */
2828 op2.mode = OP_REG;
2829 op2.reg = 0;
2830 }
2831 else
2832 {
2833 line = extract_operand (line, l2, sizeof (l2));
2834 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode,
2835 extended_op, TRUE);
2836 }
638d3803 2837
13761a11
NC
2838 if (res)
2839 break; /* Error occurred. All warnings were done before. */
2840 }
2841
2842 /* Only a restricted subset of the normal MSP430 addressing modes
2843 are supported here, so check for the ones that are allowed. */
2844 if ((op_length = try_encode_mova (imm_op, bin, & op1, & op2,
2845 & error_message)) == 0)
2469cfa2 2846 {
13761a11
NC
2847 as_bad (error_message, opcode->name);
2848 return 0;
2849 }
2850 dwarf2_emit_insn (op_length);
2851 break;
2852
2853 case 10: /* RPT */
2854 line = extract_operand (line, l1, sizeof l1);
2855 /* The RPT instruction only accepted immediates and registers. */
2856 if (*l1 == '#')
2857 {
2858 parse_exp (l1 + 1, &(op1.exp));
2859 if (op1.exp.X_op != O_constant)
2860 {
2861 as_bad (_("expected constant value as argument to RPT"));
2862 return 0;
2863 }
2864 if (op1.exp.X_add_number < 1
2865 || op1.exp.X_add_number > (1 << 4))
2866 {
2867 as_bad (_("expected constant in the range 2..16"));
2868 return 0;
2869 }
2870
2871 /* We silently accept and ignore a repeat count of 1. */
2872 if (op1.exp.X_add_number > 1)
2873 repeat_count = op1.exp.X_add_number;
2874 }
2875 else
2876 {
2877 int reg;
b18c562e 2878
13761a11
NC
2879 if ((reg = check_reg (l1)) != -1)
2880 {
2881 if (reg == 0)
2882 as_warn (_("PC used as an argument to RPT"));
2883 else
2884 repeat_count = - reg;
2885 }
2469cfa2 2886 else
13761a11
NC
2887 {
2888 as_bad (_("expected constant or register name as argument to RPT insn"));
2889 return 0;
2890 }
2469cfa2 2891 }
b18c562e 2892 break;
13761a11
NC
2893
2894 default:
2895 as_bad (_("Illegal emulated instruction "));
2896 break;
2469cfa2 2897 }
b18c562e 2898 break;
2469cfa2 2899
b18c562e
NC
2900 case 1: /* Format 1, double operand. */
2901 line = extract_operand (line, l1, sizeof (l1));
2902 line = extract_operand (line, l2, sizeof (l2));
13761a11
NC
2903 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, TRUE);
2904 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, extended_op, TRUE);
2469cfa2 2905
b18c562e
NC
2906 if (res)
2907 break; /* Error occurred. All warnings were done before. */
2469cfa2 2908
13761a11 2909 if (extended_op
638d3803 2910 && is_opcode ("movx")
13761a11
NC
2911 && addr_op
2912 && msp430_enable_relax)
2913 {
2914 /* This is the MOVX.A instruction. See if we can convert
2915 it into the MOVA instruction instead. This saves 2 bytes. */
2916 if ((op_length = try_encode_mova (imm_op, 0x0000, & op1, & op2,
2917 NULL)) != 0)
2918 {
2919 dwarf2_emit_insn (op_length);
2920 break;
2921 }
2922 }
2923
2924 /* Compute the entire length of the instruction in bytes. */
2925 insn_length =
2926 (extended_op ? 2 : 0) /* The extension word. */
2927 + 2 /* The opcode */
2928 + (2 * op1.ol) /* The first operand. */
2929 + (2 * op2.ol); /* The second operand. */
b18c562e 2930
13761a11 2931 frag = frag_more (insn_length);
b18c562e 2932 where = frag - frag_now->fr_literal;
638d3803 2933
13761a11
NC
2934 if (extended_op)
2935 {
2936 if (!addr_op)
2937 extended |= BYTE_OPERATION;
2938
2939 if ((op1.ol != 0 || op2.ol != 0) && ((extended & 0xf) != 0))
2940 {
2941 as_bad (_("repeat instruction used with non-register mode instruction"));
2942 extended &= ~ 0xf;
2943 }
2944
2945 /* If necessary, emit a reloc to update the extension word. */
2946 if (op1.mode == OP_EXP)
2947 {
2948 if (op1.exp.X_op == O_constant)
2949 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
2950
2951 else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
2952 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2953 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
2954 else
2955 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2956 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
2957 }
638d3803 2958
13761a11
NC
2959 if (op2.mode == OP_EXP)
2960 {
2961 if (op2.exp.X_op == O_constant)
2962 extended |= (op2.exp.X_add_number >> 16) & 0xf;
2963
2964 else if (op1.mode == OP_EXP)
2965 fix_new_exp (frag_now, where, 8, &(op2.exp), FALSE,
2966 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_ODST
2967 : BFD_RELOC_MSP430X_PCR20_EXT_ODST);
638d3803 2968
13761a11
NC
2969 else
2970 fix_new_exp (frag_now, where, 6, &(op2.exp), FALSE,
2971 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_DST
2972 : BFD_RELOC_MSP430X_PCR20_EXT_DST);
2973 }
2974
2975 /* Emit the extension word. */
2976 bfd_putl16 (extended, frag);
2977 where += 2;
2978 frag += 2;
2979 }
2980
2981 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
b18c562e 2982 bfd_putl16 ((bfd_vma) bin, frag);
13761a11
NC
2983 where += 2;
2984 frag += 2;
b18c562e
NC
2985
2986 if (op1.mode == OP_EXP)
2469cfa2 2987 {
13761a11
NC
2988 if (op1.exp.X_op == O_constant)
2989 {
2990 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
2991 }
b18c562e 2992 else
13761a11
NC
2993 {
2994 bfd_putl16 ((bfd_vma) ZEROS, frag);
2995
2996 if (!extended_op)
2997 {
2998 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
2999 fix_new_exp (frag_now, where, 2,
3000 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
3001 else
3002 fix_new_exp (frag_now, where, 2,
3003 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3004 }
3005 }
3006
3007 where += 2;
3008 frag += 2;
2469cfa2 3009 }
b18c562e
NC
3010
3011 if (op2.mode == OP_EXP)
2469cfa2 3012 {
13761a11
NC
3013 if (op2.exp.X_op == O_constant)
3014 {
3015 bfd_putl16 (op2.exp.X_add_number & 0xffff, frag);
3016 }
b18c562e 3017 else
13761a11
NC
3018 {
3019 bfd_putl16 ((bfd_vma) ZEROS, frag);
3020
3021 if (!extended_op)
3022 {
3023 if (op2.reg) /* Not PC relative. */
3024 fix_new_exp (frag_now, where, 2,
3025 &(op2.exp), FALSE, CHECK_RELOC_MSP430);
3026 else
3027 fix_new_exp (frag_now, where, 2,
3028 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3029 }
3030 }
3031 }
3032
3033 if (gen_interrupt_nops
638d3803
NC
3034 && target_is_430xv2 ()
3035 && ( (is_opcode ("bic") && bin == 0xc232)
3036 || (is_opcode ("bis") && bin == 0xd232)
3037 || (is_opcode ("mov") && op2.mode == OP_REG && op2.reg == 2)))
13761a11
NC
3038 {
3039 /* Emit a NOP following interrupt enable/disable.
3040 See 1.3.4.1 of the MSP430x5xx User Guide. */
3041 insn_length += 2;
3042 frag = frag_more (2);
3043 bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
2469cfa2 3044 }
13761a11
NC
3045
3046 dwarf2_emit_insn (insn_length);
b18c562e
NC
3047 break;
3048
3049 case 2: /* Single-operand mostly instr. */
3050 if (opcode->insn_opnumb == 0)
2469cfa2 3051 {
b18c562e 3052 /* reti instruction. */
13761a11 3053 insn_length += 2;
b18c562e
NC
3054 frag = frag_more (2);
3055 bfd_putl16 ((bfd_vma) bin, frag);
13761a11 3056 dwarf2_emit_insn (insn_length);
b18c562e 3057 break;
2469cfa2 3058 }
2469cfa2 3059
b18c562e 3060 line = extract_operand (line, l1, sizeof (l1));
13761a11
NC
3061 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode,
3062 &imm_op, extended_op, TRUE);
b18c562e
NC
3063 if (res)
3064 break; /* Error in operand. */
2469cfa2 3065
d1706f38
NC
3066 if (target_is_430xv2 ()
3067 && op1.mode == OP_REG
638d3803
NC
3068 && op1.reg == 0
3069 && (is_opcode ("rrax")
3070 || is_opcode ("rrcx")
3071 || is_opcode ("rra")
3072 || is_opcode ("rrc")))
3073 {
3074 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
3075 return 0;
3076 }
3077
13761a11
NC
3078 insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
3079 frag = frag_more (insn_length);
b18c562e 3080 where = frag - frag_now->fr_literal;
638d3803 3081
13761a11
NC
3082 if (extended_op)
3083 {
638d3803 3084 if (is_opcode ("swpbx") || is_opcode ("sxtx"))
13761a11
NC
3085 {
3086 /* These two instructions use a special
3087 encoding of the A/L and B/W bits. */
3088 bin &= ~ BYTE_OPERATION;
3089
3090 if (byte_op)
3091 {
3092 as_bad (_("%s instruction does not accept a .b suffix"),
3093 opcode->name);
3094 return 0;
3095 }
3096 else if (! addr_op)
3097 extended |= BYTE_OPERATION;
3098 }
3099 else if (! addr_op)
3100 extended |= BYTE_OPERATION;
3101
3102 if (op1.ol != 0 && ((extended & 0xf) != 0))
3103 {
3104 as_bad (_("repeat instruction used with non-register mode instruction"));
3105 extended &= ~ 0xf;
3106 }
3107
3108 if (op1.mode == OP_EXP)
3109 {
3110 if (op1.exp.X_op == O_constant)
3111 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
638d3803 3112
13761a11
NC
3113 else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
3114 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3115 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
3116 else
3117 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3118 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
3119 }
638d3803 3120
13761a11
NC
3121 /* Emit the extension word. */
3122 bfd_putl16 (extended, frag);
3123 frag += 2;
3124 where += 2;
3125 }
3126
3127 bin |= op1.reg | (op1.am << 4);
b18c562e 3128 bfd_putl16 ((bfd_vma) bin, frag);
13761a11
NC
3129 frag += 2;
3130 where += 2;
b18c562e
NC
3131
3132 if (op1.mode == OP_EXP)
2469cfa2 3133 {
13761a11
NC
3134 if (op1.exp.X_op == O_constant)
3135 {
3136 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
3137 }
b18c562e 3138 else
13761a11
NC
3139 {
3140 bfd_putl16 ((bfd_vma) ZEROS, frag);
3141
3142 if (!extended_op)
3143 {
3144 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
3145 fix_new_exp (frag_now, where, 2,
3146 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
3147 else
3148 fix_new_exp (frag_now, where, 2,
3149 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3150 }
3151 }
2469cfa2 3152 }
13761a11
NC
3153
3154 dwarf2_emit_insn (insn_length);
b18c562e 3155 break;
2469cfa2 3156
b18c562e
NC
3157 case 3: /* Conditional jumps instructions. */
3158 line = extract_operand (line, l1, sizeof (l1));
3159 /* l1 is a label. */
3160 if (l1[0])
2469cfa2 3161 {
b18c562e
NC
3162 char *m = l1;
3163 expressionS exp;
2469cfa2 3164
b18c562e
NC
3165 if (*m == '$')
3166 m++;
2469cfa2 3167
b18c562e 3168 parse_exp (m, &exp);
2469cfa2 3169
b18c562e 3170 /* In order to handle something like:
2469cfa2 3171
b18c562e
NC
3172 and #0x8000, r5
3173 tst r5
3174 jz 4 ; skip next 4 bytes
3175 inv r5
3176 inc r5
3177 nop ; will jump here if r5 positive or zero
2469cfa2 3178
b18c562e 3179 jCOND -n ;assumes jump n bytes backward:
2469cfa2 3180
b18c562e
NC
3181 mov r5,r6
3182 jmp -2
2469cfa2 3183
b18c562e
NC
3184 is equal to:
3185 lab:
3186 mov r5,r6
3187 jmp lab
3188
3189 jCOND $n ; jump from PC in either direction. */
2469cfa2 3190
b18c562e
NC
3191 if (exp.X_op == O_constant)
3192 {
3193 int x = exp.X_add_number;
2469cfa2 3194
b18c562e
NC
3195 if (x & 1)
3196 {
3197 as_warn (_("Even number required. Rounded to %d"), x + 1);
3198 x++;
3199 }
2469cfa2 3200
b18c562e
NC
3201 if ((*l1 == '$' && x > 0) || x < 0)
3202 x -= 2;
2469cfa2 3203
b18c562e
NC
3204 x >>= 1;
3205
3206 if (x > 512 || x < -511)
3207 {
3208 as_bad (_("Wrong displacement %d"), x << 1);
3209 break;
3210 }
3211
13761a11
NC
3212 insn_length += 2;
3213 frag = frag_more (2); /* Instr size is 1 word. */
3214
b18c562e
NC
3215 bin |= x & 0x3ff;
3216 bfd_putl16 ((bfd_vma) bin, frag);
3217 }
3218 else if (exp.X_op == O_symbol && *l1 != '$')
2469cfa2 3219 {
13761a11
NC
3220 insn_length += 2;
3221 frag = frag_more (2); /* Instr size is 1 word. */
b18c562e
NC
3222 where = frag - frag_now->fr_literal;
3223 fix_new_exp (frag_now, where, 2,
3224 &exp, TRUE, BFD_RELOC_MSP430_10_PCREL);
3225
3226 bfd_putl16 ((bfd_vma) bin, frag);
2469cfa2 3227 }
b18c562e 3228 else if (*l1 == '$')
2469cfa2 3229 {
b18c562e 3230 as_bad (_("instruction requires label sans '$'"));
2469cfa2 3231 }
b18c562e 3232 else
13761a11
NC
3233 as_bad (_
3234 ("instruction requires label or value in range -511:512"));
3235 dwarf2_emit_insn (insn_length);
2a9a06c1 3236 break;
2469cfa2 3237 }
b18c562e
NC
3238 else
3239 {
3240 as_bad (_("instruction requires label"));
3241 break;
3242 }
3243 break;
2469cfa2 3244
b18c562e 3245 case 4: /* Extended jumps. */
77592908
DD
3246 if (!msp430_enable_polys)
3247 {
20203fb9 3248 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
77592908
DD
3249 break;
3250 }
638d3803 3251
b18c562e
NC
3252 line = extract_operand (line, l1, sizeof (l1));
3253 if (l1[0])
2469cfa2 3254 {
b18c562e
NC
3255 char *m = l1;
3256 expressionS exp;
2469cfa2 3257
b18c562e
NC
3258 /* Ignore absolute addressing. make it PC relative anyway. */
3259 if (*m == '#' || *m == '$')
3260 m++;
2469cfa2 3261
b18c562e
NC
3262 parse_exp (m, & exp);
3263 if (exp.X_op == O_symbol)
2469cfa2 3264 {
b18c562e
NC
3265 /* Relaxation required. */
3266 struct rcodes_s rc = msp430_rcodes[opcode->insn_opnumb];
3267
638d3803 3268 if (target_is_430x ())
13761a11
NC
3269 rc = msp430x_rcodes[opcode->insn_opnumb];
3270
3271 /* The parameter to dwarf2_emit_insn is actually the offset to
3272 the start of the insn from the fix piece of instruction that
3273 was emitted. Since next fragments may have variable size we
3274 tie debug info to the beginning of the instruction. */
3275 insn_length += 8;
3e470ab5 3276 frag = frag_more (8);
2a9a06c1 3277 dwarf2_emit_insn (0);
3e470ab5
DD
3278 bfd_putl16 ((bfd_vma) rc.sop, frag);
3279 frag = frag_variant (rs_machine_dependent, 8, 2,
13761a11
NC
3280 /* Wild guess. */
3281 ENCODE_RELAX (rc.lpos, STATE_BITS10),
b18c562e
NC
3282 exp.X_add_symbol,
3283 0, /* Offset is zero if jump dist less than 1K. */
3284 (char *) frag);
3285 break;
2469cfa2
NC
3286 }
3287 }
b18c562e
NC
3288
3289 as_bad (_("instruction requires label"));
3290 break;
3291
3292 case 5: /* Emulated extended branches. */
77592908
DD
3293 if (!msp430_enable_polys)
3294 {
20203fb9 3295 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
77592908
DD
3296 break;
3297 }
b18c562e
NC
3298 line = extract_operand (line, l1, sizeof (l1));
3299 if (l1[0])
2469cfa2 3300 {
b18c562e
NC
3301 char * m = l1;
3302 expressionS exp;
3303
3304 /* Ignore absolute addressing. make it PC relative anyway. */
3305 if (*m == '#' || *m == '$')
3306 m++;
3307
3308 parse_exp (m, & exp);
3309 if (exp.X_op == O_symbol)
3310 {
3311 /* Relaxation required. */
3312 struct hcodes_s hc = msp430_hcodes[opcode->insn_opnumb];
3313
638d3803 3314 if (target_is_430x ())
13761a11
NC
3315 hc = msp430x_hcodes[opcode->insn_opnumb];
3316
3317 insn_length += 8;
3e470ab5 3318 frag = frag_more (8);
2a9a06c1 3319 dwarf2_emit_insn (0);
3e470ab5
DD
3320 bfd_putl16 ((bfd_vma) hc.op0, frag);
3321 bfd_putl16 ((bfd_vma) hc.op1, frag+2);
3322
3323 frag = frag_variant (rs_machine_dependent, 8, 2,
b18c562e
NC
3324 ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10), /* Wild guess. */
3325 exp.X_add_symbol,
3326 0, /* Offset is zero if jump dist less than 1K. */
3327 (char *) frag);
3328 break;
3329 }
2469cfa2
NC
3330 }
3331
b18c562e
NC
3332 as_bad (_("instruction requires label"));
3333 break;
2469cfa2 3334
b18c562e 3335 default:
79cf5950 3336 as_bad (_("Illegal instruction or not implemented opcode."));
b18c562e 3337 }
2469cfa2 3338
b18c562e
NC
3339 input_line_pointer = line;
3340 return 0;
3341}
2469cfa2 3342
b18c562e
NC
3343void
3344md_assemble (char * str)
3345{
3346 struct msp430_opcode_s * opcode;
3347 char cmd[32];
3348 unsigned int i = 0;
2469cfa2 3349
b18c562e
NC
3350 str = skip_space (str); /* Skip leading spaces. */
3351 str = extract_cmd (str, cmd, sizeof (cmd));
2469cfa2 3352
b18c562e
NC
3353 while (cmd[i] && i < sizeof (cmd))
3354 {
3355 char a = TOLOWER (cmd[i]);
3356 cmd[i] = a;
3357 i++;
2469cfa2 3358 }
2469cfa2 3359
b18c562e 3360 if (!cmd[0])
2469cfa2 3361 {
b18c562e
NC
3362 as_bad (_("can't find opcode "));
3363 return;
3364 }
2469cfa2 3365
b18c562e 3366 opcode = (struct msp430_opcode_s *) hash_find (msp430_hash, cmd);
2469cfa2 3367
b18c562e
NC
3368 if (opcode == NULL)
3369 {
3370 as_bad (_("unknown opcode `%s'"), cmd);
3371 return;
2469cfa2 3372 }
2469cfa2 3373
b18c562e
NC
3374 {
3375 char *__t = input_line_pointer;
2469cfa2 3376
b18c562e
NC
3377 msp430_operands (opcode, str);
3378 input_line_pointer = __t;
3379 }
3380}
2469cfa2
NC
3381
3382/* GAS will call this function for each section at the end of the assembly,
3383 to permit the CPU backend to adjust the alignment of a section. */
3384
3385valueT
b18c562e 3386md_section_align (asection * seg, valueT addr)
2469cfa2
NC
3387{
3388 int align = bfd_get_section_alignment (stdoutput, seg);
3389
3390 return ((addr + (1 << align) - 1) & (-1 << align));
3391}
3392
3393/* If you define this macro, it should return the offset between the
3394 address of a PC relative fixup and the position from which the PC
3395 relative adjustment should be made. On many processors, the base
3396 of a PC relative instruction is the next instruction, so this
3397 macro would return the length of an instruction. */
3398
3399long
b18c562e 3400md_pcrel_from_section (fixS * fixp, segT sec)
2469cfa2
NC
3401{
3402 if (fixp->fx_addsy != (symbolS *) NULL
3403 && (!S_IS_DEFINED (fixp->fx_addsy)
3404 || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
3405 return 0;
3406
3407 return fixp->fx_frag->fr_address + fixp->fx_where;
3408}
3409
77592908
DD
3410/* Replaces standard TC_FORCE_RELOCATION_LOCAL.
3411 Now it handles the situation when relocations
13761a11 3412 have to be passed to linker. */
77592908 3413int
13761a11 3414msp430_force_relocation_local (fixS *fixp)
77592908 3415{
13761a11
NC
3416 if (fixp->fx_r_type == BFD_RELOC_MSP430_10_PCREL)
3417 return 1;
13761a11
NC
3418 if (fixp->fx_pcrel)
3419 return 1;
77592908
DD
3420 if (msp430_enable_polys
3421 && !msp430_enable_relax)
3422 return 1;
13761a11
NC
3423
3424 return (!fixp->fx_pcrel
3425 || generic_force_reloc (fixp));
77592908
DD
3426}
3427
3428
2469cfa2
NC
3429/* GAS will call this for each fixup. It should store the correct
3430 value in the object file. */
2469cfa2 3431void
55cf6793 3432md_apply_fix (fixS * fixp, valueT * valuep, segT seg)
2469cfa2 3433{
b18c562e 3434 unsigned char * where;
2469cfa2
NC
3435 unsigned long insn;
3436 long value;
3437
3438 if (fixp->fx_addsy == (symbolS *) NULL)
3439 {
3440 value = *valuep;
3441 fixp->fx_done = 1;
3442 }
3443 else if (fixp->fx_pcrel)
3444 {
3445 segT s = S_GET_SEGMENT (fixp->fx_addsy);
3446
3447 if (fixp->fx_addsy && (s == seg || s == absolute_section))
3448 {
18af0b39
NC
3449 /* FIXME: We can appear here only in case if we perform a pc
3450 relative jump to the label which is i) global, ii) locally
3451 defined or this is a jump to an absolute symbol.
3452 If this is an absolute symbol -- everything is OK.
3453 If this is a global label, we've got a symbol value defined
3454 twice:
3455 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
3456 from this section start
3457 2. *valuep will contain the real offset from jump insn to the
3458 label
3459 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
3460 will be incorrect. Therefore remove s_get_value. */
3461 value = /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep;
2469cfa2
NC
3462 fixp->fx_done = 1;
3463 }
3464 else
3465 value = *valuep;
3466 }
3467 else
3468 {
3469 value = fixp->fx_offset;
3470
3471 if (fixp->fx_subsy != (symbolS *) NULL)
3472 {
3473 if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
3474 {
3475 value -= S_GET_VALUE (fixp->fx_subsy);
3476 fixp->fx_done = 1;
3477 }
2469cfa2
NC
3478 }
3479 }
3480
77592908
DD
3481 fixp->fx_no_overflow = 1;
3482
638d3803 3483 /* If polymorphs are enabled and relax disabled.
13761a11 3484 do not kill any relocs and pass them to linker. */
638d3803 3485 if (msp430_enable_polys
77592908 3486 && !msp430_enable_relax)
2469cfa2 3487 {
638d3803 3488 if (!fixp->fx_addsy || (fixp->fx_addsy
77592908 3489 && S_GET_SEGMENT (fixp->fx_addsy) == absolute_section))
79cf5950 3490 fixp->fx_done = 1; /* It is ok to kill 'abs' reloc. */
77592908
DD
3491 else
3492 fixp->fx_done = 0;
2469cfa2
NC
3493 }
3494
3495 if (fixp->fx_done)
3496 {
3497 /* Fetch the instruction, insert the fully resolved operand
8cd5b113 3498 value, and stuff the instruction back again. */
2132e3a3 3499 where = (unsigned char *) fixp->fx_frag->fr_literal + fixp->fx_where;
2469cfa2
NC
3500
3501 insn = bfd_getl16 (where);
3502
3503 switch (fixp->fx_r_type)
3504 {
3505 case BFD_RELOC_MSP430_10_PCREL:
3506 if (value & 1)
3507 as_bad_where (fixp->fx_file, fixp->fx_line,
3508 _("odd address operand: %ld"), value);
3509
3510 /* Jumps are in words. */
3511 value >>= 1;
3512 --value; /* Correct PC. */
3513
3514 if (value < -512 || value > 511)
3515 as_bad_where (fixp->fx_file, fixp->fx_line,
3516 _("operand out of range: %ld"), value);
3517
3518 value &= 0x3ff; /* get rid of extended sign */
3519 bfd_putl16 ((bfd_vma) (value | insn), where);
3520 break;
3521
13761a11 3522 case BFD_RELOC_MSP430X_PCR16:
b18c562e 3523 case BFD_RELOC_MSP430_RL_PCREL:
2469cfa2
NC
3524 case BFD_RELOC_MSP430_16_PCREL:
3525 if (value & 1)
3526 as_bad_where (fixp->fx_file, fixp->fx_line,
3527 _("odd address operand: %ld"), value);
13761a11 3528 /* Fall through. */
2469cfa2
NC
3529
3530 case BFD_RELOC_MSP430_16_PCREL_BYTE:
3531 /* Nothing to be corrected here. */
3532 if (value < -32768 || value > 65536)
3533 as_bad_where (fixp->fx_file, fixp->fx_line,
3534 _("operand out of range: %ld"), value);
13761a11 3535 /* Fall through. */
2469cfa2 3536
13761a11
NC
3537 case BFD_RELOC_MSP430X_ABS16:
3538 case BFD_RELOC_MSP430_16:
3539 case BFD_RELOC_16:
3540 case BFD_RELOC_MSP430_16_BYTE:
2469cfa2
NC
3541 value &= 0xffff; /* Get rid of extended sign. */
3542 bfd_putl16 ((bfd_vma) value, where);
3543 break;
3544
3545 case BFD_RELOC_32:
3546 bfd_putl16 ((bfd_vma) value, where);
3547 break;
3548
13761a11
NC
3549 case BFD_RELOC_MSP430_ABS8:
3550 case BFD_RELOC_8:
3551 bfd_put_8 (NULL, (bfd_vma) value, where);
3552 break;
3553
3554 case BFD_RELOC_MSP430X_ABS20_EXT_SRC:
3555 case BFD_RELOC_MSP430X_PCR20_EXT_SRC:
3556 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 4);
638d3803 3557 value >>= 16;
13761a11
NC
3558 bfd_putl16 ((bfd_vma) (((value & 0xf) << 7) | insn), where);
3559 break;
3560
3561 case BFD_RELOC_MSP430X_ABS20_ADR_SRC:
3562 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
638d3803 3563 value >>= 16;
13761a11
NC
3564 bfd_putl16 ((bfd_vma) (((value & 0xf) << 8) | insn), where);
3565 break;
3566
3567 case BFD_RELOC_MSP430X_ABS20_EXT_ODST:
3568 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 6);
3569 value >>= 16;
3570 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3571 break;
3572
3573 case BFD_RELOC_MSP430X_PCR20_CALL:
3574 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
3575 value >>= 16;
3576 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3577 break;
3578
3579 case BFD_RELOC_MSP430X_ABS20_EXT_DST:
3580 case BFD_RELOC_MSP430X_PCR20_EXT_DST:
3581 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 4);
3582 value >>= 16;
3583 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3584 break;
3585
3586 case BFD_RELOC_MSP430X_PCR20_EXT_ODST:
3587 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 6);
3588 value >>= 16;
3589 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3590 break;
3591
3592 case BFD_RELOC_MSP430X_ABS20_ADR_DST:
3593 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
3594 value >>= 16;
3595 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
2469cfa2 3596 break;
638d3803 3597
2469cfa2
NC
3598 default:
3599 as_fatal (_("line %d: unknown relocation type: 0x%x"),
3600 fixp->fx_line, fixp->fx_r_type);
3601 break;
3602 }
3603 }
3604 else
3605 {
3606 fixp->fx_addnumber = value;
3607 }
2469cfa2
NC
3608}
3609
13761a11
NC
3610static bfd_boolean
3611S_IS_GAS_LOCAL (symbolS * s)
3612{
3613 const char * name;
3614 unsigned int len;
3615
3616 if (s == NULL)
3617 return FALSE;
3618 name = S_GET_NAME (s);
3619 len = strlen (name) - 1;
638d3803 3620
13761a11
NC
3621 return name[len] == 1 || name[len] == 2;
3622}
3623
7be1c489
AM
3624/* GAS will call this to generate a reloc, passing the resulting reloc
3625 to `bfd_install_relocation'. This currently works poorly, as
3626 `bfd_install_relocation' often does the wrong thing, and instances of
3627 `tc_gen_reloc' have been written to work around the problems, which
3628 in turns makes it difficult to fix `bfd_install_relocation'. */
2469cfa2
NC
3629
3630/* If while processing a fixup, a reloc really needs to be created
3631 then it is done here. */
3632
13761a11 3633arelent **
b18c562e 3634tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
2469cfa2 3635{
13761a11
NC
3636 static arelent * no_relocs = NULL;
3637 static arelent * relocs[MAX_RELOC_EXPANSION + 1];
3638 arelent *reloc;
2469cfa2 3639
b18c562e 3640 reloc = xmalloc (sizeof (arelent));
2469cfa2
NC
3641 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
3642 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
13761a11 3643
2469cfa2
NC
3644 if (reloc->howto == (reloc_howto_type *) NULL)
3645 {
3646 as_bad_where (fixp->fx_file, fixp->fx_line,
3647 _("reloc %d not supported by object file format"),
3648 (int) fixp->fx_r_type);
13761a11
NC
3649 free (reloc);
3650 return & no_relocs;
3651 }
3652
3653 relocs[0] = reloc;
3654 relocs[1] = NULL;
3655
3656 if (fixp->fx_subsy
3657 && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
3658 {
3659 fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
3660 fixp->fx_subsy = NULL;
2469cfa2
NC
3661 }
3662
13761a11
NC
3663 if (fixp->fx_addsy && fixp->fx_subsy)
3664 {
3665 asection *asec, *ssec;
3666
3667 asec = S_GET_SEGMENT (fixp->fx_addsy);
3668 ssec = S_GET_SEGMENT (fixp->fx_subsy);
3669
3670 /* If we have a difference between two different, non-absolute symbols
3671 we must generate two relocs (one for each symbol) and allow the
3672 linker to resolve them - relaxation may change the distances between
3673 symbols, even local symbols defined in the same section.
3674
3675 Unfortunately we cannot do this with assembler generated local labels
3676 because there can be multiple incarnations of the same label, with
3677 exactly the same name, in any given section and the linker will have
3678 no way to identify the correct one. Instead we just have to hope
3679 that no relaxtion will occur between the local label and the other
3680 symbol in the expression.
3681
3682 Similarly we have to compute differences between symbols in the .eh_frame
3683 section as the linker is not smart enough to apply relocations there
3684 before attempting to process it. */
3685 if ((ssec != absolute_section || asec != absolute_section)
3686 && (fixp->fx_addsy != fixp->fx_subsy)
3687 && strcmp (ssec->name, ".eh_frame") != 0
3688 && ! S_IS_GAS_LOCAL (fixp->fx_addsy)
3689 && ! S_IS_GAS_LOCAL (fixp->fx_subsy))
3690 {
3691 arelent * reloc2 = xmalloc (sizeof * reloc);
2469cfa2 3692
13761a11
NC
3693 relocs[0] = reloc2;
3694 relocs[1] = reloc;
2469cfa2 3695
13761a11
NC
3696 reloc2->address = reloc->address;
3697 reloc2->howto = bfd_reloc_type_lookup (stdoutput,
3698 BFD_RELOC_MSP430_SYM_DIFF);
3699 reloc2->addend = - S_GET_VALUE (fixp->fx_subsy);
3700
3701 if (ssec == absolute_section)
3702 reloc2->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3703 else
3704 {
3705 reloc2->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
3706 *reloc2->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
3707 }
3708
638d3803 3709 reloc->addend = fixp->fx_offset;
13761a11
NC
3710 if (asec == absolute_section)
3711 {
3712 reloc->addend += S_GET_VALUE (fixp->fx_addsy);
3713 reloc->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3714 }
3715 else
3716 {
3717 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
3718 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
3719 }
3720
3721 fixp->fx_pcrel = 0;
3722 fixp->fx_done = 1;
3723 return relocs;
3724 }
3725 else
3726 {
3727 char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
3728
3729 reloc->addend = (S_GET_VALUE (fixp->fx_addsy)
3730 - S_GET_VALUE (fixp->fx_subsy) + fixp->fx_offset);
3731
3732 switch (fixp->fx_r_type)
3733 {
3734 case BFD_RELOC_8:
3735 md_number_to_chars (fixpos, reloc->addend, 1);
3736 break;
3737
3738 case BFD_RELOC_16:
3739 md_number_to_chars (fixpos, reloc->addend, 2);
3740 break;
3741
3742 case BFD_RELOC_24:
3743 md_number_to_chars (fixpos, reloc->addend, 3);
3744 break;
3745
3746 case BFD_RELOC_32:
3747 md_number_to_chars (fixpos, reloc->addend, 4);
3748 break;
3749
3750 default:
3751 reloc->sym_ptr_ptr
3752 = (asymbol **) bfd_abs_section_ptr->symbol_ptr_ptr;
3753 return relocs;
3754 }
3755
3756 free (reloc);
3757 return & no_relocs;
3758 }
3759 }
3760 else
3761 {
3762#if 0
3763 if (fixp->fx_r_type == BFD_RELOC_MSP430X_ABS16
3764 && S_GET_SEGMENT (fixp->fx_addsy) == absolute_section)
3765 {
3766 bfd_vma amount = S_GET_VALUE (fixp->fx_addsy);
3767 char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
3768
3769 md_number_to_chars (fixpos, amount, 2);
3770 free (reloc);
3771 return & no_relocs;
3772 }
3773#endif
3774 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
3775 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
3776 reloc->addend = fixp->fx_offset;
3777
3778 if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
3779 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
3780 reloc->address = fixp->fx_offset;
3781 }
3782
3783 return relocs;
2469cfa2
NC
3784}
3785
b18c562e
NC
3786int
3787md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
3788 asection * segment_type ATTRIBUTE_UNUSED)
3789{
3790 if (fragP->fr_symbol && S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
3791 {
3792 /* This is a jump -> pcrel mode. Nothing to do much here.
3793 Return value == 2. */
3794 fragP->fr_subtype =
3795 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_BITS10);
3796 }
3797 else if (fragP->fr_symbol)
3798 {
3799 /* Its got a segment, but its not ours. Even if fr_symbol is in
79cf5950 3800 an absolute segment, we don't know a displacement until we link
b18c562e
NC
3801 object files. So it will always be long. This also applies to
3802 labels in a subsegment of current. Liker may relax it to short
3803 jump later. Return value == 8. */
3804 fragP->fr_subtype =
3805 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_WORD);
3806 }
3807 else
3808 {
3809 /* We know the abs value. may be it is a jump to fixed address.
79cf5950 3810 Impossible in our case, cause all constants already handled. */
b18c562e
NC
3811 fragP->fr_subtype =
3812 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_UNDEF);
3813 }
2469cfa2 3814
b18c562e
NC
3815 return md_relax_table[fragP->fr_subtype].rlx_length;
3816}
3817
3818void
3819md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
3820 asection * sec ATTRIBUTE_UNUSED,
3821 fragS * fragP)
2469cfa2 3822{
b18c562e
NC
3823 char * where = 0;
3824 int rela = -1;
3825 int i;
3826 struct rcodes_s * cc = NULL;
3827 struct hcodes_s * hc = NULL;
3828
3829 switch (fragP->fr_subtype)
3830 {
3831 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_BITS10):
3832 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_BITS10):
3833 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_BITS10):
3834 /* We do not have to convert anything here.
3835 Just apply a fix. */
3836 rela = BFD_RELOC_MSP430_10_PCREL;
3837 break;
3838
3839 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_WORD):
3840 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_UNDEF):
3841 /* Convert uncond branch jmp lab -> br lab. */
638d3803 3842 if (target_is_430x ())
13761a11 3843 cc = msp430x_rcodes + 7;
638d3803
NC
3844 else
3845 cc = msp430_rcodes + 7;
b18c562e
NC
3846 where = fragP->fr_literal + fragP->fr_fix;
3847 bfd_putl16 (cc->lop0, where);
3848 rela = BFD_RELOC_MSP430_RL_PCREL;
3849 fragP->fr_fix += 2;
3850 break;
3851
3852 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_WORD):
3853 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_UNDEF):
3854 {
3855 /* Other simple branches. */
3856 int insn = bfd_getl16 (fragP->fr_opcode);
3857
3858 insn &= 0xffff;
3859 /* Find actual instruction. */
638d3803 3860 if (target_is_430x ())
13761a11
NC
3861 {
3862 for (i = 0; i < 7 && !cc; i++)
3863 if (msp430x_rcodes[i].sop == insn)
3864 cc = msp430x_rcodes + i;
3865 }
3866 else
3867 {
3868 for (i = 0; i < 7 && !cc; i++)
3869 if (msp430_rcodes[i].sop == insn)
3870 cc = & msp430_rcodes[i];
3871 }
3872
b18c562e
NC
3873 if (!cc || !cc->name)
3874 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
3875 __FUNCTION__, (long) insn);
3876 where = fragP->fr_literal + fragP->fr_fix;
3877 bfd_putl16 (cc->lop0, where);
3878 bfd_putl16 (cc->lop1, where + 2);
3879 rela = BFD_RELOC_MSP430_RL_PCREL;
3880 fragP->fr_fix += 4;
3881 }
3882 break;
3883
3884 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_WORD):
3885 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_UNDEF):
638d3803 3886 if (target_is_430x ())
13761a11 3887 cc = msp430x_rcodes + 6;
638d3803
NC
3888 else
3889 cc = msp430_rcodes + 6;
b18c562e
NC
3890 where = fragP->fr_literal + fragP->fr_fix;
3891 bfd_putl16 (cc->lop0, where);
3892 bfd_putl16 (cc->lop1, where + 2);
3893 bfd_putl16 (cc->lop2, where + 4);
3894 rela = BFD_RELOC_MSP430_RL_PCREL;
3895 fragP->fr_fix += 6;
3896 break;
3897
3898 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10):
3899 {
3900 int insn = bfd_getl16 (fragP->fr_opcode + 2);
3901
3902 insn &= 0xffff;
638d3803 3903 if (target_is_430x ())
13761a11
NC
3904 {
3905 for (i = 0; i < 4 && !hc; i++)
3906 if (msp430x_hcodes[i].op1 == insn)
3907 hc = msp430x_hcodes + i;
3908 }
3909 else
3910 {
3911 for (i = 0; i < 4 && !hc; i++)
3912 if (msp430_hcodes[i].op1 == insn)
3913 hc = &msp430_hcodes[i];
3914 }
b18c562e
NC
3915 if (!hc || !hc->name)
3916 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
3917 __FUNCTION__, (long) insn);
3918 rela = BFD_RELOC_MSP430_10_PCREL;
3919 /* Apply a fix for a first label if necessary.
3920 another fix will be applied to the next word of insn anyway. */
3921 if (hc->tlab == 2)
3922 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
13761a11 3923 fragP->fr_offset, TRUE, rela);
b18c562e
NC
3924 fragP->fr_fix += 2;
3925 }
3926
3927 break;
3928
3929 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_WORD):
3930 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_UNDEF):
3931 {
3932 int insn = bfd_getl16 (fragP->fr_opcode + 2);
3933
3934 insn &= 0xffff;
638d3803 3935 if (target_is_430x ())
13761a11
NC
3936 {
3937 for (i = 0; i < 4 && !hc; i++)
3938 if (msp430x_hcodes[i].op1 == insn)
3939 hc = msp430x_hcodes + i;
3940 }
3941 else
3942 {
3943 for (i = 0; i < 4 && !hc; i++)
3944 if (msp430_hcodes[i].op1 == insn)
3945 hc = & msp430_hcodes[i];
3946 }
b18c562e
NC
3947 if (!hc || !hc->name)
3948 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
3949 __FUNCTION__, (long) insn);
3950 rela = BFD_RELOC_MSP430_RL_PCREL;
3951 where = fragP->fr_literal + fragP->fr_fix;
3952 bfd_putl16 (hc->lop0, where);
3953 bfd_putl16 (hc->lop1, where + 2);
3954 bfd_putl16 (hc->lop2, where + 4);
3955 fragP->fr_fix += 6;
3956 }
3957 break;
3958
3959 default:
3960 as_fatal (_("internal inconsistency problem in %s: %lx"),
3961 __FUNCTION__, (long) fragP->fr_subtype);
3962 break;
3963 }
3964
3965 /* Now apply fix. */
3966 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
3967 fragP->fr_offset, TRUE, rela);
3968 /* Just fixed 2 bytes. */
3969 fragP->fr_fix += 2;
2469cfa2
NC
3970}
3971
b18c562e
NC
3972/* Relax fragment. Mostly stolen from hc11 and mcore
3973 which arches I think I know. */
2469cfa2 3974
b18c562e
NC
3975long
3976msp430_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS * fragP,
3977 long stretch ATTRIBUTE_UNUSED)
2469cfa2 3978{
b18c562e
NC
3979 long growth;
3980 offsetT aim = 0;
3981 symbolS *symbolP;
3982 const relax_typeS *this_type;
3983 const relax_typeS *start_type;
3984 relax_substateT next_state;
3985 relax_substateT this_state;
3986 const relax_typeS *table = md_relax_table;
3987
3988 /* Nothing to be done if the frag has already max size. */
3989 if (RELAX_STATE (fragP->fr_subtype) == STATE_UNDEF
3990 || RELAX_STATE (fragP->fr_subtype) == STATE_WORD)
3991 return 0;
3992
3993 if (RELAX_STATE (fragP->fr_subtype) == STATE_BITS10)
3994 {
3995 symbolP = fragP->fr_symbol;
3996 if (symbol_resolved_p (symbolP))
3997 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
3998 __FUNCTION__);
3999 /* We know the offset. calculate a distance. */
4000 aim = S_GET_VALUE (symbolP) - fragP->fr_address - fragP->fr_fix;
4001 }
4002
77592908
DD
4003 if (!msp430_enable_relax)
4004 {
4005 /* Relaxation is not enabled. So, make all jump as long ones
13761a11 4006 by setting 'aim' to quite high value. */
77592908
DD
4007 aim = 0x7fff;
4008 }
638d3803 4009
b18c562e
NC
4010 this_state = fragP->fr_subtype;
4011 start_type = this_type = table + this_state;
4012
4013 if (aim < 0)
4014 {
4015 /* Look backwards. */
4016 for (next_state = this_type->rlx_more; next_state;)
3e470ab5 4017 if (aim >= this_type->rlx_backward || !this_type->rlx_backward)
b18c562e
NC
4018 next_state = 0;
4019 else
4020 {
4021 /* Grow to next state. */
4022 this_state = next_state;
4023 this_type = table + this_state;
4024 next_state = this_type->rlx_more;
4025 }
4026 }
4027 else
4028 {
4029 /* Look forwards. */
4030 for (next_state = this_type->rlx_more; next_state;)
3e470ab5 4031 if (aim <= this_type->rlx_forward || !this_type->rlx_forward)
b18c562e
NC
4032 next_state = 0;
4033 else
4034 {
4035 /* Grow to next state. */
4036 this_state = next_state;
4037 this_type = table + this_state;
4038 next_state = this_type->rlx_more;
4039 }
4040 }
4041
4042 growth = this_type->rlx_length - start_type->rlx_length;
4043 if (growth != 0)
4044 fragP->fr_subtype = this_state;
4045 return growth;
2469cfa2 4046}
13761a11
NC
4047
4048/* Return FALSE if the fixup in fixp should be left alone and not
4049 adjusted. We return FALSE here so that linker relaxation will
4050 work. */
4051
4052bfd_boolean
4053msp430_fix_adjustable (struct fix *fixp ATTRIBUTE_UNUSED)
4054{
4055 /* If the symbol is in a non-code section then it should be OK. */
4056 if (fixp->fx_addsy
4057 && ((S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_CODE) == 0))
4058 return TRUE;
638d3803 4059
13761a11
NC
4060 return FALSE;
4061}
4062
4063/* Set the contents of the .MSP430.attributes section. */
4064
4065void
4066msp430_md_end (void)
4067{
4068 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_ISA,
638d3803 4069 target_is_430x () ? 2 : 1);
13761a11
NC
4070
4071 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Code_Model,
4072 large_model ? 2 : 1);
4073
4074 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Data_Model,
4075 large_model ? 2 : 1);
4076}
4077
4078/* Returns FALSE if there is a msp430 specific reason why the
4079 subtraction of two same-section symbols cannot be computed by
4080 the assembler. */
4081
4082bfd_boolean
4083msp430_allow_local_subtract (expressionS * left,
4084 expressionS * right,
4085 segT section)
4086{
4087 /* If the symbols are not in a code section then they are OK. */
4088 if ((section->flags & SEC_CODE) == 0)
4089 return TRUE;
4090
4091 if (S_IS_GAS_LOCAL (left->X_add_symbol) || S_IS_GAS_LOCAL (right->X_add_symbol))
4092 return TRUE;
4093
4094 if (left->X_add_symbol == right->X_add_symbol)
4095 return TRUE;
4096
4097 /* We have to assume that there may be instructions between the
4098 two symbols and that relaxation may increase the distance between
4099 them. */
4100 return FALSE;
4101}
This page took 0.682803 seconds and 4 git commands to generate.