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