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