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