xref: /netbsd/external/gpl3/gdb/dist/gas/config/tc-d10v.c (revision 1424dfb3)
1*1424dfb3Schristos /* tc-d10v.c -- Assembler code for the Mitsubishi D10V
2*1424dfb3Schristos    Copyright (C) 1996-2020 Free Software Foundation, Inc.
3*1424dfb3Schristos 
4*1424dfb3Schristos    This file is part of GAS, the GNU Assembler.
5*1424dfb3Schristos 
6*1424dfb3Schristos    GAS is free software; you can redistribute it and/or modify
7*1424dfb3Schristos    it under the terms of the GNU General Public License as published by
8*1424dfb3Schristos    the Free Software Foundation; either version 3, or (at your option)
9*1424dfb3Schristos    any later version.
10*1424dfb3Schristos 
11*1424dfb3Schristos    GAS is distributed in the hope that it will be useful,
12*1424dfb3Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
13*1424dfb3Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*1424dfb3Schristos    GNU General Public License for more details.
15*1424dfb3Schristos 
16*1424dfb3Schristos    You should have received a copy of the GNU General Public License
17*1424dfb3Schristos    along with GAS; see the file COPYING.  If not, write to
18*1424dfb3Schristos    the Free Software Foundation, 51 Franklin Street - Fifth Floor,
19*1424dfb3Schristos    Boston, MA 02110-1301, USA.  */
20*1424dfb3Schristos 
21*1424dfb3Schristos #include "as.h"
22*1424dfb3Schristos #include "safe-ctype.h"
23*1424dfb3Schristos #include "subsegs.h"
24*1424dfb3Schristos #include "opcode/d10v.h"
25*1424dfb3Schristos #include "elf/ppc.h"
26*1424dfb3Schristos #include "dwarf2dbg.h"
27*1424dfb3Schristos 
28*1424dfb3Schristos const char comment_chars[]        = ";";
29*1424dfb3Schristos const char line_comment_chars[]   = "#";
30*1424dfb3Schristos const char line_separator_chars[] = "";
31*1424dfb3Schristos const char *md_shortopts          = "O";
32*1424dfb3Schristos const char EXP_CHARS[]            = "eE";
33*1424dfb3Schristos const char FLT_CHARS[]            = "dD";
34*1424dfb3Schristos 
35*1424dfb3Schristos int Optimizing = 0;
36*1424dfb3Schristos 
37*1424dfb3Schristos #define AT_WORD_P(X) ((X)->X_op == O_right_shift \
38*1424dfb3Schristos 		      && (X)->X_op_symbol != NULL \
39*1424dfb3Schristos 		      && symbol_constant_p ((X)->X_op_symbol) \
40*1424dfb3Schristos 		      && S_GET_VALUE ((X)->X_op_symbol) == AT_WORD_RIGHT_SHIFT)
41*1424dfb3Schristos #define AT_WORD_RIGHT_SHIFT 2
42*1424dfb3Schristos 
43*1424dfb3Schristos /* Fixups.  */
44*1424dfb3Schristos #define MAX_INSN_FIXUPS  5
45*1424dfb3Schristos 
46*1424dfb3Schristos struct d10v_fixup
47*1424dfb3Schristos {
48*1424dfb3Schristos   expressionS exp;
49*1424dfb3Schristos   int operand;
50*1424dfb3Schristos   int pcrel;
51*1424dfb3Schristos   int size;
52*1424dfb3Schristos   bfd_reloc_code_real_type reloc;
53*1424dfb3Schristos };
54*1424dfb3Schristos 
55*1424dfb3Schristos typedef struct _fixups
56*1424dfb3Schristos {
57*1424dfb3Schristos   int fc;
58*1424dfb3Schristos   struct d10v_fixup fix[MAX_INSN_FIXUPS];
59*1424dfb3Schristos   struct _fixups *next;
60*1424dfb3Schristos } Fixups;
61*1424dfb3Schristos 
62*1424dfb3Schristos static Fixups FixUps[2];
63*1424dfb3Schristos static Fixups *fixups;
64*1424dfb3Schristos 
65*1424dfb3Schristos static int do_not_ignore_hash = 0;
66*1424dfb3Schristos 
67*1424dfb3Schristos typedef int packing_type;
68*1424dfb3Schristos #define PACK_UNSPEC 	(0)	/* Packing order not specified.  */
69*1424dfb3Schristos #define PACK_PARALLEL	(1)	/* "||"  */
70*1424dfb3Schristos #define PACK_LEFT_RIGHT (2)	/* "->"  */
71*1424dfb3Schristos #define PACK_RIGHT_LEFT (3)	/* "<-"  */
72*1424dfb3Schristos static packing_type etype = PACK_UNSPEC; /* Used by d10v_cleanup.  */
73*1424dfb3Schristos 
74*1424dfb3Schristos /* TRUE if instruction swapping warnings should be inhibited.
75*1424dfb3Schristos    --nowarnswap.  */
76*1424dfb3Schristos static bfd_boolean flag_warn_suppress_instructionswap;
77*1424dfb3Schristos 
78*1424dfb3Schristos /* TRUE if instruction packing should be performed when --gstabs is specified.
79*1424dfb3Schristos    --gstabs-packing, --no-gstabs-packing.  */
80*1424dfb3Schristos static bfd_boolean flag_allow_gstabs_packing = 1;
81*1424dfb3Schristos 
82*1424dfb3Schristos /* Local functions.  */
83*1424dfb3Schristos 
84*1424dfb3Schristos enum options
85*1424dfb3Schristos {
86*1424dfb3Schristos   OPTION_NOWARNSWAP = OPTION_MD_BASE,
87*1424dfb3Schristos   OPTION_GSTABSPACKING,
88*1424dfb3Schristos   OPTION_NOGSTABSPACKING
89*1424dfb3Schristos };
90*1424dfb3Schristos 
91*1424dfb3Schristos struct option md_longopts[] =
92*1424dfb3Schristos {
93*1424dfb3Schristos   {"nowarnswap", no_argument, NULL, OPTION_NOWARNSWAP},
94*1424dfb3Schristos   {"gstabspacking",  no_argument, NULL, OPTION_GSTABSPACKING},
95*1424dfb3Schristos   {"gstabs-packing", no_argument, NULL, OPTION_GSTABSPACKING},
96*1424dfb3Schristos   {"nogstabspacking",   no_argument, NULL, OPTION_NOGSTABSPACKING},
97*1424dfb3Schristos   {"no-gstabs-packing", no_argument, NULL, OPTION_NOGSTABSPACKING},
98*1424dfb3Schristos   {NULL, no_argument, NULL, 0}
99*1424dfb3Schristos };
100*1424dfb3Schristos 
101*1424dfb3Schristos size_t md_longopts_size = sizeof (md_longopts);
102*1424dfb3Schristos 
103*1424dfb3Schristos /* Opcode hash table.  */
104*1424dfb3Schristos static htab_t d10v_hash;
105*1424dfb3Schristos 
106*1424dfb3Schristos /* Do a binary search of the d10v_predefined_registers array to see if
107*1424dfb3Schristos    NAME is a valid register name.  Return the register number from the
108*1424dfb3Schristos    array on success, or -1 on failure.  */
109*1424dfb3Schristos 
110*1424dfb3Schristos static int
reg_name_search(char * name)111*1424dfb3Schristos reg_name_search (char *name)
112*1424dfb3Schristos {
113*1424dfb3Schristos   int middle, low, high;
114*1424dfb3Schristos   int cmp;
115*1424dfb3Schristos 
116*1424dfb3Schristos   low = 0;
117*1424dfb3Schristos   high = d10v_reg_name_cnt () - 1;
118*1424dfb3Schristos 
119*1424dfb3Schristos   do
120*1424dfb3Schristos     {
121*1424dfb3Schristos       middle = (low + high) / 2;
122*1424dfb3Schristos       cmp = strcasecmp (name, d10v_predefined_registers[middle].name);
123*1424dfb3Schristos       if (cmp < 0)
124*1424dfb3Schristos 	high = middle - 1;
125*1424dfb3Schristos       else if (cmp > 0)
126*1424dfb3Schristos 	low = middle + 1;
127*1424dfb3Schristos       else
128*1424dfb3Schristos 	return d10v_predefined_registers[middle].value;
129*1424dfb3Schristos     }
130*1424dfb3Schristos   while (low <= high);
131*1424dfb3Schristos   return -1;
132*1424dfb3Schristos }
133*1424dfb3Schristos 
134*1424dfb3Schristos /* Check the string at input_line_pointer
135*1424dfb3Schristos    to see if it is a valid register name.  */
136*1424dfb3Schristos 
137*1424dfb3Schristos static int
register_name(expressionS * expressionP)138*1424dfb3Schristos register_name (expressionS *expressionP)
139*1424dfb3Schristos {
140*1424dfb3Schristos   int reg_number;
141*1424dfb3Schristos   char c, *p = input_line_pointer;
142*1424dfb3Schristos 
143*1424dfb3Schristos   while (*p
144*1424dfb3Schristos 	 && *p != '\n' && *p != '\r' && *p != ',' && *p != ' ' && *p != ')')
145*1424dfb3Schristos     p++;
146*1424dfb3Schristos 
147*1424dfb3Schristos   c = *p;
148*1424dfb3Schristos   if (c)
149*1424dfb3Schristos     *p++ = 0;
150*1424dfb3Schristos 
151*1424dfb3Schristos   /* Look to see if it's in the register table.  */
152*1424dfb3Schristos   reg_number = reg_name_search (input_line_pointer);
153*1424dfb3Schristos   if (reg_number >= 0)
154*1424dfb3Schristos     {
155*1424dfb3Schristos       expressionP->X_op = O_register;
156*1424dfb3Schristos       /* Temporarily store a pointer to the string here.  */
157*1424dfb3Schristos       expressionP->X_op_symbol = (symbolS *) input_line_pointer;
158*1424dfb3Schristos       expressionP->X_add_number = reg_number;
159*1424dfb3Schristos       input_line_pointer = p;
160*1424dfb3Schristos       return 1;
161*1424dfb3Schristos     }
162*1424dfb3Schristos   if (c)
163*1424dfb3Schristos     *(p - 1) = c;
164*1424dfb3Schristos   return 0;
165*1424dfb3Schristos }
166*1424dfb3Schristos 
167*1424dfb3Schristos static int
check_range(unsigned long num,int bits,int flags)168*1424dfb3Schristos check_range (unsigned long num, int bits, int flags)
169*1424dfb3Schristos {
170*1424dfb3Schristos   long min, max;
171*1424dfb3Schristos   int retval = 0;
172*1424dfb3Schristos 
173*1424dfb3Schristos   /* Don't bother checking 16-bit values.  */
174*1424dfb3Schristos   if (bits == 16)
175*1424dfb3Schristos     return 0;
176*1424dfb3Schristos 
177*1424dfb3Schristos   if (flags & OPERAND_SHIFT)
178*1424dfb3Schristos     {
179*1424dfb3Schristos       /* All special shift operands are unsigned and <= 16.
180*1424dfb3Schristos 	 We allow 0 for now.  */
181*1424dfb3Schristos       if (num > 16)
182*1424dfb3Schristos 	return 1;
183*1424dfb3Schristos       else
184*1424dfb3Schristos 	return 0;
185*1424dfb3Schristos     }
186*1424dfb3Schristos 
187*1424dfb3Schristos   if (flags & OPERAND_SIGNED)
188*1424dfb3Schristos     {
189*1424dfb3Schristos       /* Signed 3-bit integers are restricted to the (-2, 3) range.  */
190*1424dfb3Schristos       if (flags & RESTRICTED_NUM3)
191*1424dfb3Schristos 	{
192*1424dfb3Schristos 	  if ((long) num < -2 || (long) num > 3)
193*1424dfb3Schristos 	    retval = 1;
194*1424dfb3Schristos 	}
195*1424dfb3Schristos       else
196*1424dfb3Schristos 	{
197*1424dfb3Schristos 	  max = (1 << (bits - 1)) - 1;
198*1424dfb3Schristos 	  min = - (1 << (bits - 1));
199*1424dfb3Schristos 	  if (((long) num > max) || ((long) num < min))
200*1424dfb3Schristos 	    retval = 1;
201*1424dfb3Schristos 	}
202*1424dfb3Schristos     }
203*1424dfb3Schristos   else
204*1424dfb3Schristos     {
205*1424dfb3Schristos       max = (1 << bits) - 1;
206*1424dfb3Schristos       min = 0;
207*1424dfb3Schristos       if (((long) num > max) || ((long) num < min))
208*1424dfb3Schristos 	retval = 1;
209*1424dfb3Schristos     }
210*1424dfb3Schristos   return retval;
211*1424dfb3Schristos }
212*1424dfb3Schristos 
213*1424dfb3Schristos void
md_show_usage(FILE * stream)214*1424dfb3Schristos md_show_usage (FILE *stream)
215*1424dfb3Schristos {
216*1424dfb3Schristos   fprintf (stream, _("D10V options:\n\
217*1424dfb3Schristos -O                      Optimize.  Will do some operations in parallel.\n\
218*1424dfb3Schristos --gstabs-packing        Pack adjacent short instructions together even\n\
219*1424dfb3Schristos                         when --gstabs is specified.  On by default.\n\
220*1424dfb3Schristos --no-gstabs-packing     If --gstabs is specified, do not pack adjacent\n\
221*1424dfb3Schristos                         instructions together.\n"));
222*1424dfb3Schristos }
223*1424dfb3Schristos 
224*1424dfb3Schristos int
md_parse_option(int c,const char * arg ATTRIBUTE_UNUSED)225*1424dfb3Schristos md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
226*1424dfb3Schristos {
227*1424dfb3Schristos   switch (c)
228*1424dfb3Schristos     {
229*1424dfb3Schristos     case 'O':
230*1424dfb3Schristos       /* Optimize. Will attempt to parallelize operations.  */
231*1424dfb3Schristos       Optimizing = 1;
232*1424dfb3Schristos       break;
233*1424dfb3Schristos     case OPTION_NOWARNSWAP:
234*1424dfb3Schristos       flag_warn_suppress_instructionswap = 1;
235*1424dfb3Schristos       break;
236*1424dfb3Schristos     case OPTION_GSTABSPACKING:
237*1424dfb3Schristos       flag_allow_gstabs_packing = 1;
238*1424dfb3Schristos       break;
239*1424dfb3Schristos     case OPTION_NOGSTABSPACKING:
240*1424dfb3Schristos       flag_allow_gstabs_packing = 0;
241*1424dfb3Schristos       break;
242*1424dfb3Schristos     default:
243*1424dfb3Schristos       return 0;
244*1424dfb3Schristos     }
245*1424dfb3Schristos   return 1;
246*1424dfb3Schristos }
247*1424dfb3Schristos 
248*1424dfb3Schristos symbolS *
md_undefined_symbol(char * name ATTRIBUTE_UNUSED)249*1424dfb3Schristos md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
250*1424dfb3Schristos {
251*1424dfb3Schristos   return 0;
252*1424dfb3Schristos }
253*1424dfb3Schristos 
254*1424dfb3Schristos const char *
md_atof(int type,char * litP,int * sizeP)255*1424dfb3Schristos md_atof (int type, char *litP, int *sizeP)
256*1424dfb3Schristos {
257*1424dfb3Schristos   return ieee_md_atof (type, litP, sizeP, TRUE);
258*1424dfb3Schristos }
259*1424dfb3Schristos 
260*1424dfb3Schristos void
md_convert_frag(bfd * abfd ATTRIBUTE_UNUSED,asection * sec ATTRIBUTE_UNUSED,fragS * fragP ATTRIBUTE_UNUSED)261*1424dfb3Schristos md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
262*1424dfb3Schristos 		 asection *sec ATTRIBUTE_UNUSED,
263*1424dfb3Schristos 		 fragS *fragP ATTRIBUTE_UNUSED)
264*1424dfb3Schristos {
265*1424dfb3Schristos   abort ();
266*1424dfb3Schristos }
267*1424dfb3Schristos 
268*1424dfb3Schristos valueT
md_section_align(asection * seg,valueT addr)269*1424dfb3Schristos md_section_align (asection *seg, valueT addr)
270*1424dfb3Schristos {
271*1424dfb3Schristos   int align = bfd_section_alignment (seg);
272*1424dfb3Schristos   return ((addr + (1 << align) - 1) & -(1 << align));
273*1424dfb3Schristos }
274*1424dfb3Schristos 
275*1424dfb3Schristos void
md_begin(void)276*1424dfb3Schristos md_begin (void)
277*1424dfb3Schristos {
278*1424dfb3Schristos   const char *prev_name = "";
279*1424dfb3Schristos   struct d10v_opcode *opcode;
280*1424dfb3Schristos   d10v_hash = str_htab_create ();
281*1424dfb3Schristos 
282*1424dfb3Schristos   /* Insert unique names into hash table.  The D10v instruction set
283*1424dfb3Schristos      has many identical opcode names that have different opcodes based
284*1424dfb3Schristos      on the operands.  This hash table then provides a quick index to
285*1424dfb3Schristos      the first opcode with a particular name in the opcode table.  */
286*1424dfb3Schristos 
287*1424dfb3Schristos   for (opcode = (struct d10v_opcode *) d10v_opcodes; opcode->name; opcode++)
288*1424dfb3Schristos     {
289*1424dfb3Schristos       if (strcmp (prev_name, opcode->name))
290*1424dfb3Schristos 	{
291*1424dfb3Schristos 	  prev_name = (char *) opcode->name;
292*1424dfb3Schristos 	  str_hash_insert (d10v_hash, opcode->name, opcode, 0);
293*1424dfb3Schristos 	}
294*1424dfb3Schristos     }
295*1424dfb3Schristos 
296*1424dfb3Schristos   fixups = &FixUps[0];
297*1424dfb3Schristos   FixUps[0].next = &FixUps[1];
298*1424dfb3Schristos   FixUps[1].next = &FixUps[0];
299*1424dfb3Schristos }
300*1424dfb3Schristos 
301*1424dfb3Schristos /* Remove the postincrement or postdecrement operator ( '+' or '-' )
302*1424dfb3Schristos    from an expression.  */
303*1424dfb3Schristos 
304*1424dfb3Schristos static int
postfix(char * p)305*1424dfb3Schristos postfix (char *p)
306*1424dfb3Schristos {
307*1424dfb3Schristos   while (*p != '-' && *p != '+')
308*1424dfb3Schristos     {
309*1424dfb3Schristos       if (*p == 0 || *p == '\n' || *p == '\r')
310*1424dfb3Schristos 	break;
311*1424dfb3Schristos       p++;
312*1424dfb3Schristos     }
313*1424dfb3Schristos 
314*1424dfb3Schristos   if (*p == '-')
315*1424dfb3Schristos     {
316*1424dfb3Schristos       *p = ' ';
317*1424dfb3Schristos       return -1;
318*1424dfb3Schristos     }
319*1424dfb3Schristos   if (*p == '+')
320*1424dfb3Schristos     {
321*1424dfb3Schristos       *p = ' ';
322*1424dfb3Schristos       return 1;
323*1424dfb3Schristos     }
324*1424dfb3Schristos 
325*1424dfb3Schristos   return 0;
326*1424dfb3Schristos }
327*1424dfb3Schristos 
328*1424dfb3Schristos static bfd_reloc_code_real_type
get_reloc(struct d10v_operand * op)329*1424dfb3Schristos get_reloc (struct d10v_operand *op)
330*1424dfb3Schristos {
331*1424dfb3Schristos   int bits = op->bits;
332*1424dfb3Schristos 
333*1424dfb3Schristos   if (bits <= 4)
334*1424dfb3Schristos     return 0;
335*1424dfb3Schristos 
336*1424dfb3Schristos   if (op->flags & OPERAND_ADDR)
337*1424dfb3Schristos     {
338*1424dfb3Schristos       if (bits == 8)
339*1424dfb3Schristos 	return BFD_RELOC_D10V_10_PCREL_R;
340*1424dfb3Schristos       else
341*1424dfb3Schristos 	return BFD_RELOC_D10V_18_PCREL;
342*1424dfb3Schristos     }
343*1424dfb3Schristos 
344*1424dfb3Schristos   return BFD_RELOC_16;
345*1424dfb3Schristos }
346*1424dfb3Schristos 
347*1424dfb3Schristos /* Parse a string of operands.  Return an array of expressions.  */
348*1424dfb3Schristos 
349*1424dfb3Schristos static int
get_operands(expressionS exp[])350*1424dfb3Schristos get_operands (expressionS exp[])
351*1424dfb3Schristos {
352*1424dfb3Schristos   char *p = input_line_pointer;
353*1424dfb3Schristos   int numops = 0;
354*1424dfb3Schristos   int post = 0;
355*1424dfb3Schristos   int uses_at = 0;
356*1424dfb3Schristos 
357*1424dfb3Schristos   while (*p)
358*1424dfb3Schristos     {
359*1424dfb3Schristos       while (*p == ' ' || *p == '\t' || *p == ',')
360*1424dfb3Schristos 	p++;
361*1424dfb3Schristos       if (*p == 0 || *p == '\n' || *p == '\r')
362*1424dfb3Schristos 	break;
363*1424dfb3Schristos 
364*1424dfb3Schristos       if (*p == '@')
365*1424dfb3Schristos 	{
366*1424dfb3Schristos 	  uses_at = 1;
367*1424dfb3Schristos 
368*1424dfb3Schristos 	  p++;
369*1424dfb3Schristos 	  exp[numops].X_op = O_absent;
370*1424dfb3Schristos 	  if (*p == '(')
371*1424dfb3Schristos 	    {
372*1424dfb3Schristos 	      p++;
373*1424dfb3Schristos 	      exp[numops].X_add_number = OPERAND_ATPAR;
374*1424dfb3Schristos 	    }
375*1424dfb3Schristos 	  else if (*p == '-')
376*1424dfb3Schristos 	    {
377*1424dfb3Schristos 	      p++;
378*1424dfb3Schristos 	      exp[numops].X_add_number = OPERAND_ATMINUS;
379*1424dfb3Schristos 	    }
380*1424dfb3Schristos 	  else
381*1424dfb3Schristos 	    {
382*1424dfb3Schristos 	      exp[numops].X_add_number = OPERAND_ATSIGN;
383*1424dfb3Schristos 	      if (*p == '+')
384*1424dfb3Schristos 		{
385*1424dfb3Schristos 		  numops++;
386*1424dfb3Schristos 		  exp[numops].X_op = O_absent;
387*1424dfb3Schristos 		  exp[numops].X_add_number = OPERAND_PLUS;
388*1424dfb3Schristos 		  p++;
389*1424dfb3Schristos 		}
390*1424dfb3Schristos 	      post = postfix (p);
391*1424dfb3Schristos 	    }
392*1424dfb3Schristos 	  numops++;
393*1424dfb3Schristos 	  continue;
394*1424dfb3Schristos 	}
395*1424dfb3Schristos 
396*1424dfb3Schristos       if (*p == ')')
397*1424dfb3Schristos 	{
398*1424dfb3Schristos 	  /* Just skip the trailing paren.  */
399*1424dfb3Schristos 	  p++;
400*1424dfb3Schristos 	  continue;
401*1424dfb3Schristos 	}
402*1424dfb3Schristos 
403*1424dfb3Schristos       input_line_pointer = p;
404*1424dfb3Schristos 
405*1424dfb3Schristos       /* Check to see if it might be a register name.  */
406*1424dfb3Schristos       if (!register_name (&exp[numops]))
407*1424dfb3Schristos 	{
408*1424dfb3Schristos 	  /* Parse as an expression.  */
409*1424dfb3Schristos 	  if (uses_at)
410*1424dfb3Schristos 	    {
411*1424dfb3Schristos 	      /* Any expression that involves the indirect addressing
412*1424dfb3Schristos 		 cannot also involve immediate addressing.  Therefore
413*1424dfb3Schristos 		 the use of the hash character is illegal.  */
414*1424dfb3Schristos 	      int save = do_not_ignore_hash;
415*1424dfb3Schristos 	      do_not_ignore_hash = 1;
416*1424dfb3Schristos 
417*1424dfb3Schristos 	      expression (&exp[numops]);
418*1424dfb3Schristos 
419*1424dfb3Schristos 	      do_not_ignore_hash = save;
420*1424dfb3Schristos 	    }
421*1424dfb3Schristos 	  else
422*1424dfb3Schristos 	    expression (&exp[numops]);
423*1424dfb3Schristos 	}
424*1424dfb3Schristos 
425*1424dfb3Schristos       if (strncasecmp (input_line_pointer, "@word", 5) == 0)
426*1424dfb3Schristos 	{
427*1424dfb3Schristos 	  input_line_pointer += 5;
428*1424dfb3Schristos 	  if (exp[numops].X_op == O_register)
429*1424dfb3Schristos 	    {
430*1424dfb3Schristos 	      /* If it looked like a register name but was followed by
431*1424dfb3Schristos                  "@word" then it was really a symbol, so change it to
432*1424dfb3Schristos                  one.  */
433*1424dfb3Schristos 	      exp[numops].X_op = O_symbol;
434*1424dfb3Schristos 	      exp[numops].X_add_symbol =
435*1424dfb3Schristos 		symbol_find_or_make ((char *) exp[numops].X_op_symbol);
436*1424dfb3Schristos 	    }
437*1424dfb3Schristos 
438*1424dfb3Schristos 	  /* Check for identifier@word+constant.  */
439*1424dfb3Schristos 	  if (*input_line_pointer == '-' || *input_line_pointer == '+')
440*1424dfb3Schristos 	    {
441*1424dfb3Schristos 	      expressionS new_exp;
442*1424dfb3Schristos 	      expression (&new_exp);
443*1424dfb3Schristos 	      exp[numops].X_add_number = new_exp.X_add_number;
444*1424dfb3Schristos 	    }
445*1424dfb3Schristos 
446*1424dfb3Schristos 	  /* Convert expr into a right shift by AT_WORD_RIGHT_SHIFT.  */
447*1424dfb3Schristos 	  {
448*1424dfb3Schristos 	    expressionS new_exp;
449*1424dfb3Schristos 	    memset (&new_exp, 0, sizeof new_exp);
450*1424dfb3Schristos 	    new_exp.X_add_number = AT_WORD_RIGHT_SHIFT;
451*1424dfb3Schristos 	    new_exp.X_op = O_constant;
452*1424dfb3Schristos 	    new_exp.X_unsigned = 1;
453*1424dfb3Schristos 	    exp[numops].X_op_symbol = make_expr_symbol (&new_exp);
454*1424dfb3Schristos 	    exp[numops].X_op = O_right_shift;
455*1424dfb3Schristos 	  }
456*1424dfb3Schristos 
457*1424dfb3Schristos 	  know (AT_WORD_P (&exp[numops]));
458*1424dfb3Schristos 	}
459*1424dfb3Schristos 
460*1424dfb3Schristos       if (exp[numops].X_op == O_illegal)
461*1424dfb3Schristos 	as_bad (_("illegal operand"));
462*1424dfb3Schristos       else if (exp[numops].X_op == O_absent)
463*1424dfb3Schristos 	as_bad (_("missing operand"));
464*1424dfb3Schristos 
465*1424dfb3Schristos       numops++;
466*1424dfb3Schristos       p = input_line_pointer;
467*1424dfb3Schristos     }
468*1424dfb3Schristos 
469*1424dfb3Schristos   switch (post)
470*1424dfb3Schristos     {
471*1424dfb3Schristos     case -1:	/* Postdecrement mode.  */
472*1424dfb3Schristos       exp[numops].X_op = O_absent;
473*1424dfb3Schristos       exp[numops++].X_add_number = OPERAND_MINUS;
474*1424dfb3Schristos       break;
475*1424dfb3Schristos     case 1:	/* Postincrement mode.  */
476*1424dfb3Schristos       exp[numops].X_op = O_absent;
477*1424dfb3Schristos       exp[numops++].X_add_number = OPERAND_PLUS;
478*1424dfb3Schristos       break;
479*1424dfb3Schristos     }
480*1424dfb3Schristos 
481*1424dfb3Schristos   exp[numops].X_op = 0;
482*1424dfb3Schristos   return numops;
483*1424dfb3Schristos }
484*1424dfb3Schristos 
485*1424dfb3Schristos static unsigned long
d10v_insert_operand(unsigned long insn,int op_type,offsetT value,int left,fixS * fix)486*1424dfb3Schristos d10v_insert_operand (unsigned long insn,
487*1424dfb3Schristos 		     int op_type,
488*1424dfb3Schristos 		     offsetT value,
489*1424dfb3Schristos 		     int left,
490*1424dfb3Schristos 		     fixS *fix)
491*1424dfb3Schristos {
492*1424dfb3Schristos   int shift, bits;
493*1424dfb3Schristos 
494*1424dfb3Schristos   shift = d10v_operands[op_type].shift;
495*1424dfb3Schristos   if (left)
496*1424dfb3Schristos     shift += 15;
497*1424dfb3Schristos 
498*1424dfb3Schristos   bits = d10v_operands[op_type].bits;
499*1424dfb3Schristos 
500*1424dfb3Schristos   /* Truncate to the proper number of bits.  */
501*1424dfb3Schristos   if (check_range (value, bits, d10v_operands[op_type].flags))
502*1424dfb3Schristos     as_bad_where (fix->fx_file, fix->fx_line,
503*1424dfb3Schristos 		  _("operand out of range: %ld"), (long) value);
504*1424dfb3Schristos 
505*1424dfb3Schristos   value &= 0x7FFFFFFF >> (31 - bits);
506*1424dfb3Schristos   insn |= (value << shift);
507*1424dfb3Schristos 
508*1424dfb3Schristos   return insn;
509*1424dfb3Schristos }
510*1424dfb3Schristos 
511*1424dfb3Schristos /* Take a pointer to the opcode entry in the opcode table and the
512*1424dfb3Schristos    array of operand expressions.  Return the instruction.  */
513*1424dfb3Schristos 
514*1424dfb3Schristos static unsigned long
build_insn(struct d10v_opcode * opcode,expressionS * opers,unsigned long insn)515*1424dfb3Schristos build_insn (struct d10v_opcode *opcode,
516*1424dfb3Schristos 	    expressionS *opers,
517*1424dfb3Schristos 	    unsigned long insn)
518*1424dfb3Schristos {
519*1424dfb3Schristos   int i, bits, shift, flags, format;
520*1424dfb3Schristos   unsigned long number;
521*1424dfb3Schristos 
522*1424dfb3Schristos   /* The insn argument is only used for the DIVS kludge.  */
523*1424dfb3Schristos   if (insn)
524*1424dfb3Schristos     format = LONG_R;
525*1424dfb3Schristos   else
526*1424dfb3Schristos     {
527*1424dfb3Schristos       insn = opcode->opcode;
528*1424dfb3Schristos       format = opcode->format;
529*1424dfb3Schristos     }
530*1424dfb3Schristos 
531*1424dfb3Schristos   for (i = 0; opcode->operands[i]; i++)
532*1424dfb3Schristos     {
533*1424dfb3Schristos       flags = d10v_operands[opcode->operands[i]].flags;
534*1424dfb3Schristos       bits = d10v_operands[opcode->operands[i]].bits;
535*1424dfb3Schristos       shift = d10v_operands[opcode->operands[i]].shift;
536*1424dfb3Schristos       number = opers[i].X_add_number;
537*1424dfb3Schristos 
538*1424dfb3Schristos       if (flags & OPERAND_REG)
539*1424dfb3Schristos 	{
540*1424dfb3Schristos 	  number &= REGISTER_MASK;
541*1424dfb3Schristos 	  if (format == LONG_L)
542*1424dfb3Schristos 	    shift += 15;
543*1424dfb3Schristos 	}
544*1424dfb3Schristos 
545*1424dfb3Schristos       if (opers[i].X_op != O_register && opers[i].X_op != O_constant)
546*1424dfb3Schristos 	{
547*1424dfb3Schristos 	  /* Now create a fixup.  */
548*1424dfb3Schristos 
549*1424dfb3Schristos 	  if (fixups->fc >= MAX_INSN_FIXUPS)
550*1424dfb3Schristos 	    as_fatal (_("too many fixups"));
551*1424dfb3Schristos 
552*1424dfb3Schristos 	  if (AT_WORD_P (&opers[i]))
553*1424dfb3Schristos 	    {
554*1424dfb3Schristos 	      /* Recognize XXX>>1+N aka XXX@word+N as special (AT_WORD).  */
555*1424dfb3Schristos 	      fixups->fix[fixups->fc].reloc = BFD_RELOC_D10V_18;
556*1424dfb3Schristos 	      opers[i].X_op = O_symbol;
557*1424dfb3Schristos 	      opers[i].X_op_symbol = NULL; /* Should free it.  */
558*1424dfb3Schristos 	      /* number is left shifted by AT_WORD_RIGHT_SHIFT so
559*1424dfb3Schristos                  that, it is aligned with the symbol's value.  Later,
560*1424dfb3Schristos                  BFD_RELOC_D10V_18 will right shift (symbol_value +
561*1424dfb3Schristos                  X_add_number).  */
562*1424dfb3Schristos 	      number <<= AT_WORD_RIGHT_SHIFT;
563*1424dfb3Schristos 	      opers[i].X_add_number = number;
564*1424dfb3Schristos 	    }
565*1424dfb3Schristos 	  else
566*1424dfb3Schristos 	    {
567*1424dfb3Schristos 	      fixups->fix[fixups->fc].reloc =
568*1424dfb3Schristos 		get_reloc ((struct d10v_operand *) &d10v_operands[opcode->operands[i]]);
569*1424dfb3Schristos 
570*1424dfb3Schristos 	      /* Check that an immediate was passed to ops that expect one.  */
571*1424dfb3Schristos 	      if ((flags & OPERAND_NUM)
572*1424dfb3Schristos 		  && (fixups->fix[fixups->fc].reloc == 0))
573*1424dfb3Schristos 		as_bad (_("operand is not an immediate"));
574*1424dfb3Schristos 	    }
575*1424dfb3Schristos 
576*1424dfb3Schristos 	  if (fixups->fix[fixups->fc].reloc == BFD_RELOC_16 ||
577*1424dfb3Schristos 	      fixups->fix[fixups->fc].reloc == BFD_RELOC_D10V_18)
578*1424dfb3Schristos 	    fixups->fix[fixups->fc].size = 2;
579*1424dfb3Schristos 	  else
580*1424dfb3Schristos 	    fixups->fix[fixups->fc].size = 4;
581*1424dfb3Schristos 
582*1424dfb3Schristos 	  fixups->fix[fixups->fc].exp = opers[i];
583*1424dfb3Schristos 	  fixups->fix[fixups->fc].operand = opcode->operands[i];
584*1424dfb3Schristos 	  fixups->fix[fixups->fc].pcrel =
585*1424dfb3Schristos 	    (flags & OPERAND_ADDR) ? TRUE : FALSE;
586*1424dfb3Schristos 	  (fixups->fc)++;
587*1424dfb3Schristos 	}
588*1424dfb3Schristos 
589*1424dfb3Schristos       /* Truncate to the proper number of bits.  */
590*1424dfb3Schristos       if ((opers[i].X_op == O_constant) && check_range (number, bits, flags))
591*1424dfb3Schristos 	as_bad (_("operand out of range: %lu"), number);
592*1424dfb3Schristos       number &= 0x7FFFFFFF >> (31 - bits);
593*1424dfb3Schristos       insn = insn | (number << shift);
594*1424dfb3Schristos     }
595*1424dfb3Schristos 
596*1424dfb3Schristos   /* kludge: for DIVS, we need to put the operands in twice on the second
597*1424dfb3Schristos      pass, format is changed to LONG_R to force the second set of operands
598*1424dfb3Schristos      to not be shifted over 15.  */
599*1424dfb3Schristos   if ((opcode->opcode == OPCODE_DIVS) && (format == LONG_L))
600*1424dfb3Schristos     insn = build_insn (opcode, opers, insn);
601*1424dfb3Schristos 
602*1424dfb3Schristos   return insn;
603*1424dfb3Schristos }
604*1424dfb3Schristos 
605*1424dfb3Schristos /* Write out a long form instruction.  */
606*1424dfb3Schristos 
607*1424dfb3Schristos static void
write_long(unsigned long insn,Fixups * fx)608*1424dfb3Schristos write_long (unsigned long insn, Fixups *fx)
609*1424dfb3Schristos {
610*1424dfb3Schristos   int i, where;
611*1424dfb3Schristos   char *f = frag_more (4);
612*1424dfb3Schristos 
613*1424dfb3Schristos   dwarf2_emit_insn (4);
614*1424dfb3Schristos   insn |= FM11;
615*1424dfb3Schristos   number_to_chars_bigendian (f, insn, 4);
616*1424dfb3Schristos 
617*1424dfb3Schristos   for (i = 0; i < fx->fc; i++)
618*1424dfb3Schristos     {
619*1424dfb3Schristos       if (fx->fix[i].reloc)
620*1424dfb3Schristos 	{
621*1424dfb3Schristos 	  where = f - frag_now->fr_literal;
622*1424dfb3Schristos 	  if (fx->fix[i].size == 2)
623*1424dfb3Schristos 	    where += 2;
624*1424dfb3Schristos 
625*1424dfb3Schristos 	  if (fx->fix[i].reloc == BFD_RELOC_D10V_18)
626*1424dfb3Schristos 	    fx->fix[i].operand |= 4096;
627*1424dfb3Schristos 
628*1424dfb3Schristos 	  fix_new_exp (frag_now,
629*1424dfb3Schristos 		       where,
630*1424dfb3Schristos 		       fx->fix[i].size,
631*1424dfb3Schristos 		       &(fx->fix[i].exp),
632*1424dfb3Schristos 		       fx->fix[i].pcrel,
633*1424dfb3Schristos 		       fx->fix[i].operand|2048);
634*1424dfb3Schristos 	}
635*1424dfb3Schristos     }
636*1424dfb3Schristos   fx->fc = 0;
637*1424dfb3Schristos }
638*1424dfb3Schristos 
639*1424dfb3Schristos /* Write out a short form instruction by itself.  */
640*1424dfb3Schristos 
641*1424dfb3Schristos static void
write_1_short(struct d10v_opcode * opcode,unsigned long insn,Fixups * fx)642*1424dfb3Schristos write_1_short (struct d10v_opcode *opcode,
643*1424dfb3Schristos 	       unsigned long insn,
644*1424dfb3Schristos 	       Fixups *fx)
645*1424dfb3Schristos {
646*1424dfb3Schristos   char *f = frag_more (4);
647*1424dfb3Schristos   int i, where;
648*1424dfb3Schristos 
649*1424dfb3Schristos   dwarf2_emit_insn (4);
650*1424dfb3Schristos   if (opcode->exec_type & PARONLY)
651*1424dfb3Schristos     as_fatal (_("Instruction must be executed in parallel with another instruction."));
652*1424dfb3Schristos 
653*1424dfb3Schristos   /* The other container needs to be NOP.
654*1424dfb3Schristos      According to 4.3.1: for FM=00, sub-instructions performed only by IU
655*1424dfb3Schristos      cannot be encoded in L-container.  */
656*1424dfb3Schristos   if (opcode->unit == IU)
657*1424dfb3Schristos     insn |= FM00 | (NOP << 15);		/* Right container.  */
658*1424dfb3Schristos   else
659*1424dfb3Schristos     insn = FM00 | (insn << 15) | NOP;	/* Left container.  */
660*1424dfb3Schristos 
661*1424dfb3Schristos   number_to_chars_bigendian (f, insn, 4);
662*1424dfb3Schristos   for (i = 0; i < fx->fc; i++)
663*1424dfb3Schristos     {
664*1424dfb3Schristos       if (fx->fix[i].reloc)
665*1424dfb3Schristos 	{
666*1424dfb3Schristos 	  where = f - frag_now->fr_literal;
667*1424dfb3Schristos 	  if (fx->fix[i].size == 2)
668*1424dfb3Schristos 	    where += 2;
669*1424dfb3Schristos 
670*1424dfb3Schristos 	  if (fx->fix[i].reloc == BFD_RELOC_D10V_18)
671*1424dfb3Schristos 	    fx->fix[i].operand |= 4096;
672*1424dfb3Schristos 
673*1424dfb3Schristos 	  /* If it's an R reloc, we may have to switch it to L.  */
674*1424dfb3Schristos 	  if ((fx->fix[i].reloc == BFD_RELOC_D10V_10_PCREL_R)
675*1424dfb3Schristos 	      && (opcode->unit != IU))
676*1424dfb3Schristos 	    fx->fix[i].operand |= 1024;
677*1424dfb3Schristos 
678*1424dfb3Schristos 	  fix_new_exp (frag_now,
679*1424dfb3Schristos 		       where,
680*1424dfb3Schristos 		       fx->fix[i].size,
681*1424dfb3Schristos 		       &(fx->fix[i].exp),
682*1424dfb3Schristos 		       fx->fix[i].pcrel,
683*1424dfb3Schristos 		       fx->fix[i].operand|2048);
684*1424dfb3Schristos 	}
685*1424dfb3Schristos     }
686*1424dfb3Schristos   fx->fc = 0;
687*1424dfb3Schristos }
688*1424dfb3Schristos 
689*1424dfb3Schristos /* Determine if there are any resource conflicts among two manually
690*1424dfb3Schristos    parallelized instructions.  Some of this was lifted from parallel_ok.  */
691*1424dfb3Schristos 
692*1424dfb3Schristos static void
check_resource_conflict(struct d10v_opcode * op1,unsigned long insn1,struct d10v_opcode * op2,unsigned long insn2)693*1424dfb3Schristos check_resource_conflict (struct d10v_opcode *op1,
694*1424dfb3Schristos 			 unsigned long insn1,
695*1424dfb3Schristos 			 struct d10v_opcode *op2,
696*1424dfb3Schristos 			 unsigned long insn2)
697*1424dfb3Schristos {
698*1424dfb3Schristos   int i, j, flags, mask, shift, regno;
699*1424dfb3Schristos   unsigned long ins, mod[2];
700*1424dfb3Schristos   struct d10v_opcode *op;
701*1424dfb3Schristos 
702*1424dfb3Schristos   if ((op1->exec_type & SEQ)
703*1424dfb3Schristos       || ! ((op1->exec_type & PAR) || (op1->exec_type & PARONLY)))
704*1424dfb3Schristos     {
705*1424dfb3Schristos       as_warn (_("packing conflict: %s must dispatch sequentially"),
706*1424dfb3Schristos 	      op1->name);
707*1424dfb3Schristos       return;
708*1424dfb3Schristos     }
709*1424dfb3Schristos 
710*1424dfb3Schristos   if ((op2->exec_type & SEQ)
711*1424dfb3Schristos       || ! ((op2->exec_type & PAR) || (op2->exec_type & PARONLY)))
712*1424dfb3Schristos     {
713*1424dfb3Schristos       as_warn (_("packing conflict: %s must dispatch sequentially"),
714*1424dfb3Schristos 	      op2->name);
715*1424dfb3Schristos       return;
716*1424dfb3Schristos     }
717*1424dfb3Schristos 
718*1424dfb3Schristos    /* See if both instructions write to the same resource.
719*1424dfb3Schristos 
720*1424dfb3Schristos       The idea here is to create two sets of bitmasks (mod and used) which
721*1424dfb3Schristos       indicate which registers are modified or used by each instruction.
722*1424dfb3Schristos       The operation can only be done in parallel if neither instruction
723*1424dfb3Schristos       modifies the same register. Accesses to control registers and memory
724*1424dfb3Schristos       are treated as accesses to a single register. So if both instructions
725*1424dfb3Schristos       write memory or if the first instruction writes memory and the second
726*1424dfb3Schristos       reads, then they cannot be done in parallel. We treat reads to the PSW
727*1424dfb3Schristos       (which includes C, F0, and F1) in isolation. So simultaneously writing
728*1424dfb3Schristos       C and F0 in two different sub-instructions is permitted.  */
729*1424dfb3Schristos 
730*1424dfb3Schristos   /* The bitmasks (mod and used) look like this (bit 31 = MSB).
731*1424dfb3Schristos      r0-r15	  0-15
732*1424dfb3Schristos      a0-a1	  16-17
733*1424dfb3Schristos      cr (not psw) 18
734*1424dfb3Schristos      psw(other)   19
735*1424dfb3Schristos      mem	  20
736*1424dfb3Schristos      psw(C flag)  21
737*1424dfb3Schristos      psw(F0 flag) 22  */
738*1424dfb3Schristos 
739*1424dfb3Schristos   for (j = 0; j < 2; j++)
740*1424dfb3Schristos     {
741*1424dfb3Schristos       if (j == 0)
742*1424dfb3Schristos 	{
743*1424dfb3Schristos 	  op = op1;
744*1424dfb3Schristos 	  ins = insn1;
745*1424dfb3Schristos 	}
746*1424dfb3Schristos       else
747*1424dfb3Schristos 	{
748*1424dfb3Schristos 	  op = op2;
749*1424dfb3Schristos 	  ins = insn2;
750*1424dfb3Schristos 	}
751*1424dfb3Schristos       mod[j] = 0;
752*1424dfb3Schristos       if (op->exec_type & BRANCH_LINK)
753*1424dfb3Schristos 	mod[j] |= 1 << 13;
754*1424dfb3Schristos 
755*1424dfb3Schristos       for (i = 0; op->operands[i]; i++)
756*1424dfb3Schristos 	{
757*1424dfb3Schristos 	  flags = d10v_operands[op->operands[i]].flags;
758*1424dfb3Schristos 	  shift = d10v_operands[op->operands[i]].shift;
759*1424dfb3Schristos 	  mask = 0x7FFFFFFF >> (31 - d10v_operands[op->operands[i]].bits);
760*1424dfb3Schristos 	  if (flags & OPERAND_REG)
761*1424dfb3Schristos 	    {
762*1424dfb3Schristos 	      regno = (ins >> shift) & mask;
763*1424dfb3Schristos 	      if (flags & (OPERAND_ACC0 | OPERAND_ACC1))
764*1424dfb3Schristos 		regno += 16;
765*1424dfb3Schristos 	      else if (flags & OPERAND_CONTROL)	/* mvtc or mvfc */
766*1424dfb3Schristos 		{
767*1424dfb3Schristos 		  if (regno == 0)
768*1424dfb3Schristos 		    regno = 19;
769*1424dfb3Schristos 		  else
770*1424dfb3Schristos 		    regno = 18;
771*1424dfb3Schristos 		}
772*1424dfb3Schristos 	      else if (flags & OPERAND_FFLAG)
773*1424dfb3Schristos 		regno = 22;
774*1424dfb3Schristos 	      else if (flags & OPERAND_CFLAG)
775*1424dfb3Schristos 		regno = 21;
776*1424dfb3Schristos 
777*1424dfb3Schristos 	      if (flags & OPERAND_DEST
778*1424dfb3Schristos 		  /* Auto inc/dec also modifies the register.  */
779*1424dfb3Schristos 		  || (op->operands[i + 1] != 0
780*1424dfb3Schristos 		      && (d10v_operands[op->operands[i + 1]].flags
781*1424dfb3Schristos 			  & (OPERAND_PLUS | OPERAND_MINUS)) != 0))
782*1424dfb3Schristos 		{
783*1424dfb3Schristos 		  mod[j] |= 1 << regno;
784*1424dfb3Schristos 		  if (flags & OPERAND_EVEN)
785*1424dfb3Schristos 		    mod[j] |= 1 << (regno + 1);
786*1424dfb3Schristos 		}
787*1424dfb3Schristos 	    }
788*1424dfb3Schristos 	  else if (flags & OPERAND_ATMINUS)
789*1424dfb3Schristos 	    {
790*1424dfb3Schristos 	      /* SP implicitly used/modified.  */
791*1424dfb3Schristos 	      mod[j] |= 1 << 15;
792*1424dfb3Schristos 	    }
793*1424dfb3Schristos 	}
794*1424dfb3Schristos 
795*1424dfb3Schristos       if (op->exec_type & WMEM)
796*1424dfb3Schristos 	mod[j] |= 1 << 20;
797*1424dfb3Schristos       else if (op->exec_type & WF0)
798*1424dfb3Schristos 	mod[j] |= 1 << 22;
799*1424dfb3Schristos       else if (op->exec_type & WCAR)
800*1424dfb3Schristos 	mod[j] |= 1 << 21;
801*1424dfb3Schristos     }
802*1424dfb3Schristos 
803*1424dfb3Schristos   if ((mod[0] & mod[1]) == 0)
804*1424dfb3Schristos     return;
805*1424dfb3Schristos   else
806*1424dfb3Schristos     {
807*1424dfb3Schristos       unsigned long x;
808*1424dfb3Schristos       x = mod[0] & mod[1];
809*1424dfb3Schristos 
810*1424dfb3Schristos       for (j = 0; j <= 15; j++)
811*1424dfb3Schristos 	if (x & (1 << j))
812*1424dfb3Schristos 	  as_warn (_("resource conflict (R%d)"), j);
813*1424dfb3Schristos       for (j = 16; j <= 17; j++)
814*1424dfb3Schristos 	if (x & (1 << j))
815*1424dfb3Schristos 	  as_warn (_("resource conflict (A%d)"), j - 16);
816*1424dfb3Schristos       if (x & (1 << 19))
817*1424dfb3Schristos 	as_warn (_("resource conflict (PSW)"));
818*1424dfb3Schristos       if (x & (1 << 21))
819*1424dfb3Schristos 	as_warn (_("resource conflict (C flag)"));
820*1424dfb3Schristos       if (x & (1 << 22))
821*1424dfb3Schristos 	as_warn (_("resource conflict (F flag)"));
822*1424dfb3Schristos     }
823*1424dfb3Schristos }
824*1424dfb3Schristos 
825*1424dfb3Schristos /* Check 2 instructions and determine if they can be safely
826*1424dfb3Schristos    executed in parallel.  Return 1 if they can be.  */
827*1424dfb3Schristos 
828*1424dfb3Schristos static int
parallel_ok(struct d10v_opcode * op1,unsigned long insn1,struct d10v_opcode * op2,unsigned long insn2,packing_type exec_type)829*1424dfb3Schristos parallel_ok (struct d10v_opcode *op1,
830*1424dfb3Schristos 	     unsigned long insn1,
831*1424dfb3Schristos 	     struct d10v_opcode *op2,
832*1424dfb3Schristos 	     unsigned long insn2,
833*1424dfb3Schristos 	     packing_type exec_type)
834*1424dfb3Schristos {
835*1424dfb3Schristos   int i, j, flags, mask, shift, regno;
836*1424dfb3Schristos   unsigned long ins, mod[2], used[2];
837*1424dfb3Schristos   struct d10v_opcode *op;
838*1424dfb3Schristos 
839*1424dfb3Schristos   if ((op1->exec_type & SEQ) != 0 || (op2->exec_type & SEQ) != 0
840*1424dfb3Schristos       || (op1->exec_type & PAR) == 0 || (op2->exec_type & PAR) == 0
841*1424dfb3Schristos       || (op1->unit == BOTH) || (op2->unit == BOTH)
842*1424dfb3Schristos       || (op1->unit == IU && op2->unit == IU)
843*1424dfb3Schristos       || (op1->unit == MU && op2->unit == MU))
844*1424dfb3Schristos     return 0;
845*1424dfb3Schristos 
846*1424dfb3Schristos   /* If this is auto parallelization, and the first instruction is a
847*1424dfb3Schristos      branch or should not be packed, then don't parallelize.  */
848*1424dfb3Schristos   if (exec_type == PACK_UNSPEC
849*1424dfb3Schristos       && (op1->exec_type & (ALONE | BRANCH)))
850*1424dfb3Schristos     return 0;
851*1424dfb3Schristos 
852*1424dfb3Schristos   /* The idea here is to create two sets of bitmasks (mod and used)
853*1424dfb3Schristos      which indicate which registers are modified or used by each
854*1424dfb3Schristos      instruction.  The operation can only be done in parallel if
855*1424dfb3Schristos      instruction 1 and instruction 2 modify different registers, and
856*1424dfb3Schristos      the first instruction does not modify registers that the second
857*1424dfb3Schristos      is using (The second instruction can modify registers that the
858*1424dfb3Schristos      first is using as they are only written back after the first
859*1424dfb3Schristos      instruction has completed).  Accesses to control registers, PSW,
860*1424dfb3Schristos      and memory are treated as accesses to a single register.  So if
861*1424dfb3Schristos      both instructions write memory or if the first instruction writes
862*1424dfb3Schristos      memory and the second reads, then they cannot be done in
863*1424dfb3Schristos      parallel.  Likewise, if the first instruction mucks with the psw
864*1424dfb3Schristos      and the second reads the PSW (which includes C, F0, and F1), then
865*1424dfb3Schristos      they cannot operate safely in parallel.  */
866*1424dfb3Schristos 
867*1424dfb3Schristos   /* The bitmasks (mod and used) look like this (bit 31 = MSB).
868*1424dfb3Schristos      r0-r15	  0-15
869*1424dfb3Schristos      a0-a1	  16-17
870*1424dfb3Schristos      cr (not psw) 18
871*1424dfb3Schristos      psw	  19
872*1424dfb3Schristos      mem	  20  */
873*1424dfb3Schristos 
874*1424dfb3Schristos   for (j = 0; j < 2; j++)
875*1424dfb3Schristos     {
876*1424dfb3Schristos       if (j == 0)
877*1424dfb3Schristos 	{
878*1424dfb3Schristos 	  op = op1;
879*1424dfb3Schristos 	  ins = insn1;
880*1424dfb3Schristos 	}
881*1424dfb3Schristos       else
882*1424dfb3Schristos 	{
883*1424dfb3Schristos 	  op = op2;
884*1424dfb3Schristos 	  ins = insn2;
885*1424dfb3Schristos 	}
886*1424dfb3Schristos       mod[j] = used[j] = 0;
887*1424dfb3Schristos       if (op->exec_type & BRANCH_LINK)
888*1424dfb3Schristos 	mod[j] |= 1 << 13;
889*1424dfb3Schristos 
890*1424dfb3Schristos       for (i = 0; op->operands[i]; i++)
891*1424dfb3Schristos 	{
892*1424dfb3Schristos 	  flags = d10v_operands[op->operands[i]].flags;
893*1424dfb3Schristos 	  shift = d10v_operands[op->operands[i]].shift;
894*1424dfb3Schristos 	  mask = 0x7FFFFFFF >> (31 - d10v_operands[op->operands[i]].bits);
895*1424dfb3Schristos 	  if (flags & OPERAND_REG)
896*1424dfb3Schristos 	    {
897*1424dfb3Schristos 	      regno = (ins >> shift) & mask;
898*1424dfb3Schristos 	      if (flags & (OPERAND_ACC0 | OPERAND_ACC1))
899*1424dfb3Schristos 		regno += 16;
900*1424dfb3Schristos 	      else if (flags & OPERAND_CONTROL)	/* mvtc or mvfc.  */
901*1424dfb3Schristos 		{
902*1424dfb3Schristos 		  if (regno == 0)
903*1424dfb3Schristos 		    regno = 19;
904*1424dfb3Schristos 		  else
905*1424dfb3Schristos 		    regno = 18;
906*1424dfb3Schristos 		}
907*1424dfb3Schristos 	      else if (flags & (OPERAND_FFLAG | OPERAND_CFLAG))
908*1424dfb3Schristos 		regno = 19;
909*1424dfb3Schristos 
910*1424dfb3Schristos 	      if (flags & OPERAND_DEST)
911*1424dfb3Schristos 		{
912*1424dfb3Schristos 		  mod[j] |= 1 << regno;
913*1424dfb3Schristos 		  if (flags & OPERAND_EVEN)
914*1424dfb3Schristos 		    mod[j] |= 1 << (regno + 1);
915*1424dfb3Schristos 		}
916*1424dfb3Schristos 	      else
917*1424dfb3Schristos 		{
918*1424dfb3Schristos 		  used[j] |= 1 << regno;
919*1424dfb3Schristos 		  if (flags & OPERAND_EVEN)
920*1424dfb3Schristos 		    used[j] |= 1 << (regno + 1);
921*1424dfb3Schristos 
922*1424dfb3Schristos 		  /* Auto inc/dec also modifies the register.  */
923*1424dfb3Schristos 		  if (op->operands[i + 1] != 0
924*1424dfb3Schristos 		      && (d10v_operands[op->operands[i + 1]].flags
925*1424dfb3Schristos 			  & (OPERAND_PLUS | OPERAND_MINUS)) != 0)
926*1424dfb3Schristos 		    mod[j] |= 1 << regno;
927*1424dfb3Schristos 		}
928*1424dfb3Schristos 	    }
929*1424dfb3Schristos 	  else if (flags & OPERAND_ATMINUS)
930*1424dfb3Schristos 	    {
931*1424dfb3Schristos 	      /* SP implicitly used/modified.  */
932*1424dfb3Schristos 	      mod[j] |= 1 << 15;
933*1424dfb3Schristos 	      used[j] |= 1 << 15;
934*1424dfb3Schristos 	    }
935*1424dfb3Schristos 	}
936*1424dfb3Schristos       if (op->exec_type & RMEM)
937*1424dfb3Schristos 	used[j] |= 1 << 20;
938*1424dfb3Schristos       else if (op->exec_type & WMEM)
939*1424dfb3Schristos 	mod[j] |= 1 << 20;
940*1424dfb3Schristos       else if (op->exec_type & RF0)
941*1424dfb3Schristos 	used[j] |= 1 << 19;
942*1424dfb3Schristos       else if (op->exec_type & WF0)
943*1424dfb3Schristos 	mod[j] |= 1 << 19;
944*1424dfb3Schristos       else if (op->exec_type & WCAR)
945*1424dfb3Schristos 	mod[j] |= 1 << 19;
946*1424dfb3Schristos     }
947*1424dfb3Schristos   if ((mod[0] & mod[1]) == 0 && (mod[0] & used[1]) == 0)
948*1424dfb3Schristos     return 1;
949*1424dfb3Schristos   return 0;
950*1424dfb3Schristos }
951*1424dfb3Schristos 
952*1424dfb3Schristos /* Expects two short instructions.
953*1424dfb3Schristos    If possible, writes out both as a single packed instruction.
954*1424dfb3Schristos    Otherwise, writes out the first one, packed with a NOP.
955*1424dfb3Schristos    Returns number of instructions not written out.  */
956*1424dfb3Schristos 
957*1424dfb3Schristos static int
write_2_short(struct d10v_opcode * opcode1,unsigned long insn1,struct d10v_opcode * opcode2,unsigned long insn2,packing_type exec_type,Fixups * fx)958*1424dfb3Schristos write_2_short (struct d10v_opcode *opcode1,
959*1424dfb3Schristos 	       unsigned long insn1,
960*1424dfb3Schristos 	       struct d10v_opcode *opcode2,
961*1424dfb3Schristos 	       unsigned long insn2,
962*1424dfb3Schristos 	       packing_type exec_type,
963*1424dfb3Schristos 	       Fixups *fx)
964*1424dfb3Schristos {
965*1424dfb3Schristos   unsigned long insn;
966*1424dfb3Schristos   char *f;
967*1424dfb3Schristos   int i, j, where;
968*1424dfb3Schristos 
969*1424dfb3Schristos   if ((exec_type != PACK_PARALLEL)
970*1424dfb3Schristos       && ((opcode1->exec_type & PARONLY) || (opcode2->exec_type & PARONLY)))
971*1424dfb3Schristos     as_fatal (_("Instruction must be executed in parallel"));
972*1424dfb3Schristos 
973*1424dfb3Schristos   if ((opcode1->format & LONG_OPCODE) || (opcode2->format & LONG_OPCODE))
974*1424dfb3Schristos     as_fatal (_("Long instructions may not be combined."));
975*1424dfb3Schristos 
976*1424dfb3Schristos   switch (exec_type)
977*1424dfb3Schristos     {
978*1424dfb3Schristos     case PACK_UNSPEC:	/* Order not specified.  */
979*1424dfb3Schristos       if (opcode1->exec_type & ALONE)
980*1424dfb3Schristos 	{
981*1424dfb3Schristos 	  /* Case of a short branch on a separate GAS line.  Pack with NOP.  */
982*1424dfb3Schristos 	  write_1_short (opcode1, insn1, fx->next);
983*1424dfb3Schristos 	  return 1;
984*1424dfb3Schristos 	}
985*1424dfb3Schristos       if (Optimizing
986*1424dfb3Schristos 	  && parallel_ok (opcode1, insn1, opcode2, insn2, exec_type))
987*1424dfb3Schristos 	{
988*1424dfb3Schristos 	  /* Parallel.  */
989*1424dfb3Schristos 	  if (opcode1->unit == IU)
990*1424dfb3Schristos 	    insn = FM00 | (insn2 << 15) | insn1;
991*1424dfb3Schristos 	  else if (opcode2->unit == MU)
992*1424dfb3Schristos 	    insn = FM00 | (insn2 << 15) | insn1;
993*1424dfb3Schristos 	  else
994*1424dfb3Schristos 	    insn = FM00 | (insn1 << 15) | insn2;
995*1424dfb3Schristos 	}
996*1424dfb3Schristos       else if (opcode1->unit == IU)
997*1424dfb3Schristos 	/* Reverse sequential with IU opcode1 on right and done first.  */
998*1424dfb3Schristos 	insn = FM10 | (insn2 << 15) | insn1;
999*1424dfb3Schristos       else
1000*1424dfb3Schristos 	/* Sequential with non-IU opcode1 on left and done first.  */
1001*1424dfb3Schristos 	insn = FM01 | (insn1 << 15) | insn2;
1002*1424dfb3Schristos       break;
1003*1424dfb3Schristos 
1004*1424dfb3Schristos     case PACK_PARALLEL:
1005*1424dfb3Schristos       if (opcode1->exec_type & SEQ || opcode2->exec_type & SEQ)
1006*1424dfb3Schristos 	as_fatal
1007*1424dfb3Schristos 	  (_("One of these instructions may not be executed in parallel."));
1008*1424dfb3Schristos       if (opcode1->unit == IU)
1009*1424dfb3Schristos 	{
1010*1424dfb3Schristos 	  if (opcode2->unit == IU)
1011*1424dfb3Schristos 	    as_fatal (_("Two IU instructions may not be executed in parallel"));
1012*1424dfb3Schristos 	  if (!flag_warn_suppress_instructionswap)
1013*1424dfb3Schristos 	    as_warn (_("Swapping instruction order"));
1014*1424dfb3Schristos 	  insn = FM00 | (insn2 << 15) | insn1;
1015*1424dfb3Schristos 	}
1016*1424dfb3Schristos       else if (opcode2->unit == MU)
1017*1424dfb3Schristos 	{
1018*1424dfb3Schristos 	  if (opcode1->unit == MU)
1019*1424dfb3Schristos 	    as_fatal (_("Two MU instructions may not be executed in parallel"));
1020*1424dfb3Schristos 	  if (!flag_warn_suppress_instructionswap)
1021*1424dfb3Schristos 	    as_warn (_("Swapping instruction order"));
1022*1424dfb3Schristos 	  insn = FM00 | (insn2 << 15) | insn1;
1023*1424dfb3Schristos 	}
1024*1424dfb3Schristos       else
1025*1424dfb3Schristos 	insn = FM00 | (insn1 << 15) | insn2;
1026*1424dfb3Schristos       check_resource_conflict (opcode1, insn1, opcode2, insn2);
1027*1424dfb3Schristos       break;
1028*1424dfb3Schristos 
1029*1424dfb3Schristos     case PACK_LEFT_RIGHT:
1030*1424dfb3Schristos       if (opcode1->unit != IU)
1031*1424dfb3Schristos 	insn = FM01 | (insn1 << 15) | insn2;
1032*1424dfb3Schristos       else if (opcode2->unit == MU || opcode2->unit == EITHER)
1033*1424dfb3Schristos 	{
1034*1424dfb3Schristos 	  if (!flag_warn_suppress_instructionswap)
1035*1424dfb3Schristos 	    as_warn (_("Swapping instruction order"));
1036*1424dfb3Schristos 	  insn = FM10 | (insn2 << 15) | insn1;
1037*1424dfb3Schristos 	}
1038*1424dfb3Schristos       else
1039*1424dfb3Schristos 	as_fatal (_("IU instruction may not be in the left container"));
1040*1424dfb3Schristos       if (opcode1->exec_type & ALONE)
1041*1424dfb3Schristos 	as_warn (_("Instruction in R container is squashed by flow control instruction in L container."));
1042*1424dfb3Schristos       break;
1043*1424dfb3Schristos 
1044*1424dfb3Schristos     case PACK_RIGHT_LEFT:
1045*1424dfb3Schristos       if (opcode2->unit != MU)
1046*1424dfb3Schristos 	insn = FM10 | (insn1 << 15) | insn2;
1047*1424dfb3Schristos       else if (opcode1->unit == IU || opcode1->unit == EITHER)
1048*1424dfb3Schristos 	{
1049*1424dfb3Schristos 	  if (!flag_warn_suppress_instructionswap)
1050*1424dfb3Schristos 	    as_warn (_("Swapping instruction order"));
1051*1424dfb3Schristos 	  insn = FM01 | (insn2 << 15) | insn1;
1052*1424dfb3Schristos 	}
1053*1424dfb3Schristos       else
1054*1424dfb3Schristos 	as_fatal (_("MU instruction may not be in the right container"));
1055*1424dfb3Schristos       if (opcode2->exec_type & ALONE)
1056*1424dfb3Schristos 	as_warn (_("Instruction in R container is squashed by flow control instruction in L container."));
1057*1424dfb3Schristos       break;
1058*1424dfb3Schristos 
1059*1424dfb3Schristos     default:
1060*1424dfb3Schristos       as_fatal (_("unknown execution type passed to write_2_short()"));
1061*1424dfb3Schristos     }
1062*1424dfb3Schristos 
1063*1424dfb3Schristos   f = frag_more (4);
1064*1424dfb3Schristos   dwarf2_emit_insn (4);
1065*1424dfb3Schristos   number_to_chars_bigendian (f, insn, 4);
1066*1424dfb3Schristos 
1067*1424dfb3Schristos   /* Process fixup chains.  fx refers to insn2 when j == 0, and to
1068*1424dfb3Schristos      insn1 when j == 1.  Yes, it's reversed.  */
1069*1424dfb3Schristos 
1070*1424dfb3Schristos   for (j = 0; j < 2; j++)
1071*1424dfb3Schristos     {
1072*1424dfb3Schristos       for (i = 0; i < fx->fc; i++)
1073*1424dfb3Schristos 	{
1074*1424dfb3Schristos 	  if (fx->fix[i].reloc)
1075*1424dfb3Schristos 	    {
1076*1424dfb3Schristos 	      where = f - frag_now->fr_literal;
1077*1424dfb3Schristos 	      if (fx->fix[i].size == 2)
1078*1424dfb3Schristos 		where += 2;
1079*1424dfb3Schristos 
1080*1424dfb3Schristos 	      if (fx->fix[i].reloc == BFD_RELOC_D10V_10_PCREL_R
1081*1424dfb3Schristos 		  /* A BFD_RELOC_D10V_10_PCREL_R relocation applied to
1082*1424dfb3Schristos 		     the instruction in the L container has to be
1083*1424dfb3Schristos 		     adjusted to BDF_RELOC_D10V_10_PCREL_L.  When
1084*1424dfb3Schristos 		     j==0, we're processing insn2's operands, so we
1085*1424dfb3Schristos 		     want to mark the operand if insn2 is *not* in the
1086*1424dfb3Schristos 		     R container.  When j==1, we're processing insn1's
1087*1424dfb3Schristos 		     operands, so we want to mark the operand if insn2
1088*1424dfb3Schristos 		     *is* in the R container.  Note that, if two
1089*1424dfb3Schristos 		     instructions are identical, we're never going to
1090*1424dfb3Schristos 		     swap them, so the test is safe.  */
1091*1424dfb3Schristos 		  && j == ((insn & 0x7fff) == insn2))
1092*1424dfb3Schristos 		fx->fix[i].operand |= 1024;
1093*1424dfb3Schristos 
1094*1424dfb3Schristos 	      if (fx->fix[i].reloc == BFD_RELOC_D10V_18)
1095*1424dfb3Schristos 		fx->fix[i].operand |= 4096;
1096*1424dfb3Schristos 
1097*1424dfb3Schristos 	      fix_new_exp (frag_now,
1098*1424dfb3Schristos 			   where,
1099*1424dfb3Schristos 			   fx->fix[i].size,
1100*1424dfb3Schristos 			   &(fx->fix[i].exp),
1101*1424dfb3Schristos 			   fx->fix[i].pcrel,
1102*1424dfb3Schristos 			   fx->fix[i].operand|2048);
1103*1424dfb3Schristos 	    }
1104*1424dfb3Schristos 	}
1105*1424dfb3Schristos       fx->fc = 0;
1106*1424dfb3Schristos       fx = fx->next;
1107*1424dfb3Schristos     }
1108*1424dfb3Schristos   return 0;
1109*1424dfb3Schristos }
1110*1424dfb3Schristos 
1111*1424dfb3Schristos /* This is the main entry point for the machine-dependent assembler.
1112*1424dfb3Schristos    str points to a machine-dependent instruction.  This function is
1113*1424dfb3Schristos    supposed to emit the frags/bytes it assembles to.  For the D10V, it
1114*1424dfb3Schristos    mostly handles the special VLIW parsing and packing and leaves the
1115*1424dfb3Schristos    difficult stuff to do_assemble().  */
1116*1424dfb3Schristos 
1117*1424dfb3Schristos static unsigned long prev_insn;
1118*1424dfb3Schristos static struct d10v_opcode *prev_opcode = 0;
1119*1424dfb3Schristos static subsegT prev_subseg;
1120*1424dfb3Schristos static segT prev_seg = 0;
1121*1424dfb3Schristos 
1122*1424dfb3Schristos /* Find the symbol which has the same name as the register in exp.  */
1123*1424dfb3Schristos 
1124*1424dfb3Schristos static symbolS *
find_symbol_matching_register(expressionS * exp)1125*1424dfb3Schristos find_symbol_matching_register (expressionS *exp)
1126*1424dfb3Schristos {
1127*1424dfb3Schristos   int i;
1128*1424dfb3Schristos 
1129*1424dfb3Schristos   if (exp->X_op != O_register)
1130*1424dfb3Schristos     return NULL;
1131*1424dfb3Schristos 
1132*1424dfb3Schristos   /* Find the name of the register.  */
1133*1424dfb3Schristos   for (i = d10v_reg_name_cnt (); i--;)
1134*1424dfb3Schristos     if (d10v_predefined_registers[i].value == exp->X_add_number)
1135*1424dfb3Schristos       break;
1136*1424dfb3Schristos 
1137*1424dfb3Schristos   if (i < 0)
1138*1424dfb3Schristos     abort ();
1139*1424dfb3Schristos 
1140*1424dfb3Schristos   /* Now see if a symbol has been defined with the same name.  */
1141*1424dfb3Schristos   return symbol_find (d10v_predefined_registers[i].name);
1142*1424dfb3Schristos }
1143*1424dfb3Schristos 
1144*1424dfb3Schristos /* Get a pointer to an entry in the opcode table.
1145*1424dfb3Schristos    The function must look at all opcodes with the same name and use
1146*1424dfb3Schristos    the operands to choose the correct opcode.  */
1147*1424dfb3Schristos 
1148*1424dfb3Schristos static struct d10v_opcode *
find_opcode(struct d10v_opcode * opcode,expressionS myops[])1149*1424dfb3Schristos find_opcode (struct d10v_opcode *opcode, expressionS myops[])
1150*1424dfb3Schristos {
1151*1424dfb3Schristos   int i, match;
1152*1424dfb3Schristos   struct d10v_opcode *next_opcode;
1153*1424dfb3Schristos 
1154*1424dfb3Schristos   /* Get all the operands and save them as expressions.  */
1155*1424dfb3Schristos   get_operands (myops);
1156*1424dfb3Schristos 
1157*1424dfb3Schristos   /* Now see if the operand is a fake.  If so, find the correct size
1158*1424dfb3Schristos      instruction, if possible.  */
1159*1424dfb3Schristos   if (opcode->format == OPCODE_FAKE)
1160*1424dfb3Schristos     {
1161*1424dfb3Schristos       int opnum = opcode->operands[0];
1162*1424dfb3Schristos       int flags;
1163*1424dfb3Schristos 
1164*1424dfb3Schristos       if (myops[opnum].X_op == O_register)
1165*1424dfb3Schristos 	{
1166*1424dfb3Schristos 	  myops[opnum].X_op = O_symbol;
1167*1424dfb3Schristos 	  myops[opnum].X_add_symbol =
1168*1424dfb3Schristos 	    symbol_find_or_make ((char *) myops[opnum].X_op_symbol);
1169*1424dfb3Schristos 	  myops[opnum].X_add_number = 0;
1170*1424dfb3Schristos 	  myops[opnum].X_op_symbol = NULL;
1171*1424dfb3Schristos 	}
1172*1424dfb3Schristos 
1173*1424dfb3Schristos       next_opcode = opcode + 1;
1174*1424dfb3Schristos 
1175*1424dfb3Schristos       /* If the first operand is supposed to be a register, make sure
1176*1424dfb3Schristos 	 we got a valid one.  */
1177*1424dfb3Schristos       flags = d10v_operands[next_opcode->operands[0]].flags;
1178*1424dfb3Schristos       if (flags & OPERAND_REG)
1179*1424dfb3Schristos 	{
1180*1424dfb3Schristos 	  int X_op = myops[0].X_op;
1181*1424dfb3Schristos 	  int num = myops[0].X_add_number;
1182*1424dfb3Schristos 
1183*1424dfb3Schristos 	  if (X_op != O_register
1184*1424dfb3Schristos 	      || (num & ~flags
1185*1424dfb3Schristos 		  & (OPERAND_GPR | OPERAND_ACC0 | OPERAND_ACC1
1186*1424dfb3Schristos 		     | OPERAND_FFLAG | OPERAND_CFLAG | OPERAND_CONTROL))
1187*1424dfb3Schristos 	      || ((flags & OPERAND_SP) && ! (num & OPERAND_SP)))
1188*1424dfb3Schristos 	    {
1189*1424dfb3Schristos 	      as_bad (_("bad opcode or operands"));
1190*1424dfb3Schristos 	      return 0;
1191*1424dfb3Schristos 	    }
1192*1424dfb3Schristos 	}
1193*1424dfb3Schristos 
1194*1424dfb3Schristos       if (myops[opnum].X_op == O_constant
1195*1424dfb3Schristos 	  || (myops[opnum].X_op == O_symbol
1196*1424dfb3Schristos 	      && S_IS_DEFINED (myops[opnum].X_add_symbol)
1197*1424dfb3Schristos 	      && (S_GET_SEGMENT (myops[opnum].X_add_symbol) == now_seg)))
1198*1424dfb3Schristos 	{
1199*1424dfb3Schristos 	  for (i = 0; opcode->operands[i + 1]; i++)
1200*1424dfb3Schristos 	    {
1201*1424dfb3Schristos 	      int bits = d10v_operands[next_opcode->operands[opnum]].bits;
1202*1424dfb3Schristos 
1203*1424dfb3Schristos 	      flags = d10v_operands[next_opcode->operands[opnum]].flags;
1204*1424dfb3Schristos 
1205*1424dfb3Schristos 	      if (flags & OPERAND_ADDR)
1206*1424dfb3Schristos 		bits += 2;
1207*1424dfb3Schristos 
1208*1424dfb3Schristos 	      if (myops[opnum].X_op == O_constant)
1209*1424dfb3Schristos 		{
1210*1424dfb3Schristos 		  if (!check_range (myops[opnum].X_add_number, bits, flags))
1211*1424dfb3Schristos 		    break;
1212*1424dfb3Schristos 		}
1213*1424dfb3Schristos 	      else
1214*1424dfb3Schristos 		{
1215*1424dfb3Schristos 		  fragS *sym_frag;
1216*1424dfb3Schristos 		  fragS *f;
1217*1424dfb3Schristos 		  unsigned long current_position;
1218*1424dfb3Schristos 		  unsigned long symbol_position;
1219*1424dfb3Schristos 		  unsigned long value;
1220*1424dfb3Schristos 		  bfd_boolean found_symbol;
1221*1424dfb3Schristos 
1222*1424dfb3Schristos 		  /* Calculate the address of the current instruction
1223*1424dfb3Schristos 		     and the address of the symbol.  Do this by summing
1224*1424dfb3Schristos 		     the offsets of previous frags until we reach the
1225*1424dfb3Schristos 		     frag containing the symbol, and the current frag.  */
1226*1424dfb3Schristos 		  sym_frag = symbol_get_frag (myops[opnum].X_add_symbol);
1227*1424dfb3Schristos 		  found_symbol = FALSE;
1228*1424dfb3Schristos 
1229*1424dfb3Schristos 		  current_position = frag_now_fix_octets ();
1230*1424dfb3Schristos 		  symbol_position = S_GET_VALUE (myops[opnum].X_add_symbol);
1231*1424dfb3Schristos 
1232*1424dfb3Schristos 		  for (f = frchain_now->frch_root; f; f = f->fr_next)
1233*1424dfb3Schristos 		    {
1234*1424dfb3Schristos 		      current_position += f->fr_fix + f->fr_offset;
1235*1424dfb3Schristos 
1236*1424dfb3Schristos 		      if (f == sym_frag)
1237*1424dfb3Schristos 			found_symbol = TRUE;
1238*1424dfb3Schristos 
1239*1424dfb3Schristos 		      if (! found_symbol)
1240*1424dfb3Schristos 			symbol_position += f->fr_fix + f->fr_offset;
1241*1424dfb3Schristos 		    }
1242*1424dfb3Schristos 
1243*1424dfb3Schristos 		  value = symbol_position;
1244*1424dfb3Schristos 
1245*1424dfb3Schristos 		  if (flags & OPERAND_ADDR)
1246*1424dfb3Schristos 		    value -= current_position;
1247*1424dfb3Schristos 
1248*1424dfb3Schristos 		  if (AT_WORD_P (&myops[opnum]))
1249*1424dfb3Schristos 		    {
1250*1424dfb3Schristos 		      if (bits > 4)
1251*1424dfb3Schristos 			{
1252*1424dfb3Schristos 			  bits += 2;
1253*1424dfb3Schristos 			  if (!check_range (value, bits, flags))
1254*1424dfb3Schristos 			    break;
1255*1424dfb3Schristos 			}
1256*1424dfb3Schristos 		    }
1257*1424dfb3Schristos 		  else if (!check_range (value, bits, flags))
1258*1424dfb3Schristos 		    break;
1259*1424dfb3Schristos 		}
1260*1424dfb3Schristos 	      next_opcode++;
1261*1424dfb3Schristos 	    }
1262*1424dfb3Schristos 
1263*1424dfb3Schristos 	  if (opcode->operands [i + 1] == 0)
1264*1424dfb3Schristos 	    as_fatal (_("value out of range"));
1265*1424dfb3Schristos 	  else
1266*1424dfb3Schristos 	    opcode = next_opcode;
1267*1424dfb3Schristos 	}
1268*1424dfb3Schristos       else
1269*1424dfb3Schristos 	/* Not a constant, so use a long instruction.  */
1270*1424dfb3Schristos 	opcode += 2;
1271*1424dfb3Schristos     }
1272*1424dfb3Schristos 
1273*1424dfb3Schristos   match = 0;
1274*1424dfb3Schristos 
1275*1424dfb3Schristos   /* Now search the opcode table table for one with operands
1276*1424dfb3Schristos      that matches what we've got.  */
1277*1424dfb3Schristos   while (!match)
1278*1424dfb3Schristos     {
1279*1424dfb3Schristos       match = 1;
1280*1424dfb3Schristos       for (i = 0; opcode->operands[i]; i++)
1281*1424dfb3Schristos 	{
1282*1424dfb3Schristos 	  int flags = d10v_operands[opcode->operands[i]].flags;
1283*1424dfb3Schristos 	  int X_op = myops[i].X_op;
1284*1424dfb3Schristos 	  int num = myops[i].X_add_number;
1285*1424dfb3Schristos 
1286*1424dfb3Schristos 	  if (X_op == 0)
1287*1424dfb3Schristos 	    {
1288*1424dfb3Schristos 	      match = 0;
1289*1424dfb3Schristos 	      break;
1290*1424dfb3Schristos 	    }
1291*1424dfb3Schristos 
1292*1424dfb3Schristos 	  if (flags & OPERAND_REG)
1293*1424dfb3Schristos 	    {
1294*1424dfb3Schristos 	      if ((X_op != O_register)
1295*1424dfb3Schristos 		  || (num & ~flags
1296*1424dfb3Schristos 		      & (OPERAND_GPR | OPERAND_ACC0 | OPERAND_ACC1
1297*1424dfb3Schristos 			 | OPERAND_FFLAG | OPERAND_CFLAG
1298*1424dfb3Schristos 			 | OPERAND_CONTROL))
1299*1424dfb3Schristos 		  || ((flags & OPERAND_SP) && ! (num & OPERAND_SP)))
1300*1424dfb3Schristos 		{
1301*1424dfb3Schristos 		  match = 0;
1302*1424dfb3Schristos 		  break;
1303*1424dfb3Schristos 		}
1304*1424dfb3Schristos 	    }
1305*1424dfb3Schristos 
1306*1424dfb3Schristos 	  if (((flags & OPERAND_MINUS)   && ((X_op != O_absent) || (num != OPERAND_MINUS))) ||
1307*1424dfb3Schristos 	      ((flags & OPERAND_PLUS)    && ((X_op != O_absent) || (num != OPERAND_PLUS))) ||
1308*1424dfb3Schristos 	      ((flags & OPERAND_ATMINUS) && ((X_op != O_absent) || (num != OPERAND_ATMINUS))) ||
1309*1424dfb3Schristos 	      ((flags & OPERAND_ATPAR)   && ((X_op != O_absent) || (num != OPERAND_ATPAR))) ||
1310*1424dfb3Schristos 	      ((flags & OPERAND_ATSIGN)  && ((X_op != O_absent) || ((num != OPERAND_ATSIGN) && (num != OPERAND_ATPAR)))))
1311*1424dfb3Schristos 	    {
1312*1424dfb3Schristos 	      match = 0;
1313*1424dfb3Schristos 	      break;
1314*1424dfb3Schristos 	    }
1315*1424dfb3Schristos 
1316*1424dfb3Schristos 	  /* Unfortunately, for the indirect operand in instructions such
1317*1424dfb3Schristos 	     as ``ldb r1, @(c,r14)'' this function can be passed
1318*1424dfb3Schristos 	     X_op == O_register (because 'c' is a valid register name).
1319*1424dfb3Schristos 	     However we cannot just ignore the case when X_op == O_register
1320*1424dfb3Schristos 	     but flags & OPERAND_REG is null, so we check to see if a symbol
1321*1424dfb3Schristos 	     of the same name as the register exists.  If the symbol does
1322*1424dfb3Schristos 	     exist, then the parser was unable to distinguish the two cases
1323*1424dfb3Schristos 	     and we fix things here. (Ref: PR14826)  */
1324*1424dfb3Schristos 
1325*1424dfb3Schristos 	  if (!(flags & OPERAND_REG) && (X_op == O_register))
1326*1424dfb3Schristos 	    {
1327*1424dfb3Schristos 	      symbolS * sym;
1328*1424dfb3Schristos 
1329*1424dfb3Schristos 	      sym = find_symbol_matching_register (& myops[i]);
1330*1424dfb3Schristos 
1331*1424dfb3Schristos 	      if (sym != NULL)
1332*1424dfb3Schristos 		{
1333*1424dfb3Schristos 		  myops[i].X_op = X_op = O_symbol;
1334*1424dfb3Schristos 		  myops[i].X_add_symbol = sym;
1335*1424dfb3Schristos 		}
1336*1424dfb3Schristos 	      else
1337*1424dfb3Schristos 		as_bad
1338*1424dfb3Schristos 		  (_("illegal operand - register name found where none expected"));
1339*1424dfb3Schristos 	    }
1340*1424dfb3Schristos 	}
1341*1424dfb3Schristos 
1342*1424dfb3Schristos       /* We're only done if the operands matched so far AND there
1343*1424dfb3Schristos 	     are no more to check.  */
1344*1424dfb3Schristos       if (match && myops[i].X_op == 0)
1345*1424dfb3Schristos 	break;
1346*1424dfb3Schristos       else
1347*1424dfb3Schristos 	match = 0;
1348*1424dfb3Schristos 
1349*1424dfb3Schristos       next_opcode = opcode + 1;
1350*1424dfb3Schristos 
1351*1424dfb3Schristos       if (next_opcode->opcode == 0)
1352*1424dfb3Schristos 	break;
1353*1424dfb3Schristos 
1354*1424dfb3Schristos       if (strcmp (next_opcode->name, opcode->name))
1355*1424dfb3Schristos 	break;
1356*1424dfb3Schristos 
1357*1424dfb3Schristos       opcode = next_opcode;
1358*1424dfb3Schristos     }
1359*1424dfb3Schristos 
1360*1424dfb3Schristos   if (!match)
1361*1424dfb3Schristos     {
1362*1424dfb3Schristos       as_bad (_("bad opcode or operands"));
1363*1424dfb3Schristos       return 0;
1364*1424dfb3Schristos     }
1365*1424dfb3Schristos 
1366*1424dfb3Schristos   /* Check that all registers that are required to be even are.
1367*1424dfb3Schristos      Also, if any operands were marked as registers, but were really symbols,
1368*1424dfb3Schristos      fix that here.  */
1369*1424dfb3Schristos   for (i = 0; opcode->operands[i]; i++)
1370*1424dfb3Schristos     {
1371*1424dfb3Schristos       if ((d10v_operands[opcode->operands[i]].flags & OPERAND_EVEN) &&
1372*1424dfb3Schristos 	  (myops[i].X_add_number & 1))
1373*1424dfb3Schristos 	as_fatal (_("Register number must be EVEN"));
1374*1424dfb3Schristos       if ((d10v_operands[opcode->operands[i]].flags & OPERAND_NOSP)
1375*1424dfb3Schristos 	  && (myops[i].X_add_number & OPERAND_SP))
1376*1424dfb3Schristos 	as_bad (_("Unsupported use of sp"));
1377*1424dfb3Schristos       if (myops[i].X_op == O_register)
1378*1424dfb3Schristos 	{
1379*1424dfb3Schristos 	  if (!(d10v_operands[opcode->operands[i]].flags & OPERAND_REG))
1380*1424dfb3Schristos 	    {
1381*1424dfb3Schristos 	      myops[i].X_op = O_symbol;
1382*1424dfb3Schristos 	      myops[i].X_add_symbol =
1383*1424dfb3Schristos 		symbol_find_or_make ((char *) myops[i].X_op_symbol);
1384*1424dfb3Schristos 	      myops[i].X_add_number = 0;
1385*1424dfb3Schristos 	      myops[i].X_op_symbol = NULL;
1386*1424dfb3Schristos 	    }
1387*1424dfb3Schristos 	}
1388*1424dfb3Schristos       if ((d10v_operands[opcode->operands[i]].flags & OPERAND_CONTROL)
1389*1424dfb3Schristos 	  && (myops[i].X_add_number == OPERAND_CONTROL + 4
1390*1424dfb3Schristos 	      || myops[i].X_add_number == OPERAND_CONTROL + 5
1391*1424dfb3Schristos 	      || myops[i].X_add_number == OPERAND_CONTROL + 6
1392*1424dfb3Schristos 	      || myops[i].X_add_number == OPERAND_CONTROL + 12
1393*1424dfb3Schristos 	      || myops[i].X_add_number == OPERAND_CONTROL + 13
1394*1424dfb3Schristos 	      || myops[i].X_add_number == OPERAND_CONTROL + 15))
1395*1424dfb3Schristos 	as_warn (_("cr%ld is a reserved control register"),
1396*1424dfb3Schristos 		 myops[i].X_add_number - OPERAND_CONTROL);
1397*1424dfb3Schristos     }
1398*1424dfb3Schristos   return opcode;
1399*1424dfb3Schristos }
1400*1424dfb3Schristos 
1401*1424dfb3Schristos /* Assemble a single instruction.
1402*1424dfb3Schristos    Return an opcode, or -1 (an invalid opcode) on error.  */
1403*1424dfb3Schristos 
1404*1424dfb3Schristos static unsigned long
do_assemble(char * str,struct d10v_opcode ** opcode)1405*1424dfb3Schristos do_assemble (char *str, struct d10v_opcode **opcode)
1406*1424dfb3Schristos {
1407*1424dfb3Schristos   unsigned char *op_start, *op_end;
1408*1424dfb3Schristos   char *save;
1409*1424dfb3Schristos   char name[20];
1410*1424dfb3Schristos   int nlen = 0;
1411*1424dfb3Schristos   expressionS myops[6];
1412*1424dfb3Schristos 
1413*1424dfb3Schristos   /* Drop leading whitespace.  */
1414*1424dfb3Schristos   while (*str == ' ')
1415*1424dfb3Schristos     str++;
1416*1424dfb3Schristos 
1417*1424dfb3Schristos   /* Find the opcode end.  */
1418*1424dfb3Schristos   for (op_start = op_end = (unsigned char *) str;
1419*1424dfb3Schristos        *op_end && !is_end_of_line[*op_end] && *op_end != ' ';
1420*1424dfb3Schristos        op_end++)
1421*1424dfb3Schristos     {
1422*1424dfb3Schristos       name[nlen] = TOLOWER (op_start[nlen]);
1423*1424dfb3Schristos       nlen++;
1424*1424dfb3Schristos       if (nlen == sizeof (name) - 1)
1425*1424dfb3Schristos 	break;
1426*1424dfb3Schristos     }
1427*1424dfb3Schristos   name[nlen] = 0;
1428*1424dfb3Schristos 
1429*1424dfb3Schristos   if (nlen == 0)
1430*1424dfb3Schristos     return -1;
1431*1424dfb3Schristos 
1432*1424dfb3Schristos   /* Find the first opcode with the proper name.  */
1433*1424dfb3Schristos   *opcode = (struct d10v_opcode *) str_hash_find (d10v_hash, name);
1434*1424dfb3Schristos   if (*opcode == NULL)
1435*1424dfb3Schristos     return -1;
1436*1424dfb3Schristos 
1437*1424dfb3Schristos   save = input_line_pointer;
1438*1424dfb3Schristos   input_line_pointer = (char *) op_end;
1439*1424dfb3Schristos   *opcode = find_opcode (*opcode, myops);
1440*1424dfb3Schristos   if (*opcode == 0)
1441*1424dfb3Schristos     return -1;
1442*1424dfb3Schristos   input_line_pointer = save;
1443*1424dfb3Schristos 
1444*1424dfb3Schristos   return build_insn ((*opcode), myops, 0);
1445*1424dfb3Schristos }
1446*1424dfb3Schristos 
1447*1424dfb3Schristos /* If while processing a fixup, a reloc really needs to be created.
1448*1424dfb3Schristos    Then it is done here.  */
1449*1424dfb3Schristos 
1450*1424dfb3Schristos arelent *
tc_gen_reloc(asection * seg ATTRIBUTE_UNUSED,fixS * fixp)1451*1424dfb3Schristos tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
1452*1424dfb3Schristos {
1453*1424dfb3Schristos   arelent *reloc;
1454*1424dfb3Schristos   reloc = XNEW (arelent);
1455*1424dfb3Schristos   reloc->sym_ptr_ptr = XNEW (asymbol *);
1456*1424dfb3Schristos   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1457*1424dfb3Schristos   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1458*1424dfb3Schristos   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1459*1424dfb3Schristos   if (reloc->howto == (reloc_howto_type *) NULL)
1460*1424dfb3Schristos     {
1461*1424dfb3Schristos       as_bad_where (fixp->fx_file, fixp->fx_line,
1462*1424dfb3Schristos 		    _("reloc %d not supported by object file format"),
1463*1424dfb3Schristos 		    (int) fixp->fx_r_type);
1464*1424dfb3Schristos       return NULL;
1465*1424dfb3Schristos     }
1466*1424dfb3Schristos 
1467*1424dfb3Schristos   if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
1468*1424dfb3Schristos     reloc->address = fixp->fx_offset;
1469*1424dfb3Schristos 
1470*1424dfb3Schristos   reloc->addend = 0;
1471*1424dfb3Schristos 
1472*1424dfb3Schristos   return reloc;
1473*1424dfb3Schristos }
1474*1424dfb3Schristos 
1475*1424dfb3Schristos int
md_estimate_size_before_relax(fragS * fragp ATTRIBUTE_UNUSED,asection * seg ATTRIBUTE_UNUSED)1476*1424dfb3Schristos md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
1477*1424dfb3Schristos 			       asection *seg ATTRIBUTE_UNUSED)
1478*1424dfb3Schristos {
1479*1424dfb3Schristos   abort ();
1480*1424dfb3Schristos   return 0;
1481*1424dfb3Schristos }
1482*1424dfb3Schristos 
1483*1424dfb3Schristos long
md_pcrel_from_section(fixS * fixp,segT sec)1484*1424dfb3Schristos md_pcrel_from_section (fixS *fixp, segT sec)
1485*1424dfb3Schristos {
1486*1424dfb3Schristos   if (fixp->fx_addsy != (symbolS *) NULL
1487*1424dfb3Schristos       && (!S_IS_DEFINED (fixp->fx_addsy)
1488*1424dfb3Schristos 	  || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
1489*1424dfb3Schristos     return 0;
1490*1424dfb3Schristos   return fixp->fx_frag->fr_address + fixp->fx_where;
1491*1424dfb3Schristos }
1492*1424dfb3Schristos 
1493*1424dfb3Schristos void
md_apply_fix(fixS * fixP,valueT * valP,segT seg ATTRIBUTE_UNUSED)1494*1424dfb3Schristos md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
1495*1424dfb3Schristos {
1496*1424dfb3Schristos   char *where;
1497*1424dfb3Schristos   unsigned long insn;
1498*1424dfb3Schristos   long value = *valP;
1499*1424dfb3Schristos   int op_type;
1500*1424dfb3Schristos   int left = 0;
1501*1424dfb3Schristos 
1502*1424dfb3Schristos   if (fixP->fx_addsy == (symbolS *) NULL)
1503*1424dfb3Schristos     fixP->fx_done = 1;
1504*1424dfb3Schristos 
1505*1424dfb3Schristos   /* We don't actually support subtracting a symbol.  */
1506*1424dfb3Schristos   if (fixP->fx_subsy != (symbolS *) NULL)
1507*1424dfb3Schristos     as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
1508*1424dfb3Schristos 
1509*1424dfb3Schristos   op_type = fixP->fx_r_type;
1510*1424dfb3Schristos   if (op_type & 2048)
1511*1424dfb3Schristos     {
1512*1424dfb3Schristos       op_type -= 2048;
1513*1424dfb3Schristos       if (op_type & 1024)
1514*1424dfb3Schristos 	{
1515*1424dfb3Schristos 	  op_type -= 1024;
1516*1424dfb3Schristos 	  fixP->fx_r_type = BFD_RELOC_D10V_10_PCREL_L;
1517*1424dfb3Schristos 	  left = 1;
1518*1424dfb3Schristos 	}
1519*1424dfb3Schristos       else if (op_type & 4096)
1520*1424dfb3Schristos 	{
1521*1424dfb3Schristos 	  op_type -= 4096;
1522*1424dfb3Schristos 	  fixP->fx_r_type = BFD_RELOC_D10V_18;
1523*1424dfb3Schristos 	}
1524*1424dfb3Schristos       else
1525*1424dfb3Schristos 	fixP->fx_r_type =
1526*1424dfb3Schristos 	  get_reloc ((struct d10v_operand *) &d10v_operands[op_type]);
1527*1424dfb3Schristos     }
1528*1424dfb3Schristos 
1529*1424dfb3Schristos   /* Fetch the instruction, insert the fully resolved operand
1530*1424dfb3Schristos      value, and stuff the instruction back again.  */
1531*1424dfb3Schristos   where = fixP->fx_frag->fr_literal + fixP->fx_where;
1532*1424dfb3Schristos   insn = bfd_getb32 ((unsigned char *) where);
1533*1424dfb3Schristos 
1534*1424dfb3Schristos   switch (fixP->fx_r_type)
1535*1424dfb3Schristos     {
1536*1424dfb3Schristos     case BFD_RELOC_D10V_10_PCREL_L:
1537*1424dfb3Schristos     case BFD_RELOC_D10V_10_PCREL_R:
1538*1424dfb3Schristos     case BFD_RELOC_D10V_18_PCREL:
1539*1424dfb3Schristos       /* If the fix is relative to a global symbol, not a section
1540*1424dfb3Schristos 	 symbol, then ignore the offset.
1541*1424dfb3Schristos          XXX - Do we have to worry about branches to a symbol + offset ?  */
1542*1424dfb3Schristos       if (fixP->fx_addsy != NULL
1543*1424dfb3Schristos 	  && S_IS_EXTERNAL (fixP->fx_addsy) )
1544*1424dfb3Schristos         {
1545*1424dfb3Schristos           segT fseg = S_GET_SEGMENT (fixP->fx_addsy);
1546*1424dfb3Schristos           segment_info_type *segf = seg_info(fseg);
1547*1424dfb3Schristos 
1548*1424dfb3Schristos 	  if ( segf && segf->sym != fixP->fx_addsy)
1549*1424dfb3Schristos 	    value = 0;
1550*1424dfb3Schristos         }
1551*1424dfb3Schristos       /* Fall through.  */
1552*1424dfb3Schristos     case BFD_RELOC_D10V_18:
1553*1424dfb3Schristos       /* Instruction addresses are always right-shifted by 2.  */
1554*1424dfb3Schristos       value >>= AT_WORD_RIGHT_SHIFT;
1555*1424dfb3Schristos       if (fixP->fx_size == 2)
1556*1424dfb3Schristos 	bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
1557*1424dfb3Schristos       else
1558*1424dfb3Schristos 	{
1559*1424dfb3Schristos 	  struct d10v_opcode *rep, *repi;
1560*1424dfb3Schristos 
1561*1424dfb3Schristos 	  rep = (struct d10v_opcode *) str_hash_find (d10v_hash, "rep");
1562*1424dfb3Schristos 	  repi = (struct d10v_opcode *) str_hash_find (d10v_hash, "repi");
1563*1424dfb3Schristos 	  if ((insn & FM11) == FM11
1564*1424dfb3Schristos 	      && ((repi != NULL
1565*1424dfb3Schristos 		   && (insn & repi->mask) == (unsigned) repi->opcode)
1566*1424dfb3Schristos 		  || (rep != NULL
1567*1424dfb3Schristos 		      && (insn & rep->mask) == (unsigned) rep->opcode))
1568*1424dfb3Schristos 	      && value < 4)
1569*1424dfb3Schristos 	    as_fatal
1570*1424dfb3Schristos 	      (_("line %d: rep or repi must include at least 4 instructions"),
1571*1424dfb3Schristos 	       fixP->fx_line);
1572*1424dfb3Schristos 	  insn =
1573*1424dfb3Schristos 	    d10v_insert_operand (insn, op_type, (offsetT) value, left, fixP);
1574*1424dfb3Schristos 	  bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1575*1424dfb3Schristos 	}
1576*1424dfb3Schristos       break;
1577*1424dfb3Schristos     case BFD_RELOC_32:
1578*1424dfb3Schristos       bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
1579*1424dfb3Schristos       break;
1580*1424dfb3Schristos     case BFD_RELOC_16:
1581*1424dfb3Schristos       bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
1582*1424dfb3Schristos       break;
1583*1424dfb3Schristos     case BFD_RELOC_8:
1584*1424dfb3Schristos       *where = value;
1585*1424dfb3Schristos       break;
1586*1424dfb3Schristos 
1587*1424dfb3Schristos     case BFD_RELOC_VTABLE_INHERIT:
1588*1424dfb3Schristos     case BFD_RELOC_VTABLE_ENTRY:
1589*1424dfb3Schristos       fixP->fx_done = 0;
1590*1424dfb3Schristos       return;
1591*1424dfb3Schristos 
1592*1424dfb3Schristos     default:
1593*1424dfb3Schristos       as_fatal (_("line %d: unknown relocation type: 0x%x"),
1594*1424dfb3Schristos 		fixP->fx_line, fixP->fx_r_type);
1595*1424dfb3Schristos     }
1596*1424dfb3Schristos }
1597*1424dfb3Schristos 
1598*1424dfb3Schristos /* d10v_cleanup() is called after the assembler has finished parsing
1599*1424dfb3Schristos    the input file, when a label is read from the input file, or when a
1600*1424dfb3Schristos    stab directive is output.  Because the D10V assembler sometimes
1601*1424dfb3Schristos    saves short instructions to see if it can package them with the
1602*1424dfb3Schristos    next instruction, there may be a short instruction that still needs
1603*1424dfb3Schristos    to be written.
1604*1424dfb3Schristos 
1605*1424dfb3Schristos    NOTE: accesses a global, etype.
1606*1424dfb3Schristos    NOTE: invoked by various macros such as md_cleanup: see.  */
1607*1424dfb3Schristos 
1608*1424dfb3Schristos int
d10v_cleanup(void)1609*1424dfb3Schristos d10v_cleanup (void)
1610*1424dfb3Schristos {
1611*1424dfb3Schristos   segT seg;
1612*1424dfb3Schristos   subsegT subseg;
1613*1424dfb3Schristos 
1614*1424dfb3Schristos   /* If cleanup was invoked because the assembler encountered, e.g., a
1615*1424dfb3Schristos      user label, we write out the pending instruction, if any.  If it
1616*1424dfb3Schristos      was invoked because the assembler is outputting a piece of line
1617*1424dfb3Schristos      debugging information, though, we write out the pending
1618*1424dfb3Schristos      instruction only if the --no-gstabs-packing command line switch
1619*1424dfb3Schristos      has been specified.  */
1620*1424dfb3Schristos   if (prev_opcode
1621*1424dfb3Schristos       && etype == PACK_UNSPEC
1622*1424dfb3Schristos       && (! outputting_stabs_line_debug || ! flag_allow_gstabs_packing))
1623*1424dfb3Schristos     {
1624*1424dfb3Schristos       seg = now_seg;
1625*1424dfb3Schristos       subseg = now_subseg;
1626*1424dfb3Schristos 
1627*1424dfb3Schristos       if (prev_seg)
1628*1424dfb3Schristos 	subseg_set (prev_seg, prev_subseg);
1629*1424dfb3Schristos 
1630*1424dfb3Schristos       write_1_short (prev_opcode, prev_insn, fixups->next);
1631*1424dfb3Schristos       subseg_set (seg, subseg);
1632*1424dfb3Schristos       prev_opcode = NULL;
1633*1424dfb3Schristos     }
1634*1424dfb3Schristos   return 1;
1635*1424dfb3Schristos }
1636*1424dfb3Schristos 
1637*1424dfb3Schristos void
d10v_frob_label(symbolS * lab)1638*1424dfb3Schristos d10v_frob_label (symbolS *lab)
1639*1424dfb3Schristos {
1640*1424dfb3Schristos   d10v_cleanup ();
1641*1424dfb3Schristos   symbol_set_frag (lab, frag_now);
1642*1424dfb3Schristos   S_SET_VALUE (lab, (valueT) frag_now_fix ());
1643*1424dfb3Schristos   dwarf2_emit_label (lab);
1644*1424dfb3Schristos }
1645*1424dfb3Schristos 
1646*1424dfb3Schristos /* Like normal .word, except support @word.
1647*1424dfb3Schristos    Clobbers input_line_pointer, checks end-of-line.  */
1648*1424dfb3Schristos 
1649*1424dfb3Schristos static void
d10v_dot_word(int dummy ATTRIBUTE_UNUSED)1650*1424dfb3Schristos d10v_dot_word (int dummy ATTRIBUTE_UNUSED)
1651*1424dfb3Schristos {
1652*1424dfb3Schristos   expressionS exp;
1653*1424dfb3Schristos   char *p;
1654*1424dfb3Schristos 
1655*1424dfb3Schristos   if (is_it_end_of_statement ())
1656*1424dfb3Schristos     {
1657*1424dfb3Schristos       demand_empty_rest_of_line ();
1658*1424dfb3Schristos       return;
1659*1424dfb3Schristos     }
1660*1424dfb3Schristos 
1661*1424dfb3Schristos   do
1662*1424dfb3Schristos     {
1663*1424dfb3Schristos       expression (&exp);
1664*1424dfb3Schristos       if (!strncasecmp (input_line_pointer, "@word", 5))
1665*1424dfb3Schristos 	{
1666*1424dfb3Schristos 	  exp.X_add_number = 0;
1667*1424dfb3Schristos 	  input_line_pointer += 5;
1668*1424dfb3Schristos 
1669*1424dfb3Schristos 	  p = frag_more (2);
1670*1424dfb3Schristos 	  fix_new_exp (frag_now, p - frag_now->fr_literal, 2,
1671*1424dfb3Schristos 		       &exp, 0, BFD_RELOC_D10V_18);
1672*1424dfb3Schristos 	}
1673*1424dfb3Schristos       else
1674*1424dfb3Schristos 	emit_expr (&exp, 2);
1675*1424dfb3Schristos     }
1676*1424dfb3Schristos   while (*input_line_pointer++ == ',');
1677*1424dfb3Schristos 
1678*1424dfb3Schristos   input_line_pointer--;		/* Put terminator back into stream.  */
1679*1424dfb3Schristos   demand_empty_rest_of_line ();
1680*1424dfb3Schristos }
1681*1424dfb3Schristos 
1682*1424dfb3Schristos /* Mitsubishi asked that we support some old syntax that apparently
1683*1424dfb3Schristos    had immediate operands starting with '#'.  This is in some of their
1684*1424dfb3Schristos    sample code but is not documented (although it appears in some
1685*1424dfb3Schristos    examples in their assembler manual). For now, we'll solve this
1686*1424dfb3Schristos    compatibility problem by simply ignoring any '#' at the beginning
1687*1424dfb3Schristos    of an operand.  */
1688*1424dfb3Schristos 
1689*1424dfb3Schristos /* Operands that begin with '#' should fall through to here.
1690*1424dfb3Schristos    From expr.c.  */
1691*1424dfb3Schristos 
1692*1424dfb3Schristos void
md_operand(expressionS * expressionP)1693*1424dfb3Schristos md_operand (expressionS *expressionP)
1694*1424dfb3Schristos {
1695*1424dfb3Schristos   if (*input_line_pointer == '#' && ! do_not_ignore_hash)
1696*1424dfb3Schristos     {
1697*1424dfb3Schristos       input_line_pointer++;
1698*1424dfb3Schristos       expression (expressionP);
1699*1424dfb3Schristos     }
1700*1424dfb3Schristos }
1701*1424dfb3Schristos 
1702*1424dfb3Schristos bfd_boolean
d10v_fix_adjustable(fixS * fixP)1703*1424dfb3Schristos d10v_fix_adjustable (fixS *fixP)
1704*1424dfb3Schristos {
1705*1424dfb3Schristos   /* We need the symbol name for the VTABLE entries.  */
1706*1424dfb3Schristos   if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
1707*1424dfb3Schristos       || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
1708*1424dfb3Schristos     return 0;
1709*1424dfb3Schristos 
1710*1424dfb3Schristos   return 1;
1711*1424dfb3Schristos }
1712*1424dfb3Schristos 
1713*1424dfb3Schristos /* The target specific pseudo-ops which we support.  */
1714*1424dfb3Schristos const pseudo_typeS md_pseudo_table[] =
1715*1424dfb3Schristos {
1716*1424dfb3Schristos   { "word",	d10v_dot_word,	2 },
1717*1424dfb3Schristos   { NULL,       NULL,           0 }
1718*1424dfb3Schristos };
1719*1424dfb3Schristos 
1720*1424dfb3Schristos void
md_assemble(char * str)1721*1424dfb3Schristos md_assemble (char *str)
1722*1424dfb3Schristos {
1723*1424dfb3Schristos   /* etype is saved extype.  For multi-line instructions.  */
1724*1424dfb3Schristos   packing_type extype = PACK_UNSPEC;		/* Parallel, etc.  */
1725*1424dfb3Schristos   struct d10v_opcode *opcode;
1726*1424dfb3Schristos   unsigned long insn;
1727*1424dfb3Schristos   char *str2;
1728*1424dfb3Schristos 
1729*1424dfb3Schristos   if (etype == PACK_UNSPEC)
1730*1424dfb3Schristos     {
1731*1424dfb3Schristos       /* Look for the special multiple instruction separators.  */
1732*1424dfb3Schristos       str2 = strstr (str, "||");
1733*1424dfb3Schristos       if (str2)
1734*1424dfb3Schristos 	extype = PACK_PARALLEL;
1735*1424dfb3Schristos       else
1736*1424dfb3Schristos 	{
1737*1424dfb3Schristos 	  str2 = strstr (str, "->");
1738*1424dfb3Schristos 	  if (str2)
1739*1424dfb3Schristos 	    extype = PACK_LEFT_RIGHT;
1740*1424dfb3Schristos 	  else
1741*1424dfb3Schristos 	    {
1742*1424dfb3Schristos 	      str2 = strstr (str, "<-");
1743*1424dfb3Schristos 	      if (str2)
1744*1424dfb3Schristos 		extype = PACK_RIGHT_LEFT;
1745*1424dfb3Schristos 	    }
1746*1424dfb3Schristos 	}
1747*1424dfb3Schristos 
1748*1424dfb3Schristos       /* str2 points to the separator, if there is one.  */
1749*1424dfb3Schristos       if (str2)
1750*1424dfb3Schristos 	{
1751*1424dfb3Schristos 	  *str2 = 0;
1752*1424dfb3Schristos 
1753*1424dfb3Schristos 	  /* If two instructions are present and we already have one saved,
1754*1424dfb3Schristos 	     then first write out the saved one.  */
1755*1424dfb3Schristos 	  d10v_cleanup ();
1756*1424dfb3Schristos 
1757*1424dfb3Schristos 	  /* Assemble first instruction and save it.  */
1758*1424dfb3Schristos 	  prev_insn = do_assemble (str, &prev_opcode);
1759*1424dfb3Schristos 	  prev_seg = now_seg;
1760*1424dfb3Schristos 	  prev_subseg = now_subseg;
1761*1424dfb3Schristos 	  if (prev_insn == (unsigned long) -1)
1762*1424dfb3Schristos 	    as_fatal (_("can't find previous opcode "));
1763*1424dfb3Schristos 	  fixups = fixups->next;
1764*1424dfb3Schristos 	  str = str2 + 2;
1765*1424dfb3Schristos 	}
1766*1424dfb3Schristos     }
1767*1424dfb3Schristos 
1768*1424dfb3Schristos   insn = do_assemble (str, &opcode);
1769*1424dfb3Schristos   if (insn == (unsigned long) -1)
1770*1424dfb3Schristos     {
1771*1424dfb3Schristos       if (extype != PACK_UNSPEC)
1772*1424dfb3Schristos 	etype = extype;
1773*1424dfb3Schristos       else
1774*1424dfb3Schristos 	as_bad (_("could not assemble: %s"), str);
1775*1424dfb3Schristos       return;
1776*1424dfb3Schristos     }
1777*1424dfb3Schristos 
1778*1424dfb3Schristos   if (etype != PACK_UNSPEC)
1779*1424dfb3Schristos     {
1780*1424dfb3Schristos       extype = etype;
1781*1424dfb3Schristos       etype = PACK_UNSPEC;
1782*1424dfb3Schristos     }
1783*1424dfb3Schristos 
1784*1424dfb3Schristos   /* If this is a long instruction, write it and any previous short
1785*1424dfb3Schristos      instruction.  */
1786*1424dfb3Schristos   if (opcode->format & LONG_OPCODE)
1787*1424dfb3Schristos     {
1788*1424dfb3Schristos       if (extype != PACK_UNSPEC)
1789*1424dfb3Schristos 	as_fatal (_("Unable to mix instructions as specified"));
1790*1424dfb3Schristos       d10v_cleanup ();
1791*1424dfb3Schristos       write_long (insn, fixups);
1792*1424dfb3Schristos       prev_opcode = NULL;
1793*1424dfb3Schristos       return;
1794*1424dfb3Schristos     }
1795*1424dfb3Schristos 
1796*1424dfb3Schristos   if (prev_opcode
1797*1424dfb3Schristos       && prev_seg
1798*1424dfb3Schristos       && ((prev_seg != now_seg) || (prev_subseg != now_subseg)))
1799*1424dfb3Schristos     d10v_cleanup ();
1800*1424dfb3Schristos 
1801*1424dfb3Schristos   if (prev_opcode
1802*1424dfb3Schristos       && (0 == write_2_short (prev_opcode, prev_insn, opcode, insn, extype,
1803*1424dfb3Schristos 			      fixups)))
1804*1424dfb3Schristos     {
1805*1424dfb3Schristos       /* No instructions saved.  */
1806*1424dfb3Schristos       prev_opcode = NULL;
1807*1424dfb3Schristos     }
1808*1424dfb3Schristos   else
1809*1424dfb3Schristos     {
1810*1424dfb3Schristos       if (extype != PACK_UNSPEC)
1811*1424dfb3Schristos 	as_fatal (_("Unable to mix instructions as specified"));
1812*1424dfb3Schristos       /* Save last instruction so it may be packed on next pass.  */
1813*1424dfb3Schristos       prev_opcode = opcode;
1814*1424dfb3Schristos       prev_insn = insn;
1815*1424dfb3Schristos       prev_seg = now_seg;
1816*1424dfb3Schristos       prev_subseg = now_subseg;
1817*1424dfb3Schristos       fixups = fixups->next;
1818*1424dfb3Schristos     }
1819*1424dfb3Schristos }
1820*1424dfb3Schristos 
1821