Support for new relocations added. Support for SDA/TDA/ZDA sections added.
[external/binutils.git] / gas / config / tc-v850.c
1 /* tc-v850.c -- Assembler code for the NEC V850
2    Copyright (C) 1996, 1997 Free Software Foundation.
3
4    This file is part of GAS, the GNU Assembler.
5
6    GAS is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2, or (at your option)
9    any later version.
10
11    GAS is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with GAS; see the file COPYING.  If not, write to
18    the Free Software Foundation, 59 Temple Place - Suite 330,
19    Boston, MA 02111-1307, USA.  */
20
21 #include <stdio.h>
22 #include <ctype.h>
23 #include "as.h"
24 #include "subsegs.h"     
25 #include "opcode/v850.h"
26
27 /* sign-extend a 16-bit number */
28 #define SEXT16(x)       ((((x) & 0xffff) ^ (~ 0x7fff)) + 0x8000)
29
30 /* Temporarily holds the reloc in a cons expression.  */
31 static bfd_reloc_code_real_type hold_cons_reloc;
32 \f
33 /* Structure to hold information about predefined registers.  */
34 struct reg_name
35 {
36   const char *name;
37   int value;
38 };
39
40 /* Generic assembler global variables which must be defined by all targets. */
41
42 /* Characters which always start a comment. */
43 const char comment_chars[] = "#";
44
45 /* Characters which start a comment at the beginning of a line.  */
46 const char line_comment_chars[] = ";#";
47
48 /* Characters which may be used to separate multiple commands on a 
49    single line.  */
50 const char line_separator_chars[] = ";";
51
52 /* Characters which are used to indicate an exponent in a floating 
53    point number.  */
54 const char EXP_CHARS[] = "eE";
55
56 /* Characters which mean that a number is a floating point constant, 
57    as in 0d1.0.  */
58 const char FLT_CHARS[] = "dD";
59 \f
60
61 const relax_typeS md_relax_table[] = {
62   {0xff, -0x100, 2, 1},
63   {0x1fffff, -0x200000, 6, 0},
64 };
65
66
67 static segT sdata_section = NULL;
68 static segT tdata_section = NULL;
69 static segT zdata_section = NULL;
70 static segT sbss_section = NULL;
71 static segT tbss_section = NULL;
72 static segT zbss_section = NULL;
73 static segT rosdata_section = NULL;
74 static segT rozdata_section = NULL;
75
76
77 /* local functions */
78 static unsigned long v850_insert_operand
79   PARAMS ((unsigned long insn, const struct v850_operand *operand,
80            offsetT val, char *file, unsigned int line));
81
82
83 /* fixups */
84 #define MAX_INSN_FIXUPS (5)
85 struct v850_fixup
86 {
87   expressionS              exp;
88   int                      opindex;
89   bfd_reloc_code_real_type reloc;
90 };
91 struct v850_fixup fixups[MAX_INSN_FIXUPS];
92 static int fc;
93 \f
94 void
95 v850_sdata (int ignore)
96 {
97   subseg_set (sdata_section, (subsegT) get_absolute_expression ());
98   
99   demand_empty_rest_of_line ();
100 }
101
102 void
103 v850_tdata (int ignore)
104 {
105   subseg_set (tdata_section, (subsegT) get_absolute_expression ());
106   
107   demand_empty_rest_of_line ();
108 }
109
110 void
111 v850_zdata (int ignore)
112 {
113   subseg_set (zdata_section, (subsegT) get_absolute_expression ());
114   
115   demand_empty_rest_of_line ();
116 }
117
118 void
119 v850_sbss (int ignore)
120 {
121   subseg_set (sbss_section, (subsegT) get_absolute_expression ());
122   
123   demand_empty_rest_of_line ();
124 }
125
126 void
127 v850_tbss (int ignore)
128 {
129   subseg_set (tbss_section, (subsegT) get_absolute_expression ());
130   
131   demand_empty_rest_of_line ();
132 }
133
134 void
135 v850_zbss (int ignore)
136 {
137   subseg_set (zbss_section, (subsegT) get_absolute_expression ());
138   
139   demand_empty_rest_of_line ();
140 }
141
142 void
143 v850_rosdata (int ignore)
144 {
145   subseg_set (rosdata_section, (subsegT) get_absolute_expression ());
146   
147   demand_empty_rest_of_line ();
148 }
149
150 void
151 v850_rozdata (int ignore)
152 {
153   subseg_set (rozdata_section, (subsegT) get_absolute_expression ());
154   
155   demand_empty_rest_of_line ();
156 }
157
158 static void
159 v850_section (int arg)
160 {
161   char   saved_c;
162   char * ptr;
163   
164   for (ptr = input_line_pointer; * ptr != '\n' && * ptr != 0; ptr ++)
165     if (* ptr == ',' && ptr[1] == '.')
166       break;
167
168   saved_c = * ptr;
169   * ptr = ';';
170   
171   obj_elf_section (arg);
172
173   * ptr = saved_c;
174 }
175
176 void
177 v850_bss (int ignore)
178 {
179   register int temp = get_absolute_expression ();
180
181   obj_elf_section_change_hook();
182   
183   subseg_set (bss_section, (subsegT) temp);
184   
185   demand_empty_rest_of_line ();
186 }
187
188 void
189 v850_offset (int ignore)
190 {
191   int temp = get_absolute_expression ();
192   
193   temp -= frag_now_fix();
194   
195   if (temp > 0)
196     (void) frag_more (temp);
197   
198   demand_empty_rest_of_line ();
199 }
200
201 /* The target specific pseudo-ops which we support.  */
202 const pseudo_typeS md_pseudo_table[] =
203 {
204   {"sdata",   v850_sdata,   0},
205   {"tdata",   v850_tdata,   0},
206   {"zdata",   v850_zdata,   0},
207   {"sbss",    v850_sbss,    0},
208   {"tbss",    v850_tbss,    0},
209   {"zbss",    v850_zbss,    0},
210   {"rosdata", v850_rosdata, 0},
211   {"rozdata", v850_rozdata, 0},
212   {"bss",     v850_bss,     0},
213   {"offset",  v850_offset,  0},
214   {"section", v850_section, 0},
215   {"word",    cons,         4},
216   { NULL,     NULL,         0}
217 };
218
219 /* Opcode hash table.  */
220 static struct hash_control *v850_hash;
221
222 /* This table is sorted. Suitable for searching by a binary search. */
223 static const struct reg_name pre_defined_registers[] =
224 {
225   { "ep",  30 },                /* ep - element ptr */
226   { "gp",   4 },                /* gp - global ptr */
227   { "hp",   2 },                /* hp - handler stack ptr */
228   { "lp",  31 },                /* lp - link ptr */
229   { "r0",   0 },
230   { "r1",   1 },
231   { "r10", 10 },
232   { "r11", 11 },
233   { "r12", 12 },
234   { "r13", 13 },
235   { "r14", 14 },
236   { "r15", 15 },
237   { "r16", 16 },
238   { "r17", 17 },
239   { "r18", 18 },
240   { "r19", 19 },
241   { "r2",   2 },
242   { "r20", 20 },
243   { "r21", 21 },
244   { "r22", 22 },
245   { "r23", 23 },
246   { "r24", 24 },
247   { "r25", 25 },
248   { "r26", 26 },
249   { "r27", 27 },
250   { "r28", 28 },
251   { "r29", 29 },
252   { "r3",   3 },
253   { "r30", 30 },
254   { "r31", 31 },
255   { "r4",   4 },
256   { "r5",   5 },
257   { "r6",   6 },
258   { "r7",   7 },
259   { "r8",   8 },
260   { "r9",   9 },
261   { "sp",   3 },                /* sp - stack ptr */
262   { "tp",   5 },                /* tp - text ptr */
263   { "zero", 0 },
264 };
265 #define REG_NAME_CNT    (sizeof (pre_defined_registers) / sizeof (struct reg_name))
266
267
268 static const struct reg_name system_registers[] = 
269 {
270 /* start-sanitize-v850e */
271   { "ctbp",  20 },
272   { "ctpc",  16 },
273   { "ctpsw", 17 },
274   { "dbpc",  18 },
275   { "dbpsw", 19 },
276 /* end-sanitize-v850e */
277   { "ecr",    4 },
278   { "eipc",   0 },
279   { "eipsw",  1 },
280   { "fepc",   2 },
281   { "fepsw",  3 },
282   { "psw",    5 },
283 };
284 #define SYSREG_NAME_CNT (sizeof (system_registers) / sizeof (struct reg_name))
285
286 static const struct reg_name cc_names[] =
287 {
288   { "c",  0x1 },
289   { "e",  0x2 },
290   { "ge", 0xe },
291   { "gt", 0xf },
292   { "h",  0xb },
293   { "l",  0x1 },
294   { "le", 0x7 },
295   { "lt", 0x6 },
296   { "n",  0x4 },
297   { "nc", 0x9 },
298   { "ne", 0xa },
299   { "nh", 0x3 },
300   { "nl", 0x9 },
301   { "ns", 0xc },
302   { "nv", 0x8 },
303   { "nz", 0xa },
304   { "p",  0xc },
305   { "s",  0x4 },
306   { "sa", 0xd },
307   { "t",  0x5 },
308   { "v",  0x0 },
309   { "z",  0x2 },
310 };
311 #define CC_NAME_CNT     (sizeof(cc_names) / sizeof(struct reg_name))
312
313 /* reg_name_search does a binary search of the given register table
314    to see if "name" is a valid regiter name.  Returns the register
315    number from the array on success, or -1 on failure. */
316
317 static int
318 reg_name_search (regs, regcount, name)
319      const struct reg_name * regs;
320      int                     regcount;
321      const char *            name;
322 {
323   int middle, low, high;
324   int cmp;
325
326   low = 0;
327   high = regcount - 1;
328
329   do
330     {
331       middle = (low + high) / 2;
332       cmp = strcasecmp (name, regs[middle].name);
333       if (cmp < 0)
334         high = middle - 1;
335       else if (cmp > 0)
336         low = middle + 1;
337       else
338         return regs[middle].value;
339     }
340   while (low <= high);
341   return -1;
342 }
343
344
345 /* Summary of register_name().
346  *
347  * in: Input_line_pointer points to 1st char of operand.
348  *
349  * out: A expressionS.
350  *      The operand may have been a register: in this case, X_op == O_register,
351  *      X_add_number is set to the register number, and truth is returned.
352  *      Input_line_pointer->(next non-blank) char after operand, or is in
353  *      its original state.
354  */
355 static boolean
356 register_name (expressionP)
357      expressionS * expressionP;
358 {
359   int    reg_number;
360   char * name;
361   char * start;
362   char   c;
363
364   /* Find the spelling of the operand */
365   start = name = input_line_pointer;
366
367   c = get_symbol_end ();
368
369   reg_number = reg_name_search (pre_defined_registers, REG_NAME_CNT, name);
370
371   * input_line_pointer = c;     /* put back the delimiting char */
372   
373   /* look to see if it's in the register table */
374   if (reg_number >= 0) 
375     {
376       expressionP->X_op         = O_register;
377       expressionP->X_add_number = reg_number;
378
379       /* make the rest nice */
380       expressionP->X_add_symbol = NULL;
381       expressionP->X_op_symbol  = NULL;
382       
383       return true;
384     }
385   else
386     {
387       /* reset the line as if we had not done anything */
388       input_line_pointer = start;
389       
390       return false;
391     }
392 }
393
394 /* Summary of system_register_name().
395  *
396  * in: Input_line_pointer points to 1st char of operand.
397  *
398  * out: A expressionS.
399  *      The operand may have been a register: in this case, X_op == O_register,
400  *      X_add_number is set to the register number, and truth is returned.
401  *      Input_line_pointer->(next non-blank) char after operand, or is in
402  *      its original state.
403  */
404 static boolean
405 system_register_name (expressionP, accept_numbers)
406      expressionS * expressionP;
407      boolean       accept_numbers;
408 {
409   int    reg_number;
410   char * name;
411   char * start;
412   char   c;
413
414   /* Find the spelling of the operand */
415   start = name = input_line_pointer;
416
417   c = get_symbol_end ();
418   reg_number = reg_name_search (system_registers, SYSREG_NAME_CNT, name);
419
420   * input_line_pointer = c;   /* put back the delimiting char */
421   
422   if (reg_number < 0
423       && accept_numbers)
424     {
425       input_line_pointer   = start; /* reset input_line pointer */
426
427       if (isdigit (* input_line_pointer))
428         reg_number = strtol (input_line_pointer, & input_line_pointer, 10);
429
430       /* Make sure that the register number is allowable. */
431       if (   reg_number < 0
432           || reg_number > 5
433 /* start-sanitize-v850e */
434           && reg_number < 16
435           || reg_number > 20
436 /* end-sanitize-v850e */
437              )
438         {
439           reg_number = -1;
440         }
441     }
442       
443   /* look to see if it's in the register table */
444   if (reg_number >= 0) 
445     {
446       expressionP->X_op         = O_register;
447       expressionP->X_add_number = reg_number;
448
449       /* make the rest nice */
450       expressionP->X_add_symbol = NULL;
451       expressionP->X_op_symbol  = NULL;
452
453       return true;
454     }
455   else
456     {
457       /* reset the line as if we had not done anything */
458       input_line_pointer = start;
459       
460       return false;
461     }
462 }
463
464 /* Summary of cc_name().
465  *
466  * in: Input_line_pointer points to 1st char of operand.
467  *
468  * out: A expressionS.
469  *      The operand may have been a register: in this case, X_op == O_register,
470  *      X_add_number is set to the register number, and truth is returned.
471  *      Input_line_pointer->(next non-blank) char after operand, or is in
472  *      its original state.
473  */
474 static boolean
475 cc_name (expressionP)
476      expressionS *expressionP;
477 {
478   int    reg_number;
479   char * name;
480   char * start;
481   char   c;
482
483   /* Find the spelling of the operand */
484   start = name = input_line_pointer;
485
486   c = get_symbol_end ();
487   reg_number = reg_name_search (cc_names, CC_NAME_CNT, name);
488
489   * input_line_pointer = c;   /* put back the delimiting char */
490   
491   /* look to see if it's in the register table */
492   if (reg_number >= 0) 
493     {
494       expressionP->X_op         = O_constant;
495       expressionP->X_add_number = reg_number;
496
497       /* make the rest nice */
498       expressionP->X_add_symbol = NULL;
499       expressionP->X_op_symbol  = NULL;
500
501       return true;
502     }
503   else
504     {
505       /* reset the line as if we had not done anything */
506       input_line_pointer = start;
507       
508       return false;
509     }
510 }
511
512 static void
513 skip_white_space (void)
514 {
515   while (   * input_line_pointer == ' '
516          || * input_line_pointer == '\t')
517     ++ input_line_pointer;
518 }
519
520 /* start-sanitize-v850e */
521 /* Summary of parse_register_list ().
522  *
523  * in: Input_line_pointer  points to 1st char of a list of registers.
524  *     insn                is the partially constructed instruction.
525  *     operand             is the operand being inserted.
526  *
527  * out: True if the parse completed successfully, False otherwise.
528  *      If the parse completes the correct bit fields in the
529  *      instruction will be filled in.
530  *
531  * Parses register lists with the syntax:
532  *
533  *   { rX }
534  *   { rX, rY }
535  *   { rX - rY }
536  *   { rX - rY, rZ }
537  *   etc
538  *
539  * and also parses constant epxressions whoes bits indicate the
540  * registers in the lists.  The LSB in the expression refers to
541  * the lowest numbered permissable register in the register list,
542  * and so on upwards.  System registers are considered to be very
543  * high numbers.
544  * 
545  */
546 static char *
547 parse_register_list
548 (
549   unsigned long *             insn,
550   const struct v850_operand * operand
551 )
552 {
553   static int  type1_regs[ 32 ] = { 30,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24 };
554 /* start-sanitize-v850eq */
555   static int  type2_regs[ 32 ] = { 19, 18, 17, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24 };
556   static int  type3_regs[ 32 ] = {  3,  2,  1,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 15, 13, 12,  7,  6,  5,  4, 11, 10,  9,  8 };
557 /* end-sanitize-v850eq */
558   int *       regs;
559   expressionS exp;
560
561
562   /* Select a register array to parse. */
563   switch (operand->shift)
564     {
565     case 0xffe00001: regs = type1_regs; break;
566 /* start-sanitize-v850eq */
567     case 0xfff8000f: regs = type2_regs; break;
568     case 0xfff8001f: regs = type3_regs; break;
569 /* end-sanitize-v850eq */
570     default:
571       as_bad ("unknown operand shift: %x\n", operand->shift );              
572       return "internal failure in parse_register_list";
573     }
574
575   skip_white_space();
576
577   /* If the expression starts with a curly brace it is a register list.
578      Otherwise it is a constant expression ,whoes bits indicate which
579      registers are to be included in the list.  */
580   
581   if (* input_line_pointer != '{')
582     {
583       int bits;
584       int reg;
585       int i;
586                 
587       expression (& exp);
588       
589       if (exp.X_op != O_constant)
590         return "constant expression or register list expected";
591
592 /* start-sanitize-v850eq */
593       if (regs == type1_regs)
594 /* end-sanitize-v850eq */
595         {
596           if (exp.X_add_number & 0xFFFFF000)
597             return "high bits set in register list expression";
598           
599           for (reg = 20; reg < 32; reg ++)
600             if (exp.X_add_number & (1 << (reg - 20)))
601               {
602                 for (i = 0; i < 32; i++)
603                   if (regs[i] == reg)
604                     * insn |= (1 << i);
605               }
606         }
607 /* start-sanitize-v850eq */
608       else if (regs == type2_regs)
609         {
610           if (exp.X_add_number & 0xFFFE0000)
611             return "high bits set in register list expression";
612           
613           for (reg = 1; reg < 16; reg ++)
614             if (exp.X_add_number & (1 << (reg - 1)))
615               {
616                 for (i = 0; i < 32; i++)
617                   if (regs[i] == reg)
618                     * insn |= (1 << i);
619               }
620
621           if (exp.X_add_number & (1 << 15))
622             * insn |= (1 << 3);
623           
624           if (exp.X_add_number & (1 << 16))
625             * insn |= (1 << 19);
626         }
627       else /* regs == type3_regs */
628         {
629           if (exp.X_add_number & 0xFFFE0000)
630             return "high bits set in register list expression";
631           
632           for (reg = 16; reg < 32; reg ++)
633             if (exp.X_add_number & (1 << (reg - 16)))
634               {
635                 for (i = 0; i < 32; i++)
636                   if (regs[i] == reg)
637                     * insn |= (1 << i);
638               }
639
640           if (exp.X_add_number & (1 << 16))
641             * insn |= (1 << 19);
642         }
643 /* end-sanitize-v850eq */
644
645       return NULL;
646     }
647
648   input_line_pointer ++;
649
650   /* Parse the register list until a terminator (closing curly brace or new-line) is found.  */
651   for (;;)
652     {
653       if (register_name (& exp))
654         {
655           int  i;
656           
657           /* Locate the given register in the list, and if it is there, insert the corresponding bit into the instruction.  */
658           for (i = 0; i < 32; i++)
659             {
660               if (regs[ i ] == exp.X_add_number)
661                 {
662                   * insn |= (1 << i);
663                   break;
664                 }
665             }
666
667           if (i == 32)
668             {
669               return "illegal register included in list";
670             }
671         }
672       else if (system_register_name (& exp, true))
673         {
674           if (regs == type1_regs)
675             {
676               return "system registers cannot be included in list";
677             }
678           else if (exp.X_add_number == 5)
679             {
680               if (regs == type2_regs)
681                 return "PSW cannot be included in list";
682               else
683                 * insn |= 0x8;
684             }
685           else
686             * insn |= 0x80000;
687         }
688       else if (* input_line_pointer == '}')
689         {
690           input_line_pointer ++;
691           break;
692         }
693       else if (* input_line_pointer == ',')
694         {
695           input_line_pointer ++;
696           continue;
697         }
698       else if (* input_line_pointer == '-')
699         {
700           /* We have encountered a range of registers: rX - rY */
701           int         j;
702           expressionS exp2;
703
704           /* Skip the dash.  */
705           ++ input_line_pointer;
706
707           /* Get the second register in the range.  */
708           if (! register_name (& exp2))
709             {
710               return "second register should follow dash in register list";
711               exp2.X_add_number = exp.X_add_number;
712             }
713
714           /* Add the rest of the registers in the range.  */
715           for (j = exp.X_add_number + 1; j <= exp2.X_add_number; j++)
716             {
717               int  i;
718           
719               /* Locate the given register in the list, and if it is there, insert the corresponding bit into the instruction.  */
720               for (i = 0; i < 32; i++)
721                 {
722                   if (regs[ i ] == j)
723                     {
724                       * insn |= (1 << i);
725                       break;
726                     }
727                 }
728
729               if (i == 32)
730                 {
731                   return "illegal register included in list";
732                 }
733             }
734         }
735       else
736         {
737           break;
738         }
739
740       skip_white_space();
741     }
742
743   return NULL;
744 }
745 /* end-sanitize-v850e */
746
747 CONST char * md_shortopts = "m:";
748
749 struct option md_longopts[] =
750 {
751   {NULL, no_argument, NULL, 0}
752 };
753 size_t md_longopts_size = sizeof md_longopts; 
754
755
756 void
757 md_show_usage (stream)
758   FILE *stream;
759 {
760   fprintf (stream, "V850 options:\n");
761   fprintf (stream, "\tnone at present\n");
762
763
764 int
765 md_parse_option (c, arg)
766      int    c;
767      char * arg;
768 {
769   return 0;
770 }
771
772 symbolS *
773 md_undefined_symbol (name)
774   char * name;
775 {
776   return 0;
777 }
778
779 char *
780 md_atof (type, litp, sizep)
781   int    type;
782   char * litp;
783   int *  sizep;
784 {
785   int            prec;
786   LITTLENUM_TYPE words[4];
787   char *         t;
788   int            i;
789
790   switch (type)
791     {
792     case 'f':
793       prec = 2;
794       break;
795
796     case 'd':
797       prec = 4;
798       break;
799
800     default:
801       *sizep = 0;
802       return "bad call to md_atof";
803     }
804   
805   t = atof_ieee (input_line_pointer, type, words);
806   if (t)
807     input_line_pointer = t;
808
809   *sizep = prec * 2;
810
811   for (i = prec - 1; i >= 0; i--)
812     {
813       md_number_to_chars (litp, (valueT) words[i], 2);
814       litp += 2;
815     }
816
817   return NULL;
818 }
819
820
821 /* Very gross.  */
822 void
823 md_convert_frag (abfd, sec, fragP)
824   bfd *      abfd;
825   asection * sec;
826   fragS *    fragP;
827 {
828   subseg_change (sec, 0);
829   if (fragP->fr_subtype == 0)
830     {
831       fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
832                fragP->fr_offset, 1, BFD_RELOC_UNUSED + (int)fragP->fr_opcode);
833       fragP->fr_var = 0;
834       fragP->fr_fix += 2;
835     }
836   else if (fragP->fr_subtype == 1)
837     {
838       /* Reverse the condition of the first branch.  */
839       fragP->fr_literal[0] &= 0xf7;
840       /* Mask off all the displacement bits.  */
841       fragP->fr_literal[0] &= 0x8f;
842       fragP->fr_literal[1] &= 0x07;
843       /* Now set the displacement bits so that we branch
844          around the unconditional branch.  */
845       fragP->fr_literal[0] |= 0x30;
846
847       /* Now create the unconditional branch + fixup to the final
848          target.  */
849       md_number_to_chars (&fragP->fr_literal[2], 0x00000780, 4);
850       fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
851                fragP->fr_offset, 1, BFD_RELOC_UNUSED + (int)fragP->fr_opcode + 1);
852       fragP->fr_var = 0;
853       fragP->fr_fix += 6;
854     }
855   else
856     abort ();
857 }
858
859 valueT
860 md_section_align (seg, addr)
861      asection * seg;
862      valueT     addr;
863 {
864   int align = bfd_get_section_alignment (stdoutput, seg);
865   return ((addr + (1 << align) - 1) & (-1 << align));
866 }
867
868 void
869 md_begin ()
870 {
871   char *                              prev_name = "";
872   register const struct v850_opcode * op;
873   flagword                            applicable;
874
875   
876   v850_hash = hash_new();
877
878   /* Insert unique names into hash table.  The V850 instruction set
879      has many identical opcode names that have different opcodes based
880      on the operands.  This hash table then provides a quick index to
881      the first opcode with a particular name in the opcode table.  */
882
883   op = v850_opcodes;
884   while (op->name)
885     {
886       if (strcmp (prev_name, op->name)) 
887         {
888           prev_name = (char *) op->name;
889           hash_insert (v850_hash, op->name, (char *) op);
890         }
891       op++;
892     }
893   
894   bfd_set_arch_mach (stdoutput, TARGET_ARCH, 0);
895   /* start-sanitize-v850e */
896   bfd_set_arch_mach (stdoutput, TARGET_ARCH, bfd_mach_v850e);
897   /* end-sanitize-v850e */
898   /* start-sanitize-v850eq */
899   bfd_set_arch_mach (stdoutput, TARGET_ARCH, bfd_mach_v850eq);
900   /* end-sanitize-v850eq */
901
902   applicable = bfd_applicable_section_flags (stdoutput);
903
904   sdata_section = subseg_new (".sdata", 0);
905   bfd_set_section_flags (stdoutput, sdata_section, applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS));
906   
907   tdata_section = subseg_new (".tdata", 0);
908   bfd_set_section_flags (stdoutput, tdata_section, applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS));
909   
910   zdata_section = subseg_new (".zdata", 0);
911   bfd_set_section_flags (stdoutput, zdata_section, applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS));
912   
913   sbss_section = subseg_new (".sbss", 0);
914   bfd_set_section_flags (stdoutput, sbss_section, applicable & SEC_ALLOC);
915   
916   tbss_section = subseg_new (".tbss", 0);
917   bfd_set_section_flags (stdoutput, tbss_section, applicable & SEC_ALLOC);
918   
919   zbss_section = subseg_new (".zbss", 0);
920   bfd_set_section_flags (stdoutput, zbss_section, applicable & SEC_ALLOC);
921   
922   rosdata_section = subseg_new (".rosdata", 0);
923   bfd_set_section_flags (stdoutput, rosdata_section, applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY));
924                          
925   rozdata_section = subseg_new (".rozdata", 0);
926   bfd_set_section_flags (stdoutput, rozdata_section, applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY));
927 }
928
929
930 /* Warning: The code in this function relies upon the definitions
931    in the v850_operands[] array (defined in opcodes/v850-opc.c)
932    matching the hard coded values conatined herein.  */
933
934 static bfd_reloc_code_real_type
935 v850_reloc_prefix (const struct v850_operand * operand)
936 {
937   boolean paren_skipped = false;
938
939
940   /* Skip leading opening parenthesis.  */
941   if (* input_line_pointer == '(')
942     {
943       ++ input_line_pointer;
944       paren_skipped = true;
945     }
946   
947   if (strncmp (input_line_pointer, "hi0(", 4) == 0)
948     {
949       input_line_pointer += 3;
950       return BFD_RELOC_HI16;
951     }
952   if (strncmp (input_line_pointer, "hi(", 3) == 0)
953     {
954       input_line_pointer += 2;
955       return BFD_RELOC_HI16_S;
956     }
957   if (strncmp (input_line_pointer, "lo(", 3) == 0)
958     {
959       input_line_pointer += 2;
960       return BFD_RELOC_LO16;
961     }
962
963   if (strncmp (input_line_pointer, "sdaoff(", 7) == 0)
964     {
965       input_line_pointer += 6;
966       
967       if (operand == NULL)                             return BFD_RELOC_V850_SDA_16_16_OFFSET;
968       if (operand->bits == 15 && operand->shift == 17) return BFD_RELOC_V850_SDA_15_16_OFFSET;
969       /* start-sanitize-v850e */
970       if (operand->bits == -1)                         return BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET;
971       /* end-sanitize-v850e */
972       
973       assert (operand->bits == 16);
974       assert (operand->shift == 16);
975       
976       return BFD_RELOC_V850_SDA_16_16_OFFSET;
977     }
978       
979   if (strncmp (input_line_pointer, "zdaoff(", 7) == 0)
980     {
981       input_line_pointer += 6;
982       
983       if (operand == NULL)                             return BFD_RELOC_V850_ZDA_16_16_OFFSET;
984       if (operand->bits == 15 && operand->shift == 17) return BFD_RELOC_V850_ZDA_15_16_OFFSET;
985       /* start-sanitize-v850e */
986       if (operand->bits == -1)                         return BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET;
987       /* end-sanitize-v850e */
988       
989       assert (operand->bits == 16);
990       assert (operand->shift == 16);
991       
992       return BFD_RELOC_V850_ZDA_16_16_OFFSET;
993     }
994   
995   if (strncmp (input_line_pointer, "tdaoff(", 7) == 0)
996     {
997       input_line_pointer += 6;
998       
999       if (operand == NULL)                               return BFD_RELOC_V850_TDA_7_7_OFFSET;
1000       if (operand->bits == 6 && operand->shift == 1)     return BFD_RELOC_V850_TDA_6_8_OFFSET;
1001       /* start-sanitize-v850e */
1002       if (operand->bits == 4 && operand->insert != NULL) return BFD_RELOC_V850_TDA_4_5_OFFSET;
1003       if (operand->bits == 4 && operand->insert == NULL) return BFD_RELOC_V850_TDA_4_4_OFFSET;
1004       /* end-sanitize-v850e */
1005       
1006       assert (operand->bits == 7);
1007       
1008       return  operand->insert != NULL ? BFD_RELOC_V850_TDA_7_8_OFFSET :  BFD_RELOC_V850_TDA_7_7_OFFSET;
1009     }
1010
1011   if (paren_skipped)
1012     /* Restore skipped character.  */
1013     -- input_line_pointer;
1014   
1015   return BFD_RELOC_UNUSED;
1016 }
1017
1018 void
1019 md_assemble (str) 
1020      char * str;
1021 {
1022   char *                    s;
1023   char *                    start_of_operands;
1024   struct v850_opcode *      opcode;
1025   struct v850_opcode *      next_opcode;
1026   const unsigned char *     opindex_ptr;
1027   int                       next_opindex;
1028   int                       relaxable;
1029   unsigned long             insn;
1030   unsigned long             insn_size;
1031   char *                    f;
1032   int                       i;
1033   int                       match;
1034   boolean                   extra_data_after_insn = false;
1035   unsigned                  extra_data_len;
1036   unsigned long             extra_data;
1037   char *                    saved_input_line_pointer;
1038   
1039   /* Get the opcode.  */
1040   for (s = str; *s != '\0' && ! isspace (*s); s++)
1041     continue;
1042   
1043   if (*s != '\0')
1044     *s++ = '\0';
1045
1046   /* find the first opcode with the proper name */
1047   opcode = (struct v850_opcode *)hash_find (v850_hash, str);
1048   if (opcode == NULL)
1049     {
1050       as_bad ("Unrecognized opcode: `%s'", str);
1051       ignore_rest_of_line ();
1052       return;
1053     }
1054
1055   str = s;
1056   while (isspace (* str))
1057     ++ str;
1058
1059   start_of_operands = str;
1060
1061   saved_input_line_pointer = input_line_pointer;
1062   
1063   for (;;)
1064     {
1065       const char * errmsg = NULL;
1066
1067       relaxable = 0;
1068       fc = 0;
1069       match = 0;
1070       next_opindex = 0;
1071       insn = opcode->opcode;
1072       extra_data_after_insn = false;
1073
1074       input_line_pointer = str = start_of_operands;
1075
1076       for (opindex_ptr = opcode->operands; *opindex_ptr != 0; opindex_ptr++)
1077         {
1078           const struct v850_operand * operand;
1079           char *                      hold;
1080           expressionS                 ex;
1081           bfd_reloc_code_real_type    reloc;
1082
1083           if (next_opindex == 0)
1084             {
1085               operand = & v850_operands[ * opindex_ptr ];
1086             }
1087           else
1088             {
1089               operand      = & v850_operands[ next_opindex ];
1090               next_opindex = 0;
1091             }
1092
1093           errmsg = NULL;
1094
1095           while (*str == ' ' || *str == ',' || *str == '[' || *str == ']')
1096             ++str;
1097
1098           if (operand->flags & V850_OPERAND_RELAX)
1099             relaxable = 1;
1100
1101           /* Gather the operand. */
1102           hold = input_line_pointer;
1103           input_line_pointer = str;
1104           
1105 /* fprintf (stderr, "operand: %s   index = %d, opcode = %s\n", input_line_pointer, opindex_ptr - opcode->operands, opcode->name ); */
1106
1107           /* lo(), hi(), hi0(), etc... */
1108           if ((reloc = v850_reloc_prefix (operand)) != BFD_RELOC_UNUSED)
1109             {
1110               expression (& ex);
1111
1112               if (ex.X_op == O_constant)
1113                 {
1114                   switch (reloc)
1115                     {
1116                     case BFD_RELOC_LO16:
1117                       {
1118                         /* Truncate, then sign extend the value.  */
1119                         ex.X_add_number = SEXT16 (ex.X_add_number);
1120                         break;
1121                       }
1122
1123                     case BFD_RELOC_HI16:
1124                       {
1125                         /* Truncate, then sign extend the value.  */
1126                         ex.X_add_number = SEXT16 (ex.X_add_number >> 16);
1127                         break;
1128                       }
1129
1130                     case BFD_RELOC_HI16_S:
1131                       {
1132                         /* Truncate, then sign extend the value.  */
1133                         int temp = (ex.X_add_number >> 16) & 0xffff;
1134
1135                         temp += (ex.X_add_number >> 15) & 1;
1136
1137                         ex.X_add_number = SEXT16 (temp);
1138                         break;
1139                       }
1140
1141                     default:
1142                       as_bad ( "AAARG -> unhandled constant reloc");
1143                       break;
1144                     }
1145
1146                   insn = v850_insert_operand (insn, operand, ex.X_add_number,
1147                                               (char *) NULL, 0);
1148                 }
1149               else
1150                 {
1151                   if (fc > MAX_INSN_FIXUPS)
1152                     as_fatal ("too many fixups");
1153
1154                   fixups[ fc ].exp     = ex;
1155                   fixups[ fc ].opindex = * opindex_ptr;
1156                   fixups[ fc ].reloc   = reloc;
1157                   fc++;
1158                 }
1159             }
1160           else
1161             {
1162               errmsg = NULL;
1163               
1164               if ((operand->flags & V850_OPERAND_REG) != 0) 
1165                 {
1166                   if (!register_name (& ex))
1167                     {
1168                       errmsg = "invalid register name";
1169                     }
1170
1171                   if ((operand->flags & V850_NOT_R0)
1172                       && ex.X_add_number == 0)
1173                     {
1174                       errmsg = "register r0 cannot be used here";
1175                     }
1176                 }
1177               else if ((operand->flags & V850_OPERAND_SRG) != 0) 
1178                 {
1179                   if (!system_register_name (& ex, true))
1180                     {
1181                       errmsg = "invalid system register name";
1182                     }
1183                 }
1184               else if ((operand->flags & V850_OPERAND_EP) != 0)
1185                 {
1186                   char * start = input_line_pointer;
1187                   char   c     = get_symbol_end ();
1188                   
1189                   if (strcmp (start, "ep") != 0 && strcmp (start, "r30") != 0)
1190                     {
1191                       /* Put things back the way we found them.  */
1192                       *input_line_pointer = c;
1193                       input_line_pointer = start;
1194                       errmsg = "expected EP register";
1195                       goto error;
1196                     }
1197                   
1198                   *input_line_pointer = c;
1199                   str = input_line_pointer;
1200                   input_line_pointer = hold;
1201               
1202                   while (*str == ' ' || *str == ',' || *str == '[' || *str == ']')
1203                     ++str;
1204                   continue;
1205                 }
1206               else if ((operand->flags & V850_OPERAND_CC) != 0) 
1207                 {
1208                   if (!cc_name (& ex))
1209                     {
1210                       errmsg = "invalid condition code name";
1211                     }
1212                 }
1213               /* start-sanitize-v850e */
1214               else if (operand->flags & V850E_PUSH_POP) 
1215                 {
1216                   errmsg = parse_register_list (& insn, operand);
1217                   
1218                   /* The parse_register_list() function has already done everything, so fake a dummy expression.  */
1219                   ex.X_op         = O_constant;
1220                   ex.X_add_number = 0;
1221                 }
1222               /* end-sanitize-v850e */
1223               /* start-sanitize-v850e */
1224               else if (operand->flags & V850E_IMMEDIATE16) 
1225                 {
1226                   expression (& ex);
1227
1228                   if (ex.X_op != O_constant)
1229                     errmsg = "constant expression expected";
1230                   else if (ex.X_add_number & 0xffff0000)
1231                     {
1232                       if (ex.X_add_number & 0xffff)
1233                         errmsg = "constant too big to fit into instruction";
1234                       else if ((insn & 0x001fffc0) == 0x00130780)
1235                         ex.X_add_number >>= 16;
1236                       else
1237                         errmsg = "constant too big to fit into instruction";
1238                     }
1239                   
1240                   extra_data_after_insn = true;
1241                   extra_data_len        = 2;
1242                   extra_data            = ex.X_add_number;
1243                   ex.X_add_number       = 0;
1244                 }
1245               /* end-sanitize-v850e */
1246               /* start-sanitize-v850e */
1247               else if (operand->flags & V850E_IMMEDIATE32) 
1248                 {
1249                   expression (& ex);
1250                   
1251                   if (ex.X_op != O_constant)
1252                     errmsg = "constant expression expected";
1253                   
1254                   extra_data_after_insn = true;
1255                   extra_data_len        = 4;
1256                   extra_data            = ex.X_add_number;
1257                   ex.X_add_number       = 0;
1258                 }
1259               /* end-sanitize-v850e */
1260               else if (register_name (&ex)
1261                        && (operand->flags & V850_OPERAND_REG) == 0)
1262                 {
1263                   errmsg = "syntax error: register not expected";
1264                 }
1265               else if (system_register_name (& ex, false)
1266                        && (operand->flags & V850_OPERAND_SRG) == 0)
1267                 {
1268                   errmsg = "syntax error: system register not expected";
1269                 }
1270               else if (cc_name (&ex)
1271                        && (operand->flags & V850_OPERAND_CC) == 0)
1272                 {
1273                   errmsg = "syntax error: condition code not expected";
1274                 }
1275               else
1276                 {
1277                   expression (& ex);
1278 /* start-sanitize-v850e */
1279                   /* Special case:
1280                      If we are assembling a MOV instruction (or a CALLT.... :-)
1281                      and the immediate value does not fit into the bits available
1282                      then create a fake error so that the next MOV instruction
1283                       will be selected.  This one has a 32 bit immediate field.  */
1284
1285                   if (((insn & 0x07e0) == 0x0200)
1286                       && ex.X_op == O_constant
1287                       && (ex.X_add_number < (- (1 << (operand->bits - 1))) || ex.X_add_number > ((1 << operand->bits) - 1)))
1288                     errmsg = "use bigger instruction";
1289 /* end-sanitize-v850e */
1290                 }
1291
1292               if (errmsg)
1293                 goto error;
1294               
1295 /* fprintf (stderr, "insn: %x, operand %d, op: %d, add_number: %d\n", insn, opindex_ptr - opcode->operands, ex.X_op, ex.X_add_number ); */
1296
1297               switch (ex.X_op) 
1298                 {
1299                 case O_illegal:
1300                   errmsg = "illegal operand";
1301                   goto error;
1302                 case O_absent:
1303                   errmsg = "missing operand";
1304                   goto error;
1305                 case O_register:
1306                   if ((operand->flags & (V850_OPERAND_REG | V850_OPERAND_SRG)) == 0)
1307                     {
1308                       errmsg = "invalid operand";
1309                       goto error;
1310                     }
1311                   insn = v850_insert_operand (insn, operand, ex.X_add_number,
1312                                               (char *) NULL, 0);
1313                   break;
1314
1315                 case O_constant:
1316                   insn = v850_insert_operand (insn, operand, ex.X_add_number,
1317                                               (char *) NULL, 0);
1318                   break;
1319
1320                 default:
1321                   /* We need to generate a fixup for this expression.  */
1322                   if (fc >= MAX_INSN_FIXUPS)
1323                     as_fatal ("too many fixups");
1324                   
1325                   fixups[ fc ].exp     = ex;
1326                   fixups[ fc ].opindex = * opindex_ptr;
1327                   fixups[ fc ].reloc   = BFD_RELOC_UNUSED;
1328                   ++fc;
1329                   break;
1330                 }
1331             }
1332
1333           str = input_line_pointer;
1334           input_line_pointer = hold;
1335
1336           while (*str == ' ' || *str == ',' || *str == '[' || *str == ']'
1337                  || *str == ')')
1338             ++str;
1339         }
1340       match = 1;
1341
1342     error:
1343       if (match == 0)
1344         {
1345           next_opcode = opcode + 1;
1346           if (next_opcode->name != NULL && strcmp (next_opcode->name, opcode->name) == 0)
1347             {
1348               opcode = next_opcode;
1349               continue;
1350             }
1351           
1352           as_bad (errmsg);
1353           ignore_rest_of_line ();
1354           input_line_pointer = saved_input_line_pointer;
1355           return;
1356         }
1357       break;
1358     }
1359       
1360   while (isspace (*str))
1361     ++str;
1362
1363   if (*str != '\0')
1364     as_bad ("junk at end of line: `%s'", str);
1365
1366   input_line_pointer = str;
1367
1368   /* Write out the instruction.
1369
1370      Four byte insns have an opcode with the two high bits on.  */ 
1371   if (relaxable && fc > 0)
1372     {
1373       f = frag_var (rs_machine_dependent, 6, 4, 0,
1374                     fixups[0].exp.X_add_symbol,
1375                     fixups[0].exp.X_add_number,
1376                     (char *)fixups[0].opindex);
1377       insn_size = 2;
1378       md_number_to_chars (f, insn, insn_size);
1379       md_number_to_chars (f + 2, 0, 4);
1380       fc = 0;
1381     }
1382   else 
1383     {
1384       if ((insn & 0x0600) == 0x0600)
1385         insn_size = 4;
1386       else
1387         insn_size = 2;
1388
1389 /* start-sanitize-v850e */
1390       /* Special case: 32 bit MOV */
1391       if ((insn & 0xffe0) == 0x0620)
1392         insn_size = 2;
1393 /* end_sanitize-v850e */
1394       
1395       f = frag_more (insn_size);
1396       
1397       md_number_to_chars (f, insn, insn_size);
1398
1399       if (extra_data_after_insn)
1400         {
1401           char * g = frag_more (extra_data_len);
1402           
1403           md_number_to_chars (g, extra_data, extra_data_len);
1404
1405           extra_data_after_insn = false;
1406         }
1407     }
1408
1409   /* Create any fixups.  At this point we do not use a
1410      bfd_reloc_code_real_type, but instead just use the
1411      BFD_RELOC_UNUSED plus the operand index.  This lets us easily
1412      handle fixups for any operand type, although that is admittedly
1413      not a very exciting feature.  We pick a BFD reloc type in
1414      md_apply_fix.  */  
1415   for (i = 0; i < fc; i++)
1416     {
1417       const struct v850_operand * operand;
1418
1419       operand = & v850_operands[ fixups[i].opindex ];
1420       
1421       if (fixups[i].reloc != BFD_RELOC_UNUSED)
1422         {
1423           reloc_howto_type * reloc_howto = bfd_reloc_type_lookup (stdoutput, fixups[i].reloc);
1424           int                size;
1425           int                address;
1426           fixS *             fixP;
1427
1428           if (!reloc_howto)
1429             abort();
1430           
1431           size = bfd_get_reloc_size (reloc_howto);
1432
1433           if (size != 2 && size != 4) /* XXX this will abort on an R_V850_8 reloc - is this reloc actually used ? */
1434             abort();
1435
1436           address = (f - frag_now->fr_literal) + insn_size - size;
1437   
1438           fixP = fix_new_exp (frag_now, address, size,
1439                               & fixups[i].exp, 
1440                               reloc_howto->pc_relative,
1441                               fixups[i].reloc);
1442
1443           switch (fixups[i].reloc)
1444             {
1445             case BFD_RELOC_LO16:
1446             case BFD_RELOC_HI16:
1447             case BFD_RELOC_HI16_S:
1448               fixP->fx_no_overflow = 1;
1449               break;
1450             }
1451         }
1452       else
1453         {
1454           fix_new_exp (frag_now, f - frag_now->fr_literal, 4,
1455                        & fixups[i].exp,
1456                        1 /* FIXME: V850_OPERAND_RELATIVE ??? */,
1457                        ((bfd_reloc_code_real_type)
1458                         (fixups[i].opindex + (int) BFD_RELOC_UNUSED)));
1459         }
1460     }
1461
1462   input_line_pointer = saved_input_line_pointer;
1463 }
1464
1465
1466 /* If while processing a fixup, a reloc really needs to be created */
1467 /* then it is done here.  */
1468                  
1469 arelent *
1470 tc_gen_reloc (seg, fixp)
1471      asection * seg;
1472      fixS *     fixp;
1473 {
1474   arelent * reloc;
1475   
1476   reloc              = (arelent *) xmalloc (sizeof (arelent));
1477   reloc->sym_ptr_ptr = & fixp->fx_addsy->bsym;
1478   reloc->address     = fixp->fx_frag->fr_address + fixp->fx_where;
1479   reloc->howto       = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1480   
1481   if (reloc->howto == (reloc_howto_type *) NULL)
1482     {
1483       as_bad_where (fixp->fx_file, fixp->fx_line,
1484                     "reloc %d not supported by object file format", (int)fixp->fx_r_type);
1485       return NULL;
1486     }
1487   
1488   reloc->addend = fixp->fx_addnumber;
1489   
1490   return reloc;
1491 }
1492
1493 /* Assume everything will fit in two bytes, then expand as necessary.  */
1494 int
1495 md_estimate_size_before_relax (fragp, seg)
1496      fragS * fragp;
1497      asection * seg;
1498 {
1499   fragp->fr_var = 4;
1500   return 2;
1501
1502
1503
1504 long
1505 md_pcrel_from (fixp)
1506      fixS * fixp;
1507 {
1508   /* If the symbol is undefined, or in a section other than our own,
1509      then let the linker figure it out.  */
1510   if (fixp->fx_addsy != (symbolS *) NULL && ! S_IS_DEFINED (fixp->fx_addsy))
1511     {
1512       /* The symbol is undefined.  Let the linker figure it out.  */
1513       return 0;
1514     }
1515   return fixp->fx_frag->fr_address + fixp->fx_where;
1516 }
1517
1518 int
1519 md_apply_fix3 (fixp, valuep, seg)
1520      fixS *   fixp;
1521      valueT * valuep;
1522      segT     seg;
1523 {
1524   valueT value;
1525   char * where;
1526
1527   if (fixp->fx_addsy == (symbolS *) NULL)
1528     {
1529       value = * valuep;
1530       fixp->fx_done = 1;
1531     }
1532   else if (fixp->fx_pcrel)
1533     value = * valuep;
1534   else
1535     {
1536       value = fixp->fx_offset;
1537       if (fixp->fx_subsy != (symbolS *) NULL)
1538         {
1539           if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
1540             value -= S_GET_VALUE (fixp->fx_subsy);
1541           else
1542             {
1543               /* We don't actually support subtracting a symbol.  */
1544               as_bad_where (fixp->fx_file, fixp->fx_line,
1545                             "expression too complex");
1546             }
1547         }
1548     }
1549
1550   if ((int) fixp->fx_r_type >= (int) BFD_RELOC_UNUSED)
1551     {
1552       int                         opindex;
1553       const struct v850_operand * operand;
1554       char *                      where;
1555       unsigned long               insn;
1556
1557       opindex = (int) fixp->fx_r_type - (int) BFD_RELOC_UNUSED;
1558       operand = & v850_operands[ opindex ];
1559
1560       /* Fetch the instruction, insert the fully resolved operand
1561          value, and stuff the instruction back again.
1562
1563          Note the instruction has been stored in little endian
1564          format!  */
1565       where = fixp->fx_frag->fr_literal + fixp->fx_where;
1566
1567       insn = bfd_getl32 ((unsigned char *) where);
1568       insn = v850_insert_operand (insn, operand, (offsetT) value,
1569                                   fixp->fx_file, fixp->fx_line);
1570       bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
1571
1572       if (fixp->fx_done)
1573         {
1574           /* Nothing else to do here. */
1575           return 1;
1576         }
1577
1578       /* Determine a BFD reloc value based on the operand information.  
1579          We are only prepared to turn a few of the operands into relocs. */
1580
1581       if (operand->bits == 22)
1582         fixp->fx_r_type = BFD_RELOC_V850_22_PCREL;
1583       else if (operand->bits == 9)
1584         fixp->fx_r_type = BFD_RELOC_V850_9_PCREL;
1585       else if (operand->bits == 16)
1586         fixp->fx_r_type = BFD_RELOC_V850_16_PCREL;
1587       else
1588         {
1589           as_bad_where(fixp->fx_file, fixp->fx_line,
1590                        "unresolved expression that must be resolved");
1591           fixp->fx_done = 1;
1592           return 1;
1593         }
1594     }
1595   else if (fixp->fx_done)
1596     {
1597       /* We still have to insert the value into memory!  */
1598       where = fixp->fx_frag->fr_literal + fixp->fx_where;
1599       if (fixp->fx_size == 1)
1600         *where = value & 0xff;
1601       if (fixp->fx_size == 2)
1602         bfd_putl16 (value & 0xffff, (unsigned char *) where);
1603       if (fixp->fx_size == 4)
1604         bfd_putl32 (value, (unsigned char *) where);
1605     }
1606   
1607   fixp->fx_addnumber = value;
1608   return 1;
1609 }
1610
1611 \f
1612 /* Insert an operand value into an instruction.  */
1613
1614 static unsigned long
1615 v850_insert_operand (insn, operand, val, file, line)
1616      unsigned long insn;
1617      const struct v850_operand * operand;
1618      offsetT val;
1619      char *file;
1620      unsigned int line;
1621 {
1622   if (operand->bits != 32)
1623     {
1624       long min, max;
1625       offsetT test;
1626
1627       if ((operand->flags & V850_OPERAND_SIGNED) != 0)
1628         {
1629           max = (1 << (operand->bits - 1)) - 1;
1630           min = - (1 << (operand->bits - 1));
1631         }
1632       else
1633         {
1634           max = (1 << operand->bits) - 1;
1635           min = 0;
1636         }
1637
1638       test = val;
1639
1640       if (test < (offsetT) min || test > (offsetT) max)
1641         {
1642           const char * err =
1643             "operand out of range (%s not between %ld and %ld)";
1644           char buf[100];
1645
1646           sprint_value (buf, test);
1647           if (file == (char *) NULL)
1648             as_warn (err, buf, min, max);
1649           else
1650             as_warn_where (file, line, err, buf, min, max);
1651         }
1652     }
1653
1654   if (operand->insert)
1655     {
1656       const char * message = NULL;
1657       
1658       insn = (*operand->insert) (insn, val, & message);
1659       if (message != NULL)
1660         {
1661           if (file == (char *) NULL)
1662             as_warn (message);
1663           else
1664             as_warn_where (file, line, message);
1665         }
1666     }
1667   else
1668     insn |= (((long) val & ((1 << operand->bits) - 1)) << operand->shift);
1669   
1670   return insn;
1671 }
1672
1673 /* Parse a cons expression.  We have to handle hi(), lo(), etc
1674    on the v850.  */
1675 void
1676 parse_cons_expression_v850 (exp)
1677   expressionS *exp;
1678 {
1679   /* See if there's a reloc prefix like hi() we have to handle.  */
1680   hold_cons_reloc = v850_reloc_prefix (NULL);
1681
1682   /* Do normal expression parsing.  */
1683   expression (exp);
1684 }
1685
1686 /* Create a fixup for a cons expression.  If parse_cons_expression_v850
1687    found a reloc prefix, then we use that reloc, else we choose an
1688    appropriate one based on the size of the expression.  */
1689 void
1690 cons_fix_new_v850 (frag, where, size, exp)
1691      fragS *frag;
1692      int where;
1693      int size;
1694      expressionS *exp;
1695 {
1696   if (hold_cons_reloc == BFD_RELOC_UNUSED)
1697     {
1698       if (size == 4)
1699         hold_cons_reloc = BFD_RELOC_32;
1700       if (size == 2)
1701         hold_cons_reloc = BFD_RELOC_16;
1702       if (size == 1)
1703         hold_cons_reloc = BFD_RELOC_8;
1704     }
1705
1706   if (exp != NULL)
1707     fix_new_exp (frag, where, size, exp, 0, hold_cons_reloc);
1708   else
1709     fix_new (frag, where, size, NULL, 0, 0, hold_cons_reloc);
1710 }