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