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