1b0480b1f9118e25a227f2567cdc41d2eee247be
[deliverable/binutils-gdb.git] / gas / config / tc-d10v.c
1 /* tc-d10v.c -- Assembler code for the Mitsubishi D10V
2
3 Copyright (C) 1996 Free Software Foundation.
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
29 const char comment_chars[] = "#;";
30 const char line_comment_chars[] = "#";
31 const char line_separator_chars[] = "";
32 const char *md_shortopts = "";
33 const char EXP_CHARS[] = "eE";
34 const char FLT_CHARS[] = "dD";
35
36
37 /* fixups */
38 #define MAX_INSN_FIXUPS (5)
39 struct d10v_fixup
40 {
41 expressionS exp;
42 bfd_reloc_code_real_type reloc;
43 };
44
45 typedef struct _fixups
46 {
47 int fc;
48 struct d10v_fixup fix[MAX_INSN_FIXUPS];
49 struct _fixups *next;
50 } Fixups;
51
52 static Fixups FixUps[2];
53 static Fixups *fixups;
54
55 /* local functions */
56 static int reg_name_search PARAMS ((char *name));
57 static int register_name PARAMS ((expressionS *expressionP));
58 static int check_range PARAMS ((unsigned long num, int bits, int flags));
59 static int postfix PARAMS ((char *p));
60 static bfd_reloc_code_real_type get_reloc PARAMS ((struct d10v_operand *op));
61 static int get_operands PARAMS ((expressionS exp[]));
62 static unsigned long build_insn PARAMS ((struct d10v_opcode *opcode, expressionS *opers, unsigned long insn));
63 static void write_long PARAMS ((struct d10v_opcode *opcode, unsigned long insn, Fixups *fx));
64 static void write_1_short PARAMS ((struct d10v_opcode *opcode, unsigned long insn, Fixups *fx));
65 static int write_2_short PARAMS ((struct d10v_opcode *opcode1, unsigned long insn1,
66 struct d10v_opcode *opcode2, unsigned long insn2, int exec_type, Fixups *fx));
67 static unsigned long do_assemble PARAMS ((char *str, struct d10v_opcode **opcode));
68 static unsigned long d10v_insert_operand PARAMS (( unsigned long insn, int op_type,
69 offsetT value, int left));
70
71
72 struct option md_longopts[] = {
73 {NULL, no_argument, NULL, 0}
74 };
75 size_t md_longopts_size = sizeof(md_longopts);
76
77 /* The target specific pseudo-ops which we support. */
78 const pseudo_typeS md_pseudo_table[] =
79 {
80 { NULL, NULL, 0 }
81 };
82
83 /* Opcode hash table. */
84 static struct hash_control *d10v_hash;
85
86 /* reg_name_search does a binary search of the pre_defined_registers
87 array to see if "name" is a valid regiter name. Returns the register
88 number from the array on success, or -1 on failure. */
89
90 static int
91 reg_name_search (name)
92 char *name;
93 {
94 int middle, low, high;
95 int cmp;
96
97 low = 0;
98 high = reg_name_cnt() - 1;
99
100 do
101 {
102 middle = (low + high) / 2;
103 cmp = strcasecmp (name, pre_defined_registers[middle].name);
104 if (cmp < 0)
105 high = middle - 1;
106 else if (cmp > 0)
107 low = middle + 1;
108 else
109 return pre_defined_registers[middle].value;
110 }
111 while (low <= high);
112 return -1;
113 }
114
115 /* register_name() checks the string at input_line_pointer
116 to see if it is a valid register name */
117
118 static int
119 register_name (expressionP)
120 expressionS *expressionP;
121 {
122 int reg_number;
123 char c, *p = input_line_pointer;
124
125 while (*p && *p!='\n' && *p!='\r' && *p !=',' && *p!=' ' && *p!=')')
126 p++;
127
128 c = *p;
129 if (c)
130 *p++ = 0;
131
132 /* look to see if it's in the register table */
133 reg_number = reg_name_search (input_line_pointer);
134 if (reg_number >= 0)
135 {
136 expressionP->X_op = O_register;
137 /* temporarily store a pointer to the string here */
138 expressionP->X_op_symbol = (struct symbol *)input_line_pointer;
139 expressionP->X_add_number = reg_number;
140 input_line_pointer = p;
141 return 1;
142 }
143 if (c)
144 *(p-1) = c;
145 return 0;
146 }
147
148
149 static int
150 check_range (num, bits, flags)
151 unsigned long num;
152 int bits;
153 int flags;
154 {
155 long min, max, bit1;
156 int retval=0;
157
158 /* don't bother checking 16-bit values */
159 if (bits == 16)
160 return 0;
161
162 if (flags & OPERAND_SHIFT)
163 {
164 /* all special shift operands are unsigned */
165 /* and <= 16. We allow 0 for now. */
166 if (num>16)
167 return 1;
168 else
169 return 0;
170 }
171
172 if (flags & OPERAND_SIGNED)
173 {
174 max = (1 << (bits - 1))-1;
175 min = - (1 << (bits - 1));
176 if (((long)num > max) || ((long)num < min))
177 retval = 1;
178 }
179 else
180 {
181 max = (1 << bits) - 1;
182 min = 0;
183 if ((num > max) || (num < min))
184 retval = 1;
185 }
186 return retval;
187 }
188
189
190 void
191 md_show_usage (stream)
192 FILE *stream;
193 {
194 fprintf(stream, "D10V options:\n\
195 none yet\n");
196 }
197
198 int
199 md_parse_option (c, arg)
200 int c;
201 char *arg;
202 {
203 return 0;
204 }
205
206 symbolS *
207 md_undefined_symbol (name)
208 char *name;
209 {
210 return 0;
211 }
212
213 char *
214 md_atof (type, litp, sizep)
215 int type;
216 char *litp;
217 int *sizep;
218 {
219 return "";
220 }
221
222 void
223 md_convert_frag (abfd, sec, fragP)
224 bfd *abfd;
225 asection *sec;
226 fragS *fragP;
227 {
228 printf ("call to md_convert_frag \n");
229 abort ();
230 }
231
232 valueT
233 md_section_align (seg, addr)
234 asection *seg;
235 valueT addr;
236 {
237 int align = bfd_get_section_alignment (stdoutput, seg);
238 return ((addr + (1 << align) - 1) & (-1 << align));
239 }
240
241
242 void
243 md_begin ()
244 {
245 char *prev_name = "";
246 struct d10v_opcode *opcode;
247 d10v_hash = hash_new();
248
249 /* Insert unique names into hash table. The D10v instruction set
250 has many identical opcode names that have different opcodes based
251 on the operands. This hash table then provides a quick index to
252 the first opcode with a particular name in the opcode table. */
253
254 for (opcode = (struct d10v_opcode *)d10v_opcodes; opcode->name; opcode++)
255 {
256 if (strcmp (prev_name, opcode->name))
257 {
258 prev_name = (char *)opcode->name;
259 hash_insert (d10v_hash, opcode->name, (char *) opcode);
260 }
261 }
262
263 fixups = &FixUps[0];
264 FixUps[0].next = &FixUps[1];
265 FixUps[1].next = &FixUps[0];
266 }
267
268
269 /* this function removes the postincrement or postdecrement
270 operator ( '+' or '-' ) from an expression */
271
272 static int postfix (p)
273 char *p;
274 {
275 while (*p != '-' && *p != '+')
276 {
277 if (*p==0 || *p=='\n' || *p=='\r')
278 break;
279 p++;
280 }
281
282 if (*p == '-')
283 {
284 *p = ' ';
285 return (-1);
286 }
287 if (*p == '+')
288 {
289 *p = ' ';
290 return (1);
291 }
292
293 return (0);
294 }
295
296
297 static bfd_reloc_code_real_type
298 get_reloc (op)
299 struct d10v_operand *op;
300 {
301 int bits = op->bits;
302
303 /* printf("get_reloc: bits=%d address=%d\n",bits,op->flags & OPERAND_ADDR); */
304 if (bits <= 4)
305 return (0);
306
307 if (op->flags & OPERAND_ADDR)
308 {
309 if (bits == 8)
310 return (BFD_RELOC_D10V_10_PCREL_R);
311 else
312 return (BFD_RELOC_D10V_18_PCREL);
313 }
314
315 return (BFD_RELOC_16);
316 }
317
318 /* get_operands parses a string of operands and returns
319 an array of expressions */
320
321 static int
322 get_operands (exp)
323 expressionS exp[];
324 {
325 char *p = input_line_pointer;
326 int numops = 0;
327 int post = 0;
328
329 while (*p)
330 {
331 while (*p == ' ' || *p == '\t' || *p == ',')
332 p++;
333 if (*p==0 || *p=='\n' || *p=='\r')
334 break;
335
336 if (*p == '@')
337 {
338 p++;
339 exp[numops].X_op = O_absent;
340 if (*p == '(')
341 {
342 p++;
343 exp[numops].X_add_number = OPERAND_ATPAR;
344 }
345 else if (*p == '-')
346 {
347 p++;
348 exp[numops].X_add_number = OPERAND_ATMINUS;
349 }
350 else
351 {
352 exp[numops].X_add_number = OPERAND_ATSIGN;
353 post = postfix (p);
354 }
355 numops++;
356 continue;
357 }
358
359 if (*p == ')')
360 {
361 /* just skip the trailing paren */
362 p++;
363 continue;
364 }
365
366 input_line_pointer = p;
367
368
369 /* check to see if it might be a register name */
370 if (!register_name (&exp[numops]))
371 {
372 /* parse as an expression */
373 expression (&exp[numops]);
374 }
375
376 if (exp[numops].X_op == O_illegal)
377 as_bad ("illegal operand");
378 else if (exp[numops].X_op == O_absent)
379 as_bad ("missing operand");
380
381 numops++;
382 p = input_line_pointer;
383 }
384
385 switch (post)
386 {
387 case -1: /* postdecrement mode */
388 exp[numops].X_op = O_absent;
389 exp[numops++].X_add_number = OPERAND_MINUS;
390 break;
391 case 1: /* postincrement mode */
392 exp[numops].X_op = O_absent;
393 exp[numops++].X_add_number = OPERAND_PLUS;
394 break;
395 }
396
397 exp[numops].X_op = 0;
398 return (numops);
399 }
400
401 static unsigned long
402 d10v_insert_operand (insn, op_type, value, left)
403 unsigned long insn;
404 int op_type;
405 offsetT value;
406 int left;
407 {
408 int shift, bits;
409
410 shift = d10v_operands[op_type].shift;
411 if (left)
412 shift += 15;
413
414 bits = d10v_operands[op_type].bits;
415
416 /* truncate to the proper number of bits */
417 if (check_range (value, bits, d10v_operands[op_type].flags))
418 as_bad("operand out of range: %d",value);
419
420 value &= 0x7FFFFFFF >> (31 - bits);
421 insn |= (value << shift);
422
423 return insn;
424 }
425
426
427 /* build_insn takes a pointer to the opcode entry in the opcode table
428 and the array of operand expressions and returns the instruction */
429
430 static unsigned long
431 build_insn (opcode, opers, insn)
432 struct d10v_opcode *opcode;
433 expressionS *opers;
434 unsigned long insn;
435 {
436 int i, bits, shift, flags, format;
437 unsigned int number;
438
439 /* the insn argument is only used for the DIVS kludge */
440 if (insn)
441 format = LONG_R;
442 else
443 {
444 insn = opcode->opcode;
445 format = opcode->format;
446 }
447
448 for (i=0;opcode->operands[i];i++)
449 {
450 flags = d10v_operands[opcode->operands[i]].flags;
451 bits = d10v_operands[opcode->operands[i]].bits;
452 shift = d10v_operands[opcode->operands[i]].shift;
453 number = opers[i].X_add_number;
454
455 if (flags & OPERAND_REG)
456 {
457 number &= REGISTER_MASK;
458 if (format == LONG_L)
459 shift += 15;
460 }
461
462 if (opers[i].X_op != O_register && opers[i].X_op != O_constant)
463 {
464 /* now create a fixup */
465
466 /*
467 printf("need a fixup: ");
468 print_expr_1(stdout,&opers[i]);
469 printf("\n");
470 */
471
472 if (fixups->fc >= MAX_INSN_FIXUPS)
473 as_fatal ("too many fixups");
474 fixups->fix[fixups->fc].exp = opers[i];
475
476 /* put the operand number here for now. We can look up
477 the reloc type and/or fixup the instruction in md_apply_fix() */
478 fixups->fix[fixups->fc].reloc = opcode->operands[i];
479 (fixups->fc)++;
480 }
481
482 /* truncate to the proper number of bits */
483 if ((opers[i].X_op == O_constant) && check_range (number, bits, flags))
484 as_bad("operand out of range: %d",number);
485 number &= 0x7FFFFFFF >> (31 - bits);
486 insn = insn | (number << shift);
487 }
488
489 /* kludge: for DIVS, we need to put the operands in twice */
490 /* on the second pass, format is changed to LONG_R to force */
491 /* the second set of operands to not be shifted over 15 */
492 if ((opcode->opcode == OPCODE_DIVS) && (format==LONG_L))
493 insn = build_insn (opcode, opers, insn);
494
495 return insn;
496 }
497
498 /* write out a long form instruction */
499 static void
500 write_long (opcode, insn, fx)
501 struct d10v_opcode *opcode;
502 unsigned long insn;
503 Fixups *fx;
504 {
505 int i;
506 char *f = frag_more(4);
507
508 insn |= FM11;
509 /* printf("INSN: %08x\n",insn); */
510 number_to_chars_bigendian (f, insn, 4);
511
512 for (i=0; i < fx->fc; i++)
513 {
514 if (get_reloc((struct d10v_operand *)&d10v_operands[fx->fix[i].reloc]))
515 {
516 /*
517 printf("fix_new_exp: where:%x size:4\n ",f - frag_now->fr_literal);
518 print_expr_1(stdout,&(fx->fix[i].exp));
519 printf("\n");
520 */
521
522 fix_new_exp (frag_now,
523 f - frag_now->fr_literal,
524 4,
525 &(fx->fix[i].exp),
526 1,
527 fx->fix[i].reloc);
528 }
529 }
530 fx->fc = 0;
531 }
532
533
534 /* write out a short form instruction by itself */
535 static void
536 write_1_short (opcode, insn, fx)
537 struct d10v_opcode *opcode;
538 unsigned long insn;
539 Fixups *fx;
540 {
541 char *f = frag_more(4);
542 int i;
543
544 if (opcode->exec_type == PARONLY)
545 as_fatal ("Instruction must be executed in parallel with another instruction.");
546
547 /* the other container needs to be NOP */
548 /* according to 4.3.1: for FM=00, sub-instructions performed only
549 by IU cannot be encoded in L-container. */
550 if (opcode->unit == IU)
551 insn |= FM00 | (NOP << 15); /* right container */
552 else
553 insn = FM00 | (insn << 15) | NOP; /* left container */
554
555 /* printf("INSN: %08x\n",insn); */
556 number_to_chars_bigendian (f, insn, 4);
557 for (i=0; i < fx->fc; i++)
558 {
559 bfd_reloc_code_real_type reloc;
560 reloc = get_reloc((struct d10v_operand *)&d10v_operands[fx->fix[i].reloc]);
561 if (reloc)
562 {
563 /*
564 printf("fix_new_exp: where:%x size:4\n ",f - frag_now->fr_literal);
565 print_expr_1(stdout,&(fx->fix[i].exp));
566 printf("\n");
567 */
568
569 /* if it's an R reloc, we may have to switch it to L */
570 if ( (reloc == BFD_RELOC_D10V_10_PCREL_R) && (opcode->unit != IU) )
571 fx->fix[i].reloc |= 1024;
572
573 fix_new_exp (frag_now,
574 f - frag_now->fr_literal,
575 4,
576 &(fx->fix[i].exp),
577 1,
578 fx->fix[i].reloc);
579 }
580 }
581 fx->fc = 0;
582 }
583
584 /* write out a short form instruction if possible */
585 /* return number of instructions not written out */
586 static int
587 write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
588 struct d10v_opcode *opcode1, *opcode2;
589 unsigned long insn1, insn2;
590 int exec_type;
591 Fixups *fx;
592 {
593 unsigned long insn;
594 char *f;
595 int i,j;
596
597 if ( (exec_type != 1) && ((opcode1->exec_type == PARONLY)
598 || (opcode2->exec_type == PARONLY)))
599 as_fatal("Instruction must be executed in parallel");
600
601 if ( (opcode1->format & LONG_OPCODE) || (opcode2->format & LONG_OPCODE))
602 as_fatal ("Long instructions may not be combined.");
603
604 if(opcode1->exec_type == BRANCH_LINK)
605 {
606 /* subroutines must be called from 32-bit boundaries */
607 /* so the return address will be correct */
608 write_1_short (opcode1, insn1, fx->next);
609 return (1);
610 }
611
612 switch (exec_type)
613 {
614 case 0:
615 if (opcode1->unit == IU)
616 {
617 /* reverse sequential */
618 insn = FM10 | (insn2 << 15) | insn1;
619 }
620 else
621 {
622 insn = FM01 | (insn1 << 15) | insn2;
623 fx = fx->next;
624 }
625 break;
626 case 1: /* parallel */
627 if (opcode1->exec_type == SEQ || opcode2->exec_type == SEQ)
628 as_fatal ("One of these instructions may not be executed in parallel.");
629
630 if (opcode1->unit == IU)
631 {
632 if (opcode2->unit == IU)
633 as_fatal ("Two IU instructions may not be executed in parallel");
634 as_warn ("Swapping instruction order");
635 insn = FM00 | (insn2 << 15) | insn1;
636 fx = fx->next;
637 }
638 else if (opcode2->unit == MU)
639 {
640 if (opcode1->unit == MU)
641 as_fatal ("Two MU instructions may not be executed in parallel");
642 as_warn ("Swapping instruction order");
643 insn = FM00 | (insn2 << 15) | insn1;
644 fx = fx->next;
645 }
646 else
647 insn = FM00 | (insn1 << 15) | insn2;
648 fx = fx->next;
649 break;
650 case 2: /* sequential */
651 if (opcode1->unit == IU)
652 as_fatal ("IU instruction may not be in the left container");
653 insn = FM01 | (insn1 << 15) | insn2;
654 fx = fx->next;
655 break;
656 case 3: /* reverse sequential */
657 if (opcode2->unit == MU)
658 as_fatal ("MU instruction may not be in the right container");
659 insn = FM10 | (insn1 << 15) | insn2;
660 break;
661 default:
662 as_fatal("unknown execution type passed to write_2_short()");
663 }
664
665 /* printf("INSN: %08x\n",insn); */
666 f = frag_more(4);
667 number_to_chars_bigendian (f, insn, 4);
668
669 for (j=0; j<2; j++)
670 {
671 bfd_reloc_code_real_type reloc;
672 for (i=0; i < fx->fc; i++)
673 {
674 reloc = get_reloc((struct d10v_operand *)&d10v_operands[fx->fix[i].reloc]);
675 if (reloc)
676 {
677 if ( (reloc == BFD_RELOC_D10V_10_PCREL_R) && (j == 0) )
678 fx->fix[i].reloc |= 1024;
679
680 /*
681 printf("fix_new_exp: where:%x reloc:%d\n ",f - frag_now->fr_literal,fx->fix[i].reloc);
682 print_expr_1(stdout,&(fx->fix[i].exp));
683 printf("\n");
684 */
685 fix_new_exp (frag_now,
686 f - frag_now->fr_literal,
687 4,
688 &(fx->fix[i].exp),
689 1,
690 fx->fix[i].reloc);
691 }
692 }
693 fx->fc = 0;
694 fx = fx->next;
695 }
696
697 return (0);
698 }
699
700
701 /* This is the main entry point for the machine-dependent assembler. str points to a
702 machine-dependent instruction. This function is supposed to emit the frags/bytes
703 it assembles to. For the D10V, it mostly handles the special VLIW parsing and packing
704 and leaves the difficult stuff to do_assemble().
705 */
706
707 static unsigned long prev_insn;
708 static struct d10v_opcode *prev_opcode = 0;
709 static subsegT prev_subseg;
710 static segT prev_seg;
711
712 void
713 md_assemble (str)
714 char *str;
715 {
716 struct d10v_opcode *opcode;
717 unsigned long insn;
718 int extype=0; /* execution type; parallel, etc */
719 static int etype=0; /* saved extype. used for multiline instructions */
720 char *str2;
721
722 /* printf("md_assemble: str=%s\n",str); */
723
724 if (etype == 0)
725 {
726 /* look for the special multiple instruction separators */
727 str2 = strstr (str, "||");
728 if (str2)
729 extype = 1;
730 else
731 {
732 str2 = strstr (str, "->");
733 if (str2)
734 extype = 2;
735 else
736 {
737 str2 = strstr (str, "<-");
738 if (str2)
739 extype = 3;
740 }
741 }
742 /* str2 points to the separator, if one */
743 if (str2)
744 {
745 *str2 = 0;
746
747 /* if two instructions are present and we already have one saved
748 then first write it out */
749 if (prev_opcode)
750 write_1_short (prev_opcode, prev_insn, fixups->next);
751
752 /* assemble first instruction and save it */
753 prev_insn = do_assemble (str, &prev_opcode);
754 if (prev_insn == -1)
755 as_fatal ("can't find opcode ");
756 fixups = fixups->next;
757 str = str2 + 2;
758 }
759 }
760
761 insn = do_assemble (str, &opcode);
762 if (insn == -1)
763 {
764 if (extype)
765 {
766 etype = extype;
767 return;
768 }
769 as_fatal ("can't find opcode ");
770 }
771
772 if (etype)
773 {
774 extype = etype;
775 etype = 0;
776 }
777
778 /* if this is a long instruction, write it and any previous short instruction */
779 if (opcode->format & LONG_OPCODE)
780 {
781 if (extype)
782 as_fatal("Unable to mix instructions as specified");
783 if (prev_opcode)
784 {
785 write_1_short (prev_opcode, prev_insn, fixups->next);
786 prev_opcode = NULL;
787 }
788 write_long (opcode, insn, fixups);
789 prev_opcode = NULL;
790 return;
791 }
792
793 if (prev_opcode && (write_2_short (prev_opcode, prev_insn, opcode, insn, extype, fixups) == 0))
794 {
795 /* no instructions saved */
796 prev_opcode = NULL;
797 }
798 else
799 {
800 if (extype)
801 as_fatal("Unable to mix instructions as specified");
802 /* save off last instruction so it may be packed on next pass */
803 prev_opcode = opcode;
804 prev_insn = insn;
805 prev_seg = now_seg;
806 prev_subseg = now_subseg;
807 fixups = fixups->next;
808 }
809 }
810
811
812 /* do_assemble assembles a single instruction and returns an opcode */
813 /* it returns -1 (an invalid opcode) on error */
814
815 static unsigned long
816 do_assemble (str, opcode)
817 char *str;
818 struct d10v_opcode **opcode;
819 {
820 struct d10v_opcode *next_opcode;
821 unsigned char *op_start, *save;
822 unsigned char *op_end;
823 char name[20];
824 int nlen = 0, i, match, numops;
825 expressionS myops[6];
826 unsigned long insn;
827
828 /* printf("do_assemble: str=%s\n",str); */
829
830 /* Drop leading whitespace */
831 while (*str == ' ')
832 str++;
833
834 /* find the opcode end */
835 for (op_start = op_end = (unsigned char *) (str);
836 *op_end
837 && nlen < 20
838 && !is_end_of_line[*op_end] && *op_end != ' ';
839 op_end++)
840 {
841 name[nlen] = op_start[nlen];
842 nlen++;
843 }
844 name[nlen] = 0;
845
846 if (nlen == 0)
847 return (-1);
848
849 /* find the first opcode with the proper name */
850 *opcode = (struct d10v_opcode *)hash_find (d10v_hash, name);
851 if (*opcode == NULL)
852 as_fatal ("unknown opcode: %s",name);
853
854 save = input_line_pointer;
855 input_line_pointer = op_end;
856
857 /* get all the operands and save them as expressions */
858 numops = get_operands (myops);
859
860 /* now see if the operand is a fake. If so, find the correct size */
861 /* instruction, if possible */
862 match = 0;
863 if ((*opcode)->format == OPCODE_FAKE)
864 {
865 int opnum = (*opcode)->operands[0];
866 if (myops[opnum].X_op == O_constant)
867 {
868 next_opcode=(*opcode)+1;
869 for (i=0; (*opcode)->operands[i+1]; i++)
870 {
871 int bits = d10v_operands[next_opcode->operands[opnum]].bits;
872 int flags = d10v_operands[next_opcode->operands[opnum]].flags;
873 if (!check_range (myops[opnum].X_add_number, bits, flags))
874 {
875 match = 1;
876 break;
877 }
878 next_opcode++;
879 }
880 }
881 else
882 {
883 /* not a constant, so use a long instruction */
884 next_opcode = (*opcode)+2;
885 match = 1;
886 }
887 if (match)
888 *opcode = next_opcode;
889 else
890 as_fatal ("value out of range");
891 }
892 else
893 {
894 /* now search the opcode table table for one with operands */
895 /* that matches what we've got */
896 while (!match)
897 {
898 match = 1;
899 for (i = 0; (*opcode)->operands[i]; i++)
900 {
901 int flags = d10v_operands[(*opcode)->operands[i]].flags;
902 int X_op = myops[i].X_op;
903 int num = myops[i].X_add_number;
904
905 if (X_op==0)
906 {
907 match=0;
908 break;
909 }
910
911 if (flags & OPERAND_REG)
912 {
913 if ((X_op != O_register) ||
914 ((flags & OPERAND_ACC) != (num & OPERAND_ACC)) ||
915 ((flags & OPERAND_FLAG) != (num & OPERAND_FLAG)) ||
916 ((flags & OPERAND_CONTROL) != (num & OPERAND_CONTROL)))
917 {
918 match=0;
919 break;
920 }
921 }
922
923 if (((flags & OPERAND_MINUS) && ((X_op != O_absent) || (num != OPERAND_MINUS))) ||
924 ((flags & OPERAND_PLUS) && ((X_op != O_absent) || (num != OPERAND_PLUS))) ||
925 ((flags & OPERAND_ATMINUS) && ((X_op != O_absent) || (num != OPERAND_ATMINUS))) ||
926 ((flags & OPERAND_ATPAR) && ((X_op != O_absent) || (num != OPERAND_ATPAR))) ||
927 ((flags & OPERAND_ATSIGN) && ((X_op != O_absent) || (num != OPERAND_ATSIGN))))
928 {
929 match=0;
930 break;
931 }
932
933 }
934
935 /* we're only done if the operands matched AND there
936 are no more to check */
937 if (match && myops[i].X_op==0)
938 break;
939
940 next_opcode = (*opcode)+1;
941 if (next_opcode->opcode == 0)
942 break;
943 if (strcmp(next_opcode->name, (*opcode)->name))
944 break;
945 (*opcode) = next_opcode;
946 }
947 }
948
949 if (!match)
950 {
951 as_bad ("bad opcode or operands");
952 return (0);
953 }
954
955 /* Check that all registers that are required to be even are. */
956 /* Also, if any operands were marked as registers, but were really symbols */
957 /* fix that here. */
958 for (i=0; (*opcode)->operands[i]; i++)
959 {
960 if ((d10v_operands[(*opcode)->operands[i]].flags & OPERAND_EVEN) &&
961 (myops[i].X_add_number & 1))
962 as_fatal("Register number must be EVEN");
963 if (myops[i].X_op == O_register)
964 {
965 if (!(d10v_operands[(*opcode)->operands[i]].flags & OPERAND_REG))
966 {
967 myops[i].X_op = O_symbol;
968 myops[i].X_add_symbol = symbol_find_or_make ((char *)myops[i].X_op_symbol);
969 myops[i].X_add_number = 0;
970 myops[i].X_op_symbol = NULL;
971 }
972 }
973 }
974
975 input_line_pointer = save;
976
977 /* at this point, we have "opcode" pointing to the opcode entry in the
978 d10v opcode table, with myops filled out with the operands. */
979 insn = build_insn ((*opcode), myops, 0);
980 /* printf("sub-insn = %lx\n",insn); */
981
982 return (insn);
983 }
984
985
986 /* if while processing a fixup, a reloc really needs to be created */
987 /* then it is done here */
988
989 arelent *
990 tc_gen_reloc (seg, fixp)
991 asection *seg;
992 fixS *fixp;
993 {
994 arelent *reloc;
995 reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
996 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
997 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
998 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
999 if (reloc->howto == (reloc_howto_type *) NULL)
1000 {
1001 as_bad_where (fixp->fx_file, fixp->fx_line,
1002 "reloc %d not supported by object file format", (int)fixp->fx_r_type);
1003 return NULL;
1004 }
1005 reloc->addend = fixp->fx_addnumber;
1006 /* printf("tc_gen_reloc: addr=%x addend=%x\n", reloc->address, reloc->addend); */
1007 return reloc;
1008 }
1009
1010 int
1011 md_estimate_size_before_relax (fragp, seg)
1012 fragS *fragp;
1013 asection *seg;
1014 {
1015 abort ();
1016 return 0;
1017 }
1018
1019 long
1020 md_pcrel_from_section (fixp, sec)
1021 fixS *fixp;
1022 segT sec;
1023 {
1024 return 0;
1025 /* return fixp->fx_frag->fr_address + fixp->fx_where; */
1026 }
1027
1028 int
1029 md_apply_fix3 (fixp, valuep, seg)
1030 fixS *fixp;
1031 valueT *valuep;
1032 segT seg;
1033 {
1034 char *where;
1035 unsigned long insn;
1036 long value;
1037 int op_type;
1038 int left=0;
1039
1040 if (fixp->fx_addsy == (symbolS *) NULL)
1041 {
1042 value = *valuep;
1043 fixp->fx_done = 1;
1044 }
1045 else if (fixp->fx_pcrel)
1046 value = *valuep;
1047 else
1048 {
1049 value = fixp->fx_offset;
1050 if (fixp->fx_subsy != (symbolS *) NULL)
1051 {
1052 if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
1053 value -= S_GET_VALUE (fixp->fx_subsy);
1054 else
1055 {
1056 /* We don't actually support subtracting a symbol. */
1057 as_bad_where (fixp->fx_file, fixp->fx_line,
1058 "expression too complex");
1059 }
1060 }
1061 }
1062
1063 /* printf("md_apply_fix: value=0x%x type=%d\n", value, fixp->fx_r_type); */
1064
1065 op_type = fixp->fx_r_type;
1066 if (op_type & 1024)
1067 {
1068 op_type -= 1024;
1069 fixp->fx_r_type = BFD_RELOC_D10V_10_PCREL_L;
1070 left = 1;
1071 }
1072 else
1073 fixp->fx_r_type = get_reloc((struct d10v_operand *)&d10v_operands[op_type]);
1074
1075 /* Fetch the instruction, insert the fully resolved operand
1076 value, and stuff the instruction back again. */
1077 where = fixp->fx_frag->fr_literal + fixp->fx_where;
1078 insn = bfd_getb32 ((unsigned char *) where);
1079
1080 switch (fixp->fx_r_type)
1081 {
1082 case BFD_RELOC_D10V_10_PCREL_L:
1083 case BFD_RELOC_D10V_10_PCREL_R:
1084 case BFD_RELOC_D10V_18_PCREL:
1085 /* instruction addresses are always right-shifted by 2
1086 and pc-relative */
1087 if (!fixp->fx_pcrel)
1088 value -= fixp->fx_where;
1089 value >>= 2;
1090 default:
1091 break;
1092 }
1093 /* printf(" insn=%x value=%x where=%x pcrel=%x\n",insn,value,fixp->fx_where,fixp->fx_pcrel); */
1094
1095 insn = d10v_insert_operand (insn, op_type, (offsetT)value, left);
1096
1097 /* printf(" new insn=%x\n",insn); */
1098
1099 bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1100
1101 if (fixp->fx_done)
1102 return 1;
1103
1104 fixp->fx_addnumber = value;
1105 return 1;
1106 }
1107
1108
1109 /* d10v_cleanup() is called after the assembler has finished parsing the input
1110 file or after a label is defined. Because the D10V assembler sometimes saves short
1111 instructions to see if it can package them with the next instruction, there may
1112 be a short instruction that still needs written. */
1113 int
1114 d10v_cleanup (done)
1115 int done;
1116 {
1117 segT seg;
1118 subsegT subseg;
1119
1120 if ( prev_opcode && (done || (now_seg == prev_seg) && (now_subseg == prev_subseg)))
1121 {
1122 seg = now_seg;
1123 subseg = now_subseg;
1124 subseg_set (prev_seg, prev_subseg);
1125 write_1_short (prev_opcode, prev_insn, fixups);
1126 subseg_set (seg, subseg);
1127 prev_opcode = NULL;
1128 }
1129 return 1;
1130 }
This page took 0.061782 seconds and 4 git commands to generate.