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