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