tc-d10v.c revision 1.1.1.8 1 1.1 christos /* tc-d10v.c -- Assembler code for the Mitsubishi D10V
2 1.1.1.8 christos Copyright (C) 1996-2025 Free Software Foundation, Inc.
3 1.1 christos
4 1.1 christos This file is part of GAS, the GNU Assembler.
5 1.1 christos
6 1.1 christos GAS is free software; you can redistribute it and/or modify
7 1.1 christos it under the terms of the GNU General Public License as published by
8 1.1 christos the Free Software Foundation; either version 3, or (at your option)
9 1.1 christos any later version.
10 1.1 christos
11 1.1 christos GAS is distributed in the hope that it will be useful,
12 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
13 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 1.1 christos GNU General Public License for more details.
15 1.1 christos
16 1.1 christos You should have received a copy of the GNU General Public License
17 1.1 christos along with GAS; see the file COPYING. If not, write to
18 1.1 christos the Free Software Foundation, 51 Franklin Street - Fifth Floor,
19 1.1 christos Boston, MA 02110-1301, USA. */
20 1.1 christos
21 1.1 christos #include "as.h"
22 1.1 christos #include "safe-ctype.h"
23 1.1 christos #include "subsegs.h"
24 1.1 christos #include "opcode/d10v.h"
25 1.1 christos #include "elf/ppc.h"
26 1.1 christos #include "dwarf2dbg.h"
27 1.1 christos
28 1.1 christos const char comment_chars[] = ";";
29 1.1 christos const char line_comment_chars[] = "#";
30 1.1 christos const char line_separator_chars[] = "";
31 1.1.1.8 christos const char md_shortopts[] = "O";
32 1.1 christos const char EXP_CHARS[] = "eE";
33 1.1 christos const char FLT_CHARS[] = "dD";
34 1.1 christos
35 1.1 christos int Optimizing = 0;
36 1.1 christos
37 1.1 christos #define AT_WORD_P(X) ((X)->X_op == O_right_shift \
38 1.1 christos && (X)->X_op_symbol != NULL \
39 1.1 christos && symbol_constant_p ((X)->X_op_symbol) \
40 1.1 christos && S_GET_VALUE ((X)->X_op_symbol) == AT_WORD_RIGHT_SHIFT)
41 1.1 christos #define AT_WORD_RIGHT_SHIFT 2
42 1.1 christos
43 1.1 christos /* Fixups. */
44 1.1 christos #define MAX_INSN_FIXUPS 5
45 1.1 christos
46 1.1 christos struct d10v_fixup
47 1.1 christos {
48 1.1 christos expressionS exp;
49 1.1 christos int operand;
50 1.1 christos int pcrel;
51 1.1 christos int size;
52 1.1 christos bfd_reloc_code_real_type reloc;
53 1.1 christos };
54 1.1 christos
55 1.1 christos typedef struct _fixups
56 1.1 christos {
57 1.1 christos int fc;
58 1.1 christos struct d10v_fixup fix[MAX_INSN_FIXUPS];
59 1.1 christos struct _fixups *next;
60 1.1 christos } Fixups;
61 1.1 christos
62 1.1 christos static Fixups FixUps[2];
63 1.1 christos static Fixups *fixups;
64 1.1 christos
65 1.1 christos static int do_not_ignore_hash = 0;
66 1.1 christos
67 1.1 christos typedef int packing_type;
68 1.1 christos #define PACK_UNSPEC (0) /* Packing order not specified. */
69 1.1 christos #define PACK_PARALLEL (1) /* "||" */
70 1.1 christos #define PACK_LEFT_RIGHT (2) /* "->" */
71 1.1 christos #define PACK_RIGHT_LEFT (3) /* "<-" */
72 1.1 christos static packing_type etype = PACK_UNSPEC; /* Used by d10v_cleanup. */
73 1.1 christos
74 1.1 christos /* TRUE if instruction swapping warnings should be inhibited.
75 1.1 christos --nowarnswap. */
76 1.1.1.6 christos static bool flag_warn_suppress_instructionswap;
77 1.1 christos
78 1.1 christos /* TRUE if instruction packing should be performed when --gstabs is specified.
79 1.1 christos --gstabs-packing, --no-gstabs-packing. */
80 1.1.1.6 christos static bool flag_allow_gstabs_packing = 1;
81 1.1 christos
82 1.1 christos /* Local functions. */
83 1.1 christos
84 1.1 christos enum options
85 1.1 christos {
86 1.1 christos OPTION_NOWARNSWAP = OPTION_MD_BASE,
87 1.1 christos OPTION_GSTABSPACKING,
88 1.1 christos OPTION_NOGSTABSPACKING
89 1.1 christos };
90 1.1 christos
91 1.1.1.8 christos const struct option md_longopts[] =
92 1.1 christos {
93 1.1 christos {"nowarnswap", no_argument, NULL, OPTION_NOWARNSWAP},
94 1.1 christos {"gstabspacking", no_argument, NULL, OPTION_GSTABSPACKING},
95 1.1 christos {"gstabs-packing", no_argument, NULL, OPTION_GSTABSPACKING},
96 1.1 christos {"nogstabspacking", no_argument, NULL, OPTION_NOGSTABSPACKING},
97 1.1 christos {"no-gstabs-packing", no_argument, NULL, OPTION_NOGSTABSPACKING},
98 1.1 christos {NULL, no_argument, NULL, 0}
99 1.1 christos };
100 1.1 christos
101 1.1.1.8 christos const size_t md_longopts_size = sizeof (md_longopts);
102 1.1 christos
103 1.1 christos /* Opcode hash table. */
104 1.1.1.6 christos static htab_t d10v_hash;
105 1.1 christos
106 1.1 christos /* Do a binary search of the d10v_predefined_registers array to see if
107 1.1.1.4 christos NAME is a valid register name. Return the register number from the
108 1.1 christos array on success, or -1 on failure. */
109 1.1 christos
110 1.1 christos static int
111 1.1 christos reg_name_search (char *name)
112 1.1 christos {
113 1.1 christos int middle, low, high;
114 1.1 christos int cmp;
115 1.1 christos
116 1.1 christos low = 0;
117 1.1 christos high = d10v_reg_name_cnt () - 1;
118 1.1 christos
119 1.1 christos do
120 1.1 christos {
121 1.1 christos middle = (low + high) / 2;
122 1.1 christos cmp = strcasecmp (name, d10v_predefined_registers[middle].name);
123 1.1 christos if (cmp < 0)
124 1.1 christos high = middle - 1;
125 1.1 christos else if (cmp > 0)
126 1.1 christos low = middle + 1;
127 1.1 christos else
128 1.1 christos return d10v_predefined_registers[middle].value;
129 1.1 christos }
130 1.1 christos while (low <= high);
131 1.1 christos return -1;
132 1.1 christos }
133 1.1 christos
134 1.1 christos /* Check the string at input_line_pointer
135 1.1 christos to see if it is a valid register name. */
136 1.1 christos
137 1.1 christos static int
138 1.1 christos register_name (expressionS *expressionP)
139 1.1 christos {
140 1.1 christos int reg_number;
141 1.1 christos char c, *p = input_line_pointer;
142 1.1 christos
143 1.1.1.8 christos while (!is_end_of_stmt (*p) && *p != ',' && !is_whitespace (*p) && *p != ')')
144 1.1 christos p++;
145 1.1 christos
146 1.1 christos c = *p;
147 1.1 christos if (c)
148 1.1 christos *p++ = 0;
149 1.1 christos
150 1.1 christos /* Look to see if it's in the register table. */
151 1.1 christos reg_number = reg_name_search (input_line_pointer);
152 1.1 christos if (reg_number >= 0)
153 1.1 christos {
154 1.1 christos expressionP->X_op = O_register;
155 1.1 christos /* Temporarily store a pointer to the string here. */
156 1.1 christos expressionP->X_op_symbol = (symbolS *) input_line_pointer;
157 1.1 christos expressionP->X_add_number = reg_number;
158 1.1 christos input_line_pointer = p;
159 1.1 christos return 1;
160 1.1 christos }
161 1.1 christos if (c)
162 1.1 christos *(p - 1) = c;
163 1.1 christos return 0;
164 1.1 christos }
165 1.1 christos
166 1.1 christos static int
167 1.1 christos check_range (unsigned long num, int bits, int flags)
168 1.1 christos {
169 1.1 christos long min, max;
170 1.1 christos int retval = 0;
171 1.1 christos
172 1.1 christos /* Don't bother checking 16-bit values. */
173 1.1 christos if (bits == 16)
174 1.1 christos return 0;
175 1.1 christos
176 1.1 christos if (flags & OPERAND_SHIFT)
177 1.1 christos {
178 1.1 christos /* All special shift operands are unsigned and <= 16.
179 1.1 christos We allow 0 for now. */
180 1.1 christos if (num > 16)
181 1.1 christos return 1;
182 1.1 christos else
183 1.1 christos return 0;
184 1.1 christos }
185 1.1 christos
186 1.1 christos if (flags & OPERAND_SIGNED)
187 1.1 christos {
188 1.1 christos /* Signed 3-bit integers are restricted to the (-2, 3) range. */
189 1.1 christos if (flags & RESTRICTED_NUM3)
190 1.1 christos {
191 1.1 christos if ((long) num < -2 || (long) num > 3)
192 1.1 christos retval = 1;
193 1.1 christos }
194 1.1 christos else
195 1.1 christos {
196 1.1 christos max = (1 << (bits - 1)) - 1;
197 1.1 christos min = - (1 << (bits - 1));
198 1.1 christos if (((long) num > max) || ((long) num < min))
199 1.1 christos retval = 1;
200 1.1 christos }
201 1.1 christos }
202 1.1 christos else
203 1.1 christos {
204 1.1 christos max = (1 << bits) - 1;
205 1.1 christos min = 0;
206 1.1 christos if (((long) num > max) || ((long) num < min))
207 1.1 christos retval = 1;
208 1.1 christos }
209 1.1 christos return retval;
210 1.1 christos }
211 1.1 christos
212 1.1 christos void
213 1.1 christos md_show_usage (FILE *stream)
214 1.1 christos {
215 1.1 christos fprintf (stream, _("D10V options:\n\
216 1.1 christos -O Optimize. Will do some operations in parallel.\n\
217 1.1 christos --gstabs-packing Pack adjacent short instructions together even\n\
218 1.1 christos when --gstabs is specified. On by default.\n\
219 1.1 christos --no-gstabs-packing If --gstabs is specified, do not pack adjacent\n\
220 1.1 christos instructions together.\n"));
221 1.1 christos }
222 1.1 christos
223 1.1 christos int
224 1.1.1.3 christos md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
225 1.1 christos {
226 1.1 christos switch (c)
227 1.1 christos {
228 1.1 christos case 'O':
229 1.1 christos /* Optimize. Will attempt to parallelize operations. */
230 1.1 christos Optimizing = 1;
231 1.1 christos break;
232 1.1 christos case OPTION_NOWARNSWAP:
233 1.1 christos flag_warn_suppress_instructionswap = 1;
234 1.1 christos break;
235 1.1 christos case OPTION_GSTABSPACKING:
236 1.1 christos flag_allow_gstabs_packing = 1;
237 1.1 christos break;
238 1.1 christos case OPTION_NOGSTABSPACKING:
239 1.1 christos flag_allow_gstabs_packing = 0;
240 1.1 christos break;
241 1.1 christos default:
242 1.1 christos return 0;
243 1.1 christos }
244 1.1 christos return 1;
245 1.1 christos }
246 1.1 christos
247 1.1 christos symbolS *
248 1.1 christos md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
249 1.1 christos {
250 1.1 christos return 0;
251 1.1 christos }
252 1.1 christos
253 1.1.1.3 christos const char *
254 1.1 christos md_atof (int type, char *litP, int *sizeP)
255 1.1 christos {
256 1.1.1.6 christos return ieee_md_atof (type, litP, sizeP, true);
257 1.1 christos }
258 1.1 christos
259 1.1 christos void
260 1.1 christos md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
261 1.1 christos asection *sec ATTRIBUTE_UNUSED,
262 1.1 christos fragS *fragP ATTRIBUTE_UNUSED)
263 1.1 christos {
264 1.1 christos abort ();
265 1.1 christos }
266 1.1 christos
267 1.1 christos valueT
268 1.1 christos md_section_align (asection *seg, valueT addr)
269 1.1 christos {
270 1.1.1.5 christos int align = bfd_section_alignment (seg);
271 1.1.1.2 christos return ((addr + (1 << align) - 1) & -(1 << align));
272 1.1 christos }
273 1.1 christos
274 1.1 christos void
275 1.1 christos md_begin (void)
276 1.1 christos {
277 1.1.1.3 christos const char *prev_name = "";
278 1.1.1.8 christos const struct d10v_opcode *opcode;
279 1.1.1.6 christos d10v_hash = str_htab_create ();
280 1.1 christos
281 1.1 christos /* Insert unique names into hash table. The D10v instruction set
282 1.1 christos has many identical opcode names that have different opcodes based
283 1.1 christos on the operands. This hash table then provides a quick index to
284 1.1 christos the first opcode with a particular name in the opcode table. */
285 1.1 christos
286 1.1.1.8 christos for (opcode = d10v_opcodes; opcode->name; opcode++)
287 1.1 christos {
288 1.1 christos if (strcmp (prev_name, opcode->name))
289 1.1 christos {
290 1.1.1.8 christos prev_name = opcode->name;
291 1.1.1.6 christos str_hash_insert (d10v_hash, opcode->name, opcode, 0);
292 1.1 christos }
293 1.1 christos }
294 1.1 christos
295 1.1 christos fixups = &FixUps[0];
296 1.1 christos FixUps[0].next = &FixUps[1];
297 1.1 christos FixUps[1].next = &FixUps[0];
298 1.1 christos }
299 1.1 christos
300 1.1 christos /* Remove the postincrement or postdecrement operator ( '+' or '-' )
301 1.1 christos from an expression. */
302 1.1 christos
303 1.1 christos static int
304 1.1 christos postfix (char *p)
305 1.1 christos {
306 1.1 christos while (*p != '-' && *p != '+')
307 1.1 christos {
308 1.1 christos if (*p == 0 || *p == '\n' || *p == '\r')
309 1.1 christos break;
310 1.1 christos p++;
311 1.1 christos }
312 1.1 christos
313 1.1 christos if (*p == '-')
314 1.1 christos {
315 1.1 christos *p = ' ';
316 1.1 christos return -1;
317 1.1 christos }
318 1.1 christos if (*p == '+')
319 1.1 christos {
320 1.1 christos *p = ' ';
321 1.1 christos return 1;
322 1.1 christos }
323 1.1 christos
324 1.1 christos return 0;
325 1.1 christos }
326 1.1 christos
327 1.1 christos static bfd_reloc_code_real_type
328 1.1.1.8 christos get_reloc (const struct d10v_operand *op)
329 1.1 christos {
330 1.1 christos int bits = op->bits;
331 1.1 christos
332 1.1 christos if (bits <= 4)
333 1.1 christos return 0;
334 1.1 christos
335 1.1 christos if (op->flags & OPERAND_ADDR)
336 1.1 christos {
337 1.1 christos if (bits == 8)
338 1.1 christos return BFD_RELOC_D10V_10_PCREL_R;
339 1.1 christos else
340 1.1 christos return BFD_RELOC_D10V_18_PCREL;
341 1.1 christos }
342 1.1 christos
343 1.1 christos return BFD_RELOC_16;
344 1.1 christos }
345 1.1 christos
346 1.1 christos /* Parse a string of operands. Return an array of expressions. */
347 1.1 christos
348 1.1 christos static int
349 1.1 christos get_operands (expressionS exp[])
350 1.1 christos {
351 1.1 christos char *p = input_line_pointer;
352 1.1 christos int numops = 0;
353 1.1 christos int post = 0;
354 1.1 christos int uses_at = 0;
355 1.1 christos
356 1.1 christos while (*p)
357 1.1 christos {
358 1.1.1.8 christos while (is_whitespace (*p) || *p == ',')
359 1.1 christos p++;
360 1.1.1.8 christos if (is_end_of_stmt (*p))
361 1.1 christos break;
362 1.1 christos
363 1.1 christos if (*p == '@')
364 1.1 christos {
365 1.1 christos uses_at = 1;
366 1.1 christos
367 1.1 christos p++;
368 1.1 christos exp[numops].X_op = O_absent;
369 1.1 christos if (*p == '(')
370 1.1 christos {
371 1.1 christos p++;
372 1.1 christos exp[numops].X_add_number = OPERAND_ATPAR;
373 1.1 christos }
374 1.1 christos else if (*p == '-')
375 1.1 christos {
376 1.1 christos p++;
377 1.1 christos exp[numops].X_add_number = OPERAND_ATMINUS;
378 1.1 christos }
379 1.1 christos else
380 1.1 christos {
381 1.1 christos exp[numops].X_add_number = OPERAND_ATSIGN;
382 1.1 christos if (*p == '+')
383 1.1 christos {
384 1.1 christos numops++;
385 1.1 christos exp[numops].X_op = O_absent;
386 1.1 christos exp[numops].X_add_number = OPERAND_PLUS;
387 1.1 christos p++;
388 1.1 christos }
389 1.1 christos post = postfix (p);
390 1.1 christos }
391 1.1 christos numops++;
392 1.1 christos continue;
393 1.1 christos }
394 1.1 christos
395 1.1 christos if (*p == ')')
396 1.1 christos {
397 1.1 christos /* Just skip the trailing paren. */
398 1.1 christos p++;
399 1.1 christos continue;
400 1.1 christos }
401 1.1 christos
402 1.1 christos input_line_pointer = p;
403 1.1 christos
404 1.1 christos /* Check to see if it might be a register name. */
405 1.1 christos if (!register_name (&exp[numops]))
406 1.1 christos {
407 1.1 christos /* Parse as an expression. */
408 1.1 christos if (uses_at)
409 1.1 christos {
410 1.1 christos /* Any expression that involves the indirect addressing
411 1.1 christos cannot also involve immediate addressing. Therefore
412 1.1 christos the use of the hash character is illegal. */
413 1.1 christos int save = do_not_ignore_hash;
414 1.1 christos do_not_ignore_hash = 1;
415 1.1 christos
416 1.1 christos expression (&exp[numops]);
417 1.1 christos
418 1.1 christos do_not_ignore_hash = save;
419 1.1 christos }
420 1.1 christos else
421 1.1 christos expression (&exp[numops]);
422 1.1 christos }
423 1.1 christos
424 1.1 christos if (strncasecmp (input_line_pointer, "@word", 5) == 0)
425 1.1 christos {
426 1.1 christos input_line_pointer += 5;
427 1.1 christos if (exp[numops].X_op == O_register)
428 1.1 christos {
429 1.1 christos /* If it looked like a register name but was followed by
430 1.1 christos "@word" then it was really a symbol, so change it to
431 1.1 christos one. */
432 1.1 christos exp[numops].X_op = O_symbol;
433 1.1 christos exp[numops].X_add_symbol =
434 1.1 christos symbol_find_or_make ((char *) exp[numops].X_op_symbol);
435 1.1 christos }
436 1.1 christos
437 1.1 christos /* Check for identifier@word+constant. */
438 1.1 christos if (*input_line_pointer == '-' || *input_line_pointer == '+')
439 1.1 christos {
440 1.1 christos expressionS new_exp;
441 1.1 christos expression (&new_exp);
442 1.1 christos exp[numops].X_add_number = new_exp.X_add_number;
443 1.1 christos }
444 1.1 christos
445 1.1 christos /* Convert expr into a right shift by AT_WORD_RIGHT_SHIFT. */
446 1.1 christos {
447 1.1 christos expressionS new_exp;
448 1.1 christos memset (&new_exp, 0, sizeof new_exp);
449 1.1 christos new_exp.X_add_number = AT_WORD_RIGHT_SHIFT;
450 1.1 christos new_exp.X_op = O_constant;
451 1.1 christos new_exp.X_unsigned = 1;
452 1.1 christos exp[numops].X_op_symbol = make_expr_symbol (&new_exp);
453 1.1 christos exp[numops].X_op = O_right_shift;
454 1.1 christos }
455 1.1 christos
456 1.1 christos know (AT_WORD_P (&exp[numops]));
457 1.1 christos }
458 1.1 christos
459 1.1 christos if (exp[numops].X_op == O_illegal)
460 1.1 christos as_bad (_("illegal operand"));
461 1.1 christos else if (exp[numops].X_op == O_absent)
462 1.1 christos as_bad (_("missing operand"));
463 1.1 christos
464 1.1 christos numops++;
465 1.1 christos p = input_line_pointer;
466 1.1 christos }
467 1.1 christos
468 1.1 christos switch (post)
469 1.1 christos {
470 1.1 christos case -1: /* Postdecrement mode. */
471 1.1 christos exp[numops].X_op = O_absent;
472 1.1 christos exp[numops++].X_add_number = OPERAND_MINUS;
473 1.1 christos break;
474 1.1 christos case 1: /* Postincrement mode. */
475 1.1 christos exp[numops].X_op = O_absent;
476 1.1 christos exp[numops++].X_add_number = OPERAND_PLUS;
477 1.1 christos break;
478 1.1 christos }
479 1.1 christos
480 1.1 christos exp[numops].X_op = 0;
481 1.1 christos return numops;
482 1.1 christos }
483 1.1 christos
484 1.1 christos static unsigned long
485 1.1 christos d10v_insert_operand (unsigned long insn,
486 1.1 christos int op_type,
487 1.1 christos offsetT value,
488 1.1 christos int left,
489 1.1 christos fixS *fix)
490 1.1 christos {
491 1.1 christos int shift, bits;
492 1.1 christos
493 1.1 christos shift = d10v_operands[op_type].shift;
494 1.1 christos if (left)
495 1.1 christos shift += 15;
496 1.1 christos
497 1.1 christos bits = d10v_operands[op_type].bits;
498 1.1 christos
499 1.1 christos /* Truncate to the proper number of bits. */
500 1.1 christos if (check_range (value, bits, d10v_operands[op_type].flags))
501 1.1 christos as_bad_where (fix->fx_file, fix->fx_line,
502 1.1 christos _("operand out of range: %ld"), (long) value);
503 1.1 christos
504 1.1 christos value &= 0x7FFFFFFF >> (31 - bits);
505 1.1 christos insn |= (value << shift);
506 1.1 christos
507 1.1 christos return insn;
508 1.1 christos }
509 1.1 christos
510 1.1 christos /* Take a pointer to the opcode entry in the opcode table and the
511 1.1 christos array of operand expressions. Return the instruction. */
512 1.1 christos
513 1.1 christos static unsigned long
514 1.1 christos build_insn (struct d10v_opcode *opcode,
515 1.1 christos expressionS *opers,
516 1.1 christos unsigned long insn)
517 1.1 christos {
518 1.1 christos int i, bits, shift, flags, format;
519 1.1 christos unsigned long number;
520 1.1 christos
521 1.1 christos /* The insn argument is only used for the DIVS kludge. */
522 1.1 christos if (insn)
523 1.1 christos format = LONG_R;
524 1.1 christos else
525 1.1 christos {
526 1.1 christos insn = opcode->opcode;
527 1.1 christos format = opcode->format;
528 1.1 christos }
529 1.1 christos
530 1.1 christos for (i = 0; opcode->operands[i]; i++)
531 1.1 christos {
532 1.1 christos flags = d10v_operands[opcode->operands[i]].flags;
533 1.1 christos bits = d10v_operands[opcode->operands[i]].bits;
534 1.1 christos shift = d10v_operands[opcode->operands[i]].shift;
535 1.1 christos number = opers[i].X_add_number;
536 1.1 christos
537 1.1 christos if (flags & OPERAND_REG)
538 1.1 christos {
539 1.1 christos number &= REGISTER_MASK;
540 1.1 christos if (format == LONG_L)
541 1.1 christos shift += 15;
542 1.1 christos }
543 1.1 christos
544 1.1 christos if (opers[i].X_op != O_register && opers[i].X_op != O_constant)
545 1.1 christos {
546 1.1 christos /* Now create a fixup. */
547 1.1 christos
548 1.1 christos if (fixups->fc >= MAX_INSN_FIXUPS)
549 1.1 christos as_fatal (_("too many fixups"));
550 1.1 christos
551 1.1 christos if (AT_WORD_P (&opers[i]))
552 1.1 christos {
553 1.1 christos /* Recognize XXX>>1+N aka XXX@word+N as special (AT_WORD). */
554 1.1 christos fixups->fix[fixups->fc].reloc = BFD_RELOC_D10V_18;
555 1.1 christos opers[i].X_op = O_symbol;
556 1.1 christos opers[i].X_op_symbol = NULL; /* Should free it. */
557 1.1 christos /* number is left shifted by AT_WORD_RIGHT_SHIFT so
558 1.1 christos that, it is aligned with the symbol's value. Later,
559 1.1 christos BFD_RELOC_D10V_18 will right shift (symbol_value +
560 1.1 christos X_add_number). */
561 1.1 christos number <<= AT_WORD_RIGHT_SHIFT;
562 1.1 christos opers[i].X_add_number = number;
563 1.1 christos }
564 1.1 christos else
565 1.1 christos {
566 1.1 christos fixups->fix[fixups->fc].reloc =
567 1.1.1.8 christos get_reloc (&d10v_operands[opcode->operands[i]]);
568 1.1 christos
569 1.1 christos /* Check that an immediate was passed to ops that expect one. */
570 1.1 christos if ((flags & OPERAND_NUM)
571 1.1 christos && (fixups->fix[fixups->fc].reloc == 0))
572 1.1 christos as_bad (_("operand is not an immediate"));
573 1.1 christos }
574 1.1 christos
575 1.1 christos if (fixups->fix[fixups->fc].reloc == BFD_RELOC_16 ||
576 1.1 christos fixups->fix[fixups->fc].reloc == BFD_RELOC_D10V_18)
577 1.1 christos fixups->fix[fixups->fc].size = 2;
578 1.1 christos else
579 1.1 christos fixups->fix[fixups->fc].size = 4;
580 1.1 christos
581 1.1 christos fixups->fix[fixups->fc].exp = opers[i];
582 1.1 christos fixups->fix[fixups->fc].operand = opcode->operands[i];
583 1.1.1.6 christos fixups->fix[fixups->fc].pcrel = (flags & OPERAND_ADDR) != 0;
584 1.1 christos (fixups->fc)++;
585 1.1 christos }
586 1.1 christos
587 1.1 christos /* Truncate to the proper number of bits. */
588 1.1 christos if ((opers[i].X_op == O_constant) && check_range (number, bits, flags))
589 1.1 christos as_bad (_("operand out of range: %lu"), number);
590 1.1 christos number &= 0x7FFFFFFF >> (31 - bits);
591 1.1 christos insn = insn | (number << shift);
592 1.1 christos }
593 1.1 christos
594 1.1 christos /* kludge: for DIVS, we need to put the operands in twice on the second
595 1.1 christos pass, format is changed to LONG_R to force the second set of operands
596 1.1 christos to not be shifted over 15. */
597 1.1 christos if ((opcode->opcode == OPCODE_DIVS) && (format == LONG_L))
598 1.1 christos insn = build_insn (opcode, opers, insn);
599 1.1 christos
600 1.1 christos return insn;
601 1.1 christos }
602 1.1 christos
603 1.1 christos /* Write out a long form instruction. */
604 1.1 christos
605 1.1 christos static void
606 1.1 christos write_long (unsigned long insn, Fixups *fx)
607 1.1 christos {
608 1.1 christos int i, where;
609 1.1 christos char *f = frag_more (4);
610 1.1 christos
611 1.1 christos dwarf2_emit_insn (4);
612 1.1 christos insn |= FM11;
613 1.1 christos number_to_chars_bigendian (f, insn, 4);
614 1.1 christos
615 1.1 christos for (i = 0; i < fx->fc; i++)
616 1.1 christos {
617 1.1 christos if (fx->fix[i].reloc)
618 1.1 christos {
619 1.1 christos where = f - frag_now->fr_literal;
620 1.1 christos if (fx->fix[i].size == 2)
621 1.1 christos where += 2;
622 1.1 christos
623 1.1 christos if (fx->fix[i].reloc == BFD_RELOC_D10V_18)
624 1.1 christos fx->fix[i].operand |= 4096;
625 1.1 christos
626 1.1 christos fix_new_exp (frag_now,
627 1.1 christos where,
628 1.1 christos fx->fix[i].size,
629 1.1 christos &(fx->fix[i].exp),
630 1.1 christos fx->fix[i].pcrel,
631 1.1 christos fx->fix[i].operand|2048);
632 1.1 christos }
633 1.1 christos }
634 1.1 christos fx->fc = 0;
635 1.1 christos }
636 1.1 christos
637 1.1 christos /* Write out a short form instruction by itself. */
638 1.1 christos
639 1.1 christos static void
640 1.1 christos write_1_short (struct d10v_opcode *opcode,
641 1.1 christos unsigned long insn,
642 1.1 christos Fixups *fx)
643 1.1 christos {
644 1.1 christos char *f = frag_more (4);
645 1.1 christos int i, where;
646 1.1 christos
647 1.1 christos dwarf2_emit_insn (4);
648 1.1 christos if (opcode->exec_type & PARONLY)
649 1.1 christos as_fatal (_("Instruction must be executed in parallel with another instruction."));
650 1.1 christos
651 1.1 christos /* The other container needs to be NOP.
652 1.1 christos According to 4.3.1: for FM=00, sub-instructions performed only by IU
653 1.1 christos cannot be encoded in L-container. */
654 1.1 christos if (opcode->unit == IU)
655 1.1 christos insn |= FM00 | (NOP << 15); /* Right container. */
656 1.1 christos else
657 1.1 christos insn = FM00 | (insn << 15) | NOP; /* Left container. */
658 1.1 christos
659 1.1 christos number_to_chars_bigendian (f, insn, 4);
660 1.1 christos for (i = 0; i < fx->fc; i++)
661 1.1 christos {
662 1.1 christos if (fx->fix[i].reloc)
663 1.1 christos {
664 1.1 christos where = f - frag_now->fr_literal;
665 1.1 christos if (fx->fix[i].size == 2)
666 1.1 christos where += 2;
667 1.1 christos
668 1.1 christos if (fx->fix[i].reloc == BFD_RELOC_D10V_18)
669 1.1 christos fx->fix[i].operand |= 4096;
670 1.1 christos
671 1.1 christos /* If it's an R reloc, we may have to switch it to L. */
672 1.1 christos if ((fx->fix[i].reloc == BFD_RELOC_D10V_10_PCREL_R)
673 1.1 christos && (opcode->unit != IU))
674 1.1 christos fx->fix[i].operand |= 1024;
675 1.1 christos
676 1.1 christos fix_new_exp (frag_now,
677 1.1 christos where,
678 1.1 christos fx->fix[i].size,
679 1.1 christos &(fx->fix[i].exp),
680 1.1 christos fx->fix[i].pcrel,
681 1.1 christos fx->fix[i].operand|2048);
682 1.1 christos }
683 1.1 christos }
684 1.1 christos fx->fc = 0;
685 1.1 christos }
686 1.1 christos
687 1.1 christos /* Determine if there are any resource conflicts among two manually
688 1.1 christos parallelized instructions. Some of this was lifted from parallel_ok. */
689 1.1 christos
690 1.1 christos static void
691 1.1 christos check_resource_conflict (struct d10v_opcode *op1,
692 1.1 christos unsigned long insn1,
693 1.1 christos struct d10v_opcode *op2,
694 1.1 christos unsigned long insn2)
695 1.1 christos {
696 1.1 christos int i, j, flags, mask, shift, regno;
697 1.1 christos unsigned long ins, mod[2];
698 1.1 christos struct d10v_opcode *op;
699 1.1 christos
700 1.1 christos if ((op1->exec_type & SEQ)
701 1.1 christos || ! ((op1->exec_type & PAR) || (op1->exec_type & PARONLY)))
702 1.1 christos {
703 1.1 christos as_warn (_("packing conflict: %s must dispatch sequentially"),
704 1.1 christos op1->name);
705 1.1 christos return;
706 1.1 christos }
707 1.1 christos
708 1.1 christos if ((op2->exec_type & SEQ)
709 1.1 christos || ! ((op2->exec_type & PAR) || (op2->exec_type & PARONLY)))
710 1.1 christos {
711 1.1 christos as_warn (_("packing conflict: %s must dispatch sequentially"),
712 1.1 christos op2->name);
713 1.1 christos return;
714 1.1 christos }
715 1.1 christos
716 1.1 christos /* See if both instructions write to the same resource.
717 1.1 christos
718 1.1 christos The idea here is to create two sets of bitmasks (mod and used) which
719 1.1 christos indicate which registers are modified or used by each instruction.
720 1.1 christos The operation can only be done in parallel if neither instruction
721 1.1 christos modifies the same register. Accesses to control registers and memory
722 1.1 christos are treated as accesses to a single register. So if both instructions
723 1.1 christos write memory or if the first instruction writes memory and the second
724 1.1 christos reads, then they cannot be done in parallel. We treat reads to the PSW
725 1.1 christos (which includes C, F0, and F1) in isolation. So simultaneously writing
726 1.1 christos C and F0 in two different sub-instructions is permitted. */
727 1.1 christos
728 1.1 christos /* The bitmasks (mod and used) look like this (bit 31 = MSB).
729 1.1 christos r0-r15 0-15
730 1.1 christos a0-a1 16-17
731 1.1 christos cr (not psw) 18
732 1.1 christos psw(other) 19
733 1.1 christos mem 20
734 1.1 christos psw(C flag) 21
735 1.1 christos psw(F0 flag) 22 */
736 1.1 christos
737 1.1 christos for (j = 0; j < 2; j++)
738 1.1 christos {
739 1.1 christos if (j == 0)
740 1.1 christos {
741 1.1 christos op = op1;
742 1.1 christos ins = insn1;
743 1.1 christos }
744 1.1 christos else
745 1.1 christos {
746 1.1 christos op = op2;
747 1.1 christos ins = insn2;
748 1.1 christos }
749 1.1 christos mod[j] = 0;
750 1.1 christos if (op->exec_type & BRANCH_LINK)
751 1.1 christos mod[j] |= 1 << 13;
752 1.1 christos
753 1.1 christos for (i = 0; op->operands[i]; i++)
754 1.1 christos {
755 1.1 christos flags = d10v_operands[op->operands[i]].flags;
756 1.1 christos shift = d10v_operands[op->operands[i]].shift;
757 1.1 christos mask = 0x7FFFFFFF >> (31 - d10v_operands[op->operands[i]].bits);
758 1.1 christos if (flags & OPERAND_REG)
759 1.1 christos {
760 1.1 christos regno = (ins >> shift) & mask;
761 1.1 christos if (flags & (OPERAND_ACC0 | OPERAND_ACC1))
762 1.1 christos regno += 16;
763 1.1 christos else if (flags & OPERAND_CONTROL) /* mvtc or mvfc */
764 1.1 christos {
765 1.1 christos if (regno == 0)
766 1.1 christos regno = 19;
767 1.1 christos else
768 1.1 christos regno = 18;
769 1.1 christos }
770 1.1 christos else if (flags & OPERAND_FFLAG)
771 1.1 christos regno = 22;
772 1.1 christos else if (flags & OPERAND_CFLAG)
773 1.1 christos regno = 21;
774 1.1 christos
775 1.1 christos if (flags & OPERAND_DEST
776 1.1 christos /* Auto inc/dec also modifies the register. */
777 1.1 christos || (op->operands[i + 1] != 0
778 1.1 christos && (d10v_operands[op->operands[i + 1]].flags
779 1.1 christos & (OPERAND_PLUS | OPERAND_MINUS)) != 0))
780 1.1 christos {
781 1.1 christos mod[j] |= 1 << regno;
782 1.1 christos if (flags & OPERAND_EVEN)
783 1.1 christos mod[j] |= 1 << (regno + 1);
784 1.1 christos }
785 1.1 christos }
786 1.1 christos else if (flags & OPERAND_ATMINUS)
787 1.1 christos {
788 1.1 christos /* SP implicitly used/modified. */
789 1.1 christos mod[j] |= 1 << 15;
790 1.1 christos }
791 1.1 christos }
792 1.1 christos
793 1.1 christos if (op->exec_type & WMEM)
794 1.1 christos mod[j] |= 1 << 20;
795 1.1 christos else if (op->exec_type & WF0)
796 1.1 christos mod[j] |= 1 << 22;
797 1.1 christos else if (op->exec_type & WCAR)
798 1.1 christos mod[j] |= 1 << 21;
799 1.1 christos }
800 1.1 christos
801 1.1 christos if ((mod[0] & mod[1]) == 0)
802 1.1 christos return;
803 1.1 christos else
804 1.1 christos {
805 1.1 christos unsigned long x;
806 1.1 christos x = mod[0] & mod[1];
807 1.1 christos
808 1.1 christos for (j = 0; j <= 15; j++)
809 1.1 christos if (x & (1 << j))
810 1.1 christos as_warn (_("resource conflict (R%d)"), j);
811 1.1 christos for (j = 16; j <= 17; j++)
812 1.1 christos if (x & (1 << j))
813 1.1 christos as_warn (_("resource conflict (A%d)"), j - 16);
814 1.1 christos if (x & (1 << 19))
815 1.1 christos as_warn (_("resource conflict (PSW)"));
816 1.1 christos if (x & (1 << 21))
817 1.1 christos as_warn (_("resource conflict (C flag)"));
818 1.1 christos if (x & (1 << 22))
819 1.1 christos as_warn (_("resource conflict (F flag)"));
820 1.1 christos }
821 1.1 christos }
822 1.1 christos
823 1.1 christos /* Check 2 instructions and determine if they can be safely
824 1.1 christos executed in parallel. Return 1 if they can be. */
825 1.1 christos
826 1.1 christos static int
827 1.1 christos parallel_ok (struct d10v_opcode *op1,
828 1.1 christos unsigned long insn1,
829 1.1 christos struct d10v_opcode *op2,
830 1.1 christos unsigned long insn2,
831 1.1 christos packing_type exec_type)
832 1.1 christos {
833 1.1 christos int i, j, flags, mask, shift, regno;
834 1.1 christos unsigned long ins, mod[2], used[2];
835 1.1 christos struct d10v_opcode *op;
836 1.1 christos
837 1.1 christos if ((op1->exec_type & SEQ) != 0 || (op2->exec_type & SEQ) != 0
838 1.1 christos || (op1->exec_type & PAR) == 0 || (op2->exec_type & PAR) == 0
839 1.1 christos || (op1->unit == BOTH) || (op2->unit == BOTH)
840 1.1 christos || (op1->unit == IU && op2->unit == IU)
841 1.1 christos || (op1->unit == MU && op2->unit == MU))
842 1.1 christos return 0;
843 1.1 christos
844 1.1 christos /* If this is auto parallelization, and the first instruction is a
845 1.1 christos branch or should not be packed, then don't parallelize. */
846 1.1 christos if (exec_type == PACK_UNSPEC
847 1.1 christos && (op1->exec_type & (ALONE | BRANCH)))
848 1.1 christos return 0;
849 1.1 christos
850 1.1 christos /* The idea here is to create two sets of bitmasks (mod and used)
851 1.1 christos which indicate which registers are modified or used by each
852 1.1 christos instruction. The operation can only be done in parallel if
853 1.1 christos instruction 1 and instruction 2 modify different registers, and
854 1.1 christos the first instruction does not modify registers that the second
855 1.1 christos is using (The second instruction can modify registers that the
856 1.1 christos first is using as they are only written back after the first
857 1.1 christos instruction has completed). Accesses to control registers, PSW,
858 1.1 christos and memory are treated as accesses to a single register. So if
859 1.1 christos both instructions write memory or if the first instruction writes
860 1.1 christos memory and the second reads, then they cannot be done in
861 1.1 christos parallel. Likewise, if the first instruction mucks with the psw
862 1.1 christos and the second reads the PSW (which includes C, F0, and F1), then
863 1.1 christos they cannot operate safely in parallel. */
864 1.1 christos
865 1.1 christos /* The bitmasks (mod and used) look like this (bit 31 = MSB).
866 1.1 christos r0-r15 0-15
867 1.1 christos a0-a1 16-17
868 1.1 christos cr (not psw) 18
869 1.1 christos psw 19
870 1.1 christos mem 20 */
871 1.1 christos
872 1.1 christos for (j = 0; j < 2; j++)
873 1.1 christos {
874 1.1 christos if (j == 0)
875 1.1 christos {
876 1.1 christos op = op1;
877 1.1 christos ins = insn1;
878 1.1 christos }
879 1.1 christos else
880 1.1 christos {
881 1.1 christos op = op2;
882 1.1 christos ins = insn2;
883 1.1 christos }
884 1.1 christos mod[j] = used[j] = 0;
885 1.1 christos if (op->exec_type & BRANCH_LINK)
886 1.1 christos mod[j] |= 1 << 13;
887 1.1 christos
888 1.1 christos for (i = 0; op->operands[i]; i++)
889 1.1 christos {
890 1.1 christos flags = d10v_operands[op->operands[i]].flags;
891 1.1 christos shift = d10v_operands[op->operands[i]].shift;
892 1.1 christos mask = 0x7FFFFFFF >> (31 - d10v_operands[op->operands[i]].bits);
893 1.1 christos if (flags & OPERAND_REG)
894 1.1 christos {
895 1.1 christos regno = (ins >> shift) & mask;
896 1.1 christos if (flags & (OPERAND_ACC0 | OPERAND_ACC1))
897 1.1 christos regno += 16;
898 1.1 christos else if (flags & OPERAND_CONTROL) /* mvtc or mvfc. */
899 1.1 christos {
900 1.1 christos if (regno == 0)
901 1.1 christos regno = 19;
902 1.1 christos else
903 1.1 christos regno = 18;
904 1.1 christos }
905 1.1 christos else if (flags & (OPERAND_FFLAG | OPERAND_CFLAG))
906 1.1 christos regno = 19;
907 1.1 christos
908 1.1 christos if (flags & OPERAND_DEST)
909 1.1 christos {
910 1.1 christos mod[j] |= 1 << regno;
911 1.1 christos if (flags & OPERAND_EVEN)
912 1.1 christos mod[j] |= 1 << (regno + 1);
913 1.1 christos }
914 1.1 christos else
915 1.1 christos {
916 1.1 christos used[j] |= 1 << regno;
917 1.1 christos if (flags & OPERAND_EVEN)
918 1.1 christos used[j] |= 1 << (regno + 1);
919 1.1 christos
920 1.1 christos /* Auto inc/dec also modifies the register. */
921 1.1 christos if (op->operands[i + 1] != 0
922 1.1 christos && (d10v_operands[op->operands[i + 1]].flags
923 1.1 christos & (OPERAND_PLUS | OPERAND_MINUS)) != 0)
924 1.1 christos mod[j] |= 1 << regno;
925 1.1 christos }
926 1.1 christos }
927 1.1 christos else if (flags & OPERAND_ATMINUS)
928 1.1 christos {
929 1.1 christos /* SP implicitly used/modified. */
930 1.1 christos mod[j] |= 1 << 15;
931 1.1 christos used[j] |= 1 << 15;
932 1.1 christos }
933 1.1 christos }
934 1.1 christos if (op->exec_type & RMEM)
935 1.1 christos used[j] |= 1 << 20;
936 1.1 christos else if (op->exec_type & WMEM)
937 1.1 christos mod[j] |= 1 << 20;
938 1.1 christos else if (op->exec_type & RF0)
939 1.1 christos used[j] |= 1 << 19;
940 1.1 christos else if (op->exec_type & WF0)
941 1.1 christos mod[j] |= 1 << 19;
942 1.1 christos else if (op->exec_type & WCAR)
943 1.1 christos mod[j] |= 1 << 19;
944 1.1 christos }
945 1.1 christos if ((mod[0] & mod[1]) == 0 && (mod[0] & used[1]) == 0)
946 1.1 christos return 1;
947 1.1 christos return 0;
948 1.1 christos }
949 1.1 christos
950 1.1 christos /* Expects two short instructions.
951 1.1 christos If possible, writes out both as a single packed instruction.
952 1.1 christos Otherwise, writes out the first one, packed with a NOP.
953 1.1 christos Returns number of instructions not written out. */
954 1.1 christos
955 1.1 christos static int
956 1.1 christos write_2_short (struct d10v_opcode *opcode1,
957 1.1 christos unsigned long insn1,
958 1.1 christos struct d10v_opcode *opcode2,
959 1.1 christos unsigned long insn2,
960 1.1 christos packing_type exec_type,
961 1.1 christos Fixups *fx)
962 1.1 christos {
963 1.1 christos unsigned long insn;
964 1.1 christos char *f;
965 1.1 christos int i, j, where;
966 1.1 christos
967 1.1 christos if ((exec_type != PACK_PARALLEL)
968 1.1 christos && ((opcode1->exec_type & PARONLY) || (opcode2->exec_type & PARONLY)))
969 1.1 christos as_fatal (_("Instruction must be executed in parallel"));
970 1.1 christos
971 1.1 christos if ((opcode1->format & LONG_OPCODE) || (opcode2->format & LONG_OPCODE))
972 1.1 christos as_fatal (_("Long instructions may not be combined."));
973 1.1 christos
974 1.1 christos switch (exec_type)
975 1.1 christos {
976 1.1 christos case PACK_UNSPEC: /* Order not specified. */
977 1.1 christos if (opcode1->exec_type & ALONE)
978 1.1 christos {
979 1.1 christos /* Case of a short branch on a separate GAS line. Pack with NOP. */
980 1.1 christos write_1_short (opcode1, insn1, fx->next);
981 1.1 christos return 1;
982 1.1 christos }
983 1.1 christos if (Optimizing
984 1.1 christos && parallel_ok (opcode1, insn1, opcode2, insn2, exec_type))
985 1.1 christos {
986 1.1 christos /* Parallel. */
987 1.1 christos if (opcode1->unit == IU)
988 1.1 christos insn = FM00 | (insn2 << 15) | insn1;
989 1.1 christos else if (opcode2->unit == MU)
990 1.1 christos insn = FM00 | (insn2 << 15) | insn1;
991 1.1 christos else
992 1.1 christos insn = FM00 | (insn1 << 15) | insn2;
993 1.1 christos }
994 1.1 christos else if (opcode1->unit == IU)
995 1.1 christos /* Reverse sequential with IU opcode1 on right and done first. */
996 1.1 christos insn = FM10 | (insn2 << 15) | insn1;
997 1.1 christos else
998 1.1 christos /* Sequential with non-IU opcode1 on left and done first. */
999 1.1 christos insn = FM01 | (insn1 << 15) | insn2;
1000 1.1 christos break;
1001 1.1 christos
1002 1.1 christos case PACK_PARALLEL:
1003 1.1 christos if (opcode1->exec_type & SEQ || opcode2->exec_type & SEQ)
1004 1.1 christos as_fatal
1005 1.1 christos (_("One of these instructions may not be executed in parallel."));
1006 1.1 christos if (opcode1->unit == IU)
1007 1.1 christos {
1008 1.1 christos if (opcode2->unit == IU)
1009 1.1 christos as_fatal (_("Two IU instructions may not be executed in parallel"));
1010 1.1 christos if (!flag_warn_suppress_instructionswap)
1011 1.1 christos as_warn (_("Swapping instruction order"));
1012 1.1 christos insn = FM00 | (insn2 << 15) | insn1;
1013 1.1 christos }
1014 1.1 christos else if (opcode2->unit == MU)
1015 1.1 christos {
1016 1.1 christos if (opcode1->unit == MU)
1017 1.1 christos as_fatal (_("Two MU instructions may not be executed in parallel"));
1018 1.1 christos if (!flag_warn_suppress_instructionswap)
1019 1.1 christos as_warn (_("Swapping instruction order"));
1020 1.1 christos insn = FM00 | (insn2 << 15) | insn1;
1021 1.1 christos }
1022 1.1 christos else
1023 1.1 christos insn = FM00 | (insn1 << 15) | insn2;
1024 1.1 christos check_resource_conflict (opcode1, insn1, opcode2, insn2);
1025 1.1 christos break;
1026 1.1 christos
1027 1.1 christos case PACK_LEFT_RIGHT:
1028 1.1 christos if (opcode1->unit != IU)
1029 1.1 christos insn = FM01 | (insn1 << 15) | insn2;
1030 1.1 christos else if (opcode2->unit == MU || opcode2->unit == EITHER)
1031 1.1 christos {
1032 1.1 christos if (!flag_warn_suppress_instructionswap)
1033 1.1 christos as_warn (_("Swapping instruction order"));
1034 1.1 christos insn = FM10 | (insn2 << 15) | insn1;
1035 1.1 christos }
1036 1.1 christos else
1037 1.1 christos as_fatal (_("IU instruction may not be in the left container"));
1038 1.1 christos if (opcode1->exec_type & ALONE)
1039 1.1 christos as_warn (_("Instruction in R container is squashed by flow control instruction in L container."));
1040 1.1 christos break;
1041 1.1 christos
1042 1.1 christos case PACK_RIGHT_LEFT:
1043 1.1 christos if (opcode2->unit != MU)
1044 1.1 christos insn = FM10 | (insn1 << 15) | insn2;
1045 1.1 christos else if (opcode1->unit == IU || opcode1->unit == EITHER)
1046 1.1 christos {
1047 1.1 christos if (!flag_warn_suppress_instructionswap)
1048 1.1 christos as_warn (_("Swapping instruction order"));
1049 1.1 christos insn = FM01 | (insn2 << 15) | insn1;
1050 1.1 christos }
1051 1.1 christos else
1052 1.1 christos as_fatal (_("MU instruction may not be in the right container"));
1053 1.1 christos if (opcode2->exec_type & ALONE)
1054 1.1 christos as_warn (_("Instruction in R container is squashed by flow control instruction in L container."));
1055 1.1 christos break;
1056 1.1 christos
1057 1.1 christos default:
1058 1.1 christos as_fatal (_("unknown execution type passed to write_2_short()"));
1059 1.1 christos }
1060 1.1 christos
1061 1.1 christos f = frag_more (4);
1062 1.1 christos dwarf2_emit_insn (4);
1063 1.1 christos number_to_chars_bigendian (f, insn, 4);
1064 1.1 christos
1065 1.1 christos /* Process fixup chains. fx refers to insn2 when j == 0, and to
1066 1.1 christos insn1 when j == 1. Yes, it's reversed. */
1067 1.1 christos
1068 1.1 christos for (j = 0; j < 2; j++)
1069 1.1 christos {
1070 1.1 christos for (i = 0; i < fx->fc; i++)
1071 1.1 christos {
1072 1.1 christos if (fx->fix[i].reloc)
1073 1.1 christos {
1074 1.1 christos where = f - frag_now->fr_literal;
1075 1.1 christos if (fx->fix[i].size == 2)
1076 1.1 christos where += 2;
1077 1.1 christos
1078 1.1 christos if (fx->fix[i].reloc == BFD_RELOC_D10V_10_PCREL_R
1079 1.1 christos /* A BFD_RELOC_D10V_10_PCREL_R relocation applied to
1080 1.1 christos the instruction in the L container has to be
1081 1.1 christos adjusted to BDF_RELOC_D10V_10_PCREL_L. When
1082 1.1 christos j==0, we're processing insn2's operands, so we
1083 1.1 christos want to mark the operand if insn2 is *not* in the
1084 1.1 christos R container. When j==1, we're processing insn1's
1085 1.1 christos operands, so we want to mark the operand if insn2
1086 1.1 christos *is* in the R container. Note that, if two
1087 1.1 christos instructions are identical, we're never going to
1088 1.1 christos swap them, so the test is safe. */
1089 1.1 christos && j == ((insn & 0x7fff) == insn2))
1090 1.1 christos fx->fix[i].operand |= 1024;
1091 1.1 christos
1092 1.1 christos if (fx->fix[i].reloc == BFD_RELOC_D10V_18)
1093 1.1 christos fx->fix[i].operand |= 4096;
1094 1.1 christos
1095 1.1 christos fix_new_exp (frag_now,
1096 1.1 christos where,
1097 1.1 christos fx->fix[i].size,
1098 1.1 christos &(fx->fix[i].exp),
1099 1.1 christos fx->fix[i].pcrel,
1100 1.1 christos fx->fix[i].operand|2048);
1101 1.1 christos }
1102 1.1 christos }
1103 1.1 christos fx->fc = 0;
1104 1.1 christos fx = fx->next;
1105 1.1 christos }
1106 1.1 christos return 0;
1107 1.1 christos }
1108 1.1 christos
1109 1.1 christos /* This is the main entry point for the machine-dependent assembler.
1110 1.1 christos str points to a machine-dependent instruction. This function is
1111 1.1 christos supposed to emit the frags/bytes it assembles to. For the D10V, it
1112 1.1 christos mostly handles the special VLIW parsing and packing and leaves the
1113 1.1 christos difficult stuff to do_assemble(). */
1114 1.1 christos
1115 1.1 christos static unsigned long prev_insn;
1116 1.1 christos static struct d10v_opcode *prev_opcode = 0;
1117 1.1 christos static subsegT prev_subseg;
1118 1.1.1.2 christos static segT prev_seg = 0;
1119 1.1 christos
1120 1.1 christos /* Find the symbol which has the same name as the register in exp. */
1121 1.1 christos
1122 1.1 christos static symbolS *
1123 1.1 christos find_symbol_matching_register (expressionS *exp)
1124 1.1 christos {
1125 1.1 christos int i;
1126 1.1 christos
1127 1.1 christos if (exp->X_op != O_register)
1128 1.1 christos return NULL;
1129 1.1 christos
1130 1.1 christos /* Find the name of the register. */
1131 1.1 christos for (i = d10v_reg_name_cnt (); i--;)
1132 1.1 christos if (d10v_predefined_registers[i].value == exp->X_add_number)
1133 1.1 christos break;
1134 1.1 christos
1135 1.1 christos if (i < 0)
1136 1.1 christos abort ();
1137 1.1 christos
1138 1.1 christos /* Now see if a symbol has been defined with the same name. */
1139 1.1 christos return symbol_find (d10v_predefined_registers[i].name);
1140 1.1 christos }
1141 1.1 christos
1142 1.1 christos /* Get a pointer to an entry in the opcode table.
1143 1.1 christos The function must look at all opcodes with the same name and use
1144 1.1 christos the operands to choose the correct opcode. */
1145 1.1 christos
1146 1.1 christos static struct d10v_opcode *
1147 1.1 christos find_opcode (struct d10v_opcode *opcode, expressionS myops[])
1148 1.1 christos {
1149 1.1 christos int i, match;
1150 1.1 christos struct d10v_opcode *next_opcode;
1151 1.1 christos
1152 1.1 christos /* Get all the operands and save them as expressions. */
1153 1.1 christos get_operands (myops);
1154 1.1 christos
1155 1.1 christos /* Now see if the operand is a fake. If so, find the correct size
1156 1.1 christos instruction, if possible. */
1157 1.1 christos if (opcode->format == OPCODE_FAKE)
1158 1.1 christos {
1159 1.1 christos int opnum = opcode->operands[0];
1160 1.1 christos int flags;
1161 1.1 christos
1162 1.1 christos if (myops[opnum].X_op == O_register)
1163 1.1 christos {
1164 1.1 christos myops[opnum].X_op = O_symbol;
1165 1.1 christos myops[opnum].X_add_symbol =
1166 1.1 christos symbol_find_or_make ((char *) myops[opnum].X_op_symbol);
1167 1.1 christos myops[opnum].X_add_number = 0;
1168 1.1 christos myops[opnum].X_op_symbol = NULL;
1169 1.1 christos }
1170 1.1 christos
1171 1.1 christos next_opcode = opcode + 1;
1172 1.1 christos
1173 1.1 christos /* If the first operand is supposed to be a register, make sure
1174 1.1 christos we got a valid one. */
1175 1.1 christos flags = d10v_operands[next_opcode->operands[0]].flags;
1176 1.1 christos if (flags & OPERAND_REG)
1177 1.1 christos {
1178 1.1 christos int X_op = myops[0].X_op;
1179 1.1 christos int num = myops[0].X_add_number;
1180 1.1 christos
1181 1.1 christos if (X_op != O_register
1182 1.1 christos || (num & ~flags
1183 1.1 christos & (OPERAND_GPR | OPERAND_ACC0 | OPERAND_ACC1
1184 1.1 christos | OPERAND_FFLAG | OPERAND_CFLAG | OPERAND_CONTROL))
1185 1.1 christos || ((flags & OPERAND_SP) && ! (num & OPERAND_SP)))
1186 1.1 christos {
1187 1.1 christos as_bad (_("bad opcode or operands"));
1188 1.1 christos return 0;
1189 1.1 christos }
1190 1.1 christos }
1191 1.1 christos
1192 1.1 christos if (myops[opnum].X_op == O_constant
1193 1.1 christos || (myops[opnum].X_op == O_symbol
1194 1.1 christos && S_IS_DEFINED (myops[opnum].X_add_symbol)
1195 1.1 christos && (S_GET_SEGMENT (myops[opnum].X_add_symbol) == now_seg)))
1196 1.1 christos {
1197 1.1 christos for (i = 0; opcode->operands[i + 1]; i++)
1198 1.1 christos {
1199 1.1 christos int bits = d10v_operands[next_opcode->operands[opnum]].bits;
1200 1.1 christos
1201 1.1 christos flags = d10v_operands[next_opcode->operands[opnum]].flags;
1202 1.1 christos
1203 1.1 christos if (flags & OPERAND_ADDR)
1204 1.1 christos bits += 2;
1205 1.1 christos
1206 1.1 christos if (myops[opnum].X_op == O_constant)
1207 1.1 christos {
1208 1.1 christos if (!check_range (myops[opnum].X_add_number, bits, flags))
1209 1.1 christos break;
1210 1.1 christos }
1211 1.1 christos else
1212 1.1 christos {
1213 1.1 christos fragS *sym_frag;
1214 1.1 christos fragS *f;
1215 1.1 christos unsigned long current_position;
1216 1.1 christos unsigned long symbol_position;
1217 1.1 christos unsigned long value;
1218 1.1.1.6 christos bool found_symbol;
1219 1.1 christos
1220 1.1 christos /* Calculate the address of the current instruction
1221 1.1 christos and the address of the symbol. Do this by summing
1222 1.1 christos the offsets of previous frags until we reach the
1223 1.1 christos frag containing the symbol, and the current frag. */
1224 1.1 christos sym_frag = symbol_get_frag (myops[opnum].X_add_symbol);
1225 1.1.1.6 christos found_symbol = false;
1226 1.1 christos
1227 1.1.1.2 christos current_position = frag_now_fix_octets ();
1228 1.1 christos symbol_position = S_GET_VALUE (myops[opnum].X_add_symbol);
1229 1.1 christos
1230 1.1 christos for (f = frchain_now->frch_root; f; f = f->fr_next)
1231 1.1 christos {
1232 1.1 christos current_position += f->fr_fix + f->fr_offset;
1233 1.1 christos
1234 1.1 christos if (f == sym_frag)
1235 1.1.1.6 christos found_symbol = true;
1236 1.1 christos
1237 1.1 christos if (! found_symbol)
1238 1.1 christos symbol_position += f->fr_fix + f->fr_offset;
1239 1.1 christos }
1240 1.1 christos
1241 1.1 christos value = symbol_position;
1242 1.1 christos
1243 1.1 christos if (flags & OPERAND_ADDR)
1244 1.1 christos value -= current_position;
1245 1.1 christos
1246 1.1 christos if (AT_WORD_P (&myops[opnum]))
1247 1.1 christos {
1248 1.1 christos if (bits > 4)
1249 1.1 christos {
1250 1.1 christos bits += 2;
1251 1.1 christos if (!check_range (value, bits, flags))
1252 1.1 christos break;
1253 1.1 christos }
1254 1.1 christos }
1255 1.1 christos else if (!check_range (value, bits, flags))
1256 1.1 christos break;
1257 1.1 christos }
1258 1.1 christos next_opcode++;
1259 1.1 christos }
1260 1.1 christos
1261 1.1 christos if (opcode->operands [i + 1] == 0)
1262 1.1 christos as_fatal (_("value out of range"));
1263 1.1 christos else
1264 1.1 christos opcode = next_opcode;
1265 1.1 christos }
1266 1.1 christos else
1267 1.1 christos /* Not a constant, so use a long instruction. */
1268 1.1 christos opcode += 2;
1269 1.1 christos }
1270 1.1 christos
1271 1.1 christos match = 0;
1272 1.1 christos
1273 1.1 christos /* Now search the opcode table table for one with operands
1274 1.1 christos that matches what we've got. */
1275 1.1 christos while (!match)
1276 1.1 christos {
1277 1.1 christos match = 1;
1278 1.1 christos for (i = 0; opcode->operands[i]; i++)
1279 1.1 christos {
1280 1.1 christos int flags = d10v_operands[opcode->operands[i]].flags;
1281 1.1 christos int X_op = myops[i].X_op;
1282 1.1 christos int num = myops[i].X_add_number;
1283 1.1 christos
1284 1.1 christos if (X_op == 0)
1285 1.1 christos {
1286 1.1 christos match = 0;
1287 1.1 christos break;
1288 1.1 christos }
1289 1.1 christos
1290 1.1 christos if (flags & OPERAND_REG)
1291 1.1 christos {
1292 1.1 christos if ((X_op != O_register)
1293 1.1 christos || (num & ~flags
1294 1.1 christos & (OPERAND_GPR | OPERAND_ACC0 | OPERAND_ACC1
1295 1.1 christos | OPERAND_FFLAG | OPERAND_CFLAG
1296 1.1 christos | OPERAND_CONTROL))
1297 1.1 christos || ((flags & OPERAND_SP) && ! (num & OPERAND_SP)))
1298 1.1 christos {
1299 1.1 christos match = 0;
1300 1.1 christos break;
1301 1.1 christos }
1302 1.1 christos }
1303 1.1 christos
1304 1.1 christos if (((flags & OPERAND_MINUS) && ((X_op != O_absent) || (num != OPERAND_MINUS))) ||
1305 1.1 christos ((flags & OPERAND_PLUS) && ((X_op != O_absent) || (num != OPERAND_PLUS))) ||
1306 1.1 christos ((flags & OPERAND_ATMINUS) && ((X_op != O_absent) || (num != OPERAND_ATMINUS))) ||
1307 1.1 christos ((flags & OPERAND_ATPAR) && ((X_op != O_absent) || (num != OPERAND_ATPAR))) ||
1308 1.1 christos ((flags & OPERAND_ATSIGN) && ((X_op != O_absent) || ((num != OPERAND_ATSIGN) && (num != OPERAND_ATPAR)))))
1309 1.1 christos {
1310 1.1 christos match = 0;
1311 1.1 christos break;
1312 1.1 christos }
1313 1.1 christos
1314 1.1 christos /* Unfortunately, for the indirect operand in instructions such
1315 1.1 christos as ``ldb r1, @(c,r14)'' this function can be passed
1316 1.1 christos X_op == O_register (because 'c' is a valid register name).
1317 1.1 christos However we cannot just ignore the case when X_op == O_register
1318 1.1 christos but flags & OPERAND_REG is null, so we check to see if a symbol
1319 1.1 christos of the same name as the register exists. If the symbol does
1320 1.1 christos exist, then the parser was unable to distinguish the two cases
1321 1.1 christos and we fix things here. (Ref: PR14826) */
1322 1.1 christos
1323 1.1 christos if (!(flags & OPERAND_REG) && (X_op == O_register))
1324 1.1 christos {
1325 1.1 christos symbolS * sym;
1326 1.1 christos
1327 1.1 christos sym = find_symbol_matching_register (& myops[i]);
1328 1.1 christos
1329 1.1 christos if (sym != NULL)
1330 1.1 christos {
1331 1.1 christos myops[i].X_op = X_op = O_symbol;
1332 1.1 christos myops[i].X_add_symbol = sym;
1333 1.1 christos }
1334 1.1 christos else
1335 1.1 christos as_bad
1336 1.1 christos (_("illegal operand - register name found where none expected"));
1337 1.1 christos }
1338 1.1 christos }
1339 1.1 christos
1340 1.1 christos /* We're only done if the operands matched so far AND there
1341 1.1 christos are no more to check. */
1342 1.1 christos if (match && myops[i].X_op == 0)
1343 1.1 christos break;
1344 1.1 christos else
1345 1.1 christos match = 0;
1346 1.1 christos
1347 1.1 christos next_opcode = opcode + 1;
1348 1.1 christos
1349 1.1 christos if (next_opcode->opcode == 0)
1350 1.1 christos break;
1351 1.1 christos
1352 1.1 christos if (strcmp (next_opcode->name, opcode->name))
1353 1.1 christos break;
1354 1.1 christos
1355 1.1 christos opcode = next_opcode;
1356 1.1 christos }
1357 1.1 christos
1358 1.1 christos if (!match)
1359 1.1 christos {
1360 1.1 christos as_bad (_("bad opcode or operands"));
1361 1.1 christos return 0;
1362 1.1 christos }
1363 1.1 christos
1364 1.1 christos /* Check that all registers that are required to be even are.
1365 1.1 christos Also, if any operands were marked as registers, but were really symbols,
1366 1.1 christos fix that here. */
1367 1.1 christos for (i = 0; opcode->operands[i]; i++)
1368 1.1 christos {
1369 1.1 christos if ((d10v_operands[opcode->operands[i]].flags & OPERAND_EVEN) &&
1370 1.1 christos (myops[i].X_add_number & 1))
1371 1.1 christos as_fatal (_("Register number must be EVEN"));
1372 1.1 christos if ((d10v_operands[opcode->operands[i]].flags & OPERAND_NOSP)
1373 1.1 christos && (myops[i].X_add_number & OPERAND_SP))
1374 1.1 christos as_bad (_("Unsupported use of sp"));
1375 1.1 christos if (myops[i].X_op == O_register)
1376 1.1 christos {
1377 1.1 christos if (!(d10v_operands[opcode->operands[i]].flags & OPERAND_REG))
1378 1.1 christos {
1379 1.1 christos myops[i].X_op = O_symbol;
1380 1.1 christos myops[i].X_add_symbol =
1381 1.1 christos symbol_find_or_make ((char *) myops[i].X_op_symbol);
1382 1.1 christos myops[i].X_add_number = 0;
1383 1.1 christos myops[i].X_op_symbol = NULL;
1384 1.1 christos }
1385 1.1 christos }
1386 1.1 christos if ((d10v_operands[opcode->operands[i]].flags & OPERAND_CONTROL)
1387 1.1 christos && (myops[i].X_add_number == OPERAND_CONTROL + 4
1388 1.1 christos || myops[i].X_add_number == OPERAND_CONTROL + 5
1389 1.1 christos || myops[i].X_add_number == OPERAND_CONTROL + 6
1390 1.1 christos || myops[i].X_add_number == OPERAND_CONTROL + 12
1391 1.1 christos || myops[i].X_add_number == OPERAND_CONTROL + 13
1392 1.1 christos || myops[i].X_add_number == OPERAND_CONTROL + 15))
1393 1.1.1.7 christos as_warn (_("cr%d is a reserved control register"),
1394 1.1.1.7 christos (int) myops[i].X_add_number - OPERAND_CONTROL);
1395 1.1 christos }
1396 1.1 christos return opcode;
1397 1.1 christos }
1398 1.1 christos
1399 1.1 christos /* Assemble a single instruction.
1400 1.1 christos Return an opcode, or -1 (an invalid opcode) on error. */
1401 1.1 christos
1402 1.1 christos static unsigned long
1403 1.1 christos do_assemble (char *str, struct d10v_opcode **opcode)
1404 1.1 christos {
1405 1.1 christos unsigned char *op_start, *op_end;
1406 1.1 christos char *save;
1407 1.1 christos char name[20];
1408 1.1 christos int nlen = 0;
1409 1.1 christos expressionS myops[6];
1410 1.1 christos
1411 1.1 christos /* Drop leading whitespace. */
1412 1.1.1.8 christos while (is_whitespace (*str))
1413 1.1 christos str++;
1414 1.1 christos
1415 1.1 christos /* Find the opcode end. */
1416 1.1 christos for (op_start = op_end = (unsigned char *) str;
1417 1.1.1.8 christos !is_end_of_stmt (*op_end) && !is_whitespace (*op_end);
1418 1.1 christos op_end++)
1419 1.1 christos {
1420 1.1 christos name[nlen] = TOLOWER (op_start[nlen]);
1421 1.1 christos nlen++;
1422 1.1 christos if (nlen == sizeof (name) - 1)
1423 1.1 christos break;
1424 1.1 christos }
1425 1.1 christos name[nlen] = 0;
1426 1.1 christos
1427 1.1 christos if (nlen == 0)
1428 1.1 christos return -1;
1429 1.1 christos
1430 1.1 christos /* Find the first opcode with the proper name. */
1431 1.1.1.8 christos *opcode = str_hash_find (d10v_hash, name);
1432 1.1 christos if (*opcode == NULL)
1433 1.1 christos return -1;
1434 1.1 christos
1435 1.1 christos save = input_line_pointer;
1436 1.1 christos input_line_pointer = (char *) op_end;
1437 1.1 christos *opcode = find_opcode (*opcode, myops);
1438 1.1 christos if (*opcode == 0)
1439 1.1 christos return -1;
1440 1.1 christos input_line_pointer = save;
1441 1.1 christos
1442 1.1 christos return build_insn ((*opcode), myops, 0);
1443 1.1 christos }
1444 1.1 christos
1445 1.1 christos /* If while processing a fixup, a reloc really needs to be created.
1446 1.1 christos Then it is done here. */
1447 1.1 christos
1448 1.1 christos arelent *
1449 1.1 christos tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
1450 1.1 christos {
1451 1.1 christos arelent *reloc;
1452 1.1.1.8 christos reloc = notes_alloc (sizeof (arelent));
1453 1.1.1.8 christos reloc->sym_ptr_ptr = notes_alloc (sizeof (asymbol *));
1454 1.1 christos *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1455 1.1 christos reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1456 1.1 christos reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1457 1.1.1.8 christos if (reloc->howto == NULL)
1458 1.1 christos {
1459 1.1 christos as_bad_where (fixp->fx_file, fixp->fx_line,
1460 1.1 christos _("reloc %d not supported by object file format"),
1461 1.1 christos (int) fixp->fx_r_type);
1462 1.1 christos return NULL;
1463 1.1 christos }
1464 1.1 christos
1465 1.1 christos if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
1466 1.1 christos reloc->address = fixp->fx_offset;
1467 1.1 christos
1468 1.1 christos reloc->addend = 0;
1469 1.1 christos
1470 1.1 christos return reloc;
1471 1.1 christos }
1472 1.1 christos
1473 1.1 christos int
1474 1.1 christos md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
1475 1.1 christos asection *seg ATTRIBUTE_UNUSED)
1476 1.1 christos {
1477 1.1 christos abort ();
1478 1.1 christos return 0;
1479 1.1 christos }
1480 1.1 christos
1481 1.1 christos long
1482 1.1 christos md_pcrel_from_section (fixS *fixp, segT sec)
1483 1.1 christos {
1484 1.1.1.8 christos if (fixp->fx_addsy != NULL
1485 1.1 christos && (!S_IS_DEFINED (fixp->fx_addsy)
1486 1.1 christos || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
1487 1.1 christos return 0;
1488 1.1 christos return fixp->fx_frag->fr_address + fixp->fx_where;
1489 1.1 christos }
1490 1.1 christos
1491 1.1 christos void
1492 1.1 christos md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
1493 1.1 christos {
1494 1.1 christos char *where;
1495 1.1 christos unsigned long insn;
1496 1.1 christos long value = *valP;
1497 1.1 christos int op_type;
1498 1.1 christos int left = 0;
1499 1.1 christos
1500 1.1.1.8 christos if (fixP->fx_addsy == NULL)
1501 1.1 christos fixP->fx_done = 1;
1502 1.1 christos
1503 1.1 christos /* We don't actually support subtracting a symbol. */
1504 1.1.1.8 christos if (fixP->fx_subsy != NULL)
1505 1.1.1.6 christos as_bad_subtract (fixP);
1506 1.1 christos
1507 1.1 christos op_type = fixP->fx_r_type;
1508 1.1 christos if (op_type & 2048)
1509 1.1 christos {
1510 1.1 christos op_type -= 2048;
1511 1.1 christos if (op_type & 1024)
1512 1.1 christos {
1513 1.1 christos op_type -= 1024;
1514 1.1 christos fixP->fx_r_type = BFD_RELOC_D10V_10_PCREL_L;
1515 1.1 christos left = 1;
1516 1.1 christos }
1517 1.1 christos else if (op_type & 4096)
1518 1.1 christos {
1519 1.1 christos op_type -= 4096;
1520 1.1 christos fixP->fx_r_type = BFD_RELOC_D10V_18;
1521 1.1 christos }
1522 1.1 christos else
1523 1.1 christos fixP->fx_r_type =
1524 1.1.1.8 christos get_reloc (&d10v_operands[op_type]);
1525 1.1 christos }
1526 1.1 christos
1527 1.1 christos /* Fetch the instruction, insert the fully resolved operand
1528 1.1 christos value, and stuff the instruction back again. */
1529 1.1 christos where = fixP->fx_frag->fr_literal + fixP->fx_where;
1530 1.1.1.8 christos insn = bfd_getb32 (where);
1531 1.1 christos
1532 1.1 christos switch (fixP->fx_r_type)
1533 1.1 christos {
1534 1.1 christos case BFD_RELOC_D10V_10_PCREL_L:
1535 1.1 christos case BFD_RELOC_D10V_10_PCREL_R:
1536 1.1 christos case BFD_RELOC_D10V_18_PCREL:
1537 1.1 christos /* If the fix is relative to a global symbol, not a section
1538 1.1 christos symbol, then ignore the offset.
1539 1.1 christos XXX - Do we have to worry about branches to a symbol + offset ? */
1540 1.1 christos if (fixP->fx_addsy != NULL
1541 1.1 christos && S_IS_EXTERNAL (fixP->fx_addsy) )
1542 1.1 christos {
1543 1.1 christos segT fseg = S_GET_SEGMENT (fixP->fx_addsy);
1544 1.1 christos segment_info_type *segf = seg_info(fseg);
1545 1.1 christos
1546 1.1 christos if ( segf && segf->sym != fixP->fx_addsy)
1547 1.1 christos value = 0;
1548 1.1 christos }
1549 1.1.1.4 christos /* Fall through. */
1550 1.1 christos case BFD_RELOC_D10V_18:
1551 1.1 christos /* Instruction addresses are always right-shifted by 2. */
1552 1.1 christos value >>= AT_WORD_RIGHT_SHIFT;
1553 1.1 christos if (fixP->fx_size == 2)
1554 1.1.1.8 christos bfd_putb16 (value, where);
1555 1.1 christos else
1556 1.1 christos {
1557 1.1 christos struct d10v_opcode *rep, *repi;
1558 1.1 christos
1559 1.1.1.8 christos rep = str_hash_find (d10v_hash, "rep");
1560 1.1.1.8 christos repi = str_hash_find (d10v_hash, "repi");
1561 1.1 christos if ((insn & FM11) == FM11
1562 1.1 christos && ((repi != NULL
1563 1.1 christos && (insn & repi->mask) == (unsigned) repi->opcode)
1564 1.1 christos || (rep != NULL
1565 1.1 christos && (insn & rep->mask) == (unsigned) rep->opcode))
1566 1.1 christos && value < 4)
1567 1.1 christos as_fatal
1568 1.1 christos (_("line %d: rep or repi must include at least 4 instructions"),
1569 1.1 christos fixP->fx_line);
1570 1.1 christos insn =
1571 1.1 christos d10v_insert_operand (insn, op_type, (offsetT) value, left, fixP);
1572 1.1.1.8 christos bfd_putb32 (insn, where);
1573 1.1 christos }
1574 1.1 christos break;
1575 1.1 christos case BFD_RELOC_32:
1576 1.1.1.8 christos bfd_putb32 (value, where);
1577 1.1 christos break;
1578 1.1 christos case BFD_RELOC_16:
1579 1.1.1.8 christos bfd_putb16 (value, where);
1580 1.1 christos break;
1581 1.1.1.5 christos case BFD_RELOC_8:
1582 1.1.1.5 christos *where = value;
1583 1.1.1.5 christos break;
1584 1.1 christos
1585 1.1 christos case BFD_RELOC_VTABLE_INHERIT:
1586 1.1 christos case BFD_RELOC_VTABLE_ENTRY:
1587 1.1 christos fixP->fx_done = 0;
1588 1.1 christos return;
1589 1.1 christos
1590 1.1 christos default:
1591 1.1 christos as_fatal (_("line %d: unknown relocation type: 0x%x"),
1592 1.1 christos fixP->fx_line, fixP->fx_r_type);
1593 1.1 christos }
1594 1.1 christos }
1595 1.1 christos
1596 1.1 christos /* d10v_cleanup() is called after the assembler has finished parsing
1597 1.1 christos the input file, when a label is read from the input file, or when a
1598 1.1 christos stab directive is output. Because the D10V assembler sometimes
1599 1.1 christos saves short instructions to see if it can package them with the
1600 1.1 christos next instruction, there may be a short instruction that still needs
1601 1.1 christos to be written.
1602 1.1 christos
1603 1.1 christos NOTE: accesses a global, etype.
1604 1.1 christos NOTE: invoked by various macros such as md_cleanup: see. */
1605 1.1 christos
1606 1.1 christos int
1607 1.1 christos d10v_cleanup (void)
1608 1.1 christos {
1609 1.1 christos segT seg;
1610 1.1 christos subsegT subseg;
1611 1.1 christos
1612 1.1 christos /* If cleanup was invoked because the assembler encountered, e.g., a
1613 1.1 christos user label, we write out the pending instruction, if any. If it
1614 1.1 christos was invoked because the assembler is outputting a piece of line
1615 1.1 christos debugging information, though, we write out the pending
1616 1.1 christos instruction only if the --no-gstabs-packing command line switch
1617 1.1 christos has been specified. */
1618 1.1 christos if (prev_opcode
1619 1.1 christos && etype == PACK_UNSPEC
1620 1.1 christos && (! outputting_stabs_line_debug || ! flag_allow_gstabs_packing))
1621 1.1 christos {
1622 1.1 christos seg = now_seg;
1623 1.1 christos subseg = now_subseg;
1624 1.1 christos
1625 1.1 christos if (prev_seg)
1626 1.1 christos subseg_set (prev_seg, prev_subseg);
1627 1.1 christos
1628 1.1 christos write_1_short (prev_opcode, prev_insn, fixups->next);
1629 1.1 christos subseg_set (seg, subseg);
1630 1.1 christos prev_opcode = NULL;
1631 1.1 christos }
1632 1.1 christos return 1;
1633 1.1 christos }
1634 1.1 christos
1635 1.1 christos void
1636 1.1 christos d10v_frob_label (symbolS *lab)
1637 1.1 christos {
1638 1.1 christos d10v_cleanup ();
1639 1.1 christos symbol_set_frag (lab, frag_now);
1640 1.1 christos S_SET_VALUE (lab, (valueT) frag_now_fix ());
1641 1.1 christos dwarf2_emit_label (lab);
1642 1.1 christos }
1643 1.1 christos
1644 1.1 christos /* Like normal .word, except support @word.
1645 1.1 christos Clobbers input_line_pointer, checks end-of-line. */
1646 1.1 christos
1647 1.1 christos static void
1648 1.1 christos d10v_dot_word (int dummy ATTRIBUTE_UNUSED)
1649 1.1 christos {
1650 1.1 christos expressionS exp;
1651 1.1 christos char *p;
1652 1.1 christos
1653 1.1 christos if (is_it_end_of_statement ())
1654 1.1 christos {
1655 1.1 christos demand_empty_rest_of_line ();
1656 1.1 christos return;
1657 1.1 christos }
1658 1.1 christos
1659 1.1 christos do
1660 1.1 christos {
1661 1.1 christos expression (&exp);
1662 1.1 christos if (!strncasecmp (input_line_pointer, "@word", 5))
1663 1.1 christos {
1664 1.1 christos exp.X_add_number = 0;
1665 1.1 christos input_line_pointer += 5;
1666 1.1 christos
1667 1.1 christos p = frag_more (2);
1668 1.1 christos fix_new_exp (frag_now, p - frag_now->fr_literal, 2,
1669 1.1 christos &exp, 0, BFD_RELOC_D10V_18);
1670 1.1 christos }
1671 1.1 christos else
1672 1.1 christos emit_expr (&exp, 2);
1673 1.1 christos }
1674 1.1 christos while (*input_line_pointer++ == ',');
1675 1.1 christos
1676 1.1 christos input_line_pointer--; /* Put terminator back into stream. */
1677 1.1 christos demand_empty_rest_of_line ();
1678 1.1 christos }
1679 1.1 christos
1680 1.1 christos /* Mitsubishi asked that we support some old syntax that apparently
1681 1.1 christos had immediate operands starting with '#'. This is in some of their
1682 1.1 christos sample code but is not documented (although it appears in some
1683 1.1 christos examples in their assembler manual). For now, we'll solve this
1684 1.1 christos compatibility problem by simply ignoring any '#' at the beginning
1685 1.1 christos of an operand. */
1686 1.1 christos
1687 1.1 christos /* Operands that begin with '#' should fall through to here.
1688 1.1 christos From expr.c. */
1689 1.1 christos
1690 1.1 christos void
1691 1.1 christos md_operand (expressionS *expressionP)
1692 1.1 christos {
1693 1.1 christos if (*input_line_pointer == '#' && ! do_not_ignore_hash)
1694 1.1 christos {
1695 1.1 christos input_line_pointer++;
1696 1.1 christos expression (expressionP);
1697 1.1 christos }
1698 1.1 christos }
1699 1.1 christos
1700 1.1.1.6 christos bool
1701 1.1 christos d10v_fix_adjustable (fixS *fixP)
1702 1.1 christos {
1703 1.1 christos /* We need the symbol name for the VTABLE entries. */
1704 1.1 christos if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
1705 1.1 christos || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
1706 1.1 christos return 0;
1707 1.1 christos
1708 1.1 christos return 1;
1709 1.1 christos }
1710 1.1 christos
1711 1.1 christos /* The target specific pseudo-ops which we support. */
1712 1.1 christos const pseudo_typeS md_pseudo_table[] =
1713 1.1 christos {
1714 1.1 christos { "word", d10v_dot_word, 2 },
1715 1.1 christos { NULL, NULL, 0 }
1716 1.1 christos };
1717 1.1 christos
1718 1.1 christos void
1719 1.1 christos md_assemble (char *str)
1720 1.1 christos {
1721 1.1 christos /* etype is saved extype. For multi-line instructions. */
1722 1.1 christos packing_type extype = PACK_UNSPEC; /* Parallel, etc. */
1723 1.1 christos struct d10v_opcode *opcode;
1724 1.1 christos unsigned long insn;
1725 1.1 christos char *str2;
1726 1.1 christos
1727 1.1 christos if (etype == PACK_UNSPEC)
1728 1.1 christos {
1729 1.1 christos /* Look for the special multiple instruction separators. */
1730 1.1 christos str2 = strstr (str, "||");
1731 1.1 christos if (str2)
1732 1.1 christos extype = PACK_PARALLEL;
1733 1.1 christos else
1734 1.1 christos {
1735 1.1 christos str2 = strstr (str, "->");
1736 1.1 christos if (str2)
1737 1.1 christos extype = PACK_LEFT_RIGHT;
1738 1.1 christos else
1739 1.1 christos {
1740 1.1 christos str2 = strstr (str, "<-");
1741 1.1 christos if (str2)
1742 1.1 christos extype = PACK_RIGHT_LEFT;
1743 1.1 christos }
1744 1.1 christos }
1745 1.1 christos
1746 1.1 christos /* str2 points to the separator, if there is one. */
1747 1.1 christos if (str2)
1748 1.1 christos {
1749 1.1 christos *str2 = 0;
1750 1.1 christos
1751 1.1 christos /* If two instructions are present and we already have one saved,
1752 1.1 christos then first write out the saved one. */
1753 1.1 christos d10v_cleanup ();
1754 1.1 christos
1755 1.1 christos /* Assemble first instruction and save it. */
1756 1.1 christos prev_insn = do_assemble (str, &prev_opcode);
1757 1.1 christos prev_seg = now_seg;
1758 1.1 christos prev_subseg = now_subseg;
1759 1.1 christos if (prev_insn == (unsigned long) -1)
1760 1.1 christos as_fatal (_("can't find previous opcode "));
1761 1.1 christos fixups = fixups->next;
1762 1.1 christos str = str2 + 2;
1763 1.1 christos }
1764 1.1 christos }
1765 1.1 christos
1766 1.1 christos insn = do_assemble (str, &opcode);
1767 1.1 christos if (insn == (unsigned long) -1)
1768 1.1 christos {
1769 1.1 christos if (extype != PACK_UNSPEC)
1770 1.1 christos etype = extype;
1771 1.1 christos else
1772 1.1 christos as_bad (_("could not assemble: %s"), str);
1773 1.1 christos return;
1774 1.1 christos }
1775 1.1 christos
1776 1.1 christos if (etype != PACK_UNSPEC)
1777 1.1 christos {
1778 1.1 christos extype = etype;
1779 1.1 christos etype = PACK_UNSPEC;
1780 1.1 christos }
1781 1.1 christos
1782 1.1 christos /* If this is a long instruction, write it and any previous short
1783 1.1 christos instruction. */
1784 1.1 christos if (opcode->format & LONG_OPCODE)
1785 1.1 christos {
1786 1.1 christos if (extype != PACK_UNSPEC)
1787 1.1 christos as_fatal (_("Unable to mix instructions as specified"));
1788 1.1 christos d10v_cleanup ();
1789 1.1 christos write_long (insn, fixups);
1790 1.1 christos prev_opcode = NULL;
1791 1.1 christos return;
1792 1.1 christos }
1793 1.1 christos
1794 1.1 christos if (prev_opcode
1795 1.1 christos && prev_seg
1796 1.1 christos && ((prev_seg != now_seg) || (prev_subseg != now_subseg)))
1797 1.1 christos d10v_cleanup ();
1798 1.1 christos
1799 1.1 christos if (prev_opcode
1800 1.1 christos && (0 == write_2_short (prev_opcode, prev_insn, opcode, insn, extype,
1801 1.1 christos fixups)))
1802 1.1 christos {
1803 1.1 christos /* No instructions saved. */
1804 1.1 christos prev_opcode = NULL;
1805 1.1 christos }
1806 1.1 christos else
1807 1.1 christos {
1808 1.1 christos if (extype != PACK_UNSPEC)
1809 1.1 christos as_fatal (_("Unable to mix instructions as specified"));
1810 1.1 christos /* Save last instruction so it may be packed on next pass. */
1811 1.1 christos prev_opcode = opcode;
1812 1.1 christos prev_insn = insn;
1813 1.1 christos prev_seg = now_seg;
1814 1.1 christos prev_subseg = now_subseg;
1815 1.1 christos fixups = fixups->next;
1816 1.1 christos }
1817 1.1 christos }
1818 1.1 christos
1819