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