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