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