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