1 /* tc-c30.c -- Assembly code for the Texas Instruments TMS320C30
2    Copyright 1998, 1999, 2000, 2001, 2002, 2003
3    Free Software Foundation, Inc.
4    Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)
5 
6    This file is part of GAS, the GNU Assembler.
7 
8    GAS is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2, or (at your option)
11    any later version.
12 
13    GAS is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with GAS; see the file COPYING.  If not, write to the Free
20    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21    02110-1301, USA.  */
22 
23 /* Texas Instruments TMS320C30 machine specific gas.
24    Written by Steven Haworth (steve@pm.cse.rmit.edu.au).
25    Bugs & suggestions are completely welcome.  This is free software.
26    Please help us make it better.  */
27 
28 #include "as.h"
29 #include "safe-ctype.h"
30 #include "opcode/tic30.h"
31 #ifdef ANSI_PROTOTYPES
32 #include <stdarg.h>
33 #else
34 #include <varargs.h>
35 #endif
36 
37 /* Put here all non-digit non-letter characters that may occur in an
38    operand.  */
39 static char operand_special_chars[] = "%$-+(,)*._~/<>&^!:[@]";
40 static char *ordinal_names[] =
41 {
42   "first", "second", "third", "fourth", "fifth"
43 };
44 
45 const int md_reloc_size = 0;
46 
47 const char comment_chars[]        = ";";
48 const char line_comment_chars[]   = "*";
49 const char line_separator_chars[] = "";
50 
51 const char *md_shortopts = "";
52 struct option md_longopts[] =
53 {
54   {NULL, no_argument, NULL, 0}
55 };
56 
57 size_t md_longopts_size = sizeof (md_longopts);
58 
59 /* Chars that mean this number is a floating point constant.
60    As in 0f12.456
61    or    0d1.2345e12.  */
62 const char FLT_CHARS[] = "fFdDxX";
63 
64 /* Chars that can be used to separate mant from exp in floating point
65    nums.  */
66 const char EXP_CHARS[] = "eE";
67 
68 /* Tables for lexical analysis.  */
69 static char opcode_chars[256];
70 static char register_chars[256];
71 static char operand_chars[256];
72 static char space_chars[256];
73 static char identifier_chars[256];
74 static char digit_chars[256];
75 
76 /* Lexical macros.  */
77 #define is_opcode_char(x)     (opcode_chars     [(unsigned char) x])
78 #define is_operand_char(x)    (operand_chars    [(unsigned char) x])
79 #define is_register_char(x)   (register_chars   [(unsigned char) x])
80 #define is_space_char(x)      (space_chars      [(unsigned char) x])
81 #define is_identifier_char(x) (identifier_chars [(unsigned char) x])
82 #define is_digit_char(x)      (digit_chars      [(unsigned char) x])
83 
84 const pseudo_typeS md_pseudo_table[] =
85 {
86   {0, 0, 0}
87 };
88 
89 static int
debug(const char * string,...)90 debug (const char *string, ...)
91 {
92   if (flag_debug)
93     {
94       char str[100];
95 
96       VA_OPEN (argptr, string);
97       VA_FIXEDARG (argptr, const char *, string);
98       vsprintf (str, string, argptr);
99       VA_CLOSE (argptr);
100       if (str[0] == '\0')
101 	return (0);
102       fputs (str, USE_STDOUT ? stdout : stderr);
103       return strlen (str);
104     }
105   else
106     return 0;
107 }
108 
109 /* Hash table for opcode lookup.  */
110 static struct hash_control *op_hash;
111 /* Hash table for parallel opcode lookup.  */
112 static struct hash_control *parop_hash;
113 /* Hash table for register lookup.  */
114 static struct hash_control *reg_hash;
115 /* Hash table for indirect addressing lookup.  */
116 static struct hash_control *ind_hash;
117 
118 void
md_begin(void)119 md_begin (void)
120 {
121   const char *hash_err;
122 
123   debug ("In md_begin()\n");
124   op_hash = hash_new ();
125 
126   {
127     const template *current_optab = tic30_optab;
128 
129     for (; current_optab < tic30_optab_end; current_optab++)
130       {
131 	hash_err = hash_insert (op_hash, current_optab->name,
132 				(char *) current_optab);
133 	if (hash_err)
134 	  as_fatal ("Internal Error: Can't Hash %s: %s",
135 		    current_optab->name, hash_err);
136       }
137   }
138 
139   parop_hash = hash_new ();
140 
141   {
142     const partemplate *current_parop = tic30_paroptab;
143 
144     for (; current_parop < tic30_paroptab_end; current_parop++)
145       {
146 	hash_err = hash_insert (parop_hash, current_parop->name,
147 				(char *) current_parop);
148 	if (hash_err)
149 	  as_fatal ("Internal Error: Can't Hash %s: %s",
150 		    current_parop->name, hash_err);
151       }
152   }
153 
154   reg_hash = hash_new ();
155 
156   {
157     const reg *current_reg = tic30_regtab;
158 
159     for (; current_reg < tic30_regtab_end; current_reg++)
160       {
161 	hash_err = hash_insert (reg_hash, current_reg->name,
162 				(char *) current_reg);
163 	if (hash_err)
164 	  as_fatal ("Internal Error: Can't Hash %s: %s",
165 		    current_reg->name, hash_err);
166       }
167   }
168 
169   ind_hash = hash_new ();
170 
171   {
172     const ind_addr_type *current_ind = tic30_indaddr_tab;
173 
174     for (; current_ind < tic30_indaddrtab_end; current_ind++)
175       {
176 	hash_err = hash_insert (ind_hash, current_ind->syntax,
177 				(char *) current_ind);
178 	if (hash_err)
179 	  as_fatal ("Internal Error: Can't Hash %s: %s",
180 		    current_ind->syntax, hash_err);
181       }
182   }
183 
184   /* Fill in lexical tables:  opcode_chars, operand_chars, space_chars.  */
185   {
186     int c;
187     char *p;
188 
189     for (c = 0; c < 256; c++)
190       {
191 	if (ISLOWER (c) || ISDIGIT (c))
192 	  {
193 	    opcode_chars[c] = c;
194 	    register_chars[c] = c;
195 	  }
196 	else if (ISUPPER (c))
197 	  {
198 	    opcode_chars[c] = TOLOWER (c);
199 	    register_chars[c] = opcode_chars[c];
200 	  }
201 	else if (c == ')' || c == '(')
202 	  register_chars[c] = c;
203 
204 	if (ISUPPER (c) || ISLOWER (c) || ISDIGIT (c))
205 	  operand_chars[c] = c;
206 
207 	if (ISDIGIT (c) || c == '-')
208 	  digit_chars[c] = c;
209 
210 	if (ISALPHA (c) || c == '_' || c == '.' || ISDIGIT (c))
211 	  identifier_chars[c] = c;
212 
213 	if (c == ' ' || c == '\t')
214 	  space_chars[c] = c;
215 
216 	if (c == '_')
217 	  opcode_chars[c] = c;
218       }
219     for (p = operand_special_chars; *p != '\0'; p++)
220       operand_chars[(unsigned char) *p] = *p;
221   }
222 }
223 
224 /* Address Mode OR values.  */
225 #define AM_Register  0x00000000
226 #define AM_Direct    0x00200000
227 #define AM_Indirect  0x00400000
228 #define AM_Immediate 0x00600000
229 #define AM_NotReq    0xFFFFFFFF
230 
231 /* PC Relative OR values.  */
232 #define PC_Register 0x00000000
233 #define PC_Relative 0x02000000
234 
235 typedef struct
236 {
237   unsigned op_type;
238   struct
239   {
240     int resolved;
241     unsigned address;
242     char *label;
243     expressionS direct_expr;
244   } direct;
245   struct
246   {
247     unsigned mod;
248     int ARnum;
249     unsigned char disp;
250   } indirect;
251   struct
252   {
253     unsigned opcode;
254   } reg;
255   struct
256   {
257     int resolved;
258     int decimal_found;
259     float f_number;
260     int s_number;
261     unsigned int u_number;
262     char *label;
263     expressionS imm_expr;
264   } immediate;
265 } operand;
266 
267 template *opcode;
268 
269 struct tic30_insn
270 {
271   template *tm;			/* Template of current instruction.  */
272   unsigned opcode;		/* Final opcode.  */
273   unsigned int operands;	/* Number of given operands.  */
274   /* Type of operand given in instruction.  */
275   operand *operand_type[MAX_OPERANDS];
276   unsigned addressing_mode;	/* Final addressing mode of instruction.  */
277 };
278 
279 struct tic30_insn insn;
280 static int found_parallel_insn;
281 
282 static char output_invalid_buf[8];
283 
284 static char *
output_invalid(char c)285 output_invalid (char c)
286 {
287   if (ISPRINT (c))
288     sprintf (output_invalid_buf, "'%c'", c);
289   else
290     sprintf (output_invalid_buf, "(0x%x)", (unsigned) c);
291   return output_invalid_buf;
292 }
293 
294 /* next_line points to the next line after the current instruction
295    (current_line).  Search for the parallel bars, and if found, merge two
296    lines into internal syntax for a parallel instruction:
297      q_[INSN1]_[INSN2] [OPERANDS1] | [OPERANDS2]
298    By this stage, all comments are scrubbed, and only the bare lines are
299    given.  */
300 
301 #define NONE           0
302 #define START_OPCODE   1
303 #define END_OPCODE     2
304 #define START_OPERANDS 3
305 #define END_OPERANDS   4
306 
307 static char *
tic30_find_parallel_insn(char * current_line,char * next_line)308 tic30_find_parallel_insn (char *current_line, char *next_line)
309 {
310   int found_parallel = 0;
311   char first_opcode[256];
312   char second_opcode[256];
313   char first_operands[256];
314   char second_operands[256];
315   char *parallel_insn;
316 
317   debug ("In tic30_find_parallel_insn()\n");
318   while (!is_end_of_line[(unsigned char) *next_line])
319     {
320       if (*next_line == PARALLEL_SEPARATOR
321 	  && *(next_line + 1) == PARALLEL_SEPARATOR)
322 	{
323 	  found_parallel = 1;
324 	  next_line++;
325 	  break;
326 	}
327       next_line++;
328     }
329   if (!found_parallel)
330     return NULL;
331   debug ("Found a parallel instruction\n");
332 
333   {
334     int i;
335     char *opcode, *operands, *line;
336 
337     for (i = 0; i < 2; i++)
338       {
339 	if (i == 0)
340 	  {
341 	    opcode = &first_opcode[0];
342 	    operands = &first_operands[0];
343 	    line = current_line;
344 	  }
345 	else
346 	  {
347 	    opcode = &second_opcode[0];
348 	    operands = &second_operands[0];
349 	    line = next_line;
350 	  }
351 
352 	{
353 	  int search_status = NONE;
354 	  int char_ptr = 0;
355 	  char c;
356 
357 	  while (!is_end_of_line[(unsigned char) (c = *line)])
358 	    {
359 	      if (is_opcode_char (c) && search_status == NONE)
360 		{
361 		  opcode[char_ptr++] = TOLOWER (c);
362 		  search_status = START_OPCODE;
363 		}
364 	      else if (is_opcode_char (c) && search_status == START_OPCODE)
365 		opcode[char_ptr++] = TOLOWER (c);
366 	      else if (!is_opcode_char (c) && search_status == START_OPCODE)
367 		{
368 		  opcode[char_ptr] = '\0';
369 		  char_ptr = 0;
370 		  search_status = END_OPCODE;
371 		}
372 	      else if (is_operand_char (c) && search_status == START_OPERANDS)
373 		operands[char_ptr++] = c;
374 
375 	      if (is_operand_char (c) && search_status == END_OPCODE)
376 		{
377 		  operands[char_ptr++] = c;
378 		  search_status = START_OPERANDS;
379 		}
380 
381 	      line++;
382 	    }
383 	  if (search_status != START_OPERANDS)
384 	    return NULL;
385 	  operands[char_ptr] = '\0';
386 	}
387       }
388   }
389   parallel_insn = malloc (strlen (first_opcode) + strlen (first_operands)
390 			  + strlen (second_opcode) + strlen (second_operands) + 8);
391   sprintf (parallel_insn, "q_%s_%s %s | %s",
392 	   first_opcode, second_opcode,
393 	   first_operands, second_operands);
394   debug ("parallel insn = %s\n", parallel_insn);
395   return parallel_insn;
396 }
397 
398 #undef NONE
399 #undef START_OPCODE
400 #undef END_OPCODE
401 #undef START_OPERANDS
402 #undef END_OPERANDS
403 
404 static operand *
tic30_operand(char * token)405 tic30_operand (char *token)
406 {
407   unsigned int count;
408   char ind_buffer[strlen (token)];
409   operand *current_op;
410 
411   debug ("In tic30_operand with %s\n", token);
412   current_op = malloc (sizeof (* current_op));
413   memset (current_op, '\0', sizeof (operand));
414 
415   if (*token == DIRECT_REFERENCE)
416     {
417       char *token_posn = token + 1;
418       int direct_label = 0;
419 
420       debug ("Found direct reference\n");
421       while (*token_posn)
422 	{
423 	  if (!is_digit_char (*token_posn))
424 	    direct_label = 1;
425 	  token_posn++;
426 	}
427 
428       if (direct_label)
429 	{
430 	  char *save_input_line_pointer;
431 	  segT retval;
432 
433 	  debug ("Direct reference is a label\n");
434 	  current_op->direct.label = token + 1;
435 	  save_input_line_pointer = input_line_pointer;
436 	  input_line_pointer = token + 1;
437 	  debug ("Current input_line_pointer: %s\n", input_line_pointer);
438 	  retval = expression (&current_op->direct.direct_expr);
439 
440 	  debug ("Expression type: %d\n",
441 		 current_op->direct.direct_expr.X_op);
442 	  debug ("Expression addnum: %d\n",
443 		 current_op->direct.direct_expr.X_add_number);
444 	  debug ("Segment: %d\n", retval);
445 
446 	  input_line_pointer = save_input_line_pointer;
447 
448 	  if (current_op->direct.direct_expr.X_op == O_constant)
449 	    {
450 	      current_op->direct.address =
451 		current_op->direct.direct_expr.X_add_number;
452 	      current_op->direct.resolved = 1;
453 	    }
454 	}
455       else
456 	{
457 	  debug ("Direct reference is a number\n");
458 	  current_op->direct.address = atoi (token + 1);
459 	  current_op->direct.resolved = 1;
460 	}
461       current_op->op_type = Direct;
462     }
463   else if (*token == INDIRECT_REFERENCE)
464     {
465       /* Indirect reference operand.  */
466       int found_ar = 0;
467       int found_disp = 0;
468       int ar_number = -1;
469       int disp_number = 0;
470       int buffer_posn = 1;
471       ind_addr_type *ind_addr_op;
472 
473       debug ("Found indirect reference\n");
474       ind_buffer[0] = *token;
475 
476       for (count = 1; count < strlen (token); count++)
477 	{
478 	  /* Strip operand.  */
479 	  ind_buffer[buffer_posn] = TOLOWER (*(token + count));
480 
481 	  if ((*(token + count - 1) == 'a' || *(token + count - 1) == 'A')
482 	      && (*(token + count) == 'r' || *(token + count) == 'R'))
483 	    {
484 	      /* AR reference is found, so get its number and remove
485 		 it from the buffer so it can pass through hash_find().  */
486 	      if (found_ar)
487 		{
488 		  as_bad ("More than one AR register found in indirect reference");
489 		  return NULL;
490 		}
491 	      if (*(token + count + 1) < '0' || *(token + count + 1) > '7')
492 		{
493 		  as_bad ("Illegal AR register in indirect reference");
494 		  return NULL;
495 		}
496 	      ar_number = *(token + count + 1) - '0';
497 	      found_ar = 1;
498 	      count++;
499 	    }
500 
501 	  if (*(token + count) == '(')
502 	    {
503 	      /* Parenthesis found, so check if a displacement value is
504 		 inside.  If so, get the value and remove it from the
505 		 buffer.  */
506 	      if (is_digit_char (*(token + count + 1)))
507 		{
508 		  char disp[10];
509 		  int disp_posn = 0;
510 
511 		  if (found_disp)
512 		    {
513 		      as_bad ("More than one displacement found in indirect reference");
514 		      return NULL;
515 		    }
516 		  count++;
517 		  while (*(token + count) != ')')
518 		    {
519 		      if (!is_digit_char (*(token + count)))
520 			{
521 			  as_bad ("Invalid displacement in indirect reference");
522 			  return NULL;
523 			}
524 		      disp[disp_posn++] = *(token + (count++));
525 		    }
526 		  disp[disp_posn] = '\0';
527 		  disp_number = atoi (disp);
528 		  count--;
529 		  found_disp = 1;
530 		}
531 	    }
532 	  buffer_posn++;
533 	}
534 
535       ind_buffer[buffer_posn] = '\0';
536       if (!found_ar)
537 	{
538 	  as_bad ("AR register not found in indirect reference");
539 	  return NULL;
540 	}
541 
542       ind_addr_op = (ind_addr_type *) hash_find (ind_hash, ind_buffer);
543       if (ind_addr_op)
544 	{
545 	  debug ("Found indirect reference: %s\n", ind_addr_op->syntax);
546 	  if (ind_addr_op->displacement == IMPLIED_DISP)
547 	    {
548 	      found_disp = 1;
549 	      disp_number = 1;
550 	    }
551 	  else if ((ind_addr_op->displacement == DISP_REQUIRED) && !found_disp)
552 	    {
553 	      /* Maybe an implied displacement of 1 again.  */
554 	      as_bad ("required displacement wasn't given in indirect reference");
555 	      return 0;
556 	    }
557 	}
558       else
559 	{
560 	  as_bad ("illegal indirect reference");
561 	  return NULL;
562 	}
563 
564       if (found_disp && (disp_number < 0 || disp_number > 255))
565 	{
566 	  as_bad ("displacement must be an unsigned 8-bit number");
567 	  return NULL;
568 	}
569 
570       current_op->indirect.mod = ind_addr_op->modfield;
571       current_op->indirect.disp = disp_number;
572       current_op->indirect.ARnum = ar_number;
573       current_op->op_type = Indirect;
574     }
575   else
576     {
577       reg *regop = (reg *) hash_find (reg_hash, token);
578 
579       if (regop)
580 	{
581 	  debug ("Found register operand: %s\n", regop->name);
582 	  if (regop->regtype == REG_ARn)
583 	    current_op->op_type = ARn;
584 	  else if (regop->regtype == REG_Rn)
585 	    current_op->op_type = Rn;
586 	  else if (regop->regtype == REG_DP)
587 	    current_op->op_type = DPReg;
588 	  else
589 	    current_op->op_type = OtherReg;
590 	  current_op->reg.opcode = regop->opcode;
591 	}
592       else
593 	{
594 	  if (!is_digit_char (*token)
595 	      || *(token + 1) == 'x'
596 	      || strchr (token, 'h'))
597 	    {
598 	      char *save_input_line_pointer;
599 	      segT retval;
600 
601 	      debug ("Probably a label: %s\n", token);
602 	      current_op->immediate.label = malloc (strlen (token) + 1);
603 	      strcpy (current_op->immediate.label, token);
604 	      current_op->immediate.label[strlen (token)] = '\0';
605 	      save_input_line_pointer = input_line_pointer;
606 	      input_line_pointer = token;
607 
608 	      debug ("Current input_line_pointer: %s\n", input_line_pointer);
609 	      retval = expression (&current_op->immediate.imm_expr);
610 	      debug ("Expression type: %d\n",
611 		     current_op->immediate.imm_expr.X_op);
612 	      debug ("Expression addnum: %d\n",
613 		     current_op->immediate.imm_expr.X_add_number);
614 	      debug ("Segment: %d\n", retval);
615 	      input_line_pointer = save_input_line_pointer;
616 
617 	      if (current_op->immediate.imm_expr.X_op == O_constant)
618 		{
619 		  current_op->immediate.s_number
620 		    = current_op->immediate.imm_expr.X_add_number;
621 		  current_op->immediate.u_number
622 		    = (unsigned int) current_op->immediate.imm_expr.X_add_number;
623 		  current_op->immediate.resolved = 1;
624 		}
625 	    }
626 	  else
627 	    {
628 	      unsigned count;
629 
630 	      debug ("Found a number or displacement\n");
631 	      for (count = 0; count < strlen (token); count++)
632 		if (*(token + count) == '.')
633 		  current_op->immediate.decimal_found = 1;
634 	      current_op->immediate.label = malloc (strlen (token) + 1);
635 	      strcpy (current_op->immediate.label, token);
636 	      current_op->immediate.label[strlen (token)] = '\0';
637 	      current_op->immediate.f_number = (float) atof (token);
638 	      current_op->immediate.s_number = (int) atoi (token);
639 	      current_op->immediate.u_number = (unsigned int) atoi (token);
640 	      current_op->immediate.resolved = 1;
641 	    }
642 	  current_op->op_type = Disp | Abs24 | Imm16 | Imm24;
643 	  if (current_op->immediate.u_number <= 31)
644 	    current_op->op_type |= IVector;
645 	}
646     }
647   return current_op;
648 }
649 
650 struct tic30_par_insn
651 {
652   partemplate *tm;		/* Template of current parallel instruction.  */
653   unsigned operands[2];		/* Number of given operands for each insn.  */
654   /* Type of operand given in instruction.  */
655   operand *operand_type[2][MAX_OPERANDS];
656   int swap_operands;		/* Whether to swap operands around.  */
657   unsigned p_field;		/* Value of p field in multiply add/sub instructions.  */
658   unsigned opcode;		/* Final opcode.  */
659 };
660 
661 struct tic30_par_insn p_insn;
662 
663 static int
tic30_parallel_insn(char * token)664 tic30_parallel_insn (char *token)
665 {
666   static partemplate *p_opcode;
667   char *current_posn = token;
668   char *token_start;
669   char save_char;
670 
671   debug ("In tic30_parallel_insn with %s\n", token);
672   memset (&p_insn, '\0', sizeof (p_insn));
673 
674   while (is_opcode_char (*current_posn))
675     current_posn++;
676   {
677     /* Find instruction.  */
678     save_char = *current_posn;
679     *current_posn = '\0';
680     p_opcode = (partemplate *) hash_find (parop_hash, token);
681     if (p_opcode)
682       {
683 	debug ("Found instruction %s\n", p_opcode->name);
684 	p_insn.tm = p_opcode;
685       }
686     else
687       {
688 	char first_opcode[6] = {0};
689 	char second_opcode[6] = {0};
690 	unsigned int i;
691 	int current_opcode = -1;
692 	int char_ptr = 0;
693 
694 	for (i = 0; i < strlen (token); i++)
695 	  {
696 	    char ch = *(token + i);
697 
698 	    if (ch == '_' && current_opcode == -1)
699 	      {
700 		current_opcode = 0;
701 		continue;
702 	      }
703 
704 	    if (ch == '_' && current_opcode == 0)
705 	      {
706 		current_opcode = 1;
707 		char_ptr = 0;
708 		continue;
709 	      }
710 
711 	    switch (current_opcode)
712 	      {
713 	      case 0:
714 		first_opcode[char_ptr++] = ch;
715 		break;
716 	      case 1:
717 		second_opcode[char_ptr++] = ch;
718 		break;
719 	      }
720 	  }
721 
722 	debug ("first_opcode = %s\n", first_opcode);
723 	debug ("second_opcode = %s\n", second_opcode);
724 	sprintf (token, "q_%s_%s", second_opcode, first_opcode);
725 	p_opcode = (partemplate *) hash_find (parop_hash, token);
726 
727 	if (p_opcode)
728 	  {
729 	    debug ("Found instruction %s\n", p_opcode->name);
730 	    p_insn.tm = p_opcode;
731 	    p_insn.swap_operands = 1;
732 	  }
733 	else
734 	  return 0;
735       }
736     *current_posn = save_char;
737   }
738 
739   {
740     /* Find operands.  */
741     int paren_not_balanced;
742     int expecting_operand = 0;
743     int found_separator = 0;
744 
745     do
746       {
747 	/* Skip optional white space before operand.  */
748 	while (!is_operand_char (*current_posn)
749 	       && *current_posn != END_OF_INSN)
750 	  {
751 	    if (!is_space_char (*current_posn)
752 		&& *current_posn != PARALLEL_SEPARATOR)
753 	      {
754 		as_bad ("Invalid character %s before %s operand",
755 			output_invalid (*current_posn),
756 			ordinal_names[insn.operands]);
757 		return 1;
758 	      }
759 	    if (*current_posn == PARALLEL_SEPARATOR)
760 	      found_separator = 1;
761 	    current_posn++;
762 	  }
763 
764 	token_start = current_posn;
765 	paren_not_balanced = 0;
766 
767 	while (paren_not_balanced || *current_posn != ',')
768 	  {
769 	    if (*current_posn == END_OF_INSN)
770 	      {
771 		if (paren_not_balanced)
772 		  {
773 		    as_bad ("Unbalanced parenthesis in %s operand.",
774 			    ordinal_names[insn.operands]);
775 		    return 1;
776 		  }
777 		else
778 		  break;
779 	      }
780 	    else if (*current_posn == PARALLEL_SEPARATOR)
781 	      {
782 		while (is_space_char (*(current_posn - 1)))
783 		  current_posn--;
784 		break;
785 	      }
786 	    else if (!is_operand_char (*current_posn)
787 		     && !is_space_char (*current_posn))
788 	      {
789 		as_bad ("Invalid character %s in %s operand",
790 			output_invalid (*current_posn),
791 			ordinal_names[insn.operands]);
792 		return 1;
793 	      }
794 
795 	    if (*current_posn == '(')
796 	      ++paren_not_balanced;
797 	    if (*current_posn == ')')
798 	      --paren_not_balanced;
799 	    current_posn++;
800 	  }
801 
802 	if (current_posn != token_start)
803 	  {
804 	    /* Yes, we've read in another operand.  */
805 	    p_insn.operands[found_separator]++;
806 	    if (p_insn.operands[found_separator] > MAX_OPERANDS)
807 	      {
808 		as_bad ("Spurious operands; (%d operands/instruction max)",
809 			MAX_OPERANDS);
810 		return 1;
811 	      }
812 
813 	    /* Now parse operand adding info to 'insn' as we go along.  */
814 	    save_char = *current_posn;
815 	    *current_posn = '\0';
816 	    p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1] =
817 	      tic30_operand (token_start);
818 	    *current_posn = save_char;
819 	    if (!p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1])
820 	      return 1;
821 	  }
822 	else
823 	  {
824 	    if (expecting_operand)
825 	      {
826 		as_bad ("Expecting operand after ','; got nothing");
827 		return 1;
828 	      }
829 	    if (*current_posn == ',')
830 	      {
831 		as_bad ("Expecting operand before ','; got nothing");
832 		return 1;
833 	      }
834 	  }
835 
836 	/* Now *current_posn must be either ',' or END_OF_INSN.  */
837 	if (*current_posn == ',')
838 	  {
839 	    if (*++current_posn == END_OF_INSN)
840 	      {
841 		/* Just skip it, if it's \n complain.  */
842 		as_bad ("Expecting operand after ','; got nothing");
843 		return 1;
844 	      }
845 	    expecting_operand = 1;
846 	  }
847       }
848     while (*current_posn != END_OF_INSN);
849   }
850 
851   if (p_insn.swap_operands)
852     {
853       int temp_num, i;
854       operand *temp_op;
855 
856       temp_num = p_insn.operands[0];
857       p_insn.operands[0] = p_insn.operands[1];
858       p_insn.operands[1] = temp_num;
859       for (i = 0; i < MAX_OPERANDS; i++)
860 	{
861 	  temp_op = p_insn.operand_type[0][i];
862 	  p_insn.operand_type[0][i] = p_insn.operand_type[1][i];
863 	  p_insn.operand_type[1][i] = temp_op;
864 	}
865     }
866 
867   if (p_insn.operands[0] != p_insn.tm->operands_1)
868     {
869       as_bad ("incorrect number of operands given in the first instruction");
870       return 1;
871     }
872 
873   if (p_insn.operands[1] != p_insn.tm->operands_2)
874     {
875       as_bad ("incorrect number of operands given in the second instruction");
876       return 1;
877     }
878 
879   debug ("Number of operands in first insn: %d\n", p_insn.operands[0]);
880   debug ("Number of operands in second insn: %d\n", p_insn.operands[1]);
881 
882   {
883     /* Now check if operands are correct.  */
884     int count;
885     int num_rn = 0;
886     int num_ind = 0;
887 
888     for (count = 0; count < 2; count++)
889       {
890 	unsigned int i;
891 	for (i = 0; i < p_insn.operands[count]; i++)
892 	  {
893 	    if ((p_insn.operand_type[count][i]->op_type &
894 		 p_insn.tm->operand_types[count][i]) == 0)
895 	      {
896 		as_bad ("%s instruction, operand %d doesn't match",
897 			ordinal_names[count], i + 1);
898 		return 1;
899 	      }
900 
901 	    /* Get number of R register and indirect reference contained
902 	       within the first two operands of each instruction.  This is
903 	       required for the multiply parallel instructions which require
904 	       two R registers and two indirect references, but not in any
905 	       particular place.  */
906 	    if ((p_insn.operand_type[count][i]->op_type & Rn) && i < 2)
907 	      num_rn++;
908 	    else if ((p_insn.operand_type[count][i]->op_type & Indirect)
909 		     && i < 2)
910 	      num_ind++;
911 	  }
912       }
913 
914     if ((p_insn.tm->operand_types[0][0] & (Indirect | Rn))
915 	== (Indirect | Rn))
916       {
917 	/* Check for the multiply instructions.  */
918 	if (num_rn != 2)
919 	  {
920 	    as_bad ("incorrect format for multiply parallel instruction");
921 	    return 1;
922 	  }
923 
924 	if (num_ind != 2)
925 	  {
926 	    /* Shouldn't get here.  */
927 	    as_bad ("incorrect format for multiply parallel instruction");
928 	    return 1;
929 	  }
930 
931 	if ((p_insn.operand_type[0][2]->reg.opcode != 0x00)
932 	    && (p_insn.operand_type[0][2]->reg.opcode != 0x01))
933 	  {
934 	    as_bad ("destination for multiply can only be R0 or R1");
935 	    return 1;
936 	  }
937 
938 	if ((p_insn.operand_type[1][2]->reg.opcode != 0x02)
939 	    && (p_insn.operand_type[1][2]->reg.opcode != 0x03))
940 	  {
941 	    as_bad ("destination for add/subtract can only be R2 or R3");
942 	    return 1;
943 	  }
944 
945 	/* Now determine the P field for the instruction.  */
946 	if (p_insn.operand_type[0][0]->op_type & Indirect)
947 	  {
948 	    if (p_insn.operand_type[0][1]->op_type & Indirect)
949 	      p_insn.p_field = 0x00000000;	/* Ind * Ind, Rn  +/- Rn.  */
950 	    else if (p_insn.operand_type[1][0]->op_type & Indirect)
951 	      p_insn.p_field = 0x01000000;	/* Ind * Rn,  Ind +/- Rn.  */
952 	    else
953 	      p_insn.p_field = 0x03000000;	/* Ind * Rn,  Rn  +/- Ind.  */
954 	  }
955 	else
956 	  {
957 	    if (p_insn.operand_type[0][1]->op_type & Rn)
958 	      p_insn.p_field = 0x02000000;	/* Rn  * Rn,  Ind +/- Ind.  */
959 	    else if (p_insn.operand_type[1][0]->op_type & Indirect)
960 	      {
961 		operand *temp;
962 		p_insn.p_field = 0x01000000;	/* Rn  * Ind, Ind +/- Rn.  */
963 		/* Need to swap the two multiply operands around so that
964 		   everything is in its place for the opcode makeup.
965 		   ie so Ind * Rn, Ind +/- Rn.  */
966 		temp = p_insn.operand_type[0][0];
967 		p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
968 		p_insn.operand_type[0][1] = temp;
969 	      }
970 	    else
971 	      {
972 		operand *temp;
973 		p_insn.p_field = 0x03000000;	/* Rn  * Ind, Rn  +/- Ind.  */
974 		temp = p_insn.operand_type[0][0];
975 		p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
976 		p_insn.operand_type[0][1] = temp;
977 	      }
978 	  }
979       }
980   }
981 
982   debug ("P field: %08X\n", p_insn.p_field);
983 
984   /* Finalise opcode.  This is easier for parallel instructions as they have
985      to be fully resolved, there are no memory addresses allowed, except
986      through indirect addressing, so there are no labels to resolve.  */
987   p_insn.opcode = p_insn.tm->base_opcode;
988 
989   switch (p_insn.tm->oporder)
990     {
991     case OO_4op1:
992       p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
993       p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
994       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
995       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
996       p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
997       p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
998       break;
999 
1000     case OO_4op2:
1001       p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
1002       p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
1003       p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
1004       p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
1005       p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 19);
1006       p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
1007       if (p_insn.operand_type[1][1]->reg.opcode == p_insn.operand_type[0][1]->reg.opcode)
1008 	as_warn ("loading the same register in parallel operation");
1009       break;
1010 
1011     case OO_4op3:
1012       p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1013       p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1014       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1015       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1016       p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1017       p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 22);
1018       break;
1019 
1020     case OO_5op1:
1021       p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
1022       p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
1023       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1024       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1025       p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1026       p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1027       p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
1028       break;
1029 
1030     case OO_5op2:
1031       p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1032       p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1033       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1034       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1035       p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1036       p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
1037       p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
1038       break;
1039 
1040     case OO_PField:
1041       p_insn.opcode |= p_insn.p_field;
1042       if (p_insn.operand_type[0][2]->reg.opcode == 0x01)
1043 	p_insn.opcode |= 0x00800000;
1044       if (p_insn.operand_type[1][2]->reg.opcode == 0x03)
1045 	p_insn.opcode |= 0x00400000;
1046 
1047       switch (p_insn.p_field)
1048 	{
1049 	case 0x00000000:
1050 	  p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1051 	  p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1052 	  p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1053 	  p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1054 	  p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
1055 	  p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 19);
1056 	  break;
1057 	case 0x01000000:
1058 	  p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum);
1059 	  p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 3);
1060 	  p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1061 	  p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1062 	  p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
1063 	  p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1064 	  break;
1065 	case 0x02000000:
1066 	  p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
1067 	  p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
1068 	  p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
1069 	  p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
1070 	  p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 16);
1071 	  p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
1072 	  break;
1073 	case 0x03000000:
1074 	  p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
1075 	  p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
1076 	  p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1077 	  p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1078 	  p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1079 	  p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1080 	  break;
1081 	}
1082       break;
1083     }
1084 
1085   {
1086     char *p;
1087 
1088     p = frag_more (INSN_SIZE);
1089     md_number_to_chars (p, (valueT) p_insn.opcode, INSN_SIZE);
1090   }
1091 
1092   {
1093     unsigned int i, j;
1094 
1095     for (i = 0; i < 2; i++)
1096       for (j = 0; j < p_insn.operands[i]; j++)
1097 	free (p_insn.operand_type[i][j]);
1098   }
1099 
1100   debug ("Final opcode: %08X\n", p_insn.opcode);
1101   debug ("\n");
1102 
1103   return 1;
1104 }
1105 
1106 /* In order to get gas to ignore any | chars at the start of a line,
1107    this function returns true if a | is found in a line.  */
1108 
1109 int
tic30_unrecognized_line(int c)1110 tic30_unrecognized_line (int c)
1111 {
1112   debug ("In tc_unrecognized_line\n");
1113   return (c == PARALLEL_SEPARATOR);
1114 }
1115 
1116 int
md_estimate_size_before_relax(fragS * fragP ATTRIBUTE_UNUSED,segT segment ATTRIBUTE_UNUSED)1117 md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
1118 			       segT segment ATTRIBUTE_UNUSED)
1119 {
1120   debug ("In md_estimate_size_before_relax()\n");
1121   return 0;
1122 }
1123 
1124 void
md_convert_frag(bfd * abfd ATTRIBUTE_UNUSED,segT sec ATTRIBUTE_UNUSED,register fragS * fragP ATTRIBUTE_UNUSED)1125 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
1126 		 segT sec ATTRIBUTE_UNUSED,
1127 		 register fragS *fragP ATTRIBUTE_UNUSED)
1128 {
1129   debug ("In md_convert_frag()\n");
1130 }
1131 
1132 void
md_apply_fix(fixS * fixP,valueT * valP,segT seg ATTRIBUTE_UNUSED)1133 md_apply_fix (fixS *fixP,
1134 	       valueT *valP,
1135 	       segT seg ATTRIBUTE_UNUSED)
1136 {
1137   valueT value = *valP;
1138 
1139   debug ("In md_apply_fix() with value = %ld\n", (long) value);
1140   debug ("Values in fixP\n");
1141   debug ("fx_size = %d\n", fixP->fx_size);
1142   debug ("fx_pcrel = %d\n", fixP->fx_pcrel);
1143   debug ("fx_where = %d\n", fixP->fx_where);
1144   debug ("fx_offset = %d\n", (int) fixP->fx_offset);
1145   {
1146     char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
1147 
1148     value /= INSN_SIZE;
1149     if (fixP->fx_size == 1)
1150       /* Special fix for LDP instruction.  */
1151       value = (value & 0x00FF0000) >> 16;
1152 
1153     debug ("new value = %ld\n", (long) value);
1154     md_number_to_chars (buf, value, fixP->fx_size);
1155   }
1156 
1157   if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
1158     fixP->fx_done = 1;
1159 }
1160 
1161 int
md_parse_option(int c ATTRIBUTE_UNUSED,char * arg ATTRIBUTE_UNUSED)1162 md_parse_option (int c ATTRIBUTE_UNUSED,
1163 		 char *arg ATTRIBUTE_UNUSED)
1164 {
1165   debug ("In md_parse_option()\n");
1166   return 0;
1167 }
1168 
1169 void
md_show_usage(FILE * stream ATTRIBUTE_UNUSED)1170 md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
1171 {
1172   debug ("In md_show_usage()\n");
1173 }
1174 
1175 symbolS *
md_undefined_symbol(char * name ATTRIBUTE_UNUSED)1176 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1177 {
1178   debug ("In md_undefined_symbol()\n");
1179   return (symbolS *) 0;
1180 }
1181 
1182 valueT
md_section_align(segT segment,valueT size)1183 md_section_align (segT segment, valueT size)
1184 {
1185   debug ("In md_section_align() segment = %d and size = %d\n",
1186 	 segment, size);
1187   size = (size + 3) / 4;
1188   size *= 4;
1189   debug ("New size value = %d\n", size);
1190   return size;
1191 }
1192 
1193 long
md_pcrel_from(fixS * fixP)1194 md_pcrel_from (fixS *fixP)
1195 {
1196   int offset;
1197 
1198   debug ("In md_pcrel_from()\n");
1199   debug ("fx_where = %d\n", fixP->fx_where);
1200   debug ("fx_size = %d\n", fixP->fx_size);
1201   /* Find the opcode that represents the current instruction in the
1202      fr_literal storage area, and check bit 21.  Bit 21 contains whether the
1203      current instruction is a delayed one or not, and then set the offset
1204      value appropriately.  */
1205   if (fixP->fx_frag->fr_literal[fixP->fx_where - fixP->fx_size + 1] & 0x20)
1206     offset = 3;
1207   else
1208     offset = 1;
1209   debug ("offset = %d\n", offset);
1210   /* PC Relative instructions have a format:
1211      displacement = Label - (PC + offset)
1212      This function returns PC + offset where:
1213      fx_where - fx_size = PC
1214      INSN_SIZE * offset = offset number of instructions.  */
1215   return fixP->fx_where - fixP->fx_size + (INSN_SIZE * offset);
1216 }
1217 
1218 char *
md_atof(int what_statement_type,char * literalP,int * sizeP)1219 md_atof (int what_statement_type,
1220 	 char *literalP,
1221 	 int *sizeP)
1222 {
1223   int prec;
1224   char *token;
1225   char keepval;
1226   unsigned long value;
1227   float float_value;
1228 
1229   debug ("In md_atof()\n");
1230   debug ("precision = %c\n", what_statement_type);
1231   debug ("literal = %s\n", literalP);
1232   debug ("line = ");
1233   token = input_line_pointer;
1234   while (!is_end_of_line[(unsigned char) *input_line_pointer]
1235 	 && (*input_line_pointer != ','))
1236     {
1237       debug ("%c", *input_line_pointer);
1238       input_line_pointer++;
1239     }
1240 
1241   keepval = *input_line_pointer;
1242   *input_line_pointer = '\0';
1243   debug ("\n");
1244   float_value = (float) atof (token);
1245   *input_line_pointer = keepval;
1246   debug ("float_value = %f\n", float_value);
1247 
1248   switch (what_statement_type)
1249     {
1250     case 'f':
1251     case 'F':
1252     case 's':
1253     case 'S':
1254       prec = 2;
1255       break;
1256 
1257     case 'd':
1258     case 'D':
1259     case 'r':
1260     case 'R':
1261       prec = 4;
1262       break;
1263 
1264     default:
1265       *sizeP = 0;
1266       return "Bad call to MD_ATOF()";
1267     }
1268 
1269   if (float_value == 0.0)
1270     value = (prec == 2) ? 0x00008000L : 0x80000000L;
1271   else
1272     {
1273       unsigned long exp, sign, mant, tmsfloat;
1274       union
1275       {
1276 	float f;
1277 	long  l;
1278       }
1279       converter;
1280 
1281       converter.f = float_value;
1282       tmsfloat = converter.l;
1283       sign = tmsfloat & 0x80000000;
1284       mant = tmsfloat & 0x007FFFFF;
1285       exp = tmsfloat & 0x7F800000;
1286       exp <<= 1;
1287       if (exp == 0xFF000000)
1288 	{
1289 	  if (mant == 0)
1290 	    value = 0x7F7FFFFF;
1291 	  else if (sign == 0)
1292 	    value = 0x7F7FFFFF;
1293 	  else
1294 	    value = 0x7F800000;
1295 	}
1296       else
1297 	{
1298 	  exp -= 0x7F000000;
1299 	  if (sign)
1300 	    {
1301 	      mant = mant & 0x007FFFFF;
1302 	      mant = -mant;
1303 	      mant = mant & 0x00FFFFFF;
1304 	      if (mant == 0)
1305 		{
1306 		  mant |= 0x00800000;
1307 		  exp = (long) exp - 0x01000000;
1308 		}
1309 	    }
1310 	  tmsfloat = exp | mant;
1311 	  value = tmsfloat;
1312 	}
1313       if (prec == 2)
1314 	{
1315 	  long exp, mant;
1316 
1317 	  if (tmsfloat == 0x80000000)
1318 	    value = 0x8000;
1319 	  else
1320 	    {
1321 	      value = 0;
1322 	      exp = (tmsfloat & 0xFF000000);
1323 	      exp >>= 24;
1324 	      mant = tmsfloat & 0x007FFFFF;
1325 	      if (tmsfloat & 0x00800000)
1326 		{
1327 		  mant |= 0xFF000000;
1328 		  mant += 0x00000800;
1329 		  mant >>= 12;
1330 		  mant |= 0x00000800;
1331 		  mant &= 0x0FFF;
1332 		  if (exp > 7)
1333 		    value = 0x7800;
1334 		}
1335 	      else
1336 		{
1337 		  mant |= 0x00800000;
1338 		  mant += 0x00000800;
1339 		  exp += (mant >> 24);
1340 		  mant >>= 12;
1341 		  mant &= 0x07FF;
1342 		  if (exp > 7)
1343 		    value = 0x77FF;
1344 		}
1345 	      if (exp < -8)
1346 		value = 0x8000;
1347 	      if (value == 0)
1348 		{
1349 		  mant = (exp << 12) | mant;
1350 		  value = mant & 0xFFFF;
1351 		}
1352 	    }
1353 	}
1354     }
1355   md_number_to_chars (literalP, value, prec);
1356   *sizeP = prec;
1357   return 0;
1358 }
1359 
1360 void
md_number_to_chars(char * buf,valueT val,int n)1361 md_number_to_chars (char *buf, valueT val, int n)
1362 {
1363   debug ("In md_number_to_chars()\n");
1364   number_to_chars_bigendian (buf, val, n);
1365 }
1366 
1367 #define F(SZ,PCREL)		(((SZ) << 1) + (PCREL))
1368 #define MAP(SZ,PCREL,TYPE)	case F(SZ,PCREL): code = (TYPE); break
1369 
1370 arelent *
tc_gen_reloc(asection * section ATTRIBUTE_UNUSED,fixS * fixP)1371 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
1372 {
1373   arelent *rel;
1374   bfd_reloc_code_real_type code = 0;
1375 
1376   debug ("In tc_gen_reloc()\n");
1377   debug ("fixP.size = %d\n", fixP->fx_size);
1378   debug ("fixP.pcrel = %d\n", fixP->fx_pcrel);
1379   debug ("addsy.name = %s\n", S_GET_NAME (fixP->fx_addsy));
1380 
1381   switch (F (fixP->fx_size, fixP->fx_pcrel))
1382     {
1383       MAP (1, 0, BFD_RELOC_TIC30_LDP);
1384       MAP (2, 0, BFD_RELOC_16);
1385       MAP (3, 0, BFD_RELOC_24);
1386       MAP (2, 1, BFD_RELOC_16_PCREL);
1387       MAP (4, 0, BFD_RELOC_32);
1388     default:
1389       as_bad ("Can not do %d byte %srelocation", fixP->fx_size,
1390 	      fixP->fx_pcrel ? "pc-relative " : "");
1391     }
1392 #undef MAP
1393 #undef F
1394 
1395   rel = xmalloc (sizeof (* rel));
1396   assert (rel != 0);
1397   rel->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
1398   *rel->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
1399   rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
1400   rel->addend = 0;
1401   rel->howto = bfd_reloc_type_lookup (stdoutput, code);
1402   if (!rel->howto)
1403     {
1404       const char *name;
1405 
1406       name = S_GET_NAME (fixP->fx_addsy);
1407       if (name == NULL)
1408 	name = "<unknown>";
1409       as_fatal ("Cannot generate relocation type for symbol %s, code %s",
1410 		name, bfd_get_reloc_code_name (code));
1411     }
1412   return rel;
1413 }
1414 
1415 void
md_operand(expressionS * expressionP ATTRIBUTE_UNUSED)1416 md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
1417 {
1418   debug ("In md_operand()\n");
1419 }
1420 
1421 void
md_assemble(char * line)1422 md_assemble (char *line)
1423 {
1424   template *opcode;
1425   char *current_posn;
1426   char *token_start;
1427   char save_char;
1428   unsigned int count;
1429 
1430   debug ("In md_assemble() with argument %s\n", line);
1431   memset (&insn, '\0', sizeof (insn));
1432   if (found_parallel_insn)
1433     {
1434       debug ("Line is second part of parallel instruction\n\n");
1435       found_parallel_insn = 0;
1436       return;
1437     }
1438   if ((current_posn =
1439        tic30_find_parallel_insn (line, input_line_pointer + 1)) == NULL)
1440     current_posn = line;
1441   else
1442     found_parallel_insn = 1;
1443 
1444   while (is_space_char (*current_posn))
1445     current_posn++;
1446 
1447   token_start = current_posn;
1448 
1449   if (!is_opcode_char (*current_posn))
1450     {
1451       as_bad ("Invalid character %s in opcode",
1452 	      output_invalid (*current_posn));
1453       return;
1454     }
1455   /* Check if instruction is a parallel instruction
1456      by seeing if the first character is a q.  */
1457   if (*token_start == 'q')
1458     {
1459       if (tic30_parallel_insn (token_start))
1460 	{
1461 	  if (found_parallel_insn)
1462 	    free (token_start);
1463 	  return;
1464 	}
1465     }
1466   while (is_opcode_char (*current_posn))
1467     current_posn++;
1468   {
1469     /* Find instruction.  */
1470     save_char = *current_posn;
1471     *current_posn = '\0';
1472     opcode = (template *) hash_find (op_hash, token_start);
1473     if (opcode)
1474       {
1475 	debug ("Found instruction %s\n", opcode->name);
1476 	insn.tm = opcode;
1477       }
1478     else
1479       {
1480 	debug ("Didn't find insn\n");
1481 	as_bad ("Unknown TMS320C30 instruction: %s", token_start);
1482 	return;
1483       }
1484     *current_posn = save_char;
1485   }
1486 
1487   if (*current_posn != END_OF_INSN)
1488     {
1489       /* Find operands.  */
1490       int paren_not_balanced;
1491       int expecting_operand = 0;
1492       int this_operand;
1493       do
1494 	{
1495 	  /* Skip optional white space before operand.  */
1496 	  while (!is_operand_char (*current_posn)
1497 		 && *current_posn != END_OF_INSN)
1498 	    {
1499 	      if (!is_space_char (*current_posn))
1500 		{
1501 		  as_bad ("Invalid character %s before %s operand",
1502 			  output_invalid (*current_posn),
1503 			  ordinal_names[insn.operands]);
1504 		  return;
1505 		}
1506 	      current_posn++;
1507 	    }
1508 	  token_start = current_posn;
1509 	  paren_not_balanced = 0;
1510 	  while (paren_not_balanced || *current_posn != ',')
1511 	    {
1512 	      if (*current_posn == END_OF_INSN)
1513 		{
1514 		  if (paren_not_balanced)
1515 		    {
1516 		      as_bad ("Unbalanced parenthesis in %s operand.",
1517 			      ordinal_names[insn.operands]);
1518 		      return;
1519 		    }
1520 		  else
1521 		    break;
1522 		}
1523 	      else if (!is_operand_char (*current_posn)
1524 		       && !is_space_char (*current_posn))
1525 		{
1526 		  as_bad ("Invalid character %s in %s operand",
1527 			  output_invalid (*current_posn),
1528 			  ordinal_names[insn.operands]);
1529 		  return;
1530 		}
1531 	      if (*current_posn == '(')
1532 		++paren_not_balanced;
1533 	      if (*current_posn == ')')
1534 		--paren_not_balanced;
1535 	      current_posn++;
1536 	    }
1537 	  if (current_posn != token_start)
1538 	    {
1539 	      /* Yes, we've read in another operand.  */
1540 	      this_operand = insn.operands++;
1541 	      if (insn.operands > MAX_OPERANDS)
1542 		{
1543 		  as_bad ("Spurious operands; (%d operands/instruction max)",
1544 			  MAX_OPERANDS);
1545 		  return;
1546 		}
1547 
1548 	      /* Now parse operand adding info to 'insn' as we go along.  */
1549 	      save_char = *current_posn;
1550 	      *current_posn = '\0';
1551 	      insn.operand_type[this_operand] = tic30_operand (token_start);
1552 	      *current_posn = save_char;
1553 	      if (insn.operand_type[this_operand] == NULL)
1554 		return;
1555 	    }
1556 	  else
1557 	    {
1558 	      if (expecting_operand)
1559 		{
1560 		  as_bad ("Expecting operand after ','; got nothing");
1561 		  return;
1562 		}
1563 	      if (*current_posn == ',')
1564 		{
1565 		  as_bad ("Expecting operand before ','; got nothing");
1566 		  return;
1567 		}
1568 	    }
1569 
1570 	  /* Now *current_posn must be either ',' or END_OF_INSN.  */
1571 	  if (*current_posn == ',')
1572 	    {
1573 	      if (*++current_posn == END_OF_INSN)
1574 		{
1575 		  /* Just skip it, if it's \n complain.  */
1576 		  as_bad ("Expecting operand after ','; got nothing");
1577 		  return;
1578 		}
1579 	      expecting_operand = 1;
1580 	    }
1581 	}
1582       while (*current_posn != END_OF_INSN);
1583     }
1584 
1585   debug ("Number of operands found: %d\n", insn.operands);
1586 
1587   /* Check that number of operands is correct.  */
1588   if (insn.operands != insn.tm->operands)
1589     {
1590       unsigned int i;
1591       unsigned int numops = insn.tm->operands;
1592 
1593       /* If operands are not the same, then see if any of the operands are
1594 	 not required.  Then recheck with number of given operands.  If they
1595 	 are still not the same, then give an error, otherwise carry on.  */
1596       for (i = 0; i < insn.tm->operands; i++)
1597 	if (insn.tm->operand_types[i] & NotReq)
1598 	  numops--;
1599       if (insn.operands != numops)
1600 	{
1601 	  as_bad ("Incorrect number of operands given");
1602 	  return;
1603 	}
1604     }
1605   insn.addressing_mode = AM_NotReq;
1606   for (count = 0; count < insn.operands; count++)
1607     {
1608       if (insn.operand_type[count]->op_type & insn.tm->operand_types[count])
1609 	{
1610 	  debug ("Operand %d matches\n", count + 1);
1611 	  /* If instruction has two operands and has an AddressMode
1612 	     modifier then set addressing mode type for instruction.  */
1613 	  if (insn.tm->opcode_modifier == AddressMode)
1614 	    {
1615 	      int addr_insn = 0;
1616 	      /* Store instruction uses the second
1617 		 operand for the address mode.  */
1618 	      if ((insn.tm->operand_types[1] & (Indirect | Direct))
1619 		  == (Indirect | Direct))
1620 		addr_insn = 1;
1621 
1622 	      if (insn.operand_type[addr_insn]->op_type & (AllReg))
1623 		insn.addressing_mode = AM_Register;
1624 	      else if (insn.operand_type[addr_insn]->op_type & Direct)
1625 		insn.addressing_mode = AM_Direct;
1626 	      else if (insn.operand_type[addr_insn]->op_type & Indirect)
1627 		insn.addressing_mode = AM_Indirect;
1628 	      else
1629 		insn.addressing_mode = AM_Immediate;
1630 	    }
1631 	}
1632       else
1633 	{
1634 	  as_bad ("The %s operand doesn't match", ordinal_names[count]);
1635 	  return;
1636 	}
1637     }
1638 
1639   /* Now set the addressing mode for 3 operand instructions.  */
1640   if ((insn.tm->operand_types[0] & op3T1)
1641       && (insn.tm->operand_types[1] & op3T2))
1642     {
1643       /* Set the addressing mode to the values used for 2 operand
1644 	 instructions in the  G addressing field of the opcode.  */
1645       char *p;
1646       switch (insn.operand_type[0]->op_type)
1647 	{
1648 	case Rn:
1649 	case ARn:
1650 	case DPReg:
1651 	case OtherReg:
1652 	  if (insn.operand_type[1]->op_type & (AllReg))
1653 	    insn.addressing_mode = AM_Register;
1654 	  else if (insn.operand_type[1]->op_type & Indirect)
1655 	    insn.addressing_mode = AM_Direct;
1656 	  else
1657 	    {
1658 	      /* Shouldn't make it to this stage.  */
1659 	      as_bad ("Incompatible first and second operands in instruction");
1660 	      return;
1661 	    }
1662 	  break;
1663 	case Indirect:
1664 	  if (insn.operand_type[1]->op_type & (AllReg))
1665 	    insn.addressing_mode = AM_Indirect;
1666 	  else if (insn.operand_type[1]->op_type & Indirect)
1667 	    insn.addressing_mode = AM_Immediate;
1668 	  else
1669 	    {
1670 	      /* Shouldn't make it to this stage.  */
1671 	      as_bad ("Incompatible first and second operands in instruction");
1672 	      return;
1673 	    }
1674 	  break;
1675 	}
1676       /* Now make up the opcode for the 3 operand instructions.  As in
1677 	 parallel instructions, there will be no unresolved values, so they
1678 	 can be fully formed and added to the frag table.  */
1679       insn.opcode = insn.tm->base_opcode;
1680       if (insn.operand_type[0]->op_type & Indirect)
1681 	{
1682 	  insn.opcode |= (insn.operand_type[0]->indirect.ARnum);
1683 	  insn.opcode |= (insn.operand_type[0]->indirect.mod << 3);
1684 	}
1685       else
1686 	insn.opcode |= (insn.operand_type[0]->reg.opcode);
1687 
1688       if (insn.operand_type[1]->op_type & Indirect)
1689 	{
1690 	  insn.opcode |= (insn.operand_type[1]->indirect.ARnum << 8);
1691 	  insn.opcode |= (insn.operand_type[1]->indirect.mod << 11);
1692 	}
1693       else
1694 	insn.opcode |= (insn.operand_type[1]->reg.opcode << 8);
1695 
1696       if (insn.operands == 3)
1697 	insn.opcode |= (insn.operand_type[2]->reg.opcode << 16);
1698 
1699       insn.opcode |= insn.addressing_mode;
1700       p = frag_more (INSN_SIZE);
1701       md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1702     }
1703   else
1704     {
1705       /* Not a three operand instruction.  */
1706       char *p;
1707       int am_insn = -1;
1708       insn.opcode = insn.tm->base_opcode;
1709       /* Create frag for instruction - all instructions are 4 bytes long.  */
1710       p = frag_more (INSN_SIZE);
1711       if ((insn.operands > 0) && (insn.tm->opcode_modifier == AddressMode))
1712 	{
1713 	  insn.opcode |= insn.addressing_mode;
1714 	  if (insn.addressing_mode == AM_Indirect)
1715 	    {
1716 	      /* Determine which operand gives the addressing mode.  */
1717 	      if (insn.operand_type[0]->op_type & Indirect)
1718 		am_insn = 0;
1719 	      if ((insn.operands > 1)
1720 		  && (insn.operand_type[1]->op_type & Indirect))
1721 		am_insn = 1;
1722 	      insn.opcode |= (insn.operand_type[am_insn]->indirect.disp);
1723 	      insn.opcode |= (insn.operand_type[am_insn]->indirect.ARnum << 8);
1724 	      insn.opcode |= (insn.operand_type[am_insn]->indirect.mod << 11);
1725 	      if (insn.operands > 1)
1726 		insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16);
1727 	      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1728 	    }
1729 	  else if (insn.addressing_mode == AM_Register)
1730 	    {
1731 	      insn.opcode |= (insn.operand_type[0]->reg.opcode);
1732 	      if (insn.operands > 1)
1733 		insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
1734 	      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1735 	    }
1736 	  else if (insn.addressing_mode == AM_Direct)
1737 	    {
1738 	      if (insn.operand_type[0]->op_type & Direct)
1739 		am_insn = 0;
1740 	      if ((insn.operands > 1)
1741 		  && (insn.operand_type[1]->op_type & Direct))
1742 		am_insn = 1;
1743 	      if (insn.operands > 1)
1744 		insn.opcode |=
1745 		  (insn.operand_type[! am_insn]->reg.opcode << 16);
1746 	      if (insn.operand_type[am_insn]->direct.resolved == 1)
1747 		{
1748 		  /* Resolved values can be placed straight
1749 		     into instruction word, and output.  */
1750 		  insn.opcode |=
1751 		    (insn.operand_type[am_insn]->direct.address & 0x0000FFFF);
1752 		  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1753 		}
1754 	      else
1755 		{
1756 		  /* Unresolved direct addressing mode instruction.  */
1757 		  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1758 		  fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2,
1759 			       & insn.operand_type[am_insn]->direct.direct_expr,
1760 			       0, 0);
1761 		}
1762 	    }
1763 	  else if (insn.addressing_mode == AM_Immediate)
1764 	    {
1765 	      if (insn.operand_type[0]->immediate.resolved == 1)
1766 		{
1767 		  char *keeploc;
1768 		  int size;
1769 
1770 		  if (insn.operands > 1)
1771 		    insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
1772 
1773 		  switch (insn.tm->imm_arg_type)
1774 		    {
1775 		    case Imm_Float:
1776 		      debug ("Floating point first operand\n");
1777 		      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1778 
1779 		      keeploc = input_line_pointer;
1780 		      input_line_pointer =
1781 			insn.operand_type[0]->immediate.label;
1782 
1783 		      if (md_atof ('f', p + 2, & size) != 0)
1784 			{
1785 			  as_bad ("invalid short form floating point immediate operand");
1786 			  return;
1787 			}
1788 
1789 		      input_line_pointer = keeploc;
1790 		      break;
1791 
1792 		    case Imm_UInt:
1793 		      debug ("Unsigned int first operand\n");
1794 		      if (insn.operand_type[0]->immediate.decimal_found)
1795 			as_warn ("rounding down first operand float to unsigned int");
1796 		      if (insn.operand_type[0]->immediate.u_number > 0xFFFF)
1797 			as_warn ("only lower 16-bits of first operand are used");
1798 		      insn.opcode |=
1799 			(insn.operand_type[0]->immediate.u_number & 0x0000FFFFL);
1800 		      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1801 		      break;
1802 
1803 		    case Imm_SInt:
1804 		      debug ("Int first operand\n");
1805 
1806 		      if (insn.operand_type[0]->immediate.decimal_found)
1807 			as_warn ("rounding down first operand float to signed int");
1808 
1809 		      if (insn.operand_type[0]->immediate.s_number < -32768 ||
1810 			  insn.operand_type[0]->immediate.s_number > 32767)
1811 			{
1812 			  as_bad ("first operand is too large for 16-bit signed int");
1813 			  return;
1814 			}
1815 		      insn.opcode |=
1816 			(insn.operand_type[0]->immediate.s_number & 0x0000FFFFL);
1817 		      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1818 		      break;
1819 		    }
1820 		}
1821 	      else
1822 		{
1823 		  /* Unresolved immediate label.  */
1824 		  if (insn.operands > 1)
1825 		    insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
1826 		  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1827 		  fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2,
1828 			       & insn.operand_type[0]->immediate.imm_expr,
1829 			       0, 0);
1830 		}
1831 	    }
1832 	}
1833       else if (insn.tm->opcode_modifier == PCRel)
1834 	{
1835 	  /* Conditional Branch and Call instructions.  */
1836 	  if ((insn.tm->operand_types[0] & (AllReg | Disp))
1837 	      == (AllReg | Disp))
1838 	    {
1839 	      if (insn.operand_type[0]->op_type & (AllReg))
1840 		{
1841 		  insn.opcode |= (insn.operand_type[0]->reg.opcode);
1842 		  insn.opcode |= PC_Register;
1843 		  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1844 		}
1845 	      else
1846 		{
1847 		  insn.opcode |= PC_Relative;
1848 		  if (insn.operand_type[0]->immediate.resolved == 1)
1849 		    {
1850 		      insn.opcode |=
1851 			(insn.operand_type[0]->immediate.s_number & 0x0000FFFF);
1852 		      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1853 		    }
1854 		  else
1855 		    {
1856 		      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1857 		      fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal),
1858 				   2, & insn.operand_type[0]->immediate.imm_expr,
1859 				   1, 0);
1860 		    }
1861 		}
1862 	    }
1863 	  else if ((insn.tm->operand_types[0] & ARn) == ARn)
1864 	    {
1865 	      /* Decrement and Branch instructions.  */
1866 	      insn.opcode |= ((insn.operand_type[0]->reg.opcode - 0x08) << 22);
1867 	      if (insn.operand_type[1]->op_type & (AllReg))
1868 		{
1869 		  insn.opcode |= (insn.operand_type[1]->reg.opcode);
1870 		  insn.opcode |= PC_Register;
1871 		  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1872 		}
1873 	      else if (insn.operand_type[1]->immediate.resolved == 1)
1874 		{
1875 		  if (insn.operand_type[0]->immediate.decimal_found)
1876 		    {
1877 		      as_bad ("first operand is floating point");
1878 		      return;
1879 		    }
1880 		  if (insn.operand_type[0]->immediate.s_number < -32768 ||
1881 		      insn.operand_type[0]->immediate.s_number > 32767)
1882 		    {
1883 		      as_bad ("first operand is too large for 16-bit signed int");
1884 		      return;
1885 		    }
1886 		  insn.opcode |= (insn.operand_type[1]->immediate.s_number);
1887 		  insn.opcode |= PC_Relative;
1888 		  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1889 		}
1890 	      else
1891 		{
1892 		  insn.opcode |= PC_Relative;
1893 		  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1894 		  fix_new_exp (frag_now, p + 2 - frag_now->fr_literal, 2,
1895 			       & insn.operand_type[1]->immediate.imm_expr,
1896 			       1, 0);
1897 		}
1898 	    }
1899 	}
1900       else if (insn.tm->operand_types[0] == IVector)
1901 	{
1902 	  /* Trap instructions.  */
1903 	  if (insn.operand_type[0]->op_type & IVector)
1904 	    insn.opcode |= (insn.operand_type[0]->immediate.u_number);
1905 	  else
1906 	    {
1907 	      /* Shouldn't get here.  */
1908 	      as_bad ("interrupt vector for trap instruction out of range");
1909 	      return;
1910 	    }
1911 	  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1912 	}
1913       else if (insn.tm->opcode_modifier == StackOp
1914 	       || insn.tm->opcode_modifier == Rotate)
1915 	{
1916 	  /* Push, Pop and Rotate instructions.  */
1917 	  insn.opcode |= (insn.operand_type[0]->reg.opcode << 16);
1918 	  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1919 	}
1920       else if ((insn.tm->operand_types[0] & (Abs24 | Direct))
1921 	       == (Abs24 | Direct))
1922 	{
1923 	  /* LDP Instruction needs to be tested
1924 	     for before the next section.  */
1925 	  if (insn.operand_type[0]->op_type & Direct)
1926 	    {
1927 	      if (insn.operand_type[0]->direct.resolved == 1)
1928 		{
1929 		  /* Direct addressing uses lower 8 bits of direct address.  */
1930 		  insn.opcode |=
1931 		    (insn.operand_type[0]->direct.address & 0x00FF0000) >> 16;
1932 		  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1933 		}
1934 	      else
1935 		{
1936 		  fixS *fix;
1937 
1938 		  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1939 		  fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal),
1940 				     1, &insn.operand_type[0]->direct.direct_expr, 0, 0);
1941 		  /* Ensure that the assembler doesn't complain
1942 		     about fitting a 24-bit address into 8 bits.  */
1943 		  fix->fx_no_overflow = 1;
1944 		}
1945 	    }
1946 	  else
1947 	    {
1948 	      if (insn.operand_type[0]->immediate.resolved == 1)
1949 		{
1950 		  /* Immediate addressing uses upper 8 bits of address.  */
1951 		  if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
1952 		    {
1953 		      as_bad ("LDP instruction needs a 24-bit operand");
1954 		      return;
1955 		    }
1956 		  insn.opcode |=
1957 		    ((insn.operand_type[0]->immediate.u_number & 0x00FF0000) >> 16);
1958 		  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1959 		}
1960 	      else
1961 		{
1962 		  fixS *fix;
1963 		  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1964 		  fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal),
1965 				     1, &insn.operand_type[0]->immediate.imm_expr,
1966 				     0, 0);
1967 		  fix->fx_no_overflow = 1;
1968 		}
1969 	    }
1970 	}
1971       else if (insn.tm->operand_types[0] & (Imm24))
1972 	{
1973 	  /* Unconditional Branch and Call instructions.  */
1974 	  if (insn.operand_type[0]->immediate.resolved == 1)
1975 	    {
1976 	      if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
1977 		as_warn ("first operand is too large for a 24-bit displacement");
1978 	      insn.opcode |=
1979 		(insn.operand_type[0]->immediate.u_number & 0x00FFFFFF);
1980 	      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1981 	    }
1982 	  else
1983 	    {
1984 	      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1985 	      fix_new_exp (frag_now, p + 1 - (frag_now->fr_literal), 3,
1986 			   & insn.operand_type[0]->immediate.imm_expr, 0, 0);
1987 	    }
1988 	}
1989       else if (insn.tm->operand_types[0] & NotReq)
1990 	/* Check for NOP instruction without arguments.  */
1991 	md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1992 
1993       else if (insn.tm->operands == 0)
1994 	/* Check for instructions without operands.  */
1995 	md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1996     }
1997   debug ("Addressing mode: %08X\n", insn.addressing_mode);
1998   {
1999     unsigned int i;
2000 
2001     for (i = 0; i < insn.operands; i++)
2002       {
2003 	if (insn.operand_type[i]->immediate.label)
2004 	  free (insn.operand_type[i]->immediate.label);
2005 	free (insn.operand_type[i]);
2006       }
2007   }
2008   debug ("Final opcode: %08X\n", insn.opcode);
2009   debug ("\n");
2010 }
2011 
2012