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