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