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