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