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