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