1 /* tc-maxq.c -- assembler code for a MAXQ chip.
2 
3    Copyright 2004, 2005 Free Software Foundation, Inc.
4 
5    Contributed by HCL Technologies Pvt. Ltd.
6 
7    Author: Vineet Sharma(vineets@noida.hcltech.com) Inderpreet
8    S.(inderpreetb@noida.hcltech.com)
9 
10    This file is part of GAS.
11 
12    GAS is free software; you can redistribute it and/or modify it under the
13    terms of the GNU General Public License as published by the Free Software
14    Foundation; either version 2, or (at your option) any later version.
15 
16    GAS is distributed in the hope that it will be useful, but WITHOUT ANY
17    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18    FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
19    details.
20 
21    You should have received a copy of the GNU General Public License along
22    with GAS; see the file COPYING.  If not, write to the Free Software
23    Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
24 
25 #include "as.h"
26 #include "safe-ctype.h"
27 #include "subsegs.h"
28 #include "dwarf2dbg.h"
29 #include "tc-maxq.h"
30 #include "opcode/maxq.h"
31 #include "ctype.h"
32 
33 #ifndef MAXQ10S
34 #define MAXQ10S 1
35 #endif
36 
37 #ifndef _STRING_H
38 #include "string.h"
39 #endif
40 
41 #ifndef DEFAULT_ARCH
42 #define DEFAULT_ARCH "MAXQ20"
43 #endif
44 
45 #ifndef MAX_OPERANDS
46 #define MAX_OPERANDS 2
47 #endif
48 
49 #ifndef MAX_MNEM_SIZE
50 #define MAX_MNEM_SIZE 8
51 #endif
52 
53 #ifndef END_OF_INSN
54 #define END_OF_INSN '\0'
55 #endif
56 
57 #ifndef IMMEDIATE_PREFIX
58 #define IMMEDIATE_PREFIX '#'
59 #endif
60 
61 #ifndef MAX_REG_NAME_SIZE
62 #define MAX_REG_NAME_SIZE 4
63 #endif
64 
65 #ifndef MAX_MEM_NAME_SIZE
66 #define MAX_MEM_NAME_SIZE 9
67 #endif
68 
69 /* opcode for PFX[0].  */
70 #define PFX0 0x0b
71 
72 /* Set default to MAXQ20.  */
73 unsigned int max_version = bfd_mach_maxq20;
74 
75 const char *default_arch = DEFAULT_ARCH;
76 
77 /* Type of the operand: Register,Immediate,Memory access,flag or bit.  */
78 
79 union _maxq20_op
80 {
81   const reg_entry *  reg;
82   char               imms; /* This is to store the immediate value operand.  */
83   expressionS *      disps;
84   symbolS *          data;
85   const mem_access * mem;
86   int                flag;
87   const reg_bit *    r_bit;
88 };
89 
90 typedef union _maxq20_op maxq20_opcode;
91 
92 /* For handling optional L/S in Maxq20.  */
93 
94 /* Exposed For Linker - maps indirectly to the liker relocations.  */
95 #define LONG_PREFIX  		MAXQ_LONGJUMP	/* BFD_RELOC_16 */
96 #define SHORT_PREFIX 		MAXQ_SHORTJUMP	/* BFD_RELOC_16_PCREL_S2 */
97 #define ABSOLUTE_ADDR_FOR_DATA 	MAXQ_INTERSEGMENT
98 
99 #define NO_PREFIX    		0
100 #define EXPLICT_LONG_PREFIX     14
101 
102 /* The main instruction structure containing fields to describe instrn */
103 typedef struct _maxq20_insn
104 {
105   /* The opcode information for the MAXQ20 */
106   MAXQ20_OPCODE_INFO op;
107 
108   /* The number of operands */
109   unsigned int operands;
110 
111   /* Number of different types of operands - Comments can be removed if reqd.
112    */
113   unsigned int reg_operands, mem_operands, disp_operands, data_operands;
114   unsigned int imm_operands, imm_bit_operands, bit_operands, flag_operands;
115 
116   /* Types of the individual operands */
117   UNKNOWN_OP types[MAX_OPERANDS];
118 
119   /* Relocation type for operand : to be investigated into */
120   int reloc[MAX_OPERANDS];
121 
122   /* Complete information of the Operands */
123   maxq20_opcode maxq20_op[MAX_OPERANDS];
124 
125   /* Choice of prefix register whenever needed */
126   int prefix;
127 
128   /* Optional Prefix for Instructions like LJUMP, SJUMP etc */
129   unsigned char Instr_Prefix;
130 
131   /* 16 bit Instruction word */
132   unsigned char instr[2];
133 }
134 maxq20_insn;
135 
136 /* Definitions of all possible characters that can start an operand.  */
137 const char *extra_symbol_chars = "@(#";
138 
139 /* Special Character that would start a comment.  */
140 const char comment_chars[] = ";";
141 
142 /* Starts a comment when it appears at the start of a line.  */
143 const char line_comment_chars[] = ";#";
144 
145 const char line_separator_chars[] = "";	/* originally may b by sudeep "\n".  */
146 
147 /*  The following are used for option processing.  */
148 
149 /* This is added to the mach independent string passed to getopt.  */
150 const char *md_shortopts = "q";
151 
152 /* Characters for exponent and floating point.  */
153 const char EXP_CHARS[] = "eE";
154 const char FLT_CHARS[] = "";
155 
156 /* This is for the machine dependent option handling.  */
157 #define OPTION_EB               (OPTION_MD_BASE + 0)
158 #define OPTION_EL               (OPTION_MD_BASE + 1)
159 #define MAXQ_10                 (OPTION_MD_BASE + 2)
160 #define MAXQ_20			(OPTION_MD_BASE + 3)
161 
162 struct option md_longopts[] =
163 {
164   {"MAXQ10", no_argument, NULL, MAXQ_10},
165   {"MAXQ20", no_argument, NULL, MAXQ_20},
166   {NULL, no_argument, NULL, 0}
167 };
168 size_t md_longopts_size = sizeof (md_longopts);
169 
170 /* md_undefined_symbol We have no need for this function.  */
171 
172 symbolS *
md_undefined_symbol(char * name ATTRIBUTE_UNUSED)173 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
174 {
175   return NULL;
176 }
177 
178 static void
maxq_target(int target)179 maxq_target (int target)
180 {
181   max_version = target;
182   bfd_set_arch_mach (stdoutput, bfd_arch_maxq, max_version);
183 }
184 
185 int
md_parse_option(int c,char * arg ATTRIBUTE_UNUSED)186 md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
187 {
188   /* Any options support will be added onto this switch case.  */
189   switch (c)
190     {
191     case MAXQ_10:
192       max_version = bfd_mach_maxq10;
193       break;
194     case MAXQ_20:
195       max_version = bfd_mach_maxq20;
196       break;
197 
198     default:
199       return 0;
200     }
201 
202   return 1;
203 }
204 
205 /* When a usage message is printed, this function is called and
206    it prints a description of the machine specific options.  */
207 
208 void
md_show_usage(FILE * stream)209 md_show_usage (FILE * stream)
210 {
211   /* Over here we will fill the description of the machine specific options.  */
212 
213   fprintf (stream, _(" MAXQ-specific assembler options:\n"));
214 
215   fprintf (stream, _("\
216 	-MAXQ20		       generate obj for MAXQ20(default)\n\
217 	-MAXQ10		       generate obj for MAXQ10\n\
218 	"));
219 }
220 
221 unsigned long
maxq20_mach(void)222 maxq20_mach (void)
223 {
224   if (!(strcmp (default_arch, "MAXQ20")))
225     return 0;
226 
227   as_fatal (_("Unknown architecture"));
228   return 1;
229 }
230 
231 arelent *
tc_gen_reloc(asection * section ATTRIBUTE_UNUSED,fixS * fixp)232 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
233 {
234   arelent *rel;
235   bfd_reloc_code_real_type code;
236 
237   switch (fixp->fx_r_type)
238     {
239     case MAXQ_INTERSEGMENT:
240     case MAXQ_LONGJUMP:
241     case BFD_RELOC_16_PCREL_S2:
242       code = fixp->fx_r_type;
243       break;
244 
245     case 0:
246     default:
247       switch (fixp->fx_size)
248 	{
249 	default:
250 	  as_bad_where (fixp->fx_file, fixp->fx_line,
251 			_("can not do %d byte relocation"), fixp->fx_size);
252 	  code = BFD_RELOC_32;
253 	  break;
254 
255 	case 1:
256 	  code = BFD_RELOC_8;
257 	  break;
258 	case 2:
259 	  code = BFD_RELOC_16;
260 	  break;
261 	case 4:
262 	  code = BFD_RELOC_32;
263 	  break;
264 	}
265     }
266 
267   rel = xmalloc (sizeof (arelent));
268   rel->sym_ptr_ptr  = xmalloc (sizeof (asymbol *));
269   *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
270 
271   rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
272   rel->addend  = fixp->fx_addnumber;
273   rel->howto   = bfd_reloc_type_lookup (stdoutput, code);
274 
275   if (rel->howto == NULL)
276     {
277       as_bad_where (fixp->fx_file, fixp->fx_line,
278 		    _("cannot represent relocation type %s"),
279 		    bfd_get_reloc_code_name (code));
280 
281       /* Set howto to a garbage value so that we can keep going.  */
282       rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
283       assert (rel->howto != NULL);
284     }
285 
286   return rel;
287 }
288 
289 /* md_estimate_size_before_relax()
290 
291    Called just before relax() for rs_machine_dependent frags.  The MAXQ
292    assembler uses these frags to handle 16 bit absolute jumps which require a
293    prefix instruction to be inserted. Any symbol that is now undefined will
294    not become defined. Return the correct fr_subtype in the frag. Return the
295    initial "guess for variable size of frag"(This will be eiter 2 or 0) to
296    caller. The guess is actually the growth beyond the fixed part.  Whatever
297    we do to grow the fixed or variable part contributes to our returned
298    value.  */
299 
300 int
md_estimate_size_before_relax(fragS * fragP,segT segment)301 md_estimate_size_before_relax (fragS *fragP, segT segment)
302 {
303   /* Check whether the symbol has been resolved or not.
304      Otherwise we will have to generate a fixup.  */
305   if ((S_GET_SEGMENT (fragP->fr_symbol) != segment)
306       || fragP->fr_subtype == EXPLICT_LONG_PREFIX)
307     {
308       RELOC_ENUM reloc_type;
309       unsigned char *opcode;
310       int old_fr_fix;
311 
312       /* Now this symbol has not been defined in this file.
313 	 Hence we will have to create a fixup.  */
314       int size = 2;
315 
316       /* This is for the prefix instruction.  */
317 
318       if (fragP->fr_subtype == EXPLICT_LONG_PREFIX)
319 	fragP->fr_subtype = LONG_PREFIX;
320 
321       if (S_GET_SEGMENT (fragP->fr_symbol) != segment
322 	  && ((!(fragP->fr_subtype) == EXPLICT_LONG_PREFIX)))
323 	fragP->fr_subtype = ABSOLUTE_ADDR_FOR_DATA;
324 
325       reloc_type =
326 	(fragP->fr_subtype ? fragP->fr_subtype : ABSOLUTE_ADDR_FOR_DATA);
327 
328       fragP->fr_subtype = reloc_type;
329 
330       if (reloc_type == SHORT_PREFIX)
331 	size = 0;
332       old_fr_fix = fragP->fr_fix;
333       opcode = (unsigned char *) fragP->fr_opcode;
334 
335       fragP->fr_fix += (size);
336 
337       fix_new (fragP, old_fr_fix - 2, size + 2,
338 	       fragP->fr_symbol, fragP->fr_offset, 0, reloc_type);
339       frag_wane (fragP);
340       return fragP->fr_fix - old_fr_fix;
341     }
342 
343   if (fragP->fr_subtype == SHORT_PREFIX)
344     {
345       fragP->fr_subtype = SHORT_PREFIX;
346       return 0;
347     }
348 
349   if (fragP->fr_subtype == NO_PREFIX || fragP->fr_subtype == LONG_PREFIX)
350     {
351       unsigned long instr;
352       unsigned long call_addr;
353       long diff;
354       fragS *f;
355       diff = diff ^ diff;;
356       call_addr = call_addr ^ call_addr;
357       instr = 0;
358       f = NULL;
359 
360       /* segment_info_type *seginfo = seg_info (segment);  */
361       instr = fragP->fr_address + fragP->fr_fix - 2;
362 
363       /* This is the offset if it is a PC relative jump.  */
364       call_addr = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset;
365 
366       /* PC stores the value of the next instruction.  */
367       diff = (call_addr - instr) - 1;
368 
369       if (diff >= (-128 * 2) && diff <= (2 * 127))
370 	{
371 	  /* Now as offset is an 8 bit value, we will pass
372 	     that to the jump instruction directly.  */
373 	  fragP->fr_subtype = NO_PREFIX;
374 	  return 0;
375 	}
376 
377       fragP->fr_subtype = LONG_PREFIX;
378       return 2;
379     }
380 
381   as_fatal (_("Illegal Reloc type in md_estimate_size_before_relax for line : %d"),
382 	    frag_now->fr_line);
383   return 0;
384 }
385 
386 /* Equal to MAX_PRECISION in atof-ieee.c */
387 #define MAX_LITTLENUMS 6
388 
389 /* Turn a string in input_line_pointer into a floating point constant of type
390    TYPE, and store the appropriate bytes in *LITP.  The number of LITTLENUMS
391    emitted is stored in *SIZEP.  An error message is returned, or NULL on OK.  */
392 
393 char *
md_atof(int type,char * litP,int * sizeP)394 md_atof (int type, char * litP, int * sizeP)
395 {
396   int prec;
397   LITTLENUM_TYPE words[4];
398   char *t;
399   int i;
400 
401   switch (type)
402     {
403     case 'f':
404       prec = 2;
405       break;
406 
407     case 'd':
408       prec = 2;
409       /* The size of Double has been changed to 2 words ie 32 bits.  */
410       /* prec = 4; */
411       break;
412 
413     default:
414       *sizeP = 0;
415       return _("bad call to md_atof");
416     }
417 
418   t = atof_ieee (input_line_pointer, type, words);
419   if (t)
420     input_line_pointer = t;
421 
422   *sizeP = prec * 2;
423 
424   for (i = prec - 1; i >= 0; i--)
425     {
426       md_number_to_chars (litP, (valueT) words[i], 2);
427       litP += 2;
428     }
429 
430   return NULL;
431 }
432 
433 void
maxq20_cons_fix_new(fragS * frag,unsigned int off,unsigned int len,expressionS * exp)434 maxq20_cons_fix_new (fragS * frag, unsigned int off, unsigned int len,
435 		     expressionS * exp)
436 {
437   int r = 0;
438 
439   switch (len)
440     {
441     case 2:
442       r = MAXQ_WORDDATA;	/* Word+n */
443       break;
444     case 4:
445       r = MAXQ_LONGDATA;	/* Long+n */
446       break;
447     }
448 
449   fix_new_exp (frag, off, len, exp, 0, r);
450   return;
451 }
452 
453 /* GAS will call this for every rs_machine_dependent fragment. The
454    instruction is compleated using the data from the relaxation pass. It may
455    also create any necessary relocations.  */
456 void
md_convert_frag(bfd * headers ATTRIBUTE_UNUSED,segT seg ATTRIBUTE_UNUSED,fragS * fragP)457 md_convert_frag (bfd *   headers ATTRIBUTE_UNUSED,
458 		 segT    seg ATTRIBUTE_UNUSED,
459 		 fragS * fragP)
460 {
461   char *opcode;
462   offsetT target_address;
463   offsetT opcode_address;
464   offsetT displacement_from_opcode_start;
465   int address;
466 
467   opcode = fragP->fr_opcode;
468   address = 0;
469   target_address = opcode_address = displacement_from_opcode_start = 0;
470 
471   target_address =
472     (S_GET_VALUE (fragP->fr_symbol) / MAXQ_OCTETS_PER_BYTE) +
473     (fragP->fr_offset / MAXQ_OCTETS_PER_BYTE);
474 
475   opcode_address =
476     (fragP->fr_address / MAXQ_OCTETS_PER_BYTE) +
477     ((fragP->fr_fix - 2) / MAXQ_OCTETS_PER_BYTE);
478 
479   /* PC points to the next Instruction.  */
480   displacement_from_opcode_start = ((target_address - opcode_address)  - 1);
481 
482   if ((displacement_from_opcode_start >= -128
483        && displacement_from_opcode_start <= 127)
484       && (fragP->fr_subtype == SHORT_PREFIX
485 	  || fragP->fr_subtype == NO_PREFIX))
486     {
487       /* Its a displacement.  */
488       *opcode = (char) displacement_from_opcode_start;
489     }
490   else
491     {
492       /* Its an absolute 16 bit jump. Now we have to
493 	 load the prefix operator with the upper 8 bits.  */
494       if (fragP->fr_subtype == SHORT_PREFIX)
495 	{
496 	  as_bad (_("Cant make long jump/call into short jump/call : %d"),
497 		  fragP->fr_line);
498 	  return;
499 	}
500 
501       /* Check whether the symbol has been resolved or not.
502 	 Otherwise we will have to generate a fixup.  */
503 
504       if (fragP->fr_subtype != SHORT_PREFIX)
505 	{
506 	  RELOC_ENUM reloc_type;
507 	  int old_fr_fix;
508 	  int size = 2;
509 
510 	  /* Now this is a basolute jump/call.
511 	     Hence we will have to create a fixup.  */
512 	  if (fragP->fr_subtype == NO_PREFIX)
513 	    fragP->fr_subtype = LONG_PREFIX;
514 
515 	  reloc_type =
516 	    (fragP->fr_subtype ? fragP->fr_subtype : LONG_PREFIX);
517 
518 	  if (reloc_type == 1)
519 	    size = 0;
520 	  old_fr_fix = fragP->fr_fix;
521 
522 	  fragP->fr_fix += (size);
523 
524 	  fix_new (fragP, old_fr_fix - 2, size + 2,
525 		   fragP->fr_symbol, fragP->fr_offset, 0, reloc_type);
526 	  frag_wane (fragP);
527 	}
528     }
529 }
530 
531 long
md_pcrel_from(fixS * fixP)532 md_pcrel_from (fixS *fixP)
533 {
534   return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
535 }
536 
537 /* Writes the val to the buf, where n is the nuumber of bytes to write.  */
538 
539 void
maxq_number_to_chars(char * buf,valueT val,int n)540 maxq_number_to_chars (char *buf, valueT val, int n)
541 {
542   if (target_big_endian)
543     number_to_chars_bigendian (buf, val, n);
544   else
545     number_to_chars_littleendian (buf, val, n);
546 }
547 
548 /* GAS will call this for each fixup. It's main objective is to store the
549    correct value in the object file. 'fixup_segment' performs the generic
550    overflow check on the 'valueT *val' argument after md_apply_fix returns.
551    If the overflow check is relevant for the target machine, then
552    'md_apply_fix' should modify 'valueT *val', typically to the value stored
553    in the object file (not to be done in MAXQ).  */
554 
555 void
md_apply_fix(fixS * fixP,valueT * valT,segT seg ATTRIBUTE_UNUSED)556 md_apply_fix (fixS *fixP, valueT *valT, segT seg ATTRIBUTE_UNUSED)
557 {
558   char *p = fixP->fx_frag->fr_literal + fixP->fx_where;
559   char *frag_to_fix_at =
560     fixP->fx_frag->fr_literal + fixP->fx_frag->fr_fix - 2;
561 
562   if (fixP)
563     {
564       if (fixP->fx_frag && valT)
565 	{
566 	  /* If the relaxation substate is not defined we make it equal
567 	     to the kind of relocation the fixup is generated for.  */
568 	  if (!fixP->fx_frag->fr_subtype)
569 	    fixP->fx_frag->fr_subtype = fixP->fx_r_type;
570 
571 	  /* For any instruction in which either we have specified an
572 	     absolute address or it is a long jump we need to add a PFX0
573 	     instruction to it. In this case as the instruction has already
574 	     being written at 'fx_where' in the frag we copy it at the end of
575 	     the frag(which is where the relocation was generated) as when
576 	     the relocation is generated the frag is grown by 2 type, this is
577 	     where we copy the contents of fx_where and add a pfx0 at
578 	     fx_where.  */
579 	  if ((fixP->fx_frag->fr_subtype == ABSOLUTE_ADDR_FOR_DATA)
580 	      || (fixP->fx_frag->fr_subtype == LONG_PREFIX))
581 	    {
582 	      *(frag_to_fix_at + 1) = *(p + 1);
583 	      maxq_number_to_chars (p + 1, PFX0, 1);
584 	    }
585 
586 	  /* Remember value for tc_gen_reloc.  */
587 	  fixP->fx_addnumber = *valT;
588 	}
589 
590       /* Some fixups generated by GAS which gets resovled before this this
591          func. is called need to be wriiten to the frag as here we are going
592          to go away with the relocations fx_done=1.  */
593       if (fixP->fx_addsy == NULL)
594 	{
595 	  maxq_number_to_chars (p, *valT, fixP->fx_size);
596 	  fixP->fx_addnumber = *valT;
597 	  fixP->fx_done = 1;
598 	}
599     }
600 }
601 
602 /* Tables for lexical analysis.  */
603 static char mnemonic_chars[256];
604 static char register_chars[256];
605 static char operand_chars[256];
606 static char identifier_chars[256];
607 static char digit_chars[256];
608 
609 /* Lexical Macros.  */
610 #define is_mnemonic_char(x)   (mnemonic_chars[(unsigned char)(x)])
611 #define is_register_char(x)   (register_chars[(unsigned char)(x)])
612 #define is_operand_char(x)    (operand_chars[(unsigned char)(x)])
613 #define is_space_char(x)      (x==' ')
614 #define is_identifier_char(x) (identifier_chars[(unsigned char)(x)])
615 #define is_digit_char(x)      (identifier_chars[(unsigned char)(x)])
616 
617 /* Special characters for operands.  */
618 static char operand_special_chars[] = "[]@.-+";
619 
620 /* md_assemble() will always leave the instruction passed to it unaltered.
621    To do this we store the instruction in a special stack.  */
622 static char save_stack[32];
623 static char *save_stack_p;
624 
625 #define END_STRING_AND_SAVE(s)	\
626   do				\
627     {				\
628       *save_stack_p++ = *(s);	\
629       *s = '\0';		\
630     }				\
631   while (0)
632 
633 #define RESTORE_END_STRING(s)	\
634   do				\
635     {				\
636       *(s) = *(--save_stack_p);	\
637     }				\
638   while (0)
639 
640 /* The instruction we are assembling.  */
641 static maxq20_insn i;
642 
643 /* The current template.  */
644 static MAXQ20_OPCODES *current_templates;
645 
646 /* The displacement operand if any.  */
647 static expressionS disp_expressions;
648 
649 /* Current Operand we are working on (0:1st operand,1:2nd operand).  */
650 static int this_operand;
651 
652 /* The prefix instruction if used.  */
653 static char PFX_INSN[2];
654 static char INSERT_BUFFER[2];
655 
656 /* For interface with expression() ????? */
657 extern char *input_line_pointer;
658 
659 /* The HASH Tables:  */
660 
661 /* Operand Hash Table.  */
662 static struct hash_control *op_hash;
663 
664 /* Register Hash Table.  */
665 static struct hash_control *reg_hash;
666 
667 /* Memory reference Hash Table.  */
668 static struct hash_control *mem_hash;
669 
670 /* Bit hash table.  */
671 static struct hash_control *bit_hash;
672 
673 /* Memory Access syntax table.  */
674 static struct hash_control *mem_syntax_hash;
675 
676 /* This is a mapping from pseudo-op names to functions.  */
677 
678 const pseudo_typeS md_pseudo_table[] =
679 {
680   {"int", cons, 2},		/* size of 'int' has been changed to 1 word
681 				   (i.e) 16 bits.  */
682   {"maxq10", maxq_target, bfd_mach_maxq10},
683   {"maxq20", maxq_target, bfd_mach_maxq20},
684   {NULL, 0, 0},
685 };
686 
687 #define SET_PFX_ARG(x) (PFX_INSN[1] = x)
688 
689 
690 /* This function sets the PFX value coresponding to the specs. Source
691    Destination Index Selection ---------------------------------- Write To|
692    SourceRegRange | Dest Addr Range
693    ------------------------------------------------------ PFX[0] | 0h-Fh |
694    0h-7h PFX[1] | 10h-1Fh | 0h-7h PFX[2] | 0h-Fh | 8h-Fh PFX[3] | 10h-1Fh |
695    8h-Fh PFX[4] | 0h-Fh | 10h-17h PFX[5] | 10h-1Fh | 10h-17h PFX[6] | 0h-Fh |
696    18h-1Fh PFX[7] | 0h-Fh | 18h-1Fh */
697 
698 static void
set_prefix(void)699 set_prefix (void)
700 {
701   short int src_index = 0, dst_index = 0;
702 
703   if (i.operands == 0)
704     return;
705   if (i.operands == 1)		/* Only SRC is Present */
706     {
707       if (i.types[0] == REG)
708 	{
709 	  if (!strcmp (i.op.name, "POP") || !strcmp (i.op.name, "POPI"))
710 	    {
711 	      dst_index = i.maxq20_op[0].reg[0].Mod_index;
712 	      src_index = 0x00;
713 	    }
714 	  else
715 	    {
716 	      src_index = i.maxq20_op[0].reg[0].Mod_index;
717 	      dst_index = 0x00;
718 	    }
719 	}
720     }
721 
722   if (i.operands == 2)
723     {
724       if (i.types[0] == REG && i.types[1] == REG)
725 	{
726 	  dst_index = i.maxq20_op[0].reg[0].Mod_index;
727 	  src_index = i.maxq20_op[1].reg[0].Mod_index;
728 	}
729       else if (i.types[0] != REG && i.types[1] == REG)	/* DST is Absent */
730 	{
731 	  src_index = i.maxq20_op[1].reg[0].Mod_index;
732 	  dst_index = 0x00;
733 	}
734       else if (i.types[0] == REG && i.types[1] != REG)	/* Id SRC is Absent */
735 	{
736 	  dst_index = i.maxq20_op[0].reg[0].Mod_index;
737 	  src_index = 0x00;
738 	}
739       else if (i.types[0] == BIT && i.maxq20_op[0].r_bit)
740 	{
741 	  dst_index = i.maxq20_op[0].r_bit->reg->Mod_index;
742 	  src_index = 0x00;
743 	}
744 
745       else if (i.types[1] == BIT && i.maxq20_op[1].r_bit)
746 	{
747 	  dst_index = 0x00;
748 	  src_index = i.maxq20_op[1].r_bit->reg->Mod_index;
749 	}
750     }
751 
752   if (src_index >= 0x00 && src_index <= 0xF)
753     {
754       if (dst_index >= 0x00 && dst_index <= 0x07)
755 	/* Set PFX[0] */
756 	i.prefix = 0;
757 
758       else if (dst_index >= 0x08 && dst_index <= 0x0F)
759 	/* Set PFX[2] */
760 	i.prefix = 2;
761 
762       else if (dst_index >= 0x10 && dst_index <= 0x17)
763 	/* Set PFX[4] */
764 	i.prefix = 4;
765 
766       else if (dst_index >= 0x18 && dst_index <= 0x1F)
767 	/* Set PFX[6] */
768 	i.prefix = 6;
769     }
770   else if (src_index >= 0x10 && src_index <= 0x1F)
771     {
772       if (dst_index >= 0x00 && dst_index <= 0x07)
773 	/* Set PFX[1] */
774 	i.prefix = 1;
775 
776       else if (dst_index >= 0x08 && dst_index <= 0x0F)
777 	/* Set PFX[3] */
778 	i.prefix = 3;
779 
780       else if (dst_index >= 0x10 && dst_index <= 0x17)
781 	/* Set PFX[5] */
782 	i.prefix = 5;
783 
784       else if (dst_index >= 0x18 && dst_index <= 0x1F)
785 	/* Set PFX[7] */
786 	i.prefix = 7;
787     }
788 }
789 
790 static unsigned char
is_a_LSinstr(const char * ln_pointer)791 is_a_LSinstr (const char *ln_pointer)
792 {
793   int i = 0;
794 
795   for (i = 0; LSInstr[i] != NULL; i++)
796     if (!strcmp (LSInstr[i], ln_pointer))
797       return 1;
798 
799   return 0;
800 }
801 
802 static void
LS_processing(const char * line)803 LS_processing (const char *line)
804 {
805   if (is_a_LSinstr (line))
806     {
807       if ((line[0] == 'L') || (line[0] == 'l'))
808 	{
809 	  i.prefix = 0;
810 	  INSERT_BUFFER[0] = PFX0;
811 	  i.Instr_Prefix = LONG_PREFIX;
812 	}
813       else if ((line[0] == 'S') || (line[0] == 's'))
814 	i.Instr_Prefix = SHORT_PREFIX;
815       else
816 	i.Instr_Prefix = NO_PREFIX;
817     }
818   else
819     i.Instr_Prefix = LONG_PREFIX;
820 }
821 
822 /* Separate mnemonics and the operands.  */
823 
824 static char *
parse_insn(char * line,char * mnemonic)825 parse_insn (char *line, char *mnemonic)
826 {
827   char *l = line;
828   char *token_start = l;
829   char *mnem_p;
830   char temp[MAX_MNEM_SIZE];
831   int ii = 0;
832 
833   memset (temp, END_OF_INSN, MAX_MNEM_SIZE);
834   mnem_p = mnemonic;
835 
836   while ((*mnem_p = mnemonic_chars[(unsigned char) *l]) != 0)
837     {
838       ii++;
839       mnem_p++;
840       if (mnem_p >= mnemonic + MAX_MNEM_SIZE)
841 	{
842 	  as_bad (_("no such instruction: `%s'"), token_start);
843 	  return NULL;
844 	}
845       l++;
846     }
847 
848   if (!is_space_char (*l) && *l != END_OF_INSN)
849     {
850       as_bad (_("invalid character %s in mnemonic"), l);
851       return NULL;
852     }
853 
854   while (ii)
855     {
856       temp[ii - 1] = toupper ((char) mnemonic[ii - 1]);
857       ii--;
858     }
859 
860   LS_processing (temp);
861 
862   if (i.Instr_Prefix != 0 && is_a_LSinstr (temp))
863     /* Skip the optional L-S.  */
864     memcpy (temp, temp + 1, MAX_MNEM_SIZE);
865 
866   /* Look up instruction (or prefix) via hash table.  */
867   current_templates = (MAXQ20_OPCODES *) hash_find (op_hash, temp);
868 
869   if (current_templates != NULL)
870     return l;
871 
872   as_bad (_("no such instruction: `%s'"), token_start);
873   return NULL;
874 }
875 
876 /* Function to calculate x to the power of y.
877    Just to avoid including the math libraries.  */
878 
879 static int
pwr(int x,int y)880 pwr (int x, int y)
881 {
882   int k, ans = 1;
883 
884   for (k = 0; k < y; k++)
885     ans *= x;
886 
887   return ans;
888 }
889 
890 static reg_entry *
parse_reg_by_index(char * imm_start)891 parse_reg_by_index (char *imm_start)
892 {
893   int k = 0, mid = 0, rid = 0, val = 0, j = 0;
894   char temp[4] = { 0 };
895   reg_entry *reg = NULL;
896 
897   do
898     {
899       if (isdigit (imm_start[k]))
900 	temp[k] = imm_start[k] - '0';
901 
902       else if (isalpha (imm_start[k])
903 	       && (imm_start[k] = tolower (imm_start[k])) < 'g')
904 	temp[k] = 10 + (int) (imm_start[k] - 'a');
905 
906       else if (imm_start[k] == 'h')
907 	break;
908 
909       else if (imm_start[k] == END_OF_INSN)
910 	{
911 	  imm_start[k] = 'd';
912 	  break;
913 	}
914 
915       else
916 	return NULL;		/* not a hex digit */
917 
918       k++;
919     }
920   while (imm_start[k] != '\n');
921 
922   switch (imm_start[k])
923     {
924     case 'h':
925       for (j = 0; j < k; j++)
926 	val += temp[j] * pwr (16, k - j - 1);
927       break;
928 
929     case 'd':
930       for (j = 0; j < k; j++)
931 	{
932 	  if (temp[j] > 9)
933 	    return NULL;	/* not a number */
934 
935 	  val += temp[j] * pwr (10, k - j - 1);
936 	  break;
937 	}
938     }
939 
940   /* Get the module and register id's.  */
941   mid = val & 0x0f;
942   rid = (val >> 4) & 0x0f;
943 
944   if (mid < 6)
945     {
946       /* Search the pheripheral reg table.  */
947       for (j = 0; j < num_of_reg; j++)
948 	{
949 	  if (new_reg_table[j].opcode == val)
950 	    {
951 	      reg = (reg_entry *) & new_reg_table[j];
952 	      break;
953 	    }
954 	}
955     }
956 
957   else
958     {
959       /* Search the system register table.  */
960       j = 0;
961 
962       while (system_reg_table[j].reg_name != NULL)
963 	{
964 	  if (system_reg_table[j].opcode == val)
965 	    {
966 	      reg = (reg_entry *) & system_reg_table[j];
967 	      break;
968 	    }
969 	  j++;
970 	}
971     }
972 
973   if (reg == NULL)
974     {
975       as_bad (_("Invalid register value %s"), imm_start);
976       return reg;
977     }
978 
979 #if CHANGE_PFX
980   if (this_operand == 0 && reg != NULL)
981     {
982       if (reg->Mod_index > 7)
983 	i.prefix = 2;
984       else
985 	i.prefix = 0;
986     }
987 #endif
988   return (reg_entry *) reg;
989 }
990 
991 /* REG_STRING starts *before* REGISTER_PREFIX.  */
992 
993 static reg_entry *
parse_register(char * reg_string,char ** end_op)994 parse_register (char *reg_string, char **end_op)
995 {
996   char *s = reg_string;
997   char *p = NULL;
998   char reg_name_given[MAX_REG_NAME_SIZE + 1];
999   reg_entry *r = NULL;
1000 
1001   r = NULL;
1002   p = NULL;
1003 
1004   /* Skip possible REGISTER_PREFIX and possible whitespace.  */
1005   if (is_space_char (*s))
1006     ++s;
1007 
1008   p = reg_name_given;
1009   while ((*p++ = register_chars[(unsigned char) *s]) != '\0')
1010     {
1011       if (p >= reg_name_given + MAX_REG_NAME_SIZE)
1012 	return (reg_entry *) NULL;
1013       s++;
1014     }
1015 
1016   *end_op = s;
1017 
1018   r = (reg_entry *) hash_find (reg_hash, reg_name_given);
1019 
1020 #if CHANGE_PFX
1021   if (this_operand == 0 && r != NULL)
1022     {
1023       if (r->Mod_index > 7)
1024 	i.prefix = 2;
1025       else
1026 	i.prefix = 0;
1027     }
1028 #endif
1029   return r;
1030 }
1031 
1032 static reg_bit *
parse_register_bit(char * reg_string,char ** end_op)1033 parse_register_bit (char *reg_string, char **end_op)
1034 {
1035   const char *s = reg_string;
1036   short k = 0;
1037   char diff = 0;
1038   reg_bit *rb = NULL;
1039   reg_entry *r = NULL;
1040   bit_name *b = NULL;
1041   char temp_bitname[MAX_REG_NAME_SIZE + 2];
1042   char temp[MAX_REG_NAME_SIZE + 1];
1043 
1044   memset (&temp, '\0', (MAX_REG_NAME_SIZE + 1));
1045   memset (&temp_bitname, '\0', (MAX_REG_NAME_SIZE + 2));
1046 
1047   diff = 0;
1048   r = NULL;
1049   rb = NULL;
1050   rb = xmalloc (sizeof (reg_bit));
1051   rb->reg = xmalloc (sizeof (reg_entry));
1052   k = 0;
1053 
1054   /* For supporting bit names.  */
1055   b = (bit_name *) hash_find (bit_hash, reg_string);
1056 
1057   if (b != NULL)
1058     {
1059       *end_op = reg_string + strlen (reg_string);
1060       strcpy (temp_bitname, b->reg_bit);
1061       s = temp_bitname;
1062     }
1063 
1064   if (strchr (s, '.'))
1065     {
1066       while (*s != '.')
1067 	{
1068 	  if (*s == '\0')
1069 	    return NULL;
1070 	  temp[k] = *s++;
1071 
1072 	  k++;
1073 	}
1074       temp[k] = '\0';
1075     }
1076 
1077   if ((r = parse_register (temp, end_op)) == NULL)
1078     return NULL;
1079 
1080   rb->reg = r;
1081 
1082   /* Skip the "."  */
1083   s++;
1084 
1085   if (isdigit ((char) *s))
1086     rb->bit = atoi (s);
1087   else if (isalpha ((char) *s))
1088     {
1089       rb->bit = (char) *s - 'a';
1090       rb->bit += 10;
1091       if (rb->bit > 15)
1092 	{
1093 	  as_bad (_("Invalid bit number : '%c'"), (char) *s);
1094 	  return NULL;
1095 	}
1096     }
1097 
1098   if (b != NULL)
1099     diff = strlen (temp_bitname) - strlen (temp) - 1;
1100   else
1101     diff = strlen (reg_string) - strlen (temp) - 1;
1102 
1103   if (*(s + diff) != '\0')
1104     {
1105       as_bad (_("Illegal character after operand '%s'"), reg_string);
1106       return NULL;
1107     }
1108 
1109   return rb;
1110 }
1111 
1112 static void
pfx_for_imm_val(int arg)1113 pfx_for_imm_val (int arg)
1114 {
1115   if (i.prefix == -1)
1116     return;
1117 
1118   if (i.prefix == 0 && arg == 0 && PFX_INSN[1] == 0 && !(i.data_operands))
1119     return;
1120 
1121   if (!(i.prefix < 0) && !(i.prefix > 7))
1122     PFX_INSN[0] = (i.prefix << 4) | PFX0;
1123 
1124   if (!PFX_INSN[1])
1125     PFX_INSN[1] = arg;
1126 
1127 }
1128 
1129 static int
maxq20_immediate(char * imm_start)1130 maxq20_immediate (char *imm_start)
1131 {
1132   int val = 0, val_pfx = 0;
1133   char sign_val = 0;
1134   int k = 0, j;
1135   int temp[4] = { 0 };
1136 
1137   imm_start++;
1138 
1139   if (imm_start[1] == '\0' && (imm_start[0] == '0' || imm_start[0] == '1')
1140       && (this_operand == 1 && ((i.types[0] == BIT || i.types[0] == FLAG))))
1141     {
1142       val = imm_start[0] - '0';
1143       i.imm_bit_operands++;
1144       i.types[this_operand] = IMMBIT;
1145       i.maxq20_op[this_operand].imms = (char) val;
1146 #if CHANGE_PFX
1147       if (i.prefix == 2)
1148 	pfx_for_imm_val (0);
1149 #endif
1150       return 1;
1151     }
1152 
1153   /* Check For Sign Charcater.  */
1154   sign_val = 0;
1155 
1156   do
1157     {
1158       if (imm_start[k] == '-' && k == 0)
1159 	sign_val = -1;
1160 
1161       else if (imm_start[k] == '+' && k == 0)
1162 	sign_val = 1;
1163 
1164       else if (isdigit (imm_start[k]))
1165 	temp[k] = imm_start[k] - '0';
1166 
1167       else if (isalpha (imm_start[k])
1168 	       && (imm_start[k] = tolower (imm_start[k])) < 'g')
1169 	temp[k] = 10 + (int) (imm_start[k] - 'a');
1170 
1171       else if (imm_start[k] == 'h')
1172 	break;
1173 
1174       else if (imm_start[k] == '\0')
1175 	{
1176 	  imm_start[k] = 'd';
1177 	  break;
1178 	}
1179       else
1180 	{
1181 	  as_bad (_("Invalid Character in immediate Value : %c"),
1182 		  imm_start[k]);
1183 	  return 0;
1184 	}
1185       k++;
1186     }
1187   while (imm_start[k] != '\n');
1188 
1189   switch (imm_start[k])
1190     {
1191     case 'h':
1192       for (j = (sign_val ? 1 : 0); j < k; j++)
1193 	val += temp[j] * pwr (16, k - j - 1);
1194       break;
1195 
1196     case 'd':
1197       for (j = (sign_val ? 1 : 0); j < k; j++)
1198 	{
1199 	  if (temp[j] > 9)
1200 	    {
1201 	      as_bad (_("Invalid Character in immediate value : %c"),
1202 		      imm_start[j]);
1203 	      return 0;
1204 	    }
1205 	  val += temp[j] * pwr (10, k - j - 1);
1206 	}
1207     }
1208 
1209   if (!sign_val)
1210     sign_val = 1;
1211 
1212   /* Now over here the value val stores the 8 bit/16 bit value. We will put a
1213      check if we are moving a 16 bit immediate value into an 8 bit register.
1214      In that case we will generate a warning and move only the lower 8 bits */
1215   if (val > 65535)
1216     {
1217       as_bad (_("Immediate value greater than 16 bits"));
1218       return 0;
1219     }
1220 
1221   val = val * sign_val;
1222 
1223   /* If it is a stack pointer and the value is greater than the maximum
1224      permissible size */
1225   if (this_operand == 1)
1226     {
1227       if ((val * sign_val) > MAX_STACK && i.types[0] == REG
1228 	  && !strcmp (i.maxq20_op[0].reg->reg_name, "SP"))
1229 	{
1230 	  as_warn (_
1231 		   ("Attempt to move a value in the stack pointer greater than the size of the stack"));
1232 	  val = val & MAX_STACK;
1233 	}
1234 
1235       /* Check the range for 8 bit registers.  */
1236       else if (((val * sign_val) > 0xFF) && (i.types[0] == REG)
1237 	       && (i.maxq20_op[0].reg->rtype == Reg_8W))
1238 	{
1239 	  as_warn (_
1240 		   ("Attempt to move 16 bit value into an 8 bit register.Truncating..\n"));
1241 	  val = val & 0xfe;
1242 	}
1243 
1244       else if (((sign_val == -1) || (val > 0xFF)) && (i.types[0] == REG)
1245 	       && (i.maxq20_op[0].reg->rtype == Reg_8W))
1246 	{
1247 	  val_pfx = val >> 8;
1248 	  val = ((val) & 0x00ff);
1249 	  SET_PFX_ARG (val_pfx);
1250 	  i.maxq20_op[this_operand].imms = (char) val;
1251 	}
1252 
1253       else if ((val <= 0xff) && (i.types[0] == REG)
1254 	       && (i.maxq20_op[0].reg->rtype == Reg_8W))
1255 	i.maxq20_op[this_operand].imms = (char) val;
1256 
1257 
1258       /* Check for 16 bit registers.  */
1259       else if (((sign_val == -1) || val > 0xFE) && i.types[0] == REG
1260 	       && i.maxq20_op[0].reg->rtype == Reg_16W)
1261 	{
1262 	  /* Add PFX for any negative value -> 16bit register.  */
1263 	  val_pfx = val >> 8;
1264 	  val = ((val) & 0x00ff);
1265 	  SET_PFX_ARG (val_pfx);
1266 	  i.maxq20_op[this_operand].imms = (char) val;
1267 	}
1268 
1269       else if (val < 0xFF && i.types[0] == REG
1270 	       && i.maxq20_op[0].reg->rtype == Reg_16W)
1271 	{
1272 	  i.maxq20_op[this_operand].imms = (char) val;
1273 	}
1274 
1275       /* All the immediate memory access - no PFX.  */
1276       else if (i.types[0] == MEM)
1277 	{
1278 	  if ((sign_val == -1) || val > 0xFE)
1279 	    {
1280 	      val_pfx = val >> 8;
1281 	      val = ((val) & 0x00ff);
1282 	      SET_PFX_ARG (val_pfx);
1283 	      i.maxq20_op[this_operand].imms = (char) val;
1284 	    }
1285 	  else
1286 	    i.maxq20_op[this_operand].imms = (char) val;
1287 	}
1288 
1289       /* Special handling for immediate jumps like jump nz, #03h etc.  */
1290       else if (val < 0xFF && i.types[0] == FLAG)
1291 	i.maxq20_op[this_operand].imms = (char) val;
1292 
1293       else if ((((sign_val == -1) || val > 0xFE)) && i.types[0] == FLAG)
1294 	{
1295 	  val_pfx = val >> 8;
1296 	  val = ((val) & 0x00ff);
1297 	  SET_PFX_ARG (val_pfx);
1298 	  i.maxq20_op[this_operand].imms = (char) val;
1299 	}
1300       else
1301 	{
1302 	  as_bad (_("Invalid immediate move operation"));
1303 	  return 0;
1304 	}
1305     }
1306   else
1307     {
1308       /* All the instruction with operation on ACC: like ADD src, etc.  */
1309       if ((sign_val == -1) || val > 0xFE)
1310 	{
1311 	  val_pfx = val >> 8;
1312 	  val = ((val) & 0x00ff);
1313 	  SET_PFX_ARG (val_pfx);
1314 	  i.maxq20_op[this_operand].imms = (char) val;
1315 	}
1316       else
1317 	i.maxq20_op[this_operand].imms = (char) val;
1318     }
1319 
1320   i.imm_operands++;
1321   return 1;
1322 }
1323 
1324 static int
extract_int_val(const char * imm_start)1325 extract_int_val (const char *imm_start)
1326 {
1327   int k, j, val;
1328   char sign_val;
1329   int temp[4];
1330 
1331   k = 0;
1332   j = 0;
1333   val = 0;
1334   sign_val = 0;
1335   do
1336     {
1337       if (imm_start[k] == '-' && k == 0)
1338 	sign_val = -1;
1339 
1340       else if (imm_start[k] == '+' && k == 0)
1341 	sign_val = 1;
1342 
1343       else if (isdigit (imm_start[k]))
1344 	temp[k] = imm_start[k] - '0';
1345 
1346       else if (isalpha (imm_start[k]) && (tolower (imm_start[k])) < 'g')
1347 	temp[k] = 10 + (int) (tolower (imm_start[k]) - 'a');
1348 
1349       else if (tolower (imm_start[k]) == 'h')
1350 	break;
1351 
1352       else if ((imm_start[k] == '\0') || (imm_start[k] == ']'))
1353 	/* imm_start[k]='d'; */
1354 	break;
1355 
1356       else
1357 	{
1358 	  as_bad (_("Invalid Character in immediate Value : %c"),
1359 		  imm_start[k]);
1360 	  return 0;
1361 	}
1362       k++;
1363     }
1364   while (imm_start[k] != '\n');
1365 
1366   switch (imm_start[k])
1367     {
1368     case 'h':
1369       for (j = (sign_val ? 1 : 0); j < k; j++)
1370 	val += temp[j] * pwr (16, k - j - 1);
1371       break;
1372 
1373     default:
1374       for (j = (sign_val ? 1 : 0); j < k; j++)
1375 	{
1376 	  if (temp[j] > 9)
1377 	    {
1378 	      as_bad (_("Invalid Character in immediate value : %c"),
1379 		      imm_start[j]);
1380 	      return 0;
1381 	    }
1382 	  val += temp[j] * pwr (10, k - j - 1);
1383 	}
1384     }
1385 
1386   if (!sign_val)
1387     sign_val = 1;
1388 
1389   return val * sign_val;
1390 }
1391 
1392 static char
check_for_parse(const char * line)1393 check_for_parse (const char *line)
1394 {
1395   int val;
1396 
1397   if (*(line + 1) == '[')
1398     {
1399       do
1400 	{
1401 	  line++;
1402 	  if ((*line == '-') || (*line == '+'))
1403 	    break;
1404 	}
1405       while (!is_space_char (*line));
1406 
1407       if ((*line == '-') || (*line == '+'))
1408 	val = extract_int_val (line);
1409       else
1410 	val = extract_int_val (line + 1);
1411 
1412       INSERT_BUFFER[0] = 0x3E;
1413       INSERT_BUFFER[1] = val;
1414 
1415       return 1;
1416     }
1417 
1418   return 0;
1419 }
1420 
1421 static mem_access *
maxq20_mem_access(char * mem_string,char ** end_op)1422 maxq20_mem_access (char *mem_string, char **end_op)
1423 {
1424   char *s = mem_string;
1425   char *p;
1426   char mem_name_given[MAX_MEM_NAME_SIZE + 1];
1427   mem_access *m;
1428 
1429   m = NULL;
1430 
1431   /* Skip possible whitespace.  */
1432   if (is_space_char (*s))
1433     ++s;
1434 
1435   p = mem_name_given;
1436   while ((*p++ = register_chars[(unsigned char) *s]) != '\0')
1437     {
1438       if (p >= mem_name_given + MAX_MEM_NAME_SIZE)
1439 	return (mem_access *) NULL;
1440       s++;
1441     }
1442 
1443   *end_op = s;
1444 
1445   m = (mem_access *) hash_find (mem_hash, mem_name_given);
1446 
1447   return m;
1448 }
1449 
1450 /* This function checks whether the operand is a variable in the data segment
1451    and if so, it returns its symbol entry from the symbol table.  */
1452 
1453 static symbolS *
maxq20_data(char * op_string)1454 maxq20_data (char *op_string)
1455 {
1456   symbolS *symbolP;
1457   symbolP = symbol_find (op_string);
1458 
1459   if (symbolP != NULL
1460       && S_GET_SEGMENT (symbolP) != now_seg
1461       && S_GET_SEGMENT (symbolP) != bfd_und_section_ptr)
1462     {
1463       /* In case we do not want to always include the prefix instruction and
1464          let the loader handle the job or in case of a 8 bit addressing mode,
1465          we will just check for val_pfx to be equal to zero and then load the
1466          prefix instruction. Otherwise no prefix instruction needs to be
1467          loaded.  */
1468       /* The prefix register will have to be loaded automatically as we have
1469 	 a 16 bit addressing field.  */
1470       pfx_for_imm_val (0);
1471       return symbolP;
1472     }
1473 
1474   return NULL;
1475 }
1476 
1477 static int
maxq20_displacement(char * disp_start,char * disp_end)1478 maxq20_displacement (char *disp_start, char *disp_end)
1479 {
1480   expressionS *exp;
1481   segT exp_seg = 0;
1482   char *save_input_line_pointer;
1483 #ifndef LEX_AT
1484   char *gotfree_input_line;
1485 #endif
1486 
1487   gotfree_input_line = NULL;
1488   exp = &disp_expressions;
1489   i.maxq20_op[this_operand].disps = exp;
1490   i.disp_operands++;
1491   save_input_line_pointer = input_line_pointer;
1492   input_line_pointer = disp_start;
1493 
1494   END_STRING_AND_SAVE (disp_end);
1495 
1496 #ifndef LEX_AT
1497   /* gotfree_input_line = lex_got (&i.reloc[this_operand], NULL); if
1498      (gotfree_input_line) input_line_pointer = gotfree_input_line; */
1499 #endif
1500   exp_seg = expression (exp);
1501 
1502   SKIP_WHITESPACE ();
1503   if (*input_line_pointer)
1504     as_bad (_("junk `%s' after expression"), input_line_pointer);
1505 #if GCC_ASM_O_HACK
1506   RESTORE_END_STRING (disp_end + 1);
1507 #endif
1508   RESTORE_END_STRING (disp_end);
1509   input_line_pointer = save_input_line_pointer;
1510 #ifndef LEX_AT
1511   if (gotfree_input_line)
1512     free (gotfree_input_line);
1513 #endif
1514   if (exp->X_op == O_absent || exp->X_op == O_big)
1515     {
1516       /* Missing or bad expr becomes absolute 0.  */
1517       as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
1518 	      disp_start);
1519       exp->X_op = O_constant;
1520       exp->X_add_number = 0;
1521       exp->X_add_symbol = (symbolS *) 0;
1522       exp->X_op_symbol = (symbolS *) 0;
1523     }
1524 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
1525 
1526   if (exp->X_op != O_constant
1527       && OUTPUT_FLAVOR == bfd_target_aout_flavour
1528       && exp_seg != absolute_section
1529       && exp_seg != text_section
1530       && exp_seg != data_section
1531       && exp_seg != bss_section && exp_seg != undefined_section
1532       && !bfd_is_com_section (exp_seg))
1533     {
1534       as_bad (_("unimplemented segment %s in operand"), exp_seg->name);
1535       return 0;
1536     }
1537 #endif
1538   i.maxq20_op[this_operand].disps = exp;
1539   return 1;
1540 }
1541 
1542 /* Parse OPERAND_STRING into the maxq20_insn structure I.
1543    Returns non-zero on error.  */
1544 
1545 static int
maxq20_operand(char * operand_string)1546 maxq20_operand (char *operand_string)
1547 {
1548   reg_entry *r = NULL;
1549   reg_bit *rb = NULL;
1550   mem_access *m = NULL;
1551   char *end_op = NULL;
1552   symbolS *sym = NULL;
1553   char *base_string = NULL;
1554   int ii = 0;
1555   /* Start and end of displacement string expression (if found).  */
1556   char *displacement_string_start = NULL;
1557   char *displacement_string_end = NULL;
1558   /* This maintains the  case sentivness.  */
1559   char case_str_op_string[MAX_OPERAND_SIZE + 1];
1560   char str_op_string[MAX_OPERAND_SIZE + 1];
1561   char *org_case_op_string = case_str_op_string;
1562   char *op_string = str_op_string;
1563 
1564 
1565   memset (op_string, END_OF_INSN, (MAX_OPERAND_SIZE + 1));
1566   memset (org_case_op_string, END_OF_INSN, (MAX_OPERAND_SIZE + 1));
1567 
1568   memcpy (op_string, operand_string, strlen (operand_string) + 1);
1569   memcpy (org_case_op_string, operand_string, strlen (operand_string) + 1);
1570 
1571   ii = strlen (operand_string) + 1;
1572 
1573   if (ii > MAX_OPERAND_SIZE)
1574     {
1575       as_bad (_("Size of Operand '%s' greater than %d"), op_string,
1576 	      MAX_OPERAND_SIZE);
1577       return 0;
1578     }
1579 
1580   while (ii)
1581     {
1582       op_string[ii - 1] = toupper ((char) op_string[ii - 1]);
1583       ii--;
1584     }
1585 
1586   if (is_space_char (*op_string))
1587     ++op_string;
1588 
1589   if (isxdigit (operand_string[0]))
1590     {
1591       /* Now the operands can start with an Integer.  */
1592       r = parse_reg_by_index (op_string);
1593       if (r != NULL)
1594 	{
1595 	  if (is_space_char (*op_string))
1596 	    ++op_string;
1597 	  i.types[this_operand] = REG;	/* Set the type.  */
1598 	  i.maxq20_op[this_operand].reg = r;	/* Set the Register value.  */
1599 	  i.reg_operands++;
1600 	  return 1;
1601 	}
1602 
1603       /* Get the origanal string.  */
1604       memcpy (op_string, operand_string, strlen (operand_string) + 1);
1605       ii = strlen (operand_string) + 1;
1606 
1607       while (ii)
1608 	{
1609 	  op_string[ii - 1] = toupper ((char) op_string[ii - 1]);
1610 	  ii--;
1611 	}
1612     }
1613 
1614   /* Check for flags.  */
1615   if (!strcmp (op_string, "Z"))
1616     {
1617       if (is_space_char (*op_string))
1618 	++op_string;
1619 
1620       i.types[this_operand] = FLAG;		/* Set the type.  */
1621       i.maxq20_op[this_operand].flag = FLAG_Z;	/* Set the Register value.  */
1622 
1623       i.flag_operands++;
1624 
1625       return 1;
1626     }
1627 
1628   else if (!strcmp (op_string, "NZ"))
1629     {
1630       if (is_space_char (*op_string))
1631 	++op_string;
1632 
1633       i.types[this_operand] = FLAG;		/* Set the type.  */
1634       i.maxq20_op[this_operand].flag = FLAG_NZ;	/* Set the Register value.  */
1635       i.flag_operands++;
1636       return 1;
1637     }
1638 
1639   else if (!strcmp (op_string, "NC"))
1640     {
1641       if (is_space_char (*op_string))
1642 	++op_string;
1643 
1644       i.types[this_operand] = FLAG;		/* Set the type.  */
1645       i.maxq20_op[this_operand].flag = FLAG_NC;	/* Set the Register value.  */
1646       i.flag_operands++;
1647       return 1;
1648     }
1649 
1650   else if (!strcmp (op_string, "E"))
1651     {
1652       if (is_space_char (*op_string))
1653 	++op_string;
1654 
1655       i.types[this_operand] = FLAG;		/* Set the type.  */
1656       i.maxq20_op[this_operand].flag = FLAG_E;	/* Set the Register value.  */
1657 
1658       i.flag_operands++;
1659 
1660       return 1;
1661     }
1662 
1663   else if (!strcmp (op_string, "S"))
1664     {
1665       if (is_space_char (*op_string))
1666 	++op_string;
1667 
1668       i.types[this_operand] = FLAG;	/* Set the type.  */
1669       i.maxq20_op[this_operand].flag = FLAG_S;	/* Set the Register value.  */
1670 
1671       i.flag_operands++;
1672 
1673       return 1;
1674     }
1675 
1676   else if (!strcmp (op_string, "C"))
1677     {
1678       if (is_space_char (*op_string))
1679 	++op_string;
1680 
1681       i.types[this_operand] = FLAG;	/* Set the type.  */
1682       i.maxq20_op[this_operand].flag = FLAG_C;	/* Set the Register value.  */
1683 
1684       i.flag_operands++;
1685 
1686       return 1;
1687     }
1688 
1689   else if (!strcmp (op_string, "NE"))
1690     {
1691 
1692       if (is_space_char (*op_string))
1693 	++op_string;
1694 
1695       i.types[this_operand] = FLAG;	/* Set the type.  */
1696 
1697       i.maxq20_op[this_operand].flag = FLAG_NE;	/* Set the Register value.  */
1698 
1699       i.flag_operands++;
1700 
1701       return 1;
1702     }
1703 
1704   /* CHECK FOR REGISTER BIT */
1705   else if ((rb = parse_register_bit (op_string, &end_op)) != NULL)
1706     {
1707       op_string = end_op;
1708 
1709       if (is_space_char (*op_string))
1710 	++op_string;
1711 
1712       i.types[this_operand] = BIT;
1713 
1714       i.maxq20_op[this_operand].r_bit = rb;
1715 
1716       i.bit_operands++;
1717 
1718       return 1;
1719     }
1720 
1721   else if (*op_string == IMMEDIATE_PREFIX)	/* FOR IMMEDITE.  */
1722     {
1723       if (is_space_char (*op_string))
1724 	++op_string;
1725 
1726       i.types[this_operand] = IMM;
1727 
1728       if (!maxq20_immediate (op_string))
1729 	{
1730 	  as_bad (_("illegal immediate operand '%s'"), op_string);
1731 	  return 0;
1732 	}
1733       return 1;
1734     }
1735 
1736   else if (*op_string == ABSOLUTE_PREFIX || !strcmp (op_string, "NUL"))
1737     {
1738      if (is_space_char (*op_string))
1739 	++op_string;
1740 
1741       /* For new requiremnt of copiler of for, @(BP,cons).  */
1742       if (check_for_parse (op_string))
1743 	{
1744 	  memset (op_string, '\0', strlen (op_string) + 1);
1745 	  memcpy (op_string, "@BP[OFFS]\0", 11);
1746 	}
1747 
1748       i.types[this_operand] = MEM;
1749 
1750       if ((m = maxq20_mem_access (op_string, &end_op)) == NULL)
1751 	{
1752 	  as_bad (_("Invalid operand for memory access '%s'"), op_string);
1753 	  return 0;
1754 	}
1755       i.maxq20_op[this_operand].mem = m;
1756 
1757       i.mem_operands++;
1758 
1759       return 1;
1760     }
1761 
1762   else if ((r = parse_register (op_string, &end_op)) != NULL)	/* Check for register.  */
1763     {
1764       op_string = end_op;
1765 
1766       if (is_space_char (*op_string))
1767 	++op_string;
1768 
1769       i.types[this_operand] = REG;	/* Set the type.  */
1770       i.maxq20_op[this_operand].reg = r;	/* Set the Register value.  */
1771       i.reg_operands++;
1772       return 1;
1773     }
1774 
1775   if (this_operand == 1)
1776     {
1777       /* Changed for orginal case of data refrence on 30 Nov 2003.  */
1778       /* The operand can either be a data reference or a symbol reference.  */
1779       if ((sym = maxq20_data (org_case_op_string)) != NULL)	/* Check for data memory.  */
1780 	{
1781 	  while (is_space_char (*op_string))
1782 	    ++op_string;
1783 
1784 	  /* Set the type of the operand.  */
1785 	  i.types[this_operand] = DATA;
1786 
1787 	  /* Set the value of the data.  */
1788 	  i.maxq20_op[this_operand].data = sym;
1789 	  i.data_operands++;
1790 
1791 	  return 1;
1792 	}
1793 
1794       else if (is_digit_char (*op_string) || is_identifier_char (*op_string))
1795 	{
1796 	  /* This is a memory reference of some sort. char *base_string;
1797 	     Start and end of displacement string expression (if found). char
1798 	     *displacement_string_start; char *displacement_string_end.  */
1799 	  base_string = org_case_op_string + strlen (org_case_op_string);
1800 
1801 	  --base_string;
1802 	  if (is_space_char (*base_string))
1803 	    --base_string;
1804 
1805 	  /* If we only have a displacement, set-up for it to be parsed
1806 	     later.  */
1807 	  displacement_string_start = org_case_op_string;
1808 	  displacement_string_end = base_string + 1;
1809 	  if (displacement_string_start != displacement_string_end)
1810 	    {
1811 	      if (!maxq20_displacement (displacement_string_start,
1812 					displacement_string_end))
1813 		{
1814 		  as_bad (_("illegal displacement operand "));
1815 		  return 0;
1816 		}
1817 	      /* A displacement operand found.  */
1818 	      i.types[this_operand] = DISP;	/* Set the type.  */
1819 	      return 1;
1820 	    }
1821 	}
1822     }
1823 
1824   /* Check for displacement.  */
1825   else if (is_digit_char (*op_string) || is_identifier_char (*op_string))
1826     {
1827       /* This is a memory reference of some sort. char *base_string;
1828          Start and end of displacement string expression (if found). char
1829          *displacement_string_start; char *displacement_string_end;  */
1830       base_string = org_case_op_string + strlen (org_case_op_string);
1831 
1832       --base_string;
1833       if (is_space_char (*base_string))
1834 	--base_string;
1835 
1836       /* If we only have a displacement, set-up for it to be parsed later.  */
1837       displacement_string_start = org_case_op_string;
1838       displacement_string_end = base_string + 1;
1839       if (displacement_string_start != displacement_string_end)
1840 	{
1841 	  if (!maxq20_displacement (displacement_string_start,
1842 				    displacement_string_end))
1843 	    return 0;
1844 	  /* A displacement operand found.  */
1845 	  i.types[this_operand] = DISP;	/* Set the type.  */
1846 	}
1847     }
1848   return 1;
1849 }
1850 
1851 /* Parse_operand takes as input instruction and operands and Parse operands
1852    and makes entry in the template.  */
1853 
1854 static char *
parse_operands(char * l,const char * mnemonic)1855 parse_operands (char *l, const char *mnemonic)
1856 {
1857   char *token_start;
1858 
1859   /* 1 if operand is pending after ','.  */
1860   short int expecting_operand = 0;
1861 
1862   /* Non-zero if operand parens not balanced.  */
1863   short int paren_not_balanced;
1864 
1865   int operand_ok;
1866 
1867   /* For Overcoming Warning of unused variable.  */
1868   if (mnemonic)
1869     operand_ok = 0;
1870 
1871   while (*l != END_OF_INSN)
1872     {
1873       /* Skip optional white space before operand.  */
1874       if (is_space_char (*l))
1875 	++l;
1876 
1877       if (!is_operand_char (*l) && *l != END_OF_INSN)
1878 	{
1879 	  as_bad (_("invalid character %c before operand %d"),
1880 		  (char) (*l), i.operands + 1);
1881 	  return NULL;
1882 	}
1883       token_start = l;
1884 
1885       paren_not_balanced = 0;
1886       while (paren_not_balanced || *l != ',')
1887 	{
1888 	  if (*l == END_OF_INSN)
1889 	    {
1890 	      if (paren_not_balanced)
1891 		{
1892 		  as_bad (_("unbalanced brackets in operand %d."),
1893 			  i.operands + 1);
1894 		  return NULL;
1895 		}
1896 
1897 	      break;
1898 	    }
1899 	  else if (!is_operand_char (*l) && !is_space_char (*l))
1900 	    {
1901 	      as_bad (_("invalid character %c in operand %d"),
1902 		      (char) (*l), i.operands + 1);
1903 	      return NULL;
1904 	    }
1905 	  if (*l == '[')
1906 	    ++paren_not_balanced;
1907 	  if (*l == ']')
1908 	    --paren_not_balanced;
1909 	  l++;
1910 	}
1911 
1912       if (l != token_start)
1913 	{
1914 	  /* Yes, we've read in another operand.  */
1915 	  this_operand = i.operands++;
1916 	  if (i.operands > MAX_OPERANDS)
1917 	    {
1918 	      as_bad (_("spurious operands; (%d operands/instruction max)"),
1919 		      MAX_OPERANDS);
1920 	      return NULL;
1921 	    }
1922 
1923 	  /* Now parse operand adding info to 'i' as we go along.  */
1924 	  END_STRING_AND_SAVE (l);
1925 
1926 	  operand_ok = maxq20_operand (token_start);
1927 
1928 	  RESTORE_END_STRING (l);
1929 
1930 	  if (!operand_ok)
1931 	    return NULL;
1932 	}
1933       else
1934 	{
1935 	  if (expecting_operand)
1936 	    {
1937 	    expecting_operand_after_comma:
1938 	      as_bad (_("expecting operand after ','; got nothing"));
1939 	      return NULL;
1940 	    }
1941 	}
1942 
1943       if (*l == ',')
1944 	{
1945 	  if (*(++l) == END_OF_INSN)
1946 	    /* Just skip it, if it's \n complain.  */
1947 	    goto expecting_operand_after_comma;
1948 
1949 	  expecting_operand = 1;
1950 	}
1951     }
1952 
1953   return l;
1954 }
1955 
1956 static int
match_operands(int type,MAX_ARG_TYPE flag_type,MAX_ARG_TYPE arg_type,int op_num)1957 match_operands (int type, MAX_ARG_TYPE flag_type, MAX_ARG_TYPE arg_type,
1958 		int op_num)
1959 {
1960   switch (type)
1961     {
1962     case REG:
1963       if ((arg_type & A_REG) == A_REG)
1964 	return 1;
1965       break;
1966     case IMM:
1967       if ((arg_type & A_IMM) == A_IMM)
1968 	return 1;
1969       break;
1970     case IMMBIT:
1971       if ((arg_type & A_BIT_0) == A_BIT_0 && (i.maxq20_op[op_num].imms == 0))
1972 	return 1;
1973       else if ((arg_type & A_BIT_1) == A_BIT_1
1974 	       && (i.maxq20_op[op_num].imms == 1))
1975 	return 1;
1976       break;
1977     case MEM:
1978       if ((arg_type & A_MEM) == A_MEM)
1979 	return 1;
1980       break;
1981 
1982     case FLAG:
1983       if ((arg_type & flag_type) == flag_type)
1984 	return 1;
1985 
1986       break;
1987 
1988     case BIT:
1989       if ((arg_type & ACC_BIT) == ACC_BIT && !strcmp (i.maxq20_op[op_num].r_bit->reg->reg_name, "ACC"))
1990 	return 1;
1991       else if ((arg_type & SRC_BIT) == SRC_BIT && (op_num == 1))
1992 	return 1;
1993       else if ((op_num == 0) && (arg_type & DST_BIT) == DST_BIT)
1994 	return 1;
1995       break;
1996     case DISP:
1997       if ((arg_type & A_DISP) == A_DISP)
1998 	return 1;
1999     case DATA:
2000       if ((arg_type & A_DATA) == A_DATA)
2001 	return 1;
2002     case BIT_BUCKET:
2003       if ((arg_type & A_BIT_BUCKET) == A_BIT_BUCKET)
2004 	return 1;
2005     }
2006   return 0;
2007 }
2008 
2009 static int
match_template(void)2010 match_template (void)
2011 {
2012   /* Points to template once we've found it.  */
2013   const MAXQ20_OPCODE_INFO *t;
2014   char inv_oper;
2015   inv_oper = 0;
2016 
2017   for (t = current_templates->start; t < current_templates->end; t++)
2018     {
2019       /* Must have right number of operands.  */
2020       if (i.operands != t->op_number)
2021 	continue;
2022       else if (!t->op_number)
2023 	break;
2024 
2025       switch (i.operands)
2026 	{
2027 	case 2:
2028 	  if (!match_operands (i.types[1], i.maxq20_op[1].flag, t->arg[1], 1))
2029 	    {
2030 	      inv_oper = 1;
2031 	      continue;
2032 	    }
2033 	case 1:
2034 	  if (!match_operands (i.types[0], i.maxq20_op[0].flag, t->arg[0], 0))
2035 	    {
2036 	      inv_oper = 2;
2037 	      continue;
2038 	    }
2039 	}
2040       break;
2041     }
2042 
2043   if (t == current_templates->end)
2044     {
2045       /* We found no match.  */
2046       as_bad (_("operand %d is invalid for `%s'"),
2047 	      inv_oper, current_templates->start->name);
2048       return 0;
2049     }
2050 
2051   /* Copy the template we have found.  */
2052   i.op = *t;
2053   return 1;
2054 }
2055 
2056 /* This function filters out the various combinations of operands which are
2057    not allowed for a particular instruction.  */
2058 
2059 static int
match_filters(void)2060 match_filters (void)
2061 {
2062   /* Now we have at our disposal the instruction i. We will be using the
2063      following fields i.op.name : This is the mnemonic name. i.types[2] :
2064      These are the types of the operands (REG/IMM/DISP/MEM/BIT/FLAG/IMMBIT)
2065      i.maxq20_op[2] : This contains the specific info of the operands.  */
2066 
2067   /* Our first filter : NO ALU OPERATIONS CAN HAVE THE ACTIVE ACCUMULATOR AS
2068      SOURCE.  */
2069   if (!strcmp (i.op.name, "AND") || !strcmp (i.op.name, "OR")
2070       || !strcmp (i.op.name, "XOR") || !strcmp (i.op.name, "ADD")
2071       || !strcmp (i.op.name, "ADDC") || !strcmp (i.op.name, "SUB")
2072       || !strcmp (i.op.name, "SUBB"))
2073     {
2074       if (i.types[0] == REG)
2075 	{
2076 	  if (i.maxq20_op[0].reg->Mod_name == 0xa)
2077 	    {
2078 	      as_bad (_
2079 		      ("The Accumulator cannot be used as a source in ALU instructions\n"));
2080 	      return 0;
2081 	    }
2082 	}
2083     }
2084 
2085   if (!strcmp (i.op.name, "MOVE") && (i.types[0] == MEM || i.types[1] == MEM)
2086       && i.operands == 2)
2087     {
2088       mem_access_syntax *mem_op = NULL;
2089 
2090       if (i.types[0] == MEM)
2091 	{
2092 	  mem_op =
2093 	    (mem_access_syntax *) hash_find (mem_syntax_hash,
2094 					     i.maxq20_op[0].mem->name);
2095 	  if ((mem_op->type == SRC) && mem_op)
2096 	    {
2097 	      as_bad (_("'%s' operand cant be used as destination in %s"),
2098 		      mem_op->name, i.op.name);
2099 	      return 0;
2100 	    }
2101 	  else if ((mem_op->invalid_op != NULL) && (i.types[1] == MEM)
2102 		   && mem_op)
2103 	    {
2104 	      int k = 0;
2105 
2106 	      for (k = 0; k < 5 || !mem_op->invalid_op[k]; k++)
2107 		{
2108 		  if (mem_op->invalid_op[k] != NULL)
2109 		    if (!strcmp
2110 			(mem_op->invalid_op[k], i.maxq20_op[1].mem->name))
2111 		      {
2112 			as_bad (_
2113 				("Invalid Instruction '%s' operand cant be used with %s"),
2114 				mem_op->name, i.maxq20_op[1].mem->name);
2115 			return 0;
2116 		      }
2117 		}
2118 	    }
2119 	}
2120 
2121       if (i.types[1] == MEM)
2122 	{
2123 	  mem_op = NULL;
2124 	  mem_op =
2125 	    (mem_access_syntax *) hash_find (mem_syntax_hash,
2126 					     i.maxq20_op[1].mem->name);
2127 	  if (mem_op->type == DST && mem_op)
2128 	    {
2129 	      as_bad (_("'%s' operand cant be used as source in %s"),
2130 		      mem_op->name, i.op.name);
2131 	      return 0;
2132 	    }
2133 	  else if (mem_op->invalid_op != NULL && i.types[0] == MEM && mem_op)
2134 	    {
2135 	      int k = 0;
2136 
2137 	      for (k = 0; k < 5 || !mem_op->invalid_op[k]; k++)
2138 		{
2139 		  if (mem_op->invalid_op[k] != NULL)
2140 		    if (!strcmp
2141 			(mem_op->invalid_op[k], i.maxq20_op[0].mem->name))
2142 		      {
2143 			as_bad (_
2144 				("Invalid Instruction '%s' operand cant be used with %s"),
2145 				mem_op->name, i.maxq20_op[0].mem->name);
2146 			return 0;
2147 		      }
2148 		}
2149 	    }
2150 	  else if (i.types[0] == REG
2151 		   && !strcmp (i.maxq20_op[0].reg->reg_name, "OFFS")
2152 		   && mem_op)
2153 	    {
2154 	      if (!strcmp (mem_op->name, "@BP[OFFS--]")
2155 		  || !strcmp (mem_op->name, "@BP[OFFS++]"))
2156 		{
2157 		  as_bad (_
2158 			  ("Invalid Instruction '%s' operand cant be used with %s"),
2159 			  mem_op->name, i.maxq20_op[0].mem->name);
2160 		  return 0;
2161 		}
2162 	    }
2163 	}
2164     }
2165 
2166   /* Added for SRC and DST in one operand instructioni i.e OR @--DP[1] added
2167      on 10-March-2004.  */
2168   if ((i.types[0] == MEM) && (i.operands == 1)
2169       && !(!strcmp (i.op.name, "POP") || !strcmp (i.op.name, "POPI")))
2170     {
2171       mem_access_syntax *mem_op = NULL;
2172 
2173       if (i.types[0] == MEM)
2174 	{
2175 	  mem_op =
2176 	    (mem_access_syntax *) hash_find (mem_syntax_hash,
2177 					     i.maxq20_op[0].mem->name);
2178 	  if (mem_op->type == DST && mem_op)
2179 	    {
2180 	      as_bad (_("'%s' operand cant be used as source in %s"),
2181 		      mem_op->name, i.op.name);
2182 	      return 0;
2183 	    }
2184 	}
2185     }
2186 
2187   if (i.operands == 2 && i.types[0] == IMM)
2188     {
2189       as_bad (_("'%s' instruction cant have first operand as Immediate vale"),
2190 	      i.op.name);
2191       return 0;
2192     }
2193 
2194   /* Our second filter : SP or @SP-- cannot be used with PUSH or POP */
2195   if (!strcmp (i.op.name, "PUSH") || !strcmp (i.op.name, "POP")
2196       || !strcmp (i.op.name, "POPI"))
2197     {
2198       if (i.types[0] == REG)
2199 	{
2200 	  if (!strcmp (i.maxq20_op[0].reg->reg_name, "SP"))
2201 	    {
2202 	      as_bad (_("SP cannot be used with %s\n"), i.op.name);
2203 	      return 0;
2204 	    }
2205 	}
2206       else if (i.types[0] == MEM
2207 	       && !strcmp (i.maxq20_op[0].mem->name, "@SP--"))
2208 	{
2209 	  as_bad (_("@SP-- cannot be used with PUSH\n"));
2210 	  return 0;
2211 	}
2212     }
2213 
2214   /* This filter checks that two memory references using DP's cannot be used
2215      together in an instruction */
2216   if (!strcmp (i.op.name, "MOVE") && i.mem_operands == 2)
2217     {
2218       if (strlen (i.maxq20_op[0].mem->name) != 6 ||
2219 	  strcmp (i.maxq20_op[0].mem->name, i.maxq20_op[1].mem->name))
2220 	{
2221 	  if (!strncmp (i.maxq20_op[0].mem->name, "@DP", 3)
2222 	      && !strncmp (i.maxq20_op[1].mem->name, "@DP", 3))
2223 	    {
2224 	      as_bad (_
2225 		      ("Operands either contradictory or use the data bus in read/write state together"));
2226 	      return 0;
2227 	    }
2228 
2229 	  if (!strncmp (i.maxq20_op[0].mem->name, "@SP", 3)
2230 	      && !strncmp (i.maxq20_op[1].mem->name, "@SP", 3))
2231 	    {
2232 	      as_bad (_
2233 		      ("Operands either contradictory or use the data bus in read/write state together"));
2234 	      return 0;
2235 	    }
2236 	}
2237       if ((i.maxq20_op[1].mem != NULL)
2238 	  && !strncmp (i.maxq20_op[1].mem->name, "NUL", 3))
2239 	{
2240 	  as_bad (_("MOVE Cant Use NUL as SRC"));
2241 	  return 0;
2242 	}
2243     }
2244 
2245   /* This filter checks that contradictory movement between DP register and
2246      Memory access using DP followed by increment or decrement.  */
2247 
2248   if (!strcmp (i.op.name, "MOVE") && i.mem_operands == 1
2249       && i.reg_operands == 1)
2250     {
2251       int memnum, regnum;
2252 
2253       memnum = (i.types[0] == MEM) ? 0 : 1;
2254       regnum = (memnum == 0) ? 1 : 0;
2255       if (!strncmp (i.maxq20_op[regnum].reg->reg_name, "DP", 2) &&
2256 	  !strncmp ((i.maxq20_op[memnum].mem->name) + 1,
2257 		    i.maxq20_op[regnum].reg->reg_name, 5)
2258 	  && strcmp ((i.maxq20_op[memnum].mem->name) + 1,
2259 		     i.maxq20_op[regnum].reg->reg_name))
2260 	{
2261 	  as_bad (_
2262 		  ("Contradictory movement between DP register and memory access using DP"));
2263 	  return 0;
2264 	}
2265       else if (!strcmp (i.maxq20_op[regnum].reg->reg_name, "SP") &&
2266 	       !strncmp ((i.maxq20_op[memnum].mem->name) + 1,
2267 			 i.maxq20_op[regnum].reg->reg_name, 2))
2268 	{
2269 	  as_bad (_
2270 		  ("SP and @SP-- cannot be used together in a move instruction"));
2271 	  return 0;
2272 	}
2273     }
2274 
2275   /* This filter restricts the instructions containing source and destination
2276      bits to only CTRL module of the serial registers. Peripheral registers
2277      yet to be defined.  */
2278 
2279   if (i.bit_operands == 1 && i.operands == 2)
2280     {
2281       int bitnum = (i.types[0] == BIT) ? 0 : 1;
2282 
2283       if (strcmp (i.maxq20_op[bitnum].r_bit->reg->reg_name, "ACC"))
2284 	{
2285 	  if (i.maxq20_op[bitnum].r_bit->reg->Mod_name >= 0x7 &&
2286 	      i.maxq20_op[bitnum].r_bit->reg->Mod_name != CTRL)
2287 	    {
2288 	      as_bad (_
2289 		      ("Only Module 8 system registers allowed in this operation"));
2290 	      return 0;
2291 	    }
2292 	}
2293     }
2294 
2295   /* This filter is for checking the register bits.  */
2296   if (i.bit_operands == 1 || i.operands == 2)
2297     {
2298       int bitnum = 0, size = 0;
2299 
2300       bitnum = (i.types[0] == BIT) ? 0 : 1;
2301       if (i.bit_operands == 1)
2302 	{
2303 	  switch (i.maxq20_op[bitnum].r_bit->reg->rtype)
2304 	    {
2305 	    case Reg_8W:
2306 	      size = 7;		/* 8 bit register, both read and write.  */
2307 	      break;
2308 	    case Reg_16W:
2309 	      size = 15;
2310 	      break;
2311 	    case Reg_8R:
2312 	      size = 7;
2313 	      if (bitnum == 0)
2314 		{
2315 		  as_fatal (_("Read only Register used as destination"));
2316 		  return 0;
2317 		}
2318 	      break;
2319 
2320 	    case Reg_16R:
2321 	      size = 15;
2322 	      if (bitnum == 0)
2323 		{
2324 		  as_fatal (_("Read only Register used as destination"));
2325 		  return 0;
2326 		}
2327 	      break;
2328 	    }
2329 
2330 	  if (size < (i.maxq20_op[bitnum].r_bit)->bit)
2331 	    {
2332 	      as_bad (_("Bit No '%d'exceeds register size in this operation"),
2333 		      (i.maxq20_op[bitnum].r_bit)->bit);
2334 	      return 0;
2335 	    }
2336 	}
2337 
2338       if (i.bit_operands == 2)
2339 	{
2340 	  switch ((i.maxq20_op[0].r_bit)->reg->rtype)
2341 	    {
2342 	    case Reg_8W:
2343 	      size = 7;		/* 8 bit register, both read and write.  */
2344 	      break;
2345 	    case Reg_16W:
2346 	      size = 15;
2347 	      break;
2348 	    case Reg_8R:
2349 	    case Reg_16R:
2350 	      as_fatal (_("Read only Register used as destination"));
2351 	      return 0;
2352 	    }
2353 
2354 	  if (size < (i.maxq20_op[0].r_bit)->bit)
2355 	    {
2356 	      as_bad (_
2357 		      ("Bit No '%d' exceeds register size in this operation"),
2358 		      (i.maxq20_op[0].r_bit)->bit);
2359 	      return 0;
2360 	    }
2361 
2362 	  size = 0;
2363 	  switch ((i.maxq20_op[1].r_bit)->reg->rtype)
2364 	    {
2365 	    case Reg_8R:
2366 	    case Reg_8W:
2367 	      size = 7;		/* 8 bit register, both read and write.  */
2368 	      break;
2369 	    case Reg_16R:
2370 	    case Reg_16W:
2371 	      size = 15;
2372 	      break;
2373 	    }
2374 
2375 	  if (size < (i.maxq20_op[1].r_bit)->bit)
2376 	    {
2377 	      as_bad (_
2378 		      ("Bit No '%d' exceeds register size in this operation"),
2379 		      (i.maxq20_op[1].r_bit)->bit);
2380 	      return 0;
2381 	    }
2382 	}
2383     }
2384 
2385   /* No branch operations should occur into the data memory. Hence any memory
2386      references have to be filtered out when used with instructions like
2387      jump, djnz[] and call.  */
2388 
2389   if (!strcmp (i.op.name, "JUMP") || !strcmp (i.op.name, "CALL")
2390       || !strncmp (i.op.name, "DJNZ", 4))
2391     {
2392       if (i.mem_operands)
2393 	as_warn (_
2394 		 ("Memory References cannot be used with branching operations\n"));
2395     }
2396 
2397   if (!strcmp (i.op.name, "DJNZ"))
2398     {
2399       if (!
2400 	  (strcmp (i.maxq20_op[0].reg->reg_name, "LC[0]")
2401 	   || strcmp (i.maxq20_op[0].reg->reg_name, "LC[1]")))
2402 	{
2403 	  as_bad (_("DJNZ uses only LC[n] register \n"));
2404 	  return 0;
2405 	}
2406     }
2407 
2408   /* No destination register used should be read only!  */
2409   if ((i.operands == 2 && i.types[0] == REG) || !strcmp (i.op.name, "POP")
2410       || !strcmp (i.op.name, "POPI"))
2411     {				/* The destination is a register */
2412       int regnum = 0;
2413 
2414       if (!strcmp (i.op.name, "POP") || !strcmp (i.op.name, "POPI"))
2415 	{
2416 	  regnum = 0;
2417 
2418 	  if (i.types[regnum] == MEM)
2419 	    {
2420 	      mem_access_syntax *mem_op = NULL;
2421 
2422 	      mem_op =
2423 		(mem_access_syntax *) hash_find (mem_syntax_hash,
2424 						 i.maxq20_op[regnum].mem->
2425 						 name);
2426 	      if (mem_op->type == SRC && mem_op)
2427 		{
2428 		  as_bad (_
2429 			  ("'%s' operand cant be used as destination  in %s"),
2430 			  mem_op->name, i.op.name);
2431 		  return 0;
2432 		}
2433 	    }
2434 	}
2435 
2436       if (i.maxq20_op[regnum].reg->rtype == Reg_8R
2437 	  || i.maxq20_op[regnum].reg->rtype == Reg_16R)
2438 	{
2439 	  as_bad (_("Read only register used for writing purposes '%s'"),
2440 		  i.maxq20_op[regnum].reg->reg_name);
2441 	  return 0;
2442 	}
2443     }
2444 
2445   /* While moving the address of a data in the data section, the destination
2446      should be either data pointers only.  */
2447   if ((i.data_operands) && (i.operands == 2))
2448     {
2449       if ((i.types[0] != REG) && (i.types[0] != MEM))
2450 	{
2451 	  as_bad (_("Invalid destination for this kind of source."));
2452 	  return 0;
2453 	}
2454 
2455 	if (i.types[0] == REG && i.maxq20_op[0].reg->rtype == Reg_8W)
2456 	  {
2457 	    as_bad (_
2458 		    ("Invalid register as destination for this kind of source.Only data pointers can be used."));
2459 	    return 0;
2460 	  }
2461     }
2462   return 1;
2463 }
2464 
2465 static int
decode_insn(void)2466 decode_insn (void)
2467 {
2468   /* Check for the format Bit if defined.  */
2469   if (i.op.format == 0 || i.op.format == 1)
2470     i.instr[0] = i.op.format << 7;
2471   else
2472     {
2473       /* Format bit not defined. We will have to be find it out ourselves.  */
2474       if (i.imm_operands == 1 || i.data_operands == 1 || i.disp_operands == 1)
2475 	i.op.format = 0;
2476       else
2477 	i.op.format = 1;
2478       i.instr[0] = i.op.format << 7;
2479     }
2480 
2481   /* Now for the destination register.  */
2482 
2483   /* If destination register is already defined . The conditions are the
2484      following: (1) The second entry in the destination array should be 0 (2)
2485      If there are two operands then the first entry should not be a register,
2486      memory or a register bit (3) If there are less than two operands and the
2487      it is not a pop operation (4) The second argument is the carry
2488      flag(applicable to move Acc.<b>,C.  */
2489   if (i.op.dst[1] == 0
2490       &&
2491       ((i.types[0] != REG && i.types[0] != MEM && i.types[0] != BIT
2492 	&& i.operands == 2) || (i.operands < 2 && strcmp (i.op.name, "POP")
2493 				&& strcmp (i.op.name, "POPI"))
2494        || (i.op.arg[1] == FLAG_C)))
2495     {
2496       i.op.dst[0] &= 0x7f;
2497       i.instr[0] |= i.op.dst[0];
2498     }
2499   else if (i.op.dst[1] == 0 && !strcmp (i.op.name, "DJNZ")
2500 	   &&
2501 	   (((i.types[0] == REG)
2502 	     && (!strcmp (i.maxq20_op[0].reg->reg_name, "LC[0]")
2503 		 || !strcmp (i.maxq20_op[0].reg->reg_name, "LC[1]")))))
2504     {
2505       i.op.dst[0] &= 0x7f;
2506       if (!strcmp (i.maxq20_op[0].reg->reg_name, "LC[0]"))
2507 	i.instr[0] |= 0x4D;
2508 
2509       if (!strcmp (i.maxq20_op[0].reg->reg_name, "LC[1]"))
2510 	i.instr[0] |= 0x5D;
2511     }
2512   else
2513     {
2514       unsigned char temp;
2515 
2516       /* Target register will have to be specified.  */
2517       if (i.types[0] == REG
2518 	  && (i.op.dst[0] == REG || i.op.dst[0] == (REG | MEM)))
2519 	{
2520 	  temp = (i.maxq20_op[0].reg)->opcode;
2521 	  temp &= 0x7f;
2522 	  i.instr[0] |= temp;
2523 	}
2524       else if (i.types[0] == MEM && (i.op.dst[0] == (REG | MEM)))
2525 	{
2526 	  temp = (i.maxq20_op[0].mem)->opcode;
2527 	  temp &= 0x7f;
2528 	  i.instr[0] |= temp;
2529 	}
2530       else if (i.types[0] == BIT && (i.op.dst[0] == REG))
2531 	{
2532 	  temp = (i.maxq20_op[0].r_bit)->reg->opcode;
2533 	  temp &= 0x7f;
2534 	  i.instr[0] |= temp;
2535 	}
2536       else if (i.types[1] == BIT && (i.op.dst[0] == BIT))
2537 	{
2538 	  temp = (i.maxq20_op[1].r_bit)->bit;
2539 	  temp = temp << 4;
2540 	  temp |= i.op.dst[1];
2541 	  temp &= 0x7f;
2542 	  i.instr[0] |= temp;
2543 	}
2544       else
2545 	{
2546 	  as_bad (_("Invalid Instruction"));
2547 	  return 0;
2548 	}
2549     }
2550 
2551   /* Now for the source register.  */
2552 
2553   /* If Source register is already known. The following conditions are
2554      checked: (1) There are no operands (2) If there is only one operand and
2555      it is a flag (3) If the operation is MOVE C,#0/#1 (4) If it is a POP
2556      operation.  */
2557 
2558   if (i.operands == 0 || (i.operands == 1 && i.types[0] == FLAG)
2559       || (i.types[0] == FLAG && i.types[1] == IMMBIT)
2560       || !strcmp (i.op.name, "POP") || !strcmp (i.op.name, "POPI"))
2561     i.instr[1] = i.op.src[0];
2562 
2563   else if (i.imm_operands == 1 && ((i.op.src[0] & IMM) == IMM))
2564     i.instr[1] = i.maxq20_op[this_operand].imms;
2565 
2566   else if (i.types[this_operand] == REG && ((i.op.src[0] & REG) == REG))
2567     i.instr[1] = (char) ((i.maxq20_op[this_operand].reg)->opcode);
2568 
2569   else if (i.types[this_operand] == BIT && ((i.op.src[0] & REG) == REG))
2570     i.instr[1] = (char) (i.maxq20_op[this_operand].r_bit->reg->opcode);
2571 
2572   else if (i.types[this_operand] == MEM && ((i.op.src[0] & MEM) == MEM))
2573     i.instr[1] = (char) ((i.maxq20_op[this_operand].mem)->opcode);
2574 
2575   else if (i.types[this_operand] == DATA && ((i.op.src[0] & DATA) == DATA))
2576     /* This will copy only the lower order bytes into the instruction. The
2577        higher order bytes have already been copied into the prefix register.  */
2578     i.instr[1] = 0;
2579 
2580   /* Decoding the source in the case when the second array entry is not 0.
2581      This means that the source register has been divided into two nibbles.  */
2582 
2583   else if (i.op.src[1] != 0)
2584     {
2585       /* If the first operand is a accumulator bit then
2586 	 the first 4 bits will be filled with the bit number.  */
2587       if (i.types[0] == BIT && ((i.op.src[0] & BIT) == BIT))
2588 	{
2589 	  unsigned char temp = (i.maxq20_op[0].r_bit)->bit;
2590 
2591 	  temp = temp << 4;
2592 	  temp |= i.op.src[1];
2593 	  i.instr[1] = temp;
2594 	}
2595       /* In case of MOVE dst.<b>,#1 The first nibble in the source register
2596          has to start with a zero. This is called a ZEROBIT */
2597       else if (i.types[0] == BIT && ((i.op.src[0] & ZEROBIT) == ZEROBIT))
2598 	{
2599 	  char temp = (i.maxq20_op[0].r_bit)->bit;
2600 
2601 	  temp = temp << 4;
2602 	  temp |= i.op.src[1];
2603 	  temp &= 0x7f;
2604 	  i.instr[1] = temp;
2605 	}
2606       /* Similarly for a ONEBIT */
2607       else if (i.types[0] == BIT && ((i.op.src[0] & ONEBIT) == ONEBIT))
2608 	{
2609 	  char temp = (i.maxq20_op[0].r_bit)->bit;
2610 
2611 	  temp = temp << 4;
2612 	  temp |= i.op.src[1];
2613 	  temp |= 0x80;
2614 	  i.instr[1] = temp;
2615 	}
2616       /* In case the second operand is a register bit (MOVE C,Acc.<b> or MOVE
2617          C,src.<b> */
2618       else if (i.types[1] == BIT)
2619 	{
2620 	  if (i.op.src[1] == 0 && i.op.src[1] == REG)
2621 	    i.instr[1] = (i.maxq20_op[1].r_bit)->reg->opcode;
2622 
2623 	  else if (i.op.src[0] == BIT && i.op.src)
2624 	    {
2625 	      char temp = (i.maxq20_op[1].r_bit)->bit;
2626 
2627 	      temp = temp << 4;
2628 	      temp |= i.op.src[1];
2629 	      i.instr[1] = temp;
2630 	    }
2631 	}
2632       else
2633 	{
2634 	  as_bad (_("Invalid Instruction"));
2635 	  return 0;
2636 	}
2637     }
2638   return 1;
2639 }
2640 
2641 /* This is a function for outputting displacement operands.  */
2642 
2643 static void
output_disp(fragS * insn_start_frag,offsetT insn_start_off)2644 output_disp (fragS *insn_start_frag, offsetT insn_start_off)
2645 {
2646   char *p;
2647   relax_substateT subtype;
2648   symbolS *sym;
2649   offsetT off;
2650   int diff;
2651 
2652   diff = 0;
2653   insn_start_frag = frag_now;
2654   insn_start_off = frag_now_fix ();
2655 
2656   switch (i.Instr_Prefix)
2657     {
2658     case LONG_PREFIX:
2659       subtype = EXPLICT_LONG_PREFIX;
2660       break;
2661     case SHORT_PREFIX:
2662       subtype = SHORT_PREFIX;
2663       break;
2664     default:
2665       subtype = NO_PREFIX;
2666       break;
2667     }
2668 
2669   /* Its a symbol. Here we end the frag and start the relaxation. Now in our
2670      case there is no need for relaxation. But we do need support for a
2671      prefix operator. Hence we will check whethere is room for 4 bytes ( 2
2672      for prefix + 2 for the current instruction ) Hence if at a particular
2673      time we find out whether the prefix operator is reqd , we shift the
2674      current instruction two places ahead and insert the prefix instruction.  */
2675   frag_grow (2 + 2);
2676   p = frag_more (2);
2677 
2678   sym = i.maxq20_op[this_operand].disps->X_add_symbol;
2679   off = i.maxq20_op[this_operand].disps->X_add_number;
2680 
2681   if (i.maxq20_op[this_operand].disps->X_add_symbol != NULL && sym && frag_now
2682       && (subtype != EXPLICT_LONG_PREFIX))
2683     {
2684       /* If in the same frag.  */
2685       if (frag_now == symbol_get_frag (sym))
2686 	{
2687 	  diff =
2688 	    ((((expressionS *) symbol_get_value_expression (sym))->
2689 	      X_add_number) - insn_start_off);
2690 
2691 	  /* PC points to the next instruction.  */
2692 	  diff = (diff / MAXQ_OCTETS_PER_BYTE) - 1;
2693 
2694 	  if (diff >= -128 && diff <= 127)
2695 	    {
2696 	      i.instr[1] = (char) diff;
2697 
2698 	      /* This will be overwritten later when the symbol is resolved.  */
2699 	      *p = i.instr[1];
2700 	      *(p + 1) = i.instr[0];
2701 
2702 	      /* No Need to create a FIXUP.  */
2703 	      return;
2704 	    }
2705 	}
2706     }
2707 
2708   /* This will be overwritten later when the symbol is resolved.  */
2709   *p = i.instr[1];
2710   *(p + 1) = i.instr[0];
2711 
2712   if (i.maxq20_op[this_operand].disps->X_op != O_constant
2713       && i.maxq20_op[this_operand].disps->X_op != O_symbol)
2714     {
2715       /* Handle complex expressions.  */
2716       sym = make_expr_symbol (i.maxq20_op[this_operand].disps);
2717       off = 0;
2718     }
2719 
2720   /* Vineet : This has been added for md_estimate_size_before_relax to
2721      estimate the correct size.  */
2722   if (subtype != SHORT_PREFIX)
2723     i.reloc[this_operand] = LONG_PREFIX;
2724 
2725   frag_var (rs_machine_dependent, 2, i.reloc[this_operand], subtype, sym, off,  p);
2726 }
2727 
2728 /* This is a function for outputting displacement operands.  */
2729 
2730 static void
output_data(fragS * insn_start_frag,offsetT insn_start_off)2731 output_data (fragS *insn_start_frag, offsetT insn_start_off)
2732 {
2733   char *p;
2734   relax_substateT subtype;
2735   symbolS *sym;
2736   offsetT off;
2737   int diff;
2738 
2739   diff = 0;
2740   off = 0;
2741   insn_start_frag = frag_now;
2742   insn_start_off = frag_now_fix ();
2743 
2744   subtype = EXPLICT_LONG_PREFIX;
2745 
2746   frag_grow (2 + 2);
2747   p = frag_more (2);
2748 
2749   sym = i.maxq20_op[this_operand].data;
2750   off = 0;
2751 
2752   /* This will be overwritten later when the symbol is resolved.  */
2753   *p = i.instr[1];
2754   *(p + 1) = i.instr[0];
2755 
2756   if (i.maxq20_op[this_operand].disps->X_op != O_constant
2757       && i.maxq20_op[this_operand].disps->X_op != O_symbol)
2758     /* Handle complex expressions.  */
2759     /* Because data is already in terms of symbol so no
2760        need to convert it from expression to symbol.  */
2761     off = 0;
2762 
2763   frag_var (rs_machine_dependent, 2, i.reloc[this_operand], subtype, sym, off,  p);
2764 }
2765 
2766 static void
output_insn(void)2767 output_insn (void)
2768 {
2769   fragS *insn_start_frag;
2770   offsetT insn_start_off;
2771   char *p;
2772 
2773   /* Tie dwarf2 debug info to the address at the start of the insn. We can't
2774      do this after the insn has been output as the current frag may have been
2775      closed off.  eg. by frag_var.  */
2776   dwarf2_emit_insn (0);
2777 
2778   /* To ALign the text section on word.  */
2779 
2780   frag_align (1, 0, 1);
2781 
2782   /* We initialise the frags for this particular instruction.  */
2783   insn_start_frag = frag_now;
2784   insn_start_off = frag_now_fix ();
2785 
2786   /* If there are displacement operators(unresolved) present, then handle
2787      them separately.  */
2788   if (i.disp_operands)
2789     {
2790       output_disp (insn_start_frag, insn_start_off);
2791       return;
2792     }
2793 
2794   if (i.data_operands)
2795     {
2796       output_data (insn_start_frag, insn_start_off);
2797       return;
2798     }
2799 
2800   /* Check whether the INSERT_BUFFER has to be written.  */
2801   if (strcmp (INSERT_BUFFER, ""))
2802     {
2803       p = frag_more (2);
2804 
2805       *p++ = INSERT_BUFFER[1];
2806       *p = INSERT_BUFFER[0];
2807     }
2808 
2809   /* Check whether the prefix instruction has to be written.  */
2810   if (strcmp (PFX_INSN, ""))
2811     {
2812       p = frag_more (2);
2813 
2814       *p++ = PFX_INSN[1];
2815       *p = PFX_INSN[0];
2816     }
2817 
2818   p = frag_more (2);
2819   /* For Little endian.  */
2820   *p++ = i.instr[1];
2821   *p = i.instr[0];
2822 }
2823 
2824 static void
make_new_reg_table(void)2825 make_new_reg_table (void)
2826 {
2827   unsigned long size_pm = sizeof (peripheral_reg_table);
2828   num_of_reg = ARRAY_SIZE (peripheral_reg_table);
2829 
2830   new_reg_table = xmalloc (size_pm);
2831   if (new_reg_table == NULL)
2832     as_bad (_("Cannot allocate memory"));
2833 
2834   memcpy (new_reg_table, peripheral_reg_table, size_pm);
2835 }
2836 
2837 /* pmmain performs the initilizations for the pheripheral modules. */
2838 
2839 static void
pmmain(void)2840 pmmain (void)
2841 {
2842   make_new_reg_table ();
2843   return;
2844 }
2845 
2846 void
md_begin(void)2847 md_begin (void)
2848 {
2849   const char *hash_err = NULL;
2850   int c = 0;
2851   char *p;
2852   const MAXQ20_OPCODE_INFO *optab;
2853   MAXQ20_OPCODES *core_optab;	/* For opcodes of the same name. This will
2854 				   be inserted into the hash table.  */
2855   struct reg *reg_tab;
2856   struct mem_access_syntax const *memsyntab;
2857   struct mem_access *memtab;
2858   struct bit_name *bittab;
2859 
2860   /* Initilize pherioipheral modules.  */
2861   pmmain ();
2862 
2863   /* Initialise the opcode hash table.  */
2864   op_hash = hash_new ();
2865 
2866   optab = op_table;		/* Initialise it to the first entry of the
2867 				   maxq20 operand table.  */
2868 
2869   /* Setup for loop.  */
2870   core_optab = xmalloc (sizeof (MAXQ20_OPCODES));
2871   core_optab->start = optab;
2872 
2873   while (1)
2874     {
2875       ++optab;
2876       if (optab->name == NULL || strcmp (optab->name, (optab - 1)->name) != 0)
2877 	{
2878 	  /* different name --> ship out current template list; add to hash
2879 	     table; & begin anew.  */
2880 
2881 	  core_optab->end = optab;
2882 #ifdef MAXQ10S
2883 	  if (max_version == bfd_mach_maxq10)
2884 	    {
2885 	      if (((optab - 1)->arch == MAXQ10) || ((optab - 1)->arch == MAX))
2886 		{
2887 		  hash_err = hash_insert (op_hash,
2888 					  (optab - 1)->name,
2889 					  (PTR) core_optab);
2890 		}
2891 	    }
2892 	  else if (max_version == bfd_mach_maxq20)
2893 	    {
2894 	      if (((optab - 1)->arch == MAXQ20) || ((optab - 1)->arch == MAX))
2895 		{
2896 #endif
2897 		  hash_err = hash_insert (op_hash,
2898 					  (optab - 1)->name,
2899 					  (PTR) core_optab);
2900 #if MAXQ10S
2901 		}
2902 	    }
2903 	  else
2904 	    as_fatal (_("Internal Error: Illegal Architecure specified"));
2905 #endif
2906 	  if (hash_err)
2907 	    as_fatal (_("Internal Error:  Can't hash %s: %s"),
2908 		      (optab - 1)->name, hash_err);
2909 
2910 	  if (optab->name == NULL)
2911 	    break;
2912 	  core_optab = xmalloc (sizeof (MAXQ20_OPCODES));
2913 	  core_optab->start = optab;
2914 	}
2915     }
2916 
2917   /* Initialise a new register table.  */
2918   reg_hash = hash_new ();
2919 
2920   for (reg_tab = system_reg_table;
2921        reg_tab < (system_reg_table + ARRAY_SIZE (system_reg_table));
2922        reg_tab++)
2923     {
2924 #if MAXQ10S
2925       switch (max_version)
2926 	{
2927 	case bfd_mach_maxq10:
2928 	  if ((reg_tab->arch == MAXQ10) || (reg_tab->arch == MAX))
2929 	    hash_err = hash_insert (reg_hash, reg_tab->reg_name, (PTR) reg_tab);
2930 	  break;
2931 
2932 	case bfd_mach_maxq20:
2933 	  if ((reg_tab->arch == MAXQ20) || (reg_tab->arch == MAX))
2934 	    {
2935 #endif
2936 	      hash_err =
2937 		hash_insert (reg_hash, reg_tab->reg_name, (PTR) reg_tab);
2938 #if MAXQ10S
2939 	    }
2940 	  break;
2941 	default:
2942 	  as_fatal (_("Invalid architecture type"));
2943 	}
2944 #endif
2945 
2946       if (hash_err)
2947 	as_fatal (_("Internal Error : Can't Hash %s : %s"),
2948 		  reg_tab->reg_name, hash_err);
2949     }
2950 
2951   /* Pheripheral Registers Entry.  */
2952   for (reg_tab = new_reg_table;
2953        reg_tab < (new_reg_table + num_of_reg - 1); reg_tab++)
2954     {
2955       hash_err = hash_insert (reg_hash, reg_tab->reg_name, (PTR) reg_tab);
2956 
2957       if (hash_err)
2958 	as_fatal (_("Internal Error : Can't Hash %s : %s"),
2959 		  reg_tab->reg_name, hash_err);
2960     }
2961 
2962   /* Initialise a new memory operand table.  */
2963   mem_hash = hash_new ();
2964 
2965   for (memtab = mem_table;
2966        memtab < mem_table + ARRAY_SIZE (mem_table);
2967        memtab++)
2968     {
2969       hash_err = hash_insert (mem_hash, memtab->name, (PTR) memtab);
2970       if (hash_err)
2971 	as_fatal (_("Internal Error : Can't Hash %s : %s"),
2972 		  memtab->name, hash_err);
2973     }
2974 
2975   bit_hash = hash_new ();
2976 
2977   for (bittab = bit_table;
2978        bittab < bit_table + ARRAY_SIZE (bit_table);
2979        bittab++)
2980     {
2981       hash_err = hash_insert (bit_hash, bittab->name, (PTR) bittab);
2982       if (hash_err)
2983 	as_fatal (_("Internal Error : Can't Hash %s : %s"),
2984 		  bittab->name, hash_err);
2985     }
2986 
2987   mem_syntax_hash = hash_new ();
2988 
2989   for (memsyntab = mem_access_syntax_table;
2990        memsyntab < mem_access_syntax_table + ARRAY_SIZE (mem_access_syntax_table);
2991        memsyntab++)
2992     {
2993       hash_err =
2994 	hash_insert (mem_syntax_hash, memsyntab->name, (PTR) memsyntab);
2995       if (hash_err)
2996 	as_fatal (_("Internal Error : Can't Hash %s : %s"),
2997 		  memsyntab->name, hash_err);
2998     }
2999 
3000   /* Initialise the lexical tables,mnemonic chars,operand chars.  */
3001   for (c = 0; c < 256; c++)
3002     {
3003       if (ISDIGIT (c))
3004 	{
3005 	  digit_chars[c] = c;
3006 	  mnemonic_chars[c] = c;
3007 	  operand_chars[c] = c;
3008 	  register_chars[c] = c;
3009 	}
3010       else if (ISLOWER (c))
3011 	{
3012 	  mnemonic_chars[c] = c;
3013 	  operand_chars[c] = c;
3014 	  register_chars[c] = c;
3015 	}
3016       else if (ISUPPER (c))
3017 	{
3018 	  mnemonic_chars[c] = TOLOWER (c);
3019 	  register_chars[c] = c;
3020 	  operand_chars[c] = c;
3021 	}
3022 
3023       if (ISALPHA (c) || ISDIGIT (c))
3024 	{
3025 	  identifier_chars[c] = c;
3026 	}
3027       else if (c > 128)
3028 	{
3029 	  identifier_chars[c] = c;
3030 	  operand_chars[c] = c;
3031 	}
3032     }
3033 
3034   /* All the special characters.  */
3035   register_chars['@'] = '@';
3036   register_chars['+'] = '+';
3037   register_chars['-'] = '-';
3038   digit_chars['-'] = '-';
3039   identifier_chars['_'] = '_';
3040   identifier_chars['.'] = '.';
3041   register_chars['['] = '[';
3042   register_chars[']'] = ']';
3043   operand_chars['_'] = '_';
3044   operand_chars['#'] = '#';
3045   mnemonic_chars['['] = '[';
3046   mnemonic_chars[']'] = ']';
3047 
3048   for (p = operand_special_chars; *p != '\0'; p++)
3049     operand_chars[(unsigned char) *p] = (unsigned char) *p;
3050 
3051   /* Set the maxq arch type.  */
3052   maxq_target (max_version);
3053 }
3054 
3055 /* md_assemble - Parse Instr - Seprate menmonics and operands - lookup the
3056    menmunonic in the operand table - Parse operands and populate the
3057    structure/template - Match the operand with opcode and its validity -
3058    Output Instr.  */
3059 
3060 void
md_assemble(char * line)3061 md_assemble (char *line)
3062 {
3063   int j;
3064 
3065   char mnemonic[MAX_MNEM_SIZE];
3066   char temp4prev[256];
3067   static char prev_insn[256];
3068 
3069   /* Initialize globals.  */
3070   memset (&i, '\0', sizeof (i));
3071   for (j = 0; j < MAX_OPERANDS; j++)
3072     i.reloc[j] = NO_RELOC;
3073 
3074   i.prefix = -1;
3075   PFX_INSN[0] = 0;
3076   PFX_INSN[1] = 0;
3077   INSERT_BUFFER[0] = 0;
3078   INSERT_BUFFER[1] = 0;
3079 
3080   memcpy (temp4prev, line, strlen (line) + 1);
3081 
3082   save_stack_p = save_stack;
3083 
3084   line = (char *) parse_insn (line, mnemonic);
3085   if (line == NULL)
3086     return;
3087 
3088   line = (char *) parse_operands (line, mnemonic);
3089   if (line == NULL)
3090     return;
3091 
3092   /* Next, we find a template that matches the given insn, making sure the
3093      overlap of the given operands types is consistent with the template
3094      operand types.  */
3095   if (!match_template ())
3096     return;
3097 
3098   /* In the MAXQ20, there are certain register combinations, and other
3099      restrictions which are not allowed. We will try to resolve these right
3100      now.  */
3101   if (!match_filters ())
3102     return;
3103 
3104   /* Check for the approprate PFX register.  */
3105   set_prefix ();
3106   pfx_for_imm_val (0);
3107 
3108   if (!decode_insn ())		/* decode insn. */
3109     need_pass_2 = 1;
3110 
3111   /* Check for Exlipct PFX instruction.  */
3112   if (PFX_INSN[0] && (strstr (prev_insn, "PFX") || strstr (prev_insn, "pfx")))
3113     as_warn (_("Ineffective insntruction %s \n"), prev_insn);
3114 
3115   memcpy (prev_insn, temp4prev, strlen (temp4prev) + 1);
3116 
3117   /* We are ready to output the insn.  */
3118   output_insn ();
3119 }
3120