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