tc-pru.c revision 1.1 1 1.1 christos /* TI PRU assembler.
2 1.1 christos Copyright (C) 2014-2018 Free Software Foundation, Inc.
3 1.1 christos Contributed by Dimitar Dimitrov <dimitar (at) dinux.eu>
4 1.1 christos Based on tc-nios2.c
5 1.1 christos
6 1.1 christos This file is part of GAS, the GNU Assembler.
7 1.1 christos
8 1.1 christos GAS is free software; you can redistribute it and/or modify
9 1.1 christos it under the terms of the GNU General Public License as published by
10 1.1 christos the Free Software Foundation; either version 3, or (at your option)
11 1.1 christos any later version.
12 1.1 christos
13 1.1 christos GAS is distributed in the hope that it will be useful,
14 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
15 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 1.1 christos GNU General Public License for more details.
17 1.1 christos
18 1.1 christos You should have received a copy of the GNU General Public License
19 1.1 christos along with GAS; see the file COPYING. If not, write to the Free
20 1.1 christos Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21 1.1 christos 02110-1301, USA. */
22 1.1 christos
23 1.1 christos #include "as.h"
24 1.1 christos #include "bfd_stdint.h"
25 1.1 christos #include "opcode/pru.h"
26 1.1 christos #include "elf/pru.h"
27 1.1 christos #include "tc-pru.h"
28 1.1 christos #include "bfd.h"
29 1.1 christos #include "dwarf2dbg.h"
30 1.1 christos #include "subsegs.h"
31 1.1 christos #include "safe-ctype.h"
32 1.1 christos #include "dw2gencfi.h"
33 1.1 christos
34 1.1 christos #ifndef OBJ_ELF
35 1.1 christos /* We are not supporting any other target so we throw a compile time error. */
36 1.1 christos #error "OBJ_ELF not defined"
37 1.1 christos #endif
38 1.1 christos
39 1.1 christos /* This array holds the chars that always start a comment. If the
40 1.1 christos pre-processor is disabled, these aren't very useful. */
41 1.1 christos const char comment_chars[] = "#;";
42 1.1 christos
43 1.1 christos /* This array holds the chars that only start a comment at the beginning of
44 1.1 christos a line. If the line seems to have the form '# 123 filename'
45 1.1 christos .line and .file directives will appear in the pre-processed output. */
46 1.1 christos /* Note that input_file.c hand checks for '#' at the beginning of the
47 1.1 christos first line of the input file. This is because the compiler outputs
48 1.1 christos #NO_APP at the beginning of its output. */
49 1.1 christos /* Also note that C style comments are always supported. */
50 1.1 christos const char line_comment_chars[] = "#;*";
51 1.1 christos
52 1.1 christos /* This array holds machine specific line separator characters. */
53 1.1 christos const char line_separator_chars[] = "";
54 1.1 christos
55 1.1 christos /* Chars that can be used to separate mant from exp in floating point nums. */
56 1.1 christos const char EXP_CHARS[] = "eE";
57 1.1 christos
58 1.1 christos /* Chars that mean this number is a floating point constant.
59 1.1 christos As in 0f12.456
60 1.1 christos or 0d1.2345e12 */
61 1.1 christos const char FLT_CHARS[] = "rRsSfFdDxXpP";
62 1.1 christos
63 1.1 christos /* Machine-dependent command-line options. */
64 1.1 christos
65 1.1 christos struct pru_opt_s
66 1.1 christos {
67 1.1 christos /* -mno-link-relax / -mlink-relax: generate (or not)
68 1.1 christos relocations for linker relaxation. */
69 1.1 christos bfd_boolean link_relax;
70 1.1 christos
71 1.1 christos /* -mno-warn-regname-label: do not output a warning that a label name
72 1.1 christos matches a register name. */
73 1.1 christos bfd_boolean warn_regname_label;
74 1.1 christos };
75 1.1 christos
76 1.1 christos static struct pru_opt_s pru_opt = { TRUE, TRUE };
77 1.1 christos
78 1.1 christos const char *md_shortopts = "r";
79 1.1 christos
80 1.1 christos enum options
81 1.1 christos {
82 1.1 christos OPTION_LINK_RELAX = OPTION_MD_BASE + 1,
83 1.1 christos OPTION_NO_LINK_RELAX,
84 1.1 christos OPTION_NO_WARN_REGNAME_LABEL,
85 1.1 christos };
86 1.1 christos
87 1.1 christos struct option md_longopts[] = {
88 1.1 christos { "mlink-relax", no_argument, NULL, OPTION_LINK_RELAX },
89 1.1 christos { "mno-link-relax", no_argument, NULL, OPTION_NO_LINK_RELAX },
90 1.1 christos { "mno-warn-regname-label", no_argument, NULL,
91 1.1 christos OPTION_NO_WARN_REGNAME_LABEL },
92 1.1 christos { NULL, no_argument, NULL, 0 }
93 1.1 christos };
94 1.1 christos
95 1.1 christos size_t md_longopts_size = sizeof (md_longopts);
96 1.1 christos
97 1.1 christos typedef struct pru_insn_reloc
98 1.1 christos {
99 1.1 christos /* Any expression in the instruction is parsed into this field,
100 1.1 christos which is passed to fix_new_exp () to generate a fixup. */
101 1.1 christos expressionS reloc_expression;
102 1.1 christos
103 1.1 christos /* The type of the relocation to be applied. */
104 1.1 christos bfd_reloc_code_real_type reloc_type;
105 1.1 christos
106 1.1 christos /* PC-relative. */
107 1.1 christos unsigned int reloc_pcrel;
108 1.1 christos
109 1.1 christos /* The next relocation to be applied to the instruction. */
110 1.1 christos struct pru_insn_reloc *reloc_next;
111 1.1 christos } pru_insn_relocS;
112 1.1 christos
113 1.1 christos /* This struct is used to hold state when assembling instructions. */
114 1.1 christos typedef struct pru_insn_info
115 1.1 christos {
116 1.1 christos /* Assembled instruction. */
117 1.1 christos unsigned long insn_code;
118 1.1 christos /* Used for assembling LDI32. */
119 1.1 christos unsigned long ldi32_imm32;
120 1.1 christos
121 1.1 christos /* Pointer to the relevant bit of the opcode table. */
122 1.1 christos const struct pru_opcode *insn_pru_opcode;
123 1.1 christos /* After parsing ptrs to the tokens in the instruction fill this array
124 1.1 christos it is terminated with a null pointer (hence the first +1).
125 1.1 christos The second +1 is because in some parts of the code the opcode
126 1.1 christos is not counted as a token, but still placed in this array. */
127 1.1 christos const char *insn_tokens[PRU_MAX_INSN_TOKENS + 1 + 1];
128 1.1 christos
129 1.1 christos /* This holds information used to generate fixups
130 1.1 christos and eventually relocations if it is not null. */
131 1.1 christos pru_insn_relocS *insn_reloc;
132 1.1 christos } pru_insn_infoS;
133 1.1 christos
134 1.1 christos /* Opcode hash table. */
135 1.1 christos static struct hash_control *pru_opcode_hash = NULL;
136 1.1 christos #define pru_opcode_lookup(NAME) \
137 1.1 christos ((struct pru_opcode *) hash_find (pru_opcode_hash, (NAME)))
138 1.1 christos
139 1.1 christos /* Register hash table. */
140 1.1 christos static struct hash_control *pru_reg_hash = NULL;
141 1.1 christos #define pru_reg_lookup(NAME) \
142 1.1 christos ((struct pru_reg *) hash_find (pru_reg_hash, (NAME)))
143 1.1 christos
144 1.1 christos /* The known current alignment of the current section. */
145 1.1 christos static int pru_current_align;
146 1.1 christos static segT pru_current_align_seg;
147 1.1 christos
148 1.1 christos static int pru_auto_align_on = 1;
149 1.1 christos
150 1.1 christos /* The last seen label in the current section. This is used to auto-align
151 1.1 christos labels preceding instructions. */
152 1.1 christos static symbolS *pru_last_label;
153 1.1 christos
154 1.1 christos
155 1.1 christos /** Utility routines. */
157 1.1 christos /* Function md_chars_to_number takes the sequence of
158 1.1 christos bytes in buf and returns the corresponding value
159 1.1 christos in an int. n must be 1, 2, 4 or 8. */
160 1.1 christos static uint64_t
161 1.1 christos md_chars_to_number (char *buf, int n)
162 1.1 christos {
163 1.1 christos int i;
164 1.1 christos uint64_t val;
165 1.1 christos
166 1.1 christos gas_assert (n == 1 || n == 2 || n == 4 || n == 8);
167 1.1 christos
168 1.1 christos val = 0;
169 1.1 christos for (i = 0; i < n; ++i)
170 1.1 christos val = val | ((buf[i] & 0xff) << 8 * i);
171 1.1 christos return val;
172 1.1 christos }
173 1.1 christos
174 1.1 christos
175 1.1 christos /* This function turns a C long int, short int or char
176 1.1 christos into the series of bytes that represent the number
177 1.1 christos on the target machine. */
178 1.1 christos void
179 1.1 christos md_number_to_chars (char *buf, valueT val, int n)
180 1.1 christos {
181 1.1 christos gas_assert (n == 1 || n == 2 || n == 4 || n == 8);
182 1.1 christos number_to_chars_littleendian (buf, val, n);
183 1.1 christos }
184 1.1 christos
185 1.1 christos /* Turn a string in input_line_pointer into a floating point constant
186 1.1 christos of type TYPE, and store the appropriate bytes in *LITP. The number
187 1.1 christos of LITTLENUMS emitted is stored in *SIZEP. An error message is
188 1.1 christos returned, or NULL on OK. */
189 1.1 christos const char *
190 1.1 christos md_atof (int type, char *litP, int *sizeP)
191 1.1 christos {
192 1.1 christos return ieee_md_atof (type, litP, sizeP, FALSE);
193 1.1 christos }
194 1.1 christos
195 1.1 christos /* Return true if STR starts with PREFIX, which should be a string literal. */
196 1.1 christos #define strprefix(STR, PREFIX) \
197 1.1 christos (strncmp ((STR), PREFIX, strlen (PREFIX)) == 0)
198 1.1 christos
199 1.1 christos /* nop fill pattern for text section. */
200 1.1 christos static char const nop[4] = { 0xe0, 0xe0, 0xe0, 0x12 };
201 1.1 christos
202 1.1 christos /* Handles all machine-dependent alignment needs. */
203 1.1 christos static void
204 1.1 christos pru_align (int log_size, const char *pfill, symbolS *label)
205 1.1 christos {
206 1.1 christos int align;
207 1.1 christos long max_alignment = 15;
208 1.1 christos
209 1.1 christos /* The front end is prone to changing segments out from under us
210 1.1 christos temporarily when -g is in effect. */
211 1.1 christos int switched_seg_p = (pru_current_align_seg != now_seg);
212 1.1 christos
213 1.1 christos align = log_size;
214 1.1 christos if (align > max_alignment)
215 1.1 christos {
216 1.1 christos align = max_alignment;
217 1.1 christos as_bad (_("Alignment too large: %d assumed"), align);
218 1.1 christos }
219 1.1 christos else if (align < 0)
220 1.1 christos {
221 1.1 christos as_warn (_("Alignment negative: 0 assumed"));
222 1.1 christos align = 0;
223 1.1 christos }
224 1.1 christos
225 1.1 christos if (align != 0)
226 1.1 christos {
227 1.1 christos if (subseg_text_p (now_seg) && align >= 2)
228 1.1 christos {
229 1.1 christos /* First, make sure we're on a four-byte boundary, in case
230 1.1 christos someone has been putting .byte values the text section. */
231 1.1 christos if (pru_current_align < 2 || switched_seg_p)
232 1.1 christos frag_align (2, 0, 0);
233 1.1 christos
234 1.1 christos /* Now fill in the alignment pattern. */
235 1.1 christos if (pfill != NULL)
236 1.1 christos frag_align_pattern (align, pfill, sizeof nop, 0);
237 1.1 christos else
238 1.1 christos frag_align (align, 0, 0);
239 1.1 christos }
240 1.1 christos else
241 1.1 christos frag_align (align, 0, 0);
242 1.1 christos
243 1.1 christos if (!switched_seg_p)
244 1.1 christos pru_current_align = align;
245 1.1 christos
246 1.1 christos /* If the last label was in a different section we can't align it. */
247 1.1 christos if (label != NULL && !switched_seg_p)
248 1.1 christos {
249 1.1 christos symbolS *sym;
250 1.1 christos int label_seen = FALSE;
251 1.1 christos struct frag *old_frag;
252 1.1 christos valueT old_value;
253 1.1 christos valueT new_value;
254 1.1 christos
255 1.1 christos gas_assert (S_GET_SEGMENT (label) == now_seg);
256 1.1 christos
257 1.1 christos old_frag = symbol_get_frag (label);
258 1.1 christos old_value = S_GET_VALUE (label);
259 1.1 christos new_value = (valueT) frag_now_fix ();
260 1.1 christos
261 1.1 christos /* It is possible to have more than one label at a particular
262 1.1 christos address, especially if debugging is enabled, so we must
263 1.1 christos take care to adjust all the labels at this address in this
264 1.1 christos fragment. To save time we search from the end of the symbol
265 1.1 christos list, backwards, since the symbols we are interested in are
266 1.1 christos almost certainly the ones that were most recently added.
267 1.1 christos Also to save time we stop searching once we have seen at least
268 1.1 christos one matching label, and we encounter a label that is no longer
269 1.1 christos in the target fragment. Note, this search is guaranteed to
270 1.1 christos find at least one match when sym == label, so no special case
271 1.1 christos code is necessary. */
272 1.1 christos for (sym = symbol_lastP; sym != NULL; sym = symbol_previous (sym))
273 1.1 christos if (symbol_get_frag (sym) == old_frag
274 1.1 christos && S_GET_VALUE (sym) == old_value)
275 1.1 christos {
276 1.1 christos label_seen = TRUE;
277 1.1 christos symbol_set_frag (sym, frag_now);
278 1.1 christos S_SET_VALUE (sym, new_value);
279 1.1 christos }
280 1.1 christos else if (label_seen && symbol_get_frag (sym) != old_frag)
281 1.1 christos break;
282 1.1 christos }
283 1.1 christos record_alignment (now_seg, align);
284 1.1 christos }
285 1.1 christos }
286 1.1 christos
287 1.1 christos
288 1.1 christos /** Support for self-check mode. */
290 1.1 christos
291 1.1 christos /* Mode of the assembler. */
292 1.1 christos typedef enum
293 1.1 christos {
294 1.1 christos PRU_MODE_ASSEMBLE, /* Ordinary operation. */
295 1.1 christos PRU_MODE_TEST /* Hidden mode used for self testing. */
296 1.1 christos } PRU_MODE;
297 1.1 christos
298 1.1 christos static PRU_MODE pru_mode = PRU_MODE_ASSEMBLE;
299 1.1 christos
300 1.1 christos /* This function is used to in self-checking mode
301 1.1 christos to check the assembled instruction.
302 1.1 christos OPCODE should be the assembled opcode, and exp_opcode
303 1.1 christos the parsed string representing the expected opcode. */
304 1.1 christos
305 1.1 christos static void
306 1.1 christos pru_check_assembly (unsigned int opcode, const char *exp_opcode)
307 1.1 christos {
308 1.1 christos if (pru_mode == PRU_MODE_TEST)
309 1.1 christos {
310 1.1 christos if (exp_opcode == NULL)
311 1.1 christos as_bad (_("expecting opcode string in self test mode"));
312 1.1 christos else if (opcode != strtoul (exp_opcode, NULL, 16))
313 1.1 christos as_bad (_("assembly 0x%08x, expected %s"), opcode, exp_opcode);
314 1.1 christos }
315 1.1 christos }
316 1.1 christos
317 1.1 christos
318 1.1 christos /** Support for machine-dependent assembler directives. */
320 1.1 christos /* Handle the .align pseudo-op. This aligns to a power of two. It
321 1.1 christos also adjusts any current instruction label. We treat this the same
322 1.1 christos way the MIPS port does: .align 0 turns off auto alignment. */
323 1.1 christos static void
324 1.1 christos s_pru_align (int ignore ATTRIBUTE_UNUSED)
325 1.1 christos {
326 1.1 christos int align;
327 1.1 christos char fill;
328 1.1 christos const char *pfill = NULL;
329 1.1 christos long max_alignment = 15;
330 1.1 christos
331 1.1 christos align = get_absolute_expression ();
332 1.1 christos if (align > max_alignment)
333 1.1 christos {
334 1.1 christos align = max_alignment;
335 1.1 christos as_bad (_("Alignment too large: %d assumed"), align);
336 1.1 christos }
337 1.1 christos else if (align < 0)
338 1.1 christos {
339 1.1 christos as_warn (_("Alignment negative: 0 assumed"));
340 1.1 christos align = 0;
341 1.1 christos }
342 1.1 christos
343 1.1 christos if (*input_line_pointer == ',')
344 1.1 christos {
345 1.1 christos input_line_pointer++;
346 1.1 christos fill = get_absolute_expression ();
347 1.1 christos pfill = (const char *) &fill;
348 1.1 christos }
349 1.1 christos else if (subseg_text_p (now_seg))
350 1.1 christos pfill = (const char *) &nop;
351 1.1 christos else
352 1.1 christos {
353 1.1 christos pfill = NULL;
354 1.1 christos pru_last_label = NULL;
355 1.1 christos }
356 1.1 christos
357 1.1 christos if (align != 0)
358 1.1 christos {
359 1.1 christos pru_auto_align_on = 1;
360 1.1 christos pru_align (align, pfill, pru_last_label);
361 1.1 christos pru_last_label = NULL;
362 1.1 christos }
363 1.1 christos else
364 1.1 christos pru_auto_align_on = 0;
365 1.1 christos
366 1.1 christos demand_empty_rest_of_line ();
367 1.1 christos }
368 1.1 christos
369 1.1 christos /* Handle the .text pseudo-op. This is like the usual one, but it
370 1.1 christos clears the saved last label and resets known alignment. */
371 1.1 christos static void
372 1.1 christos s_pru_text (int i)
373 1.1 christos {
374 1.1 christos s_text (i);
375 1.1 christos pru_last_label = NULL;
376 1.1 christos pru_current_align = 0;
377 1.1 christos pru_current_align_seg = now_seg;
378 1.1 christos }
379 1.1 christos
380 1.1 christos /* Handle the .data pseudo-op. This is like the usual one, but it
381 1.1 christos clears the saved last label and resets known alignment. */
382 1.1 christos static void
383 1.1 christos s_pru_data (int i)
384 1.1 christos {
385 1.1 christos s_data (i);
386 1.1 christos pru_last_label = NULL;
387 1.1 christos pru_current_align = 0;
388 1.1 christos pru_current_align_seg = now_seg;
389 1.1 christos }
390 1.1 christos
391 1.1 christos /* Handle the .section pseudo-op. This is like the usual one, but it
392 1.1 christos clears the saved last label and resets known alignment. */
393 1.1 christos static void
394 1.1 christos s_pru_section (int ignore)
395 1.1 christos {
396 1.1 christos obj_elf_section (ignore);
397 1.1 christos pru_last_label = NULL;
398 1.1 christos pru_current_align = 0;
399 1.1 christos pru_current_align_seg = now_seg;
400 1.1 christos }
401 1.1 christos
402 1.1 christos /* Explicitly unaligned cons. */
403 1.1 christos static void
404 1.1 christos s_pru_ucons (int nbytes)
405 1.1 christos {
406 1.1 christos int hold;
407 1.1 christos hold = pru_auto_align_on;
408 1.1 christos pru_auto_align_on = 0;
409 1.1 christos cons (nbytes);
410 1.1 christos pru_auto_align_on = hold;
411 1.1 christos }
412 1.1 christos
413 1.1 christos /* .set sets assembler options. */
414 1.1 christos static void
415 1.1 christos s_pru_set (int equiv)
416 1.1 christos {
417 1.1 christos char *save = input_line_pointer;
418 1.1 christos char *directive;
419 1.1 christos char delim = get_symbol_name (&directive);
420 1.1 christos char *endline = input_line_pointer;
421 1.1 christos
422 1.1 christos (void) restore_line_pointer (delim);
423 1.1 christos
424 1.1 christos /* We only want to handle ".set XXX" if the
425 1.1 christos user has tried ".set XXX, YYY" they are not
426 1.1 christos trying a directive. This prevents
427 1.1 christos us from polluting the name space. */
428 1.1 christos SKIP_WHITESPACE ();
429 1.1 christos if (is_end_of_line[(unsigned char) *input_line_pointer])
430 1.1 christos {
431 1.1 christos bfd_boolean done = TRUE;
432 1.1 christos *endline = 0;
433 1.1 christos
434 1.1 christos if (!strcmp (directive, "no_warn_regname_label"))
435 1.1 christos pru_opt.warn_regname_label = FALSE;
436 1.1 christos else
437 1.1 christos done = FALSE;
438 1.1 christos
439 1.1 christos if (done)
440 1.1 christos {
441 1.1 christos *endline = delim;
442 1.1 christos demand_empty_rest_of_line ();
443 1.1 christos return;
444 1.1 christos }
445 1.1 christos }
446 1.1 christos
447 1.1 christos /* If we fall through to here, either we have ".set XXX, YYY"
448 1.1 christos or we have ".set XXX" where XXX is unknown or we have
449 1.1 christos a syntax error. */
450 1.1 christos input_line_pointer = save;
451 1.1 christos s_set (equiv);
452 1.1 christos }
453 1.1 christos
454 1.1 christos /* Machine-dependent assembler directives.
455 1.1 christos Format of each entry is:
456 1.1 christos { "directive", handler_func, param } */
457 1.1 christos const pseudo_typeS md_pseudo_table[] = {
458 1.1 christos {"align", s_pru_align, 0},
459 1.1 christos {"text", s_pru_text, 0},
460 1.1 christos {"data", s_pru_data, 0},
461 1.1 christos {"section", s_pru_section, 0},
462 1.1 christos {"section.s", s_pru_section, 0},
463 1.1 christos {"sect", s_pru_section, 0},
464 1.1 christos {"sect.s", s_pru_section, 0},
465 1.1 christos /* .dword and .half are included for compatibility with MIPS. */
466 1.1 christos {"dword", cons, 8},
467 1.1 christos {"half", cons, 2},
468 1.1 christos /* PRU native word size is 4 bytes, so we override
469 1.1 christos the GAS default of 2. */
470 1.1 christos {"word", cons, 4},
471 1.1 christos /* Explicitly unaligned directives. */
472 1.1 christos {"2byte", s_pru_ucons, 2},
473 1.1 christos {"4byte", s_pru_ucons, 4},
474 1.1 christos {"8byte", s_pru_ucons, 8},
475 1.1 christos {"16byte", s_pru_ucons, 16},
476 1.1 christos {"set", s_pru_set, 0},
477 1.1 christos {NULL, NULL, 0}
478 1.1 christos };
479 1.1 christos
480 1.1 christos
481 1.1 christos int
483 1.1 christos md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
484 1.1 christos asection *seg ATTRIBUTE_UNUSED)
485 1.1 christos {
486 1.1 christos abort ();
487 1.1 christos return 0;
488 1.1 christos }
489 1.1 christos
490 1.1 christos void
491 1.1 christos md_convert_frag (bfd *headers ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED,
492 1.1 christos fragS *fragp ATTRIBUTE_UNUSED)
493 1.1 christos {
494 1.1 christos abort ();
495 1.1 christos }
496 1.1 christos
497 1.1 christos
498 1.1 christos static bfd_boolean
500 1.1 christos relaxable_section (asection *sec)
501 1.1 christos {
502 1.1 christos return ((sec->flags & SEC_DEBUGGING) == 0
503 1.1 christos && (sec->flags & SEC_CODE) != 0
504 1.1 christos && (sec->flags & SEC_ALLOC) != 0);
505 1.1 christos }
506 1.1 christos
507 1.1 christos /* Does whatever the xtensa port does. */
508 1.1 christos int
509 1.1 christos pru_validate_fix_sub (fixS *fix)
510 1.1 christos {
511 1.1 christos segT add_symbol_segment, sub_symbol_segment;
512 1.1 christos
513 1.1 christos /* The difference of two symbols should be resolved by the assembler when
514 1.1 christos linkrelax is not set. If the linker may relax the section containing
515 1.1 christos the symbols, then an Xtensa DIFF relocation must be generated so that
516 1.1 christos the linker knows to adjust the difference value. */
517 1.1 christos if (!linkrelax || fix->fx_addsy == NULL)
518 1.1 christos return 0;
519 1.1 christos
520 1.1 christos /* Make sure both symbols are in the same segment, and that segment is
521 1.1 christos "normal" and relaxable. If the segment is not "normal", then the
522 1.1 christos fix is not valid. If the segment is not "relaxable", then the fix
523 1.1 christos should have been handled earlier. */
524 1.1 christos add_symbol_segment = S_GET_SEGMENT (fix->fx_addsy);
525 1.1 christos if (! SEG_NORMAL (add_symbol_segment)
526 1.1 christos || ! relaxable_section (add_symbol_segment))
527 1.1 christos return 0;
528 1.1 christos
529 1.1 christos sub_symbol_segment = S_GET_SEGMENT (fix->fx_subsy);
530 1.1 christos return (sub_symbol_segment == add_symbol_segment);
531 1.1 christos }
532 1.1 christos
533 1.1 christos /* TC_FORCE_RELOCATION hook. */
534 1.1 christos
535 1.1 christos /* If linkrelax is turned on, and the symbol to relocate
536 1.1 christos against is in a relaxable segment, don't compute the value -
537 1.1 christos generate a relocation instead. */
538 1.1 christos int
539 1.1 christos pru_force_relocation (fixS *fix)
540 1.1 christos {
541 1.1 christos if (linkrelax && fix->fx_addsy
542 1.1 christos && relaxable_section (S_GET_SEGMENT (fix->fx_addsy)))
543 1.1 christos return 1;
544 1.1 christos
545 1.1 christos return generic_force_reloc (fix);
546 1.1 christos }
547 1.1 christos
548 1.1 christos
549 1.1 christos
550 1.1 christos /** Fixups and overflow checking. */
552 1.1 christos
553 1.1 christos /* Check a fixup for overflow. */
554 1.1 christos static bfd_reloc_status_type
555 1.1 christos pru_check_overflow (valueT fixup, reloc_howto_type *howto)
556 1.1 christos {
557 1.1 christos bfd_reloc_status_type ret;
558 1.1 christos
559 1.1 christos ret = bfd_check_overflow (howto->complain_on_overflow,
560 1.1 christos howto->bitsize,
561 1.1 christos howto->rightshift,
562 1.1 christos bfd_get_reloc_size (howto) * 8,
563 1.1 christos fixup);
564 1.1 christos
565 1.1 christos return ret;
566 1.1 christos }
567 1.1 christos
568 1.1 christos /* Emit diagnostic for fixup overflow. */
569 1.1 christos static void
570 1.1 christos pru_diagnose_overflow (valueT fixup, reloc_howto_type *howto,
571 1.1 christos fixS *fixP, valueT value)
572 1.1 christos {
573 1.1 christos if (fixP->fx_r_type == BFD_RELOC_8
574 1.1 christos || fixP->fx_r_type == BFD_RELOC_16
575 1.1 christos || fixP->fx_r_type == BFD_RELOC_32)
576 1.1 christos /* These relocs are against data, not instructions. */
577 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line,
578 1.1 christos _("immediate value 0x%x truncated to 0x%x"),
579 1.1 christos (unsigned int) fixup,
580 1.1 christos (unsigned int) (~(~(valueT) 0 << howto->bitsize) & fixup));
581 1.1 christos else
582 1.1 christos {
583 1.1 christos /* What opcode is the instruction? This will determine
584 1.1 christos whether we check for overflow in immediate values
585 1.1 christos and what error message we get. */
586 1.1 christos const struct pru_opcode *opcode;
587 1.1 christos enum overflow_type overflow_msg_type;
588 1.1 christos unsigned int range_min;
589 1.1 christos unsigned int range_max;
590 1.1 christos unsigned int address;
591 1.1 christos gas_assert (fixP->fx_size == 4);
592 1.1 christos opcode = pru_find_opcode (value);
593 1.1 christos gas_assert (opcode);
594 1.1 christos overflow_msg_type = opcode->overflow_msg;
595 1.1 christos switch (overflow_msg_type)
596 1.1 christos {
597 1.1 christos case call_target_overflow:
598 1.1 christos range_min
599 1.1 christos = ((fixP->fx_frag->fr_address + fixP->fx_where) & 0xf0000000);
600 1.1 christos range_max = range_min + 0x0fffffff;
601 1.1 christos address = fixup | range_min;
602 1.1 christos
603 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line,
604 1.1 christos _("call target address 0x%08x out of range 0x%08x to 0x%08x"),
605 1.1 christos address, range_min, range_max);
606 1.1 christos break;
607 1.1 christos case qbranch_target_overflow:
608 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line,
609 1.1 christos _("quick branch offset %d out of range %d to %d"),
610 1.1 christos (int)fixup, -((1<<9) * 4), (1 << 9) * 4);
611 1.1 christos break;
612 1.1 christos case address_offset_overflow:
613 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line,
614 1.1 christos _("%s offset %d out of range %d to %d"),
615 1.1 christos opcode->name, (int)fixup, -32768, 32767);
616 1.1 christos break;
617 1.1 christos case signed_immed16_overflow:
618 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line,
619 1.1 christos _("immediate value %d out of range %d to %d"),
620 1.1 christos (int)fixup, -32768, 32767);
621 1.1 christos break;
622 1.1 christos case unsigned_immed32_overflow:
623 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line,
624 1.1 christos _("immediate value %llu out of range %u to %lu"),
625 1.1 christos (unsigned long long)fixup, 0, 0xfffffffflu);
626 1.1 christos break;
627 1.1 christos case unsigned_immed16_overflow:
628 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line,
629 1.1 christos _("immediate value %u out of range %u to %u"),
630 1.1 christos (unsigned int)fixup, 0, 65535);
631 1.1 christos break;
632 1.1 christos case unsigned_immed5_overflow:
633 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line,
634 1.1 christos _("immediate value %u out of range %u to %u"),
635 1.1 christos (unsigned int)fixup, 0, 31);
636 1.1 christos break;
637 1.1 christos default:
638 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line,
639 1.1 christos _("overflow in immediate argument"));
640 1.1 christos break;
641 1.1 christos }
642 1.1 christos }
643 1.1 christos }
644 1.1 christos
645 1.1 christos /* Apply a fixup to the object file. */
646 1.1 christos void
647 1.1 christos md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
648 1.1 christos {
649 1.1 christos unsigned char *where;
650 1.1 christos valueT value = *valP;
651 1.1 christos long n;
652 1.1 christos
653 1.1 christos /* Assert that the fixup is one we can handle. */
654 1.1 christos gas_assert (fixP != NULL && valP != NULL
655 1.1 christos && (fixP->fx_r_type == BFD_RELOC_8
656 1.1 christos || fixP->fx_r_type == BFD_RELOC_16
657 1.1 christos || fixP->fx_r_type == BFD_RELOC_32
658 1.1 christos || fixP->fx_r_type == BFD_RELOC_64
659 1.1 christos || fixP->fx_r_type == BFD_RELOC_PRU_LDI32
660 1.1 christos || fixP->fx_r_type == BFD_RELOC_PRU_U16
661 1.1 christos || fixP->fx_r_type == BFD_RELOC_PRU_U16_PMEMIMM
662 1.1 christos || fixP->fx_r_type == BFD_RELOC_PRU_S10_PCREL
663 1.1 christos || fixP->fx_r_type == BFD_RELOC_PRU_U8_PCREL
664 1.1 christos || fixP->fx_r_type == BFD_RELOC_PRU_32_PMEM
665 1.1 christos || fixP->fx_r_type == BFD_RELOC_PRU_16_PMEM
666 1.1 christos /* Add other relocs here as we generate them. */
667 1.1 christos ));
668 1.1 christos
669 1.1 christos if (fixP->fx_r_type == BFD_RELOC_64)
670 1.1 christos {
671 1.1 christos /* We may reach here due to .8byte directives, but we never output
672 1.1 christos BFD_RELOC_64; it must be resolved. */
673 1.1 christos if (fixP->fx_addsy != NULL)
674 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line,
675 1.1 christos _("cannot create 64-bit relocation"));
676 1.1 christos else
677 1.1 christos {
678 1.1 christos md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
679 1.1 christos *valP, 8);
680 1.1 christos fixP->fx_done = 1;
681 1.1 christos }
682 1.1 christos return;
683 1.1 christos }
684 1.1 christos
685 1.1 christos /* gas_assert (had_errors () || !fixP->fx_subsy); */
686 1.1 christos
687 1.1 christos /* In general, fix instructions with immediate
688 1.1 christos constants. But leave LDI32 for the linker,
689 1.1 christos which is prepared to shorten insns. */
690 1.1 christos if (fixP->fx_addsy == (symbolS *) NULL
691 1.1 christos && fixP->fx_r_type != BFD_RELOC_PRU_LDI32)
692 1.1 christos fixP->fx_done = 1;
693 1.1 christos
694 1.1 christos else if (fixP->fx_pcrel)
695 1.1 christos {
696 1.1 christos segT s = S_GET_SEGMENT (fixP->fx_addsy);
697 1.1 christos
698 1.1 christos if (s == seg || s == absolute_section)
699 1.1 christos {
700 1.1 christos /* Blindly copied from AVR, but I don't understand why
701 1.1 christos this is needed in the first place. Fail hard to catch
702 1.1 christos when this curious code snippet is utilized. */
703 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line,
704 1.1 christos _("unexpected PC relative expression"));
705 1.1 christos value += S_GET_VALUE (fixP->fx_addsy);
706 1.1 christos fixP->fx_done = 1;
707 1.1 christos }
708 1.1 christos }
709 1.1 christos else if (linkrelax && fixP->fx_subsy)
710 1.1 christos {
711 1.1 christos /* For a subtraction relocation expression, generate one
712 1.1 christos of the DIFF relocs, with the value being the difference.
713 1.1 christos Note that a sym1 - sym2 expression is adjusted into a
714 1.1 christos section_start_sym + sym4_offset_from_section_start - sym1
715 1.1 christos expression. fixP->fx_addsy holds the section start symbol,
716 1.1 christos fixP->fx_offset holds sym2's offset, and fixP->fx_subsy
717 1.1 christos holds sym1. Calculate the current difference and write value,
718 1.1 christos but leave fx_offset as is - during relaxation,
719 1.1 christos fx_offset - value gives sym1's value. */
720 1.1 christos
721 1.1 christos offsetT diffval; /* valueT is unsigned, so use offsetT. */
722 1.1 christos
723 1.1 christos diffval = S_GET_VALUE (fixP->fx_addsy)
724 1.1 christos + fixP->fx_offset - S_GET_VALUE (fixP->fx_subsy);
725 1.1 christos
726 1.1 christos switch (fixP->fx_r_type)
727 1.1 christos {
728 1.1 christos case BFD_RELOC_8:
729 1.1 christos fixP->fx_r_type = BFD_RELOC_PRU_GNU_DIFF8;
730 1.1 christos break;
731 1.1 christos case BFD_RELOC_16:
732 1.1 christos fixP->fx_r_type = BFD_RELOC_PRU_GNU_DIFF16;
733 1.1 christos break;
734 1.1 christos case BFD_RELOC_32:
735 1.1 christos fixP->fx_r_type = BFD_RELOC_PRU_GNU_DIFF32;
736 1.1 christos break;
737 1.1 christos case BFD_RELOC_PRU_16_PMEM:
738 1.1 christos fixP->fx_r_type = BFD_RELOC_PRU_GNU_DIFF16_PMEM;
739 1.1 christos if (diffval % 4)
740 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line,
741 1.1 christos _("residual low bits in pmem diff relocation"));
742 1.1 christos diffval /= 4;
743 1.1 christos break;
744 1.1 christos case BFD_RELOC_PRU_32_PMEM:
745 1.1 christos fixP->fx_r_type = BFD_RELOC_PRU_GNU_DIFF32_PMEM;
746 1.1 christos if (diffval % 4)
747 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line,
748 1.1 christos _("residual low bits in pmem diff relocation"));
749 1.1 christos diffval /= 4;
750 1.1 christos break;
751 1.1 christos default:
752 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line,
753 1.1 christos _("expression too complex"));
754 1.1 christos break;
755 1.1 christos }
756 1.1 christos
757 1.1 christos value = *valP = diffval;
758 1.1 christos
759 1.1 christos fixP->fx_subsy = NULL;
760 1.1 christos }
761 1.1 christos /* We don't actually support subtracting a symbol. */
762 1.1 christos if (fixP->fx_subsy != (symbolS *) NULL)
763 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
764 1.1 christos
765 1.1 christos /* For the DIFF relocs, write the value into the object file while still
766 1.1 christos keeping fx_done FALSE, as both the difference (recorded in the object file)
767 1.1 christos and the sym offset (part of fixP) are needed at link relax time. */
768 1.1 christos where = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where;
769 1.1 christos switch (fixP->fx_r_type)
770 1.1 christos {
771 1.1 christos case BFD_RELOC_PRU_GNU_DIFF8:
772 1.1 christos *where = value;
773 1.1 christos break;
774 1.1 christos case BFD_RELOC_PRU_GNU_DIFF16:
775 1.1 christos case BFD_RELOC_PRU_GNU_DIFF16_PMEM:
776 1.1 christos bfd_putl16 ((bfd_vma) value, where);
777 1.1 christos break;
778 1.1 christos case BFD_RELOC_PRU_GNU_DIFF32:
779 1.1 christos case BFD_RELOC_PRU_GNU_DIFF32_PMEM:
780 1.1 christos bfd_putl32 ((bfd_vma) value, where);
781 1.1 christos break;
782 1.1 christos default:
783 1.1 christos break;
784 1.1 christos }
785 1.1 christos
786 1.1 christos if (fixP->fx_done)
787 1.1 christos /* Fully resolved fixup. */
788 1.1 christos {
789 1.1 christos reloc_howto_type *howto
790 1.1 christos = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
791 1.1 christos
792 1.1 christos if (howto == NULL)
793 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line,
794 1.1 christos _("relocation is not supported"));
795 1.1 christos else
796 1.1 christos {
797 1.1 christos valueT fixup = value;
798 1.1 christos uint64_t insn;
799 1.1 christos char *buf;
800 1.1 christos
801 1.1 christos /* Get the instruction or data to be fixed up. */
802 1.1 christos buf = fixP->fx_frag->fr_literal + fixP->fx_where;
803 1.1 christos insn = md_chars_to_number (buf, fixP->fx_size);
804 1.1 christos
805 1.1 christos /* Check for overflow, emitting a diagnostic if necessary. */
806 1.1 christos if (pru_check_overflow (fixup, howto) != bfd_reloc_ok)
807 1.1 christos pru_diagnose_overflow (fixup, howto, fixP, insn);
808 1.1 christos
809 1.1 christos /* Apply the right shift. */
810 1.1 christos fixup = ((offsetT)fixup) >> howto->rightshift;
811 1.1 christos
812 1.1 christos /* Truncate the fixup to right size. */
813 1.1 christos n = sizeof (fixup) * 8 - howto->bitsize;
814 1.1 christos fixup = (fixup << n) >> n;
815 1.1 christos
816 1.1 christos /* Fix up the instruction. Non-contiguous bitfields need
817 1.1 christos special handling. */
818 1.1 christos if (fixP->fx_r_type == BFD_RELOC_PRU_LDI32)
819 1.1 christos {
820 1.1 christos /* As the only 64-bit "insn", LDI32 needs special handling. */
821 1.1 christos uint32_t insn1 = insn & 0xffffffff;
822 1.1 christos uint32_t insn2 = insn >> 32;
823 1.1 christos SET_INSN_FIELD (IMM16, insn1, fixup >> 16);
824 1.1 christos SET_INSN_FIELD (IMM16, insn2, fixup & 0xffff);
825 1.1 christos
826 1.1 christos SET_INSN_FIELD (RDSEL, insn1, RSEL_31_16);
827 1.1 christos SET_INSN_FIELD (RDSEL, insn2, RSEL_15_0);
828 1.1 christos
829 1.1 christos md_number_to_chars (buf, insn1, 4);
830 1.1 christos md_number_to_chars (buf + 4, insn2, 4);
831 1.1 christos }
832 1.1 christos else
833 1.1 christos {
834 1.1 christos if (fixP->fx_r_type == BFD_RELOC_PRU_S10_PCREL)
835 1.1 christos SET_BROFF_URAW (insn, fixup);
836 1.1 christos else
837 1.1 christos insn = (insn & ~howto->dst_mask) | (fixup << howto->bitpos);
838 1.1 christos md_number_to_chars (buf, insn, fixP->fx_size);
839 1.1 christos }
840 1.1 christos }
841 1.1 christos
842 1.1 christos fixP->fx_done = 1;
843 1.1 christos }
844 1.1 christos
845 1.1 christos if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT)
846 1.1 christos {
847 1.1 christos fixP->fx_done = 0;
848 1.1 christos if (fixP->fx_addsy
849 1.1 christos && !S_IS_DEFINED (fixP->fx_addsy) && !S_IS_WEAK (fixP->fx_addsy))
850 1.1 christos S_SET_WEAK (fixP->fx_addsy);
851 1.1 christos }
852 1.1 christos else if (fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
853 1.1 christos fixP->fx_done = 0;
854 1.1 christos }
855 1.1 christos
856 1.1 christos
857 1.1 christos
858 1.1 christos /** Instruction parsing support. */
860 1.1 christos
861 1.1 christos /* Creates a new pru_insn_relocS and returns a pointer to it. */
862 1.1 christos static pru_insn_relocS *
863 1.1 christos pru_insn_reloc_new (bfd_reloc_code_real_type reloc_type, unsigned int pcrel)
864 1.1 christos {
865 1.1 christos pru_insn_relocS *retval;
866 1.1 christos retval = XNEW (pru_insn_relocS);
867 1.1 christos if (retval == NULL)
868 1.1 christos {
869 1.1 christos as_bad (_("can't create relocation"));
870 1.1 christos abort ();
871 1.1 christos }
872 1.1 christos
873 1.1 christos /* Fill out the fields with default values. */
874 1.1 christos retval->reloc_next = NULL;
875 1.1 christos retval->reloc_type = reloc_type;
876 1.1 christos retval->reloc_pcrel = pcrel;
877 1.1 christos return retval;
878 1.1 christos }
879 1.1 christos
880 1.1 christos /* Frees up memory previously allocated by pru_insn_reloc_new (). */
881 1.1 christos static void
882 1.1 christos pru_insn_reloc_destroy (pru_insn_relocS *reloc)
883 1.1 christos {
884 1.1 christos pru_insn_relocS *next;
885 1.1 christos
886 1.1 christos while (reloc)
887 1.1 christos {
888 1.1 christos next = reloc->reloc_next;
889 1.1 christos free (reloc);
890 1.1 christos reloc = next;
891 1.1 christos }
892 1.1 christos }
893 1.1 christos
894 1.1 christos /* The various pru_assemble_* functions call this
895 1.1 christos function to generate an expression from a string representing an expression.
896 1.1 christos It then tries to evaluate the expression, and if it can, returns its value.
897 1.1 christos If not, it creates a new pru_insn_relocS and stores the expression and
898 1.1 christos reloc_type for future use. */
899 1.1 christos static unsigned long
900 1.1 christos pru_assemble_expression (const char *exprstr,
901 1.1 christos pru_insn_infoS *insn,
902 1.1 christos pru_insn_relocS *prev_reloc,
903 1.1 christos bfd_reloc_code_real_type reloc_type,
904 1.1 christos unsigned int pcrel)
905 1.1 christos {
906 1.1 christos expressionS *ep;
907 1.1 christos pru_insn_relocS *reloc;
908 1.1 christos char *saved_line_ptr;
909 1.1 christos unsigned short value;
910 1.1 christos
911 1.1 christos gas_assert (exprstr != NULL);
912 1.1 christos gas_assert (insn != NULL);
913 1.1 christos
914 1.1 christos /* We use this blank keyword to distinguish register from
915 1.1 christos label operands. */
916 1.1 christos if (strstr (exprstr, "%label") != NULL)
917 1.1 christos {
918 1.1 christos exprstr += strlen ("%label") + 1;
919 1.1 christos }
920 1.1 christos
921 1.1 christos /* Check for pmem relocation operator.
922 1.1 christos Change the relocation type and advance the ptr to the start of
923 1.1 christos the expression proper. */
924 1.1 christos if (strstr (exprstr, "%pmem") != NULL)
925 1.1 christos {
926 1.1 christos reloc_type = BFD_RELOC_PRU_U16_PMEMIMM;
927 1.1 christos exprstr += strlen ("%pmem") + 1;
928 1.1 christos }
929 1.1 christos
930 1.1 christos /* We potentially have a relocation. */
931 1.1 christos reloc = pru_insn_reloc_new (reloc_type, pcrel);
932 1.1 christos if (prev_reloc != NULL)
933 1.1 christos prev_reloc->reloc_next = reloc;
934 1.1 christos else
935 1.1 christos insn->insn_reloc = reloc;
936 1.1 christos
937 1.1 christos /* Parse the expression string. */
938 1.1 christos ep = &reloc->reloc_expression;
939 1.1 christos saved_line_ptr = input_line_pointer;
940 1.1 christos input_line_pointer = (char *) exprstr;
941 1.1 christos SKIP_WHITESPACE ();
942 1.1 christos expression (ep);
943 1.1 christos SKIP_WHITESPACE ();
944 1.1 christos if (*input_line_pointer)
945 1.1 christos as_bad (_("trailing garbage after expression: %s"), input_line_pointer);
946 1.1 christos input_line_pointer = saved_line_ptr;
947 1.1 christos
948 1.1 christos
949 1.1 christos if (ep->X_op == O_illegal || ep->X_op == O_absent)
950 1.1 christos as_bad (_("expected expression, got %s"), exprstr);
951 1.1 christos
952 1.1 christos /* This is redundant as the fixup will put this into
953 1.1 christos the instruction, but it is included here so that
954 1.1 christos self-test mode (-r) works. */
955 1.1 christos value = 0;
956 1.1 christos if (pru_mode == PRU_MODE_TEST && ep->X_op == O_constant)
957 1.1 christos value = ep->X_add_number;
958 1.1 christos
959 1.1 christos return (unsigned long) value;
960 1.1 christos }
961 1.1 christos
962 1.1 christos /* Try to parse a non-relocatable expression. */
963 1.1 christos static unsigned long
964 1.1 christos pru_assemble_noreloc_expression (const char *exprstr)
965 1.1 christos {
966 1.1 christos expressionS exp;
967 1.1 christos char *saved_line_ptr;
968 1.1 christos unsigned long val;
969 1.1 christos
970 1.1 christos gas_assert (exprstr != NULL);
971 1.1 christos
972 1.1 christos saved_line_ptr = input_line_pointer;
973 1.1 christos input_line_pointer = (char *) exprstr;
974 1.1 christos SKIP_WHITESPACE ();
975 1.1 christos expression (&exp);
976 1.1 christos SKIP_WHITESPACE ();
977 1.1 christos if (*input_line_pointer)
978 1.1 christos as_bad (_("trailing garbage after expression: %s"), input_line_pointer);
979 1.1 christos input_line_pointer = saved_line_ptr;
980 1.1 christos
981 1.1 christos val = 0;
982 1.1 christos if (exp.X_op != O_constant)
983 1.1 christos as_bad (_("expected constant expression, got %s"), exprstr);
984 1.1 christos else
985 1.1 christos val = exp.X_add_number;
986 1.1 christos
987 1.1 christos return val;
988 1.1 christos }
989 1.1 christos
990 1.1 christos /* Argument assemble functions.
991 1.1 christos All take an instruction argument string, and a pointer
992 1.1 christos to an instruction opcode. Upon return the insn_opcode
993 1.1 christos has the relevant fields filled in to represent the arg
994 1.1 christos string. The return value is NULL if successful, or
995 1.1 christos an error message if an error was detected. */
996 1.1 christos
997 1.1 christos static void
998 1.1 christos pru_assemble_arg_d (pru_insn_infoS *insn_info, const char *argstr)
999 1.1 christos {
1000 1.1 christos struct pru_reg *dst = pru_reg_lookup (argstr);
1001 1.1 christos
1002 1.1 christos if (dst == NULL)
1003 1.1 christos as_bad (_("unknown register %s"), argstr);
1004 1.1 christos else
1005 1.1 christos {
1006 1.1 christos SET_INSN_FIELD (RD, insn_info->insn_code, dst->index);
1007 1.1 christos SET_INSN_FIELD (RDSEL, insn_info->insn_code, dst->regsel);
1008 1.1 christos }
1009 1.1 christos }
1010 1.1 christos
1011 1.1 christos static void
1012 1.1 christos pru_assemble_arg_D (pru_insn_infoS *insn_info, const char *argstr)
1013 1.1 christos {
1014 1.1 christos struct pru_reg *dst;
1015 1.1 christos
1016 1.1 christos /* The leading & before an address register is optional. */
1017 1.1 christos if (*argstr == '&')
1018 1.1 christos argstr++;
1019 1.1 christos
1020 1.1 christos dst = pru_reg_lookup (argstr);
1021 1.1 christos
1022 1.1 christos if (dst == NULL)
1023 1.1 christos as_bad (_("unknown register %s"), argstr);
1024 1.1 christos else
1025 1.1 christos {
1026 1.1 christos unsigned long rxb = 0;
1027 1.1 christos
1028 1.1 christos switch (dst->regsel)
1029 1.1 christos {
1030 1.1 christos case RSEL_31_0: rxb = 0; break; /* whole register defaults to .b0 */
1031 1.1 christos case RSEL_7_0: rxb = 0; break;
1032 1.1 christos case RSEL_15_8: rxb = 1; break;
1033 1.1 christos case RSEL_23_16: rxb = 2; break;
1034 1.1 christos case RSEL_31_24: rxb = 3; break;
1035 1.1 christos default:
1036 1.1 christos as_bad (_("data transfer register cannot be halfword"));
1037 1.1 christos }
1038 1.1 christos
1039 1.1 christos SET_INSN_FIELD (RD, insn_info->insn_code, dst->index);
1040 1.1 christos SET_INSN_FIELD (RDB, insn_info->insn_code, rxb);
1041 1.1 christos }
1042 1.1 christos }
1043 1.1 christos
1044 1.1 christos static void
1045 1.1 christos pru_assemble_arg_R (pru_insn_infoS *insn_info, const char *argstr)
1046 1.1 christos {
1047 1.1 christos struct pru_reg *dst = pru_reg_lookup (argstr);
1048 1.1 christos
1049 1.1 christos if (dst == NULL)
1050 1.1 christos as_bad (_("unknown register %s"), argstr);
1051 1.1 christos else
1052 1.1 christos {
1053 1.1 christos if (dst->regsel != RSEL_31_0)
1054 1.1 christos {
1055 1.1 christos as_bad (_("destination register must be full-word"));
1056 1.1 christos }
1057 1.1 christos
1058 1.1 christos SET_INSN_FIELD (RD, insn_info->insn_code, dst->index);
1059 1.1 christos SET_INSN_FIELD (RDSEL, insn_info->insn_code, dst->regsel);
1060 1.1 christos }
1061 1.1 christos }
1062 1.1 christos
1063 1.1 christos static void
1064 1.1 christos pru_assemble_arg_s (pru_insn_infoS *insn_info, const char *argstr)
1065 1.1 christos {
1066 1.1 christos struct pru_reg *src1 = pru_reg_lookup (argstr);
1067 1.1 christos
1068 1.1 christos if (src1 == NULL)
1069 1.1 christos as_bad (_("unknown register %s"), argstr);
1070 1.1 christos else
1071 1.1 christos {
1072 1.1 christos SET_INSN_FIELD (RS1, insn_info->insn_code, src1->index);
1073 1.1 christos SET_INSN_FIELD (RS1SEL, insn_info->insn_code, src1->regsel);
1074 1.1 christos }
1075 1.1 christos }
1076 1.1 christos
1077 1.1 christos static void
1078 1.1 christos pru_assemble_arg_S (pru_insn_infoS *insn_info, const char *argstr)
1079 1.1 christos {
1080 1.1 christos struct pru_reg *src1 = pru_reg_lookup (argstr);
1081 1.1 christos
1082 1.1 christos if (src1 == NULL)
1083 1.1 christos as_bad (_("unknown register %s"), argstr);
1084 1.1 christos else
1085 1.1 christos {
1086 1.1 christos if (src1->regsel != RSEL_31_0)
1087 1.1 christos as_bad (_("cannot use partial register %s for addressing"), argstr);
1088 1.1 christos SET_INSN_FIELD (RS1, insn_info->insn_code, src1->index);
1089 1.1 christos }
1090 1.1 christos }
1091 1.1 christos
1092 1.1 christos static void
1093 1.1 christos pru_assemble_arg_b (pru_insn_infoS *insn_info, const char *argstr)
1094 1.1 christos {
1095 1.1 christos struct pru_reg *src2 = pru_reg_lookup (argstr);
1096 1.1 christos if (src2 == NULL)
1097 1.1 christos {
1098 1.1 christos unsigned long imm8 = pru_assemble_noreloc_expression (argstr);
1099 1.1 christos if (imm8 >= 0x100)
1100 1.1 christos as_bad (_("value %lu is too large for a byte operand"), imm8);
1101 1.1 christos SET_INSN_FIELD (IMM8, insn_info->insn_code, imm8);
1102 1.1 christos SET_INSN_FIELD (IO, insn_info->insn_code, 1);
1103 1.1 christos }
1104 1.1 christos else
1105 1.1 christos {
1106 1.1 christos SET_INSN_FIELD (IO, insn_info->insn_code, 0);
1107 1.1 christos SET_INSN_FIELD (RS2, insn_info->insn_code, src2->index);
1108 1.1 christos SET_INSN_FIELD (RS2SEL, insn_info->insn_code, src2->regsel);
1109 1.1 christos }
1110 1.1 christos
1111 1.1 christos }
1112 1.1 christos
1113 1.1 christos static void
1114 1.1 christos pru_assemble_arg_B (pru_insn_infoS *insn_info, const char *argstr)
1115 1.1 christos {
1116 1.1 christos struct pru_reg *src2 = pru_reg_lookup (argstr);
1117 1.1 christos if (src2 == NULL)
1118 1.1 christos {
1119 1.1 christos unsigned long imm8;
1120 1.1 christos imm8 = pru_assemble_noreloc_expression (argstr);
1121 1.1 christos if (!imm8 || imm8 > 0xff)
1122 1.1 christos as_bad (_("loop count constant %ld is out of range [1..%d]"),
1123 1.1 christos imm8, 0xff);
1124 1.1 christos /* Note: HW expects the immediate loop count field
1125 1.1 christos to be one less than the actual loop count. */
1126 1.1 christos SET_INSN_FIELD (IMM8, insn_info->insn_code, imm8 - 1);
1127 1.1 christos SET_INSN_FIELD (IO, insn_info->insn_code, 1);
1128 1.1 christos }
1129 1.1 christos else
1130 1.1 christos {
1131 1.1 christos SET_INSN_FIELD (IO, insn_info->insn_code, 0);
1132 1.1 christos SET_INSN_FIELD (RS2, insn_info->insn_code, src2->index);
1133 1.1 christos SET_INSN_FIELD (RS2SEL, insn_info->insn_code, src2->regsel);
1134 1.1 christos }
1135 1.1 christos }
1136 1.1 christos
1137 1.1 christos static void
1138 1.1 christos pru_assemble_arg_i (pru_insn_infoS *insn_info, const char *argstr)
1139 1.1 christos {
1140 1.1 christos unsigned long imm32;
1141 1.1 christos
1142 1.1 christos /* We must not generate PRU_LDI32 relocation if relaxation is disabled in
1143 1.1 christos GAS. Consider the following scenario: GAS relaxation is disabled, so
1144 1.1 christos DIFF* expressions are fixed and not emitted as relocations. Then if LD
1145 1.1 christos has relaxation enabled, it may shorten LDI32 but will not update
1146 1.1 christos accordingly the DIFF expressions. */
1147 1.1 christos if (pru_opt.link_relax)
1148 1.1 christos imm32 = pru_assemble_expression (argstr, insn_info,
1149 1.1 christos insn_info->insn_reloc,
1150 1.1 christos BFD_RELOC_PRU_LDI32, 0);
1151 1.1 christos else
1152 1.1 christos imm32 = pru_assemble_noreloc_expression (argstr);
1153 1.1 christos
1154 1.1 christos /* QUIRK: LDI must clear IO bit high, even though it has immediate arg. */
1155 1.1 christos SET_INSN_FIELD (IO, insn_info->insn_code, 0);
1156 1.1 christos SET_INSN_FIELD (RDSEL, insn_info->insn_code, RSEL_31_16);
1157 1.1 christos SET_INSN_FIELD (IMM16, insn_info->insn_code, imm32 >> 16);
1158 1.1 christos insn_info->ldi32_imm32 = imm32;
1159 1.1 christos }
1160 1.1 christos
1161 1.1 christos static void
1162 1.1 christos pru_assemble_arg_j (pru_insn_infoS *insn_info, const char *argstr)
1163 1.1 christos {
1164 1.1 christos struct pru_reg *src2 = pru_reg_lookup (argstr);
1165 1.1 christos
1166 1.1 christos if (src2 == NULL)
1167 1.1 christos {
1168 1.1 christos unsigned long imm16 = pru_assemble_expression (argstr, insn_info,
1169 1.1 christos insn_info->insn_reloc,
1170 1.1 christos BFD_RELOC_PRU_U16_PMEMIMM,
1171 1.1 christos 0);
1172 1.1 christos SET_INSN_FIELD (IMM16, insn_info->insn_code, imm16);
1173 1.1 christos SET_INSN_FIELD (IO, insn_info->insn_code, 1);
1174 1.1 christos }
1175 1.1 christos else
1176 1.1 christos {
1177 1.1 christos SET_INSN_FIELD (IO, insn_info->insn_code, 0);
1178 1.1 christos SET_INSN_FIELD (RS2, insn_info->insn_code, src2->index);
1179 1.1 christos SET_INSN_FIELD (RS2SEL, insn_info->insn_code, src2->regsel);
1180 1.1 christos }
1181 1.1 christos }
1182 1.1 christos
1183 1.1 christos static void
1184 1.1 christos pru_assemble_arg_W (pru_insn_infoS *insn_info, const char *argstr)
1185 1.1 christos {
1186 1.1 christos unsigned long imm16 = pru_assemble_expression (argstr, insn_info,
1187 1.1 christos insn_info->insn_reloc,
1188 1.1 christos BFD_RELOC_PRU_U16, 0);
1189 1.1 christos /* QUIRK: LDI must clear IO bit high, even though it has immediate arg. */
1190 1.1 christos SET_INSN_FIELD (IO, insn_info->insn_code, 0);
1191 1.1 christos SET_INSN_FIELD (IMM16, insn_info->insn_code, imm16);
1192 1.1 christos }
1193 1.1 christos
1194 1.1 christos static void
1195 1.1 christos pru_assemble_arg_o (pru_insn_infoS *insn_info, const char *argstr)
1196 1.1 christos {
1197 1.1 christos unsigned long imm10 = pru_assemble_expression (argstr, insn_info,
1198 1.1 christos insn_info->insn_reloc,
1199 1.1 christos BFD_RELOC_PRU_S10_PCREL, 1);
1200 1.1 christos SET_BROFF_URAW (insn_info->insn_code, imm10);
1201 1.1 christos }
1202 1.1 christos
1203 1.1 christos static void
1204 1.1 christos pru_assemble_arg_O (pru_insn_infoS *insn_info, const char *argstr)
1205 1.1 christos {
1206 1.1 christos unsigned long imm8 = pru_assemble_expression (argstr, insn_info,
1207 1.1 christos insn_info->insn_reloc,
1208 1.1 christos BFD_RELOC_PRU_U8_PCREL, 1);
1209 1.1 christos SET_INSN_FIELD (LOOP_JMPOFFS, insn_info->insn_code, imm8);
1210 1.1 christos }
1211 1.1 christos
1212 1.1 christos static void
1213 1.1 christos pru_assemble_arg_l (pru_insn_infoS *insn_info, const char *argstr)
1214 1.1 christos {
1215 1.1 christos unsigned long burstlen = 0;
1216 1.1 christos struct pru_reg *blreg = pru_reg_lookup (argstr);
1217 1.1 christos
1218 1.1 christos if (blreg == NULL)
1219 1.1 christos {
1220 1.1 christos burstlen = pru_assemble_noreloc_expression (argstr);
1221 1.1 christos if (!burstlen || burstlen > LSSBBO_BYTECOUNT_R0_BITS7_0)
1222 1.1 christos as_bad (_("byte count constant %ld is out of range [1..%d]"),
1223 1.1 christos burstlen, LSSBBO_BYTECOUNT_R0_BITS7_0);
1224 1.1 christos burstlen--;
1225 1.1 christos }
1226 1.1 christos else
1227 1.1 christos {
1228 1.1 christos if (blreg->index != 0)
1229 1.1 christos as_bad (_("only r0 can be used as byte count register"));
1230 1.1 christos else if (blreg->regsel > RSEL_31_24)
1231 1.1 christos as_bad (_("only r0.bX byte fields of r0 can be used as byte count"));
1232 1.1 christos else
1233 1.1 christos burstlen = LSSBBO_BYTECOUNT_R0_BITS7_0 + blreg->regsel;
1234 1.1 christos }
1235 1.1 christos SET_BURSTLEN (insn_info->insn_code, burstlen);
1236 1.1 christos }
1237 1.1 christos
1238 1.1 christos static void
1239 1.1 christos pru_assemble_arg_n (pru_insn_infoS *insn_info, const char *argstr)
1240 1.1 christos {
1241 1.1 christos unsigned long burstlen = 0;
1242 1.1 christos struct pru_reg *blreg = pru_reg_lookup (argstr);
1243 1.1 christos
1244 1.1 christos if (blreg == NULL)
1245 1.1 christos {
1246 1.1 christos burstlen = pru_assemble_noreloc_expression (argstr);
1247 1.1 christos if (!burstlen || burstlen > LSSBBO_BYTECOUNT_R0_BITS7_0)
1248 1.1 christos as_bad (_("byte count constant %ld is out of range [1..%d]"),
1249 1.1 christos burstlen, LSSBBO_BYTECOUNT_R0_BITS7_0);
1250 1.1 christos burstlen--;
1251 1.1 christos }
1252 1.1 christos else
1253 1.1 christos {
1254 1.1 christos if (blreg->index != 0)
1255 1.1 christos as_bad (_("only r0 can be used as byte count register"));
1256 1.1 christos else if (blreg->regsel > RSEL_31_24)
1257 1.1 christos as_bad (_("only r0.bX byte fields of r0 can be used as byte count"));
1258 1.1 christos else
1259 1.1 christos burstlen = LSSBBO_BYTECOUNT_R0_BITS7_0 + blreg->regsel;
1260 1.1 christos }
1261 1.1 christos SET_INSN_FIELD (XFR_LENGTH, insn_info->insn_code, burstlen);
1262 1.1 christos }
1263 1.1 christos
1264 1.1 christos static void
1265 1.1 christos pru_assemble_arg_c (pru_insn_infoS *insn_info, const char *argstr)
1266 1.1 christos {
1267 1.1 christos unsigned long cb = pru_assemble_noreloc_expression (argstr);
1268 1.1 christos
1269 1.1 christos if (cb > 31)
1270 1.1 christos as_bad (_("invalid constant table offset %ld"), cb);
1271 1.1 christos else
1272 1.1 christos SET_INSN_FIELD (CB, insn_info->insn_code, cb);
1273 1.1 christos }
1274 1.1 christos
1275 1.1 christos static void
1276 1.1 christos pru_assemble_arg_w (pru_insn_infoS *insn_info, const char *argstr)
1277 1.1 christos {
1278 1.1 christos unsigned long wk = pru_assemble_noreloc_expression (argstr);
1279 1.1 christos
1280 1.1 christos if (wk != 0 && wk != 1)
1281 1.1 christos as_bad (_("invalid WakeOnStatus %ld"), wk);
1282 1.1 christos else
1283 1.1 christos SET_INSN_FIELD (WAKEONSTATUS, insn_info->insn_code, wk);
1284 1.1 christos }
1285 1.1 christos
1286 1.1 christos static void
1287 1.1 christos pru_assemble_arg_x (pru_insn_infoS *insn_info, const char *argstr)
1288 1.1 christos {
1289 1.1 christos unsigned long wba = pru_assemble_noreloc_expression (argstr);
1290 1.1 christos
1291 1.1 christos if (wba > 255)
1292 1.1 christos as_bad (_("invalid XFR WideBus Address %ld"), wba);
1293 1.1 christos else
1294 1.1 christos SET_INSN_FIELD (XFR_WBA, insn_info->insn_code, wba);
1295 1.1 christos }
1296 1.1 christos
1297 1.1 christos /* The function consume_arg takes a pointer into a string
1298 1.1 christos of instruction tokens (args) and a pointer into a string
1299 1.1 christos representing the expected sequence of tokens and separators.
1300 1.1 christos It checks whether the first argument in argstr is of the
1301 1.1 christos expected type, throwing an error if it is not, and returns
1302 1.1 christos the pointer argstr. */
1303 1.1 christos static char *
1304 1.1 christos pru_consume_arg (char *argstr, const char *parsestr)
1305 1.1 christos {
1306 1.1 christos char *temp;
1307 1.1 christos
1308 1.1 christos switch (*parsestr)
1309 1.1 christos {
1310 1.1 christos case 'W':
1311 1.1 christos if (*argstr == '%')
1312 1.1 christos {
1313 1.1 christos if (strprefix (argstr, "%pmem") || strprefix (argstr, "%label"))
1314 1.1 christos {
1315 1.1 christos /* We zap the parentheses because we don't want them confused
1316 1.1 christos with separators. */
1317 1.1 christos temp = strchr (argstr, '(');
1318 1.1 christos if (temp != NULL)
1319 1.1 christos *temp = ' ';
1320 1.1 christos temp = strchr (argstr, ')');
1321 1.1 christos if (temp != NULL)
1322 1.1 christos *temp = ' ';
1323 1.1 christos }
1324 1.1 christos else
1325 1.1 christos as_bad (_("badly formed expression near %s"), argstr);
1326 1.1 christos }
1327 1.1 christos break;
1328 1.1 christos
1329 1.1 christos case 'j':
1330 1.1 christos case 'o':
1331 1.1 christos case 'O':
1332 1.1 christos if (*argstr == '%')
1333 1.1 christos {
1334 1.1 christos /* Only 'j' really requires %label for distinguishing registers
1335 1.1 christos from labels, but we include 'o' and 'O' here to avoid
1336 1.1 christos confusing assembler programmers. Thus for completeness all
1337 1.1 christos jump operands can be prefixed with %label. */
1338 1.1 christos if (strprefix (argstr, "%label"))
1339 1.1 christos {
1340 1.1 christos /* We zap the parentheses because we don't want them confused
1341 1.1 christos with separators. */
1342 1.1 christos temp = strchr (argstr, '(');
1343 1.1 christos if (temp != NULL)
1344 1.1 christos *temp = ' ';
1345 1.1 christos temp = strchr (argstr, ')');
1346 1.1 christos if (temp != NULL)
1347 1.1 christos *temp = ' ';
1348 1.1 christos }
1349 1.1 christos else
1350 1.1 christos as_bad (_("badly formed expression near %s"), argstr);
1351 1.1 christos }
1352 1.1 christos break;
1353 1.1 christos
1354 1.1 christos case 'b':
1355 1.1 christos case 'B':
1356 1.1 christos case 'c':
1357 1.1 christos case 'd':
1358 1.1 christos case 'D':
1359 1.1 christos case 'E':
1360 1.1 christos case 'i':
1361 1.1 christos case 's':
1362 1.1 christos case 'S':
1363 1.1 christos case 'l':
1364 1.1 christos case 'n':
1365 1.1 christos case 'R':
1366 1.1 christos case 'w':
1367 1.1 christos case 'x':
1368 1.1 christos /* We can't have %pmem here. */
1369 1.1 christos if (*argstr == '%')
1370 1.1 christos as_bad (_("badly formed expression near %s"), argstr);
1371 1.1 christos break;
1372 1.1 christos default:
1373 1.1 christos BAD_CASE (*parsestr);
1374 1.1 christos break;
1375 1.1 christos }
1376 1.1 christos
1377 1.1 christos return argstr;
1378 1.1 christos }
1379 1.1 christos
1380 1.1 christos /* The function consume_separator takes a pointer into a string
1381 1.1 christos of instruction tokens (args) and a pointer into a string representing
1382 1.1 christos the expected sequence of tokens and separators. It finds the first
1383 1.1 christos instance of the character pointed to by separator in argstr, and
1384 1.1 christos returns a pointer to the next element of argstr, which is the
1385 1.1 christos following token in the sequence. */
1386 1.1 christos static char *
1387 1.1 christos pru_consume_separator (char *argstr, const char *separator)
1388 1.1 christos {
1389 1.1 christos char *p;
1390 1.1 christos
1391 1.1 christos p = strchr (argstr, *separator);
1392 1.1 christos
1393 1.1 christos if (p != NULL)
1394 1.1 christos *p++ = 0;
1395 1.1 christos else
1396 1.1 christos as_bad (_("expecting %c near %s"), *separator, argstr);
1397 1.1 christos return p;
1398 1.1 christos }
1399 1.1 christos
1400 1.1 christos
1401 1.1 christos /* The principal argument parsing function which takes a string argstr
1402 1.1 christos representing the instruction arguments for insn, and extracts the argument
1403 1.1 christos tokens matching parsestr into parsed_args. */
1404 1.1 christos static void
1405 1.1 christos pru_parse_args (pru_insn_infoS *insn ATTRIBUTE_UNUSED, char *argstr,
1406 1.1 christos const char *parsestr, char **parsed_args)
1407 1.1 christos {
1408 1.1 christos char *p;
1409 1.1 christos char *end = NULL;
1410 1.1 christos int i;
1411 1.1 christos p = argstr;
1412 1.1 christos i = 0;
1413 1.1 christos bfd_boolean terminate = FALSE;
1414 1.1 christos
1415 1.1 christos /* This rest of this function is it too fragile and it mostly works,
1416 1.1 christos therefore special case this one. */
1417 1.1 christos if (*parsestr == 0 && argstr != 0)
1418 1.1 christos {
1419 1.1 christos as_bad (_("too many arguments"));
1420 1.1 christos parsed_args[0] = NULL;
1421 1.1 christos return;
1422 1.1 christos }
1423 1.1 christos
1424 1.1 christos while (p != NULL && !terminate && i < PRU_MAX_INSN_TOKENS)
1425 1.1 christos {
1426 1.1 christos parsed_args[i] = pru_consume_arg (p, parsestr);
1427 1.1 christos ++parsestr;
1428 1.1 christos if (*parsestr != '\0')
1429 1.1 christos {
1430 1.1 christos p = pru_consume_separator (p, parsestr);
1431 1.1 christos ++parsestr;
1432 1.1 christos }
1433 1.1 christos else
1434 1.1 christos {
1435 1.1 christos /* Check that the argument string has no trailing arguments. */
1436 1.1 christos /* If we've got a %pmem relocation, we've zapped the parens with
1437 1.1 christos spaces. */
1438 1.1 christos if (strprefix (p, "%pmem") || strprefix (p, "%label"))
1439 1.1 christos end = strpbrk (p, ",");
1440 1.1 christos else
1441 1.1 christos end = strpbrk (p, " ,");
1442 1.1 christos
1443 1.1 christos if (end != NULL)
1444 1.1 christos as_bad (_("too many arguments"));
1445 1.1 christos }
1446 1.1 christos
1447 1.1 christos if (*parsestr == '\0' || (p != NULL && *p == '\0'))
1448 1.1 christos terminate = TRUE;
1449 1.1 christos ++i;
1450 1.1 christos }
1451 1.1 christos
1452 1.1 christos parsed_args[i] = NULL;
1453 1.1 christos
1454 1.1 christos /* There are no instructions with optional arguments; complain. */
1455 1.1 christos if (*parsestr != '\0')
1456 1.1 christos as_bad (_("missing argument"));
1457 1.1 christos }
1458 1.1 christos
1459 1.1 christos
1460 1.1 christos /** Assembler output support. */
1462 1.1 christos
1463 1.1 christos /* Output a normal instruction. */
1464 1.1 christos static void
1465 1.1 christos output_insn (pru_insn_infoS *insn)
1466 1.1 christos {
1467 1.1 christos char *f;
1468 1.1 christos pru_insn_relocS *reloc;
1469 1.1 christos
1470 1.1 christos f = frag_more (4);
1471 1.1 christos /* This allocates enough space for the instruction
1472 1.1 christos and puts it in the current frag. */
1473 1.1 christos md_number_to_chars (f, insn->insn_code, 4);
1474 1.1 christos /* Emit debug info. */
1475 1.1 christos dwarf2_emit_insn (4);
1476 1.1 christos /* Create any fixups to be acted on later. */
1477 1.1 christos for (reloc = insn->insn_reloc; reloc != NULL; reloc = reloc->reloc_next)
1478 1.1 christos fix_new_exp (frag_now, f - frag_now->fr_literal, 4,
1479 1.1 christos &reloc->reloc_expression, reloc->reloc_pcrel,
1480 1.1 christos reloc->reloc_type);
1481 1.1 christos }
1482 1.1 christos
1483 1.1 christos /* Output two LDI instructions from LDI32 macro */
1484 1.1 christos static void
1485 1.1 christos output_insn_ldi32 (pru_insn_infoS *insn)
1486 1.1 christos {
1487 1.1 christos char *f;
1488 1.1 christos pru_insn_relocS *reloc;
1489 1.1 christos unsigned long insn2;
1490 1.1 christos
1491 1.1 christos f = frag_more (8);
1492 1.1 christos SET_INSN_FIELD (IMM16, insn->insn_code, insn->ldi32_imm32 >> 16);
1493 1.1 christos SET_INSN_FIELD (RDSEL, insn->insn_code, RSEL_31_16);
1494 1.1 christos md_number_to_chars (f, insn->insn_code, 4);
1495 1.1 christos
1496 1.1 christos insn2 = insn->insn_code;
1497 1.1 christos SET_INSN_FIELD (IMM16, insn2, insn->ldi32_imm32 & 0xffff);
1498 1.1 christos SET_INSN_FIELD (RDSEL, insn2, RSEL_15_0);
1499 1.1 christos md_number_to_chars (f + 4, insn2, 4);
1500 1.1 christos
1501 1.1 christos /* Emit debug info. */
1502 1.1 christos dwarf2_emit_insn (8);
1503 1.1 christos
1504 1.1 christos /* Create any fixups to be acted on later. */
1505 1.1 christos for (reloc = insn->insn_reloc; reloc != NULL; reloc = reloc->reloc_next)
1506 1.1 christos fix_new_exp (frag_now, f - frag_now->fr_literal, 4,
1507 1.1 christos &reloc->reloc_expression, reloc->reloc_pcrel,
1508 1.1 christos reloc->reloc_type);
1509 1.1 christos }
1510 1.1 christos
1511 1.1 christos
1512 1.1 christos /** External interfaces. */
1514 1.1 christos
1515 1.1 christos /* The following functions are called by machine-independent parts of
1516 1.1 christos the assembler. */
1517 1.1 christos int
1518 1.1 christos md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
1519 1.1 christos {
1520 1.1 christos switch (c)
1521 1.1 christos {
1522 1.1 christos case 'r':
1523 1.1 christos /* Hidden option for self-test mode. */
1524 1.1 christos pru_mode = PRU_MODE_TEST;
1525 1.1 christos break;
1526 1.1 christos case OPTION_LINK_RELAX:
1527 1.1 christos pru_opt.link_relax = TRUE;
1528 1.1 christos break;
1529 1.1 christos case OPTION_NO_LINK_RELAX:
1530 1.1 christos pru_opt.link_relax = FALSE;
1531 1.1 christos break;
1532 1.1 christos case OPTION_NO_WARN_REGNAME_LABEL:
1533 1.1 christos pru_opt.warn_regname_label = FALSE;
1534 1.1 christos break;
1535 1.1 christos default:
1536 1.1 christos return 0;
1537 1.1 christos break;
1538 1.1 christos }
1539 1.1 christos
1540 1.1 christos return 1;
1541 1.1 christos }
1542 1.1 christos
1543 1.1 christos const char *
1544 1.1 christos pru_target_format (void)
1545 1.1 christos {
1546 1.1 christos return "elf32-pru";
1547 1.1 christos }
1548 1.1 christos
1549 1.1 christos /* Machine-dependent usage message. */
1550 1.1 christos void
1551 1.1 christos md_show_usage (FILE *stream)
1552 1.1 christos {
1553 1.1 christos fprintf (stream,
1554 1.1 christos _("PRU options:\n"
1555 1.1 christos " -mlink-relax generate relocations for linker relaxation (default).\n"
1556 1.1 christos " -mno-link-relax don't generate relocations for linker relaxation.\n"
1557 1.1 christos ));
1558 1.1 christos
1559 1.1 christos }
1560 1.1 christos
1561 1.1 christos /* This function is called once, at assembler startup time.
1562 1.1 christos It should set up all the tables, etc. that the MD part of the
1563 1.1 christos assembler will need. */
1564 1.1 christos void
1565 1.1 christos md_begin (void)
1566 1.1 christos {
1567 1.1 christos int i;
1568 1.1 christos const char *inserted;
1569 1.1 christos
1570 1.1 christos /* Create and fill a hashtable for the PRU opcodes, registers and
1571 1.1 christos arguments. */
1572 1.1 christos pru_opcode_hash = hash_new ();
1573 1.1 christos pru_reg_hash = hash_new ();
1574 1.1 christos
1575 1.1 christos for (i = 0; i < NUMOPCODES; ++i)
1576 1.1 christos {
1577 1.1 christos inserted
1578 1.1 christos = hash_insert (pru_opcode_hash, pru_opcodes[i].name,
1579 1.1 christos (PTR) & pru_opcodes[i]);
1580 1.1 christos if (inserted != NULL)
1581 1.1 christos {
1582 1.1 christos fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
1583 1.1 christos pru_opcodes[i].name, inserted);
1584 1.1 christos /* Probably a memory allocation problem? Give up now. */
1585 1.1 christos as_fatal (_("Broken assembler. No assembly attempted."));
1586 1.1 christos }
1587 1.1 christos }
1588 1.1 christos
1589 1.1 christos for (i = 0; i < pru_num_regs; ++i)
1590 1.1 christos {
1591 1.1 christos inserted
1592 1.1 christos = hash_insert (pru_reg_hash, pru_regs[i].name,
1593 1.1 christos (PTR) & pru_regs[i]);
1594 1.1 christos if (inserted != NULL)
1595 1.1 christos {
1596 1.1 christos fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
1597 1.1 christos pru_regs[i].name, inserted);
1598 1.1 christos /* Probably a memory allocation problem? Give up now. */
1599 1.1 christos as_fatal (_("Broken assembler. No assembly attempted."));
1600 1.1 christos }
1601 1.1 christos
1602 1.1 christos }
1603 1.1 christos
1604 1.1 christos linkrelax = pru_opt.link_relax;
1605 1.1 christos /* Initialize the alignment data. */
1606 1.1 christos pru_current_align_seg = now_seg;
1607 1.1 christos pru_last_label = NULL;
1608 1.1 christos pru_current_align = 0;
1609 1.1 christos }
1610 1.1 christos
1611 1.1 christos
1612 1.1 christos /* Assembles a single line of PRU assembly language. */
1613 1.1 christos void
1614 1.1 christos md_assemble (char *op_str)
1615 1.1 christos {
1616 1.1 christos char *argstr;
1617 1.1 christos char *op_strdup = NULL;
1618 1.1 christos pru_insn_infoS thisinsn;
1619 1.1 christos pru_insn_infoS *insn = &thisinsn;
1620 1.1 christos
1621 1.1 christos /* Make sure we are aligned on a 4-byte boundary. */
1622 1.1 christos if (pru_current_align < 2)
1623 1.1 christos pru_align (2, NULL, pru_last_label);
1624 1.1 christos else if (pru_current_align > 2)
1625 1.1 christos pru_current_align = 2;
1626 1.1 christos pru_last_label = NULL;
1627 1.1 christos
1628 1.1 christos /* We don't want to clobber to op_str
1629 1.1 christos because we want to be able to use it in messages. */
1630 1.1 christos op_strdup = strdup (op_str);
1631 1.1 christos insn->insn_tokens[0] = strtok (op_strdup, " ");
1632 1.1 christos argstr = strtok (NULL, "");
1633 1.1 christos
1634 1.1 christos /* Assemble the opcode. */
1635 1.1 christos insn->insn_pru_opcode = pru_opcode_lookup (insn->insn_tokens[0]);
1636 1.1 christos insn->insn_reloc = NULL;
1637 1.1 christos
1638 1.1 christos if (insn->insn_pru_opcode != NULL)
1639 1.1 christos {
1640 1.1 christos const char *argsfmt = insn->insn_pru_opcode->args;
1641 1.1 christos const char **argtk = &insn->insn_tokens[1];
1642 1.1 christos const char *argp;
1643 1.1 christos
1644 1.1 christos /* Set the opcode for the instruction. */
1645 1.1 christos insn->insn_code = insn->insn_pru_opcode->match;
1646 1.1 christos
1647 1.1 christos if (pru_mode == PRU_MODE_TEST)
1648 1.1 christos {
1649 1.1 christos /* Add the "expected" instruction parameter used for validation. */
1650 1.1 christos argsfmt = malloc (strlen (argsfmt) + 3);
1651 1.1 christos sprintf ((char *)argsfmt, "%s,E", insn->insn_pru_opcode->args);
1652 1.1 christos }
1653 1.1 christos pru_parse_args (insn, argstr, argsfmt,
1654 1.1 christos (char **) &insn->insn_tokens[1]);
1655 1.1 christos
1656 1.1 christos for (argp = argsfmt; !had_errors () && *argp && *argtk; ++argp)
1657 1.1 christos {
1658 1.1 christos gas_assert (argtk <= &insn->insn_tokens[PRU_MAX_INSN_TOKENS]);
1659 1.1 christos
1660 1.1 christos switch (*argp)
1661 1.1 christos {
1662 1.1 christos case ',':
1663 1.1 christos continue;
1664 1.1 christos
1665 1.1 christos case 'd':
1666 1.1 christos pru_assemble_arg_d (insn, *argtk++);
1667 1.1 christos continue;
1668 1.1 christos case 'D':
1669 1.1 christos pru_assemble_arg_D (insn, *argtk++);
1670 1.1 christos continue;
1671 1.1 christos case 'R':
1672 1.1 christos pru_assemble_arg_R (insn, *argtk++);
1673 1.1 christos continue;
1674 1.1 christos case 's':
1675 1.1 christos pru_assemble_arg_s (insn, *argtk++);
1676 1.1 christos continue;
1677 1.1 christos case 'S':
1678 1.1 christos pru_assemble_arg_S (insn, *argtk++);
1679 1.1 christos continue;
1680 1.1 christos case 'b':
1681 1.1 christos pru_assemble_arg_b (insn, *argtk++);
1682 1.1 christos continue;
1683 1.1 christos case 'B':
1684 1.1 christos pru_assemble_arg_B (insn, *argtk++);
1685 1.1 christos continue;
1686 1.1 christos case 'i':
1687 1.1 christos pru_assemble_arg_i (insn, *argtk++);
1688 1.1 christos continue;
1689 1.1 christos case 'j':
1690 1.1 christos pru_assemble_arg_j (insn, *argtk++);
1691 1.1 christos continue;
1692 1.1 christos case 'W':
1693 1.1 christos pru_assemble_arg_W (insn, *argtk++);
1694 1.1 christos continue;
1695 1.1 christos case 'o':
1696 1.1 christos pru_assemble_arg_o (insn, *argtk++);
1697 1.1 christos continue;
1698 1.1 christos case 'O':
1699 1.1 christos pru_assemble_arg_O (insn, *argtk++);
1700 1.1 christos continue;
1701 1.1 christos case 'l':
1702 1.1 christos pru_assemble_arg_l (insn, *argtk++);
1703 1.1 christos continue;
1704 1.1 christos case 'n':
1705 1.1 christos pru_assemble_arg_n (insn, *argtk++);
1706 1.1 christos continue;
1707 1.1 christos case 'c':
1708 1.1 christos pru_assemble_arg_c (insn, *argtk++);
1709 1.1 christos continue;
1710 1.1 christos case 'w':
1711 1.1 christos pru_assemble_arg_w (insn, *argtk++);
1712 1.1 christos continue;
1713 1.1 christos case 'x':
1714 1.1 christos pru_assemble_arg_x (insn, *argtk++);
1715 1.1 christos continue;
1716 1.1 christos
1717 1.1 christos case 'E':
1718 1.1 christos pru_check_assembly (insn->insn_code, *argtk++);
1719 1.1 christos continue;
1720 1.1 christos
1721 1.1 christos default:
1722 1.1 christos BAD_CASE (*argp);
1723 1.1 christos }
1724 1.1 christos }
1725 1.1 christos
1726 1.1 christos if (*argp && !had_errors ())
1727 1.1 christos as_bad (_("missing argument"));
1728 1.1 christos
1729 1.1 christos if (!had_errors ())
1730 1.1 christos {
1731 1.1 christos if (insn->insn_pru_opcode->pinfo & PRU_INSN_LDI32)
1732 1.1 christos {
1733 1.1 christos output_insn_ldi32 (insn);
1734 1.1 christos }
1735 1.1 christos else
1736 1.1 christos {
1737 1.1 christos output_insn (insn);
1738 1.1 christos }
1739 1.1 christos }
1740 1.1 christos
1741 1.1 christos if (pru_mode == PRU_MODE_TEST)
1742 1.1 christos free ((char *)argsfmt);
1743 1.1 christos }
1744 1.1 christos else
1745 1.1 christos /* Unrecognised instruction - error. */
1746 1.1 christos as_bad (_("unrecognised instruction %s"), insn->insn_tokens[0]);
1747 1.1 christos
1748 1.1 christos /* Don't leak memory. */
1749 1.1 christos pru_insn_reloc_destroy (insn->insn_reloc);
1750 1.1 christos free (op_strdup);
1751 1.1 christos }
1752 1.1 christos
1753 1.1 christos /* Round up section size. */
1754 1.1 christos valueT
1755 1.1 christos md_section_align (asection *seg, valueT addr)
1756 1.1 christos {
1757 1.1 christos int align = bfd_get_section_alignment (stdoutput, seg);
1758 1.1 christos return ((addr + (1 << align) - 1) & (-((valueT) 1 << align)));
1759 1.1 christos }
1760 1.1 christos
1761 1.1 christos /* Implement tc_fix_adjustable. */
1762 1.1 christos int
1763 1.1 christos pru_fix_adjustable (fixS *fixp)
1764 1.1 christos {
1765 1.1 christos if (fixp->fx_addsy == NULL)
1766 1.1 christos return 1;
1767 1.1 christos
1768 1.1 christos /* Prevent all adjustments to global symbols. */
1769 1.1 christos if (OUTPUT_FLAVOR == bfd_target_elf_flavour
1770 1.1 christos && (S_IS_EXTERNAL (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)))
1771 1.1 christos return 0;
1772 1.1 christos
1773 1.1 christos if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
1774 1.1 christos || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
1775 1.1 christos return 0;
1776 1.1 christos
1777 1.1 christos /* Preserve relocations against symbols with function type. */
1778 1.1 christos if (symbol_get_bfdsym (fixp->fx_addsy)->flags & BSF_FUNCTION)
1779 1.1 christos return 0;
1780 1.1 christos
1781 1.1 christos return 1;
1782 1.1 christos }
1783 1.1 christos
1784 1.1 christos /* The function tc_gen_reloc creates a relocation structure for the
1785 1.1 christos fixup fixp, and returns a pointer to it. This structure is passed
1786 1.1 christos to bfd_install_relocation so that it can be written to the object
1787 1.1 christos file for linking. */
1788 1.1 christos arelent *
1789 1.1 christos tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
1790 1.1 christos {
1791 1.1 christos arelent *reloc = XNEW (arelent);
1792 1.1 christos reloc->sym_ptr_ptr = XNEW (asymbol *);
1793 1.1 christos *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1794 1.1 christos
1795 1.1 christos reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1796 1.1 christos reloc->addend = fixp->fx_offset; /* fixp->fx_addnumber; */
1797 1.1 christos
1798 1.1 christos reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1799 1.1 christos if (reloc->howto == NULL)
1800 1.1 christos {
1801 1.1 christos as_bad_where (fixp->fx_file, fixp->fx_line,
1802 1.1 christos _("can't represent relocation type %s"),
1803 1.1 christos bfd_get_reloc_code_name (fixp->fx_r_type));
1804 1.1 christos
1805 1.1 christos /* Set howto to a garbage value so that we can keep going. */
1806 1.1 christos reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
1807 1.1 christos gas_assert (reloc->howto != NULL);
1808 1.1 christos }
1809 1.1 christos return reloc;
1810 1.1 christos }
1811 1.1 christos
1812 1.1 christos long
1813 1.1 christos md_pcrel_from (fixS *fixP ATTRIBUTE_UNUSED)
1814 1.1 christos {
1815 1.1 christos return fixP->fx_where + fixP->fx_frag->fr_address;
1816 1.1 christos }
1817 1.1 christos
1818 1.1 christos /* Called just before the assembler exits. */
1819 1.1 christos void
1820 1.1 christos md_end (void)
1821 1.1 christos {
1822 1.1 christos hash_die (pru_opcode_hash);
1823 1.1 christos hash_die (pru_reg_hash);
1824 1.1 christos }
1825 1.1 christos
1826 1.1 christos symbolS *
1827 1.1 christos md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1828 1.1 christos {
1829 1.1 christos return NULL;
1830 1.1 christos }
1831 1.1 christos
1832 1.1 christos /* Implement tc_frob_label. */
1833 1.1 christos void
1834 1.1 christos pru_frob_label (symbolS *lab)
1835 1.1 christos {
1836 1.1 christos /* Emit dwarf information. */
1837 1.1 christos dwarf2_emit_label (lab);
1838 1.1 christos
1839 1.1 christos /* Update the label's address with the current output pointer. */
1840 1.1 christos symbol_set_frag (lab, frag_now);
1841 1.1 christos S_SET_VALUE (lab, (valueT) frag_now_fix ());
1842 1.1 christos
1843 1.1 christos /* Record this label for future adjustment after we find out what
1844 1.1 christos kind of data it references, and the required alignment therewith. */
1845 1.1 christos pru_last_label = lab;
1846 1.1 christos
1847 1.1 christos if (pru_opt.warn_regname_label && pru_reg_lookup (S_GET_NAME (lab)))
1848 1.1 christos as_warn (_("Label \"%s\" matches a CPU register name"), S_GET_NAME (lab));
1849 1.1 christos }
1850 1.1 christos
1851 1.1 christos static inline char *
1852 1.1 christos skip_space (char *s)
1853 1.1 christos {
1854 1.1 christos while (*s == ' ' || *s == '\t')
1855 1.1 christos ++s;
1856 1.1 christos return s;
1857 1.1 christos }
1858 1.1 christos
1859 1.1 christos /* Parse special CONS expression: pmem (expression). Idea from AVR.
1860 1.1 christos
1861 1.1 christos Used to catch and mark code (program memory) in constant expression
1862 1.1 christos relocations. Return non-zero for program memory. */
1863 1.1 christos
1864 1.1 christos int
1865 1.1 christos pru_parse_cons_expression (expressionS *exp, int nbytes)
1866 1.1 christos {
1867 1.1 christos int is_pmem = FALSE;
1868 1.1 christos char *tmp;
1869 1.1 christos
1870 1.1 christos tmp = input_line_pointer = skip_space (input_line_pointer);
1871 1.1 christos
1872 1.1 christos if (nbytes == 4 || nbytes == 2)
1873 1.1 christos {
1874 1.1 christos const char *pmem_str = "%pmem";
1875 1.1 christos int len = strlen (pmem_str);
1876 1.1 christos
1877 1.1 christos if (strncasecmp (input_line_pointer, pmem_str, len) == 0)
1878 1.1 christos {
1879 1.1 christos input_line_pointer = skip_space (input_line_pointer + len);
1880 1.1 christos
1881 1.1 christos if (*input_line_pointer == '(')
1882 1.1 christos {
1883 1.1 christos input_line_pointer = skip_space (input_line_pointer + 1);
1884 1.1 christos is_pmem = TRUE;
1885 1.1 christos expression (exp);
1886 1.1 christos
1887 1.1 christos if (*input_line_pointer == ')')
1888 1.1 christos ++input_line_pointer;
1889 1.1 christos else
1890 1.1 christos {
1891 1.1 christos as_bad (_("`)' required"));
1892 1.1 christos is_pmem = FALSE;
1893 1.1 christos }
1894 1.1 christos
1895 1.1 christos return is_pmem;
1896 1.1 christos }
1897 1.1 christos
1898 1.1 christos input_line_pointer = tmp;
1899 1.1 christos }
1900 1.1 christos }
1901 1.1 christos
1902 1.1 christos expression (exp);
1903 1.1 christos
1904 1.1 christos return is_pmem;
1905 1.1 christos }
1906 1.1 christos
1907 1.1 christos /* Implement TC_CONS_FIX_NEW. */
1908 1.1 christos void
1909 1.1 christos pru_cons_fix_new (fragS *frag, int where, unsigned int nbytes,
1910 1.1 christos expressionS *exp, const int is_pmem)
1911 1.1 christos {
1912 1.1 christos bfd_reloc_code_real_type r;
1913 1.1 christos
1914 1.1 christos switch (nbytes | (!!is_pmem << 8))
1915 1.1 christos {
1916 1.1 christos case 1 | (0 << 8): r = BFD_RELOC_8; break;
1917 1.1 christos case 2 | (0 << 8): r = BFD_RELOC_16; break;
1918 1.1 christos case 4 | (0 << 8): r = BFD_RELOC_32; break;
1919 1.1 christos case 8 | (0 << 8): r = BFD_RELOC_64; break;
1920 1.1 christos case 2 | (1 << 8): r = BFD_RELOC_PRU_16_PMEM; break;
1921 1.1 christos case 4 | (1 << 8): r = BFD_RELOC_PRU_32_PMEM; break;
1922 1.1 christos default:
1923 1.1 christos as_bad (_("illegal %s relocation size: %d"),
1924 1.1 christos is_pmem ? "text" : "data", nbytes);
1925 1.1 christos return;
1926 1.1 christos }
1927 1.1 christos
1928 1.1 christos fix_new_exp (frag, where, (int) nbytes, exp, 0, r);
1929 1.1 christos }
1930 1.1 christos
1931 1.1 christos /* Implement tc_regname_to_dw2regnum, to convert REGNAME to a DWARF-2
1932 1.1 christos register number. */
1933 1.1 christos int
1934 1.1 christos pru_regname_to_dw2regnum (char *regname)
1935 1.1 christos {
1936 1.1 christos struct pru_reg *r = pru_reg_lookup (regname);
1937 1.1 christos if (r == NULL)
1938 1.1 christos return -1;
1939 1.1 christos return r->index;
1940 1.1 christos }
1941 1.1 christos
1942 1.1 christos /* Implement tc_cfi_frame_initial_instructions, to initialize the DWARF-2
1943 1.1 christos unwind information for this procedure. */
1944 1.1 christos void
1945 1.1 christos pru_frame_initial_instructions (void)
1946 1.1 christos {
1947 1.1 christos const unsigned fp_regno = 4;
1948 1.1 christos cfi_add_CFA_def_cfa (fp_regno, 0);
1949 1.1 christos }
1950 1.1 christos
1951 1.1 christos bfd_boolean
1952 1.1 christos pru_allow_local_subtract (expressionS * left,
1953 1.1 christos expressionS * right,
1954 1.1 christos segT section)
1955 1.1 christos {
1956 1.1 christos /* If we are not in relaxation mode, subtraction is OK. */
1957 1.1 christos if (!linkrelax)
1958 1.1 christos return TRUE;
1959 1.1 christos
1960 1.1 christos /* If the symbols are not in a code section then they are OK. */
1961 1.1 christos if ((section->flags & SEC_CODE) == 0)
1962 1.1 christos return TRUE;
1963
1964 if (left->X_add_symbol == right->X_add_symbol)
1965 return TRUE;
1966
1967 /* We have to assume that there may be instructions between the
1968 two symbols and that relaxation may increase the distance between
1969 them. */
1970 return FALSE;
1971 }
1972