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